DIRECTORY CD, Convert, Core, CoreCreate, CoreOps, CoreGeometry, CoreProperties, IO, Ports, PWCore, Rope, Rosemary, Sinix, Sisyph, Sch, TerminalIO, TilingClass; SchImpl: CEDAR PROGRAM IMPORTS Convert, CoreCreate, CoreOps, CoreGeometry, CoreProperties, IO, PWCore, Rope, Sinix, Sisyph, TerminalIO, TilingClass EXPORTS Sch = BEGIN OPEN Sch; iconRope: ROPE _ ".icon"; schRope: ROPE _ ".sch"; Name: PROC [cx: Context] RETURNS [name: ROPE] = { RETURN [Sisyph.mode.nameProc[Sisyph.GetCDObj[cx], cx]]; }; Sch: PUBLIC PROC [cx: Context, name: ROPE] = { CheckObjectName[cx, Rope.Cat[name, schRope]]; Sisyph.AddProp[cx, $PWCoreSourceDesign, "design", FALSE]; }; Icon: PUBLIC PROC [cx: Context, name: ROPE] RETURNS [ct: CellType] = { CheckObjectName[cx, Rope.Cat[name, iconRope]]; ct _ Sisyph.ExtractSchematicByName[Rope.Cat[name, schRope], cx]; }; CheckObjectName: PUBLIC PROC [cx: Context, assertedName: ROPE] = { objectName: ROPE _ Name[cx]; IF NOT Rope.Equal[objectName, assertedName] THEN TerminalIO.PutF["Warning: ChipNDale directory name %g does not correspond to asserted name %g", IO.refAny[objectName], IO.refAny[assertedName]]; }; Orient: PUBLIC PROC [cx: Context, atom: ATOM] RETURNS [ct: CellType] = { objectName: ROPE _ Name[cx]; baseCell: Core.CellType _ Sisyph.ExtractSchematicByName[objectName, cx]; ct _ PWCore.RotateCellType[baseCell, atom]; Sisyph.Store[cx, Sisyph.corePropsRope, NEW [Core.Properties _ NIL]]; -- ??? I do not understand that one [BS, April 24, 1987 2:35:53 pm PDT] }; WireSide: PROC [wire: Core.Wire, baseCT: Core.CellType] RETURNS [sides: CoreGeometry.Sides _ CoreGeometry.noSide] ~ { EachPin: CoreGeometry.EachPinProc = { sides[side] _ TRUE; }; [] _ CoreGeometry.EnumerateSides[Sisyph.mode.decoration, baseCT, wire, EachPin]; }; WireSideProblem: PROC [wire: Core.Wire, msg: ROPE, baseCT: Core.CellType] ~ { TerminalIO.PutF["\n*** Wire %g %g in cell %g\n", IO.rope[CoreOps.GetFullWireName[baseCT.public, wire]], IO.rope[msg], IO.rope[CoreOps.GetCellTypeName[baseCT]]]; SIGNAL Sinix.CallerBug[]; }; CSeqStitch: PUBLIC PROC [cx: Sisyph.Context, count: NAT, dir: XorY] RETURNS [ct: Core.CellType] = { ct _ CSeqStitchOb[Name[cx], cx, count, dir]; }; CSeqStitchOb: PROC [obName: ROPE, cx: Sisyph.Context, count: NAT, dir: XorY] RETURNS [ct: Core.CellType] = { sWires, fsWires: LIST OF CoreCreate.WR; EachWire: CoreOps.EachWireProc = { sides: CoreGeometry.Sides = WireSide[wire, baseCT]; vertical: BOOL = sides[top] OR sides[bottom]; horizontal: BOOL = sides[left] OR sides[right]; IF ~(vertical OR horizontal) THEN RETURN; -- This wire has no pins, try its sons IF vertical AND horizontal THEN WireSideProblem[wire, "touches adjacent sides", baseCT]; IF (horizontal AND (dir=X OR dir=RX)) OR (vertical AND (dir=Y OR dir=RY)) THEN { wireName: Rope.ROPE _ CoreOps.GetShortWireName[wire]; inWire: BOOL _ Rope.Match["*In", wireName]; IF inWire OR Rope.Match["*Out", wireName] THEN { this: BOOL _ sides[left] OR sides[bottom]; searchName: Rope.ROPE _ Rope.Cat[Rope.Substr[wireName, 0, Rope.Length[wireName] - (IF inWire THEN Rope.Length["In"] ELSE Rope.Length["Out"])], IF inWire THEN "Out" ELSE "In"]; IF (sides[top] AND sides[bottom]) OR (sides[left] AND sides[right]) THEN WireSideProblem[wire, "touches both sides but is a stitch", baseCT]; FOR pas: LIST OF CoreCreate.PA _ stitchPorts, pas.rest UNTIL pas=NIL DO IF Rope.Equal[NARROW[IF this THEN pas.first.actual ELSE pas.first.public], searchName] THEN { IF this THEN pas.first.public _ wireName ELSE pas.first.actual _ wireName; EXIT; }; REPEAT FINISHED => stitchPorts _ CONS[IF this THEN [wireName, NIL] ELSE [NIL, wireName], stitchPorts]; ENDLOOP; } }; IF (vertical AND (dir=X OR dir=RX)) OR (horizontal AND (dir=Y OR dir=RY)) THEN IF wire.size=0 THEN sWires _ CONS[wire, sWires] ELSE fsWires _ CONS[wire, fsWires]; subWires _ FALSE; }; baseCT: Core.CellType _ Sisyph.ExtractSchematicByName[obName, cx]; stitchPorts: LIST OF CoreCreate.PA _ NIL; IF count=0 THEN RETURN[NIL]; [] _ CoreOps.VisitWireSeq[baseCT.public, EachWire]; ct _ CoreCreate.SequenceCell[ name: Rope.Cat[obName, "Seq", SELECT dir FROM X => "X", Y => "Y", RX => "RX", RY => "RY", ENDCASE => ERROR], baseCell: baseCT, count: count, sequencePorts: CoreCreate.WireList[sWires], flatSequencePorts: CoreCreate.WireList[fsWires], stitchPorts: stitchPorts]; SELECT dir FROM X => PWCore.SetArrayX[ct]; Y => PWCore.SetArrayY[ct]; RX => PWCore.SetLayout[ct, $ReverseArrayX]; RY => PWCore.SetLayout[ct, $ReverseArrayY]; ENDCASE => ERROR; Sisyph.Store[cx, Sisyph.corePropsRope, NEW [Core.Properties _ NIL]]; -- To prevent coreProps of the object from overriding (??? No comprendo [BS April 24, 1987 2:36:38 pm PDT]) }; CSeq: PUBLIC PROC [cx: Sisyph.Context, count: NAT, dir: XorY] RETURNS [ct: Core.CellType] = { ct _ CSeqOb[Name[cx], cx, count, dir]; }; CSeqOb: PUBLIC PROC [obName: ROPE, cx: Sisyph.Context, count: NAT, dir: XorY] RETURNS [ct: Core.CellType] = { sWires, fsWires: LIST OF CoreCreate.WR; EachWire: CoreOps.EachWireProc = { sides: CoreGeometry.Sides = WireSide[wire, baseCT]; vertical: BOOL = sides[top] OR sides[bottom]; horizontal: BOOL = sides[left] OR sides[right]; IF ~(vertical OR horizontal) THEN RETURN; -- This wire has no pins, try its sons IF vertical AND horizontal THEN WireSideProblem[wire, "touches adjacent sides", baseCT]; IF (vertical AND (dir=X OR dir=RX)) OR (horizontal AND (dir=Y OR dir=RY)) THEN IF wire.size=0 THEN sWires _ CONS[wire, sWires] ELSE fsWires _ CONS[wire, fsWires]; subWires _ FALSE; }; baseCT: Core.CellType _ Sisyph.ExtractSchematicByName[obName, cx]; IF count=0 THEN RETURN[NIL]; [] _ CoreOps.VisitWireSeq[baseCT.public, EachWire]; ct _ CoreCreate.SequenceCell[ name: Rope.Cat[obName, "Seq", SELECT dir FROM X => "X", Y => "Y", RX => "RX", RY => "RY", ENDCASE => ERROR], baseCell: baseCT, count: count, sequencePorts: CoreCreate.WireList[sWires], flatSequencePorts: CoreCreate.WireList[fsWires] ]; SELECT dir FROM X => PWCore.SetArrayX[ct]; Y => PWCore.SetArrayY[ct]; RX => PWCore.SetLayout[ct, $ReverseArrayX]; RY => PWCore.SetLayout[ct, $ReverseArrayY]; ENDCASE => ERROR; Sisyph.Store[cx, Sisyph.corePropsRope, NEW [Core.Properties _ NIL]]; -- To prevent coreProps of the object from overriding (??? I do not understand that [BS, April 24, 1987 2:33:34 pm PDT]) }; CStitch: PUBLIC PROC [cx: Context, count: NAT, dir: XorY] RETURNS [ct: CellType] = { ct _ CStitchOb[Name[cx], cx, count, dir]; }; CStitchOb: PUBLIC PROC [obName: ROPE, cx: Context, count: NAT, dir: XorY] RETURNS [ct: CellType] = { IF count=0 THEN RETURN[NIL]; SELECT dir FROM X => ct _ StitchX[obName, cx, count]; Y => ct _ StitchY[obName, cx, count]; ENDCASE => ERROR; Sisyph.Store[cx, Sisyph.corePropsRope, NEW [Core.Properties _ CoreProperties.Props[[$Layout, CoreProperties.GetCellTypeProp[ct, $Layout]]]]]; }; StitchX: PROC [obName: ROPE, cx: Sisyph.Context, count: NAT] RETURNS [ct: CellType] ~ { public: Wire; tileRow: TilingClass.TileRow _ NEW [TilingClass.TileRowRec[count]]; tileArray: TilingClass.TileArray _ NEW [TilingClass.TileArrayRec[1]]; baseCT: CellType _ Sisyph.ExtractSchematicByName[obName, cx]; publicElements, arrayedWires, leftSideOnlyWires, rightSideOnlyWires, globalWires: Wires _ NIL; EachWire: CoreOps.EachWireProc = { sides: CoreGeometry.Sides = WireSide[wire, baseCT]; vertical: BOOL = sides[top] OR sides[bottom]; IF vertical AND (sides[right] OR sides[left]) THEN WireSideProblem[wire, "touches adjacent sides", baseCT]; IF vertical THEN { newPublic: Wire _ CoreOps.CreateWires[count, CoreOps.GetShortWireName[wire]]; arrayedWires _ CONS[wire, arrayedWires]; FOR i: INT IN [0..count) DO newPublic[i] _ CoreOps.SetShortWireName[CoreOps.CopyWire[wire], NIL]; ENDLOOP; publicElements _ CONS[newPublic, publicElements]; } ELSE { IF sides=CoreGeometry.noSide THEN { IF IsGlobal[wire, cx] THEN { globalWires _ CONS [wire, globalWires]; publicElements _ CONS [wire, publicElements] } } ELSE { IF sides[left] THEN leftSideOnlyWires _ CONS[wire, leftSideOnlyWires]; IF sides[right] THEN rightSideOnlyWires _ CONS[wire, rightSideOnlyWires]; publicElements _ CONS [wire, publicElements] } } }; [] _ CoreOps.VisitWireSeq[baseCT.public, EachWire]; public _ CoreOps.CreateWire[publicElements]; FOR i: INT IN [0..count) DO tileRow[i] _ NEW [TilingClass.TileRec _ [type: baseCT]] ENDLOOP; FOR wl: Wires _ leftSideOnlyWires, wl.rest WHILE wl#NIL DO wireName: ROPE _ CoreOps.GetShortWireName[wl.first]; tileRow[0].renaming _ CONS[[wireName, wireName], tileRow[0].renaming]; ENDLOOP; FOR wl: Wires _ rightSideOnlyWires, wl.rest WHILE wl#NIL DO wireName: ROPE _ CoreOps.GetShortWireName[wl.first]; tileRow[count-1].renaming _ CONS[[wireName, wireName], tileRow[count-1].renaming]; ENDLOOP; FOR wl: Wires _ globalWires, wl.rest WHILE wl#NIL DO wireName: ROPE _ CoreOps.GetShortWireName[wl.first]; FOR i: NAT IN [0..count) DO tileRow[i].renaming _ CONS[[wireName, wireName], tileRow[i].renaming]; ENDLOOP; ENDLOOP; FOR wl: Wires _ arrayedWires, wl.rest WHILE wl#NIL DO wireName: ROPE _ CoreOps.GetShortWireName[wl.first]; FOR i: NAT IN [0..count) DO tileRow[i].renaming _ CONS[[wireName, Rope.Cat[wireName, "[", Convert.RopeFromInt[i], "]"]], tileRow[i].renaming]; ENDLOOP; ENDLOOP; tileArray[0] _ tileRow; ct _ TilingClass.CreateTiling[CoreOps.CopyWire[public], tileArray, TilingClass.SchematicsNeighborX, TilingClass.SchematicsNeighborY, Rope.Cat[obName, ".StitchX"]]; }; StitchY: PROC [obName: ROPE, cx: Sisyph.Context, count: NAT] RETURNS [ct: CellType] ~ { public: Wire; tileArray: TilingClass.TileArray _ NEW [TilingClass.TileArrayRec[count]]; baseCT: CellType _ Sisyph.ExtractSchematicByName[obName, cx]; publicElements, arrayedWires, botSideOnlyWires, topSideOnlyWires, globalWires: Wires _ NIL; EachWire: CoreOps.EachWireProc = { sides: CoreGeometry.Sides = WireSide[wire, baseCT]; horizontal: BOOL = sides[left] OR sides[right]; IF horizontal AND (sides[top] OR sides[bottom]) THEN WireSideProblem[wire, "touches adjacent sides", baseCT]; IF horizontal THEN { newPublic: Wire _ CoreOps.CreateWires[count, CoreOps.GetShortWireName[wire]]; arrayedWires _ CONS[wire, arrayedWires]; FOR i: INT IN [0..count) DO newPublic[i] _ CoreOps.SetShortWireName[CoreOps.CopyWire[wire], NIL]; ENDLOOP; publicElements _ CONS[newPublic, publicElements]; } ELSE { IF sides=CoreGeometry.noSide THEN { IF IsGlobal[wire, cx] THEN { globalWires _ CONS [wire, globalWires]; publicElements _ CONS [wire, publicElements] } } ELSE { IF sides[bottom] THEN botSideOnlyWires _ CONS[wire, botSideOnlyWires]; IF sides[top] THEN topSideOnlyWires _ CONS[wire, topSideOnlyWires]; publicElements _ CONS [wire, publicElements] } } }; [] _ CoreOps.VisitWireSeq[baseCT.public, EachWire]; public _ CoreOps.CreateWire[publicElements]; FOR i: INT IN [0..count) DO tileArray[i] _ NEW [TilingClass.TileRowRec[1]]; tileArray[i][0] _ NEW [TilingClass.TileRec _ [type: baseCT]] ENDLOOP; FOR wl: Wires _ botSideOnlyWires, wl.rest WHILE wl#NIL DO wireName: ROPE _ CoreOps.GetShortWireName[wl.first]; tileArray[0][0].renaming _ CONS[[wireName, wireName], tileArray[0][0].renaming]; ENDLOOP; FOR wl: Wires _ topSideOnlyWires, wl.rest WHILE wl#NIL DO wireName: ROPE _ CoreOps.GetShortWireName[wl.first]; tileArray[count-1][0].renaming _ CONS[[wireName, wireName], tileArray[count-1][0].renaming]; ENDLOOP; FOR wl: Wires _ globalWires, wl.rest WHILE wl#NIL DO wireName: ROPE _ CoreOps.GetShortWireName[wl.first]; FOR i: NAT IN [0..count) DO tileArray[i][0].renaming _ CONS[[wireName, wireName], tileArray[i][0].renaming]; ENDLOOP; ENDLOOP; FOR wl: Wires _ arrayedWires, wl.rest WHILE wl#NIL DO wireName: ROPE _ CoreOps.GetShortWireName[wl.first]; FOR i: NAT IN [0..count) DO tileArray[i][0].renaming _ CONS[[wireName, Rope.Cat[wireName, "[", Convert.RopeFromInt[i], "]"]], tileArray[i][0].renaming]; ENDLOOP; ENDLOOP; ct _ TilingClass.CreateTiling[CoreOps.CopyWire[public], tileArray, TilingClass.SchematicsNeighborX, TilingClass.SchematicsNeighborY, Rope.Cat[obName, ".StitchY"]]; }; WSeq: PUBLIC PROC [name: ROPE _ NIL, size: NAT] RETURNS [wire: Wire] = { wire _ CoreCreate.Seq[name, size]; }; WRange: PUBLIC PROC [name: ROPE, start: NAT, size: NAT] RETURNS [wire: Core.Wire] = { wire _ CoreCreate.Seq[size: size]; FOR i: NAT IN [0..size) DO [] _ CoreOps.SetShortWireName[wire[i], IO.PutFR["%g[%g]", IO.rope[name], IO.int[start+i]]]; ENDLOOP; }; WIndex: PUBLIC PROC [name: ROPE, index: NAT] RETURNS [wire: Core.Wire] = { wire _ CoreOps.CreateWire[name: name]; [] _ CoreOps.SetShortWireName[wire, IO.PutFR["%g[%g]", IO.rope[name], IO.int[index]]]; }; InitPort: PUBLIC PROC [cx: Context, initType: Ports.LevelType _ b, initDrive: Ports.Drive _ none] = { Sisyph.Store[cx, "initType", NEW [Ports.LevelType _ initType]]; Sisyph.Store[cx, "initDrive", NEW [Ports.Drive _ initDrive]]; Sisyph.AddProp[ cx, $PortData, "NEW[Ports.PortDataRec _ [levelType: initType, driveType: aggregate, drive: initDrive, drives: NIL]]", TRUE]; }; TSize: PUBLIC PROC [cx: Context, size: Rosemary.TransistorSize] = { Sisyph.Store[cx, "size", NEW [Rosemary.TransistorSize _ size]]; Sisyph.AddProp[cx, $RoseTransistorSize, "NEW[Ports.Drive _ size]", TRUE]; }; SetWire: PUBLIC PROC [cx: Context, level: Ports.Level _ L, size: Rosemary.WireSize _ charge] = { Sisyph.Store[cx, "level", NEW [Ports.Level _ level]]; Sisyph.Store[cx, "size", NEW [Rosemary.WireSize _ size]]; Sisyph.AddProp[cx, $RoseWireData, "NEW[Rosemary.RoseWireDataRec _ [level, size]]", TRUE]; }; IsGlobal: PROC [w: Wire, cx: Sisyph.Context] RETURNS [BOOL _ FALSE] = { name: ROPE _ CoreOps.GetShortWireName[w]; FOR lr: LIST OF ROPE _ Sisyph.GetGlobalNames[cx], lr.rest WHILE lr#NIL DO IF Rope.Equal[name, lr.first] THEN RETURN [TRUE] ENDLOOP; }; END. ΠSchImpl.mesa Copyright Σ 1986, 1987 by Xerox Corporation. All rights reserved. Louis Monier February 13, 1986 3:46:07 pm PST Barth, February 18, 1987 11:08:39 pm PST Last Edited by: Louis Monier January 22, 1987 10:48:47 pm PST Jean-Marc Frailong December 17, 1986 6:20:02 pm PST Pradeep Sindhu June 26, 1987 2:02:27 pm PDT Bertrand Serlet April 24, 1987 2:37:49 pm PDT Finds the sides on which wire touches baseCT (of which it is a public). CoreGeometry.noSide will be returned if the wire has no pins. This should be in CoreGeometry. Copying the public is necessary to avoid sharing of wires between cellTypes Copying the public is necessary to avoid sharing of wires between cellTypes Internal Utilities ΚŠ– "cedar" style˜codešœ ™ KšœB™BKšœ*Οk™-Kšœ%™(Kšœ:™=Kšœ0™3Kšœ+™+Kšœ-™-K™—Kš œœDœM˜ŸK˜•StartOfExpansion[]šΠbnœœ˜Kšœ=œ6˜|Kšœ˜ Kšœœœ˜—K˜Kšœ œ ˜Kšœ œ ˜K˜šΟnœœœœ˜1Kšœ1˜7K˜K˜—šŸœœœœ˜.Kšœ-˜-Kšœ2œ˜9Kšœ˜K™—š Ÿœœœœœ˜FKšœ.˜.Kšœ@˜@Kšœ˜K™—šŸœœœœ˜BKšœ œ ˜Kš œœ&œaœœ˜ΑKšœ˜K™—š Ÿœœœœœ˜HKšœ œ ˜KšœH˜HJšœ+˜+Jšœ'œœΟcG˜ŒK˜K˜—šŸœœ*œ6˜uKšœ₯™₯šŸœ˜%Kšœœ˜K˜—KšœP˜PK˜K˜—šŸœœœ˜Mšœ0˜0Kšœ4˜6Kšœ ˜ Kšœ(˜*—Kšœ˜K˜K˜—š Ÿ œœœœ œ˜cKšœ,˜,K˜K˜—š Ÿ œœ œœ œ˜lKšœœœ œ˜'šŸœ˜"Kšœ3˜3Kšœ œœ˜-Kšœ œœ˜/Kš œ œ œœ &˜PKšœ œ œ9˜Xšœ œœœœ œœœœ˜QKšœœ"˜5Kšœœ˜+šœœœ˜0Kšœœœ˜*Kšœœ>œœœœœœ˜―Kš œ œœœœE˜š œœœ œœœ˜Gš œ œœœœ œ˜]Kšœœœ˜JKšœ˜K˜—Kšœœœœœ œœœ˜fKšœ˜—K˜—K˜—Kšœ œœœœ œœœœœ œ œœ œ˜£Kšœ œ˜Kšœ˜—KšœB˜BKš œ œœ œœ˜)Kšœ œœœ˜Kšœ3˜3šœ˜šœœ˜-Jš œœ œ œœ˜@—Kšœ˜Kšœ ˜ Kšœ,˜,Kšœ1˜1Kšœ˜—šœ˜Jšœ˜Jšœ˜Jšœ)˜+Jšœ)˜+Jšœœ˜—Kšœ'œœ k˜°K˜K˜—š Ÿœœœœ œ˜]Kšœ&˜&K˜K˜—š Ÿœœœ œœ œ˜mKšœœœ œ˜'šŸœ˜"Kšœ3˜3Kšœ œœ˜-Kšœ œœ˜/Kš œ œ œœ &˜PKšœ œ œ9˜XKšœ œœœœ œœœœœ œ œœ œ˜£Kšœ œ˜Kšœ˜—KšœB˜BKšœ œœœ˜Kšœ3˜3šœ˜šœœ˜-Jš œœ œ œœ˜@—Kšœ˜Kšœ ˜ Kšœ,˜,Kšœ/˜/Kšœ˜—šœ˜Jšœ˜Jšœ˜Jšœ)˜+Jšœ)˜+Jšœœ˜—Kšœ'œœ x˜½K˜K˜—š Ÿœœœœ œ˜TKšœ)˜)K˜—K˜š Ÿ œœœ œœ œ˜dKšœ œœœ˜šœ˜Kšœ&˜&Kšœ%˜%Kšœœ˜—Kšœ'œc˜K˜K˜—š Ÿœœ œœœ˜WK˜ Kšœœ!˜CKšœ#œ˜EKšœ=˜=KšœZœ˜^K˜šŸœ˜"Kšœ3˜3Kšœ œœ˜-Kšœ œœœ9˜kšœ ˜ šœ˜KšœM˜MKšœœ˜(šœœœ ˜Kšœ@œ˜EKšœ˜—Kšœœ˜1K˜—šœ˜šœ˜šœ˜šœœ˜Kšœœ˜'Kšœœ˜,K˜—K˜—šœ˜Kšœ œœ˜GKšœœœ˜IKšœœ˜,K˜——K˜——K˜K˜—K˜Kšœ3˜3Kšœ,˜,K˜šœœœ ˜Kšœ œ'˜7Kšœ˜—J˜šœ(œœ˜:Jšœ œ&˜4Jšœœ,˜FJšœ˜—J˜šœ)œœ˜;Jšœ œ&˜4Jšœœ2˜RJšœ˜—J˜šœ"œœ˜4Jšœ œ&˜4šœœœ ˜Jšœœ,˜FJšœ˜—Jšœ˜J˜—šœ#œœ˜5Jšœ œ&˜4šœœœ ˜JšœœX˜rJšœ˜—Jšœ˜—K˜K˜KšœK™KKšœ£˜£K˜K˜—š Ÿœœ œœœ˜WK˜ Kšœ#œ#˜IKšœ=˜=KšœWœ˜[K˜šŸœ˜"Kšœ3˜3Kšœ œœ˜/Kšœ œ œœ9˜mšœ ˜ šœ˜KšœM˜MKšœœ˜(šœœœ ˜Kšœ@œ˜EKšœ˜—Kšœœ˜1K˜—šœ˜šœ˜šœ˜šœœ˜Kšœœ˜'Kšœœ˜,K˜—K˜—šœ˜Kšœœœ˜GKšœ œœ˜CKšœœ˜,K˜——K˜——K˜K˜—K˜Kšœ3˜3Kšœ,˜,K˜šœœœ ˜Kšœœ˜/Kšœœ'˜