DIRECTORY Buttons USING [ButtonProc, Create], ColorDisplayHeadDorado, Commander USING [CommandProc, Handle, Register], Containers USING [ChildXBound, Create], IO USING [card, Error, GetCard, GetReal, PutFR, real, RIS], Labels USING [Create, Set], Menus USING [AppendMenuEntry, CreateEntry, CreateMenu, Menu, MenuProc], MessageWindow USING [Append, Blink], MonitorToolButtons USING [BitsPerPixel, EntryViewer, EntryViewerRec, Handle, HBlank, MTViewerRec, Position, Refresh, ResultViewer, ResultViewerRec, ScreenHeight, ScreenWidth, VBlank], MonitorToolDefs USING [DoMonitorParams, fieldFreq, fieldTime, hBLeadLength, hBTrailLength, hRamMaxAddr, hSTrailAddr, MonitorParam, MonitorParamRec, SetMonitorParams, trueDiv, trueLinefreq, trueLinetime, trueMul, truePixelfreq, truePixeltime, vbToVS, visibleLines, vsToVB, vsToVS], Rope USING [Equal, ROPE], Rules USING [Create, Rule], VFonts USING [CharWidth], ViewerOps USING [PaintViewer, SetOpenHeight], ViewerTools USING [EnableUserEdits, GetContents, InhibitUserEdits, MakeNewTextViewer, SetContents], WindowManager USING [ScreenPos, StopColorViewers]; MonitorToolImpl: CEDAR PROGRAM IMPORTS Buttons, Containers, ColorDisplayHeadDorado, IO, Labels, Menus, MessageWindow, MonitorToolButtons, MonitorToolDefs, Rope, Rules, Commander, VFonts, ViewerOps, ViewerTools, WindowManager SHARES ColorDisplayHeadDorado = { entryHeight: CARDINAL = 15; -- how tall to make each line of items entryVSpace: CARDINAL = 6; -- vertical leading space between lines entryHSpace: CARDINAL = 10; -- horizontal space between items in a line entryTabSpace: CARDINAL _ 36*3; -- horizontal tab between items in a line ruleHeight: CARDINAL _ 4; resultWidth: CARDINAL = 12*VFonts.CharWidth['0];-- 12 digits worth of width defaultScreenWidth: Rope.ROPE = "1024"; defaultScreenHeight: Rope.ROPE = "768"; defaultRefresh: Rope.ROPE = "30"; defaultHBlank: Rope.ROPE = "6"; defaultVBlank: Rope.ROPE = "850"; defaultBPP: Rope.ROPE = "8"; defaultPosition: Rope.ROPE = "right"; MakeMonitorTool: Commander.CommandProc = TRUSTED { myRule: Rules.Rule; myMenu: Menus.Menu _ Menus.CreateMenu[]; my: MonitorToolButtons.Handle _ NEW[MonitorToolButtons.MTViewerRec]; Menus.AppendMenuEntry[ -- add command to the menu menu: myMenu, entry: Menus.CreateEntry[ name: "Calculate", -- name of the command proc: CalculateProc, -- MenuProc associated with command clientData: my ] ]; Menus.AppendMenuEntry[ -- add command to the menu menu: myMenu, entry: Menus.CreateEntry[ name: "Set", -- name of the command proc: SetParametersProc, -- MenuProc associated with command clientData: my ] ]; Menus.AppendMenuEntry[ -- add command to the menu menu: myMenu, entry: Menus.CreateEntry[ name: "TurnOff", -- name of the command proc: TurnOffProc, -- MenuProc associated with command clientData: my ] ]; Menus.AppendMenuEntry[ -- add command to the menu menu: myMenu, entry: Menus.CreateEntry[ name: "NTSC", -- name of the command proc: NTSCProc, -- MenuProc associated with command clientData: my ] ]; my.container _ Containers.Create[info: [-- construct the outer container name: "MonitorTool", -- name displayed in the caption iconic: FALSE, -- so tool won't be iconic (small) when first created column: left, -- initially in the left column menu: myMenu, -- displaying our menu command scrollable: TRUE ]]; -- allow scrolling contents my.screenWidth _ MakeEntryViewer[handle: my, buttonName: "screen width", labelName: "visible pixels", proc: MonitorToolButtons.ScreenWidth, initialData: defaultScreenWidth]; my.screenHeight _ MakeEntryViewer[handle: my, buttonName: "screen height", labelName: "visible pixels", proc: MonitorToolButtons.ScreenHeight, initialData: defaultScreenHeight]; my.refresh _ MakeEntryViewer[handle: my, buttonName: "refresh rate", labelName: "frames per second", proc: MonitorToolButtons.Refresh, initialData: defaultRefresh]; my.hBlank _ MakeEntryViewer[handle: my, buttonName: "hBlank time", labelName: "microseconds", proc: MonitorToolButtons.HBlank, initialData: defaultHBlank]; my.vBlank _ MakeEntryViewer[handle: my, buttonName: "vBlank time", labelName: "microseconds", proc: MonitorToolButtons.VBlank, initialData: defaultVBlank]; my.bpp _ MakeEntryViewer[handle: my, buttonName: "bits per pixel", labelName: "{1,2,4,8,24}", proc: MonitorToolButtons.BitsPerPixel, initialData: defaultBPP]; my.position _ MakeEntryViewer[handle: my, buttonName: "Position", labelName: "{Left/Right}", proc: MonitorToolButtons.Position, initialData: defaultPosition]; my.height _ my.height + entryHeight+ entryVSpace; --space down myRule _ Rules.Create[info: [parent: my.container, wx: my.screenWidth.button.wx, wy: my.height, ww: my.container.ww-my.screenWidth.button.wx*2, wh: ruleHeight]]; my.height _ my.height + ruleHeight+ entryVSpace; --space down Containers.ChildXBound[my.container, myRule]; my.fieldTime _ MakeResultViewer[handle: my, leftLabelName: "field time", rightLabelName: "milliseconds"]; my.fieldFreq _ MakeResultViewer[handle: my, leftLabelName: "field freq", rightLabelName: "Hz"]; my.lineTime _ MakeResultViewer[handle: my, leftLabelName: "line time", rightLabelName: "microseconds"]; my.lineFreq _ MakeResultViewer[handle: my, leftLabelName: "line freq", rightLabelName: "KHz"]; my.pixelTime _ MakeResultViewer[handle: my, leftLabelName: "pixel time", rightLabelName: "nanoseconds"]; my.pixelFreq _ MakeResultViewer[handle: my, leftLabelName: "pixel freq", rightLabelName: "MHz"]; my.MUL _ MakeResultViewer[handle: my, leftLabelName: "MUL", rightLabelName: "[0..255]"]; my.DIV _ MakeResultViewer[handle: my, leftLabelName: "DIV", rightLabelName: "[0..15]"]; my.vControl _ MakeResultViewer[handle: my, leftLabelName: "vertical ctrl", rightLabelName: "", entryheight: 4*entryHeight, entrywidth: 3*resultWidth]; my.hControl _ MakeResultViewer[handle: my, leftLabelName: "horizontal ctrl", rightLabelName: "", entryheight: 4*entryHeight, entrywidth: 3*resultWidth]; CalculateProc[parent: NIL, clientData: my]; MessageWindow.Append[message: "Default Parameters for 1024x768 Monitor", clearFirst: TRUE]; ViewerOps.SetOpenHeight[my.container, my.height]; -- hint our desired height ViewerOps.PaintViewer[my.container, all]; -- reflect above change }; TurnOffProc: Menus.MenuProc = TRUSTED { WindowManager.StopColorViewers[]; }; NTSCProc: Menus.MenuProc = TRUSTED { mp: MonitorToolDefs.MonitorParam; bpp: LONG CARDINAL; full: BOOLEAN_FALSE; my: MonitorToolButtons.Handle _ NARROW[clientData]; {--for catch phrases bpp _ IO.GetCard[IO.RIS[ViewerTools.GetContents[my.bpp.input]] ! IO.Error => { MessageWindow.Append[message: "Input Syntax Error in ", clearFirst: TRUE]; MessageWindow.Append[message: my.bpp.button.name, clearFirst: FALSE]; GOTO error };]; SELECT bpp FROM 24 => full_TRUE; 8,4,2,1 => NULL; ENDCASE => { MessageWindow.Append[message: "Input Value Error in ", clearFirst: TRUE]; MessageWindow.Append[message: my.bpp.button.name, clearFirst: FALSE]; GOTO error; }; mp _ NEW[MonitorToolDefs.MonitorParamRec _ [ hRes: 640, vRes: 480, vc: [VBtoVS: 3, VStoVS: 3, VStoVB: 20B, VisibleLines: 240], hc: [HRamMaxAddr: 909, HBLeadLength: 12, HSTrailAddr: 56, HBTrailLength: 202], cc: [zero: 5, mul: 115, div: 14], lmarg: 474, truePixelFreq: 0, truePixelTime: 0]]; MonitorToolDefs.SetMonitorParams[bpp: bpp, mp: mp]; IF NOT full THEN { --bpp#24 ColorDisplayHeadDorado.channelA.pixelsPerLine_2777B; ColorDisplayHeadDorado.channelA.scanControl.resolution_half; }; MessageWindow.Append[message: "Note: NTSC REQUIRES LATE MODEL HARDWARE", clearFirst: TRUE]; MessageWindow.Blink[]; MessageWindow.Blink[]; EXITS error => NULL; }; --for catch phrases }; SetParametersProc: Menus.MenuProc = TRUSTED { my: MonitorToolButtons.Handle _ NARROW[clientData]; sw, sh, refresh, bpp: LONG CARDINAL; hBlank, vBlank: REAL; posRope: Rope.ROPE; pos: WindowManager.ScreenPos; mp: MonitorToolDefs.MonitorParam; { --for catch phrases sw _ IO.GetCard[IO.RIS[ViewerTools.GetContents[my.screenWidth.input]] ! IO.Error => { MessageWindow.Append[message: "Input Syntax Error in ", clearFirst: TRUE]; MessageWindow.Append[message: my.screenWidth.button.name, clearFirst: FALSE]; GOTO error };]; sh _ IO.GetCard[IO.RIS[ViewerTools.GetContents[my.screenHeight.input]] ! IO.Error => { MessageWindow.Append[message: "Input Syntax Error in ", clearFirst: TRUE]; MessageWindow.Append[message: my.screenHeight.button.name, clearFirst: FALSE]; GOTO error };]; refresh _ IO.GetCard[IO.RIS[ViewerTools.GetContents[my.refresh.input]] ! IO.Error => { MessageWindow.Append[message: "Input Syntax Error in ", clearFirst: TRUE]; MessageWindow.Append[message: my.refresh.button.name, clearFirst: FALSE]; GOTO error };]; bpp _ IO.GetCard[IO.RIS[ViewerTools.GetContents[my.bpp.input]] ! IO.Error => { MessageWindow.Append[message: "Input Syntax Error in ", clearFirst: TRUE]; MessageWindow.Append[message: my.bpp.button.name, clearFirst: FALSE]; GOTO error };]; hBlank _ 1E-6* IO.GetReal[IO.RIS[ViewerTools.GetContents[my.hBlank.input]] ! IO.Error => { MessageWindow.Append[message: "Input Syntax Error in ", clearFirst: TRUE]; MessageWindow.Append[message: my.hBlank.button.name, clearFirst: FALSE]; GOTO error };]; vBlank _ 1E-6* IO.GetReal[IO.RIS[ViewerTools.GetContents[my.vBlank.input]] ! IO.Error => { MessageWindow.Append[message: "Input Syntax Error in ", clearFirst: TRUE]; MessageWindow.Append[message: my.vBlank.button.name, clearFirst: FALSE]; GOTO error };]; posRope _ ViewerTools.GetContents[my.position.input ! IO.Error => { MessageWindow.Append[message: "Input Syntax Error in ", clearFirst: TRUE]; MessageWindow.Append[message: my.position.button.name, clearFirst: FALSE]; GOTO error };]; SELECT TRUE FROM Rope.Equal[s1: posRope, s2: "left", case: FALSE] => pos _ left; Rope.Equal[s1: posRope, s2: "right", case: FALSE] => pos _ right; ENDCASE => { MessageWindow.Append[message: "Input Syntax Error in Position", clearFirst: TRUE]; GOTO error }; mp _ MonitorToolDefs.DoMonitorParams[sw,sh,refresh,hBlank,vBlank]; MonitorToolDefs.SetMonitorParams[bpp, pos, mp]; EXITS error => NULL; }; --for catch phrases }; CalculateProc: Menus.MenuProc = TRUSTED { my: MonitorToolButtons.Handle _ NARROW[clientData]; sw, sh, refresh, bpp: LONG CARDINAL; hBlank, vBlank: REAL; mp: MonitorToolDefs.MonitorParam; { --for catch phrases sw _ IO.GetCard[IO.RIS[ViewerTools.GetContents[my.screenWidth.input]] ! IO.Error => { MessageWindow.Append[message: "Input Syntax Error in ", clearFirst: TRUE]; MessageWindow.Append[message: my.screenWidth.button.name, clearFirst: FALSE]; GOTO error };]; sh _ IO.GetCard[IO.RIS[ViewerTools.GetContents[my.screenHeight.input]] ! IO.Error => { MessageWindow.Append[message: "Input Syntax Error in ", clearFirst: TRUE]; MessageWindow.Append[message: my.screenHeight.button.name, clearFirst: FALSE]; GOTO error };]; refresh _ IO.GetCard[IO.RIS[ViewerTools.GetContents[my.refresh.input]] ! IO.Error => { MessageWindow.Append[message: "Input Syntax Error in ", clearFirst: TRUE]; MessageWindow.Append[message: my.refresh.button.name, clearFirst: FALSE]; GOTO error };]; bpp _ IO.GetCard[IO.RIS[ViewerTools.GetContents[my.bpp.input]] ! IO.Error => { MessageWindow.Append[message: "Input Syntax Error in ", clearFirst: TRUE]; MessageWindow.Append[message: my.bpp.button.name, clearFirst: FALSE]; GOTO error };]; hBlank _ 1E-6* IO.GetReal[IO.RIS[ViewerTools.GetContents[my.hBlank.input]] ! IO.Error => { MessageWindow.Append[message: "Input Syntax Error in ", clearFirst: TRUE]; MessageWindow.Append[message: my.hBlank.button.name, clearFirst: FALSE]; GOTO error };]; vBlank _ 1E-6* IO.GetReal[IO.RIS[ViewerTools.GetContents[my.vBlank.input]] ! IO.Error => { MessageWindow.Append[message: "Input Syntax Error in ", clearFirst: TRUE]; MessageWindow.Append[message: my.vBlank.button.name, clearFirst: FALSE]; GOTO error };]; EXITS error => RETURN; }; --for catch phrases mp _ MonitorToolDefs.DoMonitorParams[sw,sh,refresh,hBlank,vBlank]; Labels.Set[label: my.fieldTime.data, value: IO.PutFR[format: "%g", v1: IO.real[1E3*MonitorToolDefs.fieldTime]]]; Labels.Set[label: my.fieldFreq.data, value: IO.PutFR[format: "%g", v1: IO.real[MonitorToolDefs.fieldFreq]]]; Labels.Set[label: my.lineTime.data, value: IO.PutFR[format: "%g", v1: IO.real[1E6*MonitorToolDefs.trueLinetime]]]; Labels.Set[label: my.lineFreq.data, value: IO.PutFR[format: "%g", v1: IO.real[1E-3*MonitorToolDefs.trueLinefreq]]]; Labels.Set[label: my.pixelTime.data, value: IO.PutFR[format: "%g", v1: IO.real[1E9*MonitorToolDefs.truePixeltime]]]; Labels.Set[label: my.pixelFreq.data, value: IO.PutFR[format: "%g", v1: IO.real[1E-6*MonitorToolDefs.truePixelfreq]]]; Labels.Set[label: my.MUL.data, value: IO.PutFR[format: "%g", v1: IO.card[MonitorToolDefs.trueMul]]]; Labels.Set[label: my.DIV.data, value: IO.PutFR[format: "%g", v1: IO.card[MonitorToolDefs.trueDiv]]]; ViewerTools.EnableUserEdits[my.hControl.data]; ViewerTools.SetContents[viewer: my.hControl.data, contents: IO.PutFR[format: "HRamMaxAddr: %g\nHBlankLeadLength: %g\nHSTrailAddr: %g\nHBTrailLength: %g", v1: IO.card[MonitorToolDefs.hRamMaxAddr], v2: IO.card[MonitorToolDefs.hBLeadLength], v3: IO.card[MonitorToolDefs.hSTrailAddr], v4: IO.card[MonitorToolDefs.hBTrailLength]]]; ViewerTools.InhibitUserEdits[my.hControl.data]; ViewerTools.EnableUserEdits[my.vControl.data]; ViewerTools.SetContents[viewer: my.vControl.data, contents: IO.PutFR[format: "VBtoVSLines: %g\nVStoVSLines: %g\nVStoVBLines: %g\nVisibleLines: %g", v1: IO.card[MonitorToolDefs.vbToVS], v2: IO.card[MonitorToolDefs.vsToVS], v3: IO.card[MonitorToolDefs.vsToVB], v4: IO.card[MonitorToolDefs.visibleLines]]]; ViewerTools.InhibitUserEdits[my.vControl.data]; }; MakeEntryViewer: PROCEDURE [handle: MonitorToolButtons.Handle, buttonName: Rope.ROPE, labelName: Rope.ROPE, proc: Buttons.ButtonProc, initialData: Rope.ROPE] RETURNS [ev: MonitorToolButtons.EntryViewer] = { ev _ NEW[MonitorToolButtons.EntryViewerRec]; ev.button_ Buttons.Create[ info: [ name: buttonName, wy: handle.height, wh: entryHeight, -- specify rather than defaulting so line is uniform parent: handle.container, border: FALSE ], proc: proc, clientData: handle]; -- this will be passed to our button proc ev.input _ ViewerTools.MakeNewTextViewer[ [ parent: handle.container, wx: entryTabSpace, wy: handle.height+2, ww: 12*VFonts.CharWidth['0], -- 12 digits worth of width wh: entryHeight, data: initialData, -- initial contents scrollable: FALSE, border: TRUE]]; ev.units _ Labels.Create[ [ name: labelName, wx: ev.input.wx + ev.input.ww + entryHSpace, wy: handle.height, wh: entryHeight, parent: handle.container, border: FALSE]]; handle.height _ handle.height + entryHeight+ entryVSpace; --space down for next guy }; MakeResultViewer: PROCEDURE [handle: MonitorToolButtons.Handle, leftLabelName, rightLabelName: Rope.ROPE, entryheight: CARDINAL _ entryHeight, entrywidth: CARDINAL _ resultWidth]RETURNS [rv: MonitorToolButtons.ResultViewer] = { initialData: Rope.ROPE = " ????? "; rv _ NEW[MonitorToolButtons.ResultViewerRec]; rv.left _ Labels.Create[ [ name: leftLabelName, wy: handle.height, wh: entryHeight, parent: handle.container, scrollable: FALSE, border: FALSE]]; rv.data _ ViewerTools.MakeNewTextViewer[ [ data: initialData, wx: entryTabSpace, wy: handle.height, ww: entrywidth, wh: entryheight, scrollable: FALSE, parent: handle.container, border: TRUE]]; rv.right _ Labels.Create[ [ name: rightLabelName, wx: rv.data.wx + rv.data.ww + entryHSpace, wy: handle.height, wh: entryHeight, parent: handle.container, scrollable: FALSE, border: FALSE]]; handle.height _ handle.height + entryheight+ entryVSpace; --space down for next guy }; Commander.Register[key: "MonitorTool", proc: MakeMonitorTool, doc: "Create a color monitor control tool" ]; }. fMonitorToolImpl.mesa Last Edited by: Pier, July 30, 1985 5:35:43 pm PDT default values for 1024X768 monitor now create output viewers now set up default values this proc should only be called when a Dorado with NTSC-modified DispM board is set up to do video tape recording. The parameters in the 24 Bpp MonitorParam below were carefully determined by Pier and Gasbarro using trial and error on 8/24/83. N.B.: we will set up the monitor waveforms identicallty for all bpp values. The values are the same as the "double speed" values for 24 bpp. This guarantees locking to the NTSC frequency. For bpp#24, run the video at 1/2 resolution horizontally and double the visible pixels per line. MenuProc: TYPE = PROC [parent: REF ANY, clientData: REF ANY _ NIL, mouseButton: MouseButton _ red, shift, control: BOOL _ FALSE] ; adds an entry viewer with a button, text viewer, and suffix label to the container default the width so that it will be computed for us -- default ww adds a result viewer with a label, text viewer, and units to the container default the width so that it will be computed for us -- default ww Κ ’˜Icodešœ™Kšœ2™2K™šΟk ˜ Kšœœ˜#K˜Kšœ œ!˜0Kšœ œ˜'Kšœœ.œ˜;Kšœœ˜Kšœœ<˜GKšœœ˜$KšœœŸ˜·Kšœœƒ˜˜Kšœœ œ˜Kšœœ˜Kšœœ ˜Kšœ œ˜-Kšœ œR˜cKšœœ˜2—K˜šΟbœœ˜Kšœ0œŒ˜ΕKšœ˜!K˜Kšœ œΟc&˜BKšœ œŸ'˜CKšœ œŸ+˜HKšœœ Ÿ)˜JKšœ œ˜Kšœ œŸ˜KK™Kšœ#™#Kšœœ ˜'Kšœœ ˜'Kšœœ˜!Kšœœ˜Kšœœ ˜!Kšœœ˜Kšœœ ˜%šœ)œ˜2K˜K˜(Kšœ œ!˜DšœŸ˜2K˜ ˜KšœŸ˜)KšœŸ#˜9K˜K˜—K˜—šœŸ˜2K˜ ˜Kšœ Ÿ˜#KšœŸ#˜=K˜K˜—K˜—šœŸ˜2K˜ ˜KšœŸ˜'KšœŸ#˜7K˜K˜—K˜—šœŸ˜2K˜ ˜KšœŸ˜$KšœŸ#˜4K˜K˜—K˜—K˜šœ(Ÿ ˜HKšœŸ ˜5KšœœŸ5˜FKšœŸ˜0KšœŸ˜-Kšœ œŸ˜1—K˜Kšœ­˜­Kšœ±˜±Kšœ€˜€Kšœ›˜›Kšœ›˜›Kšœž˜žKšœž˜žK˜Kšœ2Ÿ ˜>K˜‘Kšœ1Ÿ ˜=K˜-K˜Kšœ™K˜iK˜_K˜gK˜^K˜hK˜`KšœœR˜XKšœœQ˜WK˜–K˜˜K˜Kšœ™Kšœœ˜+KšœUœ˜[Kšœ2Ÿ˜LKšœ-Ÿ˜DK˜—K˜šœœ˜'K˜!K˜—K˜šœœ˜$KšœL™LKšœW™WKšœP™PK˜!Kšœœœ˜Kšœœœ˜Kšœ œ ˜3šœŸ˜š œœ œœ*œ ˜NKšœDœ˜JKšœ>œ˜EKšœ˜ K˜—šœ˜Kšœ œ˜Kšœ œ˜Kšœ˜ KšœCœ˜IKšœ>œ˜EKšœ˜ K˜—K˜Kšœž™žK˜šœœ$˜,K˜QK˜NK˜S—K˜3šœœœŸ˜K˜4K˜œ˜EKšœ˜ K˜—š œœ œœ-œ ˜ZKšœDœ˜JKšœAœ˜HKšœ˜ K˜—š œœ œœ-œ ˜ZKšœDœ˜JKšœAœ˜HKšœ˜ K˜—šœ6œ ˜CKšœDœ˜JKšœCœ˜JKšœ˜ K˜—šœœ˜Kšœ*œ˜?Kšœ+œ˜AKšœ˜ KšœLœ˜RKšœ˜ K˜—K˜K˜BK˜/Kš˜Kšœ œ˜KšœŸ˜—K˜—šœ œ˜)K˜Kšœ œ ˜3Kšœœœ˜$Kšœœ˜K˜!K˜šœŸ˜š œœ œœ2œ ˜UKšœDœ˜JKšœFœ˜MKšœ˜ K˜—š œœ œœ3œ ˜VKšœDœ˜JKšœGœ˜NKšœ˜ K˜—š œ œ œœ.œ ˜VKšœDœ˜JKšœBœ˜IKšœ˜ K˜—š œœ œœ*œ ˜NKšœDœ˜JKšœ>œ˜EKšœ˜ K˜—š œœ œœ-œ ˜ZKšœDœ˜JKšœAœ˜HKšœ˜ K˜—š œœ œœ-œ ˜ZKšœDœ˜JKšœAœ˜HKšœ˜ K˜—Kš˜Kšœ œ˜KšœŸ˜—K˜K˜BK˜Kšœ-œœ'˜qKšœ-œœ#˜mKšœ,œœ*˜sKšœ,œœ+˜tKšœ-œœ+˜uKšœ-œœ,˜vKšœœœœ!˜eKšœœœœ!˜eK˜K˜.Kš œ=œ`œ(œ)œ(œ'˜ΗK˜/K˜K˜.Kš œ=œZœ#œ#œ#œ&˜°K˜/K˜—š Οnœ œ6œœ.œœ)˜ΞKšœR™RKšœœ$˜,˜˜K˜K˜Kšœ7™7KšœŸ4˜EK˜Kšœœ˜—K˜ KšœŸ)˜>—˜+K˜K˜K˜KšœŸ˜8K˜KšœŸ˜&Kšœ œ˜Kšœœ˜—˜K˜K˜,K˜Kšœ ™ K˜K˜Kšœœ˜—Kšœ:Ÿ˜SK˜—š  œ œIœœœœ*˜δK˜KšœJ™JKšœœ˜%Kšœœ%˜-˜K˜K˜Kšœ7™7K˜K˜Kšœ œ˜Kšœœ˜—˜*K˜K˜K˜K˜K˜Kšœ œ˜K˜Kšœœ˜—˜K˜K˜*K˜Kšœ ™ K˜K˜Kšœ œ˜Kšœœ˜—Kšœ:Ÿ˜SK˜—K˜˜=K˜-—K˜——…—=8M@