DIRECTORY CD, CDBasics, CDCallSpecific, CDDirectory, CDDirectoryOps, CDEvents, CDGenerate, CDRemote, CDImports, CDImportsExtras, CDInstances, CDInterestRects, CDIO, CDOps, CDOrient, CDProperties, CDValue, Rope, TerminalIO, TokenIO; CDImportsImpl: CEDAR PROGRAM IMPORTS CD, CDBasics, CDDirectory, CDDirectoryOps, CDEvents, CDGenerate, CDRemote, CDInstances, CDInterestRects, CDIO, CDOps, CDOrient, CDProperties, CDValue, Rope, TerminalIO, TokenIO EXPORTS CDImports, CDImportsExtras SHARES CDDirectory, CDRemote = BEGIN BoolOrInteractive: TYPE = CDImports.BoolOrInteractive; ReferencePtr: TYPE = CDImports.ReferencePtr; ReferenceRep: TYPE = CDImports.ReferenceRep; ImportList: TYPE = CDImports.ImportList; Import: TYPE = CDImports.Import; importListKey: ATOM = $ImportList; -- for CDValue pForReference: REF CD.ObjectClass = CD.RegisterObjectClass[$Import]; EnumerateItsObjects: PROC [me: CD.Object, p: CDDirectory.EnumerateObjectsProc, x: REF] = BEGIN END; ReplaceDirectChild: CDDirectory.ReplaceDChildsProc = BEGIN END; InternalCreateReference: PROC [design: CD.Design, size: CD.Position_[1, 1], --ignored if allowConflicts ir: CD.Rect _ [0, 0, -1, -1], objectName, importeeName: Rope.ROPE, autoImport: BoolOrInteractive_false, --creates an import if not already done autoCreateOb: BoolOrInteractive_false, --creates if not found but design available allowConflicts: BoolOrInteractive_false, --allow size conflicts of the object include: BOOL_TRUE] RETURNS [CD.Object] = BEGIN ob: CD.Object; rp: ReferencePtr; import: REF Import = GetImport[design, importeeName, autoImport]; probablySize: CD.Position _ CDBasics.MaxPoint[size, [1, 1]]; iR: CD.Rect; IF CDBasics.NonEmpty[ir] THEN iR _ ir ELSE iR _ CDBasics.RectAt[[0, 0], probablySize]; IF import=NIL THEN RETURN [NIL]; FOR list: LIST OF CD.Object _ import.referenceList, list.rest WHILE list#NIL DO ob _ list.first; rp _ NARROW[ob.specificRef, ReferencePtr]; IF Rope.Equal[rp.objectName, objectName] AND Rope.Equal[rp.designName, importeeName] THEN { IF ob.size=size OR allowConflicts=true THEN RETURN [ob] ELSE IF allowConflicts=interactive AND TerminalIO.UserSaysYes[ text: "size conflict\n", label: "ignore?" ] THEN RETURN [ob] ELSE RETURN [NIL] }; ENDLOOP; IF import.importee#NIL THEN { found: BOOL; referedOb: CD.Object; [found, referedOb] _ CDDirectory.Fetch[import.importee, objectName]; IF ~found THEN { IF autoCreateOb=false OR (autoCreateOb=interactive AND ~TerminalIO.UserSaysYes[ text: "object not found\n", label: "ignore?" ]) THEN RETURN [NIL]; } ELSE { IF allowConflicts=true THEN { probablySize _ referedOb.size; iR _ CD.InterestRect[referedOb]; }; } }; ob _ NEW[CD.ObjectRep_[ size: probablySize, class: pForReference, layer: CD.combined, specificRef: NEW[ReferenceRep _ [ objectName: objectName, ir: iR, designName: importeeName ]] ]]; import.referenceList _ CONS[ob, import.referenceList]; IF include THEN [] _ CDDirectory.Include[design: design, object: ob, alternateName: Rope.Cat[importeeName, ".", objectName]]; IF import.importee#NIL THEN [] _ BindReference[design, ob, import.importee, allowConflicts]; RETURN [ob] END; GetReference: PUBLIC PROC [design: CD.Design, objectName, importeeName: Rope.ROPE] RETURNS [ob: CD.Object] = BEGIN ob _ InternalCreateReference[design: design, objectName: objectName, importeeName: importeeName, autoCreateOb: false, autoImport: false, allowConflicts: true, include: TRUE]; END; ReferenceName: PROC [me: CD.Object] RETURNS [Rope.ROPE] = BEGIN n: Rope.ROPE = CDDirectory.Name[me]; IF Rope.IsEmpty[n] THEN { rp: ReferencePtr = NARROW[me.specificRef]; RETURN [Rope.Cat[rp.designName, ".", rp.objectName]] }; RETURN [n] END; ShortName: PROC [me: CD.Object, rp: ReferencePtr] RETURNS [Rope.ROPE] = INLINE BEGIN n: Rope.ROPE = CDDirectory.Name[me]; IF Rope.IsEmpty[n] THEN { RETURN [rp.objectName] }; RETURN [n] END; DescribeReference: PROC[me: CD.Object] RETURNS [Rope.ROPE] = BEGIN RETURN [Rope.Concat["reference to ", ReferenceName[me]]] END; DrawReference: PROC [inst: CD.Instance, pos: CD.Position, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN rp: ReferencePtr = NARROW[inst.ob.specificRef]; IF rp.boundInstance#NIL THEN { pr.drawChild[rp.boundInstance, pos, orient, pr]; } ELSE { r: CD.Rect = IntRect[inst.ob, pos, orient]; pr.drawRect[r, CD.highLightShade, pr]; pr.drawComment[r, ShortName[inst.ob, rp], pr]; } END; IntRect: PROC [ob: CD.Object, pos: CD.Position, orient: CD.Orientation] RETURNS [CD.Rect] = INLINE BEGIN RETURN [CDOrient.MapRect[ itemInCell: CD.InterestRect[ob], cellSize: ob.size, cellInstOrient: orient, cellInstPos: pos ]] END; QuickDrawReference: PROC [inst: CD.Instance, pos: CD.Position, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN rp: ReferencePtr = NARROW[inst.ob.specificRef]; IF rp.boundInstance#NIL THEN { rp.boundInstance.ob.class.quickDrawMe[rp.boundInstance, pos, orient, pr]; } ELSE { r: CD.Rect = IntRect[inst.ob, pos, orient]; pr.drawRect[r, CD.highLightShade, pr]; pr.drawComment[r, ShortName[inst.ob, rp], pr]; } END; DrawReferenceSelection: PROC [inst: CD.Instance, pos: CD.Position, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN rp: ReferencePtr = NARROW[inst.ob.specificRef]; IF rp.boundInstance#NIL THEN rp.boundInstance.ob.class.showMeSelected[rp.boundInstance, pos, orient, pr] ELSE pr.drawOutLine[IntRect[inst.ob, pos, orient], pr] END; InterestRect: PROC [ob: CD.Object] RETURNS [CD.Rect] = BEGIN RETURN [NARROW[ob.specificRef, ReferencePtr].ir] END; WriteRect: PROC[r: CD.Rect] = BEGIN TokenIO.WriteInt[r.x1]; TokenIO.WriteInt[r.y1]; TokenIO.WriteInt[r.x2]; TokenIO.WriteInt[r.y2]; END; ReadRect: PROC [] RETURNS [CD.Rect] = BEGIN r: CD.Rect; r.x1 _ TokenIO.ReadInt[]; r.y1 _ TokenIO.ReadInt[]; r.x2 _ TokenIO.ReadInt[]; r.y2 _ TokenIO.ReadInt[]; RETURN [r] END; WriteReference: CD.InternalWriteProc -- PROC [me: Object] -- = BEGIN rp: ReferencePtr = NARROW[me.specificRef]; TokenIO.WriteInt[me.size.x]; TokenIO.WriteInt[me.size.y]; WriteRect[rp.ir]; TokenIO.WriteRope[rp.objectName]; TokenIO.WriteRope[rp.designName]; END; ReadReference: CD.InternalReadProc --PROC [] RETURNS [Object]-- = BEGIN x: INT = TokenIO.ReadInt[]; y: INT = TokenIO.ReadInt[]; ir: CD.Rect; objectName: Rope.ROPE; importeeName: Rope.ROPE; ob: CD.Object; IF CDIO.VersionKey[] >= 8 THEN ir _ ReadRect[] ELSE ir _ CDBasics.RectAt[[0, 0], [x, y]]; objectName _ TokenIO.ReadRope[]; importeeName _ TokenIO.ReadRope[]; ob _ InternalCreateReference[ design: CDIO.DesignInReadOperation[], ir: ir, size: [x, y], objectName: objectName, autoCreateOb: true, importeeName: importeeName, autoImport: true, allowConflicts: interactive, include: FALSE ]; RETURN [ob] END; GetImportList: PUBLIC PROC [design: CD.Design] RETURNS [imp: REF ImportList] = BEGIN WITH CDValue.Fetch[boundTo: design, key: importListKey, propagation: design] SELECT FROM imp: REF ImportList => RETURN[imp]; ENDCASE => { imp _ NEW[ImportList _ [list: NIL]]; CDValue.Store[boundTo: design, key: importListKey, value: imp]; }; END; GetImport: PUBLIC PROC [design: CD.Design, importeeName: Rope.ROPE_NIL, createIfNotFound: BoolOrInteractive _ true] RETURNS [REF Import] = BEGIN ToBool: PROC[b: BoolOrInteractive, r: Rope.ROPE, default: BOOL_TRUE, r2: Rope.ROPE_NIL] RETURNS [BOOL] = BEGIN SELECT b FROM true => RETURN [TRUE]; false => RETURN [FALSE]; ENDCASE => { TerminalIO.WriteRope[r]; TerminalIO.WriteRope[r2]; RETURN [TerminalIO.UserSaysYes[r,, default]] } END; mdata: REF Import _ NIL; impl: REF ImportList = GetImportList[design]; IF Rope.IsEmpty[importeeName] THEN ERROR CD.Error[ec: other, explanation: "design has empty name, but shouldn't" ]; IF impl#NIL THEN FOR l: LIST OF REF Import _ impl.list, l.rest WHILE l#NIL DO IF l.first#NIL AND Rope.Equal[l.first.importeeName, importeeName] THEN RETURN [l.first] ENDLOOP; IF ToBool[createIfNotFound, "create an import", TRUE, importeeName] THEN { mdata _ NEW[Import _ [importeeName: importeeName, importee: NIL, referenceList: NIL]]; impl.list _ CONS[mdata, impl.list]; --atomic-- }; RETURN [mdata] END; BindImportee: PROC [importer, importee: CD.Design, allowSizeConflicts, allowOverload: BoolOrInteractive _ true] = BEGIN ENABLE TerminalIO.UserAbort => GOTO UserAborted; done1: BOOL_TRUE; mdata: REF Import = GetImport[importer, importee.name]; IF mdata=NIL THEN ERROR; IF mdata.importee#NIL THEN { IF allowOverload=false THEN RETURN ELSE IF allowOverload=interactive THEN IF NOT TerminalIO.UserSaysYes[ text: "design already loaded; shall overload?\n", label: "overload?"] THEN { TerminalIO.WriteRope["dont overload; not done\n"]; RETURN } }; mdata.importee _ importee; FOR list: LIST OF CD.Object _ mdata.referenceList, list.rest WHILE list#NIL DO done1 _ done1 AND BindReference[importer, list.first, mdata.importee, allowSizeConflicts].ok ENDLOOP; IF NOT done1 THEN TerminalIO.WriteRope["some import not bound\n"]; CDOps.DelayedRedraw[importer]; EXITS UserAborted => {TerminalIO.WriteRope["aborted, design not bound\n"]}; END; BindReference: PROC [design: CD.Design, reference: CD.Object, importee: CD.Design, allowSizeConflicts: BoolOrInteractive _ true] RETURNS [ok: BOOL_FALSE] = BEGIN ENABLE TerminalIO.UserAbort => GOTO UserAborted; rp: ReferencePtr = NARROW[reference.specificRef, ReferencePtr]; found: BOOL; oldRect, newRect: CD.Rect; referedOb: CD.Object; [found, referedOb] _ CDDirectory.Fetch[importee, rp.objectName]; IF NOT found THEN { TerminalIO.WriteRope["entry "]; TerminalIO.WriteRope[rp.objectName]; TerminalIO.WriteRope[" in "]; TerminalIO.WriteRope[importee.name]; TerminalIO.WriteRope[" not found\n"]; RETURN }; oldRect _ InterestRect[reference]; newRect _ CD.InterestRect[referedOb]; IF newRect#oldRect THEN { TerminalIO.WriteRope["object "]; TerminalIO.WriteRope[rp.objectName]; TerminalIO.WriteRope[" has different size; "]; IF CDBasics.SizeOfRect[oldRect]=CDBasics.SizeOfRect[newRect] THEN TerminalIO.WriteRope[" has different outer size; "] ELSE TerminalIO.WriteRope[" has different interest size; "]; IF allowSizeConflicts=false THEN { TerminalIO.WriteRope["not resolved\n"]; RETURN }; IF allowSizeConflicts=interactive THEN { IF ~TerminalIO.UserSaysYes[text: "import anyway? ", label: "import different sized ob?"] THEN { TerminalIO.WriteRope["no\n"]; RETURN }; TerminalIO.WriteRope["yes\n"]; }; }; rp.boundInstance _ CDInstances.NewInstance[ob: referedOb]; rp.boundInstance.location _ [0, 0]; BEGIN oldSize: CD.Position = reference.size; oldBase: CD.Position = CDBasics.BaseOfRect[oldRect]; newSize: CD.Position = referedOb.size; newBase: CD.Position = CDBasics.BaseOfRect[newRect]; IF oldSize#newSize OR oldRect#newRect THEN { reference.size _ newSize; rp.ir _ newRect; CDDirectory.RepositionObject[design: design, ob: reference, oldSize: oldSize, baseOff: CDBasics.SubPoints[oldBase, newBase] ]; }; END; ok _ TRUE; EXITS UserAborted => {TerminalIO.WriteRope["aborted, entry not replaced\n"]}; END; DoImport: PUBLIC PROC [design: CD.Design, importee: CD.Design, allowOverload, allowConflicts: BoolOrInteractive_true] RETURNS [done: BOOL_FALSE] = BEGIN indirectImport: REF ImportList ~ GetImportList[importee]; IF indirectImport^.list#NIL THEN TerminalIO.WriteRope["There are indirect imports\n"]; FOR list: LIST OF REF Import _ indirectImport^, list.rest WHILE list#NIL DO IF Rope.Equal[list.first.importeeName, design.name] THEN { TerminalIO.WriteRope["**creates circular imports\n"]; RETURN } ENDLOOP; BindImportee[importer: design, importee: importee, allowSizeConflicts: allowConflicts, allowOverload: allowOverload]; FOR list: LIST OF REF Import _ GetImportList[design]^, list.rest WHILE list#NIL DO IF list.first.importee#NIL THEN BindImportee[importer: list.first.importee, importee: importee, allowSizeConflicts: false, allowOverload: true]; ENDLOOP; FOR list: LIST OF REF Import _ indirectImport^, list.rest WHILE list#NIL DO IF list.first.importee=NIL THEN { imp: REF Import _ GetImport[design, list.first.importeeName, false]; IF imp#NIL AND imp.importee#NIL THEN BindImportee[importer: importee, importee: imp.importee, allowSizeConflicts: false, allowOverload: true]; } ENDLOOP; done _ TRUE; END; DesignHasBeenRenamed: CDEvents.EventProc --PROC [event: REF, design: CD.Design, x: REF] RETURNS [dont: BOOL_FALSE]-- = BEGIN imp: REF Import ~ GetImport[design: design, importeeName: design.name, createIfNotFound: false]; IF imp#NIL THEN { dont _ TRUE; TerminalIO.WriteRope["rename causes circularities; not done\n"] }; END; ReplaceChildrenByImports: PROC[me: CD.Object, design: CD.Design, importeeName: Rope.ROPE] = BEGIN replaceList: CDDirectory.ReplaceList_NIL; PerChild: CDDirectory.EnumerateObjectsProc --PROC [me: CD.Object, x: REF] -- = BEGIN IF me.class.inDirectory THEN { impChild: CD.Object; FOR list: CDDirectory.ReplaceList _ replaceList, list.rest WHILE list#NIL DO IF list.first.old=me THEN RETURN -- eliminate duplicates ENDLOOP; impChild _ InternalCreateReference[ design: design, objectName: CDDirectory.Name[me], importeeName: importeeName, size: me.size, autoImport: true, autoCreateOb: true, allowConflicts: true, include: TRUE ]; replaceList _ CONS[ NEW[CDDirectory.ReplaceRec_[ old: me, oldSize: me.size, new: impChild, newSize: impChild.size, off: [0, 0] ]], replaceList ]; } END; CDDirectory.EnumerateChildObjects[me: me, p: PerChild, x: NIL]; IF replaceList#NIL THEN [] _ CDDirectory.DoReplaceDirectChild[me: me, design: design, replace: replaceList]; END; OneLevelIncludedCopy: PUBLIC PROC [impObject: CD.Object, design: CD.Design] RETURNS [CD.Object] = BEGIN WITH impObject.specificRef SELECT FROM rp: ReferencePtr => { newOb: CD.Object; import: REF Import = GetImport[design, rp.designName, false]; IF rp.boundInstance=NIL OR import=NIL OR import.importee=NIL THEN ERROR CD.Error[callingError, "OneLevelIncludedCopy impObject not bound "]; newOb _ CDDirectory.Another[me: rp.boundInstance.ob, from: import.importee, to: design]; ReplaceChildrenByImports[me: newOb, design: design, importeeName: import.importeeName]; RETURN [newOb] }; ENDCASE => ERROR CD.Error[callingError, "OneLevelIncludedCopy impObject not reference"] END; Another: PROC [me: CD.Object, from, to: CD.Design] RETURNS [CD.Object] = BEGIN rp: ReferencePtr = NARROW[me.specificRef]; newOb: CD.Object = InternalCreateReference[design: to, objectName: rp.objectName, importeeName: rp.designName, autoCreateOb: true, autoImport: true, allowConflicts: true, include: TRUE, size: me.size]; newOb.properties _ CDProperties.AppendProps[looser: me.properties, winner: newOb.properties]; IF newOb=NIL THEN ERROR; RETURN [newOb]; END; MergeInImport: PUBLIC PROC [design: CD.Design, importeeName: Rope.ROPE] = BEGIN imp: REF Import _ GetImport[design, importeeName, false]; IF imp=NIL THEN { TerminalIO.WriteRope["MergeInImport not done; design "]; TerminalIO.WriteRope[importeeName]; TerminalIO.WriteRope[" is not imported\n"]; RETURN } ELSE IF imp.importee=NIL THEN { TerminalIO.WriteRope["MerginImport not done; design "]; TerminalIO.WriteRope[importeeName]; TerminalIO.WriteRope[" is not loaded\n"]; RETURN } ELSE { generatorTable: CDGenerate.Table; importee: CD.Design _ imp.importee; objectList: LIST OF CD.Object _ NIL; doList: LIST OF CD.Object _ NIL; dontList: LIST OF CD.Object _ NIL; CDRemote.CacheDesign[for: design, remote: imp.importee]; generatorTable _ CDRemote.GetTable[imp.importeeName]; FOR list: LIST OF CD.Object _ imp.referenceList, list.rest WHILE list#NIL DO IF NARROW[list.first.specificRef, ReferencePtr].boundInstance#NIL THEN doList _ CONS[list.first, doList] ELSE dontList _ CONS[list.first, dontList]; ENDLOOP; FOR list: LIST OF CD.Object _ doList, list.rest WHILE list#NIL DO pr: ReferencePtr = NARROW[list.first.specificRef]; newOb: CD.Object _ CDGenerate.FetchNCall[table: generatorTable, design: design, key: pr.objectName, cache: TRUE]; IF newOb#NIL THEN { CDDirectory.ReplaceObject[design: design, old: list.first, new: newOb]; [] _ CDDirectoryOps.RemoveObjectFromDirectory[design: design, ob: list.first]; } ELSE dontList _ CONS[list.first, dontList]; ENDLOOP; imp.referenceList _ dontList; } END; HasUnloadedImports: PUBLIC PROC [design: CD.Design] RETURNS [yes: BOOL_FALSE] = BEGIN impList: REF CDImports.ImportList = GetImportList[design]; IF impList#NIL THEN FOR list: LIST OF REF CDImports.Import _ impList^, list.rest WHILE list#NIL DO IF list.first.importee=NIL THEN { RETURN [yes _ TRUE] } ENDLOOP; END; OldSetInterest: PROC [ob: CD.Object, r: CD.Rect] = BEGIN cptr: ReferencePtr = NARROW[ob.specificRef]; cptr.ir _ r; END; Init: PROC [] = BEGIN rp: REF CDDirectory.DirectoryProcs ~ CDDirectory.InstallDirectoryProcs[pForReference]; rp.enumerateChildObjects _ EnumerateItsObjects; rp.replaceDirectChilds _ ReplaceDirectChild; rp.another _ Another; pForReference.drawMe _ DrawReference; pForReference.quickDrawMe _ QuickDrawReference; pForReference.showMeSelected _ DrawReferenceSelection; pForReference.internalRead _ ReadReference; pForReference.internalWrite _ WriteReference; pForReference.describe _ DescribeReference; pForReference.interestRect _ InterestRect; CDInterestRects.InstallOldSetInterest[pForReference, OldSetInterest]; CDValue.EnregisterKey[importListKey]; CDEvents.RegisterEventProc[$RenameDesign, DesignHasBeenRenamed]; END; Init[]; END. êCDImportsImpl.mesa (part of ChipNDale) Copyright c 1984, 1985 by Xerox Corporation. All rights reserved. by Christian Jacobi, March 20, 1984 5:50:51 pm PST last edited Christian Jacobi, August 29, 1985 4:37:42 pm PDT dont !!! rp: ReferencePtr ~ NARROW[me.specificRef]; IF rp.boundInstance#NIL THEN class[rp.boundInstance.ob, x]; -- PROC[me: CD.Object, design: CD.Design, replace: LIST OF REF ReplaceRec] -- dont, don't ERROR: don't ERROR, because the client doese not know that imports cannot be changed --search first for an already imported object object --already imported object has not been found; make import -- check for forbidden circular import -- no circular import --check already imported designs for importing the new design --check the new design for importing of already imported designs -- prevent a renaming which would cause circularity --build list of direct children --replace each direct child by an import --imp is an imported and bound object which will be made local to design --Includes all the imported and bound objects from importeeName (including --their transitive closure; but not indirect imports) into design. --split the reference list in bounded and not bounded --make includes for all bounded references Ê ˜šœ(™(Jšœ Ïmœ7™BJšœ3™3Jšœ<™Jšœ˜Jšœ˜Jšœžœžœ˜—Jšžœžœžœ˜—Jšœ˜—Jšžœ˜—Jšœ9™9šžœžœžœ˜Jšœžœ˜ Jšœ žœ˜JšœD˜Dšžœžœ˜šžœžœžœ˜OJšœ˜Jšœ˜Jšœžœžœžœ˜—J˜—šžœ˜šžœžœ˜Jšœ˜Jšœžœ˜ Jšœ˜—J˜—J˜—šœžœžœ ˜Jšœ˜Jšœ˜Jšœžœ ˜šœ žœ˜!Jšœ˜Jšœ˜Jšœ˜Jšœ˜—Jšœ˜—Jšœžœ˜6Jšžœ žœn˜}JšžœžœžœA˜\Jšžœ˜ Jšžœ˜—J˜š¡ œžœžœ žœ(žœžœžœ ˜lJšž˜Jšœ¨žœ˜®Jšžœ˜—Jšœ˜š ¡ œžœžœ žœžœ˜9Jšž˜Jšœžœ˜$šžœžœ˜Jšœžœ˜*Jšžœ.˜4J˜—Jšžœ˜ Jšžœ˜—J˜š ¡ œžœžœžœžœž˜NJšž˜Jšœžœ˜$šžœžœ˜Jšžœ˜J˜—Jšžœ˜ Jšžœ˜—J˜š ¡œžœžœ žœžœ˜=Jšž˜Jšžœ2˜8Jšžœ˜—J˜š ¡ œžœžœžœžœ ˜QJšœžœ ˜Jšž˜Jšœžœ˜/šžœžœžœ˜Jšœ0˜0J˜—šžœ˜Jšœžœ&˜+Jšœžœ˜&Jšœ.˜.J˜—Jšžœ˜J˜—š¡œžœžœžœžœžœžœ ž˜bJšž˜šžœ˜Jšœ ˜ Jšœ˜Jšœ˜Jšœ˜Jšœ˜—Jšžœ˜J˜—š ¡œžœžœžœžœ ˜VJšœžœ ˜Jšž˜Jšœžœ˜/šžœžœžœ˜JšœI˜IJ˜—šžœ˜Jšœžœ&˜+Jšœžœ˜&Jšœ.˜.J˜—Jšžœ˜J˜—š ¡œžœžœžœžœ ˜ZJšœžœ ˜Jšž˜Jšœžœ˜/šžœžœžœ˜JšœK˜K—šžœ˜Jšœ1˜1—Jšžœ˜—J˜š ¡ œžœžœ žœžœ˜6Jšž˜Jšžœžœ"˜0Jšžœ˜J˜—š¡ œžœžœ˜Jšž˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšžœ˜—J˜š¡œžœžœžœ˜%Jšž˜Jšœžœ˜ J˜J˜J˜J˜Jšžœ˜ Jšžœ˜—J˜codeš¡œžœ œ˜>Jšž˜Jšœžœ˜*Jšœ˜Jšœ˜Jšœ˜Jšœ!˜!Jšœ!˜!Jšžœ˜—J˜šŸ œžœ œ˜AJšž˜Jšœžœ˜Jšœžœ˜Jšœžœ˜ Jšœžœ˜Jšœžœ˜Jšœžœž˜Jšžœžœžœ˜/Jšžœ&˜*Jšœ ˜ Jšœ"˜"šœ˜Jšœžœ˜&Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ žœ˜Jšœ˜—Jšžœ˜ Jšžœ˜—J˜š ¡ œžœžœ žœ žœžœ˜NJšž˜šžœIžœž˜XJšœžœžœ˜#šžœ˜ Jšœžœžœ˜$Jšœ?˜?J˜——Jšžœ˜—J˜š¡ œžœžœ žœžœžœ.žœžœ ˜ŠJšž˜J˜š¡œžœžœ žœžœ žœžœžœžœ˜hJšž˜šžœž˜ Jšœžœžœ˜Jšœ žœžœ˜šžœ˜ Jšœ˜Jšœ˜Jšžœ&˜,J˜——Jšžœ˜—J˜Jšœžœ žœ˜Jšœžœ$˜-šžœžœžœžœ˜=Jšœ3˜3Jšœ˜—šžœžœž˜š žœžœžœžœžœžœž˜˜>šž˜Jšžœžœ ˜0—Jšœžœžœ˜Jšœžœ-˜7Jšžœžœžœžœ˜šžœžœžœ˜Jšžœžœž˜"šžœžœž˜&šžœžœ˜Jšœ2˜2šœžœ˜Jšœ2˜2Jšžœ˜J˜———J˜—Jšœ˜š žœžœžœžœ)žœžœž˜NJšœžœK˜\Jšžœ˜—Jšžœžœžœ1˜BJšœ˜šž˜JšœE˜E—Jšžœ˜—J˜š¡ œžœ žœžœžœ7žœžœžœ˜›šž˜Jšžœžœ ˜0—Jšœžœ&˜?Jšœžœ˜ Jšœžœ˜Jšœ žœ˜Jšœ@˜@šžœžœžœ˜Jšœ˜Jšœ$˜$Jšœ˜Jšœ$˜$Jšœ%˜%Jšž˜J˜—Jšœ"˜"Jšœ%˜%šžœžœ˜Jšœ ˜ Jšœ$˜$Jšœ.˜.šžœ;žœ˜BJšœ3˜3—šžœ˜Jšœ7˜7—šžœžœ˜"Jšœ'˜'Jšž˜J˜—šžœ žœ˜(šžœ2˜4šœ%žœ˜+Jšœ˜Jšž˜Jšœ˜——Jšœ˜Jšœ˜—J˜—Jšœ:˜:Jšœ#˜#šž˜Jšœ žœ˜&Jšœ žœ)˜4Jšœ žœ˜&Jšœ žœ)˜4šžœžœžœ˜,Jšœ˜Jšœ˜šœ,˜,Jšœ˜Jšœ˜Jšœ-˜-Jšœ˜—J˜—Jšžœ˜—Jšœžœ˜ šž˜JšœG˜G—Jšžœ˜—J˜š Ðbnœžœžœ žœžœ˜>Jšœ7žœžœžœ˜TJšž˜Jšœžœ'˜:Jšžœžœžœ6˜VJšœ&™&š žœžœžœžœ%žœžœž˜Kšžœ2žœ˜:Jšœ5˜5Jšž˜Jšœ˜—Jšžœ˜ —Jšœ™Jšœu˜uJšœ=™=š žœžœžœžœ,žœžœž˜Ršžœžœž˜Jšœp˜p—Jšžœ˜ —Jšœ@™@š žœžœžœžœ%žœžœž˜Kšžœžœžœ˜!Jšœžœ<˜Dš žœžœžœžœž˜$Jšœi˜i—J˜—Jšžœ˜ —Jšœžœ˜ Jšžœ˜—J˜šŸœ˜)Jš žœ žœ žœ žœžœžœžœ œ˜MJšœ3™3Jšž˜JšœžœX˜`šžœžœžœ˜Jšœžœ˜ Jšœ?˜?J˜—Jšžœ˜—J˜š ¡œžœžœžœžœ˜[Jšž˜Jšœ%žœ˜)J˜šŸœ# !œ˜NJšž˜šžœžœ˜Jšœ žœ˜šžœ8žœžœž˜LJšžœžœž ˜8Jšžœ˜ —šœ#˜#JšœM˜MJšœTž˜XJšœ˜—šœžœ˜šžœ˜Jšœ ˜ Jšœ˜Jšœ˜Jšœ˜Jšœ ˜ Jšœ˜—Jšœ ˜ Jšœ˜—J˜—Jšžœ˜—J™Jšœ™Jšœ:žœ˜?Jšœ(™(šžœ žœžœ˜JšœT˜T—Jšžœ˜—J˜š¡œžœžœ žœžœ žœžœ ˜aJšœH™HJšž˜šžœžœž˜&šœ˜Jšœžœ˜Jšœžœ2˜=šžœžœžœžœžœžœžœ˜BJšžœžœB˜J—JšœX˜XJšœW˜WJšžœ˜J˜—JšžœžœžœD˜W—Jšžœ˜—J˜š ¡œžœžœžœ žœžœ ˜HJšž˜Jšœžœ˜*Jšœžœ«žœ˜ÉJšœ]˜]Jšžœžœžœž˜Jšžœ ˜Jšžœ˜—J˜š ¡ œžœžœ žœžœ˜IJšœL™LJšœB™BJšž˜Jšœžœ1˜9šžœžœžœ˜Jšœ8˜8Jšœ#˜#Jšœ+˜+Jšž˜J˜—šžœžœžœžœ˜Jšœ7˜7Jšœ#˜#Jšœ)˜)Jšž˜J˜—šžœ˜Jšœ!˜!Jšœ žœ˜$Jš œ žœžœžœ žœ˜$Jš œžœžœžœ žœ˜ Jš œ žœžœžœ žœ˜"Jšœ8˜8Jšœ5˜5Jšœ5™5š žœžœžœžœ'žœžœž˜Lšžœžœ5žœžœ˜GJšœ žœ˜!—Jšžœ žœ˜+Jšžœ˜—Jšœ,™,š žœžœžœžœžœžœž˜AJšœžœ˜2Jšœžœbžœ˜qšžœžœžœ˜JšœG˜GJšœN˜NJ˜—Jšžœ žœ˜+Jšžœ˜—Jšœ˜J˜—Jšžœ˜—J˜š ¡œž œ žœ žœžœžœ˜OJšž˜Jšœ žœ.˜:šžœ žœž˜š žœžœžœžœ(žœžœž˜Nšžœžœžœ˜!Jšžœžœ˜J˜—Jšžœ˜——Jšžœ˜—J˜š¡œžœžœ žœ˜2Jšž˜Jšœžœ˜,Jšœ ˜ Jšžœ˜J˜—š¡œžœ˜Jšž˜JšœžœO˜VJšœ/˜/Jšœ,˜,Jšœ˜Jšœ%˜%Jšœ/˜/Jšœ6˜6Jšœ+˜+Jšœ-˜-Jšœ+˜+Jšœ*˜*JšœE˜EJšœ%˜%J˜@Jšžœ˜—J˜J˜Jšžœ˜J˜—…—C6_*