DIRECTORY Asserting, Basics, Convert, IO, OrderedSymbolTableRef, Rope, RoseCreate, RoseEvents, RoseRun, RoseTypes; RoseCreateImpl: CEDAR PROGRAM IMPORTS Asserting, Convert, IO, OSTR: OrderedSymbolTableRef, Rope, RoseCreate, RoseEvents, RoseRun, RoseTypes EXPORTS RoseCreate, RoseTypes = BEGIN OPEN RoseCreate, RoseTypes; LORA: TYPE = LIST OF REF ANY; cellTypes: SymbolTable _ OSTR.CreateTable[CompareCellTypes]; roots: PUBLIC SymbolTable _ OSTR.CreateTable[CompareComponents]; bogosityKey: ATOM = $bogosityKey; simERClass: ERClass _ NEW [ERClassRep _ [ CellInstance: CellInstance, NodeInstance: NodeInstance, SplitJoin: SplitJoin, ChangeReps: ChangeReps]]; CompareCellTypes: -- --OSTR.CompareProc = BEGIN ToKey: SAFE PROC [ref: REF ANY] RETURNS [ROPE] = {RETURN [WITH ref SELECT FROM r: ROPE => r, ct: CellType => ct.name, ENDCASE => ERROR]}; RETURN [ToKey[r1].Compare[ToKey[r2]]]; END; CompareComponents: PUBLIC PROC [r1, r2: REF ANY] RETURNS [Basics.Comparison] --OSTR.CompareProc-- = BEGIN ToKey: SAFE PROC [ref: REF ANY] RETURNS [ROPE] = {RETURN [WITH ref SELECT FROM r: ROPE => r, c: Cell => c.name, ENDCASE => ERROR]}; RETURN [ToKey[r1].Compare[ToKey[r2]]]; END; CompareNodes: PUBLIC PROC [r1, r2: REF ANY] RETURNS [Basics.Comparison] --OSTR.CompareProc-- = BEGIN k1, k2: ROPE; WITH r1 SELECT FROM r: ROPE => k1 _ r; n: Node => k1 _ n.name; ENDCASE => ERROR; k2 _ WITH r2 SELECT FROM r: ROPE => r, n: Node => n.name, ENDCASE => ERROR; RETURN [k1.Compare[k2]]; END; RegisterCellType: PUBLIC PROC [name: ROPE, expandProc: ExpandProc _ NIL, ioCreator: IOCreator _ NIL, initializer: Initializer _ NIL, evals: EvalProcs, blackBox, stateToo: CellTestProc _ NIL, ports: Ports, drivePrototype: REF ANY _ NIL, typeData: REF ANY _ NIL, other: Assertions _ NIL] RETURNS [type: CellType] = BEGIN type _ NARROW[cellTypes.Lookup[name]]; IF type = NIL THEN { type _ NEW [CellTypeRep _ [name: name, ioWordCount: 0, firstInstance: NIL]]; cellTypes.Insert[type]; FOR portIndex: CARDINAL IN [0 .. ports.length) DO port: Port _ ports[portIndex]; type.ioWordCount _ MAX[type.ioWordCount, port.firstWord + port.wordCount]; IF port.type = NIL THEN ERROR Error[IO.PutFR["No NodeType given for Port %g", IO.rope[port.name]]]; IF port.special THEN type.hasASpecialPort _ TRUE; ENDLOOP; } ELSE BEGIN IF type.firstInstance # NIL THEN BEGIN ok: BOOLEAN _ TRUE; IF ports.length # type.ports.length THEN ok _ FALSE ELSE BEGIN FOR portIndex: CARDINAL IN [0 .. type.ports.length) DO IF ( ports[portIndex].firstWord # type.ports[portIndex].firstWord OR ports[portIndex].wordCount # type.ports[portIndex].wordCount OR ports[portIndex].type # type.ports[portIndex].type OR ports[portIndex].input # type.ports[portIndex].input OR ports[portIndex].output # type.ports[portIndex].output OR NOT ports[portIndex].name.Equal[type.ports[portIndex].name]) THEN {ok _ FALSE; EXIT}; ENDLOOP; END; IF NOT ok THEN ERROR Error[IO.PutFR["Redefinition of Type %g not allowed because of different interface", IO.rope[name]]]; END; FOR instance: Cell _ type.firstInstance, instance.nextInstance WHILE instance # NIL DO IF instance.type # type THEN ERROR; IF instance.expansion = Leaf THEN BEGIN IF instance.realCellStuff.evals # type.evals THEN ERROR; instance.realCellStuff.evals _ evals; END; ENDLOOP; END; type.expand _ expandProc; type.ioCreator _ ioCreator; type.initializer _ initializer; type.evals _ evals; type.blackBox _ blackBox; type.stateToo _ stateToo; type.ports _ ports; type.drivePrototype _ drivePrototype; type.typeData _ typeData; type.other _ Asserting.Union[other, type.other]; END; GetCellType: PUBLIC PROC [name: ROPE] RETURNS [type: CellType] = {type _ NARROW[cellTypes.Lookup[name]]}; CreateSim: PUBLIC PROC [steady: BOOL] RETURNS [sim: Simulation] = { sim _ NEW [SimulationRep _ [ steady: steady, root: NIL]]; RoseEvents.Notify[event: $NewSim, arg: sim]; }; CreateTopCell: PUBLIC PROC [instanceName, typeName: ROPE, decider: ExpandDeciderClosure, sim: Simulation] RETURNS [cell: Cell] = BEGIN type: CellType; type _ NARROW[cellTypes.Lookup[typeName]]; IF type = NIL THEN ERROR Error[IO.PutFR["No such type: %g", IO.rope[typeName]]]; sim.root _ cell _ NEW [CellRep _ [ name: instanceName, type: type, sim: sim, parent: NIL, leftChild: NIL, rightSibling: NIL, firstInternalNode: NIL, internalNodes: OSTR.CreateTable[CompareNodes], components: OSTR.CreateTable[CompareComponents], interfaceNodes: NEW [NodeSR[0]], other: NIL, substantiality: Shadow, expansion: Inline, realCellStuff: NIL]]; cell.other _ Asserting.AssertFn1[$ExpandDeciderClosure, decider, cell.other]; FinishCreatingCell[cell, NIL, TRUE]; END; CellInstance: PROC [erInstance: REF ANY, instanceName, typeName, interfaceNodes: ROPE] RETURNS [cell: Cell] = BEGIN within: Cell _ NARROW[erInstance]; type: CellType; type _ NARROW[cellTypes.Lookup[typeName]]; IF type = NIL THEN ERROR Error[IO.PutFR["No such type: %g", IO.rope[typeName]]]; cell _ NEW [CellRep _ [ name: instanceName, type: type, sim: within.sim, parent: within, leftChild: NIL, rightSibling: NIL, firstInternalNode: NIL, internalNodes: OSTR.CreateTable[CompareNodes], components: OSTR.CreateTable[CompareComponents], interfaceNodes: NEW [NodeSR[type.ports.length]], other: NIL, substantiality: Shadow, expansion: Inline, realCellStuff: NIL]]; FinishCreatingCell[cell, interfaceNodes, FALSE]; END; FinishCreatingCell: PROC [cell: Cell, interfaceNodes: ROPE, isRoot: BOOL] = BEGIN type: CellType _ cell.type; thisChild, lastChild: Cell; thisNode, lastNode: Node; IF (cell.parent = NIL) AND (type.ports.length > 0) THEN ERROR Error["Can't make root with non-empty interface", cell]; IF cell.parent # NIL THEN BEGIN cell.parent.components.Insert[cell !OSTR.DuplicateKey => ERROR Error[IO.PutFR["Duplicated Cell name: %g", IO.rope[cell.name]]]]; cell.rightSibling _ cell.parent.leftChild; --do it in wrong order for now; parent will fix up after done expanding-- cell.parent.leftChild _ cell; END; cell.nextInstance _ type.firstInstance; type.firstInstance _ cell; FillInInterfaceNodes[cell, interfaceNodes]; cell.expansion _ FindAndUseExpandDecider[cell]; SELECT cell.expansion FROM Inline => BEGIN cell.substantiality _ Shadow; cell.realCellStuff _ NIL; FOR index: CARDINAL IN [0 .. type.ports.length) DO interfaceNode: Node _ cell.interfaceNodes[index]; IF NOT type.ports[index].output THEN interfaceNode.unwriteability _ interfaceNode.unwriteability + 1; ENDLOOP; type.expand[thisCell: cell, to: [cell, simERClass]]; FOR index: CARDINAL IN [0 .. type.ports.length) DO interfaceNode: Node _ cell.interfaceNodes[index]; IF NOT type.ports[index].output THEN interfaceNode.unwriteability _ interfaceNode.unwriteability - 1; ENDLOOP; END; Leaf, Nested => BEGIN cell.substantiality _ Real; cell.realCellStuff _ NEW [RealCellStuffRep _ [schedNext: notInCellList, nextNeeded: notInCellList, nextNoted: notInCellList, newIO: NIL, oldIO: NIL, switchIO: NIL, newIOAsWP: NIL, oldIOAsWP: NIL, switchIOAsWP: NIL, state: NIL, evals: type.evals]]; FOR portIndex: CARDINAL IN [0..type.ports.length) DO node: Node _ cell.interfaceNodes[portIndex]; targType: NodeType _ cell.type.ports[portIndex].type; IF node.type = NIL THEN ERROR--node.type _ targType--; IF targType # node.type THEN ERROR InterfaceMismatch[cell: cell, index: portIndex, expected: targType, got: node.type]; IF cell.type.ports[portIndex].input AND cell.type.ports[portIndex].XPhobic THEN node.XPhobic _ TRUE; NoteConnection[node, [cell, portIndex], cell.type.ports[portIndex].input, cell.type.ports[portIndex].output]; NoteMaybeVisible[node, [cell, portIndex]]; ENDLOOP; IF type.ioCreator # NIL THEN type.ioCreator[cell: cell] ELSE IF type.ioWordCount > 0 THEN ERROR Error[IO.PutFR["No IOCreator for type %g", IO.rope[type.name]]]; cell.realCellStuff.newIOAsWP _ LOOPHOLE[cell.realCellStuff.newIO]; cell.realCellStuff.oldIOAsWP _ LOOPHOLE[cell.realCellStuff.oldIO]; cell.realCellStuff.switchIOAsWP _ LOOPHOLE[cell.realCellStuff.switchIO]; FOR portIndex: CARDINAL IN [0 .. type.ports.length) DO targType: NodeType _ cell.type.ports[portIndex].type; node: Node _ cell.interfaceNodes[portIndex]; IF targType.procs.InitPort # NIL THEN targType.procs.InitPort[ node, SocketToWP[[cell, portIndex]]]; IF node.initialValue # NIL AND node.type.simple THEN Initialize[node, SocketToWP[[cell, portIndex]]]; ENDLOOP; IF type.initializer # NIL THEN type.initializer[cell: cell, leafily: cell.expansion = Leaf]; IF cell.expansion = Nested THEN BEGIN insides: Structure; cell.realCellStuff.evals _ RoseRun.StrEvals; cell.realCellStuff.state _ insides _ NEW [StructureRep _ [ container: cell, mirror: NIL, schedFirst: NIL, schedLast: NIL, insideNodes: NEW [NodeSR[type.ports.length]], nextPerturbed: notInStrList, nextWasPerturbed: notInStrList ]]; IF cell.parent # NIL THEN insides.mirror _ NEW [CellRep _ [ name: " -mirror- ", type: GetMirrorType[cell.type], sim: cell.sim, parent: cell, leftChild: NIL, rightSibling: NIL, firstInternalNode: NIL, internalNodes: NIL, components: NIL, interfaceNodes: insides.insideNodes, other: NIL, substantiality: Real, expansion: Leaf, realCellStuff: NEW [RealCellStuffRep _ [ schedNext: notInCellList, nextNeeded: notInCellList, nextNoted: notInCellList, newIO: cell.realCellStuff.newIO, oldIO: cell.realCellStuff.oldIO, switchIO: cell.realCellStuff.switchIO, newIOAsWP: cell.realCellStuff.newIOAsWP, oldIOAsWP: cell.realCellStuff.oldIOAsWP, switchIOAsWP: cell.realCellStuff.switchIOAsWP, state: ContainingStr[cell], evals: RoseRun.StrMirrorEvals]]]]; FOR index: CARDINAL IN [0 .. type.ports.length) DO outsideNode: Node _ cell.interfaceNodes[index]; insideNode: Node _ NodeInstance[erInstance: cell, name: type.ports[index].name, type: outsideNode.type, initialValue: outsideNode.initialValue]; insides.insideNodes[index] _ insideNode; IF type.ports[index].output AND type.ports[index].XPhobic THEN insideNode.XPhobic _ TRUE; IF cell.parent # NIL THEN { NoteMaybeVisible[insideNode, [insides.mirror, index]]; NoteConnection[insideNode, [insides.mirror, index], cell.type.ports[index].output, cell.type.ports[index].input]; }; IF NOT type.ports[index].output THEN insideNode.unwriteability _ insideNode.unwriteability + 1; ENDLOOP; type.expand[thisCell: cell, to: [cell, simERClass]]; END; END; ENDCASE => ERROR; lastChild _ NIL; thisChild _ cell.leftChild; WHILE thisChild # NIL DO nextChild: Cell _ thisChild.rightSibling; thisChild.rightSibling _ lastChild; lastChild _ thisChild; thisChild _ nextChild; ENDLOOP; cell.leftChild _ lastChild; lastNode _ NIL; thisNode _ cell.firstInternalNode; WHILE thisNode # NIL DO nextNode: Node _ thisNode.next; thisNode.next _ lastNode; lastNode _ thisNode; thisNode _ nextNode; ENDLOOP; cell.firstInternalNode _ lastNode; IF isRoot THEN roots.Insert[cell !OSTR.DuplicateKey => ERROR Error[IO.PutFR["Duplicated Root name: %g", IO.rope[cell.name]]]] ELSE IF cell.substantiality = Real THEN RoseRun.ScheduleCell[cell]; END; NoteConnection: PROC [node: Node, socket: Socket, input, output: BOOLEAN] = BEGIN IF input THEN BEGIN IF output THEN node.bidirs _ CONS[socket, node.bidirs] ELSE node.readers _ CONS[socket, node.readers]; END ELSE IF output THEN node.writers _ CONS[socket, node.writers] ELSE ERROR; END; FillInInterfaceNodes: PUBLIC PROC [cell: Cell, interfaceNodes: ROPE] = BEGIN index: CARDINAL _ 0; in: IO.STREAM _ IO.RIS[interfaceNodes]; [] _ in.GetIndex[]; --wake up generic GetIndex impl [] _ in.SkipWhitespace[]; IF NOT in.EndOf[] THEN DO name: ROPE _ in.GetTokenRope[IDBreak].token; key: ROPE; this: CARDINAL; [] _ in.SkipWhitespace[]; IF (IF in.EndOf[] THEN FALSE ELSE in.PeekChar[] = ':) THEN BEGIN key _ name; IF in.GetChar[] # ': THEN ERROR; IF in.EndOf[] THEN ERROR Error[IO.PutFR["Interface spec syntax error, at %g", IO.int[in.GetIndex[]]]]; name _ in.GetTokenRope[IDBreak].token; IF (this _ GetIndex[cell.type.ports, key]) = notFound THEN ERROR Error[IO.PutFR["No such port (%g) for CellType %g", IO.rope[key], IO.rope[cell.type.name]]]; END ELSE BEGIN IF index >= cell.interfaceNodes.length THEN ERROR Error[IO.PutFR["No %g'th element in %g's Interface", IO.int[index], IO.rope[cell.type.name]]]; key _ cell.type.ports[this _ index].name; END; IF cell.interfaceNodes[this] # NIL THEN ERROR Error[IO.PutFR["Port %g specified twice in \"%g\"", IO.rope[key], IO.rope[interfaceNodes]]]; cell.interfaceNodes[this] _ LookupCellNode[cell.parent, name]; IF cell.interfaceNodes[this] = NIL THEN ERROR Error[IO.PutFR["Node %g not found", IO.rope[name]]]; IF cell.type.ports[this].output AND cell.interfaceNodes[this].unwriteability > 0 THEN SIGNAL Warning[IO.PutFR["Node %g is, but shouldn't be, written to by port %g of cell %g", IO.rope[cell.interfaceNodes[this].name], IO.rope[cell.type.ports[this].name], IO.rope[cell.name]]]; index _ index + 1; [] _ in.SkipWhitespace[]; IF in.EndOf[] THEN EXIT; IF in.GetChar[] # ', THEN ERROR Error[IO.PutFR["Interface spec syntax error (missing comma), at %g", IO.int[in.GetIndex[]]]]; ENDLOOP; FOR this: CARDINAL IN [0 .. cell.interfaceNodes.length) DO IF cell.interfaceNodes[this] = NIL THEN BEGIN name: ROPE _ cell.type.ports[this].name; cell.interfaceNodes[this] _ LookupCellNode[cell.parent, name]; IF cell.interfaceNodes[this] = NIL THEN ERROR Error[IO.PutFR["Port %g not specified in \"%g\"", IO.rope[name], IO.rope[interfaceNodes]]] ELSE IF cell.type.ports[this].output AND cell.interfaceNodes[this].unwriteability > 0 THEN SIGNAL Warning[IO.PutFR["Node %g is, but shouldn't be, written to by port %g of cell %g", IO.rope[cell.interfaceNodes[this].name], IO.rope[cell.type.ports[this].name], IO.rope[cell.name]]]; END; ENDLOOP; in.Close[]; END; IDBreak: IO.BreakProc = {RETURN [SELECT char FROM IO.SP, IO.CR, IO.LF, IO.TAB => sepr, ',, ': => break, ENDCASE => other]}; GetIndex: PUBLIC PROC [ports: Ports, key: ROPE] RETURNS [index: CARDINAL] = BEGIN FOR i: CARDINAL IN [0..ports.length) DO IF key.Equal[ports[i].name] THEN RETURN [i]; ENDLOOP; RETURN [notFound]; END; FindAndUseExpandDecider: PROC [cell: Cell] RETURNS [ExpandDecision] = BEGIN ed: ExpandDecision; possibilities: [0..3]; [ed, possibilities] _ PickOne[cell]; IF possibilities = 1 THEN RETURN [ed]; IF possibilities = 0 THEN ERROR Error[IO.PutFR["Can't do anything with type %g", IO.rope[cell.type.name]]]; FOR temp: Cell _ cell, temp.parent WHILE temp # NIL DO asAny: REF ANY _ Asserting.FnVal[$ExpandDeciderClosure, temp.other]; edc: ExpandDeciderClosure; try: ExpandDecision; IF asAny = NIL THEN LOOP; edc _ NARROW[asAny]; try _ edc.Decide[cell, edc.otherData]; RETURN [IF Possible[cell, try] THEN try ELSE ed]; ENDLOOP; RETURN [ed]; END; PickOne: PROC [cell: Cell] RETURNS [whatToDo: ExpandDecision, possibilities: [0..3]] = BEGIN possibilities _ 0; FOR i: [1..3] IN [1..3] DO d: ExpandDecision _ orderedChoices[i]; IF Possible[cell, d] THEN {whatToDo _ d; possibilities _ possibilities + 1}; ENDLOOP; END; orderedChoices: ARRAY [1..3] OF ExpandDecision = [Leaf, Nested, Inline]; NoteMaybeVisible: PROC [node: Node, socket: Socket] = INLINE BEGIN IF node.visible.cell = NIL THEN node.visible _ socket ELSE IF node.visible.cell.type.ports[node.visible.index].output THEN RETURN ELSE node.visible _ socket; END; GetMirrorType: PROC [type: CellType] RETURNS [mirrorType: CellType] = BEGIN name: ROPE _ type.name.Concat["-mirror"]; asAny: REF ANY; IF (asAny _ cellTypes.Lookup[name]) # NIL THEN RETURN [NARROW[asAny]]; mirrorType _ RegisterCellType[ name: name, evals: RoseRun.StrMirrorEvals, ports: MirrorPorts[type.ports]]; END; Possible: PUBLIC PROC [cell: Cell, whatToDo: ExpandDecision] RETURNS [possible: BOOLEAN] = BEGIN evalable: BOOL _ cell.type.evals.EvalSimple # NIL OR cell.type.evals.PropUD # NIL; iok: BOOL _ cell.type.ioWordCount = 0 OR cell.type.ioCreator # NIL; RETURN [SELECT whatToDo FROM Leaf => evalable AND iok, Nested => cell.type.expand # NIL AND iok, Inline => cell.type.expand # NIL AND cell.parent # NIL, ENDCASE => ERROR]; END; XPhobicize: PUBLIC PROC [n: Node] RETURNS [m: Node-- = n --] = { m _ n; m.XPhobic _ TRUE}; NodeInstance: PROC [erInstance: REF ANY, name: ROPE, type: NodeType, initialValue: ROPE _ NIL, initData: REF ANY _ NIL] RETURNS [node: Node] = BEGIN within: Cell _ NARROW[erInstance]; bits: CARDINAL _ type.procs.Bits[type]; words: CARDINAL _ (bits + 15)/16; node _ NEW [NodeRep _ [ name: name, type: type, cellIn: within, initialValue: initialValue, nextPerturbed: notInNodeList, nextAffected: notInNodeList, nextX: notInNodeList, prevX: notInNodeList, next: within.firstInternalNode ]]; within.internalNodes.Insert[node !OSTR.DuplicateKey => ERROR Error[IO.PutFR["Duplicated Node name: %g", IO.rope[name]]]]; within.firstInternalNode _ node; --link in wrong order now; fix up when done expanding-- IF type.procs.InitNode # NIL THEN type.procs.InitNode[node, initData, within.sim.steady]; IF initialValue # NIL THEN Initialize[node, ValWP[node]]; IF NOT node.type.simple THEN RoseRun.PerturbNode[node, within]; END; Initialize: PROC [node: Node, wp: WordPtr] = BEGIN ivs: IO.STREAM _ IO.RIS[node.initialValue]; fmt: Format _ node.type.procs.GetFormat[node.type, NIL]; ok: BOOLEAN _ fmt.ParseValue[ node, fmt, wp, ivs]; ivs.Close[]; IF NOT ok THEN { SIGNAL Warning[IO.PutFR[ "Unable to parse %g by default format (%g) for node %g (of type %g)", IO.rope[Convert.RopeFromRope[node.initialValue]], IO.rope[fmt.key], IO.rope[node.name], IO.rope[node.type.procs.UserDescription[node.type]]]]; node.initialValue _ NIL}; END; SplitJoin: PROC [erInstance: REF ANY, a, b: StretchList, writeA, writeB: BOOLEAN] = BEGIN within: Cell _ NARROW[erInstance]; c: Cell; IF (a = NIL) # (b = NIL) THEN ERROR; IF a = NIL THEN RETURN; c _ a.first.node.type.procs.MakeSplitJoin[within, a, b, writeA, writeB, [erInstance, simERClass]]; IF c = NIL THEN ERROR; c.other _ Asserting.AssertFn1[fn: bogosityKey, val: $T, inAdditionTo: c.other]; END; ChangeReps: PROC [erInstance: REF ANY, a, b: Node, writeA, writeB: BOOLEAN] = BEGIN within: Cell _ NARROW[erInstance]; c: Cell _ NIL; IF c = NIL AND a.type.procs.MakeTransducer # NIL THEN c _ a.type.procs.MakeTransducer[a, b, within, writeA, writeB, [erInstance, simERClass]]; IF c = NIL AND b.type.procs.MakeTransducer # NIL THEN c _ b.type.procs.MakeTransducer[b, a, within, writeB, writeA, [erInstance, simERClass]]; IF c = NIL THEN ERROR; c.other _ Asserting.AssertFn1[fn: bogosityKey, val: $T, inAdditionTo: c.other]; END; END. x[Indigo]2.6>Rosemary.df=>RoseCreateImpl.Mesa Last Edited by: Spreitzer, October 7, 1984 2:16:01 pm PDT Κ– "cedar" style˜J™6J™9J˜IcodešΟk œœJ˜rK˜šΠbxœœ˜KšœœœI˜mKšœ˜—K˜Kšœœ˜!K˜Kš œœœœœœ˜K˜Kšœœ˜Kšœ˜Kšœ˜—šœœœ˜4Kšœ0˜0—Kšœ˜—Kšœœœ>˜\šœ˜Kš˜Kšœ˜K˜,šœ%œ˜:Kšœœ˜Kšœ œ œ˜ Kšœ œ˜-Kšœ˜Kšœ"˜"—šœœœœ ˜;Kšœ˜Kšœ˜K˜Kšœ ˜ Kšœ œ˜Kšœœ˜Kšœœ˜Kšœœ˜Kšœ œ˜Kšœ$˜$Kšœœ˜ Kšœ˜K˜šœœ˜(Kšœ˜Kšœ˜Kšœ˜Kšœ ˜ Kšœ ˜ Kšœ&˜&Kšœ(˜(Kšœ(˜(Kšœ.˜.Kšœ˜Kšœ"˜"——šœœœ˜2Kšœ/˜/Kšœ˜Kšœ(˜(Kšœœœœ˜Yšœœœ˜Kšœ6˜6Kšœq˜qKšœ˜—Kšœœœ;˜_Kšœ˜—Kšœ4˜4Kšœ˜—Kšœ˜—Kšœœ˜—Kšœ œ˜K˜šœ œ˜K˜)K˜#K˜K˜Kšœ˜—K˜Kšœ œ˜K˜"šœ œ˜K˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜—Kšœ"˜"šœ˜ Kš œœœœ#œ˜sKšœœœ˜C—Kšœ˜—K˜šŸœœ-œ˜KKš˜šœ˜ Kš˜Kšœœœ˜6Kšœœ˜/Kš˜—Kšœœœœ˜=Kšœœ˜ Kšœ˜—K˜šŸœœœœ˜FKš˜Kšœœ˜Kš œœœœœ˜'Kšœ ˜3Kšœ˜šœœ œ˜Kšœœ"˜,Kšœœ˜ Kšœœ˜Kšœ˜š œœ œœœ˜:Kš˜K˜ Kšœœœ˜ Kš œ œœœ-œ˜fKšœ&˜&Kš œ4œœœ,œ œ˜Kš˜—šœ˜ Kš œ%œœœ-œ œ˜Kšœ)˜)Kšœ˜—Kšœœœœœ,œ œ˜ŠK˜>Kš œœœœœœ˜bKšœœ.œœ œIœ'œ#œ˜“K˜Kšœ˜Kšœ œœ˜Kš œœœœ=œ˜}Kšœ˜—šœœœ#˜:šœœ˜'Kš˜Kšœœ˜(K˜>Kšœœœœœ*œ œ˜ˆKšœœœ.œœ œIœ'œ#œ˜˜Kšœ˜—Kšœ˜—K˜ Kšœ˜—K˜šŸœœ ˜šœœœ˜Kšœœœœœœœœ ˜$Kšœ˜Kšœ ˜——K˜š Ÿœœœœœ œ˜KKš˜šœœœ˜'Kšœœœ˜,Kšœ˜—Kšœ ˜Kšœ˜—K˜šŸœœœ˜EKš˜K˜K˜K˜$Kšœœœ˜&Kš œœœœ)œ˜kšœ œœ˜6Kšœœœ6˜DK˜Kšœ˜Kšœ œœœ˜Kšœœ˜Kšœ&˜&Kšœœœœ˜1Kšœ˜—Kšœ˜ Kšœ˜—K˜šŸœœœ4˜VKš˜K˜šœ œ˜Kšœ&˜&Kšœœ3˜LKšœ˜—Kšœ˜—K˜Kšœœœ)˜HK˜šŸœœ ˜