DIRECTORY FS USING [ComponentPositions, PagesForBytes, ExpandName], IO, Menus, Rope, TiogaMenuOps USING [PrevPlace], TiogaOps USING [SearchDir, FindText], UserProfile USING [Token], ViewerBLT USING[ChangeNumberOfLines], ViewerClasses USING [Viewer], ViewerOps, ViewerTools USING [GetSelectionContents], WalnutNewMail USING [CheckGrapevine], WalnutOps USING [ActiveMsgSetName, DeletedMsgSetName, MsgSet, CreateMsgSet, DestroyMsgSet, LogLength, MsgSetExists, SizeOfDatabase, SizeOfMsgSet, WriteArchiveFile], WalnutSendOps USING [WalnutSendProc], WalnutControlInternal USING [walnutRootFile, DoWaitCall], WalnutDisplayerInternal USING [QDisplayMsgSet], WalnutPrintOps USING [PrintMsgSet], WalnutWindowInternal USING [MsgSetButton, msgSetsVersion, msgSetsTViewer, walnut, walnutQueue, walnutTS, AddMsgSetButton, DeleteMsgSetButton, GetButton, GetSelectedMsgSets, Report, ReportRope, RetrieveNewMail], WalnutViewer USING [CreateMenuEntry], WalnutWindow USING [EnumWalnutViewers, Expunge]; WalnutWindowMenuImpl: CEDAR MONITOR IMPORTS FS, Menus, IO, Rope, UserProfile, TiogaMenuOps, TiogaOps, ViewerBLT, ViewerOps, ViewerTools, WalnutNewMail, WalnutOps, WalnutControlInternal, WalnutDisplayerInternal, WalnutPrintOps, WalnutSendOps, WalnutViewer, WalnutWindow, WalnutWindowInternal EXPORTS WalnutControlInternal = BEGIN OPEN WalnutControlInternal, WalnutWindowInternal; ROPE: TYPE = Rope.ROPE; Viewer: TYPE = ViewerClasses.Viewer; responseSynch: CONDITION; userHasResponded, userConfirmed: BOOL_ FALSE; noMsgSetsSelected: ROPE = "No seleted MsgSet(s)"; ChangeMenu: PUBLIC ENTRY PROC[m: Menus.Menu, isBusy: BOOL] = { ENABLE UNWIND => NULL; InternalChangeMenu[m, isBusy] }; InternalChangeMenu: INTERNAL PROC[menu: Menus.Menu, isBusy: BOOL] = { oldCount, newCount: Menus.MenuLine; IF walnut = NIL THEN RETURN; oldCount _ Menus.GetNumberOfLines[walnut.menu]; newCount _ Menus.GetNumberOfLines[menu]; walnut.menu _ menu; IF oldCount # newCount THEN ViewerBLT.ChangeNumberOfLines[walnut, newCount]; ViewerOps.PaintViewer[walnut, menu]; walnut.newVersion _ isBusy; ViewerOps.PaintViewer[walnut, caption]; }; GetUserResponse: PUBLIC ENTRY PROC[m: Menus.Menu _ NIL] RETURNS[BOOL] = { ENABLE UNWIND => NULL; InternalChangeMenu[IF m = NIL THEN confirmMenu ELSE m, FALSE]; IF walnut.iconic THEN ViewerOps.BlinkIcon[walnut, 0] ELSE ViewerOps.BlinkIcon[walnutTS]; UNTIL userHasResponded DO WAIT responseSynch; ENDLOOP; userHasResponded _ FALSE; InternalChangeMenu[workingMenu, FALSE]; RETURN[userConfirmed]; }; walnutMenu: PUBLIC Menus.Menu; workingMenu: PUBLIC Menus.Menu _ Menus.CreateMenu[]; confirmMenu: Menus.Menu _ Menus.CreateMenu[]; blankMenu: PUBLIC Menus.Menu _ Menus.CreateMenu[]; startupConfirmMenu: Menus.Menu _ Menus.CreateMenu[]; forceQuitMenu: PUBLIC Menus.Menu _ Menus.CreateMenu[]; maybeQuitMenu: PUBLIC Menus.Menu _ Menus.CreateMenu[]; scavMenu: PUBLIC Menus.Menu _ Menus.CreateMenu[]; mailDBMenu: PUBLIC Menus.Menu _ Menus.CreateMenu[]; readOnlyDBMenu: PUBLIC Menus.Menu _ Menus.CreateMenu[]; nonMailDBMenu: PUBLIC Menus.Menu _ Menus.CreateMenu[]; BuildWalnutMenus: PUBLIC PROC = { OPEN Menus; AppendMenuEntry[mailDBMenu, CreateEntry["Sender", NewSenderProc]]; AppendMenuEntry[mailDBMenu, CreateEntry["NewMail", NewMailProc]]; AppendMenuEntry[mailDBMenu, WalnutViewer.CreateMenuEntry[walnutQueue, "CloseAll", CloseAllProc]]; AppendMenuEntry[mailDBMenu, CreateEntry["MsgSetOps", MsgSetOpsProc]]; AppendMenuEntry[mailDBMenu, WalnutViewer.CreateMenuEntry[walnutQueue, "NumMsgs", NumMsgsProc]]; AppendMenuEntry[mailDBMenu, WalnutViewer.CreateMenuEntry[walnutQueue, "ExpInfo", ExpungeInfo]]; AppendMenuEntry[mailDBMenu, CreateEntry["Find", FindProc]]; AppendMenuEntry[mailDBMenu, CreateEntry[name: "Exp", proc: MenuExpunge, guarded: TRUE], 1]; AppendMenuEntry[mailDBMenu, CreateEntry["Delete", DeleteMsgSetsProc], 1]; AppendMenuEntry[mailDBMenu, CreateEntry["SizeOf", SizeOfMsgSetsProc], 1]; AppendMenuEntry[mailDBMenu, CreateEntry["Print", PrintMsgSetsProc], 1]; AppendMenuEntry[mailDBMenu, CreateEntry["Create", CreateMsgSetButtonProc], 1]; AppendMenuEntry[mailDBMenu, CreateEntry["Archive", ArchiveButtonProc], 1]; AppendMenuEntry[mailDBMenu, CreateEntry["Append", AppendButtonProc], 1]; AppendMenuEntry[mailDBMenu, CreateEntry["PrevPlace", PrevPlaceProc], 1]; Menus.ChangeNumberOfLines[mailDBMenu, 1]; AppendMenuEntry[readOnlyDBMenu, CreateEntry["Sender", NewSenderProc]]; AppendMenuEntry[readOnlyDBMenu, WalnutViewer.CreateMenuEntry[walnutQueue, "CloseAll", CloseAllProc]]; AppendMenuEntry[readOnlyDBMenu, CreateEntry["SizeOf", SizeOfMsgSetsProc]]; AppendMenuEntry[readOnlyDBMenu, WalnutViewer.CreateMenuEntry[walnutQueue, "NumMsgs", NumMsgsProc]]; AppendMenuEntry[readOnlyDBMenu, CreateEntry["MsgSetOps", MsgSetOpsProc]]; AppendMenuEntry[readOnlyDBMenu, CreateEntry["Find", FindProc]]; AppendMenuEntry[readOnlyDBMenu, CreateEntry["Print", PrintMsgSetsProc],1]; AppendMenuEntry[readOnlyDBMenu, CreateEntry["Archive", ArchiveButtonProc], 1]; AppendMenuEntry[readOnlyDBMenu, CreateEntry["Append", AppendButtonProc], 1]; AppendMenuEntry[readOnlyDBMenu, CreateEntry["PrevPlace", PrevPlaceProc], 1]; Menus.ChangeNumberOfLines[readOnlyDBMenu, 1]; AppendMenuEntry[nonMailDBMenu, CreateEntry["Sender", NewSenderProc]]; AppendMenuEntry[nonMailDBMenu, WalnutViewer.CreateMenuEntry[walnutQueue, "CloseAll", CloseAllProc]]; AppendMenuEntry[nonMailDBMenu, CreateEntry["MsgSetOps", MsgSetOpsProc]]; AppendMenuEntry[nonMailDBMenu, WalnutViewer.CreateMenuEntry[walnutQueue, "NumMsgs", NumMsgsProc]]; AppendMenuEntry[nonMailDBMenu, WalnutViewer.CreateMenuEntry[walnutQueue, "ExpInfo", ExpungeInfo]]; AppendMenuEntry[nonMailDBMenu, CreateEntry["Find", FindProc]]; AppendMenuEntry[nonMailDBMenu, CreateEntry[name: "Exp", proc: MenuExpunge, guarded: TRUE], 1]; AppendMenuEntry[nonMailDBMenu, CreateEntry["Delete", DeleteMsgSetsProc], 1]; AppendMenuEntry[nonMailDBMenu, CreateEntry["SizeOf", SizeOfMsgSetsProc], 1]; AppendMenuEntry[nonMailDBMenu, CreateEntry["Print", PrintMsgSetsProc], 1]; AppendMenuEntry[nonMailDBMenu, CreateEntry["Create", CreateMsgSetButtonProc], 1]; AppendMenuEntry[nonMailDBMenu, CreateEntry["Archive", ArchiveButtonProc], 1]; AppendMenuEntry[nonMailDBMenu, CreateEntry["Append", AppendButtonProc], 1]; AppendMenuEntry[nonMailDBMenu, CreateEntry["PrevPlace", PrevPlaceProc], 1]; Menus.ChangeNumberOfLines[nonMailDBMenu, 1]; AppendMenuEntry[workingMenu, CreateEntry["Sender", NewSenderProc]]; AppendMenuEntry[confirmMenu, CreateEntry["Sender", NewSenderProc]]; AppendMenuEntry[confirmMenu, CreateEntry["Confirm", WWConfirmProc]]; AppendMenuEntry[confirmMenu, CreateEntry["Deny", WWDenyProc]]; AppendMenuEntry[startupConfirmMenu, CreateEntry["Continue", WWConfirmProc]]; AppendMenuEntry[startupConfirmMenu, CreateEntry["Quit", WWDenyProc]]; AppendMenuEntry[forceQuitMenu, CreateEntry["Quit", WWConfirmProc]]; AppendMenuEntry[maybeQuitMenu, CreateEntry["Quit", WWConfirmProc]]; AppendMenuEntry[maybeQuitMenu, CreateEntry["Retry", WWDenyProc]]; AppendMenuEntry[scavMenu, CreateEntry["Quit", WWDenyProc]]; AppendMenuEntry[scavMenu, CreateEntry["Scavenge", WWConfirmProc]]; }; NewSenderProc: Menus.MenuProc = { WalnutSendOps.WalnutSendProc[fromExec: FALSE]}; MsgSetOpsProc: Menus.MenuProc = { v: Viewer = NARROW[parent]; count: NAT = Menus.GetNumberOfLines[v.menu]; newCount: NAT = IF count = 2 THEN 1 ELSE 2; Menus.ChangeNumberOfLines[v.menu, newCount]; ViewerBLT.ChangeNumberOfLines[v, newCount]; }; MenuExpunge: Menus.MenuProc = { ENABLE UNWIND => ChangeMenu[walnutMenu, FALSE]; ChangeMenu[workingMenu, TRUE]; WalnutWindow.Expunge[]; }; ExpungeInfo: Menus.MenuProc = { len: INT _ WalnutOps.LogLength[]; numIn: INT _ WalnutOps.SizeOfMsgSet[WalnutOps.DeletedMsgSetName].messages; total: INT _ WalnutOps.SizeOfDatabase[].messages; Report[IO.PutFR[" The log file is %g bytes (%g pages) long", IO.int[len], IO.int[FS.PagesForBytes[len]]]]; Report[IO.PutFR[ " There are %g deleted msgs, (%g total msgs)", IO.int[numIn], IO.int[total] ]]; }; NumMsgsProc: Menus.MenuProc = { messages, msgSets: INT; [messages, msgSets] _ WalnutOps.SizeOfDatabase[]; Report[IO.PutFR["There are %g messages & %g msgSets in this database", IO.int[messages], IO.int[msgSets] ]]; }; NewMailProc: Menus.MenuProc = { IF mouseButton = blue THEN WalnutNewMail.CheckGrapevine[] ELSE WalnutWindowInternal.RetrieveNewMail[] }; CloseAllProc: Menus.MenuProc = { msgSetList, msgList: LIST OF Viewer; mpViewer: Viewer; [msgSetList, msgList] _ WalnutWindow.EnumWalnutViewers[TRUE]; FOR vL: LIST OF Viewer _ msgList, vL.rest UNTIL vL=NIL DO IF ViewerOps.FetchProp[vL.first, $Frozen] = NIL THEN ViewerOps.DestroyViewer[vL.first]; ENDLOOP; FOR vL: LIST OF Viewer _ msgSetList, vL.rest UNTIL vL=NIL DO ViewerOps.CloseViewer[vL.first]; ENDLOOP; IF (mpViewer _ ViewerOps.FindViewer["NewMail Retrieval"]) # NIL THEN ViewerOps.CloseViewer[mpViewer]; ViewerOps.CloseViewer[walnut]; }; WWDenyProc: ENTRY Menus.MenuProc = { ENABLE UNWIND => NULL; userConfirmed _ FALSE; userHasResponded _ TRUE; BROADCAST responseSynch }; WWConfirmProc: ENTRY Menus.MenuProc = { ENABLE UNWIND => NULL; userConfirmed _ TRUE; userHasResponded _ TRUE; BROADCAST responseSynch }; -- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * CreateMsgSetButtonProc: Menus.MenuProc = { msName: ROPE _ ViewerTools.GetSelectionContents[]; Cmsb: PROC = { IF msName.Length[] = 0 THEN { Report["No MsgSet name specified"]; RETURN}; IF msName.Find[" "] >=0 THEN { Report[" MsgSet names may not contain spaces"]; RETURN}; IF WalnutOps.MsgSetExists[msName, WalnutWindowInternal.msgSetsVersion].exists THEN Report["MsgSet: ", msName, " already exists"] ELSE { WalnutOps.CreateMsgSet[msName, WalnutWindowInternal.msgSetsVersion]; [] _ AddMsgSetButton[msName, TRUE]; WalnutWindowInternal.msgSetsVersion _ WalnutWindowInternal.msgSetsVersion + 1; }; }; [] _ DoWaitCall[Cmsb]; }; SizeOfMsgSetsProc: Menus.MenuProc = { Sms: PROC = { msgSetList: LIST OF MsgSetButton _ GetSelectedMsgSets[]; msgSet: ROPE; IF msgSetList = NIL THEN { Report[noMsgSetsSelected]; RETURN}; FOR mL: LIST OF MsgSetButton _ msgSetList, mL.rest UNTIL mL=NIL DO num: INT _ WalnutOps.SizeOfMsgSet[msgSet _ mL.first.msgSet.name].messages; Report[IO.PutFR[" %g msgs in MsgSet %g", IO.int[num], IO.rope[msgSet]]]; ENDLOOP; }; [] _ DoWaitCall[Sms]; }; DeleteMsgSetsProc: Menus.MenuProc = { Dms: PROC = { msgSetList: LIST OF MsgSetButton _ GetSelectedMsgSets[]; name: ROPE; someInDeleted: BOOL; anyDeleted: BOOL _ TRUE; IF msgSetList = NIL THEN { Report[noMsgSetsSelected, " to delete"]; RETURN}; ChangeMenu[workingMenu, TRUE]; FOR mL: LIST OF MsgSetButton _ msgSetList, mL.rest UNTIL mL=NIL DO name _ mL.first.msgSet.name; IF name.Equal[WalnutOps.DeletedMsgSetName, FALSE] THEN { Report["Can't delete the Deleted MsgSet"]; LOOP}; IF WalnutOps.SizeOfMsgSet[name].messages # 0 THEN { Report[" Confirm deletion of messages in MsgSet: ", name]; IF ~GetUserResponse[] THEN { ChangeMenu[walnutMenu, FALSE]; RETURN } }; DeleteMsgSetButton[name]; someInDeleted _ WalnutOps.DestroyMsgSet[ mL.first.msgSet, WalnutWindowInternal.msgSetsVersion]; anyDeleted _ anyDeleted OR someInDeleted; IF ~name.Equal[WalnutOps.ActiveMsgSetName, FALSE] THEN Report["MsgSet: ", name, " has been deleted"] ELSE Report["Msgs have been removed from Active"]; WalnutWindowInternal.msgSetsVersion _ WalnutWindowInternal.msgSetsVersion + 1; ENDLOOP; IF anyDeleted THEN RedisplayDeleted[]; ChangeMenu[walnutMenu, FALSE]; }; [] _ DoWaitCall[Dms]; }; PrintMsgSetsProc: PUBLIC Menus.MenuProc = { Pms: PROC = { msgSetList: LIST OF MsgSetButton _ GetSelectedMsgSets[]; IF msgSetList = NIL THEN { Report[noMsgSetsSelected, " to print"]; RETURN }; ChangeMenu[workingMenu, TRUE]; FOR mL: LIST OF MsgSetButton _ msgSetList, mL.rest UNTIL mL=NIL DO IF ~WalnutPrintOps.PrintMsgSet[mL.first.msgSet.name] THEN EXIT; ENDLOOP; ChangeMenu[walnutMenu, FALSE]; }; [] _ DoWaitCall[Pms]; }; ArchiveButtonProc: Menus.MenuProc = { ArchiveOrAppend[FALSE, mouseButton=blue] }; AppendButtonProc: Menus.MenuProc = { ArchiveOrAppend[TRUE, mouseButton=blue] }; ArchiveOrAppend: PROC[append, destroyMsgSets: BOOL] = { fileName: ROPE _ ViewerTools.GetSelectionContents[]; msgSetList: LIST OF MsgSetButton _ GetSelectedMsgSets[]; AorA: PROC = { ENABLE UNWIND => ChangeMenu[walnutMenu, FALSE]; anyInDeleted: BOOL _ FALSE; msList: LIST OF WalnutOps.MsgSet; ChangeMenu[workingMenu, TRUE]; FOR mL: LIST OF MsgSetButton _ msgSetList, mL.rest UNTIL mL=NIL DO msList _ CONS[mL.first.msgSet, msList]; ENDLOOP; IF ~DoArchive[fileName, msList, append] THEN { ChangeMenu[walnutMenu, FALSE]; RETURN }; IF ~destroyMsgSets THEN { ChangeMenu[walnutMenu, FALSE]; RETURN }; FOR mL: LIST OF MsgSetButton _ msgSetList, mL.rest UNTIL mL = NIL DO someInDeleted: BOOL; name: ROPE; DeleteMsgSetButton[name _ mL.first.msgSet.name]; -- ignores Active & Deleted IF ~name.Equal[WalnutOps.DeletedMsgSetName, FALSE] THEN someInDeleted _ WalnutOps.DestroyMsgSet[ mL.first.msgSet, WalnutWindowInternal.msgSetsVersion ]; anyInDeleted _ anyInDeleted OR someInDeleted; ENDLOOP; IF anyInDeleted THEN RedisplayDeleted[]; ChangeMenu[walnutMenu, FALSE]; }; [] _ DoWaitCall[AorA]; }; DoArchive: PUBLIC PROC[fileName: ROPE, msList: LIST OF WalnutOps.MsgSet, append: BOOL] RETURNS[ok: BOOL] = { fullName: ROPE; num: INT _ 0; ok _ FALSE; IF fileName.Length[] = 0 THEN { Report["No Archive file specified"]; RETURN}; IF msList = NIL THEN { Report[noMsgSetsSelected, " to archive"]; RETURN}; BEGIN cp: FS.ComponentPositions; wDir: ROPE _ UserProfile.Token["Walnut.DefaultArchiveDir"]; [fullName, cp, ] _ FS.ExpandName[fileName, wDir]; IF cp.ext.length = 0 THEN fullName _ fullName.Concat[".ArchiveLog"]; END; IF Rope.Equal[fullName, walnutRootFile, FALSE] THEN { Report["Can't archive on log file"]; RETURN}; IF append THEN Report["Appending msgs to the file: ", fileName]; ReportRope["Archiving the MsgSet(s): "]; FOR mL: LIST OF WalnutOps.MsgSet _ msList, mL.rest UNTIL mL = NIL DO msName: ROPE = mL.first.name; this: INT _ WalnutOps.SizeOfMsgSet[msName].messages; ReportRope[msName, IO.PutFR[" (%g messages) ", IO.int[this]]]; num _ num + this; WalnutOps.WriteArchiveFile[file: fullName, msgSetList: LIST[mL.first], append: append]; append _ TRUE; -- always true after the first write ENDLOOP; Report[IO.PutFR["\n %g messages archived on file: %g", IO.int[num], IO.rope[fullName]]]; RETURN[TRUE] }; RedisplayDeleted: PROC = { msb: MsgSetButton _ GetButton[WalnutOps.DeletedMsgSetName]; IF msb.msViewer = NIL THEN RETURN; [] _ WalnutDisplayerInternal.QDisplayMsgSet[msb, msb.msViewer, FALSE]; }; FindProc: Menus.MenuProc = { IF ~TiogaOps.FindText[ viewer: WalnutWindowInternal.msgSetsTViewer, whichDir: GetDirection[mouseButton], which: feedback, case: ~shift] THEN ViewerOps.BlinkIcon[WalnutWindowInternal.msgSetsTViewer]; }; PrevPlaceProc: Menus.MenuProc = { TiogaMenuOps.PrevPlace[WalnutWindowInternal.msgSetsTViewer] }; GetDirection: PROC[mb: Menus.MouseButton] RETURNS[sd: TiogaOps.SearchDir] = { SELECT mb FROM red => RETURN[forwards]; yellow => RETURN[anywhere]; blue => RETURN[backwards]; ENDCASE; }; END. WalnutWindowMenuImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Willie-Sue, November 5, 1985 11:03:46 am PST Contents: Menu control for the Top level Viewer for Walnut created March, 1985 by Willie-Sue Walnut Viewers types and global data * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * menu for personal mail database now for the second line menu for read only database menu for nonMail writeable database now for the second line Create a new blank form in a viewer for user to send msg with. "immediate" buttons that gather some parameters and then queue the real proc to call make sure didn't specify same name as log file * * * * * * * * * * Ê6˜šÏn™Jšœ Ïmœ1™˜>Jšœ/˜/Jšœ9˜9—Jšœ Ÿœ˜%šœ Ÿœ˜0J˜——šœŸœŸ˜#šŸ˜JšŸœ Ÿœ˜!Jšœ˜J˜"J˜Jšœ˜J˜7J˜0—JšŸœ˜J˜—JšŸœŸœ-˜7J˜Jšœ$™$J˜JšŸœŸœŸœ˜JšœŸœ˜$J˜JšœŸ œ˜Jšœ!ŸœŸœ˜-JšœŸœ˜1J˜JšœO™O™š œŸœŸœŸœŸœ˜>JšŸœŸœŸœ˜Jšœ˜Jšœ˜J˜—šœŸœŸœŸœ˜EJ˜#JšŸœ ŸœŸœŸœ˜J˜/J˜(J˜JšŸœŸœ1˜LJ˜$Jšœ˜Jšœ(˜(Jšœ˜—J˜šœŸœŸœŸœŸœŸœŸœ˜IJšŸœŸœŸœ˜Jš œŸœŸœŸœ ŸœŸœ˜>JšŸœŸœ Ÿœ˜XJšŸœŸœŸœŸœ˜6JšœŸœ˜Jšœ Ÿœ˜'JšŸœ˜Jšœ˜——J˜J™JšœO™OJšœ Ÿœ ˜Jšœ Ÿœ!˜4J˜-Jšœ Ÿœ!˜2J˜4JšœŸœ!˜6JšœŸœ!˜6Jšœ Ÿœ!˜1J˜Jšœ Ÿœ!˜3JšœŸœ!˜7JšœŸœ!˜6˜šœŸœŸœ˜!JšŸœ˜ J˜šœ™J˜BJ˜A˜J˜E—J˜E˜J˜C—˜JšœC˜C—Jšœ;˜;—J™šœ™˜Jšœ5Ÿœ˜?—J˜JšœI˜IJšœI˜IJšœG˜GJšœN˜NJšœJ˜JJšœH˜HJšœH˜HJ˜J˜)J˜—šœ™J˜F˜J˜E—JšœJ˜J˜J˜C—JšœI˜IJšœ?˜?J˜JšœJ˜JJšœN˜NJšœL˜LJšœL˜LJ˜Jšœ-˜-J˜—šœ#™#J˜E˜J˜E—J˜H˜J˜C—˜JšœC˜C—J˜>J™—šœ™˜Jšœ5Ÿœ˜?—J˜LJ˜LJ˜JJ˜QJ˜MJ˜KJ˜KJ˜J˜,J˜J˜CJ˜J˜CJ˜DJ˜>J˜J˜LJ˜E—˜J˜CJ˜J˜CJ˜AJ˜J˜;J˜BJ˜———˜š œ<Ÿœ˜QJšœ?™?J˜—š œ˜!Jšœ Ÿœ ˜JšœŸœ"˜,Jš œ ŸœŸœ ŸœŸœ˜+J˜,J˜+Jšœ˜J˜—š œ˜JšŸœŸœŸœ˜/JšœŸœ˜Jšœ˜J˜—J˜š œ˜JšœŸœ˜!JšœŸœ@˜JJšœŸœ'˜1šœŸœ5˜>JšŸœ ŸœŸœ˜-—šœŸœ˜Jšœ1Ÿœ Ÿœ˜Q—J˜——˜š œ˜JšœŸœ˜Jšœ1˜1šœŸœ=˜FJšŸœŸœ˜%—J˜—J˜š œ˜šŸœŸœ˜9JšŸœ'˜+—J˜J˜—š œ˜ JšœŸœŸœ˜$Jšœ˜Jšœ7Ÿœ˜=š ŸœŸœŸœŸœŸœŸ˜9JšŸœ*ŸœŸœ#˜WJšŸœ˜—š ŸœŸœŸœŸœŸœŸ˜š ŸœŸœŸœ$ŸœŸœŸ˜BJšœŸœA˜JJšœŸœ Ÿœ Ÿœ˜HJšŸœ˜—J˜—J˜J˜——˜šœ˜%šœŸœ˜ Jšœ ŸœŸœ%˜8JšœŸœ˜ JšœŸœ˜Jšœ ŸœŸœ˜JšŸœŸœŸœ,Ÿœ˜LJšœŸœ˜J˜š ŸœŸœŸœ$ŸœŸœŸ˜BJšœ˜šŸœ)ŸœŸ˜6Jšœ-Ÿœ˜3—J˜šŸœ+Ÿœ˜3Jšœ:˜:šŸœŸ˜JšœŸœŸœ˜)—J˜—J˜J˜šœ(˜(Jšœ6˜6—JšœŸœ˜)šŸœ)ŸœŸ˜6Jšœ-˜-JšŸœ.˜2—JšœN˜N—JšŸœ˜J˜JšŸœ Ÿœ˜&JšœŸœ˜Jšœ˜—J˜J˜——˜šœŸœ˜+šœŸœ˜ Jšœ ŸœŸœ%˜8JšŸœŸœŸœ+Ÿœ˜LšœŸœ˜J˜—š ŸœŸœŸœ$ŸœŸœŸ˜BJšŸœ3ŸœŸœ˜?JšŸœ˜—JšœŸœ˜Jšœ˜—J˜J˜—J˜šœ˜#JšœŸœ˜-J˜—šœ˜"JšœŸœ˜,—J˜šœŸœŸœ˜7Jšœ Ÿœ&˜4Jšœ ŸœŸœ%˜8šœŸœ˜JšŸœŸœŸœ˜/J˜JšœŸœŸœ˜JšœŸœŸœ˜!J˜JšœŸœ˜š ŸœŸœŸœ$ŸœŸœŸ˜BJšœ ŸœŸœ˜0—J˜šŸœ&Ÿ˜,JšœŸœŸœ˜*—J˜šŸœŸ˜JšœŸœŸœ˜*—J˜š ŸœŸœŸœ$ŸœŸœŸ˜DJšœŸœ˜JšœŸœ˜ Jšœ2 ˜MšŸœ*ŸœŸ˜7šœ(˜(Jšœ7˜7——JšœŸœ˜-JšŸœ˜—JšŸœŸœ˜(JšœŸœ˜Jšœ˜—J˜J˜—J˜š œŸœŸœ Ÿœ ŸœŸœŸœ˜VJšŸœŸœ˜Jšœ Ÿœ˜JšœŸœ˜ JšœŸœ˜ JšŸœŸœ(Ÿœ˜MšŸœ ŸœŸ˜Jšœ,Ÿœ˜4—Jšœ.™.šŸ˜JšœŸœ˜JšœŸœ1˜;JšœŸœ˜1JšŸœŸœ+˜DJšŸœ˜—J˜šŸœ&ŸœŸ˜3Jšœ'Ÿœ˜/—J˜JšŸœŸœ2˜@J˜(J˜š ŸœŸœŸœ$ŸœŸœŸ˜DJšœŸœ˜JšœŸœ*˜4JšœŸœŸœ ˜>Jšœ˜Jšœ7Ÿœ˜WJšœ Ÿœ $˜4JšŸœ˜—J˜JšœŸœ.Ÿœ Ÿœ˜XJšŸœŸœ˜ J˜—J˜šœŸœ˜J˜;JšŸœŸœŸœŸœ˜"Jšœ?Ÿœ˜FJ˜—J˜šœ˜šŸœ˜Jšœ,˜,Jšœ$˜$Jšœ˜Jšœ ˜ JšŸœ:˜>—J˜—J˜š œ˜Jšœ@˜@—J˜š œŸœŸœ˜MšŸœŸ˜JšœŸœ ˜Jšœ Ÿœ ˜JšœŸœ ˜—JšŸœ˜J˜—J˜—J˜Jšœ™J˜JšŸœ˜J˜J˜—…—:ØM&