$$include '../../meta/macros.ptl'

import [mix linreg clamp fallback] from "@iosevka/util"
import [Box] from "@iosevka/geometry/box"
import [Joining] from "@iosevka/glyph/relation"

glyph-module

glyph-block Symbol-Math-Relation-Common : begin
	glyph-block-import Common-Derivatives
	glyph-block-import CommonShapes

	glyph-block-export EqualHoleWidth
	define EqualHoleWidth : AdviceStroke 5

	glyph-block-export EqualHalfSpace
	define EqualHalfSpace : (OperTop - OperBot) * 2 * DesignParameters.equal_wideness

	glyph-block-export IdentHalfSpace
	define IdentHalfSpace : EqualHalfSpace * 1.5

	glyph-block-export LessSlope
	define LessSlope : (5 / 13) * (OperTop - OperBot) / (RightSB - SB)

	glyph-block-export dH
	define dH : LessSlope * (RightSB - SB)

	glyph-block-export dHSubstSimple
	define dHSubstSimple : dH * 1

	glyph-block-export dHElem
	define dHElem : dH * 7 / 6

	glyph-block-export dHSmallElem
	define dHSmallElem : dH * (3 / 4)

	glyph-block-export lessEqDist
	define lessEqDist : Math.max (XH * 0.16) : AdviceStroke 4

	glyph-block-export dSH
	define dSH : (dH * 2 + lessEqDist * 2) / 3

glyph-block Symbol-Math-Relation-Equal : begin
	glyph-block-import CommonShapes
	glyph-block-import Common-Derivatives
	glyph-block-import Symbol-Math-Relation-Common : EqualHalfSpace IdentHalfSpace dH EqualHoleWidth
	glyph-block-import Symbol-Math-Arith : JunctDiamond

	glyph-block-export : EqualShape
	define [EqualShape left right] : union
		HBar.m left right (SymbolMid + EqualHalfSpace) OperatorStroke
		HBar.m left right (SymbolMid - EqualHalfSpace) OperatorStroke

	define [EqualShape.joinCap x] : union
		JunctDiamond x (SymbolMid + EqualHalfSpace) OperatorStroke
		JunctDiamond x (SymbolMid - EqualHalfSpace) OperatorStroke

	glyph-block-export : EqualHole
	define [EqualHole x]
		VBar.m x (SymbolMid - EqualHalfSpace) (SymbolMid + EqualHalfSpace) EqualHoleWidth

	glyph-block-export : IdentShape
	define [IdentShape left right] : union
		HBar.m left right (SymbolMid + IdentHalfSpace) OperatorStroke
		HBar.m left right SymbolMid OperatorStroke
		HBar.m left right (SymbolMid - IdentHalfSpace) OperatorStroke

	define [IdentShape.joinCap x] : union
		JunctDiamond x (SymbolMid + IdentHalfSpace) OperatorStroke
		JunctDiamond x SymbolMid OperatorStroke
		JunctDiamond x (SymbolMid - IdentHalfSpace) OperatorStroke

	glyph-block-export : IdentHole
	define [IdentHole x]
		VBar.m x (SymbolMid - IdentHalfSpace) (SymbolMid + IdentHalfSpace) EqualHoleWidth

	create-glyph 'equal' '=' : glyph-proc
		include : EqualShape SB RightSB

	define EqDotDistance : EqualHalfSpace * 2 + DotRadius * OperatorStroke / Stroke

	WithDotVariants 'oneDotApproxEq' 0x2250 : function [DrawAt kr ov] : glyph-proc
		local dr : DotRadius * kr * OperatorStroke / Stroke
		include : refer-glyph 'equal'
		include : DrawAt Middle (SymbolMid + EqDotDistance) (dr - ov)

	WithDotVariants 'twoDotApproxEqCenter' 0x2251 : function [DrawAt kr ov] : glyph-proc
		local dr : DotRadius * kr * OperatorStroke / Stroke
		include : refer-glyph 'equal'
		include : DrawAt Middle (SymbolMid + EqDotDistance) (dr - ov)
		include : DrawAt Middle (SymbolMid - EqDotDistance) (dr - ov)

	WithDotVariants 'twoDotApproxEq' 0x2252 : function [DrawAt kr ov] : glyph-proc
		local dr : DotRadius * kr * OperatorStroke / Stroke
		include : refer-glyph 'equal'
		include : DrawAt [mix SB RightSB (1/6)] (SymbolMid + EqDotDistance) (dr - ov)
		include : DrawAt [mix SB RightSB (5/6)] (SymbolMid - EqDotDistance) (dr - ov)

	WithDotVariants 'twoDotApproxEqAlt' 0x2253 : function [DrawAt kr ov] : glyph-proc
		local dr : DotRadius * kr * OperatorStroke / Stroke
		include : refer-glyph 'equal'
		include : DrawAt [mix SB RightSB (5/6)] (SymbolMid + EqDotDistance) (dr - ov)
		include : DrawAt [mix SB RightSB (1/6)] (SymbolMid - EqDotDistance) (dr - ov)

	create-glyph 'ringInEqual' 0x2256 : glyph-proc
		local ringSw : AdviceStroke 4
		include : difference
			refer-glyph 'equal'
			RingAt Middle SymbolMid (EqualHalfSpace + O + ringSw / 2)
		include : RingStrokeAt Middle SymbolMid (EqualHalfSpace + ringSw / 2) ringSw

	create-glyph 'ringEqual' 0x2257 : composite-proc
		refer-glyph 'equal'
		MarkSet.plus
		refer-glyph 'ringAbove'
		clear-anchors

	create-glyph 'geometricallyEquivalentTo' 0x224E : glyph-proc
		local ringSw : AdviceStroke 4
		local halfGap : EqualHalfSpace - OperatorStroke / 2
		local outerRad : EqualHalfSpace + ringSw / 2
		include : difference
			refer-glyph 'equal'
			OShapeOutline.NoOvershoot
				SymbolMid + EqualHalfSpace + outerRad
				SymbolMid - EqualHalfSpace - outerRad
				Middle - outerRad
				Middle + outerRad
				begin ringSw
				ArchDepthAOf outerRad Width
				ArchDepthBOf outerRad Width
		include : difference
			OShape
				SymbolMid + EqualHalfSpace + outerRad
				SymbolMid - EqualHalfSpace - outerRad
				Middle - outerRad
				Middle + outerRad
				begin ringSw
				ArchDepthAOf outerRad Width
				ArchDepthBOf outerRad Width
			Rect (SymbolMid + halfGap) (SymbolMid - halfGap) 0 Width

	create-glyph 'differenceBetween' 0x224F : glyph-proc
		include : intersection
			Rect ParenTop SymbolMid 0 Width
			refer-glyph 'geometricallyEquivalentTo'
		include : intersection
			Rect SymbolMid ParenBot 0 Width
			refer-glyph 'equal'

	create-glyph 'ident' 0x2261 : glyph-proc
		include : IdentShape SB RightSB

	create-glyph 'iiiident' 0x2263 : glyph-proc
		include : HBar.m SB RightSB (SymbolMid + EqualHalfSpace * 2.25) OperatorStroke
		include : HBar.m SB RightSB (SymbolMid + EqualHalfSpace * 0.75) OperatorStroke
		include : HBar.m SB RightSB (SymbolMid - EqualHalfSpace * 0.75) OperatorStroke
		include : HBar.m SB RightSB (SymbolMid - EqualHalfSpace * 2.25) OperatorStroke

	create-glyph 'equivalentTo' 0x224D : glyph-proc
		define kArcExtY1   3
		define kArcExtY2 : 3 + TanSlope * 2
		define kArcExtX    2
		include : intersection [MaskRight SB] [MaskLeft RightSB] : union
			dispiro
				widths.center OperatorStroke
				g4 [mix Middle SB      kArcExtX] (SymbolMid + EqualHalfSpace * kArcExtY1)
				g4 Middle (SymbolMid + EqualHalfSpace) [heading Rightward]
				g4 [mix Middle RightSB kArcExtX] (SymbolMid + EqualHalfSpace * kArcExtY2)
			dispiro
				widths.center OperatorStroke
				g4 [mix Middle SB      kArcExtX] (SymbolMid - EqualHalfSpace * kArcExtY2)
				g4 Middle (SymbolMid - EqualHalfSpace) [heading Rightward]
				g4 [mix Middle RightSB kArcExtX] (SymbolMid - EqualHalfSpace * kArcExtY1)

	create-glyph 'equalParallel' 0x22D5 : composite-proc
		refer-glyph 'equal'
		refer-glyph 'parallel'

	create-glyph 'equalDoubleSlash' 0x29E3 : composite-proc
		EqualShape [mix SB 0 0.5] [mix RightSB Width 0.5]
		refer-glyph 'slantedParallel'

	create-glyph 'equalDoubleSlashTilde' 0x29E4 : composite-proc
		refer-glyph 'equalDoubleSlash'
		MarkSet.tack
		refer-glyph 'tildeAbove'
		clear-anchors

	create-glyph 'identDoubleSlash' 0x29E5 : composite-proc
		IdentShape [mix SB 0 0.5] [mix RightSB Width 0.5]
		refer-glyph 'slantedParallel'

	create-glyph 'recordMark' 0x29E7 : composite-proc
		refer-glyph 'equal'
		refer-glyph 'stile'

	turned 'equalDot' 0x2A66 'oneDotApproxEq' Middle SymbolMid

	WithDotVariants 'oneDotIdent' 0x2A67 : function [DrawAt kr ov] : glyph-proc
		local dr : DotRadius * kr * OperatorStroke / Stroke
		include : refer-glyph 'ident'
		include : DrawAt Middle (SymbolMid + EqualHalfSpace * 0.5 + EqDotDistance) (dr - ov)

	create-glyph 'identParallel' 0x2A68 : composite-proc
		refer-glyph 'ident'
		refer-glyph 'parallel'

	create-glyph 'identInterleave' 0x2A69 : composite-proc
		IdentShape [mix SB 0 0.5] [mix RightSB Width 0.5]
		refer-glyph 'interleave'

	create-glyph 'bumpEqual' 0x2AAE : glyph-proc
		include : intersection
			Rect ParenTop SymbolMid 0 Width
			refer-glyph 'geometricallyEquivalentTo'
		include : ApparentTranslate 0 (EqualHalfSpace * 0.5)

		include : HBar.m SB RightSB SymbolMid OperatorStroke
		include : HBar.m SB RightSB (SymbolMid - EqualHalfSpace * 1.5) OperatorStroke

	create-glyph 'groupMark' 0x2BD2 : composite-proc
		refer-glyph 'ident'
		refer-glyph 'stile'

