DIRECTORY AbSets, Asserting, BasicTime, BiRelBasics, BiRels, Convert, Histograms, IntStuff, IO, LichenDataOps, LichenDataStructure, LichenNavigation, LichenStructuring, Process, RealFns, Rope, SetBasics; LichenData5Impl: CEDAR PROGRAM IMPORTS AbSets, Asserting, BasicTime, BiRelBasics, BiRels, Convert, Histograms, IntStuff, IO, LichenDataOps, LichenDataStructure, LichenNavigation, LichenStructuring, Process, RealFns, Rope, SetBasics = BEGIN OPEN LichenDataOps, LichenDataStructure, Sets:AbSets, IS:IntStuff, LichenStructuring; base: REAL ~ RealFns.Power[2, 1.0/4]; minTime: REAL ~ 1.0/32; portTimes: Histograms.Histogram ~ Histograms.Create2D[iFactor: base, jFactor: base, iOffset: 1, jOffset: minTime, logI: TRUE, logJ: TRUE]; wireTimes: Histograms.Histogram ~ Histograms.Create2D[iFactor: base, jFactor: base, iOffset: 1, jOffset: minTime, logI: TRUE, logJ: TRUE]; Break: SIGNAL ~ CODE; breakCTN: ROPE _ NIL; breakKill: SteppyName _ NIL; checkA: BOOL _ TRUE; checkB: BOOL _ FALSE; checkC: BOOL _ FALSE; AddDeducedStructureToDesign: PROC [design: Design, pacify: IO.STREAM _ NIL] ~ { n: INT _ 0; PerCellType: PROC [val: REF ANY] ~ { ct: CellType ~ NARROW[val]; portSize: LNAT ~ PortSize[ct.port]; n _ n + 1; Process.CheckForAbort[]; IF breakCTN#NIL AND Asserting.Test1[nameReln, breakCTN, ct.otherPublic] THEN Break; IF pacify#NIL THEN pacify.PutF["%g %g: %g; port %g ", [rope[Convert.RopeFromTime[from: BasicTime.Now[], start: hours, end: seconds, useAMPM: FALSE, includeZone: FALSE]]], [integer[n]], [rope[Describe[ct, design]]], [integer[portSize]]]; {start: BasicTime.Pulses ~ BasicTime.GetClockPulses[]; AddDeducedStructureToPort[ct.port]; {mid: BasicTime.Pulses ~ BasicTime.GetClockPulses[]; portTime: REAL ~ BasicTime.PulsesToSeconds[mid - start]; portTimes.ChangeTransformed[portSize, MAX[portTime, minTime]]; IF pacify#NIL THEN pacify.PutF["* %g s", [real[portTime]]]; IF ct.asUnorganized#NIL THEN { wireSize: LNAT ~ WireSize[ct.asUnorganized.internalWire]; IF pacify#NIL THEN pacify.PutF["; wire %g ", [integer[wireSize]]]; {before: BasicTime.Pulses ~ BasicTime.GetClockPulses[]; AddDeducedStructureToWire[ct.asUnorganized.internalWire]; {after: BasicTime.Pulses ~ BasicTime.GetClockPulses[]; wireTime: REAL ~ BasicTime.PulsesToSeconds[after - before]; wireTimes.ChangeTransformed[wireSize, MAX[wireTime, minTime]]; IF pacify#NIL THEN pacify.PutF["* %g s", [real[wireTime]]]; }}}; IF pacify#NIL THEN pacify.PutRope[" .\n"]; RETURN}}}; IF pacify#NIL THEN pacify.PutF["Total: %g\n", [integer[design.cellTypes.Size.EN]]]; design.cellTypes.EnumA[PerCellType]; RETURN}; AddDeducedStructureToPort: PROC [port: Port] ~ { AddDeducedStructureToThing[root: port, ToChildren: LichenNavigation.portToChildren, ToNames: LichenNavigation.portNames, Rename: RenamePort, Group: GroupPorts]; RETURN}; AddDeducedStructureToWire: PROC [wire: Wire] ~ { AddDeducedStructureToThing[root: wire, ToChildren: LichenNavigation.wireToChildren, ToNames: LichenNavigation.vertexNames, Rename: RenameWire, Group: GroupWires]; RETURN}; RenamePort: PROC [thing: Thing, old, new: SteppyName] ~ { port: Port ~ NARROW[thing]; IF NOT port.PortNames.RemA[old] THEN ERROR; [] _ port.PortNames.AddA[new]; RETURN}; RenameWire: PROC [thing: Thing, old, new: SteppyName] ~ { w: Wire ~ NARROW[thing]; ForgetVertexName[w, old]; KnowVertexName[w, new]; RETURN}; setOfOne: Set ~ Sets.CreateSingleton[AV[NEW [INT _ 1]], nameStepSpace]; r0: REF INT ~ NEW [INT _ 0]; AddDeducedStructureToThing: PROC [root: Thing, ToChildren: Function--thing _ Seq of child things--, ToNames: Function--thing _ Set(of SteppyName)--, Rename: PROC [thing: Thing, old, new: SteppyName], Group: PROC [sibs: Seq--of child thing--, parentNames: ListData] RETURNS [parent: Thing]] ~ { Work: PROC [subroot: Thing] ~ { children: Seq--of thing-- ~ BiRels.DeRef[ToChildren.ApplyA[subroot].MA]; IF children.Empty THEN RETURN; {dag: StepDAG ~ CreateDAG[subroot, NIL]; InsertThing: PROC [child: Thing] ~ { names: Set--of SteppyName-- ~ Sets.DeRef[ToNames.ApplyA[child].MA]; PerName: PROC [val: REF ANY] ~ { name: SteppyName ~ FixSteppyName[NARROW[val]]; Process.CheckForAbort[]; InsertInDAG[dag, dag.rootNode, name, child]; RETURN}; names.EnumA[PerName]; RETURN}; LeafizeInternal: PROC [parenta, deca: REF ANY] ~ { parent: StepNode ~ NARROW[parenta]; dec: Decomp ~ NARROW[deca]; mv: Sets.MaybeValue ~ dag.toThing.ApplyA[parent]; IF NOT mv.found THEN RETURN; IF NOT dec^.SetOn[left].Equal[setOfOne] THEN ERROR; {thing: Thing ~ mv.MA; downd: StepNode ~ GetDown[dag, parent, r0, TRUE]; parentNamesData: ListData ~ CreateSteppyNames[]; parentNames: Set--of SteppyName-- ~ [listClass, AV[parentNamesData]]; ChangeName: PROC [ra: REF ANY] ~ { old: SteppyName ~ NARROW[ra]; new: SteppyName ~ CopyTil[[old]].Append[r0].head; Rename[thing, old, new]; RETURN}; GetNames[dag, parent, parentNames, NIL]; parentNames.EnumA[ChangeName]; dag.toThing.RemOldAA[parent, thing]; dag.toThing.AddNewAA[downd, thing]; IF checkC THEN VerifyDAG[dag]; RETURN}}; candSize: Function--StepNode _ size-- ~ BiRels.GenCreate[spaces: [SetBasics.refs, SetBasics.ints], functional: [TRUE, FALSE], hints: [leftToRight: [[$Hash]], rightToLeft: [[$BalancedTree], [$Hash]]]]; SizeCand: PROC [canda: REF ANY] ~ { cand: StepNode ~ NARROW[canda]; g: CandGrade ~ GradeCand[dag, cand]; IF g.good THEN candSize.AddNewPair[[AV[cand], IV[g.size]]]; RETURN}; Groupit: PROC [canda: REF ANY] ~ { cand: StepNode ~ NARROW[canda]; parentNames: ListData ~ CreateSteppyNames[]; dec: Decomp ~ GetDecomp[dag, cand, FALSE]; aKid: StepNode ~ NARROW[dec^.APair.P[][right].VA]; IF GetDecomp[dag, aKid, FALSE]#NIL THEN { kids: Set--of StepNode-- ~ dec^.SetOn[right]; kids.EnumA[Groupit]; canda _ canda}; GetNames[dag, cand, [listClass, AV[parentNames]], NIL]; {seq: Seq ~ Sequify[dec^.Compose[right: dag.toThing, restricts: [TRUE, FALSE]]]; repl: Thing ~ Group[seq, parentNames]; Delit: PROC [step, child: REF ANY] ~ {RemoveLeaf[dag, NARROW[child]]}; dag.toThing.AddNewAA[cand, repl]; dec^.EnumAA[Delit]; IF checkA THEN VerifyDAG[dag]; RETURN}}; children.SetOn[right].EnumA[Work]; children.SetOn[right].EnumA[InsertThing]; IF checkA THEN VerifyDAG[dag]; dag.down.EnumAA[LeafizeInternal]; dag.prefixd _ TRUE; IF checkA THEN VerifyDAG[dag]; CommonizeLeaves[dag]; dag.leavesCommonized _ TRUE; IF checkA THEN VerifyDAG[dag]; DiscoverAndLowerSeqs[dag, dag.rootNode]; CommonizeDecomps[dag]; IF checkA THEN VerifyDAG[dag]; dag.cands.EnumA[SizeCand]; dag.cands _ candSize.SetOn[left]; IF checkA THEN VerifyDAG[dag]; UNTIL candSize.Empty[] DO cand: StepNode ~ NARROW[candSize.Pop[[[no, bwd], right]].P[][left].VA[]]; KillCand[dag, candSize, cand, one]; Groupit[cand]; root _ root; ENDLOOP; IF checkA THEN VerifyDAG[dag]; RETURN}}; Work[root]; RETURN}; KillCand: PROC [dag: StepDAG, candSize: Function--StepNode _ size--, cand: StepNode, phase: {one, two, three--phase one enumerates all descendants; phase two kills all their candidate ancestors; phase three kills all their descendants--}] ~ { IF breakKill#NIL THEN WITH dag.toThing.ApplyA[cand].MDA SELECT FROM p: Port => IF p.PortNames.HasMemA[breakKill] THEN Break; w: Wire => IF w.VertexNames.HasMemA[breakKill] THEN Break; ENDCASE => NULL; IF phase>one AND NOT candSize.DeleteA[cand] THEN RETURN; --now cand is either an ex-candidate or a descendant of one-- NULL; IF phase#three THEN {ups: Ups ~ GetUps[dag, cand, FALSE]; KillParent: PROC [parent: REF ANY, step: NameStep] ~ { KillCand[dag, candSize, NARROW[parent], two]; RETURN}; IF ups#NIL THEN ups^.EnumAA[KillParent]}; {dec: Decomp ~ GetDecomp[dag, cand, FALSE]; KillKid: PROC [step: NameStep, child: REF ANY] ~ { KillCand[dag, candSize, NARROW[child], IF phase=one THEN one ELSE three]; RETURN}; IF dec#NIL THEN dec^.EnumAA[KillKid]}; RETURN}; GetNames: PROC [dag: StepDAG, node: StepNode, parentNameSet: Set--of SteppyName--, sofar: SteppyName] ~ { IF node=dag.rootNode THEN { IF NOT parentNameSet.AddA[sofar] THEN ERROR; RETURN} ELSE { ups: Ups ~ GetUps[dag, node, FALSE]; PerUp: PROC [parenta, step: REF ANY] ~ { parent: StepNode ~ NARROW[parenta]; next: SteppyName ~ CONS[step, sofar]; GetNames[dag, parent, parentNameSet, next]; RETURN}; ups^.EnumAA[PerUp]; RETURN}; }; DiscoverAndLowerSeqs: PROC [dag: StepDAG, subroot: StepNode] ~ { dec: Decomp ~ GetDecomp[dag, subroot, FALSE]; DoLower: PROC [step, childa: REF ANY] ~ {DiscoverAndLowerSeqs[dag, NARROW[childa]]}; CheckName: PROC [pair: BiRels.Pair] RETURNS [BOOL] ~ { WITH pair[left].VA SELECT FROM x: ROPE => RETURN [TRUE]; x: REF INT => RETURN [FALSE]; ENDCASE => ERROR; }; IF dec=NIL THEN RETURN; dec^.EnumAA[DoLower]; IF dec^.Scan[CheckName].found THEN RETURN; {toDo: StepDAG ~ CreateDAG[subroot, dag]; FindPaths: PROC [step, child: REF ANY] ~ { WITH step SELECT FROM x: ROPE => ERROR; x: REF INT => FindPath[NARROW[child], subroot, x]; ENDCASE => ERROR; RETURN}; FindPath: PROC [from, to: StepNode, index: REF INT] ~ { leaf: BOOL ~ IsKidCand[dag, from]; IF leaf THEN { [] _ toDo.cands.AddA[to]; AddLink[toDo, to, index, from]; RETURN} ELSE { dec: Decomp ~ GetDecomp[dag, from, FALSE]; Subadd: PROC [step: NameStep, oldKida: REF ANY] ~ { oldKid: StepNode ~ NARROW[oldKida]; newKid: StepNode ~ GetDown[toDo, to, step, TRUE]; FindPath[oldKid, newKid, index]; RETURN}; dec^.EnumAA[Subadd]; RETURN}; }; PruneBadCands: PROC [parent: StepNode] ~ { ddec: Decomp ~ GetDecomp[toDo, parent, FALSE]; cand: BOOL ~ toDo.cands.HasMemA[parent]; bounds: IS.Interval _ IS.anEmptyInterval; badBranchSeen: BOOL _ FALSE; size: NATURAL _ 0; seen: Set--of StepNode-- ~ IF cand THEN Sets.CreateHashSet[] ELSE Sets.nilSet; PerPair: PROC [step, childa: REF ANY] ~ { child: StepNode ~ NARROW[childa]; IF NOT (cand AND IsKidCand[dag, child]) THEN { badBranchSeen _ TRUE; PruneBadCands[child]; RETURN} ELSE IF seen.AddA[child] THEN { ri: REF INT ~ NARROW[step]; size _ size + 1; bounds _ bounds.MBI[[ri^, ri^]]; IF NOT cand THEN ERROR; RETURN} ELSE { badBranchSeen _ TRUE; RETURN}; }; IF ddec#NIL THEN ddec^.EnumAA[PerPair]; IF NOT cand THEN RETURN; IF badBranchSeen OR NOT (parent#dag.rootNode AND bounds.min IN [0 .. 1] AND bounds.Length.EN=size AND size>1) THEN PruneCand[toDo, parent]; RETURN}; RootDownToDelete: PROC [seqStep: NameStep] RETURNS [ur: StepTriple] ~ { ur _ [subroot, seqStep, GetDown[dag, subroot, seqStep, FALSE]]; IF ur.child=NIL THEN ERROR}; MovePath: PROC [from, to: StepNode, DownToDelete: PROC [seqStep: NameStep] RETURNS [ur: StepTriple]] ~ { ddec: Decomp ~ GetDecomp[toDo, from, FALSE]; fromIsCand: BOOL ~ toDo.cands.HasMemA[from]; MoveDec: PROC [step: NameStep, childa: REF ANY] ~ { child: StepNode ~ NARROW[childa]; leaf1: BOOL ~ dag.toThing.HasMapA[child] OR dag.cands.HasMemA[child]; leaf2: BOOL ~ NOT toDo.down.HasMapA[child]; IF leaf1#leaf2 OR leaf1#fromIsCand THEN ERROR; IF leaf1 THEN { ur: StepTriple ~ DownToDelete[step]; IF ur.child#child THEN ERROR; RemoveLink[dag, ur.parent, ur.step, ur.child, do]; AddLink[dag, to, step, child]; IF checkB THEN VerifyDAG[dag]; RETURN} ELSE { SubDownToDelete: PROC [seqStep: NameStep] RETURNS [ur: StepTriple] ~ { urParent: StepNode ~ DownToDelete[seqStep].ur.child; urKid: StepNode ~ GetDown[dag, urParent, step, FALSE]; IF urKid=NIL THEN ERROR; RETURN [[urParent, step, urKid]]}; fake: StepNode ~ GetDown[dag, to, step, TRUE]; MovePath[child, fake, SubDownToDelete]; RETURN}; }; IF fromIsCand THEN IF NOT dag.cands.AddA[to] THEN ERROR; ddec^.EnumAA[MoveDec]; RETURN}; IF NOT dag.prefixd THEN ERROR--needed to compute leaf1 in MoveDec--; toDo.prefixd _ dag.prefixd; toDo.leavesCommonized _ dag.leavesCommonized; dec^.EnumAA[FindPaths]; PruneBadCands[subroot]; IF NOT toDo.down.Empty THEN { IF checkB THEN VerifyDAG[dag]; MovePath[subroot, subroot, RootDownToDelete]; IF checkA AND NOT checkB THEN VerifyDAG[dag]; }; RETURN}}; PortSize: PROC [p: Port] RETURNS [size: LNAT--number of leaves-- _ 1] ~ { FOR c: Port _ p.FirstChildPort[], c.NextChildPort[] WHILE c # NIL DO size _ size + PortSize[c]; p _ p; ENDLOOP; RETURN}; WireSize: PROC [p: Wire] RETURNS [size: LNAT--number of leaves-- _ 1] ~ { FOR c: Wire _ p.FirstChildWire[], c.NextChildWire[] WHILE c # NIL DO size _ size + WireSize[c]; p _ p; ENDLOOP; RETURN}; FixSteppyName: PROC [old: SteppyName] RETURNS [SteppyName] ~ { copied: BOOL _ FALSE; copy: TList _ []; IF skipFix THEN RETURN [old]; FOR cur: SteppyName _ old, cur.rest WHILE cur#NIL DO {WITH cur.first SELECT FROM x: ROPE => {dotPos: INT ~ x.FindBackward["."]; IF dotPos<0 THEN GOTO Not; {sepPos: INT ~ x.Index[s2: "_", pos1: dotPos]; FOR i: INT IN (dotPos .. sepPos) DO IF x.InlineFetch[i] NOT IN ['0 .. '9] THEN GOTO Not; ENDLOOP; IF NOT copied THEN {copy _ CopyTil[[old, cur]]; copied _ TRUE}; copy _ copy.Append[x.Substr[len: dotPos].Concat[x.Substr[start: sepPos]]].Append[NEW [INT _ Convert.IntFromRope[x.Substr[start: dotPos+1, len: sepPos - dotPos - 1]]]]; }}; x: REF INT => GOTO Not; ENDCASE => ERROR; EXITS Not => IF copied THEN copy _ copy.Append[cur.first]; }ENDLOOP; RETURN [IF copied THEN copy.head ELSE old]}; skipFix: BOOL _ FALSE; Start: PROC ~ { [] _ portTimes.Show[viewerInit: [name: "Deduce port structure size * time"], base: 2, updatePeriod: 5]; [] _ wireTimes.Show[viewerInit: [name: "Deduce wire structure size * time"], base: 2, updatePeriod: 5]; RETURN}; Start[]; END. ^LichenData5Impl.Mesa Last tweaked by Mike Spreitzer on February 1, 1988 8:56:39 am PST ΚΉ˜™IcodešœA™A—J˜KšΟk œSœm˜ΛK˜šΡbnxœœ˜KšœSœl˜ΘKšœ˜—K˜Kšœœ%Οnœ œ˜[K˜Kšœœ˜%Kšœ œ ˜Kšœxœœ˜ŠKšœxœœ˜ŠK˜KšŸœœœ˜Kšœ œœ˜Kšœœ˜Kšœœœ˜Kšœœœ˜Kšœœœ˜K˜š Ÿœœœœœ˜OKšœœ˜ šŸ œœœœ˜$Kšœœ˜Kšœ œ˜#Kšœ ˜ K˜Kšœ œœ5œ˜SKš œœœ|œœF˜νKšœ6˜6Kšœ#˜#Kšœ4˜4Kšœ œ*˜8Kšœ&œ˜>Kšœœœ)˜;šœœœ˜Kšœ œ+˜9Kšœœœ1˜CKšœ7˜7Kšœ9˜9Kšœ6˜6Kšœ œ-˜;Kšœ&œ˜>Kšœœœ)˜;Kšœ˜—Kšœœœ˜*Kšœ˜ —Kšœœœ;œ˜SKšœ$˜$Kšœ˜—K˜šŸœœ˜0Kš œ'Ÿ œ#ŸœŸœŸœ˜ Kšœ˜—K˜šŸœœ˜0Kš œ'Ÿ œ#Ÿœ ŸœŸœ˜’Kšœ˜—K˜šŸ œœ)˜9Kšœ œ˜Kšœœœœ˜+K˜Kšœ˜—K˜šŸ œœ)˜9Kšœ œ˜Kšœ˜Kšœ˜Kšœ˜—K˜Kšœ%œœœ˜GKš œœœœœ˜K˜šŸœœŸ œ ΟcΠcm œŸœ  ‘ œŸœœ'Ÿœœ  œœ˜₯šŸœœ˜Kšœ   œ+œ˜HKšœœœ˜Kšœ#œ˜(šŸ œœ˜$Kšœ  œ$œ˜CšŸœœœœ˜ Kšœ!œ˜.K˜Kšœ,˜,Kšœ˜—K˜Kšœ˜—šŸœœœœ˜2Kšœœ ˜#Kšœœ˜K˜1Kšœœ œœ˜Kšœœ"œœ˜3Kšœœ˜Kšœ+œ˜1Kšœ0˜0Kšœ œœ˜EšŸ œœœœ˜"Kšœœ˜Kšœ1˜1Kšœ˜Kšœ˜—Kšœ#œ˜(Kšœ˜K˜$K˜#Kšœœ˜Kšœ˜ —Kš œ  ‘ œKœœM˜ΘšŸœœ œœ˜#Kšœœ˜K˜$Kšœœœœ ˜;Kšœ˜—šŸœœ œœ˜"Kšœœ˜Kšœ,˜,Kšœ#œ˜*Kšœœœ˜2šœœœœ˜)Kšœ  œ˜-Kšœ˜Kšœ˜—Kšœ œœ˜7KšœAœœ˜PKšœ&˜&Kš Ÿœœœœœ ˜FK˜!Kšœ˜Kšœœ˜Kšœ˜ —K˜"Kšœ)˜)Kšœœ˜Kšœ!˜!Kšœœ˜Kšœœ˜Kšœ˜Kšœœ˜Kšœœ˜Kšœ(˜(Kšœ˜Kšœœ˜Kšœ˜K˜!Kšœœ˜šœ˜Kšœœ,œ˜IKšœ#˜#K˜Kšœ œ˜—Kšœœ˜Kšœ˜ —K˜ Kšœ˜—K˜š Ÿœœ"  ‘ œ) €œ˜ςš œ œœœœœ˜CKšœ œ œ˜8Kšœ œ"œ˜:Kšœœ˜—Kš œ œœœœ˜8Kš =œœ˜Cšœ œœ˜9šŸ œœ œœ˜6Kšœœ˜-Kšœ˜—Kšœœœ˜)—Kšœ$œ˜+šŸœœœœ˜2Kš œœ œ œœ˜IKšœ˜—Kšœœœ˜&Kšœ˜—K˜šŸœœ2 œ˜išœœ˜Kšœœœœ˜,Kšœ˜—šœ˜Kšœœ˜$šŸœœœœ˜(Kšœœ ˜#Kšœœ˜%Kšœ+˜+Kšœ˜—Kšœ˜Kšœ˜—K˜—K˜šŸœœ&˜@Kšœ&œ˜-Kš Ÿœœœœœ ˜TšŸ œœœœ˜6šœ œœ˜Kšœœœœ˜Kš œœœœœ˜Kšœœ˜—K˜—Kšœœœœ˜Kšœ˜Kšœœœ˜*Kšœ)˜)šŸ œœœœ˜*šœœ˜Kšœœœ˜Kšœœœ œ˜2Kšœœ˜—Kšœ˜—šŸœœœœ˜7Kšœœ˜"šœœ˜Kšœ˜Kšœ˜Kšœ˜—šœ˜Kšœ#œ˜*šŸœœœœ˜3Kšœœ ˜#Kšœ+œ˜1Kšœ ˜ Kšœ˜—Kšœ˜Kšœ˜—Kšœ˜—šŸ œœ˜*Kšœ'œ˜.Kšœœ˜(Kšœœ œ˜)Kšœœœ˜Kšœœ˜Kš œ  œœœœ ˜NšŸœœœœ˜)Kšœœ ˜!šœœœœ˜.Kšœœ˜Kšœ˜Kšœ˜—šœœœ˜Kšœœœœ˜Kšœ˜Kšœœ ˜ Kšœœœœ˜Kšœ˜—šœ˜Kšœœ˜Kšœ˜—K˜—Kšœœœ˜'Kšœœœœ˜Kšœœœœ œ œœœ œ˜‹Kšœ˜—šŸœœœ˜GKšœ7œ˜?Kšœ œœœ˜—š ŸœœŸ œœœ˜hKšœ%œ˜,Kšœ œ˜,šŸœœœœ˜3Kšœœ ˜!Kšœœœ˜EKšœœœ˜+Kšœ œœœ˜.šœœ˜Kšœ$˜$Kšœœœ˜Kšœ2˜2Kšœ˜Kšœœ˜Kšœ˜—šœ˜šŸœœœ˜FKšœ4˜4Kšœ/œ˜6Kšœœœœ˜Kšœ˜"—Kšœ(œ˜.Kšœ'˜'Kšœ˜—Kšœ˜—Kš œ œœœœœ˜8Kšœ˜Kšœ˜—Kš œœ œ &œ˜DKšœ˜Kšœ-˜-Kšœ˜K˜šœœœ˜Kšœœ˜Kšœ-˜-Kšœœœœ˜-K˜—Kšœ˜ —K˜š Ÿœœ œ œ ˜Išœ1œœ˜DKšœ˜K˜Kšœ˜—Kšœ˜—K˜š Ÿœœ œ œ ˜Išœ1œœ˜DKšœ˜K˜Kšœ˜—Kšœ˜—K˜šŸ œœœ˜>Kšœœœ˜K˜Kšœ œœ˜šœ!œœ˜4šœœ œ˜šœœ œ˜.Kšœ œœ˜Kšœ œ"˜.šœœœ˜#Kš œœœ œœ˜4Kšœ˜—Kšœœœ'œ˜?KšœQœœN˜§K˜—Kšœœœœ˜Kšœœ˜—Kšœœœ˜:Kšœœ˜ —Kšœœœ œ˜,Kšœ œœ˜—K˜šŸœœ˜Kšœg˜gKšœg˜gKšœ˜—K˜K˜K˜Kšœ˜—…—3¦D½