DIRECTORY Buttons USING [Button, ButtonProc, Create, SetDisplayStyle], Commander USING [CommandProc, Register], Containers USING [ChildXBound, ChildYBound, Create], Cursors USING [CursorArray], FileNames USING [CurrentWorkingDirectory], FS USING [Close, GetInfo, Open, OpenFile, Read], Graphics USING [Context, DrawBox, Mark, Restore, Save, SetCP, SetPaintMode], GraphicsOps USING [BitmapRef, BitmapRep, DrawBitmap], IconManager USING [selectedIcon], Icons USING [IconFlavor, IconFileFormat, IconRef, IconRep], IO USING [Close, Flush, PutF, time], Labels USING [Create, Label], Menus USING [AppendMenuEntry, ChangeNumberOfLines, CreateMenu, CreateEntry, GetNumberOfLines, Menu, MenuLine, MenuProc], MessageWindow USING [Append, Blink], Rope USING [ROPE], Rules USING [Create, Rule], spGlobals USING[ConRec, DumpIt, FuncTable, Handle, Level2Model, ModelTable, NodeRec, NormalRun, RefConRec, RefNodeRec, RefR, RefUnReal, ResistorBody, ShowDetails, spFunctions, spModels, Stages, StopIt, ThymeToolRec, ToggleShowDetails, UnReal], TiogaOps USING [FindDef, FindText, FindWord, SearchDir], TypeScript USING [Create, TS], VFonts USING[CharWidth, StringWidth], ViewerBLT USING[ChangeNumberOfLines], ViewerClasses USING [PaintProc, Viewer, ViewerClass, ViewerClassRec], ViewerEvents USING [EventProc, RegisterEventProc], ViewerIO USING [CreateViewerStreams], ViewerOps USING [AddProp, CreateViewer, FetchProp, PaintViewer, RegisterViewerClass, RestoreViewer, SaveViewer, --SetMenu, --SetOpenHeight], ViewerTools USING [GetContents, MakeNewTextViewer, SetSelection], VM USING [AddressForPageNumber, Allocate, Free, Interval]; ThymeViewers: CEDAR MONITOR IMPORTS Buttons, Commander, Containers, FileNames, FS, Graphics, GraphicsOps, IconManager, IO, Labels, Menus, MessageWindow, Rules, spGlobals, TiogaOps, TypeScript, ViewerEvents, ViewerIO, ViewerOps, VFonts, ViewerBLT, ViewerTools, VM EXPORTS spGlobals = { version: PUBLIC Rope.ROPE_ "Thyme - Cedar5.2 - May 1985"; refNodeRec: PUBLIC spGlobals.RefNodeRec= NEW[spGlobals.NodeRec]; refConRec: PUBLIC spGlobals.RefConRec= NEW[spGlobals.ConRec]; refR: PUBLIC spGlobals.RefR= NEW[spGlobals.ResistorBody]; refUnReal: PUBLIC spGlobals.RefUnReal= NEW[spGlobals.UnReal]; modelTable: PUBLIC spGlobals.ModelTable_ NIL; functionTable: PUBLIC spGlobals.FuncTable_ NIL; msgViewerH: CARDINAL = 100; MakeThymeViewers: PUBLIC PROC[wDir: Rope.ROPE _ NIL] RETURNS [handle: spGlobals.Handle _ NIL] = { thymeMenus: Menus.Menu; handle _ NEW[spGlobals.ThymeToolRec _ []]; thymeMenus _ MakeThymeMenus[handle]; TRUSTED{ handle.outer _ Containers.Create[ info: [ name: version, file: LOOPHOLE[handle], -- sorry, no better place. iconic: TRUE, icon: private, menu: thymeMenus, column: left, scrollable: FALSE], paint: FALSE]; }; IF ThymeNormalPaint = NIL THEN ThymeNormalPaint _ handle.outer.class.paint; handle.outer.class.paint _ ThymeViewerPaint; Menus.ChangeNumberOfLines[thymeMenus, 1]; MakeMainViewer[ handle: handle, workingDir: IF wDir = NIL THEN FileNames.CurrentWorkingDirectory[] ELSE wDir]; MakeMsgViewer[handle]; ViewerOps.SetOpenHeight[handle.outer, handle.height + msgViewerH]; ViewerOps.PaintViewer[handle.outer, all]; }; -- MakeThymeViewers MakeThymeMenus: PROC[handle: spGlobals.Handle] RETURNS[menu: Menus.Menu] = { requestConfirmMsg: Rope.ROPE = "Please confirm by clicking at it again."; menu _ Menus.CreateMenu[]; Menus.AppendMenuEntry[ menu: menu, entry: Menus.CreateEntry[ name: "Stop", proc: Stop, clientData: handle, guarded: TRUE, documentation: requestConfirmMsg] ]; Menus.AppendMenuEntry[ menu: menu, entry: Menus.CreateEntry[ name: "Dump", proc: Dump, clientData: handle, guarded: TRUE, documentation: requestConfirmMsg] ]; Menus.AppendMenuEntry[ menu: menu, entry: Menus.CreateEntry[name: "Run", proc: Run, clientData: handle] ]; Menus.AppendMenuEntry[ menu: menu, entry: Menus.CreateEntry[name: "New", proc: New, clientData: handle] ]; Menus.AppendMenuEntry[ menu: menu, entry: Menus.CreateEntry[name: "TypeScriptMenus", proc: TypeScriptMenus, clientData: handle] ]; Menus.AppendMenuEntry[ menu: menu, entry: Menus.CreateEntry[ name: "Save", proc: Save, clientData: handle, guarded: TRUE, documentation: requestConfirmMsg], line: 1 ]; Menus.AppendMenuEntry[ menu: menu, entry: Menus.CreateEntry[ name: "Reset", proc: Reset, clientData: handle, guarded: TRUE, documentation: requestConfirmMsg], line: 1 ]; Menus.AppendMenuEntry[ menu: menu, entry: Menus.CreateEntry[name: "Find", proc: Find, clientData: handle], line: 1 ]; Menus.AppendMenuEntry[ menu: menu, entry: Menus.CreateEntry[name: "Word", proc: Word, clientData: handle], line: 1 ]; Menus.AppendMenuEntry[ menu: menu, entry: Menus.CreateEntry[name: "Def", proc: Def, clientData: handle], line: 1 ]; Menus.AppendMenuEntry[ menu: menu, entry: Menus.CreateEntry[name: "FindError", proc: FindError, clientData: handle], line: 1 ]; }; -- MakeThymeMenus Stop: ENTRY Menus.MenuProc = { ENABLE UNWIND => NULL; handle: spGlobals.Handle _ NARROW[clientData]; spGlobals.StopIt[handle]; }; -- Stop Run: ENTRY Menus.MenuProc = { ENABLE UNWIND => NULL; handle: spGlobals.Handle _ NARROW[clientData]; spGlobals.NormalRun[handle]; }; -- Run Dump: ENTRY Menus.MenuProc = { ENABLE UNWIND => NULL; handle: spGlobals.Handle _ NARROW[clientData]; spGlobals.DumpIt[handle]; }; -- Dump New: Menus.MenuProc = { handle: spGlobals.Handle _ NARROW[clientData]; []_ MakeThymeViewers[ViewerTools.GetContents[handle.wDir]]; }; TypeScriptMenus: ENTRY Menus.MenuProc = { ENABLE UNWIND => NULL; viewer: ViewerClasses.Viewer _ NARROW[parent]; menu: Menus.Menu _ viewer.menu; numLines: Menus.MenuLine _ Menus.GetNumberOfLines[menu]; SELECT numLines FROM 1 => { numLines _ numLines + 1; }; 2 => numLines _ numLines - 1; ENDCASE => ERROR; ViewerBLT.ChangeNumberOfLines[viewer, numLines]; }; -- TypeScriptMenus Save: ENTRY Menus.MenuProc = { ENABLE UNWIND => NULL; handle: spGlobals.Handle _ NARROW[clientData]; IF handle # NIL THEN { IF handle.simulation # NIL THEN MessageWindow.Append["Thyme.log could NOT be saved when a circuit is being simulated.", TRUE] ELSE IF handle.msgStream # NIL THEN { handle.msgStream.PutF["\nSaved: %g\n", IO.time[]]; handle.msgStream.Flush[]; ViewerOps.SaveViewer[handle.message]; }; }; }; -- Save Reset: ENTRY Menus.MenuProc = { ENABLE UNWIND => NULL; handle: spGlobals.Handle _ NARROW[clientData]; IF handle # NIL THEN { IF handle.simulation # NIL THEN MessageWindow.Append["Thyme.log could NOT be reset when a circuit is being simulated.", TRUE] ELSE IF handle.msgStream # NIL THEN { ViewerOps.RestoreViewer[handle.message]; handle.msgStream.PutF["File: Thyme.log\nCreated: %g\n", IO.time[]]; }; }; }; -- Reset Find: ENTRY Menus.MenuProc = { ENABLE UNWIND => NULL; handle: spGlobals.Handle _ NARROW[clientData]; IF handle # NIL THEN { IF handle.msgStream # NIL AND handle.message # NIL THEN { dir: TiogaOps.SearchDir = SELECT mouseButton FROM red => forwards, yellow => anywhere, ENDCASE => backwards; case: BOOL = NOT shift; found: BOOL _ TiogaOps.FindText[ viewer: handle.message, rope: NIL, -- automatically uses contents of primary selection whichDir: dir, which: primary, case: case]; IF NOT found THEN BlinkMsg["Text not found."]; }; }; }; -- Find Word: ENTRY Menus.MenuProc = { ENABLE UNWIND => NULL; handle: spGlobals.Handle _ NARROW[clientData]; IF handle # NIL THEN { IF handle.msgStream # NIL AND handle.message # NIL THEN { dir: TiogaOps.SearchDir = SELECT mouseButton FROM red => forwards, yellow => anywhere, ENDCASE => backwards; case: BOOL = NOT shift; found: BOOL _ TiogaOps.FindWord[ viewer: handle.message, rope: NIL, -- automatically uses contents of primary selection whichDir: dir, which: primary, case: case]; IF NOT found THEN BlinkMsg["Text not found."]; }; }; }; -- Word Def: ENTRY Menus.MenuProc = { ENABLE UNWIND => NULL; handle: spGlobals.Handle _ NARROW[clientData]; IF handle # NIL THEN { IF handle.msgStream # NIL AND handle.message # NIL THEN { dir: TiogaOps.SearchDir = SELECT mouseButton FROM red => forwards, yellow => anywhere, ENDCASE => backwards; case: BOOL = NOT shift; found: BOOL _ TiogaOps.FindDef[ viewer: handle.message, rope: NIL, -- automatically uses contents of primary selection whichDir: dir, which: primary, case: case]; IF NOT found THEN BlinkMsg["Text not found."]; }; }; }; -- Def FindError: ENTRY Menus.MenuProc = { ENABLE UNWIND => NULL; handle: spGlobals.Handle _ NARROW[clientData]; IF handle # NIL THEN { IF handle.msgStream # NIL AND handle.message # NIL THEN { dir: TiogaOps.SearchDir = SELECT mouseButton FROM red => forwards, yellow => anywhere, ENDCASE => backwards; case: BOOL = NOT shift; found: BOOL _ TiogaOps.FindText[ viewer: handle.message, rope: "g Error ", whichDir: dir, which: primary, case: case]; IF NOT found THEN BlinkMsg["Text not found."]; }; }; }; -- FindError BlinkMsg: PROC[msg: Rope.ROPE] = { MessageWindow.Blink[]; MessageWindow.Append[msg, TRUE]; }; -- BlinkMsg MakeMainViewer: PROC [handle: spGlobals.Handle, workingDir: Rope.ROPE _ NIL] = { entryHeight: CARDINAL = 12; entryVSpace: CARDINAL = 6; entryHSpace: CARDINAL = 10; initialOutputName: Rope.ROPE = ""; outLabel, progressLabel, timeLabel, stepLabel: Labels.Label; wDirButton, inputButton: Buttons.Button; initialInputName: Rope.ROPE = ""; handle.height _ handle.height + entryVSpace; wDirButton _ Buttons.Create[ info: [ name: "Working Directory:", parent: handle.outer, wy: handle.height + 2, wh: entryHeight, -- default the width so that it will be computed for us border: FALSE ], clientData: handle, proc: DirPrompt, paint: FALSE]; handle.wDir _ ViewerTools.MakeNewTextViewer[ info: [ parent: handle.outer, wx: wDirButton.wx + wDirButton.ww + entryHSpace, wy: handle.height, ww: 80*VFonts.CharWidth['M], wh: entryHeight + 2, data: workingDir, border: FALSE], paint: FALSE]; handle.height _ handle.height + entryHeight + entryVSpace; inputButton _ Buttons.Create[ info: [ name: "Input File:", parent: handle.outer, wy: handle.height + 2, wh: entryHeight, border: FALSE ], clientData: handle, proc: InputPrompt, paint: FALSE]; handle.input _ ViewerTools.MakeNewTextViewer[ info: [ parent: handle.outer, wx: inputButton.wx + inputButton.ww + entryHSpace, wy: handle.height, ww: 80*VFonts.CharWidth['M], wh: entryHeight + 2, data: initialInputName, border: FALSE], paint: FALSE]; handle.height _ handle.height + entryHeight + entryVSpace; outLabel _ Labels.Create[ info: [ name: "Output File:", parent: handle.outer, wy: handle.height, border: FALSE ], paint: FALSE]; handle.output _ Labels.Create[ info: [ name: initialOutputName, parent: handle.outer, wx: VFonts.StringWidth["Output File:"] + entryHSpace, wy: handle.height + 2, ww: 80*VFonts.CharWidth['W], wh: entryHeight, border: FALSE], paint: FALSE]; handle.height _ handle.height + entryHeight + entryVSpace; progressLabel _ Labels.Create[ info: [name: "Progress:", parent: handle.outer, wy: handle.height, border: FALSE ], paint: FALSE]; handle.progress _ ViewerOps.CreateViewer[ flavor: $ThymeCursor, info: [ parent: handle.outer, wx: progressLabel.wx + progressLabel.ww + entryHSpace, wy: handle.height, ww: 16, wh: 16, data: idleBitmap, border: FALSE], paint: FALSE]; handle.showDetailsButton _ Buttons.Create[ info: [ name: "details:", parent: handle.outer, wx: handle.progress.wx + handle.progress.ww + entryHSpace + entryHSpace, wy: handle.height, wh: entryHeight + 3, border: TRUE ], clientData: handle, proc: ShowDetailsProc, paint: FALSE]; Buttons.SetDisplayStyle[handle.showDetailsButton, IF spGlobals.ShowDetails[handle] THEN $WhiteOnBlack ELSE $BlackOnWhite]; timeLabel _ Labels.Create[ info: [ name: "time:", parent: handle.outer, wx: handle.showDetailsButton.wx + handle.showDetailsButton.ww + entryHSpace, wy: handle.height + 2, wh: entryHeight, border: FALSE ], paint: FALSE]; handle.time _ Labels.Create[ info: [ parent: handle.outer, wx: timeLabel.wx + timeLabel.ww + entryHSpace, wy: handle.height + 2, ww: 10*VFonts.StringWidth["M"], wh: entryHeight, border: FALSE], paint: FALSE]; stepLabel _ Labels.Create[ info: [ name: "step:", parent: handle.outer, wx: handle.time.wx + handle.time.ww + entryHSpace, wy: handle.height + 2, wh: entryHeight, border: FALSE ], paint: FALSE]; handle.step _ Labels.Create[ info: [ parent: handle.outer, wx: stepLabel.wx + stepLabel.ww + entryHSpace, wy: handle.height + 2, ww: 15*VFonts.StringWidth["M"], wh: entryHeight, border: FALSE], paint: FALSE]; handle.height _ handle.height + entryHeight + entryVSpace; }; -- MakeMainViewer DirPrompt: Buttons.ButtonProc = { handle: spGlobals.Handle _ NARROW[clientData]; IF handle # NIL THEN ViewerTools.SetSelection[handle.wDir]; }; -- InputPrompt InputPrompt: Buttons.ButtonProc = { handle: spGlobals.Handle _ NARROW[clientData]; IF handle # NIL THEN ViewerTools.SetSelection[handle.input]; }; -- InputPrompt ShowDetailsProc: Buttons.ButtonProc = { handle: spGlobals.Handle _ NARROW[clientData]; IF handle # NIL THEN { spGlobals.ToggleShowDetails[handle]; Buttons.SetDisplayStyle[handle.showDetailsButton, IF spGlobals.ShowDetails[handle] THEN $WhiteOnBlack ELSE $BlackOnWhite]; }; }; -- InputPrompt MakeMsgViewer: PROC [handle: spGlobals.Handle] = { rule: Rules.Rule _ Rules.Create[ info: [ parent: handle.outer, wy: handle.height, ww: handle.outer.cw, wh: 1], paint: FALSE]; Containers.ChildXBound[handle.outer, rule]; handle.height_ handle.height + 2; handle.message_ TypeScript.Create[ info: [ parent: handle.outer, wy: handle.height, ww: handle.outer.cw, wh: 800, border: FALSE, file: "Thyme.log"], paint: FALSE ]; IF ViewerOps.FetchProp[handle.message, $ThymeToolData] = NIL THEN ViewerOps.AddProp[handle.message, $ThymeToolData, handle]; [in: , out: handle.msgStream] _ ViewerIO.CreateViewerStreams[ name: "Thyme.log", viewer: handle.message, backingFile: "Thyme.log"]; IO.PutF[handle.msgStream, "File: Thyme.log\nCreated: %g\n", IO.time[]]; Containers.ChildXBound[handle.outer, handle.message]; Containers.ChildYBound[handle.outer, handle.message]; }; -- MakeMsgViewer MyDestroy: ViewerEvents.EventProc = { h: spGlobals.Handle _ NARROW[ViewerOps.FetchProp[viewer, $ThymeToolData]]; IF h=NIL THEN RETURN; IF event=destroy AND before THEN { h.msgStream.Close[]; h.outer.file _ NIL; }; }; -- MyDestroy iconW: INTEGER = 64; iconH: INTEGER = 64; thymeIconBitmap, idleBitmap, inputBitmap, bombBitmap, topoBitmap: REF GraphicsOps.BitmapRep; runBitmap: ARRAY [0..4) OF REF GraphicsOps.BitmapRep; ThymeViewerPaint: ViewerClasses.PaintProc = { IF self.iconic THEN ThymeIconPaint[self, context, whatChanged, clear] ELSE ThymeNormalPaint[self, context, whatChanged, clear]; }; -- ThymeViewerPaint ThymeNormalPaint: ViewerClasses.PaintProc _ NIL; -- will be assigned Containers PaintProc ThymeIconPaint: ViewerClasses.PaintProc = { handle: spGlobals.Handle; mark: Graphics.Mark _ Graphics.Save[context]; bitmap: REF GraphicsOps.BitmapRep; TRUSTED{handle _ NARROW[LOOPHOLE[self.file]]}; bitmap _ NARROW[handle.progress.data]; IF whatChanged # $ThymeStatus THEN { Graphics.SetCP[context, 0, iconH]; GraphicsOps.DrawBitmap[context, thymeIconBitmap, iconW, iconH]; }; Graphics.SetCP[context, 25, 39]; [] _ Graphics.SetPaintMode[context, opaque]; GraphicsOps.DrawBitmap[context, bitmap, 15, 15]; Graphics.Restore[context, mark]; IF IconManager.selectedIcon = self THEN { [] _ Graphics.SetPaintMode[context, invert]; Graphics.DrawBox[context, [0, 0, iconW, iconW]]; }; }; -- ThymeIconPaint MakeBitmaps: PROC[file: Rope.ROPE _ "Thyme.icons"]= TRUSTED { iconRaster: INTEGER = 4; CursorArray: TYPE= Cursors.CursorArray; fh: FS.OpenFile _ FS.Open[file]; pages: INT _ FS.GetInfo[fh].pages; space: VM.Interval _ VM.Allocate[count: pages]; iconBase: LONG POINTER TO Icons.IconFileFormat _ VM.AddressForPageNumber[space.page]; cursorsBase: LONG POINTER TO Icons.IconFileFormat _ iconBase + SIZE[Icons.IconFileFormat]; iconRef: Icons.IconRef; MakeCursorBitmap: PROC[offset: INTEGER] RETURNS [bitmap: REF GraphicsOps.BitmapRep] = TRUSTED{ refArray: REF CursorArray _ NEW[CursorArray]; FOR i: INTEGER IN [0..16) DO refArray[i] _ cursorsBase.bits[offset + i * iconRaster]; ENDLOOP; bitmap _ NEW[GraphicsOps.BitmapRep _ [base: LOOPHOLE[refArray, REF], raster: 1, width: 16, height: 16]]; }; -- MakeBitmap FS.Read[file: fh, from: 0, nPages: pages, to: iconBase]; iconRef _ NEW[Icons.IconRep _ [iconBase.bits, iconBase.label, iconBase.invertLabel, 0--filler--, iconBase.lx, iconBase.ly, iconBase.lw, iconBase.lh]]; thymeIconBitmap _ NEW[GraphicsOps.BitmapRep _ [iconRef, iconW/16, iconW, iconH]]; idleBitmap _ MakeCursorBitmap[0]; inputBitmap _ MakeCursorBitmap[1]; bombBitmap _ MakeCursorBitmap[2]; topoBitmap _ MakeCursorBitmap[3]; FOR ir: CARDINAL IN [0..4) DO runBitmap[ir] _ MakeCursorBitmap[16 * iconRaster + ir]; ENDLOOP; VM.Free[space]; FS.Close[fh]; }; -- MakeBitmaps SetCursor: PUBLIC PROC [handle: spGlobals.Handle, invert: BOOL _ FALSE] = { ENABLE UNWIND => {}; d: REF ANY; IF handle = NIL THEN RETURN; IF handle.progress = NIL THEN RETURN; SELECT handle.stage FROM idle => d _ idleBitmap; input => d _ inputBitmap; bomb => d _ bombBitmap; topo => d _ topoBitmap; run => d _ IF handle.vars = NIL THEN runBitmap[0] ELSE runBitmap[handle.vars.runState]; ENDCASE => BlinkMsg["* Weird situation at SetCursor detected. Please inform Thyme implementor."]; handle.progress.data _ d; IF handle.outer.iconic THEN ViewerOps.PaintViewer[handle.outer, client, FALSE, $ThymeStatus] ELSE ViewerOps.PaintViewer[handle.progress, client, FALSE, $ThymeStatus]; }; -- SetCursor ThymeCursorPaint: ViewerClasses.PaintProc = { ctx: Graphics.Context _ context; bitmap: REF GraphicsOps.BitmapRep _ NARROW[self.data]; mark: Graphics.Mark _ Graphics.Save[ctx]; Graphics.SetCP[ctx, 0, 16]; [] _ Graphics.SetPaintMode[ctx, opaque]; GraphicsOps.DrawBitmap[ctx, bitmap, 15, 15]; Graphics.Restore[ctx, mark]; }; -- ThymeCursorPaint thymeCursorClass: ViewerClasses.ViewerClass _ NEW[ViewerClasses.ViewerClassRec _ [ paint: ThymeCursorPaint, tipTable: NIL] ]; MakeThyme: Commander.CommandProc = {[] _ MakeThymeViewers[];}; MakeBitmaps[]; ViewerOps.RegisterViewerClass[$ThymeCursor, thymeCursorClass]; Commander.Register[ key: "Thyme", proc: MakeThyme, doc: "Start an instance of the circuit simulator Thyme." ]; [] _ ViewerEvents.RegisterEventProc[proc: MyDestroy, event: destroy]; START spGlobals.spModels; START spGlobals.Level2Model; START spGlobals.spFunctions; }. šThymeViewers.mesa -- Some parts stolen from PseudoCursorsImpl.mesa Last Edited by: SChen, May 21, 1985 7:42:45 pm PDT GetLine, SetLine, MenuEntry public global variables local constants menus typescript menus Menus.SetLine[menu, 1, tsMenuEntry]; openInput: Buttons.Button; working directory scrollable: FALSE, input file scrollable: FALSE, output file progress cursor force the selection into the user input field message viewer divider the typescript destroy proc paint procs build the library functions and models CHANGE LOG Chen, June 12, 1984 11:21:28 am PDT, created. Chen, May 14, 1985 8:05:48 pm PDT, implemented custom icon that shows status. Κ˜JšœB™BJ™2J™šΟk ˜ Jšœœ/˜˜LJšœ œ$˜5Jšœ œ˜!Jšœœ0˜;Jšœœ˜$Jšœœ˜šœœ@˜KJšœ™Jšœ,˜,—Jšœœ˜$Jšœœœ˜Jšœœ˜Jšœ œδ˜σJšœ œ*˜8Jšœ œ œ˜Jšœœ˜%Jšœ œ˜%Jšœœ2˜EJšœ œ ˜2Jšœ œ˜%Jšœ œaΟc œ˜ŒJšœ œ0˜AJšœœ2˜:—J˜šœœ˜Jšœ,œ&œ‹˜κJšœ˜—J˜™J˜—Jšœ œœ ˜9Jšœ œœ˜@Jšœ œœ˜=Jšœœœ˜9Jšœ œœ˜>Jšœ œœ˜-Jšœœœ˜/J˜J™J˜Jšœ œ˜J™š Οnœœœ œœ˜4Jšœœ˜,Jšœ˜J˜Jšœ œ˜*Jšœ$˜$J˜šœ˜šœ!˜!šœ˜Jšœ˜Jšœœ ž˜2Jšœœ˜ Jšœ˜Jšœ˜Jšœ ˜ Jšœ œ˜—Jšœœ˜—J˜—J˜Jšœœœ-˜KJšœ,˜,J˜Jšœ)˜)šœ˜Jšœ˜Jš œ œœœ%œ˜N—Jšœ˜J˜JšœB˜BJšœ)˜)Jšœž˜—J˜J™J˜šŸœœœ˜LJšœœ-˜IJšœ˜J˜šœ˜Jšœ ˜ šœ˜Jšœ ˜ Jšœ ˜ Jšœ˜Jšœ œ˜Jšœ!˜!—Jšœ˜—emphasisšœ˜Jšœ ˜ šœ˜Jšœ ˜ Jšœ ˜ Jšœ˜Jšœ œ˜Jšœ!˜!—Jšœ˜—šœ˜Jšœ ˜ JšœD˜DJšœ˜—šœ˜Jšœ ˜ JšœD˜DJšœ˜—šœ˜Jšœ ˜ šœH˜HJšœ˜—Jšœ˜—J˜Jšœ™šœ˜Jšœ ˜ šœ˜Jšœ ˜ Jšœ ˜ Jšœ˜Jšœ œ˜Jšœ"˜"—J˜Jšœ˜—šœ˜Jšœ ˜ šœ˜Jšœ˜Jšœ ˜ Jšœ˜Jšœ œ˜Jšœ"˜"—J˜Jšœ˜—šœ˜Jšœ ˜ JšœG˜GJ˜Jšœ˜—šœ˜Jšœ ˜ JšœG˜GJ˜Jšœ˜—šœ˜Jšœ ˜ JšœE˜EJ˜Jšœ˜—šœ˜Jšœ ˜ JšœQ˜QJ˜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šœ8˜8šœ ˜šœ˜Jšœ$™$Jšœ˜J˜—Jšœ˜Jšœœ˜—Jšœ0˜0Jšœž˜—J˜šœœ˜Jšœœœ˜Jšœœ ˜.šœ œœ˜JšœœœYœ˜}šœœœœ˜%Jšœ'œ ˜2Jšœ˜Jšœ%˜%J˜—J˜—Jšœž˜ —J˜šœœ˜Jšœœœ˜Jšœœ ˜.šœ œœ˜JšœœœYœ˜}šœœœœ˜%Jšœ(˜(Jšœ8œ ˜CJ˜—J˜—Jšœž˜ J˜—šœœ˜Jšœœœ˜Jšœœ ˜.šœ œœ˜š œœœœœ˜9šœœ ˜1Jšœ%œ˜:—Jšœœœ˜šœœ˜ Jšœ˜Jšœœž3˜>Jšœ˜Jšœ˜Jšœ ˜ —Jšœœœ˜.J˜—J˜—Jšœž˜ —J˜šœœ˜Jšœœœ˜Jšœœ ˜.šœ œœ˜š œœœœœ˜9šœœ ˜1Jšœ%œ˜:—Jšœœœ˜šœœ˜ Jšœ˜Jšœœž3˜>Jšœ˜Jšœ˜Jšœ ˜ —Jšœœœ˜.J˜—J˜—Jšœž˜ J˜—šœœ˜Jšœœœ˜Jšœœ ˜.šœ œœ˜š œœœœœ˜9šœœ ˜1Jšœ%œ˜:—Jšœœœ˜šœœ˜Jšœ˜Jšœœž3˜>Jšœ˜Jšœ˜Jšœ ˜ —Jšœœœ˜.J˜—J˜—Jšœž˜ —J˜šœ œ˜#Jšœœœ˜Jšœœ ˜.šœ œœ˜š œœœœœ˜9šœœ ˜1Jšœ%œ˜:—Jšœœœ˜šœœ˜ Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ ˜ —Jšœœœ˜.J˜—J˜—Jšœž ˜—J˜šŸœœ œ˜"J˜Jšœœ˜ Jšœž ˜—J˜šŸœœ-œœ˜PJšœ œ˜Jšœ œ˜Jšœ œ˜Jšœœ6˜RIunit˜˜>J˜J˜J™Jšœ>˜>J˜šœ˜Jšœ ˜ Jšœ˜Jšœ;˜;J˜—JšœE˜EJ˜J™&J˜Jšœ˜Jšœ˜Jšœ˜J˜Jšœ˜J˜J™ ™J™-J™M——…—Gΰa