DIRECTORY Core, CoreClasses, CoreFlat, CoreOps, CoreProperties, ElectricalCoreClasses, HashTable, IO, Mint, PWCore, Rope, Schedule, WriteCapa; MintInputImpl: CEDAR PROGRAM IMPORTS CoreClasses, CoreFlat, CoreOps, CoreProperties, ElectricalCoreClasses, HashTable, IO, Mint, PWCore, Schedule, WriteCapa EXPORTS Mint ~ BEGIN OPEN Mint; FlatCellProc: TYPE = PROC [cell: Core.CellType, target: CoreFlat.FlatCellTypeRec _ CoreFlat.allFlatCells, flatCell: CoreFlat.FlatCellTypeRec _ [], instance: CoreClasses.CellInstance _ NIL, parent: Core.CellType _ NIL, flatParent: CoreFlat.FlatCellTypeRec _ [], circuit: Circuit, wireName: HashTable.Table, ignoreFlag, capaEvalFlag: BOOLEAN]; defaultIndex: NAT _ LAST[NAT]; kilo: REAL = 1000.0; TypeTable: PUBLIC ARRAY CoreClasses.TransistorType OF TType _ [NEW[TTypeRec _ ["nETran", 0.0012, 0.00025, 20000.0]], NEW[TTypeRec _ ["pETran", 0.0012, 0.00025, 50000.0]], NEW[TTypeRec _ ["nDTran", 0.0012, 0.00025, 20000.0]]]; debug: BOOL _ FALSE; verbose: BOOL _ FALSE; debugCellType: Core.CellType _ NIL; debugCircuit: Circuit _ NIL; debugNode: Node _ NIL; debugNodeList: NodeList _ NIL; ignoreMe: PUBLIC ATOM _ CoreProperties.RegisterProperty[ prop: $MintIgnoreMe, properties: CoreProperties.Props[[CoreProperties.propPrint, CoreProperties.PropDontPrint]] ]; CreateCircuit: PUBLIC PROC [rootCell: Core.CellType] RETURNS [circuit: Circuit] ~ { WireToNode: PROC[wire: Core.Wire] = { flatWire: CoreFlat.FlatWire _ NEW[CoreFlat.FlatWireRec _ [ flatCell: CoreFlat.rootCellType, wireRoot: public, wire: wire ]]; node: Node _ BuildNode[flatWire, circuit]; }; -- GuessInput circuit _ NEW[CircuitRec]; circuit.rootCell _ rootCell; circuit.info _ NEW[InfoRec]; circuit.nodeTable _ HashTable.Create[equal: CoreFlat.FlatWireEqual, hash: CoreFlat.FlatWireHash]; CreatePrivate[circuit]; CoreOps.VisitRootAtomics[root: rootCell.public, eachWire: WireToNode]; }; BuildNode: PUBLIC PROC[flatWire: CoreFlat.FlatWire, circuit: Circuit] RETURNS [Node] = { new: Node; val: HashTable.Value; found: BOOLEAN; [found: found, value: val] _ HashTable.Fetch[circuit.nodeTable, flatWire]; IF found THEN RETURN[NARROW[val]]; new _ NEW[NodeRec]; new.flatWire _ flatWire; IF debug THEN new.watched _ TRUE; -- keeps everything for ever if you debug the cell ... or the program. [] _ HashTable.Store[table: circuit.nodeTable, key: flatWire, value: new]; circuit.info.totalNodes _ circuit.info.totalNodes + 1; new.cap _ WriteCapa.GetRootCap[flatWire.wire]; new.ignoreMe _ CheckIgnoreProp[flatWire.wire]; new.fetSeq _ NEW[FetSeqRec[2]]; RETURN [new]; }; CheckIgnoreProp: PROC [wire: Core.Wire] RETURNS [ignored: BOOLEAN] ~ { ignored _ NARROW[CoreProperties.GetWireProp[from: wire, prop: ignoreMe], ATOM]=$TRUE; }; AddFetToNode: PROC [fet: Fet, node: Node, circuit: Circuit] ~ { fetSeq: FetSeq; nTotal: NAT _ node.fetSeq.size; nUsed: NAT _ node.fetSeq.nUsed; IF nUsed { gndNode: Node _ Mint.NodeFromRope["public.Gnd", circuit]; n0Wire: CoreFlat.FlatWire _ NARROW[HashTable.Fetch[wireName, cell.public[0]].value]; n0Node: Node _ NARROW[HashTable.Fetch[circuit.nodeTable, n0Wire].value]; n1Wire: CoreFlat.FlatWire _ NARROW[HashTable.Fetch[wireName, cell.public[1]].value]; n1Node: Node _ NARROW[HashTable.Fetch[circuit.nodeTable, n1Wire].value]; capa: ElectricalCoreClasses.Capacitor _ NARROW[cell.data]; SELECT TRUE FROM n0Node=gndNode => n1Node.cap _ n1Node.cap+capa.value; n1Node=gndNode => n0Node.cap _ n0Node.cap+capa.value; ENDCASE => IO.PutF[StdOut, "Capacitor between %g and %g discarded\n", IO.rope[Mint.RopeFromNode[n0Node, circuit]], IO.rope[Mint.RopeFromNode[n0Node, circuit]]]; }; ElectricalCoreClasses.signalGeneratorCellClass => { nWire: CoreFlat.FlatWire _ NARROW[HashTable.Fetch[wireName, cell.public[0]].value]; nNode: Node _ NARROW[HashTable.Fetch[circuit.nodeTable, nWire].value]; sig: ElectricalCoreClasses.SignalGenerator _ NARROW[cell.data]; nNode.input _ TRUE; SELECT sig.type FROM DC => nNode.history _ Schedule.CreateHistory[0.0, sig.onLevel*kilo]; RectWave => { delay: ps _ sig.tDelay*kilo; offLevel: mVolt _ sig.offLevel*kilo; onLevel: mVolt _ sig.onLevel*kilo; tRise: ps _ sig.tRise*kilo; tFall: ps _ sig.tFall*kilo; width: ps _ sig.width*kilo; period: ps _ sig.period*kilo; nNode.history _ Schedule.CreateHistory[0.0, offLevel]; THROUGH [0..3] DO nNode.history _ Schedule.AddToHistory[nNode.history, delay, offLevel]; nNode.history _ Schedule.AddToHistory[nNode.history, delay+tRise, onLevel]; nNode.history _ Schedule.AddToHistory[nNode.history, delay+width-tFall, onLevel]; nNode.history _ Schedule.AddToHistory[nNode.history, delay+width, offLevel]; delay _ delay+period; ENDLOOP; }; OneShot => { delay: ps _ sig.tDelay*kilo; offLevel: mVolt _ sig.offLevel*kilo; onLevel: mVolt _ sig.onLevel*kilo; tRise: ps _ sig.tRise*kilo; tFall: ps _ sig.tFall*kilo; width: ps _ sig.width*kilo; nNode.history _ Schedule.CreateHistory[0.0, offLevel]; nNode.history _ Schedule.AddToHistory[nNode.history, delay, offLevel]; nNode.history _ Schedule.AddToHistory[nNode.history, delay+tRise, onLevel]; nNode.history _ Schedule.AddToHistory[nNode.history, delay+width-tFall, onLevel]; nNode.history _ Schedule.AddToHistory[nNode.history, delay+width, offLevel]; }; Step => { delay: ps _ sig.tDelay*kilo; offLevel: mVolt _ sig.offLevel*kilo; onLevel: mVolt _ sig.onLevel*kilo; tRise: ps _ sig.tRise*kilo; nNode.history _ Schedule.CreateHistory[0.0, offLevel]; nNode.history _ Schedule.AddToHistory[nNode.history, delay, offLevel]; nNode.history _ Schedule.AddToHistory[nNode.history, delay+tRise, onLevel]; }; ENDCASE => ERROR; }; ElectricalCoreClasses.probeCellClass => { IF NARROW[cell.data, ElectricalCoreClasses.Probe].type=Voltage THEN { nWire: CoreFlat.FlatWire _ NARROW[HashTable.Fetch[wireName, cell.public[0]].value]; nNode: Node _ NARROW[HashTable.Fetch[circuit.nodeTable, nWire].value]; nNode.watched _ TRUE; } ELSE IO.PutF[StdOut, "No current probes allowed\n"]; }; ElectricalCoreClasses.panelCellClass => { panel: ElectricalCoreClasses.Panel _ NARROW[cell.data]; circuit.info.tStart _ panel.tMin; circuit.info.tStop _ panel.tMax; }; CoreClasses.transistorCellClass => { gateWire: CoreFlat.FlatWire _ NARROW[HashTable.Fetch[table: wireName, key: cell.public[ORD[CoreClasses.TransistorPort.gate]]].value]; ch1Wire: CoreFlat.FlatWire _ NARROW[HashTable.Fetch[table: wireName, key: cell.public[ORD[CoreClasses.TransistorPort.ch1]]].value]; ch2Wire: CoreFlat.FlatWire _ NARROW[HashTable.Fetch[table: wireName, key: cell.public[ORD[CoreClasses.TransistorPort.ch2]]].value]; tran: CoreClasses.Transistor _ NARROW[cell.data]; BuildFet[gateWire, ch1Wire, ch2Wire, tran.type, tran.length, tran.width, circuit]; }; CoreClasses.recordCellClass => { rct: CoreClasses.RecordCellType _ NARROW[cell.data]; InsertNonPublicWires[cell.public, rct.internal, flatCell, circuit, wireName, ignoreFlag, capaEvalFlag]; NextCellType[cell, target, flatCell, instance, parent, flatParent, circuit, wireName, ignoreFlag, capaEvalFlag, Flatten] }; ENDCASE => { IF cell.class.recast=NIL THEN IO.PutF[StdOut, "What is a %g ?\n", IO.rope[cell.class.name]] ELSE NextCellType[cell, target, flatCell, instance, parent, flatParent, circuit, wireName, ignoreFlag, capaEvalFlag, Flatten] }; }; InsertNonPublicWires: PROC [public, internal: Core.Wire, flatCell: CoreFlat.FlatCellTypeRec, circuit: Circuit, wireName: HashTable.Table, ignoreFlag, capaEvalFlag: BOOLEAN] ~ { MarkAtomicPublic: PROC[wire: Core.Wire] = { [] _ HashTable.Store[table: publicsTable, key: wire, value: $Public]; }; InsertInternal: PROC[wire: Core.Wire] = { IF NOT HashTable.Fetch[table: publicsTable, key: wire].found THEN { node: Node _ InsertWire[wire, flatCell, circuit, wireName]; node.ignoreMe _ ignoreFlag; IF capaEvalFlag THEN node.cap _ node.cap+circuit.info.eachWireCapa; }; }; publicsTable: HashTable.Table _ HashTable.Create[public.size+1]; CoreOps.VisitRootAtomics[root: public, eachWire: MarkAtomicPublic]; CoreOps.VisitRootAtomics[root: internal, eachWire: InsertInternal]; }; InsertWire: PROC [wire: Core.Wire, flatCell: CoreFlat.FlatCellTypeRec, circuit: Circuit, wireName: HashTable.Table, wireRoot: CoreFlat.WireRoot _ internal] RETURNS[node: Node]= { flatWire: CoreFlat.FlatWire _ NEW[CoreFlat.FlatWireRec]; flatWire.flatCell _ flatCell; flatWire.wireRoot _ wireRoot; flatWire.wire _ wire; node _ BuildNode[flatWire, circuit]; [] _ HashTable.Store[table: wireName, key: wire, value: flatWire]; }; NetFromCore: PUBLIC PROC[circuit: Circuit, layout: BOOLEAN _ TRUE] = { InsertPublic: PROC[wire: Core.Wire] = { [] _ InsertWire[wire, CoreFlat.rootCellType, circuit, wireName, public]; }; wireName: HashTable.Table _ HashTable.Create[]; IO.PutF[Mint.StdOut, "\nConverting cell %g . . .", IO.rope[CoreOps.GetCellTypeName[circuit.rootCell]]]; CoreOps.VisitRootAtomics[root: circuit.rootCell.public, eachWire: InsertPublic]; Flatten[cell: circuit.rootCell, circuit: circuit, wireName: wireName, ignoreFlag: FALSE, capaEvalFlag: ~layout]; IO.PutRope[Mint.StdOut, "Finished\n"]; }; Stats: PUBLIC PROC[circuit: Circuit] = { total: INT _ 0; IO.PutF[Mint.StdOut, "Total number of nodes: %d.\n", IO.int[circuit.info.totalNodes]]; FOR i: CoreClasses.TransistorType IN CoreClasses.TransistorType DO IF circuit.info.totalFets[i] = 0 THEN LOOP; IO.PutF[Mint.StdOut, "Number of %s transistors: %d.\n", IO.rope[TypeTable[i].name], IO.int[circuit.info.totalFets[i]]]; total _ total + circuit.info.totalFets[i]; ENDLOOP; IO.PutF[Mint.StdOut, "Total number of transistors: %d.\n", IO.int[total]]; }; InputData: PUBLIC PROC [circuit: Circuit, fixedVList: NodeList, layout: BOOLEAN _ TRUE, eachWireCapa: pF _0.0] ~ { GuessInput: PROC[wire: Core.Wire] = { flatWire: CoreFlat.FlatWire _ NEW[CoreFlat.FlatWireRec _ [ flatCell: CoreFlat.rootCellType, wireRoot: public, wire: wire ]]; node: Node _ NARROW[HashTable.Fetch[circuit.nodeTable, flatWire].value]; IF ~node.fixedV THEN { node.input _ TRUE; FOR i: NAT IN [0..node.fetSeq.nUsed) DO fet: Fet _ node.fetSeq[i]; IF fet.ch1=node OR fet.ch2=node THEN { node.input _ FALSE; EXIT; }; ENDLOOP; }; node.watched _ TRUE; }; -- GuessInput circuit.info.eachWireCapa _ eachWireCapa; FOR iNodeList: NodeList _ fixedVList, iNodeList.rest UNTIL iNodeList = NIL DO iNodeList.first.fixedV _ TRUE; ENDLOOP; NetFromCore[circuit, layout]; CoreOps.VisitRootAtomics[root: circuit.rootCell.public, eachWire: GuessInput]; Stats[circuit]; PrepareSets[circuit, fixedVList]; }; NextNodeList: PROC [set: Set, fetList: FetList] RETURNS [nodeList: NodeList _ NIL] ~ { FOR iFetList: FetList _ fetList, iFetList.rest UNTIL iFetList = NIL DO IF NOT iFetList.first.ch1.done THEN { nodeList _ CONS[iFetList.first.ch1, nodeList]; iFetList.first.ch1.done _ TRUE; AddNodeToSet[set, iFetList.first.ch1]; }; IF NOT iFetList.first.ch2.done THEN { nodeList _ CONS[iFetList.first.ch2, nodeList]; iFetList.first.ch2.done _ TRUE; AddNodeToSet[set, iFetList.first.ch2]; }; ENDLOOP; }; --NextNodeList NextFetList: PROC [set: Set, nodeList: NodeList] RETURNS [fetList: FetList _ NIL] ~ { FOR iNodeList: NodeList _ nodeList, iNodeList.rest UNTIL iNodeList = NIL DO FOR i: NAT IN [0..iNodeList.first.fetSeq.nUsed) DO fet: Fet = iNodeList.first.fetSeq[i]; IF NOT fet.done THEN IF fet.gate # iNodeList.first THEN { fetList _ CONS[fet, fetList]; fet.done _ TRUE; AddFetToSet[set, fet]; }; ENDLOOP; ENDLOOP; }; --NextFetList AddNodeToSet: PROC [set: Set, node: Node] ~ { set.lNodes _ CONS[node, set.lNodes]; set.type.nNodes _ set.type.nNodes+1; node.done _ TRUE; }; AddFetToSet: PROC [set: Set, fet: Fet] ~ { set.lFets _ CONS[fet, set.lFets]; fet.done _ TRUE; set.type.nFets[fet.type.type] _ set.type.nFets[fet.type.type]+1; }; PrepareSets: PUBLIC PROC [circuit: Circuit, fixedVList: NodeList] ~ { FindOneSet: HashTable.EachPairAction ~ { nodeList: NodeList; fetList: FetList; set: Set; node: Node _ NARROW[value]; IF node.done THEN RETURN; set _ NEW[SetRec]; set.type _ NEW[SetTypeRec]; nodeList _ LIST[node]; AddNodeToSet[set, node]; UNTIL nodeList = NIL DO fetList _ NextFetList[set, nodeList]; nodeList _ NextNodeList[set, fetList]; ENDLOOP; FindInputs[set]; FindFixedV[set, fixedVList, GndNode, VddNode]; FOR il: Library _ circuit.library, il.rest UNTIL il=NIL DO IF TypeEqual[set.type, il.first.type] THEN { il.first.nElem _ il.first.nElem+1; il.first.setList _ CONS[set, il.first.setList]; set.type _ il.first.type; RETURN; }; ENDLOOP; circuit.library _ CONS[NEW[LibraryElemRec _ [set.type, 1, LIST[set]]], circuit.library]; }; GndNode: Node _ Mint.NodeFromRope["public.Gnd", circuit]; VddNode: Node _ Mint.NodeFromRope["public.Vdd", circuit]; FOR inode: NodeList _ fixedVList, inode.rest UNTIL inode=NIL DO inode.first.done _ TRUE; inode.first.input _ TRUE; ENDLOOP; [] _ HashTable.Pairs[circuit.nodeTable, FindOneSet] }; -- PrepareSets FindInputs: PROC [set: Set] ~ { found: BOOLEAN; FOR ifet: FetList _ set.lFets, ifet.rest UNTIL ifet=NIL DO found _ FALSE; FOR inode: NodeList _ set.lNodes, inode.rest UNTIL inode=NIL DO IF inode.first=ifet.first.gate THEN { found _ TRUE; EXIT; }; ENDLOOP; IF ~found THEN { found _ FALSE; FOR inode: NodeList _ set.inList, inode.rest UNTIL inode=NIL DO IF inode.first=ifet.first.gate THEN { found _ TRUE; EXIT; }; ENDLOOP; IF ~found THEN { set.type.nInput _ set.type.nInput+1; set.inList _ CONS[ifet.first.gate, set.inList]; ifet.first.gate.setList _ CONS[set, ifet.first.gate.setList] }; }; ENDLOOP; }; FindFixedV: PROC [set: Set, fixedVList: NodeList, GndNode, VddNode: Node] ~ { found: BOOLEAN; FOR ifet: FetList _ set.lFets, ifet.rest UNTIL ifet=NIL DO FOR fix: NodeList _ fixedVList, fix.rest UNTIL fix=NIL DO IF ifet.first.ch1=fix.first OR ifet.first.ch2=fix.first THEN { IF fix.first=VddNode THEN set.type.nVddTran _ set.type.nVddTran+1; IF fix.first=GndNode THEN set.type.nGndTran _ set.type.nGndTran+1; found _ FALSE; FOR inode: NodeList _ set.fixedV, inode.rest UNTIL inode=NIL DO IF inode.first=fix.first THEN { found _ TRUE; EXIT; }; ENDLOOP; IF ~found THEN set.fixedV _ CONS[fix.first, set.fixedV]; }; ENDLOOP; ENDLOOP; }; TypeEqual: PROC [s1, s2: SetType] RETURNS [ok: BOOLEAN _ FALSE] ~ { FOR tt: CoreClasses.TransistorType IN CoreClasses.TransistorType DO IF s1.nFets[tt]#s2.nFets[tt] THEN RETURN; ENDLOOP; IF s1.nVddTran#s2.nVddTran THEN RETURN; IF s1.nGndTran#s2.nGndTran THEN RETURN; IF s1.nNodes#s2.nNodes THEN RETURN; IF s1.nInput#s2.nInput THEN RETURN; ok _ TRUE; }; PrintSetType: PROC [out: IO.STREAM, setType: SetType] ~ { IO.PutF[out, " %4d, %4d,", IO.int[setType.nFets[nE]], IO.int[setType.nFets[pE]]]; IO.PutF[out, " %4d, %4d, %4d, %4d", IO.int[setType.nVddTran], IO.int[setType.nGndTran], IO.int[setType.nNodes], IO.int[setType.nInput]]; }; SolveInverter: PROC [set: Set, t: ps] RETURNS [tlast: ps] ~ { out: Node ~ set.lNodes.first; in: Node ~ set.inList.first; }; ErrMsg: PROC [nodeList: NodeList, msg: Rope.ROPE, circuit: Circuit] ~ { IO.PutF[Mint.StdOut, "\n%g:", IO.rope[msg]]; FOR iNodeList: NodeList _ nodeList, iNodeList.rest UNTIL iNodeList=NIL DO IO.PutF[Mint.StdOut, "\n%g", IO.rope[Mint.RopeFromNode[iNodeList.first, circuit]]]; ENDLOOP; IO.PutF[Mint.StdOut, "\n" ]; }; CheckLibrary: PUBLIC PROC [circuit: Circuit] ~ { n: NAT _ 0; FOR il: Library _ circuit.library, il.rest UNTIL il=NIL DO SELECT TRUE FROM il.first.type.nFets[nE]+il.first.type.nFets[pE]=0 => FOR iSetList: SetList _ il.first.setList, iSetList.rest UNTIL iSetList=NIL DO IF iSetList.first.lNodes.first.flatWire.wireRoot#public THEN { IF iSetList.first.lNodes.first.setList=NIL THEN ErrMsg[iSetList.first.lNodes, "This Node is isolated", circuit] ELSE ErrMsg[iSetList.first.lNodes, "This Node is not loaded by any fet", circuit]}; ENDLOOP; il.first.type.nVddTran=0 => FOR iSetList: SetList _ il.first.setList, iSetList.rest UNTIL iSetList=NIL DO ErrMsg[iSetList.first.lNodes, "These Nodes have no path to Vdd", circuit]; ENDLOOP; il.first.type.nGndTran=0 => FOR iSetList: SetList _ il.first.setList, iSetList.rest UNTIL iSetList=NIL DO ErrMsg[iSetList.first.lNodes, "These Nodes have no path to Gnd", circuit]; ENDLOOP; ENDCASE; ENDLOOP; }; OutputResults: PUBLIC PROC [circuit: Circuit] ~ { n: NAT _ 0; IO.PutF[Mint.StdOut, " nE pE ^Vdd ^Gnd nodes inputs\n"]; FOR il: Library _ circuit.library, il.rest UNTIL il=NIL DO IO.PutF[Mint.StdOut, "%5d el: %5d Type: ", IO.int[n], IO.int[il.first.nElem]]; PrintSetType[Mint.StdOut, il.first.type]; IO.PutF[Mint.StdOut, "\n" ]; n _ n+1; ENDLOOP; }; END. ”MintInputImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Christian LeCocq April 18, 1987 10:25:17 am PDT Bertrand Serlet October 18, 1986 8:12:25 pm PDT some usefull definitions Basic data stuctures builders This procedure sees if a given node exists, and makes a new one if necessary. A pointer is returned to the new or existing node. ooops! sounds like we've exceded our available space... IF nFets>127 THEN fetSeq _ NEW[FetSeqRec[nFets+1]] ELSE { poolIndex: NAT _ IF circuit.private.fetSeqPool[nFets+1]=NIL THEN fetSeq _ NEW[FetSeqRec[nFets+1]] ELSE { fetSeq _ circuit.private.fetSeqPool[nFets+1].first; circuit.private.fetSeqPool[nFets+1] _ circuit.private.fetSeqPool[nFets+1].rest; }; IF nFets>0 THEN circuit.private.fetSeqPool[nFets] _ CONS[node.fetSeq, circuit.private.fetSeqPool[nFets]]; }; IF fetSeq.size#nFets+1 THEN ERROR; --temporary while debug (hopefully..) This procedure builds a transistor data structure and links it into the network under construction. cap: REAL; Input From Core PROC [actualWire, publicWire: Wire] Circuit Preparation PROC [key: Key, value: Value] RETURNS [quit: BOOLEAN _ FALSE]; ... to be finished. Κ/˜šœ™Icodešœ Οmœ1™Kšœ˜Kšœ˜K˜ Kšœ žœ˜Kšžœ žœžœ˜Kšœžœ ˜Kšœ žœ ˜Kšœ žœ˜Kšœ˜šžœ žœž˜Kšœ%˜%Kšœ&˜&Kšžœ˜—Kšœ˜Kšœ.˜.šžœ(žœžœž˜:šžœ#žœ˜,K˜"Kšœžœ˜/Kšœ˜Kšžœ˜K˜—Kšžœ˜—Kšœžœžœ žœ˜XK˜K˜—Kšœ9˜9Kšœ9˜9šžœ*žœžœž˜?Kšœžœ˜Kšœžœ˜Kšžœ˜—Kšœ3˜3Kšœ‘˜K˜—š  œžœ˜Kšœžœ˜šžœ&žœžœž˜:Kšœžœ˜šžœ*žœžœž˜?šžœžœ˜%Kšœžœ˜ Kšžœ˜K˜—Kšžœ˜—šžœžœ˜Kšœžœ˜šžœ*žœžœž˜?šžœžœ˜%Kšœžœ˜ Kšžœ˜K˜—Kšžœ˜—šžœžœ˜Kšœ$˜$Kšœ žœ˜/Kšœžœ˜Kšžœžœ)˜BKšžœžœ)˜BKšœžœ˜šžœ*žœžœž˜?šžœžœ˜Kšœžœ˜ Kšžœ˜K˜—Kšžœ˜—Kšžœžœžœ˜8K˜—Kšžœ˜—Kšžœ˜—K˜K˜—š ’ œžœžœžœžœ˜Cšžœ žœž˜CKšžœžœžœ˜)Kšžœ˜—Kšžœžœžœ˜'Kšžœžœžœ˜'Kšžœžœžœ˜#Kšžœžœžœ˜#Kšœžœ˜ K˜K˜—š  œžœžœžœ˜:Kšžœžœžœ˜QKš žœ"žœžœžœžœ˜ˆK˜K˜—š  œžœžœ˜=K˜Kšœ˜K™K˜K˜—š œžœ žœ˜GKšžœ*˜,šžœ0žœ žœž˜IKšžœžœ4˜SKšžœ˜—Kšžœ˜K˜K˜—š  œž œ˜0Kšœžœ˜ šžœ(žœžœž˜:šžœžœž˜šœ5žœ5žœ žœž˜‚šžœ6žœ˜>Kšžœ%žœžœAžœO˜Γ—Kšžœ˜—šœžœ5žœ žœž˜iKšœJ˜JKšžœ˜—šœžœ5žœ žœž˜iKšœJ˜JKšžœ˜—Kšžœ˜—Kšžœ˜—K˜K˜—š  œž œ˜1Kšœžœ˜ KšžœT˜Všžœ(žœžœž˜:Kšžœ,žœ žœ˜QKšœ)˜)Kšžœ˜K˜Kšžœ˜—K˜K˜——Jšžœ˜—…—LΎf