glyph-block Symbol-Math-Relation-Addons : begin
	glyph-block-import CommonShapes
	glyph-block-import Common-Derivatives
	glyph-block-import Symbol-Math-Relation-Common : lessEqDist dH dSH

	glyph-block-export lesslessSW muchLessSW lesslessSWO llggHeight
	define lesslessSW : AdviceStroke 3.5
	define muchLessSW : AdviceStroke 4.5 para.advanceScaleMM
	define lesslessSWO : Math.max lesslessSW lessEqDist
	define llggHeight : dH * 2 + lessEqDist * 2

	glyph-block-export EqEqBarNegationImpl
	define [EqEqBarNegationImpl sw y1 y2] : dispiro
		widths.center sw
		flat (Middle + lessEqDist) (y1 + lesslessSWO) [heading Downward]
		flat (Middle - lessEqDist) (y2 - lesslessSWO) [heading Downward]

	glyph-block-export EqEqBarNegation
	define [EqEqBarNegation] : EqEqBarNegationImpl lesslessSW
		SymbolMid - dSH + lessEqDist * 2 / 3
		SymbolMid - dSH - lessEqDist

glyph-block Symbol-Math-Relation-Colons : begin
	glyph-block-import CommonShapes
	glyph-block-import Common-Derivatives
	glyph-block-import Symbol-Arrow-Shared : ArrowShape
	glyph-block-import Symbol-Math-Relation-Equal : EqualShape

	define ColonEqSbSquash 0.5
	define [ColonEqColonShape sign DrawAt kr ov] : new-glyph : glyph-proc
		local dr : DotRadius * kr * OperatorStroke / Stroke
		include : DrawAt Middle dr (dr - ov)
		include : DrawAt Middle (XH - dr) (dr - ov)

		local delta : Math.max 0 : Middle - dr - SB * ColonEqSbSquash
		include : ApparentTranslate (sign * delta) (SymbolMid - XH / 2)

	WithDotVariants 'eqColon' 0x2255 : function [DrawAt kr ov] : glyph-proc
		include : ColonEqColonShape (+1) DrawAt kr ov
		include : EqualShape (SB * ColonEqSbSquash) (RightSB - DotSize * kr)

	WithDotVariants 'colonEq' 0x2254 : function [DrawAt kr ov] : glyph-proc
		include : ColonEqColonShape (-1) DrawAt kr ov
		include : EqualShape (SB + DotSize * kr) (Width - SB * ColonEqSbSquash)

	WithDotVariants 'colonArrow' 0x29F4 : function [DrawAt kr ov] : glyph-proc
		local barLeft : SB + DotSize * kr
		local barRight : Width - SB * ColonEqSbSquash
		local arrowHeadSize : Math.min ((PlusTop - PlusBot) / 2) (0.75 * (barRight - barLeft))
		include : ColonEqColonShape (-1) DrawAt kr ov
		include : HBar.m [mix SB barLeft 0.8] [mix barLeft barRight 0.5] SymbolMid OperatorStroke
		include : ArrowShape barLeft SymbolMid barRight SymbolMid arrowHeadSize

