DIRECTORY CD, CDCells, CDDirectory, CDInstances, CDMenus, CDOps, CDProperties, CDRects, CDSequencer, CDViewer, CDViewHighlight, Core, CoreClasses, CoreOps, CoreProperties, HashTable, IO, Rope, Sinix, SinixHighlight, TerminalIO, ViewerClasses; SinixHighlightImpl: CEDAR PROGRAM IMPORTS CDCells, CDDirectory, CDInstances, CDMenus, CDOps, CDProperties, CDRects, CDViewer, CDViewHighlight, CoreClasses, CoreOps, CoreProperties, HashTable, IO, Sinix, TerminalIO EXPORTS SinixHighlight = BEGIN OPEN Core, SinixHighlight; WireSet: TYPE ~ Core.Wires; inboundProp: ATOM _ CoreProperties.RegisterProperty[$SinixInBinding, CoreProperties.Props[[CoreProperties.propPrint, CoreProperties.PropDontPrint]]]; outboundProp: ATOM _ CoreProperties.RegisterProperty[$SinixOutBinding, CoreProperties.Props[[CoreProperties.propPrint, CoreProperties.PropDontPrint]]]; AddWireToSet: PROC [w: Wire, set: WireSet] RETURNS [WireSet] ~ INLINE { RETURN [IF CoreOps.Member[set, w] THEN set ELSE CONS[w, set]]; }; MergeWiresSets: PROC [set, into: WireSet] RETURNS [WireSet]~ { WHILE set#NIL DO into _ AddWireToSet[set.first, into]; set _ set.rest; ENDLOOP; RETURN [into]; }; FlattenWires: PROC [in: WireSet] RETURNS [out: WireSet _ NIL] ~ { ForEachAtomicWire: PROC [wire: Wire] ~ { out _ AddWireToSet[wire, out]; }; WHILE in#NIL DO wire: Wire = in.first; IF wire.size=0 THEN out _ AddWireToSet[wire, out] ELSE [] _ CoreOps.VisitAtomicWires[wire, ForEachAtomicWire]; in _ in.rest; ENDLOOP; }; FindParents: PROC [set: WireSet, root: Wire] RETURNS [parents: WireSet _ NIL] ~ { AddIfParent: PROC [wire: Wire] RETURNS [isParent: BOOL _ FALSE] ~ { IF wire.size=0 THEN RETURN [CoreOps.Member[set, wire]]; FOR i: INT IN [0 .. wire.size) DO IF AddIfParent[wire.elements[i]] THEN isParent _ TRUE; ENDLOOP; IF isParent THEN parents _ AddWireToSet[wire, parents]; }; [] _ AddIfParent[root]; }; CreateBindingTables: PROC [inst: CoreClasses.CellInstance] RETURNS [inBound, outBound: HashTable.Table] ~ { EachPair: CoreOps.EachWirePairProc ~ { wires: Wires; [] _ HashTable.Insert[table: outBound, key: publicWire, value: actualWire]; wires _ NARROW [HashTable.Fetch[table: inBound, key: actualWire].value]; IF NOT CoreOps.Member[wires, actualWire] THEN wires _ CONS [publicWire, wires]; [] _ HashTable.Store[table: inBound, key: actualWire, value: wires]; }; actual: Wire = inst.actual; public: Wire = inst.type.public; inBound _ HashTable.Create[]; outBound _ HashTable.Create[]; FOR i: NAT IN [0 .. actual.size) DO [] _ CoreOps.VisitBinding[actual: actual.elements[i], public: public.elements[i], eachWirePair: EachPair]; ENDLOOP; CoreProperties.PutCellInstanceProp[on: inst, prop: inboundProp, value: inBound]; CoreProperties.PutCellInstanceProp[on: inst, prop: outboundProp, value: outBound]; }; WireSetIntoInstance: PROC [out: WireSet, inst: CoreClasses.CellInstance] RETURNS [in: WireSet _ NIL] ~ { table: HashTable.Table _ NARROW [CoreProperties.GetCellInstanceProp[from: inst, prop: inboundProp]]; IF table=NIL THEN table _ CreateBindingTables[inst].inBound; WHILE out#NIL DO found: BOOLEAN; binding: HashTable.Value; [found, binding] _ HashTable.Fetch[table: table, key: out.first]; IF found THEN FOR wires: Wires _ NARROW[binding], wires.rest WHILE wires#NIL DO in _ AddWireToSet[wires.first, in]; ENDLOOP; out _ out.rest; ENDLOOP; }; WireSetFromInstance: PROC [in: WireSet, inst: CoreClasses.CellInstance] RETURNS [out: WireSet _ NIL] ~ { table: HashTable.Table _ NARROW [CoreProperties.GetCellInstanceProp[from: inst, prop: outboundProp]]; IF table=NIL THEN table _ CreateBindingTables[inst].outBound; WHILE in#NIL DO found: BOOLEAN; binding: HashTable.Value; [found, binding] _ HashTable.Fetch[table: table, key: in.first]; IF found THEN out _ AddWireToSet[NARROW[binding], out]; in _ in.rest; ENDLOOP; }; SameCDInstance: PROC [i,j: CD.Instance] RETURNS [BOOL] ~ INLINE { RETURN [i.ob=j.ob AND i.location=j.location AND i.orientation=j.orientation] }; RelocateInInstance: PROC [inInst, outInst: CD.Instance] RETURNS [CD.Instance] ~ { RETURN [CDInstances.DeComposed[inst: inInst, cellPos: outInst.location, cellSize: outInst.ob.size, cellOrient: outInst.orientation]]; }; InstanceInRecordCell: PROC [in, out: CD.Instance, mode: Sinix.Mode] RETURNS [coreInst: CoreClasses.CellInstance _ NIL, cell: CellType _ NIL] ~ { record: CoreClasses.RecordCellType; wire: Wire; category: ATOM; [cell, wire, category] _ Extract[out.ob, mode]; IF cell=NIL OR cell.class#CoreClasses.recordCellClass THEN BEGIN TerminalIO.WriteF["*** Cell %g does not extract to record cell\n", IO.rope[CDDirectory.Name[out.ob]]]; RETURN; END; record _ NARROW [cell.data]; FOR i: INT IN [0 .. record.size) DO possibleInst: CD.Instance = Sinix.GetInstanceTransformationProp[mode, record[i]]; IF SameCDInstance[possibleInst, in] THEN {coreInst _ record[i]; EXIT}; ENDLOOP; }; Extract: PROC [obj: CD.Object, mode: Sinix.Mode] RETURNS [cellType: CellType _ NIL, wire: Wire _ NIL, category: ATOM _ $Device] ~ { ref: REF _ CDProperties.GetObjectProp[obj, mode.cacheProp]; WITH ref SELECT FROM ct: CellType => cellType _ ct; w: Wire => {wire _ w; category _ $Wire}; ENDCASE => ERROR; }; HighLightOb: PROC [ob: CD.Object] RETURNS [hob: CD.Object] = { SELECT ob.class.objectType FROM $Rect => hob _ CDRects.CreateRect[ob.size, CD.shadeLayer]; $Cell => { cellPtr, hcellPtr: CD.CellPtr; hob _ CDCells.CreateEmptyCell[]; cellPtr _ NARROW [ob.specificRef]; hcellPtr _ NARROW [hob.specificRef]; hcellPtr.contents _ HighLightListInst[cellPtr.contents]; hob.size _ ob.size; }; ENDCASE => { hob _ CDDirectory.Expand[ob, NIL, NIL].new; IF hob=NIL THEN RETURN[CDRects.CreateRect[ob.size, CD.undefLayer]]; hob _ HighLightOb[hob]; }; }; HighLightInst: PROC [inst: CD.Instance] RETURNS [hinst: CD.Instance] = { hinst _ NEW [CD.InstanceRep _ [ ob: IF inst.ob.class.objectType=$PinOb0 THEN CDRects.CreateRect[inst.ob.size, CD.shadeLayer] ELSE HighLightOb[inst.ob], location: inst.location, orientation: inst.orientation]]; }; HighLightListInst: PROC [instances: LIST OF CD.Instance] RETURNS [hlist: LIST OF CD.Instance _ NIL] = { WHILE instances#NIL DO hlist _ CONS[HighLightInst[instances.first], hlist]; instances _ instances.rest; ENDLOOP; }; CreateHighlightInstance: PROC [hinsts: CD.InstanceList, in: CD.Instance] RETURNS [highlight: CD.Instance _ NIL] ~ { IF hinsts#NIL THEN BEGIN hob: CD.Object _ CDCells.CreateEmptyCell[]; hcellPtr: CD.CellPtr _ NARROW [hob.specificRef]; hob.size _ in.ob.size; hcellPtr.contents _ hinsts; hcellPtr.simplifyOn _ 0.0; highlight _ NEW [CD.InstanceRep _ [ob: hob, location: in.location, orientation: in.orientation, properties: NIL]]; END; }; SelectedInstancesInTopPushedInstance: PROC [design: CD.Design] RETURNS [selectedList: CD.InstanceList _ NIL] ~ { closed: CD.Instance = design.actual.first.mightReplace; open: CD.Instance = design.actual.first.dummyCell; IF design.actual.rest=NIL THEN RETURN; FOR list: CD.InstanceList _ NARROW [open.ob.specificRef, CD.CellPtr].contents, list.rest WHILE list#NIL DO IF list.first.selected THEN selectedList _ CONS [RelocateInInstance[list.first, closed], selectedList]; ENDLOOP; }; SelectedWires: PROC [mode: Sinix.Mode, design: CD.Design] RETURNS [cellType: CellType, wires: WireSet] ~ { top: CD.Instance = design.actual.first.mightReplace; wireList: WireSet _ NIL; dummyWire: Wire; dummyCellType: CellType; category: ATOM; rec: CoreClasses.RecordCellType; [cellType, dummyWire, category] _ Extract[top.ob, mode]; IF cellType=NIL OR cellType.class#CoreClasses.recordCellClass THEN BEGIN TerminalIO.WriteF["*** Extraction must return a record cell\n"]; RETURN; END; rec _ NARROW [cellType.data]; FOR selectedList: CD.InstanceList _ SelectedInstancesInTopPushedInstance[design], selectedList.rest WHILE selectedList#NIL DO [dummyCellType, dummyWire, category] _ Extract[selectedList.first.ob, mode]; SELECT category FROM $Wire => BEGIN -- Relocate the wire geometry inside the instance, connect to internals TouchesWire: CoreOps.EachWireProc ~ { FOR client: CD.InstanceList _ Sinix.GetWireGeometryProp[mode,wire], client.rest WHILE client#NIL DO FOR list: CD.InstanceList _ target, list.rest WHILE list#NIL DO IF SameCDInstance[list.first, client.first] THEN { wireList _ AddWireToSet[wire, wireList]; RETURN [quit: TRUE]; }; ENDLOOP; ENDLOOP; }; target: CD.InstanceList _ CDInstances.ComposedList[ il: NARROW [Sinix.GetPinsProp[mode, dummyWire]], cellPos: selectedList.first.location, cellSize: selectedList.first.ob.size, cellOrient: selectedList.first.orientation]; [] _ CoreOps.VisitWire[rec.internal, TouchesWire]; END; $Device => BEGIN -- Add all the actuals to the list of selected wires sel: CoreClasses.CellInstance; cell: CellType; [sel, cell] _ InstanceInRecordCell[in: selectedList.first, out: top, mode: mode]; IF sel#NIL THEN FOR i: NAT IN [0 .. sel.actual.size) DO wireList _ AddWireToSet[sel.actual.elements[i], wireList]; ENDLOOP; END; ENDCASE => {}; ENDLOOP; wires _ FlattenWires[wireList]; }; HighlightWires: PROC [wires: WireSet, hinsts: CD.InstanceList, mode: Sinix.Mode] RETURNS [CD.InstanceList] ~ { WHILE wires#NIL DO FOR l: CD.InstanceList _ Sinix.GetWireGeometryProp[mode, wires.first], l.rest WHILE l#NIL DO hinsts _ CONS [HighLightInst[l.first], hinsts]; ENDLOOP; wires _ wires.rest; ENDLOOP; RETURN [hinsts]; }; HighlightPins: PROC [wires: WireSet, hinsts: CD.InstanceList, mode: Sinix.Mode] RETURNS [CD.InstanceList] ~ { WHILE wires#NIL DO FOR l: CD.InstanceList _ Sinix.GetPinsProp[mode, wires.first], l.rest WHILE l#NIL DO hinsts _ CONS [HighLightInst[l.first], hinsts]; ENDLOOP; wires _ wires.rest; ENDLOOP; RETURN [hinsts]; }; HighlightWiresDownwards: PROC [cdInst: CD.Instance, cell: CellType, wires: WireSet, except: CoreClasses.CellInstance _ NIL, hinsts: CD.InstanceList _ NIL, mode: Sinix.Mode] RETURNS [highlight: CD.Instance _ NIL] ~ { IF wires#NIL THEN DO SELECT cell.class FROM CoreClasses.recordCellClass => { rec: CoreClasses.RecordCellType _ NARROW[cell.data]; FOR i: NAT IN [0 .. rec.size) DO coreInst: CoreClasses.CellInstance = rec.instances[i]; IF coreInst#except THEN BEGIN highlight: CD.Instance = HighlightWiresDownwards[ cdInst: Sinix.GetInstanceTransformationProp[mode, coreInst], cell: coreInst.type, wires: WireSetIntoInstance[wires, coreInst], mode: mode]; IF highlight#NIL THEN hinsts _ CONS[highlight, hinsts]; END; ENDLOOP; hinsts _ HighlightWires[wires, hinsts, mode]; hinsts _ HighlightWires[FindParents[wires, rec.internal], hinsts, mode]; EXIT; }; CoreClasses.transistorCellClass, CoreClasses.identityCellClass => { hinsts _ HighlightPins[wires, hinsts, mode]; EXIT; }; ENDCASE => cell _ CoreOps.Recast[cell]; ENDLOOP; highlight _ CreateHighlightInstance[hinsts, cdInst]; }; HighlightWiresUpwards: PROC [stack: LIST OF CD.PushRec, cell: CellType, wires: WireSet, mode: Sinix.Mode] RETURNS [highlight: CD.Instance] ~ { HighlightContext: TYPE ~ REF HighlightContextRep; HighlightContextRep: TYPE ~ RECORD [ from: CoreClasses.CellInstance, in: CD.Instance, cell: CellType, wires: WireSet]; request, initialRequest: LIST OF HighlightContext; currentInst: CD.Instance _ stack.first.mightReplace; stack _ stack.rest; initialRequest _ LIST [NEW[HighlightContextRep _ [NIL, currentInst, cell, wires]]]; WHILE stack.rest#NIL DO previousInst: CD.Instance = currentInst; previousCoreInst: CoreClasses.CellInstance; currentInst _ stack.first.mightReplace; [previousCoreInst, cell] _ InstanceInRecordCell[ in: RelocateInInstance[previousInst, currentInst], out: currentInst, mode: mode]; IF previousCoreInst=NIL THEN RETURN [NIL]; wires _ WireSetFromInstance[wires, previousCoreInst]; initialRequest _ CONS [ NEW[HighlightContextRep _ [previousCoreInst, currentInst, cell, wires]], initialRequest]; stack _ stack.rest; ENDLOOP; request _ NIL; wires _ NIL; WHILE initialRequest#NIL DO currentRequest: HighlightContext = initialRequest.first; IF wires#NIL THEN currentRequest.wires _ MergeWiresSets[wires, currentRequest.wires]; request _ CONS [currentRequest, request]; wires _ IF currentRequest.from#NIL THEN WireSetIntoInstance[currentRequest.wires, currentRequest.from] ELSE NIL; initialRequest _ initialRequest.rest; ENDLOOP; highlight _ HighlightWiresDownwards[cdInst: request.first.in, cell: request.first.cell, wires: request.first.wires, mode: mode]; request _ request.rest; WHILE request#NIL DO highlight _ HighlightWiresDownwards[ cdInst: request.first.in, cell: request.first.cell, wires: request.first.wires, mode: mode, except: request.first.from, hinsts: LIST [RelocateInInstance[highlight, request.first.in]]]; request _ request.rest; ENDLOOP; }; ExtractOuterInstance: PROC [design: CD.Design, context: ExtractContext] RETURNS [BOOL] ~ { result: REF; extractibleInstance: CD.Instance _ NIL; FOR stack: LIST OF CD.PushRec _ design.actual, stack.rest WHILE stack.rest#NIL DO IF stack.first.changed THEN { TerminalIO.WriteF["*** Impossible to highlight, cell %g has been changed and not saved\n", IO.rope[CDDirectory.Name[stack.first.mightReplace.ob]]]; RETURN [TRUE]; }; extractibleInstance _ stack.first.mightReplace; ENDLOOP; IF extractibleInstance=NIL THEN { TerminalIO.WriteF["*** No currently pushed-in cell\n"]; RETURN[TRUE]; }; [result] _ Sinix.Extract[ obj: extractibleInstance.ob, mode: context.mode, properties: extractibleInstance.properties, userData: context.userData]; IF NOT ISTYPE [result, CellType] THEN BEGIN TerminalIO.WriteF["*** Top cell does not extract to device\n"]; RETURN[TRUE]; END; RETURN[FALSE]; }; GetExtractContext: PROC [command: CDSequencer.Command] RETURNS [ExtractContext] ~ { contextCreator: REF ExtractContextCreator; contextCreator _ NARROW [CDProperties.GetProp[command.design.technology, command.key]]; IF contextCreator=NIL THEN contextCreator _ NARROW [CDProperties.GetProp[$Context, command.key]]; RETURN [IF contextCreator#NIL THEN contextCreator^[command.design] ELSE NIL] }; DeepHighLightSelected: PROC [command: CDSequencer.Command] ~ { highlight: CD.Instance; context: ExtractContext; selWires: WireSet; inCell: CellType; mode: Sinix.Mode; context _ GetExtractContext[command]; IF context=NIL THEN BEGIN TerminalIO.WriteF["*** Command not supported for this technology\n"]; RETURN; END; mode _ context.mode; IF ExtractOuterInstance[command.design, context] THEN RETURN; [inCell, selWires] _ SelectedWires[mode, command.design]; IF selWires=NIL THEN BEGIN TerminalIO.WriteF["*** No wires selected\n"]; RETURN; END; highlight _ HighlightWiresUpwards[command.design.actual, inCell, selWires, mode]; IF highlight#NIL THEN FOR viewers: LIST OF ViewerClasses.Viewer _ CDViewer.ViewersOf[command.design], viewers.rest WHILE viewers#NIL DO CDViewHighlight.ShowInstance[viewers.first, highlight]; ENDLOOP; }; ExtractSelected: PROC [command: CDSequencer.Command] = { context: ExtractContext; first: CD.Instance; multiple: BOOL; result: REF; context _ GetExtractContext[command]; [first, multiple] _ CDOps.SelectedInstance[command.design]; IF multiple THEN {TerminalIO.WriteF["Multiple instances selected. No action.\n"]; RETURN}; IF first=NIL THEN {TerminalIO.WriteF["No instance selected. No action.\n"]; RETURN}; [result] _ Sinix.Extract[first.ob, context.mode, first.properties, context.userData]; IF result=NIL THEN TerminalIO.WriteF["*** Extraction returned NIL\n"] ELSE CoreOps.Print[result, TerminalIO.TOS[]]; }; RegisterOtherProgramWithContext: PROC [program: PROC [CDSequencer.Command], technology: CD.Technology, contextCreator: ExtractContextCreator, prompt: Rope.ROPE, key: ATOM] ~ { [] _ CDProperties.RegisterProperty[key, $HighlightProperty]; CDProperties.PutProp[IF technology#NIL THEN technology ELSE $Context, key, NEW [ExtractContextCreator _ contextCreator]]; CDMenus.ImplementEntryCommand[menu: $OtherProgramMenu, entry: prompt, p: program, key: key, technology: technology]; }; RegisterHighlightCommand: PUBLIC PROC [technology: CD.Technology _ NIL, contextCreator: ExtractContextCreator, prompt: Rope.ROPE, key: ATOM] ~ { RegisterOtherProgramWithContext[DeepHighLightSelected, technology, contextCreator, prompt, key]; }; RegisterExtractCommand: PUBLIC PROC [technology: CD.Technology _ NIL, contextCreator: ExtractContextCreator, prompt: Rope.ROPE, key: ATOM] ~ { RegisterOtherProgramWithContext[ExtractSelected, technology, contextCreator, prompt, key]; }; RegisterDefaultLayoutMode: PUBLIC PROC [technology: CD.Technology, contextCreator: ExtractContextCreator] ~ { IF technology=NIL THEN ERROR; RegisterExtractCommand[technology, contextCreator, "Extract layout", $ExtractLayout]; RegisterHighlightCommand[technology, contextCreator, "Highlight net in layout", $HighlightNetInLayout]; }; END. LSinixHighlightImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Jean-Marc Frailong May 30, 1986 11:00:50 pm PDT Bertrand Serlet June 1, 1986 3:42:11 pm PDT Wire utilities Add a wire to a set of wires. Merge a set of wires into another set of wires Return all the atomic wires referred to in the set uniquely Enumerate the parents relative to root of all elements of the list Create the hash tables that gives the match from actual to public and back. The wires are assumed to match... Propagate a set of wires into a core instance Propagate a set of wires from a core instance CD coordinates utilities Check that two CD instances are logically the same Given inInst and outInst in world coordinates, return instance of inInst if it were in outInst. The basics code for this is found in CDInstances.DeComposed Links between Core and ChipNDale Given in, an instance in out, recover the celltype for out and the right instance for in in it. This is a local version of Sinix.Extract that always gets value from the cache, as the top cell is supposed to have been extracted. Generation of highlighted objects Convert object to highlighted object Convert instance to highlighted instance Convert instance list to highlighted instance list Create a single object relative to an instance that contains a list of highlighted instances Locating selected things Return all instances that are selected in the topmost pushed-in instance, in its local reference frame. Actually, only a copy of the instances is returned as cells pushed-in change their coordinate system in CD... If the cell has been modified, you may get garbage. For all the selected instances in the currently pushed-in CD instance, find all wires that touch and return the set. For instances that extract to wire, explore against all wires internal to the cell to find the matching ones. For instances that extract to a device, include all the actuals for the instance. Highlight wires top-down Add to hinsts the highlight for all the requested wires, return new highlight list. Add to hinsts the highlight for all the requested pins, return new highlight list. Return a CD Instance that is a highlight for the given list of wires in the cellType, which is exactly the extraction of the cdInst. Everything is explored downwards, except for the special instance cell from which the net originated (if applicable). Hinsts is a list of pre-built highlighted instances to be included in the final object. The CD instance is used to remap the highlighted object at the right location. -- Highlight in included cells -- Highlight atomic wires -- Highlight parents in record cell Propagate selected wires to the top and highlight Given the stack and a list of wires in the topmost cell, highlight locally then proceed upwards to obtain finally the completely highlighted net. As wire connectivity is computed by Sinix only on a bottom-up basis, bottom-up exploration does not work straightforwardly: wires that are connected only through an enclosing cell will not be detected correctly! Hence, the process consists of computing wire propagation to the top, then going down to merge propagations downwards, finally redisplaying up... First, build initialRequest by unwinding the CD stack Now, build request from initialRequest by propagating wires down again Finally, do the highlighting from request The real thing Go up the stack, extract the topmost instance. From now on, refer to extraction only by using the cache... Return TRUE if in error, FALSE if all is OK. Recover the extract context from the technology, or from the key if not found in technology. Registration Κί˜– "Cedar" stylešœ™Icode– "Cedar" stylešœ Οmœ1™K˜—K˜K™.šŸœžœžœ ˜>šžœžœž˜Kšœ%˜%Kšœ˜Kšžœ˜—Kšžœ˜Kšœ˜—K™Kšœ;™;šŸ œžœžœžœ˜AKšŸœžœ3˜Jšžœžœž˜K˜Kšžœ žœ˜1Kšžœ8˜šžœž˜Jšœ,žœ ˜;šœ ˜ Jšœžœ ˜Jšœ ˜ Jšœ žœ˜"Jšœ žœ˜$Jšœ8˜8Jšœ˜J˜—šžœ˜ Jšœžœžœ˜+Jš žœžœžœžœžœ˜CJšœ˜J˜——J˜—J˜J™)š Ÿ œžœžœ žœ žœ˜Hšœžœžœ˜Jš œžœ"žœ"žœ žœ˜yJšœ9˜9—J˜—J˜J™4šŸœžœ žœžœžœ žœ žœžœžœ žœ˜gšžœ žœžœ˜JšœžœE˜QJšžœ˜—J˜—K˜K™\šŸœžœ žœžœ žœ žœ žœ˜sšžœžœžœž˜Kšœžœ$˜+Jšœ žœ žœ˜0Jšœ˜Jšœ˜Jšœ˜Jšœ žœžœYžœ˜rKšžœ˜—K˜——™K™‰š Ÿ$œžœ žœ žœžœžœ˜pKšœžœ-˜7Kšœžœ*˜2Kšžœžœžœžœ˜&š žœžœžœžœžœžœž˜jšžœž˜Kšœžœ8˜K—Kšžœ˜—K˜—K˜Jšœ΄™΄šŸ œžœžœ žœ)˜jKšœžœ-˜4Kšœžœ˜Kšœ4žœ˜:Kšœ ˜ Kšœ8˜8š žœ žœžœ,žœž˜HKšœ@˜@Kšžœ˜Kšžœ˜—Kšœžœ˜š žœžœPžœžœž˜}KšœL˜Lšžœ ž˜šœ žœΟcG˜VšŸ œ˜%š žœ žœBžœžœž˜cš žœžœ"žœžœž˜?šžœ*žœ˜2Kšœ(˜(Kšžœžœ˜K˜—Kšžœ˜—Kšžœ˜—K˜—šœžœ)˜3Kšœžœ&˜0Kšœ%˜%Kšœ%˜%Kšœ,˜,—Kšœ2˜2Kšžœ˜—šœ žœ 4˜EKšœ˜Kšœ˜KšœQ˜Qš žœžœžœžœžœžœž˜7Kšœ:˜:Kšžœ˜—Kšžœ˜—Kšžœ˜—Kšžœ˜—Kšœ˜K˜——™K™Sš Ÿœžœžœ!žœžœ˜nšžœžœž˜š žœžœEžœžœž˜\Kšœ žœ"˜/Kšžœ˜—K˜Kšžœ˜—Kšžœ ˜K˜K˜—K™Rš Ÿ œžœžœ!žœžœ˜mšžœžœž˜š žœžœ=žœžœž˜TKšœ žœ"˜/Kšžœ˜—K˜Kšžœ˜—Kšžœ ˜K˜—˜K˜—Kšœ‘™‘šŸœžœ žœNžœ žœžœžœ žœ žœ˜Χšžœžœžœž˜šžœ ž˜šœ ˜ Kšœ"žœ ˜4Kšœ™šžœžœžœž˜ Kšœ6˜6šžœžœž˜šœ žœ$˜1Kšœ<˜Jšœ žœ ˜J˜K˜$K˜Kšœ%˜%šžœ žœžœž˜KšœE˜EKšžœ˜Kšžœ˜—K˜Kšžœ/žœžœ˜=Kšœ9˜9šžœ žœžœž˜Kšœ-˜-Kšžœ˜Kšžœ˜—KšœQ˜Qšžœ žœžœžœ žœžœIžœ žœž˜‡Jšœ7˜7Kšžœ˜—Jšœ˜J˜—šŸœžœ#˜8J˜Jšœžœžœ˜#Jšœžœ˜ Kšœ%˜%Jšœ;˜;Jšžœ žœCžœ˜[Kšžœžœžœ<žœ˜UJšœU˜Ušžœžœ˜Kšžœ4˜8Kšžœ"žœ˜-—Jšœ˜——™ š Ÿœžœ žœ$žœAžœžœ˜―Kšœ<˜