DIRECTORY CD, CDAtomicObjects, CDCells, CDPrivate, CDRects, CDTexts, CDSymbolicObjects, Convert, Core, CoreIO, CoreProperties, CoreGeometry, CoreGeometryBackdoor, GList, HashTable, IO, Rope, PWObjects; CoreGeometryIOImpl: CEDAR PROGRAM IMPORTS CD, CDAtomicObjects, CDCells, CDPrivate, CDRects, CDSymbolicObjects, CDTexts, Convert, CoreIO, CoreGeometry, CoreGeometryBackdoor, CoreProperties, GList, HashTable, IO, Rope, PWObjects EXPORTS CoreGeometryBackdoor SHARES CDCells, CDRects, CDTexts, CDSymbolicObjects, CoreGeometry = BEGIN OPEN CoreIO, CoreGeometry, CoreGeometryBackdoor; objectClassRegistry: HashTable.Table _ HashTable.Create[]; ObjectClassData: TYPE = REF ObjectClassDataRec; ObjectClassDataRec: TYPE = RECORD [ write: ObjectClassWriteProc _ NIL, read: ObjectClassReadProc _ NIL]; ObjectClassWriteProc: TYPE = PROC [h: Handle, me: CD.Object]; ObjectClassReadProc: TYPE = PROC [h: Handle] RETURNS [obj: CD.Object]; RegisterObjectClass: PUBLIC PROC [objectClass: CD.ObjectClass, write: ObjectClassWriteProc, read: ObjectClassReadProc] = { data: ObjectClassData _ NEW[ObjectClassDataRec _ [write, read]]; IF write=NIL OR read=NIL THEN ERROR; -- if only one NIL then invariant for object write/read is broken [] _ HashTable.Store[objectClassRegistry, objectClass.objectType, data]; }; WriteBool: PUBLIC PROC [h: Handle, bool: BOOL] = { IO.PutChar[h.stream, IF bool THEN '1 ELSE '0]; IO.PutChar[h.stream, ' ]; }; ReadBool: PUBLIC PROC [h: Handle] RETURNS [bool: BOOL] = { bool _ SELECT IO.GetInt[h.stream] FROM 0 => FALSE, 1 => TRUE, ENDCASE => ERROR; [] _ IO.GetChar[h.stream]; }; WritePosition: PUBLIC PROC [h: Handle, position: CD.Position] = { WriteInt[h, position.x]; WriteInt[h, position.y]; }; ReadPosition: PUBLIC PROC [h: Handle] RETURNS [position: CD.Position] = { position.x _ ReadInt[h]; position.y _ ReadInt[h]; }; WriteRect: PUBLIC PROC [h: Handle, rect: CD.Rect] = { WriteInt[h, rect.x1]; WriteInt[h, rect.y1]; WriteInt[h, rect.x2]; WriteInt[h, rect.y2]; }; ReadRect: PUBLIC PROC [h: Handle] RETURNS [rect: CD.Rect] = { rect.x1 _ ReadInt[h]; rect.y1 _ ReadInt[h]; rect.x2 _ ReadInt[h]; rect.y2 _ ReadInt[h]; }; WriteTechnology: PUBLIC PROC [h: Handle, technology: CD.Technology] = { WriteAtom[h, IF technology=NIL THEN $NILTechnology ELSE technology.key]; }; ReadTechnology: PUBLIC PROC [h: Handle] RETURNS [technology: CD.Technology] = { atom: ATOM _ ReadAtom[h]; technology _ IF atom=$NILTechnology THEN NIL ELSE CD.FetchTechnology[atom]; }; WriteLayer: PUBLIC PROC [h: Handle, layer: CD.Layer] = { WriteTechnology[h, CDPrivate.layers[layer].technology]; WriteAtom[h, CD.LayerKey[layer]]; }; ReadLayer: PUBLIC PROC [h: Handle] RETURNS [layer: CD.Layer] = { technology: CD.Technology _ ReadTechnology[h]; layer _ CD.FetchLayer[technology, ReadAtom[h]]; }; WriteOrient: PUBLIC PROC [h: Handle, orient: CD.Orientation] = { WriteInt[h, ORD[orient]]; }; ReadOrient: PUBLIC PROC [h: Handle] RETURNS [orient: CD.Orientation] = { aux: [ORD[FIRST[CD.Orientation]] .. ORD[LAST[CD.Orientation]]] _ NAT [ReadInt[h]]; orient _ LOOPHOLE [aux]; }; WriteTrans: PUBLIC PROC [h: Handle, trans: CD.Transformation] = { WritePosition[h, trans.off]; WriteOrient[h, trans.orient]; }; ReadTrans: PUBLIC PROC [h: Handle] RETURNS [trans: CD.Transformation] = { off: CD.Position _ ReadPosition[h]; trans _ [off, ReadOrient[h]]; }; WriteCDProperties: PUBLIC PROC [h: Handle, properties: CD.PropList] = { props: Core.Properties _ NIL; WHILE properties#NIL DO IF ISTYPE [properties.first.key, ATOM] THEN props _ CoreProperties.PutProp[props, NARROW [properties.first.key], properties.first.val]; properties _ properties.rest; ENDLOOP; WriteProperties[h, props]; }; ReadCDProperties: PUBLIC PROC [h: Handle] RETURNS [properties: CD.PropList _ NIL] = { Consume: PROC [key: ATOM, val: REF] = { properties _ CONS [[key, val], properties]; }; CoreProperties.Enumerate[ReadProperties[h], Consume]; }; WriteCDInstance: PUBLIC PROC [h: Handle, instance: CD.Instance] = { WriteObject[h, instance.ob]; WriteTrans[h, instance.trans]; WriteCDProperties[h, instance.properties]; }; ReadCDInstance: PUBLIC PROC [h: Handle] RETURNS [instance: CD.Instance] = { instance _ NEW [CD.InstanceRep _ [ob: ReadObject[h]]]; instance.trans _ ReadTrans[h]; instance.properties _ ReadCDProperties[h]; }; WriteCDInstances: PUBLIC PROC [h: Handle, instances: LIST OF CD.Instance] = { WriteInt[h, GList.Length[instances]]; WHILE instances#NIL DO WriteCDInstance[h, instances.first]; instances _ instances.rest; ENDLOOP; }; ReadCDInstances: PUBLIC PROC [h: Handle] RETURNS [instances: LIST OF CD.Instance _ NIL] = { THROUGH [1 .. ReadInt[h]] DO instances _ CONS [ReadCDInstance[h], instances]; ENDLOOP; }; WriteInstance: PUBLIC PROC [h: Handle, instance: Instance] = { WriteObject[h, instance.obj]; WriteTrans[h, instance.trans]; }; ReadInstance: PUBLIC PROC [h: Handle] RETURNS [instance: Instance] = { obj: CD.Object _ ReadObject[h]; instance _ [obj, ReadTrans[h]]; }; WriteInstances: PUBLIC PROC [h: Handle, instances: Instances] = { WriteInt[h, Length[instances]]; WHILE instances#NIL DO WriteInstance[h, instances.first]; instances _ instances.rest; ENDLOOP; }; ReadInstances: PUBLIC PROC [h: Handle] RETURNS [instances: Instances _ NIL] = { THROUGH [0 .. ReadInt[h]) DO instances _ CONS [ReadInstance[h], instances]; ENDLOOP; }; WriteObjectIDPair: HashWriteProc = { id: ROPE _ NARROW[key]; object: CD.Object _ NARROW[value]; WriteID[h, id]; WriteObject[h, object]; }; ReadObjectIDPair: HashReadProc = { key _ ReadID[h]; value _ ReadObject[h]; }; WriteObject: PUBLIC PROC [h: Handle, obj: CD.Object] = { objects: HashTable.Table _ NARROW [CoreProperties.GetProp[h.properties, objectsAtom]]; objectID: ROPE _ NIL; IF objects=NIL THEN { objects _ HashTable.Create[]; h.properties _ CoreProperties.PutProp[h.properties, objectsAtom, objects]; }; objectID _ NARROW [HashTable.Fetch[objects, obj].value]; IF objectID=NIL THEN { classData: ObjectClassData _ NARROW[HashTable.Fetch[objectClassRegistry, obj.class.objectType].value]; objectID _ Rope.Cat["O", Convert.RopeFromInt[from: HashTable.GetSize[objects], base: 16, showRadix: FALSE]]; IF NOT HashTable.Insert[objects, obj, objectID] THEN ERROR; WriteID[h, objectID]; WriteAtom[h, obj.class.objectType]; IF classData=NIL THEN { IF CDAtomicObjects.IsAtomicOb[obj] THEN { WriteTechnology[h, obj.class.technology]; WritePosition[h, CD.InterestSize[obj]]; WriteLayer[h, obj.layer]; } ELSE ERROR; -- no write proc and not atomic } ELSE classData.write[h, obj]; WriteCDProperties[h, obj.properties]; } ELSE WriteID[h, objectID]; }; ReadObject: PUBLIC PROC [h: Handle] RETURNS [obj: CD.Object] = { objects: HashTable.Table _ NARROW [CoreProperties.GetProp[h.properties, objectsAtom]]; objectID: ROPE; IF objects=NIL THEN { objects _ HashTable.Create[equal: HashTable.RopeEqual, hash: HashTable.HashRope]; h.properties _ CoreProperties.PutProp[h.properties, objectsAtom, objects]; }; objectID _ ReadID[h]; IF Rope.Fetch[objectID]#'O THEN ERROR; obj _ NARROW [HashTable.Fetch[objects, objectID].value]; IF obj=NIL THEN { classAtom: ATOM _ ReadAtom[h]; classData: ObjectClassData _ NARROW[HashTable.Fetch[objectClassRegistry, classAtom].value]; IF classData=NIL THEN { technology: CD.Technology _ ReadTechnology[h]; pos: CD.Position _ ReadPosition[h]; layer: CD.Layer _ ReadLayer[h]; obj _ CDAtomicObjects.CreateAtomicOb[classAtom, pos, technology, layer]; } ELSE obj _ classData.read[h]; obj.properties _ ReadCDProperties[h]; IF NOT HashTable.Insert[objects, objectID, obj] THEN ERROR; }; }; PinsInstancesPropWrite: PropWriteProc = { count: INT _ 0; Incr: EachInstanceProc = {count _ count+1}; Write: EachInstanceProc = {WriteInstance[h, instance]}; [] _ RawEnumeratePins[prop, value, Incr]; WriteInt[h, count]; [] _ RawEnumeratePins[prop, value, Write]; }; GeometryInstancesPropWrite: PropWriteProc = { count: INT _ 0; Incr: EachInstanceProc = {count _ count+1}; Write: EachInstanceProc = {WriteInstance[h, instance]}; [] _ RawEnumerateGeometry[prop, value, Incr]; WriteInt[h, count]; [] _ RawEnumeratePins[prop, value, Write]; }; InstancesPropRead: PropReadProc = { value _ ReadInstances[h]; }; ObjectPropWrite: PropWriteProc = {WriteObject[h, NARROW [value]]}; ObjectPropRead: PropReadProc = {value _ ReadObject[h]}; TransPropWrite: PropWriteProc = {WriteTrans[h, NARROW [value, REF CD.Transformation]^]}; TransPropRead: PropReadProc = {value _ NEW [CD.Transformation _ ReadTrans[h]]}; WriteObjectsProp: PropWriteProc = { WriteHashTable[h, NARROW[value], WriteObjectIDPair]; }; ReadObjectsProp: PropReadProc = { value _ ReadHashTable[h, ReadObjectIDPair, HashTable.RopeEqual, HashTable.HashRope]; }; WriteRectangle: ObjectClassWriteProc = { WritePosition[h, CD.InterestSize[me]]; WriteLayer[h, me.layer]; }; ReadRectangle: ObjectClassReadProc = { sz: CD.Position = ReadPosition[h]; l: CD.Layer = ReadLayer[h]; ob: CD.Object = CDRects.CreateRect[sz, l]; RETURN [ob] }; WriteCell: ObjectClassWriteProc = { ConsInstance: CDCells.InstEnumerator = {insts _ CONS [inst, insts]}; insts: LIST OF CD.Instance _ NIL; cellPtr: CD.CellSpecific _ NARROW [me.specific]; [] _ CDCells.EnumerateInstances[me, ConsInstance]; WriteRect[h, me.bbox]; WriteCDInstances[h, insts]; WriteRect[h, cellPtr.ir]; WriteRope[h, cellPtr.name]; WriteReal[h, cellPtr.simplifyOn]; WriteBool[h, cellPtr.drawBorder]; WriteBool[h, cellPtr.specifiedIr]; }; ReadCell: ObjectClassReadProc = { cellPtr: CD.CellSpecific _ NEW [CD.CellRep]; obj _ NEW [CD.ObjectRep _ [class: CDCells.pCellClass]]; obj.bbox _ ReadRect[h]; cellPtr.contents _ ReadCDInstances[h]; cellPtr.ir _ ReadRect[h]; cellPtr.name _ ReadRope[h]; cellPtr.simplifyOn _ ReadReal[h]; cellPtr.drawBorder _ ReadBool[h]; cellPtr.specifiedIr _ ReadBool[h]; obj.specific _ cellPtr; CDCells.ToSequenceMode[obj]; }; WriteAbut: ObjectClassWriteProc = { count: INT _ 0; Count: PWObjects.EachSubObjectProc = {count _ count + 1}; Write: PWObjects.EachSubObjectProc = {WriteObject[h, subObject]}; WriteRect[h, me.bbox]; WriteBool[h, me.class=PWObjects.abutXClass]; PWObjects.EnumerateSubObjects[me, Count]; WriteInt[h, count]; PWObjects.EnumerateSubObjects[me, Write]; }; ReadAbut: ObjectClassReadProc = { bbox: CD.Rect _ ReadRect[h]; inX: BOOL _ ReadBool[h]; size: INT _ ReadInt[h]; subObjects: LIST OF CD.Object _ NIL; THROUGH [0 .. size) DO subObjects _ CONS [ReadObject[h], subObjects] ENDLOOP; obj _ (IF inX THEN PWObjects.CreateNewAbutX ELSE PWObjects.CreateNewAbutY)[NARROW [GList.Reverse[subObjects]]]; IF obj.bbox#bbox THEN ERROR; }; WriteRouting: ObjectClassWriteProc = { routing: PWObjects.RoutingSpecific _ NARROW [me.specific]; WriteRect[h, me.bbox]; WriteInt[h, routing.size]; WriteRect[h, routing.ir]; FOR i: NAT IN [0 .. routing.size) DO node: PWObjects.Node = routing[i]; WriteInt[h, node.size]; WriteCDProperties[h, node.properties]; FOR j: NAT IN [0 .. node.size) DO WriteObject[h, node[j].object]; WritePosition[h, node[j].position]; ENDLOOP; ENDLOOP; }; ReadRouting: ObjectClassReadProc = { bbox: CD.Rect _ ReadRect[h]; size: NAT _ NAT [ReadInt[h]]; routing: PWObjects.RoutingSpecific _ NEW [PWObjects.RoutingRep[size]]; routing.ir _ ReadRect[h]; FOR i: NAT IN [0 .. size) DO nb: NAT _ NAT [ReadInt[h]]; node: PWObjects.Node = NEW [PWObjects.NodeRep[nb]]; node.properties _ ReadCDProperties[h]; FOR j: NAT IN [0 .. nb) DO object: CD.Object _ ReadObject[h]; node[j] _ [object: object, position: ReadPosition[h]]; ENDLOOP; routing[i] _ node; ENDLOOP; obj _ NEW [CD.ObjectRep _ [class: PWObjects.routingClass, specific: routing, bbox: bbox]]; }; WriteIndirect: ObjectClassWriteProc = { indirect: CD.Object _ NARROW [me.specific]; WriteRect[h, me.bbox]; WriteObject[h, indirect]; }; ReadIndirect: ObjectClassReadProc = { bbox: CD.Rect _ ReadRect[h]; indirect: CD.Object _ ReadObject[h]; IF indirect.bbox#bbox THEN ERROR; obj _ PWObjects.CreateIndirect[indirect]; }; WriteMark: ObjectClassWriteProc = { }; ReadMark: ObjectClassReadProc = { RETURN[CDSymbolicObjects.CreateMark[]]; }; WriteSegment: ObjectClassWriteProc = { WritePosition[h, CD.InterestSize[me]]; }; ReadSegment: ObjectClassReadProc = { p: CD.Position _ ReadPosition[h]; RETURN [CDSymbolicObjects.CreateSegment[p.y, p.x]] }; WritePin: ObjectClassWriteProc = { WritePosition[h, CD.InterestSize[me]]; }; ReadPin: ObjectClassReadProc = { RETURN [CDSymbolicObjects.CreatePin[ReadPosition[h]]] }; WriteText: ObjectClassWriteProc = { text: CDTexts.TextSpecific _ NARROW [me.specific]; WriteRope[h, text.text]; WriteRope[h, text.cdFont.supposedName]; WriteInt[h, text.cdFont.scaleI]; }; ReadText: ObjectClassReadProc = { text: ROPE _ ReadRope[h]; fontName: ROPE _ ReadRope[h]; scale: INT _ ReadInt[h]; font: CDTexts.CDFont _ CDTexts.MakeFont[fontName, scale]; obj _ CDTexts.Create[text, font]; }; WriteLayerRef: PropWriteProc = { WriteLayer[h, NARROW [value, CDPrivate.LayerRef].number]; }; ReadLayerRef: PropReadProc = { value _ CDPrivate.layers[ReadLayer[h]]; }; RegisterDecorationIO: PUBLIC PROC [decoration: Decoration] = { [] _ RegisterProperty[decoration.objectProp, ObjectPropWrite, ObjectPropRead]; [] _ RegisterProperty[decoration.pinsProp, PinsInstancesPropWrite, InstancesPropRead]; [] _ RegisterProperty[decoration.geometryProp, GeometryInstancesPropWrite, InstancesPropRead]; [] _ RegisterProperty[decoration.transProp, TransPropWrite, TransPropRead]; }; objectsAtom: ATOM = RegisterProperty[$CoreGeometryIOObjects, WriteObjectsProp, ReadObjectsProp]; [] _ RegisterProperty[$layerOfPin, WriteLayerRef, ReadLayerRef]; RegisterObjectClass[CDRects.bareRectClass, WriteRectangle, ReadRectangle]; RegisterObjectClass[CDCells.pCellClass, WriteCell, ReadCell]; RegisterObjectClass[PWObjects.abutXClass, WriteAbut, ReadAbut]; RegisterObjectClass[PWObjects.abutYClass, WriteAbut, ReadAbut]; RegisterObjectClass[PWObjects.routingClass, WriteRouting, ReadRouting]; RegisterObjectClass[PWObjects.indirectClass, WriteIndirect, ReadIndirect]; RegisterObjectClass[CDSymbolicObjects.markClass, WriteMark, ReadMark]; RegisterObjectClass[CDSymbolicObjects.segmentClass, WriteSegment, ReadSegment]; RegisterObjectClass[CDSymbolicObjects.pinClass, WritePin, ReadPin]; RegisterObjectClass[CD.FetchObjectClass[$C2NDifRect, CD.FetchTechnology[$cmosB]], WriteRectangle, ReadRectangle]; -- HACK! RegisterObjectClass[CD.FetchObjectClass[$C2PDifRect, CD.FetchTechnology[$cmosB]], WriteRectangle, ReadRectangle]; -- HACK! RegisterObjectClass[CDTexts.flipTextClass, WriteText, ReadText]; RegisterObjectClass[CDTexts.rigidTextClass, WriteText, ReadText]; END. rCoreGeometryIOImpl.mesa Copyright Ó 1986, 1987 by Xerox Corporation. All rights reserved. Bertrand Serlet March 14, 1987 1:06:01 am PST Barth, December 4, 1986 6:01:02 pm PST The following classes are not saved even though they are loaded with CMosB. This assumes that they are not atomic objects. CDImportsImpl $Import CDRepetitionsImpl $Repetitions CDRectsImpl $SaveRect CDCurvesImpl $FilledCurve0, $Line0, $Polygon0, $Spline0 CDOpsImpl $GCollected CDPolygonsImpl $Polygon Object Class Registration Low Level IO Utilities Object Class IO Utilities A HashTable [CD.Object -> Rope ID] is stored on the handle under the key objectsAtom CMosBObsImpl $C2DifShortCon, $C2LargeSimpleCon, $C2LargeVia, $C2LargeWellSimpleCon, $C2LTrans, $C2LWellTrans, $C2SimpleCon, $C2Trans, $C2Via, $C2WellDifShortCon, $C2WellSimpleCon, $C2WellTrans, $CLWellTrans A HashTable [Rope ID -> CD.Object] is stored on the handle under the key objectsAtom CoreIO Object Property IO Object Class IO CMosBWellDifImpl $C2NDifRect, $C2PDifRect; CDRectsImpl $Rect CDCellsImpl $Cell PWObjects $AbutX $AbutY PWObjects $RoutingClass PWObjects $Indirect CDSymbolicObjectsImpl $AlignmentMarkOb, $PinOb0, $SymbolicSegment CDTextsImpl $FlipText, $RigidText Hack for Pins (one more time!) Initialization The prop write and read procedures are only called when the hash tables are initialized for reading, never for writing. ʼ˜– "Cedar" stylešœ™Icode– "Cedar" stylešœB™BKšœ-™-Kšœ#Ïk™&—J˜š œ˜ JšœL˜NJšœ ˜ JšœA˜AJšœœ˜&J˜—šÏnœœœ˜"Jšœœ£œ˜ÀJšœ˜Jšœ>˜DJšœœ,˜6—J˜šœ{™{Jšœ™Jšœ™Jšœ™Jšœ7™7Jšœ™Jšœ™—head™šœ:˜:K˜—Kšœœœ˜/šœœœ˜#Kšœœ˜"Kšœœ˜!K˜—šœœœœ ˜=K˜—š œœœ œœ ˜FK˜—šžœœœœI˜zKšœœ%˜@Kš œœœœœœÏcA˜gKšœH˜HKšœ˜K˜——šœ œ ™šž œœœœ˜2Kšœœœœ˜.Kšœ˜K˜K˜—š žœœœ œœ˜:šœœœ˜&Kšœœ˜ Kšœœ˜ Kšœœ˜—Kšœœ˜K˜K˜—šž œœœœ˜AKšœ˜Kšœ˜Kšœ˜K˜—š ž œœœ œ œ˜IKšœ˜Kšœ˜K˜K˜—šž œœœœ ˜5Kšœ,˜,Kšœ,˜,K˜K˜—š žœœœ œœ ˜=Kšœ,˜,Kšœ,˜,K˜K˜—šžœœœœ˜GKš œ œ œœœ˜HKšœ˜K˜—š žœœœ œœ˜OKšœœ˜Kš œ œœœœœ˜KKšœ˜K˜—šž œœœœ ˜8Kšœ7˜7Kšœ œ˜!Kšœ˜K˜—š ž œœœ œ œ ˜@Kšœ œ ˜.Kšœœ%˜/Kšœ˜K˜—šž œœœœ˜@Kšœ œ ˜Kšœ˜K˜—š ž œœœ œ œ˜HKšœœœœœœœœ˜RKšœ œ˜Kšœ˜K˜—šž œœœœ˜AKšœ˜Kšœ˜K˜K˜—š ž œœœ œ œ˜IKšœœ˜#Kšœ˜K˜K˜—šžœœœœ˜GJšœœ˜šœ œœ˜Kš œœœœ'œ0˜ˆJšœ˜Jšœ˜—Jšœ˜K˜K˜—š žœœœ œœ œ˜Ušžœœœœ˜'Jšœ œ˜+Jšœ˜—Jšœ5˜5K˜——šœ œ ™šžœœœœ˜CKšœ˜Kšœ˜Kšœ*˜*K˜K˜—š žœœœ œ œ˜KKšœ œœ$˜6Kšœ˜Kšœ*˜*K˜K˜—š žœœœœœœ˜MKšœ&˜&šœ œ˜Kšœ$˜$Kšœ˜Kšœ˜—K˜K˜—šžœœœ œ œœœ œ˜[šœ˜Jšœ œ ˜0Jšœ˜—K˜K˜—šž œœœ$˜>Kšœ˜Kšœ˜K˜K˜—šž œœœ œ˜FKšœœ˜Kšœ˜K˜K˜—šžœœœ&˜AKšœ ˜ šœ œ˜Kšœ"˜"Kšœ˜Kšœ˜—K˜K˜—š ž œœœ œœ˜Ošœ˜Jšœ œ˜.Jšœ˜—K˜K˜—šžœ˜$Kšœœœ˜Kšœœ œ˜"Kšœ˜Kšœ˜K˜K˜—šžœ˜"Kšœ˜Kšœ˜Kšœ˜K˜—Kšœ œœ3™TJšœÎ™Îšž œœœœ ˜8Kšœœ5˜VKšœ œœ˜šœ œœ˜Kšœ˜KšœJ˜JKšœ˜—Kšœ œ'˜8šœ œœ˜KšœœC˜fKšœdœ˜lKšœœ*œœ˜;Kšœ˜Kšœ#˜#šœ œœ˜šœ!œ˜)Kšœ)˜)Kšœœ˜'Kšœ˜Kšœ˜—KšœœŸ˜,Kšœ˜—Kšœ˜J˜%K˜—Kšœ˜K˜K˜—Kšœœœ:™Tš ž œœœ œœ ˜@Kšœœ5˜VKšœ œ˜šœ œœ˜KšœQ˜QKšœJ˜JKšœ˜—Kšœ˜Kšœœœ˜&Kšœœ,˜8šœœœ˜Kšœ œ˜Kšœœ8˜[šœ œœ˜Kšœ œ ˜.Kšœœ˜#Kšœœ˜KšœH˜HK˜—Kšœ˜J˜%Kšœœ*œœ˜;K˜—K˜——šœ™šžœ˜)Kšœœ˜Kšžœ'˜+Kšžœ2˜7Kšœ)˜)Jšœ˜Kšœ*˜*K˜—šžœ˜-Kšœœ˜Kšžœ'˜+Kšžœ2˜7Kšœ-˜-Jšœ˜Kšœ*˜*K˜—šžœ˜#Kšœ˜Kšœ˜K˜—Kšžœ"œ ˜Bšžœ)˜7K˜—Kšžœ!œ œœ˜Xšž œœœ!˜OK˜—šžœ˜#Kšœœ˜4K˜K™—šžœ˜!KšœT˜TK˜——šœ ™šœ<™<šÐbnœ˜(Kšœœ˜&Kšœ˜Kšœ˜K˜—š  œ˜&Kšœœ˜"Kšœœ˜Kšœœ$˜*Kšœ˜ Kšœ˜——šœ™šž œ˜#Jšž œ$œ˜DJš œœœœ œ˜!Jšœ œœ˜0Jšœ2˜2Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ!˜!Jšœ!˜!Jšœ#˜#Kšœ˜K˜—šžœ˜!Kšœ œœœ ˜,Kšœœœ*˜7Kšœ˜Kšœ&˜&Kšœ˜Kšœ˜Kšœ!˜!Kšœ!˜!Kšœ"˜"Kšœ˜Kšœ˜Kšœ˜——šœ™šž œ˜#Jšœœ˜Jšžœ4˜9Jšžœ<˜AJšœ˜Jšœ,˜,Jšœ)˜)J˜Jšœ)˜)Kšœ˜K˜—šžœ˜!Kšœœ˜Kšœœ˜Kšœœ˜Jš œ œœœ œ˜$Jšœ œœœ˜MJš œœœœœ˜oKšœœœ˜Kšœ˜——šœ™šž œ˜&Jšœ%œ˜:Jšœ˜Jšœ˜Jšœ˜šœœœ˜$Jšœ"˜"Jšœ˜Jšœ&˜&šœœœ˜!Kšœ˜Kšœ#˜#Kšœ˜—Jšœ˜—Kšœ˜K˜—šž œ˜$Kšœœ˜Kšœœœ˜Kšœ%œ˜FKšœ˜šœœœ ˜Jšœœœ˜Jšœœ˜3Jšœ&˜&šœœœ ˜Kšœœ˜"Kšœ6˜6Kšœ˜—Jšœ˜Jšœ˜—KšœœœM˜ZKšœ˜——šœ™šž œ˜'Jšœ œ œ˜+Jšœ˜Jšœ˜Kšœ˜K˜—šž œ˜%Kšœœ˜Jšœ œ˜$Kšœœœ˜!Kšœ)˜)Kšœ˜——šœA™Aš  œ˜#Kšœ˜K˜—š œ˜!Kšœ!˜'Kšœ˜K˜—šž œ˜&Kšœœ˜&Kšœ˜K˜—š  œ˜$Kšœœ˜!Kšœ,˜2Kšœ˜K˜—šžœ˜"Kšœœ˜&Kšœ˜K˜—š œ˜ Kšœ/˜5Kšœ˜——šœ!™!šž œ˜#Kšœœ˜2Kšœ˜Kšœ'˜'Kšœ ˜ Kšœ˜K˜—šžœ˜!Kšœœ˜Kšœ œ˜Kšœœ˜Kšœ9˜9Kšœ!˜!Kšœ˜———™šž œ˜ Kšœœ%˜9K˜K˜—šž œ˜Kšœ'˜'K˜——™šžœ œ˜>KšœN˜NKšœV˜VKšœ^˜^KšœK˜KK˜K˜—šœ œO˜`Kšœw™wK™—šœ@˜@K˜—KšœJ˜JKšœ=˜=Kšœ?˜?Kšœ?˜?KšœG˜GKšœJ˜JKšœF˜FKšœO˜OKšœC˜CKšœœœC˜zKšœœœC˜zKšœ@˜@KšœA˜AK˜—Jšœ˜J˜—…—8®OÜ