-- TJaMGraphicsImpl.mesa -- Last changed by Bill Paxton, March 12, 1982 8:19 am -- Last changed by Maureen Stone January 31, 1984 2:14:15 pm PST -- Last changed by McGregor, September 13, 1982 1:44 pm -- Last changed by Doug Wyatt, September 16, 1982 12:14 am DIRECTORY Graphics, GraphicsOps, GL USING [ Start, End, Draw], GraphicsBasic USING [Vec], CGVector USING [Sub, Cross], Rope USING [ROPE, Equal, Fetch, FromChar], Spline USING [Ref, Knot, Enter], ViewerOps USING[PaintViewer], ViewerClasses USING [Viewer], JaM USING [State, PopInt, PushInt, PushReal, PopReal, PopRope, PushBool, PopBool, Register], TJaMGraphics, TJaMGraphicsContexts, TJaMGraphicsInfo; TJaMGraphicsImpl: CEDAR MONITOR IMPORTS JaM, TJaMGraphics, TJaMGraphicsInfo, Graphics, GraphicsOps, CGVector, Rope, Spline, ViewerOps, GL, TJaMGraphicsContexts EXPORTS TJaMGraphics, TJaMGraphicsInfo = { OPEN J: JaM, G: Graphics, E: GraphicsOps, Vector: CGVector, TJaMGraphics, TJaMGraphicsInfo, TDC: TJaMGraphicsContexts; Vec: TYPE = GraphicsBasic.Vec; GProc: TYPE = TDC.GProc; ROPE: TYPE = Rope.ROPE; Paint: PUBLIC ENTRY SAFE PROCEDURE [self: ViewerClasses.Viewer, context: G.Context, whatChanged: REF ANY, clear: BOOL] = TRUSTED { ENABLE UNWIND => NULL; info: Info _ NARROW[self.data]; IF whatChanged=NIL THEN { -- reestablish context and erase G.SetCP[context, 0, 0]; info.vinitdc _ G.CopyContext[context]; info.vdc _G.CopyContext[info.vinitdc]; IF ~clear THEN { -- cannot simply call JErase because of monitor deadlock mark: G.Mark _ G.Save[info.vdc]; G.SetColor[info.vdc, G.white]; G.DrawBox[info.vdc,G.GetBounds[info.vdc]]; G.Restore[info.vdc,mark] }; IF info.drawGL THEN { gl: TDC.DCList _ NIL; FOR l: TDC.DCList _ info.dcList, l.next UNTIL l=NIL DO IF l.name=$GList THEN gl _ l; ENDLOOP; info.gl _ GL.End[gl.dc]; IF info.gl#NIL THEN GL.Draw[info.vdc,info.gl]; gl.dc _ GL.Start[info.gl]; }; RETURN }; info.proc[info]; }; Painter: PUBLIC PROCEDURE[proc: PROC [Graphics.Context], frame: J.State] = { info: Info; CallBack: PROC [info: Info] = { proc[info.vdc] }; info _ GetInfo[frame]; TDC.ForAllDCs[info.dcList,proc]; IF info.venabled THEN TRUSTED { info.proc _ CallBack; ViewerOps.PaintViewer[viewer: info.viewer, hint: client, whatChanged: info, clearClient: FALSE]; }; }; PushDC: PROCEDURE [frame: JaM.State] = { pushdc: GProc = {[] _ G.Save[dc]}; Painter[pushdc,frame]; }; PopDC: PROCEDURE [frame: J.State] = { popdc: GProc = {[] _ G.Restore[dc]}; Painter[popdc, frame]; }; GetVec: PROCEDURE [frame: J.State] RETURNS[Vec] = { y: REAL _ J.PopReal[frame]; x: REAL _ J.PopReal[frame]; RETURN[[x,y]] }; GetPoint: PROCEDURE [frame: J.State] RETURNS[x,y: REAL] = { y _ J.PopReal[frame]; x _ J.PopReal[frame]; RETURN[x,y] }; PutPoint: PROCEDURE[frame: J.State, x,y: REAL] = { J.PushReal[frame,x]; J.PushReal[frame,y] }; Rect: TYPE = RECORD[xmin,ymin,xmax,ymax: REAL]; GetRect: PROCEDURE [frame: J.State] RETURNS[r: Rect] = { [r.xmax,r.ymax] _ GetPoint[frame]; [r.xmin,r.ymin] _ GetPoint[frame]; RETURN[r]; }; PutRect: PROCEDURE[frame: J.State, r: Rect] = { PutPoint[frame,r.xmin,r.ymin]; PutPoint[frame,r.xmax,r.ymax]; }; JSetVw: PROCEDURE [frame: J.State] = { rt: Rect _ GetRect[frame]; rf: Rect _ GetRect[frame]; -- *** fix this -- SetView[dc,@rf,@rt]; }; JClipArea: PROCEDURE [frame: J.State] = { info: Info _ GetInfo[frame]; paint: GProc ={G.ClipArea[self: dc, path: info.path]}; Painter[paint,frame]; }; JClipEOArea: PROCEDURE [frame: J.State] = { info: Info _ GetInfo[frame]; paint: GProc ={G.ClipArea[self: dc, path: info.path, parityFill: TRUE]}; Painter[paint,frame]; }; JClipXArea: PROCEDURE [frame: J.State] = { info: Info _ GetInfo[frame]; paint: GProc ={G.ClipArea[self: dc, path: info.path, exclude: TRUE]}; Painter[paint,frame]; }; JClipBox: PROCEDURE [frame: J.State] = { paint: GProc ={G.ClipBox[dc, box]}; box: G.Box _ GetBox[frame]; Painter[paint,frame]; }; JClipXBox: PROCEDURE [frame: J.State] = { paint: GProc ={G.ClipBox[dc,box,TRUE]}; box: G.Box _ GetBox[frame]; Painter[paint,frame]; }; JTranslate: PROCEDURE [frame: J.State] = { paint: GProc ={G.Translate[dc,tx,ty]}; tx,ty: REAL; [tx,ty]_GetPoint[frame]; Painter[paint,frame]; }; JScale: PROCEDURE [frame: J.State] = { paint: GProc ={ G.Scale[dc,sx,sy]}; sx,sy: REAL; [sx,sy]_GetPoint[frame]; Painter[paint,frame]; }; JRotate: PROCEDURE [frame: J.State] = { paint: GProc ={G.Rotate[dc,a]}; a: REAL _ J.PopReal[frame]; Painter[paint,frame]; }; JSixPoint: PROCEDURE [frame: J.State] = { paint: GProc ={ G.Translate[dc,t1.x,t1.y]; G.Concat[dc,m11,m12,m21,m22]; G.Translate[dc,-f1.x,-f1.y]; }; f1,f2,f3,t1,t2,t3,df1,df2,dt1,dt2: Vec; adet: REAL; m11,m12,m21,m22: REAL; t3_GetVec[frame]; t2_GetVec[frame]; t1_GetVec[frame]; f3_GetVec[frame]; f2_GetVec[frame]; f1_GetVec[frame]; dt1_Vector.Sub[t2,t1]; df1_Vector.Sub[f2,f1]; dt2_Vector.Sub[t3,t1]; df2_Vector.Sub[f3,f1]; adet_1.0/Vector.Cross[df1,df2]; m11_(dt1.x*df2.y-dt2.x*df1.y)*adet; m12_(dt1.y*df2.y-dt2.y*df1.y)*adet; m21_(df1.x*dt2.x-df2.x*dt1.x)*adet; m22_(df1.x*dt2.y-df2.x*dt1.y)*adet; Painter[paint,frame]; }; JConcat: PROCEDURE [frame: J.State] = { paint: GProc ={G.Concat[dc,m11,m12,m21,m22]}; m11,m12,m21,m22: REAL; m22 _ J.PopReal[frame]; m21 _ J.PopReal[frame]; m12 _ J.PopReal[frame]; m11 _ J.PopReal[frame]; Painter[paint,frame]; }; --note multiple display context behavior JGetPos: PROCEDURE [frame: J.State] = { paint: GProc ={[x,y]_G.GetCP[dc]}; x,y: REAL; Painter[paint,frame]; PutPoint[frame,x,y]; }; JSetPos: PROCEDURE [frame: J.State] = { paint: GProc ={G.SetCP[dc,x,y]}; x,y: REAL; [x,y] _ GetPoint[frame]; Painter[paint,frame]; }; JRelSetPos: PROCEDURE [frame: J.State] = { paint: GProc ={ G.SetCP[dc,x,y,TRUE]}; x,y: REAL; [x,y]_GetPoint[frame]; Painter[paint,frame]; }; JDrawTo: PROCEDURE [frame: J.State] = { paint: GProc ={G.DrawTo[dc,x,y]}; x,y: REAL; [x,y]_GetPoint[frame]; Painter[paint,frame]; }; JRelDrawTo: PROCEDURE [frame: J.State] = { paint: GProc ={G.DrawTo[dc,x,y,TRUE]}; x,y: REAL; [x,y]_GetPoint[frame]; Painter[paint,frame]; }; JDrawBox: PROCEDURE [frame: J.State] = { paint: GProc ={G.DrawBox[dc,box]}; box: G.Box _ GetBox[frame]; Painter[paint,frame]; }; JCover: PROCEDURE [frame: J.State] = { paint: GProc ={G.DrawBox[dc,G.GetBounds[dc]]}; Painter[paint,frame]; }; JSetInvert: PROCEDURE [frame: J.State] = { paint: GProc ={[] _ G.SetPaintMode[dc, invert]}; Painter[paint,frame]; }; JSetFat: PROCEDURE [frame: J.State] = { paint: GProc ={[] _ G.SetFat[dc,b]}; b: BOOLEAN _ J.PopBool[frame]; Painter[paint,frame]; }; JSetOpaque: PROCEDURE [frame: J.State] = { paint: GProc ={[] _ G.SetPaintMode[dc,IF b THEN opaque ELSE transparent]}; b: BOOLEAN _ J.PopBool[frame]; Painter[paint,frame]; }; JGetTouch: PROCEDURE [frame: J.State] = { mx,my: REAL; [mx,my] _ RealViewerMouse[frame,TRUE]; PutPoint[frame,mx,my]; }; JGetMouse: PROCEDURE [frame: J.State] = { mx,my: REAL; [mx,my] _ RealViewerMouse[frame,FALSE]; PutPoint[frame,mx,my]; }; JSetFont: PROCEDURE [frame: J.State] = { info: Info _ GetInfo[frame]; info.text _ J.PopRope[frame]; FOR f: FontCache _ fontCache, f.next UNTIL f = NIL DO IF info.text.Equal[f.fontName, FALSE] THEN { info.font _ f.fontRef; RETURN; }; ENDLOOP; info.font _ G.MakeFont[info.text]; fontCache _ NEW[FontCacheRec _ [fontCache, info.text, info.font]]; }; FontCache: TYPE = REF FontCacheRec; FontCacheRec: TYPE = RECORD [ next: FontCache, fontName: Rope.ROPE, fontRef: GraphicsOps.FontRef]; fontCache: FontCache _ NIL; JGetYMode: PROCEDURE [frame: J.State] = { paint: GProc ={mode _ E.GetYMode[dc]}; mode: E.YMode; Painter[paint,frame]; J.PushInt[frame, IF mode=topDown THEN 1 ELSE 0]; }; JSetYMode: PROCEDURE [frame: J.State] = { mode: LONG INTEGER _ J.PopInt[frame]; paint: GProc ={E.SetYMode[dc,IF mode>0 THEN topDown ELSE bottomUp]}; Painter[paint,frame]; }; JDrawChar: PROCEDURE [frame: J.State] = { paint: GProc ={G.DrawChar[self: dc, char: Rope.Fetch[info.text], font: info.font]}; info: Info _ GetInfo[frame]; info.text _ J.PopRope[frame]; Painter[paint,frame]; }; JDrawText: PROCEDURE [frame: J.State] = { paint: GProc ={G.DrawRope[self: dc, rope: info.text, font: info.font]}; info: Info _ GetInfo[frame]; info.text _ J.PopRope[frame]; Painter[paint,frame]; }; JCharBox: PROCEDURE [frame: J.State] = { info: Info _ GetInfo[frame]; info.text _ J.PopRope[frame]; info.text _ Rope.FromChar[Rope.Fetch[info.text]]; PushTextBox[frame,info.text]; }; JTextBox: PROCEDURE [frame: J.State] = { info: Info _ GetInfo[frame]; info.text _ J.PopRope[frame]; PushTextBox[frame,info.text]; }; JCharWidth: PROCEDURE [frame: J.State] = { info: Info _ GetInfo[frame]; info.text _ J.PopRope[frame]; info.text _ Rope.FromChar[Rope.Fetch[info.text]]; PushTextWidth[frame,info.text]; }; JTextWidth: PROCEDURE [frame: J.State] = { info: Info _ GetInfo[frame]; info.text _ J.PopRope[frame]; PushTextWidth[frame,info.text]; }; PushTextBox: PROCEDURE[frame: J.State, text: ROPE] = { info: Info _ GetInfo[frame]; xmin,xmax,ymin,ymax: REAL; [xmin: xmin, ymin: ymin, xmax: xmax, ymax: ymax] _ G.RopeBox[info.font,info.text]; J.PushReal[frame,xmin]; J.PushReal[frame,ymin]; J.PushReal[frame,xmax]; J.PushReal[frame,ymax]; }; PushTextWidth: PROCEDURE[frame: J.State, text: ROPE] = { info: Info _ GetInfo[frame]; xw,yw: REAL; [xw: xw, yw: yw] _ G.RopeWidth[info.font,info.text]; J.PushReal[frame,xw]; J.PushReal[frame,yw]; }; JFontBox: PROCEDURE [frame: J.State] = { info: Info _ GetInfo[frame]; xmin,xmax,ymin,ymax: REAL; [xmin: xmin, ymin: ymin, xmax: xmax, ymax: ymax] _ G.FontBox[info.font]; J.PushReal[frame,xmin]; J.PushReal[frame,ymin]; J.PushReal[frame,xmax]; J.PushReal[frame,ymax]; }; PutBox: PROC[frame: J.State, b: G.Box] = { PutPoint[frame,b.xmin,b.ymin]; PutPoint[frame,b.xmax,b.ymax]; }; GetBox: PROC [frame: J.State] RETURNS[G.Box] = { b: G.Box; [b.xmax,b.ymax] _ GetPoint[frame]; [b.xmin,b.ymin] _ GetPoint[frame]; RETURN[b]; }; JStartBoxing: PROCEDURE [frame: J.State] = { -- info: Info _ GetInfo[frame]; -- E.BeginBox[dc]; }; JStopBoxing: PROCEDURE [frame: J.State] = { -- info: Info _ GetInfo[frame]; -- b: G.Box _ E.EndBox[dc]; -- PutBox[frame,b]; }; JPushBox: PROCEDURE [frame: J.State] = { -- b: G.Box _ GetBox[frame]; -- G.PushClipBox[dc,b]; -- **** temporarily removed **** }; JPopBox: PROCEDURE [frame: J.State] = { -- G.PopClipBox[dc]; -- **** temporarily removed **** }; JVisible: PROCEDURE [frame: J.State] = { b: BOOLEAN; paint: GProc = {b _ G.Visible[dc]}; Painter[paint,frame]; J.PushBool[frame,b]; }; JFlushPath: PROCEDURE [frame: J.State] = { info: Info _ GetInfo[frame]; G.FlushPath[info.path]; }; JMoveTo: PROCEDURE [frame: J.State] = { info: Info _ GetInfo[frame]; x,y: REAL; [x,y]_GetPoint[frame]; G.MoveTo[info.path,x,y]; }; JMoveToNext: PROCEDURE [frame: J.State] = { info: Info _ GetInfo[frame]; x,y: REAL; [x,y]_GetPoint[frame]; G.MoveTo[info.path,x,y,FALSE]; }; JLineTo: PROCEDURE [frame: J.State] = { info: Info _ GetInfo[frame]; x,y: REAL; [x,y]_GetPoint[frame]; G.LineTo[info.path,x,y]; }; JCurveTo: PROCEDURE [frame: J.State] = { info: Info _ GetInfo[frame]; x1,y1,x2,y2,x3,y3: REAL; [x3,y3]_GetPoint[frame]; [x2,y2]_GetPoint[frame]; [x1,y1]_GetPoint[frame]; G.CurveTo[info.path,x1,y1,x2,y2,x3,y3]; }; JRectangle: PROCEDURE [frame: J.State] = { info: Info _ GetInfo[frame]; x0,y0,x1,y1: REAL; [x1,y1]_GetPoint[frame]; [x0,y0]_GetPoint[frame]; G.Rectangle[info.path,x0,y0,x1,y1]; }; JDrawArea: PROCEDURE [frame: J.State] = { info: Info _ GetInfo[frame]; paint: GProc = {G.DrawArea[dc, info.path]}; Painter[paint,frame]; }; JDrawEOArea: PROCEDURE [frame: J.State] = { info: Info _ GetInfo[frame]; paint: GProc = {G.DrawArea[dc,info.path,TRUE]}; Painter[paint,frame]; }; JDrawStroke: PROCEDURE [frame: J.State] = { info: Info _ GetInfo[frame]; paint: GProc = {G.DrawStroke[dc,info.path,width,FALSE,ends]}; i: INTEGER _ J.PopInt[frame]; width: REAL _ J.PopReal[frame]; ends: G.StrokeEnds _ (IF i=1 THEN square ELSE IF i=2 THEN round ELSE butt); Painter[paint,frame]; }; JDrawStrokeClosed: PROCEDURE [frame: J.State] = { info: Info _ GetInfo[frame]; paint: GProc = {G.DrawStroke[dc,info.path,width,TRUE]}; width: REAL _ J.PopReal[frame]; Painter[paint,frame]; }; JKnot: PROCEDURE [frame: J.State] = { info: Info _ GetInfo[frame]; y: REAL _ J.PopReal[frame]; x: REAL _ J.PopReal[frame]; Spline.Knot[info.spline,x,y]; }; JSpline: PROCEDURE [frame: J.State] = { info: Info _ GetInfo[frame]; Spline.Enter[info.spline,info.path,FALSE]; }; JCSpline: PROCEDURE [frame: J.State] = { info: Info _ GetInfo[frame]; Spline.Enter[info.spline,info.path,TRUE]; }; bmw: CARDINAL = 250; bmh: CARDINAL = 200; GetBitmapSize: PUBLIC PROC RETURNS [w, h: CARDINAL] = {RETURN[bmw,bmh]}; JBitmap: PROCEDURE [frame: J.State] = { info: Info _ GetInfo[frame]; paint: GProc = {E.DrawBitmap[dc,info.bitmap,bmw,bmh,0,0,0,bmh]}; Painter[paint,frame]; }; JSetTarget: PROC [frame: J.State] = { info: Info _ GetInfo[frame]; b: BOOLEAN _ J.PopBool[frame]; paint: GProc = {E.SetTargetBitmap[dc,IF b THEN info.bitmap ELSE NIL]}; Painter[paint,frame]; }; JScreenCoords: PROCEDURE [frame: J.State] = { y: REAL _ J.PopReal[frame]; x: REAL _ J.PopReal[frame]; paint: GProc = {[x, y] _ Graphics.UserToWorld[dc, x, y]}; -- get screen coordinates Painter[paint,frame]; J.PushReal[frame,x]; J.PushReal[frame,y]; }; JUserCoords: PROCEDURE [frame: J.State] = { y: REAL _ J.PopReal[frame]; x: REAL _ J.PopReal[frame]; paint: GProc = {[x, y] _ Graphics.WorldToUser[dc, x, y]}; -- get user coordinates Painter[paint,frame]; J.PushReal[frame,x]; J.PushReal[frame,y]; }; -- Initialization starts here RegisterGraphics: PUBLIC PROC[frame: J.State] = { J.Register[frame,".pushdc",PushDC]; J.Register[frame,".popdc",PopDC]; -- J.Register[frame,".setview",JSetVw]; J.Register[frame,".translate",JTranslate]; J.Register[frame,".scale",JScale]; J.Register[frame,".rotate",JRotate]; J.Register[frame,".sixpoint",JSixPoint]; J.Register[frame,".concat",JConcat]; J.Register[frame,".getpos",JGetPos]; J.Register[frame,".setpos",JSetPos]; J.Register[frame,".rsetpos",JRelSetPos]; J.Register[frame,".drawto",JDrawTo]; J.Register[frame,".rdrawto",JRelDrawTo]; J.Register[frame,".drawbox",JDrawBox]; J.Register[frame,".cover",JCover]; J.Register[frame,".setinvert",JSetInvert]; J.Register[frame,".setfat",JSetFat]; J.Register[frame,".setopaque",JSetOpaque]; J.Register[frame,".touch",JGetTouch]; J.Register[frame,".mouse",JGetMouse]; J.Register[frame,".setfont",JSetFont]; J.Register[frame,".drawchar",JDrawChar]; J.Register[frame,".drawtext",JDrawText]; J.Register[frame,".charbox",JCharBox]; J.Register[frame,".textbox",JTextBox]; J.Register[frame,".charwidth",JCharWidth]; J.Register[frame,".textwidth",JTextWidth]; J.Register[frame,".fontbox",JFontBox]; -- J.Register[frame,".initboxer",JStartBoxing]; -- J.Register[frame,".stopboxer",JStopBoxing]; -- J.Register[frame,".pushbox",JPushBox]; -- J.Register[frame,".popbox",JPopBox]; J.Register[frame,".visible",JVisible]; J.Register[frame,".cliparea",JClipArea]; J.Register[frame,".clipbox",JClipBox]; J.Register[frame,".flushpath",JFlushPath]; J.Register[frame,".moveto",JMoveTo]; J.Register[frame,".movetonext",JMoveToNext]; J.Register[frame,".lineto",JLineTo]; J.Register[frame,".curveto",JCurveTo]; J.Register[frame,".rect",JRectangle]; J.Register[frame,".drawarea",JDrawArea]; J.Register[frame,".draweoarea",JDrawEOArea]; J.Register[frame,".drawstroke",JDrawStroke]; J.Register[frame,".drawstrokeclosed",JDrawStrokeClosed]; J.Register[frame,".knot",JKnot]; J.Register[frame,".spline",JSpline]; J.Register[frame,".cspline",JCSpline]; J.Register[frame,".bitmap",JBitmap]; J.Register[frame,".clipeoarea",JClipEOArea]; J.Register[frame,".clipxarea",JClipXArea]; J.Register[frame,".clipxbox",JClipXBox]; J.Register[frame,".getymode",JGetYMode]; J.Register[frame,".setymode",JSetYMode]; J.Register[frame,".settarget",JSetTarget]; J.Register[frame,".screencoords",JScreenCoords]; J.Register[frame,".usercoords",JUserCoords]; }; }. ΚJ– "Mesa" style˜procšΠΟc…œΟk œžœžœ&žœžœžœžœ$žœ!žœžœžœ§ž œžœbžœžœ$žœžœžœ žœCžœžœžœžœžœžœžœΟnœžœžœžœž œ'žœžœžœ žœžœžœžœžœžœžœ žœžœ!œžœ*žœ%žœ žœžœ9œ žœžœžœžœžœžœžœžœ žœ žœ žœžœžœžœžœžœžœžœžœžœžœ žœžœžœ&žœžœŸœžœž œžœ9Ÿœžœ?žœ žœžœžœxžœŸœž œ0žœ+Ÿœž œ,žœ/Ÿœž œžœžœžœžœžœžœ Ÿœž œžœžœ žœžœžœ Ÿœž œžœžœžœžœžœžœŸœž œžœZžœ Ÿœž œfŸœž œRœœŸ œž œFžœEŸ œž œFžœ1žœ"Ÿ œž œFžœ.žœ"Ÿœž œ'žœžœ5Ÿ œž œ'žœžœ žœ5Ÿ œž œ&žœžœ8Ÿœž œ'žœžœ8Ÿœž œ&žœžœžœ.Ÿ œž œ)žœžœžœQžœžœ§Ÿœž œ'žœ1žœ žœžœžœžœ/Πci(Ÿœž œ-žœžœ8Ÿœž œ'žœžœ:Ÿ œž œ(žœžœ žœ7Ÿœž œ'žœžœ:Ÿ œž œ'žœžœ žœ;Ÿœž œ'žœžœ4Ÿœž œ'žœ žœ0Ÿ œž œ,žœ:Ÿœž œ,žœžœžœ0Ÿ œž œ,žœžœžœžœžœžœ/Ÿ œž œžœ$žœ"Ÿ œž œžœ$žœ"Ÿœž œT˜τ9šžœ"žœžœž˜5šžœžœžœ˜,Jšœ˜Jšžœ˜J˜—Jšž˜—Kšœ žœ˜"Jšœ žœ3˜B—Kšœ˜Jšœ žœžœ˜#šœžœžœ˜J˜Jšœžœ˜Jšœ˜—Jšœžœ˜J˜KšαœŸ œž œ.žœžœ"žœžœžœžœ Ÿ œž œžœžœžœ!žœ žœžœ žœ+Ÿ œž œΙŸ œž œ½Ÿœž œ―Ÿœž œ{Ÿ œž œ±Ÿ œž œ}Ÿ œž œžœ<žœ7žœ žœžœžœžœŸ œž œžœ.žœžœžœžœŸœž œLžœ7žœžœžœžœžœŸœžœžœRŸœžœžœžœžœRžœ Ÿ œž œ5œŸ œž œSœŸœž œXœŸœž œ7œŸœž œžœžœ)žœŸ œž œ7žœŸœž œ<žœžœŸ œž œ<žœžœžœ Ÿœž œ<žœžœŸœž œJžœUžœ-Ÿ œž œDžœ:žœ)Ÿ œž œGžœ9Ÿ œž œGžœžœ"Ÿ œž œGžœžœžœžœžœžœžœžœžœžœžœžœžœ&Ÿœž œGžœžœ žœžœ/Ÿœž œ:žœžœžœžœ7Ÿœž œZžœ Ÿœž œZžœžœ žœ Ÿ œžœžœžœžœžœ Ÿœž œGžœNŸ œžœ:žœžœ#žœžœžœ žœžœ"Ÿ œž œžœžœžœžœMœžœžœŸ œž œžœžœžœžœMœžœžœœŸœžœžœžœ%žœ" 'œžœ,žœ$žœ&žœ*žœ&žœ&žœ&žœ*žœ&žœ*žœ(žœ$žœ,žœ&žœ,žœ'žœ'žœ(žœ*žœ*žœ(žœ(žœ,žœ,žœ& ΄œžœ(žœ*žœ(žœ,žœ&žœ.žœ&žœ(žœ'žœ*žœ.žœ.žœ:žœ"žœ&žœ(žœ&žœ.žœ,žœ*žœ*žœ*žœ,žœ2žœ6˜»E—…—API