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], 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: PUBLIC 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] _ displayData[0]; -- green pixels are LSBs of 16-bit pixelmap displayData[0] _ GetPixelMap[0, 0, vt.colorWidth, vt.colorHeight, 8]; -- red 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 mainMap: NAT _ 0; -- Bitmap to be pinned to display 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] _ displayData[0]; -- green pixels are LSBs of 16-bit pixelmap displayData[0] _ GetPixelMap[box.x, box.y, box.w, box.h, 8]; -- red pixels displayData[3] _ GetPixelMap[box.x, box.y, box.w, box.h, 8]; -- alpha pixels mainMap _ 1; }; }; } 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[mainMap].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 ]; }; 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, mainMap, secondMap: 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 data.displayClass.displayType = $SmoothColor THEN { mainMap _ 1; secondMap _ 2; } ELSE { mainMap _ 0; secondMap _ 1; }; IF channelsVisible = all THEN { fSize2 _ data[secondMap].fSize; sSize2 _ data[secondMap].sSize; } ELSE { fSize2 _ data[mainMap].fSize; sSize2 _ data[mainMap].sSize; }; [] _ TerminalColorExtras.SetColorBitmapState[ vt, displayed, mode, channelsVisible, data[mainMap].fSize, data[mainMap].sSize, fSize2, sSize2, NARROW[data[mainMap].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; 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..MIN[colorEntries.length, 1024]) DO IF NOT mode.full THEN oldColorData.map[i] _ colorEntries[i]; loadColor[ colorEntries[i], colorCalibration, i ]; ENDLOOP; oldColorData.nextEntry _ colorEntries.length; }; IF rgbEntries # NIL THEN { color: ConstantColor; FOR i: NAT IN [0..MIN[rgbEntries.length, 1024]) DO color _ ConstantColors.RGBToColor[ rgbEntries[i].r/255.0, rgbEntries[i].g/255.0, rgbEntries[i].b/255.0, colorCalibration ]; IF NOT mode.full THEN oldColorData.map[i] _ color; loadColor[ color, 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 WindowManager.StartColorViewers[displaySide, mode.bitsPerPixelChannelA]; -- problems!!!?? 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 ΚV˜Ihead1™šœ Οmœ1™žœ˜]Jšœ˜—Nšœ žœ˜ Mšœ*˜*Mšœ žœ$˜2Jšœžœžœžœžœžœžœžœžœžœ˜Fšœžœžœžœ ˜AJšžœžœ˜)—šžœž˜Mšœ˜Mšœ˜Mšœ˜Mšžœ+˜2M˜—Jšœžœžœžœ˜;Jšžœ)Ÿ,˜\Jšœ#Ÿ7˜ZJ˜šžœžœžœŸ˜:šœžœŸ ˜:J™ —šžœžœŸ˜Ÿ ˜KJšœ>Ÿ˜MJšœ ˜ Jšœ˜—J˜—J˜—šžœžœ žœŸ˜8Jšœ žœžœ˜šžœ˜ Jšœ(˜(Jšœ8˜8Jšœ˜—Jšžœžœžœ ˜Jšœ=˜=Jšœ>˜>J˜—šžœ Ÿ˜-šžœ˜Jšžœžœžœ7Ÿ ˜Všœ-˜-Jšœ%˜%Jšœ˜Jšžœ<˜BJ˜—šžœžœžœ˜3JšœI˜I—Jšœ˜JšœV˜VJšœ˜—šž˜JšœW˜W——Jšœ˜J˜—šžœžœ žœ˜,Jšœ˜JšœS˜SJ˜—šžœžœžœžœ˜&Jšœ%Ÿ˜6Jšžœ žœžœ Ÿ˜JJšœŸ˜3Jšœ˜—JšœHŸœ™[šœ(˜(JšŸP™P—JšœB˜BJšœB˜BJšœžœ˜Jšœžœ˜Jšœ žœ%˜4Jšœžœ˜Jšœ.˜.Jšœ˜Jšœžœ˜Jšœ(˜(Jšœ˜J˜JšœQ˜QJšœR˜RJšœ˜J˜—š  œžœžœ)žœ˜`M™JMšœ$žœ˜(šœ,˜,Mšžœžœ.˜QMšžœžœ˜M™—Mšžœžœžœ.˜NJšžœ)Ÿ,˜\M˜šžœ.˜0Mšžœ'˜+Mšžœ&˜*—šžœ˜MšžœI˜MMšœžœJ˜O—šœ-˜-Jšœ%˜%Jšœ9˜9Jšžœ5˜;J˜—šžœžœžœ˜3JšœI˜I—Jšœ˜JšœI˜IM˜šžœžœžœžœ˜&Jšœ%Ÿ˜6Jšžœ žœžœ Ÿ˜JJšœŸ˜3Jšœ˜—Mšœ˜M™—š œžœžœ.˜JM™)Mšžœžœ&˜CJšžœ)Ÿ,˜\šœ-˜-Jšœ/˜/J˜—JšœK˜KMšœžœ˜Mšœ˜J˜—š   œžœžœžœžœ˜BMšœžœ˜Jšœžœžœžœžœžœžœžœžœžœ˜6Mšœžœ žœžœ˜%Mšœ˜Mšœžœ žœžœ˜%Mšžœ/˜6Jšœ˜M˜—š  œžœžœ˜!Mšžœ.˜5Mšœ˜M˜—š  œž œ$žœ!˜aJšœ*˜*šœ˜Jšœ˜Jšœžœ˜Jšœžœ˜Jšœžœ$˜-Jšœžœ#˜,Jšœ˜—Jšœ žœ+˜:Jšœ$˜$Jšœ˜J˜—Jš  œž œ˜2Jšœ;žœ˜DšœD˜Dš œžœ˜Jšœ2˜2šžœžœžœ˜Jšœ˜Jšœ˜Jšœ˜—šžœžœž˜šœ!˜!šœ˜Jšœ ˜ Jšœ&˜&Jšœ$˜$Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜—J˜—Jšžœ(˜/—Jšœ˜—Jšœžœ˜Jšœ žœžœžœ˜Jšœžœ˜Jšœ žœ&žœ˜XJšœ4˜4Jšœ˜Jšœ˜Jšžœ!žœ%˜LJšœ žœ˜'š žœžœ&žœžœžœ˜Ušžœ˜JšœH˜HšžœGž˜MJšœ-˜-—Jšžœ˜J˜—Jšžœ˜—Jšœ˜J˜—Mš   œžœžœžœž˜AMšœ#ž˜%šœžœ(˜>Mšœžœ˜Jšœ žœ%žœ˜8Jšœžœ'žœ˜˜BJšžœ?˜CJ™V—JšœMžœ˜ašœžœDžœ˜[Jšžœžœ˜—šœ6˜6JšœK˜KJšœ˜—M˜M˜M˜—˜Jšœ1˜1M˜—Mšžœ˜J˜J˜—…—CβYD