DIRECTORY Containers USING [ChildXBound, ChildYBound], Convert USING [RopeFromInt], Graph USING [Entity, EntityGroup, EntityGroupList, EntityList, GraphHandle, GraphProc, NestedEntities, NestedEntitiesList, ROPE, Text, Texts, Viewer], GraphPrivate USING [CallWithLock, RemoveEntity, RemoveText, ShowEntity, ShowText, UserEditAllowed], GraphUtil USING [BlinkMsg, ControllerViewerExits, HandleNotNil], Rope USING [Concat, Fetch, IsEmpty, Length], TiogaFileOps USING [AddLooks, CreateRoot, InsertAsLastChild, InsertNode, Ref, SetContents, Store], TiogaButtons USING [CreateButton, CreateButtonFromNode, CreateViewer, LoadViewer, MarkViewerNotEdited, TiogaButton, TiogaButtonList, TiogaButtonProc], TiogaOps USING [Break, FirstChild, GetProp, GetRope, InsertRope, LastChild, Lock, LockSel, Nest, Next, Ref, RestoreSelA, SaveSelA, SelectPoint, SetSelection, StepForward, Unlock, UnlockSel, ViewerDoc], ViewerTools USING [SetContents]; GraphTable: CEDAR PROGRAM IMPORTS Containers, Convert, GraphPrivate, GraphUtil, Rope, TiogaFileOps, TiogaOps, TiogaButtons, ViewerTools EXPORTS GraphPrivate = { OPEN Graph, GraphPrivate; GraphButtonData: TYPE = REF GraphButtonDataRec; GraphButtonDataRec: TYPE = RECORD[ handle: GraphHandle _ NIL, ref: REF ANY _ NIL ]; MakeTable: PUBLIC PROC [handle: GraphHandle, file: ROPE, sx, sy: INTEGER] = { IF GraphUtil.HandleNotNil[handle] THEN { OPEN handle; controller.table _ TiogaButtons.CreateViewer[ info: [ wx: sx, wy: sy, ww: 1000, wh: 1000, menu: NIL, parent: controller.viewer, scrollable: TRUE, border: FALSE, caption: FALSE ]]; Containers.ChildXBound[controller.viewer, controller.table]; Containers.ChildYBound[controller.viewer, controller.table]; MakeTableFile[handle, file]; TiogaButtons.LoadViewer[controller.table, file]; CreateButtons[handle]; }; }; -- MakeTable MakeTableFile: PROC [handle: GraphHandle, tableFile: ROPE] = { root, prev: TiogaFileOps.Ref; IF GraphUtil.HandleNotNil[handle] THEN { OPEN handle; root _ TiogaFileOps.CreateRoot[]; prev _ TextsTable[handle, root]; FOR egl: EntityGroupList _ entityGroupList, egl.rest UNTIL egl = NIL DO prev _ NETable[handle, egl.first.ys, root, root, prev]; ENDLOOP; TiogaFileOps.Store[root, tableFile]; }; }; -- MakeTableFile NextNode: PROC [root, prev: TiogaFileOps.Ref, rope: ROPE, child: BOOL, look: ROPE _ NIL] RETURNS [new: TiogaFileOps.Ref] = { new _ TiogaFileOps.InsertNode[prev, child]; TiogaFileOps.SetContents[new, rope]; IF NOT look.IsEmpty[] THEN FOR i: INT IN [0..look.Length[]) DO TiogaFileOps.AddLooks[new, 0, rope.Length[], look.Fetch[i], root]; ENDLOOP; }; -- NextNode LastChild: PROC [root, parent, prev: TiogaFileOps.Ref, rope: ROPE, look: ROPE _ NIL] RETURNS [new: TiogaFileOps.Ref] = { new _ TiogaFileOps.InsertAsLastChild[parent, prev]; TiogaFileOps.SetContents[new, rope]; IF NOT look.IsEmpty[] THEN FOR i: INT IN [0..look.Length[]) DO TiogaFileOps.AddLooks[new, 0, rope.Length[], look.Fetch[i], root]; ENDLOOP; }; -- LastChild TextsTable: PROC [handle: GraphHandle, root: TiogaFileOps.Ref] RETURNS [new: TiogaFileOps.Ref] = { new _ NextNode[root, root, "", TRUE]; new _ NextNode[root, new, "Texts", FALSE, "lb"]; -- texts parent new _ NextNode[root, new, "", TRUE]; -- leading blank line FOR ts: Texts _ handle.allTexts, ts.rest UNTIL ts = NIL DO t: Text _ ts.first; -- error if nil. new _ NextNode[ root: root, prev: new, rope: IF t.text = NIL THEN Convert.RopeFromInt[t.id] ELSE t.text, child: FALSE, look: NIL ]; ENDLOOP; }; -- TextsTable EntityListTable: PROC [handle: GraphHandle, entityList: EntityList, root, parent: TiogaFileOps.Ref] RETURNS [new: TiogaFileOps.Ref] = { new _ parent; -- which is also the previous node. IF entityList # NIL THEN new _ NextNode[root, parent, "", TRUE]; FOR el: EntityList _ entityList, el.rest UNTIL el = NIL DO entity: Entity _ el.first; -- error if nil. new _ LastChild[root: root, parent: parent, prev: new, rope: IF entity.name.IsEmpty[] AND entity.comment.IsEmpty[] THEN Convert.RopeFromInt[entity.id] ELSE entity.name.Concat[entity.comment], look: NIL ]; ENDLOOP; }; -- EntityListTable NETable: PROC [handle: GraphHandle, ne: NestedEntities, root, parent, prev: TiogaFileOps.Ref] RETURNS [new: TiogaFileOps.Ref] = { new _ prev; IF ne # NIL THEN { topLevel: BOOL _ parent = root; neNode: TiogaFileOps.Ref; new _ LastChild[root: root, parent: parent, prev: prev, rope: "", look: NIL]; neNode _ new _ NextNode[root: root, prev: new, -- ne.node rope: ne.name.Concat[ne.comment], child: FALSE, look: IF topLevel THEN "lb" ELSE "b" ]; new _ EntityListTable[handle, ne.entityList, root, neNode]; FOR nel: NestedEntitiesList _ ne.children, nel.rest UNTIL nel = NIL DO new _ NETable[handle, nel.first, root, neNode, new]; ENDLOOP; }; }; -- NETable CreateButtons: PROC [handle: GraphHandle] = { OPEN handle; root: TiogaOps.Ref _ TiogaOps.ViewerDoc[controller.table]; prev: TiogaOps.Ref; prev _ TextsButtons[handle, root]; FOR egl: EntityGroupList _ entityGroupList, egl.rest UNTIL egl = NIL DO prev _ NEButtons[handle, egl.first.ys, root, root, prev]; ENDLOOP; }; -- CreateButtons TextsButtons: PROC [handle: GraphHandle, root: TiogaOps.Ref] RETURNS [last: TiogaOps.Ref] = { OPEN handle; last _ TiogaOps.FirstChild[root]; controller.textsParent _ last _ TiogaOps.StepForward[last]; last _ TiogaOps.StepForward[last]; FOR ts: Texts _ handle.allTexts, ts.rest UNTIL ts = NIL DO t: Text _ ts.first; -- error if nil. last _ TiogaOps.StepForward[last]; [] _ TiogaButtons.CreateButtonFromNode[node: last, proc: TextButtonProc, clientData: NEW[GraphButtonDataRec _ [handle, t]] ]; ENDLOOP; }; -- TextsButtons EntityListButtons: PROC [handle: GraphHandle, entityList: EntityList, root, parent: TiogaOps.Ref] RETURNS [last: TiogaOps.Ref] = { last _ parent; -- which is also the previous node. IF entityList # NIL THEN last _ TiogaOps.StepForward[last]; FOR el: EntityList _ entityList, el.rest UNTIL el = NIL DO entity: Entity _ el.first; -- error if nil. last _ TiogaOps.StepForward[last]; [] _ TiogaButtons.CreateButtonFromNode[node: last, proc: EntityButtonProc, clientData: NEW[GraphButtonDataRec _ [handle, entity]] ]; ENDLOOP; }; -- EntityListButtons NEButtons: PROC [handle: GraphHandle, ne: NestedEntities, root, parent, prev: TiogaOps.Ref] RETURNS [last: TiogaOps.Ref] = { last _ prev; IF ne # NIL THEN { topLevel: BOOL _ parent = root; last _ TiogaOps.StepForward[last]; ne.node _ last _ TiogaOps.StepForward[last]; last _ EntityListButtons[handle, ne.entityList, root, ne.node]; FOR nel: NestedEntitiesList _ ne.children, nel.rest UNTIL nel = NIL DO last _ NEButtons[handle, nel.first, root, ne.node, last]; ENDLOOP; }; }; -- NEButtons EntityGroupButtonProc: TiogaButtons.TiogaButtonProc = { -- noop for now }; -- EntityGroupButtonProc NestedEntitiesButtonProc: TiogaButtons.TiogaButtonProc = { -- noop for now. }; -- NestedEntitiesButtonProc EntityButtonProc: TiogaButtons.TiogaButtonProc = { data: GraphButtonData _ NARROW[clientData]; proc: GraphProc = { entity: Entity _ NARROW[data.ref]; SELECT mouseButton FROM red => { ViewerTools.SetContents[handle.controller.entityId, Convert.RopeFromInt[entity.id]]; ShowEntity[handle, entity]; }; blue => RemoveEntity[handle, entity]; ENDCASE; }; IF UserEditAllowed[data.handle] THEN CallWithLock[data.handle, proc]; }; -- EntityButtonProc TextButtonProc: TiogaButtons.TiogaButtonProc = { data: GraphButtonData _ NARROW[clientData]; proc: GraphProc = { t: Text _ NARROW[data.ref]; SELECT mouseButton FROM red => { ViewerTools.SetContents[handle.controller.textId, Convert.RopeFromInt[t.id]]; ShowText[handle, t]; }; blue => RemoveText[handle, t]; ENDCASE; }; CallWithLock[data.handle, proc]; }; -- EntityButtonProc AddTextButton: PUBLIC PROC [handle: GraphHandle, text: Text] = { IF GraphUtil.ControllerViewerExits[handle] AND handle.controller.table # NIL AND text # NIL THEN { root: TiogaOps.Ref _ TiogaOps.ViewerDoc[handle.controller.table]; TiogaOps.Lock[root]; TiogaOps.SelectPoint[handle.controller.table, [TiogaOps.LastChild[handle.controller.textsParent], -1]]; TiogaOps.LockSel[]; TiogaOps.Break[]; TiogaOps.InsertRope[ IF text.text = NIL THEN Convert.RopeFromInt[text.id] ELSE text.text]; TiogaOps.UnlockSel[]; TiogaOps.Unlock[root]; [] _ TiogaButtons.CreateButtonFromNode[ node: TiogaOps.LastChild[handle.controller.textsParent], start: , end: , proc: TextButtonProc, clientData: NEW[GraphButtonDataRec _ [handle, text]] ]; }; }; -- AddTextButton AddEntityButton: PUBLIC PROC [handle: GraphHandle, entity: Entity] = { IF GraphUtil.ControllerViewerExits[handle] AND handle.controller.table # NIL AND entity # NIL THEN { root: TiogaOps.Ref _ TiogaOps.ViewerDoc[handle.controller.table]; group: EntityGroup _ entity.group; TiogaOps.Lock[root]; TiogaOps.SelectPoint[handle.controller.table, [TiogaOps.LastChild[group.ys.node], -1]]; TiogaOps.LockSel[]; TiogaOps.Break[]; TiogaOps.Nest[]; TiogaOps.InsertRope[ IF entity.name.IsEmpty[] AND entity.comment.IsEmpty[] THEN Convert.RopeFromInt[entity.id] ELSE entity.name.Concat[entity.comment]]; TiogaOps.UnlockSel[]; TiogaOps.Unlock[root]; [] _ TiogaButtons.CreateButtonFromNode[ node: TiogaOps.LastChild[group.ys.node], start: , end: , proc: EntityButtonProc, clientData: NEW[GraphButtonDataRec _ [handle, entity]] ]; }; }; -- AddEntityButton AddGroupButton: PUBLIC PROC[handle: GraphHandle, entityGroup: EntityGroup] = { IF GraphUtil.ControllerViewerExits[handle] AND handle.controller.table # NIL AND entityGroup # NIL THEN { b: TiogaButtons.TiogaButton _ TiogaButtons.CreateButton[ viewer: handle.controller.table, rope: entityGroup.ys.name.Concat[entityGroup.ys.comment], looks: "b", proc: NestedEntitiesButtonProc, clientData: NEW[GraphButtonDataRec _ [handle, entityGroup.ys]] ]; entityGroup.ys.node _ TiogaOps.LastChild[TiogaOps.ViewerDoc[handle.controller.table]] }; }; -- AddGroupButton UpdateTextButton: PUBLIC PROC [handle: GraphHandle, text: Text] = { IF GraphUtil.ControllerViewerExits[handle] AND handle.controller.table # NIL AND text # NIL THEN { root: TiogaOps.Ref _ TiogaOps.ViewerDoc[handle.controller.table]; self: TiogaOps.Ref _ NIL; TiogaOps.Lock[root]; FOR n: TiogaOps.Ref _ TiogaOps.FirstChild[handle.controller.textsParent], TiogaOps.Next[n] UNTIL n = NIL DO list: TiogaButtons.TiogaButtonList _ NIL; tb: TiogaButtons.TiogaButton; gbd: GraphButtonData; tt: Text; ref: REF ANY _ TiogaOps.GetProp[n, $TiogaButtonList]; IF ref = NIL THEN LOOP; IF ISTYPE[ref, TiogaButtons.TiogaButtonList] THEN list _ NARROW[ref] ELSE LOOP; IF (tb _ list.first) = NIL THEN LOOP; IF (gbd _ NARROW[tb.clientData]) = NIL THEN LOOP; IF gbd.ref = NIL THEN LOOP; IF ISTYPE[gbd.ref, Text] THEN { tt _ NARROW[gbd.ref]; IF tt = text THEN {self _ n; EXIT}; }; ENDLOOP; IF self = NIL THEN GraphUtil.BlinkMsg["Can't find the text on table."] ELSE { TiogaOps.SaveSelA[]; TiogaOps.SetSelection[viewer: handle.controller.table, start: [self, 0], end: [self, TiogaOps.GetRope[self].Length[]], level: char, caretBefore: TRUE, pendingDelete: TRUE, which: primary]; TiogaOps.LockSel[]; TiogaOps.InsertRope[ IF text.text.IsEmpty[] THEN Convert.RopeFromInt[text.id] ELSE text.text]; TiogaOps.UnlockSel[]; TiogaButtons.MarkViewerNotEdited[root]; }; TiogaOps.RestoreSelA[]; TiogaOps.Unlock[root]; }; }; -- UpdateTextButton UpdateEntityButton: PUBLIC PROC [handle: GraphHandle, entity: Entity] = { IF GraphUtil.ControllerViewerExits[handle] AND handle.controller.table # NIL AND entity # NIL THEN { root: TiogaOps.Ref _ TiogaOps.ViewerDoc[handle.controller.table]; self: TiogaOps.Ref _ NIL; TiogaOps.Lock[root]; FOR n: TiogaOps.Ref _ TiogaOps.FirstChild[entity.parent.node], TiogaOps.Next[n] UNTIL n = NIL DO list: TiogaButtons.TiogaButtonList _ NIL; tb: TiogaButtons.TiogaButton; gbd: GraphButtonData; te: Entity; ref: REF ANY _ TiogaOps.GetProp[n, $TiogaButtonList]; IF ref = NIL THEN LOOP; IF ISTYPE[ref, TiogaButtons.TiogaButtonList] THEN list _ NARROW[ref] ELSE LOOP; IF (tb _ list.first) = NIL THEN LOOP; IF (gbd _ NARROW[tb.clientData]) = NIL THEN LOOP; IF gbd.ref = NIL THEN LOOP; IF ISTYPE[gbd.ref, Entity] THEN { te _ NARROW[gbd.ref]; IF te = entity THEN {self _ n; EXIT}; }; ENDLOOP; IF self = NIL THEN GraphUtil.BlinkMsg["Can't find the entity on table."] ELSE { TiogaOps.SaveSelA[]; TiogaOps.SetSelection[viewer: handle.controller.table, start: [self, 0], end: [self, TiogaOps.GetRope[self].Length[]], level: char, caretBefore: TRUE, pendingDelete: TRUE, which: primary]; TiogaOps.LockSel[]; TiogaOps.InsertRope[ IF entity.name.IsEmpty[] AND entity.comment.IsEmpty[] THEN Convert.RopeFromInt[entity.id] ELSE entity.name.Concat[entity.comment] ]; TiogaOps.UnlockSel[]; TiogaButtons.MarkViewerNotEdited[root]; }; TiogaOps.RestoreSelA[]; TiogaOps.Unlock[root]; }; }; -- UpdateEntityButton }. LOG. SChen, created at October 9, 1985 6:57:10 pm PDT. €GraphTable.mesa, Copyright c 1985 by Xerox Corporation. All rights reserved. Last Edited by: Sweetsun Chen, November 27, 1985 11:14:12 pm PST InputFocus USING [SetInputFocus], called by NewController, which should have made sure the following not nil: handle, handle.controller, etc. TiogaOps.Jump[controller.table, [controller.textsParent, 0]]; heading now its entity list and children. TiogaOps.Lock[root]; TiogaOps.SaveSelA[]; TiogaOps.Unlock[root]; TiogaOps.RestoreSelA[]; handle: GraphHandle _ NARROW[ViewerOps.FetchProp[parent, $GraphController]]; group: EntityGroup _ NARROW[clientData]; some checking might be necessary. SetIntField[controller.groupId, group.id]; Control[handle, resume, $Group]; SELECT moustButton FROM red => IF control THEN Control[handle, display, $Group]; blue => IF control THEN Control[handle, remove, $Group]; ENDCASE; replace the rope of a text button replace the rope of an entity button Κ Ε˜JšœΟmœ1™Mšœ™Icode™0—šΟk ˜ Jšœ žœ˜,Jšœžœ˜Jšœžœpžœ˜–Jšœ žœQ˜cJšœ žœ1˜@Jšœ žœ™!Jšœžœ"˜,Jšœ žœP˜bJšœ žœ„˜–Jšœ žœ»˜ΙJšœ žœ˜ —J˜šœ žœž˜Jšžœe˜mJšžœžœ˜2—J˜Jšœžœžœ˜/šœžœžœ˜"Jšœžœ˜Jšœžœžœž˜J˜—J˜š Οn œžœžœžœ žœ˜MJšœk™kšžœ žœžœ˜5šœ-˜-šœ˜Jšœ#˜#Jšœžœ˜ Jšœ˜Jšœ žœ˜Jšœžœ˜Jšœ ž˜Jšœ˜——Jšœ<˜Jšœ˜šžœ žœžœ˜5Jšœ!˜!Jšœ ˜ šžœ2žœžœž˜GJšœ7˜7Jšžœ˜—Jšœ$˜$J˜—Jšœ ˜J˜—šŸœžœ&žœ žœžœžœžœ˜|Kšœ+˜+Kšœ$˜$š žœžœžœžœžœžœž˜>KšœB˜BKšžœ˜—Kšœ  ˜J˜—š Ÿ œžœ.žœžœžœžœ˜xKšœ3˜3Kšœ$˜$š žœžœžœžœžœžœž˜>KšœB˜BKšžœ˜—Kšœ  ˜J˜—šŸ œžœ/žœ˜bJšœžœ˜%Jšœ#žœ  ˜@Jšœžœ ˜:šžœ&žœžœž˜:Jšœ ˜$šœ˜Jšœ˜Jš œžœ žœžœžœ˜AJšœžœ˜ Jšœž˜ Jšœ˜—Jšžœ˜—Jšœ  ˜J™—šŸœžœOžœ˜‡Jšœ #˜1Jšžœžœžœ"žœ˜@šžœ&žœžœž˜:Jšœ ˜+šœ7˜7šœžœžœ˜;Jšžœ˜#Jšžœ$˜(—Jšœž˜ J˜—Jšžœ˜—Jšœ ˜J˜—šŸœžœQžœ˜J˜ šžœžœžœ˜Jšœ žœ˜šœ˜J™—JšœHžœ˜Mšœ/  ˜9Jšœ!˜!Jšœžœ˜ Jšœžœ žœžœ˜$Jšœ˜J™!—Jšœ;˜;šžœ1žœžœž˜FJšœ4˜4Jšžœ˜—J˜—Jšœ  ˜ J˜—šŸ œžœžœ˜:Jšœ:˜:Jšœ˜J™J™J˜"šžœ2žœžœž˜GJšœ9˜9Jšžœ˜—J™Jšœ™Jšœ ˜J˜—šŸ œžœ+žœžœ˜jJšœ!˜!Jšœ;˜;Jšœ"˜"šžœ&žœžœž˜:Jšœ ˜$Jšœ"˜"šœ2˜2Jšœ˜Jšœ žœ"˜1J˜—Jšžœ˜—Jšœ ˜J˜—šŸœžœKžœ˜‚Jšœ #˜2Jšžœžœžœ#˜;šžœ&žœžœž˜:Jšœ ˜+Jšœ"˜"šœ2˜2Jšœ˜Jšœ žœ'˜6J˜—Jšžœ˜—Jšœ ˜J˜—šŸ œžœMžœ˜|J˜ šžœžœžœ˜Jšœ žœ˜Jšœ"˜"Jšœ,˜,Jšœ?˜?šžœ1žœžœž˜FJšœ9˜9Jšžœ˜—J˜—Jšœ  ˜J˜—šœ8 ˜GJšœžœ0™Lšœžœ ™(Jšœ!™!—Jšœ*™*Jšœ ™ šžœ ž™Jšœžœ žœ"™8Jšœžœ žœ!™8Jšžœ™—Jšœ ˜J˜—šœ; ˜KJšœ ˜J˜—šœ2˜2Jšœžœ ˜+˜Jšœžœ ˜"šžœ ž˜šœ˜JšœT˜TJšœ˜J˜—Jšœ%˜%Jšžœ˜—J˜—Jšžœžœ!˜EJšœ ˜J˜—šœ0˜0Jšœžœ ˜+˜Jšœ žœ ˜šžœ ž˜šœ˜JšœM˜MJšœ˜J˜—Jšœ˜Jšžœ˜—J˜—Jšœ ˜ Jšœ ˜—J˜—šŸ œžœžœ&˜@š žœ)žœžœžœžœžœ˜bJšœA˜AJ˜šœ-˜-Jšœ9˜9—J˜J˜šœ˜Jšžœ žœžœžœ ˜E—J˜J˜šœ'˜'JšœH˜HJšœ˜Jšœ žœ%˜4Jšœ˜—J˜—Jšœ ˜J™—šŸœžœžœ*˜Fš žœ)žœžœžœ žœžœ˜dJšœA˜AJšœ"˜"J˜šœ-˜-Jšœ)˜)—J˜J˜J˜šœ˜Jšžœžœžœ˜YJšžœ%˜)—J˜J˜šœ'˜'Jšœ8˜8Jšœ˜Jšœ žœ'˜6Jšœ˜—J˜—Jšœ ˜J˜—šŸœžœžœ3˜Nš žœ)žœžœžœžœžœ˜i˜8J˜ Jšœ9˜9J˜ Jšœ˜Jšœ žœ/˜>Jšœ˜—JšœU˜UJ˜—Jšœ ˜J˜—šŸœžœžœ&˜CJ™!š žœ)žœžœžœžœžœ˜bJšœA˜AJšœžœ˜J˜šžœXžœžœž˜kJšœ%žœ˜)J˜Jšœ˜J˜ Jšœžœžœ)˜5Jšžœžœžœžœ˜Jš žœžœ$žœžœžœžœ˜OJšžœžœžœžœ˜%Jš žœžœžœžœžœ˜1Jšžœ žœžœžœ˜šžœžœžœ˜Jšœžœ ˜Jšžœ žœ žœ˜#J˜—Jšžœ˜—Jšžœžœžœ4˜Fšžœ˜J˜šœ6˜6JšœL˜LJšœ žœžœ˜8—J˜šœ˜Jšžœžœžœ ˜I—J˜Jšœ'˜'J˜—Jšœ˜J˜J˜—Jšœ ˜J˜—šŸœžœžœ*˜IJ™$š žœ)žœžœžœ žœžœ˜dJšœA˜AJšœžœ˜J˜šžœMžœžœž˜`Jšœ%žœ˜)J˜Jšœ˜J˜ Jšœžœžœ)˜5Jšžœžœžœžœ˜Jš žœžœ$žœžœžœžœ˜OJšžœžœžœžœ˜%Jš žœžœžœžœžœ˜1Jšžœ žœžœžœ˜šžœžœžœ˜!Jšœžœ ˜Jšžœ žœ žœ˜%J˜—Jšžœ˜—Jšžœžœžœ6˜Hšžœ˜J˜šœ6˜6JšœL˜LJšœ žœžœ˜8—J˜šœ˜Jšžœžœžœ˜YJšžœ#˜'J˜—J˜Jšœ'˜'J˜—Jšœ˜J˜J˜—Jšœ ˜—J˜J˜J˜šžœ˜J˜1——…—1¨C