glyph-block Symbol-Math-Relation-Sym : begin
	glyph-block-import CommonShapes
	glyph-block-import Common-Derivatives
	glyph-block-import Mark-Above : TildeShape
	glyph-block-import Symbol-Math-Relation-Common : EqualHalfSpace IdentHalfSpace
	glyph-block-import Symbol-Math-Relation-Addons : EqEqBarNegationImpl

	# Sym parameters
	local approxDist : EqualHalfSpace * 1.75
	local symMag : (OperTop - SymbolMid) * 0.17

	glyph-block-export symWave
	define [symWave height mul sw] : TildeShape
		ttop -- height + symMag * mul
		tbot -- height - symMag * mul
		leftEnd -- SB
		rightEnd -- RightSB
		hs -- [fallback sw OperatorStroke] / 2

	create-glyph 'sym' 0x223C : symWave SymbolMid 1
	create-glyph 'flipSym' 0x223D : symWave SymbolMid (-1)

	WithDotVariants 'twoDotSym' 0x223B : function [DrawAt kr ov] : composite-proc
		refer-glyph 'sym'
		DrawAt Middle PlusTop (DotRadius * kr * OperatorStroke / Stroke - ov)
		DrawAt Middle PlusBot (DotRadius * kr * OperatorStroke / Stroke - ov)

	VDual 'approx' 0x2248 'sym' approxDist

	create-glyph 'aapprox' 0x224B : glyph-proc
		include : symWave (SymbolMid + approxDist) 1
		include : symWave SymbolMid 1
		include : symWave (SymbolMid - approxDist) 1

	create-glyph 'approxBar' 0x224A : glyph-proc
		include : symWave (SymbolMid + approxDist) 1
		include : symWave SymbolMid 1
		include : HBar.m SB RightSB (SymbolMid - approxDist) OperatorStroke

	create-glyph 'barSym' 0x2242 : glyph-proc
		include [refer-glyph 'sym'] AS_BASE
		include : ApparentTranslate 0 (-approxDist / 2)
		include : HBar.m SB RightSB (SymbolMid + approxDist / 2) OperatorStroke

	create-glyph 'symEq' 0x2243 : glyph-proc
		include [refer-glyph 'sym'] AS_BASE
		include : ApparentTranslate 0 (approxDist / 2)
		include : HBar.m SB RightSB (SymbolMid - approxDist / 2) OperatorStroke

	create-glyph 'symEqEq' 0x2245 : glyph-proc
		local sympShift : approxDist + IdentHalfSpace
		include [refer-glyph 'sym'] AS_BASE
		include : ApparentTranslate 0 (sympShift / 2)
		include : HBar.m SB RightSB (SymbolMid - sympShift / 2 + IdentHalfSpace) OperatorStroke
		include : HBar.m SB RightSB (SymbolMid - sympShift / 2) OperatorStroke

		create-forked-glyph 'symEqEqBarNegated' 0x2246 : EqEqBarNegationImpl OperatorStroke
			SymbolMid - sympShift / 2 + IdentHalfSpace
			SymbolMid - sympShift / 2

	create-glyph 'flipSymEq' 0x22CD : glyph-proc
		include [refer-glyph 'flipSym'] AS_BASE
		include : ApparentTranslate 0 (approxDist / 2)
		include : HBar.m SB RightSB (SymbolMid - approxDist / 2) OperatorStroke

	create-glyph 'flipSymEqEq' 0x224C : glyph-proc
		local sympShift : approxDist + IdentHalfSpace
		include [refer-glyph 'flipSym'] AS_BASE
		include : ApparentTranslate 0 (sympShift / 2)
		include : HBar.m SB RightSB (SymbolMid - sympShift / 2 + IdentHalfSpace) OperatorStroke
		include : HBar.m SB RightSB (SymbolMid - sympShift / 2) OperatorStroke

	WithDotVariants 'oneDotSym' 0x2A6A : function [DrawAt kr ov] : composite-proc
		refer-glyph 'sym'
		DrawAt Middle PlusTop (DotRadius * kr * OperatorStroke / Stroke - ov)

	WithDotVariants 'twoDotSymAlt' 0x2A6B : function [DrawAt kr ov] : glyph-proc
		local dr : DotRadius * kr * OperatorStroke / Stroke
		include : refer-glyph 'sym'
		include : DrawAt [mix SB RightSB (1/6)] PlusBot (dr - ov)
		include : DrawAt [mix SB RightSB (5/6)] PlusTop (dr - ov)

	create-glyph 'symMinusSym' 0x2A6C : glyph-proc
		include : symWave (SymbolMid + approxDist) 1
		include : HBar.m SB RightSB SymbolMid OperatorStroke
		include : symWave (SymbolMid - approxDist) 1

	WithDotVariants 'oneDotSymEqEq' 0x2A6D : function [DrawAt kr ov] : composite-proc
		refer-glyph 'symEqEq'
		DrawAt Middle (PlusTop + IdentHalfSpace) (DotRadius * kr * OperatorStroke / Stroke - ov)

	create-glyph 'approxCircumflex' 0x2A6F : composite-proc
		refer-glyph 'approx'
		MarkSet.plus
		refer-glyph 'circumflexAbove'
		clear-anchors

	create-glyph 'approxEqEq' 0x2A70 : glyph-proc
		include : symWave (SymbolMid + approxDist * 1.375) 1
		include : symWave (SymbolMid + approxDist * 0.375) 1
		include : HBar.m SB RightSB (SymbolMid - approxDist * 1.5 + IdentHalfSpace) OperatorStroke
		include : HBar.m SB RightSB (SymbolMid - approxDist * 1.5) OperatorStroke

	create-glyph 'eqEqSym' 0x2A73 : glyph-proc
		local sympShift : approxDist + IdentHalfSpace
		include [refer-glyph 'sym'] AS_BASE
		include : ApparentTranslate 0 (-sympShift / 2)
		include : HBar.m SB RightSB (SymbolMid + sympShift / 2 - IdentHalfSpace) OperatorStroke
		include : HBar.m SB RightSB (SymbolMid + sympShift / 2) OperatorStroke

