DIRECTORY AtomButtonsTypes, CoordSys, Feedback, FS, GGParseIn, Imager, ImagerColor, IO, Matrix3d, Rope, SV2d, SV3d, SVArtwork, SVGraphics, SVMappings, SVMatrix2d, SVModelTypes, SVPolygon3d, SVScene, SVSceneTypes, TFI3d, ViewerClasses; TFI3dImpl: CEDAR PROGRAM IMPORTS CoordSys, Feedback, FS, GGParseIn, ImagerColor, IO, Matrix3d, Rope, SVArtwork, SVGraphics, SVMappings, SVMatrix2d, SVPolygon3d, SVScene EXPORTS TFI3d = BEGIN Artwork: TYPE = SVModelTypes.Artwork; ArtworkClass: TYPE = SVModelTypes.ArtworkClass; Color: TYPE = Imager.Color; CoordSystem: TYPE = SVModelTypes.CoordSystem; CoordSysList: TYPE = SVModelTypes.CoordSysList; DrawStyle: TYPE = SVModelTypes.DrawStyle; FeedbackData: TYPE = AtomButtonsTypes.FeedbackData; FileCamera: TYPE = SVSceneTypes.FileCamera; FrameBox: TYPE = REF FrameBoxObj; FrameBoxObj: TYPE = SVModelTypes.FrameBoxObj; Matrix3by3: TYPE = SV2d.Matrix3by3; Matrix4by4: TYPE = SV3d.Matrix4by4; OMap: TYPE = SVModelTypes.OMap; Plane: TYPE = SV3d.Plane; Point3d: TYPE = SV3d.Point3d; Point2d: TYPE = SV2d.Point2d; Projection: TYPE = SVModelTypes.Projection; Scene: TYPE = SVSceneTypes.Scene; Slice: TYPE = SVSceneTypes.Slice; SpaceFunction: TYPE = REF SpaceFunctionObj; SpaceFunctionObj: TYPE = SVModelTypes.SpaceFunctionObj; Vector3d: TYPE = SV3d.Vector3d; Viewer: TYPE = ViewerClasses.Viewer; Material: TYPE = SVModelTypes.Material; SMap: TYPE = SVModelTypes.SMap; CharClass: TYPE = IO.CharClass; FileinMatrix: PUBLIC PROC [f: IO.STREAM] RETURNS [mat: Matrix4by4] = { mat _ Matrix3d.Identity[]; GGParseIn.ReadWRope[f, "["]; GGParseIn.ReadWRope[f, "["]; mat[1][1] _ GGParseIn.ReadWReal[f]; FOR j: NAT IN[2..4] DO GGParseIn.ReadWRope[f,","]; mat[1][j] _ GGParseIn.ReadWReal[f]; ENDLOOP; GGParseIn.ReadBlank[f]; GGParseIn.ReadWRope[f, "]"]; FOR i: NAT IN[2..3] DO GGParseIn.ReadWRope[f, ","]; GGParseIn.ReadWRope[f, "["]; mat[i][1] _ GGParseIn.ReadWReal[f]; FOR j: NAT IN[2..4] DO GGParseIn.ReadWRope[f, ","]; mat[i][j] _ GGParseIn.ReadWReal[f]; ENDLOOP; GGParseIn.ReadWRope[f, "]"]; ENDLOOP; GGParseIn.ReadWRope[f, "]"]; }; -- end of FileinMatrix FileinMatrix3by3: PUBLIC PROC [f: IO.STREAM] RETURNS [mat: Matrix3by3] = { mat _ SVMatrix2d.Identity[]; GGParseIn.ReadWRope[f, "["]; GGParseIn.ReadWRope[f, "["]; mat[1][1] _ GGParseIn.ReadWReal[f]; FOR j: NAT IN[2..3] DO GGParseIn.ReadWRope[f,","]; mat[1][j] _ GGParseIn.ReadWReal[f]; ENDLOOP; GGParseIn.ReadBlank[f]; GGParseIn.ReadWRope[f, "]"]; GGParseIn.ReadWRope[f, ","]; GGParseIn.ReadWRope[f, "["]; mat[2][1] _ GGParseIn.ReadWReal[f]; FOR j: NAT IN[2..3] DO GGParseIn.ReadWRope[f, ","]; mat[2][j] _ GGParseIn.ReadWReal[f]; ENDLOOP; GGParseIn.ReadWRope[f, "]"]; GGParseIn.ReadWRope[f, "]"]; }; -- end of FileinMatrix3by3 RopeNotOnTop: PUBLIC SIGNAL [position: NAT, wasThere: Rope.ROPE, notThere: Rope.ROPE] = CODE; ReadReturn: PUBLIC PROC [f: IO.STREAM] = { GGParseIn.ReadChar[f, IO.CR]; }; KeyWordBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = CHECKED { SELECT char FROM IO.CR =>RETURN [break]; ': => RETURN [break]; ENDCASE => RETURN [other]; }; ReadKeyWord: PUBLIC PROC [f: IO.STREAM] RETURNS [keyWord: Rope.ROPE, good: BOOL] = { end: BOOL _ FALSE; nextChar: Rope.ROPE; [keyWord, ----] _ IO.GetTokenRope[f, KeyWordBreakProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end THEN {good _ FALSE; keyWord _ NIL; RETURN}; [nextChar, ----] _ IO.GetTokenRope[f, KeyWordBreakProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end THEN {good _ FALSE; RETURN}; good _ Rope.Equal[nextChar, ":", TRUE]; }; ReadPoint3d: PUBLIC PROC [f: IO.STREAM] RETURNS [point3d: Point3d] = { GGParseIn.ReadWRope[f, "["]; point3d[1] _ GGParseIn.ReadWReal[f]; GGParseIn.ReadWRope[f, ","]; point3d[2] _ GGParseIn.ReadWReal[f]; GGParseIn.ReadWRope[f, ","]; point3d[3] _ GGParseIn.ReadWReal[f]; GGParseIn.ReadWRope[f, "]"]; }; ReadPoint2d: PUBLIC PROC [f: IO.STREAM] RETURNS [point2d: Point2d] = { GGParseIn.ReadWRope[f, "["]; point2d[1] _ GGParseIn.ReadWReal[f]; GGParseIn.ReadWRope[f, ","]; point2d[2] _ GGParseIn.ReadWReal[f]; GGParseIn.ReadWRope[f, "]"]; }; ReadPoint2dAsPoint3d: PUBLIC PROC [f: IO.STREAM] RETURNS [point3d: Point3d] = { GGParseIn.ReadWRope[f, "["]; point3d[1] _ GGParseIn.ReadWReal[f]; GGParseIn.ReadWRope[f, ","]; point3d[2] _ GGParseIn.ReadWReal[f]; point3d[3] _ 0; GGParseIn.ReadWRope[f, "]"]; }; ReadPlane: PUBLIC PROC [f: IO.STREAM] RETURNS [plane: Plane] = { A, B, C, D: REAL; GGParseIn.ReadWRope[f, "["]; A _ GGParseIn.ReadWReal[f]; GGParseIn.ReadWRope[f, ","]; B _ GGParseIn.ReadWReal[f]; GGParseIn.ReadWRope[f, ","]; C _ GGParseIn.ReadWReal[f]; GGParseIn.ReadWRope[f, ","]; D _ GGParseIn.ReadWReal[f]; GGParseIn.ReadWRope[f, "]"]; plane _ SVPolygon3d.PlaneFromCoefficients[A, B, C, D]; }; ReadColor: PUBLIC PROC [f: IO.STREAM] RETURNS [color: Color] = { r, g, b: REAL; GGParseIn.ReadChar[f, '[]; r _ GGParseIn.ReadWReal[f]; GGParseIn.ReadChar[f, ',]; g _ GGParseIn.ReadWReal[f]; GGParseIn.ReadChar[f, ',]; b _ GGParseIn.ReadWReal[f]; GGParseIn.ReadChar[f, ']]; color _ ImagerColor.ColorFromRGB[[r, g, b]]; }; -- end of ReadColor ReadSurface: PUBLIC PROC [f: IO.STREAM] RETURNS [surface: REF ANY] = { surfType: Rope.ROPE _ GGParseIn.ReadWWord[f]; SELECT TRUE FROM Rope.Equal[surfType, "tube", FALSE] => { radius, height: REAL; GGParseIn.ReadWRope[f, "[radius:"]; radius _ GGParseIn.ReadWReal[f]; GGParseIn.ReadWRope[f, ","]; GGParseIn.ReadWRope[f, "height:"]; height _ GGParseIn.ReadWReal[f]; GGParseIn.ReadWRope[f, "]"]; surface _ SVMappings.CreateTube[radius, height]; }; Rope.Equal[surfType, "box", FALSE] => { boxSide: Vector3d; GGParseIn.ReadBlank[f]; boxSide _ ReadPoint3d[f]; surface _ SVMappings.CreateBox[boxSide[1], boxSide[2], boxSide[3]]; }; Rope.Equal[surfType, "NIL"] => {}; ENDCASE => ERROR; }; -- end of ReadSurface ReadMaterial: PUBLIC PROC [f: IO.STREAM] RETURNS [material: Material] = { matRope: Rope.ROPE _ GGParseIn.ReadWWord[f]; success: BOOL; [material, success] _ SVArtwork.RopeToMaterial[matRope]; IF NOT success THEN ERROR; }; ReadSMap: PUBLIC PROC [f: IO.STREAM] RETURNS [sMap: SMap] = { mapRope: Rope.ROPE _ GGParseIn.ReadWWord[f]; success: BOOL; [sMap, success] _ SVArtwork.RopeToSMap[mapRope]; IF NOT success THEN ERROR; }; ReadOMap: PUBLIC PROC [f: IO.STREAM] RETURNS [oMap: OMap] = { mapRope: Rope.ROPE _ GGParseIn.ReadWWord[f]; success: BOOL; [oMap, success] _ SVArtwork.RopeToOMap[mapRope]; IF NOT success THEN ERROR; }; ReadCamera: PUBLIC PROC [f: IO.STREAM, worldCS: CoordSystem, scene: Scene, version: REAL] RETURNS [fileCamera: FileCamera] = { name: Rope.ROPE; origin, focusPoint: Point3d; slant, focalLength, resolution: REAL; projection: Projection; projectionRope: Rope.ROPE; clippingPlanes: LIST OF Plane; visibleAssemblies: LIST OF Rope.ROPE; frame: FrameBox; success: BOOL; GGParseIn.ReadWRope[f, "Camera:"]; name _ GGParseIn.ReadWWord[f]; GGParseIn.ReadWRope[f, "origin:"]; GGParseIn.ReadBlank[f]; origin _ ReadPoint3d[f]; GGParseIn.ReadWRope[f, "focusPoint:"]; GGParseIn.ReadBlank[f]; focusPoint _ ReadPoint3d[f]; GGParseIn.ReadWRope[f, "slant:"]; slant _ GGParseIn.ReadWReal[f]; GGParseIn.ReadWRope[f, "resolution:"]; resolution _ GGParseIn.ReadWReal[f]; GGParseIn.ReadWRope[f, "focalLength:"]; focalLength _ GGParseIn.ReadWReal[f]; IF version > 5.1 THEN { GGParseIn.ReadWRope[f, "projection:"]; projectionRope _ GGParseIn.ReadWWord[f]; [projection, success] _ SVGraphics.RopeToProjection[projectionRope]; IF NOT success THEN projection _ perspective; } ELSE projection _ perspective; GGParseIn.ReadWRope[f, "frame:"]; GGParseIn.ReadBlank[f]; frame _ ReadFrame[f, version]; GGParseIn.ReadWRope[f, "clippingPlanes:"]; clippingPlanes _ ReadClippingPlanes[f]; GGParseIn.ReadWRope[f, "visibleAssemblies:"]; visibleAssemblies _ ReadListOfRope[f]; GGParseIn.ReadBlank[f]; fileCamera _ SVScene.CreateFileCamera[name, origin, focusPoint, slant, resolution, focalLength, projection, frame, clippingPlanes, visibleAssemblies]; }; ReadFrame: PUBLIC PROC [f: IO.STREAM, version: REAL] RETURNS [frame: FrameBox] = { success: BOOL; point: Point2d; frame _ NEW[FrameBoxObj]; GGParseIn.ReadWRope[f, "["]; GGParseIn.ReadBlank[f]; point _ ReadPoint2d[f]; frame.downLeft[1] _ point[1]; frame.upRight[2] _ point[2]; GGParseIn.ReadWRope[f, ","]; GGParseIn.ReadBlank[f]; point _ ReadPoint2d[f]; frame.upRight[1] _ point[1]; frame.downLeft[2] _ point[2]; GGParseIn.ReadWRope[f, "fullScreen:"]; GGParseIn.ReadBlank[f]; [frame.fullScreen, success] _ GGParseIn.ReadBool[f, version]; IF NOT success THEN frame.fullScreen _ TRUE; GGParseIn.ReadWRope[f, "]"]; }; -- end of ReadFrame ReadClippingPlanes: PUBLIC PROC [f: IO.STREAM] RETURNS [clippingPlanes: LIST OF Plane] = { plane: Plane; continue: BOOL; clippingPlanes _ NIL; continue _ GGParseIn.ReadHorizontalBlank[f]; IF NOT continue THEN RETURN; plane _ ReadPlane[f]; clippingPlanes _ AppendPlaneToList[plane, clippingPlanes]; WHILE TRUE DO continue _ GGParseIn.ReadHorizontalBlank[f]; IF NOT continue THEN RETURN; GGParseIn.ReadWRope[f, ","]; GGParseIn.ReadBlank[f]; plane _ ReadPlane[f]; clippingPlanes _ AppendPlaneToList[plane, clippingPlanes]; ENDLOOP; }; ReadVisibleAssemblies: PUBLIC PROC [f: IO.STREAM, scene: Scene, feedback: FeedbackData] RETURNS [assemblyList: LIST OF Slice] = { end: BOOL _ FALSE; assembly: Slice; assemblyName: Rope.ROPE; continue, found: BOOL; assemblyList _ NIL; found _ TRUE; WHILE continue DO [assemblyName, ----] _ IO.GetTokenRope[f, RopesOnOneLineProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end OR assemblyName = NIL OR Rope.Equal[assemblyName, Rope.FromChar[IO.CR]] THEN continue _ FALSE ELSE { [assembly, ----] _ SVScene.FindAssemblyFromName[assemblyName, scene ! SVScene.AssemblyNotFound => {found _ FALSE; CONTINUE}]; IF NOT found THEN { index: NAT _ IO.GetIndex[f]; Feedback.PutF[feedback, oneLiner, "Slice %g not found at: %g.", [rope[assemblyName]], [integer[index]]]; Feedback.Blink[feedback]; } ELSE assemblyList _ AppendAssemblyToList[assembly, assemblyList]; }; ENDLOOP; }; AppendPlaneToList: PROC [plane: Plane, list: LIST OF Plane] RETURNS [LIST OF Plane] = { z: LIST OF Plane _ list; IF z = NIL THEN RETURN[CONS[plane,NIL]]; UNTIL z.rest = NIL DO z _ z.rest; ENDLOOP; z.rest _ CONS[plane,NIL]; RETURN[list]; }; ReadStyle: PUBLIC PROC [f: IO.STREAM] RETURNS [style: DrawStyle] = { styleName: Rope.ROPE _ GGParseIn.ReadWWord[f]; success: BOOL; [style, success] _ SVGraphics.RopeToDrawStyle[styleName]; IF NOT success THEN style _ wire; }; -- end of ReadStyle RopeToArtworkClass: PROC [className: Rope.ROPE] RETURNS [class: ArtworkClass] = { SELECT TRUE FROM Rope.Equal[className, "c"] => class _ justColor; Rope.Equal[className, "justColor"] => class _ justColor; Rope.Equal[className, "simpleSurface"] => class _ simpleSurface; Rope.Equal[className, "spaceFunction"] => class _ spaceFunction; ENDCASE => ERROR; }; ReadArtwork: PUBLIC PROC [f: IO.STREAM, csList: CoordSysList, defaultCS: CoordSystem, wdir: Rope.ROPE, version: REAL, feedback: FeedbackData] RETURNS [artwork: Artwork] = { source, isColorRope, nextWord, aisFileName: Rope.ROPE _ NIL; surface: REF ANY; material: Material; mat: Matrix3by3; color: Imager.Color; isColorFile: BOOL; sMap: SMap; oMap: OMap; resolution: REAL; success: BOOL; csName, className: Rope.ROPE; coordSys: CoordSystem; class: ArtworkClass; IF version >= 7.03 THEN { className _ GGParseIn.ReadWWord[f]; class _ RopeToArtworkClass[className]; GGParseIn.ReadBlank[f]; material _ ReadMaterial[f]; GGParseIn.ReadBlank[f]; SELECT class FROM justColor => { color _ ReadColor[f]; artwork _ SVArtwork.CreateColorArtwork[color, material]; RETURN; }; simpleSurface, spaceFunction => { GGParseIn.ReadWRope[f, "coordSys: "]; csName _ GGParseIn.ReadWWord[f]; IF Rope.Equal[csName, "NIL"] THEN coordSys _ NIL ELSE coordSys _ CoordSys.FindCoordSysInList[csName, csList]; }; ENDCASE => ERROR; } ELSE { IF version > 5.2 THEN { GGParseIn.ReadWRope[f, "coordSys: "]; csName _ GGParseIn.ReadWWord[f]; IF Rope.Equal[csName, "NIL"] THEN coordSys _ NIL ELSE coordSys _ CoordSys.FindCoordSysInList[csName, csList]; GGParseIn.ReadWRope[f, "class: "]; className _ GGParseIn.ReadWWord[f]; class _ RopeToArtworkClass[className]; } ELSE { coordSys _ defaultCS; class _ simpleSurface; }; GGParseIn.ReadWRope[f, "material:"]; GGParseIn.ReadBlank[f]; material _ ReadMaterial[f]; }; GGParseIn.ReadWRope[f, "surface:"]; surface _ ReadSurface[f]; IF (surface # NIL) AND class # spaceFunction THEN { nextWord _ GGParseIn.ReadWWord[f]; SELECT TRUE FROM Rope.Equal[nextWord, "source:"] => {-- oMap and sMap are defaulted source _ GGParseIn.ReadWWord[f]; SELECT TRUE FROM ISTYPE[surface, SVModelTypes.Tube] => {oMap _ tubeO; sMap _ tubeS}; ISTYPE[surface, SVModelTypes.Box] => {oMap _ orthogonal; sMap _ unfoldedBox}; ENDCASE => ERROR; }; Rope.Equal[nextWord, "SMap:"] => { GGParseIn.ReadBlank[f]; sMap _ ReadSMap[f]; GGParseIn.ReadWRope[f, "OMap:"]; GGParseIn.ReadBlank[f]; oMap _ ReadOMap[f]; GGParseIn.ReadWRope[f, "source:"]; source _ GGParseIn.ReadWWord[f]; }; ENDCASE => ERROR; isColorRope _ GGParseIn.ReadWWord[f]; SELECT TRUE FROM Rope.Equal[isColorRope, "colorFile", FALSE] => isColorFile _ TRUE; Rope.Equal[isColorRope, "bwFile", FALSE] => isColorFile _ FALSE; ENDCASE => ERROR; GGParseIn.ReadWRope[f, "resolution:"]; GGParseIn.ReadBlank[f]; resolution _ GGParseIn.ReadWReal[f]; GGParseIn.ReadWRope[f, "mat:"]; GGParseIn.ReadBlank[f]; mat _ FileinMatrix3by3[f]; success _ TRUE; [aisFileName,,] _ FS.ExpandName[source, wdir ! FS.Error => { IF error.group = user THEN { success _ FALSE; Feedback.Append[feedback, error.explanation, oneLiner]; CONTINUE; }; }]; IF NOT success THEN ERROR SVArtwork.FileNotFound; GGParseIn.ReadWRope[f, "color:"]; GGParseIn.ReadBlank[f]; color _ ReadColor[f]; artwork _ SVArtwork.CreateFileArtwork[coordSys, material, surface, oMap, sMap, aisFileName, isColorFile, color, resolution, mat]; -- may generate ERROR SVArtwork.FileNotFound } ELSE { IF surface = NIL AND class#spaceFunction THEN { GGParseIn.ReadWRope[f, "color:"]; GGParseIn.ReadBlank[f]; color _ ReadColor[f]; artwork _ SVArtwork.CreateColorArtwork[color, material] } ELSE { spaceFunction: SpaceFunction; GGParseIn.ReadWRope[f, "scalars:"]; spaceFunction _ NEW[SpaceFunctionObj]; GGParseIn.ReadBlank[f]; spaceFunction.scalars _ ReadPoint3d[f]; GGParseIn.ReadWRope[f, "func: colorcube"]; artwork _ SVArtwork.Create3DArtwork[coordSys, material, spaceFunction]; }; }; }; RopesOnOneLineProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = CHECKED { SELECT char FROM IO.CR =>RETURN [break]; IO.SP, IO.TAB, ', , '; => RETURN [sepr]; ENDCASE => RETURN [other]; }; ReadListOfRope: PUBLIC PROC [f: IO.STREAM] RETURNS [ropeList: LIST OF Rope.ROPE] = { rope: Rope.ROPE; end: BOOL _ FALSE; ropeList _ NIL; WHILE TRUE DO [rope, ----] _ IO.GetTokenRope[f, RopesOnOneLineProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end OR rope = NIL THEN RETURN; IF Rope.Equal[rope, Rope.FromChar[IO.CR]] THEN RETURN ELSE ropeList _ AppendRopeToRopeList[rope, ropeList]; ENDLOOP; }; AppendRopeToRopeList: PROC [rope: Rope.ROPE, list: LIST OF Rope.ROPE] RETURNS [LIST OF Rope.ROPE] = { z: LIST OF Rope.ROPE _ list; IF z = NIL THEN RETURN[CONS[rope,NIL]]; UNTIL z.rest = NIL DO z _ z.rest; ENDLOOP; z.rest _ CONS[rope,NIL]; RETURN[list]; }; AppendAssemblyToList: PROC [assembly: Slice, list: LIST OF Slice] RETURNS [LIST OF Slice] = { z: LIST OF Slice _ list; IF z = NIL THEN RETURN[CONS[assembly,NIL]]; UNTIL z.rest = NIL DO z _ z.rest; ENDLOOP; z.rest _ CONS[assembly,NIL]; RETURN[list]; }; END. ฮFile: TFI3dImpl.mesa (Text File-In for 3d scenes) Last edited by Bier on July 17, 1987 12:45:56 pm PDT Copyright c 1984 by Xerox Corporation. All rights reserved. Contents: convenience functions for parsing low-level parts of a 3d fileout produced by fileout3d.mesa {break, sepr, other} Convenience function. Equivalent to GGParseIn.ReadChar[f, IO.CR]; Reads a rope until a ':' or are encountered. If CR is encountered first, then good is FALSE since ":" is expected after a keyword. Assumes the next rope on the stream will be of the form "[,,]". Assumes the next rope on the stream will be of the form "[,]". Assumes the next rope on the stream will be of the form "[,]". Fills in point3d[3] with zero. A copy of List.Nconc1 for LIST OF Plane instead of LIST OF REF ANY A copy of List.Nconc1 for LIST OF Rope.ROPE instead of LIST OF REF ANY A copy of List.Nconc1 for LIST OF Slice instead of LIST OF REF ANY สด– "cedar" style˜Iheadšœ1™1Iprocšœ4™4Jšœ ฯmœ1™˜DLšžœH˜NLšžœžœ˜—Lšœ˜—šœ"˜"Lšœ˜Lšœ˜Lšœ ˜ Lšœ˜Lšœ˜Lšœ"˜"Lšœ ˜ Lšœ˜—Lšžœžœ˜—Lšœ%˜%šžœžœž˜Lšœ%žœžœ˜BLšœ"žœžœ˜@Lšžœžœ˜—Lšœ&˜&Lšœ˜Lšœ$˜$Lšœ˜Lšœ˜Lšœ˜Lšœ žœ˜šœžœ˜,šœžœ ˜šžœžœ˜Lšœ žœ˜Lšœ7˜7Lšžœ˜ L˜—L˜——Lšžœžœ žœžœ˜1Lšœ!˜!Lšœ˜Lšกœ˜Lšœกœ] ,˜ฎLšœ˜—šžœ˜šžœ žœžœžœ˜/Lšœ!˜!Lšœ˜Lšกœ˜Lšœกœ˜7L˜—šžœ˜Lšœ˜Lšœ#˜#Lšœžœ˜&L˜LšœŸ œ˜'Lšœ*˜*LšœG˜GL˜—L˜—Lšœ˜L˜—šŸœžœžœžœžœžœžœ˜Mšžœž˜Lšžœžœžœ ˜Lš žœžœžœžœ žœ˜(Lšžœžœ ˜—Lšœ˜—šŸœžœžœžœžœžœ žœžœžœ˜TLšœ žœ˜Lšœžœžœ˜Lšœ žœ˜šžœžœž˜ šœ œžœ#˜4Lšœžœžœžœ˜+—Lš žœžœžœžœžœ˜!Lš žœ žœžœžœž˜5Lšžœ1˜5—Lšžœ˜L˜—šŸœžœ žœžœžœžœžœžœžœžœ˜eJšœF™FJšœžœžœžœ˜Jš žœžœžœžœžœžœ˜'Jšžœ žœžœ žœ˜*Jšœ žœžœ˜Jšžœ˜ Jšœ˜L˜—šŸœžœžœžœžœžœžœ ˜]JšœB™BJšœžœžœ˜Jš žœžœžœžœžœ žœ˜+Jšžœ žœžœ žœ˜*Jšœ žœ žœ˜Jšžœ˜ Jšœ˜—L˜Lšžœ˜—…—