DIRECTORY PrincOps, PrincOpsUtils, Buttons, ViewerOps, CKViewerPanel, CKViewerButtons, GraphicsColor, MessageWindow, Basics, Real, Process, Terminal, Interminal; CKViewerOps: PROGRAM IMPORTS PrincOpsUtils, Buttons, Terminal, Interminal, Basics, Real, Process, MessageWindow, CKViewerButtons, ViewerOps EXPORTS CKViewerButtons, CKViewerPanel = BEGIN OPEN MW: MessageWindow; CKViewer: TYPE = CKViewerButtons.CKViewer; CKViewerState: TYPE = CKViewerButtons.CKViewerState; sym: BOOLEAN _ FALSE; bbspace: PrincOps.BBTableSpace; bb: PrincOps.BBptr _ InitBB[@bbspace]; grayword: CARDINAL _ 0; bitmapB: LONG POINTER _ NIL; lbpp,lbppB: CARDINAL _ 0; -- log (base 2) bits per pixel bpp,bppB: CARDINAL _ 0; -- bits per pixel full: BOOLEAN _ FALSE; ashow,bshow: BOOLEAN _ TRUE; splat: BOOLEAN _ TRUE; cornerSize: CARDINAL _ 4; cornerColor: CARDINAL _ 8; Triple: TYPE = RECORD[r,g,b: [0..256)]; testmap: ARRAY[0..8] OF Triple _ [ [127,127,127], -- gray (background) [ 0, 0, 0], -- black [255, 0, 0], -- red [ 0,255, 0], -- green [255,255, 0], -- yellow [ 0, 0,255], -- blue [255, 0,255], -- magenta [ 0,255,255], -- cyan [255,255,255] -- white ]; Diag: PROC [] = { Bham: PROC [fx,fy,lx,ly: INTEGER, color: [0..8]] = { yt: REAL; xx, xi: INTEGER; yy, yi: INTEGER; dx: INTEGER _ lx-fx; dy: INTEGER _ ly-fy; IF dy>dx OR dx<=0 OR dy<=0 THEN ERROR; FOR xi IN [0..dx) DO yt _ (Real.Float[dy]/Real.Float[dx])*Real.Float[xi]; yi _ Real.FixI[yt+0.5]; xx_fx+xi; yy_fy+yi; TestRect[xx,yy,1,1,color]; TestRect[iWidth-xx,yy,1,1,color]; TestRect[xx,iHeight-yy,1,1,color]; TestRect[iWidth-xx,iHeight-yy,1,1,color]; ENDLOOP; }; black: [0..8] = 1; --testmap[1] is black white: [0..8] = 8; --testmap[8] is white iWidth: INTEGER _ Interminal.terminal.colorWidth; iHeight: INTEGER _ Interminal.terminal.colorHeight; deltaX: INTEGER _ iWidth/40; deltaY: INTEGER _ (deltaX*iHeight)/iWidth; xi: INTEGER _ 0; yi: INTEGER _ 0; IF full THEN Positive[] ELSE { FOR i: CARDINAL IN[0..9) DO Terminal.SetColor[vt: Interminal.terminal, aChannelValue: i, red: testmap[i].r, green: testmap[i].g, blue: testmap[i].b]; ENDLOOP; SetShowButtons[TRUE,FALSE,FALSE]; }; TestRect[0,0,Interminal.terminal.colorWidth,Interminal.terminal.colorHeight,black]; --black background FOR n: INTEGER _ 0, n+1 UNTIL xi >=iWidth DO Bham[fx: xi, fy: 0, lx: iWidth-1, ly: iHeight-n*deltaY, color: white]; xi_xi+deltaX; ENDLOOP; }; ShowTPat: PROC = { x: CARDINAL = 60; h: CARDINAL = 60; w: CARDINAL = 50; gap: CARDINAL = 15; IF full THEN Positive[] ELSE { FOR i: CARDINAL IN[0..9) DO Terminal.SetColor[vt: Interminal.terminal, aChannelValue: i, red: testmap[i].r, green: testmap[i].g, blue: testmap[i].b]; ENDLOOP; SetShowButtons[TRUE,FALSE,FALSE]; }; TestRect[0,0,Interminal.terminal.colorWidth,Interminal.terminal.colorHeight,0]; { s: CARDINAL = cornerSize; c: CARDINAL = cornerColor; -- color TestRect[0,0,s,s,c]; TestRect[Interminal.terminal.colorWidth-s,0,s,s,c]; TestRect[0,Interminal.terminal.colorHeight-s,s,s,c]; TestRect[Interminal.terminal.colorWidth-s,Interminal.terminal.colorHeight-s,s,s,c]; }; FOR i: CARDINAL IN[0..8) DO r,g,b: [0..256); r _ (i MOD 2)*255; g _ ((i/2) MOD 2)*255; b _ ((i/4) MOD 2)*255; TestRect[4,i*h+10,x,h-20,i+1]; ENDLOOP; FOR i: CARDINAL IN[0..8) DO r,g,b: [0..256); r _ (i MOD 2)*255; g _ ((i/2) MOD 2)*255; b _ ((i/4) MOD 2)*255; TestRect[x+i*w+gap,0,w-gap,8*h,i+1]; ENDLOOP; }; TestRect: PROC[x,y,w,h: CARDINAL, i: [0..8]] = { IF NOT (x Interminal.terminal.colorWidth DO TestRect[xx, 0, vThick, Interminal.terminal.colorHeight, white]; ENDLOOP; FOR v: CARDINAL _ 0, v+vStep UNTIL v > Interminal.terminal.colorHeight DO TestRect[0, v, Interminal.terminal.colorWidth, hThick ,white]; ENDLOOP; }; ShowBig: PROCEDURE [big: BOOLEAN, color: GraphicsColor.Color] = { r,g,b: CARDINAL; rectheight: CARDINAL _ Interminal.terminal.colorHeight/16; --sixteen rectangles cInc: CARDINAL _ IF big THEN 20B ELSE 1; maxIntensity: CARDINAL _ IF full THEN 400B ELSE (Basics.BITSHIFT[1,bpp]); groupSize: CARDINAL _ MAX[16/maxIntensity,1]; groupIndex: CARDINAL _ 16/groupSize; IF NOT full THEN SetShowButtons[TRUE,FALSE,FALSE] ELSE SetShowButtons[TRUE,TRUE,TRUE]; FOR gI: CARDINAL IN [0..groupIndex) DO inten: CARDINAL _ gI*cInc; SELECT color FROM GraphicsColor.red => {r_inten; b_g_0}; GraphicsColor.green => {g_inten; b_r_0}; GraphicsColor.blue => {b_inten; r_g_0}; ENDCASE => ERROR; IF full THEN { OPEN Terminal; SetRedMap[Interminal.terminal, gI,r]; SetGreenMap[Interminal.terminal, gI,g]; SetBlueMap[Interminal.terminal, gI,b];} ELSE Terminal.SetColor[vt: Interminal.terminal, aChannelValue: gI, red: r, green: g, blue: b]; FOR x: CARDINAL IN [0..groupSize) DO nextRect: CARDINAL _ gI*groupSize + x; Rect[0,nextRect*rectheight,Interminal.terminal.colorWidth,rectheight, gI]; ENDLOOP; ENDLOOP; }; ShowBigRed: PROCEDURE [big: BOOLEAN] = { ShowBig[big, GraphicsColor.red]; }; ShowBigGreen: PROCEDURE [big: BOOLEAN] = { ShowBig[big, GraphicsColor.green]; }; ShowBigBlue: PROCEDURE [big: BOOLEAN] = { ShowBig[big, GraphicsColor.blue]; }; ShowCBars: PROCEDURE = { graywidth: CARDINAL _ Interminal.terminal.colorWidth/128; --this must integer divide evenly grayheight: CARDINAL _ Interminal.terminal.colorHeight/2; --this must integer divide evenly cbarwidth: CARDINAL _ (Interminal.terminal.colorWidth)/9; --this may truncate cbarheight: CARDINAL _ Interminal.terminal.colorHeight/2; --this must integer divide evenly IF full THEN HalfPositive[] ELSE { --set up gray map k: CARDINAL _ (Basics.BITSHIFT[1,bpp])/2; -- half the number of pixel values FOR n: CARDINAL IN [0..k) DO Terminal.SetColor[vt: Interminal.terminal, aChannelValue: n+200B, red: n*2, green: n*2, blue: n*2]; --use top half of colormap. Only makes sense for 8 BPP ENDLOOP; }; FOR i: CARDINAL IN[0..9) DO --set up color bars IF full THEN {Terminal.SetRedMap[Interminal.terminal, i,testmap[i].r]; Terminal.SetGreenMap[Interminal.terminal, i,testmap[i].g]; Terminal.SetBlueMap[Interminal.terminal, i,testmap[i].b];} ELSE Terminal.SetColor[vt: Interminal.terminal, aChannelValue: i, red: testmap[i].r, green: testmap[i].g, blue: testmap[i].b] ENDLOOP; FOR x: CARDINAL IN [0..128) DO --gray wedge Rect[x*graywidth, 0, graywidth, grayheight, x+128]; ENDLOOP; FOR x: CARDINAL IN [0..8] DO --colorbars Rect[x*cbarwidth, cbarheight, cbarwidth, cbarheight, x]; ENDLOOP; SetShowButtons[TRUE,full,full]; }; NextRoll: PROCEDURE [] = { OPEN Terminal; r,g,b,r0,g0,b0: [0..256); IF full THEN { r0_GetRedMap[Interminal.terminal, 0]; g0_GetGreenMap[Interminal.terminal, 0]; b0_GetBlueMap[Interminal.terminal, 0]; FOR i: CARDINAL IN[0..255) DO r _ GetRedMap[Interminal.terminal, i+1]; g _ GetGreenMap[Interminal.terminal, i+1]; b _ GetBlueMap[Interminal.terminal, i+1]; SetRedMap[Interminal.terminal, i,r]; SetGreenMap[Interminal.terminal, i,g]; SetBlueMap[Interminal.terminal, i,b]; ENDLOOP; SetRedMap[Interminal.terminal, 255,r0]; SetGreenMap[Interminal.terminal, 255,g0]; SetBlueMap[Interminal.terminal, 255,b0]; } ELSE { [r0,g0,b0] _ Terminal.GetColor[vt: Interminal.terminal, aChannelValue: 0]; FOR i: CARDINAL IN[0..255) DO [r,g,b] _ Terminal.GetColor[vt: Interminal.terminal, aChannelValue: i+1]; Terminal.SetColor[Interminal.terminal,i,0,r,g,b]; ENDLOOP; Terminal.SetColor[Interminal.terminal,255,0,r0,g0,b0]; }; Wait[100]; }; NextScramble: PROCEDURE [] = { SetUpColors[]; Wait[200]; }; background: INTEGER _ 0; -- initially black ClearScreen: PROCEDURE = { IF NOT full THEN { Terminal.SetColor[Interminal.terminal, 0, 0, background, background, background]; SetGray[0] } ELSE {Terminal.SetGreenMap[Interminal.terminal, 0,0]; Terminal.SetBlueMap[Interminal.terminal, 0,0]; Terminal.SetRedMap[Interminal.terminal, 0,0];}; Rectangle[lx: 0, ty: 0, rx: Interminal.terminal.colorWidth, by: Interminal.terminal.colorHeight, fn: null, clear: TRUE]; }; Wait: PROCEDURE[millisecs: CARDINAL] = INLINE { Process.Pause[Process.MsecToTicks[millisecs]] }; defaultSeed: CARDINAL = 27183; numCalls: INTEGER = 3; a: ARRAY [0..55] OF CARDINAL; p: INTEGER [0..55]; InitRandom: PUBLIC PROC[seed: INTEGER] RETURNS[INTEGER] = { minSeed: CARDINAL = LAST[CARDINAL]/10; g, gPrev, gSave: CARDINAL; IF seed<=0 THEN seed _ defaultSeed; WHILE seed max THEN ERROR; intervalLen _ max - min + 1; --is 0 when min=0, max=LAST[CARDINAL] IF intervalLen = 0 THEN RETURN[Random[]]; DO r, rem: CARDINAL; p _ p-1; IF p=0 THEN { RandomGen[]; p _ 55 }; r _ a[p]; rem _ r MOD intervalLen; IF (r - rem) > LOOPHOLE[-LOOPHOLE[intervalLen,INTEGER],CARDINAL] THEN LOOP; RETURN[min + rem]; ENDLOOP; };--Choose SetLogBitsPerPixel: PROC[n: [0..4)] RETURNS[BOOLEAN] = { b: CARDINAL _ Basics.BITSHIFT[1,n]; mode: Terminal.ColorMode _ [FALSE,b,1]; IF NOT Terminal.LegalColorMode[Interminal.terminal, mode] THEN { mode.bitsPerPixelChannelB _ 0; IF NOT Terminal.LegalColorMode[Interminal.terminal, mode] THEN RETURN[FALSE]; }; []_Terminal.SetColorMode[Interminal.terminal, mode]; Terminal.TurnOnColorDisplay[Interminal.terminal]; lbpp _ n; bpp _ b; full _ FALSE; lbppB _ 0; bppB _ 1; SetShowButtons[TRUE, TRUE, FALSE]; bitmapB _ Interminal.terminal.colorBitmapB; ClearScreen[]; SetUpColors[]; RETURN[TRUE]; }; Set24BitsPerPixel: PROC = { mode: Terminal.ColorMode _ [TRUE,0,0]; IF NOT Terminal.LegalColorMode[Interminal.terminal, mode] THEN RETURN; Process.SetPriority[Process.priorityNormal]; []_Terminal.SetColorMode[Interminal.terminal, mode]; Terminal.TurnOnColorDisplay[Interminal.terminal]; lbpp _ 0; bpp _ 0; full _ TRUE; SetShowButtons[TRUE, TRUE, FALSE]; bitmapB _ NIL; ClearScreen[]; SetUpColors[]; Process.SetPriority[Process.priorityBackground]; }; Go: PUBLIC PROC [ckViewer: CKViewer] = { [] _ InitRandom[0]; public _ ckViewer; Terminal.TurnOnColorDisplay[Interminal.terminal]; Terminal.TurnOffColorDisplay[Interminal.terminal]; SELECT TRUE FROM SetLogBitsPerPixel[3] => NULL; SetLogBitsPerPixel[2] => NULL; ENDCASE => { MW.Append[message: "NO COLOR DISPLAY !!", clearFirst: TRUE]; MW.Blink[]; RETURN; }; Process.SetPriority[Process.priorityBackground]; DO IF ckViewer.state.quit THEN { ClearScreen; ViewerOps.DestroyViewer[ckViewer.container]; []_Terminal.SetColorBitmapState[vt: Interminal.terminal, newState: none, newMode: Terminal.GetColorMode[Interminal.terminal], newVisibility: none]; EXIT; }; IF ckViewer.state.testingPanel THEN LOOP; --turned off by FinalizeTest IF ckViewer.state.bpp=1 AND bpp#1 THEN { [] _ SetLogBitsPerPixel[0]; SetSplat[] }; IF ckViewer.state.bpp=2 AND bpp#2 THEN { [] _ SetLogBitsPerPixel[1]; SetSplat[] }; IF ckViewer.state.bpp=4 AND bpp#4 THEN { [] _ SetLogBitsPerPixel[2]; SetSplat[] }; IF ckViewer.state.bpp=8 AND bpp#8 THEN { [] _ SetLogBitsPerPixel[3]; SetSplat[] }; IF ckViewer.state.bpp=24 AND NOT full THEN { Set24BitsPerPixel[]; SetSplat[] }; IF ckViewer.state.aToggle THEN { SetShowButtons[NOT ashow, bshow,FALSE]; ckViewer.state.aToggle _ FALSE}; IF ckViewer.state.bToggle THEN { SetShowButtons[ashow, NOT bshow,FALSE]; ckViewer.state.bToggle _ FALSE}; IF ckViewer.state.random THEN { sym _ FALSE; SetSplat[]; ClearScreen[]; ckViewer.state.random _ FALSE}; IF ckViewer.state.symmetric THEN { sym _ TRUE; SetSplat[]; ClearScreen[]; ckViewer.state.symmetric _ FALSE}; IF NOT ckViewer.state.freeze THEN { ckViewer.state.roll _ ckViewer.state.scramble _ FALSE; --only TRUE when frozen SELECT TRUE FROM ckViewer.state.testPattern => { splat _ FALSE; ShowTPat[]; ckViewer.state.testPattern _ FALSE; }; ckViewer.state.cbars => {ShowCBars[]; splat _ ckViewer.state.cbars _ FALSE}; ckViewer.state.converge => {ShowConverge[]; splat _ ckViewer.state.converge _ FALSE}; ckViewer.state.diag => {Diag[]; splat _ ckViewer.state.diag _ FALSE}; ckViewer.state.bigRed => {ShowBigRed[big: TRUE]; splat _ ckViewer.state.bigRed _ FALSE}; ckViewer.state.bigGreen => {ShowBigGreen[big: TRUE]; splat _ ckViewer.state.bigGreen _ FALSE}; ckViewer.state.bigBlue => {ShowBigBlue[big: TRUE]; splat _ ckViewer.state.bigBlue _ FALSE}; ckViewer.state.smallRed => {ShowBigRed[big: FALSE]; splat _ ckViewer.state.smallRed _ FALSE}; ckViewer.state.smallGreen => {ShowBigGreen[big: FALSE]; splat _ ckViewer.state.smallGreen _ FALSE}; ckViewer.state.smallBlue => {ShowBigBlue[big: FALSE]; splat _ ckViewer.state.smallBlue _ FALSE}; ENDCASE => IF splat THEN RandomSplat[ckViewer]; } ELSE { SELECT TRUE FROM ckViewer.state.scramble => NextScramble[]; ckViewer.state.roll => NextRoll[]; ENDCASE => NULL; }; ENDLOOP; }; SetSplat: PROCEDURE [] = { splat _ TRUE; SetShowButtons[ashow,bshow,FALSE]; CKViewerButtons.SetStaticButtons[public, IF sym THEN public.buttons.symmetricButton ELSE public.buttons.randomButton] }; SetShowButtons: PROCEDURE [a, b, c: BOOL] = { vis: Terminal.ChannelsVisible; ashow_a; bshow_b; vis _ SELECT TRUE FROM a AND b => all, a AND NOT b => aOnly, NOT a AND b => bOnly, NOT a AND NOT b => none, ENDCASE => ERROR; Terminal.SetVisibility[vt: Interminal.terminal, visibility: vis]; Buttons.SetDisplayStyle[public.buttons.aChanButtton, IF ashow THEN $WhiteOnBlack ELSE $BlackOnWhite]; Buttons.SetDisplayStyle[public.buttons.bChanButton, IF bshow THEN $WhiteOnBlack ELSE $BlackOnWhite]; }; SetUpPanelTest: PUBLIC PROCEDURE [ckViewer: CKViewer] = { ckViewer.state.testingPanel _ TRUE; Wait[2000]; --stupid synchronizer so main loop in Go will quit messing with screen ClearScreen []; --FILL FIFOS WITH Zeroes Terminal.SetVisibility[vt: Interminal.terminal, visibility: all]; --so when ChannelOn glitches nothing bad will happen Wait[36]; --be sure both a and b actually show SetShowButtons[ashow,bshow,TRUE]; --restore ashow/bshow }; public: CKViewer_NIL; END. ÚCKViewerOps.mesa Last edited by Ken Pier, February 16, 1984 2:05:54 pm PST draw a set of diagonal lines draw a line from (fx,fy) to (lx,ly) gray background four corners various colors at left edge a bunch of stripes bitmap A bitmap B Constant definitions (meanings described in InitRandom below) Module state Holds 55 random cardinals, to be returned by Random. (A[0] is wasted to make the code generator produce better array accesses.) a[1..p-1] has not yet been returned by Random; p is [1..55] except within Random. Procedures The parameter seed determines the sequence generated by procedure Random below. If seed=0, a default seed value is used to determine the starting point of the sequence; if seed>0, seed is scaled if necessary and then used; if seed<0, a seed value is derived from the system clock. In any case, the seed value actually used (after scaling) is the integer value returned. Now scale the seed into the proper range (no log routine available...) Seed can't be too big since LAST[INTEGER] < LAST[CARDINAL]*(9/10) The array a is initialized by placing seed in a[55], and scattering the values (-1)**(i-1) * (F(i) - seed*F(i-1)) MOD maxRand, 0˜>Jšœ˜—J˜—J˜šŸœ œœ!˜AJšœœ˜Jšœ œ'ž˜OJš œœœœœ˜(Jš œœœœœ œ ˜IJšœ œœ˜-Jšœ œ˜$Jšœœœœœœœœœœ˜VJ˜šœœœ˜'Jšœœ ˜šœ˜Jšœ&˜&Jšœ(˜(Jšœ'˜'Jšœœ˜—šœœ˜Jšœ€˜„—JšœZ˜^šœœœ˜%Jšœ œ˜&JšœJ˜J—Jšœ˜—Jšœ˜J˜—J˜J˜šŸ œ œœ˜(Jšœ ˜ Jšœ˜—J˜šŸ œ œœ˜*Jšœ"˜"Jšœ˜—J˜šŸ œ œœ˜)Jšœ!˜!Jšœ˜—J˜J˜šŸ œ œ˜Jšœ œ'ž!˜[Jšœ œ%ž"˜[Jšœ œ'ž˜MJšœ œ&ž!˜[J˜šœœœž˜4Jšœœ œ ž"˜Lšœœœ˜Jšœdž7˜›Jšœ˜—J˜—š œœœœž˜/Jšœœ°˜¼Jšœy˜}Jšœ˜—š œœœ œž ˜,J˜3Jšœ˜—š œœœœž ˜)Jšœ8˜8Jšœ˜—Jšœœ ˜Jšœ˜—J˜šŸœ œ˜Jšœ ˜J˜šœœ˜Jšœt˜tšœœœ ˜Jšœ~˜~Jšœr˜rJšœ˜—Jšœ{˜{J˜—šœ˜JšœJ˜Jšœœœ ˜JšœI˜IJšœ1˜1Jšœ˜—Jšœ6˜6J˜—J˜ Jšœ˜—J˜šŸ œ œ˜J˜Jšœ˜—J˜Jšœ œž˜+J˜šŸ œ œ˜šœœœ˜JšœQ˜QJ˜ —Jšœ˜”Jšœrœ˜xJ˜J˜—šŸœ œ œœ˜/J˜0J˜Jšœ=™=J˜Jšœ œ ˜Jšœ œ˜J˜J˜Jšœ ™ J˜šœœ œœ˜JšœP™PJšœ.™.—šœœ ˜JšœQ™QJ˜J˜—Jšœ ™ J˜š Ÿ œœœœœœ˜;JšœO™OJšœN™NJšœR™RJšœR™RJšœ.™.J˜Jšœ œœœ˜&Jšœœ˜J˜Jšœ œ˜#JšœF™FJšœœœ˜,JšœA™AJšœN™NJ˜Jšœ7™7J˜JšœN™NJšœL™LJšœ™J˜J˜J˜šœœœ ˜Jšœ œ˜J˜/—Jšœ˜šœ˜J˜ —Jšœ˜JšœH™HJ˜Jšœ˜ —Jšœž ˜J˜J˜š Ÿœœœœœœ˜0J˜Jšœœ˜'Jšœ˜ —Jšœž˜ J˜J˜šŸ œœœ˜JšœO™OJšœQ™QJšœ?™?šœœœ œ˜J˜—Jšœ˜šœœœ œ˜J˜—Jšœ˜—Jšœž ˜ J˜J˜š Ÿœœœ œœžœ˜KJšœ œ˜Jšœ œœ˜Jšœž%˜BJšœœœ ˜)š˜JšœV™VJšœU™UJšœZ™ZJšœ;™;Jšœœ˜Jšœ™J˜Jšœœ˜'J˜ Jšœœ ˜Jšœ œœ œœœœ˜KJšœ ˜—Jšœ˜—Jšœž˜ J˜—šŸœœ œœ˜8Jšœœ œ˜#Jšœœ˜'šœœ4œ˜@Jšœ˜Jš œœ4œœœ˜MJ˜—Jšœ4˜4Jšœ1˜1Jšœœ˜ J˜Jšœœœœ˜"Jšœ+˜+J˜J˜J˜Jšœœ˜ J˜J˜—šŸœœ˜Jšœœ˜&Jšœœ4œœ˜FJšœ,˜,Jšœ4˜4Jšœ1˜1Jšœœ˜Jšœœœœ˜"Jšœ œ˜Jšœ˜J˜Jšœ0˜0J˜J˜—šŸœœœ˜(Jšœ˜Jšœ˜J˜1J˜2šœœ˜Jšœœ˜Jšœœ˜šœ˜ Jšœ4œ˜Jšœ˜—JšœEœ˜LJšœNœ˜UJšœ>œ˜EJšœ*œ#œ˜XJšœ.œ%œ˜^Jšœ,œ$œ˜[Jšœ,œ%œ˜]Jšœ0œ'œ˜cJšœ.œ&œ˜`Jšœœœ˜/—Jšœ˜—šœ˜šœœ˜Jšœ*˜*Jšœ"˜"Jšœœ˜—˜J˜——Jšœ˜˜J˜——šŸœ œ˜Jšœœœ˜0Jšœ)œœ œ˜uJ˜—J˜šŸœ œ œ˜-Jšœ˜Jšœ˜šœœœ˜Jšœœ ˜Jšœœœ ˜Jšœœ ˜Jšœœœ ˜Jšœœ˜J˜—JšœA˜AJšœ5œœœ˜eJšœ4œœœ˜dJ˜—J˜šŸœœ œ˜:Jšœœ˜#Jšœ žF˜RJšœž˜(JšœBž4˜vJšœ ž$˜.Jšœœž˜7Jšœ˜—J˜Jšœœ˜J˜Jšœ˜J˜—…—Q&rT