DIRECTORY Commander, Controls, G3dBasic, G3dDraw, G3dOctree, G3dTool, G3dVector, ImplicitDesign, ImplicitMinimal, ImplicitValue, MessageWindow, RealFns, Rope, Vector2, ViewerClasses; ImplicitSimpleCmdImpl: CEDAR PROGRAM IMPORTS Controls, G3dDraw, G3dTool, G3dVector, ImplicitDesign, ImplicitValue, MessageWindow, RealFns, Rope, Vector2 ~ BEGIN Triple: TYPE ~ G3dBasic.Triple; TripleSequence: TYPE ~ G3dBasic.TripleSequence; Tool: TYPE ~ ImplicitDesign.Tool; Function: TYPE ~ ImplicitMinimal.Function; Source3dSequence: TYPE ~ ImplicitValue.Source3dSequence; ROPE: TYPE ~ Rope.ROPE; ClickProc: TYPE ~ ViewerClasses.ClickProc; Op: TYPE ~ {union, sphere, cylinder, torus, plane, wiffle, blob, fourPoleBlob, ellipsoid, doubleCone, saddle, tubularCorner, teapotTop}; SimpleData: TYPE ~ REF SimpleDataRep; SimpleDataRep: TYPE ~ RECORD [ tool: Tool ¬ NIL, op: Op ¬ sphere, -- which of simple objects points: TripleSequence ¬ NIL, -- for quick drawing of sphere cylLength: REAL ¬ 0.0, -- half length of cylinder r: REAL ¬ 0.0, -- radius of cylinder, sphere, torus r2: REAL ¬ 0.0, -- radius squared rr: REAL ¬ 0.0, -- minor torus radius rr2, r4, rr4, a, b, c: REAL ¬ 0.0, -- accelerators for torus blobSeparation: REAL ¬ 0.185, -- distance between blob centers blobbiness: REAL ¬ 0.0, -- blobbiness between two centers blobSources: Source3dSequence ¬ NIL, -- blob centers sphereCount: INTEGER ¬ 0 ]; SimpleCommand: Commander.CommandProc ~ { s: SimpleData ~ NEW[SimpleDataRep]; Setup[s, 0.1]; s.tool ¬ ImplicitDesign.MakeTool[ name: "Simple", function: Value, start: Start, client: [draw: Draw, data: s], extraButtons: LIST[ Controls.ClickButton["Radius", Radius, s], Controls.ClickButton["BSep", BlobSeparation, s], Controls.ClickButton["Bness", Blobbiness, s], Controls.ClickButton["Type: sphere", SimpleCycle, s]], useArcBalls: FALSE, camera: [[0, 2, 0], [], 2.5, 60], toolSettings: [level: 0.0] ]; }; Start: ImplicitDesign.StartProc ~ { s: SimpleData ¬ NARROW[clientData]; point ¬ IF s.op = wiffle THEN [0.6605536, -1.449449, 1.804281] ELSE []; }; Setup: PROC [s: SimpleData, radius: REAL] ~ { s.r ¬ radius; -- radius for sphere, cylinder, major radius for torus s.cylLength ¬ 2.0*s.r; s.points ¬ G3dDraw.GetSpherePoints[[0.0, 0.0, 0.0], s.r, 10]; s.rr ¬ 0.2*radius; -- minor radius for torus s.r2 ¬ s.r*s.r; s.rr2 ¬ s.rr*s.rr; s.r4 ¬ s.r2*s.r2; s.rr4 ¬ s.rr2*s.rr2; s.a ¬ s.r2+s.rr2; s.b ¬ s.r2-s.rr2; s.c ¬ s.r2*s.rr2; s.blobSources ¬ NEW[ImplicitValue.Source3dSequenceRep[2]]; s.blobSources.length ¬ 2; s.blobSources[0] ¬ [[-0.5*s.blobSeparation, 0.0, 0.0], s.r, 1.0/(s.r*s.r)]; s.blobSources[1] ¬ [[0.5*s.blobSeparation, 0.0, 0.0], 0.5*s.r, 1.0/(0.5*0.5*s.r*s.r)]; }; Value: Function ~ { s: SimpleData ¬ NARROW[clientData]; SELECT s.op FROM union => { c1: Triple ¬ [-.15, 0, 0]; r1: REAL ¬ 0.35; c2: Triple ¬ [0.5, 0, 0]; r2: REAL ¬ 0.5; RETURN[MAX[r1-G3dVector.Distance[point, c1], r2-G3dVector.Distance[point, c2]]]; }; blob => { IF s.blobbiness < 0.0 THEN FOR n: NAT IN [0..s.blobSources.length) DO b: ImplicitValue.Source3d ¬ s.blobSources[n]; rSqrd: REAL ¬ G3dVector.SquareDistance[b.p, point]; rR: REAL ¬ rSqrd*b.sInvSqrd; exp: REAL ¬ s.blobbiness*(rR-1.0); IF exp > 50.0 THEN RETURN[1000.0]; IF exp > -50.0 THEN value ¬ value+RealFns.Exp[exp]; ENDLOOP ELSE value ¬ ImplicitValue.OfSources3d[point, s.blobSources, inverseSqrd]; value ¬ value-1.0; }; wiffle => { ax: REAL ¬ point.x/2.4; bx: REAL ¬ point.x/2.0; ay: REAL ¬ point.y/2.4; by: REAL ¬ point.y/2.0; az: REAL ¬ point.z/2.4; bz: REAL ¬ point.z/2.0; bx2: REAL ¬ bx*bx; by2: REAL ¬ by*by; bz2: REAL ¬ bz*bz; bx4: REAL ¬ bx2*bx2; by4: REAL ¬ by2*by2; bz4: REAL ¬ bz2*bz2; terma: REAL ¬ ax*ax+ay*ay+az*az; termb: REAL ¬ bx4*bx4+by4*by4+bz4*bz4; terma2: REAL ¬ terma*terma; termb2: REAL ¬ termb*termb; terma6: REAL ¬ terma2*terma2*terma2; termb6: REAL ¬ termb2*termb2*termb2; value ¬ (1.0-termb6-1.0/terma6); }; sphere => { s.sphereCount ¬ s.sphereCount+1; value ¬ s.r2-G3dVector.Square[point]; }; cylinder => value ¬ s.r2-(SELECT point.x FROM < -s.cylLength => G3dVector.SquareDistance[point, [-s.cylLength, 0.0, 0.0]], > s.cylLength => G3dVector.SquareDistance[point, [ s.cylLength, 0.0, 0.0]], ENDCASE => Vector2.Square[[point.y, point.z]]); torus => { x2: REAL ~ point.x*point.x; y2: REAL ~ point.y*point.y; z2: REAL ~ point.z*point.z; u: REAL ¬ x2+y2+z2+s.r2-s.rr2; value ¬ u*u-4*s.r2*(y2+z2); }; plane => value ¬ point.y; fourPoleBlob => { x2: REAL ¬ point.x*point.x; y2: REAL ¬ point.y*point.y; z2: REAL ¬ point.z*point.z; value ¬ x2*y2+x2*z2+y2*z2+7.0*point.x*point.y*point.z+x2+y2+z2-1; }; ellipsoid => value ¬ point.x*point.x+point.y*point.y+4.0*point.z*point.z-1.0; doubleCone => value ¬ point.x*point.x+point.y*point.y-0.8*point.z*point.z-0.3; saddle => value ¬ 3.0*point.x*point.x-point.y*point.y+2.0*point.z; tubularCorner => { x2: REAL ¬ point.x*point.x; y2: REAL ¬ point.y*point.y; z2: REAL ¬ point.z*point.z; value ¬ x2*y2+x2*z2+y2*z2+point.x+point.y-point.z+1.0; }; teapotTop => { z2: REAL ¬ point.z*point.z; value ¬ point.x*point.x+point.y*point.y+point.z*z2+1.8*z2-1.0; }; ENDCASE; }; Radius: ClickProc ~ { s: SimpleData ¬ NARROW[clientData]; s.r ¬ ReadValue[s.tool, "Radius", s.r]; Setup[s, s.r]; }; BlobSeparation: ClickProc ~ { s: SimpleData ¬ NARROW[clientData]; s.blobSeparation ¬ ReadValue[s.tool, "Blob separation", s.blobSeparation]; s.blobSources[0].p ¬ [-0.5*s.blobSeparation, 0.0, 0.0]; s.blobSources[1].p ¬ [0.5*s.blobSeparation, 0.0, 0.0]; }; Blobbiness: ClickProc ~ { s: SimpleData ¬ NARROW[clientData]; s.blobbiness ¬ ReadValue[s.tool, "Blobbiness (< 0)", s.blobbiness]; }; Draw: G3dTool.DrawProc ~ { s: SimpleData ¬ NARROW[clientData]; SELECT s.op FROM blob => { G3dDraw.Sphere[context, s.blobSources[0].p, s.blobSources[0].strength, 8, view, vp]; G3dDraw.Sphere[context, s.blobSources[1].p, s.blobSources[1].strength, 8, view, vp]; }; sphere => G3dDraw.Sphere[context, [0.0, 0.0, 0.0], s.r, 10, view, vp, s.points]; ENDCASE; }; SimpleCycle: ClickProc ~ { Roper: PROC [op: Op] RETURNS [name: ROPE] ~ { name ¬ Rope.Concat["Type: ", SELECT op FROM sphere => "sphere", cylinder => "cylinder", torus => "torus", plane => "plane", wiffle => "wiffle", union => "union", blob => "blob", fourPoleBlob => "four pole blob", ellipsoid => "ellipsoid", doubleCone => "double cone", saddle => "saddle", tubularCorner => "tubular corner", teapotTop => "teapot top", ENDCASE => NIL]; }; requests: LIST OF Controls.Request ¬ LIST[ --1-- ["sphere", "a sphere of the given radius"], --2-- ["cylinder", "a cylinder of the given radius"], --3-- ["torus", "a torus of given minor and major radii"], --4-- ["plane", "the xz plane"], --5-- ["wiffle", "the rounded edges of a cube"], --6-- ["union", "the union of two spheres"], --7-- ["blob", "the blobby combination of sources"], --8-- ["fourPoleBlob", "blobby of four elements"], --9-- ["ellipsoid", "ellipsoidal shape"], --10-- ["doubleCone", "two cones"], --11-- ["saddle", "saddle surface"], --12-- ["tubularCorner", "corners"], --13-- ["teapotTop", "top of a teapot"] ]; d: SimpleData ~ NARROW[clientData]; old: Op ~ d.op; d.op ¬ SELECT Controls.PopUpRequest[["Simple Functions"], requests] FROM 1 => sphere, 2 => cylinder, 3 => torus, 4 => plane, 5 => wiffle, 6 => union, 7 => blob, 8 => fourPoleBlob, 9 => ellipsoid, 10 => doubleCone, 11 => saddle, 12 => tubularCorner, 13 => teapotTop, ENDCASE => d.op; Controls.ButtonRelabel[d.tool.tool3d.outerData, Roper[old], Roper[d.op]]; IF mouseButton = blue THEN ImplicitDesign.Repaint[d.tool, $Client]; }; TSWrite: PROC [s: SimpleData, r: ROPE] ~{G3dTool.TSWrite[s.tool.tool3d, r]}; Blink: PROC [message: ROPE] ~ { MessageWindow.Append[message, TRUE]; MessageWindow.Blink[]; }; ReadValue: PROC [t: Tool, prompt: ROPE, value: REAL] RETURNS [REAL] ~ { RETURN[Controls.TypescriptReadValue[t.tool3d.typescript, prompt, value]]; }; ImplicitDesign.Register["Simple", SimpleCommand, "plane, sphere, cylinder, torus, blob."]; END. .. IF whatChanged = NIL THEN { IF s.doInspect THEN G3dCubeDraw.SimpleCube[context, s.inspect, view, vp,, solid]; } ELSE IF s.doInspect THEN { }; Toggle: PROC [data: REF ANY, button: ViewerClasses.MouseButton, name: ROPE] ~ { d: SimpleData ~ NARROW[data]; bool: BOOL ¬ SELECT TRUE FROM Rope.Equal[name, "Inspect"] => (d.doInspect ¬ NOT d.doInspect), Rope.Equal[name, "Dual"] => (d.doInspect ¬ NOT d.doInspect), Rope.Equal[name, "Clip"] => (d.doClip ¬ NOT d.doClip), ENDCASE => FALSE; Controls.ButtonToggle[d.tool.tool3d.outerData, bool, Rope.Concat[name, "-On"], Rope.Concat[name, "-Off"]]; IF button = blue THEN [] ¬ ImplicitDesign.Repaint[d.tool]; }; SphereNormal: NormalProc ~ {RETURN[point]}; SphereTexture: TextureProc ~ { polar: Triple ~ G3dVector.PolarFromCartesian[vertex.point]; RETURN[[polar.x/360.0, polar.y/360.0]]; }; SetBlobColors: PROC [surface: Surface, blobSources: Source3dSequence] ~ { p0: Triple ~ blobSources[0].p; p1: Triple ~ blobSources[1].p; r0Sqd: REAL ~ blobSources[0].strength*blobSources[0].strength; r1Sqd: REAL ~ blobSources[1].strength*blobSources[1].strength; FOR n: NAT IN [0..surface.vertices.length) DO v: Vertex ~ surface.vertices[n]; pot0: REAL ~ r0Sqd/MAX[0.0001, G3dVector.SquareDistance[p0, v.point]]; pot1: REAL ~ r1Sqd/MAX[0.0001, G3dVector.SquareDistance[p1, v.point]]; [[v.rgb.x, v.rgb.y, v.rgb.z]] ¬ ImagerColorFns.RGBFromHSL[[pot0/(pot0+pot1), 1.0, 0.5]]; ENDLOOP; surface.vertexValidities.color ¬ TRUE; }; ToggleInspect: ClickProc ~ {Toggle[clientData, mouseButton, "Inspect"]}; ToggleDual: ClickProc ~ {Toggle[clientData, mouseButton, "Dual"]}; ToggleClip: ClickProc ~ {Toggle[clientData, mouseButton, "Clip"]}; Controls.ClickButton["Inspect-Off", ToggleInspect, s], Controls.ClickButton["Dual-Off", ToggleDual, s], Controls.ClickButton["Clip-Off", ToggleClip, s], Controls.ClickButton["PrintSphereCount", PrintSphereCount, s], PrintSphereCount: ClickProc ~ { s: SimpleData ¬ NARROW[clientData]; TSWrite[s, IO.PutFR["sphere count: %g",IO.int[s.sphereCount]]]; }; ž ImplicitSimpleCmdImpl.mesa Copyright Σ 1985, 1990 by Xerox Corporation. All rights reserved. Bloomenthal, February 20, 1993 6:06 pm PST Types Simple Surfaces savedOctreeType: OctreeType ¬ track, doInspect: BOOL ¬ FALSE, -- inspect a cube? doDual: BOOL ¬ FALSE, -- ?? root: Cube ¬ NIL, -- the root of the octree inspect: Cube ¬ NIL, -- moving, inspecting cube oldInspect: Cube ¬ NIL, -- previous inspecting cube doClip: BOOL ¬ FALSE, -- clip the sphere? Controls.ClickButton["L", Move, s], Controls.ClickButton["R", Move, s], Controls.ClickButton["B", Move, s], Controls.ClickButton["T", Move, s], Controls.ClickButton["N", Move, s], Controls.ClickButton["F", Move, s], Controls.ClickButton["Up", Up, s], Controls.ClickButton["Down", Down, s], Controls.ClickButton["?", Query, s], After surface computed: SetBlobColors[p.surface, blobSources]; size: 0.1 value ¬ IF s.doClip AND point.x < -0.321 THEN -1.0 ELSE s.r2-G3dVector.Square[point]; Try (x2+y2+z2+R2-r2)2-4R2(y2+z2) -(x2*x2+y2*y2+z2*z2+s.r4+s.rr4+2.*(x2*y2+x2*z2+y2*z2-s.a*x2+s.b*y2-s.a*z2-s.c)); IF old = blob THEN d.tool.octreeType ¬ d.savedOctreeType; IF d.op = blob THEN { d.savedOctreeType ¬ d.tool.octreeType; d.tool.octreeType ¬ track; }; Support Initialization GetDataAndTestRoot: PROC [clientData: REF ANY] RETURNS [s: SimpleData] ~ { s ¬ NARROW[clientData]; IF s.tool.octree.root # s.root THEN s.inspect ¬ s.root ¬ s.tool.octree.root; }; Move: ClickProc ~ { s: SimpleData ~ GetDataAndTestRoot[clientData]; direction: G3dOctree.Direction ~ G3dOctree.DirectionFromRope[parent.name]; new: Cube ~ G3dOctree.Neighbor[s.inspect, direction]; IF new = NIL THEN Blink["Can't move in that direction."] ELSE { s.oldInspect ¬ s.inspect; s.inspect ¬ new; ImplicitDesign.Repaint[s.tool, $Client]; }; }; Up: ClickProc ~ { s: SimpleData ~ GetDataAndTestRoot[clientData]; IF s.inspect.parent = NIL THEN Blink["No parent."] ELSE { s.oldInspect ¬ s.inspect; s.inspect ¬ s.inspect.parent; ImplicitDesign.Repaint[s.tool, $Client]; }; }; Down: ClickProc ~ { s: SimpleData ~ GetDataAndTestRoot[clientData]; IF s.inspect.terminal THEN Blink["No children."] ELSE { s.oldInspect ¬ s.inspect; s.inspect ¬ s.inspect.kids[lbn]; ImplicitDesign.Repaint[s.tool, $Client]; }; }; Query: ClickProc ~ { s: SimpleData ~ NARROW[clientData]; c: Cube ¬ s.inspect; roundness: REAL ¬ ImplicitAdapt.Roundness[c, Value, s.tool.threshold, NIL]; TSWrite[s, IO.PutFR1["\n%4.3f round", IO.real[roundness]]]; TSWrite[s, IO.PutFR1[", %4.3f error", IO.real[ImplicitAdapt.LinearDeviation[c]]]]; }; IF s.doDual THEN { size: REAL ¬ G3dOctree.Size[s.root]; center: Triple ¬ G3dOctree.Center[s.root]; clip: Cube ¬ G3dOctree.NewCube[size, [center.x+0.5*size, center.y, center.z]]; IF NOT s.tool.surface.curvesValid THEN ImplicitSurface.SetSurfaceCurves[s.tool.surface]; FOR n: NAT IN [0..s.tool.surface.curves.length) DO c: G3dSpline.Spline ¬ s.tool.surface.curves[n]; p0: Triple ¬ G3dSpline.Position[c, 0.0]; p1: Triple ¬ G3dSpline.Position[c, 1.0]; IF p0.x < 0.0 OR p1.x < 0.0 THEN G3dDraw.Curve[context, c, view, vp]; ENDLOOP; }; Show: PROC [cube: Cube, color: Imager.Color, width: REAL] ~ { IF cube = NIL THEN RETURN; Imager.SetColor[context, color]; Imager.SetStrokeWidth[context, width]; G3dCubeDraw.SimpleCube[context, cube, view, vp,, solid]; }; Show[s.oldInspect, Imager.white, 2.0]; Show[s.oldInspect, Imager.black, 1.0]; Show[s.inspect, Imager.black, 2.0]; Imager.SetStrokeWidth[context, 0.0]; Κ•NewlineDelimiter ™™JšœB™BJ™*J˜JšΟk œ­˜ΆJ˜—–0.320 0.931 0.362 textColoršΠblœΠbkΟbŸ˜$Jšœl˜sJ˜—šœ˜J˜—head–0.0 24 .div 1 1 textColoršΟl™Jšœ œ˜"Jšœœ˜0Jšœ œ˜%Jšœ œ˜-Jšœœ"˜8Jšœœœ˜Jšœ œ˜,—–0.0 24 .div 1 1 textColorš‘™Jšœœ*œœ œ˜B˜OJ˜—Jšœ œœ˜'šœœœ˜Jšœœ˜JšœΟc˜6Jšœœ’˜CJšœœ ’˜:Jšœ œ ’$˜?Jšœ œ ’˜-Jšœ œ ’˜1Jšœœ ’˜CJšœœ’ ˜EJšœœ ’!˜BJšœ$œ’˜9Jšœœ˜J™&Jšœœœ’™3Jšœ œœ’™$Jšœœ’™6Jšœœ’™9Jšœœ’™™>J˜J˜—–(Postfix0.320 0.931 0.362 textColoršΠbnœ˜Jšœœ ˜#šœ˜˜ J™ Jšœœ˜+Jšœœ˜*JšœœF˜PJ˜—šœ ˜ šœ˜š œœœœ˜/J˜-Jšœœ(˜3Jšœœ˜Jšœœ˜"Jšœ œœ ˜"Jšœ œ ˜3Jš˜—JšœF˜J—J˜J˜—˜ Jšœœœ˜/Jšœœœ˜/Jšœœœ˜/Jšœœœœ ˜8Jšœœœœ ˜>Jšœœ˜ Jšœœ˜&Jšœœœ˜7Jšœœ!œ˜IJ˜ J˜—šœ ˜ J˜ J˜%šœœ œ™(Jšœœ™,—J˜—šœœ ˜-JšœL˜LJšœL˜LJšœ(˜/—˜ JšœΟuœ₯œ₯œ₯œ₯œ₯œ₯œ₯œ₯œ™ Jšœ₯œœ˜Jšœ₯œœ˜Jšœ₯œœ˜Jš œœ₯œ₯œ₯œ₯œ₯œ˜Jšœ₯œ₯œ₯œ˜JšœΠsuœ¦œ¦œ¦œ¦œ¦œ¦œ¦œ¦œ¦œ¦œ¦œ¦œ¦œ¦œ™PJ˜—J˜˜Jšœ₯œœ˜Jšœ₯œœ˜Jšœ₯œœ˜Jšœœ₯œ₯œ₯œ₯œ₯œ₯œ₯œ₯œ₯œ˜AJ˜—J˜MJ˜NJ˜B˜Jšœ₯œœ˜Jšœ₯œœ˜Jšœ₯œœ˜Jš œ ₯œ₯œ₯œ₯œ₯œ₯œ˜6J˜—˜Jšœ₯œœ˜Jšœœ)₯œ₯œ˜>J˜—Jšœ˜—˜J˜——–(Postfix0.320 0.931 0.362 textColorš£œ˜Jšœœ ˜#J˜'J˜Icode˜L˜—–(Postfix0.320 0.931 0.362 textColorš£œ˜Jšœœ ˜#J˜JJ˜7J˜6L˜L˜—–( Postfix0.320 0.931 0.362 textColorš£ œ˜Jšœœ ˜#J˜CL˜L˜—–(Postfix0.320 0.931 0.362 textColorš£œ˜Jšœœ ˜#šœ˜˜ Jš œΟsœ§œ§œ§œ ˜TJš œ§œ§œ§œ§œ ˜TJ˜—J˜PJšœ˜—J˜J˜—–( Postfix0.320 0.931 0.362 textColorš£ œ˜–(Postfix0.320 0.931 0.362 textColor(š£œœ œœ˜-šœœ˜+J˜J˜J˜J˜J˜J˜J˜J˜!J˜J˜J˜J˜"J˜Jšœœ˜—J˜—šœ œœœœ˜*Jš’œ,˜1Jš’œ0˜5Jš’œ5˜:Jš’œ˜ Jš’œ+˜0Jš’œ'˜,Jš’œ.œ˜4Jš’œ-˜2Jš’œ$˜)Jš’œ˜#Jš’œ˜$Jš’œ˜$Jš’œ!˜'J˜—Jšœœ ˜#J˜šœœ7˜HJ˜WJ˜WJ˜Jšœ ˜—Jšœ œ'™9šœ œ™J™&J™J™—J˜IJšœœ)˜CJ˜——–0.0 24 .div 1 1 textColorš‘™–(Postfix0.320 0.931 0.362 textColorEš£œœœ'˜LJ˜—–(Postfix0.320 0.931 0.362 textColorš£œœ œ˜Jšœœ˜$J˜J˜J˜—–( Postfix0.320 0.931 0.362 textColor>š £ œœœ œœœ˜GJšœC˜IJ˜——–0.0 24 .div 1 1 textColorš‘™J˜ZJ˜—Jšœ˜˜J™–(Postfix0.320 0.931 0.362 textColor8š £œœœœœ™JJšœœ ™Jšœœ)™LJ™J™—–(Postfix0.320 0.931 0.362 textColorš£œ™Jšœ/™/JšœJ™JJ™5Jšœœœ'™8šœ™J™J™J™(J™—L™L™—–(Postfix0.320 0.931 0.362 textColorš£œ™Jšœ/™/šœ™Jšœ™šœ™J™J™J™(J™——L™L™—–(Postfix0.320 0.931 0.362 textColorš£œ™Jšœ/™/šœ™Jšœ™šœ™J™J™ J™(J™——L™L™—–(Postfix0.320 0.931 0.362 textColorš£œ™Jšœœ ™#J™Jšœ œ6œ™KJšœ œ§œœ™;Jšœ œœ*™RJ™J˜—šœ˜šœ˜Jšœ œ>˜Qšœ œ™Jšœœ™$J™*J™Ošœœ™!Jšœ2™6—šœœœ#™2J™/J™(J™(Jšœ œ œ%™EJšœ™—J™—J˜—šœœ œ˜–(Postfix0.320 0.931 0.362 textColor9š£œœ*œ™=Jšœœœœ™J™ J™&Jšœ8™8J™—J™&J™&J™#J™$J˜J˜——–(Postfix0.320 0.931 0.362 textColorIš €œœœœ+œ˜OJšœœ˜šœœœœ˜Jšœ.œ˜?Jšœ,œ˜=Jšœ)œ ˜7Jšœœ˜—J˜jJšœœ%˜:L˜L˜—Jš  œœ ˜+š£ œ˜J˜;Jšœ!˜'J˜J˜—š£ œœ6˜IJ˜J˜Jšœœ3˜>Jšœœ3˜>šœœœ˜-J˜ Jšœœ œ0˜FJšœœ œ0˜FJ˜XJšœ˜—Jšœ!œ˜&J˜J˜—Jš€ œ;˜HJš  œ9˜CJš  œ9˜CL˜J˜6J˜0Jšœ0˜0˜>J˜—š£œ˜Jšœœ ˜#Jšœ §œ§œœ˜?L˜L˜——J˜—…—'VF