glyph-block Symbol-Math-Relation-Inequality : begin
	glyph-block-import CommonShapes
	glyph-block-import Common-Derivatives
	glyph-block-import Symbol-Math-Relation-Common : dH dSH lessEqDist
	glyph-block-import Symbol-Math-Relation-Sym : symWave
	glyph-block-import Symbol-Math-Relation-Addons : lesslessSW muchLessSW llggHeight
	glyph-block-import Symbol-Math-Relation-Addon-Glyphs

	define [LessGreaterExpansion top bot l r]
		Math.sqrt : 1 + (top - bot) / (2 * (r - l)) * (top - bot) / (2 * (r - l))

	define [LessMaskShape top bot l r] : spiro-outline
		corner r top
		corner r bot
		corner l [mix bot top 0.5]
	define [GreaterMaskShape top bot l r] : spiro-outline
		corner l top
		corner l bot
		corner r [mix bot top 0.5]

	define [LessShapeHalf sign top bot l r s p] : begin
		define exp : LessGreaterExpansion top bot l r
		define expAmend : Math.min Math.SQRT2 exp
		define endAdj : 0.5 * s * (exp - expAmend)
		define pp : fallback p 1

		return : dispiro
			widths.center s
			flat [mix l r pp] [mix [mix top bot 0.5] [mix bot top sign] pp]
			curl (l - endAdj) [mix top bot 0.5] [widths.center.heading (s * expAmend) Leftward]

	define [GreaterShapeHalf sign top bot l r s p] : begin
		define exp : LessGreaterExpansion top bot l r
		define expAmend : Math.min Math.SQRT2 exp
		define endAdj : 0.5 * s * (exp - expAmend)
		define pp : fallback p 1

		return : dispiro
			widths.center s
			flat [mix r l pp] [mix [mix top bot 0.5] [mix bot top sign] pp]
			curl (r + endAdj) [mix top bot 0.5] [widths.center.heading (s * expAmend) Rightward]

	glyph-block-export LessShape
	define [LessShape top bot l r s] : union
		LessShapeHalf 0 top bot l r [fallback s OperatorStroke]
		LessShapeHalf 1 top bot l r [fallback s OperatorStroke]

	glyph-block-export LigationLessShape
	define [LigationLessShape top bot l r s t gap] : union
		intersection
			Rect [mix bot top 2] [mix top bot 2] [mix r l 2] r
			union
				LessShapeHalf 0 top bot l r [fallback s OperatorStroke] 2
				LessShapeHalf 1 top bot l r [fallback s OperatorStroke] 2
		intersection
			LessMaskShape top bot l r
			difference
				dispiro
					widths.lhs [fallback t OperatorStroke]
					corner r bot
					corner r top
				Rect ([mix top bot 0.5] + gap / 2) ([mix top bot 0.5] - gap / 2) (l + O) (r - O)

	define [NormalSubsetShape top bot l r s] : LigationLessShape top bot l r s s 0
	define [AntirestrictionLeftShape top bot l r s s2] : union [NormalSubsetShape top bot l r s]
		intersection
			LessMaskShape top bot l r
			HBar.m l r [mix top bot 0.5] [fallback s2 s OperatorStroke]
	define [SmallerShape top bot l r s] : union [LessShape top bot l r s]
		intersection
			LessMaskShape top bot l r
			HBar.m l r [mix top bot 0.5] [fallback s OperatorStroke]

	glyph-block-export GreaterShape
	define [GreaterShape top bot l r s] : union
		GreaterShapeHalf 0 top bot l r [fallback s OperatorStroke]
		GreaterShapeHalf 1 top bot l r [fallback s OperatorStroke]

	glyph-block-export LigationGreaterShape
	define [LigationGreaterShape top bot l r s t gap] : union
		intersection
			Rect [mix bot top 2] [mix top bot 2] [mix l r 2] l
			union
				GreaterShapeHalf 0 top bot l r [fallback s OperatorStroke] 2
				GreaterShapeHalf 1 top bot l r [fallback s OperatorStroke] 2
		intersection
			GreaterMaskShape top bot l r
			difference
				dispiro
					widths.rhs [fallback t OperatorStroke]
					corner l bot
					corner l top
				Rect ([mix top bot 0.5] + gap / 2) ([mix top bot 0.5] - gap / 2) (l + O) (r - O)

	define [NormalSupersetShape top bot l r s] : LigationGreaterShape top bot l r s s 0
	define [AntirestrictionRightShape top bot l r s s2] : union [NormalSupersetShape top bot l r s]
		intersection
			GreaterMaskShape top bot l r
			HBar.m l r [mix top bot 0.5] [fallback s2 s OperatorStroke]
	define [LargerShape top bot l r s] : union [GreaterShape top bot l r s]
		intersection
			GreaterMaskShape top bot l r
			HBar.m l r [mix top bot 0.5] [fallback s OperatorStroke]

	create-glyph 'less' '<' : glyph-proc
		include : LessShape (SymbolMid + dH) (SymbolMid - dH) SB RightSB

	WithDotVariants 'lessDot' 0x22D6 : function [DrawAt kr ov] : composite-proc
		LessShape (SymbolMid + dH) (SymbolMid - dH) SB RightSB [AdviceStroke 4]
		DrawAt (RightSB - DotRadius) SymbolMid (DotRadius * kr * [AdviceStroke 4] / Stroke - ov)

	create-glyph 'observerEye' 0x23FF : glyph-proc
		local lensXP 0.8
		local lensRX : (RightSB - SB) * (1 - lensXP) + [HSwToV : 0.25 * OperatorStroke]
		local lensRY : dH * lensXP + 0.25 * OperatorStroke
		include : refer-glyph 'less'
		include : intersection
			union
				LessMaskShape (SymbolMid + dH) (SymbolMid - dH) SB RightSB
				MaskRight RightSB
			Ellipse.Outline.At [mix SB RightSB lensXP] SymbolMid lensRX lensRY

	create-glyph 'normalSubsetOf' 0x22B2 : glyph-proc
		include : NormalSubsetShape (SymbolMid + dH) (SymbolMid - dH) SB RightSB

	create-glyph 'zNotationDomainAntirestriction' 0x2A64 : glyph-proc
		include : AntirestrictionLeftShape (SymbolMid + dH) (SymbolMid - dH) SB RightSB OperatorStroke [AdviceStroke 4.5]

	create-glyph 'smaller' 0x2AAA : glyph-proc
		include : SmallerShape (SymbolMid + dH) (SymbolMid - dH) SB RightSB

	create-glyph 'greater' '>' : glyph-proc
		include : GreaterShape (SymbolMid + dH) (SymbolMid - dH) SB RightSB

	WithDotVariants 'greaterDot' 0x22D7 : function [DrawAt kr ov] : composite-proc
		GreaterShape (SymbolMid + dH) (SymbolMid - dH) SB RightSB [AdviceStroke 4]
		DrawAt (SB + DotRadius) SymbolMid (DotRadius * kr * [AdviceStroke 4] / Stroke - ov)

	create-glyph 'normalSupersetOf' 0x22B3 : glyph-proc
		include : NormalSupersetShape (SymbolMid + dH) (SymbolMid - dH) SB RightSB

	create-glyph 'zNotationRangeAntirestriction' 0x2A65 : glyph-proc
		include : AntirestrictionRightShape (SymbolMid + dH) (SymbolMid - dH) SB RightSB OperatorStroke [AdviceStroke 4.5]

	create-glyph 'larger' 0x2AAB : glyph-proc
		include : LargerShape (SymbolMid + dH) (SymbolMid - dH) SB RightSB

	create-glyph 'lessEqUpper'         : LessShape           (SymbolMid + dSH + lessEqDist) (SymbolMid - dSH + lessEqDist) SB RightSB
	create-glyph 'greaterEqUpper'      : GreaterShape        (SymbolMid + dSH + lessEqDist) (SymbolMid - dSH + lessEqDist) SB RightSB
	create-glyph 'normalSubsetUpper'   : NormalSubsetShape   (SymbolMid + dSH + lessEqDist) (SymbolMid - dSH + lessEqDist) SB RightSB
	create-glyph 'normalSupersetUpper' : NormalSupersetShape (SymbolMid + dSH + lessEqDist) (SymbolMid - dSH + lessEqDist) SB RightSB
	create-glyph 'smallerEqUpper'      : SmallerShape        (SymbolMid + dSH + lessEqDist) (SymbolMid - dSH + lessEqDist) SB RightSB
	create-glyph 'largerEqUpper'       : LargerShape         (SymbolMid + dSH + lessEqDist) (SymbolMid - dSH + lessEqDist) SB RightSB

	derive-composites 'less.narrow'         null 'lessEqUpper' [ApparentTranslate 0 (-lessEqDist)]
	derive-composites 'lessEq'            0x2264 'lessEqUpper' 'eqLower'
	derive-composites 'lessEqBarNegated'  0x2A87 'lessEqUpper' 'eqBarNegatedLower'
	derive-composites 'lessSym'           0x2272 'lessEqUpper' 'symLower'
	derive-composites 'lessSymBarNegated' 0x22E6 'lessEqUpper' 'symBarNegatedLower'
	derive-composites 'lessEqSlant'       0x2A7D 'lessEqUpper'
		LessShapeHalf 0 (SymbolMid + dH - lessEqDist) (SymbolMid - dH - lessEqDist) SB RightSB OperatorStroke

	WithDotVariants 'lessEqSlantDot' 0x2A7F : function [DrawAt kr ov] : composite-proc
		LessShape (SymbolMid + dSH + lessEqDist) (SymbolMid - dSH + lessEqDist) SB RightSB [AdviceStroke 4]
		LessShapeHalf 0 (SymbolMid + dH - lessEqDist) (SymbolMid - dH - lessEqDist) SB RightSB [AdviceStroke 4]
		DrawAt (RightSB - DotRadius) (SymbolMid + lessEqDist) (DotRadius * kr * [AdviceStroke 4] / Stroke - ov)

	derive-composites 'greater.narrow'         null 'greaterEqUpper' [ApparentTranslate 0 (-lessEqDist)]
	derive-composites 'greaterEq'            0x2265 'greaterEqUpper' 'eqLower'
	derive-composites 'greaterEqBarNegated'  0x2A88 'greaterEqUpper' 'eqBarNegatedLower'
	derive-composites 'greaterSym'           0x2273 'greaterEqUpper' 'symLower'
	derive-composites 'greaterSymBarNegated' 0x22E7 'greaterEqUpper' 'symBarNegatedLower'
	derive-composites 'greaterEqSlant'       0x2A7E 'greaterEqUpper'
		GreaterShapeHalf 0 (SymbolMid + dH - lessEqDist) (SymbolMid - dH - lessEqDist) SB RightSB OperatorStroke

	WithDotVariants 'greaterEqSlantDot' 0x2A80 : function [DrawAt kr ov] : composite-proc
		GreaterShape (SymbolMid + dSH + lessEqDist) (SymbolMid - dSH + lessEqDist) SB RightSB [AdviceStroke 4]
		GreaterShapeHalf 0 (SymbolMid + dH - lessEqDist) (SymbolMid - dH - lessEqDist) SB RightSB [AdviceStroke 4]
		DrawAt (SB + DotRadius) (SymbolMid + lessEqDist) (DotRadius * kr * [AdviceStroke 4] / Stroke - ov)

	derive-composites 'normalSubsetEq'   0x22B4 'normalSubsetUpper' 'eqLower'
	derive-composites 'normalSupersetEq' 0x22B5 'normalSupersetUpper' 'eqLower'
	derive-composites 'smallerEq' 0x2AAC 'smallerEqUpper' 'eqLower'
	derive-composites 'largerEq'  0x2AAD 'largerEqUpper'  'eqLower'

	turned 'turnGreaterEq' 0x22DC 'greaterEq' Middle SymbolMid
	turned 'turnLessEq'    0x22DD 'lessEq' Middle SymbolMid

	do "Ligation Glyphs"
		define l : 0.3 * Width
		define r : 2 * Width - l
		define l2 : l - Width
		define r2 : r - Width
		create-glyph 'less.lig2' : glyph-proc
			Joining.set currentGlyph Joining.Classes.Right
			include : LessShape (SymbolMid + dH + lessEqDist) (SymbolMid - dH + lessEqDist) l r
		create-glyph 'greater.lig2' : glyph-proc
			Joining.set currentGlyph Joining.Classes.Right
			include : GreaterShape (SymbolMid + dH + lessEqDist) (SymbolMid - dH + lessEqDist) l r
		create-glyph 'eq.at-lteq.lig2.flat' : glyph-proc
			Joining.set currentGlyph Joining.Classes.Left
			include : HBar.m l2 r2 (SymbolMid - dH - lessEqDist) OperatorStroke
			create-aliased-glyph 'eq.at-gteq.lig2.flat'
		create-glyph 'eq.at-lteq.lig2.slanted' : glyph-proc
			Joining.set currentGlyph Joining.Classes.Left
			include : LessShapeHalf 0 (SymbolMid + dH - lessEqDist) (SymbolMid - dH - lessEqDist) l2 r2 OperatorStroke
		create-glyph 'eq.at-gteq.lig2.slanted' : glyph-proc
			Joining.set currentGlyph Joining.Classes.Left
			include : GreaterShapeHalf 0 (SymbolMid + dH - lessEqDist) (SymbolMid - dH - lessEqDist) l2 r2 OperatorStroke

	select-variant 'eq.at-lteq.lig2'
	select-variant 'eq.at-gteq.lig2'

	create-glyph 'lessEqEqUpper'    : LessShape    (SymbolMid + dSH + lessEqDist) (SymbolMid - dSH + lessEqDist * 1.75) SB RightSB lesslessSW
	create-glyph 'greaterEqEqUpper' : GreaterShape (SymbolMid + dSH + lessEqDist) (SymbolMid - dSH + lessEqDist * 1.75) SB RightSB lesslessSW

	derive-composites 'lessEqEq'                0x2266 'lessEqEqUpper'    'eqEqLower'
	derive-composites 'greaterEqEq'             0x2267 'greaterEqEqUpper' 'eqEqLower'
	derive-composites 'lessEqEqBarNegated'      0x2268 'lessEqEqUpper'    'eqEqBarNegatedLower'
	derive-composites 'greaterEqEqBarNegated'   0x2269 'greaterEqEqUpper' 'eqEqBarNegatedLower'
	derive-composites 'lessSymSym'              0x2A85 'lessEqEqUpper'    'symSymLower'
	derive-composites 'greaterSymSym'           0x2A86 'greaterEqEqUpper' 'symSymLower'
	derive-composites 'lessSymSymBarNegated'    0x2A89 'lessEqEqUpper'    'symSymBarNegatedLower'
	derive-composites 'greaterSymSymBarNegated' 0x2A8A 'greaterEqEqUpper' 'symSymBarNegatedLower'
	derive-composites 'lessSymEq'               0x2A8D 'lessEqEqUpper'    'symEqLower'
	derive-composites 'greaterSymEq'            0x2A8E 'greaterEqEqUpper' 'symEqLower'

	turned 'turnGreaterEqSlant'    0x2A95 'greaterEqSlant'    Middle SymbolMid
	turned 'turnLessEqSlant'       0x2A96 'lessEqSlant'       Middle SymbolMid
	turned 'turnGreaterEqSlantDot' 0x2A97 'greaterEqSlantDot' Middle SymbolMid
	turned 'turnLessEqSlantDot'    0x2A98 'lessEqSlantDot'    Middle SymbolMid
	turned 'turnGreaterEqEq'       0x2A99 'greaterEqEq'       Middle SymbolMid
	turned 'turnLessEqEq'          0x2A9A 'lessEqEq'          Middle SymbolMid
	turned 'turnGreaterSym'        0x2A9D 'greaterSym'        Middle SymbolMid
	turned 'turnLessSym'           0x2A9E 'lessSym'           Middle SymbolMid

	create-glyph 'lessGreater' 0x2276 : glyph-proc
		include : LessShape (SymbolMid + llggHeight / 2) (SymbolMid - llggHeight / 6 + lessEqDist) SB RightSB lesslessSW
		include : GreaterShape (SymbolMid + llggHeight / 6 - lessEqDist) (SymbolMid - llggHeight / 2) SB RightSB lesslessSW
	create-glyph 'greaterLess' 0x2277 : glyph-proc
		include : GreaterShape (SymbolMid + llggHeight / 2) (SymbolMid - llggHeight / 6 + lessEqDist) SB RightSB lesslessSW
		include : LessShape (SymbolMid + llggHeight / 6 - lessEqDist) (SymbolMid - llggHeight / 2) SB RightSB lesslessSW
	create-glyph 'lessEqGreater' 0x22DA : glyph-proc
		include : LessShape (SymbolMid + llggHeight / 2 + lessEqDist) (SymbolMid - llggHeight / 6 + lessEqDist * 2) SB RightSB lesslessSW
		include : GreaterShape (SymbolMid + llggHeight / 6 - lessEqDist * 2) (SymbolMid - llggHeight / 2 - lessEqDist) SB RightSB lesslessSW
		include : HBar.m SB RightSB (SymbolMid) lesslessSW
	create-glyph 'greaterEqLess' 0x22DB : glyph-proc
		include : GreaterShape (SymbolMid + llggHeight / 2 + lessEqDist) (SymbolMid - llggHeight / 6 + lessEqDist * 2) SB RightSB lesslessSW
		include : LessShape (SymbolMid + llggHeight / 6 - lessEqDist * 2) (SymbolMid - llggHeight / 2 - lessEqDist) SB RightSB lesslessSW
		include : HBar.m SB RightSB (SymbolMid) lesslessSW
	create-glyph 'normalSupersetNormalSubset' 0x29CE : glyph-proc
		include : NormalSupersetShape (SymbolMid + llggHeight / 2) (SymbolMid - llggHeight / 6 + lessEqDist) SB RightSB lesslessSW
		include : NormalSubsetShape (SymbolMid + llggHeight / 6 - lessEqDist) (SymbolMid - llggHeight / 2) SB RightSB lesslessSW

	create-glyph 'lessless' 0x226A : glyph-proc
		include : LessShape (SymbolMid + dH) (SymbolMid - dH) (SB - lessEqDist / 2) (RightSB - lessEqDist * 2) lesslessSW
		include : LessShape (SymbolMid + dH) (SymbolMid - dH) (SB + lessEqDist * 2) (RightSB + lessEqDist / 2) lesslessSW
	create-glyph 'greatergreater' 0x226B : glyph-proc
		include : GreaterShape (SymbolMid + dH) (SymbolMid - dH) (SB - lessEqDist / 2) (RightSB - lessEqDist * 2) lesslessSW
		include : GreaterShape (SymbolMid + dH) (SymbolMid - dH) (SB + lessEqDist * 2) (RightSB + lessEqDist / 2) lesslessSW

	create-glyph 'muchLess' 0x22D8 : glyph-proc
		local df : include : DivFrame para.advanceScaleMM 3
		include : LessShape (SymbolMid + dH) (SymbolMid - dH) [mix df.leftSB df.rightSB (0/3)] [mix df.leftSB df.rightSB (1/3)] muchLessSW
		include : LessShape (SymbolMid + dH) (SymbolMid - dH) [mix df.leftSB df.rightSB (1/3)] [mix df.leftSB df.rightSB (2/3)] muchLessSW
		include : LessShape (SymbolMid + dH) (SymbolMid - dH) [mix df.leftSB df.rightSB (2/3)] [mix df.leftSB df.rightSB (3/3)] muchLessSW
	create-glyph 'muchGreater' 0x22D9 : glyph-proc
		local df : include : DivFrame para.advanceScaleMM 3
		include : GreaterShape (SymbolMid + dH) (SymbolMid - dH) [mix df.leftSB df.rightSB (0/3)] [mix df.leftSB df.rightSB (1/3)] muchLessSW
		include : GreaterShape (SymbolMid + dH) (SymbolMid - dH) [mix df.leftSB df.rightSB (1/3)] [mix df.leftSB df.rightSB (2/3)] muchLessSW
		include : GreaterShape (SymbolMid + dH) (SymbolMid - dH) [mix df.leftSB df.rightSB (2/3)] [mix df.leftSB df.rightSB (3/3)] muchLessSW

