DIRECTORY Atom USING [GetPName], CreateNode USING [SpanInfo], FileWriter USING [blockSize, BumpWriter, Ref, WriteChar, WriteRope], NameSymbolTable USING [RopeFromName], NodeProps USING [GetProp, MapProps, GetSpecs], OutputStructure, Rope USING [ROPE], RopeEdit USING [Size], RopeReader USING [FreeRopeReader, GetRopeReader, GetString, Ref, SetPosition], RunReader USING [FreeRunReader, GetRunReader, MergedGet, Ref, SetPosition], T2FileOps, TiogaLooks USING [Look, Looks, noLooks, Runs], TiogaLooksOps USING [CountRuns], TiogaBasicClass USING [BasicClass], TiogaBranchClass USING [BranchClass, branchChildrenAtom, branchContentsAtom, defaultBranchClass], TiogaItemClass USING [ItemClass], TiogaNode USING [Name, nullName, Offset, Ref, RefBasicNode, RefBoxNode, RefBranchNode, RefItemNode, RefListNode, RefTextNode], TiogaNodeOps USING [FetchBasicClass, FetchItemClass, IsBranch]; OutputStructureImpl: CEDAR MONITOR IMPORTS Atom, FileWriter, NameSymbolTable, NodeProps, RopeEdit, RopeReader, RunReader, TiogaBranchClass, TiogaLooksOps, TiogaNodeOps EXPORTS OutputStructure SHARES RopeReader, FileWriter, TiogaNode = BEGIN Output: PUBLIC PROC [ ctrl, data: FileWriter.Ref, node: TiogaNode.Ref, contents: TiogaNode.Ref _ NIL, children: TiogaNode.RefBranchNode _ NIL] RETURNS [flags: CHAR] = { NoOfRuns: PROCEDURE [runs: TiogaLooks.Runs, size: INT] RETURNS [n: INT] = INLINE { IF runs=NIL THEN RETURN [0]; [n, ,] _ TiogaLooksOps.CountRuns[runs, 0, size] }; Output32: PROC [len: TiogaNode.Offset, forwards: BOOLEAN] = { first, second, fourth: T2FileOps.LengthByte; third: T2FileOps.ThirdByte; lenBytes: T2FileOps.IntBytes _ LOOPHOLE[len]; IF lenBytes.fourth # 0 THEN { fourth.data _ lenBytes.fourth; first.others _ second.others _ third.others _ TRUE }; IF lenBytes.thirdTop # 0 OR lenBytes.thirdBottom # 0 THEN { third.dataTop _ lenBytes.thirdTop; third.dataBottom _ lenBytes.thirdBottom; first.others _ second.others _ TRUE }; IF lenBytes.second # 0 THEN { second.data _ lenBytes.second; first.others _ TRUE }; first.data _ lenBytes.first; IF forwards THEN { WriteChar[LOOPHOLE[first], ctrl]; IF first.others THEN { WriteChar[LOOPHOLE[second], ctrl]; IF second.others THEN { WriteChar[LOOPHOLE[third], ctrl]; IF third.others THEN WriteChar[LOOPHOLE[fourth], ctrl] }}} ELSE { IF first.others THEN { IF second.others THEN { IF third.others THEN WriteChar[LOOPHOLE[fourth], ctrl]; WriteChar[LOOPHOLE[third], ctrl] }; WriteChar[LOOPHOLE[second], ctrl] }; WriteChar[LOOPHOLE[first], ctrl] }}; OutputAtom: PROC [atom: ATOM] = INLINE { OutputControlRope[Atom.GetPName[atom]] }; OutputB32: PROCEDURE [len: TiogaNode.Offset] = INLINE { Output32[len, FALSE] }; OutputTemplateInfo: PROCEDURE [node: TiogaNode.Ref] = INLINE { SELECT node.templateInfo FROM normal => NULL; application => FileWriter.WriteChar[T2FileOps.APPLICATION, ctrl]; formal => FileWriter.WriteChar[T2FileOps.FORMAL, ctrl]; ENDCASE => ERROR }; wholeTreeLevel: NAT = 3; PushBranchData: PROC [ctrlLen, dataLen: INT] = { top: NAT; IF (top _ branchIOStack.top)=branchIOStack.length THEN { -- make it bigger new: REF BranchIOStack _ NEW[BranchIOStack[top*2]]; FOR i: NAT _ 0, i+1 UNTIL i=top DO new[i] _ branchIOStack[i]; ENDLOOP; FreeBranchIOStack[branchIOStack]; branchIOStack _ new }; branchIOStack[top].ctrlLen _ ctrlLen; branchIOStack[top].dataLen _ dataLen; branchIOStack.top _ top+1 }; OutputBranch: PROCEDURE [ branch: TiogaNode.RefBranchNode, level: NAT, pushData: BOOL, contents: TiogaNode.Ref _ NIL, children: TiogaNode.RefBranchNode _ NIL] = { IF branch.deleted THEN ERROR; IF branch.externalRepValid THEN { brInfo: CreateNode.SpanInfo _ NARROW[NodeProps.GetProp[branch, $BranchInfo]]; FileWriter.WriteRope[ brInfo.externalRepRope, brInfo.charsLen, data, externRopeReader, brInfo.charsStart]; FileWriter.WriteRope[ brInfo.externalRepRope, brInfo.ctrlLen, ctrl, externRopeReader, brInfo.ctrlStart]; IF pushData THEN PushBranchData[brInfo.ctrlLen, brInfo.charsLen] } ELSE { WriterPos: PROC [writer: FileWriter.Ref] RETURNS [len: INT] = INLINE { RETURN [writer.blockCount*LONG[FileWriter.blockSize]+writer.block.length] }; doClass, doFormat: BOOL _ FALSE; op: T2FileOps.Op _ T2FileOps.branch; start: NAT; specs: Rope.ROPE; classInfo: TiogaBranchClass.BranchClass; startCtrlLoc, startDataLoc: INT; IF branch.hasbranchclass THEN classInfo _ NARROW[NodeProps.GetProp[branch, $BranchClass]]; IF classInfo=NIL THEN classInfo _ TiogaBranchClass.defaultBranchClass; IF pushData THEN { start _ branchIOStack.top; startCtrlLoc _ WriterPos[ctrl]; startDataLoc _ WriterPos[data] }; IF classInfo.flavor # $Branch THEN { op _ op + T2FileOps.classBit; doClass _ TRUE }; IF branch.format#TiogaNode.nullName THEN { op _ op + T2FileOps.formatBit; doFormat _ TRUE }; IF branch.comment THEN op _ op + T2FileOps.commentBit; WriteChar[op, ctrl]; IF doClass THEN OutputAtom[classInfo.flavor]; IF doFormat THEN OutputControlRope[NameSymbolTable.RopeFromName[branch.format]]; OutputTemplateInfo[branch]; IF branch.hasPropList THEN OutputProps[branch]; IF contents=NIL THEN contents _ branch.contents; IF (contents=NIL AND branch.hasbranchclass AND (specs _ NARROW[NodeProps.GetProp[branch, TiogaBranchClass.branchContentsAtom]])#NIL) OR (classInfo.getContents#NIL AND (specs _ classInfo.getContents[branch])#NIL) THEN { WriteChar[T2FileOps.BRANCHCONTENTSPECS, ctrl]; OutputControlRope[specs] } ELSE IF contents # NIL THEN OutputContentsList[contents]; IF children=NIL THEN children _ branch.child; IF (children=NIL AND branch.hasbranchclass AND (specs _ NARROW[NodeProps.GetProp[branch, TiogaBranchClass.branchChildrenAtom]])#NIL) OR (classInfo.getChildren#NIL AND (specs _ classInfo.getChildren[branch])#NIL) THEN { WriteChar[T2FileOps.CHILDSPECS, ctrl]; OutputControlRope[specs] } ELSE IF children=NIL THEN WriteChar[T2FileOps.NOCHILD, ctrl] ELSE { -- output the children branches count: NAT _ 0; -- number of children childLevel: NAT _ level+1; childrenPush: BOOL _ childLevel < wholeTreeLevel; IF ~childrenPush THEN WriteChar[T2FileOps.STARTC, ctrl] ELSE FileWriter.WriteChar[T2FileOps.ENDITEMS, ctrl]; FOR b: TiogaNode.RefBranchNode _ children, NARROW[b.next] DO OutputBranch[b, childLevel, childrenPush]; count _ count+1; IF b.last THEN EXIT; ENDLOOP; WriteChar[T2FileOps.ENDC, ctrl]; IF childrenPush THEN { -- write lengths and number of children IF count # branchIOStack.top-start THEN ERROR; -- children should have pushed info UNTIL branchIOStack.top=start DO -- pop and write ctrlLen and dataLen item: NAT _ branchIOStack.top-1; OutputB32[branchIOStack[item].ctrlLen]; OutputB32[branchIOStack[item].dataLen]; branchIOStack.top _ item; ENDLOOP; OutputB32[count] }}; IF pushData THEN PushBranchData[WriterPos[ctrl]-startCtrlLoc, WriterPos[data]-startDataLoc] }}; OutputControlRope: PROC [r: Rope.ROPE] = INLINE { len: INT _ RopeEdit.Size[r]; OutputF32[len]; FileWriter.WriteRope[r, len, ctrl, externRopeReader]; }; OutputCountRopeCR: PROC [r: Rope.ROPE, writer: FileWriter.Ref] = INLINE { OutputF32[RopeEdit.Size[r]]; OutputRope[r, writer]; }; OutputF32: PROCEDURE [len: TiogaNode.Offset] = INLINE { Output32[len, TRUE]; }; OutputContentsList: PROCEDURE [ref: TiogaNode.Ref] = { IF ref=NIL THEN RETURN; DO WITH ref SELECT FROM t: TiogaNode.RefTextNode => OutputTI[t]; br: TiogaNode.RefBranchNode => OutputBranch[br, wholeTreeLevel, FALSE]; ENDCASE => OutputOther[ref]; IF ref.last THEN RETURN; ref _ ref.next; ENDLOOP }; OutputProperty: PROC [name: ATOM, value: REF] RETURNS [BOOL] = { specs: Rope.ROPE _ NodeProps.GetSpecs[name, value, node]; -- node argument set by caller IF specs=NIL AND (specs _ NarrowToRope[value])=NIL THEN RETURN [FALSE]; WriteChar[T2FileOps.PROPERTY, ctrl]; OutputAtom[name]; OutputControlRope[specs]; RETURN [FALSE] }; OutputRope: PROC [r: Rope.ROPE, writer: FileWriter.Ref] = INLINE { FileWriter.WriteRope[r, RopeEdit.Size[r], writer, externRopeReader]; WriteChar[15C, writer] }; OutputRuns: PROCEDURE [runs: TiogaLooks.Runs, noOfRuns: TiogaNode.Offset] RETURNS [loc: TiogaNode.Offset _ 0] = { cnt: TiogaNode.Offset _ 0; RunReader.SetPosition[runReader, runs, 0]; OutputF32[noOfRuns]; WHILE (cnt_cnt+1) <= noOfRuns DO -- Process each run descriptor looks: TiogaLooks.Looks; len: TiogaNode.Offset; [len, looks] _ RunReader.MergedGet[runReader]; IF looks=TiogaLooks.noLooks THEN WriteChar[T2FileOps.NOLOOKS, ctrl] ELSE { -- write op's to set the bits; one op per bit that is set last: CHAR; initial: BOOL _ TRUE; FOR c: CHAR IN TiogaLooks.Look DO IF ~looks[c] THEN LOOP; IF initial THEN { last _ c; initial _ FALSE } -- save the first one to write out last ELSE WriteChar[T2FileOps.addLooksFirst+(c-FIRST[TiogaLooks.Look]), ctrl]; ENDLOOP; WriteChar[T2FileOps.lastLooksFirst+(last-FIRST[TiogaLooks.Look]), ctrl] }; OutputF32[len]; loc _ loc+len; ENDLOOP }; OutputTI: PROCEDURE [t: TiogaNode.RefTextNode] = { ropeSize: TiogaNode.Offset _ RopeEdit.Size[t.rope]; noOfRuns: TiogaNode.Offset _ NoOfRuns[t.runs, ropeSize]; op: T2FileOps.Op; doClass, doFormat, doProps, doRuns: BOOL _ FALSE; classInfo: TiogaItemClass.ItemClass _ TiogaNodeOps.FetchItemClass[t.class]; op _ T2FileOps.text; IF t.hasPropList OR t.templateInfo # normal THEN { op _ op + T2FileOps.propsBit; doProps _ TRUE }; IF classInfo.flavor # $Text THEN { op _ op + T2FileOps.classBit; doClass _ TRUE }; IF t.format#TiogaNode.nullName THEN { op _ op + T2FileOps.formatBit; doFormat _ TRUE }; IF noOfRuns # 0 THEN { op _ op + T2FileOps.runsBit; doRuns _ TRUE }; IF t.comment THEN op _ op + T2FileOps.commentBit; WriteChar[op, ctrl]; IF doClass THEN OutputAtom[classInfo.flavor]; IF doFormat THEN OutputControlRope[NameSymbolTable.RopeFromName[t.format]]; IF doRuns AND OutputRuns[t.runs, noOfRuns] # ropeSize THEN ERROR; OutputCountRopeCR[t.rope, IF t.comment THEN ctrl ELSE data]; IF doProps THEN { OutputTemplateInfo[t]; OutputProps[t]; WriteChar[T2FileOps.ENDPROPS, ctrl] }}; NarrowToRope: PROC [x: REF] RETURNS [Rope.ROPE] = { IF x=NIL THEN RETURN [NIL]; WITH x SELECT FROM r: Rope.ROPE => RETURN [r]; ENDCASE; RETURN [NIL] }; OutputProps: PROC [t: TiogaNode.Ref] = INLINE { IF t.hasPropList THEN { node _ t; [] _ NodeProps.MapProps[t, OutputProperty, FALSE, FALSE] }}; OutputOther: PROCEDURE [t: TiogaNode.Ref, contents: TiogaNode.Ref _ NIL] = { doFormat, doClass: BOOL _ FALSE; op: T2FileOps.Op; flavor: ATOM; classData, contentSpecs: Rope.ROPE; WITH t SELECT FROM bs: TiogaNode.RefBasicNode => { classInfo: TiogaBasicClass.BasicClass _ TiogaNodeOps.FetchBasicClass[bs.class]; op _ T2FileOps.basic; IF (flavor _ classInfo.flavor) # $Basic THEN { doClass _ TRUE; op _ op + T2FileOps.classBit }; IF bs.data#NIL AND classInfo.get#NIL THEN classData _ NARROW[classInfo.get[bs, $Save]] ELSE classData _ NarrowToRope[bs.data] }; bx: TiogaNode.RefBoxNode => { classInfo: TiogaItemClass.ItemClass _ TiogaNodeOps.FetchItemClass[bx.class]; op _ T2FileOps.box; IF (flavor _ classInfo.flavor) # $Box THEN { doClass _ TRUE; op _ op + T2FileOps.classBit }; IF contents=NIL THEN contents _ bx.contents; IF bx.data#NIL AND classInfo.get#NIL THEN classData _ NARROW[classInfo.get[bx, $Save]] ELSE classData _ NarrowToRope[bx.data] }; ls: TiogaNode.RefListNode => { classInfo: TiogaItemClass.ItemClass _ TiogaNodeOps.FetchItemClass[ls.class]; op _ T2FileOps.list; IF (flavor _ classInfo.flavor) # $List THEN { doClass _ TRUE; op _ op + T2FileOps.classBit }; IF contents=NIL THEN contents _ ls.contents; IF ls.data#NIL AND classInfo.get#NIL THEN classData _ NARROW[classInfo.get[ls, $Save]] ELSE classData _ NarrowToRope[ls.data] }; ENDCASE => ERROR; IF t.format#TiogaNode.nullName THEN { op _ op + T2FileOps.formatBit; doFormat _ TRUE }; IF t.comment THEN op _ op + T2FileOps.commentBit; WriteChar[op, ctrl]; IF doClass THEN OutputAtom[flavor]; IF doFormat THEN OutputControlRope[NameSymbolTable.RopeFromName[t.format]]; OutputTemplateInfo[t]; OutputProps[t]; IF contents=NIL THEN NULL ELSE IF contentSpecs#NIL THEN { WriteChar[T2FileOps.ITEMCONTENTSPECS, ctrl]; OutputControlRope[contentSpecs] } ELSE { IF TiogaNodeOps.IsBranch[contents] THEN WriteChar[T2FileOps.STARTBR, ctrl]; OutputContentsList[contents] }; IF classData=NIL THEN WriteChar[T2FileOps.NODATA, ctrl] ELSE { WriteChar[T2FileOps.CLASSDATA, ctrl]; OutputControlRope[classData] }}; WriteChar: PROC [c: CHAR, writer: FileWriter.Ref] = INLINE { FileWriter.WriteChar[c, writer] }; branchIOStack: REF BranchIOStack _ GetBranchIOStack[]; externRopeReader: RopeReader.Ref _ RopeReader.GetRopeReader[]; runReader: RunReader.Ref _ RunReader.GetRunReader[]; flags _ 0C; WITH node SELECT FROM t: TiogaNode.RefTextNode => OutputTI[t]; br: TiogaNode.RefBranchNode => { flags _ flags + T2FileOps.isBranchFlagBit; OutputBranch[br, 0, FALSE, contents, children] }; ENDCASE => OutputOther[node, contents]; RunReader.FreeRunReader[runReader]; RopeReader.FreeRopeReader[externRopeReader]; FreeBranchIOStack[branchIOStack] }; BranchIORecord: TYPE = RECORD [ctrlLen, dataLen: INT]; BranchIOStack: TYPE = RECORD [top: NAT _ 0, seq: SEQUENCE length: NAT OF BranchIORecord]; stack1, stack2, stack3: REF BranchIOStack; GetBranchIOStack: ENTRY PROC RETURNS [stack: REF BranchIOStack] = { ENABLE UNWIND => NULL; IF stack3 # NIL THEN { stack _ stack3; stack3 _ NIL } ELSE IF stack2 # NIL THEN { stack _ stack2; stack2 _ NIL } ELSE IF stack1 # NIL THEN { stack _ stack1; stack1 _ NIL } ELSE stack _ NEW[BranchIOStack[63]] }; FreeBranchIOStack: ENTRY PROC [stack: REF BranchIOStack] = { ENABLE UNWIND => NULL; IF stack3 = stack OR stack2 = stack OR stack1 = stack THEN ERROR; stack.top _ 0; IF stack3 = NIL THEN stack3 _ stack ELSE IF stack2 = NIL THEN stack2 _ stack ELSE IF stack1 = NIL THEN stack1 _ stack }; END. JOutputStructureImpl.Mesa written by Paxton. August 1983 Last Edited by: Paxton, August 26, 1983 4:48 pm The bytes are in the right place now write them out in the appropriate order Output a rope onto a given stream, preceeded its length and followed by a CR FORWARD32 : : = 1..4 RECORD [more: BOOL, data: [0..127]] Output a rope to the given stream followed by a CR IF (contents=NIL AND bx.hasPropList AND (contentSpecs _ NARROW[NodeProps.GetProp[bx, TiogaItemClass.itemContentsAtom]])#NIL) THEN NULL ELSE IF contents#NIL AND classInfo.getContents#NIL THEN contentSpecs _ classInfo.getContents[bx]; IF (contents=NIL AND ls.hasPropList AND (contentSpecs _ NARROW[NodeProps.GetProp[ls, TiogaItemClass.itemContentsAtom]])#NIL) THEN NULL ELSE IF contents#NIL AND classInfo.getContents#NIL THEN contentSpecs _ classInfo.getContents[ls]; Κέ– "cedar" style˜Jšœ™Jšœ™Jšœ/™/J™šΟk ˜ Jšœ œ ˜Jšœ œ ˜ Jšœ œ5˜HJšœœ˜'Jšœ œ ˜2Jšœ˜Jšœœœ˜Jšœ œ ˜Jšœ œ?˜RJšœ œ=˜OJšœ ˜ Jšœ œ˜2Jšœœ˜#Jšœœ˜&JšœœL˜cJšœœ˜$Jšœ œo˜Jšœ œ-˜A—J˜šœ ˜"Jšœ}˜„Jšœ˜Jšœ$˜*J˜—Jš˜J˜šΟnœœœ˜Jšœ0˜0Jšœœ&œ˜GJšœ œ˜J˜š žœ œœœœœ˜RJšœœœœ˜Jšœ2˜2—J˜šžœœ#œ˜=J˜,J˜Jšœœ˜-šœœ˜J˜Jšœ.œ˜6—šœœœ˜;J˜"J˜(Jšœœ˜'—šœœ˜Jšœ.œ˜5—J˜J™Lšœ œ˜Jšœ œ˜!šœœ˜Jšœ œ˜"šœœ˜Jšœ œ˜!Jšœœ œ˜:———šœ˜šœœ˜šœœ˜Jšœœ œ˜7Jšœ œ˜#—Jšœ œ˜$—Jšœ œ˜$——J˜Jšž œœœœ,˜RJ˜Jšž œ œœœ˜OJ˜šžœ œœ˜>šœ˜Jšœ œ˜Jšœ. œ˜AJšœ)œ˜7Jšœœ˜——J˜Jšœœ˜J˜šžœœœ˜0Jšœ˜ šœ0œΟc˜JJšœœœ˜3Jš œœ œœœ˜FJšœ!˜!Jšœ˜—Jšœ%˜%Jšœ%˜%Jšœ˜—J˜šž œ œ˜Jšœ(œ ˜Jšœ!œœŸ#˜RšœœŸ$˜EJšœœ˜ Jšœ'˜'Jšœ'˜'Jšœ˜Jšœ˜—Jšœ˜——Jšœ œO˜_——J˜šžœœ œœ˜2Jšœœ˜Jšœ˜Jšœ5˜5J˜—J˜šžœœ œœ˜IJ™LJšœ˜J˜J˜—J˜šž œ œœ˜7Jšœ9™9Jšœœ˜J˜—J˜šžœ œ˜6Jšœœœœ˜š˜šœœ˜Jšœ(˜(Jšœ@œ˜GJšœ˜—Jšœ œœ˜Jšœ˜Jšœ˜ ——J˜š žœœœ œœœ˜@Jšœ œ*Ÿ˜XJšœœœœœœœ˜GJšœœ ˜%J˜Jšœ˜Jšœœ˜—J˜šž œœ œœ˜BJ™2J˜DJ˜—J˜šž œ œ4˜IJšœ ˜'Jšœ˜J˜*Jšœ˜šœœŸ˜?J˜Jšœ˜J˜.Jšœœœ˜CšœŸ9˜@Jšœœ˜ Jšœ œœ˜šœœœ˜!Jšœ œœ˜Jšœ œœŸ'˜UJšœ&œ˜IJš˜—Jšœ)œ˜J—Jšœ˜J˜Jšœ˜ ——J˜šžœ œ˜2J˜3Jšœ8˜8Jšœ˜Jšœ$ œ˜2JšœK˜KJšœ˜Jšœœœ+œ˜bJšœœ+œ˜RJšœœ-œ˜WJšœœ)œ˜DJšœ œ!˜2Jšœ˜Jšœœ˜-Jšœ œ;˜KJšœœ)Ÿœ˜AJšœœ œœ˜œ ˜`—J˜š ž œœœœœ˜3Jš œœœœœ˜Jš œœœœœœ˜7Jšœœ˜—J˜šž œœœ˜/Jšœœ8œœ˜^—J˜šž œ œ.œ˜LJšœ œ˜!Jšœ˜Jšœœ˜ Jšœœ˜#šœœ˜šœ˜JšœO˜OJšœ˜Jšœ%œ œ!˜^Jš œ œœœœ œ˜VJšœ%˜)—šœ˜JšœL˜LJšœ˜Jšœ#œ œ!˜\Jšœ œœ˜,šœ œœ™'Jšœœ:œ™T—Jšœ™ š œœ œœœ™7Jšœ)™)—Jš œ œœœœ œ˜VJšœ%˜)—šœ˜JšœL˜LJšœ˜Jšœ$œ œ!˜]Jšœ œœ˜,šœ œœ™'Jšœœ:œ™T—Jšœ™ š œœ œœœ™7Jšœ)™)—Jš œ œœœœ œ˜VJšœ%˜)—Jšœœ˜—J˜Jšœœ-œ˜Wšœ œ!˜2J˜—Jšœ˜Jšœœ˜#Jšœ œ;˜KJšœ&˜&Jšœ œœ˜šœœœœ˜Jšœœ*˜N—šœ˜Jšœ!œœ˜KJšœ˜—Jšœ œœœ˜7Jšœ œ)˜M—J˜Jšž œœœœ%˜_J˜Jšœœ$˜6J˜>J˜4J˜ šœœ˜Jšœ(˜(šœ ˜ Jšœ?œ˜\—Jšœ ˜'—J˜#J˜,šœ#˜#J™——Jšœœœœ˜6š œœœœ œ œœ˜YJ˜—šœœ˜*J˜—š žœœœœ œ˜CJš œœ˜Jšœ œœœ˜5Jš œœ œœœ˜:Jš œœ œœœ˜:Jšœ œ˜&J˜—šžœœœœ˜