DIRECTORY Atom, CD, CDPrivate, CDApplications, CDConvertLayers, CDDirectory, CDEvents, CDBasics, CDOrient, Graphics, Process, RefTab, Rope USING [Cat, IsEmpty, ROPE], SafeStorage, TerminalIO; CDImpl: CEDAR MONITOR IMPORTS Atom, CD, CDApplications, CDDirectory, CDEvents, CDBasics, CDOrient, Graphics, Process, RefTab, Rope, SafeStorage, TerminalIO EXPORTS CD, CDPrivate, CDConvertLayers SHARES CD, CDPrivate = BEGIN Error: PUBLIC ERROR[ec: CD.ErrorCode _ programmingError, explanation: Rope.ROPE _ NIL] = CODE; DebugCall: PUBLIC SIGNAL[what: REF] = CODE; permanent: ZONE = SafeStorage.GetPermanentZone[]; layers: PUBLIC REF ARRAY CD.Layer OF CDPrivate.LayerRef = permanent.NEW[ARRAY CD.Layer OF CDPrivate.LayerRef]; registerTechEvent: CDEvents.EventRegistration = CDEvents.RegisterEventType[$RegisterTechnology]; technologyRegistration: RefTab.Ref = RefTab.Create[]; -- contains technologies TechnologyPrivate: TYPE = REF TechnologyPrivateRep; TechnologyPrivateRep: PUBLIC TYPE = RECORD [ objectRegisterTab: RefTab.Ref, -- contains object types layerKeyTab: RefTab.Ref -- contains Layers ]; nilTechnologyPrivate: TechnologyPrivate = NEW[TechnologyPrivateRep_[ objectRegisterTab: RefTab.Create[], --for technology dependant objects it contains NIL layerKeyTab: RefTab.Create[] ]]; RegisterObjectType: PUBLIC PROC [objectType: ATOM, technology: CD.Technology_NIL] RETURNS [REF CD.ObjectProcs] = BEGIN done: BOOL; p: REF CD.ObjectProcs = permanent.NEW[CD.ObjectProcs]; p.technology _ technology; p.objectType _ objectType; p.further _ RefTab.Create[]; p.drawMe _ DefaultDrawMe; p.quickDrawMe _ DefaultQuickDrawMe; p.showMeSelected _ OutlineObjectProc; p.hitInside _ DefaultHitInside; p.interestRect _ DefaultInterestRect; p.oldInsideRect _ DefaultOldInsideRect; p.inDirectory _ FALSE; p.wireTyped _ FALSE; p.describe _ DefaultDescribe; p.describeApp _ DefaultDescribeApp; p.origin _ DefaultOrigin; IF technology=NIL THEN done _ RefTab.Insert[nilTechnologyPrivate.objectRegisterTab, objectType, p] ELSE { techPriv: TechnologyPrivate = technology.technologyPrivate; objectRegisterTab: RefTab.Ref = techPriv.objectRegisterTab; globFound: BOOL; x: REF; [globFound, x] _ RefTab.Fetch[nilTechnologyPrivate.objectRegisterTab, objectType]; IF globFound AND x#NIL THEN done _ FALSE ELSE { [] _ RefTab.Insert[nilTechnologyPrivate.objectRegisterTab, objectType, NIL]; done _ RefTab.Insert[objectRegisterTab, objectType, p]; -- technology register } }; IF NOT done THEN RETURN [NIL]; RETURN [p] END; FetchObjectProcs: PUBLIC PROC [objectType: REF, technology: CD.Technology_NIL] RETURNS [REF CD.ObjectProcs] = BEGIN x: REF; p: REF CD.ObjectProcs_NIL; found: BOOL _ FALSE; IF technology#NIL THEN { -- search in technology table techPriv: TechnologyPrivate = technology.technologyPrivate; [found, x] _ RefTab.Fetch[techPriv.objectRegisterTab, objectType]; }; IF NOT found THEN { -- search in global table [found, x] _ RefTab.Fetch[nilTechnologyPrivate.objectRegisterTab, objectType]; }; IF found THEN TRUSTED {p _ LOOPHOLE[x]}; RETURN [p] END; DefaultDrawMe: PROC [aptr: CD.ApplicationPtr, pos: CD.DesignPosition, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN IF aptr.ob.p.quickDrawMe#DefaultQuickDrawMe THEN aptr.ob.p.quickDrawMe[aptr, pos, orient, pr] ELSE { ob1: CD.ObPtr = CDDirectory.ExpandHard[aptr.ob, pr.design, NIL]; IF ob1#NIL THEN { app: CD.ApplicationPtr = NEW[CD.Application_[ob: ob1, properties: aptr.properties, location: pos, selected: FALSE]]; ob1.p.drawMe[app, pos, orient, pr]; app.ob _ NIL; app.properties _ NIL; } ELSE pr.drawRect[CDOrient.RectAt[pos, aptr.ob.size, orient], CD.highLightShade, pr] } END; DefaultDrawChild: PROC [aptr: CD.ApplicationPtr, pos: CD.DesignPosition, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN aptr.ob.p.drawMe[aptr, pos, orient, pr] END; DefaultQuickDrawMe: PROC [aptr: CD.ApplicationPtr, pos: CD.DesignPosition, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN IF aptr.ob.p.drawMe#DefaultDrawMe THEN aptr.ob.p.drawMe[aptr, pos, orient, pr] ELSE { ob1: CD.ObPtr = CDDirectory.ExpandHard[aptr.ob, pr.design, NIL]; IF ob1#NIL THEN { app: CD.ApplicationPtr = NEW[CD.Application_[ob: ob1, properties: aptr.properties, location: pos, selected: FALSE]]; ob1.p.quickDrawMe[app, pos, orient, pr]; app.ob _ NIL; app.properties _ NIL; } ELSE pr.drawRect[CDOrient.RectAt[pos, aptr.ob.size, orient], CD.highLightShade, pr] } END; OutlineObjectProc: PROC [aptr: CD.ApplicationPtr, pos: CD.DesignPosition, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN pr.outLineProc[ CDOrient.MapRect[ itemInCell: CD.InterestRect[aptr.ob], cellSize: aptr.ob.size, cellInstOrient: orient, cellInstPos: pos ], pr ] END; DefaultHitInside: PROC [aptr: CD.ApplicationPtr, hitRect: CD.DesignRect] RETURNS [BOOL] = BEGIN RETURN [ CDBasics.Intersect[hitRect, CDApplications.ARectO[aptr]] AND CDBasics.Intersect[hitRect, CDOrient.MapRect[ itemInCell: CD.InterestRect[aptr.ob], cellSize: aptr.ob.size, cellInstOrient: aptr.orientation, cellInstPos: aptr.location ]] ] END; DefaultDefaultsInterestRecProc: PROC [ob: CD.ObPtr] RETURNS [BOOL] = BEGIN RETURN [TRUE] END; DefaultInterestRect: PROC [ob: CD.ObPtr] RETURNS [CD.DesignRect] = BEGIN RETURN [CDBasics.RectAt[[0, 0], ob.size]] END; DefaultOrigin: PROC [ob: CD.ObPtr] RETURNS [CD.DesignPosition] = BEGIN RETURN [CDBasics.BaseOfRect[ob.p.interestRect[ob]]] END; DefaultOldInsideRect: PROC [ob: CD.ObPtr] RETURNS [CD.DesignRect] = BEGIN RETURN [ob.p.interestRect[ob]] END; DefaultDescribeApp: PROC [app: CD.ApplicationPtr] RETURNS [Rope.ROPE] = BEGIN RETURN [app.ob.p.describe[app.ob]] END; DefaultDescribe: PROC [me: CD.ObPtr] RETURNS [Rope.ROPE] = BEGIN Desc: PROC [p: REF READONLY CD.ObjectProcs] RETURNS [Rope.ROPE] = INLINE BEGIN RETURN [ IF p.description=NIL THEN Atom.GetPName[p.objectType] ELSE p.description ] END; IF me.p.inDirectory THEN { n: Rope.ROPE = CDDirectory.Name[me]; IF ~Rope.IsEmpty[n] THEN RETURN [Rope.Cat[Desc[me.p], " ", n]] }; RETURN [Desc[me.p]] END; DefaultDrawComment: PROC [r: CD.DesignRect, comment: Rope.ROPE, pr: CD.DrawRef] = BEGIN END; lastLayer: CD.Layer _ 3; InitiateLayer: PROC [lev: CD.Layer, technology: CD.Technology_NIL, uniqueKey: ATOM] = BEGIN techPriv: TechnologyPrivate; layers[lev].technology _ technology; layers[lev].uniqueKey _ uniqueKey; IF technology=NIL THEN techPriv _ nilTechnologyPrivate ELSE { techPriv _ technology.technologyPrivate; technology.usedLayers _ CONS[lev, technology.usedLayers] }; [] _ RefTab.Insert[techPriv.layerKeyTab, uniqueKey, layers[lev]]; END; ConvertLayer: PUBLIC ENTRY PROC [technology: CD.Technology, uniqueKey: ATOM, into: CD.Layer] = BEGIN ENABLE UNWIND => NULL; techPriv: TechnologyPrivate; IF uniqueKey=NIL OR uniqueKey=$NIL THEN RETURN WITH ERROR Error[callingError, "bad uniqueKey"]; -- avoid problems with NIL as ATOM; any IO routine might use $NIL instead IF technology=NIL THEN techPriv _ nilTechnologyPrivate ELSE techPriv _ technology.technologyPrivate; [] _ RefTab.Insert[techPriv.layerKeyTab, uniqueKey, layers[into]]; END; NewLayer: PUBLIC ENTRY PROC [technology: CD.Technology_NIL, uniqueKey: ATOM] RETURNS [CD.Layer] = BEGIN ENABLE UNWIND => NULL; IF uniqueKey=NIL OR uniqueKey=$NIL THEN RETURN WITH ERROR Error[callingError, "bad uniqueKey"]; -- avoid problems with NIL as ATOM; any IO routine might use $NIL instead IF lastLayer>=CD.layerNum-1 THEN RETURN WITH ERROR Error[noResource, "too many layers have been requested; (probaly too many different technologies are used)"]; lastLayer _ lastLayer+1; InitiateLayer[lastLayer, technology, uniqueKey]; RETURN [lastLayer] END; DefaultDrawContext: PROC [pr: CD.DrawRef, proc: CD.DrawContextLayerProc, ob: CD.ObPtr, pos: CD.DesignPosition, orient: CD.Orientation, layer: CD.Layer] = BEGIN IF pr.deviceContext#NIL AND pr.contextFilter#NIL AND pr.contextFilter[layer].doit THEN { mark: Graphics.Mark = pr.deviceContext.Save[]; [] _ pr.deviceContext.SetPaintMode[pr.contextFilter[layer].paintMode]; pr.deviceContext.SetColor[pr.contextFilter[layer].color]; IF ob#NIL THEN { pr.deviceContext.Translate[pos.x, pos.y]; CDOrient.OrientateContext[pr.deviceContext, ob.size, orient]; }; proc[pr.deviceContext, ob, layer ! UNWIND => { pr.deviceContext.Restore[mark]; GOTO return } ]; pr.deviceContext.Restore[mark] } EXITS return => NULL; END; FetchLayer: PUBLIC PROC [t: CD.Technology, uniqueKey: ATOM] RETURNS [CD.Layer] = BEGIN found: BOOL_FALSE; l: CD.Layer _ CD.highLightError; x: REF; IF t#NIL THEN { techPriv: TechnologyPrivate = t.technologyPrivate; [found: found, val: x] _ RefTab.Fetch[techPriv.layerKeyTab, uniqueKey]; }; IF ~found THEN { [found: found, val: x] _ RefTab.Fetch[nilTechnologyPrivate.layerKeyTab, uniqueKey]; }; IF found THEN l _ NARROW[x, CDPrivate.LayerRef].number; RETURN [l] END; LayerTechnology: PUBLIC PROC [l: CD.Layer] RETURNS [CD.Technology] = BEGIN RETURN [layers[l].technology]; END; LayerKey: PUBLIC PROC [l: CD.Layer] RETURNS [ATOM] = BEGIN RETURN [layers[l].uniqueKey]; END; nestingDepht: CARDINAL _ 400; CreateDrawRef: PUBLIC PROC [design: CD.Design, deviceContext: Graphics.Context] RETURNS [CD.DrawRef] = BEGIN p: CD.DrawRef ~ NEW[CD.DrawInformation]; p.interestClip _ CDBasics.universe; p.minimalSize _ 0; p.scaleHint _ 0.0; p.drawRect _ DrawRectWithGraphics; p.drawComment _ DefaultDrawComment; p.drawChild _ DefaultDrawChild; p.outLineProc _ EmptyOutLineProc; p.saveRect _ SaveByDraw; p.stopFlag _ NEW[BOOL _ FALSE]; p.drawContext _ DefaultDrawContext; p.deviceContext _ deviceContext; p.devicePrivate _ NIL; p.setGround _ DefaultSetGround; p.design _ design; p.nesting _ NEW[CD.Nesting[nestingDepht]]; p.nestDepth _ 0; RETURN [p] END; EmptyOutLineProc: PROC[r: CD.Rect, pr: CD.DrawRef] = {}; SaveByDraw: PROC [r: CD.Rect, l: CD.Layer, pr: CD.DrawRef] = {pr.drawRect[r, l, pr]}; DefaultSetGround: PROC [pr: CD.DrawRef, pushedOut: BOOL] = {}; DrawRectWithGraphics: PROC [r: CD.Rect, l: CD.Layer, pr: CD.DrawRef] = BEGIN DrawRectInContext: PROC [context: Graphics.Context, ob: CD.ObPtr, layer: CD.Layer] = { context.DrawBox[Graphics.Box[xmin: r.x1, xmax: r.x2, ymin: r.y1, ymax: r.y2]]; }; pr.drawContext[pr, DrawRectInContext, NIL, [0, 0], 0, l] END; RegisterTechnology: PUBLIC PROC [key: ATOM, name: Rope.ROPE] RETURNS [CD.Technology] = BEGIN t: CD.Technology = permanent.NEW[CD.TechnologyRec]; IF ~RefTab.Insert[technologyRegistration, key, t] THEN RETURN[NIL]; t.key _ key; t.name _ name; t.usedLayers _ NIL; t.technologyPrivate _ permanent.NEW[TechnologyPrivateRep _ [RefTab.Create[], RefTab.Create[]]]; [] _ CDEvents.ProcessEvent[ev: registerTechEvent, design: NIL, x: t]; RETURN[t] END; FetchTechnology: PUBLIC PROC [key: ATOM] RETURNS [CD.Technology] = BEGIN x: REF; found: BOOL; tech: CD.Technology _ NIL; [found: found, val: x] _ RefTab.Fetch[technologyRegistration, key]; IF found THEN tech _ NARROW[x]; RETURN[tech] END; BreakProc: PROC [msg: Rope.ROPE, what: REF] = {SIGNAL DebugCall[what]}; Debug: PUBLIC PROC [msg: Rope.ROPE_NIL, what: REF_NIL, mayProceed: BOOL_TRUE] = BEGIN n: INT_0; IF msg=NIL THEN msg _ "Unknown error"; IF mayProceed THEN { DO TerminalIO.WriteRope[msg]; TerminalIO.WriteRope["\nif you don't know what to do,\n"]; TerminalIO.WriteRope[" then mouse-click on proceed,\n"]; TerminalIO.WriteRope[" save your design onto a new file,\n"]; TerminalIO.WriteRope[" and restart chipndale\n"]; n _ TerminalIO.RequestSelection[ label: "Debug options", choice: LIST["proceed", "signal and proceed", "signal in main process"]]; SELECT n FROM 1 => {TerminalIO.WriteRope["proceed\n"]; EXIT}; 2 => {TRUSTED {Process.Detach[FORK BreakProc[msg, what]]}; EXIT}; 3 => {BreakProc[msg, what]; EXIT}; ENDCASE => TerminalIO.WriteRope["skipped\n"]; ENDLOOP; } ELSE { TerminalIO.WriteRope[msg]; ERROR DebugCall[what] }; END; IF registerTechEvent=NIL THEN ERROR; FOR l: CD.Layer IN CD.Layer DO layers[l] _ permanent.NEW[CDPrivate.LayerRec]; layers[l].number _ l; layers[l].globalUniqueKey _ layers[l]; ENDLOOP; InitiateLayer[CD.combined, NIL, $combined]; InitiateLayer[CD.highLightShade, NIL, $highLightShade]; InitiateLayer[CD.highLightError, NIL, $highLightError]; InitiateLayer[CD.backGround, NIL, $backGround]; END. 2CDImpl.mesa (part of ChipNDale) Copyright c 1983, 1985 by Xerox Corporation. All rights reserved. Christian Jacobi, June 24, 1983 5:07 pm last edited Christian Jacobi, May 7, 1985 12:45:59 pm PDT --assume everithing gets correct even if all references are lost, --don't care about memory area, hint only --also initializes procedures with default values --still check if it might be global --global register it used per technology --may find it but have NIL value: then is technologydependant --sorry XXXX IF found THEN p _ NARROW[x]; --pr.drawRect[CDOrient.RectAt[pos, aptr.ob.size, orient], CD.highLightShade, pr] --Helps conversion when layers are renamed --calls proc which may use context; mode and color are set to layer's need --call is suppressed if layer does not need drawing; this is default. --on recursive calls, the context may or may not include previous transformations --pr.deviceContext.ClipBox[[xmin: pr.interestClip.x1, ymin: pr.interestClip.y1, xmax: pr.interestClip.x2, ymax: pr.interestClip.y2]]; --Returns NIL if key is already in use --This must be the only way to create data of type TechnologyRec --not ENTRY since RefTab.Insert does necessary monitoring and CDEvents.ProcessEvent --is dangerous --Returns NIL if key is not registered -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- Ê5˜šœ!™!Jšœ Ïmœ7™BJšœ(™(Jšœ9™9—J˜šÏk ˜ Jšœ˜Jšžœ˜Jšœ ˜ J˜Jšœ˜Jšœ ˜ J˜ J˜ Jšœ ˜ J˜ J˜J˜Jšœžœžœ˜ J˜ J˜ —J˜šÏbœžœžœ˜Jšžœ˜†Jšžœžœ˜&Jšžœžœ˜—Jšž˜J˜Jš œžœžœžœ1žœžœžœ˜^Jš œ žœžœžœžœ˜+šœ žœ#˜2JšœB™BJšœ)™)—J˜š œžœžœžœžœžœ˜:Jš œ žœžœžœžœ˜5—J˜J˜`J˜Jšœ6Ïc˜NJ˜Jšœžœžœ˜3šœžœžœžœ˜,Jšœ ˜7Jšœ ˜*J˜J˜J˜—šœ*žœ˜DJšœ$ 3˜WJšœ˜Jšœ˜—J˜J˜š Ïnœžœžœžœžœ žœ˜RJšžœžœ˜Jšœ2™2Jšž˜Jšœžœ˜ Jšœžœžœžœ˜6J˜J˜Jšœ˜J˜J˜#J˜%J˜J˜%Jšœ'˜'Jšœžœ˜Jšœžœ˜Jšœ˜Jšœ#˜#Jšžœ˜Jšžœ žœžœL˜bšž˜J˜;J˜;Jšœ žœ˜Jšœžœ˜šœS˜SJšœ#™#—Jš žœ žœžœžœž˜(šžœ˜šœGžœ˜MJšœ(™(—Jšœ8 ˜NJšž˜—Jšžœ˜—Jš žœžœžœžœžœ˜Jšžœ˜ Jšžœ˜J˜—š ¡œžœžœžœžœ žœ˜OJšžœžœ˜Jšž˜Jšœžœ˜Jšœžœ žœ˜Jšœžœžœ˜šžœ žœžœ ˜6J˜;J˜BJšœ˜—šžœžœžœ ˜-JšœN˜NJšœ=™=Jšœ˜—Jšœ)™)Jšžœžœžœžœ˜(Jšžœ˜ Jšžœ˜J˜—š ¡ œžœžœžœžœ ˜]Jšœžœ ˜Jšž˜šžœ*žœ˜1Jšœ,˜,—šžœ˜Jšœžœ4žœ˜@šžœžœžœ˜Jš œžœžœžœMžœ˜tJšœ#˜#Jšœ žœ˜ Jšœžœ˜J˜—Jšžœ9žœ˜SJ˜—Jšžœ˜J˜—š ¡œžœžœžœžœ ˜`Jšœžœ ˜Jšž˜Jšœ'˜'Jšžœ˜J˜—š ¡œžœžœžœžœ ˜bJšœžœ ˜Jšž˜šžœ žœ˜'Jšœ'˜'—šžœ˜Jšœ:žœ™PJšœžœ4žœ˜@šžœžœžœ˜Jš œžœžœžœMžœ˜tJšœ(˜(Jšœ žœ˜ Jšœžœ˜J˜—Jšžœ9žœ˜SJ˜—Jšžœ˜J˜—š¡œžœ žœžœ ˜aJšœžœ ˜Jšž˜šœ˜šœ˜Jšœ%˜%Jšœ˜Jšœ˜Jšœ˜Jšœ˜—Jšœ˜Jšœ˜—Jšžœ˜J˜—š ¡œžœžœžœ žœžœ˜YJšž˜šžœ˜Jšœ9ž˜<šœ˜šœ˜Jšœ žœ˜%Jšœ˜Jšœ!˜!Jšœ˜Jšœ˜——J˜—Jšžœ˜J˜—š ¡œžœžœžœžœ˜EJšž˜Jšžœžœ˜ Jšžœ˜J˜—š ¡œžœžœžœžœ˜CJšž˜Jšžœ#˜)Jšžœ˜J˜—š ¡ œžœžœžœžœ˜AJšž˜Jšžœ-˜3Jšžœ˜J˜—š ¡œžœžœžœžœ˜DJšž˜Jšžœ˜Jšžœ˜J˜—š ¡œžœžœžœžœ˜GJšž˜Jšžœ˜"Jšžœ˜—J˜š ¡œžœžœžœžœ˜:Jšž˜š ¡œžœžœž œžœžœ˜AJšž ˜ šžœ˜Jšžœžœžœ˜5Jšžœ˜J˜—Jšžœ˜—šžœžœ˜Jšœžœ˜$Jšžœžœžœ ˜?Jšœ˜—Jšžœ ˜Jšžœ˜—J˜š ¡œžœžœžœžœ ˜QJšž˜Jšžœ˜—J˜Jšœ žœ ˜J˜š ¡ œžœžœžœ žœ žœ˜UJšž˜Jšœ˜Jšœ$˜$Jšœ"˜"Jšžœ žœžœ ˜6šžœ˜J˜(Jšœžœ˜8J˜—JšœA˜AJšžœ˜—J˜š¡ œžœžœžœžœžœžœ ˜^Jšœ*™*Jšž˜Jšžœžœžœ˜Jšœ˜šžœ žœžœžœ˜(Jšžœžœžœ' I˜—Jšžœ žœžœ ˜6Jšžœ)˜-JšœB˜BJšžœ˜—J˜š¡œžœžœžœžœ žœ žœžœžœ ˜aJšž˜Jšžœžœžœ˜šžœ žœžœžœ˜(Jšžœžœžœ' I˜—šžœ žœ žœ˜!Jšžœžœžœn˜—J˜Jšœ0˜0Jšžœ ˜Jšžœ˜J˜—š¡œžœžœžœžœ žœžœžœ ˜™JšœJ™JJšœE™EJšœQ™QJšž˜š žœžœžœžœžœžœ˜YJšœ.˜.JšœF˜FJšœ9˜9Jšœ…™…šžœžœžœ˜Jšœ)˜)Jšœ=˜=J˜—šœ#˜#šžœ˜ Jšœ ˜ Jšžœ˜ Jšœ˜—Jšœ˜—Jšœ˜J˜—šž˜Jšœ žœ˜—Jšžœ˜—J˜š¡ œžœžœžœžœžœžœ ˜PJšž˜Jšœž œ˜Jšœžœ žœ˜ Jšœžœ˜šžœžœžœ˜J˜2JšœG˜GJšœ˜—šžœžœ˜JšœS˜SJ˜—Jšžœžœžœ˜7Jšžœ˜ Jšžœ˜J˜—š¡œžœžœžœ˜DJšž˜Jšžœ˜Jšžœ˜—J˜š ¡œžœžœžœžœžœ˜4Jšž˜Jšžœ˜Jšžœ˜—J˜Jšœžœ˜J˜š ¡ œžœžœ žœ*žœžœ ˜fJšž˜Jšœžœ žœžœ˜(Jšœ#˜#J˜Jšœ˜Jšœ"˜"Jšœ#˜#Jšœ˜J˜!J˜Jšœ žœžœžœ˜ Jšœ#˜#Jšœ ˜ Jšœžœ˜Jšœ˜J˜Jšœ žœžœ˜*Jšœ˜Jšžœ˜ šžœ˜J˜——Jš¡œžœžœ žœ˜8Jš ¡ œžœžœ žœ žœ$˜UJš¡œžœžœžœ˜>J˜š ¡œžœžœ žœ žœ ˜GJšž˜š¡œžœ!žœžœ ˜VJšœN˜NJšœ˜—Jšœ8˜8Jšžœ˜—J˜š¡œžœžœžœ žœžœžœ˜VJšœ&™&šœ@™@JšœS™SJšœ™—Jšž˜Jšœžœžœžœ˜3Jšžœ0žœžœžœ˜CJ˜ J˜Jšœžœ˜šœ žœ˜:Jšœ$˜$—Jšœ:žœ˜EJšžœ˜ Jšžœ˜J˜—š ¡œžœžœžœžœžœ˜BJšœ&™&Jšž˜Jšœžœ˜Jšœžœ˜ Jšœžœ žœ˜J˜CJšžœžœžœ˜!Jšžœ˜ Jšžœ˜—J˜Jšœ™Jš ¡ œžœ žœžœžœ˜GJ˜š¡œžœžœ žœžœžœžœžœžœ˜PJšžœ˜Jšœžœ˜ Jšžœžœžœ˜&šžœ žœ˜šž˜Jšœ˜Jšœ;˜;Jšœ:˜:Jšœ?˜?Jšœ3˜3šœ ˜ J˜Jšœžœ=˜I—šžœž˜ Jšœ)žœ˜/Jšœžœžœžœ˜AJšœžœ˜"Jšžœ&˜-—Jšžœ˜—J˜—šžœ˜Jšœ˜Jšžœ˜Jšœ˜—Jšžœ˜—J™Jšœ™Jšžœžœžœžœ˜&š žœžœžœžœž˜Jšœžœ˜.Jšœ˜Jšœ&˜&Jšžœ˜—Jšœžœ žœ ˜+Jšœžœžœ˜7Jšœžœžœ˜7Jšœžœ žœ˜/Jšžœ˜J˜J˜—…—/zEá