glyph-block Symbol-Math-Relation-Precedes-Succeeds : begin
	glyph-block-import CommonShapes
	glyph-block-import Common-Derivatives
	glyph-block-import Symbol-Math-Relation-Common : dH dSH lessEqDist
	glyph-block-import Symbol-Math-Relation-Addons : lesslessSW
	glyph-block-import Symbol-Math-Relation-Addon-Glyphs

	define [PrecedesShapeA top bot l r s cth] : begin
		local fine : s * cth
		return : dispiro
			widths.center s
			g4 r top
			straight.left.end l ([mix top bot 0.5] + s / 2) [widths.heading fine 0 Leftward]
	define [PrecedesShapeB top bot l r s cth] : begin
		local fine : s * cth
		return : dispiro
			widths.center s
			g4 r bot
			straight.left.end l ([mix top bot 0.5] - s / 2) [widths.heading 0 fine Leftward]
	define [SucceedsShapeA top bot l r s cth] : begin
		local fine : s * cth
		return : dispiro
			widths.center s
			g4 l top
			straight.right.end r ([mix top bot 0.5] + s / 2) [widths.heading 0 fine Rightward]
	define [SucceedsShapeB top bot l r s cth] : begin
		local fine : s * cth
		return : dispiro
			widths.center s
			g4 l bot
			straight.right.end r ([mix top bot 0.5] - s / 2) [widths.heading fine 0 Rightward]

	define [PrecedesShape top bot l r s] : glyph-proc
		include : PrecedesShapeA top bot l r [fallback s OperatorStroke] CThin
		include : PrecedesShapeB top bot l r [fallback s OperatorStroke] CThin
	define [SucceedsShape top bot l r s] : glyph-proc
		include : SucceedsShapeA top bot l r [fallback s OperatorStroke] CThin
		include : SucceedsShapeB top bot l r [fallback s OperatorStroke] CThin

	create-glyph 'precedes' 0x227a   : PrecedesShape (SymbolMid + dH) (SymbolMid - dH) SB RightSB
	create-glyph 'succeeds' 0x227b   : SucceedsShape (SymbolMid + dH) (SymbolMid - dH) SB RightSB
	create-glyph 'precedesEqUpper'   : PrecedesShape (SymbolMid + dSH + lessEqDist) (SymbolMid - dSH + lessEqDist) SB RightSB
	create-glyph 'precedesEqEqUpper' : PrecedesShape (SymbolMid + dSH + lessEqDist) (SymbolMid - dSH + lessEqDist * 1.75) SB RightSB lesslessSW
	create-glyph 'succeedsEqUpper'   : SucceedsShape (SymbolMid + dSH + lessEqDist) (SymbolMid - dSH + lessEqDist) SB RightSB
	create-glyph 'succeedsEqEqUpper' : SucceedsShape (SymbolMid + dSH + lessEqDist) (SymbolMid - dSH + lessEqDist * 1.75) SB RightSB lesslessSW

	derive-composites 'precedes.narrow'         null 'precedesEqUpper' [ApparentTranslate 0 (-lessEqDist)]
	derive-composites 'precedesEq'            0x2AAF 'precedesEqUpper' 'eqLower'
	derive-composites 'precedesEqBarNegated'  0x2AB1 'precedesEqUpper' 'eqBarNegatedLower'
	derive-composites 'precedesSym'           0x227E 'precedesEqUpper' 'symLower'
	derive-composites 'precedesSymBarNegated' 0x22E8 'precedesEqUpper' 'symBarNegatedLower'
	derive-composites 'precedesEqSlant'       0x227C 'precedesEqUpper'
		PrecedesShapeB (SymbolMid + dH - lessEqDist) (SymbolMid - dH - lessEqDist) SB RightSB OperatorStroke 1

	derive-composites 'precedesEqEq'             0x2AB3 'precedesEqEqUpper' 'eqEqLower'
	derive-composites 'precedesEqEqBarNegated'   0x2AB5 'precedesEqEqUpper' 'eqEqBarNegatedLower'
	derive-composites 'precedesSymSym'           0x2AB7 'precedesEqEqUpper' 'symSymLower'
	derive-composites 'precedesSymSymBarNegated' 0x2AB9 'precedesEqEqUpper' 'symSymBarNegatedLower'


	derive-composites 'succeeds.narrow'         null 'succeedsEqUpper' [ApparentTranslate 0 (-lessEqDist)]
	derive-composites 'succeedsEq'            0x2AB0 'succeedsEqUpper' 'eqLower'
	derive-composites 'succeedsEqBarNegated'  0x2AB2 'succeedsEqUpper' 'eqBarNegatedLower'
	derive-composites 'succeedsSym'           0x227F 'succeedsEqUpper' 'symLower'
	derive-composites 'succeedsSymBarNegated' 0x22E9 'succeedsEqUpper' 'symBarNegatedLower'
	derive-composites 'succeedsEqSlant'       0x227D 'succeedsEqUpper'
		SucceedsShapeB (SymbolMid + dH - lessEqDist) (SymbolMid - dH - lessEqDist) SB RightSB OperatorStroke 1

	derive-composites 'succeedsEqEq'             0x2AB4 'succeedsEqEqUpper' 'eqEqLower'
	derive-composites 'succeedsEqEqBarNegated'   0x2AB6 'succeedsEqEqUpper' 'eqEqBarNegatedLower'
	derive-composites 'succeedsSymSym'           0x2AB8 'succeedsEqEqUpper' 'symSymLower'
	derive-composites 'succeedsSymSymBarNegated' 0x2ABA 'succeedsEqEqUpper' 'symSymBarNegatedLower'

	turned 'turnSucceedsEqSlant' 0x22DE 'succeedsEqSlant' Middle SymbolMid
	turned 'turnPrecedesEqSlant' 0x22DF 'precedesEqSlant' Middle SymbolMid

