DIRECTORY CoreClasses, Rope, SC, SCInstUtil, SCPrivate, SCRowUtil, SCUtil, RTSets; SCInstUtilImpl: CEDAR PROGRAM IMPORTS SC, SCInstUtil, SCRowUtil, SCUtil, Rope, RTSets EXPORTS SCInstUtil SHARES SC = BEGIN defltLgOrien: PUBLIC SCPrivate.Orientation _ 1; defltBpOrien: PUBLIC ARRAY SC.Side OF SCPrivate.Orientation _ [3, 1, 4, 2]; InstWidth: PUBLIC PROCEDURE[inst: SCPrivate.Instance] RETURNS[width: SC.Number] = BEGIN orien: SCPrivate.OrientationOrNone _ inst.curOrien; SELECT orien FROM 0, 1, 3, 5, 6 => width _ inst.object.size.p; 2, 4, 7, 8 => width _ inst.object.size.q; ENDCASE; END; InstHeight: PUBLIC PROCEDURE[inst: SCPrivate.Instance] RETURNS[height: SC.Number] = BEGIN orien: SCPrivate.OrientationOrNone _ inst.curOrien; SELECT orien FROM 0, 1, 3, 5, 6 => height _ inst.object.size.q; 2, 4, 7, 8 => height _ inst.object.size.p; ENDCASE; END; BpHeight: PUBLIC PROCEDURE[inst: SCPrivate.Instance] RETURNS[height: SC.Number] = { IF inst.whichClass # io THEN SC.Error[programmingError, Rope.Cat["Instance: ", inst.name, " should be an IO"]]; SELECT inst.curSide FROM top, bottom => height _ InstHeight[inst]; left, right => height _ InstWidth[inst]; ENDCASE => SC.Error[programmingError, NIL]}; BpWidth: PUBLIC PROCEDURE[inst: SCPrivate.Instance] RETURNS[width: SC.Number] = { IF inst.whichClass # io THEN SC.Error[programmingError, Rope.Cat["Instance: ", inst.name, " should be an IO"]]; SELECT inst.curSide FROM top, bottom => width _ InstWidth[inst]; left, right => width _ InstHeight[inst]; ENDCASE => SC.Error[programmingError, NIL]}; MinMaxBPOffset: PUBLIC PROCEDURE[handle: SC.Handle, side: SC.Side] RETURNS [minOffset, maxOffset: SC.Number] = { InstProc: SCRowUtil.EachInstProc = { minOffset _ MIN[minOffset, instance.offset]; maxOffset _ MAX[maxOffset, instance.offset]}; minOffset _ LAST[INT]; maxOffset _ -minOffset; [] _ SCRowUtil.EnumerateAllInstsOnSide[handle, side, InstProc]}; BpOffsets: PUBLIC PROCEDURE[handle: SC.Handle, side: SC.Side, pos1, pos2: SCPrivate.ZMaxPosSr] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; bpRow: SCPrivate.BpRow _ layoutData.bpRows[side]; offset: SC.Number; posA: SCPrivate.ZMaxPosSr _ MIN[pos1, pos2]; posB: SCPrivate.ZMaxPosSr _ MAX[pos1, pos2]; IF posA <= 1 THEN {posA _ 1; offset _ 0} ELSE {inst: SCPrivate.Instance _ bpRow.bpsOnSide[posA-1]; offset _ inst.offset + InstWidth[inst] + bpRow.bpSpacing}; IF posB = 0 OR posB > bpRow.nBpsOnSide THEN posB _ bpRow.nBpsOnSide; FOR posIndex: SCPrivate.ZMaxPosSr IN [posA .. posB] DO inst: SCPrivate.Instance _ bpRow.bpsOnSide[posIndex]; width: SC.Number _ BpWidth[inst]; IF side = bottom OR side = right THEN inst.offset _ offset ELSE inst.offset _ offset + width; offset _ offset + width + bpRow.bpSpacing; ENDLOOP}; BpPos: PUBLIC PROCEDURE[handle: SC.Handle, inst: SCPrivate.Instance] RETURNS[result: SC.Number] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; bpRow: SCPrivate.BpRow _ layoutData.bpRows[inst.curSide]; IF inst.whichClass # io THEN SC.Error[programmingError, " "]; SELECT inst.curSide FROM right => result _ bpRow.sideOrg.q + inst.offset; bottom => result _ bpRow.sideOrg.p + inst.offset; left => result _ bpRow.sideOrg.q - inst.offset; top => result _ bpRow.sideOrg.p - inst.offset; ENDCASE}; PosOf: PUBLIC PROCEDURE[inst: SCPrivate.Instance, pin: SCPrivate.ObjectPin] RETURNS [pinDes: SCInstUtil.PinDescription] = { x, y: SC.Number; SELECT pin.pinPos.side FROM bottom => {x _ pin.pinPos.location; y _ pin.pinPos.depth}; right => {x _ InstWidth[inst] - pin.pinPos.depth; y _ pin.pinPos.location}; top => {x _ InstWidth[inst] - pin.pinPos.location; y _ InstHeight[inst] - pin.pinPos.depth}; left => {x _ pin.pinPos.depth; y _ InstHeight[inst] - pin.pinPos.location}; ENDCASE; SELECT inst.curOrien FROM 0, 1 => {pinDes.xPos _ x; pinDes.yPos _ y}; 2 => {pinDes.xPos _ y; pinDes.yPos _ InstWidth[inst] - x}; 3 => {pinDes.xPos _ InstWidth[inst] - x; pinDes.yPos _ InstHeight[inst] - y}; 4 => {pinDes.xPos _ InstHeight[inst] - y; pinDes.yPos _ x}; 5 => {pinDes.xPos _ InstWidth[inst] - x; pinDes.yPos _ y}; 6 => {pinDes.xPos _ x; pinDes.yPos _ InstHeight[inst] - y}; 7 => {pinDes.xPos _ y; pinDes.yPos _ x}; 8 => {pinDes.xPos _ InstHeight[inst] - y; pinDes.yPos _ InstWidth[inst] - x}; ENDCASE; pinDes.sideOn _ SCUtil.SideTranslate[pin.pinPos.side, inst.curOrien]}; PowerPosOf: PUBLIC PROCEDURE[handle: SC.Handle, row: SCPrivate.ZMaxRowSr, net: SCPrivate.Net, lRSide: SCPrivate.LRSide] RETURNS [xPos, yPos: SC.Number _ 0, found: BOOLEAN _ FALSE] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; lgRow: SCPrivate.LgRow _ layoutData.lgRows.rows[row]; maxPos: SCPrivate.ZMaxPosSr _ lgRow.nLgsOnRow; pd: SCInstUtil.PinDescription _ [0, 0, bottom]; inst: SCPrivate.Instance; IF maxPos > 0 THEN { pin: SCPrivate.ObjectPin; SELECT lRSide FROM left => inst _ lgRow.lgsOnRow[1]; right => inst _ lgRow.lgsOnRow[maxPos]; ENDCASE; pin _ SCUtil.FindPin[inst.object, net.name]; IF pin # NIL THEN {pd _ PosOf[inst, pin]; found _ TRUE} ELSE -- this is a hack until cells have power pins {IF Rope.Equal[net.name, layoutData.powerBuses[lRSide].name] THEN {SELECT lRSide FROM left => {pd.xPos _ 0; pd.yPos _ InstHeight[inst] - handle.rules.sideRules.trunkWidth/2; found _ TRUE}; right => {pd.xPos _ InstWidth[inst]; pd.yPos _ handle.rules.sideRules.trunkWidth/2; found _ TRUE}; ENDCASE}}}; xPos _ lgRow.rowOrg.p + inst.offset + pd.xPos; yPos _ lgRow.rowOrg.q + pd.yPos}; RotateRect: PUBLIC PROCEDURE[inst: SCPrivate.Instance, defRect: SC.Rect] RETURNS [newRect: SC.Rect] = { SELECT inst.curOrien FROM 1 => {newRect.x1 _ defRect.x1; newRect.y1 _ defRect.y1; newRect.x2 _ defRect.x2; newRect.y2 _ defRect.y2}; 2 => {newRect.x1 _ defRect.y1; newRect.y1 _ InstWidth[inst] - defRect.x1; newRect.x2 _ defRect.y2; newRect.y2 _ InstWidth[inst] - defRect.x2}; 3 => {newRect.x1 _ InstWidth[inst] - defRect.x1; newRect.y1 _ InstHeight[inst] - defRect.y1; newRect.x2 _ InstWidth[inst] - defRect.x2; newRect.y2 _ InstHeight[inst] - defRect.y2}; 4 => {newRect.x1 _ InstHeight[inst] - defRect.y1; newRect.y1 _ defRect.x1; newRect.x2 _ InstHeight[inst] - defRect.y2; newRect.y2 _ defRect.x2}; 5 => {newRect.x1 _ InstWidth[inst] - defRect.x1; newRect.y1 _ defRect.y1; newRect.x2 _ InstWidth[inst] - defRect.x2; newRect.y2 _ defRect.y2}; 6 => {newRect.x1 _ defRect.x1; newRect.y1 _ InstHeight[inst] - defRect.y1; newRect.x2 _ defRect.x2; newRect.y2 _ InstHeight[inst] - defRect.y2}; 7 => {newRect.x1 _ defRect.y1; newRect.y1 _ defRect.x1; newRect.x2 _ defRect.y2; newRect.y2 _ defRect.x2}; 8 => {newRect.x1 _ InstHeight[inst] - defRect.y1; newRect.y1 _ InstWidth[inst] - defRect.x1; newRect.x2 _ InstHeight[inst] - defRect.y2; newRect.y2 _ InstWidth[inst] - defRect.x2}; ENDCASE}; LgOffsets: PUBLIC PROCEDURE[handle: SC.Handle, row: SCPrivate.ZMaxRowSr, pos1, pos2: SCPrivate.ZMaxPosSr] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; lgRows: SCPrivate.LgRows _ layoutData.lgRows; lgRow: SCPrivate.LgRow _ lgRows.rows[row]; offset: SC.Number; posA: SCPrivate.ZMaxPosSr _ MIN[pos1, pos2]; posB: SCPrivate.ZMaxPosSr _ MAX[pos1, pos2]; IF posA <= 1 THEN {posA _ 1; offset _ 0} ELSE {inst: SCPrivate.Instance _ lgRow.lgsOnRow[posA-1]; offset _ inst.offset + InstWidth[inst]}; IF posB = 0 OR posB > lgRow.nLgsOnRow THEN posB _ lgRow.nLgsOnRow; FOR posIndex: SCPrivate.MaxPosSr IN [posA .. posB] DO inst: SCPrivate.Instance _ lgRow.lgsOnRow[posIndex]; SELECT inst.whichClass FROM ft, logic => {inst.offset _ offset; offset _ offset + InstWidth[inst]}; ENDCASE; ENDLOOP; IF posB = lgRow.nLgsOnRow THEN {lgRow.size.p _ offset; IF lgRow.size.p >= lgRows.maxRowWidth THEN {lgRows.maxRowWidth _ lgRow.size.p; lgRows.numMaxRows _ 1} ELSE [lgRows.maxRowWidth, lgRows.numMaxRows] _ SCRowUtil.FindMaxRow[handle]}}; AllOffsets: PUBLIC PROCEDURE [handle: SC.Handle] = { RowRroc: SCRowUtil.EachRowProc = { LgOffsets[handle, row, 0, 0]}; SideProc: SCRowUtil.EachSideProc = { BpOffsets[handle, side, 0, 0]}; [] _ SCRowUtil.EnumerateRows[handle, RowRroc]; [] _ SCRowUtil.EnumerateSides[handle, SideProc]}; AsgnChanPos: PUBLIC PROCEDURE[handle: SC.Handle] = BEGIN EachSide: SCRowUtil.EachSideProc = { sideDim[side] _ bpRows[side].size.p + (bpRows[side].nBpsOnSide -1) * bpRows[side].bpSpacing}; layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; lgRows: SCPrivate.LgRows _ layoutData.lgRows; bpRows: SCPrivate.BpRows _ layoutData.bpRows; sideChans: SCPrivate.SideChans _ layoutData.sideChans; rowChans: SCPrivate.RowChans _ layoutData.rowChans; nRows: SCPrivate.MaxRowSr _ lgRows.count; nChans: SCPrivate.MaxChanSr _ rowChans.count; sideDim: ARRAY SC.Side OF SC.Number; upperActiveLimit, rightActiveLimit, realTotHeight: SC.Number; [] _ SCRowUtil.EnumerateSides[handle, EachSide]; FOR row: SCPrivate.MaxRowSr IN [1 .. nRows] DO IF lgRows.rows[row].dimInvalid THEN SCRowUtil.ComputeRowHeight[handle, row]; ENDLOOP; IF bpRows[left].dimInvalid THEN SCRowUtil.ComputeSideHeight[handle, left]; IF bpRows[bottom].dimInvalid THEN SCRowUtil.ComputeSideHeight[handle, bottom]; rowChans.chans[1].chanPos _ bpRows[bottom].size.q; sideChans[left].sideChanPos _ bpRows[left].size.q; lgRows.horzRowOrg _ bpRows[left].size.q + sideChans[left].sideChanResult; lgRows.rows[1].rowOrg.p _ lgRows.horzRowOrg + (lgRows.maxRowWidth - lgRows.rows[1].size.p)/2; lgRows.rows[1].rowOrg.q _ rowChans.chans[1].chanPos + rowChans.chans[1].chanResult; FOR chan: SCPrivate.MaxChanSr IN [2 .. nChans] DO rowChans.chans[chan].chanPos _ lgRows.rows[chan-1].rowOrg.q + lgRows.rows[chan-1].size.q; IF chan <= nRows THEN { lgRows.rows[chan].rowOrg.q _ rowChans.chans[chan].chanPos + MAX[rowChans.chans[chan].chanWidth, rowChans.chans[chan].minChanWidth]; lgRows.rows[chan].rowOrg.p _ lgRows.horzRowOrg + (lgRows.maxRowWidth - lgRows.rows[chan].size.p)/2}; ENDLOOP; sideChans[right].sideChanPos _ lgRows.horzRowOrg + lgRows.maxRowWidth; upperActiveLimit _ rowChans.chans[nChans].chanPos + MAX[rowChans.chans[nChans].chanWidth, rowChans.chans[nChans].minChanWidth]; layoutData.totHeight _ realTotHeight _ upperActiveLimit + bpRows[top].size.q; rightActiveLimit _ sideChans[right].sideChanPos + MAX[sideChans[right].sideChanWidth, sideChans[right].minSideChanWidth]; layoutData.totWidth _ rightActiveLimit + bpRows[right].size.q; bpRows[bottom].sideOrg.q _ 0; bpRows[bottom].sideOrg.p _ lgRows.horzRowOrg + (lgRows.maxRowWidth - sideDim[bottom]) / 2; IF bpRows[top].dimInvalid THEN SCRowUtil.ComputeSideHeight[handle, top]; IF bpRows[right].dimInvalid THEN SCRowUtil.ComputeSideHeight[handle, right]; bpRows[right].sideOrg.p _ rightActiveLimit; bpRows[right].sideOrg.q _ (realTotHeight - sideDim[right])/ 2; bpRows[top].sideOrg.p _ lgRows.horzRowOrg + (lgRows.maxRowWidth + sideDim[top])/ 2; bpRows[top].sideOrg.q _ upperActiveLimit; bpRows[left].sideOrg.p _ 0; bpRows[left].sideOrg.q _ (realTotHeight +sideDim[left])/ 2; END; ChansForInsts: PUBLIC PROCEDURE[handle: SC.Handle, insts: SCPrivate.InstanceList] RETURNS [touchesChan: SCPrivate.ChanSet _ RTSets.RTMdSetEmpty] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; FOR instList: SCPrivate.InstanceList _ insts, instList.rest WHILE instList # NIL DO inst: SCPrivate.Instance _ instList.first; SELECT inst.whichClass FROM ft, logic => {IF inst.curRow > 0 THEN {touchesChan _ RTSets.RTMdSetUnion[touchesChan, RTSets.RTMdSetGenerateElement[(inst.curRow+1)-1]]; touchesChan _ RTSets.RTMdSetUnion[touchesChan , RTSets.RTMdSetGenerateElement[(inst.curRow)-1]]}}; io => {IF inst.curSide = bottom THEN touchesChan _ RTSets.RTMdSetUnion[touchesChan, RTSets.RTMdSetGenerateElement[(1)-1]]; IF inst.curSide = top THEN touchesChan _ RTSets.RTMdSetUnion[touchesChan, RTSets.RTMdSetGenerateElement[(layoutData.rowChans.count)-1]]}; ENDCASE; ENDLOOP}; CheckInst: PUBLIC PROCEDURE[handle: SC.Handle, inst: SCPrivate.Instance] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; SELECT inst.whichClass FROM logic, ft => {row: SC.Number _ inst.curRow; pos: SC.Number _ inst.curPos; lgRow: SCPrivate.LgRow _ layoutData.lgRows.rows[row]; IF row <= 0 OR row > layoutData.rowChans.count THEN {IF ~(row = 0 AND pos = 0 AND inst.whichClass = ft) THEN SC.Error[programmingError, " "]} ELSE IF pos <= 0 OR pos > lgRow.nLgsOnRow THEN SC.Error[programmingError, " "] ELSE {trialInst: SCPrivate.Instance _ lgRow.lgsOnRow[pos]; IF inst # trialInst THEN SC.Error[programmingError, " "]}}; io => {side: SC.Side _ inst.curSide; pos: SC.Number _ inst.curPos; bpRow: SCPrivate.BpRow _ layoutData.bpRows[side]; IF side = none THEN SC.Error[programmingError, " "] ELSE IF pos <= 0 OR pos > bpRow.nBpsOnSide THEN SC.Error[programmingError, " "] ELSE {trialInst: SCPrivate.Instance _ bpRow.bpsOnSide[pos]; IF inst # trialInst THEN SC.Error[programmingError, " "]}}; ENDCASE}; CheckInsts: PUBLIC PROCEDURE[handle: SC.Handle] = { EachInst: SCInstUtil.EachInstanceProc = { CheckInst[handle, instance]}; [] _ SCInstUtil.EnumerateInstances[handle, EachInst]}; EnumerateInstances: PUBLIC PROC [handle: SC.Handle, eachInstance: SCInstUtil.EachInstanceProc] RETURNS [quit: BOOL] = { structureData: SCPrivate.StructureData _ NARROW[handle.structureData]; FOR inst: SCPrivate.MaxInstanceSr IN [1 .. structureData.instances.count] DO [] _ eachInstance[structureData.instances.inst[inst]]; ENDLOOP}; EnumeratePinsOnInst: PUBLIC PROC [instance: SCPrivate.Instance, eachPin: SCInstUtil.EachPinProc] RETURNS [quit: BOOL _ FALSE] = { FOR pin: NAT IN [0 .. instance.pinNets.size) WHILE ~quit DO quit _ eachPin[instance, pin, instance.pinNets.n[pin]]; ENDLOOP}; DefineInstance: PUBLIC PROCEDURE [handle: SC.Handle, instanceName: Rope.ROPE, object: SCPrivate.Object, coreInstance: CoreClasses.CellInstance, equivName: Rope.ROPE _ NIL] RETURNS [instance: SCPrivate.Instance _ NIL] = { structureData: SCPrivate.StructureData _ NARROW[handle.structureData]; instances: SCPrivate.Instances _ structureData.instances; object.numTimesUsed _ object.numTimesUsed + 1; SELECT object.typeClass FROM logic => {instance _ NEW[logic SCPrivate.InstanceRec]; instance.whichClass _ logic; instances.numLogics _ instances.numLogics + 1}; ft => {instance _ NEW[ft SCPrivate.InstanceRec]; instance.whichClass _ ft; instances.numFts _ instances.numFts + 1}; io => {instance _ NEW[io SCPrivate.InstanceRec]; instance.equivPortClass _ equivName; instance.whichClass _ io; instances.numIOs _ instances.numIOs + 1}; ENDCASE => SC.Error[callingError, Rope.Cat["Feedthrus not allowed in input: ", instance.name, ", object: ", object.name, "\n"]]; instance.name _ instanceName; instance.object _ object; instance.pinNets _ NEW[SCPrivate.PinNetsRec[object.numPins]]; instances.count _ instances.count + 1; instance.instanceNum _ instances.count; instances.inst[instances.count] _ instance}; NumInstsOnList: PUBLIC PROCEDURE [instances: SCPrivate.InstanceList] RETURNS [count: SCPrivate.ZMaxInstanceSr _ 0] = { FOR instList: SCPrivate.InstanceList _ instances, instList.rest WHILE instList # NIL DO count _ count + 1; ENDLOOP}; END. ¸file ///StdCell/SCInstUtilImpl.mesa compoments utility routines -- InstWidth - find width of component at current orientation -- InstHeight - find height of component at current orientation -- BpHeight - find height of bp when considering side it is on -- BpWidth - find width of bp when considering side it is on -- MinMaxBPOffset - find min and max offsets of bonding pads on side -- BpOffsets - find offsets of bonding pads on side -- BpPos - find position of inst on side -- PosOf- find the position (side, x, and y) of a component on a pin -- PowerPosOf- find the position (x, and y) of a power pin -- RotateRect- Rotate a rectangle of a cell -- LgOffsets- determine offsets of components in row -- AllOffsets - determine all component offsets -- AsgnChanPos - assign current positions to horizontal and vertical channels -- CheckInsts - check row and position of comps -- CheckInst - check row and position of a inst -- EnumeratePinsOnInst - enumerate the net pins on an instance find width of component at current orientation find current orientation now get width based on orientation find height of component at current orientation find current orientation now get height based on orientation find height of bp when considering its side (this is, the dimension perpendicular to side) find height of bp when considering side it is on this is along to side find offsets of bonding pads on side find offsets of bonding pads on side find position of inst on side assumes that channel and bp positions have been assigned. find the position (side, x, and y) of a component on a pin first find the position at normal orientation now rotate the pin position to current orien find the position (x, and y) of a power pin find the position of a rotated rectangle wintin a component now rotate the pin position to current orien determine offsets of components in row compute offsets of all comps on row update max row widths determine all component offsets assign current positions to horizontal and vertical channels compute the minimum channel dimensions row 1 and channel 1 data now the interior channels now the right side get total height and width now update the side orgs update right side data update top side data update left side data find chans that these comps touch check row and position of a inst check row and position of a inst define a component (an instance of object) construct he instance record initialize the nets connected to these pins Êÿ˜Jšœ#™#J˜Jšœ™JšÏn œ1™=Jš œ2™?Jšœœ3™>Jšœœ2™J˜šÏk ˜ J˜ Jšœ˜Jšžœ˜Jšœ ˜ Jšœ ˜ Jšœ ˜ J˜Jšœ˜J˜—šœžœž˜Jšžœžœ-˜7Jšžœ ˜Jšžœžœ˜ J˜Jšž˜Jšœžœ˜/Jš œžœžœžœžœ&˜KJ˜—˜Jšœ.™.š œžœž œžœžœ ˜RJ˜Jšž˜Jšœ™Jšœ3˜3J˜Jšœ"™"šžœž˜Jšœ,˜,Jšœ)˜)Jšžœ˜—Jšžœ˜J˜—Jšœ/™/š œžœž œžœ žœ ˜TJ˜Jšž˜Jšœ™šœ3˜3J˜—Jšœ$™$šžœž˜Jšœ-˜-Jšœ*˜*Jšžœ˜—Jšžœ˜J˜—Jšœ+™+Jšœ/™/š œžœž œžœ žœ ˜SJ˜šžœž˜JšžœP˜RJ˜—šžœž˜Jšœ)˜)Jšœ(˜(Jšžœžœžœ˜,J˜——Jšœ0™0Jšœ™š œžœž œžœžœ ˜QJ˜šžœž˜JšžœP˜RJ˜—šžœž˜Jšœ'˜'Jšœ(˜(Jšžœžœžœžœ˜,—J™—Jšœ%™%šœžœž œ žœžœžœžœ ˜pJ˜šœ$˜$Jšœ žœ˜,Jšœ žœ˜-J˜—Jšœ žœžœ˜Jšœ˜Jšœ@˜@J˜—Jšœ%™%š œžœž œ žœžœ+˜bJ˜Icodešœ#žœ˜=Kšœ1˜1Jšœžœ˜Jšœžœ ˜,Jšœžœ ˜,Jšžœ žœ˜(šž˜Jšœ4˜4Jšœ:˜:—Jšžœ žœžœ˜DJ˜šžœžœžœ˜7Jšœ5˜5Jšœžœ˜!šžœžœž˜%Jšœ˜—šž˜Jšœ˜—Jšœ*˜*Jšžœ˜ —J˜—Jšœ™Jšœ9™9š œžœž œ žœ#žœ žœ ˜cJ˜Kšœ#žœ˜=Kšœ9˜9šžœž˜Jšžœ˜ —šžœž˜Jšœ0˜0Jšœ1˜1Jšœ/˜/Jšœ.˜.Jšžœ˜ —J˜—Jšœ;™;šœžœž œ4˜KJšžœ(˜/J˜Jšœžœ˜J™Jšœ.™.šžœž˜Jšœ:˜:JšœK˜KJšœ\˜\JšœK˜Kšžœ˜ J˜——Jšœ-™-šžœž˜Jšœ+˜+Jšœ:˜:JšœM˜MJšœ;˜;Jšœ:˜:Jšœ;˜;Jšœ(˜(JšœM˜MJšžœ˜—J˜JšœF˜FJ˜—Jšœ,™,š œžœž œ žœP˜wJšžœžœžœžœ˜?J˜Kšœ#žœ˜=Kšœ5˜5Jšœ.˜.J˜0Jšœ˜šžœ žœ˜Jšœ˜šžœž˜Jšœ!˜!Jšœ'˜'Jšžœ˜ —Jšœ,˜,J˜šžœžœž˜Jšœ žœ˜%—šžœÏc-˜2šœžœ:ž˜Ašœžœž˜šœ˜JšœA˜AJšœžœ˜—šœ$˜$Jšœ.˜.Jšœžœ˜—Jšžœžœ˜ ————Jšœ.˜.Jšœ!˜!J˜—Jšœ;™;š œžœž œ$žœ˜HJšžœ žœ ˜J˜Jšœ-™-šžœž˜šœ˜Jšœ2˜2Jšœ2˜2—šœ˜JšœD˜DJšœD˜D—šœ˜JšœW˜WJšœW˜W—šœ˜JšœE˜EJšœE˜E—šœ˜JšœD˜DJšœD˜D—šœ˜JšœE˜EJšœE˜E—šœ˜Jšœ2˜2Jšœ2˜2—šœ˜JšœW˜WJšœW˜W—Jšžœ˜ —J˜—Jšœ'™'š œžœž œ žœG˜mJ˜Jšœ#™#Jšœ#žœ˜=Jšœ-˜-Jšœ*˜*Jšœžœ˜Jšœžœ ˜,Jšœžœ ˜,Jšžœ žœ˜(šž˜Jšœ3˜3Jšœ(˜(—Jšžœ žœžœ˜BJ˜šžœžœžœ˜6Jšœ4˜4šžœž˜JšœG˜GJšžœ˜—Jšžœ˜J˜—Jšœ™šžœž˜Jšœ˜šžœ$ž˜*Jšœ:˜:—JšžœK˜O—J˜—Jšœ ™ š œžœž œ žœ ˜4J˜šœ"˜"Jšœ˜—šœ$˜$Jšœ˜—Jšœ.˜.Jšœ1˜1J˜—Jšœ=™=š œžœž œ žœ ˜3J˜Jšž˜Jšœ&™&šœ$˜$Jšœ]˜]J˜—Jšœ#žœ˜=Jšœ-˜-Jšœ-˜-Jšœ6˜6Jšœ3˜3Jšœ)˜)Jšœ-˜-Jš œ žœžœžœžœ˜$Jšœ3žœ˜=J˜Jšœ0˜0J˜šžœžœžœ˜/Jšžœžœ)˜LJšžœ˜—J˜Jšœ™Jšžœžœ+˜JJšžœžœ-˜NJšœ2˜2Jšœ2˜2J˜JšœI˜IJšœ]˜]JšœS˜SJ˜Jšœ™šžœžœžœ˜2JšœY˜Yšžœžœ˜Jšœ<žœD˜ƒJšœd˜d—šžœ˜J˜—Jšœ™šœF˜FJ˜—Jšœ™J˜Jšœ4žœH˜JšœM˜MJ˜šœ1˜1JšžœD˜G—J˜Jšœ>˜>J˜Jšœ™Jšœ˜šœZ˜ZJ˜—Jšœ™Jšžœžœ*˜HJšžœžœ,˜LJšœ+˜+šœ>˜>J˜—Jšœ™JšœS˜Sšœ)˜)J˜—Jšœ™Jšœ˜Jšœ;˜;Jšžœ˜—J˜—Jšœ"™"š œžœž œ žœ'˜QJšžœ;˜BJ˜Jšœ#žœ˜=šžœ9žœ žœžœ˜TJšœ*˜*šžœž˜šœžœž˜%šœb˜bJšœb˜b——šœžœž˜$JšœU˜Ušžœž˜Jšœn˜n——Jšžœ˜—Jšžœ˜ —J˜—Jšœ!™!š œžœž œ žœ&˜LJšœ#žœ˜=šžœž˜šœ ˜ Kšœžœ˜Kšœžœ˜Kšœ5˜5šžœ žœ!ž˜3šœžœ žœ žœž˜8Kšžœ˜ ——šžœžœ žœž˜.Kšžœ˜—šž˜Jšœ5˜5šžœž˜Kšžœ ˜"———šœ˜Kšœžœ˜Kšœžœ˜Kšœ1˜1šžœ ž˜Kšžœ˜—šžœžœ žœž˜/Kšžœ˜—šž˜Jšœ6˜6šžœž˜Kšžœ ˜"———Jšžœ˜ —J˜—Jšœ!™!š œžœž œ žœ ˜3J˜šœ)˜)Jšœ˜—Kšœ6˜6K˜—š œžœžœ žœ4žœžœ˜wJ˜Jšœ)žœ˜Fšžœžœ&ž˜LJšœ6˜6Kšžœ˜ —K˜—š œžœžœAžœžœžœ˜K˜š žœžœžœžœžœ˜