DIRECTORY Imager USING [XOR, Error], ImagerBasic USING [DeviceRectangle, Color, ColorRep, IntRectangle], ImagerDisplay USING [DisplayClass, DisplayClassRep, DisplayData, DisplayDataRep], ImagerMasks USING [Mask, ApplyConstant, BoundingBox], ImagerPixelMaps USING [PixelMap, PixelMapRep, Fill, Function], ColorModels USING [Calibration, GetPhosphorCalibration], ConstantColors USING [RGBToColor, white], Terminal USING [ColorMode, ChannelsVisible, Current, GetColorMode, Virtual, WaitForBWVerticalRetrace], TerminalExtras USING [LockColorFrame, UnlockColorFrame], TerminalColorExtras USING [SetColorBitmapState], Interminal USING [TurnOnColorCursor, TurnOffColorCursor], Basics USING [bitsPerWord, LongMult, BITSHIFT], Atom USING [MakeAtom, PutPropOnList, GetPropFromList], WindowManager USING [ScreenPos, StopColorViewers, StartColorViewers], ColorDisplayFaceExtras USING [DisplayType, SetMonitorType, SetBOffsets, SwitchChannels], CountedVM USING [Allocate, Pointer, Handle], UserProfile USING [Token, ProfileChangedProc, CallWhenProfileChanges], Rope USING [ROPE, Equal], ImagerStdColorDisplay; ImagerStdColorDisplayImpl: CEDAR PROGRAM IMPORTS Imager, ImagerMasks, ColorModels, ConstantColors, Terminal, TerminalExtras, TerminalColorExtras, Atom, UserProfile, Rope, CountedVM, Basics, Interminal, ColorDisplayFaceExtras, ImagerPixelMaps, WindowManager EXPORTS ImagerStdColorDisplay ~ BEGIN DisplayClass: TYPE ~ ImagerDisplay.DisplayClass; DisplayClassRep: TYPE ~ ImagerDisplay.DisplayClassRep; DisplayData: TYPE ~ ImagerDisplay.DisplayData; DisplayDataRep: TYPE ~ ImagerDisplay.DisplayDataRep; DeviceRectangle: TYPE ~ ImagerBasic.DeviceRectangle; Color: TYPE ~ ImagerBasic.Color; ColorRep: TYPE ~ ImagerBasic.ColorRep; SampledColor: TYPE = REF ColorRep.sampled; ConstantColor: TYPE = REF ColorRep.constant; SpecialColor: TYPE = REF ColorRep.special; Mask: TYPE ~ ImagerMasks.Mask; ColorDisplayError: PUBLIC SIGNAL [reason: ATOM] ~ CODE; pixelsPerInch: NAT; monitorType: ColorDisplayFaceExtras.DisplayType; currentDisplay: DisplayData _ NIL; -- Currently displayed context displaySide: WindowManager.ScreenPos; colorCalibration: PUBLIC ColorModels.Calibration; Create: PUBLIC PROC [vt: Terminal.Virtual, mode: Terminal.ColorMode, displayClass: DisplayClass, creationData: REF, bitsPerPixel: NAT, setUpMapProc: ImagerStdColorDisplay.SetUpMapProc] RETURNS [displayData: DisplayData] ~ { GetPixelMap: PROC [x, y, width, height, bitsPerPixel: NAT, pointer: LONG POINTER _ NIL] RETURNS[pixelMap: ImagerPixelMaps.PixelMap] ~ { lgBitsPerPixel: NAT; words: INT; storage: CountedVM.Handle _ NIL; wordsPerLineA: INT _ width * MIN[ bitsPerPixel, IF mode.full THEN 16 ELSE mode.bitsPerPixelChannelA]; wordsPerLineB: INT _ IF bitsPerPixel > mode.bitsPerPixelChannelA THEN width * mode.bitsPerPixelChannelB ELSE 0; IF wordsPerLineA MOD Basics.bitsPerWord # 0 THEN wordsPerLineA _ wordsPerLineA/ Basics.bitsPerWord + 1 ELSE wordsPerLineA _ wordsPerLineA/ Basics.bitsPerWord; IF wordsPerLineB MOD Basics.bitsPerWord # 0 THEN wordsPerLineB _ wordsPerLineB/ Basics.bitsPerWord + 1 ELSE wordsPerLineB _ wordsPerLineB/ Basics.bitsPerWord; words _ Basics.LongMult[wordsPerLineA + wordsPerLineB, height + 1] + 2048; IF mode.full THEN words _ words + 512; -- extra space for extra color tables IF pointer = NIL THEN { storage _ CountedVM.Allocate[words: words]; TRUSTED { pointer _ CountedVM.Pointer[storage]; }; }; IF bitsPerPixel > mode.bitsPerPixelChannelA AND ~mode.full THEN bitsPerPixel _ mode.bitsPerPixelChannelA; SELECT bitsPerPixel FROM -- log bits per pixel for first map 1 => lgBitsPerPixel _ 0; 2 => lgBitsPerPixel _ 1; 4 => lgBitsPerPixel _ 2; 8 => lgBitsPerPixel _ 3; 16,24,32 => lgBitsPerPixel _ 4; ENDCASE => ColorDisplayError[$BitsPerPixelWrong]; pixelMap _ [ sOrigin: y, fOrigin: x, sMin: 0, fMin: 0, sSize: height, fSize: width, refRep: NEW [ImagerPixelMaps.PixelMapRep _ [ ref: storage, pointer: pointer, words: words, lgBitsPerPixel: lgBitsPerPixel, rast: wordsPerLineA, lines: height ]] ]; ImagerPixelMaps.Fill[ pixelMap, [0, 0, height, width], Basics.BITSHIFT[1, bitsPerPixel] - 1 ] }; numMaps: NAT; channelsVisible: Terminal.ChannelsVisible; colorData: REF ImagerStdColorDisplay.ColorMapData; creationList: LIST OF REF ANY _ NARROW[creationData, LIST OF REF ANY]; adjPixPerInch: NAT _ IF monitorType = conrac7211Hi AND mode.full THEN pixelsPerInch/2 ELSE pixelsPerInch; SELECT bitsPerPixel FROM 1,2,4,6,10 => numMaps _ 1; 16,24 => numMaps _ 2; 32 => numMaps _ 4; ENDCASE => ColorDisplayError[$BitsPerPixelWrong]; channelsVisible _ IF bitsPerPixel > 16 THEN all ELSE aOnly; TRUSTED { Interminal.TurnOffColorCursor[]; }; -- for safety's sake, disallow cursor action WindowManager.StopColorViewers[]; -- !!!!! this should be done when terminalimpl is fixed IF creationList = NIL THEN { -- use default pixel map displayData _ NEW[DisplayDataRep[numMaps]]; -- Make a rep IF mode.bitsPerPixelChannelB < 8 THEN { -- no overlays here mode.bitsPerPixelChannelB _ 0; bitsPerPixel _ mode.bitsPerPixelChannelA; }; [] _ TerminalColorExtras.SetColorBitmapState[vt, displayed, mode, channelsVisible]; displayData[0] _ GetPixelMap[0, 0, vt.colorWidth, vt.colorHeight, bitsPerPixel, vt.colorBitmapA]; -- gets up to 24 bits per pixel from Terminal IF currentDisplay # NIL THEN currentDisplay.props _ Atom.PutPropOnList[ currentDisplay.props, $PixelMapStatus, $Allocated ]; currentDisplay _ displayData; displayData.props _ Atom.PutPropOnList[displayData.props, $PixelMapStatus, $Displayed]; IF mode.full THEN { -- full color, set up multiple pixel maps blueMap: NAT _ IF numMaps = 4 THEN 2 ELSE 1; -- position of Blue map in sequence displayData[blueMap] _ GetPixelMap[0, 0, vt.colorWidth, vt.colorHeight, 8, vt.colorBitmapB]; IF numMaps = 4 THEN { displayData[1] _ GetPixelMap[0, 0, vt.colorWidth, vt.colorHeight, 8]; -- green pixels displayData[3] _ GetPixelMap[0, 0, vt.colorWidth, vt.colorHeight, 8]; -- alpha pixels }; } ELSE IF numMaps = 2 THEN -- second pixel map used as overlay or double buffer displayData[1] _ GetPixelMap[0, 0, vt.colorWidth, vt.colorHeight, bitsPerPixel - mode.bitsPerPixelChannelA, vt.colorBitmapB]; } ELSE { -- Non-nil creation list, build new pixel map pinned: BOOLEAN _ TRUE; box, box2: REF ImagerBasic.IntRectangle _ NIL; nullBox: ImagerBasic.IntRectangle _ [0, 0, 0, 0]; WHILE creationList # NIL DO -- pick up pin command, box, or both WITH creationList.first SELECT FROM pinTruth: REF BOOLEAN => pinned _ pinTruth^; -- Display now or just compute? boxRef: REF ImagerBasic.IntRectangle => IF box = NIL THEN box _ boxRef -- For less than the full screen ELSE box2 _ boxRef; -- For overlays (both boxes needed) ENDCASE; creationList _ creationList.rest ENDLOOP; IF box = NIL THEN box^ _ [0, 0, vt.colorWidth, vt.colorHeight]; -- use screen size IF box2 # NIL AND numMaps = 1 THEN numMaps _ 2 -- an overlay map needed ELSE IF numMaps = 1 THEN { bitsPerPixel _ mode.bitsPerPixelChannelA; mode.bitsPerPixelChannelB _ 0; }; displayData _ NEW[DisplayDataRep[numMaps]]; -- Make a rep displayData[0] _ GetPixelMap[box.x, box.y, box.w, box.h, bitsPerPixel]; -- gets up to 24 bpp IF mode.full THEN { -- full color, set up multiple pixel maps IF numMaps > 1 THEN { blueMap: NAT _ IF numMaps = 4 THEN 2 ELSE 1; blueBits: LONG POINTER; -- blue pixels lie above 16-bit interleaved RG pixels TRUSTED { blueBits _ displayData[0].refRep.pointer + Basics.LongMult[displayData[0].refRep.rast, box.h] }; displayData[blueMap] _ GetPixelMap[box.x, box.y, box.w, box.h, 8, blueBits]; IF numMaps = 4 THEN { displayData[1] _ GetPixelMap[box.x, box.y, box.w, box.h, 8]; -- green pixels displayData[3] _ GetPixelMap[box.x, box.y, box.w, box.h, 8]; -- alpha pixels }; }; } ELSE IF numMaps = 2 THEN { -- overlay or double buffer mapBits: LONG POINTER; TRUSTED { mapBits _ displayData[0].refRep.pointer + Basics.LongMult[displayData[0].refRep.rast, box.h] }; IF box2 = NIL THEN box2 _ box; displayData[1] _ GetPixelMap[box2.x, box2.y, box2.w, box2.h, bitsPerPixel - mode.bitsPerPixelChannelA, mapBits]; }; IF pinned -- point display at bits THEN { IF box2 = NIL THEN { box2 _ box; mode.bitsPerPixelChannelB _ 0; }; -- single map [] _ TerminalColorExtras.SetColorBitmapState[ vt, displayed, mode, channelsVisible, box.w, box.h, box2.w, box2.h, NARROW[displayData[0].refRep.ref, CountedVM.Handle].interval ]; IF currentDisplay # NIL THEN currentDisplay.props _ Atom.PutPropOnList[ currentDisplay.props, $PixelMapStatus, $Allocated ]; currentDisplay _ displayData; displayData.props _ Atom.PutPropOnList[displayData.props, $PixelMapStatus,$Displayed]; } ELSE displayData.props _ Atom.PutPropOnList[displayData.props, $PixelMapStatus, $Allocated]; }; IF bitsPerPixel < 16 AND numMaps = 2 THEN { channelsVisible _ all; [] _ TerminalColorExtras.SetColorBitmapState[vt, displayed, mode, channelsVisible]; }; IF currentDisplay # NIL THEN TRUSTED { Interminal.TurnOnColorCursor[ -- turn on cursor IF mode.full THEN 24 ELSE mode.bitsPerPixelChannelA, -- bits per pixel displaySide = left -- true => on left ]; }; WindowManager.StartColorViewers[displaySide, mode.bitsPerPixelChannelA]; -- problems!!!?? displayData.displayClass _ displayClass; displayData.xRes _ adjPixPerInch * displayClass.viewUnitsPerPixel; displayData.yRes _ adjPixPerInch * displayClass.viewUnitsPerPixel; displayData.rotate _ TRUE; displayData.cachedColor _ NIL; colorData _ NEW[ImagerStdColorDisplay.ColorMapData]; colorData.pixelValueList _ NIL; colorData.colorCalibration _ colorCalibration; colorData.nextEntry _ 0; colorData.map _ NIL; displayData.cachedColorData _ colorData; setUpMapProc[displayData]; displayData.surfaceWidth _ displayData[0].fSize * displayClass.viewUnitsPerPixel; displayData.surfaceHeight _ displayData[0].sSize * displayClass.viewUnitsPerPixel; }; PinPixelMap: PUBLIC PROC [vt: Terminal.Virtual, data: DisplayData, mode: Terminal.ColorMode] ~ { fSize2, sSize2: NAT; channelsVisible: Terminal.ChannelsVisible _ IF data.numberOfSeparations > 1 AND (mode.bitsPerPixelChannelB # 8 OR mode.full) THEN all ELSE aOnly; IF data[0].refRep.ref = NIL THEN ColorDisplayError[$ContextDoesntOwnPixelMap]; TRUSTED { Interminal.TurnOffColorCursor[]; }; -- for safety's sake, disallow cursor action IF channelsVisible = all THEN { fSize2 _ data[1].fSize; sSize2 _ data[1].sSize; } ELSE { fSize2 _ data[0].fSize; sSize2 _ data[0].sSize; }; [] _ TerminalColorExtras.SetColorBitmapState[ vt, displayed, mode, channelsVisible, data[0].fSize, data[0].sSize, fSize2, sSize2, NARROW[data[0].refRep.ref, CountedVM.Handle].interval ]; IF currentDisplay # NIL THEN currentDisplay.props _ Atom.PutPropOnList[ currentDisplay.props, $PixelMapStatus, $Allocated ]; currentDisplay _ data; data.props _ Atom.PutPropOnList[ data.props, $PixelMapStatus,$Displayed]; IF currentDisplay # NIL THEN TRUSTED { Interminal.TurnOnColorCursor[ -- turn on cursor IF mode.full THEN 24 ELSE mode.bitsPerPixelChannelA, -- bits per pixel displaySide = left -- true => on left ]; }; }; ReleasePixelMap: PUBLIC PROC [vt: Terminal.Virtual, data: DisplayData] ~ { IF data # currentDisplay THEN Imager.Error[$DataNotCurrentDisplay]; TRUSTED { Interminal.TurnOffColorCursor[]; }; -- for safety's sake, disallow cursor action [] _ TerminalColorExtras.SetColorBitmapState[ vt, allocated, Terminal.GetColorMode[vt], none, ]; data.props _ Atom.PutPropOnList[ data.props, $PixelMapStatus, $Allocated ]; currentDisplay _ NIL; }; MoveOverlay: PUBLIC PROC [vt: Terminal.Virtual, data: REF ANY] ~ { x, y: NAT _ 0; list: LIST OF REF ANY _ NARROW[data, LIST OF REF ANY]; x _ NARROW[list.first, REF INTEGER]^; list _ list.rest; y _ NARROW[list.first, REF INTEGER]^; TRUSTED { ColorDisplayFaceExtras.SetBOffsets[x, y]; }; }; SwitchBuffers: PUBLIC PROC [] ~ { TRUSTED { ColorDisplayFaceExtras.SwitchChannels[]; }; }; DoUnderLock: PUBLIC PROC [displayData: DisplayData, action: PROC, rectangle: DeviceRectangle] ~ { vt: Terminal.Virtual _ Terminal.Current[]; TerminalExtras.LockColorFrame[ vt: vt, xmin: MAX[rectangle.fMin, 0], ymin: MAX[rectangle.sMin, 0], xmax: MAX[rectangle.fMin+rectangle.fSize, 0], ymax: MAX[rectangle.sMin+rectangle.sSize, 0] ]; action[! UNWIND => {TerminalExtras.UnlockColorFrame[vt]}]; TerminalExtras.UnlockColorFrame[vt]; }; ApplyMask: PUBLIC PROC [displayData: DisplayData, color: Color, mask: Mask, sTranslate, fTranslate: INTEGER, cachedColorProc: ImagerStdColorDisplay.CachedColorProc] ~ { LockedApplyMask: PROC ~ { function: ImagerPixelMaps.Function _ [null, null]; IF color = Imager.XOR THEN { color _ ConstantColors.white; function _ [xor, null]; }; WITH color SELECT FROM constantColor: ConstantColor => { ImagerMasks.ApplyConstant[ mask: mask, clipper: displayData.compositeClipper, dest: displayData[separationNumber], value: currentPixelValue, function: function, sTranslate: sTranslate, fTranslate: fTranslate ]; }; ENDCASE => Imager.Error[$UnsupportedColorType]; }; separationNumber: NAT; pixelValues: LIST OF CARDINAL; currentPixelValue: CARDINAL; colorData: REF ImagerStdColorDisplay.ColorMapData _ NARROW[displayData.cachedColorData]; bb: DeviceRectangle _ ImagerMasks.BoundingBox[mask]; bb.sMin _ bb.sMin + sTranslate; bb.fMin _ bb.fMin + fTranslate; IF color # displayData.cachedColor THEN cachedColorProc[displayData, color]; pixelValues _ colorData.pixelValueList; FOR separationNumber IN [0..displayData.numberOfSeparations) DO IF pixelValues # NIL THEN { currentPixelValue _ pixelValues.first; pixelValues _ pixelValues.rest; IF Atom.GetPropFromList[displayData.props, $PixelMapStatus] = $Displayed THEN DoUnderLock[displayData, LockedApplyMask, bb] ELSE LockedApplyMask[]; }; ENDLOOP; }; LoadColorMap: PUBLIC PROC [ vt: Terminal.Virtual, data: REF ANY, displayData: DisplayData, loadColor: ImagerStdColorDisplay.LoadColorProc] ~ { start: NAT _ 0; rgbEntries: REF ImagerStdColorDisplay.RGBSequence _ NIL; colorEntries: REF ImagerStdColorDisplay.ColorSequence _ NIL; colorData: REF ImagerStdColorDisplay.ColorMapData _ NIL; oldColorData: REF ImagerStdColorDisplay.ColorMapData _ NARROW[displayData.cachedColorData]; colorCalibration: ColorModels.Calibration _ oldColorData.colorCalibration; list: LIST OF REF ANY _ NARROW[data, LIST OF REF ANY]; mode: Terminal.ColorMode _ vt.GetColorMode; vt.WaitForBWVerticalRetrace[]; -- await vt selection and top of scan (to control update rate) WHILE list # NIL DO WITH list.first SELECT FROM -- pick up map description rgb: REF ImagerStdColorDisplay.RGBSequence => rgbEntries _ rgb; color: REF ImagerStdColorDisplay.ColorSequence => colorEntries _ color; colorMap: REF ImagerStdColorDisplay.ColorMapData => colorData _ colorMap; calibration: ColorModels.Calibration => colorCalibration _ calibration; nat: REF INTEGER => start _ nat^; ENDCASE; list _ list.rest; ENDLOOP; IF colorData # NIL THEN { colorEntries _ colorData.map; oldColorData _ colorData; }; IF rgbEntries = NIL AND colorEntries # NIL THEN { FOR i: NAT IN [0..MAX[colorEntries.length, 256]) DO oldColorData.map[i] _ colorEntries[i]; loadColor[ colorEntries[i], colorCalibration, i ]; ENDLOOP; oldColorData.nextEntry _ colorEntries.length; }; IF rgbEntries # NIL THEN { FOR i: NAT IN [0..MAX[rgbEntries.length, 256]) DO oldColorData.map[i] _ ConstantColors.RGBToColor[ rgbEntries[i].r/255.0, rgbEntries[i].g/255.0, rgbEntries[i].b/255.0, colorCalibration ]; loadColor[ oldColorData.map[i], colorCalibration, i ]; ENDLOOP; oldColorData.nextEntry _ rgbEntries.length; }; }; MonitorSpecs: UserProfile.ProfileChangedProc = TRUSTED { displayType: Rope.ROPE _ UserProfile.Token["ColorDisplay.Type", "conrac7211Lo"]; SELECT TRUE FROM Rope.Equal[displayType, "ramtek714", FALSE] => { monitorType _ ramtek714; pixelsPerInch _ 64; }; Rope.Equal[displayType, "Hitachi2713", FALSE] => { monitorType _ hitachi2713; pixelsPerInch _ 64; }; Rope.Equal[displayType, "conrac7211Lo", FALSE] => { monitorType _ conrac7211Lo; pixelsPerInch _ 42; }; Rope.Equal[displayType, "conrac7211Hi", FALSE] => { monitorType _ conrac7211Hi; pixelsPerInch _ 68; }; ENDCASE => Imager.Error[$UnknownDisplayType]; IF monitorType = conrac7211Hi THEN ColorDisplayFaceExtras.SetMonitorType[monitorType, 1024, 768] ELSE ColorDisplayFaceExtras.SetMonitorType[monitorType, 640, 480]; [] _ TerminalColorExtras.SetColorBitmapState[Terminal.Current[], allocated, [FALSE, 1, 0], none]; displaySide _ IF Rope.Equal[UserProfile.Token["ColorDisplay.Side", "left"], "left", FALSE] THEN left ELSE right; colorCalibration _ ColorModels.GetPhosphorCalibration[ Atom.MakeAtom[UserProfile.Token["ColorDisplay.Calibration", "DefaultLP"] ] ]; }; { UserProfile.CallWhenProfileChanges[MonitorSpecs]; }; END. °ImagerStdColorDisplayImpl.mesa Copyright c 1984 by Xerox Corporation. All rights reserved. Frank Crow, June 15, 1984 2:28:59 pm PDT This provides support for the Dorado color display hardware common to standard displays. The creationData is inherited from the Create call. Here it is used to specify the dimensions of the pixel map and whether or not to pin it to the screen. NIL, defaults to using the hardware's display dimensions and pinning immediately. Words to allocate: add 8 pages for maps, etc. needed by color display Get display set up and turned on Pixels/inch. Depends on display size and # of lines, from User.Profile in Init[] Pin a pixel map to the color display, replacing whatever was there before. Remove a pixel map from the color display Initialize: set left margin assuming monitor type from resolution (potentially wrong) Get display parameters (height, width, etc.) registered in Terminal's global variables Κφ˜Ihead1™šœ Οmœ1™˜OJšœ$˜$Jšœžœ$˜9Jšœžœ˜0Jšœ žœ)˜;Jšœ žœžœ˜3Jšœ žœ,˜:Jšœžœ2˜EJšœžœ<˜XJšœ žœ˜.Jšœžœ5˜HJšœ žœžœ ˜Jšœ˜J˜—head2šœžœž˜(JšžœL˜SJšœP˜PJšœ:˜:Jšžœ˜J˜Jšœž˜™XJ˜—Jšœžœ˜0Jšœžœ!˜6Jšœ žœ˜.Jšœžœ ˜4Jšœžœ˜4šœžœ˜ Jšœ žœ˜&Jšœžœžœ˜*Jšœžœžœ˜,Jšœžœžœ˜*—šœžœ˜J˜—Jš œžœžœ žœžœ˜7J˜Iašœžœ˜Mšœ0˜0MšœžœΟc"˜HM˜Mšœ%˜%Mšœžœ˜1M˜—JšΟnœž œ2˜EJšœ2žœ˜7šœžœ3˜LJšž œ˜*Jšœξ™ξIunitš  œžœ%žœ˜;Mšœžœž œ˜%šœžœ(˜5Jšœžœ˜Jšœž˜ Jšœžœ˜!Jšœžœ žœ˜0Jšœ žœ žœžœ˜Bšœžœžœ*˜AJšžœ#žœ˜.—šžœžœž˜,Jšžœ7˜;Jšžœ3˜7—šžœžœž˜,Jšžœ7˜;Jšžœ3˜7JšœE™E—JšœJ˜JJšžœ žœŸ%˜Ošžœ žœžœ˜Jšœ+˜+Jšžœ-˜4J˜J˜—šžœ*žœ ˜:Mšžœ*˜.—šžœžŸ'˜?Mšœ˜Mšœ˜Mšœ˜Mšœ˜Mšœ!˜!Mšžœ,˜3—šœžœ˜ Jšœ)˜)Jšœ˜Jšœ ˜ šœžœ!˜,Jšœ ˜ Jšœ˜Jšœ ˜ Jšœ˜Jšœ˜Jšœ ˜ Jšœ˜—J˜—Jšœ>žœ˜]Jšœ˜—Nšœ žœ˜ Mšœ*˜*Mšœ žœ$˜2Jšœžœžœžœžœžœžœžœžœžœ˜Fšœžœžœžœ ˜AJšžœžœ˜)—šžœž˜Mšœ˜Mšœ˜Mšœ˜Mšžœ+˜2M˜—Jšœžœžœžœ˜;Jšžœ)Ÿ,˜\Jšœ#Ÿ7˜ZJ˜šžœžœžœŸ˜:šœžœŸ ˜:J™ —šžœžœŸ˜Ÿ˜MJšœ>Ÿ˜MJšœ˜—J˜—J˜—šžœžœ žœŸ˜8Jšœ žœžœ˜šžœ˜ Jšœ(˜(Jšœ8˜8Jšœ˜—Jšžœžœžœ ˜Jšœ=˜=Jšœ>˜>J˜—šžœ Ÿ˜-šžœ˜Jšžœžœžœ7Ÿ ˜Všœ-˜-Jšœ%˜%Jšœ˜Jšžœ6˜Mšœžœ˜Jšœ žœ%žœ˜8Jšœžœ'žœ˜˜]M˜—šžœžœžœ˜šžœ žœžœŸ˜7Jšœžœ7˜?Jšœžœ=˜GJšœ žœ<˜IJšœG˜GJšœžœžœ˜!Jšžœ˜—Jšœ˜Jšžœ˜—Nšžœ žœžœB˜Yš žœžœžœžœžœ˜1š žœžœžœžœž˜3Mšœ&˜&Mšœ2˜2Mšžœ˜—Mšœ-˜-M˜—šžœžœžœ˜š žœžœžœžœž˜1Mšœ0˜0MšœK˜KMšœ˜Mšœ6˜6Mšžœ˜—Mšœ+˜+M˜—Mšœ˜M˜—šΟb œ#žœ˜8MšŸU™UJšœžœ:˜Pšžœžœž˜Jšœ%žœ!˜KJšœ*˜*Jšœ'žœ#˜OJšœ*˜*Jšœ(žœ#˜PJšœ*˜*Jšœ(žœ"˜OJšœ*˜*Jšžœ&˜-J˜—šžœ˜Jšžœ>˜BJšžœ?˜CJ™V—JšœMžœ˜ašœžœDžœ˜[Jšžœžœ˜—šœ6˜6JšœK˜KJšœ˜—M˜M˜M˜—˜Jšœ1˜1M˜—Mšžœ˜J˜J˜—…—BΒWh