glyph-block Symbol-Math-Relation-Precedes-Succeeds-Under-Relation : begin
	glyph-block-import CommonShapes
	glyph-block-import Common-Derivatives
	glyph-block-import Symbol-Math-Relation-Common : dH

	define [PrecedesUnderRelationShape t b l r s] : glyph-proc
		local yBias : s * 0.375
		local fine : s * CThin
		local hookDepth : Math.max ((r - l) / 4) (s * 2)
		local hookWidth : Math.max ((t - b) / 6) (s * 1.25)
		include : dispiro
			straight.right.start (r - hookDepth) (t - O + yBias) [widths.rhs.heading s Rightward]
			archv
			g4.down.mid r (t - hookWidth + yBias) [heading Downward]
			arcvh
			straight.left.end l ([mix t b 0.5] + s / 2 - fine) [widths.rhs.heading fine Leftward]
		include : dispiro
			straight.right.start (r - hookDepth) (b + O - yBias) [widths.lhs.heading s Rightward]
			archv
			g4.up.mid   r (b + hookWidth - yBias) [heading Upward]
			arcvh
			straight.left.end l ([mix t b 0.5] - s / 2 + fine) [widths.lhs.heading fine Leftward]

	define [SucceedsUnderRelationShape t b l r s] : new-glyph : glyph-proc
		include : PrecedesUnderRelationShape t b l r s
		include : FlipAround [mix l r 0.5] [mix t b 0.5]

	create-glyph 'precedesUnderRelation' 0x22B0
		PrecedesUnderRelationShape (SymbolMid + dH) (SymbolMid - dH) SB RightSB OperatorStroke
	create-glyph 'succeedsUnderRelation' 0x22B1
		SucceedsUnderRelationShape (SymbolMid + dH) (SymbolMid - dH) SB RightSB OperatorStroke

