DIRECTORY Basics, Convert, Rope, SC, SCChanUtil, SCInstUtil, SCNetUtil, SCPrivate, SCPlaceUtil, SCSmash, SCWidthUtil, SCRowUtil, SCUtil, RTSets, TerminalIO; SCPlaceImproveImpl: CEDAR PROGRAM IMPORTS Convert, Rope, SC, SCChanUtil, SCInstUtil, SCNetUtil, SCPlaceUtil, SCRowUtil, SCWidthUtil, SCSmash, SCUtil, TerminalIO EXPORTS SCPrivate SHARES SC = { debug: BOOLEAN _ FALSE; PosResult: TYPE = RECORD[ area, channelWidth, wireLength: SC.Number, numFts: INT]; PlaceResult: TYPE = RECORD[ area, channelWidth, wireLength: SC.Number, numFts: INT]; WritePosResult: PROCEDURE [header: Rope.ROPE, Result: PosResult] = { -- write the results TerminalIO.WriteRope[header]; TerminalIO.WriteRope[" area: "]; TerminalIO.WriteInt[Result.area]; TerminalIO.WriteRope[", channelWidth: "]; TerminalIO.WriteInt[Result.channelWidth]; TerminalIO.WriteRope["\n wireLength: "]; TerminalIO.WriteInt[Result.wireLength]; TerminalIO.WriteRope[", numFts: "]; TerminalIO.WriteInt[Result.numFts]; TerminalIO.WriteLn[]}; ComparePosResult: PROCEDURE [result1, result2: PosResult] RETURNS [FirstRelationSecond: Basics.Comparison] = { IF result1.area < result2.area THEN FirstRelationSecond _ less ELSE IF result1.area > result2.area THEN FirstRelationSecond _ greater ELSE IF result1.channelWidth < result2.channelWidth THEN FirstRelationSecond _ less ELSE IF result1.channelWidth > result2.channelWidth THEN FirstRelationSecond _ greater ELSE IF result1.wireLength < result2.wireLength THEN FirstRelationSecond _ less ELSE IF result1.wireLength > result2.wireLength THEN FirstRelationSecond _ greater ELSE IF result1.numFts < result2.numFts THEN FirstRelationSecond _ less ELSE IF result1.numFts > result2.numFts THEN FirstRelationSecond _ greater ELSE FirstRelationSecond _ equal}; -- they are equal ComparePlaceResult: PROCEDURE [result1, result2: PlaceResult] RETURNS [FirstRelationSecond: Basics.Comparison] = BEGIN IF result1.area < result2.area THEN FirstRelationSecond _ less ELSE IF result1.area > result2.area THEN FirstRelationSecond _ greater ELSE IF result1.channelWidth < result2.channelWidth THEN FirstRelationSecond _ less ELSE IF result1.channelWidth > result2.channelWidth THEN FirstRelationSecond _ greater ELSE IF result1.wireLength < result2.wireLength THEN FirstRelationSecond _ less ELSE IF result1.wireLength > result2.wireLength THEN FirstRelationSecond _ greater ELSE IF result1.numFts < result2.numFts THEN FirstRelationSecond _ less ELSE IF result1.numFts > result2.numFts THEN FirstRelationSecond _ greater ELSE FirstRelationSecond _ equal; -- they are equal END; -- ComparePlaceResult DoWidths: PROCEDURE [handle: SC.Handle, doChanWidth: SCPrivate.ChanSet, doSideWidth: SCPrivate.LRSideSet, doRowWidth: SCPrivate.RowSet, fom: SCPrivate.FomType] RETURNS [wireLength: SC.Number _ 0] = { EachRow: SCRowUtil.EachRowProc = { IF doRowWidth[(row)-1] THEN SCInstUtil.LgOffsets[handle, row, 0, 0]}; EachRowChan: SCChanUtil.EachRowChanProc = { IF doChanWidth[(chan )-1] THEN [rowChan.chanWidth, rowChan.wireLength] _ SCWidthUtil.GetChanWidth[handle, rowChan, fom, TRUE]; wireLength _ wireLength + layoutData.rowChans.chans[chan].wireLength}; EachSideChan: SCChanUtil.EachSideChanProc = { IF doSideWidth[LOOPHOLE[lrSide, INTEGER]] THEN { sideChan: SCPrivate.SideChan _ layoutData.sideChans[lrSide]; [sideChan.sideChanWidth, sideChan.wireLength] _ SCWidthUtil.GetSideWidth[handle, lrSide, fom]}; wireLength _ wireLength + sideChan.wireLength}; layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; [] _ SCRowUtil.EnumerateRows[handle, EachRow]; [] _ SCChanUtil.EnumerateRowChans[handle, EachRowChan]; [] _ SCChanUtil.EnumerateSideChans[handle, EachSideChan]}; ChosRow: PROCEDURE[handle: SC.Handle, rowIndex: SCPrivate.ZMaxRowSr] RETURNS[rowToDo: SCPrivate.LgRow, doUpper, doLower: BOOLEAN] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; lgRows: SCPrivate.LgRows _ layoutData.lgRows; row: SCPrivate.ZMaxRowSr; SELECT TRUE FROM layoutData.bpRows[top].fnlBpFxd AND layoutData.bpRows[bottom].fnlBpFxd => {IF (rowIndex MOD 2) # 0 THEN row _ (lgRows.count+1) /2 - (rowIndex-1) /2 ELSE row _ (lgRows.count+1) /2 + rowIndex /2; doUpper _ doLower _ TRUE}; layoutData.bpRows[top].fnlBpFxd => {row _ lgRows.count - rowIndex + 1; doUpper _ TRUE; doLower _ FALSE}; layoutData.bpRows[bottom].fnlBpFxd => {row _ rowIndex; doUpper _ FALSE; doLower _ TRUE}; ENDCASE => {IF (rowIndex MOD 2) # 0 THEN row _ (lgRows.count+1) /2 - (rowIndex-1) /2 ELSE row _ (lgRows.count+1) /2 + rowIndex /2; IF row = (lgRows.count+1) /2 THEN {doUpper _ TRUE; doLower _ TRUE} ELSE IF row < (lgRows.count+1) /2 THEN {doUpper _ TRUE; doLower _ FALSE} ELSE {doUpper _ FALSE; doLower _ TRUE}}; rowToDo _ lgRows.rows[row]}; PosImproveRow: PROCEDURE [handle: SC.Handle, lgRow: SCPrivate.LgRow, doUpper, doLower: BOOLEAN, whichFom: SCPrivate.FomType] RETURNS [goodExch: BOOLEAN _ FALSE] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; structureData: SCPrivate.StructureData _ NARROW[handle.structureData]; lgRows: SCPrivate.LgRows _ layoutData.lgRows; row: SCPrivate.MaxRowSr _ lgRow.rowNum; rowChans: SCPrivate.RowChans _ layoutData.rowChans; lowerChan: SCPrivate.RowChan _ rowChans.chans[row]; upperChan: SCPrivate.RowChan _ rowChans.chans[row+1]; numFts: INT _ structureData.instances.numFts; oldLowChWidth, oldUpChWidth, oldLowWireLength, oldUpWireLength: SC.Number; oldResult: PosResult; TrialInterchange: SCRowUtil.EachInstProc = { nextPos: SCPrivate.MaxPosSr _ pos + 1; lowChWidth, upChWidth, upWireLength, lowWireLength: SC.Number; newResult: PosResult; SCPlaceUtil.ExchPosRow[handle, pos, nextPos, row]; [lowChWidth, lowWireLength] _ SCWidthUtil.GetChanWidth[handle, lowerChan, whichFom, doLower]; [upChWidth, upWireLength] _ SCWidthUtil.GetChanWidth[handle, upperChan, whichFom, doUpper]; newResult _ PosResult[(lowChWidth + upChWidth) * lgRows.maxRowWidth, (lowChWidth + upChWidth), (lowWireLength + upWireLength), numFts]; IF debug THEN WritePosResult[" trial result: ", newResult]; SELECT ComparePosResult[newResult, oldResult] FROM less => { -- strict improvement, thats good IF debug THEN TerminalIO.WriteRope[" accept improvement\n"]; lowerChan.chanWidth _ lowChWidth; upperChan.chanWidth _ upChWidth; oldResult _ newResult; goodExch _ TRUE}; equal => { -- neutral improvement, take it IF debug THEN TerminalIO.WriteRope[" accept neutral exchange\n"]; lowerChan.chanWidth _ lowChWidth; upperChan.chanWidth _ upChWidth; oldResult _ newResult}; greater => { -- this change made it worse, restore old placement IF debug THEN WritePosResult[" restore old result: ", oldResult]; SCPlaceUtil.ExchPosRow[handle, pos, nextPos, row]}; ENDCASE}; IF lgRow.nLgsOnRow > 0 AND ~lgRow.fnlLgFxd AND (doUpper OR doLower) THEN { TerminalIO.WriteRope[" improve row "]; TerminalIO.WriteInt[row]; TerminalIO.WriteRope[Rope.Cat[" doUpper: ", Convert.RopeFromBool[doUpper], " doLower: ", Convert.RopeFromBool[doLower]]]; TerminalIO.WriteLn[]; [oldLowChWidth, oldLowWireLength] _ SCWidthUtil.GetChanWidth[handle, lowerChan, whichFom, doLower]; [oldUpChWidth, oldUpWireLength] _ SCWidthUtil.GetChanWidth[handle, upperChan, whichFom, doUpper]; oldResult _ PosResult[(oldLowChWidth + oldUpChWidth) * lgRows.maxRowWidth, (oldLowChWidth + oldUpChWidth), (oldLowWireLength + oldUpWireLength), numFts]; IF debug THEN WritePosResult[" original logic result: ", oldResult]; [] _ SCRowUtil.EnumerateInstsOnRow[handle, row, 1, MAX[0, lgRow.nLgsOnRow-1], TrialInterchange]}}; PosImproveLeftRight: PROCEDURE[handle: SC.Handle, side: SC.Side, whichFom: SCPrivate.FomType] RETURNS [goodExch: BOOLEAN _ FALSE] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; structureData: SCPrivate.StructureData _ NARROW[handle.structureData]; lgRows: SCPrivate.LgRows _ layoutData.lgRows; bpRow: SCPrivate.BpRow _ layoutData.bpRows[side]; sideChan: SCPrivate.SideChan _ layoutData.sideChans[side]; wireLength: SC.Number; oldResult: PlaceResult; TrialInterchange: SCRowUtil.EachInstProc = { doChanWidth: SCPrivate.ChanSet _ RTSets.RTMdSetEmpty; doRowWidth: SCPrivate.ChanSet _ RTSets.RTMdSetEmpty; doSideWidth: SCPrivate.LRSideSet _ RTSets.RTSmSetEmpty; nextPos: SCPrivate.MaxPosSr _ pos +1; newWireLength: SC.Number; newResult: PlaceResult; nets: SCPrivate.NetList _ SCNetUtil.NetsOnInst[LIST[bpRow.bpsOnSide[pos], bpRow.bpsOnSide[nextPos]]]; [doChanWidth, doSideWidth, doRowWidth] _ SCSmash.RemoveNetsWFts[handle, nets, TRUE, doChanWidth, doSideWidth, doRowWidth]; SCPlaceUtil.ExchPosSide[handle, pos, nextPos, side]; [doChanWidth, doSideWidth, doRowWidth] _ SCSmash.SmashNets[handle, nets, FALSE, doChanWidth, doSideWidth, doRowWidth]; newWireLength _ DoWidths[handle, doChanWidth, doSideWidth, doRowWidth, whichFom]; [lgRows.maxRowWidth, lgRows.numMaxRows] _ SCRowUtil.FindMaxRow[handle]; SCInstUtil.AsgnChanPos[handle]; newResult _ PlaceResult[layoutData.totWidth * layoutData.totHeight, layoutData.sideChans[side].sideChanWidth, newWireLength, structureData.instances.numFts]; IF debug THEN WritePosResult[" trial result: ", newResult]; SELECT ComparePlaceResult[newResult, oldResult] FROM less => { -- strict improvement, thats good IF debug THEN TerminalIO.WriteRope[" accept improvement\n"]; wireLength _ newWireLength; oldResult _ newResult; goodExch _ TRUE}; equal => { -- neutral exchange, take it IF debug THEN TerminalIO.WriteRope[" accept neutral exchange\n"]; wireLength _ newWireLength; oldResult _ newResult}; greater => { -- this change made it worse, restore old placement IF debug THEN WritePosResult[" restore old result: ", oldResult]; [doChanWidth, doSideWidth, doRowWidth] _ SCSmash.RemoveNetsWFts[handle, nets, FALSE, RTSets.RTMdSetEmpty, RTSets.RTSmSetEmpty, RTSets.RTMdSetEmpty]; SCPlaceUtil.ExchPosSide[handle, pos, nextPos, side]; [doChanWidth, doSideWidth, doRowWidth] _ SCSmash.RestoreNetsWFts[handle, nets, doChanWidth, doSideWidth, doRowWidth]; wireLength _ DoWidths[handle, doChanWidth, doSideWidth, doRowWidth, whichFom]; [lgRows.maxRowWidth, lgRows.numMaxRows] _ SCRowUtil.FindMaxRow[handle]; SCInstUtil.AsgnChanPos[handle]}; ENDCASE}; IF ~ bpRow.fnlBpFxd THEN { TerminalIO.WriteRope[Rope.Cat[" improve ", SCRowUtil.sideName[side], " side\n"]]; SCWidthUtil.AllChanWidths[handle, whichFom]; wireLength _ DoWidths[handle, RTSets.RTMdSetEmpty, RTSets.RTSmSetEmpty, RTSets.RTMdSetEmpty, whichFom]; [lgRows.maxRowWidth, lgRows.numMaxRows] _ SCRowUtil.FindMaxRow[handle]; SCInstUtil.AsgnChanPos[handle]; oldResult _ PlaceResult[layoutData.totWidth * layoutData.totHeight, sideChan.sideChanWidth, wireLength, structureData.instances.numFts]; IF debug THEN WritePosResult[Rope.Cat[" original ", SCRowUtil.sideName[side] ," result: "], oldResult]; [] _ SCRowUtil.EnumerateInstsOnSide[handle, side, 1, MAX[0, bpRow.nBpsOnSide -1], TrialInterchange]; SCWidthUtil.AllChanWidths[handle, areaFom]}}; PosImproveTopBot: PROCEDURE[handle: SC.Handle, side: SC.Side, whichFom: SCPrivate.FomType] RETURNS [goodExch: BOOLEAN _ FALSE] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; structureData: SCPrivate.StructureData _ NARROW[handle.structureData]; lgRows: SCPrivate.LgRows _ layoutData.lgRows; bpRow: SCPrivate.BpRow _ layoutData.bpRows[side]; rowChans: SCPrivate.RowChans _ layoutData.rowChans; numFts: INT _ structureData.instances.numFts; oldChWidth, oldWireLength: SC.Number; oldResult: PosResult; chan: SCPrivate.RowChan _ SELECT side FROM top => rowChans.chans[rowChans.count], bottom => rowChans.chans[1], ENDCASE => SC.Error[programmingError, "Invalid side in Placement Improvement"]; TrialInterchange: SCRowUtil.EachInstProc = { nextPos: SCPrivate.MaxPosSr _ pos + 1; chWidth, wireLength: SC.Number; newResult: PosResult; SCPlaceUtil.ExchPosSide[handle, pos, nextPos, side]; [chWidth, wireLength] _ SCWidthUtil.GetChanWidth[handle, chan, whichFom, TRUE]; newResult _ PosResult[chWidth * lgRows.maxRowWidth, chWidth, wireLength, numFts]; IF debug THEN WritePosResult[" trial result: ", newResult]; SELECT ComparePosResult[newResult, oldResult] FROM less => { -- strict improvement, thats good IF debug THEN TerminalIO.WriteRope[" accept improvement\n"]; chan.chanWidth _ chWidth; oldResult _ newResult; goodExch _ TRUE}; equal => { -- neutral exchange, take what you can get IF debug THEN TerminalIO.WriteRope[" accept neutral exchange\n"]; chan.chanWidth _ chWidth; oldResult _ newResult}; greater => { -- this change made it worse, restore old placement IF debug THEN WritePosResult[" restore old result: ", oldResult]; SCPlaceUtil.ExchPosSide[handle, pos, nextPos, side]}; ENDCASE}; IF ~ bpRow.fnlBpFxd THEN { TerminalIO.WriteRope[Rope.Cat[" improve ", SCRowUtil.sideName[side], " side\n"]]; [oldChWidth, oldWireLength] _ SCWidthUtil.GetChanWidth[handle, chan, whichFom, TRUE]; oldResult _ PosResult[oldChWidth * lgRows.maxRowWidth, oldChWidth, oldWireLength, numFts]; IF debug THEN WritePosResult[Rope.Cat[" original ", SCRowUtil.sideName[side]," result: "], oldResult]; [] _ SCRowUtil.EnumerateInstsOnSide[handle, side, 1, MAX[0, bpRow.nBpsOnSide-1], TrialInterchange]}}; PosImprove: PUBLIC PROCEDURE [handle: SC.Handle, whichFom: SCPrivate.FomType] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; lgRows: SCPrivate.LgRows _ layoutData.lgRows; bpRows: SCPrivate.BpRows _ layoutData.bpRows; startArea: SC.Number; [lgRows.maxRowWidth, lgRows.numMaxRows] _ SCRowUtil.FindMaxRow[handle]; SCWidthUtil.AllChanWidths[handle, areaFom]; SCInstUtil.AsgnChanPos[handle]; startArea _ SCUtil.WriteResults["Position improvement\n starting area:", handle, 0]; DO goodExch: BOOLEAN _ FALSE; goodTopExch, goodBottomExch, goodRightExch, goodLeftExch: BOOLEAN; EachRow: SCRowUtil.EachRowProc = { rowToDo: SCPrivate.LgRow; doUpper, doLower: BOOLEAN; goodRowExch: BOOLEAN; [rowToDo, doUpper, doLower] _ ChosRow[handle, row]; goodRowExch _ PosImproveRow[handle, rowToDo, doUpper, doLower, whichFom]; goodExch _ goodExch OR goodRowExch}; goodLeftExch _ PosImproveLeftRight[handle, left, whichFom]; goodRightExch _ PosImproveLeftRight[handle, right, whichFom]; SCInstUtil.AsgnChanPos[handle]; [] _ SCRowUtil.EnumerateRows[handle, EachRow]; goodTopExch _ PosImproveTopBot[handle, top, whichFom]; goodBottomExch _ PosImproveTopBot[handle, bottom, whichFom]; IF ~(goodExch OR goodLeftExch OR goodRightExch OR goodTopExch OR goodBottomExch) THEN EXIT; SCInstUtil.AsgnChanPos[handle]; ENDLOOP; SCInstUtil.AllOffsets[handle]; [lgRows.maxRowWidth, lgRows.numMaxRows] _ SCRowUtil.FindMaxRow[handle]; SCWidthUtil.AllChanWidths[handle, areaFom]; SCInstUtil.AsgnChanPos[handle]; [] _ SCUtil.WriteResults["End position improvement\n ending area:", handle, startArea]; IF debug THEN SCPlaceUtil.WriteCurPlace[handle]}; -- PosImprove }. 6file: SCPlaceImproveImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. map a row index in to a row improve positions on logic rows improve positions on bonding pad sides improve positions on bonding pad sides improve the left and right sides now improve the top and bottom sides Κ ¦˜šœ™Icodešœ Οmœ0™;—J˜šΟk ˜ J˜Jšœ˜Jšœ˜Jšžœ˜J˜ Jšœ ˜ J˜ J˜ Jšœ ˜ Jšœ ˜ Jšœ ˜ Jšœ ˜ J˜Jšœ˜Jšœ ˜ J˜—šœžœž˜!J˜Jšžœžœe˜~J˜Jšžœ ˜Jšžœžœ˜J˜Jšœžœžœ˜J˜šœ žœžœ˜Jšœ žœ˜*Jšœžœ˜ —J˜šœ žœžœ˜Jšœ žœ˜*Jšœžœ˜ —J˜š Οnœž œžœžœΟc˜YJšœ˜JšœD˜DJšœS˜SJšœU˜UJšœG˜GJšœ˜J˜—šŸœž œ˜9Jšžœ-˜4šžœž˜#Jšœ˜—šžœžœž˜(Jšœ˜—šžœžœ-ž˜8Jšœ˜—šžœžœ-ž˜8Jšœ˜—šžœžœ)ž˜4Jšœ˜—šžœžœ)ž˜4Jšœ˜—šžœžœ!ž˜,Jšœ˜—šžœžœ!ž˜,Jšœ˜—šž˜Jšœ ˜/——J˜šŸœž œ ˜=Jšžœ+˜2J˜Jšž˜šžœž˜#Jšœ˜—šžœžœž˜(Jšœ˜—šžœžœ-ž˜8Jšœ˜—šžœžœ-ž˜8Jšœ˜—šžœžœ)ž˜4Jšœ˜—šžœžœ)ž˜4Jšœ˜—šžœžœ!ž˜,Jšœ˜—šžœžœ!ž˜,Jšœ˜—šž˜Jšœ ˜.—Jšžœ  œ ˜J˜—šŸœž œ žœ˜'Jšœ˜Jšœ!˜!Jšœ˜Jšœ˜Jšžœž œ ˜'J˜šœ#˜#Jšžœžœ*˜E—J˜šœ,˜,šžœž˜JšœYžœ˜_—JšœF˜F—J˜šœ-˜-šžœ žœ žœž˜0Jšœ<˜Jšœ˜J˜Jšœ2˜2Jšœ]˜]Jšœ[˜[Jšœ‡˜‡Jšžœžœ0˜=J˜Jšžœ(ž˜2šœžœ "˜,Jšžœžœ1˜>Jšœ!˜!Jšœ ˜ Jšœ˜Jšœ žœ˜—J˜šœžœ  ˜+Jšžœžœ6˜CJšœ!˜!Jšœ ˜ Jšœ˜—J˜šœ žœ 4˜AJšžœžœ6˜CJšœ3˜3—Jšžœ˜ J˜—š žœžœžœ žœ žœ˜JJšœ@˜@šœJ˜JJšœ.˜.—Jšœ˜J˜Jšœc˜cJšœa˜aJšœ™˜™Jšžœžœ9˜FJ˜Jšœb˜b——J˜Jšœ'™'šŸœž œ žœžœ$žœ žœžœ˜…J˜Jšœ#žœ˜=Jšœ)žœ˜FJšœ-˜-Jšœ1˜1Jšœ:˜:Jšœ ž œ˜Jšœ˜J˜šœ,˜,Jšœ5˜5Jšœ4˜4Jšœ7˜7Jšœ%˜%Jšœž œ˜Jšœ˜J˜Jšœ/žœ2˜eJšœNžœ(˜zJšœ4˜4JšœIžœ(˜vJšœQ˜QJšœG˜GJšœ˜Jšœ˜Jšžœžœ0˜=J˜šžœ*ž˜4šœžœ !˜+Jšžœžœ1˜>Jšœ˜Jšœ˜Jšœ žœ˜—J˜šœžœ ˜'Jšžœžœ6˜CJšœ˜Jšœ˜—J˜šœ žœ 4˜AJšžœžœ6˜CJšœNžœA˜”Jšœ4˜4Jšœu˜uJ˜JšœN˜NJšœG˜GJšœ ˜ —Jšžœ˜ J˜——šžœž˜JšœQ˜QJ˜Jšœ,˜,Jšœg˜gJšœG˜GJšœ˜Jšœˆ˜ˆJšžœžœ\˜iJ˜Jšœd˜dJ˜Jšœ-˜-—J˜—Jšœ'™'šŸœž œ žœžœ$žœ žœžœ˜‚J˜Jšœ#žœ˜=Jšœ)žœ˜FJšœ-˜-Jšœ1˜1Jšœ3˜3Jšœžœ"˜-Jšœž œ˜%Jšœ˜šœžœž˜*Jšœ&˜&Jšœ˜JšžœžœB˜O—J˜šœ,˜,Jšœ&˜&Jšœž œ˜Jšœ˜J˜Jšœ4˜4JšœIžœ˜OJšœQ˜QJšžœžœ0˜=J˜Jšžœ(ž˜2šœžœ "˜,Jšžœžœ1˜>Jšœ˜Jšœ˜Jšœ žœ˜—J˜šœžœ +˜6šžœžœ˜Jšœ5˜5—Jšœ˜Jšœ˜—J˜šœžœ 4˜AJšžœžœ6˜CJšœ5˜5—Jšžœ˜ —J˜šžœžœ˜JšœQ˜QJ˜JšœOžœ˜UJšœZ˜ZJšžœžœ[˜hJ˜Jšœe˜e——J˜šŸ œžœž œ žœ)˜QJ˜Jšœ#žœ˜=Jšœ-˜-Jšœ-˜-Jšœ ž œ˜J˜JšœG˜GJšœ+˜+Jšœ˜JšœT˜TJ˜šž˜Jšœ žœžœ˜Jšœ:žœ˜Bšœ#˜#Jšœ˜Jšœžœ˜Jšœ žœ˜Jšœ3˜3JšœI˜Išœžœ˜$J˜——Jšœ!™!Jšœ;˜;Jšœ=˜=J˜Jšœ˜Jšœ.˜.J˜Jšœ%™%Jšœ6˜6Jšœ<˜