DIRECTORY Buttons USING [ButtonProc, Create], Containers USING [Create], Graphics USING [black, Box, Context, DrawBox, DrawRope, DrawStroke, DrawTo, FontRef, GetBounds, NewPath, Path, Rectangle, SetColor, SetCP, SetPaintMode, SetStipple, white], IconManager USING [selectedIcon], Menus USING [AppendMenuEntry, CreateEntry, CreateMenu, Menu, MenuProc], Rope USING [Cat, Equal, Length, ROPE], VFonts USING [EstablishFont, GraphicsFont], ViewerClasses USING[Column, InitProc, NotifyProc, PaintProc, SaveProc, ViewerClass, ViewerClassRec, ViewerFlavor, Viewer], ViewerEvents USING [EventProc, RegisterEventProc], ViewerLocks USING [CallUnderViewerTreeLock], ViewerOps USING [AddProp, CloseViewer, ChangeColumn, ComputeColumn, CreateViewer, DestroyViewer, EnumerateChildren, EnumerateViewers, EnumProc, FetchProp, FetchViewerClass, FindViewer, GrowViewer, MoveBoundary, MoveViewer, OpenIcon, PaintEverything, PaintViewer, RegisterViewerClass, TopViewer], ViewerSpecs USING [openLeftWidth, openBottomY], ViewerTools USING [GetSelectedViewer, GetSelectionContents]; ViewerSetImpl: CEDAR MONITOR IMPORTS Buttons, Containers, Graphics, IconManager, Menus, Rope, VFonts, ViewerEvents, ViewerLocks, ViewerOps, ViewerSpecs, ViewerTools SHARES ViewerOps = BEGIN OPEN ViewerClasses; ViewerSetData: TYPE = REF ViewerSetDataRec; ViewerSetDataRec: TYPE = RECORD[ openLeftWidth: INTEGER _ 0, openBottomY: INTEGER _ 0, cacheLimit: INTEGER _ 0]; Entry: TYPE = REF EntryRec; EntryRec: TYPE = RECORD[ name: Rope.ROPE, flavor: ViewerClasses.ViewerFlavor, viewer: ViewerClasses.Viewer, column: ViewerClasses.Column, iconic: BOOLEAN, position: INTEGER, height: INTEGER, wy, wh: INTEGER]; current: Viewer; MRUCache: Viewer; buttonHeight: INTEGER _ 16; firstButton: INTEGER _ 3; menu: Menus.Menu; iconFont: Graphics.FontRef _VFonts.GraphicsFont[VFonts.EstablishFont["TimesRoman", 8]]; screenH: INTEGER _ 808; screenW: INTEGER _ 1024; Init: PROC = BEGIN desktop, container: ViewerClasses.ViewerClass; menu _ Menus.CreateMenu[]; Menus.AppendMenuEntry[menu, Menus.CreateEntry["Open", MenuOpen]]; -- Menus.AppendMenuEntry[menu, Menus.CreateEntry["Save", MenuSave]]; Menus.AppendMenuEntry[menu, Menus.CreateEntry["New", MenuCreate]]; Menus.AppendMenuEntry[menu, Menus.CreateEntry["Rename", MenuRename]]; Menus.AppendMenuEntry[menu, Menus.CreateEntry["AddSelected", AddSelected]]; container _ ViewerOps.FetchViewerClass[$Container]; desktop _ NEW[ViewerClassRec _ container^]; desktop.flavor _ $DeskTop; desktop.notify _ ClassNotify; desktop.save _ ClassSave; desktop.init _ ClassInit; desktop.paint _ ClassPaint; desktop.menu _ menu; desktop.icon _ document; ContainerInit _ container.init; -- save for future use ViewerOps.RegisterViewerClass[$DeskTop, desktop]; [] _ Buttons.Create[info: [name: "Clean", column: static], proc: ClearIcons]; END; MenuCreate: Menus.MenuProc = {[] _ Create[]}; MenuSave: Menus.MenuProc = {Save[NARROW[parent]]}; MenuOpen: Menus.MenuProc = {Open[NARROW[parent]]}; MenuRename: Menus.MenuProc = { desktop: Viewer = NARROW[parent]; desktop.name _ ViewerTools.GetSelectionContents[]; ViewerOps.PaintViewer[desktop, caption]}; ContainerInit: ViewerClasses.InitProc; ClassInit: ViewerClasses.InitProc = { data: ViewerSetData _ NEW[ViewerSetDataRec _ []]; ContainerInit[self]; self.icon _ private; -- Save[self]; data.openBottomY _ ViewerSpecs.openBottomY; data.openLeftWidth _ ViewerSpecs.openLeftWidth; ViewerOps.AddProp[self, $ViewerSetData, data]; IF current = NIL THEN MakeCurrent[desktop: self, repaintOnSave: TRUE]}; ClassSave: ViewerClasses.SaveProc = {}; -- Save[self]}; ClassPaint: ViewerClasses.PaintProc = BEGIN IF ~self.iconic THEN RETURN; PaintDeskTop[self, context]; IF IconManager.selectedIcon = self THEN{ [] _ Graphics.SetPaintMode[context, invert]; Graphics.DrawBox[context, Graphics.GetBounds[context]]}; END; PaintDeskTop: PROC[self: Viewer, context: Graphics.Context] = BEGIN scale: REAL = 16; box: Graphics.Box; frobX, frobY: REAL; data: ViewerSetData; left, right: BOOL _ TRUE; box _ Graphics.GetBounds[context]; Graphics.SetColor[context, Graphics.white]; Graphics.DrawBox[context, [box.xmin, box.ymin, box.xmax, box.ymax]]; data _ NARROW[ViewerOps.FetchProp[self, $ViewerSetData]]; frobX _ data.openLeftWidth/scale; frobY _ data.openBottomY/scale + 13; Graphics.SetColor[context, Graphics.black]; IF self # current THEN FOR child: Viewer _ self.child, child.sibling WHILE child # NIL DO entry: Entry _ NARROW[ViewerOps.FetchProp[child, $Entry]]; IF entry = NIL OR entry.iconic THEN LOOP; SELECT entry.column FROM left => {DrawRectangle[context, 0, 13+entry.wy/scale, frobX, 13+entry.wy/scale+entry.wh/scale]; left _ FALSE}; right => {DrawRectangle[context, frobX, 13+entry.wy/scale, box.xmax, 13+entry.wy/scale+entry.wh/scale]; right _ FALSE}; ENDCASE; ENDLOOP; Graphics.SetStipple[context, 122645B]; IF self # current THEN { Graphics.DrawBox[context, [box.xmin, 13, box.xmax, frobY]]; IF left THEN Graphics.DrawBox[context, [box.xmin, 13, frobX-1, box.ymax]]; IF right THEN Graphics.DrawBox[context, [frobX+1, 13, box.xmax, box.ymax]]}; IF self = current THEN { Graphics.DrawBox[context, [box.xmin, box.ymin+13, box.xmax, box.ymax]]}; Graphics.SetColor[context, Graphics.black]; DrawRectangle[context, box.xmin, box.ymin+1, box.xmax-1, box.ymax]; IF self = current THEN DrawRectangle[context, box.xmin+1, box.ymin+2, box.xmax-2, box.ymax-1]; Graphics.SetCP[context, box.xmin, 13]; Graphics.DrawTo[context, box.xmax, 13]; Graphics.SetCP[context, 3, 3]; Graphics.DrawRope[self: context, rope: self.name, font: iconFont]; END; DrawRectangle: PROCEDURE[context: Graphics.Context, x1, y1, x2, y2: REAL] = BEGIN path: Graphics.Path; path _ Graphics.NewPath[4]; Graphics.Rectangle[path, x1, y1, x2, y2]; Graphics.DrawStroke[self: context, path: path, closed: TRUE]; END; ClassNotify: ViewerClasses.NotifyProc = BEGIN FOR input _ input, input.rest WHILE input # NIL DO SELECT input.first FROM $OpenDesktop => Open[self]; ENDCASE; ENDLOOP; END; ClearIcons: Buttons.ButtonProc = BEGIN list: LIST OF Viewer; LockedClear: PROC = BEGIN AddIconic: ViewerOps.EnumProc = { IF v.iconic AND UneditedDocument[v] THEN list _ CONS[v, list]}; ViewerOps.EnumerateViewers[AddIconic]; AddViewers[MRUCache, list]; FOR list _ list, list.rest WHILE list # NIL DO ViewerOps.DestroyViewer[list.first]; ENDLOOP; END; IF MRUCache = NIL OR MRUCache.destroyed THEN { MRUCache _ Containers.Create[info: [name: "MRU Cache", column: right, iconic: TRUE]]; ViewerOps.AddProp[MRUCache, $ViewerSetData, NEW[ViewerSetDataRec _ [cacheLimit: 25]]]}; IF MRUCache.offDeskTop THEN ViewerOps.ChangeColumn[MRUCache, right]; ViewerLocks.CallUnderViewerTreeLock[LockedClear]; END; Create: PUBLIC PROC[name: Rope.ROPE _ NIL] RETURNS[desktop: Viewer] = BEGIN FindDeskTop: ViewerOps.EnumProc = { IF v.class.flavor = $DeskTop AND Rope.Equal[v.name, name] THEN {desktop _ v; RETURN[TRUE]}}; IF name.Length[] = 0 THEN name _ "Desktop"; ViewerOps.EnumerateViewers[FindDeskTop]; IF desktop = NIL THEN desktop _ ViewerOps.CreateViewer[flavor: $DeskTop, info: [name: name, column: right, iconic: TRUE]]; IF desktop.offDeskTop THEN ViewerOps.ChangeColumn[desktop, right]; END; Save: PROC[desktop: Viewer] = BEGIN LockedSave: PROC = { AddToList: ViewerOps.EnumProc = { IF v.column # static THEN list _ CONS[v, list]}; MoveOffDeskTop: ViewerOps.EnumProc = { IF v.column = static THEN RETURN; IF ~v.iconic THEN ViewerOps.CloseViewer[v, FALSE]; IF v.class.flavor = $DeskTop THEN RETURN; IF v.class.flavor = $Clock THEN RETURN; IF v.class.flavor = $FileTool THEN RETURN; -- IF Rope.Equal[v.name, "EditTool"] THEN RETURN; -- IF Rope.Equal[v.name, "Watch"] THEN RETURN; -- IF Rope.Equal[v.name, "Work Area A: Executive"] THEN RETURN; ViewerOps.ChangeColumn[v, static]}; data: ViewerSetData; list: LIST OF Viewer; data _ NARROW[ViewerOps.FetchProp[desktop, $ViewerSetData]]; data.openLeftWidth _ ViewerSpecs.openLeftWidth; data.openBottomY _ ViewerSpecs.openBottomY; ViewerOps.EnumerateViewers[AddToList]; [] _ Erase[desktop, save, TRUE]; AddViewers[desktop, list]; ViewerOps.EnumerateViewers[MoveOffDeskTop]; }; IF desktop = NIL OR desktop.class.flavor # $DeskTop THEN RETURN; ViewerLocks.CallUnderViewerTreeLock[LockedSave]; END; Open: PROC[desktop: Viewer] = BEGIN LockedOpen: PROC = { OpenItems: ViewerOps.EnumProc = {OpenItem[button: v, all: TRUE]}; SetHeights: ViewerOps.EnumProc = {IF ~v.iconic THEN SetHeight[v]}; data: ViewerSetData = NARROW[ViewerOps.FetchProp[desktop, $ViewerSetData]]; MakeCurrent[desktop]; -- ViewerOps.GreyScreen[0, 0, 9999, 9999, FALSE, FALSE]; IF data # NIL THEN IF data.openLeftWidth # ViewerSpecs.openLeftWidth OR data.openBottomY # ViewerSpecs.openBottomY THEN ViewerOps.MoveBoundary[data.openLeftWidth, data.openBottomY]; ViewerOps.EnumerateChildren[desktop, OpenItems]; ViewerOps.EnumerateChildren[desktop, SetHeights]}; IF desktop = NIL OR desktop.class.flavor # $DeskTop THEN RETURN; ViewerLocks.CallUnderViewerTreeLock[LockedOpen]; ViewerOps.PaintEverything[]; END; MakeCurrent: ENTRY PROC[desktop: Viewer, repaintOnSave: BOOL _ FALSE] = BEGIN old: Viewer = current; current _ desktop; IF old # NIL THEN { IF old # desktop THEN { Save[old]; IF repaintOnSave THEN ViewerOps.PaintEverything[]}; IF old.iconic THEN ViewerOps.PaintViewer[old, all]}; END; Erase: ViewerEvents.EventProc = BEGIN list: LIST OF Viewer; MakeList: ViewerOps.EnumProc = {list _ CONS[v, list]}; IF event = destroy AND viewer = current THEN current _ NIL; ViewerOps.EnumerateChildren[viewer, MakeList]; FOR list _ list, list.rest WHILE list # NIL DO entry: Entry = NARROW[ViewerOps.FetchProp[list.first, $Entry]]; IF entry # NIL AND entry.viewer # NIL AND ~entry.viewer.destroyed AND entry.viewer.offDeskTop THEN ViewerOps.ChangeColumn[entry.viewer, entry.column]; ViewerOps.DestroyViewer[list.first, FALSE]; ENDLOOP; END; AddSelected: Menus.MenuProc = BEGIN column: ViewerClasses.Column; viewer: Viewer = NARROW[parent]; selected: Viewer _ ViewerTools.GetSelectedViewer[]; IF selected = NIL THEN RETURN; column _ selected.column; IF ~selected.iconic THEN ViewerOps.CloseViewer[selected, FALSE]; ViewerOps.ComputeColumn[column]; AddViewers[viewer, LIST[selected]]; ViewerOps.ChangeColumn[selected, static]; END; AddViewers: PROCEDURE [desktop: Viewer, list: LIST OF Viewer] = BEGIN data: ViewerSetData = NARROW[ViewerOps.FetchProp[desktop, $ViewerSetData]]; added: INTEGER; count: INTEGER _ 0; NewEntry: PROCEDURE [v: Viewer] RETURNS [Entry] = {RETURN[NEW[EntryRec _ [v.name, v.class.flavor, v, v.column, v.iconic, v.position, v.openHeight, v.wy, v.wh]]]}; CountViewers: PROC[list: LIST OF Viewer] RETURNS[c: INTEGER _ 0] = INLINE { FOR v: LIST OF Viewer _ list, v.rest WHILE v # NIL DO c _ c + 1; ENDLOOP}; EliminateDuplicates: ViewerOps.EnumProc = BEGIN last: LIST OF Viewer; entry: Entry = NARROW[ViewerOps.FetchProp[v, $Entry]]; IF entry = NIL OR entry.viewer = NIL OR entry.viewer.destroyed THEN RETURN; FOR temp: LIST OF Viewer _ list, temp.rest WHILE temp # NIL DO IF temp.first # entry.viewer THEN {last _ temp; LOOP}; IF last = NIL THEN list _ temp.rest ELSE last.rest _ temp.rest; EXIT; ENDLOOP; END; MoveOrDestroy: ViewerOps.EnumProc = BEGIN IF v.class.flavor # $Button THEN RETURN; IF data # NIL AND data.cacheLimit > 0 AND v.wy - firstButton + added*buttonHeight >= data.cacheLimit*buttonHeight THEN ViewerOps.DestroyViewer[v, FALSE] ELSE ViewerOps.MoveViewer[v, v.wx, v.wy+added*buttonHeight, v.ww, v.wh, FALSE]; END; ViewerOps.EnumerateChildren[desktop, EliminateDuplicates]; added _ CountViewers[list]; ViewerOps.EnumerateChildren[desktop, MoveOrDestroy]; FOR l: LIST OF Viewer _ list, l.rest WHILE l # NIL DO entry: Entry _ NewEntry[l.first]; name: Rope.ROPE _ Rope.Cat[Atom.GetPName[entry.flavor], ": ", entry.name]; button: Viewer _ Buttons.Create[ info: [name: name, parent: desktop, wy: firstButton + count*buttonHeight], proc: MyButtonProc, paint: FALSE]; ViewerOps.AddProp[button, $Entry, entry]; count _ count + 1; ENDLOOP; ViewerOps.PaintViewer[desktop, all]; END; MyButtonProc: Buttons.ButtonProc = BEGIN LockedOpenItem: PROC = {IF control THEN RemoveItem[NARROW[parent]] ELSE OpenItem[NARROW[parent], FALSE, shift]}; ViewerLocks.CallUnderViewerTreeLock[LockedOpenItem]; END; OpenItem: PROC[button: Viewer, all, grow: BOOL _ FALSE] = BEGIN e: Entry = NARROW[ViewerOps.FetchProp[button, $Entry]]; iconic: BOOLEAN _ all AND e.iconic; moved: BOOLEAN _ FALSE; IF e.viewer.destroyed THEN { -- find or create a replacement e.viewer _ ViewerOps.FindViewer[e.name]; IF e.viewer # NIL AND e.viewer.class.flavor # e.flavor THEN e.viewer _ NIL; IF e.viewer = NIL THEN { e.viewer _ ViewerOps.CreateViewer[flavor: e.flavor, info: [name: e.name, file: e.name, iconic: iconic, column: e.column], paint: ~all]; moved _ TRUE}}; IF e.viewer.offDeskTop THEN { ViewerOps.ChangeColumn[e.viewer, e.column]; IF ~all THEN iconic _ e.iconic}; IF iconic AND ~e.viewer.iconic THEN { ViewerOps.CloseViewer[e.viewer, ~all]; moved _ TRUE}; IF e.column # e.viewer.column THEN { -- close viewer to avoid repainting the world IF ~e.viewer.iconic AND all THEN ViewerOps.CloseViewer[e.viewer, ~all]; ViewerOps.ChangeColumn[e.viewer, e.column]; moved _ TRUE}; IF ~iconic AND e.viewer.iconic THEN { ViewerOps.OpenIcon[icon: e.viewer, paint: ~all]; moved _ TRUE}; IF all THEN {ViewerOps.TopViewer[e.viewer, ~all]; moved _ TRUE}; IF grow THEN {ViewerOps.GrowViewer[e.viewer]; moved _ TRUE}; IF ~all AND ~moved THEN ViewerOps.PaintViewer[e.viewer, all]; END; SetHeight: PROC[button: Viewer] = BEGIN e: Entry _ NARROW[ViewerOps.FetchProp[button, $Entry]]; e.viewer.position _ e.position; e.viewer.openHeight _ e.height; END; RemoveItem: PROC[button: Viewer] = BEGIN parent: Viewer = button.parent; entry: Entry = NARROW[ViewerOps.FetchProp[button, $Entry]]; MoveUp: ViewerOps.EnumProc = {IF v.wy > button.wy THEN ViewerOps.MoveViewer[v, v.wx, v.wy-buttonHeight, v.ww, v.wh, FALSE]}; IF entry.viewer # NIL AND ~entry.viewer.destroyed AND entry.viewer.offDeskTop THEN ViewerOps.ChangeColumn[entry.viewer, entry.column]; ViewerOps.EnumerateChildren[parent, MoveUp]; ViewerOps.DestroyViewer[button, FALSE]; ViewerOps.PaintViewer[parent, all]; END; UneditedDocument: PROC[v: Viewer] RETURNS[BOOLEAN] = INLINE { RETURN[v # NIL AND v.class.flavor = $Text AND ~v.newVersion AND ~v.newFile]}; [] _ ViewerEvents.RegisterEventProc[Erase, destroy, $DeskTop]; Init[]; END. |ViewerSetImpl.mesa -- Last Edited by: Maxwell, February 9, 1983 9:41 am ******* initialization and menu ******* create menu create new class [self: Viewer, context: Graphics.Context, whatChanged: REF ANY, clear: BOOL] ; invert if selected erase icon area draw outlines of inner boxes paint in grey areas draw lines draw name $SaveDesktop => Save[self]; $ResetDesktop => Reset[]; ******* basic procedures ******* [viewer: Viewer, event: ViewerEvent, before: BOOL] ******* detail procedures ******* IF e.viewer.class.flavor # $Text THEN RETURN; move the viewer to where it should be if the viewer hasn't been moved, repaint it Ê€˜Jšœ™JšÏc4™4J˜šÏk ˜ Jšœžœ˜#Jšœ žœ ˜šœ žœR˜`JšœL˜L—Jšœ žœ˜!Jšœžœ<˜GJšœžœžœ˜&Jšœžœ˜+šœžœ4˜GJšœ3˜3—Jšœ žœ ˜2Jšœ žœ˜,šœ žœC˜RJšœÕ˜Õ—Jšœ žœ˜/Jšœ žœ+˜<—J˜Jšœžœžœ˜Jšžœ€˜‡Jšžœ ž˜Jšžœ˜J˜Jšœžœžœ˜+šœžœžœ˜ Jšœžœ˜Jšœ žœ˜Jšœ žœ˜—J˜Jšœžœžœ ˜šœ žœžœ˜Jšœ žœ˜Jšœ#˜#J˜J˜Jšœžœ˜Jšœ žœ˜Jšœž˜Jšœžœ˜—J˜J˜J˜Jšœžœ˜Jšœ žœ˜J˜J˜J˜WJšœ žœ˜Jšœ žœ˜J˜Jšœ'™'J™šÏnœžœž˜J˜.Jšœ ™ J˜J˜BJ˜EJ˜CJ˜FJ˜KJšœ™J˜3Jšœ žœ˜+J˜Jšœ˜Jšœ˜J˜J˜J˜J˜Jšœ ˜6J˜1J˜J˜MJšžœ˜—J˜šÏb œ#˜-J˜—š œžœ ˜2J˜—š œžœ ˜2J˜—š  œ˜Jšœžœ ˜!Jšœ2˜2J˜)—J˜š  œ˜&J˜—š  œ˜%Jšœžœ˜1J˜Jšœ˜Jšœ˜J˜+J˜/Jšœ.˜.Jšžœ žœžœ+žœ˜GJ˜—š  œ˜7J˜—š  œž˜+JšœN™NJšžœžœžœ˜J˜Jšœ™šžœ!žœ˜(J˜,J˜8—Jšžœ˜J˜—šŸ œžœ,ž˜CJšœžœ˜J˜Jšœžœ˜J˜Jšœ žœžœ˜J™J˜"J˜+J˜DJšœ™Jšœžœ,˜9Jšœ!˜!Jšœ$˜$J˜+š žœžœžœ+žœ žœž˜YJšœžœ%˜:Jš žœ žœžœžœžœ˜)šžœž˜šœ6˜6Jšœ)˜)Jšœžœ˜—šœ;˜;Jšœ,˜,Jšœžœ˜—Jšžœ˜—Jšžœ˜—Jšœ™Jšœ&˜&šžœžœ˜J˜;Jšžœžœ>˜JJšžœžœ@˜M—šžœžœ˜J˜H—Jšœ ™ J˜+J˜Cšžœžœ˜J˜G—J˜&J˜'Jšœ ™ J˜JšœB˜BJšžœ˜J˜šŸ œž œ,žœž˜QJšœ˜Jšœ˜Jšœ)˜)Jšœ7žœ˜=Jšžœ˜——š  œž˜-šžœžœ žœž˜2šžœ ž˜J˜Jšœ™Jšœ™Jšžœ˜—Jšžœ˜Jšžœ˜——J˜Jšœ!™!J˜š  œž˜&Jšœžœžœ˜šŸ œžœž˜š  œ˜!Jšžœ žœžœžœ ˜?—J˜&Jšœ˜šžœžœžœž˜.J˜$Jšžœ˜—Jšžœ˜J˜—šžœ žœžœžœ˜.JšœNžœ˜Ušœ,˜,Jšžœ(˜+——Jšžœžœ)˜DJ˜J˜1Jšžœ˜J˜—š Ÿœž œ žœžœžœž˜Kš  œ˜#šžœžœ˜:Jšžœžœžœ˜"J˜——Jšžœžœ˜+J˜(šžœ žœžœ4˜IJšœ*žœ˜1—Jšžœžœ(˜BJšžœ˜J˜—šŸœžœž˜#šÐbn  žœ˜š  œ˜!Jšžœžœžœ ˜0—š œ˜&Jšžœžœžœ˜!Jšžœ žœžœ˜2Jšžœžœžœ˜)Jšžœžœžœ˜'Jšžœžœžœ˜*Jšžœ žœžœ˜1Jšžœžœžœ˜.Jšžœ.žœžœ˜?Jšœ#˜#—Jšœ˜Jšœžœžœ˜Jšœžœ/˜˜B—Jšœ0˜0Jšœ2˜2—J˜Jš žœ žœžœ!žœžœ˜@J˜0J˜Jšžœ˜J˜—š Ÿ œžœžœ!žœžœž˜MJ˜Jšœ˜šžœžœžœ˜šžœžœ˜Jšœ žœžœ˜>—Jšžœ žœ"˜4—Jšžœ˜—J˜šŸœž˜%Jšœ2™2Jšœžœžœ˜Jšœ'žœ ˜6Jšžœžœžœ žœ˜;Jšœ.˜.šžœžœžœž˜.Jšœžœ*˜?š žœ žœžœžœžœ˜*Jšœžœ˜4Jšžœ4˜8—Jšœ$žœ˜+Jšžœ˜—Jšžœ˜—J˜Jšœ!™!J™š  œž˜#J˜Jšœžœ ˜ J˜3Jšžœ žœžœžœ˜J˜Jšžœžœ!žœ˜@J˜ Jšœžœ ˜#J˜)Jšžœ˜J˜—š Ÿ œž œžœžœ ž˜EJšœžœ/˜KJšœžœ˜Jšœžœ˜š Ÿœž œ žœ žœžœ ˜IJšœY˜Y—š Ÿ œžœžœžœ žœžœž˜KJšžœžœžœžœžœžœ žœ˜J—š œž˜/Jšœžœžœ˜Jšœžœ!˜6Jšžœ žœžœžœžœžœžœ˜Kš žœžœžœžœžœž˜>Jšžœžœžœ˜6Jšžœžœžœžœ˜?Jšžœžœ˜—Jšžœ˜—š  œž˜)Jšžœžœžœ˜(šžœžœžœžœ˜*JšœG˜GJšžœžœ˜&JšžœDžœ˜O—Jšžœ˜—J˜Jšœ:˜:Jšœ˜Jšœ4˜4J˜š žœžœžœžœžœž˜5Jšœ!˜!Jšœ žœ;˜Jšœ ˜ JšœJ˜JJšœžœ˜"—J˜)J˜Jšžœ˜J˜—Jšœ$˜$Jšžœ˜J˜—š  œž˜(š Ÿœžœžœ žœ žœ ˜CJšžœ žœ žœ ˜-J˜—J˜4Jšžœ˜J˜—š ¡œžœžœžœž˜?Jšœ žœ&˜7Jšœžœžœ ˜#Jšœžœžœ˜šžœžœ˜J˜J˜J˜Jšžœ˜—…—84J0