glyph-block Symbol-Math-Relation-Subset : begin
	glyph-block-import CommonShapes
	glyph-block-import Common-Derivatives
	glyph-block-import Symbol-Math-Relation-Common : dH dSH dHSubstSimple lessEqDist dHElem dHSmallElem
	glyph-block-import Symbol-Math-Relation-Addon-Glyphs

	define [SubsetMaskShape] : with-params [top bot [sw OperatorStroke] [offset 0] [xShift 0]] : spiro-outline
		corner RightSB (top - offset) [heading Leftward]
		curl (SB + [Math.max (sw * 1.5) ((xShift + top - bot) / 2)]) (top - offset)
		archv
		g4   (SB + xShift + offset + O) [mix top bot 0.5]
		arcvh
		flat (SB + [Math.max (sw * 1.5) ((xShift + top - bot) / 2)]) (bot + offset)
		corner RightSB (bot + offset) [heading Rightward]


	define [SubsetShape] : with-params [top bot [sw OperatorStroke] [offset 0] [xShift 0]] : dispiro
		widths.lhs sw
		flat RightSB (top - offset) [heading Leftward]
		curl (SB + [Math.max (sw * 1.5) ((xShift + top - bot) / 2)]) (top - offset)
		archv
		g4   (SB + xShift + offset + O) [mix top bot 0.5]
		arcvh
		flat (SB + [Math.max (sw * 1.5) ((xShift + top - bot) / 2)]) (bot + offset)
		curl RightSB (bot + offset) [heading Rightward]

	define [SupsetShape top bot sw] : glyph-proc
		include : SubsetShape top bot sw
		include : FlipAround Middle [mix top bot 0.5]
	define [SubsetClosedShape top bot sw] : glyph-proc
		include : SubsetShape top bot sw
		include : VBar.r RightSB bot top sw
	define [SupsetClosedShape top bot sw] : glyph-proc
		include : SubsetClosedShape top bot sw
		include : FlipAround Middle [mix top bot 0.5]

	create-glyph 'subst' 0x2282
		SubsetShape (SymbolMid + dHSubstSimple) (SymbolMid - dHSubstSimple)
	create-glyph 'subst/aplLeft'
		SubsetShape (SymbolMid + dHSubstSimple) (SymbolMid - dHSubstSimple) [AdviceStroke 3.5]
	create-glyph 'doubleSubst' 0x22D0 : glyph-proc
		local sw : AdviceStroke 6
		local gap : Math.max (Width / 8) (sw / 2)

		include : SubsetShape (SymbolMid + dHSubstSimple) (SymbolMid - dHSubstSimple) (sw -- sw)
		include : SubsetShape (SymbolMid + dHSubstSimple) (SymbolMid - dHSubstSimple) (sw -- sw) (offset -- gap + sw)
	create-glyph 'substClosed' 0x2ACF
		SubsetClosedShape (SymbolMid + dHSubstSimple) (SymbolMid - dHSubstSimple) OperatorStroke

	turned 'supst'       0x2283 'subst' Middle SymbolMid
	turned 'doubleSupst' 0x22D1 'doubleSubst' Middle SymbolMid
	turned 'supstClosed' 0x2AD0 'substClosed' Middle SymbolMid

	create-glyph 'substBarUpper'
		SubsetShape (SymbolMid + dSH + lessEqDist) (SymbolMid - dSH + lessEqDist)
	create-glyph 'supstBarUpper'
		SupsetShape (SymbolMid + dSH + lessEqDist) (SymbolMid - dSH + lessEqDist)

	derive-composites 'substBar'        0x2286 'substBarUpper' 'eqLower'
	derive-composites 'substBarNoRise'    null 'subst' 'eqLower2'
	derive-composites 'substBarNegated' 0x228A 'substBarUpper' 'eqBarNegatedLower'
	derive-composites 'supstBar'        0x2287 'supstBarUpper' 'eqLower'
	derive-composites 'supstBarNoRise'    null 'supst' 'eqLower2'
	derive-composites 'supstBarNegated' 0x228B 'supstBarUpper' 'eqBarNegatedLower'

	create-glyph 'substClosedBar' 0x2AD1 : composite-proc
		SubsetClosedShape (SymbolMid + dSH + lessEqDist) (SymbolMid - dSH + lessEqDist) OperatorStroke
		refer-glyph 'eqLower'
	create-glyph 'supstClosedBar' 0x2AD2 : composite-proc
		SupsetClosedShape (SymbolMid + dSH + lessEqDist) (SymbolMid - dSH + lessEqDist) OperatorStroke
		refer-glyph 'eqLower'

	define supstDotShift : SB + [Math.max (OperatorStroke * 1.5) dHSubstSimple] - Middle
	derive-composites 'substDot' 0x2ABD 'mathCDot' [ApparentTranslate (+supstDotShift) 0] 'subst'
	derive-composites 'supstDot' 0x2ABE 'mathCDot' [ApparentTranslate (-supstDotShift) 0] 'supst'

	create-glyph 'element' 0x2208 : glyph-proc
		include : SubsetShape (SymbolMid + dHElem) (SymbolMid - dHElem)
		include : HBar.m (SB + HalfStroke) RightSB SymbolMid OperatorStroke

	create-glyph 'elementWithTwoHorizontalStrokes' 0x22F9 : glyph-proc
		define sw : Math.min OperatorStroke : AdviceStroke2 2 4 (2 * dHElem)
		include : SubsetShape (SymbolMid + dHElem) (SymbolMid - dHElem) (sw -- sw)
		include : intersection
			SubsetMaskShape (SymbolMid + dHElem) (SymbolMid - dHElem) (sw -- sw) (offset -- 1)
			union
				HBar.m SB RightSB (SymbolMid - (dHElem / 3) + (sw / 6)) sw
				HBar.m SB RightSB (SymbolMid + (dHElem / 3) - (sw / 6)) sw

	turned 'turnElement' 0x220B 'element' Middle SymbolMid

	define [CodeNonApl u] : if (para.variantSelector.__enableAplForm === 'enable') null u
	define [CodeApl    u] : if (para.variantSelector.__enableAplForm === 'enable') u null

	create-glyph 'smallElement' [CodeNonApl 0x220A] : glyph-proc
		local sw : AdviceStroke2 3 2.5 (dHSmallElem * 2)
		include : SubsetShape (SymbolMid + dHSmallElem) (SymbolMid - dHSmallElem) (sw -- sw)
		include : HBar.m (SB + HalfStroke) RightSB SymbolMid sw

	create-glyph 'smallElement.aplForm' [CodeApl 0x220A] : glyph-proc
		local sw : AdviceStroke2 3 2.5 (dHSmallElem * 2)
		include : SubsetShape XH 0 (sw -- sw)
		include : HBar.m (SB + HalfStroke) RightSB (0.5 * XH) sw

	turned 'turnSmallElement' 0x220D 'smallElement' Middle SymbolMid

	create-glyph 'elementStroke' 0x22F2 : glyph-proc
		include : SubsetShape (SymbolMid + dHElem) (SymbolMid - dHElem)
			xShift -- ((RightSB - SB) * 0.2 + [HSwToV QuarterStroke])
		include : HBar.m (SB + HalfStroke) RightSB SymbolMid OperatorStroke

	turned 'turnElementStroke' 0x22FA 'elementStroke' Middle SymbolMid

	define [ElementBarHalfHeight h] : h / 2 - OperatorStroke / 4

	create-glyph 'elementBarAtEnd' 0x22F3 : glyph-proc
		include : SubsetShape (SymbolMid + dHElem) (SymbolMid - dHElem)
		include : VBar.r RightSB (SymbolMid - [ElementBarHalfHeight dHElem]) (SymbolMid + [ElementBarHalfHeight dHElem]) OperatorStroke
		include : HBar.m (SB + HalfStroke) RightSB SymbolMid OperatorStroke

	turned 'turnElementBarAtEnd' 0x22FB 'elementBarAtEnd' Middle SymbolMid

	create-glyph 'smallElementBarAtEnd' 0x22F4 : glyph-proc
		local sw : AdviceStroke2 3 2.75 (dHSmallElem * 2)
		include : SubsetShape (SymbolMid + dHSmallElem) (SymbolMid - dHSmallElem) (sw -- sw)
		include : VBar.r RightSB (SymbolMid - [ElementBarHalfHeight dHSmallElem]) (SymbolMid + [ElementBarHalfHeight dHSmallElem]) sw
		include : HBar.m (SB + HalfStroke) RightSB SymbolMid sw

	turned 'turnSmallElementBarAtEnd' 0x22FC 'smallElementBarAtEnd' Middle SymbolMid

	local dSHElem : dHElem * dSH / dH
	create-glyph 'elementAtUpper' : glyph-proc
		include : SubsetShape (SymbolMid + dSHElem) (SymbolMid - dSHElem)
		include : HBar.m (SB + HalfStroke) RightSB SymbolMid OperatorStroke

	turned 'turnElementAtUpper' null 'elementAtUpper' Middle SymbolMid

	WithDotVariants 'elementOfWithDotAbove' 0x22F5 : function [DrawAt kDotRadius overshoot]
		composite-proc [refer-glyph 'elementAtUpper']
			ApparentTranslate 0 (-lessEqDist)
			DrawAt Middle (SymbolMid + (dSHElem + lessEqDist)) (kDotRadius + DotRadius - overshoot)
	create-glyph 0x22F6 : composite-proc [refer-glyph 'elementAtUpper']
		ApparentTranslate 0 (-lessEqDist)
		HBar.m SB RightSB (SymbolMid + (dSHElem + lessEqDist)) OperatorStroke
	create-glyph 0x22FD : composite-proc [refer-glyph 'turnElementAtUpper']
		ApparentTranslate 0 (-lessEqDist)
		HBar.m SB RightSB (SymbolMid + (dSHElem + lessEqDist)) OperatorStroke
	create-glyph 0x22F8 : composite-proc [refer-glyph 'elementAtUpper']
		ApparentTranslate 0 (+lessEqDist)
		HBar.m SB RightSB (SymbolMid - (dSHElem + lessEqDist)) OperatorStroke

	create-glyph 0x22F7 : composite-proc [refer-glyph 'smallElement']
		ApparentTranslate 0 (-(dHSmallElem / dHElem) * lessEqDist)
		HBar.m SB RightSB (SymbolMid + (dHSmallElem + (dHSmallElem / dHElem) * lessEqDist)) OperatorStroke
	create-glyph 0x22FE : composite-proc [refer-glyph 'turnSmallElement']
		ApparentTranslate 0 (-(dHSmallElem / dHElem) * lessEqDist)
		HBar.m SB RightSB (SymbolMid + (dHSmallElem + (dHSmallElem / dHElem) * lessEqDist)) OperatorStroke

