DIRECTORY Commander, Controls, ControlsPrivate, Draw2d, Imager, ImagerFont, IO, MessageWindow, Process, Real, Rope, SF, ViewerSpecs, ViewerOps, ViewerTools; ControlsCommandsImpl: CEDAR PROGRAM IMPORTS Commander, Controls, ControlsPrivate, Draw2d, Imager, ImagerFont, IO, MessageWindow, Process, Real, Rope, SF, ViewerOps, ViewerSpecs, ViewerTools ~ BEGIN ROPE: TYPE ~ Rope.ROPE; Control: TYPE ~ Controls.Control; IntegerPair: TYPE ~ Controls.IntegerPair; Mouse: TYPE ~ Controls.Mouse; OuterData: TYPE ~ Controls.OuterData; Context: TYPE ~ Imager.Context; Font: TYPE ~ ImagerFont.Font; Box: TYPE ~ SF.Box; ControlsExamplesData: TYPE ~ REF ControlsExamplesDataRep; ControlsExamplesDataRep: TYPE ~ RECORD [ outer: Controls.Viewer ฌ NIL, outerData: OuterData ฌ NIL, font: Font ฌ NIL, oldBox: Box ฌ [[0, 0], [1000, 1000]], pos: IntegerPair ฌ [0, 0], controls: LIST OF Control, text: ROPE ฌ "Some Text", toggleState: BOOL ฌ TRUE, mtEnabled: BOOL ฌ TRUE, natState: NAT ฌ 0, newControl: Control ฌ NIL, newControlState: {add, del} ฌ add ]; ControlsExamples: Commander.CommandProc ~ { d: ControlsExamplesData ฌ NEW[ControlsExamplesDataRep]; d.pos ฌ [ViewerSpecs.openLeftWidth/2, 100]; d.font ฌ ImagerFont.Scale[ImagerFont.Find["xerox/pressfonts/helvetica-mrr"], 16.0]; d.controls ฌ LIST[ Controls.NewControl["no detents", dial, d,, 360.0, 90.0], Controls.NewControl["1 detent", dial, d,, 360.0, 60.0,,,,,,,,,,, LIST[[180.0]]], Controls.NewControl["2 detents", dial, d,, 360.0,,,,,,,,,,,, LIST[[45], [290]]], Controls.NewControl["Lin", vSlider, d,, 1.0, 0.3,,,,,,,,,,, LIST[[0.6]]], Controls.NewControl["Log", vSlider, d,, 1.0, 0.3,,,,,,,,,,,, log], Controls.NewControl["Exp", vSlider, d,, 1.0,,,,,,,,,,,,, exp], Controls.NewControl["Horiz", hSlider, d,, 1.0, 0.5,,,,,,, 60], Controls.NewControl["Side", hSlider, d,, 1.0, 0.5,,,,,,, 60,, [left, center, TRUE]], Controls.NewControl[name: "Function", type: function, w: 180, min: 0.0, max: 1., row: 1], Controls.NewControl[name: "Contour", type: contour, w: 180], Controls.NewControl[name: "Sketch", type: sketch, w: 180]]; d.outer ฌ Controls.OuterViewer[ name: "Controls Examples", controls: d.controls, buttons: LIST[ Controls.ClickButton["Trapping: on", ToggleMouseTrap, d], Controls.ClickButton["Toggle", ToggleButton, d], Controls.ClickButton["State 0", StateButton, d], Controls.ClickButton["Text", TextButton, d], Controls.TextButton["Msg1: ", "??", Msg1Button, d], Controls.TextButton["Msg2: ", "??", Msg2Button, d], Controls.ClickButton["Add Control", NewControlButton, d], Controls.ClickButton["Reset Sliders and Dials", ClearButton, d,,,,,,, TRUE]], typescriptHeight: 18, biScrollable: TRUE, graphicsHeight: 200, mouseProc: MouseProc, drawProc: DrawProc, clientData: d ].parent; d.outerData ฌ NARROW[d.outer.data]; }; OverwriteText: PROC [context: Context, oldBox: Box, pos: IntegerPair, text: ROPE, font: Font] RETURNS [Box] ~ { Action: PROC ~ { Imager.SetFont[context, font]; Imager.SetXY[context, [pos.x, pos.y]]; Imager.ShowRope[context, text]; }; e: ImagerFont.Extents ฌ ImagerFont.RopeBoundingBox[font, text]; newMin: SF.Vec ฌ [Real.Round[pos.y-e.descent]-2, Real.Round[pos.x-e.leftExtent]-2]; newMax: SF.Vec ฌ [Real.Round[pos.y+e.ascent]+2, Real.Round[pos.x+e.rightExtent]+2]; min: SF.Vec ฌ SF.Min[newMin, oldBox.min]; max: SF.Vec ฌ SF.Max[newMax, oldBox.max]; Imager.DoWithBuffer[context, Action, min.f, min.s, max.f-min.f, max.s-min.s, Imager.white]; RETURN[[newMin, newMax]]; }; DrawProc: Controls.DrawProc ~ { d: ControlsExamplesData ฌ NARROW[clientData]; d.oldBox ฌ OverwriteText[context, d.oldBox, d.pos, d.text, d.font]; }; MouseProc: Controls.MouseProc ~ { d: ControlsExamplesData ฌ NARROW[clientData]; d.pos ฌ [mouse.pos.x, mouse.pos.y]; IF mouse.state # up THEN ViewerOps.PaintViewer[d.outerData.graphics, client, FALSE, clientData]; }; Msg1Button: Controls.ClickProc ~ { button: Controls.Button ฌ NARROW[ViewerOps.FetchProp[parent, $ButtonText]]; MessageWindow.Append[Rope.Cat["Message 1 is: ", ViewerTools.GetContents[parent], "; button name is ", button.name], TRUE]; ViewerTools.SetContents[parent, "??"]; }; Msg2Button: Controls.ClickProc ~ { button: Controls.Button ฌ NARROW[ViewerOps.FetchProp[parent, $ButtonText]]; MessageWindow.Append[Rope.Cat["Message 2 is: ", ViewerTools.GetContents[parent], "; button name is ", button.name], TRUE]; ViewerTools.SetContents[parent, "??"]; }; ToggleButton: Controls.ClickProc ~ { d: ControlsExamplesData ฌ NARROW[clientData]; d.toggleState ฌ NOT d.toggleState; Controls.ButtonStyle[ d.outerData, "Toggle", IF d.toggleState THEN $BlackOnWhite ELSE $WhiteOnBlack]; }; ToggleMouseTrap: Controls.ClickProc ~ { d: ControlsExamplesData ฌ NARROW[clientData]; old: ROPE ฌ IO.PutFR1["Trap Mouse: %g", IO.rope[IF d.mtEnabled THEN "on" ELSE "off"]]; new: ROPE ฌ IO.PutFR1["Trap Mouse: %g", IO.rope[IF d.mtEnabled THEN "off" ELSE "on"]]; ControlsPrivate.EnableMouseTrapping[d.mtEnabled ฌ NOT d.mtEnabled]; Controls.ButtonRelabel[d.outerData, old, new]; }; StateButton: Controls.ClickProc ~ { d: ControlsExamplesData ฌ NARROW[clientData]; old: ROPE ฌ IO.PutFR1["State %g", IO.int[d.natState]]; new: ROPE ฌ IO.PutFR1["State %g", IO.int[d.natState ฌ (d.natState+1) MOD 4]]; Controls.ButtonRelabel[d.outerData, old, new]; }; TextButton: Controls.ClickProc ~ { d: ControlsExamplesData ฌ NARROW[clientData]; d.text ฌ Controls.TypescriptRead[d.outerData.typescript, "\nType something (end with CR) "]; Controls.TypescriptWrite[d.outerData.typescript, IO.PutFR1["\nReply was %g",IO.rope[d.text]]]; ViewerOps.PaintViewer[d.outerData.graphics, client, FALSE, d.outerData.graphics]; }; NewControlButton: Controls.ClickProc ~ { d: ControlsExamplesData ฌ NARROW[clientData]; SELECT d.newControlState FROM add => { IF d.newControl = NIL THEN d.newControl ฌ Controls.NewControl[ name: "new", type: vSlider, min: 0.0, max: 1.0, init: 0.5, x: 495, y: 15, w: 25, h: 60]; Controls.ControlViewer[d.outer, d.newControl, d.outerData.graphics, d.outerData]; Controls.ButtonRelabel[d.outerData, "Add Control", "Del Control"]; d.newControlState ฌ del; ViewerOps.PaintViewer[d.outer, client, FALSE, NIL]; }; del => { Controls.ButtonRelabel[d.outerData, "Del Control", "Add Control"]; ViewerOps.DestroyViewer[d.newControl.viewer, FALSE]; ViewerOps.DestroyViewer[d.newControl.title, FALSE]; ViewerOps.DestroyViewer[d.newControl.status, TRUE]; d.newControlState ฌ add; }; ENDCASE; }; ClearButton: Controls.ClickProc ~ { d: ControlsExamplesData ฌ NARROW[clientData]; FOR c: Controls.ControlList ฌ d.outerData.controls, c.rest WHILE c # NIL DO SELECT c.first.type FROM function, contour, sketch => NULL; ENDCASE => Controls.Reset[c.first]; ENDLOOP; }; ControlsSketcher: Commander.CommandProc ~ { d: ControlsExamplesData ฌ NEW[ControlsExamplesDataRep]; d.controls ฌ LIST[Controls.NewControl[name: "Sketch", type: sketch, w: 550, h: 400]]; d.outer ฌ Controls.OuterViewer[ name: "Controls Sketcher", controls: d.controls, buttons: LIST[ Controls.ClickButton["Clear Sketch", ClearButton, d], Controls.ClickButton["Delete Last Stroke", DeleteOneButton, d], Controls.ClickButton["IP Output Sketch", OutputSketchButton, d]], typescriptHeight: 18, clientData: d ].parent; d.outerData ฌ NARROW[d.outer.data]; }; DeleteOneButton: Controls.ClickProc ~ { d: ControlsExamplesData ฌ NARROW[clientData]; ControlsPrivate.DeleteLastSketchStroke[d.controls.first]; }; OutputSketchButton: Controls.ClickProc ~ { SketchDraw: Controls.DrawProc ~ { ips: Controls.IntegerPairSequences ฌ Controls.GetSketch[d.controls.first]; IF ips # NIL THEN { FOR s: NAT IN [0..ips.length) DO stroke: Controls.IntegerPairSequence ฌ ips[s]; FOR n: NAT IN [1..stroke.length) DO i0: IntegerPair ฌ stroke[n-1]; i1: IntegerPair ฌ stroke[n]; Imager.MaskVectorI[context, i0.x, i0.y, i1.x, i1.y]; ENDLOOP; ENDLOOP; }; }; d: ControlsExamplesData ฌ NARROW[clientData]; filename: ROPE ฌ Controls.TypescriptReadFileName[d.outerData.typescript]; IF filename # NIL THEN Draw2d.IPOut[filename, SketchDraw]; }; MouseTestData: TYPE ~ REF MouseTestDataRep; MouseTestDataRep: TYPE ~ RECORD [mouse: Mouse, outerData: OuterData, oldBox: Box]; ControlsMouseTest: Commander.CommandProc ~ { d: MouseTestData ฌ NEW[MouseTestDataRep]; d.outerData ฌ Controls.OuterViewer[ name: "Controls Mouse Test", graphicsHeight: 200, drawProc: MouseTestDrawProc, mouseProc: MouseTestMouseProc, clientData: d]; }; MouseTestDrawProc: Controls.DrawProc ~ { d: MouseTestData ฌ NARROW[clientData]; text: ROPE; font: Font ฌ ImagerFont.Scale[ImagerFont.Find["xerox/pressfonts/helvetica-mrr"], 16.0]; text ฌ SELECT d.mouse.button FROM left =>"left, ", middle =>"middle, ", ENDCASE => "right, "; text ฌ Rope.Concat[text, SELECT d.mouse.state FROM up=>"up", down=>"down", ENDCASE=>"held"]; text ฌ Rope.Concat[text, IF d.mouse.shiftKey THEN ", shift" ELSE NIL]; text ฌ Rope.Concat[text, IF d.mouse.controlKey THEN ", control" ELSE NIL]; d.oldBox ฌ OverwriteText[context, d.oldBox, [d.mouse.pos.x, d.mouse.pos.y], text, font]; }; MouseTestMouseProc: Controls.MouseProc ~ { d: MouseTestData ฌ NARROW[clientData]; d.mouse ฌ mouse; ViewerOps.PaintViewer[d.outerData.graphics, client, FALSE, clientData]; }; VernierData: TYPE ~ REF VernierDataRep; VernierDataRep: TYPE ~ RECORD [ cmdOut: IO.STREAM, res, vernier, lastMoused: Control ฌ NIL, cwIncrease: BOOL ฌ TRUE ]; ControlsVernier: Commander.CommandProc ~ { d: VernierData ฌ NEW[VernierDataRep]; d.cmdOut ฌ cmd.out; d.res ฌ Controls.NewControl["Resolution",, d,, 100, 10, Res,,,, 200, 15, 50, 75, [right,],,, exp]; d.vernier ฌ Controls.NewControl[, dial, d,,,, Vernier, FALSE,,, 75, 15, 75, 75, [left,]]; [] ฌ Controls.OuterViewer[ name: "Vernier For Most Recently Moused Control", buttons: LIST[Controls.ClickButton[" CW Increasing", CWToggle]], controls: LIST[d.vernier, d.res], column: right, clientData: d]; }; Res: Controls.ControlProc ~ {SaveLastMoused[control]}; SaveLastMoused: PROC [control: Control] ~ { d: VernierData ~ NARROW[control.clientData]; SELECT control.mouse.state FROM down => d.lastMoused ฌ Controls.LastControlMoused[]; up => Controls.SetLastControlMoused[d.lastMoused]; ENDCASE; }; Vernier: Controls.ControlProc ~ { l: Control; d: VernierData ~ NARROW[control.clientData]; SaveLastMoused[control]; l ฌ Controls.LastControlMoused[]; IF l # NIL AND l # d.res AND l # d.vernier THEN { Controls.Vernier[control, l, d.cwIncrease, d.res.value]; l.mouse ฌ control.mouse; IF l.precision > 0 THEN ControlsPrivate.ForkControlProc[l]; }; }; CWToggle: Controls.ClickProc ~ { o: OuterData ฌ NARROW[clientData]; d: VernierData ฌ NARROW[o.clientData]; d.cwIncrease ฌ NOT d.cwIncrease; Controls.ButtonToggle[o, d.cwIncrease, " CW Increasing", "CCW Increasing"]; }; ControlsTopLevel: Commander.CommandProc ~ { top: Control ฌ Controls.NewControl[name: "A Top Level Control", proc: Top, type: hSlider]; Controls.ControlViewer[NIL, top, NIL, NIL]; ViewerOps.OpenIcon[top.viewer]; }; Top: Controls.ControlProc ~ { m: Mouse ~ control.mouse; IF m.state # held THEN MessageWindow.Append[Rope.Concat[ Rope.Cat["state: ", IF m.state = down THEN "down" ELSE "up", ", button: ", SELECT m.button FROM left => "left", middle => "middle", right => "right", ENDCASE => "none"], Rope.Cat[", shift: ", IF m.shiftKey THEN "yes" ELSE "no", ", ctrl: ", IF m.controlKey THEN "yes" ELSE "no", IO.PutFR[", x: %g, y: %g", IO.real[m.pos.x], IO.real[m.pos.y]]]]]; }; ControlsQueueTest: Commander.CommandProc ~ { [] ฌ Controls.OuterViewer[ name: "Controls Queue Test", controls: LIST[Controls.NewControl[type: dial, name: "Queue", proc: QueueTest]]]; }; State: PROC [state: Controls.MouseState] RETURNS [r: ROPE] ~ { r ฌ SELECT state FROM down=>"d", up=>"u", ENDCASE=>"h"; }; QueueTest: Controls.ControlProc ~ { IF NOT Controls.CalledFromQueue[control] OR control.mouse.state = up THEN { Process.PauseMsec[1000]; Controls.SetSliderDialValue[control, 0.0]; }; }; SimpleViewerData: TYPE ~ RECORD [graphics: Controls.Viewer, x, y: REAL ฌ 10]; ControlsSimpleViewer: Commander.CommandProc ~ { s: REF SimpleViewerData ฌ NEW[SimpleViewerData]; s.graphics ฌ Controls.OuterViewer[ name: "Controls SimpleViewer", graphicsHeight: 350, mouseProc: Mouser, drawProc: Draw, clientData: s].graphics; }; Draw: Controls.DrawProc ~ { s: REF SimpleViewerData ฌ NARROW[clientData]; Imager.MaskRectangle[context, [s.x, s.y, 25, 25]]; }; Mouser: Controls.MouseProc ~ { s: REF SimpleViewerData ฌ NARROW[clientData]; s.x ฌ mouse.pos.x; s.y ฌ mouse.pos.y; ViewerOps.PaintViewer[s.graphics, client]; }; Commander.Register["ControlsTopLevel", ControlsTopLevel, "\nTest a top level control."]; Commander.Register["ControlsExamples", ControlsExamples, "\nTest various control functions."]; Commander.Register["ControlsMouseTest", ControlsMouseTest, "\nTest mouse proc."]; Commander.Register["ControlsVernier", ControlsVernier, "\nFine tune other controls."]; Commander.Register["ControlsSketcher", ControlsSketcher, "\nDo some free hand sketching."]; Commander.Register["ControlsQueueTest", ControlsQueueTest, "\nTest slider dial queuing."]; Commander.Register["ControlsSimpleViewer", ControlsSimpleViewer, "\nSee SimpleViewer."]; END. | ControlsCommandsmpl.mesa Copyright ำ 1985, 1990, 1992 by Xerox Corporation. All rights reserved. Bloomenthal, July 2, 1992 6:12 pm PDT ControlsExamples Command Controls.PopUpButton["PopUp", PopUp, LIST[[$OneOn, "Turn this off"], [$Two]],,, d], PopUp: Controls.PopUpButtonProc ~ { d: ControlsExamplesData _ NARROW[classData]; ChangeOne: PROC [atom: ATOM, rope: ROPE] ~ { Controls.TypescriptWrite[d.outerData.typescript, "\nOne chosen"]; Controls.ButtonNewChoice[viewer, key, atom, rope]; }; SELECT key FROM $OneOn => ChangeOne[$OneOff, "Turn this on"]; $OneOff => ChangeOne[$OneOn, "Turn this off"]; $Two => { choice: INT _ PopUpSelection.Request[ "Sub Choices:", LIST["A", "B"], "A further choice", LIST["Pick A", "Pick B"]]; Controls.TypescriptWrite[d.outerData.typescript, SELECT choice FROM 0 => "\nTwo-Nothing", 1 => "\nTwo-A chosen", 2 => "\nTwo-B chosen", ENDCASE => "\nTwo-Timeout"]; }; ENDCASE; }; ControlsSketcher Command ControlsMouseTest Command ControlsVernier Command ControlsTopLevel Command ControlsQueueTest Command PrintForkStatus: PROC [c: Control] ~ { TerminalIO.PutRope[Rope.Cat["status= ", SELECT CedarProcess.GetStatus[c.process] FROM done => "done", aborted=>"aborted", debugging=>"debugging", busy=>"busy", ENDCASE=>"invalid", "; "]]; TerminalIO.PutRope[IF Controls.CalledFromQueue[c] THEN "from queue; " ELSE "not queued; "]; TerminalIO.PutRope[Rope.Cat["(", State[c.mouse.state], ")\n"]]; }; PrintQueue: PROC [c: Control] ~ { queue: LIST OF ControlsPrivate.Event; r: ROPE _ Rope.Cat["Call: ", State[c.mouse.state], "; "]; queue _ ControlsPrivate.GetQueue[c]; IF queue = NIL THEN r _ Rope.Concat[r, "no queue"] ELSE FOR l: LIST OF ControlsPrivate.Event _ queue, l.rest WHILE l # NIL DO r _ Rope.Cat[r, " ", State[l.first.mouse.state]]; ENDLOOP; TerminalIO.PutF["%g\n", IO.rope[r]]; }; PrintForkStatus[control]; PrintQueue[control]; ControlsSimpleViewer Command Start Code ส–"cedarcode" style•NewlineDelimiter ™šœ™Jšœ ฯeœ=™HJ™%—J˜Jšฯk œCžœN˜œJ˜šัblnœžœž˜#JšžœCžœM˜™—J˜šœž˜J˜Jšžœžœžœ˜Jšœ žœ˜"Jšœ žœ˜)Jšœžœ˜Jšœ žœ˜%Jšœ žœ˜ Jšœžœ˜Jšœžœžœ˜—headšฯl™Jšœžœžœ˜:šœžœžœ˜(Jšœ!žœ˜%Jšœžœ˜!Jšœžœ˜J˜,J˜"Jšœžœžœ ˜!Jšœ žœ˜!Jšœžœžœ˜Jšœžœžœ˜Jšœžœ˜Jšœžœ˜ J˜&Jšœ˜J˜—šฯnœ˜+Jšœžœ˜7J˜+J˜Sšœ žœ˜Jšœ9˜9JšœAžœ ˜PJšœ=žœ˜PJšœ<žœ ˜IJšœB˜BJšœ>˜>Jšœ>˜>JšœMžœ˜TJ˜YJ˜JšœX˜X—JšœQ˜QJšœB˜BJ˜Jšœ'žœžœ˜3J˜—˜JšœB˜BJšœ-žœ˜4Jšœ,žœ˜3Jšœ-žœ˜3J˜J˜—Jšžœ˜—Jšœ˜J˜—šข œ˜#Jšœžœ ˜-šžœ8žœžœž˜Kšžœž˜Jšœžœ˜"Jšžœ˜#—Jšžœ˜—Jšœ˜——š ™šกœ˜+Jšœžœ˜7Jšœ žœD˜U˜Jšœ˜Jšœ˜šœ žœ˜Jšœ5˜5Jšœ?˜?JšœA˜A—Jšœ˜Jšœ ˜ Jšœ ˜ —Jšœžœ˜#J˜J˜—šขœ˜'Jšœžœ ˜-J˜9Jšœ˜J˜—šขœ˜*šก œ˜!J˜Jšžœžœžœ˜šžœžœžœž˜ J˜.šžœžœžœž˜#J˜J˜Jšœ4˜4Jšžœ˜—Jšžœ˜—J˜—J˜—Jšœžœ ˜-Jšœ žœ;˜IJšžœ žœžœ$˜:Jšœ˜——š ™Jšœžœžœ˜,šœžœžœ3˜RJ˜—šกœ˜,Jšœžœ˜)˜#Jšœ˜Jšœ˜J˜Jšœ˜Jšœ˜—J˜J˜—šกœ˜(Jšœžœ ˜&Jšœžœ˜ Jšœ/ฯsœ ˜WJš œžœžœ&ž œžœ ˜]Jšœžœžœžœ ˜\Jš œžœžœ žœžœ˜FJš œžœžœ žœžœ˜JJ˜XJ˜J˜—šขœ˜*Jšœžœ ˜&J˜Jšœ4žœ˜GJ˜——š ™Jšœžœžœ˜)šœžœžœ˜ Jšœ žœžœ˜Jšœ$žœ˜(Jšœžœž˜Jšœ˜J˜—šขœ˜*Jšœžœ˜%J˜J˜bJšœ7žœ˜Y˜Jšœ1˜1Jšœ žœ3˜@Jšœ žœ˜!J˜J˜—J˜J˜—Jšขœ3˜6J˜šกœžœ˜+Jšœžœ˜,šžœž˜J˜4Jšœ3˜3Jšžœ˜—Jšœ˜J˜—šขœ˜!Jšœ ˜ Jšœžœ˜,Jšœ˜J˜!š žœžœžœ žœžœ˜1Jšœ8˜8J˜Jšžœžœ$˜;J˜—Jšœ˜J˜—šขœ˜ Jšœžœ ˜"Jšœžœ˜&Jšœžœ˜ JšœK˜KJšœ˜——š ™šกœ˜+J˜ZJšœžœžœžœ˜+Jšœ˜J˜J˜—šกœ˜J˜šžœ˜šžœ"˜&Jš œžœžœžœžœ žœ7žœ ˜ฉJšœžœ žœžœžœžœžœžœžœžœ˜ฎ——J˜——š ™šกœ˜,˜Jšœ˜Jšœ žœC˜Q—J˜J˜—šกœžœžœžœ˜>Jšœžœžœžœ˜7Jšœ˜J˜—šกœžœ™&Jšœ(žœ#žœLžœ™ผJšœžฃœฃžฃœฃœฃœฃžฃœ ฃœ™[J™?J™J™—šก œžœ™!Jšœžœžœ™%Jšœžœ2™9Jšœ$™$šžœ ž™Jšžœ™#š žœžœžœžœ'žœžœž™JJšœ1™1Jšžœ™——Jšœžœ ™$J™J™—šข œ˜#J™šžœžœ"žœžœ˜KJ™Jšœ˜J˜*J˜—J˜——š ™šœžœžœ#žœ˜MJ˜—šกœ˜/Jšœžœžœ˜0˜"Jšœ˜J˜J˜Jšœ˜Jšœ˜—J˜J˜—šกœ˜Jšœžœžœ ˜-Jšœ2˜2J˜J˜—šกœ˜Jšœžœžœ ˜-J˜J˜Jšœ*˜*J˜——š  ™ JšœX˜XJšœ^˜^JšœQ˜QJšœV˜VJšœ[˜[J˜ZJ˜XJ˜—Jšžœ˜J˜—…—3dHแ