DIRECTORY CD, CDBasics, CDCells, CDOrient, CDProperties, CDRects, CDSymbolicObjects, Convert, PW, PWPins, PWRoute, Rope, Route, RouteUtil, RTBasic, SC, SCChanUtil, SCInstUtil, SCNetUtil, SCPrivate, SCRoutePinsUtil, SCRowUtil, SCUtil; SCRouteImpl: CEDAR PROGRAM IMPORTS CD, CDBasics, CDCells, CDProperties, CDRects, CDSymbolicObjects, Convert, PW, PWPins, PWRoute, Rope, RouteUtil, RTBasic, SCChanUtil, SCInstUtil, SCNetUtil, SCRoutePinsUtil, SCRowUtil, SCUtil EXPORTS SCPrivate SHARES SC = BEGIN 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 { rowOffset: SC.Number _ lgRow.rowOrg.p - lgRows.horzRowOrg; rect: CD.Rect _ SCInstUtil.RotateRect[instance, netPin.pin.rect]; position: CD.Position _ SCUtil.PQToXY[handle, [p: rowOffset + instance.offset + rect.x1, q: rect.y1]]; SCRoutePinsUtil.EnterPin[rect, position, netPin, RTBasic.OtherSide[side], lgRow.cdOb]}}}; ExternalPins: SCInstUtil.EachPinProc = { IF netPin.net #NIL AND netPin.net.externNet = externalNet THEN { IF side = SCInstUtil.PosOf[instance, netPin.pin].sideOn AND SCNetUtil.ExitOnSide[handle, netPin.net, side] THEN { rowOffset: SC.Number _ lgRow.rowOrg.p - lgRows.horzRowOrg; rect: CD.Rect _ SCInstUtil.RotateRect[instance, netPin.pin.rect]; position: CD.Position _ SCUtil.PQToXY[handle, [p: rowOffset + instance.offset + rect.x1, q: rect.y1]]; SCRoutePinsUtil.EnterPin[rect, position, netPin, RTBasic.OtherSide[side], lgRow.cdOb]}}}; InternalPinsInstance: SCRowUtil.EachInstProc = { [] _ SCInstUtil.EnumeratePinsOnInst[instance, AllPins]}; ExternalPinsInstance: SCRowUtil.EachInstProc = { [] _ SCInstUtil.EnumeratePinsOnInst[instance, ExternalPins]}; layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; lgRows: SCPrivate.LgRows _ layoutData.lgRows; chan: SCPrivate.MaxChanSr _ rowChan.chanNum; side: SC.Side; lgRow: SCPrivate.LgRow; IF chan = 1 THEN { side _ bottom; lgRow _ lgRows.rows[1]; [] _ SCRowUtil.EnumerateAllInstsOnRow[handle, lgRow.rowNum, ExternalPinsInstance]} ELSE IF chan = lgRows.count + 1 THEN { side _ top; lgRow _ lgRows.rows[lgRows.count]; [] _ SCRowUtil.EnumerateAllInstsOnRow[handle, lgRow.rowNum, ExternalPinsInstance]} ELSE { 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] = { cell: CD.Object; ExitPins: SCChanUtil.EachExitProc = {SCRoutePinsUtil.EnterExit[exit, lrSide, cell]}; EachSide: SCRowUtil.EachSideProc ~ { IF side = left OR side = right THEN { cell _ CDCells.CreateEmptyCell[]; [] _ SCChanUtil.EnumerateExits[handle, rowChan, side, ExitPins]; rowChan.exitCells[side] _ cell}}; [] _ SCRowUtil.EnumerateSides[handle, EachSide]}; FinishExitsForChannel: PROC [handle: SC.Handle, rowChan: SCPrivate.RowChan] = { EachSide: SCRowUtil.EachSideProc ~ { IF side = left OR side = right THEN { rect: CD.Rect; cell: CD.Object _ rowChan.exitCells[side]; SELECT side FROM -- pw needs a better way of finding sides left => rect _ [-trunkWidth, -trunkWidth, trunkWidth, 2*trunkWidth]; right => rect _ [0, -trunkWidth, 2*trunkWidth, 2*trunkWidth]; ENDCASE; CDCells.SetInterestRect[cell, rect]; -- set interestRect of cell RTBasic.RepositionCell[cell]}}; trunkWidth: SC.Number _ handle.rules.rowRules.trunkWidth; [] _ SCRowUtil.EnumerateSides[handle, EachSide]}; CreateWireAndContact: PROC [handle: SC.Handle, pin: CD.Instance, size: Route.Position, length: CD.Number, trunkLayer: CD.Layer, cdLambda: Route.Number] RETURNS [obj: CD.Object] = { branchLayer: CD.Layer _ CDSymbolicObjects.GetLayer[pin]; obj _ CDCells.CreateEmptyCell[]; [] _ PW.IncludeInCell[obj, CreateWireFromPin[handle, pin, length]]; RouteUtil.AddVia[obj, CDSymbolicObjects.GetName[pin], [length-size.x/2, size.y/2], size, trunkLayer, branchLayer, cdLambda]; RTBasic.RepositionCell[obj]}; CreateWireFromPin: PROC [handle: SC.Handle, pin: CD.Instance, length: CD.Number] RETURNS [wire: CD.Object] = { wx: CD.Number _ length; wy: CD.Number _ pin.ob.size.y; wSize: CD.Position _ SCUtil.PQToXY[handle, [wx, wy]]; layer: CD.Layer _ CDSymbolicObjects.GetLayer[pin]; wire _ CDRects.CreateRect[wSize, layer]}; AlwaysExtendPin: PROC [handle: SC.Handle, inst: CD.Instance, extLen: CD.Number, side: SC.Side] RETURNS [obj: CD.Object _ NIL] = { IF CDSymbolicObjects.IsSymbolicOb[inst.ob] THEN { pinInst, wireInst: CD.Instance; name: Rope.ROPE _ CDSymbolicObjects.GetName[inst]; wire: CD.Object _ CreateWireFromPin[handle, inst, extLen]; pinOb: CD.Object _ CDSymbolicObjects.CreateSegment[inst.ob.size.y]; obj _ CDCells.CreateEmptyCell[]; pinInst _ PW.IncludeInCell[obj, pinOb, [extLen-pinOb.size.x, 0], CDSymbolicObjects.OrientFromDirection[east]]; wireInst _ PW.IncludeInCell[obj, wire]; CDProperties.PutProp[wireInst, $SignalName, name]; CDSymbolicObjects.SetName[pinInst, name]; CDSymbolicObjects.SetLayer[pinInst, CDSymbolicObjects.GetLayer[inst]]; RTBasic.SetCDCellName[obj, Rope.Cat[name, IF side = right THEN "Right" ELSE "Left", name]]; RTBasic.RepositionCell[obj]}}; LogicRoute: PROC [handle: SC.Handle] RETURNS [logicOb: CD.Object] = { ForEachRow: SCRowUtil.EachRowProc = { ExtendPin: PW.ForEachPinProc = { IF Rope.Equal[CDSymbolicObjects.GetName[inst], layoutData.powerBuses[side].name] THEN obj _ AlwaysExtendPin[handle, inst, extLen, side]}; extLen: CD.Number; side: SCPrivate.LRSide; leftObject, rightObject: CD.Object; leftTemplate: CD.Object _ lgRow.lgsOnRow[1].object.cdOb; rightTemplate: CD.Object _ lgRow.lgsOnRow[lgRow.nLgsOnRow].object.cdOb; lgRows: SCPrivate.LgRows _ layoutData.lgRows; maxRowWidth: CD.Number _ lgRows.maxRowWidth; rowLength: SC.Number _ lgRow.size.p; rowOffset: SC.Number _ lgRow.rowOrg.p - lgRows.horzRowOrg; IF rowOffset > 0 AND rowLength < maxRowWidth THEN { -- needs filler on left and right side _ left; extLen _ rowOffset; leftObject _ TransferCell[template: leftTemplate, objSide: left, width: extLen, objProc: ExtendPin, stopEnumerateDeepPins: FALSE]; RTBasic.SetCDCellName[leftObject, Rope.Cat[handle.name, "LeftRow",Convert.RopeFromInt[lgRow.rowNum]]]; side _ right; extLen _ maxRowWidth - (rowOffset + rowLength); rightObject _ TransferCell[template: rightTemplate, objSide: right, width: extLen, objProc: ExtendPin, stopEnumerateDeepPins: FALSE]; RTBasic.SetCDCellName[rightObject, Rope.Cat[handle.name, "RightRow",Convert.RopeFromInt[lgRow.rowNum]]]} ELSE IF rowLength < maxRowWidth THEN { -- rowOffset = 0, no filler on left side _ right; extLen _ maxRowWidth - rowLength; rightObject _ TransferCell[template: rightTemplate, objSide: right, width: extLen, objProc: ExtendPin, stopEnumerateDeepPins: FALSE]; RTBasic.SetCDCellName[rightObject, Rope.Cat[handle.name, "RightRow",Convert.RopeFromInt[lgRow.rowNum]]]; leftObject _ NIL} ELSE -- no filler needed {leftObject _ NIL; rightObject _ NIL}; lgRow.cdOb _ ConstructRow[handle, leftObject, lgRow, rightObject]}; ForEachChannel: SCChanUtil.EachRowChanProc = { rowChans: SCPrivate.RowChans _ layoutData.rowChans; SCRoutePinsUtil.InitGetChanPins[handle]; IF 1 < rowChan.chanNum AND rowChan.chanNum < rowChans.count THEN CreateExitsForChannel[handle: handle, rowChan: rowChan]; CreatePinsForChannel[handle: handle, rowChan: rowChan]; SCRoutePinsUtil.EnterNetDat[handle, chan, MakeNetPin, MakeExit, NIL]; SCRoutePinsUtil.TermGetChanPins[handle]; IF 1 < rowChan.chanNum AND rowChan.chanNum < rowChans.count THEN FinishExitsForChannel[handle: handle, rowChan: rowChan]}; MakeExit: SCRoutePinsUtil.ExitProc = { pinOb: CD.Object _ CDSymbolicObjects.CreatePin[size: [trunkWidth, exit.net.trunkWidth]]; pinInst: CD.Instance _ PW.IncludeInCell[cell: cell, obj: pinOb]; CDSymbolicObjects.SetName[pinInst, exit.net.name]; CDSymbolicObjects.SetLayer[pinInst, exit.layer]}; MakeNetPin: SCRoutePinsUtil.PinProc = { pinOb: CD.Object _ CDSymbolicObjects.CreatePin[CDBasics.SizeOfRect[rect]]; pinInst: CD.Instance _ PW.IncludeInCell[cell: cell, obj: pinOb, position: position]; CDSymbolicObjects.SetName[pinInst, netPin.net.name]; CDSymbolicObjects.SetLayer[pinInst, netPin.pin.layer]}; layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; parms: SCPrivate.Parms _ NARROW[handle.parms]; technologyKey: ATOM _ NARROW[handle.rules.technology, CD.Technology].key; routerParams: PWRoute.RouterParams _ NEW[PWRoute.RouterParamsRec _ [trunkLayer: handle.rules.horizLayer, branchLayer: handle.rules.vertLayer, technologyKey: technologyKey, signalBreakAtExit: FALSE, signalSinglePinNets: TRUE]]; [] _ SCRowUtil.EnumerateRows[handle: handle, eachRow: ForEachRow]; [] _ SCChanUtil.EnumerateRowChans[handle: handle, eachRowChan: ForEachChannel]; logicOb _ RouteRows[handle, routerParams]; }; IncludeTrunkPin: PROC [handle: SC.Handle, cell: CD.Object, name: Rope.ROPE, tbSide: SCPrivate.TBSide, trunkSize, trunkPos: SCPrivate.PQPos, layer: CD.Layer] = { pin: CD.Object _ CDSymbolicObjects.CreateSegment[trunkSize.p]; pinPos: SCPrivate.PQPos _ [trunkPos.p, IF tbSide = top THEN trunkPos.q + trunkSize.q - pin.size.x ELSE trunkPos.q]; pos: CD.Position _ SCUtil.PQToXY[handle, pinPos]; pinInst: CD.Instance _ PW.IncludeInCell[cell, pin, pos, CDSymbolicObjects.OrientFromDirection[IF tbSide = top THEN north ELSE south]]; CDSymbolicObjects.SetName[pinInst, name]; CDSymbolicObjects.SetLayer[pinInst, layer]}; PowerRoute: PROC [handle: SC.Handle, pwOb: CD.Object] RETURNS [obj: CD.Object] = { EachSide: SCRowUtil.EachSideProc ~ { IF side = left OR side = right THEN { ExtendPin: PW.ForEachPinProc = { name: Rope.ROPE _ CDSymbolicObjects.GetName[inst]; otherPBus: SCPrivate.PowerBus = layoutData.powerBuses[RTBasic.OtherSide[side]]; SELECT TRUE FROM Rope.Equal[name, pBus.name] => obj _ CreateWireAndContact[handle, inst, [trunkWidth, RTBasic.IRSize[inst.ob].y], width, trunkLayer, handle.rules.sideRules.CDLambda]; Rope.Equal[name, otherPBus.name] => NULL; ENDCASE => obj _ AlwaysExtendPin[handle, inst, width, side]}; pBus: SCPrivate.PowerBus _ layoutData.powerBuses[side]; width: SC.Number _ MAX[pBus.width, rules.trunkToTrunk]; trunkWidth: SC.Number _ width - rules.trunkSpacing; extLen: SC.Number _ rules.trunkSpacing; trunkSize: SCPrivate.PQPos _ [p: trunkWidth, q: RTBasic.IRSize[pwOb].y]; trunkPos: SCPrivate.PQPos _ [IF side = right THEN extLen ELSE 0, 0]; pwSide: PWPins.Side _ SELECT side FROM right => right, left => left, ENDCASE => ERROR; trunk: CD.Object _ CDRects.CreateRect[SCUtil.PQToXY[handle, trunkSize], trunkLayer]; ext[side] _ TransferCell[template: pwOb, objSide: pwSide, width: width, objProc: ExtendPin, stopEnumerateDeepPins: FALSE]; RTBasic.SetCDCellName[ext[side], Rope.Cat[handle.name, IF side = right THEN "RightPower" ELSE "LeftPower"]]; [] _ PW.IncludeInCell[ext[side], trunk, SCUtil.PQToXY[handle, trunkPos]]; IncludeTrunkPin[handle, ext[side], pBus.name, top, trunkSize, trunkPos , trunkLayer]; IncludeTrunkPin[handle, ext[side], pBus.name, bottom, trunkSize, trunkPos, trunkLayer]}}; ext: ARRAY SCPrivate.LRSide OF CD.Object; rules: Route.DesignRules _ handle.rules.sideRules; trunkLayer: CD.Layer _ rules.trunkLayer; layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; [] _ SCRowUtil.EnumerateSides[handle, EachSide]; obj _ ConstructLayout[o1: ext[left], o2: pwOb, o3: ext[right], name: handle.name]}; DetailRoute: PUBLIC PROC [handle: SC.Handle] RETURNS [result: SC.Result] = { centerObj, fullObj: CD.Object; lgRows: SCPrivate.LgRows _ NARROW[handle.layoutData, SCPrivate.LayoutData].lgRows; SCInstUtil.AllOffsets[handle]; [lgRows.maxRowWidth, lgRows.numMaxRows] _ SCRowUtil.FindMaxRow[handle]; centerObj _ LogicRoute[handle]; fullObj _ PowerRoute[handle, centerObj]; result _ NEW[SC.ResultRec _ [handle: handle, object: fullObj]]}; TransferCell: PROC [template: PW.Object, objSide: PWPins.Side, width: INT, objProc: PW.ForEachPinProc, stopEnumerateDeepPins: BOOLEAN _ TRUE] RETURNS [cell: CD.Object _ CDCells.CreateEmptyCell[]] = { KeepPinOnEdge: PWPins.InstanceEnumerator = { newObj: CD.Object; side: PWPins.Side _ PWPins.GetSide[template, inst].side; IF side=objSide THEN { newObj _ objProc[inst]; IF newObj=NIL THEN RETURN; [] _ PW.IncludeInCell[cell, newObj, Position[inst, template, objSide], SideToOrient[objSide]]}}; iRect: CD.Rect; IF objSide=none THEN ERROR; iRect _ CD.InterestRect[template]; -- copy interestRect of obj CDCells.SetInterestRect[cell, IRect[iRect, width, objSide]]; -- set interestRect of cell [] _ PWPins.EnumerateEdgePins[template, KeepPinOnEdge, stopEnumerateDeepPins]; RTBasic.RepositionCell[cell]}; IRect: PROC [templateRect: CD.Rect, otherDim: INT, side: PWPins.Side] RETURNS [iRect: CD.Rect] = { iRect _ SELECT side FROM top, bottom => [0, 0, templateRect.x2-templateRect.x1, otherDim], left, right => [0, 0, otherDim, templateRect.y2-templateRect.y1], ENDCASE => ERROR}; SideToOrient: PROC [side: PWPins.Side] RETURNS [orient: CD.Orientation] ~ { orient _ SELECT side FROM bottom => CDOrient.rotate270, right => CDOrient.original, top => CDOrient.rotate90, left => CDOrient.rotate180, ENDCASE => ERROR}; Position: PROC [inst: CD.Instance, template: CD.Object, side: PWPins.Side] RETURNS [position: CD.Position] = { position _ PW.GetLocation[inst, template]; SELECT side FROM top, bottom => position.y _ 0; left, right => position.x _ 0; ENDCASE => ERROR}; ConstructRow: PROC [handle: SC.Handle, leftObject: CD.Object, lgRow: SCPrivate.LgRow, rightObject: CD.Object] RETURNS [row: CD.Object _ CDCells.CreateEmptyCell[]] ~ { ForEachInstance: SCRowUtil.EachInstProc = { object: CD.Object _ instance.object.cdOb; cdInst: CD.Instance _ PW.IncludeInCell[cell: row, obj: object, position: [offset, 0], orientation: SCInstUtil.CDOrien[instance]]; CDProperties.PutInstanceProp[cdInst, $InstanceName, instance.name]; CDProperties.PutProp[cdInst, $StopEnumerateDeepPins, $StopEnumerateDeepPins]; offset _ offset + RTBasic.IRSize[object].x}; offset: SC.Number _ 0; IF leftObject # NIL THEN { [] _ PW.IncludeInCell[cell: row, obj: leftObject, position: [offset, 0], orientation: 0]; offset _ offset + RTBasic.IRSize[leftObject].x}; [] _ SCRowUtil.EnumerateAllInstsOnRow[handle, lgRow.rowNum, ForEachInstance]; IF rightObject # NIL THEN { [] _ PW.IncludeInCell[cell: row, obj: rightObject, position: [offset, 0], orientation: 0]; offset _ offset + RTBasic.IRSize[rightObject].x}; RTBasic.RepositionCell[row]; RTBasic.SetCDCellName[row, Rope.Cat[handle.name, "Row",Convert.RopeFromInt[lgRow.rowNum]]]}; ConstructLayout: PROC [o1, o2, o3, o4, o5: CD.Object _ NIL, name: Rope.ROPE] RETURNS [obj: CD.Object _ CDCells.CreateEmptyCell[]] ~ { offset: SC.Number _ 0; IF o1 # NIL THEN { [] _ PW.IncludeInCell[cell: obj, obj: o1, position: [offset, 0], orientation: 0]; offset _ offset + RTBasic.IRSize[o1].x}; IF o2 # NIL THEN { [] _ PW.IncludeInCell[cell: obj, obj: o2, position: [offset, 0], orientation: 0]; offset _ offset + RTBasic.IRSize[o2].x}; IF o3 # NIL THEN { [] _ PW.IncludeInCell[cell: obj, obj: o3, position: [offset, 0], orientation: 0]; offset _ offset + RTBasic.IRSize[o3].x}; IF o4 # NIL THEN { [] _ PW.IncludeInCell[cell: obj, obj: o4, position: [offset, 0], orientation: 0]; offset _ offset + RTBasic.IRSize[o4].x}; IF o5 # NIL THEN { [] _ PW.IncludeInCell[cell: obj, obj: o5, position: [offset, 0], orientation: 0]; offset _ offset + RTBasic.IRSize[o5].x}; RTBasic.RepositionCell[obj]; RTBasic.SetCDCellName[obj, name]}; RouteRows: PROC [handle: SC.Handle, routerParams: PWRoute.RouterParams] RETURNS [obj: CD.Object _ CDCells.CreateEmptyCell[]] ~ { EachChannel: SCChanUtil.EachRowChanProc ~ { IF chan # 1 THEN { bottomRow: CD.Object _ lgRows.rows[rowChan.chanNum-1].cdOb; rowInst: CD.Instance _ PW.IncludeInCell[cell: obj, obj: bottomRow, position: [0, offset], orientation: 0]; CDProperties.PutInstanceProp[rowInst, $InstanceName, Rope.Cat["Row", Convert.RopeFromInt[rowChan.chanNum]]]; offset _ offset + RTBasic.IRSize[ bottomRow].y; IF chan # rowChans.count THEN { topRow: CD.Object _ lgRows.rows[rowChan.chanNum].cdOb; result: Route.RoutingResult _ PWRoute.DoRoute[bottomRow, topRow, rowChan.exitCells[left], rowChan.exitCells[right], routerParams, FALSE, channel]; channel: CD.Object _ PWRoute.GetRouting[result, NIL]; chanInst: CD.Instance _ PW.IncludeInCell[cell: obj, obj: channel, position: [0, offset], orientation: 0]; RTBasic.SetCDCellName[channel, Rope.Cat[handle.name, "Channel", Convert.RopeFromInt[rowChan.chanNum]]]; CDProperties.PutInstanceProp[chanInst, $InstanceName, Rope.Cat["Channel", Convert.RopeFromInt[rowChan.chanNum]]]; offset _ offset + RTBasic.IRSize[channel].y; rowChans.chans[chan].routing _ result}}}; 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.RepositionCell[obj]; RTBasic.SetCDCellName[obj, Rope.Cat[handle.name, "Center"]]}; END. pSCRouteImpl.mesa: Implementation of SC.DetailedRoute Copyright c 1986 by Xerox Corporation. All rights reserved. Frank Bowers June 3, 1986 10:58:48 am PDT Bryan Preas August 13, 1986 5:21:56 pm PDT [instance: SCPrivate.Instance, pin: NAT, netPin: SCPrivate.PinNet] [instance: SCPrivate.Instance, pin: NAT, netPin: SCPrivate.PinNet] [side: SC.Side, bpRow: SCPrivate.BpRow] RETURNS [quit: BOOL _ FALSE] [side: SC.Side, bpRow: SCPrivate.BpRow] RETURNS [quit: BOOL _ FALSE] create wire and copy pin to end of wire [row: SCPrivate.MaxRowSr, lgRow: SCPrivate.LgRow] RETURNS [quit: BOOL _ FALSE] [rect: SC.Rect, position: CD.Position, netPin: SCPrivate.PinNet, cell: CD.Object] ext end power pins on edges and put in power rails [side: SC.Side, bpRow: SCPrivate.BpRow] RETURNS [quit: BOOL _ FALSE] -- Start with an empty cell of appropriate interestRect (origin in 0,0) -- Parse the pins [pos: NAT, instance: SCPrivate.Instance] RETURNS [quit: BOOL _ FALSE] route the channels and include rows and channels into the layout [chan: SCPrivate.MaxChanSr, rowChan: SCPrivate.RowChan] RETURNS [quit: BOOL _ FALSE] route each channel ΚΙ˜šœ5™5Icodešœ Οmœ1™Kšœ žœ-˜:Jšœžœ9˜AJšœ žœZ˜fJšœY˜Y——J˜—šŸ œ˜(Jš $‘ ™BJ™šžœ žœžœ%žœ˜Cšžœ6žœ0žœ˜qKšœ žœ-˜:Jšœžœ9˜AJšœ žœZ˜fJšœY˜Y——J˜—šŸœ˜0Jšœ8˜8J˜—šŸœ˜0Jšœ=˜=J˜—Kšœ#žœ˜=Kšœ-˜-Jšœ,˜,Jšœžœ˜Jšœ˜šžœ žœ˜Jšœ&˜&JšœR˜R—šžœžœžœ˜&Jšœ.˜.JšœR˜R—šžœ˜Jšœ*˜*JšœR˜RJšœ)˜)JšœT˜T—J˜—šŸœžœ žœ(˜OJšœžœ˜J˜šŸœL˜TJ˜—šŸœ˜$JšœD™Dšžœ žœžœ˜%Jšœ!˜!Kšœ@˜@Kšœ!˜!—K˜—Kšœ1˜1J˜—šŸœžœ žœ(˜OJ˜šŸœ˜$JšœD™Dšžœ žœžœ˜%Jšœžœ˜Kšœžœ"˜*šžœžœΟc)˜:JšœD˜DJšœ=˜=Jšžœ˜—Jšœ%’˜@Jšœ˜—J˜—Jšœ žœ+˜9Kšœ1˜1J˜J˜—š Ÿœžœ žœžœ)žœžœ˜—Jšžœžœ ˜J˜Jšœ žœ)˜8Jšœ ˜ Jšœžœ<˜CJšœ|˜|Jšœ˜J˜—š Ÿœžœ žœžœžœ˜PJšžœžœ ˜Jšœžœ˜Jšœžœ˜Jšœžœ,˜5Jšœžœ)˜2Jšœ)˜)J˜—š Ÿœžœ žœžœžœ˜_Kšžœžœ žœ˜"K™'K˜šžœ)žœ˜1Kšœžœ ˜Kšœ2˜2Kšœžœ2˜:Kšœžœ:˜CKšœ ˜ Kšœ žœb˜nKšœ žœ˜'Kšœ2˜2Kšœ)˜)KšœF˜FKšœ*žœžœ žœ˜[Kšœ˜—K˜—š Ÿ œžœ žœ žœ žœ ˜EJ˜šŸ œ˜%JšœN™NJ˜šŸ œžœ˜ šžœOž˜UJšœ3˜3J˜——Jšœžœ˜J˜Jšœžœ˜#Jšœžœ(˜8Jšœžœ6˜GJšœ-˜-Jšœ žœ˜,Kšœ žœ˜$Kšœ žœ-˜:K˜šžœžœžœ’!˜UKšœ ˜ Kšœ{žœ˜‚Kšœf˜fKšœ=˜=Kšœ~žœ˜…Kšœh˜h—šžœžœžœ’#˜KKšœ/˜/Kšœ~žœ˜…Kšœh˜hJšœ žœ˜—šžœ’˜Jšœžœžœ˜&—JšœC˜CJ˜—šŸœ ˜.Kšœ3˜3Jšœ(˜(šžœžœ"ž˜@J˜8—Jšœ7˜7Jšœ@žœ˜EJšœ(˜(šžœžœ"ž˜@Jšœ9˜9——J˜šŸœ˜&KšœžœO˜XJšœ žœ žœ'˜@Jšœ2˜2Jšœ1˜1J˜—šŸ œ˜'Jš  œ  œ žœ  !žœ ™QJ™JšœžœA˜JJšœ žœ žœ;˜TJšœ4˜4Jšœ7˜7J˜—Kšœ#žœ˜=Jšœžœ˜/Jšœžœžœžœ˜IJšœ%žœ—žœžœ˜βJšœB˜BJšœO˜OJšœ*˜*Jšœ˜J˜—š Ÿœžœ žœžœžœIžœ ˜ J˜Jšœžœ7˜>Jšœ'žœžœ'žœ ˜sJšœžœ*˜1Jš œ žœ žœEžœžœžœ ˜†Jšœ)˜)Jšœ-˜-J˜—šŸ œžœ žœžœ˜5Jšžœžœ ˜Jšœ3™3J™šŸœ˜$JšœD™DKšžœ žœžœ˜%˜šŸ œžœ˜ Jšœ žœ#˜2JšœO˜Ošžœžœž˜šœ˜Jšœ‡˜‡—Jšœ$žœ˜)Jšžœ6˜=—J˜—Kšœ7˜7Kšœžœ žœ!˜7Kšœ žœ%˜3Kšœžœ˜'KšœH˜HKšœžœžœžœ˜DKš œžœžœžœžœ˜VKšœžœK˜TKšœsžœ˜zJšœ7žœžœžœ˜lKšœžœB˜IKšœU˜UKšœY˜Y—K˜—Jšœžœžœžœ˜*Jšœ2˜2Jšœ žœ˜(Jšœ#žœ˜=J˜Kšœ0˜0JšœS˜SJ˜—š Ÿ œžœžœ žœ žœ žœ ˜LJšœžœ˜Jšœžœ1˜RJšœ˜JšœG˜GJšœ˜Jšœ(˜(Jšœ žœžœ1˜@J˜—šŸ œžœ žœ&žœ žœ(žœžœžœžœ(˜ΗJ˜šŸ œ˜,Jšœžœ˜Jšœ8˜8šžœžœ˜Jš œžœžœžœžœ˜2JšœžœY˜`J˜——Jšœžœ˜Jšœ+’™GJšžœžœžœ˜Jšœžœ’˜@Jšœ=’˜XJ™JšœN˜NJšœ˜J˜—š Ÿœžœžœžœžœ žœ ˜bšœžœž˜JšœA˜AJšœA˜AJšžœžœ˜—J˜—šŸ œžœžœ žœ˜Kšœ žœž˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšžœžœ˜—J˜—š Ÿœžœžœžœžœ žœ˜nJšœ žœ˜*šžœž˜Jšœ˜Jšœ˜Jšžœžœ˜——J˜šŸ œžœ žœžœ.žœ žœžœ(˜¦K˜šŸœ˜+KšœE™EKšœžœ˜)Kšœžœ žœi˜JšœC˜CJšœM˜MKšœ,˜,J˜—Kšœžœ ˜šžœžœžœ˜KšœžœR˜YKšœ0˜0—J˜JšœM˜MK˜šžœžœžœ˜KšœžœS˜ZKšœ1˜1—Jšœ˜Jšœ\˜\—J˜šŸœžœžœ žœ žœžœžœ(˜…Kšœžœ ˜šžœžœžœ˜KšœžœJ˜QKšœ(˜(—šžœžœžœ˜KšœžœJ˜QKšœ(˜(—šžœžœžœ˜KšœžœJ˜QKšœ(˜(—šžœžœžœ˜KšœžœJ˜QKšœ(˜(—šžœžœžœ˜KšœžœJ˜QKšœ(˜(—Jšœ˜Jšœ"˜"K˜—š Ÿ œžœ žœ-žœžœ(˜€Kšœ@™@K˜šŸ œ ˜+KšœT™TKšœ™K˜šžœ žœ˜Jšœ žœ.˜;Kšœ žœ žœQ˜kKšœl˜lKšœ/˜/šžœžœ˜Jšœžœ,˜6Jšœ‚žœ ˜’Jšœ žœ%žœ˜5Kšœ žœ žœO˜iKšœg˜gKšœq˜qKšœ,˜,Kšœ)˜)——K˜—Kšœ#žœ˜=Kšœ3˜3Kšœ-˜-Kšœžœ ˜Kšœ7˜7Jšœ˜Jšœ=˜=—J˜šžœ˜J˜J˜J˜J˜J˜J˜—J˜—…—BΒUϋ