glyph-block Symbol-Math-Relation-Precedes-Succeeds-Prefix-Suffix : begin
	glyph-block-import CommonShapes
	glyph-block-import Common-Derivatives
	glyph-block-import Symbol-Math-Relation-Common : EqualHalfSpace dSH dHSubstSimple lessEqDist dHElem
	glyph-block-import Symbol-Math-Relation-Addon-Glyphs

	define [PrefixShape top bot sw] : union
		VBar.l SB bot top [fallback sw OperatorStroke]
		HBar.t  SB RightSB top [fallback sw OperatorStroke]
		HBar.b SB RightSB bot [fallback sw OperatorStroke]

	define [SuffixShape top bot sw] : glyph-proc
		include : PrefixShape top bot sw
		include : FlipAround Middle [mix top bot 0.5]

	create-glyph 'prefix' 0x228F
		PrefixShape (SymbolMid + dHSubstSimple) (SymbolMid - dHSubstSimple)
	create-glyph 'suffix' 0x2290
		SuffixShape (SymbolMid + dHSubstSimple) (SymbolMid - dHSubstSimple)

	create-glyph 'prefixBarUpper'
		PrefixShape (SymbolMid + dSH + lessEqDist) (SymbolMid - dSH + lessEqDist)
	create-glyph 'suffixBarUpper'
		SuffixShape (SymbolMid + dSH + lessEqDist) (SymbolMid - dSH + lessEqDist)

	derive-composites 'prefixBar'        0x2291 'prefixBarUpper' 'eqLower'
	derive-composites 'prefixBarNegated' 0x22E4 'prefixBarUpper' 'eqBarNegatedLower'
	derive-composites 'suffixBar'        0x2292 'suffixBarUpper' 'eqLower'
	derive-composites 'suffixBarNegated' 0x22E5 'suffixBarUpper' 'eqBarNegatedLower'

	create-glyph 'prefixElement' 0x22FF : glyph-proc
		include : PrefixShape (SymbolMid + dHElem) (SymbolMid - dHElem)
		include : HBar.m (SB + HalfStroke) RightSB SymbolMid

	create-glyph 'leftInteriorProduct' 0x2A3C : glyph-proc
		include : HBar.m SB RightSB (SymbolMid - EqualHalfSpace) OperatorStroke
		include : VBar.r RightSB (SymbolMid - EqualHalfSpace) (SymbolMid + EqualHalfSpace) OperatorStroke

	create-glyph 'rightInteriorProduct' 0x2A3D : glyph-proc
		include : HBar.m SB RightSB (SymbolMid - EqualHalfSpace) OperatorStroke
		include : VBar.l SB (SymbolMid - EqualHalfSpace) (SymbolMid + EqualHalfSpace) OperatorStroke

glyph-block Symbol-Math-Relation-Between : begin
	glyph-block-import CommonShapes
	glyph-block-import Common-Derivatives

	create-glyph 'between' 0x226C : glyph-proc
		define frame : new Box (PlusTop + OperatorStroke / 2) (PlusBot - OperatorStroke / 2) SB RightSB
		define kShape 0.25
		define kExt   0.2
		include : dispiro
			g4 [frame.mixX (kExt)] [frame.mixY 1.0] [widths.rhs OperatorStroke]
			alsoThru.g2 (1 - kShape) 0.5
			g4 [frame.mixX (1 - kExt)] [frame.mixY 0.5] [widths.center OperatorStroke]
			alsoThru.g2 (kShape) 0.5
			g4 [frame.mixX (kExt)] [frame.mixY 0.0] [widths.rhs OperatorStroke]
		include : dispiro
			g4 [frame.mixX (1 - kExt)] [frame.mixY 1.0] [widths.lhs OperatorStroke]
			alsoThru.g2 (1 - kShape) 0.5
			g4 [frame.mixX (kExt)] [frame.mixY 0.5] [widths.center OperatorStroke]
			alsoThru.g2 (kShape) 0.5
			g4 [frame.mixX (1 - kExt)] [frame.mixY 0.0] [widths.lhs OperatorStroke]

glyph-block Symbol-Math-Relation-Addon-Glyphs : begin
	glyph-block-import CommonShapes
	glyph-block-import Common-Derivatives
	glyph-block-import Symbol-Math-Relation-Common : dSH lessEqDist
	glyph-block-import Symbol-Math-Relation-Sym : symWave
	glyph-block-import Symbol-Math-Relation-Addons : lesslessSW EqEqBarNegation

	define [BarNegator symbolBottom dist] : begin
		local swo : Math.max (OperatorStroke * 1.5) (dist * 1.5)
		return : dispiro
			widths.center OperatorStroke
			flat (Middle + dist) (symbolBottom - dist + swo) [heading Downward]
			flat (Middle - dist) (symbolBottom - dist - swo) [heading Downward]

	create-glyph 'eqLower'            : HBar.m SB RightSB (SymbolMid - dSH - lessEqDist) OperatorStroke
	create-glyph 'eqLower2'           : HBar.m SB RightSB (SymbolMid - dSH - 2 * lessEqDist) OperatorStroke
	create-glyph 'eqBarNegatedLower'  : union [refer-glyph 'eqLower'] [BarNegator (SymbolMid - dSH) lessEqDist]
	create-glyph 'symLower'           : symWave (SymbolMid - dSH - lessEqDist) 1
	create-glyph 'symBarNegatedLower' : union [refer-glyph 'symLower'] [BarNegator (SymbolMid - dSH) lessEqDist]

	create-glyph 'eqEqLower' : union
		HBar.m SB RightSB (SymbolMid - dSH + lessEqDist * 2 / 3) lesslessSW
		HBar.m SB RightSB (SymbolMid - dSH - lessEqDist) lesslessSW
	create-glyph 'symSymLower' : union
		symWave (SymbolMid - dSH + lessEqDist * 2 / 3) 1 lesslessSW
		symWave (SymbolMid - dSH - lessEqDist) 1 lesslessSW
	create-glyph 'symEqLower' : union
		symWave (SymbolMid - dSH + lessEqDist * 2 / 3) 1 lesslessSW
		HBar.m SB RightSB (SymbolMid - dSH - lessEqDist * 7 / 6) lesslessSW
	create-glyph 'eqEqBarNegatedLower'   : union [refer-glyph 'eqEqLower']   [EqEqBarNegation]
	create-glyph 'symSymBarNegatedLower' : union [refer-glyph 'symSymLower'] [EqEqBarNegation]
