DIRECTORY CD, CDCells, CDOps, CDProperties, Convert, Core, CoreGeometry, CoreOps, CoreRoute, DABasics, Rope, Route, RouteUtil, RTBasic, SC, SCChanUtil, SCInstUtil, SCNetUtil, SCPrivate, SCNewRoutePinsUtil, SCRowUtil, SCUtil, Sinix; SCNewRouteImpl: CEDAR PROGRAM IMPORTS CDCells, CDOps, CDProperties, Convert, CoreGeometry, CoreOps, CoreRoute, Rope, Route, RouteUtil, RTBasic, SC, SCChanUtil, SCInstUtil, SCNetUtil, SCNewRoutePinsUtil, SCRowUtil, SCUtil EXPORTS SCPrivate SHARES SC = BEGIN keepStats: BOOL _ FALSE; -- should be FALSE for production; TRUE enables collection of detailed statistics DetailRoute: PUBLIC PROC [handle: SC.Handle] RETURNS [result: SC.Result] = { object: CD.Object; stats: LIST OF SC.ChannelStats _ NIL; lgRows: SCPrivate.LgRows _ NARROW[handle.layoutData, SCPrivate.LayoutData].lgRows; SCInstUtil.AllOffsets[handle]; [lgRows.maxRowWidth, lgRows.numMaxRows] _ SCRowUtil.FindMaxRow[handle]; [object, stats] _ RouteChannels[handle]; result _ NEW[SC.ResultRec _ [handle: handle, object: object, stats: stats]]; SCInstUtil.AsgnChanPos[handle]; [] _ SCUtil.WriteResults["End detailed routing\n", handle, 0]}; ConstructRow: PROC [handle: SC.Handle, lgRow: SCPrivate.LgRow] RETURNS [row: CD.Object _ CDCells.CreateEmptyCell[]] ~ { LeftEnumerateSegments: PROC [eachSegment: PROC [CoreRoute.Segment]] ~ { EachWirePin: CoreGeometry.EachWirePinProc = { IF side=left THEN eachSegment[[label: CoreOps.GetShortWireName[wire], min: min, max: max, layer: layer]]}; [] _ CoreGeometry.EnumerateWireSides[mode.decoration, lgRow.lgsOnRow[1].object.cellType, EachWirePin]}; RightEnumerateSegments: PROC [eachSegment: PROC [CoreRoute.Segment]] ~ { EachWirePin: CoreGeometry.EachWirePinProc = { IF side=right THEN eachSegment[[label: CoreOps.GetShortWireName[wire], min: min, max: max, layer: layer]]}; [] _ CoreGeometry.EnumerateWireSides[mode.decoration, lgRow.lgsOnRow[lgRow.nLgsOnRow].object.cellType, EachWirePin]}; ForEachInstance: SCRowUtil.EachInstProc = { LabelProc: PROC [pinName: Rope.ROPE] RETURNS [label: Route.Label _ NIL] ~ { EachPin: SCInstUtil.EachPinProc ~ { IF Rope.Equal[netPin.pin.name, pinName] THEN { label _ netPin.net.name; quit _ TRUE; }; }; IF SCUtil.IsPowerName[handle, pinName] THEN label _ pinName ELSE IF ~SCInstUtil.EnumeratePinsOnInst[instance: instance, eachPin: EachPin] THEN SC.Signal[callingError, "FeedThrough definition in library does not have all rectangles marked."]}; instOrientation: CD.Orientation _ SCInstUtil.CDOrien[instance]; object: CD.Object _ IF (instance.whichClass = ft) OR (instance.object = parms.vddObject) OR (instance.object = parms.gndObject) THEN CoreRoute.MakeRoutingCell[instance.object.cdOb, LabelProc] ELSE instance.object.cdOb; instPosition: CD.Position _ CDOps.FitObjectI[ob: object, location: [offset, 0], orientation: instOrientation].off; cdInst: CD.Instance _ RouteUtil.Include[cell: row, ob: object, position: instPosition, orientation: instOrientation]; CDProperties.PutInstanceProp[cdInst, $InstanceName, instance.name]; offset _ offset + RTBasic.IRSize[object].x}; parms: SCPrivate.Parms = NARROW [handle.parms]; mode: Sinix.Mode = parms.mode; layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; maxRowWidth: CD.Number _ layoutData.lgRows.maxRowWidth; rowLength: SC.Number _ lgRow.size.p; rowOffset: SC.Number _ lgRow.rowOrg.p - layoutData.lgRows.horzRowOrg; offset: SC.Number _ 0; IF rowOffset > 0 THEN { leftObject: CD.Object _ CoreRoute.ExtendObject[enumerateSegments: LeftEnumerateSegments, size: [rowOffset, lgRow.size.q], side: left, extendProc: CoreRoute.ExtendSegment]; [] _ RouteUtil.Include[cell: row, ob: leftObject, position: [offset, 0]]; offset _ offset + RTBasic.IRSize[leftObject].x}; [] _ SCRowUtil.EnumerateAllInstsOnRow[handle, lgRow.rowNum, ForEachInstance]; IF rowOffset + rowLength < maxRowWidth THEN { rightObject: CD.Object _ CoreRoute.ExtendObject[enumerateSegments: RightEnumerateSegments, size: [maxRowWidth - (rowOffset + rowLength), lgRow.size.q], side: right, extendProc: CoreRoute.ExtendSegment]; [] _ RouteUtil.Include[cell: row, ob: rightObject, position: [offset, 0]]; offset _ offset + RTBasic.IRSize[rightObject].x}; RTBasic.RepositionCell[row]}; RouteChannels: PROC [handle: SC.Handle] RETURNS [obj: CD.Object _ CDCells.CreateEmptyCell[], stats: LIST OF SC.ChannelStats _ NIL] ~ { RouteChannel: PROC [enumerateNets: Route.EnumerateChannelNetsProc, rowChan: SCPrivate.RowChan] ~ { BrokenNet: Route.BrokenNetProc ~ { net: SCPrivate.Net _ NARROW[netData]; IF NOT net.externNet THEN newLabel _ NIL ELSE { net.numberOfRegions _ net.numberOfRegions + 1; newLabel _ CoreRoute.LabelBrokenNet[net.name, net.numberOfRegions]; net.brokenNets _ CONS[newLabel, net.brokenNets]}}; channel: CD.Object _ Route.Channel[enumerateNets: enumerateNets, min: lgRows.horzRowOrg, max: lgRows.horzRowOrg + lgRows.maxRowWidth, rulesParameters: handle.rules.rowParms, name: Rope.Cat[handle.name, "Chan", Convert.RopeFromInt[rowChan.chanNum]], brokenNets: BrokenNet, channelData: handle].object; [] _ RouteUtil.Include[cell: obj, ob: channel, position: [0, offset]]; offset _ offset + RTBasic.IRSize[channel].y; rowChan.chanWidth _ RTBasic.IRSize[channel].y}; EachChannel: SCChanUtil.EachRowChanProc ~ { LowerChannel: Route.EnumerateChannelNetsProc ~ { LowerChannelNet: SCNetUtil.EachNetProc ~ { leftExit: BOOL _ net.chanExits[left][rowChan.chanNum-1]; rightExit: BOOL _ net.chanExits[right][rowChan.chanNum-1]; IF net.pinsOnChan # NIL OR leftExit OR rightExit THEN { eachNet[name: net.name, enumeratePins: LowerChannelPins, exitLeftOrBottom: leftExit, exitRightOrTop: rightExit, trunkSize: net.trunkWidth, netData: net]}}; [] _ SCNetUtil.EnumerateNets[handle, LowerChannelNet]}; InteriorChannel: Route.EnumerateChannelNetsProc ~ { InteriorChannelNet: SCNetUtil.EachNetProc ~ { leftExit: BOOL _ net.chanExits[left][rowChan.chanNum-1]; rightExit: BOOL _ net.chanExits[right][rowChan.chanNum-1]; IF net.pinsOnChan # NIL OR leftExit OR rightExit THEN { eachNet[name: net.name, enumeratePins: InteriorChannelPins, exitLeftOrBottom: leftExit, exitRightOrTop: rightExit, trunkSize: net.trunkWidth, netData: net]}}; [] _ SCNetUtil.EnumerateNets[handle, InteriorChannelNet]}; LowerChannelPins: Route.EnumerateChannelPinsProc ~ { net: SCPrivate.Net _ NARROW[netData]; pinList: LIST OF Route.Pin _ NARROW[net.pinsOnChan]; FOR pins: LIST OF Route.Pin _ pinList, pins.rest UNTIL pins = NIL DO pin: Route.Pin _ pins.first; bottomOrLeftSide: BOOL _ pin.side = bottom; xfer: BOOLEAN _ net.externNet AND SCNetUtil.ExitOnSide[handle, net, bottom] AND pin.side = top; eachPin[bottomOrLeftSide: bottomOrLeftSide, min: pin.min, max: pin.max, depth: pin.depth, layer: pin.layer]; IF xfer THEN eachPin[bottomOrLeftSide: ~bottomOrLeftSide, min: pin.min, max: pin.max, depth: pin.depth, layer: pin.layer]; ENDLOOP}; InteriorChannelPins: Route.EnumerateChannelPinsProc ~ { net: SCPrivate.Net _ NARROW[netData]; pinList: LIST OF Route.Pin _ NARROW[net.pinsOnChan]; FOR pins: LIST OF Route.Pin _ pinList, pins.rest UNTIL pins = NIL DO pin: Route.Pin _ pins.first; bottomOrLeftSide: BOOL _ pin.side = bottom; eachPin[bottomOrLeftSide: bottomOrLeftSide, min: pin.min, max: pin.max, depth: pin.depth, layer: pin.layer]; ENDLOOP}; GlobalRouteChannel[handle, rowChan]; IF chan # 1 THEN { -- include the specified row in the object being constructed [] _ RouteUtil.Include[cell: obj, ob: ConstructRow[handle, lgRows.rows[chan-1]], position: [0, offset]]; offset _ offset + lgRows.rows[chan-1].size.q}; IF chan = 1 AND rowChans.count = 2 THEN { IF keepStats THEN stats _ CONS[NEW[SC.ChannelStatsRec _ [channel: chan, netStats: LowerChannelNetStats[handle, rowChan]]], stats]; RouteChannel[LowerChannel, rowChan]}; IF chan # rowChans.count AND chan # 1 THEN { IF keepStats THEN stats _ CONS[NEW[SC.ChannelStatsRec _ [channel: chan, netStats: InteriorChannelNetStats[handle, rowChan]]], stats]; RouteChannel[InteriorChannel, rowChan]}}; layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; rowChans: SCPrivate.RowChans _ layoutData.rowChans; lgRows: SCPrivate.LgRows _ layoutData.lgRows; offset: SC.Number _ 0; [] _ SCChanUtil.EnumerateRowChans[handle, EachChannel]; RTBasic.SetCDCellName[obj, handle.name]; RTBasic.RepositionCell[obj]}; GlobalRouteChannel: PROC [handle: SC.Handle, rowChan: SCPrivate.RowChan] ~ { InitNet: SCNetUtil.EachNetProc = {net.pinsOnChan _ NIL}; layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; rowChans: SCPrivate.RowChans _ layoutData.rowChans; useThisChan: BOOLEAN _ (1 < rowChan.chanNum AND rowChan.chanNum < rowChans.count) OR (rowChan.chanNum = 1 AND rowChans.count = 2); [] _ SCNetUtil.EnumerateNets[handle, InitNet]; SCNewRoutePinsUtil.InitGetChanPins[handle, rowChan]; IF useThisChan THEN CreateExitsForChannel[handle: handle, rowChan: rowChan]; CreatePinsForChannel[handle: handle, rowChan: rowChan]; SCNewRoutePinsUtil.CreateNetDat[handle, rowChan]; SCNewRoutePinsUtil.GetAllNetSegInChan[handle, rowChan, NIL, MakeNetPin, NIL]; SCNewRoutePinsUtil.TermGetChanPins[handle, rowChan]}; CreatePinsForChannel: PROC [handle: SC.Handle, rowChan: SCPrivate.RowChan] = { AllPins: SCInstUtil.EachPinProc = { IF netPin.net #NIL THEN { IF side = SCInstUtil.PosOf[instance, netPin.pin].sideOn THEN { alwaysUse: BOOLEAN _ (chan = 1 OR chan = rowChans.count) AND netPin.net.externNet AND SCNetUtil.ExitOnSide[handle, netPin.net, side]; rowOffset: SC.Number _ lgRows.horzRowOrg + lgRow.rowOrg.p; rect: CD.Rect _ SCInstUtil.RotateRect[instance, netPin.pin.rect]; min: SC.Number _ rowOffset + instance.offset + rect.x1; [] _ SCNewRoutePinsUtil.EnterPin[rowChan: rowChan, min: min, max: min + rect.x2 - rect.x1, depth: 0, layer: netPin.pin.layer, net: netPin.net, side: RTBasic.OtherSide[side], alwaysUse: alwaysUse]}}}; ExternalPins: SCInstUtil.EachPinProc = { IF netPin.net #NIL AND netPin.net.externNet THEN { IF side = SCInstUtil.PosOf[instance, netPin.pin].sideOn AND SCNetUtil.ExitOnSide[handle, netPin.net, side] THEN { rowOffset: SC.Number _ lgRows.horzRowOrg + lgRow.rowOrg.p; rect: CD.Rect _ SCInstUtil.RotateRect[instance, netPin.pin.rect]; min: SC.Number _ rowOffset + instance.offset + rect.x1; [] _ SCNewRoutePinsUtil.EnterPin[rowChan: rowChan, min: min, max: min + rect.x2 - rect.x1, depth: 0, layer: netPin.pin.layer, net: netPin.net, side: RTBasic.OtherSide[side], alwaysUse: TRUE]}}}; InternalPinsInstance: SCRowUtil.EachInstProc = { [] _ SCInstUtil.EnumeratePinsOnInst[instance, AllPins]}; ExternalPinsInstance: SCRowUtil.EachInstProc = { [] _ SCInstUtil.EnumeratePinsOnInst[instance, ExternalPins]}; lgRows: SCPrivate.LgRows _ NARROW[handle.layoutData, SCPrivate.LayoutData].lgRows; rowChans: SCPrivate.RowChans _ NARROW[handle.layoutData, SCPrivate.LayoutData].rowChans; chan: SCPrivate.MaxChanSr _ rowChan.chanNum; side: SC.Side; lgRow: SCPrivate.LgRow; SELECT TRUE FROM chan = 1 AND lgRows.count = 1 => { side _ bottom; lgRow _ lgRows.rows[1]; [] _ SCRowUtil.EnumerateAllInstsOnRow[handle, lgRow.rowNum, InternalPinsInstance]}; chan = 1 => { side _ bottom; lgRow _ lgRows.rows[1]; [] _ SCRowUtil.EnumerateAllInstsOnRow[handle, lgRow.rowNum, ExternalPinsInstance]}; chan = lgRows.count + 1 => { side _ top; lgRow _ lgRows.rows[lgRows.count]; [] _ SCRowUtil.EnumerateAllInstsOnRow[handle, lgRow.rowNum, ExternalPinsInstance]}; ENDCASE => { side _ top; lgRow _ lgRows.rows[chan - 1]; [] _ SCRowUtil.EnumerateAllInstsOnRow[handle, lgRow.rowNum, InternalPinsInstance]; side _ bottom; lgRow _ lgRows.rows[chan]; [] _ SCRowUtil.EnumerateAllInstsOnRow[handle, lgRow.rowNum, InternalPinsInstance]}}; CreateExitsForChannel: PROC [handle: SC.Handle, rowChan: SCPrivate.RowChan] = { ExitPins: SCChanUtil.EachExitProc = { pos: SC.Number _ IF lrSide = left THEN lgRows.horzRowOrg ELSE lgRows.horzRowOrg + lgRows.maxRowWidth; [] _ SCNewRoutePinsUtil.EnterExit[rowChan, pos, exit.layer, exit.net, lrSide]}; EachSide: SCRowUtil.EachSideProc ~ { IF side = left OR side = right THEN { [] _ SCChanUtil.EnumerateExits[handle, rowChan, side, ExitPins]}}; layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; lgRows: SCPrivate.LgRows _ layoutData.lgRows; [] _ SCRowUtil.EnumerateSides[handle, EachSide]}; MakeNetPin: SCNewRoutePinsUtil.PinProc = { pin: Route.Pin _ NEW[Route.PinRec _ [min: min, max: max, depth: depth, layer: layer, side: side]]; net.pinsOnChan _ CONS[pin, net.pinsOnChan]}; InteriorChannelNetStats: PROC [handle: SC.Handle, rowChan: SCPrivate.RowChan] RETURNS [netStats: LIST OF SC.NetEntry _ NIL] ~ { InteriorChannelNets: SCNetUtil.EachNetProc ~ { leftExit: BOOL _ net.chanExits[left][rowChan.chanNum-1]; rightExit: BOOL _ net.chanExits[right][rowChan.chanNum-1]; IF net.pinsOnChan # NIL OR leftExit OR rightExit THEN { pinList: LIST OF Route.Pin _ net.pinsOnChan; netStats _ CONS[NEW[SC.NetEntryRec _ [name: net.name, leftExit: leftExit, rightExit: rightExit, pinStats: NIL, ftStats: FTsOnNet[handle, net, rowChan]]], netStats]; FOR pins: LIST OF Route.Pin _ pinList, pins.rest UNTIL pins = NIL DO pin: Route.Pin _ pins.first; bottom: BOOL _ pin.side = bottom; netStats.first.pinStats _ CONS[NEW[SC.PinEntryRec _ [bottom: bottom, position: (pin.min + pin.max)/2]], netStats.first.pinStats]; ENDLOOP}}; [] _ SCNetUtil.EnumerateNets[handle, InteriorChannelNets]}; LowerChannelNetStats: PROC [handle: SC.Handle, rowChan: SCPrivate.RowChan] RETURNS [netStats: LIST OF SC.NetEntry _ NIL] ~ { LowerChannelNet: SCNetUtil.EachNetProc ~ { leftExit: BOOL _ net.chanExits[left][rowChan.chanNum-1]; rightExit: BOOL _ net.chanExits[right][rowChan.chanNum-1]; IF net.pinsOnChan # NIL OR leftExit OR rightExit THEN { pinList: LIST OF Route.Pin _ net.pinsOnChan; netStats _ CONS[NEW[SC.NetEntryRec _ [name: net.name, leftExit: leftExit, rightExit: rightExit, pinStats: NIL, ftStats: FTsOnNet[handle, net, rowChan]]], netStats]; FOR pins: LIST OF Route.Pin _ pinList, pins.rest UNTIL pins = NIL DO pin: Route.Pin _ pins.first; bottom: BOOL _ pin.side = bottom; xfer: BOOLEAN _ net.externNet AND SCNetUtil.ExitOnSide[handle, net, bottom] AND pin.side = top; netStats.first.pinStats _ CONS[NEW[SC.PinEntryRec _ [bottom: bottom, position: (pin.min + pin.max)/2]], netStats.first.pinStats]; IF xfer THEN netStats.first.pinStats _ CONS[NEW[SC.PinEntryRec _ [bottom: ~bottom, position: (pin.min + pin.max)/2]], netStats.first.pinStats]; ENDLOOP}}; [] _ SCNetUtil.EnumerateNets[handle, LowerChannelNet]}; FTsOnNet: PROC [handle: SC.Handle, net: SCPrivate.Net, rowChan: SCPrivate.RowChan] RETURNS [ftStats: LIST OF SC.PinEntry _ NIL] ~ { EachPin: SCNetUtil.EachPinProc ~ { IF netPin.pinClass = ftPin AND netPin.instance.curRow = rowChan.chanNum THEN { side: SC.Side _ SCInstUtil.PosOf[netPin.instance, netPin.pin].sideOn; IF side = top THEN ftStats _ CONS[NEW[SC.PinEntryRec _ [bottom: FALSE, position: SCInstUtil.InstPosOf[handle, netPin.instance, netPin.pin].pos.p]], ftStats]} ELSE IF netPin.pinClass = ftPin AND netPin.instance.curRow = rowChan.chanNum-1 THEN { side: SC.Side _ SCInstUtil.PosOf[netPin.instance, netPin.pin].sideOn; IF side = bottom THEN ftStats _ CONS[NEW[SC.PinEntryRec _ [bottom: TRUE, position: SCInstUtil.InstPosOf[handle, netPin.instance, netPin.pin].pos.p]], ftStats]}}; [] _ SCNetUtil.EnumeratePinsOnNet[net, EachPin]}; END. RSCNewRouteImpl.mesa: Implements of SC.DetailedRoute Copyright c 1986, 1987 by Xerox Corporation. All rights reserved. Frank Bowers June 3, 1986 10:58:48 am PDT Last Edited by: Bryan Preas August 12, 1987 4:08:01 pm PDT Christian Le Cocq December 2, 1987 3:00:23 pm PST Jean-Marc Frailong October 14, 1987 5:47:12 pm PDT Detail Route Operation Construct The Rows enumerate public wires for left side of row PROC [wire: Wire, min, max: INT, side: Side, layer: CD.Layer] RETURNS [quit: BOOL _ FALSE]; enumerate public wires for right side of row PROC [wire: Wire, min, max: INT, side: Side, layer: CD.Layer] RETURNS [quit: BOOL _ FALSE]; [pos: NAT, instance: SCPrivate.Instance] RETURNS [quit: BOOL _ FALSE] find label for this pin PROC [instance: SCPrivate.Instance, pin: NAT, netPin: SCPrivate.PinNet] RETURNS [quit: BOOL _ FALSE]; Route The Channels route the channels and include rows and channels into the layout route the specified channeland include in the object being constructed PROC [netData: REF, sourceNet: Label, regionNumber, numberOfRegions: NAT] RETURNS [newLabel: Label]; [chan: SCPrivate.MaxChanSr, rowChan: SCPrivate.RowChan] RETURNS [quit: BOOL _ FALSE] route the channel specified by rowChan PROC [eachNet: EachChannelNetProc]; PROC [net: SCPrivate.Net] RETURNS [quit: BOOL _ FALSE]; PROC [eachNet: EachChannelNetProc]; PROC [net: SCPrivate.Net] RETURNS [quit: BOOL _ FALSE]; PROC [netData: REF, eachPin: EachChannelPinProc]; PROC [netData: REF, eachPin: EachChannelPinProc]; do the bottom channel if it is the only one do the interior channels collect the pins that are to be connected for this channel [instance: SCPrivate.Instance, pin: NAT, netPin: SCPrivate.PinNet] [instance: SCPrivate.Instance, pin: NAT, netPin: SCPrivate.PinNet] only one row, must route one exterior channel. Choose the bottom one bottom exterior channel, transfer the exterior pins top exterior channel, transfer the exterior pins the interior channels PROC [exitNum: SCPrivate.MaxExitsSr, lrSide: SCPrivate.LRSide, rowChan: SCPrivate.RowChan, exit: SCPrivate.Exit] RETURNS [quit: BOOL _ FALSE] [side: SC.Side, bpRow: SCPrivate.BpRow] RETURNS [quit: BOOL _ FALSE] PROC [min, max, depth: SC.Number, side: SC.Side, layer: SC.Layer, net: SCPrivate.Net]; construct a list of nets with list of pins on channel for statistics PROC [net: SCPrivate.Net] RETURNS [quit: BOOL _ FALSE]; construct a list of nets with list of pins on channel for statistics PROC [net: SCPrivate.Net] RETURNS [quit: BOOL _ FALSE]; return a list of feedthrough pins on this net that are on this channel PROC [netPin: SCPrivate.NetPin] RETURNS [quit: BOOL _ FALSE]; Κ]˜codešœ$Οkœ™4Kšœ Οmœ7™BKšœ&™)Kšœ:™:K™1K™2K™—š ˜ Kšœ|œ]˜έK˜—šΠlnœœ˜šœ·˜ΎKšœ˜—Kšœ ˜Kšœœ˜K˜Kšœ œœΟcQ˜k—headšΟnœ™š ‘ œœœ œ œ œ ˜LK˜Kšœœ˜Kš œœœœ œ˜%Kšœœ1˜RKšœ˜KšœG˜GKšœ(˜(Kšœ œœ=˜LKšœ˜Kšœ?˜?——™š ‘ œœ œ!œœ(˜wK˜š‘œœœ˜GKšœ+™+K˜š‘ œ"˜-Kšœ[™[Kšœ œY˜jK˜—Kšœg˜gK˜—š‘œœœ˜HKšœ,™,K˜š‘ œ"˜-Kšœ[™[Kšœ œY˜k—Kšœu˜uK˜—š‘œ˜+Kš œœ œœœ™EK˜š ‘ œœœœœ˜KKšœ™š‘œ˜#Kš œ%œœœœ™ešœ&œ˜.Kšœ œ˜%Kšœ˜—Kšœ˜K˜—Kšœ%œ˜;šœœGœ˜SKšœa˜c—K˜—Kšœœ,˜?š œœ œœ#œ#œ;˜ΏKšœ˜—Kšœœb˜rKšœœk˜uKšœC˜CKšœ,˜,K˜—Kšœœ˜/Kšœ˜Kšœ#œ˜=Kšœ œ(˜7Kšœ œ˜$Kšœ œ8˜EKšœœ ˜K˜šœœ˜Kšœ œ˜«KšœI˜IKšœ0˜0K˜—šœM˜MK˜—šœ%œ˜-Kšœ œ»˜ΚKšœJ˜JKšœ1˜1K˜—Kšœ˜——™š‘ œœ œ œœ,œœœ œ˜†Kšœ@™@K˜š‘ œœP˜bšœF™FK˜—š‘ œ˜"Kšœ œ3œœ™dKšœœ ˜%Kšœœœ ˜(šœ˜K˜.KšœC˜CKšœœ˜2K˜——Kšœ œ‘˜¬KšœF˜FKšœ,˜,Kšœ/˜/K˜—š‘ œ ˜+Kšœ8œœœ™TKšœ&™&K˜š‘ œ$˜0Kšœ™#š‘œ˜*Kšœœœœ™7Kšœ8˜8Kšœ:˜:š œœœœ ˜7šœ˜Kšœ ˜ Kšœ˜Kšœ˜Kšœ˜Kšœ˜———Kšœ7˜7K˜—š‘œ$˜3Kšœ™#š‘œ˜-Kšœœœœ™7Kšœ8˜8Kšœ:˜:š œœœœ ˜7šœ˜Kšœ#˜#Kšœ˜Kšœ˜Kšœ˜Kšœ˜———Kšœ:˜:K˜—š‘œ$˜4Kšœ œ™1K˜Kšœ%˜%Kšœ œœ$˜4š œœœ œœ˜DKšœ˜Kšœ+˜+Kšœœœ+œ˜_Kšœl˜lKšœœn˜zKšœ˜ —K˜—š‘œ$˜7Kšœ œ™1K˜Kšœ%˜%Kšœ œœ$˜4š œœœ œœ˜DKšœ˜Kšœ+˜+Kšœl˜lKšœ˜ —K˜—Kšœ$˜$K˜šœ œ <˜OKšœh˜hKšœ.˜.—K˜šœ œœ˜)Kšœ+™+šœ ˜Kšœœœœ]˜p—Kšœ%˜%K˜—šœœ œ˜,Kšœ™šœ ˜Kšœœœœ`˜s—Kšœ)˜)—K˜—Kšœ#œ˜=Kšœ3˜3Kšœ-˜-Kšœœ ˜Kšœ7˜7Kšœ(˜(Kšœ˜K˜—š‘œœ œ(˜LKšœ:™:Kš‘œ,œ˜8K˜Kšœ#œ˜=Kšœ3˜3Kš œ œœ#œœ˜‚K˜Kšœ.˜.Kšœ4˜4Kšœ œ9˜LKšœ7˜7Kšœ1˜1Kšœ7œœ˜MKšœ5˜5K˜—š‘œœ œ(˜NK˜š‘œ˜#šΟi$Πik’™BK™—šœ œœ˜šœ6œ˜>Kš œ œ œœœ0˜…Kšœ œ-˜:Kšœœ9˜AKšœœ0˜7KšœΗ˜Η——K˜—š‘ œ˜(Kš’$£’™BK™šœ œœœ˜5šœ6œ0œ˜qKšœ œ-˜:Kšœœ9˜AKšœœ0˜7KšœΉœ˜Β——K˜—š‘œ˜0Kšœ8˜8K˜—š‘œ˜0Kšœ=˜=K˜—Kšœœ1˜RKšœœ3˜XKšœ,˜,Kšœœ˜Kšœ˜šœœ˜šœ œ˜"KšœD™DKšœ&˜&KšœS˜S—šœ ˜ Kšœ3™3Kšœ&˜&KšœS˜S—šœ˜Kšœ0™0Kšœ.˜.KšœS˜S—šœ˜ Kšœ™Kšœ*˜*KšœR˜RKšœ)˜)KšœT˜T——K˜—š‘œœ œ(˜OK˜š‘œ˜%Kšœmœœœ™Kš œœ œœœ(˜eKšœO˜OK˜—š‘œ˜$Kš œœœœœ™Dšœ œœ˜%KšœB˜B—K˜—Kšœ#œ˜=K˜-Kšœ1˜1K˜—š‘ œ ˜*Kšœœœœ™VK™KšœœN˜bKšœœ˜,K˜—š‘œœ œ%œ œœœ œ˜KšœD™DK˜š‘œ˜.Kšœœœœ™7Kšœ œ*˜8Kšœ œ+˜:š œœœ œ œ˜7Kšœ œœ˜,Kš œ œœœTœ7˜€š œœœ œœ˜DKšœ˜Kšœœ˜!Kšœœœœ\˜Kšœ˜ K˜———Kšœ;˜;K˜—š‘œœ œ%œ œœœ œ˜|KšœD™DK˜š‘œ˜*Kšœœœœ™7Kšœ œ*˜8Kšœ œ+˜:š œœœ œ œ˜7Kšœ œœ˜,Kš œ œœœTœ7˜€š œœœ œœ˜DKšœ˜Kšœœ˜!Kšœœœ+œ˜_Kšœœœœ\˜šœ˜ Kšœœœœ]˜‚—K˜Kšœ˜ K˜———Kšœ7˜7K˜—š‘œœEœ œœœ œ˜ƒKšœF™FK˜š‘œ˜"Kšœœœœ™=šœœ*œ˜NKšœœ=˜Ešœ œ˜Kš œ œœœœX˜Š——šœœœ,œ˜UKšœœ=˜Ešœœ˜Kš œ œœœœZ˜‹———K˜Kšœ1˜1——šœ˜K˜K˜K˜—K˜—…—;~T-