DIRECTORY Imager USING [Error], ImagerPath USING [ArcToProc, ConicToProc, CurveToProc, LineToProc, MoveToProc, Outline, OutlineRep, PathProc, Trajectory, TrajectoryList, TrajectoryRep], ImagerTransformation USING [Transform, Transformation], RealFns USING [ArcTanDeg, CosDeg, SinDeg, SqRt], Vector2 USING [Add, Cross, Dot, Square, Sub, VEC]; ImagerPathImpl: CEDAR PROGRAM IMPORTS Imager, ImagerTransformation, RealFns, Vector2 EXPORTS ImagerPath ~ BEGIN OPEN ImagerPath; VEC: TYPE ~ Vector2.VEC; Transformation: TYPE ~ ImagerTransformation.Transformation; threshold: REAL _ 0.01; fourThirds: REAL _ 4.0/3.0; ConicToCurves: PUBLIC PROC[p0, p1, p2: VEC, r: REAL, curveTo: CurveToProc] ~ { IF NOT (r IN [0.0..1.0]) THEN ERROR Imager.Error[[$specification, "The ratio r in conic specification must be in [0..1]"]]; IF ABS[r-0.5]<=threshold THEN { f: REAL ~ fourThirds*r; p01: VEC ~ [p0.x+f*(p1.x-p0.x), p0.y+f*(p1.y-p0.y)]; p21: VEC ~ [p2.x+f*(p1.x-p2.x), p2.y+f*(p1.y-p2.y)]; curveTo[p01, p21, p2]; } ELSE { m: VEC ~ [(p0.x+p2.x)*0.5, (p0.y+p2.y)*0.5]; p: VEC ~ [m.x+r*(p1.x-m.x), m.y+r*(p1.y-m.y)]; p01: VEC ~ [p0.x+r*(p1.x-p0.x), p0.y+r*(p1.y-p0.y)]; p21: VEC ~ [p2.x+r*(p1.x-p2.x), p2.y+r*(p1.y-p2.y)]; rNew: REAL ~ MIN[1.0/(1.0+RealFns.SqRt[2.0*(1-r)]), 0.99999]; ConicToCurves[p0, p01, p, rNew, curveTo]; ConicToCurves[p, p21, p2, rNew, curveTo]; }; }; ArcToConics: PUBLIC PROC[p0, p1, p2: VEC, conicTo: ConicToProc] ~ { OPEN Vector2; DistSqr: PROC[a, b: VEC] RETURNS[REAL] ~ { RETURN[Square[Sub[a, b]]] }; IF p0 = p2 THEN { c: VEC ~ [(p0.x+p1.x)*0.5, (p0.y+p1.y)*0.5]; -- center of the circle v: VEC ~ [p0.x-c.x, p0.y-c.y]; -- vector from center to p0 p: VEC ~ [-v.y, v.x]; -- v rotated by +90 degrees r: REAL ~ RealFns.SqRt[2.0]-1.0; -- conic ratio for a 90 degree arc conicTo[Add[p0,p], Add[c,p], r]; conicTo[Add[p1,p], p1, r]; conicTo[Sub[p1,p], Sub[c,p], r]; conicTo[Sub[p2,p], p2, r]; } ELSE { sgn: REAL ~ IF Cross[Sub[p1,p0], Sub[p2,p0]] >= 0 THEN 1.0 ELSE -1.0; distProd: REAL ~ RealFns.SqRt[DistSqr[p0,p1]*DistSqr[p2,p1]]; IF distProd = 0 THEN { conicTo[p1,p2,0.5]; } ELSE { dot: REAL ~ Dot[Sub[p0,p1], Sub[p2,p1]]; cos: REAL ~ -dot/distProd; IF cos>=0.5 THEN { tan: REAL ~ Cross[Sub[p0,p1], Sub[p2,p1]]/dot; m: VEC ~ [(p0.x+p2.x)*0.5, (p0.y+p2.y)*0.5]; p: VEC ~ [tan*(m.y-p0.y)+m.x, tan*(p0.x-m.x)+m.y]; r: REAL ~ cos/(1.0+cos); conicTo[p, p2, r]; } ELSE { m1: VEC ~ [(p0.x+p1.x)*0.5, (p0.y+p1.y)*0.5]; -- midpoint of segment from p0 to p1 v1: VEC ~ [m1.y-p0.y, p0.x-m1.x]; -- direction vector of perpendicular bisector a1: REAL ~ v1.y; b1: REAL ~ -v1.x; c1: REAL ~ a1*m1.x+b1*m1.y; m2: VEC ~ [(p0.x+p2.x)*0.5, (p0.y+p2.y)*0.5]; v2: VEC ~ [m2.y-p0.y, p0.x-m2.x]; a2: REAL ~ v2.y; b2: REAL ~ -v2.x; c2: REAL ~ a2*m2.x+b2*m2.y; det: REAL ~ a1*b2-a2*b1; Center: PROC RETURNS [VEC] ~ INLINE { IF det = 0 OR ABS[det] < ABS[a1*b2]*0.000005 THEN { v: VEC _ Add[v1, v2]; m: REAL; IF DistSqr[v1, v2] > v.x*v.x + v.y*v.y THEN v _ Sub[v1, v2]; m _ 1.0E+9/RealFns.SqRt[v.x*v.x + v.y*v.y]; p1 _ [2.0*m*v.x, 2.0*m*v.y]; RETURN [[m*v.x, m*v.y]]; } ELSE RETURN [[(c1*b2-c2*b1)/det, (a1*c2-a2*c1)/det]]; }; center: VEC ~ Center[]; theta0: REAL ~ RealFns.ArcTanDeg[p0.y-center.y, p0.x-center.x]; theta1: REAL _ RealFns.ArcTanDeg[p1.y-center.y, p1.x-center.x]; theta2: REAL _ RealFns.ArcTanDeg[p2.y-center.y, p2.x-center.x]; WHILE theta1 - theta0 < 0 DO theta1 _ theta1 + 360 ENDLOOP; WHILE theta2 - theta0 < 0 DO theta2 _ theta2 + 360 ENDLOOP; IF theta2 < theta1 THEN {theta1 _ theta1 - 360; theta2 _ theta2 - 360}; IF (theta1 - theta0)*(theta2 - theta0) < 0 THEN ERROR ELSE { radius: REAL _ RealFns.SqRt[DistSqr[center, p0]]; PointOnCircle: PROC [theta: REAL] RETURNS [VEC] ~ { RETURN [[center.x+radius*RealFns.CosDeg[theta], center.y+radius*RealFns.SinDeg[theta]]] }; pMid: VEC _ PointOnCircle[(theta0+theta2)*0.5]; ArcToConics[p0, PointOnCircle[0.75*theta0+0.25*theta2], pMid, conicTo]; ArcToConics[pMid, PointOnCircle[0.25*theta0+0.75*theta2], p2, conicTo]; }; }; }; }; }; Filter: PUBLIC PROC[path: PathProc, moveTo: MoveToProc _, lineTo: LineToProc _, curveTo: CurveToProc _, conicTo: ConicToProc _ NIL, arcTo: ArcToProc _ NIL, close: PROC _ NIL] ~ { p0: VEC _ [0, 0]; Eq: PROC[a, b: VEC] RETURNS[BOOL] ~ INLINE { RETURN[a.x=b.x AND a.y=b.y] }; first: BOOL _ TRUE; move: PROC[p: VEC] ~ { IF first THEN first _ FALSE ELSE IF close#NIL THEN close[]; moveTo[p]; p0 _ p; }; line: PROC[p1: VEC] ~ { IF first THEN move[p0]; IF Eq[p1, p0] THEN NULL ELSE lineTo[p1]; p0 _ p1; }; curve: PROC[p1, p2, p3: VEC] ~ { n: NAT _ 3; -- count position changes IF first THEN move[p0]; IF Eq[p0, p1] THEN n _ n-1; IF Eq[p1, p2] THEN n _ n-1; IF Eq[p2, p3] THEN n _ n-1; IF n=0 THEN NULL ELSE IF n=1 THEN line[p3] ELSE curveTo[p1, p2, p3]; p0 _ p3; }; conic: PROC[p1, p2: VEC, r: REAL] ~ { IF conicTo=NIL THEN ConicToCurves[p0, p1, p2, r, curve] ELSE { n: NAT _ 2; -- count position changes IF first THEN move[p0]; IF Eq[p0, p1] THEN n _ n-1; IF Eq[p1, p2] THEN n _ n-1; IF n=0 THEN NULL ELSE IF n=1 THEN line[p2] ELSE conicTo[p1, p2, r]; p0 _ p2; }; }; arc: PROC[p1, p2: VEC] ~ { IF arcTo=NIL THEN ArcToConics[p0, p1, p2, conic] ELSE { n: NAT _ 2; -- count position changes IF first THEN move[p0]; IF Eq[p0, p1] THEN n _ n-1; IF Eq[p1, p2] THEN n _ n-1; IF n=0 THEN NULL ELSE IF n=1 THEN line[p2] ELSE arcTo[p1, p2]; p0 _ p2; }; }; path[move, line, curve, conic, arc]; IF first THEN NULL ELSE IF close#NIL THEN close[]; }; Transform: PUBLIC PROC[path: PathProc, m: Transformation _ NIL, moveTo: MoveToProc _, lineTo: LineToProc _, curveTo: CurveToProc _, conicTo: ConicToProc _ NIL, arcTo: ArcToProc _ NIL, close: PROC _ NIL] ~ { first: BOOL _ TRUE; p0: VEC _ [0, 0]; -- in path's coordinates, not transformed TransformMoveTo: PROC[p: VEC] ~ { IF first THEN first _ FALSE ELSE { IF close#NIL THEN close[] }; IF m=NIL THEN moveTo[p] ELSE moveTo[m.Transform[p]]; p0 _ p; }; TransformLineTo: PROC[p1: VEC] ~ { IF first THEN TransformMoveTo[p0]; IF m=NIL THEN lineTo[p1] ELSE lineTo[m.Transform[p1]]; p0 _ p1; }; TransformCurveTo: PROC[p1, p2, p3: VEC] ~ { IF first THEN TransformMoveTo[p0]; IF m=NIL THEN curveTo[p1, p2, p3] ELSE curveTo[m.Transform[p1], m.Transform[p2], m.Transform[p3]]; p0 _ p3; }; TransformConicTo: PROC[p1, p2: VEC, r: REAL] ~ { IF conicTo=NIL THEN GOTO Curves; IF first THEN TransformMoveTo[p0]; IF m=NIL THEN conicTo[p1, p2, r] ELSE conicTo[m.Transform[p1], m.Transform[p2], r]; p0 _ p2; EXITS Curves => ConicToCurves[p0, p1, p2, r, TransformCurveTo]; }; TransformArcTo: PROC[p1, p2: VEC] ~ { IF arcTo=NIL THEN GOTO Conics; IF m#NIL THEN GOTO Conics; -- in general, can't just transform control points IF first THEN TransformMoveTo[p0]; arcTo[p1, p2]; p0 _ p2; EXITS Conics => ArcToConics[p0, p1, p2, TransformConicTo]; }; path[moveTo: TransformMoveTo, lineTo: TransformLineTo, curveTo: TransformCurveTo, conicTo: TransformConicTo, arcTo: TransformArcTo]; IF first THEN NULL ELSE { IF close#NIL THEN close[] }; }; LastPoint: PUBLIC PROC[t: Trajectory] RETURNS[VEC] ~ { RETURN[t.lp]; }; MoveTo: PUBLIC PROC[p: VEC] RETURNS[Trajectory] ~ { RETURN[NEW[TrajectoryRep[move] _ [ prev: NIL, length: 1, lp: p, variant: move[]]]]; }; LineTo: PUBLIC PROC[t: Trajectory, p1: VEC] RETURNS[Trajectory] ~ { RETURN[NEW[TrajectoryRep[line] _ [ prev: t, length: t.length+1, lp: p1, variant: line[]]]]; }; LineToX: PUBLIC PROC[t: Trajectory, x: REAL] RETURNS[Trajectory] ~ { RETURN[NEW[TrajectoryRep[line] _ [ prev: t, length: t.length+1, lp: [x, t.lp.y], variant: line[]]]]; }; LineToY: PUBLIC PROC[t: Trajectory, y: REAL] RETURNS[Trajectory] ~ { RETURN[NEW[TrajectoryRep[line] _ [ prev: t, length: t.length+1, lp: [t.lp.x, y], variant: line[]]]]; }; CurveTo: PUBLIC PROC[t: Trajectory, p1, p2, p3: VEC] RETURNS[Trajectory] ~ { RETURN[NEW[TrajectoryRep[curve] _ [ prev: t, length: t.length+1, lp: p3, variant: curve[p1, p2]]]]; }; ConicTo: PUBLIC PROC[t: Trajectory, p1, p2: VEC, r: REAL] RETURNS[Trajectory] ~ { RETURN[NEW[TrajectoryRep[conic] _ [ prev: t, length: t.length+1, lp: p2, variant: conic[p1, r]]]]; }; ArcTo: PUBLIC PROC[t: Trajectory, p1, p2: VEC] RETURNS[Trajectory] ~ { RETURN[NEW[TrajectoryRep[arc] _ [ prev: t, length: t.length+1, lp: p2, variant: arc[p1]]]]; }; MapTrajectory: PUBLIC PROC[trajectory: Trajectory, moveTo: MoveToProc, lineTo: LineToProc, curveTo: CurveToProc, conicTo: ConicToProc, arcTo: ArcToProc] ~ { Map: PROC[trajectory: Trajectory, length: INT] ~ { max: NAT ~ 16; array: ARRAY[0..max) OF Trajectory; size: NAT ~ MIN[length, max]; n: INT ~ IF length>size THEN length/size ELSE 1; rem: INT ~ length-n*size; t: Trajectory _ trajectory; FOR i: NAT IN[0..size) DO array[i] _ t; THROUGH [0..n) DO t _ t.prev ENDLOOP; ENDLOOP; IF rem>0 THEN Map[t, rem]; IF n>1 THEN FOR i: NAT DECREASING IN[0..size) DO Map[array[i], n] ENDLOOP ELSE FOR i: NAT DECREASING IN[0..size) DO WITH array[i] SELECT FROM t: REF TrajectoryRep[move] => moveTo[t.lp]; t: REF TrajectoryRep[line] => lineTo[t.lp]; t: REF TrajectoryRep[curve] => curveTo[t.p1, t.p2, t.lp]; t: REF TrajectoryRep[conic] => conicTo[t.p1, t.lp, t.r]; t: REF TrajectoryRep[arc] => arcTo[t.p1, t.lp]; ENDCASE => ERROR; -- unknown variant ENDLOOP; }; Map[trajectory, trajectory.length]; }; MapTrajectoryBackward: PUBLIC PROC[trajectory: Trajectory, moveTo: MoveToProc, lineTo: LineToProc, curveTo: CurveToProc, conicTo: ConicToProc, arcTo: ArcToProc] ~ { moveTo[trajectory.lp]; FOR t: Trajectory _ trajectory, t.prev UNTIL t.prev=NIL DO p0: VEC ~ t.prev.lp; WITH t SELECT FROM t: REF TrajectoryRep[move] => ERROR; -- should have had t.prev=NIL t: REF TrajectoryRep[line] => lineTo[p0]; t: REF TrajectoryRep[curve] => curveTo[t.p2, t.p1, p0]; t: REF TrajectoryRep[conic] => conicTo[t.p1, p0, t.r]; t: REF TrajectoryRep[arc] => arcTo[t.p1, p0]; ENDCASE => ERROR; -- unknown variant ENDLOOP; }; MapTrajectoryList: PUBLIC PROC[trajectoryList: TrajectoryList, moveTo: MoveToProc, lineTo: LineToProc, curveTo: CurveToProc, conicTo: ConicToProc, arcTo: ArcToProc] ~ { FOR list: TrajectoryList _ trajectoryList, list.rest UNTIL list=NIL DO MapTrajectory[list.first, moveTo, lineTo, curveTo, conicTo, arcTo]; ENDLOOP; }; MapOutline: PUBLIC PROC[outline: Outline, moveTo: MoveToProc, lineTo: LineToProc, curveTo: CurveToProc, conicTo: ConicToProc, arcTo: ArcToProc] ~ { FOR i: NAT IN[0..outline.size) DO MapTrajectory[outline[i], moveTo, lineTo, curveTo, conicTo, arcTo]; ENDLOOP; }; TrajectoriesFromPath: PUBLIC PROC[path: PathProc, m: Transformation _ NIL, action: PROC[Trajectory]] ~ { t: Trajectory _ NIL; move: PROC[p: VEC] ~ { t _ MoveTo[p] }; line: PROC[p1: VEC] ~ { t _ LineTo[t, p1] }; curve: PROC[p1, p2, p3: VEC] ~ { t _ CurveTo[t, p1, p2, p3] }; conic: PROC[p1, p2: VEC, r: REAL] ~ { t _ ConicTo[t, p1, p2, r] }; arc: PROC[p1, p2: VEC] ~ { t _ ArcTo[t, p1, p2] }; close: PROC ~ { action[t] }; Transform[path, m, move, line, curve, conic, arc, close]; }; TrajectoryListFromPath: PUBLIC PROC[path: PathProc, m: Transformation _ NIL] RETURNS[list: TrajectoryList _ NIL] ~ { tail: TrajectoryList _ NIL; action: PROC[t: Trajectory] ~ { new: TrajectoryList ~ CONS[t, NIL]; IF tail=NIL THEN list _ new ELSE tail.rest _ new; tail _ new; }; TrajectoriesFromPath[path, m, action]; }; OutlineFromPath: PUBLIC PROC[path: PathProc, m: Transformation _ NIL] RETURNS[outline: Outline _ NIL] ~ { list: LIST OF Trajectory _ NIL; size: NAT _ 0; action: PROC[t: Trajectory] ~ { list _ CONS[t, list]; size _ size+1 }; TrajectoriesFromPath[path, m, action]; outline _ NEW[OutlineRep[size]]; FOR i: NAT DECREASING IN[0..size) DO outline[i] _ list.first; list _ list.rest ENDLOOP; }; END. ΜImagerPathImpl.mesa Copyright c 1984, 1985 by Xerox Corporation. All rights reserved. Doug Wyatt, March 8, 1985 9:12:15 am PST Michael Plass, November 6, 1985 10:40:48 am PST positive if arc is counterclockwise p1 coincides with p0 or p2 - shame, shame cos of 1/2 the angle subtended by the arc a1*x + b1*y = c1 is the equation of the perpendicular bisector *** Possible side effect on p1 in degenerate case The determinant is zero, or the calculation has lost most of its significant digits; in this case the points are practically collinear, but p1 is not between the other two. Pick as the center a point way out in the boonies, but in the right direction. Not so big that later calls on ArcToConics will overflow. -- could test for special cases of m here (uniform scaling, for example) RopeFromTrajectory: PROC[t: Trajectory, backward: BOOL _ FALSE] RETURNS[Rope.ROPE] ~ { out: IO.STREAM ~ IO.ROS[]; PutReal: PROC[out: IO.STREAM, r: REAL] ~ { IO.PutF[out, "%g ", IO.real[r]] }; PutVec: PROC[out: IO.STREAM, p: VEC] ~ { PutReal[out, p.x]; PutReal[out, p.y] }; moveTo: PROC[p0: VEC] ~ { PutVec[out, p0]; IO.PutRope[out, "MOVETO "]; }; lineTo: PROC[p1: VEC] ~ { PutVec[out, p1]; IO.PutRope[out, "LINETO "]; }; curveTo: PROC[p1, p2, p3: VEC] ~ { PutVec[out, p1]; PutVec[out, p2]; PutVec[out, p3]; IO.PutRope[out, "CURVETO "]; }; conicTo: PROC[p1, p2: VEC, r: REAL] ~ { PutVec[out, p1]; PutVec[out, p2]; PutReal[out, r]; IO.PutRope[out, "CONICTO "]; }; arcTo: PROC[p1, p2: VEC] ~ { PutVec[out, p1]; PutVec[out, p2]; IO.PutRope[out, "ARCTO "]; }; IF backward THEN MapTrajectoryBackward[t, moveTo, lineTo, curveTo, conicTo, arcTo] ELSE MapTrajectory[t, moveTo, lineTo, curveTo, conicTo, arcTo]; RETURN[IO.RopeFromROS[out]]; }; Κ$˜codešœ™Kšœ Οmœ7™BKšœ(™(K™/—K™šΟk ˜ Kšœžœ ˜Kšœ žœ‰˜™Kšœžœ˜7Kšœžœ#˜0Kšœžœ žœ˜2—K˜KšΠblœžœž˜Kšžœ/˜6Kšžœ ˜Kšœžœžœ ˜K˜Kšžœžœ žœ˜Kšœžœ'˜;K˜Kšœ žœ˜šœ žœ ˜K˜—š Οn œžœžœ žœžœ˜NKš žœžœžœ žœžœX˜{šžœžœžœ˜Kšœžœ˜Kšœžœ,˜4Kšœžœ,˜4Kšœ˜Kšœ˜—šžœ˜Kšœžœ&˜,Kšœžœ(˜.Kšœžœ,˜4Kšœžœ,˜4Kšœžœžœ-˜=Kšœ)˜)Kšœ)˜)Kšœ˜—K˜K˜—š  œžœžœ žœ˜CKšžœ ˜ Kš  œžœžœžœžœžœ˜Gšžœ žœ˜Kšœžœ'Οc˜DKšœžœ‘˜:Kšœžœ‘˜1Kšœžœ‘"˜CKšœ ˜ Kšœ˜Kšœ ˜ Kšœ˜Kšœ˜—šžœ˜š œžœžœ$žœžœ˜EK™#—Kšœ žœ/˜=šžœžœ˜Kšœ)™)Kšœ˜Kšœ˜—šžœ˜Kšœžœ˜(šœžœ˜K™)—šžœ žœ˜Kšœžœ%˜.Kšœžœ&˜,Kšœžœ,˜2Kšœžœ˜Kšœ˜Kšœ˜—šžœ˜Kšœžœ'‘$˜RKšœžœ‘-˜OKšœžœ˜Kšœžœ ˜šœžœ˜K™>—Kšœžœ&˜-Kšœžœ˜!Kšœžœ˜Kšœžœ ˜Kšœžœ˜Kšœžœ˜š  œžœžœžœžœ˜%K™1š žœ žœžœžœžœ˜3K™όKšœžœ˜Kšœžœ˜Kšžœ%žœ˜<šœ+˜+Kšœ9™9—Kšœ˜Kšžœ˜Kšœ˜—Kšžœžœ*˜5Kšœ˜—Kšœžœ ˜Kšœžœ3˜?Kšœžœ3˜?Kšœžœ3˜?Kšžœžœžœ˜;Kšžœžœžœ˜;Kšžœžœ0˜GKšžœ)žœž˜5šžœ˜Kšœžœ%˜1š   œžœ žœžœžœ˜3KšžœQ˜WKšœ˜—Kšœžœ&˜/KšœG˜GKšœG˜GKšœ˜—Kšœ˜—Kšœ˜—Kšœ˜—K˜K˜—K˜š œžœžœlžœžœ žœžœ˜²Kšœžœ ˜Kš œžœžœžœžœžœžœ žœ ˜KKšœžœžœ˜šœžœžœ˜Kšžœžœ žœžœžœžœžœ ˜;Kšœ ˜ K˜Kšœ˜—šœžœžœ˜Kšžœžœ ˜Kšžœ žœž˜Kšžœ ˜K˜Kšœ˜—šœžœ žœ˜ Kšœžœ‘˜%Kšžœžœ ˜Kšžœ žœ ˜Kšžœ žœ ˜Kšžœ žœ ˜Kšžœžœž˜Kšžœžœžœ ˜Kšžœ˜K˜K˜—šœžœ žœžœ˜%Kšžœ žœžœ$˜7šžœ˜Kšœžœ‘˜%Kšžœžœ ˜Kšžœ žœ ˜Kšžœ žœ ˜Kšžœžœž˜Kšžœžœžœ ˜Kšžœ˜K˜K˜—K˜—šœžœ žœ˜Kšžœžœžœ˜0šžœ˜Kšœžœ‘˜%Kšžœžœ ˜Kšžœ žœ ˜Kšžœ žœ ˜Kšžœžœž˜Kšžœžœžœ ˜Kšžœ˜K˜K˜—Kšœ˜—K˜$Kšžœžœžœžœžœžœžœ ˜2K˜K˜—š  œžœžœ%žœ]žœžœ žœžœ˜ΞKšœžœžœ˜Kšœžœ ‘)˜;š œžœžœ˜!Kšžœžœ žœžœžœžœžœ ˜?Kšžœžœžœ ˜Kšžœ˜K˜Kšœ˜—š œžœžœ˜"Kšžœžœ˜"Kšžœžœžœ ˜Kšžœ˜K˜Kšœ˜—š œžœ žœ˜+Kšžœžœ˜"Kšžœžœžœ˜!Kšžœ<˜@K˜Kšœ˜—š œžœ žœžœ˜0Kšžœ žœžœžœ˜ Kšžœžœ˜"Kšžœžœžœ˜ Kšžœ.˜2Kšœ˜Kšžœ:˜?Kšœ˜—š œžœ žœ˜%Kšžœžœžœžœ˜š žœžœžœžœ ‘2˜MK™H—Kšžœžœ˜"Kšœ˜Kšœ˜Kšžœ5˜:Kšœ˜—Kšœ„˜„Kšžœžœžœžœžœžœžœ ˜6K˜K˜—K˜š   œžœžœžœžœ˜6Kšžœ˜ K˜K™—š  œžœžœžœžœ˜3šžœžœ˜"Kšœžœ'˜0—K˜K™—š  œžœžœžœžœ˜Cšžœžœ˜"Kšœ8˜8—K˜K™—š  œžœžœžœžœ˜Dšžœžœ˜"KšœA˜A—K˜K™—š  œžœžœžœžœ˜Dšžœžœ˜"KšœA˜A—K˜K™—š  œžœžœžœžœ˜Lšžœžœ˜#Kšœ?˜?—K˜K˜—š  œžœžœžœžœžœ˜Qšžœžœ˜#Kšœ>˜>—K˜K˜—š  œžœžœžœžœ˜Fšžœžœ˜!Kšœ9˜9—K˜K˜—K˜š  œžœžœƒ˜š œžœ!žœ˜2Kšœžœ˜Kšœžœ žœ ˜#Kšœžœžœ˜Kš œžœžœ žœ žœ˜0Kšœžœ˜Kšœ˜šžœžœžœ ž˜Kšœ ˜ Kšžœžœ žœ˜%Kšžœ˜—Kšžœžœ ˜Kšžœžœžœžœž œžœ žœž˜Iš žœžœžœž œžœ ž˜)šžœ žœž˜Kšœžœ%˜+Kšœžœ%˜+Kšœžœ3˜9Kšœžœ2˜8Kšœžœ)˜/Kšžœžœ‘˜$—Kšžœ˜—K˜—Kšœ#˜#K˜K˜—š œžœžœƒ˜₯Kšœ˜šžœ$žœžœž˜:Kšœžœ ˜šžœžœž˜Kšœžœžœ‘˜BKšœžœ#˜)Kšœžœ1˜7Kšœžœ0˜6Kšœžœ'˜-Kšžœžœ‘˜$—Kšžœ˜—K˜K˜—š  œžœžœžœžœžœ™VKš œžœžœžœžœ™Kš œžœžœžœžœžœžœ ™MKš  œžœžœžœžœ-™Pšœžœžœ™K™Kšžœ™K™—šœžœžœ™Kšœ™Kšžœ™K™—šœ žœ žœ™"Kšœ™Kšœ™Kšœ™Kšžœ™K™—šœ žœ žœžœ™'Kšœ™Kšœ™Kšœ™Kšžœ™K™—šœžœ žœ™Kšœ™Kšœ™Kšžœ™K™—Kšžœ žœB™RKšžœ;™?Kšžœžœ™K™K™—š œžœžœ‹˜©šžœ2žœžœž˜FK˜CKšžœ˜—K˜—K˜š  œžœžœ}˜”šžœžœžœž˜!K˜CKšžœ˜—K˜K˜—š  œžœžœ&žœ žœ˜iKšœžœ˜Kšœžœžœ˜'Kšœžœžœ˜,Kšœžœ žœ#˜>Kšœžœ žœžœ"˜BKšœžœ žœ˜2Kšœžœ˜Kšœ9˜9K˜K˜—š  œžœžœ&žœžœžœ˜uKšœžœ˜šœžœ˜Kšœžœžœ˜#Kšžœžœžœ žœ˜1K˜ Kšœ˜—K˜&K˜K˜—š  œžœžœ&žœžœžœ˜jKšœžœžœžœ˜Kšœžœ˜Kšœžœžœ˜FK˜&Kšœ žœ˜ Kš žœžœž œžœ žœ+žœ˜WK˜K˜—Kšžœ˜—…—-&E