Repository: xamarin/Workbooks Branch: master Commit: 630fae550140 Files: 657 Total size: 4.9 MB Directory structure: gitextract_k3w_f6vi/ ├── .gitignore ├── LICENSE.md ├── README.md ├── SDK/ │ ├── .gitignore │ ├── README.md │ ├── Samples/ │ │ ├── KitchenSink/ │ │ │ ├── AgentIntegration.cs │ │ │ ├── Api.cs │ │ │ ├── KitchenSink.workbook │ │ │ ├── KitchenSinkIntegration.csproj │ │ │ ├── KitchenSinkIntegration.js │ │ │ ├── KitchenSinkIntegration.sln │ │ │ └── Person.cs │ │ └── XamarinInteractive.targets │ └── typings/ │ └── xamarin-interactive.d.ts ├── android/ │ ├── README.md │ ├── getting-started/ │ │ ├── AndroidAppBasics.workbook │ │ ├── hello-android-workbook.workbook │ │ └── meta.json │ ├── meta.json │ └── user-interface/ │ ├── 2D-drawing.workbook │ ├── AutoCompleteTextView.workbook │ ├── PropertyAnimation.workbook │ ├── listview.workbook │ ├── meta.json │ ├── popupmenus.workbook │ ├── spinner.workbook │ ├── switch.workbook │ └── views.workbook ├── azure/ │ ├── cogs/ │ │ ├── emotion.workbook/ │ │ │ ├── employees.csx │ │ │ └── index.workbook │ │ └── meta.json │ ├── meta.json │ └── tryazure/ │ ├── TryAzure-Mac.workbook │ ├── TryAzure-WPF.workbook │ ├── TryAzure-iOS.workbook │ └── meta.json ├── charts/ │ ├── meta.json │ ├── oxyplot/ │ │ ├── OxyPlot.workbook │ │ └── meta.json │ └── xplot/ │ ├── XPlot.workbook │ └── meta.json ├── csharp/ │ ├── async/ │ │ ├── README.md │ │ ├── async-await-wpf.workbook │ │ ├── async-await.workbook │ │ └── meta.json │ ├── collections/ │ │ ├── README.md │ │ ├── arrays.workbook │ │ └── meta.json │ ├── csharp6/ │ │ ├── README.md │ │ ├── csharp6.workbook │ │ └── meta.json │ ├── csharp7/ │ │ ├── csharp7.workbook │ │ ├── index.workbook │ │ └── meta.json │ ├── linq/ │ │ ├── 101-linq-examples.workbook/ │ │ │ ├── 101_Linq_Examples.csx │ │ │ ├── Customers.xml │ │ │ └── index.workbook │ │ └── meta.json │ ├── meta.json │ └── roslyn/ │ ├── meta.json │ └── roslyn-syntax-trees.workbook/ │ └── index.workbook ├── graphics/ │ ├── meta.json │ ├── skiasharp/ │ │ ├── colors/ │ │ │ └── colors.workbook/ │ │ │ └── index.workbook │ │ ├── images/ │ │ │ └── images.workbook/ │ │ │ └── index.workbook │ │ ├── introduction/ │ │ │ └── introduction.workbook/ │ │ │ └── index.workbook │ │ ├── logo/ │ │ │ └── skialogo-ios.workbook/ │ │ │ └── index.workbook │ │ ├── meta.json │ │ └── pixmap/ │ │ └── pixmap.workbook/ │ │ └── index.workbook │ ├── tiny-renderer/ │ │ ├── README.md │ │ ├── Renderer/ │ │ │ ├── Listings/ │ │ │ │ ├── ListingTexture.cs │ │ │ │ └── ListingZBuffer.cs │ │ │ ├── Program.cs │ │ │ ├── Properties/ │ │ │ │ └── AssemblyInfo.cs │ │ │ ├── Renderer.csproj │ │ │ ├── Renderer.sln │ │ │ ├── Tests/ │ │ │ │ ├── GouraudShaderFixture.cs │ │ │ │ ├── MatrixFixture.cs │ │ │ │ ├── ModelFixture.cs │ │ │ │ └── VectorFixture.cs │ │ │ ├── WorkbookItems/ │ │ │ │ ├── Geometry.cs │ │ │ │ ├── Image.cs │ │ │ │ ├── Matrix.cs │ │ │ │ ├── Model.cs │ │ │ │ ├── Shaders.cs │ │ │ │ └── Utils.cs │ │ │ └── packages.config │ │ ├── lesson1.workbook/ │ │ │ ├── Geometry.csx │ │ │ ├── Image.csx │ │ │ ├── ImageResultHandler.csx │ │ │ ├── LICENSE.txt │ │ │ ├── Matrix.csx │ │ │ ├── Model.csx │ │ │ ├── WpfImageResultHandler.csx │ │ │ ├── index.workbook │ │ │ ├── lesson1.csx │ │ │ └── obj/ │ │ │ └── african_head.obj │ │ ├── lesson2.workbook/ │ │ │ ├── Geometry.csx │ │ │ ├── Image.csx │ │ │ ├── ImageResultHandler.csx │ │ │ ├── LICENSE.txt │ │ │ ├── Matrix.csx │ │ │ ├── Model.csx │ │ │ ├── WpfImageResultHandler.csx │ │ │ ├── index.workbook │ │ │ ├── lesson1.csx │ │ │ ├── lesson1.workbook │ │ │ ├── lesson2.csx │ │ │ └── obj/ │ │ │ └── african_head.obj │ │ ├── lesson3.workbook/ │ │ │ ├── Geometry.csx │ │ │ ├── Image.csx │ │ │ ├── ImageResultHandler.csx │ │ │ ├── LICENSE.txt │ │ │ ├── Matrix.csx │ │ │ ├── Model.csx │ │ │ ├── WpfImageResultHandler.csx │ │ │ ├── index.workbook │ │ │ ├── lesson1.csx │ │ │ ├── lesson1.workbook │ │ │ ├── lesson2.csx │ │ │ ├── lesson2.workbook │ │ │ ├── lesson3.csx │ │ │ └── obj/ │ │ │ ├── african_head.obj │ │ │ ├── african_head_diffuse.tga │ │ │ ├── african_head_nm.tga │ │ │ ├── african_head_nm_tangent.tga │ │ │ └── african_head_spec.tga │ │ ├── lesson4.workbook/ │ │ │ ├── Geometry.csx │ │ │ ├── Image.csx │ │ │ ├── ImageResultHandler.csx │ │ │ ├── LICENSE.txt │ │ │ ├── Matrix.csx │ │ │ ├── Model.csx │ │ │ ├── WpfImageResultHandler.csx │ │ │ ├── index.workbook │ │ │ ├── lesson1.csx │ │ │ ├── lesson1.workbook │ │ │ ├── lesson2.csx │ │ │ ├── lesson2.workbook │ │ │ ├── lesson3.csx │ │ │ ├── lesson3.workbook │ │ │ ├── lesson4.csx │ │ │ └── obj/ │ │ │ └── cube.obj │ │ ├── lesson5.workbook/ │ │ │ ├── Geometry.csx │ │ │ ├── Image.csx │ │ │ ├── ImageResultHandler.csx │ │ │ ├── LICENSE.txt │ │ │ ├── Matrix.csx │ │ │ ├── Model.csx │ │ │ ├── WpfImageResultHandler.csx │ │ │ ├── index.workbook │ │ │ ├── lesson1.csx │ │ │ ├── lesson1.workbook │ │ │ ├── lesson2.csx │ │ │ ├── lesson2.workbook │ │ │ ├── lesson3.csx │ │ │ ├── lesson3.workbook │ │ │ ├── lesson4.csx │ │ │ ├── lesson4.workbook │ │ │ ├── lesson5.csx │ │ │ └── obj/ │ │ │ ├── african_head.obj │ │ │ ├── african_head_diffuse.tga │ │ │ ├── african_head_nm.tga │ │ │ ├── african_head_nm_tangent.tga │ │ │ └── african_head_spec.tga │ │ ├── lesson6.workbook/ │ │ │ ├── Geometry.csx │ │ │ ├── Image.csx │ │ │ ├── ImageResultHandler.csx │ │ │ ├── LICENSE.txt │ │ │ ├── Matrix.csx │ │ │ ├── Model.csx │ │ │ ├── WpfImageResultHandler.csx │ │ │ ├── index.workbook │ │ │ ├── lesson1.csx │ │ │ ├── lesson1.workbook │ │ │ ├── lesson2.csx │ │ │ ├── lesson2.workbook │ │ │ ├── lesson3.csx │ │ │ ├── lesson3.workbook │ │ │ ├── lesson4.csx │ │ │ ├── lesson4.workbook │ │ │ ├── lesson5.csx │ │ │ ├── lesson5.workbook │ │ │ ├── lesson6.csx │ │ │ └── obj/ │ │ │ ├── african_head.obj │ │ │ ├── african_head_diffuse.tga │ │ │ ├── african_head_nm.tga │ │ │ ├── african_head_nm_tangent.tga │ │ │ ├── african_head_spec.tga │ │ │ ├── diablo3-total-occlusion.tga │ │ │ ├── diablo3_pose.obj │ │ │ ├── diablo3_pose_diffuse.tga │ │ │ ├── diablo3_pose_glow.tga │ │ │ ├── diablo3_pose_nm.tga │ │ │ ├── diablo3_pose_nm_tangent.tga │ │ │ └── diablo3_pose_spec.tga │ │ ├── lesson6bis.workbook/ │ │ │ ├── Geometry.csx │ │ │ ├── Image.csx │ │ │ ├── ImageResultHandler.csx │ │ │ ├── LICENSE.txt │ │ │ ├── Matrix.csx │ │ │ ├── Model.csx │ │ │ ├── WpfImageResultHandler.csx │ │ │ ├── index.workbook │ │ │ ├── lesson1.csx │ │ │ ├── lesson1.workbook │ │ │ ├── lesson2.csx │ │ │ ├── lesson2.workbook │ │ │ ├── lesson3.csx │ │ │ ├── lesson3.workbook │ │ │ ├── lesson4.csx │ │ │ ├── lesson4.workbook │ │ │ ├── lesson5.csx │ │ │ ├── lesson5.workbook │ │ │ ├── lesson6.csx │ │ │ ├── lesson6.workbook │ │ │ ├── lesson6bis.csx │ │ │ └── obj/ │ │ │ ├── african_head.obj │ │ │ ├── african_head_diffuse.tga │ │ │ ├── african_head_nm.tga │ │ │ ├── african_head_nm_tangent.tga │ │ │ └── african_head_spec.tga │ │ ├── lesson7.workbook/ │ │ │ ├── Geometry.csx │ │ │ ├── Image.csx │ │ │ ├── ImageResultHandler.csx │ │ │ ├── LICENSE.txt │ │ │ ├── Matrix.csx │ │ │ ├── Model.csx │ │ │ ├── WpfImageResultHandler.csx │ │ │ ├── index.workbook │ │ │ ├── lesson1.csx │ │ │ ├── lesson1.workbook │ │ │ ├── lesson2.csx │ │ │ ├── lesson2.workbook │ │ │ ├── lesson3.csx │ │ │ ├── lesson3.workbook │ │ │ ├── lesson4.csx │ │ │ ├── lesson4.workbook │ │ │ ├── lesson5.csx │ │ │ ├── lesson5.workbook │ │ │ ├── lesson6.csx │ │ │ ├── lesson6.workbook │ │ │ ├── lesson6bis.csx │ │ │ ├── lesson6bis.workbook │ │ │ └── obj/ │ │ │ ├── diablo3-total-occlusion.tga │ │ │ ├── diablo3_pose.obj │ │ │ ├── diablo3_pose_diffuse.tga │ │ │ ├── diablo3_pose_glow.tga │ │ │ ├── diablo3_pose_nm.tga │ │ │ ├── diablo3_pose_nm_tangent.tga │ │ │ └── diablo3_pose_spec.tga │ │ ├── lesson8.workbook/ │ │ │ ├── Geometry.csx │ │ │ ├── Image.csx │ │ │ ├── ImageResultHandler.csx │ │ │ ├── LICENSE.txt │ │ │ ├── Matrix.csx │ │ │ ├── Model.csx │ │ │ ├── WpfImageResultHandler.csx │ │ │ ├── index.workbook │ │ │ ├── lesson1.csx │ │ │ ├── lesson1.workbook │ │ │ ├── lesson2.csx │ │ │ ├── lesson2.workbook │ │ │ ├── lesson3.csx │ │ │ ├── lesson3.workbook │ │ │ ├── lesson4.csx │ │ │ ├── lesson4.workbook │ │ │ ├── lesson5.csx │ │ │ ├── lesson5.workbook │ │ │ ├── lesson6.csx │ │ │ ├── lesson6.workbook │ │ │ ├── lesson6bis.csx │ │ │ ├── lesson6bis.workbook │ │ │ ├── lesson7.workbook │ │ │ └── obj/ │ │ │ ├── diablo3-total-occlusion.tga │ │ │ ├── diablo3_pose.obj │ │ │ ├── diablo3_pose_diffuse.tga │ │ │ ├── diablo3_pose_glow.tga │ │ │ ├── diablo3_pose_nm.tga │ │ │ ├── diablo3_pose_nm_tangent.tga │ │ │ └── diablo3_pose_spec.tga │ │ └── meta.json │ └── urhosharp/ │ ├── .gitignore │ ├── animated-model/ │ │ └── animated-model.workbook/ │ │ ├── Data/ │ │ │ ├── Animations/ │ │ │ │ ├── Mutant_Block_LY.ani │ │ │ │ ├── Mutant_Death.ani │ │ │ │ ├── Mutant_HipHop1.ani │ │ │ │ ├── Mutant_HitHead_LY.ani │ │ │ │ ├── Mutant_Idle0.ani │ │ │ │ ├── Mutant_Idle1.ani │ │ │ │ ├── Mutant_Jump.ani │ │ │ │ ├── Mutant_Jump1.ani │ │ │ │ ├── Mutant_JumpAttack.ani │ │ │ │ ├── Mutant_JumpAttack_RM.ani │ │ │ │ ├── Mutant_JumpStop.ani │ │ │ │ ├── Mutant_Kick.ani │ │ │ │ ├── Mutant_Punch.ani │ │ │ │ ├── Mutant_Run.ani │ │ │ │ ├── Mutant_Swipe.ani │ │ │ │ ├── Mutant_Throw_LY.ani │ │ │ │ ├── Mutant_Walk.ani │ │ │ │ └── Mutant_Wave_LY.ani │ │ │ ├── License.txt │ │ │ ├── Materials/ │ │ │ │ └── mutant_M.xml │ │ │ └── Models/ │ │ │ └── Mutant.mdl │ │ └── index.workbook │ ├── barchart/ │ │ └── charts.workbook/ │ │ └── index.workbook │ ├── building-polyhedra/ │ │ └── BuildingPolyhedra.workbook/ │ │ ├── CreateModel.csx │ │ ├── UrhoSettings.csx │ │ └── index.workbook │ ├── circle-of-life/ │ │ └── CircleOfLife.workbook/ │ │ ├── Data/ │ │ │ ├── Materials/ │ │ │ │ └── phong1.xml │ │ │ └── monkey.mdl │ │ └── index.workbook │ ├── compound-shapes/ │ │ └── CreatingUrhoCompoundShapes.workbook/ │ │ └── index.workbook │ ├── coordinates/ │ │ └── ExploringUrhoCoordinates.workbook/ │ │ └── index.workbook │ ├── custom-geometries/ │ │ └── CustomGeometries.workbook/ │ │ ├── CreateModel.csx │ │ └── index.workbook │ ├── meta.json │ ├── mobius-strip-speedway/ │ │ └── MobiusStripSpeedway.workbook/ │ │ ├── Data/ │ │ │ ├── BlueRacer/ │ │ │ │ ├── Materials/ │ │ │ │ │ ├── Material1.xml │ │ │ │ │ ├── White.xml │ │ │ │ │ ├── White_0.xml │ │ │ │ │ ├── White_1.xml │ │ │ │ │ ├── White_10.xml │ │ │ │ │ ├── White_11.xml │ │ │ │ │ ├── White_12.xml │ │ │ │ │ ├── White_13.xml │ │ │ │ │ ├── White_14.xml │ │ │ │ │ ├── White_15.xml │ │ │ │ │ ├── White_16.xml │ │ │ │ │ ├── White_17.xml │ │ │ │ │ ├── White_18.xml │ │ │ │ │ ├── White_19.xml │ │ │ │ │ ├── White_2.xml │ │ │ │ │ ├── White_20.xml │ │ │ │ │ ├── White_21.xml │ │ │ │ │ ├── White_22.xml │ │ │ │ │ ├── White_3.xml │ │ │ │ │ ├── White_4.xml │ │ │ │ │ ├── White_5.xml │ │ │ │ │ ├── White_6.xml │ │ │ │ │ ├── White_7.xml │ │ │ │ │ ├── White_8.xml │ │ │ │ │ └── White_9.xml │ │ │ │ ├── Models/ │ │ │ │ │ ├── Object.1.mdl │ │ │ │ │ ├── Object.10.mdl │ │ │ │ │ ├── Object.11.mdl │ │ │ │ │ ├── Object.12.mdl │ │ │ │ │ ├── Object.13.mdl │ │ │ │ │ ├── Object.14.mdl │ │ │ │ │ ├── Object.15.mdl │ │ │ │ │ ├── Object.16.mdl │ │ │ │ │ ├── Object.17.mdl │ │ │ │ │ ├── Object.18.mdl │ │ │ │ │ ├── Object.19.mdl │ │ │ │ │ ├── Object.2.mdl │ │ │ │ │ ├── Object.20.mdl │ │ │ │ │ ├── Object.21.mdl │ │ │ │ │ ├── Object.22.mdl │ │ │ │ │ ├── Object.23.mdl │ │ │ │ │ ├── Object.24.mdl │ │ │ │ │ ├── Object.25.mdl │ │ │ │ │ ├── Object.26.mdl │ │ │ │ │ ├── Object.27.mdl │ │ │ │ │ ├── Object.28.mdl │ │ │ │ │ ├── Object.29.mdl │ │ │ │ │ ├── Object.3.mdl │ │ │ │ │ ├── Object.30.mdl │ │ │ │ │ ├── Object.31.mdl │ │ │ │ │ ├── Object.32.mdl │ │ │ │ │ ├── Object.33.mdl │ │ │ │ │ ├── Object.34.mdl │ │ │ │ │ ├── Object.35.mdl │ │ │ │ │ ├── Object.36.mdl │ │ │ │ │ ├── Object.37.mdl │ │ │ │ │ ├── Object.38.mdl │ │ │ │ │ ├── Object.39.mdl │ │ │ │ │ ├── Object.4.mdl │ │ │ │ │ ├── Object.40.mdl │ │ │ │ │ ├── Object.41.mdl │ │ │ │ │ ├── Object.42.mdl │ │ │ │ │ ├── Object.43.mdl │ │ │ │ │ ├── Object.44.mdl │ │ │ │ │ ├── Object.45.mdl │ │ │ │ │ ├── Object.46.mdl │ │ │ │ │ ├── Object.47.mdl │ │ │ │ │ ├── Object.48.mdl │ │ │ │ │ ├── Object.49.mdl │ │ │ │ │ ├── Object.5.mdl │ │ │ │ │ ├── Object.50.mdl │ │ │ │ │ ├── Object.51.mdl │ │ │ │ │ ├── Object.52.mdl │ │ │ │ │ ├── Object.53.mdl │ │ │ │ │ ├── Object.54.mdl │ │ │ │ │ ├── Object.55.mdl │ │ │ │ │ ├── Object.56.mdl │ │ │ │ │ ├── Object.57.mdl │ │ │ │ │ ├── Object.58.mdl │ │ │ │ │ ├── Object.59.mdl │ │ │ │ │ ├── Object.6.mdl │ │ │ │ │ ├── Object.7.mdl │ │ │ │ │ ├── Object.8.mdl │ │ │ │ │ └── Object.9.mdl │ │ │ │ └── node.xml │ │ │ └── RedRolls/ │ │ │ ├── Materials/ │ │ │ │ ├── White.xml │ │ │ │ ├── White_0.xml │ │ │ │ ├── White_1.xml │ │ │ │ ├── White_10.xml │ │ │ │ ├── White_11.xml │ │ │ │ ├── White_12.xml │ │ │ │ ├── White_13.xml │ │ │ │ ├── White_14.xml │ │ │ │ ├── White_15.xml │ │ │ │ ├── White_16.xml │ │ │ │ ├── White_17.xml │ │ │ │ ├── White_2.xml │ │ │ │ ├── White_3.xml │ │ │ │ ├── White_4.xml │ │ │ │ ├── White_5.xml │ │ │ │ ├── White_6.xml │ │ │ │ ├── White_7.xml │ │ │ │ ├── White_8.xml │ │ │ │ └── White_9.xml │ │ │ ├── Models/ │ │ │ │ ├── Object.1.mdl │ │ │ │ ├── Object.10.mdl │ │ │ │ ├── Object.11.mdl │ │ │ │ ├── Object.12.mdl │ │ │ │ ├── Object.13.mdl │ │ │ │ ├── Object.14.mdl │ │ │ │ ├── Object.15.mdl │ │ │ │ ├── Object.16.mdl │ │ │ │ ├── Object.17.mdl │ │ │ │ ├── Object.18.mdl │ │ │ │ ├── Object.19.mdl │ │ │ │ ├── Object.2.mdl │ │ │ │ ├── Object.20.mdl │ │ │ │ ├── Object.21.mdl │ │ │ │ ├── Object.22.mdl │ │ │ │ ├── Object.23.mdl │ │ │ │ ├── Object.24.mdl │ │ │ │ ├── Object.25.mdl │ │ │ │ ├── Object.26.mdl │ │ │ │ ├── Object.27.mdl │ │ │ │ ├── Object.28.mdl │ │ │ │ ├── Object.29.mdl │ │ │ │ ├── Object.3.mdl │ │ │ │ ├── Object.30.mdl │ │ │ │ ├── Object.31.mdl │ │ │ │ ├── Object.32.mdl │ │ │ │ ├── Object.33.mdl │ │ │ │ ├── Object.34.mdl │ │ │ │ ├── Object.35.mdl │ │ │ │ ├── Object.36.mdl │ │ │ │ ├── Object.37.mdl │ │ │ │ ├── Object.38.mdl │ │ │ │ ├── Object.39.mdl │ │ │ │ ├── Object.4.mdl │ │ │ │ ├── Object.40.mdl │ │ │ │ ├── Object.41.mdl │ │ │ │ ├── Object.42.mdl │ │ │ │ ├── Object.43.mdl │ │ │ │ ├── Object.44.mdl │ │ │ │ ├── Object.45.mdl │ │ │ │ ├── Object.46.mdl │ │ │ │ ├── Object.47.mdl │ │ │ │ ├── Object.48.mdl │ │ │ │ ├── Object.49.mdl │ │ │ │ ├── Object.5.mdl │ │ │ │ ├── Object.50.mdl │ │ │ │ ├── Object.51.mdl │ │ │ │ ├── Object.52.mdl │ │ │ │ ├── Object.53.mdl │ │ │ │ ├── Object.54.mdl │ │ │ │ ├── Object.55.mdl │ │ │ │ ├── Object.56.mdl │ │ │ │ ├── Object.57.mdl │ │ │ │ ├── Object.58.mdl │ │ │ │ ├── Object.59.mdl │ │ │ │ ├── Object.6.mdl │ │ │ │ ├── Object.60.mdl │ │ │ │ ├── Object.7.mdl │ │ │ │ ├── Object.8.mdl │ │ │ │ └── Object.9.mdl │ │ │ └── node.xml │ │ └── index.workbook │ ├── physics/ │ │ └── physics.workbook/ │ │ ├── Data/ │ │ │ └── bucket.mdl │ │ └── index.workbook │ └── planetearth/ │ └── planetearth.workbook/ │ ├── Data/ │ │ ├── Materials/ │ │ │ └── SatNoTexture.xml │ │ ├── Models/ │ │ │ └── BigSatellite.mdl │ │ ├── RenderPaths/ │ │ │ └── Outline.xml │ │ ├── Shaders/ │ │ │ └── GLSL/ │ │ │ └── Outline.glsl │ │ ├── Techniques/ │ │ │ ├── NoTextureOutline.xml │ │ │ └── TextureOutline.xml │ │ └── Textures/ │ │ └── License.txt │ └── index.workbook ├── ios/ │ ├── README.md │ ├── getting-started/ │ │ ├── Learning-iOS.workbook │ │ ├── hello-ios-workbook.workbook │ │ └── meta.json │ ├── meta.json │ ├── platform-features/ │ │ ├── auto-layout/ │ │ │ └── programmatical-constraints.workbook │ │ ├── meta.json │ │ ├── scenekit/ │ │ │ ├── README.md │ │ │ ├── exploring-scenekit.workbook/ │ │ │ │ └── index.workbook │ │ │ └── scngeometrysource.workbook/ │ │ │ └── index.workbook │ │ ├── texttospeech/ │ │ │ └── TextToSpeech.workbook │ │ ├── touchid/ │ │ │ └── TouchID.workbook │ │ └── widecolor/ │ │ └── widecolor.workbook/ │ │ └── index.workbook │ └── user-interface/ │ ├── UIButton/ │ │ └── uibutton.workbook/ │ │ └── index.workbook │ ├── UIImage/ │ │ └── uiimage.workbook/ │ │ └── index.workbook │ ├── UILabel/ │ │ └── uilabel.workbook/ │ │ └── index.workbook │ ├── UINavigationController/ │ │ ├── README.md │ │ └── uinavigationcontroller.workbook/ │ │ ├── Hierarchical-Navigation.csx │ │ └── index.workbook │ ├── UISwitch/ │ │ └── index.workbook │ ├── UITableView/ │ │ └── uitableview.workbook/ │ │ └── index.workbook │ ├── alerts/ │ │ └── alert-controller.workbook/ │ │ ├── alert_controller.csx │ │ └── index.workbook │ ├── meta.json │ ├── uitableview-1/ │ │ ├── README.md │ │ └── uitableview1.workbook/ │ │ └── index.workbook │ └── web-views/ │ └── web-views.workbook/ │ ├── index.workbook │ └── tabbar.csx ├── mac/ │ ├── README.md │ ├── getting-started/ │ │ ├── README.md │ │ ├── hello-mac-workbook.workbook │ │ └── meta.json │ ├── meta.json │ └── user-interface/ │ ├── README.md │ ├── meta.json │ ├── outlineview/ │ │ ├── NSOutlineView.workbook │ │ └── README.md │ ├── segues/ │ │ ├── README.md │ │ └── Segues.workbook/ │ │ ├── Main.storyboard │ │ ├── Main.storyboardc/ │ │ │ ├── 4cK-Eu-ujv-view-YYD-CQ-DLY.nib │ │ │ ├── CCf-Sq-ZKC-view-E33-5d-PF3.nib │ │ │ ├── Info.plist │ │ │ ├── Kgw-Zr-aQ8-view-3jo-us-oYx.nib │ │ │ ├── MainMenu.nib │ │ │ ├── NSViewController-CCf-Sq-ZKC.nib │ │ │ ├── NSViewController-Kgw-Zr-aQ8.nib │ │ │ ├── NSViewController-hlZ-SX-RFF.nib │ │ │ ├── NSWindowController-B8D-0N-5wS.nib │ │ │ ├── NSWindowController-plf-cC-dqu.nib │ │ │ ├── XdO-WJ-HvK-view-Tof-WT-yQ6.nib │ │ │ ├── XfG-lQ-9wD-view-m2S-Jp-Qdl.nib │ │ │ └── hlZ-SX-RFF-view-404-bt-De6.nib │ │ ├── StoryboardResources.csx │ │ ├── Walkthrough.storyboard │ │ ├── Walkthrough.storyboardc/ │ │ │ ├── 4cK-Eu-ujv-view-YYD-CQ-DLY.nib │ │ │ ├── CCf-Sq-ZKC-view-E33-5d-PF3.nib │ │ │ ├── Info.plist │ │ │ ├── Kgw-Zr-aQ8-view-3jo-us-oYx.nib │ │ │ ├── MainMenu.nib │ │ │ ├── NSViewController-CCf-Sq-ZKC.nib │ │ │ ├── NSViewController-Kgw-Zr-aQ8.nib │ │ │ ├── NSViewController-hlZ-SX-RFF.nib │ │ │ ├── NSWindowController-B8D-0N-5wS.nib │ │ │ ├── NSWindowController-plf-cC-dqu.nib │ │ │ ├── XdO-WJ-HvK-view-Tof-WT-yQ6.nib │ │ │ ├── XfG-lQ-9wD-view-m2S-Jp-Qdl.nib │ │ │ └── hlZ-SX-RFF-view-404-bt-De6.nib │ │ └── index.workbook │ ├── tableview/ │ │ ├── NSTableView.workbook │ │ └── README.md │ ├── toolbars/ │ │ ├── README.md │ │ └── toolbars.workbook/ │ │ ├── index.workbook │ │ └── toolbar-resources.csx │ ├── ui-in-code/ │ │ ├── README.md │ │ └── codebasedui.workbook/ │ │ └── index.workbook │ └── webbrowser/ │ ├── README.md │ └── webbrowser.workbook/ │ ├── Main.storyboard │ ├── Main.storyboardc/ │ │ ├── Info.plist │ │ ├── MainMenu.nib │ │ ├── MainViewController.nib │ │ ├── MainWindowController.nib │ │ └── XfG-lQ-9wD-view-m2S-Jp-Qdl.nib │ ├── StoryboardResources.csx │ └── index.workbook ├── machine-learning/ │ └── ML - Getting Started - Sentiment Analysis.workbook/ │ ├── index.workbook │ ├── ml-sent.csx │ ├── sentiment-imdb-train.txt │ └── sentiment-yelp-test.txt ├── workbooks/ │ ├── README.md │ ├── getting-started/ │ │ ├── meta.json │ │ └── welcome.workbook │ ├── meta.json │ └── visualizers/ │ ├── README.md │ ├── Visualizers-console.workbook │ ├── Visualizers-ios.workbook │ ├── Visualizers-mac.workbook │ ├── Visualizers-wpf.workbook │ └── meta.json ├── wpf/ │ ├── README.md │ ├── getting-started/ │ │ ├── HelloWPF.workbook │ │ ├── hello-wpf-workbook.workbook │ │ └── meta.json │ ├── meta.json │ └── user-interface/ │ ├── graphics/ │ │ └── PenroseTriangle.workbook/ │ │ └── index.workbook │ └── meta.json └── xamarin-forms/ ├── README.md ├── advanced/ │ ├── MandelbrotTouch.workbook/ │ │ ├── BitmapInfo.csx │ │ ├── BmpMaker.csx │ │ ├── Complex.csx │ │ ├── FormsInit.csx │ │ ├── Mandelbrot.png.txt │ │ ├── MandelbrotModel.csx │ │ └── index.workbook │ ├── RPNCalculator/ │ │ ├── README.md │ │ ├── RpnCalculator-ios.workbook │ │ └── RpnCalculator.workbook │ └── meta.json ├── application-fundamentals/ │ ├── database/ │ │ └── database.workbook/ │ │ ├── FormsInit.csx │ │ └── index.workbook │ ├── files/ │ │ └── files.workbook/ │ │ ├── FormsInit.csx │ │ └── index.workbook │ ├── hierarchical-navigation/ │ │ └── hierarchical-navigation.workbook/ │ │ ├── FormsInit.csx │ │ └── index.workbook │ ├── meta.json │ └── text-to-speech/ │ └── text-to-speech.workbook/ │ ├── FormsInit.csx │ └── index.workbook ├── getting-started/ │ ├── GettingStartedWithXamarinForms-ios.workbook │ ├── GettingStartedWithXamarinForms.workbook │ └── meta.json ├── meta.json └── user-interface/ ├── alerts/ │ └── alerts.workbook/ │ ├── FormsInit.csx │ └── index.workbook ├── button/ │ └── button.workbook/ │ ├── FormsInit.csx │ └── index.workbook ├── editor/ │ └── editor.workbook/ │ ├── FormsInit.csx │ └── index.workbook ├── entry/ │ └── entry.workbook/ │ ├── FormsInit.csx │ └── index.workbook ├── image/ │ └── image.workbook/ │ ├── FormsInit.csx │ └── index.workbook ├── label/ │ └── label.workbook/ │ ├── FormsInit.csx │ └── index.workbook ├── layout-options/ │ └── layout-options.workbook/ │ ├── FormsInit.csx │ └── index.workbook ├── listview/ │ ├── ListView.workbook │ ├── ListView1-android.workbook │ └── ListView1-ios.workbook ├── map/ │ └── map.workbook/ │ ├── FormsInit.csx │ └── index.workbook ├── margins-padding/ │ └── margins-and-padding/ │ ├── FormsInit.csx │ └── index.workbook ├── meta.json ├── picker/ │ └── picker.workbook/ │ ├── FormsInit.csx │ └── index.workbook ├── slider/ │ └── slider.workbook/ │ ├── FormsInit.csx │ └── index.workbook ├── stacklayout/ │ └── stacklayout.workbook/ │ ├── FormsInit.csx │ └── index.workbook ├── switch/ │ └── switch.workbook/ │ ├── FormsInit.csx │ └── index.workbook ├── tabbedpage/ │ └── tabbedpage.workbook/ │ ├── FormsInit.csx │ └── index.workbook ├── webview/ │ └── webview.workbook/ │ ├── FormsInit.csx │ └── index.workbook └── xaml/ └── LoadXaml.workbook ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ .DS_Store [Bb]in/ graphics/tiny-renderer/Renderer/obj/ ================================================ FILE: LICENSE.md ================================================ The code in this repository is licensed under the terms of the MIT license: The MIT License (MIT) Copyright (c) 2016 Microsoft, Inc Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # Sample Workbooks This repository contains workbooks to learn various APIs across Android, iOS and Windows. **If you are looking to file issues or contribute to development of the Xamarin Workbooks app, please head to https://github.com/Microsoft/workbooks.** --- To use these samples, simply checkout this repository and open any of the `.workbook` files with [Xamarin Workbooks](https://developer.xamarin.com/guides/cross-platform/workbooks/) The examples are organized by categories: * SDK - This directory contains sample integrations and accompanying support materials for integrating with Xamarin Workbooks. * Azure - Samples showing how to use Azure services, like Cognitive Services and MobileServices * CSharp - Walkthrough various new features in the C# language * Graphics - The TinyRender graphics tutorial, 2D graphics with SkiaSharp and 3D graphics with Urho * Xamarin-Forms - cross-platform mobile apps with Xamarin.Forms Platform specific: * Android - Android workbooks * Mac - Mac workbooks * iOS - iOS workbooks * WPF - Windows Presentation Foundation workbooks ================================================ FILE: SDK/.gitignore ================================================ bin/ obj/ *.user* ================================================ FILE: SDK/README.md ================================================ # Custom Integrations with Xamarin Workbooks This directory contains sample integrations and accompanying support materials for integrating with Xamarin Workbooks. See the [full SDK documentation][docs] for details on the Xamarin Developer site. [docs]: https://developer.xamarin.com/guides/cross-platform/workbooks/sdk/ ================================================ FILE: SDK/Samples/KitchenSink/AgentIntegration.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using Xamarin.Interactive; using Xamarin.Interactive.Representations; [assembly: AgentIntegration (typeof (KitchenSinkIntegration.AgentIntegration))] namespace KitchenSinkIntegration { class AgentIntegration : IAgentIntegration { const string TAG = nameof (AgentIntegration); public void IntegrateWith (IAgent agent) { agent.RepresentationManager.AddProvider (new SampleRepresentationProvider ()); } class SampleRepresentationProvider : RepresentationProvider { public override bool HasSensibleEnumerator (IEnumerable enumerable) { // for some reason rendering Arrays as enumerables just doesn't // make sense in the context of this agent integration! if (enumerable is Array) return false; return base.HasSensibleEnumerator (enumerable); } public override IEnumerable ProvideRepresentations (object obj) { // we really like green, so return it for all objects! yield return new Color (0, 1, 0, 0.5); } } } } ================================================ FILE: SDK/Samples/KitchenSink/Api.cs ================================================ using System; using Xamarin.Interactive.Representations; public static class KitchenSink { static readonly Random random = new Random (); public static Color RandomColor () => new Color (random.NextDouble (), random.NextDouble (), random.NextDouble ()); } ================================================ FILE: SDK/Samples/KitchenSink/KitchenSink.workbook ================================================ --- uti: com.xamarin.workbook platform: MacMobile --- ```csharp #r "bin/KitchenSinkIntegration.dll" ``` ```csharp KitchenSink.RandomColor () ``` ```csharp new KitchenSinkIntegration.Person ("Aaron") ``` ```csharp new [] { 1, 2, 3 } ``` ================================================ FILE: SDK/Samples/KitchenSink/KitchenSinkIntegration.csproj ================================================ Debug AnyCPU 8.0.30703 2.0 {AA977F86-97C7-47E0-9A53-300799386F30} {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} Library KitchenSinkIntegration KitchenSinkIntegration v4.5 Profile78 true full false bin DEBUG; prompt 4 PreserveNewest ================================================ FILE: SDK/Samples/KitchenSink/KitchenSinkIntegration.js ================================================ console.log("hello from some third party code => %O", xamarin.interactive) var PersonRenderer = (function () { function PersonRenderer () { } PersonRenderer.prototype.cssClass = "renderer-third-party-person"; PersonRenderer.prototype.getRepresentations = function () { return [ { shortDisplayName: "Person" } ] }; PersonRenderer.prototype.bind = function (renderState) { console.log("PersonRenderer: bind: %O", renderState) this.renderState = renderState; }; PersonRenderer.prototype.render = function (target) { console.log("PersonRenderer: render %O to %O", this.renderState, target) var elem = document.createElement("div"); elem.innerHTML = "Person: " + this.renderState.source.Name + ""; target.inlineTarget.appendChild(elem); } return PersonRenderer; })(); xamarin.interactive.RendererRegistry.registerRenderer( function (source) { if (source.$type === "KitchenSinkIntegration.Person") return new PersonRenderer; } ); ================================================ FILE: SDK/Samples/KitchenSink/KitchenSinkIntegration.sln ================================================ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2012 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KitchenSinkIntegration", "KitchenSinkIntegration.csproj", "{AA977F86-97C7-47E0-9A53-300799386F30}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {AA977F86-97C7-47E0-9A53-300799386F30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {AA977F86-97C7-47E0-9A53-300799386F30}.Debug|Any CPU.Build.0 = Debug|Any CPU EndGlobalSection EndGlobal ================================================ FILE: SDK/Samples/KitchenSink/Person.cs ================================================ using System; using Xamarin.Interactive.Serialization; namespace KitchenSinkIntegration { public sealed class Person : ISerializableObject { public string Name { get; } public Person (string name) { if (name == null) throw new ArgumentNullException (nameof (name)); Name = name; } void ISerializableObject.Serialize (ObjectSerializer serializer) => serializer.Property (nameof (Name), Name); } } ================================================ FILE: SDK/Samples/XamarinInteractive.targets ================================================ \Library\Frameworks\Xamarin.Interactive.framework\Versions\Current\SDK C:\Program Files (x86)\Xamarin\Workbooks\SDK $(InteractiveSDKLocation) ================================================ FILE: SDK/typings/xamarin-interactive.d.ts ================================================ declare module "xamarin/interactive/dotnet" { /** * A .NET CultureInfo. * See https://msdn.microsoft.com/en-us/library/system.globalization.cultureinfo.aspx . */ export interface CultureInfo { name: string lcid: number } /** * A serialized .NET object. */ export interface ManagedObject { /** * The value of `GetType ().ToString ()` for the underlying .NET object. * Includes namepspace but no assembly qualification. */ $type: string } } declare module "xamarin/interactive/rendering" { import { ManagedObject, CultureInfo } from "xamarin/interactive/dotnet" export enum RendererRepresentationOptions { None = 0, /** * The representation will always be provided the expanded render * targets and will not be collapsible at all. */ ForceExpand = 1, /** * The representation is collapsible, but will be expanded by default. */ ExpandedByDefault = 2, /** * The representation is collapsible and will be collapsed by default if * it is the only or initially selected renderer, and otherwise expanded * automatically when selected from the menu. */ ExpandedFromMenu = 4, /** * The display name of the representation will be suppressed in the * representation button label and shown only in the button's menu, * but only if all other representations also have the hint. */ SuppressDisplayNameHint = 8 } /** * One (of perhaps many) representation(s) for a given renderer. */ export interface RendererRepresentation { /** * The name to show in the representation drop-down menu in the client. */ shortDisplayName: string /** * An optional piece of state for use by the renderer. */ state?: any /** * Optional. Defaults to RendererRepresentationOptions.None. */ options?: RendererRepresentationOptions /** * Optional numerical value to determine sort order of renderers in the * client's drop-down menu. Defaults to 0. */ order?: number } /** * Provides access to the HTML targets during Renderer.render. */ export interface RenderTarget { /** * The selected representation to render. */ representation: RendererRepresentation /** * The container element to modify for the 'collapsed' rendering. */ inlineTarget: HTMLElement /** * The container element to modify for the 'expanded' rendering. */ expandedTarget: HTMLElement /** * Returns true if the representation is currently expanded. */ isExpanded: boolean } /** * Provides access to the serialized object being rendered, and other state. */ export interface RenderState { /** * The state of the parent object, if there is one. Renderers might choose * to layout differently depending on whether or not they are being displayed * as part of a member row in an interactive object table, for example. */ parentState: RenderState /** * The serialized .NET source object. */ source: ManagedObject /** * Optional CultureInfo. */ cultureInfo?: CultureInfo } /** * Provides custom rendering(s) for ManagedObjects. */ export interface Renderer { /** * The CSS class added to both the inline rendering target and the expanded * rendering target. */ cssClass: string /** * The representation(s) provided by this Renderer. */ getRepresentations(): RendererRepresentation[] /** * Called once when an object is ready for rendering (though some other * renderer may currently be selected). Useful for doing one-time work. */ bind(renderState: RenderState): void /** * Called when it is time to render the serialized object into the HTML target(s). */ render(target: RenderTarget): void /** * Optional; set to false to prevent this renderer's representations from * showing up in the client's drop-down menu. */ isEnabled?: boolean /** * Optional; set to true to enable showing the expanded rendering target. */ canExpand?: boolean /** * Optional. Notifies renderer when a collapse occurs, in case extra work is * needed beyond the work done during render. */ collapse?(): void /** * Optional. Notifies renderer when an expand occurs, in case extra work is * needed beyond the work done during render. */ expand?(): void } /** * Accessible via xamarin.interactive.RendererRegistry, this is used to * register renderers. */ export class RendererRegistry { /** * Register a renderer factory method. Typically this method will check the * type of the source object, and return an appropriate Renderer if it is * a type the caller wants to handle. */ registerRenderer(factory: (source: ManagedObject) => Renderer): void } } ================================================ FILE: android/README.md ================================================ Android Workbooks ============ * Getting Started * User Interface ================================================ FILE: android/getting-started/AndroidAppBasics.workbook ================================================ --- uti: com.xamarin.workbook platform: Android packages: [] --- # Android App Basics In this interactive tutorial, you will learn the basics of creating an Android application using Xamarin.Android. ## Android User Interface The graphical user interface for an Android app is constructed from *widgets* such as text fields, buttons, and checkboxes. Widgets can be thought of as the building blocks that you use to create a user interface. `View` widgets are used to show text, display graphics, and interact with the user. `ViewGroup` widgets are invisible containers that arrange other widgets on the screen. This tutorial demonstrates how to build a basic user interface for an Android app by creating these widgets, laying them out on the screen, and wiring them up for user interaction. ## Getting Started Start by importing several namespaces that will be required for the code in the rest of this tutorial: ```csharp using Android.App; using Android.Widget; using Android.OS; ``` In Android, each screen is controlled by an `Activity`. The `Activity` is responsible for managing user interaction within a screen of information. There is only one `Activity` in a Xamarin Workbook. The following code creates a reference to this `Activity` object: ```csharp var rootActivity = StartedActivities.First (); ``` This `rootActivity` reference is used throughout the remainder of this tutorial. ## Defining the User Interface The first step in creating a UI is to define a `ViewGroup` that will hold the various widgets that comprise the UI of the `Activity`. Next, one or more `View`s are added to this `ViewGroup` and their parameters are configured to set how and where each `View` is displayed within the `ViewGroup`. ### Creating a Layout `LinearLayout` is a `ViewGroup` that arranges its child `View`s from top to bottom (or from left to right) as they are added. Instantiate a `LinearLayout` object and set its orientation to vertical: ```csharp var layout = new LinearLayout (rootActivity); layout.Orientation = Orientation.Vertical; ``` Setting the orientation to vertical causes widgets to be arranged from top to bottom of the screen as they are added to the layout. ### Adding a Button The first widget to add to this layout is a `Button`. Instantiate a `Button` object, set its display text to **Click Me!**, and add the button to the layout: ```csharp Button button = new Button(rootActivity); button.Text = "Click Me!"; layout.AddView (button); ``` Run the following code to display the resulting user interface on the screen: ```csharp rootActivity.SetContentView(layout); ``` When you click the button, the app does not respond. That is because there is no code to handle the button's click event. This code will be added later in this tutorial. ### Adding a TextView The next widget to add to this layout is a `TextView`. Instantiate a `TextView` object, initialize its text, and add it to the layout: ```csharp TextView textView = new TextView(rootActivity); textView.Text = "This Space is for Rent"; layout.AddView (textView); ``` When you run this code, a `TextView` is created and its message is displayed below the button. Run the following code, change the text to something different, and then run it again: ```csharp textView.Text = "This Space is Taken"; ``` ### Modifying View Layout Parameters You can call methods on a `View` object to modify how it looks after it is instantiated. Run the following line of code to center the `TextView` within the `LinearLayout`: ```csharp textView.Gravity = Android.Views.GravityFlags.CenterHorizontal; ``` The `TextView` would look better if it had more space around it. Run the following code to add padding (20 pixels top and bottom, 10 pixels on each side): ```csharp textView.SetPadding(10, 20, 10, 20); ``` To make the text easier to read, run the following line of code to change the color of the text to yellow: ```csharp textView.SetTextColor(Android.Graphics.Color.Yellow); ``` At this point, the app has a simple (though passive) user interface that is displayed in a single `Activity`. The next step is to add code to handle user input. ## Responding to User Input After the app's user interface is designed, the next step is to create event handlers to respond to user input. The following examples demonstrate how to create event handlers to respond to user clicks on the button. ### Creating an Event Handler There are a number of different ways that you can write code to handle user-triggered events. The following code implements an *anonymous delegate* to handle the button click event. This one-line event handler changes the text on the button face when it is clicked: ```csharp button.Click += delegate { button.Text = "This Button was clicked"; }; ``` Click the button after running this code to see the text on the button change. ### Displaying a Toast Another way to repond to user input is to display a *Toast* message that indicates that the button was clicked. Run this code and click the button again: ```csharp button.Click += delegate { Toast.MakeText(rootActivity, "Clicked!", ToastLength.Long).Show(); }; ``` A toast message is briefly displayed near the bottom of the screen to indicate that the button was clicked. Note that the button text is *also* updated with each click. This is because each call to `button.Click +=` adds an additional event handler that responds to button clicks (i.e., it doesn't replace the previously defined event handler). Each event handler that is added to the button `Click` event is called when when the button is clicked. ## Exercises You have now seen the basics of how to create a Xamarin.Android user interface and handle user input. Here are some things you can try to test your understanding: - Add a `count` variable and increment this count each time the button is clicked. - Display the new click count on the button face each time the button is clicked. - Try displaying the click count in the `TextView` as well as on the face of the button. ## Further Reading In a typical Android application, you develop a user interface by defining its layout in an XML file. This XML file describes the hierarchical relationships of `View`s and `ViewGroup`s in your UI (rather than programmatically, as was demonstrated in this tutorial), and it defines the configuration parameters for each `View` and `ViewGroup` . For a more detailed explanation about building your first Android app using Xamarin Studio or Visual Studio, see [Hello, Android](https://developer.xamarin.com/guides/android/getting_started/hello,android/). ================================================ FILE: android/getting-started/hello-android-workbook.workbook ================================================ --- uti: com.xamarin.workbook platform: Android --- # Android ```csharp var mainActivity = StartedActivities.First(); var label = new Android.Widget.TextView(mainActivity) { Text = "Hello, Workbooks", TextSize = 36 }; mainActivity.SetContentView(label); ``` ================================================ FILE: android/getting-started/meta.json ================================================ { "order":{ "AndroidAppBasics.workbook":"App Basics", "hello-android-workbook.workbook":"Hello, Android" } } ================================================ FILE: android/meta.json ================================================ { "order":{ "getting-started":"Getting Started", "user-interface":"User Interface" } } ================================================ FILE: android/user-interface/2D-drawing.workbook ================================================ --- uti: com.xamarin.workbook platform: Android packages: [] --- # 2D Graphics in Xamarin.Android In this workbook, you will learn the basics of creating a custom View and 2D drawing using Xamarin.Android. One technique for drawing 2D graphics in Android is to use the Canvas APIs. This is a powerful API that allows for very fine grained control for how 2D graphics are created. The Canvas API uses a\* painter’s model\* for 2D drawing. Settings such as colour, stroke type, are programatically applied. Methods on the Canvas object are called to perform drawing actions, which are applied in successive order on the underlying bitmap. There are two ways to obtain and draw on a `Canvas` object. One is to create a bitmap and provide as a parameter to the `Canvas` constructor. The other way is to subclass `Android.Views.View`, and override the `OnDraw` method. Android will invoke this method each time the View needs to be draw, and will pass in a `Canvas` object to be draw on. For this example, let’s consider the case of drawing a progress bar. Part of the bar will be red, and the other part is green. To beging, let’s declare all the namespaces that are required for this work through and obtain a reference to the Activity that we will be drawing on: ```csharp using System; using Android.App; using Android.Content; using Android.Graphics; using Android.Graphics.Drawables; using Android.Graphics.Drawables.Shapes; using Android.OS; using Android.Views; Activity activity=StartedActivities.First(); ``` ## Creating a Custom View for Drawing The code for drawing the progress bar will be contained in a custom class that extends `Android.Views.View`. This code for this is shown in the following class: ```csharp public class MyRedGreenBar : Android.Views.View { Paint greenPaint; Paint redPaint; public MyRedGreenBar(Context context) : base(context) { greenPaint = new Paint { AntiAlias=true, Color = Color.Rgb(0x99,0xCC, 0) }; greenPaint.SetStyle(Paint.Style.FillAndStroke); redPaint = new Paint { AntiAlias = true, Color = Color.Rgb(0xFF, 0x44, 0x44) }; redPaint.SetStyle(Paint.Style.FillAndStroke); } protected override void OnDraw(Canvas canvas) { base.OnDraw(canvas); // First, fill the canvas with the red paint. canvas.DrawPaint(redPaint); // Next, draw a green rectangle that covers the left 25% of the canvaa. float middle = canvas.Width * 0.25f; canvas.DrawRect(0,0, middle, Height, greenPaint); } } ``` ## Display the View To display this view, just set it as the content view for the Activity: ```csharp activity.SetContentView(new MyRedGreenBar(activity)); ``` ## Further Reading To learn more, you might want to read the [Graphics & Animation Guide](https://developer.xamarin.com/guides/android/application_fundamentals/graphics_and_animation/) in the Xamarin Developer Portal. ================================================ FILE: android/user-interface/AutoCompleteTextView.workbook ================================================ --- uti: com.xamarin.workbook platform: Android packages: [] --- # AutoCompleteTextView This guide will demonstrate how to use an AutoCompleteTextView in an Android application. An AutoCompleteTextView will display a list of suggestions that match the text a user has entered into a TextView. An AutoCompleteTextView doesn’t work alone - it requires the assistance of another widget which must extend `Android.Widget.BaseAdapter`. The adapter is a special class that will display a individual item from a list in the drop down list UI that is presented by the AutoCompleteTextView. First, let’s import the necessary namespaces that we need, and declare a list hat holds the names of some monkeys. ```csharp using System; using Android.App; using Android.Util; using Android.Views; using Android.Widget; // Get a reference to the Activity. Activity activity = StartedActivities.First(); // A small list of some different types of monkeys List allTheMonkeys = new List { "Allen's swamp monkey", "Black capuchin", "Black-headed marmoset", "Black-headed night monkey", "Black-shanked douc", "Cotton top tamarin", "Drill", "Gee's golden lemur", "Geoffrey's tamarin", "Gelada", "Golden lion Tamarin", "Grivet", "Japanese macaque", "Lesula", "Mandril", "Yellow baboon" }; ``` We will need to create an `ArrayAdapter` and assign it to the AutoTextCompleteTextView widget. In this example, each row in the AutoCompleteTextView will use a built-in Android layout, the `Android.Resource.Layout.SimpleListItem1`: ```csharp ArrayAdapter adapter = new ArrayAdapter(activity, Android.Resource.Layout.SimpleListItem1, allTheMonkeys); adapter.SetDropDownViewResource(Android.Resource.Layout.SimpleSpinnerDropDownItem); AutoCompleteTextView actv = new AutoCompleteTextView(activity); actv.Adapter = adapter; ``` In the next snippet, we add the `actv` to the Activity, want to add some padding to the views. Typically, one uses *device-independent pixels (DPs)* for positioning views on an Android layout. However, the `SetPadding` method takes pixels. The `DP2Pixel` method will take a DP value and convert that to pixels appropriate to the device. ```csharp int DP2Pixel(int dpValue) { float density = activity.Resources.DisplayMetrics.Density; int paddingDP = (int) (dpValue * density); return paddingDP; } int paddingLeft = DP2Pixel(10); int paddingRight = paddingLeft; int paddingTop = DP2Pixel(20); int paddingBottom = DP2Pixel(9); actv.SetPadding(paddingLeft, 0, paddingRight, 0); LinearLayout rootLayout = new LinearLayout(activity); TextView label = new TextView(activity); label.Text = "Pick a Monkey:"; label.SetPadding(paddingLeft, paddingTop, paddingRight, paddingBottom); rootLayout.Orientation = Orientation.Vertical; rootLayout.AddView(label); rootLayout.AddView(actv); activity.SetContentView(rootLayout); ``` ## Further Reading You may want to check out the ListView and the Spinner workbooks as they are very similar to the AutoCompleteTextView control. To display more complex data, such as a POCO, it is better to create a custom Adapter in C#; you can learn more about this by consulting the [Xamarin ListView & Adapters guide](https://developer.xamarin.com/guides/android/user_interface/working_with_listviews_and_adapters/). ================================================ FILE: android/user-interface/PropertyAnimation.workbook ================================================ ```json {"platform":"Android","uti":"com.xamarin.workbook","packages":[]} ``` # Android View Property Animation In this interactive tutorial, you will learn the basics of `View` property animation in Xamarin.Android. For a more detailed account of the various Android animation APIs, please checkout out [the documentation](https://developer.xamarin.com/guides/android/application_fundamentals/graphics_and_animation/ "Xamarin.Android animation documentation"). ## Getting Started We’ll start by importing several namespaces that we will need. ```csharp using Android.Views; using Android.Widget; using Android.Util; using Android.Graphics; using Android.Graphics.Drawables; using Android.Graphics.Drawables.Shapes; ``` There is only one `Activity` in a Xamarin Workbook. Grab the first so that we can adjust its content later (for information on `StartedActivities`, type `help` in a workbook code entry). ```csharp var rootActivity = StartedActivities.First (); ``` `DimToPixels` is a handy utility function we’ll use later on. ```csharp int DimToPixels (int dip, ComplexUnitType type = ComplexUnitType.Dip) => (int)TypedValue.ApplyDimension (type, dip, rootActivity.Resources.DisplayMetrics); ``` ## World Clocks Our first example demonstrates animating a collection of `TextClock` views. We start with a set of timezones. Feel free to adjust this list however you like. ```csharp var timezones = new[] { "UTC", // The World! "US/Pacific", // San Francisco "US/Eastern", // Boston "America/Buenos_Aires", "Europe/Copenhagen", "Europe/London" }; ``` Pick a color to use for the clockface. ```csharp var clockColor = Color.Rgb (0x73, 0x81, 0x82) ``` Creating and styling a `TextClock` is fairly straightforward. We make the background a circle using `OvalShape`. ```csharp TextClock CreateClockForZone (string zone) { var clock = new TextClock (rootActivity) { TimeZone = zone, Gravity = GravityFlags.Center, }; var background = new ShapeDrawable (new OvalShape ()); background.Paint.Color = clockColor; clock.Background = background; var padding = DimToPixels (12); clock.SetPadding (padding, padding, padding, padding); var size = DimToPixels (90); clock.SetMinimumWidth (size); clock.SetMinimumHeight (size); clock.SetTextSize (ComplexUnitType.Sp, 15); clock.SetTextColor (Color.White); return clock; } ``` ### Animation Android provides a `ViewPropertyAnimator` that drives the `View.Animate` method. Properties that can be animated using this method include: * `alpha` * `rotation(X|Y)` * `scale(X|Y)` * `translation(X|Y|Z)` * `x|y|z` Let's make an extension method that animates the `TextClock` as it is added to the grid. ```csharp static void AnimateEntrance (this TextClock clock, int index) { // Set the initial values to animate from clock.ScaleX = clock.ScaleY = 0.3f; clock.Alpha = 0; // Animate in the new values clock.Animate () .Alpha (1) .ScaleX (1) .ScaleY (1) .SetStartDelay (index * 100 + 10) .SetDuration (400) .Start (); } ``` So now we can: 1. Create a `TextClock` for each of our time zones. 2. Add it to the grid. 3. Set up the entrance animation. ```csharp void AddClocksToGrid (GridLayout grid, IList zones) { var index = 1; foreach (var zone in zones) { var clock = CreateClockForZone (zone); grid.AddView (clock); clock.AnimateEntrance (index++); } } ``` ### Putting it all together Finally, we set up our content `GridLayout` and add the clocks. ```csharp var rootGrid = new GridLayout (rootActivity) { ColumnCount = 3, UseDefaultMargins = true, AlignmentMode = GridAlign.Bounds, }; var padding = DimToPixels (16, ComplexUnitType.Dip); rootGrid.SetPadding (padding, padding, padding, padding); rootActivity.SetContentView (rootGrid, new ViewGroup.LayoutParams (-1, -1)); ``` ```csharp AddClocksToGrid (rootGrid, timezones) ``` ### Exercises You have now seen the basics of how `View` animation works in Android. Here are some things you can try, to test your understanding: * Animate the rotation of the clock. Note that the rotation value is in **degrees**. * Increase the **size of the clock text**. What happens to the clock’s shape? Can you fix it? * Combine what you’ve learned in previous lessons about the `Touch` event. Can you make the clock **shrink a bit when tapped**? * Replace the clock with a **layout** that includes the clock and a **timezone label**. ================================================ FILE: android/user-interface/listview.workbook ================================================ --- uti: com.xamarin.workbook platform: Android packages: [] --- # Using a ListView in Xamarin.Android This guide will demonstrate how to use a ListView in an Android application. Although it is an older UI widget, it is great for quick lists. The ListView doesn’t work by itself, the data displayed in a ListView by a class that extends `Android.Widget.BaseAdapter`. In this workbook, we won’t create our own class, instead we’ll just use `Android.Widget.ArrayAdapter` class. Let’s get started by importing the namespaces and initializing a list of string to display in the ListView. We will also get a reference to the Android Activity used by this workbook: ```csharp using System; using Android.App; using Android.Views; using Android.Widget; Activity activity = StartedActivities.First(); List allTheMonkeys = new List { "Allen's swamp monkey", "Black capuchin", "Black-headed marmoset", "Black-headed night monkey", "Black-shanked douc", "Cotton top tamarin", "Drill", "Gee's golden lemur", "Geoffrey's tamarin", "Gelada", "Golden lion Tamarin", "Grivet", "Japanese macaque", "Lesula", "Mandril", "Yellow baboon" }; ``` We will need to create an `ArrayAdapter` and assign it to the ListView widget. In this example, each row in the ListView will use a built-in Android layout, the `Android.Resource.Layout.SimpleListItem1`: ```csharp ArrayAdapter adapter = new ArrayAdapter(activity, Android.Resource.Layout.SimpleListItem1, allTheMonkeys); adapter.SetDropDownViewResource(Android.Resource.Layout.SimpleSpinnerDropDownItem); ListView listview = new ListView(activity); listview.Adapter = adapter; // Set an event handler for when the user makes a selection from the spinner. listview.ItemClick += (object sender, AdapterView.ItemClickEventArgs e) => { ListView l = (ListView) sender; string message = String.Format("Your favourite monkey is {0}.", allTheMonkeys[e.Position]); Toast.MakeText(activity, message, ToastLength.Short).Show(); } ; ``` In the next snippet, we add the `listview` to the Activity, want to add some padding to the views. Typically, one uses *device-independent pixels (DPs)* for positioning views on an Android layout. However, the `SetPadding` method takes pixels. The `DP2Pixel` method will take a DP value and convert that to pixels appropriate to the device. ```csharp int DP2Pixel(int dpValue) { float density = activity.Resources.DisplayMetrics.Density; int paddingDP = (int) (dpValue * density); return paddingDP; } int paddingLeft = DP2Pixel(10); int paddingRight = paddingLeft; int paddingTop = DP2Pixel(20); int paddingBottom = DP2Pixel(9); listview.SetPadding(paddingLeft, 0, paddingRight, 0); LinearLayout rootLayout = new LinearLayout(activity); TextView label = new TextView(activity); label.Text = "Pick a Monkey:"; label.SetPadding(paddingLeft, paddingTop, paddingRight, paddingBottom); rootLayout.Orientation = Orientation.Vertical; rootLayout.AddView(label); rootLayout.AddView(listview); activity.SetContentView(rootLayout); ``` ## Further Reading You may want to check out the Spinner and the AutoCompleteTextView workbooks as they are very similar to the ListView control. To display more complex data, such as a POCO, it is better to create a custom Adapter in C#; you can learn more about this by consulting the [Xamarin ListView & Adapters guide](https://developer.xamarin.com/guides/android/user_interface/working_with_listviews_and_adapters/). ================================================ FILE: android/user-interface/meta.json ================================================ { "order":{ "2D-drawing.workbook":"2D Drawing", "AutoCompleteTextView.workbook":"AutoComplete Text View", "listview.workbook":"ListView", "popupmenus.workbook":"Popup Menus", "PropertyAnimation.workbook":"Property Animation", "spinner.workbook":"Spinner", "switch.workbook":"Switch", "views.workbook":"Views" } } ================================================ FILE: android/user-interface/popupmenus.workbook ================================================ --- uti: com.xamarin.workbook platform: Android packages: [] --- # Android Popup Menus A *Popup menu* is a menu that is displayed in a window that is anchored to a `View`. In this interactive tutorial, you will learn how to create a single popup menu item and attach it to a `TextView`. ## Getting Started Start by importing several namespaces that will be required for the code in the rest of this tutorial: ```csharp using Android.App; using Android.Widget; using Android.OS; ``` Next, create an Android `Activity` and instantiate a screen layout: ```csharp var rootActivity = StartedActivities.First (); var layout = new LinearLayout (rootActivity); layout.Orientation = Orientation.Vertical; rootActivity.SetContentView(layout); ``` Because `PopupMenu` must be anchored to a `View`, the next step is add a `TextView` to the layout. This `TextView` will anchor the popup menu: ```csharp TextView textView = new TextView(rootActivity); textView.Text = "Click to Launch Popup Menu"; layout.AddView (textView); ``` When you run this code, a `TextView` should be displayed near the top of the screen. ## Adding a Popup Menu `PopupMenu` is a `View` that displays a single menu item. Run the following code to create a new `PopupMenu` and set its title: ```csharp PopupMenu popup = new PopupMenu(rootActivity, textView); popup.Menu.Add(new Java.Lang.String("This is a Popup Menu")); ``` To display a `PopupMenu`, call its `Show` method. The following code causes the popup menu instantiated above to be displayed when the `TextView` is clicked. Run this code and click the `TextView` to see what happens: ```csharp textView.Click += (s, arg) => { popup.Show(); }; ``` Clicking the `TextView` causes the **This is a Popup Menu** menu item to be displayed. In the above code, a *lambda exression* is used to implement the event handler for the `TextView` click event. The lambda expression code (the code within the curly braces) calls the popup menu's `Show` method when the `TextView` is clicked. ## Handling Menu Events When the user selects a menu item, the `MenuItemClick` event is raised. The following code displays a `Toast` when the menu item is clicked. Run the following code, click the `TextView`, and then click the menu to see what happens: ```csharp popup.MenuItemClick += (s, arg) => { Toast.MakeText(rootActivity, arg.Item.TitleFormatted + " selected", ToastLength.Long).Show(); }; ``` The argument passed in the event contains a reference to the popup menu item. In the above code, the title of the selected menu item is extracted (via the passed `Item` reference) and displayed in the toast message. When the menu item is dismissed, its `DismissEvent` is raised. Run the following code, click the `TextView`, and then click the screen to dismiss the menu item: ```csharp popup.DismissEvent += (s, arg) => { Toast.MakeText(rootActivity, "Dismissed", ToastLength.Long).Show(); }; ``` When you dismiss the menu item, the `DismissEvent` handler above displays a toast to indicate that the `DismissEvent` handler was called. ## Exercises You have now seen the basics of how to use `PopupMenu` in a Xamarin.Android application. Here are some things you can try to test your understanding: 1. Modify the `MenuItemClick` event handler to display the menu item's `ItemId` in the toast. (Hint: use Workbook code completion to see which properties and methods are available from the `Item` reference.) 2. Is it possible to modify the `DismissEvent` to retrieve and display the menu item's title from the argument passed to `DismissEvent`? ================================================ FILE: android/user-interface/spinner.workbook ================================================ --- uti: com.xamarin.workbook platform: Android packages: [] --- # Using a Spinner in Xamarin.Android This guide will demonstrate how to use a Spinner in an Android application. The Spinner doesn’t work by itself, the data displayed in a Spinner is displayed by a class that extends `Android.Widget.BaseAdapter`. In this workbook, we won’t create our own class, instead we’ll just use `Android.Widget.ArrayAdapter` class. Let’s get started by importing the namespaces and initializing a list of string to display in the Spinner. We will also get a reference to the Android Activity used by this workbook: Start by importing the namespaces that will be required for the rest of this workbook and get a reference to the Activity: ```csharp using System; using Android.App; using Android.Views; using Android.Widget; Activity activity = StartedActivities.First(); List allTheMonkeys = new List { "Allen's swamp monkey", "Black capuchin", "Black-headed marmoset", "Black-headed night monkey", "Black-shanked douc", "Cotton top tamarin", "Drill", "Gee's golden lemur", "Geoffrey's tamarin", "Gelada", "Golden lion Tamarin", "Grivet", "Japanese macaque", "Lesula", "Mandril", "Yellow baboon" }; ``` We will need to create an `ArrayAdapter` and assign it to the Spinner widget. In this example, each row in the Spinner will use a built-in Android layout, the `Android.Resource.Layout.SimpleSpinnerItem`. We can also control the layout used in the Spinner’s drop down list using the `SetDropDownViewResource method`: ```csharp ArrayAdapter adapter = new ArrayAdapter(activity, Android.Resource.Layout.SimpleSpinnerItem, allTheMonkeys); adapter.SetDropDownViewResource(Android.Resource.Layout.SimpleSpinnerDropDownItem); Spinner spinner = new Spinner(activity); spinner.Adapter = adapter; // Set an event handler for when the user makes a selection from the spinner. spinner.ItemSelected += (sender, args) => { Spinner s= (Spinner) sender; AdapterView.ItemSelectedEventArgs e = (AdapterView.ItemSelectedEventArgs) args; string message = String.Format("Your favourite monkey is {0}.", allTheMonkeys[e.Position]); Toast.MakeText(activity, message, ToastLength.Short).Show(); }; ``` In the next snippet, we add the `spinner` to the Activity. Typically, one uses *device-independent pixels (DPs)* for positioning views on an Android layout. However, the `SetPadding` method takes pixels. The `DP2Pixel` method will take a DP value and convert that to pixels appropriate to the device. ```csharp int DP2Pixel(int dpValue) { float density = activity.Resources.DisplayMetrics.Density; int paddingDP = (int) (dpValue * density); return paddingDP; } int paddingLeft = DP2Pixel(10); int paddingRight = paddingLeft; int paddingTop = DP2Pixel(20); int paddingBottom = DP2Pixel(9); spinner.SetPadding(paddingLeft, 0, paddingRight, 0); LinearLayout rootLayout = new LinearLayout(activity); TextView label = new TextView(activity); label.Text = "Pick a Monkey:"; label.SetPadding(paddingLeft, paddingTop, paddingRight, paddingBottom); rootLayout.Orientation = Orientation.Vertical; rootLayout.AddView(label); rootLayout.AddView(spinner); activity.SetContentView(rootLayout); ``` ## Further Reading You may want to check out the ListViewand the AutoCompleteTextView workbooks as they are very similar to the Spinner control. To display more complex data, such as a POCO, it is better to create a custom Adapter in C#; you can learn more about this by consulting the [Xamarin ListView & Adapters guide](https://developer.xamarin.com/guides/android/user_interface/working_with_listviews_and_adapters/). ================================================ FILE: android/user-interface/switch.workbook ================================================ --- uti: com.xamarin.workbook platform: Android packages: [] --- # Android Switches In this interactive tutorial, you will learn the basics of working with the Android `Switch` widget in Xamarin.Android. The `Switch` widget allows a user to toggle between two states such as **ON** and **OFF**. ## Getting Started Start by importing several namespaces that will be required for the code in the rest of this tutorial: ```csharp using Android.App; using Android.Widget; using Android.OS; ``` Next, create an Android `Activity` and instantiate a screen layout to host the `Switch`: ```csharp var rootActivity = StartedActivities.First (); var layout = new LinearLayout (rootActivity); layout.Orientation = Orientation.Vertical; rootActivity.SetContentView(layout); ``` This `LinearLayout` is the `ViewGroup` that manages views on the screen. The only view that will be added to this layout is a `Switch`, but you may add more views in the exercises at the end of this tutorial. ## Creating a Switch Run the following code to create a `Switch` object and display it on the screen: ```csharp Switch mySwitch = new Switch (rootActivity); layout.AddView (mySwitch); ``` The `Switch` defaults to the **OFF** state. Repeatedly click the `Switch` to toggle it **ON** and **OFF**. You should see the `Switch` slide to the right and become highlighted when it is turned **ON**. Also, each click causes a sound to be produced. ## Toggling the Switch You can programmatically turn the switch **ON** and **OFF** by changing its `Checked` property. Make sure the switch is **OFF**, and then run the following line of code to switch it back to **ON**: ```csharp mySwitch.Checked = true; ``` Setting the `Checked` property to `false` turns the switch back **OFF**: ```csharp mySwitch.Checked = false; ``` You can use the `Checked` property to programatically change the value of the `Switch` to your chosen default state when the app starts up. ## Labeling the Switch Often is is useful to a attach a label to a `Switch` to indicate what it does. When you set the `Switch`'s `Text` property to a string, that string is displayed next to the `Switch`: ```csharp mySwitch.Text = "Label for switch" ``` ## Handling Switch Events When the `Switch`'s value changes, it raises a `CheckedChange` event. The following code captures this event and displays a `Toast` message. Run this code and repeatedly click the `Switch` to see what happens: ```csharp mySwitch.CheckedChange += delegate(object sender, CompoundButton.CheckedChangeEventArgs e) { if (e.IsChecked) Toast.MakeText(rootActivity, "Switch was turned ON!", ToastLength.Long).Show(); else Toast.MakeText(rootActivity, "Switch was turned OFF", ToastLength.Long).Show(); } ``` When the Switch button is clicked, the `IsChecked` property of the event is set to indicate the state of the Switch after it was clicked. If `IsChecked` is `true`, the `Switch` is **ON** and a `Toast` message displays the new state of the `Switch`. If `IsChecked` is `false`, the `Toast` displays that the `Switch` has been turned **OFF**. ## Exercises You have now seen how to create a `Switch`, label it, modify its state, and handle `Switch` events. Here are some things you can try to test your understanding: - Change the `Switch` event handler to update the `Switch` label (`Text` property) rather than display a `Toast` each time the `Switch` is clicked. - Add a `Button` that toggles the state of the `Switch` on and off each time the `Button` is clicked. - Add a second `Switch` and implement a logical exclusive-OR operation: set the `Button` text to **ON** when one and only one `Switch` is turned on. Set the text to **OFF** when both `Switch`es are turned off or both are turned on. ================================================ FILE: android/user-interface/views.workbook ================================================ ```json {"platform":"Android","uti":"com.xamarin.workbook"} ``` # Android View Property Animation In this interactive tutorial, you will learn the basics of `View` property animation in Xamarin.Android. For a more detailed account of the various Android animation APIs, please checkout out [the documentation](https://developer.xamarin.com/guides/android/application_fundamentals/graphics_and_animation/ "Xamarin.Android animation documentation"). ## Getting Started We’ll start by importing several namespaces that we will need. ```csharp using Android.Views; using Android.Widget; using Android.Util; using Android.Graphics; using Android.Graphics.Drawables; using Android.Graphics.Drawables.Shapes; ``` There is only one `Activity` in a Xamarin Workbook. Grab the first so that we can adjust its content later (for information on `StartedActivities`, type `help` in a workbook code entry). ```csharp var rootActivity = StartedActivities.First (); ``` `DimToPixels` is a handy utility function we’ll use later on. ```csharp int DimToPixels (int dip, ComplexUnitType type = ComplexUnitType.Dip) => (int)TypedValue.ApplyDimension (type, dip, rootActivity.Resources.DisplayMetrics); ``` ## World Clocks Our first example demonstrates animating a collection of `TextClock` views. We start with a set of timezones. Feel free to adjust this list however you like. ```csharp var timezones = new[] { "UTC", // The World! "US/Pacific", // San Francisco "US/Eastern", // Boston "America/Buenos_Aires", "Europe/Copenhagen", "Europe/London" }; ``` Pick a color to use for the clockface. ```csharp var clockColor = Color.Rgb (0x73, 0x81, 0x82) ``` Creating and styling a `TextClock` is fairly straightforward. We make the background a circle using `OvalShape`. ```csharp TextClock CreateClockForZone (string zone) { var clock = new TextClock (rootActivity) { TimeZone = zone, Gravity = GravityFlags.Center, }; var background = new ShapeDrawable (new OvalShape ()); background.Paint.Color = clockColor; clock.Background = background; var padding = DimToPixels (12); clock.SetPadding (padding, padding, padding, padding); var size = DimToPixels (90); clock.SetMinimumWidth (size); clock.SetMinimumHeight (size); clock.SetTextSize (ComplexUnitType.Sp, 15); clock.SetTextColor (Color.White); return clock; } ``` ### Animation Android provides a `ViewPropertyAnimator` that drives the `View.Animate` method. Properties that can be animated using this method include: * `alpha` * `rotation(X|Y)` * `scale(X|Y)` * `translation(X|Y|Z)` * `x|y|z` Let's make an extension method that animates the `TextClock` as it is added to the grid. ```csharp static void AnimateEntrance (this TextClock clock, int index) { // Set the initial values to animate from clock.ScaleX = clock.ScaleY = 0.3f; clock.Alpha = 0; // Animate in the new values clock.Animate () .Alpha (1) .ScaleX (1) .ScaleY (1) .SetStartDelay (index * 100 + 10) .SetDuration (400) .Start (); } ``` So now we can: 1. Create a `TextClock` for each of our time zones. 2. Add it to the grid. 3. Set up the entrance animation. ```csharp void AddClocksToGrid (GridLayout grid, IList zones) { var index = 1; foreach (var zone in zones) { var clock = CreateClockForZone (zone); grid.AddView (clock); clock.AnimateEntrance (index++); } } ``` ### Putting it all together Finally, we set up our content `GridLayout` and add the clocks. ```csharp var rootGrid = new GridLayout (rootActivity) { ColumnCount = 3, UseDefaultMargins = true, AlignmentMode = GridAlign.Bounds, }; var padding = DimToPixels (16, ComplexUnitType.Dip); rootGrid.SetPadding (padding, padding, padding, padding); rootActivity.SetContentView (rootGrid, new ViewGroup.LayoutParams (-1, -1)); ``` ```csharp AddClocksToGrid (rootGrid, timezones) ``` ### Exercises You have now seen the basics of how `View` animation works in Android. Here are some things you can try, to test your understanding: * Animate the rotation of the clock. Note that the rotation value is in **degrees**. * Increase the **size of the clock text**. What happens to the clock’s shape? Can you fix it? * Combine what you’ve learned in previous lessons about the `Touch` event. Can you make the clock **shrink a bit when tapped**? * Replace the clock with a **layout** that includes the clock and a **timezone label**. ================================================ FILE: azure/cogs/emotion.workbook/employees.csx ================================================ // https://github.com/xamarinhq/app-acquaint/blob/2ca9e83c8344d35288e4ea7868ea6e5795a25e9c/App/Common/Acquaint.Data/SeedData.cs using System.Collections.Generic; public static class SeedData { public static List Get() { return new List() { new Acquaintance() { FirstName = "Joseph", LastName = "Grimes", Company = "GG Mechanical", JobTitle = "Vice President", Email = "jgrimes@ggmechanical.com", Phone = "414-367-4348", Street = "2030 Judah St", City = "San Francisco", PostalCode = "94144", State = "CA", PhotoUrl = "https://acquaint.blob.core.windows.net/images/josephgrimes.jpg" }, new Acquaintance() { FirstName = "Monica", LastName = "Green", Company = "Calcom Logistics", JobTitle = "Director", Email = "mgreen@calcomlogistics.com", Phone = "925-353-8029", Street = "230 3rd Ave", City = "San Francisco", PostalCode = "94118", State = "CA", PhotoUrl = "https://acquaint.blob.core.windows.net/images/monicagreen.jpg" }, new Acquaintance() { FirstName = "Joan", LastName = "Mancum", Company = "Bay Unified School District", JobTitle = "Principal", Email = "joan.mancum@busd.org", Phone = "914-870-7670", Street = "448 Grand Ave", City = "South San Francisco", PostalCode = "94080", State = "CA", PhotoUrl = "https://acquaint.blob.core.windows.net/images/joanmancum.jpg" }, new Acquaintance() { FirstName = "Alvin", LastName = "Gray", Company = "Pacific Cabinetry", JobTitle = "Office Manager", Email = "agray@pacificcabinets.com", Phone = "720-344-7823", Street = "1773 Lincoln St", City = "Santa Clara", PostalCode = "95050", State = "CA", PhotoUrl = "https://acquaint.blob.core.windows.net/images/alvingray.jpg" }, new Acquaintance() { FirstName = "Michelle", LastName = "Wilson", Company = "Evergreen Mechanical", JobTitle = "Sales Manager", Email = "mwilson@evergreenmech.com", Phone = "917-245-7975", Street = "208 Jackson St", City = "San Jose", PostalCode = "95112", State = "CA", PhotoUrl = "https://acquaint.blob.core.windows.net/images/michellewilson.jpg" }, new Acquaintance() { FirstName = "Jennifer", LastName = "Gillespie", Company = "Peninsula University", JobTitle = "Superintendent", Email = "jgillespie@peninsula.org", Phone = "831-427-6746", Street = "10002 N De Anza Blvd", City = "Cupertino", PostalCode = "95014", State = "CA", PhotoUrl = "https://acquaint.blob.core.windows.net/images/jennifergillespie.jpg" }, new Acquaintance() { FirstName = "Thomas", LastName = "White", Company = "Creative Automotive Group", JobTitle = "Service Manager", Email = "tom.white@creativeauto.com", Phone = "214-865-0771", Street = "1181 Linda Mar Blvd", City = "Pacifica", PostalCode = "94044", State = "CA", PhotoUrl = "https://acquaint.blob.core.windows.net/images/thomaswhite.jpg" }, new Acquaintance() { FirstName = "Leon", LastName = "Muks", Company = "Spacey", JobTitle = "President", Email = "leon.muks@spacey.io", Phone = "310-586-0181", Street = "2518 Durant Ave", City = "Berkeley", PostalCode = "94704", State = "CA", PhotoUrl = "https://acquaint.blob.core.windows.net/images/leonmuks.jpg" }, new Acquaintance() { FirstName = "Floyd", LastName = "Bell", Company = "Netcore", JobTitle = "Procurement", Email = "floyd.bell@netcore.net", Phone = "603-226-4115", Street = "450 15th St", City = "Oakland", PostalCode = "94612", State = "CA", PhotoUrl = "https://acquaint.blob.core.windows.net/images/floydbell.jpg" }, new Acquaintance() { FirstName = "Vanessa", LastName = "Thornton", Company = "Total Sources", JobTitle = "Product Manager", Email = "vanessa.thornton@totalsourcesinc.com", Phone = "419-998-6611", Street = "550 Quarry Rd", City = "San Carlos", PostalCode = "94070", State = "CA", PhotoUrl = "https://acquaint.blob.core.windows.net/images/vanessathornton.jpg" }, new Acquaintance() { FirstName = "John", LastName = "Boone", Company = "A. L. Price", JobTitle = "Executive Associate", Email = "jboone@alpricellc.com", Phone = "973-579-4610", Street = "233 E Harris Ave", City = "South San Francisco", PostalCode = "94080", State = "CA", PhotoUrl = "https://acquaint.blob.core.windows.net/images/johnboone.jpg" }, new Acquaintance() { FirstName = "Ann", LastName = "Temple", Company = "Foxmoor", JobTitle = "Director", Email = "ann.temple@foxmoorinc.com", Phone = "608-821-7667", Street = "1270 San Pablo Ave", City = "Berkeley", PostalCode = "94706", State = "CA", PhotoUrl = "https://acquaint.blob.core.windows.net/images/anntemple.jpg" }, new Acquaintance() { FirstName = "Joseph", LastName = "Meeks", Company = "Rose Records", JobTitle = "Manager", Email = "jmeeks@roserecordsllc.com", Phone = "978-628-6826", Street = "28 N 1st St", City = "San Jose", PostalCode = "95113", State = "CA", PhotoUrl = "https://acquaint.blob.core.windows.net/images/josephmeeks.jpg" }, new Acquaintance() { FirstName = "Michelle", LastName = "Herring", Company = "Full Color", JobTitle = "Production Specialist", Email = "michelle.herring@fullcolorus.com", Phone = "201-319-9344", Street = "213 2nd Ave", City = "San Mateo", PostalCode = "94401", State = "CA", PhotoUrl = "https://acquaint.blob.core.windows.net/images/michelleherring.jpg" }, new Acquaintance() { FirstName = "Daniel", LastName = "Jones", Company = "Flexus", JobTitle = "Quality Assurance Associate", Email = "daniel.jones@flexusinc.com", Phone = "228-432-8712", Street = "850 Bush St", City = "San Francisco", PostalCode = "94108", State = "CA", PhotoUrl = "https://acquaint.blob.core.windows.net/images/danieljones.jpg" }, new Acquaintance() { FirstName = "Margaret", LastName = "Cargill", Company = "Redwood City Medical Group", JobTitle = "Director", Email = "mcargill@rcmg.org", Phone = "208-816-9793", Street = "1037 Middlefield Road", City = "Redwood City", PostalCode = "94063", State = "CA", PhotoUrl = "https://acquaint.blob.core.windows.net/images/margaretcargill.jpg" }, new Acquaintance() { FirstName = "Benjamin", LastName = "Jones", Company = "JH Manufacturing", JobTitle = "Head of Manufacturing", Email = "ben.jones@jh.com", Phone = "505.562.3086", Street = "2091 Cowper St", City = "Palo Alto", PostalCode = "94306", State = "CA", PhotoUrl = "https://acquaint.blob.core.windows.net/images/benjaminjones.jpg" }, new Acquaintance() { FirstName = "Ivan", LastName = "Diaz", Company = "XYZ Robotics", JobTitle = "CEO", Email = "ivan.diaz@xyzrobotics.com", Phone = "406-496-8774", Street = "1960 Mandela Parkway", City = "Oakland", PostalCode = "94607", State = "CA", PhotoUrl = "https://acquaint.blob.core.windows.net/images/ivandiaz.jpg" }, new Acquaintance() { FirstName = "Eric", LastName = "Grant", Company = "MMSRI, Inc.", JobTitle = "Senior Manager", Email = "egrant@mmsri.com", Phone = "360-693-2388", Street = "2043 Martin Luther King Jr. Way", City = "Berkeley", PostalCode = "94704", State = "CA", PhotoUrl = "https://acquaint.blob.core.windows.net/images/ericgrant.jpg" }, new Acquaintance() { FirstName = "Stacey", LastName = "Valdovinos", Company = "Global Manufacturing", JobTitle = "CEO", Email = "svaldovinos@globalmanuf.com", Phone = "440-243-7987", Street = "98 Udayakavi Lane", City = "Danville", PostalCode = "94526", State = "CA", PhotoUrl = "https://acquaint.blob.core.windows.net/images/staceyvaldovinos.jpg" }, new Acquaintance() { FirstName = "Jesus", LastName = "Cardell", Company = "Pacific Marine Supply", JobTitle = "Manager", Email = "jcardella@pacificmarine.com", Phone = "410-745-5521", Street = "1008 Rachele Road", City = "Walnut Creek", PostalCode = "94597", State = "CA", PhotoUrl = "https://acquaint.blob.core.windows.net/images/jesuscardell.jpg" }, new Acquaintance() { FirstName = "Wilma", LastName = "Woolley", Company = "Mission School District", JobTitle = "Superintendent", Email = "wwoolley@missionsd.org", Phone = "940-696-1852", Street = "7277 Moeser Lane", City = "El Cerrito", PostalCode = "94530", State = "CA", PhotoUrl = "https://acquaint.blob.core.windows.net/images/wilmawoolley.jpg" }, new Acquaintance() { FirstName = "Evan", LastName = "Armstead", Company = "City of Richmond", JobTitle = "Board Member", Email = "evan.armstead@richmond.org", Phone = "415-336-2228", Street = "398 23rd St", City = "Richmond", PostalCode = "94804", State = "CA", PhotoUrl = "https://acquaint.blob.core.windows.net/images/evanarmstead.jpg" }, new Acquaintance() { FirstName = "James", LastName = "Jones", Company = "East Bay Commercial Bank", JobTitle = "Manager", Email = "james.jones@eastbaybank.com", Phone = "313-248-7644", Street = "4501 Pleasanton Way", City = "Pleasanton", PostalCode = "94556", State = "CA", PhotoUrl = "https://acquaint.blob.core.windows.net/images/jamesjones.jpg" }, new Acquaintance() { FirstName = "Douglas", LastName = "Greenly", Company = "Bay Tech Credit Union", JobTitle = "Vice President", Email = "d.greenly@baytechcredit.com", Phone = "201-929-0094", Street = "2267 Alameda Ave", City = "Alameda", PostalCode = "94501", State = "CA", PhotoUrl = "https://acquaint.blob.core.windows.net/images/douglasgreenly.jpg" }, new Acquaintance() { FirstName = "Brent", LastName = "Mason", Company = "Rockridge Hotel", JobTitle = "Concierge", Email = "brent.mason@rockridgehotel.com", Phone = "940-482-7759", Street = "1960 Mandela Parkway", City = "Oakland", PostalCode = "94607", State = "CA", PhotoUrl = "https://acquaint.blob.core.windows.net/images/brentmason.jpg" }, new Acquaintance() { FirstName = "Richard", LastName = "Hogan", Company = "Marin Luxury Senior Living", JobTitle = "Customer Care", Email = "rhogan@marinseniorliving.com", Phone = "978-658-7545", Street = "674 Tiburon Blvd", City = "Belvedere Tiburon", PostalCode = "94920", State = "CA", PhotoUrl = "https://acquaint.blob.core.windows.net/images/richardhogan.jpg" }, new Acquaintance() { FirstName = "Daniel", LastName = "Granville", Company = "Cityview Consulting", JobTitle = "Consultant", Email = "dgranville@cityviewconsulting.com", Phone = "330-616-7467", Street = "300 Spencer Ave", City = "Sausalito", PostalCode = "94965", State = "CA", PhotoUrl = "https://acquaint.blob.core.windows.net/images/danielgranville.jpg" }, new Acquaintance() { FirstName = "Margaret", LastName = "Kidd", Company = "Marin Cultural Center", JobTitle = "President", Email = "mkidd@marincultural.org", Phone = "406-784-0602", Street = "106 Throckmorton Ave", City = "Mill Valley", PostalCode = "94941", State = "CA", PhotoUrl = "https://acquaint.blob.core.windows.net/images/margaretkidd.jpg" }, new Acquaintance() { FirstName = "Leo", LastName = "Parson", Company = "San Rafel Chamber of Commerce", JobTitle = "Board Member", Email = "leo.parson@sanrafaelcoc.org", Phone = "773-991-5214", Street = "199 Clorinda Ave", City = "San Rafael", PostalCode = "94901", State = "CA", PhotoUrl = "https://acquaint.blob.core.windows.net/images/leoparson.jpg" }, }; } } ================================================ FILE: azure/cogs/emotion.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook platforms: - iOS packages: - id: Newtonsoft.Json version: 8.0.3 - id: Microsoft.Net.Http version: 2.2.29 - id: Microsoft.ProjectOxford.Emotion version: 1.0.331.1 - id: Microsoft.ProjectOxford.Common version: 1.0.308 - id: Microsoft.Bcl.Build version: 1.0.21 - id: Microsoft.Bcl version: 1.1.10 --- # Azure Cognitive Services Image analysis with the Cognitive Services' `EmotionServiceClient` > ⚠️ Visit [Microsoft Cognitive Services](https://www.microsoft.com/cognitive-services) and get a key before you begin. ```csharp var emotionKey = "YOUR_EMOTION_SERVICE_KEY_HERE"; ``` Start by adding the `Microsoft.ProjectOxford.Emotion` NuGet to the iOS Workbook. The required references are loaded into the workbook below: ```csharp #r "System.Collections" #r "System.IO" #r "System.Runtime" #r "System.Threading.Tasks" #r "System.Net.Http" #r "System.Net.Http.Primitives" #r "System.Net.Http.Extensions" #r "Newtonsoft.Json" #r "Microsoft.ProjectOxford.Common" #r "Microsoft.ProjectOxford.Emotion" ``` We first define a simple data structure to model an employee. Remote properties will be populated from Azure. We define a couple of local properties as well that we’ll need later. ```csharp using Newtonsoft.Json; public class Acquaintance { public string FirstName { get; set; } public string LastName { get; set; } public string Company { get; set; } public string JobTitle { get; set; } public string Email { get; set; } public string Phone { get; set; } public string Street { get; set; } public string City{ get; set; } public string PostalCode { get; set; } public string State { get; set; } public string PhotoUrl { get; set; } public override string ToString () { return $"{FirstName} {LastName} ({JobTitle}) " + (AvatarImage == null?"⚪️":"☑️"); } // client-local properties [JsonIgnore] public float Happiness { get; set; } [JsonIgnore] public UIImage AvatarImage { get; set; } } ``` The list is populated from another sample’s [seed data](https://github.com/xamarinhq/app-acquaint/blob/2ca9e83c8344d35288e4ea7868ea6e5795a25e9c/App/Common/Acquaint.Data/SeedData.cs). ```csharp #load "employees.csx" var employees = SeedData.Get(); ``` Here we fetch the avatar images for each person and cache them back on the model object. Inspecting the `employees` list now shows happy faces! ```csharp foreach (var employee in employees) { var imageData = NSData.FromUrl (new NSUrl (employee.PhotoUrl)); if (imageData != null) employee.AvatarImage = UIImage.LoadFromData (imageData); } employees ``` ## Cognitive Services For some real fun, we can analyze employee emotions using the Emotions API from [Microsoft Cognitive Services](https://www.microsoft.com/cognitive-services). To test the process, analyze the first employee’s emotions in their avatar photo. The Emotion service will fetch the avatar from a URL in this case, but it can also process raw image data sent directly from the client. ```csharp using System.IO; using Microsoft.ProjectOxford.Emotion; var emotionClient = new EmotionServiceClient (emotionKey); await emotionClient.RecognizeAsync (employees.First ().PhotoUrl) ``` The Emotion API provides an estimation of overall happiness. Perform the same analysis for all the employees and record their happiness. If the service cannot detect a human face, it will return no scores. ```csharp foreach (var employee in employees) { var emotionData = await emotionClient.RecognizeAsync (employee.PhotoUrl); employee.Happiness = (emotionData.FirstOrDefault ()?.Scores?.Happiness).GetValueOrDefault (); } employees ``` We want our least happy employees to show up first... ```csharp employees = employees.OrderBy (x => x.Happiness).ToList () ``` ## Bringing it together on iOS The data can be rendered in a UITableView, to interact with live in the iOS simulator. ```csharp class EmployeeTableSource : UITableViewDataSource { List employees; public EmployeeTableSource (List emps) { employees = emps; } public override nint RowsInSection (UITableView tableview, nint section) => employees.Count; public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath) { var employee = employees [indexPath.Row]; string emoji; if (employee.Happiness >= 0.9) { emoji = "😀"; } else if (employee.Happiness >= 0.8) { emoji = "🙂"; } else if (employee.Happiness >= 0.4) { emoji = "😕"; } else if (employee.Happiness == 0) { emoji = "🐶"; } else { emoji = "😡"; } return new UITableViewCell (UITableViewCellStyle.Subtitle, "MyTableCell") { TextLabel = { Text = $"{employee.FirstName} {employee.LastName}" }, DetailTextLabel = { Text = $"{employee.Happiness:P} {emoji}" }, ImageView = { Image = employee.AvatarImage } }; } } ``` To actually render on the simulator, set the the root view controller: ```csharp KeyWindow.RootViewController = new UINavigationController (new UITableViewController { Title = "Happiness Training Candidates", TableView = { DataSource = new EmployeeTableSource (employees) } }) ``` ### Exercises * Change the background color of the `UITableViewCell` based on the happiness of the employee. * The Emotions API covers more than just happiness. Try adding information about anger, available in `emotionData`. * Implement a custom `UITableViewCell` that shows all emotion data. ================================================ FILE: azure/cogs/meta.json ================================================ { "order":{ "emotion.workbook":"Emotion Service" } } ================================================ FILE: azure/meta.json ================================================ { "order":{ "tryazure":"Try Azure", "cogs":"Cognitive Services" } } ================================================ FILE: azure/tryazure/TryAzure-Mac.workbook ================================================ --- uti: com.xamarin.workbook platform: MacNet45 packages: - id: Newtonsoft.Json version: 9.0.1 - id: Microsoft.Net.Http version: 2.2.29 - id: Microsoft.Azure.Mobile.Client version: 3.0.1 - id: Microsoft.Bcl version: 1.1.10 --- # Azure TryAppService Two NuGets - **Microsoft.Azure.Mobile.Client** & Newtonsoft.Json - have been added and require these references: ```csharp #r "Newtonsoft.Json" #r "Microsoft.WindowsAzure.Mobile" #r "Microsoft.WindowsAzure.Mobile.Ext" ``` Use the [tryappservice.azure.com](https://tryappservice.azure.com/ "tryappservice.azure.com") **Mobile App > TodoList** to create a free back-end to test. This class matches the mobile app backend that is automatically created: ```csharp using Newtonsoft.Json; using Microsoft.WindowsAzure.MobileServices; public class TodoItem { [JsonProperty(PropertyName = "id")] public string ID {get;set;} [JsonProperty(PropertyName = "text")] public string Name {get;set;} [JsonProperty(PropertyName = "complete")] public bool Done {get;set;} [Version] public string Version { get; set; } public override string ToString() { return $"{Name} is " + (Done?"done":"not done"); } } ``` Replace the URL below with your temporary, generated endpoint URL: ```csharp var mobileService = new MobileServiceClient ("https://da0cfa57-0ee0-4-231-b9ee.azurewebsites.net/"); var table = mobileService.GetTable (); ``` Now it’s possible to interact with the **Azure App Service**. The following code creates a new `TodoItem` class, inserts it into the table on the server, and retrieves the list from the server: ```csharp var rememberTo = new TodoItem {Name="buy apples"}; await table.InsertAsync (rememberTo); List todos = await table.Take (10).ToListAsync (); ``` ================================================ FILE: azure/tryazure/TryAzure-WPF.workbook ================================================ --- uti: com.xamarin.workbook platform: WPF packages: - id: Microsoft.Bcl version: 1.1.10 - id: Newtonsoft.Json version: 9.0.1 - id: Microsoft.Net.Http version: 2.2.29 - id: Microsoft.Azure.Mobile.Client version: 3.0.1 --- # Azure TryAppService Two NuGets - **Microsoft.Azure.Mobile.Client** & Newtonsoft.Json - have been added and require these references: ```csharp #r "Newtonsoft.Json" #r "Microsoft.WindowsAzure.Mobile" #r "Microsoft.WindowsAzure.Mobile.Ext" ``` Use the [tryappservice.azure.com](https://tryappservice.azure.com/ "tryappservice.azure.com") **Mobile App > TodoList** to create a free back-end to test. This class matches the mobile app backend that is automatically created: ```csharp using Newtonsoft.Json; using Microsoft.WindowsAzure.MobileServices; public class TodoItem { [JsonProperty(PropertyName = "id")] public string ID {get;set;} [JsonProperty(PropertyName = "text")] public string Name {get;set;} [JsonProperty(PropertyName = "complete")] public bool Done {get;set;} [Version] public string Version { get; set; } public override string ToString() { return $"{Name} is " + (Done?"done":"not done"); } } ``` Replace the URL below with your temporary, generated endpoint URL: ```csharp var mobileService = new MobileServiceClient ("https://da0cfa57-0ee0-4-231-b9ee.azurewebsites.net/"); var table = mobileService.GetTable (); ``` Now it’s possible to interact with the **Azure App Service**. The following code creates a new `TodoItem` class, inserts it into the table on the server, and retrieves the list from the server: ```csharp var rememberTo = new TodoItem {Name="buy apples"}; await table.InsertAsync (rememberTo); List todos = await table.Take (10).ToListAsync (); ``` ================================================ FILE: azure/tryazure/TryAzure-iOS.workbook ================================================ --- uti: com.xamarin.workbook platform: iOS packages: - id: Microsoft.Bcl version: 1.1.10 - id: Microsoft.Net.Http version: 2.2.29 - id: Microsoft.Azure.Mobile.Client version: 3.0.1 - id: Newtonsoft.Json version: 9.0.1 --- # Azure TryAppService Two NuGets - **Microsoft.Azure.Mobile.Client** & Newtonsoft.Json - have been added and require these references: ```csharp #r "Newtonsoft.Json" #r "Microsoft.WindowsAzure.Mobile" #r "Microsoft.WindowsAzure.Mobile.Ext" ``` Use the [tryappservice.azure.com](https://tryappservice.azure.com/ "tryappservice.azure.com") **Mobile App > TodoList** to create a free back-end to test. This class matches the mobile app backend that is automatically created: ```csharp using Newtonsoft.Json; using Microsoft.WindowsAzure.MobileServices; public class TodoItem { [JsonProperty(PropertyName = "id")] public string ID {get;set;} [JsonProperty(PropertyName = "text")] public string Name {get;set;} [JsonProperty(PropertyName = "complete")] public bool Done {get;set;} [Version] public string Version { get; set; } public override string ToString() { return $"{Name} is " + (Done?"done":"not done"); } } ``` Replace the URL below with your temporary, generated endpoint URL: ```csharp var mobileService = new MobileServiceClient ("https://da0cfa57-0ee0-4-231-b9ee.azurewebsites.net/"); var table = mobileService.GetTable (); ``` Now it’s possible to interact with the **Azure App Service**. The following code creates a new `TodoItem` class, inserts it into the table on the server, and retrieves the list from the server: ```csharp var rememberTo = new TodoItem {Name="buy apples"}; await table.InsertAsync (rememberTo); List todos = await table.Take (10).ToListAsync (); ``` ================================================ FILE: azure/tryazure/meta.json ================================================ { "order":{ "TryAzure-iOS.workbook":"Try Azure for iOS", "TryAzure-Mac.workbook":"Try Azure for Mac", "TryAzure-WPF.workbook":"Try Azure for WPF" } } ================================================ FILE: charts/meta.json ================================================ { "order":{ "oxyplot":"OxyPlot", "xplot":"XPlot" } } ================================================ FILE: charts/oxyplot/OxyPlot.workbook ================================================ --- id: ee57cfd4-3bc0-4069-952d-4fa85802fceb uti: com.xamarin.workbook copyright: © Copyright 2015, OxyPlot Contributors. title: Plotting with OxyPlot platforms: - Console packages: - id: OxyPlot.Core version: 1.0.0 --- # Plotting with OxyPlot ```csharp #r "OxyPlot" using OxyPlot; using OxyPlot.Series; using OxyPlot.Axes; using static System.Math; ``` ## Function Series First we create a model, and then add a data series to it. ```csharp var plot = new PlotModel { Title = "Trigonometric functions", Subtitle = "Example using the FunctionSeries", PlotType = PlotType.Cartesian }; plot.Series.Add (new FunctionSeries ( Sin, -10, 10, 0.1, "sin(x)")); plot.Series.Add (new FunctionSeries ( Cos, -10, 10, 0.1, "cos(x)")); plot.Series.Add (new FunctionSeries ( t => 5 * Cos (t), t => 5 * Sin (t), 0, 2 * PI, 0.1, "5cos(t), 5sin(t)")); ``` And finally render the result by ensuring the cell yields a `PlotModel` object as its last result. ```csharp plot ``` ## Bonus: Fun with bats! ```csharp double batFn1 (double x) => 2 * Sqrt(-Abs(Abs(x) - 1) * Abs(3 - Abs(x)) / ((Abs(x) - 1) * (3 - Abs(x)))) *   (1 + Abs(Abs(x) - 3) / (Abs(x) - 3)) * Sqrt(1 - Pow((x / 7), 2)) + (5 + 0.97 * (Abs(x - 0.5) + Abs(x + 0.5)) - 3 *   (Abs(x - 0.75) + Abs(x + 0.75))) * (1 + Abs(1 - Abs(x)) / (1 - Abs(x))); double batFn2 (double x) => -3 * Sqrt(1 - Pow((x / 7), 2)) * Sqrt(Abs(Abs(x) - 4) / (Abs(x) - 4)); double batFn3 (double x) => Abs(x / 2) - 0.0913722 * (Pow(x, 2)) - 3 + Sqrt(1 - Pow((Abs(Abs(x) - 2) - 1), 2)); double batFn4 (double x) => (2.71052 + (1.5 - .5 * Abs(x)) - 1.35526 * Sqrt(4 - Pow((Abs(x) - 1), 2))) *   Sqrt(Abs(Abs(x) - 1) / (Abs(x) - 1)) + 0.9; var plot = new PlotModel { Title = "Fun with Bats" }; plot.Series.Add (new FunctionSeries (batFn1, -8, 8, 0.0001));  plot.Series.Add (new FunctionSeries (batFn2, -8, 8, 0.0001));  plot.Series.Add (new FunctionSeries (batFn3, -8, 8, 0.0001));  plot.Series.Add (new FunctionSeries (batFn4, -8, 8, 0.0001)); plot; ``` ## Heat Map Series ```csharp var plot = new PlotModel { Title = "Heatmap" }; // Color axis (the X and Y axes are generated automatically) plot.Axes.Add(new LinearColorAxis { Palette = OxyPalettes.Rainbow(100) }); // generate 1d normal distribution var singleData = new double[100]; for (int x = 0; x < 100; ++x) singleData[x] = Exp ((-1.0 / 2.0) * Pow (((double)x - 50.0) / 20.0, 2.0)); // generate 2d normal distribution var data = new double[100, 100]; for (int x = 0; x < 100; ++x) { for (int y = 0; y < 100; ++y) data[y, x] = singleData[x] * singleData[(y + 30) % 100] * 100; } var heatMapSeries = new HeatMapSeries { X0 = 0, X1 = 99, Y0 = 0, Y1 = 99, Interpolate = true, RenderMethod = HeatMapRenderMethod.Bitmap, Data = data }; plot.Series.Add (heatMapSeries); plot; ``` > ℹ️ This workbook was adapted from the official [OxyPlot documentation](http://docs.oxyplot.org/en/latest/). ================================================ FILE: charts/oxyplot/meta.json ================================================ { "order":{ "OxyPlot.workbook":"Get Started with OxyPlot" } } ================================================ FILE: charts/xplot/XPlot.workbook ================================================ --- uti: com.xamarin.workbook id: 036795c2-a071-4ad5-9375-d0c82482d37d title: XPlot platforms: - Console packages: - id: XPlot.Plotly version: 1.4.2 --- ```csharp #r "XPlot.Plotly" ``` # Plotly Example Random data, 3D scatter plot. ```csharp using XPlot.Plotly; var traces = new List(); var rnd = new Random(); (List x, List y, List z) GenerateNumbers (int count) { var x = new List(); var y = new List(); var z = new List(); for (int digit = 0; digit < count; digit ++) { x.Add(rnd.NextDouble()*50); y.Add(rnd.NextDouble()*50); z.Add(rnd.NextDouble()*50); } return (x, y, z); } for (int i = 0; i < 3; i++) { var (x, y, z) = GenerateNumbers (25); string randomcolor = $"rgb({rnd.Next(50, 200)},{rnd.Next(50, 200)},{rnd.Next(50, 200)})"; var trace = new Graph.Scatter3d() { x = x, y = y, z = z, mode = "markers", marker = new Graph.Marker() { color = randomcolor, size = 5.0, symbol = "circle", line = new Graph.Line() { color = "rgb(0,0,0)", width = 0.0 } }, line = new Graph.Line() { color = "#1f77b4", width = 1.0 } }; traces.Add(trace); } var layout = new Layout.Layout() { title = "Dots In Space", autosize = false, margin = new Graph.Margin() { l = 0, r = 0, b = 0, t = 65 } }; var scatterplot = Chart.Plot(traces.ToArray(), layout); scatterplot.WithWidth(800); scatterplot.WithHeight(500); scatterplot ``` ================================================ FILE: charts/xplot/meta.json ================================================ { "order":{ "XPlot.workbook":"Get Started with XPlot" } } ================================================ FILE: csharp/async/README.md ================================================ Async-Await Workbook ========= A simple `callback` versus `await` demo related to [Xamarin's async support overview](https://developer.xamarin.com/guides/cross-platform/advanced/async_support_overview/). ![](Screenshots/async.png) ================================================ FILE: csharp/async/async-await-wpf.workbook ================================================ --- uti: com.xamarin.workbook platform: WPF packages: [] --- # Async 101 A quick explanation of why `async-await` code is easier to read/follow than old-style callbacks. Read more at [Xamarin's async support overview](https://developer.xamarin.com/guides/cross-platform/advanced/async_support_overview/). ## The Old Way - Callbacks 1. Get all the config out of the way ```csharp var webClient = new System.Net.WebClient(); webClient.Encoding = System.Text.Encoding.UTF8; var xmlUri = new Uri("http://api.geonames.org/earthquakesXML?north=44.1&south=-9.9&east=-22.4&west=55.2&username=bertt"); ``` 2. We have to set up the 'callback' handler which is called when the network operation completes ```csharp var response1 = ""; webClient.DownloadStringCompleted += (s, e) => { response1 = e.Result; // get the downloaded text }; webClient.DownloadStringAsync(xmlUri); ``` 3. *Then* we call the actual method - confusing huh? The code we just wrote above gets executed *after* this completes! ```csharp // this will be blank because the completed even won't have fired in most cases // type `response1` in the interactive window to confirm that the XML was downloaded response1 ``` (we'll check on the response later) ## The New Way - Async 1. Get all the config out of the way ```csharp #r "System.Net.Http" ``` ```csharp using System.Net.Http; using System.Threading.Tasks; using System.IO; var jsonUri = "http://api.geonames.org/earthquakesJSON?north=44.1&south=-9.9&east=-22.4&west=55.2&username=bertt"; ``` 2. The network call code is in a logical place ```csharp var response2 = await new HttpClient().GetStringAsync(jsonUri); ``` 3. *Then* we do something with the result - much easier to follow what's happening in the code! ```csharp Console.WriteLine(response2.Substring(0,100) + "..."); ``` ## Finally... Check `response1` from the first example again - the completed callback has probably been executed by now... ```csharp response1 ``` ================================================ FILE: csharp/async/async-await.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 --- # Async 101 A quick explanation of why `async-await` code is easier to read/follow than old-style callbacks. Read more at [Xamarin's async support overview](https://developer.xamarin.com/guides/cross-platform/advanced/async_support_overview/). ## The Old Way - Callbacks 1. Get all the config out of the way ```csharp var webClient = new System.Net.WebClient(); webClient.Encoding = System.Text.Encoding.UTF8; var xmlUri = new Uri("http://api.geonames.org/earthquakesXML?north=44.1&south=-9.9&east=-22.4&west=55.2&username=bertt"); ``` 1. We have to set up the 'callback' handler which is called when the network operation completes ```csharp var response1 = ""; webClient.DownloadStringCompleted += (s, e) => { response1 = e.Result; // get the downloaded text }; webClient.DownloadStringAsync(xmlUri); ``` 1. *Then* we call the actual method - confusing huh? The code we just wrote above gets executed *after* this completes! ```csharp // this will be blank because the completed even won't have fired in most cases // type `response1` in the interactive window to confirm that the XML was downloaded response1 ``` \(we'll check on the response later) ## The New Way - Async 1. Get all the config out of the way ```csharp #r "System.Net.Http" ``` ```csharp using System.Net.Http; using System.Threading.Tasks; using System.IO; var jsonUri = "http://api.geonames.org/earthquakesJSON?north=44.1&south=-9.9&east=-22.4&west=55.2&username=bertt"; ``` 1. The network call code is in a logical place ```csharp var response2 = await new HttpClient().GetStringAsync(jsonUri); ``` 1. *Then* we do something with the result - much easier to follow what's happening in the code! ```csharp Console.WriteLine(response2.Substring(0,100) + "..."); ``` ## Finally... Check `response1` from the first example again - the completed callback has probably been executed by now... ```csharp response1 ``` ================================================ FILE: csharp/async/meta.json ================================================ { "order":{ "async-await.workbook":"Async Await", "async-await-wpf.workbook":"Async Await for WPF" } } ================================================ FILE: csharp/collections/README.md ================================================ Collections: Arrays Workbook ========= Quick explanation of how C# arrays work. ![](Screenshots/arrays.png) ================================================ FILE: csharp/collections/arrays.workbook ================================================ --- uti: com.xamarin.workbook platforms: - Console --- # Collections: Arrays An array is a simple data structure: * it stores a collection of data elements, * it has a fixed size, * it only contains elements that match the declared type. ## Initialization Syntax The easiest way to create an array with known values is using C#'s initialization syntax: ```csharp int[] primes = {2,3,5,7,11,13,17,19,31,37,41,43,47,53,59,61,67,71} ``` Each value in the array has an `index`, and we can get a value by its index: ```csharp primes[9] // prints the 10th prime - arrays are zero-based! ``` ## Create a fixed size array Another way to create an array is to declare the array with a known size (20 elements in this example), and then set each value using the index (remember it starts at zero): ```csharp var squares = new int[20]; // 20 elements with default(int) value for (var i = 0; i <20; i++) { squares[i] = i*i; } squares ``` The values in the array can then be retrieved by their index: ```csharp squares[4] // 5th square ``` The value at an index can also be set to a different value: ```csharp squares[4] = 444 // replace the value in index '4' ``` ## Declare and then set If the size of the array is initially unknown, an array variable can be declared without specifying the size. ```csharp string[] dwarves; // ... dwarves = new string[4]; dwarves[0] = "Sleepy"; dwarves[1] = "Sneezy"; dwarves[2] = "Dopey"; dwarves[3] = "Doc"; dwarves ``` This highlights a problem with arrays – once the size has been declared, we can't easily change it to add another three dwarves: `dwarves[4] = "Bashful"` will result in an `IndexOutOfRangeException`. The only option is to assign a totally new array to the variable: ```csharp dwarves = new string[7]; dwarves[0] = "Sleepy"; dwarves[1] = "Sneezy"; dwarves[2] = "Dopey"; dwarves[3] = "Doc"; dwarves[4] = "Bashful"; dwarves[5] = "Grumpy"; dwarves[6] = "Happy"; dwarves ``` ## Not just simple Types Arrays can also store objects, not just `string` and `int`: ```csharp class Person { public string FirstName {get;set;} public string LastName {get;set;} public override string ToString() => $"{FirstName} {LastName}"; } var goodguys = new Person[2]; goodguys[0] = new Person {FirstName="Snow",LastName="White"}; goodguys[1] = new Person {FirstName="Humbert",LastName="Huntsman"}; ``` ```csharp goodguys // view the array data ``` ## Pros & Cons of Arrays ### Pros * Simple and easy to understand * Fast and efficient ### Cons * Cannot be resized * Elements cannot be added or removed Other collection types like `List` and `Dictionary` address some of the array's limitations. ================================================ FILE: csharp/collections/meta.json ================================================ { "order":{ "arrays.workbook":"Arrays" } } ================================================ FILE: csharp/csharp6/README.md ================================================ C# 6 Workbook ========= A smattering of C# 6 syntax examples from this [C# 6 overview](https://developer.xamarin.com/guides/cross-platform/advanced/csharp_six/). ![](Screenshots/csharp6.png) ================================================ FILE: csharp/csharp6/csharp6.workbook ================================================ --- uti: com.xamarin.workbook platforms: - Console --- # Using C# 6 Some examples from Xamarin's [intro to C# 6](https://developer.xamarin.com/guides/cross-platform/advanced/csharp_six/). * Null-conditional operator * String Interpolation * Expression-bodied Function Members * Auto-property Initialization * Index Initializers * using static ## Null-conditional operator The `?.` operator automatically does a null-check before referencing the specified member. The example string array below has a `null` entry: ```csharp var names = new string[] { "Foo", null }; ``` In C# 5, a null-check is required before accessing the `.Length` property: ```csharp // C# 5 int secondLength = 0; if (names[1] != null) secondLength = names[1].Length; ``` C# 6 allows the length to be queried in a single line; the entire statement returns `null` if any object is null. ```csharp var length0 = names[0]?.Length; // 3 var length1 = names[1]?.Length; // null ``` This can be used in conjunction with the `??` null coalescing operator to set a default value (such as `0`) in the example below: ```csharp var lengths = names.Select (names => names?.Length ?? 0); //[3, 0] ``` ## String Interpolation Previously strings were built in a number of different ways: ```csharp var animal = "Monkeys"; var food = "bananas"; var out1 = String.Format ("{0} love to eat {1}", animal, food); var out2 = animal + " love to eat " + food; // or even StringBuilder ``` C# 6 provides a simple syntax where the fieldname can be embedded directly in the string: ```csharp $"{animal} love to eat {food}" ``` String-formatting can also be done with this syntax: ```csharp var values = new int[] { 1, 2, 3, 4, 12, 123456 }; foreach (var s in values.Select (i => $"The value is {i,10:N2}.")) { Console.WriteLine (s); } ``` ## Expression-bodied Function Members The `ToString` override in the following class is an expression-bodied function - a more succinct declaration syntax. ```csharp class Person { public string FirstName { get; } public string LastName { get; } public Person (string firstname, string lastname) { FirstName = firstname; LastName = lastname; } // note there is no explicit `return` keyword public override string ToString () => $"{LastName}, {FirstName} {LastName}"; } ``` `void` expression bodied functions are also allowed so long as the expression is a statement: ```csharp public void Log(string message) => System.Console.WriteLine($"{DateTime.Now.ToString ("s", System.Globalization.CultureInfo.InvariantCulture )}: {message}"); ``` This simple example calls these two methods: ```csharp Log(new Person("James", "Bond").ToString()) ``` ## Auto-property Initialization Properties (ie. specified with `{get;set;}`) can be initialized inline with C# 6: ```csharp class Todo { public bool Done { get; set; } = false; public DateTime Created { get; } = DateTime.Now; public string Description { get; } public Todo (string description) { this.Description = description; // can assign (only in constructor!) } public override string ToString () => $"'{Description}' was created on {Created}"; } ``` ```csharp new Todo("buy apples") ``` ## Index Initializers Dictionary-style data structures let you specify key/value types with a simple object-initializer-like syntax: ```csharp var userInfo = new Dictionary { ["Created"] = DateTime.Now, ["Due"] = DateTime.Now.AddSeconds(60 * 60 * 24), ["Task"] = "buy lettuce" }; ``` ## using static Enumerations, and certain classes such as System.Math, are primarily holders of static values and functions. In C# 6, you can import all static members of a type with a single using static statement: ```csharp using static System.Math; ``` C# 6 code can then reference the static members directly, avoiding repetition of the class name (eg. `Math.PI` becomes `PI`): ```csharp public class Location { public Location (double lat, double @long) {Latitude = lat; Longitude = @long;} public double Latitude = 0; public double Longitude = 0; } static public double MilesBetween(Location loc1, Location loc2) { double rlat1 = PI * loc1.Latitude / 180; double rlat2 = PI * loc2.Latitude / 180; double theta = loc1.Longitude - loc2.Longitude; double rtheta = PI * theta / 180; double dist = Sin(rlat1) * Sin(rlat2) + Cos(rlat1) * Cos(rlat2) * Cos(rtheta); dist = Acos(dist); dist = dist*180/PI; dist = dist*60*1.1515; return dist; //miles } ``` ```csharp MilesBetween (new Location(-12,22), new Location(-13,33)) ``` ================================================ FILE: csharp/csharp6/meta.json ================================================ { "order":{ "csharp6.workbook":"Using C# 6" } } ================================================ FILE: csharp/csharp7/csharp7.workbook ================================================ --- uti: com.xamarin.workbook title: What's New in C# 7 | C# Guide platforms: - Console --- > ⚠️ C# 7 is supported in Xamarin Workbooks 1.2 (or newer). > Please update to version 1.2 if you experience issues with this Workbook (you may need to switch to the Alpha or Beta channel). # What's new in C# 7 C# 7 adds a number of new features to the C# language: * `out` variables * You can declare `out` values inline as arguments to the method where they are used. * Tuples * You can create lightweight, unnamed types that contain multiple public fields. Compilers and IDE tools understand the semantics of these types. * Pattern Matching * You can create branching logic based on arbitrary types and values of the members of those types. * `ref` locals and returns * Method arguments and local variables can be references to other storage. * Local Functions * You can nest functions inside other functions to limit their scope and visibility. * More expression-bodied members * The list of members that can be authored using expressions has grown. * `throw` Expressions * You can throw exceptions in code constructs that previously were not allowed because `throw` was a statement. * Generalized async return types * Methods declared with the `async` modifier can return other types in addition to `Task` and `Task`. * Numeric literal syntax improvements * New tokens improve readability for numeric constants. The remainder of this topic discusses each of the features. For each feature, you'll learn the reasoning behind it. You'll learn the syntax. You'll see some sample scenarios where using the new feature will make you more productive as a developer. ## `out` variables The existing syntax that supports `out` parameters has been improved in this version. Previously, you would need to separate the declaration of the out variable and its initialization into two different statements: ```csharp var input = "8675309"; int numericResult; if (int.TryParse(input, out numericResult)) Console.WriteLine(numericResult); else Console.WriteLine("Could not parse input"); ``` You can now declare `out` variables in the argument list of a method call, rather than writing a separate declaration statement: ```csharp if (int.TryParse(input, out int result)) Console.WriteLine(result); else Console.WriteLine("Could not parse input"); ``` You may want to specify the type of the `out` variable for clarity, as shown above. However, the language does support using an implicitly typed local variable: ```csharp if (int.TryParse(input, out var answer)) Console.WriteLine(answer); else Console.WriteLine("Could not parse input"); ``` * The code is easier to read. * You declare the out variable where you use it, not on another line above. * No need to assign an initial value. * By declaring the `out` variable where it is used in a method call, you can't accidentally use it before it is assigned. The most common use for this feature will be the `Try` pattern. In this pattern, a method returns a `bool` indicating success or failure and an`out` variable that provides the result if the method succeeds. ## Tuples C# provides a rich syntax for classes and structs that is used to explain your design intent. But sometimes that rich syntax requires extra work with minimal benefit. You may often write methods that need a simple structure containing more than one data element. To support these scenarios *tuples* were added to C#. Tuples are lightweight data structures that contain multiple fields to represent the data members. The fields are not validated, and you cannot define your own methods > ℹ️  Tuples were available before C# 7 as an API, but had many limitations. Most importantly, the members of these tuples were named `Item1`, `Item2` and so on. The language support enables semantic names for the fields of a Tuple. You can create a tuple by assigning each member to a value: ```csharp var letters = ("a", "b"); ``` That assignment creates a tuple whose members are `Item1` and `Item2`, following the existing System.Tuple syntax. You can modify that assignment to create a tuple that provides semantic names to each of the members of the tuple: ```csharp (string Alpha, string Beta) namedLetters = ("a", "b"); ``` > ℹ️  The new tuples features require the `System.ValueTuple` type. For Visual Studio 15 Preview 5 and earlier preview releases, you must add the NuGet package "System.ValueTuple", available in the pre-release stream. The `namedLetters` tuple contains fields referred to as `Alpha` and `Beta`. In a tuple assignment, you can also specify the names of the fields on the right-hand side of the assignment: ```csharp var alphabetStart = (Alpha: "a", Beta: "b"); ``` The language allows you to specify names for the fields on both the left and right-hand side of the assignment: ```csharp (string First, string Second) firstLetters = (Alpha: "a", Beta: "b"); ``` The line above generates a warning, `CS8123`, telling you that the names on the right side of the assignment, `Alpha` and `Beta` are ignored because they conflict with the names on the left side, `First` and `Second`. The examples above show the basic syntax to declare tuples. Tuples are most useful as return types for `private` and `internal` methods. Tuples provide a simple syntax for those methods to return multiple discrete values: You save the work of authoring a `class` or a `struct` that defines the type returned. There is no need for creating a new type. Creating a tuple is more efficient and more productive. It is a simpler, lightweight syntax to define a data structure that carries more than one value. The example method below returns the minimum and maximum values found in a sequence of integers: ```csharp private static (int Max, int Min) Range(IEnumerable numbers) { int min = int.MaxValue; int max = int.MinValue; foreach(var n in numbers) { min = (n < min) ? n : min; max = (n > max) ? n : max; } return (max, min); } ``` Using tuples in this way offers several advantages: * You save the work of authoring a `class` or a `struct` that defines the type returned. * You do not need to create new type. * The language enhancements removes the need to call the `System.Tuple.Create()` methods. The declaration for the method provides the names for the fields of the tuple that is returned. When you call the method, the return value is a tuple whose fields are `Max` and `Min`: ```csharp int [] numbers = { 97, 243, 254, 41, 132, 26, 167, 19, 201, 252, 119, 68, 17, 66, 131 }; var range = Range(numbers); ``` There may be times when you want to unpackage the members of a tuple that were returned from a method. You can do that by declaring separate variables for each of the values in the tuple. This is called *deconstructing* the tuple: ```csharp (int max, int min) = Range(numbers); ``` You can also provide a similar deconstruction for any type in .NET. This is done by writing a `Deconstruct` method as a member of the class. That `Deconstruct` method provides a set of `out` arguments for each of the properties you want to extract. Consider this `Point` class that provides a deconstructor method that extracts the `X` and `Y` coordinates: ```csharp public class Point { public Point(double x, double y) { this.X = x; this.Y = y; } public double X { get; } public double Y { get; } public void Deconstruct(out double x, out double y) { x = this.X; y = this.Y; } } ``` You can extract the individual fields by assigning a tuple to a `Point`: ```csharp var p = new Point(3.14, 2.71); (double X, double Y) = p; ``` You are not bound by the names defined in the `Deconstruct` method. You can rename the extract variables as part of the assignment: ```csharp (double horizontalDistance, double verticalDistance) = p; ``` ## Pattern matching *Pattern matching* is a feature that allows you to implement method dispatch on properties other than the type of an object. You're probably already familiar with method dispatch based on the type of an object. In Object Oriented programming, virtual and override methods provide language syntax to implement method dispatching based on an object's type. Base and Derived classes provide different implementations. Pattern matching expressions extend this concept so that you can easily implement similar dispatch patterns for types and data elements that are not related through an inheritance hierarchy. Pattern matching supports `is` expressions and `switch` expressions. Each enables inspecting an object and its properties to determine if that object satisfies the sought pattern. You use the `when` keyword to specify additional rules to the pattern. ### `is` expressions The `is` pattern expressions extend the familiar `is` operator to query a object beyond its type. Let's start with a simple scenario. We'll add capabilities to this scenario that demonstrate how pattern matching expressions make algorithms that work with unrelated types easy. We'll start with a method that computes the sum of a number of die rolls: ```csharp public static int DiceSum(IEnumerable values) => values.Sum() ``` You might quickly find that you need to find the sum of die rolls where some of the rolls are made with more than one die. Part of the input sequence may be multiple results instead of a single number: ```csharp public static int DiceSum2(IEnumerable values) { var sum = 0; foreach(var item in values) { if (item is int val) sum += val; else if (item is IEnumerable subList) sum += DiceSum2(subList); } return sum; } ``` The `is` pattern expression works quite well in this scenario. As part of checking the type, you write a variable initialization. This creates a new variable of the validated runtime type. As you keep extending these scenarios, you may find that you build more `if` and `else if` statements. Once that becomes unwieldy, you'll likely want to switch to `switch` pattern expressions. ### `switch` expressions The `switch` pattern expression has a familiar syntax, based on the `switch` statement already part of the C# language. Let's translate the existing code to use a `switch` expression before adding new cases: ```csharp public static int DiceSum3(IEnumerable values) { var sum = 0; foreach (var item in values) { switch (item) { case int val: sum += val; break; case IEnumerable subList: sum += DiceSum3(subList); break; } } return sum; } ``` The `switch` expressions have a slightly different syntax than the `is` expressions, where you declare the type and variable at the beginning of the `case` expression. The `switch` expressions also support constants. This can save time by factoring out simple cases: ```csharp public static int DiceSum4(IEnumerable values) { var sum = 0; foreach (var item in values) { switch (item) { case 0: break; case int val: sum += val; break; case IEnumerable subList when subList.Any(): sum += DiceSum4(subList); break; case IEnumerable subList: break; case null: break; default: throw new InvalidOperationException("unknown item type"); } } return sum; } ``` The code above adds cases for `0` as a special case of `int`, and `null` as a special case when there is no input. This demonstrates one important new feature in switch pattern expressions: the order of the `case` expressions now matters. The `0` case must appear before the general `int` case. Otherwise, the first pattern to match would be the `int` case, even when the value is `0`. This same behavior enables the special case for an empty input sequence. You can see that the case for an `IEnumerable` item that has elements must appear before the general `IEnumerable` case. This version has also added a `default` case. The `default` case is always evaluated last, regardless of the order it appears in the source. For that reason, convention is to put the `default` case last. Finally, let's add one last `case` for a new style of die. Some games use percentile dice to represent larger ranges of numbers. > ℹ️  Two 10-sided percentile dice can represent every number from 0 through 99. One die has sides labelled `00`, `10`, `20`, ... `90`. The other die has sides labeled `0`, `1`, `2`, ... `9`. Add the two die values together and you can get every number from 0 through 99. To add this kind of die to your collection, first define a type to represent the percentile die: ```csharp public struct PercentileDie { public int Value { get; } public int Multiplier { get; } public PercentileDie(int multiplier, int value) { this.Value = value; this.Multiplier = multiplier; } } ``` Then, add a `case` expression for the new type: ```csharp public static int DiceSum5(IEnumerable values) { var sum = 0; foreach (var item in values) { switch (item) { case 0: break; case int val: sum += val; break; case PercentileDie die: sum += die.Multiplier * die.Value; break; case IEnumerable subList when subList.Any(): sum += DiceSum5(subList); break; case IEnumerable subList: break; case null: break; default: throw new InvalidOperationException("unknown item type"); } } return sum; } ``` The new syntax for pattern matching expressions makes it easier to create dispatch algorithms based on an object's type, or other properties, using a clear and concise syntax. Pattern matching expressions enable these constructs on data types that are unrelated by inheritance. ## Local functions Many designs for classes include methods that are called from only one location. These additional private methods keep each method small and focused. However, they can make it harder to understand a class when reading it the first time. These methods must be understood outside of the context of the single calling location. For those designs, *local functions* enable you to declare methods inside the context of another method. This makes it easier for readers of the class to see that the local method is only called from the context in which is it declared. There are two very common use cases for local functions: public iterator methods and public async methods. Both types of methods generate code that reports errors later than programmers might expect. In the case of iterator methods, any exceptions are observed only when calling code that enumerates the returned sequence. In the case of async methods, any exceptions are only observed when the returned `Task` is awaited. Let's start with an iterator method: ```csharp public static IEnumerable AlphabetSubset(char start, char end) { if ((start < 'a') || (start > 'z')) throw new ArgumentOutOfRangeException(paramName: nameof(start), message: "start must be a letter"); if ((end < 'a') || (end > 'z')) throw new ArgumentOutOfRangeException(paramName: nameof(end), message: "end must be a letter"); if (end <= start) throw new ArgumentException($"{nameof(end)} must be greater than {nameof(start)}"); for (var c = start; c < end; c++) yield return c; } ``` Examine the code below that calls the iterator method incorrectly: ```csharp var resultSet = AlphabetSubset('f', 'a'); Console.WriteLine("iterator created"); foreach (var thing in resultSet) Console.Write($"{thing}, "); ``` The exception is thrown when `resultSet` is iterated, not when `resultSet` is created. In this contained example, most developers could quickly diagnose the problem. However, in larger codebases, the code that creates an iterator often isn't as close to the code that enumerates the result. You can refactor the code so that the public method validates all arguments, and a private method generates the enumeration: ```csharp public static IEnumerable AlphabetSubset2(char start, char end) { if ((start < 'a') || (start > 'z')) throw new ArgumentOutOfRangeException(paramName: nameof(start), message: "start must be a letter"); if ((end < 'a') || (end > 'z')) throw new ArgumentOutOfRangeException(paramName: nameof(end), message: "end must be a letter"); if (end <= start) throw new ArgumentException($"{nameof(end)} must be greater than {nameof(start)}"); return alphabetSubsetImplementation(start, end); } private static IEnumerable alphabetSubsetImplementation(char start, char end) { for (var c = start; c < end; c++) yield return c; } ``` This refactored version will throw exceptions immediately because the public method is not an iterator method; only the private method uses the `yield return` syntax. However, there are potential problems with this refactoring. The private method should only be called from the public interface method, because otherwise all argument validation is skipped. Readers of the class must discover this fact by reading the entire class and searching for any other references to the `alphabetSubsetImplementation` method. You can make that design intent more clear by declaring the `alphabetSubsetImplementation` as a local function inside the public API method: ```csharp public static IEnumerable AlphabetSubset3(char start, char end) { if ((start < 'a') || (start > 'z')) throw new ArgumentOutOfRangeException(paramName: nameof(start), message: "start must be a letter"); if ((end < 'a') || (end > 'z')) throw new ArgumentOutOfRangeException(paramName: nameof(end), message: "end must be a letter"); if (end <= start) throw new ArgumentException($"{nameof(end)} must be greater than {nameof(start)}"); return alphabetSubsetImplementation(); IEnumerable alphabetSubsetImplementation() { for (var c = start; c < end; c++) yield return c; } } ``` The version above makes it clear that the local method is referenced only in the context of the outer method. The rules for local functions also ensure that a developer can't accidentally call the local function from another location in the class and bypass the argument validation. The same technique can be employed with `async` methods to ensure that exceptions arising from argument validation are thrown before the asynchronous work begins: ```csharp public Task PerformLongRunningWork(string address, int index, string name) { if (string.IsNullOrWhiteSpace(address)) throw new ArgumentException(message: "An address is required", paramName: nameof(address)); if (index < 0) throw new ArgumentOutOfRangeException(paramName: nameof(index), message: "The index must be non-negative"); if (string.IsNullOrWhiteSpace(name)) throw new ArgumentException(message: "You must supply a name", paramName: nameof(name)); return longRunningWorkImplementation(); async Task longRunningWorkImplementation() { var interimResult = await FirstWork(address); var secondResult = await SecondStep(index, name); return $"The results are {interimResult} and {secondResult}. Enjoy."; Task FirstWork(string x) => Task.FromResult (x); Task SecondStep(int i, string x) => Task.FromResult ($"{x}: {i}"); } } ``` > ℹ️  Some of the designs that are supported by local functions could also be accomplished using *lambda expressions*. ## More expression-bodied members C# 6 introduced expression-bodied members for member functions, and read-only properties. C# 7 expands the allowed members that can be implemented as expressions. In C# 7, you can implement *constructors*, *finalizers*, and `get` and `set` accessors on *properties* and *indexers*. The following code shows examples of each: ```csharp class ExpressionMembersExample { // Expression-bodied constructor public ExpressionMembersExample(string label) => this.Label = label; // Expression-bodied finalizer ~ExpressionMembersExample() => Console.Error.WriteLine("Finalized!"); private string label; // Expression-bodied get / set accessors. public string Label { get => label; set => this.label = value ?? "Default label"; } } ``` > ℹ️  This example does not need a finalizer, but it is shown to demonstrate the syntax. You should not implement a finalizer in your class unless it is necessary to release unmanaged resources. You should also consider using the `System.Runtime.InteropServices.SafeHandle` class instead of managing unmanaged resources directly. These new locations for expression-bodied members represent an important milestone for the C# language: These features were implemented by community members working on the open-source [Roslyn](https://github.com/dotnet/Roslyn) project. ## Throw expressions In C#, `throw` has always been a statement. Because `throw` is a statement, not an expression, there were C# constructs where you could not use it. These included conditional expressions, null coalescing expressions, and some lambda expressions. The addition of expression-bodied members adds more locations where `throw` expressions would be useful. So that you can write any of these constructs, C# 7 introduces *throw expressions*. The syntax is the same as you've always used for `throw` statements. The only difference is that now you can place them in new locations, such as in a conditional expression: ```csharp class ExpressionMembersExample { private string name; public string Name { get => name; set => name = value ?? throw new ArgumentNullException(paramName: nameof(value), message: "New name must not be null"); } } ``` This features enables using throw expressions in initialization expressions: ```csharp class ConfigResource { } static ConfigResource LoadConfigResourceOrDefault () => null; private ConfigResource loadedConfig = LoadConfigResourceOrDefault() ?? throw new InvalidOperationException("Could not load config"); ``` Previously, those initializations would need to be in a constructor, with the throw statements in the body of the constructor: ```csharp class ApplicationOptions { public ApplicationOptions() { var loadedConfig = LoadConfigResourceOrDefault(); if (loadedConfig == null) throw new InvalidOperationException("Could not load config"); } } ``` > ℹ️  Both of the preceding constructs will cause exceptions to be thrown during the construction of an object. Those are often difficult to recover from. For that reason, designs that throw exceptions during construction are discouraged. ## Numeric literal syntax improvements Misreading numeric constants can make it harder to understand code when reading it for the first time. This often occurs when those numbers are used as bit masks or other symbolic rather than numeric values. C# 7 includes two new features to make it easier to write numbers in the most readable fashion for the intended use: *binary literals*, and *digit separators*. For those times when you are creating bit masks, or whenever a binary representation of a number makes the most readable code, write that number in binary: ```csharp public const int One = 0b0001; public const int Two = 0b0010; public const int Four = 0b0100; public const int Eight = 0b1000; ``` The `0b` at the beginning of the constant indicates that the number is written as a binary number. Binary numbers can get very long, so it's often easier to see the bit patterns by introducing the `_` as a digit separator: ```csharp public const int Sixteen = 0b0001_0000; public const int ThirtyTwo = 0b0010_0000; public const int SixtyFour = 0b0100_0000; public const int OneHundredTwentyEight = 0b1000_0000; ``` The digit separator can appear anywhere in the constant. For base 10 numbers, it would be common to use it as a thousands separator: ```csharp public const long BillionsAndBillions = 100_000_000_000; ``` The digit separator can be used with `decimal`, `float` and `double` types as well: ```csharp public const double AvogadroConstant = 6.022_140_857_747_474e23; public const decimal GoldenRatio = 1.618_033_988_749_894_848_204_586_834_365_638_117_720_309_179M; ``` Taken together, you can declare numeric constants with much more readability. ## Ref locals and returns This feature enables algorithms that use and return references to variables defined elsewhere. One example is working with large matrices, and finding a single location with certain characteristics. One method would return the two indices for a single location in the matrix: ```csharp public static (int i, int j) Find(int[,] matrix, Func predicate) { for (int i = 0; i < matrix.GetLength(0); i++) for (int j = 0; j < matrix.GetLength(1); j++) if (predicate(matrix[i, j])) return (i, j); return (-1, -1); // Not found } ``` There are many issues with this code. First of all, it's a public method that's returning a tuple. The language supports this, but user defined types (either classes or structs) are preferred for public APIs. Second, this method is returning the indices to the item in the matrix. That leads callers to write code that uses those indices to dereference the matrix and modify a single element: ```csharp var matrix = new int[,] { { 5, 9, 11, 4}, { 3, 10, 18, 9}, { 1, 19, 42, 2}, { 0, 3, 4, 31}, }; var indices = Find(matrix, (val) => val == 42); Console.WriteLine(indices); matrix[indices.i, indices.j] = 24; ``` You'd rather write a method that returns a *reference* to the element of the matrix that you want to change. You could only accomplish this by using unsafe code and returning a pointer to an `int` in previous versions. Let's walk through a series of changes to demonstrate the ref local feature and show how to create a method that returns a reference to internal storage. Along the way, you'll learn the rules of the ref return and ref local feature that protects you from accidentally misusing it. Start by modifying the `Find` method declaration so that it returns a `ref int` instead of a tuple. Then, modify the return statement so it returns the value stored in the matrix instead of the two indices: ```csharp // Note that this won't compile. // Method declaration indicates ref return, // but return statement specifies a value return. // // public static ref int Find2(int[,] matrix, Func predicate) // { // for (int i = 0; i < matrix.GetLength(0); i++) // for (int j = 0; j < matrix.GetLength(1); j++) // if (predicate(matrix[i, j])) // return matrix[i, j]; // throw new InvalidOperationException("Not found"); // } ``` When you declare that a method returns a `ref` variable, you must also add the `ref` keyword to each return statement. That indicates return by reference, and helps developers reading the code later remember that the method returns by reference: ```csharp public static ref int Find3(int[,] matrix, Func predicate) { for (int i = 0; i < matrix.GetLength(0); i++) for (int j = 0; j < matrix.GetLength(1); j++) if (predicate(matrix[i, j])) return ref matrix[i, j]; throw new InvalidOperationException("Not found"); } ``` Now that the method returns a reference to the integer value in the matrix, you need to modify where it's called. The `var` declaration means that `valItem` is now an `int` rather than a tuple: ```csharp var valItem = Find3(matrix, (val) => val == 42); Console.WriteLine(valItem); valItem = 24; Console.WriteLine(matrix[4, 2]); ``` The second `WriteLine` statement in the example above prints out the value `42`, not `24`. The variable `valItem` is an `int`, not a `ref int`. The `var` keyword enables the compiler to specify the type, but will not implicitly add the `ref` modifier. Instead, the value referred to by the `ref return` is *copied* to the variable on the left-hand side of the assignment. The variable is not a `ref` local. In order to get the result you want, you need to add the `ref` modifier to the local variable declaration to make the variable a reference when the return value is a reference: ```csharp ref var item = ref Find3(matrix, (val) => val == 42); Console.WriteLine(item); item = 24; Console.WriteLine(matrix[4, 2]); ``` Now, the second `WriteLine` statement in the example above will print out the value `24`, indicating that the storage in the matrix has been modified. The local variable has been declared with the `ref` modifier, and it will take a `ref` return. You must initialize a `ref` variable when it is declared, you cannot split the declaration and the initialization. The C# language has two other rules that protect you from misusing the `ref` locals and returns: * You cannot assign a value to a `ref` variable. * That disallows statements like `ref int i = sequence.Count();` * You cannot return a `ref` to a variable whose lifetime does not extend beyond the execution of the method. * That means you cannot return a reference to a local variable, or similar scope. These rules ensure that you cannot accidentally mix value variables and reference variables. They also ensure that you cannot have a reference variable refer to storage that is a candidate for garbage collection. The addition of ref locals and ref returns enable algorithms that are more efficient by avoiding copying values, or performing dereferencing operations multiple times. ================================================ FILE: csharp/csharp7/index.workbook ================================================ --- uti: com.xamarin.workbook title: What's New in C# 7 | C# Guide platforms: - Console --- > ⚠️ C# 7 is supported in Xamarin Workbooks 1.2 (or newer). > Please update to version 1.2 if you experience issues with this Workbook (you may need to switch to the Alpha or Beta channel). # What's new in C# 7 C# 7 adds a number of new features to the C# language: * `out` variables * You can declare `out` values inline as arguments to the method where they are used. * Tuples * You can create lightweight, unnamed types that contain multiple public fields. Compilers and IDE tools understand the semantics of these types. * Pattern Matching * You can create branching logic based on arbitrary types and values of the members of those types. * `ref` locals and returns * Method arguments and local variables can be references to other storage. * Local Functions * You can nest functions inside other functions to limit their scope and visibility. * More expression-bodied members * The list of members that can be authored using expressions has grown. * `throw` Expressions * You can throw exceptions in code constructs that previously were not allowed because `throw` was a statement. * Generalized async return types * Methods declared with the `async` modifier can return other types in addition to `Task` and `Task`. * Numeric literal syntax improvements * New tokens improve readability for numeric constants. The remainder of this topic discusses each of the features. For each feature, you'll learn the reasoning behind it. You'll learn the syntax. You'll see some sample scenarios where using the new feature will make you more productive as a developer. ## `out` variables The existing syntax that supports `out` parameters has been improved in this version. Previously, you would need to separate the declaration of the out variable and its initialization into two different statements: ```csharp var input = "8675309"; int numericResult; if (int.TryParse(input, out numericResult)) Console.WriteLine(numericResult); else Console.WriteLine("Could not parse input"); ``` You can now declare `out` variables in the argument list of a method call, rather than writing a separate declaration statement: ```csharp if (int.TryParse(input, out int result)) Console.WriteLine(result); else Console.WriteLine("Could not parse input"); ``` You may want to specify the type of the `out` variable for clarity, as shown above. However, the language does support using an implicitly typed local variable: ```csharp if (int.TryParse(input, out var answer)) Console.WriteLine(answer); else Console.WriteLine("Could not parse input"); ``` * The code is easier to read. * You declare the out variable where you use it, not on another line above. * No need to assign an initial value. * By declaring the `out` variable where it is used in a method call, you can't accidentally use it before it is assigned. The most common use for this feature will be the `Try` pattern. In this pattern, a method returns a `bool` indicating success or failure and an`out` variable that provides the result if the method succeeds. ## Tuples C# provides a rich syntax for classes and structs that is used to explain your design intent. But sometimes that rich syntax requires extra work with minimal benefit. You may often write methods that need a simple structure containing more than one data element. To support these scenarios *tuples* were added to C#. Tuples are lightweight data structures that contain multiple fields to represent the data members. The fields are not validated, and you cannot define your own methods > ℹ️  Tuples were available before C# 7 as an API, but had many limitations. Most importantly, the members of these tuples were named `Item1`, `Item2` and so on. The language support enables semantic names for the fields of a Tuple. You can create a tuple by assigning each member to a value: ```csharp var letters = ("a", "b"); ``` That assignment creates a tuple whose members are `Item1` and `Item2`, following the existing System.Tuple syntax. You can modify that assignment to create a tuple that provides semantic names to each of the members of the tuple: ```csharp (string Alpha, string Beta) namedLetters = ("a", "b"); ``` > ℹ️  The new tuples features require the `System.ValueTuple` type. For Visual Studio 15 Preview 5 and earlier preview releases, you must add the NuGet package "System.ValueTuple", available in the pre-release stream. The `namedLetters` tuple contains fields referred to as `Alpha` and `Beta`. In a tuple assignment, you can also specify the names of the fields on the right-hand side of the assignment: ```csharp var alphabetStart = (Alpha: "a", Beta: "b"); ``` The language allows you to specify names for the fields on both the left and right-hand side of the assignment: ```csharp (string First, string Second) firstLetters = (Alpha: "a", Beta: "b"); ``` The line above generates a warning, `CS8123`, telling you that the names on the right side of the assignment, `Alpha` and `Beta` are ignored because they conflict with the names on the left side, `First` and `Second`. The examples above show the basic syntax to declare tuples. Tuples are most useful as return types for `private` and `internal` methods. Tuples provide a simple syntax for those methods to return multiple discrete values: You save the work of authoring a `class` or a `struct` that defines the type returned. There is no need for creating a new type. Creating a tuple is more efficient and more productive. It is a simpler, lightweight syntax to define a data structure that carries more than one value. The example method below returns the minimum and maximum values found in a sequence of integers: ```csharp private static (int Max, int Min) Range(IEnumerable numbers) { int min = int.MaxValue; int max = int.MinValue; foreach(var n in numbers) { min = (n < min) ? n : min; max = (n > max) ? n : max; } return (max, min); } ``` Using tuples in this way offers several advantages: * You save the work of authoring a `class` or a `struct` that defines the type returned. * You do not need to create new type. * The language enhancements removes the need to call the `System.Tuple.Create()` methods. The declaration for the method provides the names for the fields of the tuple that is returned. When you call the method, the return value is a tuple whose fields are `Max` and `Min`: ```csharp int [] numbers = { 97, 243, 254, 41, 132, 26, 167, 19, 201, 252, 119, 68, 17, 66, 131 }; var range = Range(numbers); ``` There may be times when you want to unpackage the members of a tuple that were returned from a method. You can do that by declaring separate variables for each of the values in the tuple. This is called *deconstructing* the tuple: ```csharp (int max, int min) = Range(numbers); ``` You can also provide a similar deconstruction for any type in .NET. This is done by writing a `Deconstruct` method as a member of the class. That `Deconstruct` method provides a set of `out` arguments for each of the properties you want to extract. Consider this `Point` class that provides a deconstructor method that extracts the `X` and `Y` coordinates: ```csharp public class Point { public Point(double x, double y) { this.X = x; this.Y = y; } public double X { get; } public double Y { get; } public void Deconstruct(out double x, out double y) { x = this.X; y = this.Y; } } ``` You can extract the individual fields by assigning a tuple to a `Point`: ```csharp var p = new Point(3.14, 2.71); (double X, double Y) = p; ``` You are not bound by the names defined in the `Deconstruct` method. You can rename the extract variables as part of the assignment: ```csharp (double horizontalDistance, double verticalDistance) = p; ``` ## Pattern matching *Pattern matching* is a feature that allows you to implement method dispatch on properties other than the type of an object. You're probably already familiar with method dispatch based on the type of an object. In Object Oriented programming, virtual and override methods provide language syntax to implement method dispatching based on an object's type. Base and Derived classes provide different implementations. Pattern matching expressions extend this concept so that you can easily implement similar dispatch patterns for types and data elements that are not related through an inheritance hierarchy. Pattern matching supports `is` expressions and `switch` expressions. Each enables inspecting an object and its properties to determine if that object satisfies the sought pattern. You use the `when` keyword to specify additional rules to the pattern. ### `is` expressions The `is` pattern expressions extend the familiar `is` operator to query a object beyond its type. Let's start with a simple scenario. We'll add capabilities to this scenario that demonstrate how pattern matching expressions make algorithms that work with unrelated types easy. We'll start with a method that computes the sum of a number of die rolls: ```csharp public static int DiceSum(IEnumerable values) => values.Sum() ``` You might quickly find that you need to find the sum of die rolls where some of the rolls are made with more than one die. Part of the input sequence may be multiple results instead of a single number: ```csharp public static int DiceSum2(IEnumerable values) { var sum = 0; foreach(var item in values) { if (item is int val) sum += val; else if (item is IEnumerable subList) sum += DiceSum2(subList); } return sum; } ``` The `is` pattern expression works quite well in this scenario. As part of checking the type, you write a variable initialization. This creates a new variable of the validated runtime type. As you keep extending these scenarios, you may find that you build more `if` and `else if` statements. Once that becomes unwieldy, you'll likely want to switch to `switch` pattern expressions. ### `switch` expressions The `switch` pattern expression has a familiar syntax, based on the `switch` statement already part of the C# language. Let's translate the existing code to use a `switch` expression before adding new cases: ```csharp public static int DiceSum3(IEnumerable values) { var sum = 0; foreach (var item in values) { switch (item) { case int val: sum += val; break; case IEnumerable subList: sum += DiceSum3(subList); break; } } return sum; } ``` The `switch` expressions have a slightly different syntax than the `is` expressions, where you declare the type and variable at the beginning of the `case` expression. The `switch` expressions also support constants. This can save time by factoring out simple cases: ```csharp public static int DiceSum4(IEnumerable values) { var sum = 0; foreach (var item in values) { switch (item) { case 0: break; case int val: sum += val; break; case IEnumerable subList when subList.Any(): sum += DiceSum4(subList); break; case IEnumerable subList: break; case null: break; default: throw new InvalidOperationException("unknown item type"); } } return sum; } ``` The code above adds cases for `0` as a special case of `int`, and `null` as a special case when there is no input. This demonstrates one important new feature in switch pattern expressions: the order of the `case` expressions now matters. The `0` case must appear before the general `int` case. Otherwise, the first pattern to match would be the `int` case, even when the value is `0`. This same behavior enables the special case for an empty input sequence. You can see that the case for an `IEnumerable` item that has elements must appear before the general `IEnumerable` case. This version has also added a `default` case. The `default` case is always evaluated last, regardless of the order it appears in the source. For that reason, convention is to put the `default` case last. Finally, let's add one last `case` for a new style of die. Some games use percentile dice to represent larger ranges of numbers. > ℹ️  Two 10-sided percentile dice can represent every number from 0 through 99. One die has sides labelled `00`, `10`, `20`, ... `90`. The other die has sides labeled `0`, `1`, `2`, ... `9`. Add the two die values together and you can get every number from 0 through 99. To add this kind of die to your collection, first define a type to represent the percentile die: ```csharp public struct PercentileDie { public int Value { get; } public int Multiplier { get; } public PercentileDie(int multiplier, int value) { this.Value = value; this.Multiplier = multiplier; } } ``` Then, add a `case` expression for the new type: ```csharp public static int DiceSum5(IEnumerable values) { var sum = 0; foreach (var item in values) { switch (item) { case 0: break; case int val: sum += val; break; case PercentileDie die: sum += die.Multiplier * die.Value; break; case IEnumerable subList when subList.Any(): sum += DiceSum5(subList); break; case IEnumerable subList: break; case null: break; default: throw new InvalidOperationException("unknown item type"); } } return sum; } ``` The new syntax for pattern matching expressions makes it easier to create dispatch algorithms based on an object's type, or other properties, using a clear and concise syntax. Pattern matching expressions enable these constructs on data types that are unrelated by inheritance. ## Local functions Many designs for classes include methods that are called from only one location. These additional private methods keep each method small and focused. However, they can make it harder to understand a class when reading it the first time. These methods must be understood outside of the context of the single calling location. For those designs, *local functions* enable you to declare methods inside the context of another method. This makes it easier for readers of the class to see that the local method is only called from the context in which is it declared. There are two very common use cases for local functions: public iterator methods and public async methods. Both types of methods generate code that reports errors later than programmers might expect. In the case of iterator methods, any exceptions are observed only when calling code that enumerates the returned sequence. In the case of async methods, any exceptions are only observed when the returned `Task` is awaited. Let's start with an iterator method: ```csharp public static IEnumerable AlphabetSubset(char start, char end) { if ((start < 'a') || (start > 'z')) throw new ArgumentOutOfRangeException(paramName: nameof(start), message: "start must be a letter"); if ((end < 'a') || (end > 'z')) throw new ArgumentOutOfRangeException(paramName: nameof(end), message: "end must be a letter"); if (end <= start) throw new ArgumentException($"{nameof(end)} must be greater than {nameof(start)}"); for (var c = start; c < end; c++) yield return c; } ``` Examine the code below that calls the iterator method incorrectly: ```csharp var resultSet = AlphabetSubset('f', 'a'); Console.WriteLine("iterator created"); foreach (var thing in resultSet) Console.Write($"{thing}, "); ``` The exception is thrown when `resultSet` is iterated, not when `resultSet` is created. In this contained example, most developers could quickly diagnose the problem. However, in larger codebases, the code that creates an iterator often isn't as close to the code that enumerates the result. You can refactor the code so that the public method validates all arguments, and a private method generates the enumeration: ```csharp public static IEnumerable AlphabetSubset2(char start, char end) { if ((start < 'a') || (start > 'z')) throw new ArgumentOutOfRangeException(paramName: nameof(start), message: "start must be a letter"); if ((end < 'a') || (end > 'z')) throw new ArgumentOutOfRangeException(paramName: nameof(end), message: "end must be a letter"); if (end <= start) throw new ArgumentException($"{nameof(end)} must be greater than {nameof(start)}"); return alphabetSubsetImplementation(start, end); } private static IEnumerable alphabetSubsetImplementation(char start, char end) { for (var c = start; c < end; c++) yield return c; } ``` This refactored version will throw exceptions immediately because the public method is not an iterator method; only the private method uses the `yield return` syntax. However, there are potential problems with this refactoring. The private method should only be called from the public interface method, because otherwise all argument validation is skipped. Readers of the class must discover this fact by reading the entire class and searching for any other references to the `alphabetSubsetImplementation` method. You can make that design intent more clear by declaring the `alphabetSubsetImplementation` as a local function inside the public API method: ```csharp public static IEnumerable AlphabetSubset3(char start, char end) { if ((start < 'a') || (start > 'z')) throw new ArgumentOutOfRangeException(paramName: nameof(start), message: "start must be a letter"); if ((end < 'a') || (end > 'z')) throw new ArgumentOutOfRangeException(paramName: nameof(end), message: "end must be a letter"); if (end <= start) throw new ArgumentException($"{nameof(end)} must be greater than {nameof(start)}"); return alphabetSubsetImplementation(); IEnumerable alphabetSubsetImplementation() { for (var c = start; c < end; c++) yield return c; } } ``` The version above makes it clear that the local method is referenced only in the context of the outer method. The rules for local functions also ensure that a developer can't accidentally call the local function from another location in the class and bypass the argument validation. The same technique can be employed with `async` methods to ensure that exceptions arising from argument validation are thrown before the asynchronous work begins: ```csharp public Task PerformLongRunningWork(string address, int index, string name) { if (string.IsNullOrWhiteSpace(address)) throw new ArgumentException(message: "An address is required", paramName: nameof(address)); if (index < 0) throw new ArgumentOutOfRangeException(paramName: nameof(index), message: "The index must be non-negative"); if (string.IsNullOrWhiteSpace(name)) throw new ArgumentException(message: "You must supply a name", paramName: nameof(name)); return longRunningWorkImplementation(); async Task longRunningWorkImplementation() { var interimResult = await FirstWork(address); var secondResult = await SecondStep(index, name); return $"The results are {interimResult} and {secondResult}. Enjoy."; Task FirstWork(string x) => Task.FromResult (x); Task SecondStep(int i, string x) => Task.FromResult ($"{x}: {i}"); } } ``` > ℹ️  Some of the designs that are supported by local functions could also be accomplished using *lambda expressions*. ## More expression-bodied members C# 6 introduced expression-bodied members for member functions, and read-only properties. C# 7 expands the allowed members that can be implemented as expressions. In C# 7, you can implement *constructors*, *finalizers*, and `get` and `set` accessors on *properties* and *indexers*. The following code shows examples of each: ```csharp class ExpressionMembersExample { // Expression-bodied constructor public ExpressionMembersExample(string label) => this.Label = label; // Expression-bodied finalizer ~ExpressionMembersExample() => Console.Error.WriteLine("Finalized!"); private string label; // Expression-bodied get / set accessors. public string Label { get => label; set => this.label = value ?? "Default label"; } } ``` > ℹ️  This example does not need a finalizer, but it is shown to demonstrate the syntax. You should not implement a finalizer in your class unless it is necessary to release unmanaged resources. You should also consider using the `System.Runtime.InteropServices.SafeHandle` class instead of managing unmanaged resources directly. These new locations for expression-bodied members represent an important milestone for the C# language: These features were implemented by community members working on the open-source [Roslyn](https://github.com/dotnet/Roslyn) project. ## Throw expressions In C#, `throw` has always been a statement. Because `throw` is a statement, not an expression, there were C# constructs where you could not use it. These included conditional expressions, null coalescing expressions, and some lambda expressions. The addition of expression-bodied members adds more locations where `throw` expressions would be useful. So that you can write any of these constructs, C# 7 introduces *throw expressions*. The syntax is the same as you've always used for `throw` statements. The only difference is that now you can place them in new locations, such as in a conditional expression: ```csharp class ExpressionMembersExample { private string name; public string Name { get => name; set => name = value ?? throw new ArgumentNullException(paramName: nameof(value), message: "New name must not be null"); } } ``` This features enables using throw expressions in initialization expressions: ```csharp class ConfigResource { } static ConfigResource LoadConfigResourceOrDefault () => null; private ConfigResource loadedConfig = LoadConfigResourceOrDefault() ?? throw new InvalidOperationException("Could not load config"); ``` Previously, those initializations would need to be in a constructor, with the throw statements in the body of the constructor: ```csharp class ApplicationOptions { public ApplicationOptions() { var loadedConfig = LoadConfigResourceOrDefault(); if (loadedConfig == null) throw new InvalidOperationException("Could not load config"); } } ``` > ℹ️  Both of the preceding constructs will cause exceptions to be thrown during the construction of an object. Those are often difficult to recover from. For that reason, designs that throw exceptions during construction are discouraged. ## Numeric literal syntax improvements Misreading numeric constants can make it harder to understand code when reading it for the first time. This often occurs when those numbers are used as bit masks or other symbolic rather than numeric values. C# 7 includes two new features to make it easier to write numbers in the most readable fashion for the intended use: *binary literals*, and *digit separators*. For those times when you are creating bit masks, or whenever a binary representation of a number makes the most readable code, write that number in binary: ```csharp public const int One = 0b0001; public const int Two = 0b0010; public const int Four = 0b0100; public const int Eight = 0b1000; ``` The `0b` at the beginning of the constant indicates that the number is written as a binary number. Binary numbers can get very long, so it's often easier to see the bit patterns by introducing the `_` as a digit separator: ```csharp public const int Sixteen = 0b0001_0000; public const int ThirtyTwo = 0b0010_0000; public const int SixtyFour = 0b0100_0000; public const int OneHundredTwentyEight = 0b1000_0000; ``` The digit separator can appear anywhere in the constant. For base 10 numbers, it would be common to use it as a thousands separator: ```csharp public const long BillionsAndBillions = 100_000_000_000; ``` The digit separator can be used with `decimal`, `float` and `double` types as well: ```csharp public const double AvogadroConstant = 6.022_140_857_747_474e23; public const decimal GoldenRatio = 1.618_033_988_749_894_848_204_586_834_365_638_117_720_309_179M; ``` Taken together, you can declare numeric constants with much more readability. ## Ref locals and returns This feature enables algorithms that use and return references to variables defined elsewhere. One example is working with large matrices, and finding a single location with certain characteristics. One method would return the two indices for a single location in the matrix: ```csharp public static (int i, int j) Find(int[,] matrix, Func predicate) { for (int i = 0; i < matrix.GetLength(0); i++) for (int j = 0; j < matrix.GetLength(1); j++) if (predicate(matrix[i, j])) return (i, j); return (-1, -1); // Not found } ``` There are many issues with this code. First of all, it's a public method that's returning a tuple. The language supports this, but user defined types (either classes or structs) are preferred for public APIs. Second, this method is returning the indices to the item in the matrix. That leads callers to write code that uses those indices to dereference the matrix and modify a single element: ```csharp var matrix = new int[,] { { 5, 9, 11, 4}, { 3, 10, 18, 9}, { 1, 19, 42, 2}, { 0, 3, 4, 31}, }; var indices = Find(matrix, (val) => val == 42); Console.WriteLine(indices); matrix[indices.i, indices.j] = 24; ``` You'd rather write a method that returns a *reference* to the element of the matrix that you want to change. You could only accomplish this by using unsafe code and returning a pointer to an `int` in previous versions. Let's walk through a series of changes to demonstrate the ref local feature and show how to create a method that returns a reference to internal storage. Along the way, you'll learn the rules of the ref return and ref local feature that protects you from accidentally misusing it. Start by modifying the `Find` method declaration so that it returns a `ref int` instead of a tuple. Then, modify the return statement so it returns the value stored in the matrix instead of the two indices: ```csharp // Note that this won't compile. // Method declaration indicates ref return, // but return statement specifies a value return. // // public static ref int Find2(int[,] matrix, Func predicate) // { // for (int i = 0; i < matrix.GetLength(0); i++) // for (int j = 0; j < matrix.GetLength(1); j++) // if (predicate(matrix[i, j])) // return matrix[i, j]; // throw new InvalidOperationException("Not found"); // } ``` When you declare that a method returns a `ref` variable, you must also add the `ref` keyword to each return statement. That indicates return by reference, and helps developers reading the code later remember that the method returns by reference: ```csharp public static ref int Find3(int[,] matrix, Func predicate) { for (int i = 0; i < matrix.GetLength(0); i++) for (int j = 0; j < matrix.GetLength(1); j++) if (predicate(matrix[i, j])) return ref matrix[i, j]; throw new InvalidOperationException("Not found"); } ``` Now that the method returns a reference to the integer value in the matrix, you need to modify where it's called. The `var` declaration means that `valItem` is now an `int` rather than a tuple: ```csharp var valItem = Find3(matrix, (val) => val == 42); Console.WriteLine(valItem); valItem = 24; Console.WriteLine(matrix[4, 2]); ``` The second `WriteLine` statement in the example above prints out the value `42`, not `24`. The variable `valItem` is an `int`, not a `ref int`. The `var` keyword enables the compiler to specify the type, but will not implicitly add the `ref` modifier. Instead, the value referred to by the `ref return` is *copied* to the variable on the left-hand side of the assignment. The variable is not a `ref` local. In order to get the result you want, you need to add the `ref` modifier to the local variable declaration to make the variable a reference when the return value is a reference: ```csharp ref var item = ref Find3(matrix, (val) => val == 42); Console.WriteLine(item); item = 24; Console.WriteLine(matrix[4, 2]); ``` Now, the second `WriteLine` statement in the example above will print out the value `24`, indicating that the storage in the matrix has been modified. The local variable has been declared with the `ref` modifier, and it will take a `ref` return. You must initialize a `ref` variable when it is declared, you cannot split the declaration and the initialization. The C# language has two other rules that protect you from misusing the `ref` locals and returns: * You cannot assign a value to a `ref` variable. * That disallows statements like `ref int i = sequence.Count();` * You cannot return a `ref` to a variable whose lifetime does not extend beyond the execution of the method. * That means you cannot return a reference to a local variable, or similar scope. These rules ensure that you cannot accidentally mix value variables and reference variables. They also ensure that you cannot have a reference variable refer to storage that is a candidate for garbage collection. The addition of ref locals and ref returns enable algorithms that are more efficient by avoiding copying values, or performing dereferencing operations multiple times. ================================================ FILE: csharp/csharp7/meta.json ================================================ { "order":{ "csharp7.workbook":"What's new in C# 7" } } ================================================ FILE: csharp/linq/101-linq-examples.workbook/101_Linq_Examples.csx ================================================ #r "System.Xml.Linq" #r "System.Data" #r "System.Data.DataSetExtensions" using System.Xml.Linq; using System.Data; public class Product { public int ProductID { get; set; } public string ProductName { get; set; } public string Category { get; set; } public decimal UnitPrice { get; set; } public int UnitsInStock { get; set; } } public class Order { public int OrderID { get; set; } public DateTime OrderDate { get; set; } public decimal Total { get; set; } } public class Customer { public string CustomerID { get; set; } public string CompanyName { get; set; } public string Address { get; set; } public string City { get; set; } public string Region { get; set; } public string PostalCode { get; set; } public string Country { get; set; } public string Phone { get; set; } public string Fax { get; set; } public Order[] Orders { get; set; } } // Data var productList = new List { new Product { ProductID = 1, ProductName = "Chai", Category = "Beverages", UnitPrice = 18.0000M, UnitsInStock = 39 }, new Product { ProductID = 2, ProductName = "Chang", Category = "Beverages", UnitPrice = 19.0000M, UnitsInStock = 17 }, new Product { ProductID = 3, ProductName = "Aniseed Syrup", Category = "Condiments", UnitPrice = 10.0000M, UnitsInStock = 13 }, new Product { ProductID = 4, ProductName = "Chef Anton's Cajun Seasoning", Category = "Condiments", UnitPrice = 22.0000M, UnitsInStock = 53 }, new Product { ProductID = 5, ProductName = "Chef Anton's Gumbo Mix", Category = "Condiments", UnitPrice = 21.3500M, UnitsInStock = 0 }, new Product { ProductID = 6, ProductName = "Grandma's Boysenberry Spread", Category = "Condiments", UnitPrice = 25.0000M, UnitsInStock = 120 }, new Product { ProductID = 7, ProductName = "Uncle Bob's Organic Dried Pears", Category = "Produce", UnitPrice = 30.0000M, UnitsInStock = 15 }, new Product { ProductID = 8, ProductName = "Northwoods Cranberry Sauce", Category = "Condiments", UnitPrice = 40.0000M, UnitsInStock = 6 }, new Product { ProductID = 9, ProductName = "Mishi Kobe Niku", Category = "Meat/Poultry", UnitPrice = 97.0000M, UnitsInStock = 29 }, new Product { ProductID = 10, ProductName = "Ikura", Category = "Seafood", UnitPrice = 31.0000M, UnitsInStock = 31 }, new Product { ProductID = 11, ProductName = "Queso Cabrales", Category = "Dairy Products", UnitPrice = 21.0000M, UnitsInStock = 22 }, new Product { ProductID = 12, ProductName = "Queso Manchego La Pastora", Category = "Dairy Products", UnitPrice = 38.0000M, UnitsInStock = 86 }, new Product { ProductID = 13, ProductName = "Konbu", Category = "Seafood", UnitPrice = 6.0000M, UnitsInStock = 24 }, new Product { ProductID = 14, ProductName = "Tofu", Category = "Produce", UnitPrice = 23.2500M, UnitsInStock = 35 }, new Product { ProductID = 15, ProductName = "Genen Shouyu", Category = "Condiments", UnitPrice = 15.5000M, UnitsInStock = 39 }, new Product { ProductID = 16, ProductName = "Pavlova", Category = "Confections", UnitPrice = 17.4500M, UnitsInStock = 29 }, new Product { ProductID = 17, ProductName = "Alice Mutton", Category = "Meat/Poultry", UnitPrice = 39.0000M, UnitsInStock = 0 }, new Product { ProductID = 18, ProductName = "Carnarvon Tigers", Category = "Seafood", UnitPrice = 62.5000M, UnitsInStock = 42 }, new Product { ProductID = 19, ProductName = "Teatime Chocolate Biscuits", Category = "Confections", UnitPrice = 9.2000M, UnitsInStock = 25 }, new Product { ProductID = 20, ProductName = "Sir Rodney's Marmalade", Category = "Confections", UnitPrice = 81.0000M, UnitsInStock = 40 }, new Product { ProductID = 21, ProductName = "Sir Rodney's Scones", Category = "Confections", UnitPrice = 10.0000M, UnitsInStock = 3 }, new Product { ProductID = 22, ProductName = "Gustaf's Knäckebröd", Category = "Grains/Cereals", UnitPrice = 21.0000M, UnitsInStock = 104 }, new Product { ProductID = 23, ProductName = "Tunnbröd", Category = "Grains/Cereals", UnitPrice = 9.0000M, UnitsInStock = 61 }, new Product { ProductID = 24, ProductName = "Guaraná Fantástica", Category = "Beverages", UnitPrice = 4.5000M, UnitsInStock = 20 }, new Product { ProductID = 25, ProductName = "NuNuCa Nuß-Nougat-Creme", Category = "Confections", UnitPrice = 14.0000M, UnitsInStock = 76 }, new Product { ProductID = 26, ProductName = "Gumbär Gummibärchen", Category = "Confections", UnitPrice = 31.2300M, UnitsInStock = 15 }, new Product { ProductID = 27, ProductName = "Schoggi Schokolade", Category = "Confections", UnitPrice = 43.9000M, UnitsInStock = 49 }, new Product { ProductID = 28, ProductName = "Rössle Sauerkraut", Category = "Produce", UnitPrice = 45.6000M, UnitsInStock = 26 }, new Product { ProductID = 29, ProductName = "Thüringer Rostbratwurst", Category = "Meat/Poultry", UnitPrice = 123.7900M, UnitsInStock = 0 }, new Product { ProductID = 30, ProductName = "Nord-Ost Matjeshering", Category = "Seafood", UnitPrice = 25.8900M, UnitsInStock = 10 }, new Product { ProductID = 31, ProductName = "Gorgonzola Telino", Category = "Dairy Products", UnitPrice = 12.5000M, UnitsInStock = 0 }, new Product { ProductID = 32, ProductName = "Mascarpone Fabioli", Category = "Dairy Products", UnitPrice = 32.0000M, UnitsInStock = 9 }, new Product { ProductID = 33, ProductName = "Geitost", Category = "Dairy Products", UnitPrice = 2.5000M, UnitsInStock = 112 }, new Product { ProductID = 34, ProductName = "Sasquatch Ale", Category = "Beverages", UnitPrice = 14.0000M, UnitsInStock = 111 }, new Product { ProductID = 35, ProductName = "Steeleye Stout", Category = "Beverages", UnitPrice = 18.0000M, UnitsInStock = 20 }, new Product { ProductID = 36, ProductName = "Inlagd Sill", Category = "Seafood", UnitPrice = 19.0000M, UnitsInStock = 112 }, new Product { ProductID = 37, ProductName = "Gravad lax", Category = "Seafood", UnitPrice = 26.0000M, UnitsInStock = 11 }, new Product { ProductID = 38, ProductName = "Côte de Blaye", Category = "Beverages", UnitPrice = 263.5000M, UnitsInStock = 17 }, new Product { ProductID = 39, ProductName = "Chartreuse verte", Category = "Beverages", UnitPrice = 18.0000M, UnitsInStock = 69 }, new Product { ProductID = 40, ProductName = "Boston Crab Meat", Category = "Seafood", UnitPrice = 18.4000M, UnitsInStock = 123 }, new Product { ProductID = 41, ProductName = "Jack's New England Clam Chowder", Category = "Seafood", UnitPrice = 9.6500M, UnitsInStock = 85 }, new Product { ProductID = 42, ProductName = "Singaporean Hokkien Fried Mee", Category = "Grains/Cereals", UnitPrice = 14.0000M, UnitsInStock = 26 }, new Product { ProductID = 43, ProductName = "Ipoh Coffee", Category = "Beverages", UnitPrice = 46.0000M, UnitsInStock = 17 }, new Product { ProductID = 44, ProductName = "Gula Malacca", Category = "Condiments", UnitPrice = 19.4500M, UnitsInStock = 27 }, new Product { ProductID = 45, ProductName = "Rogede sild", Category = "Seafood", UnitPrice = 9.5000M, UnitsInStock = 5 }, new Product { ProductID = 46, ProductName = "Spegesild", Category = "Seafood", UnitPrice = 12.0000M, UnitsInStock = 95 }, new Product { ProductID = 47, ProductName = "Zaanse koeken", Category = "Confections", UnitPrice = 9.5000M, UnitsInStock = 36 }, new Product { ProductID = 48, ProductName = "Chocolade", Category = "Confections", UnitPrice = 12.7500M, UnitsInStock = 15 }, new Product { ProductID = 49, ProductName = "Maxilaku", Category = "Confections", UnitPrice = 20.0000M, UnitsInStock = 10 }, new Product { ProductID = 50, ProductName = "Valkoinen suklaa", Category = "Confections", UnitPrice = 16.2500M, UnitsInStock = 65 }, new Product { ProductID = 51, ProductName = "Manjimup Dried Apples", Category = "Produce", UnitPrice = 53.0000M, UnitsInStock = 20 }, new Product { ProductID = 52, ProductName = "Filo Mix", Category = "Grains/Cereals", UnitPrice = 7.0000M, UnitsInStock = 38 }, new Product { ProductID = 53, ProductName = "Perth Pasties", Category = "Meat/Poultry", UnitPrice = 32.8000M, UnitsInStock = 0 }, new Product { ProductID = 54, ProductName = "Tourtière", Category = "Meat/Poultry", UnitPrice = 7.4500M, UnitsInStock = 21 }, new Product { ProductID = 55, ProductName = "Pâté chinois", Category = "Meat/Poultry", UnitPrice = 24.0000M, UnitsInStock = 115 }, new Product { ProductID = 56, ProductName = "Gnocchi di nonna Alice", Category = "Grains/Cereals", UnitPrice = 38.0000M, UnitsInStock = 21 }, new Product { ProductID = 57, ProductName = "Ravioli Angelo", Category = "Grains/Cereals", UnitPrice = 19.5000M, UnitsInStock = 36 }, new Product { ProductID = 58, ProductName = "Escargots de Bourgogne", Category = "Seafood", UnitPrice = 13.2500M, UnitsInStock = 62 }, new Product { ProductID = 59, ProductName = "Raclette Courdavault", Category = "Dairy Products", UnitPrice = 55.0000M, UnitsInStock = 79 }, new Product { ProductID = 60, ProductName = "Camembert Pierrot", Category = "Dairy Products", UnitPrice = 34.0000M, UnitsInStock = 19 }, new Product { ProductID = 61, ProductName = "Sirop d'érable", Category = "Condiments", UnitPrice = 28.5000M, UnitsInStock = 113 }, new Product { ProductID = 62, ProductName = "Tarte au sucre", Category = "Confections", UnitPrice = 49.3000M, UnitsInStock = 17 }, new Product { ProductID = 63, ProductName = "Vegie-spread", Category = "Condiments", UnitPrice = 43.9000M, UnitsInStock = 24 }, new Product { ProductID = 64, ProductName = "Wimmers gute Semmelknödel", Category = "Grains/Cereals", UnitPrice = 33.2500M, UnitsInStock = 22 }, new Product { ProductID = 65, ProductName = "Louisiana Fiery Hot Pepper Sauce", Category = "Condiments", UnitPrice = 21.0500M, UnitsInStock = 76 }, new Product { ProductID = 66, ProductName = "Louisiana Hot Spiced Okra", Category = "Condiments", UnitPrice = 17.0000M, UnitsInStock = 4 }, new Product { ProductID = 67, ProductName = "Laughing Lumberjack Lager", Category = "Beverages", UnitPrice = 14.0000M, UnitsInStock = 52 }, new Product { ProductID = 68, ProductName = "Scottish Longbreads", Category = "Confections", UnitPrice = 12.5000M, UnitsInStock = 6 }, new Product { ProductID = 69, ProductName = "Gudbrandsdalsost", Category = "Dairy Products", UnitPrice = 36.0000M, UnitsInStock = 26 }, new Product { ProductID = 70, ProductName = "Outback Lager", Category = "Beverages", UnitPrice = 15.0000M, UnitsInStock = 15 }, new Product { ProductID = 71, ProductName = "Flotemysost", Category = "Dairy Products", UnitPrice = 21.5000M, UnitsInStock = 26 }, new Product { ProductID = 72, ProductName = "Mozzarella di Giovanni", Category = "Dairy Products", UnitPrice = 34.8000M, UnitsInStock = 14 }, new Product { ProductID = 73, ProductName = "Röd Kaviar", Category = "Seafood", UnitPrice = 15.0000M, UnitsInStock = 101 }, new Product { ProductID = 74, ProductName = "Longlife Tofu", Category = "Produce", UnitPrice = 10.0000M, UnitsInStock = 4 }, new Product { ProductID = 75, ProductName = "Rhönbräu Klosterbier", Category = "Beverages", UnitPrice = 7.7500M, UnitsInStock = 125 }, new Product { ProductID = 76, ProductName = "Lakkalikööri", Category = "Beverages", UnitPrice = 18.0000M, UnitsInStock = 57 }, new Product { ProductID = 77, ProductName = "Original Frankfurter grüne Soße", Category = "Condiments", UnitPrice = 13.0000M, UnitsInStock = 32 } }; List GetProductList() => productList; // Customer/Order data read into memory from XML file using XLinq: var customerList = ( from e in XDocument.Load("Customers.xml"). Root.Elements("customer") select new Customer { CustomerID = (string)e.Element("id"), CompanyName = (string)e.Element("name"), Address = (string)e.Element("address"), City = (string)e.Element("city"), Region = (string)e.Element("region"), PostalCode = (string)e.Element("postalcode"), Country = (string)e.Element("country"), Phone = (string)e.Element("phone"), Fax = (string)e.Element("fax"), Orders = ( from o in e.Elements("orders").Elements("order") select new Order { OrderID = (int)o.Element("id"), OrderDate = (DateTime)o.Element("orderdate"), Total = (decimal)o.Element("total") }) .ToArray() }) .ToList(); List GetCustomerList() => customerList; public class Supplier { public string SupplierName { get; set; } public string Address { get; set; } public string City { get; set; } public string Country { get; set; } } var supplierList = new List(){ new Supplier {SupplierName = "Exotic Liquids", Address = "49 Gilbert St.", City = "London", Country = "UK"}, new Supplier {SupplierName = "New Orleans Cajun Delights", Address = "P.O. Box 78934", City = "New Orleans", Country = "USA"}, new Supplier {SupplierName = "Grandma Kelly's Homestead", Address = "707 Oxford Rd.", City = "Ann Arbor", Country = "USA"}, new Supplier {SupplierName = "Tokyo Traders", Address = "9-8 Sekimai Musashino-shi", City = "Tokyo", Country = "Japan"}, new Supplier {SupplierName = "Cooperativa de Quesos 'Las Cabras'", Address = "Calle del Rosal 4", City = "Oviedo", Country = "Spain"}, new Supplier {SupplierName = "Mayumi's", Address = "92 Setsuko Chuo-ku", City = "Osaka", Country = "Japan"}, new Supplier {SupplierName = "Pavlova, Ltd.", Address = "74 Rose St. Moonie Ponds", City = "Melbourne", Country = "Australia"}, new Supplier {SupplierName = "Specialty Biscuits, Ltd.", Address = "29 King's Way", City = "Manchester", Country = "UK"}, new Supplier {SupplierName = "PB Knäckebröd AB", Address = "Kaloadagatan 13", City = "Göteborg", Country = "Sweden"}, new Supplier {SupplierName = "Refrescos Americanas LTDA", Address = "Av. das Americanas 12.890", City = "Sao Paulo", Country = "Brazil"}, new Supplier {SupplierName = "Heli Süßwaren GmbH & Co. KG", Address = "Tiergartenstraße 5", City = "Berlin", Country = "Germany"}, new Supplier {SupplierName = "Plutzer Lebensmittelgroßmärkte AG", Address = "Bogenallee 51", City = "Frankfurt", Country = "Germany"}, new Supplier {SupplierName = "Nord-Ost-Fisch Handelsgesellschaft mbH", Address = "Frahmredder 112a", City = "Cuxhaven", Country = "Germany"}, new Supplier {SupplierName = "Formaggi Fortini s.r.l.", Address = "Viale Dante, 75", City = "Ravenna", Country = "Italy"}, new Supplier {SupplierName = "Norske Meierier", Address = "Hatlevegen 5", City = "Sandvika", Country = "Norway"}, new Supplier {SupplierName = "Bigfoot Breweries", Address = "3400 - 8th Avenue Suite 210", City = "Bend", Country = "USA"}, new Supplier {SupplierName = "Svensk Sjöföda AB", Address = "Brovallavägen 231", City = "Stockholm", Country = "Sweden"}, new Supplier {SupplierName = "Aux joyeux ecclésiastiques", Address = "203, Rue des Francs-Bourgeois", City = "Paris", Country = "France"}, new Supplier {SupplierName = "New England Seafood Cannery", Address = "Order Processing Dept. 2100 Paul Revere Blvd.", City = "Boston", Country = "USA"}, new Supplier {SupplierName = "Leka Trading", Address = "471 Serangoon Loop, Suite #402", City = "Singapore", Country = "Singapore"}, new Supplier {SupplierName = "Lyngbysild", Address = "Lyngbysild Fiskebakken 10", City = "Lyngby", Country = "Denmark"}, new Supplier {SupplierName = "Zaanse Snoepfabriek", Address = "Verkoop Rijnweg 22", City = "Zaandam", Country = "Netherlands"}, new Supplier {SupplierName = "Karkki Oy", Address = "Valtakatu 12", City = "Lappeenranta", Country = "Finland"}, new Supplier {SupplierName = "G'day, Mate", Address = "170 Prince Edward Parade Hunter's Hill", City = "Sydney", Country = "Australia"}, new Supplier {SupplierName = "Ma Maison", Address = "2960 Rue St. Laurent", City = "Montréal", Country = "Canada"}, new Supplier {SupplierName = "Pasta Buttini s.r.l.", Address = "Via dei Gelsomini, 153", City = "Salerno", Country = "Italy"}, new Supplier {SupplierName = "Escargots Nouveaux", Address = "22, rue H. Voiron", City = "Montceau", Country = "France"}, new Supplier {SupplierName = "Gai pâturage", Address = "Bat. B 3, rue des Alpes", City = "Annecy", Country = "France"}, new Supplier {SupplierName = "Forêts d'érables", Address = "148 rue Chasseur", City = "Ste-Hyacinthe", Country = "Canada"}, }; List GetSupplierList() => supplierList; #region Projection var testDS = TestHelper.CreateTestDataset(); internal class TestHelper { internal static IEnumerable ZipToStrings(IEnumerable xs, IEnumerable ys, Func fn){ return xs.Zip(ys, fn); } internal static DataSet CreateTestDataset() { DataSet ds = new DataSet(); // Customers Table ds.Tables.Add(CreateNumbersTable()); ds.Tables.Add(CreateLowNumbersTable()); ds.Tables.Add(CreateEmptyNumbersTable()); ds.Tables.Add(CreateProductList()); ds.Tables.Add(CreateDigitsTable()); ds.Tables.Add(CreateWordsTable()); ds.Tables.Add(CreateWords2Table()); ds.Tables.Add(CreateWords3Table()); ds.Tables.Add(CreateWords4Table()); ds.Tables.Add(CreateAnagramsTable()); ds.Tables.Add(CreateNumbersATable()); ds.Tables.Add(CreateNumbersBTable()); ds.Tables.Add(CreateFactorsOf300()); ds.Tables.Add(CreateDoublesTable()); ds.Tables.Add(CreateScoreRecordsTable()); ds.Tables.Add(CreateAttemptedWithdrawalsTable()); ds.Tables.Add(CreateEmployees1Table()); ds.Tables.Add(CreateEmployees2Table()); CreateCustomersAndOrdersTables(ds); ds.AcceptChanges(); return ds; } private static DataTable CreateNumbersTable() { int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; DataTable table = new DataTable("Numbers"); table.Columns.Add("number", typeof(int)); foreach (int n in numbers) { table.Rows.Add(new object[] { n }); } return table; } private static DataTable CreateEmptyNumbersTable() { DataTable table = new DataTable("EmptyNumbers"); table.Columns.Add("number", typeof(int)); return table; } private static DataTable CreateDigitsTable() { string[] digits = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" }; DataTable table = new DataTable("Digits"); table.Columns.Add("digit", typeof(string)); foreach (string digit in digits) { table.Rows.Add(new object[] { digit }); } return table; } private static DataTable CreateWordsTable() { string[] words = { "aPPLE", "BlUeBeRrY", "cHeRry" }; DataTable table = new DataTable("Words"); table.Columns.Add("word", typeof(string)); foreach (string word in words) { table.Rows.Add(new object[] { word }); } return table; } private static DataTable CreateWords2Table() { string[] words = { "believe", "relief", "receipt", "field" }; DataTable table = new DataTable("Words2"); table.Columns.Add("word", typeof(string)); foreach (string word in words) { table.Rows.Add(new object[] { word }); } return table; } private static DataTable CreateWords3Table() { string[] words = { "aPPLE", "AbAcUs", "bRaNcH", "BlUeBeRrY", "ClOvEr", "cHeRry" }; DataTable table = new DataTable("Words3"); table.Columns.Add("word", typeof(string)); foreach (string word in words) { table.Rows.Add(new object[] { word }); } return table; } private static DataTable CreateWords4Table() { string[] words = { "blueberry", "chimpanzee", "abacus", "banana", "apple", "cheese" }; DataTable table = new DataTable("Words4"); table.Columns.Add("word", typeof(string)); foreach (string word in words) { table.Rows.Add(new object[] { word }); } return table; } private static DataTable CreateAnagramsTable() { string[] anagrams = { "from ", " salt", " earn ", " last ", " near ", " form " }; DataTable table = new DataTable("Anagrams"); table.Columns.Add("anagram", typeof(string)); foreach (string word in anagrams) { table.Rows.Add(new object[] { word }); } return table; } private static DataTable CreateScoreRecordsTable() { var scoreRecords = new[] { new {Name = "Alice", Score = 50}, new {Name = "Bob" , Score = 40}, new {Name = "Cathy", Score = 45} }; DataTable table = new DataTable("ScoreRecords"); table.Columns.Add("Name", typeof(string)); table.Columns.Add("Score", typeof(int)); foreach (var r in scoreRecords) { table.Rows.Add(new object[] { r.Name, r.Score }); } return table; } private static DataTable CreateAttemptedWithdrawalsTable() { int[] attemptedWithdrawals = { 20, 10, 40, 50, 10, 70, 30 }; DataTable table = new DataTable("AttemptedWithdrawals"); table.Columns.Add("withdrawal", typeof(int)); foreach (var r in attemptedWithdrawals) { table.Rows.Add(new object[] { r }); } return table; } private static DataTable CreateNumbersATable() { int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 }; DataTable table = new DataTable("NumbersA"); table.Columns.Add("number", typeof(int)); foreach (int number in numbersA) { table.Rows.Add(new object[] { number }); } return table; } private static DataTable CreateNumbersBTable() { int[] numbersB = { 1, 3, 5, 7, 8 }; DataTable table = new DataTable("NumbersB"); table.Columns.Add("number", typeof(int)); foreach (int number in numbersB) { table.Rows.Add(new object[] { number }); } return table; } private static DataTable CreateLowNumbersTable() { int[] lowNumbers = { 1, 11, 3, 19, 41, 65, 19 }; DataTable table = new DataTable("LowNumbers"); table.Columns.Add("number", typeof(int)); foreach (int number in lowNumbers) { table.Rows.Add(new object[] { number }); } return table; } private static DataTable CreateFactorsOf300() { int[] factorsOf300 = { 2, 2, 3, 5, 5 }; DataTable table = new DataTable("FactorsOf300"); table.Columns.Add("factor", typeof(int)); foreach (int factor in factorsOf300) { table.Rows.Add(new object[] { factor }); } return table; } private static DataTable CreateDoublesTable() { double[] doubles = { 1.7, 2.3, 1.9, 4.1, 2.9 }; DataTable table = new DataTable("Doubles"); table.Columns.Add("double", typeof(double)); foreach (double d in doubles) { table.Rows.Add(new object[] { d }); } return table; } private static DataTable CreateEmployees1Table() { DataTable table = new DataTable("Employees1"); table.Columns.Add("id", typeof(int)); table.Columns.Add("name", typeof(string)); table.Columns.Add("worklevel", typeof(int)); table.Rows.Add(new object[] { 1, "Jones", 5 }); table.Rows.Add(new object[] { 2, "Smith", 5 }); table.Rows.Add(new object[] { 2, "Smith", 5 }); table.Rows.Add(new object[] { 3, "Smith", 6 }); table.Rows.Add(new object[] { 4, "Arthur", 11 }); table.Rows.Add(new object[] { 5, "Arthur", 12 }); return table; } private static DataTable CreateEmployees2Table() { DataTable table = new DataTable("Employees2"); table.Columns.Add("id", typeof(int)); table.Columns.Add("lastname", typeof(string)); table.Columns.Add("level", typeof(int)); table.Rows.Add(new object[] { 1, "Jones", 10 }); table.Rows.Add(new object[] { 2, "Jagger", 5 }); table.Rows.Add(new object[] { 3, "Thomas", 6 }); table.Rows.Add(new object[] { 4, "Collins", 11 }); table.Rows.Add(new object[] { 4, "Collins", 12 }); table.Rows.Add(new object[] { 5, "Arthur", 12 }); return table; } private static void CreateCustomersAndOrdersTables(DataSet ds) { DataTable customers = new DataTable("Customers"); customers.Columns.Add("CustomerID", typeof(string)); customers.Columns.Add("CompanyName", typeof(string)); customers.Columns.Add("Address", typeof(string)); customers.Columns.Add("City", typeof(string)); customers.Columns.Add("Region", typeof(string)); customers.Columns.Add("PostalCode", typeof(string)); customers.Columns.Add("Country", typeof(string)); customers.Columns.Add("Phone", typeof(string)); customers.Columns.Add("Fax", typeof(string)); ds.Tables.Add(customers); DataTable orders = new DataTable("Orders"); orders.Columns.Add("OrderID", typeof(int)); orders.Columns.Add("CustomerID", typeof(string)); orders.Columns.Add("OrderDate", typeof(DateTime)); orders.Columns.Add("Total", typeof(decimal)); ds.Tables.Add(orders); DataRelation co = new DataRelation("CustomersOrders", customers.Columns["CustomerID"], orders.Columns["CustomerID"], true); ds.Relations.Add(co); var customerList = ( from e in XDocument.Load("customers.xml"). Root.Elements("customer") select new Customer { CustomerID = (string)e.Element("id"), CompanyName = (string)e.Element("name"), Address = (string)e.Element("address"), City = (string)e.Element("city"), Region = (string)e.Element("region"), PostalCode = (string)e.Element("postalcode"), Country = (string)e.Element("country"), Phone = (string)e.Element("phone"), Fax = (string)e.Element("fax"), Orders = ( from o in e.Elements("orders").Elements("order") select new Order { OrderID = (int)o.Element("id"), OrderDate = (DateTime)o.Element("orderdate"), Total = (decimal)o.Element("total") }) .ToArray() } ).ToList(); foreach (Customer cust in customerList) { customers.Rows.Add(new object[] {cust.CustomerID, cust.CompanyName, cust.Address, cust.City, cust.Region, cust.PostalCode, cust.Country, cust.Phone, cust.Fax}); foreach (Order order in cust.Orders) { orders.Rows.Add(new object[] { order.OrderID, cust.CustomerID, order.OrderDate, order.Total }); } } } private static DataTable CreateProductList() { DataTable table = new DataTable("Products"); table.Columns.Add("ProductID", typeof(int)); table.Columns.Add("ProductName", typeof(string)); table.Columns.Add("Category", typeof(string)); table.Columns.Add("UnitPrice", typeof(decimal)); table.Columns.Add("UnitsInStock", typeof(int)); var productList = new[] { new { ProductID = 1, ProductName = "Chai", Category = "Beverages", UnitPrice = 18.0000M, UnitsInStock = 39 }, new { ProductID = 2, ProductName = "Chang", Category = "Beverages", UnitPrice = 19.0000M, UnitsInStock = 17 }, new { ProductID = 3, ProductName = "Aniseed Syrup", Category = "Condiments", UnitPrice = 10.0000M, UnitsInStock = 13 }, new { ProductID = 4, ProductName = "Chef Anton's Cajun Seasoning", Category = "Condiments", UnitPrice = 22.0000M, UnitsInStock = 53 }, new { ProductID = 5, ProductName = "Chef Anton's Gumbo Mix", Category = "Condiments", UnitPrice = 21.3500M, UnitsInStock = 0 }, new { ProductID = 6, ProductName = "Grandma's Boysenberry Spread", Category = "Condiments", UnitPrice = 25.0000M, UnitsInStock = 120 }, new { ProductID = 7, ProductName = "Uncle Bob's Organic Dried Pears", Category = "Produce", UnitPrice = 30.0000M, UnitsInStock = 15 }, new { ProductID = 8, ProductName = "Northwoods Cranberry Sauce", Category = "Condiments", UnitPrice = 40.0000M, UnitsInStock = 6 }, new { ProductID = 9, ProductName = "Mishi Kobe Niku", Category = "Meat/Poultry", UnitPrice = 97.0000M, UnitsInStock = 29 }, new { ProductID = 10, ProductName = "Ikura", Category = "Seafood", UnitPrice = 31.0000M, UnitsInStock = 31 }, new { ProductID = 11, ProductName = "Queso Cabrales", Category = "Dairy Products", UnitPrice = 21.0000M, UnitsInStock = 22 }, new { ProductID = 12, ProductName = "Queso Manchego La Pastora", Category = "Dairy Products", UnitPrice = 38.0000M, UnitsInStock = 86 }, new { ProductID = 13, ProductName = "Konbu", Category = "Seafood", UnitPrice = 6.0000M, UnitsInStock = 24 }, new { ProductID = 14, ProductName = "Tofu", Category = "Produce", UnitPrice = 23.2500M, UnitsInStock = 35 }, new { ProductID = 15, ProductName = "Genen Shouyu", Category = "Condiments", UnitPrice = 15.5000M, UnitsInStock = 39 }, new { ProductID = 16, ProductName = "Pavlova", Category = "Confections", UnitPrice = 17.4500M, UnitsInStock = 29 }, new { ProductID = 17, ProductName = "Alice Mutton", Category = "Meat/Poultry", UnitPrice = 39.0000M, UnitsInStock = 0 }, new { ProductID = 18, ProductName = "Carnarvon Tigers", Category = "Seafood", UnitPrice = 62.5000M, UnitsInStock = 42 }, new { ProductID = 19, ProductName = "Teatime Chocolate Biscuits", Category = "Confections", UnitPrice = 9.2000M, UnitsInStock = 25 }, new { ProductID = 20, ProductName = "Sir Rodney's Marmalade", Category = "Confections", UnitPrice = 81.0000M, UnitsInStock = 40 }, new { ProductID = 21, ProductName = "Sir Rodney's Scones", Category = "Confections", UnitPrice = 10.0000M, UnitsInStock = 3 }, new { ProductID = 22, ProductName = "Gustaf's Knäckebröd", Category = "Grains/Cereals", UnitPrice = 21.0000M, UnitsInStock = 104 }, new { ProductID = 23, ProductName = "Tunnbröd", Category = "Grains/Cereals", UnitPrice = 9.0000M, UnitsInStock = 61 }, new { ProductID = 24, ProductName = "Guaraná Fantástica", Category = "Beverages", UnitPrice = 4.5000M, UnitsInStock = 20 }, new { ProductID = 25, ProductName = "NuNuCa Nuß-Nougat-Creme", Category = "Confections", UnitPrice = 14.0000M, UnitsInStock = 76 }, new { ProductID = 26, ProductName = "Gumbär Gummibärchen", Category = "Confections", UnitPrice = 31.2300M, UnitsInStock = 15 }, new { ProductID = 27, ProductName = "Schoggi Schokolade", Category = "Confections", UnitPrice = 43.9000M, UnitsInStock = 49 }, new { ProductID = 28, ProductName = "Rössle Sauerkraut", Category = "Produce", UnitPrice = 45.6000M, UnitsInStock = 26 }, new { ProductID = 29, ProductName = "Thüringer Rostbratwurst", Category = "Meat/Poultry", UnitPrice = 123.7900M, UnitsInStock = 0 }, new { ProductID = 30, ProductName = "Nord-Ost Matjeshering", Category = "Seafood", UnitPrice = 25.8900M, UnitsInStock = 10 }, new { ProductID = 31, ProductName = "Gorgonzola Telino", Category = "Dairy Products", UnitPrice = 12.5000M, UnitsInStock = 0 }, new { ProductID = 32, ProductName = "Mascarpone Fabioli", Category = "Dairy Products", UnitPrice = 32.0000M, UnitsInStock = 9 }, new { ProductID = 33, ProductName = "Geitost", Category = "Dairy Products", UnitPrice = 2.5000M, UnitsInStock = 112 }, new { ProductID = 34, ProductName = "Sasquatch Ale", Category = "Beverages", UnitPrice = 14.0000M, UnitsInStock = 111 }, new { ProductID = 35, ProductName = "Steeleye Stout", Category = "Beverages", UnitPrice = 18.0000M, UnitsInStock = 20 }, new { ProductID = 36, ProductName = "Inlagd Sill", Category = "Seafood", UnitPrice = 19.0000M, UnitsInStock = 112 }, new { ProductID = 37, ProductName = "Gravad lax", Category = "Seafood", UnitPrice = 26.0000M, UnitsInStock = 11 }, new { ProductID = 38, ProductName = "Côte de Blaye", Category = "Beverages", UnitPrice = 263.5000M, UnitsInStock = 17 }, new { ProductID = 39, ProductName = "Chartreuse verte", Category = "Beverages", UnitPrice = 18.0000M, UnitsInStock = 69 }, new { ProductID = 40, ProductName = "Boston Crab Meat", Category = "Seafood", UnitPrice = 18.4000M, UnitsInStock = 123 }, new { ProductID = 41, ProductName = "Jack's New England Clam Chowder", Category = "Seafood", UnitPrice = 9.6500M, UnitsInStock = 85 }, new { ProductID = 42, ProductName = "Singaporean Hokkien Fried Mee", Category = "Grains/Cereals", UnitPrice = 14.0000M, UnitsInStock = 26 }, new { ProductID = 43, ProductName = "Ipoh Coffee", Category = "Beverages", UnitPrice = 46.0000M, UnitsInStock = 17 }, new { ProductID = 44, ProductName = "Gula Malacca", Category = "Condiments", UnitPrice = 19.4500M, UnitsInStock = 27 }, new { ProductID = 45, ProductName = "Rogede sild", Category = "Seafood", UnitPrice = 9.5000M, UnitsInStock = 5 }, new { ProductID = 46, ProductName = "Spegesild", Category = "Seafood", UnitPrice = 12.0000M, UnitsInStock = 95 }, new { ProductID = 47, ProductName = "Zaanse koeken", Category = "Confections", UnitPrice = 9.5000M, UnitsInStock = 36 }, new { ProductID = 48, ProductName = "Chocolade", Category = "Confections", UnitPrice = 12.7500M, UnitsInStock = 15 }, new { ProductID = 49, ProductName = "Maxilaku", Category = "Confections", UnitPrice = 20.0000M, UnitsInStock = 10 }, new { ProductID = 50, ProductName = "Valkoinen suklaa", Category = "Confections", UnitPrice = 16.2500M, UnitsInStock = 65 }, new { ProductID = 51, ProductName = "Manjimup Dried Apples", Category = "Produce", UnitPrice = 53.0000M, UnitsInStock = 20 }, new { ProductID = 52, ProductName = "Filo Mix", Category = "Grains/Cereals", UnitPrice = 7.0000M, UnitsInStock = 38 }, new { ProductID = 53, ProductName = "Perth Pasties", Category = "Meat/Poultry", UnitPrice = 32.8000M, UnitsInStock = 0 }, new { ProductID = 54, ProductName = "Tourtière", Category = "Meat/Poultry", UnitPrice = 7.4500M, UnitsInStock = 21 }, new { ProductID = 55, ProductName = "Pâté chinois", Category = "Meat/Poultry", UnitPrice = 24.0000M, UnitsInStock = 115 }, new { ProductID = 56, ProductName = "Gnocchi di nonna Alice", Category = "Grains/Cereals", UnitPrice = 38.0000M, UnitsInStock = 21 }, new { ProductID = 57, ProductName = "Ravioli Angelo", Category = "Grains/Cereals", UnitPrice = 19.5000M, UnitsInStock = 36 }, new { ProductID = 58, ProductName = "Escargots de Bourgogne", Category = "Seafood", UnitPrice = 13.2500M, UnitsInStock = 62 }, new { ProductID = 59, ProductName = "Raclette Courdavault", Category = "Dairy Products", UnitPrice = 55.0000M, UnitsInStock = 79 }, new { ProductID = 60, ProductName = "Camembert Pierrot", Category = "Dairy Products", UnitPrice = 34.0000M, UnitsInStock = 19 }, new { ProductID = 61, ProductName = "Sirop d'érable", Category = "Condiments", UnitPrice = 28.5000M, UnitsInStock = 113 }, new { ProductID = 62, ProductName = "Tarte au sucre", Category = "Confections", UnitPrice = 49.3000M, UnitsInStock = 17 }, new { ProductID = 63, ProductName = "Vegie-spread", Category = "Condiments", UnitPrice = 43.9000M, UnitsInStock = 24 }, new { ProductID = 64, ProductName = "Wimmers gute Semmelknödel", Category = "Grains/Cereals", UnitPrice = 33.2500M, UnitsInStock = 22 }, new { ProductID = 65, ProductName = "Louisiana Fiery Hot Pepper Sauce", Category = "Condiments", UnitPrice = 21.0500M, UnitsInStock = 76 }, new { ProductID = 66, ProductName = "Louisiana Hot Spiced Okra", Category = "Condiments", UnitPrice = 17.0000M, UnitsInStock = 4 }, new { ProductID = 67, ProductName = "Laughing Lumberjack Lager", Category = "Beverages", UnitPrice = 14.0000M, UnitsInStock = 52 }, new { ProductID = 68, ProductName = "Scottish Longbreads", Category = "Confections", UnitPrice = 12.5000M, UnitsInStock = 6 }, new { ProductID = 69, ProductName = "Gudbrandsdalsost", Category = "Dairy Products", UnitPrice = 36.0000M, UnitsInStock = 26 }, new { ProductID = 70, ProductName = "Outback Lager", Category = "Beverages", UnitPrice = 15.0000M, UnitsInStock = 15 }, new { ProductID = 71, ProductName = "Flotemysost", Category = "Dairy Products", UnitPrice = 21.5000M, UnitsInStock = 26 }, new { ProductID = 72, ProductName = "Mozzarella di Giovanni", Category = "Dairy Products", UnitPrice = 34.8000M, UnitsInStock = 14 }, new { ProductID = 73, ProductName = "Röd Kaviar", Category = "Seafood", UnitPrice = 15.0000M, UnitsInStock = 101 }, new { ProductID = 74, ProductName = "Longlife Tofu", Category = "Produce", UnitPrice = 10.0000M, UnitsInStock = 4 }, new { ProductID = 75, ProductName = "Rhönbräu Klosterbier", Category = "Beverages", UnitPrice = 7.7500M, UnitsInStock = 125 }, new { ProductID = 76, ProductName = "Lakkalikööri", Category = "Beverages", UnitPrice = 18.0000M, UnitsInStock = 57 }, new { ProductID = 77, ProductName = "Original Frankfurter grüne Soße", Category = "Condiments", UnitPrice = 13.0000M, UnitsInStock = 32 } }; foreach (var x in productList) { table.Rows.Add(new object[] { x.ProductID, x.ProductName, x.Category, x.UnitPrice, x.UnitsInStock }); } return table; } } #endregion ================================================ FILE: csharp/linq/101-linq-examples.workbook/Customers.xml ================================================  ALFKI Alfreds Futterkiste
Obere Str. 57
Berlin 12209 Germany 030-0074321 030-0076545 10643 1997-08-25T00:00:00 814.50 10692 1997-10-03T00:00:00 878.00 10702 1997-10-13T00:00:00 330.00 10835 1998-01-15T00:00:00 845.80 10952 1998-03-16T00:00:00 471.20 11011 1998-04-09T00:00:00 933.50
ANATR Ana Trujillo Emparedados y helados
Avda. de la Constitución 2222
México D.F. 05021 Mexico (5) 555-4729 (5) 555-3745 10308 1996-09-18T00:00:00 88.80 10625 1997-08-08T00:00:00 479.75 10759 1997-11-28T00:00:00 320.00 10926 1998-03-04T00:00:00 514.40
ANTON Antonio Moreno Taquería
Mataderos 2312
México D.F. 05023 Mexico (5) 555-3932 10365 1996-11-27T00:00:00 403.20 10507 1997-04-15T00:00:00 749.06 10535 1997-05-13T00:00:00 1940.85 10573 1997-06-19T00:00:00 2082.00 10677 1997-09-22T00:00:00 813.36 10682 1997-09-25T00:00:00 375.50 10856 1998-01-28T00:00:00 660.00
AROUT Around the Horn
120 Hanover Sq.
London WA1 1DP UK (171) 555-7788 (171) 555-6750 10355 1996-11-15T00:00:00 480.00 10383 1996-12-16T00:00:00 899.00 10453 1997-02-21T00:00:00 407.70 10558 1997-06-04T00:00:00 2142.90 10707 1997-10-16T00:00:00 1641.00 10741 1997-11-14T00:00:00 228.00 10743 1997-11-17T00:00:00 319.20 10768 1997-12-08T00:00:00 1477.00 10793 1997-12-24T00:00:00 191.10 10864 1998-02-02T00:00:00 282.00 10920 1998-03-03T00:00:00 390.00 10953 1998-03-16T00:00:00 4441.25 11016 1998-04-10T00:00:00 491.50
BERGS Berglunds snabbköp
Berguvsvägen 8
Luleå S-958 22 Sweden 0921-12 34 65 0921-12 34 67 10278 1996-08-12T00:00:00 1488.80 10280 1996-08-14T00:00:00 613.20 10384 1996-12-16T00:00:00 2222.40 10444 1997-02-12T00:00:00 1031.70 10445 1997-02-13T00:00:00 174.90 10524 1997-05-01T00:00:00 3192.65 10572 1997-06-18T00:00:00 1501.08 10626 1997-08-11T00:00:00 1503.60 10654 1997-09-02T00:00:00 601.83 10672 1997-09-17T00:00:00 3815.25 10689 1997-10-01T00:00:00 472.50 10733 1997-11-07T00:00:00 1459.00 10778 1997-12-16T00:00:00 96.50 10837 1998-01-16T00:00:00 1064.50 10857 1998-01-28T00:00:00 2048.21 10866 1998-02-03T00:00:00 1096.20 10875 1998-02-06T00:00:00 709.55 10924 1998-03-04T00:00:00 1835.70
BLAUS Blauer See Delikatessen
Forsterstr. 57
Mannheim 68306 Germany 0621-08460 0621-08924 10501 1997-04-09T00:00:00 149.00 10509 1997-04-17T00:00:00 136.80 10582 1997-06-27T00:00:00 330.00 10614 1997-07-29T00:00:00 464.00 10853 1998-01-27T00:00:00 625.00 10956 1998-03-17T00:00:00 677.00 11058 1998-04-29T00:00:00 858.00
BLONP Blondel père et fils
24, place Kléber
Strasbourg 67000 France 88.60.15.31 88.60.15.32 10265 1996-07-25T00:00:00 1176.00 10297 1996-09-04T00:00:00 1420.00 10360 1996-11-22T00:00:00 7390.20 10436 1997-02-05T00:00:00 1994.52 10449 1997-02-18T00:00:00 1838.20 10559 1997-06-05T00:00:00 520.41 10566 1997-06-12T00:00:00 1761.00 10584 1997-06-30T00:00:00 593.75 10628 1997-08-12T00:00:00 450.00 10679 1997-09-23T00:00:00 660.00 10826 1998-01-12T00:00:00 730.00
BOLID Bólido Comidas preparadas
C/ Araquil, 67
Madrid 28023 Spain (91) 555 22 82 (91) 555 91 99 10326 1996-10-10T00:00:00 982.00 10801 1997-12-29T00:00:00 3026.85 10970 1998-03-24T00:00:00 224.00
BONAP Bon app'
12, rue des Bouchers
Marseille 13008 France 91.24.45.40 91.24.45.41 10331 1996-10-16T00:00:00 88.50 10340 1996-10-29T00:00:00 2436.18 10362 1996-11-25T00:00:00 1549.60 10470 1997-03-11T00:00:00 1820.80 10511 1997-04-18T00:00:00 2550.00 10525 1997-05-02T00:00:00 818.40 10663 1997-09-10T00:00:00 1930.40 10715 1997-10-23T00:00:00 1296.00 10730 1997-11-05T00:00:00 484.26 10732 1997-11-06T00:00:00 360.00 10755 1997-11-26T00:00:00 1948.50 10827 1998-01-12T00:00:00 843.00 10871 1998-02-05T00:00:00 1979.23 10876 1998-02-09T00:00:00 917.00 10932 1998-03-06T00:00:00 1788.63 10940 1998-03-11T00:00:00 360.00 11076 1998-05-06T00:00:00 792.75
BOTTM Bottom-Dollar Markets
23 Tsawassen Blvd.
Tsawassen BC T2F 8M4 Canada (604) 555-4729 (604) 555-3745 10389 1996-12-20T00:00:00 1832.80 10410 1997-01-10T00:00:00 802.00 10411 1997-01-10T00:00:00 966.80 10431 1997-01-30T00:00:00 1892.25 10492 1997-04-01T00:00:00 851.20 10742 1997-11-14T00:00:00 3118.00 10918 1998-03-02T00:00:00 1447.50 10944 1998-03-12T00:00:00 1025.32 10949 1998-03-13T00:00:00 4422.00 10975 1998-03-25T00:00:00 717.50 10982 1998-03-27T00:00:00 1014.00 11027 1998-04-16T00:00:00 877.72 11045 1998-04-23T00:00:00 1309.50 11048 1998-04-24T00:00:00 525.00
BSBEV B's Beverages
Fauntleroy Circus
London EC2 5NT UK (171) 555-1212 10289 1996-08-26T00:00:00 479.40 10471 1997-03-11T00:00:00 1328.00 10484 1997-03-24T00:00:00 386.20 10538 1997-05-15T00:00:00 139.80 10539 1997-05-16T00:00:00 355.50 10578 1997-06-24T00:00:00 477.00 10599 1997-07-15T00:00:00 493.00 10943 1998-03-11T00:00:00 711.00 10947 1998-03-13T00:00:00 220.00 11023 1998-04-14T00:00:00 1500.00
CACTU Cactus Comidas para llevar
Cerrito 333
Buenos Aires 1010 Argentina (1) 135-5555 (1) 135-4892 10521 1997-04-29T00:00:00 225.50 10782 1997-12-17T00:00:00 12.50 10819 1998-01-07T00:00:00 477.00 10881 1998-02-11T00:00:00 150.00 10937 1998-03-10T00:00:00 644.80 11054 1998-04-28T00:00:00 305.00
CENTC Centro comercial Moctezuma
Sierras de Granada 9993
México D.F. 05022 Mexico (5) 555-3392 (5) 555-7293 10259 1996-07-18T00:00:00 100.80
CHOPS Chop-suey Chinese
Hauptstr. 29
Bern 3012 Switzerland 0452-076545 10254 1996-07-11T00:00:00 556.62 10370 1996-12-03T00:00:00 1117.60 10519 1997-04-28T00:00:00 2314.20 10731 1997-11-06T00:00:00 1890.50 10746 1997-11-19T00:00:00 2311.70 10966 1998-03-20T00:00:00 1098.46 11029 1998-04-16T00:00:00 1286.80 11041 1998-04-22T00:00:00 1773.00
COMMI Comércio Mineiro
Av. dos Lusíadas, 23
São Paulo SP 05432-043 Brazil (11) 555-7647 10290 1996-08-27T00:00:00 2169.00 10466 1997-03-06T00:00:00 216.00 10494 1997-04-02T00:00:00 912.00 10969 1998-03-23T00:00:00 108.00 11042 1998-04-22T00:00:00 405.75
CONSH Consolidated Holdings
Berkeley Gardens, 12 Brewery
London WX1 6LT UK (171) 555-2282 (171) 555-9199 10435 1997-02-04T00:00:00 631.60 10462 1997-03-03T00:00:00 156.00 10848 1998-01-23T00:00:00 931.50
DRACD Drachenblut Delikatessen
Walserweg 21
Aachen 52066 Germany 0241-039123 0241-059428 10363 1996-11-26T00:00:00 447.20 10391 1996-12-23T00:00:00 86.40 10797 1997-12-25T00:00:00 420.00 10825 1998-01-09T00:00:00 1030.76 11036 1998-04-20T00:00:00 1692.00 11067 1998-05-04T00:00:00 86.85
DUMON Du monde entier
67, rue des Cinquante Otages
Nantes 44000 France 40.67.88.88 40.67.89.89 10311 1996-09-20T00:00:00 268.80 10609 1997-07-24T00:00:00 424.00 10683 1997-09-26T00:00:00 63.00 10890 1998-02-16T00:00:00 860.10
EASTC Eastern Connection
35 King George
London WX3 6FW UK (171) 555-0297 (171) 555-3373 10364 1996-11-26T00:00:00 950.00 10400 1997-01-01T00:00:00 3063.00 10532 1997-05-09T00:00:00 796.35 10726 1997-11-03T00:00:00 655.00 10987 1998-03-31T00:00:00 2772.00 11024 1998-04-15T00:00:00 1966.81 11047 1998-04-24T00:00:00 817.88 11056 1998-04-28T00:00:00 3740.00
ERNSH Ernst Handel
Kirchgasse 6
Graz 8010 Austria 7675-3425 7675-3426 10258 1996-07-17T00:00:00 1614.88 10263 1996-07-23T00:00:00 1873.80 10351 1996-11-11T00:00:00 5398.72 10368 1996-11-29T00:00:00 1689.78 10382 1996-12-13T00:00:00 2900.00 10390 1996-12-23T00:00:00 2090.88 10402 1997-01-02T00:00:00 2713.50 10403 1997-01-03T00:00:00 855.02 10430 1997-01-30T00:00:00 4899.20 10442 1997-02-11T00:00:00 1792.00 10514 1997-04-22T00:00:00 8623.45 10571 1997-06-17T00:00:00 550.59 10595 1997-07-10T00:00:00 4725.00 10633 1997-08-15T00:00:00 5510.59 10667 1997-09-12T00:00:00 1536.80 10698 1997-10-09T00:00:00 3436.44 10764 1997-12-03T00:00:00 2286.00 10771 1997-12-10T00:00:00 344.00 10773 1997-12-11T00:00:00 2030.40 10776 1997-12-15T00:00:00 6635.28 10795 1997-12-24T00:00:00 2158.00 10836 1998-01-16T00:00:00 4705.50 10854 1998-01-27T00:00:00 2966.50 10895 1998-02-18T00:00:00 6379.40 10968 1998-03-23T00:00:00 1408.00 10979 1998-03-26T00:00:00 4813.50 10990 1998-04-01T00:00:00 4288.85 11008 1998-04-08T00:00:00 4680.90 11017 1998-04-13T00:00:00 6750.00 11072 1998-05-05T00:00:00 5218.00
FAMIA Familia Arquibaldo
Rua Orós, 92
São Paulo SP 05442-030 Brazil (11) 555-9857 10347 1996-11-06T00:00:00 814.42 10386 1996-12-18T00:00:00 166.00 10414 1997-01-14T00:00:00 224.83 10512 1997-04-21T00:00:00 525.30 10581 1997-06-26T00:00:00 310.00 10650 1997-08-29T00:00:00 1779.20 10725 1997-10-31T00:00:00 287.80
FISSA FISSA Fabrica Inter. Salchichas S.A.
C/ Moralzarzal, 86
Madrid 28034 Spain (91) 555 94 44 (91) 555 55 93
FOLIG Folies gourmandes
184, chaussée de Tournai
Lille 59000 France 20.16.10.16 20.16.10.17 10408 1997-01-08T00:00:00 1622.40 10480 1997-03-20T00:00:00 756.00 10634 1997-08-15T00:00:00 4985.50 10763 1997-12-03T00:00:00 616.00 10789 1997-12-22T00:00:00 3687.00
FOLKO Folk och fä HB
Åkergatan 24
Bräcke S-844 67 Sweden 0695-34 67 21 10264 1996-07-24T00:00:00 695.62 10327 1996-10-11T00:00:00 1810.00 10378 1996-12-10T00:00:00 103.20 10434 1997-02-03T00:00:00 321.12 10460 1997-02-28T00:00:00 176.10 10533 1997-05-12T00:00:00 2222.20 10561 1997-06-06T00:00:00 2844.50 10703 1997-10-14T00:00:00 2545.00 10762 1997-12-02T00:00:00 4337.00 10774 1997-12-11T00:00:00 868.75 10824 1998-01-09T00:00:00 250.80 10880 1998-02-10T00:00:00 1500.00 10902 1998-02-23T00:00:00 863.43 10955 1998-03-17T00:00:00 74.40 10977 1998-03-26T00:00:00 2233.00 10980 1998-03-27T00:00:00 248.00 10993 1998-04-01T00:00:00 4895.44 11001 1998-04-06T00:00:00 2769.00 11050 1998-04-27T00:00:00 810.00
FRANK Frankenversand
Berliner Platz 43
München 80805 Germany 089-0877310 089-0877451 10267 1996-07-29T00:00:00 3536.60 10337 1996-10-24T00:00:00 2467.00 10342 1996-10-30T00:00:00 1840.64 10396 1996-12-27T00:00:00 1903.80 10488 1997-03-27T00:00:00 1512.00 10560 1997-06-06T00:00:00 1072.42 10623 1997-08-07T00:00:00 1336.95 10653 1997-09-02T00:00:00 1083.15 10670 1997-09-16T00:00:00 2301.75 10675 1997-09-19T00:00:00 1423.00 10717 1997-10-24T00:00:00 1270.75 10791 1997-12-23T00:00:00 1829.76 10859 1998-01-29T00:00:00 1078.69 10929 1998-03-05T00:00:00 1174.75 11012 1998-04-09T00:00:00 2825.30
FRANR France restauration
54, rue Royale
Nantes 44000 France 40.32.21.21 40.32.21.20 10671 1997-09-17T00:00:00 920.10 10860 1998-01-29T00:00:00 519.00 10971 1998-03-24T00:00:00 1733.06
FRANS Franchi S.p.A.
Via Monte Bianco 34
Torino 10100 Italy 011-4988260 011-4988261 10422 1997-01-22T00:00:00 49.80 10710 1997-10-20T00:00:00 93.50 10753 1997-11-25T00:00:00 88.00 10807 1997-12-31T00:00:00 18.40 11026 1998-04-15T00:00:00 1030.00 11060 1998-04-30T00:00:00 266.00
FURIB Furia Bacalhau e Frutos do Mar
Jardim das rosas n. 32
Lisboa 1675 Portugal (1) 354-2534 (1) 354-2535 10328 1996-10-14T00:00:00 1168.00 10352 1996-11-12T00:00:00 136.30 10464 1997-03-04T00:00:00 1609.28 10491 1997-03-31T00:00:00 259.50 10551 1997-05-28T00:00:00 1677.30 10604 1997-07-18T00:00:00 230.85 10664 1997-09-10T00:00:00 1288.39 10963 1998-03-19T00:00:00 57.80
GALED Galería del gastrónomo
Rambla de Cataluña, 23
Barcelona 08022 Spain (93) 203 4560 (93) 203 4561 10366 1996-11-28T00:00:00 136.00 10426 1997-01-27T00:00:00 338.20 10568 1997-06-13T00:00:00 155.00 10887 1998-02-13T00:00:00 70.00 10928 1998-03-05T00:00:00 137.50
GODOS Godos Cocina Típica
C/ Romero, 33
Sevilla 41101 Spain (95) 555 82 82 10303 1996-09-11T00:00:00 1117.80 10550 1997-05-28T00:00:00 683.30 10629 1997-08-12T00:00:00 2775.05 10872 1998-02-05T00:00:00 2058.46 10874 1998-02-06T00:00:00 310.00 10888 1998-02-16T00:00:00 605.00 10911 1998-02-26T00:00:00 858.00 10948 1998-03-13T00:00:00 2362.25 11009 1998-04-08T00:00:00 616.50 11037 1998-04-21T00:00:00 60.00
GOURL Gourmet Lanchonetes
Av. Brasil, 442
Campinas SP 04876-786 Brazil (11) 555-9482 10423 1997-01-23T00:00:00 1020.00 10652 1997-09-01T00:00:00 318.84 10685 1997-09-29T00:00:00 801.10 10709 1997-10-17T00:00:00 3424.00 10734 1997-11-07T00:00:00 1498.35 10777 1997-12-15T00:00:00 224.00 10790 1997-12-22T00:00:00 722.50 10959 1998-03-18T00:00:00 131.75 11049 1998-04-24T00:00:00 273.60
GREAL Great Lakes Food Market
2732 Baker Blvd.
Eugene OR 97403 USA (503) 555-7555 10528 1997-05-06T00:00:00 392.20 10589 1997-07-04T00:00:00 72.00 10616 1997-07-31T00:00:00 4807.00 10617 1997-07-31T00:00:00 1402.50 10656 1997-09-04T00:00:00 604.22 10681 1997-09-25T00:00:00 1287.40 10816 1998-01-06T00:00:00 8446.45 10936 1998-03-09T00:00:00 456.00 11006 1998-04-07T00:00:00 329.68 11040 1998-04-22T00:00:00 200.00 11061 1998-04-30T00:00:00 510.00
GROSR GROSELLA-Restaurante
5ª Ave. Los Palos Grandes
Caracas DF 1081 Venezuela (2) 283-2951 (2) 283-3397 10268 1996-07-30T00:00:00 1101.20 10785 1997-12-18T00:00:00 387.50
HANAR Hanari Carnes
Rua do Paço, 67
Rio de Janeiro RJ 05454-876 Brazil (21) 555-0091 (21) 555-8765 10250 1996-07-08T00:00:00 1552.60 10253 1996-07-10T00:00:00 1444.80 10541 1997-05-19T00:00:00 1946.52 10645 1997-08-26T00:00:00 1535.00 10690 1997-10-02T00:00:00 862.50 10770 1997-12-09T00:00:00 236.25 10783 1997-12-18T00:00:00 1442.50 10886 1998-02-13T00:00:00 3127.50 10903 1998-02-24T00:00:00 932.05 10922 1998-03-03T00:00:00 742.50 10925 1998-03-04T00:00:00 475.15 10981 1998-03-27T00:00:00 15810.00 11022 1998-04-14T00:00:00 1402.00 11052 1998-04-27T00:00:00 1332.00
HILAA HILARIÓN-Abastos
Carrera 22 con Ave. Carlos Soublette #8-35
San Cristóbal Táchira 5022 Venezuela (5) 555-1340 (5) 555-1948 10257 1996-07-16T00:00:00 1119.90 10395 1996-12-26T00:00:00 2122.92 10476 1997-03-17T00:00:00 180.48 10486 1997-03-26T00:00:00 1272.00 10490 1997-03-31T00:00:00 3163.20 10498 1997-04-07T00:00:00 575.00 10552 1997-05-29T00:00:00 880.50 10601 1997-07-16T00:00:00 2285.00 10613 1997-07-29T00:00:00 353.20 10641 1997-08-22T00:00:00 2054.00 10705 1997-10-15T00:00:00 378.00 10796 1997-12-25T00:00:00 2341.36 10863 1998-02-02T00:00:00 441.15 10901 1998-02-23T00:00:00 934.50 10957 1998-03-18T00:00:00 1762.70 10960 1998-03-19T00:00:00 265.35 10976 1998-03-25T00:00:00 912.00 11055 1998-04-28T00:00:00 1727.50
HUNGC Hungry Coyote Import Store
City Center Plaza, 516 Main St.
Elgin OR 97827 USA (503) 555-6874 (503) 555-2376 10375 1996-12-06T00:00:00 338.00 10394 1996-12-25T00:00:00 442.00 10415 1997-01-15T00:00:00 102.40 10600 1997-07-16T00:00:00 479.80 10660 1997-09-08T00:00:00 1701.00
HUNGO Hungry Owl All-Night Grocers
8 Johnstown Road
Cork Co. Cork Ireland 2967 542 2967 3333 10298 1996-09-05T00:00:00 2645.00 10309 1996-09-19T00:00:00 1762.00 10335 1996-10-22T00:00:00 2036.16 10373 1996-12-05T00:00:00 1366.40 10380 1996-12-12T00:00:00 1313.82 10429 1997-01-29T00:00:00 1441.38 10503 1997-04-11T00:00:00 2048.50 10516 1997-04-24T00:00:00 2381.05 10567 1997-06-12T00:00:00 2519.00 10646 1997-08-27T00:00:00 1446.00 10661 1997-09-09T00:00:00 562.60 10687 1997-09-30T00:00:00 4960.90 10701 1997-10-13T00:00:00 2864.50 10712 1997-10-21T00:00:00 1233.48 10736 1997-11-11T00:00:00 997.00 10897 1998-02-19T00:00:00 10835.24 10912 1998-02-26T00:00:00 6200.55 10985 1998-03-30T00:00:00 2023.38 11063 1998-04-30T00:00:00 1342.95
ISLAT Island Trading
Garden House, Crowther Way
Cowes Isle of Wight PO31 7PJ UK (198) 555-8888 10315 1996-09-26T00:00:00 516.80 10318 1996-10-01T00:00:00 240.40 10321 1996-10-03T00:00:00 144.00 10473 1997-03-13T00:00:00 230.40 10621 1997-08-05T00:00:00 758.50 10674 1997-09-18T00:00:00 45.00 10749 1997-11-20T00:00:00 1080.00 10798 1997-12-26T00:00:00 446.60 10829 1998-01-13T00:00:00 1764.00 10933 1998-03-06T00:00:00 920.60
KOENE Königlich Essen
Maubelstr. 90
Brandenburg 14776 Germany 0555-09876 10323 1996-10-07T00:00:00 164.40 10325 1996-10-09T00:00:00 1497.00 10456 1997-02-25T00:00:00 557.60 10457 1997-02-25T00:00:00 1584.00 10468 1997-03-07T00:00:00 717.60 10506 1997-04-15T00:00:00 415.80 10542 1997-05-20T00:00:00 469.11 10630 1997-08-13T00:00:00 903.60 10718 1997-10-27T00:00:00 3463.00 10799 1997-12-26T00:00:00 1553.50 10817 1998-01-06T00:00:00 10952.84 10849 1998-01-23T00:00:00 967.82 10893 1998-02-18T00:00:00 5502.11 11028 1998-04-16T00:00:00 2160.00
LACOR La corne d'abondance
67, avenue de l'Europe
Versailles 78000 France 30.59.84.10 30.59.85.11 10858 1998-01-29T00:00:00 649.00 10927 1998-03-05T00:00:00 800.00 10972 1998-03-24T00:00:00 251.50 10973 1998-03-24T00:00:00 291.55
LAMAI La maison d'Asie
1 rue Alsace-Lorraine
Toulouse 31000 France 61.77.61.10 61.77.61.11 10350 1996-11-11T00:00:00 642.06 10358 1996-11-20T00:00:00 429.40 10371 1996-12-03T00:00:00 72.96 10413 1997-01-14T00:00:00 2123.20 10425 1997-01-24T00:00:00 360.00 10454 1997-02-21T00:00:00 331.20 10493 1997-04-02T00:00:00 608.40 10500 1997-04-09T00:00:00 523.26 10610 1997-07-25T00:00:00 299.25 10631 1997-08-14T00:00:00 55.80 10787 1997-12-19T00:00:00 2622.76 10832 1998-01-14T00:00:00 475.11 10923 1998-03-03T00:00:00 748.80 11051 1998-04-27T00:00:00 36.00
LAUGB Laughing Bacchus Wine Cellars
1900 Oak St.
Vancouver BC V3F 2K1 Canada (604) 555-3392 (604) 555-7293 10495 1997-04-03T00:00:00 278.00 10620 1997-08-05T00:00:00 57.50 10810 1998-01-01T00:00:00 187.00
LAZYK Lazy K Kountry Store
12 Orchestra Terrace
Walla Walla WA 99362 USA (509) 555-7969 (509) 555-6221 10482 1997-03-21T00:00:00 147.00 10545 1997-05-22T00:00:00 210.00
LEHMS Lehmanns Marktstand
Magazinweg 7
Frankfurt a.M. 60528 Germany 069-0245984 069-0245874 10279 1996-08-13T00:00:00 351.00 10284 1996-08-19T00:00:00 1170.38 10343 1996-10-31T00:00:00 1584.00 10497 1997-04-04T00:00:00 1380.60 10522 1997-04-30T00:00:00 2318.24 10534 1997-05-12T00:00:00 465.70 10536 1997-05-14T00:00:00 1645.00 10557 1997-06-03T00:00:00 1152.50 10592 1997-07-08T00:00:00 516.47 10593 1997-07-09T00:00:00 1994.40 10772 1997-12-10T00:00:00 3603.22 10862 1998-01-30T00:00:00 581.00 10891 1998-02-17T00:00:00 368.93 10934 1998-03-09T00:00:00 500.00 11070 1998-05-05T00:00:00 1629.98
LETSS Let's Stop N Shop
87 Polk St. Suite 5
San Francisco CA 94117 USA (415) 555-5938 10579 1997-06-25T00:00:00 317.75 10719 1997-10-27T00:00:00 844.25 10735 1997-11-10T00:00:00 536.40 10884 1998-02-12T00:00:00 1378.07
LILAS LILA-Supermercado
Carrera 52 con Ave. Bolívar #65-98 Llano Largo
Barquisimeto Lara 3508 Venezuela (9) 331-6954 (9) 331-7256 10283 1996-08-16T00:00:00 1414.80 10296 1996-09-03T00:00:00 1050.60 10330 1996-10-16T00:00:00 1649.00 10357 1996-11-19T00:00:00 1167.68 10381 1996-12-12T00:00:00 112.00 10461 1997-02-28T00:00:00 1538.70 10499 1997-04-08T00:00:00 1412.00 10543 1997-05-21T00:00:00 1504.50 10780 1997-12-16T00:00:00 720.00 10823 1998-01-09T00:00:00 2826.00 10899 1998-02-20T00:00:00 122.40 10997 1998-04-03T00:00:00 1885.00 11065 1998-05-01T00:00:00 189.42 11071 1998-05-05T00:00:00 484.50
LINOD LINO-Delicateses
Ave. 5 de Mayo Porlamar
I. de Margarita Nueva Esparta 4980 Venezuela (8) 34-56-12 (8) 34-93-93 10405 1997-01-06T00:00:00 400.00 10485 1997-03-25T00:00:00 1584.00 10638 1997-08-20T00:00:00 2720.05 10697 1997-10-08T00:00:00 805.42 10729 1997-11-04T00:00:00 1850.00 10811 1998-01-02T00:00:00 852.00 10838 1998-01-19T00:00:00 1938.38 10840 1998-01-19T00:00:00 211.20 10919 1998-03-02T00:00:00 1122.80 10954 1998-03-17T00:00:00 1659.54 11014 1998-04-10T00:00:00 243.18 11039 1998-04-21T00:00:00 3090.00
LONEP Lonesome Pine Restaurant
89 Chiaroscuro Rd.
Portland OR 97219 USA (503) 555-9573 (503) 555-9646 10307 1996-09-17T00:00:00 424.00 10317 1996-09-30T00:00:00 288.00 10544 1997-05-21T00:00:00 417.20 10662 1997-09-09T00:00:00 125.00 10665 1997-09-11T00:00:00 1295.00 10867 1998-02-03T00:00:00 98.40 10883 1998-02-12T00:00:00 36.00 11018 1998-04-13T00:00:00 1575.00
MAGAA Magazzini Alimentari Riuniti
Via Ludovico il Moro 22
Bergamo 24100 Italy 035-640230 035-640231 10275 1996-08-07T00:00:00 291.84 10300 1996-09-09T00:00:00 608.00 10404 1997-01-03T00:00:00 1591.25 10467 1997-03-06T00:00:00 235.20 10635 1997-08-18T00:00:00 1326.22 10754 1997-11-25T00:00:00 55.20 10784 1997-12-18T00:00:00 1488.00 10818 1998-01-07T00:00:00 833.00 10939 1998-03-10T00:00:00 637.50 10950 1998-03-16T00:00:00 110.00
MAISD Maison Dewey
Rue Joseph-Bens 532
Bruxelles B-1180 Belgium (02) 201 24 67 (02) 201 24 68 10529 1997-05-07T00:00:00 946.00 10649 1997-08-28T00:00:00 1434.00 10760 1997-12-01T00:00:00 2917.00 10892 1998-02-17T00:00:00 2090.00 10896 1998-02-19T00:00:00 750.50 10978 1998-03-26T00:00:00 1303.20 11004 1998-04-07T00:00:00 295.38
MEREP Mère Paillarde
43 rue St. Laurent
Montréal Québec H1J 1C3 Canada (514) 555-8054 (514) 555-8055 10332 1996-10-17T00:00:00 1786.88 10339 1996-10-28T00:00:00 3354.00 10376 1996-12-09T00:00:00 399.00 10424 1997-01-23T00:00:00 9194.56 10439 1997-02-07T00:00:00 1078.00 10505 1997-04-14T00:00:00 147.90 10565 1997-06-11T00:00:00 639.90 10570 1997-06-17T00:00:00 2465.25 10590 1997-07-07T00:00:00 1101.00 10605 1997-07-21T00:00:00 4109.70 10618 1997-08-01T00:00:00 2697.50 10619 1997-08-04T00:00:00 1260.00 10724 1997-10-30T00:00:00 638.50
MORGK Morgenstern Gesundkost
Heerstr. 22
Leipzig 04179 Germany 0342-023176 10277 1996-08-09T00:00:00 1200.80 10575 1997-06-20T00:00:00 2147.40 10699 1997-10-09T00:00:00 114.00 10779 1997-12-16T00:00:00 1335.00 10945 1998-03-12T00:00:00 245.00
NORTS North/South
South House, 300 Queensbridge
London SW7 1RZ UK (171) 555-7733 (171) 555-2530 10517 1997-04-24T00:00:00 352.00 10752 1997-11-24T00:00:00 252.00 11057 1998-04-29T00:00:00 45.00
OCEAN Océano Atlántico Ltda.
Ing. Gustavo Moncada 8585, Piso 20-A
Buenos Aires 1010 Argentina (1) 135-5333 (1) 135-5535 10409 1997-01-09T00:00:00 319.20 10531 1997-05-08T00:00:00 110.00 10898 1998-02-20T00:00:00 30.00 10958 1998-03-18T00:00:00 781.00 10986 1998-03-30T00:00:00 2220.00
OLDWO Old World Delicatessen
2743 Bering St.
Anchorage AK 99508 USA (907) 555-7584 (907) 555-2880 10260 1996-07-19T00:00:00 1504.65 10305 1996-09-13T00:00:00 3741.30 10338 1996-10-25T00:00:00 934.50 10441 1997-02-10T00:00:00 1755.00 10594 1997-07-09T00:00:00 565.50 10680 1997-09-24T00:00:00 1261.88 10706 1997-10-16T00:00:00 1893.00 10855 1998-01-27T00:00:00 2227.89 10965 1998-03-20T00:00:00 848.00 11034 1998-04-20T00:00:00 539.40
OTTIK Ottilies Käseladen
Mehrheimerstr. 369
Köln 50739 Germany 0221-0644327 0221-0765721 10407 1997-01-07T00:00:00 1194.00 10508 1997-04-16T00:00:00 240.00 10554 1997-05-30T00:00:00 1728.52 10580 1997-06-26T00:00:00 1013.74 10684 1997-09-26T00:00:00 1768.00 10766 1997-12-05T00:00:00 2310.00 10833 1998-01-15T00:00:00 906.93 10999 1998-04-03T00:00:00 1197.95 11020 1998-04-14T00:00:00 632.40
PARIS Paris spécialités
265, boulevard Charonne
Paris 75012 France (1) 42.34.22.66 (1) 42.34.22.77
PERIC Pericles Comidas clásicas
Calle Dr. Jorge Cash 321
México D.F. 05033 Mexico (5) 552-3745 (5) 545-3745 10322 1996-10-04T00:00:00 112.00 10354 1996-11-14T00:00:00 568.80 10474 1997-03-13T00:00:00 1249.10 10502 1997-04-10T00:00:00 816.30 10995 1998-04-02T00:00:00 1196.00 11073 1998-05-05T00:00:00 300.00
PICCO Piccolo und mehr
Geislweg 14
Salzburg 5020 Austria 6562-9722 6562-9723 10353 1996-11-13T00:00:00 8593.28 10392 1996-12-24T00:00:00 1440.00 10427 1997-01-27T00:00:00 651.00 10489 1997-03-28T00:00:00 439.20 10530 1997-05-08T00:00:00 4180.00 10597 1997-07-11T00:00:00 718.08 10686 1997-09-30T00:00:00 1404.45 10747 1997-11-19T00:00:00 1912.85 10844 1998-01-21T00:00:00 735.00 11053 1998-04-27T00:00:00 3055.00
PRINI Princesa Isabel Vinhos
Estrada da saúde n. 58
Lisboa 1756 Portugal (1) 356-5634 10336 1996-10-23T00:00:00 285.12 10397 1996-12-27T00:00:00 716.72 10433 1997-02-03T00:00:00 851.20 10477 1997-03-17T00:00:00 558.00 10808 1998-01-01T00:00:00 1411.00 11007 1998-04-08T00:00:00 2633.90
QUEDE Que Delícia
Rua da Panificadora, 12
Rio de Janeiro RJ 02389-673 Brazil (21) 555-4252 (21) 555-4545 10261 1996-07-19T00:00:00 448.00 10291 1996-08-27T00:00:00 497.52 10379 1996-12-11T00:00:00 863.28 10421 1997-01-21T00:00:00 1194.27 10587 1997-07-02T00:00:00 807.38 10647 1997-08-27T00:00:00 636.00 10720 1997-10-28T00:00:00 550.00 10794 1997-12-24T00:00:00 314.76 10989 1998-03-31T00:00:00 1353.60
QUEEN Queen Cozinha
Alameda dos Canàrios, 891
São Paulo SP 05487-020 Brazil (11) 555-1189 10372 1996-12-04T00:00:00 9210.90 10406 1997-01-07T00:00:00 1830.78 10487 1997-03-26T00:00:00 889.70 10637 1997-08-19T00:00:00 2761.94 10659 1997-09-05T00:00:00 1227.02 10704 1997-10-14T00:00:00 595.50 10728 1997-11-04T00:00:00 1296.75 10786 1997-12-19T00:00:00 1531.08 10868 1998-02-04T00:00:00 1920.60 10913 1998-02-26T00:00:00 768.75 10914 1998-02-27T00:00:00 537.50 10961 1998-03-19T00:00:00 1119.90 11068 1998-05-04T00:00:00 2027.08
QUICK QUICK-Stop
Taucherstraße 10
Cunewalde 01307 Germany 0372-035188 10273 1996-08-05T00:00:00 2037.28 10285 1996-08-20T00:00:00 1743.36 10286 1996-08-21T00:00:00 3016.00 10313 1996-09-24T00:00:00 182.40 10345 1996-11-04T00:00:00 2924.80 10361 1996-11-22T00:00:00 2046.24 10418 1997-01-17T00:00:00 1814.80 10451 1997-02-19T00:00:00 3849.66 10515 1997-04-23T00:00:00 9921.30 10527 1997-05-05T00:00:00 1503.00 10540 1997-05-19T00:00:00 10191.70 10549 1997-05-27T00:00:00 3554.28 10588 1997-07-03T00:00:00 3120.00 10658 1997-09-05T00:00:00 4464.60 10691 1997-10-03T00:00:00 10164.80 10694 1997-10-06T00:00:00 4825.00 10721 1997-10-29T00:00:00 923.88 10745 1997-11-18T00:00:00 4529.80 10765 1997-12-04T00:00:00 1515.60 10788 1997-12-22T00:00:00 731.50 10845 1998-01-21T00:00:00 3812.70 10865 1998-02-02T00:00:00 16387.50 10878 1998-02-10T00:00:00 1539.00 10938 1998-03-10T00:00:00 2731.88 10962 1998-03-19T00:00:00 3584.00 10991 1998-04-01T00:00:00 2296.00 10996 1998-04-02T00:00:00 560.00 11021 1998-04-14T00:00:00 6306.24
RANCH Rancho grande
Av. del Libertador 900
Buenos Aires 1010 Argentina (1) 123-5555 (1) 123-5556 10448 1997-02-17T00:00:00 443.40 10716 1997-10-24T00:00:00 706.00 10828 1998-01-13T00:00:00 932.00 10916 1998-02-27T00:00:00 686.70 11019 1998-04-13T00:00:00 76.00
RATTC Rattlesnake Canyon Grocery
2817 Milton Dr.
Albuquerque NM 87110 USA (505) 555-5939 (505) 555-3620 10262 1996-07-22T00:00:00 584.00 10272 1996-08-02T00:00:00 1456.00 10294 1996-08-30T00:00:00 1887.60 10314 1996-09-25T00:00:00 2094.30 10316 1996-09-27T00:00:00 2835.00 10346 1996-11-05T00:00:00 1618.88 10401 1997-01-01T00:00:00 3868.60 10479 1997-03-19T00:00:00 10495.60 10564 1997-06-10T00:00:00 1234.05 10569 1997-06-16T00:00:00 890.00 10598 1997-07-14T00:00:00 2388.50 10761 1997-12-02T00:00:00 507.00 10820 1998-01-07T00:00:00 1140.00 10852 1998-01-26T00:00:00 2984.00 10889 1998-02-16T00:00:00 11380.00 10988 1998-03-31T00:00:00 3574.80 11000 1998-04-06T00:00:00 903.75 11077 1998-05-06T00:00:00 1255.72
REGGC Reggiani Caseifici
Strada Provinciale 124
Reggio Emilia 42100 Italy 0522-556721 0522-556722 10288 1996-08-23T00:00:00 80.10 10428 1997-01-28T00:00:00 192.00 10443 1997-02-12T00:00:00 517.44 10562 1997-06-09T00:00:00 488.70 10586 1997-07-02T00:00:00 23.80 10655 1997-09-03T00:00:00 154.40 10727 1997-11-03T00:00:00 1624.50 10812 1998-01-02T00:00:00 1692.80 10908 1998-02-26T00:00:00 663.10 10942 1998-03-11T00:00:00 560.00 11010 1998-04-09T00:00:00 645.00 11062 1998-04-30T00:00:00 406.40
RICAR Ricardo Adocicados
Av. Copacabana, 267
Rio de Janeiro RJ 02389-890 Brazil (21) 555-3412 10287 1996-08-22T00:00:00 819.00 10299 1996-09-06T00:00:00 349.50 10447 1997-02-14T00:00:00 914.40 10481 1997-03-20T00:00:00 1472.00 10563 1997-06-10T00:00:00 965.00 10622 1997-08-06T00:00:00 560.00 10648 1997-08-28T00:00:00 372.38 10813 1998-01-05T00:00:00 602.40 10851 1998-01-26T00:00:00 2603.00 10877 1998-02-09T00:00:00 1955.12 11059 1998-04-29T00:00:00 1838.00
RICSU Richter Supermarkt
Grenzacherweg 237
Genève 1203 Switzerland 0897-034214 10255 1996-07-12T00:00:00 2490.50 10419 1997-01-20T00:00:00 2097.60 10537 1997-05-14T00:00:00 1823.80 10666 1997-09-12T00:00:00 4666.94 10751 1997-11-24T00:00:00 1631.48 10758 1997-11-28T00:00:00 1644.60 10931 1998-03-06T00:00:00 799.20 10951 1998-03-16T00:00:00 458.76 11033 1998-04-17T00:00:00 3232.80 11075 1998-05-06T00:00:00 498.10
ROMEY Romero y tomillo
Gran Vía, 1
Madrid 28001 Spain (91) 745 6200 (91) 745 6210 10281 1996-08-14T00:00:00 86.50 10282 1996-08-15T00:00:00 155.40 10306 1996-09-16T00:00:00 498.50 10917 1998-03-02T00:00:00 365.89 11013 1998-04-09T00:00:00 361.00
SANTG Santé Gourmet
Erling Skakkes gate 78
Stavern 4110 Norway 07-98 92 35 07-98 92 47 10387 1996-12-18T00:00:00 1058.40 10520 1997-04-29T00:00:00 200.00 10639 1997-08-20T00:00:00 500.00 10831 1998-01-14T00:00:00 2684.40 10909 1998-02-26T00:00:00 670.00 11015 1998-04-10T00:00:00 622.35
SAVEA Save-a-lot Markets
187 Suffolk Ln.
Boise ID 83720 USA (208) 555-8097 10324 1996-10-08T00:00:00 5275.72 10393 1996-12-25T00:00:00 2556.95 10398 1996-12-30T00:00:00 2505.60 10440 1997-02-10T00:00:00 4924.14 10452 1997-02-20T00:00:00 2018.50 10510 1997-04-18T00:00:00 4707.54 10555 1997-06-02T00:00:00 2944.40 10603 1997-07-18T00:00:00 1483.00 10607 1997-07-22T00:00:00 6475.40 10612 1997-07-28T00:00:00 6375.00 10627 1997-08-11T00:00:00 1185.75 10657 1997-09-04T00:00:00 4371.60 10678 1997-09-23T00:00:00 5256.50 10700 1997-10-10T00:00:00 1638.40 10711 1997-10-21T00:00:00 4451.70 10713 1997-10-22T00:00:00 2827.90 10714 1997-10-22T00:00:00 2205.75 10722 1997-10-29T00:00:00 1570.00 10748 1997-11-20T00:00:00 2196.00 10757 1997-11-27T00:00:00 3082.00 10815 1998-01-05T00:00:00 40.00 10847 1998-01-22T00:00:00 4931.92 10882 1998-02-11T00:00:00 892.64 10894 1998-02-18T00:00:00 2753.10 10941 1998-03-11T00:00:00 4011.75 10983 1998-03-27T00:00:00 720.90 10984 1998-03-30T00:00:00 1809.75 11002 1998-04-06T00:00:00 1811.10 11030 1998-04-17T00:00:00 12615.05 11031 1998-04-17T00:00:00 2393.50 11064 1998-05-01T00:00:00 4330.40
SEVES Seven Seas Imports
90 Wadhurst Rd.
London OX15 4NB UK (171) 555-1717 (171) 555-5646 10359 1996-11-21T00:00:00 3471.68 10377 1996-12-09T00:00:00 863.60 10388 1996-12-19T00:00:00 1228.80 10472 1997-03-12T00:00:00 1036.80 10523 1997-05-01T00:00:00 2444.31 10547 1997-05-23T00:00:00 1792.80 10800 1997-12-26T00:00:00 1468.94 10804 1997-12-30T00:00:00 2278.40 10869 1998-02-04T00:00:00 1630.00
SIMOB Simons bistro
Vinbæltet 34
København 1734 Denmark 31 12 34 56 31 13 35 57 10341 1996-10-29T00:00:00 352.60 10417 1997-01-16T00:00:00 11188.40 10556 1997-06-03T00:00:00 835.20 10642 1997-08-22T00:00:00 696.00 10669 1997-09-15T00:00:00 570.00 10802 1997-12-29T00:00:00 2942.81 11074 1998-05-06T00:00:00 232.08
SPECD Spécialités du monde
25, rue Lauriston
Paris 75016 France (1) 47.55.60.10 (1) 47.55.60.20 10738 1997-11-12T00:00:00 52.35 10907 1998-02-25T00:00:00 108.50 10964 1998-03-20T00:00:00 2052.50 11043 1998-04-22T00:00:00 210.00
SPLIR Split Rail Beer & Ale
P.O. Box 555
Lander WY 82520 USA (307) 555-4680 (307) 555-6525 10271 1996-08-01T00:00:00 48.00 10329 1996-10-15T00:00:00 4578.43 10349 1996-11-08T00:00:00 141.60 10369 1996-12-02T00:00:00 2390.40 10385 1996-12-17T00:00:00 691.20 10432 1997-01-31T00:00:00 485.00 10756 1997-11-27T00:00:00 1990.00 10821 1998-01-08T00:00:00 678.00 10974 1998-03-25T00:00:00 439.00
SUPRD Suprêmes délices
Boulevard Tirou, 255
Charleroi B-6000 Belgium (071) 23 67 22 20 (071) 23 67 22 21 10252 1996-07-09T00:00:00 3597.90 10302 1996-09-10T00:00:00 2708.80 10458 1997-02-26T00:00:00 3891.00 10463 1997-03-04T00:00:00 713.30 10475 1997-03-14T00:00:00 1505.18 10767 1997-12-05T00:00:00 28.00 10841 1998-01-20T00:00:00 4581.00 10846 1998-01-22T00:00:00 1112.00 10885 1998-02-12T00:00:00 1209.00 10930 1998-03-06T00:00:00 2255.50 11035 1998-04-20T00:00:00 1754.50 11038 1998-04-21T00:00:00 732.60
THEBI The Big Cheese
89 Jefferson Way, Suite 2
Portland OR 97201 USA (503) 555-3612 10310 1996-09-20T00:00:00 336.00 10708 1997-10-17T00:00:00 180.40 10805 1997-12-30T00:00:00 2775.00 10992 1998-04-01T00:00:00 69.60
THECR The Cracker Box
55 Grizzly Peak Rd.
Butte MT 59801 USA (406) 555-5834 (406) 555-8083 10624 1997-08-07T00:00:00 1393.24 10775 1997-12-12T00:00:00 228.00 11003 1998-04-06T00:00:00 326.00
TOMSP Toms Spezialitäten
Luisenstr. 48
Münster 44087 Germany 0251-031259 0251-035695 10438 1997-02-06T00:00:00 454.00 10446 1997-02-14T00:00:00 246.24 10548 1997-05-26T00:00:00 240.10 10608 1997-07-23T00:00:00 1064.00 10967 1998-03-23T00:00:00 910.40
TORTU Tortuga Restaurante
Avda. Azteca 123
México D.F. 05033 Mexico (5) 555-2933 10276 1996-08-08T00:00:00 420.00 10293 1996-08-29T00:00:00 848.70 10304 1996-09-12T00:00:00 954.40 10319 1996-10-02T00:00:00 1191.20 10518 1997-04-25T00:00:00 4150.05 10576 1997-06-23T00:00:00 838.45 10676 1997-09-22T00:00:00 534.85 10842 1998-01-20T00:00:00 975.00 10915 1998-02-27T00:00:00 539.50 11069 1998-05-04T00:00:00 360.00
TRADH Tradição Hipermercados
Av. Inês de Castro, 414
São Paulo SP 05634-030 Brazil (11) 555-2167 (11) 555-2168 10249 1996-07-05T00:00:00 1863.40 10292 1996-08-28T00:00:00 1296.00 10496 1997-04-04T00:00:00 190.00 10606 1997-07-22T00:00:00 1130.40 10830 1998-01-13T00:00:00 1974.00 10834 1998-01-15T00:00:00 1432.71 10839 1998-01-19T00:00:00 827.55
TRAIH Trail's Head Gourmet Provisioners
722 DaVinci Blvd.
Kirkland WA 98034 USA (206) 555-8257 (206) 555-2174 10574 1997-06-19T00:00:00 764.30 10577 1997-06-23T00:00:00 569.00 10822 1998-01-08T00:00:00 237.90
VAFFE Vaffeljernet
Smagsløget 45
Århus 8200 Denmark 86 21 32 43 86 22 33 44 10367 1996-11-28T00:00:00 834.20 10399 1996-12-31T00:00:00 1765.60 10465 1997-03-05T00:00:00 2518.00 10591 1997-07-07T00:00:00 812.50 10602 1997-07-17T00:00:00 48.75 10688 1997-10-01T00:00:00 3160.60 10744 1997-11-17T00:00:00 736.00 10769 1997-12-08T00:00:00 1684.28 10921 1998-03-03T00:00:00 1936.00 10946 1998-03-12T00:00:00 1407.50 10994 1998-04-02T00:00:00 940.50
VICTE Victuailles en stock
2, rue du Commerce
Lyon 69004 France 78.32.54.86 78.32.54.87 10251 1996-07-08T00:00:00 654.06 10334 1996-10-21T00:00:00 144.80 10450 1997-02-19T00:00:00 425.12 10459 1997-02-27T00:00:00 1659.20 10478 1997-03-18T00:00:00 471.20 10546 1997-05-23T00:00:00 2812.00 10806 1997-12-31T00:00:00 439.60 10814 1998-01-05T00:00:00 1788.45 10843 1998-01-21T00:00:00 159.00 10850 1998-01-23T00:00:00 629.00
VINET Vins et alcools Chevalier
59 rue de l'Abbaye
Reims 51100 France 26.47.15.10 26.47.15.11 10274 1996-08-06T00:00:00 538.60 10295 1996-09-02T00:00:00 121.60 10737 1997-11-11T00:00:00 139.80 10739 1997-11-12T00:00:00 240.00
WANDK Die Wandernde Kuh
Adenauerallee 900
Stuttgart 70563 Germany 0711-020361 0711-035428 10301 1996-09-09T00:00:00 755.00 10312 1996-09-23T00:00:00 1614.80 10348 1996-11-07T00:00:00 363.60 10356 1996-11-18T00:00:00 1106.40 10513 1997-04-22T00:00:00 1942.00 10632 1997-08-14T00:00:00 589.00 10640 1997-08-21T00:00:00 708.75 10651 1997-09-01T00:00:00 397.80 10668 1997-09-15T00:00:00 625.28 11046 1998-04-23T00:00:00 1485.80
WARTH Wartian Herkku
Torikatu 38
Oulu 90110 Finland 981-443655 981-443655 10266 1996-07-26T00:00:00 346.56 10270 1996-08-01T00:00:00 1376.00 10320 1996-10-03T00:00:00 516.00 10333 1996-10-18T00:00:00 877.20 10412 1997-01-13T00:00:00 334.80 10416 1997-01-16T00:00:00 720.00 10437 1997-02-05T00:00:00 393.00 10455 1997-02-24T00:00:00 2684.00 10526 1997-05-05T00:00:00 1151.40 10553 1997-05-30T00:00:00 1546.30 10583 1997-06-30T00:00:00 2237.50 10636 1997-08-19T00:00:00 629.50 10750 1997-11-21T00:00:00 1590.56 10781 1997-12-17T00:00:00 975.88 11025 1998-04-15T00:00:00 270.00
WELLI Wellington Importadora
Rua do Mercado, 12
Resende SP 08737-363 Brazil (14) 555-8122 10256 1996-07-15T00:00:00 517.80 10420 1997-01-21T00:00:00 1707.84 10585 1997-07-01T00:00:00 142.50 10644 1997-08-25T00:00:00 1371.80 10803 1997-12-30T00:00:00 1193.01 10809 1998-01-01T00:00:00 140.00 10900 1998-02-20T00:00:00 33.75 10905 1998-02-24T00:00:00 342.00 10935 1998-03-09T00:00:00 619.50
WHITC White Clover Markets
305 - 14th Ave. S. Suite 3B
Seattle WA 98128 USA (206) 555-4112 (206) 555-4115 10269 1996-07-31T00:00:00 642.20 10344 1996-11-01T00:00:00 2296.00 10469 1997-03-10T00:00:00 956.68 10483 1997-03-24T00:00:00 668.80 10504 1997-04-11T00:00:00 1388.50 10596 1997-07-11T00:00:00 1180.88 10693 1997-10-06T00:00:00 2071.20 10696 1997-10-08T00:00:00 996.00 10723 1997-10-30T00:00:00 468.45 10740 1997-11-13T00:00:00 1416.00 10861 1998-01-30T00:00:00 3523.40 10904 1998-02-24T00:00:00 1924.25 11032 1998-04-17T00:00:00 8902.50 11066 1998-05-01T00:00:00 928.75
WILMK Wilman Kala
Keskuskatu 45
Helsinki 21240 Finland 90-224 8858 90-224 8858 10248 1996-07-04T00:00:00 440.00 10615 1997-07-30T00:00:00 120.00 10673 1997-09-18T00:00:00 412.35 10695 1997-10-07T00:00:00 642.00 10873 1998-02-06T00:00:00 336.80 10879 1998-02-10T00:00:00 611.30 10910 1998-02-26T00:00:00 452.90 11005 1998-04-07T00:00:00 586.00
WOLZA Wolski Zajazd
ul. Filtrowa 68
Warszawa 01-012 Poland (26) 642-7012 (26) 642-7012 10374 1996-12-05T00:00:00 459.00 10611 1997-07-25T00:00:00 808.00 10792 1997-12-23T00:00:00 399.85 10870 1998-02-04T00:00:00 160.00 10906 1998-02-25T00:00:00 427.50 10998 1998-04-03T00:00:00 686.00 11044 1998-04-23T00:00:00 591.60
================================================ FILE: csharp/linq/101-linq-examples.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook platforms: - Console --- # 101 (and then some) LINQ Examples Language Integrated Query provides a consistent query syntax across a variety of data sources and formats. In a LINQ query, you are always working with objects. You use the same basic coding patterns to query and transform data in XML documents, SQL databases, Datasets, .NET collections, and any other format for which a LINQ provider is available. ```csharp //Support classes #load "101_Linq_Examples.csx" ``` ## Restriction Operators These examples show different uses of Restriction Operators: ### Where - Simple 1 This example finds all elements of an array less than 5 ```csharp int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; var lowNums = from num in numbers where num < 5 select num; ``` ### Where - Simple 2 This example finds all products that are out of stock. ```csharp List products = productList; var soldOutProducts = from prod in products where prod.UnitsInStock == 0 select prod; Console.WriteLine("Sold out products:"); foreach (var product in soldOutProducts) { Console.WriteLine($"{product.ProductName} is sold out."); }; soldOutProducts ``` ### Where - Simple 3 This example finds all products that are in stock and cost more than 3.00 per unit. ```csharp var expensiveInStockProducts = from prod in products where prod.UnitsInStock > 0 && prod.UnitPrice > 3.00M select prod; Console.WriteLine("In-stock products that cost more than $3.00:"); foreach (var product in expensiveInStockProducts) { Console.WriteLine($"{product.ProductName} is in stock and costs ${product.UnitPrice:N2}."); } expensiveInStockProducts ``` ### Where - Drilldown This example finds all customers in Washington and then uses the resulting sequence to drill down into their orders. ```csharp var waCustomers = from cust in customerList where cust.Region == "WA" select cust; Console.WriteLine("Customers from Washington and their orders:"); foreach (var customer in waCustomers) { Console.WriteLine("Customer {0}: {1}", customer.CustomerID, customer.CompanyName); foreach (var order in customer.Orders) { Console.WriteLine(" Order {0}: {1}", order.OrderID, order.OrderDate); } } waCustomers ``` ### Where - Indexed This example shows an indexed Where clause that returns digits whose name is shorter than their value. ```csharp string[] digits = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" }; var shortDigits = digits.Where((digit, index) => digit.Length < index); Console.WriteLine("Short digits:"); foreach (var d in shortDigits) { Console.WriteLine($"The word {d} is shorter than its value."); } ``` ## Projection Operators These samples shows different uses of Projection Operators ### Select - Simple 1 This sample uses `select` to produce a sequence of ints one higher than those in an existing array of ints. ```csharp using System.Data; using System.Linq; var numbers = testDS.Tables["Numbers"].AsEnumerable(); var numsPlusOne = from n in numbers select n.Field(0) + 1; Console.WriteLine("Numbers and their successors:"); TestHelper.ZipToStrings(numbers, numsPlusOne, (a,b)=>$"{a.Field(0)} + 1 = {b}"); ``` ### Select - Simple 2 This sample uses `select` to return a sequence of just the names of a list of products. ```csharp var products = testDS.Tables["Products"].AsEnumerable(); var productNames = from p in products select p.Field("ProductName"); Console.WriteLine("Product Names:"); foreach (var productName in productNames) { Console.WriteLine(productName); } ``` ### Select - Transformation This sample uses `select` to produce a sequence of strings representing the text version of a sequence of ints. ```csharp var numbers = testDS.Tables["Numbers"].AsEnumerable(); var strings = new [] { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" }; var textNums = numbers.Select(p => strings[p.Field("number")]); Console.WriteLine("Number strings:"); TestHelper.ZipToStrings(numbers, textNums, (a,b)=>$"String at index [{a.Field("number")}] is {b}"); ``` ### Select - Anonymous Types 1 This sample uses `select` to produce a sequence of the uppercase and lowercase versions of each word in the original array ```csharp var words = testDS.Tables["Words"].AsEnumerable(); var upperLowerWords = words.Select(p => new { Upper = (p.Field(0)).ToUpper(), Lower = (p.Field(0)).ToLower() }); foreach (var ul in upperLowerWords) { Console.WriteLine("Uppercase: " + ul.Upper + ", Lowercase: " + ul.Lower); } ``` ### Select - Anonymous Types 2 This sample uses `select` to produce a sequence containing text representations of digits and whether their length is even or odd. ```csharp var numbers = testDS.Tables["Numbers"].AsEnumerable(); var digits = testDS.Tables["Digits"]; string[] strings = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" }; var digitOddEvens = numbers. Select(n => new { Digit = digits.Rows[n.Field("number")]["digit"], Even = (n.Field("number") % 2 == 0) }); foreach (var d in digitOddEvens) { Console.WriteLine("The digit {0} is {1}.", d.Digit, d.Even ? "even" : "odd"); } ``` ### Select - Anonymous Types 3 This sample uses `select` to produce a sequence containing some properties of `Products`, including `UnitPrice` which is renamed to `Price` in the resulting type. ```csharp var products = testDS.Tables["Products"].AsEnumerable(); var productInfos = products. Select(n => new { ProductName = n.Field("ProductName"), Category = n.Field("Category"), Price = n.Field("UnitPrice") }); Console.WriteLine("Product Info:"); foreach (var productInfo in productInfos) { Console.WriteLine($"{productInfo.ProductName} is in the category {productInfo.Category} and costs ${productInfo.Price:N2} per unit."); } ``` ### Select - Indexed This sample uses an indexed `Select` clause to determine if the value of ints in an array match their position in the array. ```csharp var numbers = testDS.Tables["Numbers"].AsEnumerable(); var numsInPlace = numbers.Select((num, index) => new { Num = num.Field("number"), InPlace = (num.Field("number") == index) }); Console.WriteLine("Number: In-place:"); foreach (var n in numsInPlace) { Console.WriteLine("{0}: {1}", n.Num, n.InPlace); } ``` ### Select - Filtered This sample combines `select` and `where` to make a simple query that returns the text form of each digit less than 5. ```csharp var numbers = testDS.Tables["Numbers"].AsEnumerable(); var digits = testDS.Tables["Digits"]; var lowNums = from n in numbers where n.Field("number") < 5 select digits.Rows[n.Field("number")].Field("digit"); Console.WriteLine("Numbers < 5:"); foreach (var num in lowNums) { Console.WriteLine(num); } ``` ### SelectMany - Compound from 1 This sample uses a compound `from` clause to make a query that returns all pairs of numbers from both arrays such that the number from `numbersA` is less than the number from `numbersB`. ```csharp var numbersA = testDS.Tables["NumbersA"].AsEnumerable(); var numbersB = testDS.Tables["NumbersB"].AsEnumerable(); var pairs = from a in numbersA from b in numbersB where a.Field("number") < b.Field("number") select new { a = a.Field("number"), b = b.Field("number") }; Console.WriteLine("Pairs where a < b:"); foreach (var pair in pairs) { Console.WriteLine("{0} is less than {1}", pair.a, pair.b); } ``` ### SelectMany - Compound from 2 This sample uses a compound `from` clause to select all orders where the order total is less than 500.00. ```csharp var customers = testDS.Tables["Customers"].AsEnumerable(); var orders = testDS.Tables["Orders"].AsEnumerable(); var smallOrders = from c in customers from o in orders where c.Field("CustomerID") == o.Field("CustomerID") && o.Field("Total") < 500.00M select new { CustomerID = c.Field("CustomerID"), OrderID = o.Field("OrderID"), Total = o.Field("Total") }; ``` ### SelectMany - Compound from 3 This sample uses a compound `from` clause to select all orders where the order was made in 1998 or later. ```csharp var customers = testDS.Tables["Customers"].AsEnumerable(); var orders = testDS.Tables["Orders"].AsEnumerable(); var myOrders = from c in customers from o in orders where c.Field("CustomerID") == o.Field("CustomerID") && o.Field("OrderDate") >= new DateTime(1998, 1, 1) select new { CustomerID = c.Field("CustomerID"), OrderID = o.Field("OrderID"), OrderDate = o.Field("OrderDate") }; ``` ### SelectMany - from Assignment This sample uses a compound `from` clause to select all orders where the order total is greater than 2000.00 and uses `from` assignment to avoid requesting the total twice. ```csharp var customers = testDS.Tables["Customers"].AsEnumerable(); var orders = testDS.Tables["Orders"].AsEnumerable(); var myOrders = from c in customers from o in orders let total = o.Field("Total") where c.Field("CustomerID") == o.Field("CustomerID") && total >= 2000.0M select new { CustomerID = c.Field("CustomerID"), OrderID = o.Field("OrderID"), total }; ``` ### SelectMany - Multiple from This sample uses multiple `from` clauses so that filtering on customers can be done before selecting their orders. This makes the query more efficient by not selecting and then discarding orders for customers outside of Washington. ```csharp var customers = testDS.Tables["Customers"].AsEnumerable(); var orders = testDS.Tables["Orders"].AsEnumerable(); DateTime cutoffDate = new DateTime(1997, 1, 1); var myOrders = from c in customers where c.Field("Region") == "WA" from o in orders where c.Field("CustomerID") == o.Field("CustomerID") && (DateTime)o["OrderDate"] >= cutoffDate select new { CustomerID = c.Field("CustomerID"), OrderID = o.Field("OrderID") }; ``` ### SelectMany - Indexed This sample uses an indexed `SelectMany` clause to select all orders, while referring to customers by the order in which they are returned from the query. ```csharp var customers = testDS.Tables["Customers"].AsEnumerable(); var orders = testDS.Tables["Orders"].AsEnumerable(); var customerOrders = customers.SelectMany( (cust, custIndex) => orders.Where(o => cust.Field("CustomerID") == o.Field("CustomerID")) .Select(o => new { CustomerIndex = custIndex + 1, OrderID = o.Field("OrderID") })); ``` ## Partitioning Operators These samples show different uses of Partitioning Operators ### Take - Simple This sample uses `Take` to get only the first 3 elements of the array. ```csharp int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; var first3Numbers = numbers.Take(3); ``` ## Take - Nested This sample uses `Take` to get the first 3 orders from customers in Washington. ```csharp List customers = customerList; var first3WAOrders = ( from cust in customers from order in cust.Orders where cust.Region == "WA" select new { cust.CustomerID, order.OrderID, order.OrderDate }) .Take(3); ``` ## Skip - Simple This sample uses `Skip` to get all but the first four elements of the array. ```csharp int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; var allButFirst4Numbers = numbers.Skip(4); Console.WriteLine("All but first 4 numbers:"); foreach (var n in allButFirst4Numbers) { Console.WriteLine(n); } ``` ## Skip - Nested This sample uses `Skip` to get all but the first 2 orders from customers in Washington. ```csharp List customers = customerList; var waOrders = from cust in customers from order in cust.Orders where cust.Region == "WA" select new { cust.CustomerID, order.OrderID, order.OrderDate }; var allButFirst2Orders = waOrders.Skip(2); ``` ## TakeWhile - Simple This sample uses `TakeWhile` to return elements starting from the beginning of the array until a number is read whose value is not less than 6. ```csharp int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; var firstNumbersLessThan6 = numbers.TakeWhile(n => n < 6); ``` ## TakeWhile - Indexed This sample uses `TakeWhile` to return elements starting from the beginning of the array until a number is hit that is less than its position in the array. ```csharp int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; var firstSmallNumbers = numbers.TakeWhile((n, index) => n >= index); ``` ## SkipWhile - Simple This sample uses `SkipWhile` to get the elements of the array starting from the first element divisible by 3. ```csharp int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; // In the lambda expression, 'n' is the input parameter that identifies each // element in the collection in succession. It is is inferred to be // of type int because numbers is an int array. var allButFirst3Numbers = numbers.SkipWhile(n => n % 3 != 0); ``` ## SkipWhile - Indexed This sample uses `SkipWhile` to get the elements of the array starting from the first element less than its position. ```csharp int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; var laterNumbers = numbers.SkipWhile((n, index) => n >= index); ``` ## Ordering operators These samples show different uses of Ordering Operators. ### OrderBy - Simple 1 This sample uses `orderby` to sort a list of words alphabetically. ```csharp string[] words = { "cherry", "apple", "blueberry" }; var sortedWords = from word in words orderby word select word; ``` ### OrderBy - Simple 2 This sample uses `orderby` to sort a list of words by length. ```csharp string[] words = { "cherry", "apple", "blueberry" }; var sortedWords = from word in words orderby word.Length select word; ``` ### OrderBy - Simple 3 This sample uses `orderby` to sort a list of products by name. Use the "descending" keyword at the end of the clause to perform a reverse ordering ```csharp List products = productList; var sortedProducts = from prod in products orderby prod.ProductName select prod; ``` ### OrderBy - Comparer This sample uses an `OrderBy` clause with a custom comparer to do a case-insensitive sort of the words in an array. ```csharp // Custom comparer for use with ordering operators public class CaseInsensitiveComparer : IComparer { public int Compare(string x, string y) { return string.Compare(x, y, StringComparison.OrdinalIgnoreCase); } } string[] words = { "aPPLE", "AbAcUs", "bRaNcH", "BlUeBeRrY", "ClOvEr", "cHeRry" }; var sortedWords = words.OrderBy(a => a, new CaseInsensitiveComparer()); ``` ### OrderByDescending - Simple 1 This sample uses `orderby` and `descending` to sort a list of doubles from highest to lowest. ```csharp double[] doubles = { 1.7, 2.3, 1.9, 4.1, 2.9 }; var sortedDoubles = from d in doubles orderby d descending select d; ``` ### OrderByDescending - Simple 2 This sample uses `orderby` to sort a list of products by units in stock from highest to lowest. ```csharp List products = productList; var sortedProducts = from prod in products orderby prod.UnitsInStock descending select prod ``` ### OrderByDescending - Comparer This sample uses method syntax to call `OrderByDescending` because it enables you to use a custom comparer. ```csharp string[] words = { "aPPLE", "AbAcUs", "bRaNcH", "BlUeBeRrY", "ClOvEr", "cHeRry" }; var sortedWords = words.OrderByDescending(a => a, new CaseInsensitiveComparer()); ``` ### ThenBy - Simple This sample uses a compound `orderby` to sort a list of digits, first by length of their name, and then alphabetically by the name itself. ```csharp string[] digits = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" }; var sortedDigits = from digit in digits orderby digit.Length, digit select digit; ``` ### ThenBy - Comparer The first query in this sample uses method syntax to call `OrderBy` and `ThenBy` with a custom comparer to sort first by word length and then by a case-insensitive sort of the words in an array. The second two queries show another way to perform the same task. ```csharp string[] words = { "aPPLE", "AbAcUs", "bRaNcH", "BlUeBeRrY", "ClOvEr", "cHeRry" }; var sortedWords = words.OrderBy(a => a.Length) .ThenBy(a => a, new CaseInsensitiveComparer()); ``` Alternative: ```csharp // Another way. TODO is this use of ThenBy correct? It seems to work on this sample array. var sortedWords2 = from word in words orderby word.Length select word; ``` Another alternative: ```csharp var sortedWords3 = sortedWords2.ThenBy(a => a, new CaseInsensitiveComparer()); ``` ### ThenByDescending - Simple This sample uses a compound `orderby` to sort a list of products, first by category, and then by unit price, from highest to lowest. ```csharp List products = productList; var sortedProducts = from prod in products orderby prod.Category, prod.UnitPrice descending select prod; ``` ### ThenByDescending - Comparer This sample uses an `OrderBy` and a `ThenBy` clause with a custom comparer to sort first by word length and then by a case-insensitive descending sort of the words in an array. ```csharp string[] words = { "aPPLE", "AbAcUs", "bRaNcH", "BlUeBeRrY", "ClOvEr", "cHeRry" }; var sortedWords = words.OrderBy(a => a.Length) .ThenByDescending(a => a, new CaseInsensitiveComparer()); ``` ### Reverse This sample uses `Reverse` to create a list of all digits in the array whose second letter is 'i' that is reversed from the order in the original array. ```csharp string[] digits = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" }; var reversedIDigits = ( from digit in digits where digit[1] == 'i' select digit) .Reverse(); ``` ## Grouping Operators These samples shows different uses of Grouping Operators. ### GroupBy - Simple 1 This sample uses `group by` to partition a list of numbers by their remainder when divided by 5. ```csharp var numbers = testDS.Tables["Numbers"].AsEnumerable(); var numberGroups = from n in numbers group n by n.Field("number") % 5 into g select new { Remainder = g.Key, Numbers = g }; foreach (var g in numberGroups) { Console.WriteLine("Numbers with a remainder of {0} when divided by 5:", g.Remainder); foreach (var n in g.Numbers) { Console.WriteLine(n.Field("number")); } } ``` ### GroupBy - Simple 2 This sample uses `group by` to partition a list of words by their first letter. ```csharp var words4 = testDS.Tables["Words4"].AsEnumerable(); var wordGroups = from w in words4 group w by w.Field("word")[0] into g select new { FirstLetter = g.Key, Words = g }; foreach (var g in wordGroups) { Console.WriteLine("Words that start with the letter '{0}':", g.FirstLetter); foreach (var w in g.Words) { Console.WriteLine(w.Field("word")); } } ``` ### GroupBy - Simple 3 This sample uses `group by` to partition a list of products by category. ```csharp var products = testDS.Tables["Products"].AsEnumerable(); var productGroups = from p in products group p by p.Field("Category") into g select new { Category = g.Key, Products = g }; foreach (var g in productGroups) { Console.WriteLine("Category: {0}", g.Category); foreach (var w in g.Products) { Console.WriteLine("\t" + w.Field("ProductName")); } } ``` ### GroupBy - Nested This sample uses `group by` to partition a list of each customer's orders, first by year, and then by month. ```csharp var customers = testDS.Tables["Customers"].AsEnumerable(); var customerOrderGroups = from c in customers select new { CompanyName = c.Field("CompanyName"), YearGroups = from o in c.GetChildRows("CustomersOrders") group o by o.Field("OrderDate").Year into yg select new { Year = yg.Key, MonthGroups = from o in yg group o by o.Field("OrderDate").Month into mg select new { Month = mg.Key, Orders = mg } } }; foreach (var cog in customerOrderGroups) { Console.WriteLine("CompanyName= {0}", cog.CompanyName); foreach (var yg in cog.YearGroups) { Console.WriteLine("\t Year= {0}", yg.Year); foreach (var mg in yg.MonthGroups) { Console.WriteLine("\t\t Month= {0}", mg.Month); foreach (var order in mg.Orders) { Console.WriteLine("\t\t\t OrderID= {0} ", order.Field("OrderID")); Console.WriteLine("\t\t\t OrderDate= {0} ", order.Field("OrderDate")); } } } } ``` ### GroupBy - Comparer This sample uses `GroupBy` to partition trimmed elements of an array using a custom comparer that matches words that are anagrams of each other. ```csharp private class AnagramEqualityComparer : IEqualityComparer { public bool Equals(string x, string y) { return getCanonicalString(x) == getCanonicalString(y); } public int GetHashCode(string obj) { return getCanonicalString(obj).GetHashCode(); } private string getCanonicalString(string word) { char[] wordChars = word.ToCharArray(); Array.Sort(wordChars); return new string(wordChars); } } var anagrams = testDS.Tables["Anagrams"].AsEnumerable(); var orderGroups = anagrams.GroupBy(w => w.Field("anagram").Trim(), new AnagramEqualityComparer()); foreach (var g in orderGroups) { Console.WriteLine("Key: {0}", g.Key); foreach (var w in g) { Console.WriteLine($"\t has the anagram: {w.Field("anagram")}"); } } ``` ### GroupBy - Comparer, Mapped This sample uses `GroupBy` to partition trimmed elements of an array using a custom comparer that matches words that are anagrams of each other, and then converts the results to uppercase. ```csharp var anagrams = testDS.Tables["Anagrams"].AsEnumerable(); var orderGroups = anagrams.GroupBy( w => w.Field("anagram").Trim(), a => a.Field("anagram").ToUpper(), new AnagramEqualityComparer() ); foreach (var g in orderGroups) { Console.WriteLine("Key: {0}", g.Key); foreach (var w in g) { Console.WriteLine("\t" + w); } } ``` ## Set Operators These samples show different uses of Set Operators. ### Distinct - 1 This sample uses `Distinct` to remove duplicate elements in a sequence of factors of 300. ```csharp int[] factorsOf300 = { 2, 2, 3, 5, 5 }; var uniqueFactors = factorsOf300.Distinct(); ``` ### Distinct - 2 This sample uses `Distinct` to find the unique Category names. ```csharp List products = productList; var categoryNames = ( from prod in products select prod.Category) .Distinct(); ``` ### Union - 1 This sample uses `Union` to create one sequence that contains the unique values from both arrays. ```csharp int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 }; int[] numbersB = { 1, 3, 5, 7, 8 }; var uniqueNumbers = numbersA.Union(numbersB); ``` ### Union - 2 This sample uses `Union` to create one sequence that contains the unique first letter from both product and customer names. ```csharp List products = GetProductList(); List customers = GetCustomerList(); var productFirstChars = from prod in products select prod.ProductName[0]; var customerFirstChars = from cust in customers select cust.CompanyName[0]; var uniqueFirstChars = productFirstChars.Union(customerFirstChars); ``` ### Intersect - 1 This sample uses `Intersect` to create one sequence that contains the common values shared by both arrays. ```csharp int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 }; int[] numbersB = { 1, 3, 5, 7, 8 }; var commonNumbers = numbersA.Intersect(numbersB); ``` ### Intersect - 2 This sample uses `Intersect` to create one sequence that contains the common first letter from both product and customer names. ```csharp List products = GetProductList(); List customers = GetCustomerList(); var productFirstChars = from prod in products select prod.ProductName[0]; var customerFirstChars = from cust in customers select cust.CompanyName[0]; var commonFirstChars = productFirstChars.Intersect(customerFirstChars); ``` ### Except - 1 This sample uses `Except` to create a sequence that contains the values from `numbersA` that are not also in `numbersB`. ```csharp int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 }; int[] numbersB = { 1, 3, 5, 7, 8 }; IEnumerable aOnlyNumbers = numbersA.Except(numbersB); ``` ### Except - 2 This sample uses `Except` to create one sequence that contains the first letters of product names that are not also first letters of customer names. ```csharp List products = GetProductList(); List customers = GetCustomerList(); var productFirstChars = from prod in products select prod.ProductName[0]; var customerFirstChars = from cust in customers select cust.CompanyName[0]; var productOnlyFirstChars = productFirstChars.Except(customerFirstChars); ``` ## Conversion Operators These samples show different uses of Conversion Operators. ### ToArray This sample uses `ToArray` to immediately evaluate a sequence into an array. ```csharp double[] doubles = { 1.7, 2.3, 1.9, 4.1, 2.9 }; var sortedDoubles = from d in doubles orderby d descending select d; var doublesArray = sortedDoubles.ToArray(); Console.WriteLine("Every other double from highest to lowest:"); for (int d = 0; d < doublesArray.Length; d += 2) { Console.WriteLine(doublesArray[d]); } ``` ### ToList This sample uses `ToList` to immediately evaluate a sequence into a `List`. ```csharp string[] words = { "cherry", "apple", "blueberry" }; var sortedWords = from w in words orderby w select w; var wordList = sortedWords.ToList(); Console.WriteLine("The sorted word list:"); foreach (var w in wordList) { Console.WriteLine(w); } ``` ### ToDictionary This sample uses `ToDictionary` to immediately evaluate a sequence and a related key expression into a dictionary. ```csharp var scoreRecords = new[] { new {Name = "Alice", Score = 50}, new {Name = "Bob" , Score = 40}, new {Name = "Cathy", Score = 45} }; var scoreRecordsDict = scoreRecords.ToDictionary(sr => sr.Name); Console.WriteLine("Bob's score: {0}", scoreRecordsDict["Bob"]); ``` ### OfType This sample uses `OfType` to return only the elements of the array that are of type double. ```csharp object[] numbers = { null, 1.0, "two", 3, "four", 5, "six", 7.0 }; var doubles = numbers.OfType(); ``` ## Element Operators These samples show different uses of Element Operators ### First - Simple This sample uses `First` to return the first matching element as a `Product`. ```csharp List products = GetProductList(); Product product12 = ( from prod in products where prod.ProductID == 12 select prod) .First(); ``` ### First - Condition This sample uses `First` to find the first element in the array that starts with 'o'. ```csharp string[] strings = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" }; string startsWithO = strings.First(s => s[0] == 'o'); ``` ### FirstOrDefault - Simple This sample uses `FirstOrDefault` to try to return the first element of the sequence, unless there are no elements, in which case the default value for that type is returned. `FirstOrDefault` is useful for creating outer joins. ```csharp int[] numbers = { }; int firstNumOrDefault = numbers.FirstOrDefault(); ``` ### FirstOrDefault - Condition This sample uses `FirstOrDefault` to return the first product whose ProductID is 789 as a single `Product` object, unless there is no match, in which case `null` is returned. ```csharp List products = GetProductList(); Product product789 = products.FirstOrDefault(p => p.ProductID == 789); Console.WriteLine("Product 789 exists: {0}", product789 != null); ``` ### ElementAt This sample uses `ElementAt` to retrieve the second number greater than 5 from an array. ```csharp int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; int fourthLowNum = ( from num in numbers where num > 5 select num) .ElementAt(1); // second number is index 1 because sequences use 0-based indexing Console.WriteLine("Second number > 5: {0}", fourthLowNum); ``` ## Generation Operators These samples show different uses of Generation Operators. ### Range This sample uses `Range` to generate a sequence of numbers from 100 to 149 that is used to find which numbers in that range are odd and even. ```csharp var numbers = from n in Enumerable.Range(100, 50) select new { Number = n, OddEven = n % 2 == 1 ? "odd" : "even" }; foreach (var n in numbers) { Console.WriteLine("The number {0} is {1}.", n.Number, n.OddEven); } ``` ### Repeat This sample uses `Repeat` to generate a sequence that contains the number 7 ten times. ```csharp var numbers = Enumerable.Repeat(7, 10); foreach (var n in numbers) { Console.WriteLine(n); } ``` ## Quantifiers These samples show different uses of Quantifiers. ### Any - Simple This sample uses `Any`to determine if any of the words in the array contain the substring 'ei'. ```csharp string[] words = { "believe", "relief", "receipt", "field" }; bool iAfterE = words.Any(w => w.Contains("ei")); ``` ### Any - Grouped This sample uses `Any` to return a grouped a list of products only for categories that have at least one product that is out of stock. ```csharp List products = GetProductList(); var productGroups = from prod in products group prod by prod.Category into prodGroup where prodGroup.Any(p => p.UnitsInStock == 0) select new { Category = prodGroup.Key, Products = prodGroup }; ``` ### All - Simple This sample uses `All` to determine whether an array contains only odd numbers. ```csharp int[] numbers = { 1, 11, 3, 19, 41, 65, 19 }; bool onlyOdd = numbers.All(n => n % 2 == 1); ``` ### All - Grouped This sample uses `All` to return a grouped a list of products only for categories that have all of their products in stock. ```csharp List products = GetProductList(); var productGroups = from prod in products group prod by prod.Category into prodGroup where prodGroup.All(p => p.UnitsInStock > 0) select new { Category = prodGroup.Key, Products = prodGroup }; ``` ## Aggregate Operators These samples show different uses of Aggregate Operators ### Count - Simple This sample uses `Count` to get the number of unique factors of 300. ```csharp int[] primeFactorsOf300 = { 2, 2, 3, 5, 5 }; int uniqueFactors = primeFactorsOf300.Distinct().Count(); Console.WriteLine("There are {0} unique prime factors of 300.", uniqueFactors); ``` ### Count - Conditional This sample uses `Count` to get the number of odd ints in the array. ```csharp int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; int oddNumbers = numbers.Count(n => n % 2 == 1); Console.WriteLine("There are {0} odd numbers in the list.", oddNumbers); ``` ### Count - Nested This sample uses `Count` to return a list of customers and how many orders each has. ```csharp List customers = GetCustomerList(); var orderCounts = from cust in customers select new { cust.CustomerID, OrderCount = cust.Orders.Count() }; ``` ### Count - Grouped This sample uses `Count`to return a list of categories and how many products each has. ```csharp List products = GetProductList(); var categoryCounts = from prod in products group prod by prod.Category into prodGroup select new { Category = prodGroup.Key, ProductCount = prodGroup.Count() }; ``` ### Sum - Simple This sample uses `Sum` to add all the numbers in an array. ```csharp int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; double numSum = numbers.Sum(); ``` ### Sum - Projection This sample uses `Sum` to get the total number of characters of all words in the array. ```csharp string[] words = { "cherry", "apple", "blueberry" }; double totalChars = words.Sum(w => w.Length); ``` ### Sum - Grouped This sample uses `Sum` to get the total units in stock for each product category. ```csharp List products = GetProductList(); var categories = from prod in products group prod by prod.Category into prodGroup select new { Category = prodGroup.Key, TotalUnitsInStock = prodGroup.Sum(p => p.UnitsInStock) }; ``` ### Min - Simple This sample uses `Min` to get the lowest number in an array. ```csharp int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; int minNum = numbers.Min(); ``` ### Min - Projection This sample uses `Min` to get the length of the shortest word in an array. ```csharp string[] words = { "cherry", "apple", "blueberry" }; int shortestWord = words.Min(w => w.Length); ``` ### Min - Grouped This sample uses `Min` to get the cheapest price among each category's products. ```csharp List products = GetProductList(); var categories = from prod in products group prod by prod.Category into prodGroup select new { Category = prodGroup.Key, CheapestPrice = prodGroup.Min(p => p.UnitPrice) }; ``` ### Min - Elements This sample uses `Min` to get the products with the cheapest price in each category. ```csharp List products = GetProductList(); var categories = from prod in products group prod by prod.Category into prodGroup let minPrice = prodGroup.Min(p => p.UnitPrice) select new { Category = prodGroup.Key, CheapestProducts = prodGroup.Where(p => p.UnitPrice == minPrice) }; ``` ### Max - Simple This sample uses `Max` to get the highest number in an array. ```csharp int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; int maxNum = numbers.Max(); ``` ### Max - Projection This sample uses `Max` to get the length of the longest word in an array. ```csharp string[] words = { "cherry", "apple", "blueberry" }; int longestLength = words.Max(w => w.Length); ``` ### Max - Grouped This sample uses `Max` to get the most expensive price among each category's products. ```csharp List products = GetProductList(); var categories = from prod in products group prod by prod.Category into prodGroup select new { Category = prodGroup.Key, MostExpensivePrice = prodGroup.Max(p => p.UnitPrice) }; ``` ### Max - Elements This sample uses `Max` to get the products with the most expensive price in each category. ```csharp List products = GetProductList(); var categories = from prod in products group prod by prod.Category into prodGroup let maxPrice = prodGroup.Max(p => p.UnitPrice) select new { Category = prodGroup.Key, MostExpensiveProducts = prodGroup.Where(p => p.UnitPrice == maxPrice) }; ``` ### Average - Simple This sample uses `Average` to get the average of all numbers in an array. ```csharp int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; double averageNum = numbers.Average(); ``` ### Average - Projection This sample uses `Average` to get the average length of the words in the array. ```csharp string[] words = { "cherry", "apple", "blueberry" }; double averageLength = words.Average(w => w.Length); ``` ### Average - Grouped This sample uses `Average` to get the average price of each category's products. ```csharp List products = GetProductList(); var categories = from prod in products group prod by prod.Category into prodGroup select new { Category = prodGroup.Key, AveragePrice = prodGroup.Average(p => p.UnitPrice) }; ``` ### Aggregate - Simple This sample uses `Aggregate` to create a running product on the array that calculates the total product of all elements. ```csharp double[] doubles = { 1.7, 2.3, 1.9, 4.1, 2.9 }; double product = doubles.Aggregate((runningProduct, nextFactor) => runningProduct * nextFactor); ``` ### Aggregate - Seed This sample uses `Aggregate` to create a running account balance that subtracts each withdrawal from the initial balance of 100, as long as the balance never drops below 0. ```csharp double startBalance = 100.0; int[] attemptedWithdrawals = { 20, 10, 40, 50, 10, 70, 30 }; double endBalance = attemptedWithdrawals.Aggregate(startBalance, (balance, nextWithdrawal) => ((nextWithdrawal <= balance) ? (balance - nextWithdrawal) : balance)); ``` ## Miscellaneous Operators These samples show different uses of Miscellaneous Operators. ### Concat - 1 This sample uses `Concat` to create one sequence that contains each array's values, one after the other. ```csharp int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 }; int[] numbersB = { 1, 3, 5, 7, 8 }; var allNumbers = numbersA.Concat(numbersB); ``` ### Concat - 2 This sample uses `Concat` to create one sequence that contains the names of all customers and products, including any duplicates. ```csharp List customers = GetCustomerList(); List products = GetProductList(); var customerNames = from cust in customers select cust.CompanyName; var productNames = from prod in products select prod.ProductName; var allNames = customerNames.Concat(productNames); ``` ### EqualAll - 1 This sample uses `SequenceEquals` to see if two sequences match on all elements in the same order. ```csharp var wordsA = new string[] { "cherry", "apple", "blueberry" }; var wordsB = new string[] { "cherry", "apple", "blueberry" }; bool match = wordsA.SequenceEqual(wordsB); ``` ### EqualAll - 2 This sample uses `SequenceEqual` to see if two sequences match on all elements in the same order. ```csharp var wordsA = new string[] { "cherry", "apple", "blueberry" }; var wordsB = new string[] { "apple", "blueberry", "cherry" }; bool match = wordsA.SequenceEqual(wordsB); ``` ## Custom Sequence Operators This sample shows the use of a Custom Sequence Operator. It calculates the dot product of two integer vectors. ```csharp public static IEnumerable Combine(this IEnumerable first, IEnumerable second, System.Func func) { using (IEnumerator e1 = first.GetEnumerator(), e2 = second.GetEnumerator()) { while (e1.MoveNext() && e2.MoveNext()) { yield return func(e1.Current, e2.Current); } } } var numbersA = testDS.Tables["NumbersA"].AsEnumerable(); var numbersB = testDS.Tables["NumbersB"].AsEnumerable(); int dotProduct = numbersA.Combine(numbersB, (a, b) => a.Field("number") * b.Field("number")).Sum(); ``` ## Query Execution These samples show different concepts of Query Execution. ### Deferred Execution The following sample shows how query execution is deferred until the query is enumerated at a foreach statement. ```csharp // Queries are not executed until you enumerate over them. int[] numbers = new int[] { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; int i = 0; var simpleQuery = from num in numbers select ++i; // The local variable 'i' is not incremented // until the query is executed in the foreach loop. Console.WriteLine("The current value of i is {0}", i); //i is still zero foreach (var item in simpleQuery) { Console.WriteLine("v = {0}, i = {1}", item, i); // now i is incremented } ``` ### Immediate Execution The following sample shows how queries can be executed immediately with operators such as `ToList()`. ```csharp // Methods like ToList(), Max(), and Count() cause the query to be // executed immediately. int[] numbers = new int[] { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; int i = 0; var immediateQuery = ( from num in numbers select ++i) .ToList(); Console.WriteLine("The current value of i is {0}", i); //i has been incremented foreach (var item in immediateQuery) { Console.WriteLine("v = {0}, i = {1}", item, i); } ``` ### Query Reuse The following sample shows how, because of deferred execution, queries can be used again after data changes and will then operate on the new data. ```csharp // Deferred execution lets us define a query once // and then reuse it later in various ways. int[] numbers = new int[] { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; var lowNumbers = from num in numbers where num <= 3 select num; Console.WriteLine("First run numbers <= 3:"); foreach (int n in lowNumbers) { Console.WriteLine(n); } // Query the original query. var lowEvenNumbers = from num in lowNumbers where num % 2 == 0 select num; Console.WriteLine("Run lowEvenNumbers query:"); foreach (int n in lowEvenNumbers) { Console.WriteLine(n); } // Modify the source data. for (int i = 0; i < 10; i++) { numbers[i] = -numbers[i]; } // During this second run, the same query object, // lowNumbers, will be iterating over the new state // of numbers[], producing different results: Console.WriteLine("Second run numbers <= 3:"); foreach (int n in lowNumbers) { Console.WriteLine(n); } ``` ## Join Operators These samples show different uses of Join Operators. ### Cross Join This sample shows how to perform a simple inner equijoin of two sequences to produce a flat result set that consists of each element in suppliers that has a matching element in customers. ```csharp List customers = GetCustomerList(); List suppliers = GetSupplierList(); var custSupJoin = from sup in suppliers join cust in customers on sup.Country equals cust.Country select new { Country = sup.Country, SupplierName = sup.SupplierName, CustomerName = cust.CompanyName }; foreach (var item in custSupJoin) { Console.WriteLine("Country = {0}, Supplier = {1}, Customer = {2}", item.Country, item.SupplierName, item.CustomerName); } ``` ### Group Join A group join produces a hierarchical sequence. The following query is an inner join that produces a sequence of objects, each of which has a key and an inner sequence of all matching elements. ```csharp List customers = GetCustomerList(); List suppliers = GetSupplierList(); var custSupQuery = from sup in suppliers join cust in customers on sup.Country equals cust.Country into cs select new { Key = sup.Country, Items = cs }; foreach (var item in custSupQuery) { Console.WriteLine(item.Key + ":"); foreach (var element in item.Items) { Console.WriteLine(" " + element.CompanyName); } } ``` ### Group Join - 2 The group join operator is more general than join, as this slightly more verbose version of the cross join sample shows. ```csharp string[] categories = new string[]{ "Beverages", "Condiments", "Vegetables", "Dairy Products", "Seafood" }; List products = GetProductList(); var prodByCategory = from cat in categories join prod in products on cat equals prod.Category into ps from p in ps select new { Category = cat, p.ProductName }; foreach (var item in prodByCategory) { Console.WriteLine(item.ProductName + ": " + item.Category); } ``` ### Left Outer Join A left outer join produces a result set that includes all the left hand side elements at least once, even if they don't match any right hand side elements. ```csharp List customers = GetCustomerList(); List suppliers = GetSupplierList(); var supplierCusts = from sup in suppliers join cust in customers on sup.Country equals cust.Country into cs from c in cs.DefaultIfEmpty() // DefaultIfEmpty preserves left-hand elements that have no matches on the right side orderby sup.SupplierName select new { Country = sup.Country, CompanyName = c == null ? "(No customers)" : c.CompanyName, SupplierName = sup.SupplierName }; foreach (var item in supplierCusts) { Console.WriteLine("{0} ({1}): {2}", item.SupplierName, item.Country, item.CompanyName); } ``` ## Join With Projection For each customer in the table of customers, this query returns all the suppliers from that same country, or else a string indicating that no suppliers from that country were found. ```csharp List customers = GetCustomerList(); List suppliers = GetSupplierList(); var custSuppliers = from cust in customers join sup in suppliers on cust.Country equals sup.Country into ss from s in ss.DefaultIfEmpty() orderby cust.CompanyName select new { Country = cust.Country, CompanyName = cust.CompanyName, SupplierName = s == null ? "(No suppliers)" : s.SupplierName }; foreach (var item in custSuppliers) { Console.WriteLine("{0} ({1}): {2}", item.CompanyName, item.Country, item.SupplierName); } ``` ## Join With Projection - 2 For each supplier in the table of suppliers, this query returns all the customers from the same city and country, or else a string indicating that no customers from that city/country were found. Note the use of anonymous types to encapsulate the multiple key values. ```csharp List customers = GetCustomerList(); List suppliers = GetSupplierList(); var supplierCusts = from sup in suppliers join cust in customers on new { sup.City, sup.Country } equals new { cust.City, cust.Country } into cs from c in cs.DefaultIfEmpty() //Remove DefaultIfEmpty method call to make this an inner join orderby sup.SupplierName select new { Country = sup.Country, City = sup.City, SupplierName = sup.SupplierName, CompanyName = c == null ? "(No customers)" : c.CompanyName }; foreach (var item in supplierCusts) { Console.WriteLine("{0} ({1}, {2}): {3}", item.SupplierName, item.City, item.Country, item.CompanyName); } ``` ================================================ FILE: csharp/linq/meta.json ================================================ { "order":{ "101-linq-examples.workbook":"101 Linq Examples" } } ================================================ FILE: csharp/meta.json ================================================ { "order":{ "csharp7":"C# 7", "csharp6":"C# 6", "async":"Async Await", "collections":"Collections", "linq":"Linq", "roslyn":".NET Compiler Platform (Roslyn)" } } ================================================ FILE: csharp/roslyn/meta.json ================================================ { "order":{ "roslyn-syntax-trees.workbook":"Exploring Roslyn Syntax Trees" } } ================================================ FILE: csharp/roslyn/roslyn-syntax-trees.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook platforms: - Console packages: - id: Microsoft.CodeAnalysis.CSharp version: 1.3.2 --- # Exploring Roslyn Syntax Trees A compiler is often visualized as a “black box”: Source code goes in, and machine code comes out. Today’s compilers, however, need to be much more sophisticated. Programming environments such as Visual Studio make use of the intermediate results of parsing and compilation to display possible errors, to adjust formatting, and to provide suggestions to the programmer. Modern compilers are actually services with a vast infrastructure of APIs. The .NET Compiler Platform is Microsoft’s open-source C# and Visual Basic compiler that does indeed expose a rich collection of APIs for source-code analysis and other tasks. Although the official name of the .NET Compiler Platform is descriptive and not too wordy, it is still generally referred to by its original codename, Roslyn, named after the city in Washington state. The Roslyn information hub is the Github repository where it resides: [https://github.com/dotnet/roslyn](https://github.com/dotnet/roslyn "Roslyn repository on Github") The ReadMe file in the root directory contains links to other resources, including an alternative source-code browser for Roslyn that supports searching and hyperlinks: [http://source.roslyn.io/](http://source.roslyn.io/ "Roslyn source code") This workbook explores a few basic concepts of Roslyn. You’ll see how Roslyn translates a C# or Visual Basic source code file or code snippet into a syntax tree, which is a tree of nodes of type `SyntaxNode`. Every syntax node object corresponds to a code element and generally a span of text in the source-code file. If you wish to create your own workbooks to use Roslyn to analyze C# code, you’ll need to invoke the **File | Add Package** menu command to add the **Microsoft.CodeAnalysis.CSharp** Nuget package. That’s already been done for this workbook. Adding this package creates the following assembly reference: ```csharp #r "Microsoft.CodeAnalysis.CSharp" ``` The **Microsoft.CodeAnalysis.Common** assembly is automatically included as well. You’ll need a few `using` directives: ```csharp using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; ``` Here is a string containing a tiny but complete C# program that performs a little calculation and displays the words “Hello, Roslyn!”: ```csharp string helloRoslyn = @"using System; namespace HelloRoslyn { class MyProgram { static void Main(string[] args) { double twoPi = 2 * Math.PI; Console.WriteLine(""Hello, Roslyn!""); } } }" ``` What you will *not* see in this workbook is this program actually running! The program won’t even be compiled. Instead, this workbook demonstrates how you can use Roslyn tools to parse the code and analyze the program. ## The Tree and its Root The static `CSharpSyntaxTree.ParseText` method breaks the code down into a tree of `SyntaxNode` objects: ```csharp SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(helloRoslyn); ``` The `ParseText` method is defined as returning an object of type `SyntaxTree`. By default, the workbook displays the `ToString` representation of the `SyntaxTree` object, which is the entire text of the little program. If you choose **Object Members** rather than **ToString()** from the dropdown menu, you’ll see that the object is actually of type `ParsedSyntaxTree`, a private class embedded in (and deriving from) the `CSharpSyntaxTree` class, which derives from `SyntaxTree`. The `SyntaxTree` class defines a `GetRoot` method that returns a `SyntaxNode` object that represents the entire code document: ```csharp SyntaxNode rootSyntaxNode = syntaxTree.GetRoot(); ``` Again, the `ToString` representation is the entire program. But as you can see by selecting **Object Members** from the dropdown, the object returned from `GetRoot` is actually of type `CompilationUnitSyntax`, which is a type of `SyntaxNode` that refers to a chunk of code that can be compiled. There are 218 classes in the `Microsoft.CodeAnalysis.CSharp.Syntax` namespace that derive from `SyntaxNode` and `CSharpSyntaxNode`, and they all have a `Syntax` suffix. A few of the other classes that derive from `SyntaxNode` are: * `ClassDeclarationSyntax` * `StructDeclarationSyntax` * `MethodDeclarationSyntax` * `PropertyDeclarationSyntax` * `LocalDeclarationStatementSyntax` * `ExpressionStatementSyntax` In the **Object Members** listing of `CompilationUnitSyntax`, you can see several properties with the word `Trivia` in their names. This term refers to elements of the source code that are not generally important to the compilation, such as whitespace and comments. These are not syntax nodes in themselves but they are part of syntax nodes. The trivia occurs either at the beginning of the node (referred to as `Leading`) or at the end of the node (`Trailing`). Any embedded whitespace or comments are part of child nodes. The `Span` property indicates the starting offset of the text for this node, and the length of the text encompassed by the node. Notice how the `Span` property is displayed with the syntax **\[num1..num2)**. The square bracket at the beginning and a parenthesis at the end means that the span of text begins at offset **num1** and goes up to but *not* including offset **num2**. The `FullSpan` property includes trivia. The `ToString` method of `SyntaxNode` returns the text associated with the syntax node, which is the text encompassed by the `Span` property. `SyntaxNode` also defines a `ToFullString` method that returns the text encompassed by the `FullSpan` property and which includes trivia. Some of the most important characteristics of a `SyntaxNode` object are not exposed as properties but instead must be accessed through methods. One of these methods is `Kind`: ```csharp SyntaxKind kind = rootSyntaxNode.Kind(); ``` This method returns a member of the `SyntaxKind` enumeration, which has about 480 members. ([Take a look](http://source.roslyn.io/#Microsoft.CodeAnalysis.CSharp/Syntax/SyntaxKind.cs "SyntaxKind.cs").) Many of these members correspond to classes that derive from `SyntaxNode`. For example, if the `Kind` method of a `SyntaxNode` object returns `NullableType`, then the `SyntaxNode` object is actually of type `NullableTypeSyntax`. But there are more members of the `SyntaxKind` enumeration than types of `SyntaxNode` derivatives. You’ll see many with the suffix of `Token` and others with a suffix of `Keyword`. You’ll see some of those later in this workbook. ## Child Nodes `SyntaxNode` also defines a `ChildNodes` method: ```csharp IEnumerable rootChildren = rootSyntaxNode.ChildNodes(); ``` When you run this code cell you can easily identify the two items in this collection by their `ToString` representations: The first is a collection of `using` directives and the second is the remainder of the program beginning with the `namespace` declaration. By selecting **Object Members** from the dropdown menus for these items, you’ll see that the first is a `SyntaxNode` of type `UsingDirectiveSyntax`, and the second is a `SyntaxNode` of type `NamspaceDeclarationSyntax`, which encompasses the `namespace` declaration and everything in it. It’s posible to write a small method that calls the `ChildNodes` method recursively to obtain a full list of all the syntax nodes that make up the compilation unit. The following method first displays the result of the `Kind()` method and the `Span` start and length values. If the node has no children, then the text associated with the node is displayed. Otherwise the method is called recursively for the node’s children: ```csharp void DisplayNodes(SyntaxNode syntaxNode, int indent = 0) { Console.Write("{0}{1} {2}", new string('\u00A0', 4 * indent), syntaxNode.Kind(), syntaxNode.Span); IEnumerable childNodes = syntaxNode.ChildNodes(); if (childNodes.Count() == 0) { Console.WriteLine(" {0}", syntaxNode); } else { Console.WriteLine(); // end the line displayed with Write foreach (SyntaxNode childNode in childNodes) { DisplayNodes(childNode, indent + 1); } } } ``` The `indent` parameter to `DisplayNodes` causes each line to be indented based on the nesting level. You can run this function for the entire little program by passing the root node as an argument: ```csharp DisplayNodes(rootSyntaxNode); ``` Keep in mind that the text that begins each line is a member of the `SyntaxKind` enumeration returned from the `Kind` method, and the type of the `SyntaxNode` is that same name with the word `Syntax` appended. When discussing these nodes you can use either name. Notice how these nodes correspond to the overall structure of the program. The `NamespaceDeclaration` node includes a `ClassDeclaration`, which includes a `MethodDeclaration`, which includes a method `ParameterList` and a `Block`, which is the method body delimited by curly braces. The `Block` contains two statements: a `LocalDeclarationStatement` for the `twoPi` variable, and an `ExpressionStatement` for the `Console.WriteLine` call.\ \ The `DisplayNode` function that creates this listing only displays the text associated with a node if the node has no children. Otherwise, many nodes would encompass multiple lines of text and the display would look like a mess. You’ll see in this list several recognizable portions of the little program, but certainly not all of them. For example, where is the class name of `MyProgram` and the method name of `Main`? ## Syntax Nodes in Detail The class name and method name are not themselves `SyntaxNode` objects. They are part of other syntax nodes, and to see them you’ll need to examine the `ClassDeclarationSyntax` and `MethodDeclarationSyntax` objects in more detail. Here is a little function that recursively enumerates the entire syntax tree and returns a particular `SyntaxNode` corresponding to a criterion that you can set as a parameter to the function: ```csharp SyntaxNode FindNode(SyntaxNode syntaxNode, Func criterion) { if (criterion(syntaxNode)) return syntaxNode; foreach (SyntaxNode childNode in syntaxNode.ChildNodes()) { SyntaxNode foundNode = FindNode(childNode, criterion); if (foundNode != null) { return foundNode; } } return null; } ``` The following call returns the first `SyntaxNode` in the tree whose `Kind` method returns `SyntaxKind.ClassDeclaration`: ```csharp SyntaxNode classDeclarationSyntax = FindNode(rootSyntaxNode, (syntaxNode) => syntaxNode.Kind() == SyntaxKind.ClassDeclaration); ``` A `SyntaxNode` of type `ClassDeclarationSyntax` contains information about an entire class. The `Identifier` property is the name of the class. The `Modifiers` property contains information about the class modifiers (such as `public` and `static`), the `BaseList` is a list of the classes this class derives from and the interfaces it implements, and the `Members`property provides information about all the class’s members. The information is similar to what you can obtain from .NET reflection but very differently organized. Similarly, you can find the `Main` method like this: ```csharp SyntaxNode methodDeclarationSyntax = FindNode(rootSyntaxNode, (syntaxNode) => syntaxNode.Kind() == SyntaxKind.MethodDeclaration); ``` The method name is available in the `Identifier` property, and the `Parameters` property contains information about all the parameters to the method. ## Syntax Nodes \+ Tokens \+ Keywords It’s also possible to display a tree containing the text of the entire program (without trivia) by enumerating not only syntax nodes, but also tokens. Tokens include punctuation characters, string literals, numeric literals, identifiers, and keywords. You can rewrite the `DisplayNodes` function to be `DisplayNodesAndTokens` by replacing occurrences of the `SyntaxNode` type with `SyntaxNodeOrToken`, and replacing the `ChildNodes` method call with `ChildNodesAndTokens`: ```csharp void DisplayNodesAndTokens(SyntaxNodeOrToken syntaxNodeOrToken, int indent = 0) { Console.Write("{0}{1} [{2}..{3})", new string('\u00A0', 4 * indent), syntaxNodeOrToken.Kind(), syntaxNodeOrToken.Span.Start, syntaxNodeOrToken.Span.End); IEnumerable childNodesOrTokens = syntaxNodeOrToken.ChildNodesAndTokens(); if (childNodesOrTokens.Count() == 0) { Console.WriteLine(" {0}", syntaxNodeOrToken); } else { Console.WriteLine(); foreach (SyntaxNodeOrToken childNodeOrToken in childNodesOrTokens) { DisplayNodesAndTokens(childNodeOrToken, indent + 1); } } } ``` Now run this method starting at the root node: ```csharp DisplayNodesAndTokens(rootSyntaxNode); ``` Now you can see every little character that makes up this little program, all identified with members of the `SyntaxKind` enumeration, including members with suffixes of `Token` and `Keyword`. ## Experiment! Of course, you’ll want to go back to the original string that contains this little program to make changes and see what happens. You’ll also want to introduce errors into the code and see how that is handled. Keep in mind that this little program has only been parsed for syntax. It has not been compiled. The parser is not trying to resolve the `Math.PI` field or the `Console.WriteLine` methods. The parser clearly recognizes the `void` return value of `Main` as a `VoidKeyword` token, but if you change that return type to something else (for example, `xoid`), it merely becomes an `IdentifierToken` whose meaning is not yet known. Compilation adds semantics to syntax. But that’s a step for another workbook. ## Bonus Addendum The 219 classes that derive from `SyntaxNode` correspond to all the structural elements that potentially comprise a C# program. Wouldn’t it be interesting to see a class hierarchy of these `SyntaxNode` derivatives? You could use Roslyn to do that, but you would need to load in the Roslyn source code files. Since this workbook has access to some Roslyn assemblies, it makes more sense to use standard .NET reflection for this job. The first step is to define a class to store all the names of the classes that derive from `SyntaxNode` and the base class name of each of those classes: ```csharp class ClassAndBase { public ClassAndBase(string name, string baseClass = null) { Name = name; BaseClass = baseClass; } public string Name { private set; get; } public string BaseClass { private set; get; } } ``` The following code loops through all the types in the **Microsoft.CodeAnalysis.CSharp** assembly, which contains all the classes for C# that derive from `SyntaxNode` but not `Syntax Node` itself. These are accumulated in a `List` object and then sorted: ```csharp var assembly = System.Reflection.Assembly.GetAssembly(typeof(ClassDeclarationSyntax)); List classList = new List(); foreach (Type type in assembly.GetExportedTypes()) { if (type.IsSubclassOf(typeof(SyntaxNode))) { classList.Add(new ClassAndBase(type.Name, type.BaseType.Name)); } } classList.Sort((arg1, arg2) => arg1.Name.CompareTo(arg2.Name)); ``` The following recursive function displays a class and all of its subclasses: ```csharp void DisplayClassAndSubclasses(ClassAndBase baseClass, int indent = 0) { Console.WriteLine("{0}{1}", new string('\u00A0', 4 * indent), baseClass.Name); foreach (ClassAndBase subclass in classList) { if (subclass.BaseClass == baseClass.Name) { DisplayClassAndSubclasses(subclass, indent + 1); } } } ``` To kick off the display, simply call the function starting with `SyntaxNode`: ```csharp DisplayClassAndSubclasses(new ClassAndBase("SyntaxNode")); ``` At first glance, you might think it impossible that you’re familiar with all these many types of syntax structures possible in a C# program. But take a closer look. Probably the most familiar will be the classes that derive from `ExpressionSyntax`, `StatementSyntax` and `MemberDeclarationSyntax`, which also includes the various types supported by C#. You might conclude you know C# better than you thought, but exploring Roslyn is a great way to learn the language in even more depth. ================================================ FILE: graphics/meta.json ================================================ { "order":{ "skiasharp":"SkiaSharp", "urhosharp":"UrhoSharp", "tiny-renderer":"TinyRenderer" } } ================================================ FILE: graphics/skiasharp/colors/colors.workbook/index.workbook ================================================ --- title: Working with SKColor uti: com.xamarin.workbook id: a8709e7d-ba63-47a4-8fb3-bed7d3bf9fbb platforms: - Console packages: - id: SkiaSharp version: 1.57.1 --- ```csharp // install SkiaSharp #r "SkiaSharp" using SkiaSharp; ``` # SkiaSharp and colors In previous workbooks, we’ve explored the SkiaSharp drawing and image APIs. In this workbook, we’re going to do a quick demo of `SKColor`, used by SkiaSharp to represent colors. We’ve seen `SKColor` before in the canvas-filling APIs, and you can see it in the image filters that create colored lights. Here, we’ll just demonstrate some of the built-in colors and the way they’re presented in Workbooks. First, a SKColor rainbow: ```csharp new [] { new SKColor (255, 0, 0), new SKColor (255, 127, 0), new SKColor (255, 255, 0), new SKColor (0, 255, 0), new SKColor (0, 0, 255), new SKColor (75, 0, 130), new SKColor (143, 0, 255) } ``` SkiaSharp also provides a massive list of named colors—it includes all of the CSS named colors: ```csharp new [] { SKColors.AliceBlue, SKColors.AntiqueWhite, SKColors.Aqua, SKColors.Aquamarine, SKColors.Azure, SKColors.Beige, SKColors.Bisque, SKColors.Black, SKColors.BlanchedAlmond, SKColors.Blue, SKColors.BlueViolet, SKColors.Brown, SKColors.BurlyWood, SKColors.CadetBlue, SKColors.Chartreuse, SKColors.Chocolate, SKColors.Coral, SKColors.CornflowerBlue, SKColors.Cornsilk, SKColors.Crimson, SKColors.Cyan, SKColors.DarkBlue, SKColors.DarkCyan, SKColors.DarkGoldenrod, SKColors.DarkGray, SKColors.DarkGreen, SKColors.DarkKhaki, SKColors.DarkMagenta, SKColors.DarkOliveGreen, SKColors.DarkOrange, SKColors.DarkOrchid, SKColors.DarkRed, SKColors.DarkSalmon, SKColors.DarkSeaGreen, SKColors.DarkSlateBlue, SKColors.DarkSlateGray, SKColors.DarkTurquoise, SKColors.DarkViolet, SKColors.DeepPink, SKColors.DeepSkyBlue, SKColors.DimGray, SKColors.DodgerBlue, SKColors.Firebrick, SKColors.FloralWhite, SKColors.ForestGreen, SKColors.Fuchsia, SKColors.Gainsboro, SKColors.GhostWhite, SKColors.Gold, SKColors.Goldenrod, SKColors.Gray, SKColors.Green, SKColors.GreenYellow, SKColors.Honeydew, SKColors.HotPink, SKColors.IndianRed, SKColors.Indigo, SKColors.Ivory, SKColors.Khaki, SKColors.Lavender, SKColors.LavenderBlush, SKColors.LawnGreen, SKColors.LemonChiffon, SKColors.LightBlue, SKColors.LightCoral, SKColors.LightCyan, SKColors.LightGoldenrodYellow, SKColors.LightGray, SKColors.LightGreen, SKColors.LightPink, SKColors.LightSalmon, SKColors.LightSeaGreen, SKColors.LightSkyBlue, SKColors.LightSlateGray, SKColors.LightSteelBlue, SKColors.LightYellow, SKColors.Lime, SKColors.LimeGreen, SKColors.Linen, SKColors.Magenta, SKColors.Maroon, SKColors.MediumAquamarine, SKColors.MediumBlue, SKColors.MediumOrchid, SKColors.MediumPurple, SKColors.MediumSeaGreen, SKColors.MediumSlateBlue, SKColors.MediumSpringGreen, SKColors.MediumTurquoise, SKColors.MediumVioletRed, SKColors.MidnightBlue, SKColors.MintCream, SKColors.MistyRose, SKColors.Moccasin, SKColors.NavajoWhite, SKColors.Navy, SKColors.OldLace, SKColors.Olive, SKColors.OliveDrab, SKColors.Orange, SKColors.OrangeRed, SKColors.Orchid, SKColors.PaleGoldenrod, SKColors.PaleGreen, SKColors.PaleTurquoise, SKColors.PaleVioletRed, SKColors.PapayaWhip, SKColors.PeachPuff, SKColors.Peru, SKColors.Pink, SKColors.Plum, SKColors.PowderBlue, SKColors.Purple, SKColors.Red, SKColors.RosyBrown, SKColors.RoyalBlue, SKColors.SaddleBrown, SKColors.Salmon, SKColors.SandyBrown, SKColors.SeaGreen, SKColors.SeaShell, SKColors.Sienna, SKColors.Silver, SKColors.SkyBlue, SKColors.SlateBlue, SKColors.SlateGray, SKColors.Snow, SKColors.SpringGreen, SKColors.SteelBlue, SKColors.Tan, SKColors.Teal, SKColors.Thistle, SKColors.Tomato, SKColors.Turquoise, SKColors.Violet, SKColors.Wheat, SKColors.White, SKColors.WhiteSmoke, SKColors.Yellow, SKColors.YellowGreen, SKColors.Transparent }; ``` There are no convenience APIs provided for it, but colors can be darkened or lightened by fiddling with the HSL (hue, saturation, lightness) values: ```csharp float hue, saturation, luminance; SKColors.WhiteSmoke.ToHsl(out hue, out saturation, out luminance); SKColors.WhiteSmoke; ``` Here we’ve converted `SKColors.WhiteSmoke` into HSL via the `ToHsl` method. We want to make it 20% darker, so we’ll reduce its luminance by 20%—i.e., we’ll multiply by 0.8. ```csharp var newLuma = luminance * 0.8f; var newColor = SKColor.FromHsl(hue, saturation, newLuma, 0xff); ``` We see our new color—it looks approximately 20% darker than the previous one indeed. You can manipulate hue and saturation as well—you can think of hue as the pure color value (that is, the base color), saturation as how much color there is (100% being pure color, 0% being pure grey), and lightness as the change from white to black. See [Wikipedia](https://en.wikipedia.org/wiki/HSL_and_HSV "HLS and HSV - Wikipedia") for more information. ================================================ FILE: graphics/skiasharp/images/images.workbook/index.workbook ================================================ --- packages: - id: SkiaSharp version: 1.57.1 uti: com.xamarin.workbook id: 42aced37-cff5-4cd5-8cd7-a23c986406f3 title: Exploring SKImage platforms: - Console --- ```csharp // install SkiaSharp #r "SkiaSharp" using SkiaSharp; ``` # Exploring SKImage In previous workbooks, we’ve explored the basics of SkiaSharp, and we’ve explored drawing with SkiaSharp, drawing an Archimedes spiral and a Xamagon. In addition to powerful drawing APIs, SkiaSharp also has powerful image manipulation APIs for loading, resizing, and even filtering images. ## Loading an image We’ve included an image with this workbook, called `cat.jpeg`. Let’s load it using the `SKBitmap` and `SKImage` classes. `SKImage` doesn’t have any methods for directly loading images, which is why we need to use an `SKBitmap`. ```csharp using System.IO; SKBitmap bitmap; using (var stream = File.OpenRead ("cat.jpeg")) bitmap = SKBitmap.Decode (stream); bitmap; ``` As you can see, the image is a bit large at 1080x1080. Let’s use `SKBitmap`’s resizing support to scale it down to a more manageable size, like 540x540. We’ll use the Lanczos resizing method, as it tends to produce the most visually pleasing results. We’ll re-assign the new bitmap back to the original variable—we could keep both to compare, but we don’t need them right now. ```csharp bitmap = bitmap.Resize (new SKImageInfo (540, 540), SKBitmapResizeMethod.Lanczos3); ``` ## Filtering images Now that we have our image loaded, we’d like to apply some filters to express our artistic desire—SkiaSharp provides numerous filters via the `SKImageFilter.Create*` static API. In particular, we’d like to use the Erode and Dilate filters, which will help us create a new image that’s styled like a painting from our original photo. Skia’s filtering API lets us chain filters to produce complex effects without having to apply the filters multiple times to an image, and we’ll use that here. ```csharp // First, load the image from the bitmap. var image = SKImage.FromBitmap (bitmap); // Next, set up some rectangles. Since we want to apply our filters to the whole image, we'll create // two rectangles that encompass the whole image. var imageRect = SKRect.Create (0, 0, image.Width, image.Height); var cropRect = new SKImageFilter.CropRect (imageRect, SKCropRectFlags.HasAll); // Next, we need to create our filters. We'll create the dilate filter first, and then // the erode filter, passing in the dilate filter as an input. var dilate = SKImageFilter.CreateDilate (radiusX: 6, radiusY: 6, input: null, cropRect: cropRect); var erode = SKImageFilter.CreateErode (radiusX: 12, radiusY: 12, input: dilate, cropRect: cropRect); // Now we need to create a final rectangle for the filter, and set up some return variables // for the applied filter. ApplyImageFilter returns a new image, so we don't need to do anything // to have Workbooks display it! var imageRectI = SKRectI.Ceiling (imageRect); SKRectI outRect; SKPoint outPoint; image.ApplyImageFilter (erode, imageRectI, imageRectI, out outRect, out outPoint); ``` As you can see, our cat now looks like a painting. The filter APIs are incredibly powerful for imagine manipulations—you can use them to tile images, do blends, blurs, and color filtering, or change the lighting in a photo! ### Exercises for image filtering * Try resizing the image to different sizes or using different resize methods. * Try going up in size instead of just down to see how the different resize methods affect that. * Try some other filters, or change the parameters/order of the existing filters. ================================================ FILE: graphics/skiasharp/introduction/introduction.workbook/index.workbook ================================================ --- id: dd45fdd0-cb47-4fa9-ae05-cb7549704db3 title: Introduction to SkiaSharp uti: com.xamarin.workbook platforms: - Console packages: - id: SkiaSharp version: 1.57.1 --- ```csharp // install SkiaSharp #r "SkiaSharp" ``` # SkiaSharp SkiaSharp is a fully cross-platform, rich 2D graphics drawing API powered by [Google's Skia library](https://skia.org/), the same library that drives Google Chrome, Mozilla Firefox, and Android's graphics stack. Not only is SkiaSharp powerful, it is also very simple to use—all you need to do is install the [SkiaSharp NuGet](https://www.nuget.org/packages/SkiaSharp). SkiaSharp can be used to render images on many platforms, including iOS, macOS, tvOS, Android, and Universal Windows Platform (UWP). Not only does SkiaSharp support native mobile apps, it also supports .NET Standard 1.3 and .NET Core on macOS and Windows, as well as Classic Windows Desktop and WPF applications. *This cool introduction is also available as a Xamarin.Forms app for iOS, Android and Windows: [mattleibow/SkiaSharpDemo](https://github.com/mattleibow/SkiaSharpDemo "SkiaSharpDemo") Download and try it out on your device.* ## Creating a Surface Before we can use SkiaSharp in our app, we need to make sure we add the `using` statement: ```csharp using SkiaSharp; ``` Now we want to draw something, but we need something to draw on. In this workbook, we are going to draw on a bitmap. As with all bitmaps, we need to have a size: ```csharp const int BitmapWidth = 300; const int BitmapHeight = 300; ``` Now, we are going to create the bitmap. This is as simple as instantiating `SKBitmap` with the size that we decided on earlier: ```csharp var bitmap = new SKBitmap(BitmapWidth, BitmapHeight); ``` Right now, the bitmap is very boring and we can't even see it. But, this is where we can start doing interesting things. *On some platforms, the memory is not cleared before the bitmap is allocated. When this happens, there are artifacts from what was in memory last - which is often just random bits of data.* Before we can draw on the bitmap, we need a canvas. And to do this we instantiate `SKCanvas`, and pass it the bitmap we just created: ```csharp var canvas = new SKCanvas(bitmap); ``` A `SKCanvas` does not appear in the workbook as an image because it doesn't really contain any image data. This is the layer that translates your drawing commands, such as `DrawRect` and `DrawPath`, into the appropriate commands for drawing on the current surface. Now that we have our canvas created, we can start drawing. The first thing we want to do is to make sure that the canvas is cleared. ```csharp canvas.Clear(SKColors.White); bitmap ``` We can't really see anything yet, as the bitmap is just white, but now we have a clean surface to draw some shapes. To do this we will need to create a `SKPaint`, which is where we control what the drawing looks like. We can call the drawing methods multiple times and by only changing the paint, the rectangle will look totally different. ## Drawing Shapes Here we are going to draw a blue circle in the top, left corner. So, we set the `IsAntialias` property to make the edges smooth, the `Style` property to indicate that we want to do a fill and finally the `Color`. ```csharp var circleFill = new SKPaint { IsAntialias = true, Style = SKPaintStyle.Fill, Color = SKColors.Blue }; ``` We can now use that paint and draw our circle using `DrawCircle`. We pass the center coordinates, the radius and then the paint to the method: ```csharp canvas.DrawCircle(100, 100, 40, circleFill); bitmap ``` If we want to but a border on that circle, we can just run that same draw command again. But, this time we pass a different paint. We have changed the `Style` to be a stroke and added a `StrokeWidth`: ```csharp var circleBorder = new SKPaint { IsAntialias = true, Style = SKPaintStyle.Stroke, Color = SKColors.Red, StrokeWidth = 5 }; canvas.DrawCircle(100, 100, 40, circleBorder); bitmap ``` All done! We have a nice blue circle with a thick red border. ## Drawing Paths Although we have some simple shapes we can draw, we often want to draw complex geometry. This is done with a path. The `SKPath` type has many methods that allow us to build up any shape that we may want. Here, we are just going to draw a simple X shape using `MoveTo` and `LineTo`: ```csharp var path = new SKPath(); path.MoveTo(160, 60); path.LineTo(240, 140); path.MoveTo(240, 60); path.LineTo(160, 140); ``` Creating a path is pretty straight forward, and so is drawing it. As with all drawing, we need to create a paint - making sure that we set the style to be a stroke, and give it a width. Then, we can draw the path using `DrawPath`: ```csharp var pathStroke = new SKPaint { IsAntialias = true, Style = SKPaintStyle.Stroke, Color = SKColors.Green, StrokeWidth = 5 }; canvas.DrawPath(path, pathStroke); bitmap ``` ## Drawing Text Just as it is easy to draw shapes and paths, so is it easy to draw text. Drawing text also uses a paint, and we can draw either an outline with a stroke, of solid text with fill: ```csharp var textSize = 40; var textPaint = new SKPaint { IsAntialias = true, Style = SKPaintStyle.Fill, Color = SKColors.Orange, TextSize = textSize }; ``` Unlike other operations in SkiaSharp which draw from the top, left, drawing text occurs from the text baseline. All this means is that we have to “move” the text down by the height of the text: ```csharp canvas.DrawText("SkiaSharp", 60, 160 + textSize, textPaint); bitmap ``` And, that is all there is to it! SkiaSharp is a simple library, but a powerful library. ## Overview Getting off the ground with SkiaSharp is easy—all you need is one NuGet: [SkiaSharp](https://www.nuget.org/packages/SkiaSharp). This package provides everything necessary to create and manipulate drawings on any platform. If you're looking to display your drawings on-screen, you can check out the [SkiaSharp.Views](https://www.nuget.org/packages/SkiaSharp.Views) NuGet package. This package has a set of views, layers, and controls that get you going with displaying your drawing on-screen. If you have a Xamarin.Forms app, then you can install the [SkiaSharp.Views.Forms](https://www.nuget.org/packages/SkiaSharp.Views.Forms) NuGet package, which provides the same views for Xamarin.Forms. Finally, we have a lightweight SVG loading library that can be used to load an SVG into a `SKPicture`: [SkiaSharp.Svg](https://www.nuget.org/packages/SkiaSharp.Svg). ## Documentation and Forums We've documented all of the APIs of SkiaSharp on the [Xamarin developer site](https://developer.xamarin.com/api/root/SkiaSharp/), along with the [developer guides](https://developer.xamarin.com/guides/cross-platform/drawing/), which provide even more information on using SkiaSharp. You can also ask questions on the [Xamarin SkiaSharp forums](https://forums.xamarin.com/categories/skiasharp). If you prefer StackOverflow, [we're there, too](http://stackoverflow.com/questions/tagged/skiasharp)! If you want to chat or ask questions, some users also hang out on Gitter.im here: [xamarin/XamarinComponents](https://gitter.im/xamarin/XamarinComponents). ## Code, Issues and Suggestions The SkiaSharp codebase is constantly growing and improving. If you want to contribute, you can do so by forking on GitHub: [mono/SkiaSharp](https://github.com/mono/SkiaSharp). If you have any questions, bugs or suggestions, we welcome them as [issues](https://github.com/mono/SkiaSharp/issues). ================================================ FILE: graphics/skiasharp/logo/skialogo-ios.workbook/index.workbook ================================================ --- id: 06a9e50c-6510-47e6-9a31-f0c4e2ba9b1a title: Exploring Drawing with SkiaSharp uti: com.xamarin.workbook platforms: - iOS packages: - id: SkiaSharp version: 1.57.1 --- ```csharp // install SkiaSharp #r "SkiaSharp" using SkiaSharp; ``` # Exploring SkiaSharp As we saw in the [Introduction to SkiaSharp](https://developer.xamarin.com/workbooks/graphics/skiasharp/introduction/introduction.workbook "Introduction to SkiaSharp") workbook, SkiaSharp provides a powerful C# API for doing 2D graphics. It is powered by [Google’s Skia library](http://skia.org/), the same library that powers Google Chrome, Firefox and Android’s graphic stacks. In this Workbook, we’ll do a spiral drawing, and then a Xamarin logo drawing using only the SkiaSharp APIs! We’ve installed the NuGet package into the workbook and already added a `using` statement, and are now ready to go. ## Creating a drawing surface To start, we’ll need a surface to draw on—we’ll create an `SKSurface` with size 640x480. You’ll see the surface appear as an image in the Workbook—because we haven’t drawn anything on it yet, it will appear blank! ```csharp var surface = SKSurface.Create (640, 480, SKColorType.Rgba8888, SKAlphaType.Premul); ``` To draw on the surface we’ve created, we’ll need to use its canvas—we’ll start by clearing everything to a dim gray color so we can see at least some output. ```csharp var canvas = surface.Canvas; canvas.Clear(SKColors.DimGray); surface; ``` Both the `surface` and the `canvas` are limited resources, so in application code you should wrap them in `using` statements. The `SKCanvas` uses a drawing model similar in spirit to other drawing models that you might be familiar with, it uses colors with an optional transparency channel and can draw lines, arcs, text and images. ## Drawing a spiral We want to draw an Archimedean spiral—we’ll approximate it using Bézier curves, following an algorithm from Math.StackExchange. ```csharp //Ref. http://math.stackexchange.com/questions/179000/b%C3%A9zier-approximation-of-archimedes-spiral bool TryGetZELineIntersection (float m1, float b1, float m2, float b2, out float xIntercept, out float yIntercept) { xIntercept = yIntercept = float.NaN; if (Math.Abs (m1 - m2) < float.Epsilon) { //Lines are parallel, so they don't intersect return false; } xIntercept = (b2 - b1) / (m1 - m2); yIntercept = m1 * xIntercept + b1; return true; } SKPath BuildPath (SKPoint center, float startRadius, float spacePerLoop, float startTheta, float endTheta, float thetaStep) { var path = new SKPath (); var oldTheta = startTheta; var newTheta = startTheta; var oldR = startRadius + spacePerLoop * oldTheta; var newR = startRadius + spacePerLoop * newTheta; var oldSlope = float.MaxValue; var newSlope = oldSlope; var newPoint = new SKPoint ( (float)(center.X + oldR * Math.Cos (oldTheta)), (float)(center.Y + oldR * Math.Sin (oldTheta)) ); path.MoveTo (newPoint.X, newPoint.Y); var firstSlope = true; while (oldTheta < endTheta - thetaStep) { oldTheta = newTheta; newTheta += thetaStep; oldR = newR; newR = startRadius + spacePerLoop * newTheta; newPoint = new SKPoint ( (float)(center.X + newR * Math.Cos (newTheta)), (float)(center.Y + newR * Math.Sin (newTheta)) ); // Slope calculation with the formula: // (spacePerLoop * sinΘ + (startRadius + bΘ) * cosΘ) / (spacePerLoop * cosΘ - (startRadius + bΘ) * sinΘ) var aPlusBTheta = startRadius + spacePerLoop * newTheta; if (firstSlope) { oldSlope = (float)( (spacePerLoop * Math.Sin (oldTheta) + aPlusBTheta * Math.Cos (oldTheta)) / (spacePerLoop * Math.Cos (oldTheta) - aPlusBTheta * Math.Sin (oldTheta)) ); firstSlope = false; } else { oldSlope = newSlope; } newSlope = (float)( (spacePerLoop * Math.Sin (newTheta) + aPlusBTheta * Math.Cos (newTheta)) / (spacePerLoop * Math.Cos (newTheta) - aPlusBTheta * Math.Sin (newTheta)) ); var oldIntercept = (float) -(oldSlope * oldR * Math.Cos (oldTheta) - oldR * Math.Sin (oldTheta)); var newIntercept = (float) -(newSlope * newR * Math.Cos (newTheta) - newR * Math.Sin (newTheta)); float xIntercept, yIntercept; if (TryGetZELineIntersection (oldSlope, oldIntercept, newSlope, newIntercept, out xIntercept, out yIntercept)) { var controlPoint = new SKPoint (xIntercept + center.X, yIntercept + center.Y); path.LineTo (controlPoint.X, controlPoint.Y); } else { throw new ArgumentException ("These lines should never be parallel."); } } return path; } var path = BuildPath ( new SKPoint (320, 240), startRadius: 0, spacePerLoop: 3.3f, startTheta: 0, endTheta: 50, thetaStep: (float) (Math.PI / 16.0) ); ``` Now, with a path in hand, we can draw it to the `canvas`: ```csharp canvas.Clear(SKColors.LightGray); using (var paint = new SKPaint ()) { paint.IsAntialias = true; paint.Color = SKColors.Blue; paint.StrokeCap = SKStrokeCap.Round; paint.StrokeWidth = 2; paint.IsStroke = true; canvas.DrawPath (path, paint); } surface; ``` As you can see, our drawing surface now has a spiral drawn in the center of it. You can play with the spiral to produce different results! ### Spiral Exercises * Change the color or stroke of the `SKPaint` used to actually draw the spiral’s path. How does this change the output? * Change the parameters to the BuildPath function. How do they change the output’s shape, particularly the `startRadius`, `spacePerLoop`, and `endTheta` parameters. ## Drawing the Xamarin Xamagon Drawing the Xamagon will use most of the same concepts as we used for drawing the spiral—we’ll even reuse the same canvas and surface for drawing, we just need to clear them again. ```csharp canvas.Clear (SKColors.White); surface; ``` Next, we’ll create the Xamagon body: ```csharp var xamagonBody = new SKPath(); xamagonBody.MoveTo(71.4311121f, 56f); xamagonBody.CubicTo(68.6763107f, 56.0058575f, 65.9796704f, 57.5737917f, 64.5928855f, 59.965729f); xamagonBody.LineTo(43.0238921f, 97.5342563f); xamagonBody.CubicTo(41.6587026f, 99.9325978f, 41.6587026f, 103.067402f, 43.0238921f, 105.465744f); xamagonBody.LineTo(64.5928855f, 143.034271f); xamagonBody.CubicTo(65.9798162f, 145.426228f, 68.6763107f, 146.994582f, 71.4311121f, 147f); xamagonBody.LineTo(114.568946f, 147f); xamagonBody.CubicTo(117.323748f, 146.994143f, 120.020241f, 145.426228f, 121.407172f, 143.034271f); xamagonBody.LineTo(142.976161f, 105.465744f); xamagonBody.CubicTo(144.34135f, 103.067402f, 144.341209f, 99.9325978f, 142.976161f, 97.5342563f); xamagonBody.LineTo(121.407172f, 59.965729f); xamagonBody.CubicTo(120.020241f, 57.5737917f, 117.323748f, 56.0054182f, 114.568946f, 56f); xamagonBody.LineTo(71.4311121f, 56f); xamagonBody.Close(); ``` And then we’ll do the same thing as we did with the spiral, and use an `SKPaint` to draw the Xamagon. ```csharp using (var paint = new SKPaint ()) { paint.IsAntialias = true; paint.Color = new SKColor(0x34, 0x98, 0xdb, 0xff); paint.StrokeCap = SKStrokeCap.Round; canvas.DrawPath(xamagonBody, paint); } surface; ``` Finally, we need to path the X body and draw it onto the surface. ```csharp var xBody = new SKPath(); xBody.MoveTo(71.8225901f, 77.9780432f); xBody.CubicTo(71.8818491f, 77.9721857f, 71.9440029f, 77.9721857f, 72.0034464f, 77.9780432f); xBody.LineTo(79.444074f, 77.9780432f); xBody.CubicTo(79.773437f, 77.9848769f, 80.0929203f, 78.1757336f, 80.2573978f, 78.4623994f); xBody.LineTo(92.8795281f, 101.015639f); xBody.CubicTo(92.9430615f, 101.127146f, 92.9839987f, 101.251384f, 92.9995323f, 101.378901f); xBody.CubicTo(93.0150756f, 101.251354f, 93.055974f, 101.127107f, 93.1195365f, 101.015639f); xBody.LineTo(105.711456f, 78.4623994f); xBody.CubicTo(105.881153f, 78.167045f, 106.215602f, 77.975134f, 106.554853f, 77.9780432f); xBody.LineTo(113.995483f, 77.9780432f); xBody.CubicTo(114.654359f, 77.9839007f, 115.147775f, 78.8160066f, 114.839019f, 79.4008677f); xBody.LineTo(102.518299f, 101.500005f); xBody.LineTo(114.839019f, 123.568869f); xBody.CubicTo(115.176999f, 124.157088f, 114.671442f, 125.027775f, 113.995483f, 125.021957f); xBody.LineTo(106.554853f, 125.021957f); xBody.CubicTo(106.209673f, 125.019028f, 105.873247f, 124.81384f, 105.711456f, 124.507327f); xBody.LineTo(93.1195365f, 101.954088f); xBody.CubicTo(93.0560031f, 101.84258f, 93.0150659f, 101.718333f, 92.9995323f, 101.590825f); xBody.CubicTo(92.983989f, 101.718363f, 92.9430906f, 101.842629f, 92.8795281f, 101.954088f); xBody.LineTo(80.2573978f, 124.507327f); xBody.CubicTo(80.1004103f, 124.805171f, 79.7792269f, 125.008397f, 79.444074f, 125.021957f); xBody.LineTo(72.0034464f, 125.021957f); xBody.CubicTo(71.3274867f, 125.027814f, 70.8220664f, 124.157088f, 71.1600463f, 123.568869f); xBody.LineTo(83.4807624f, 101.500005f); xBody.LineTo(71.1600463f, 79.400867f); xBody.CubicTo(70.8647037f, 78.86725f, 71.2250368f, 78.0919422f, 71.8225901f, 77.9780432f); xBody.LineTo(71.8225901f, 77.9780432f); xBody.Close(); ``` And paint it: ```csharp using (var paint = new SKPaint ()) { paint.IsAntialias = true; paint.Color = SKColors.White; paint.StrokeCap = SKStrokeCap.Round; canvas.DrawPath(xBody, paint); } surface; ``` Tada! We’ve now got ourselves a Xamagon. ### Xamagon Exercises * You’ll notice that the Xamagon is a bit…small. How can you increase its size, without modifying the paths themselves.\ Explore the APIs on `SKCanvas` and `SKSurface` for anything relevant. * What happens if you change the `SKPaint` properties? ================================================ FILE: graphics/skiasharp/meta.json ================================================ { "order":{ "introduction/introduction.workbook":"An Introduction", "logo/skialogo-ios.workbook":"Logo for iOS", "colors/colors.workbook":"Working with SKColor", "images/images.workbook":"Exploring SKImage", "pixmap/pixmap.workbook":"Working with SKPixmap" } } ================================================ FILE: graphics/skiasharp/pixmap/pixmap.workbook/index.workbook ================================================ --- packages: - id: SkiaSharp version: 1.57.1 title: Working with SKPixmap uti: com.xamarin.workbook id: ab5c4303-8a59-4786-8dca-752524d8445c platforms: - Console --- ```csharp // install SkiaSharp #r "SkiaSharp" using SkiaSharp; ``` # Working with SKPixmap SkiaSharp exposes the `SKPixmap` type, which is used when you manually want to manage image memory, or color table memory. This is useful if you’re receiving this from another library, or generating pixel data yourself and want to avoid copies. In this case, we’ll demonstrate how to manually decode an image and load it into an `SKPixmap`. We’ll use the same `cat.jpeg` image that we used in the `SKImage` workbook here to demonstrate manual loading. > ⚠️ `SKPixmap` uses some advanced .NET concepts, such as unsafe code and pinning. ```csharp using System.IO; // First, load our image data. In other cases, this may be data you // received in a web app, or from some other library, or generated pixels. var imageData = File.ReadAllBytes ("cat.jpeg"); // Decode the image data we've loaded into a byte[] of pure pixels. var codec = SKCodec.Create (new SKMemoryStream (imageData)); var decoded = codec.Pixels; SKPixmap pixmap; unsafe { // Because SKPixmap wants an IntPtr for data, we have to pin our existing // byte[] so that the garbage collector doesn't move it. fixed (byte* decodedPtr = decoded) { // Create the SKPixmap instance. pixmap = new SKPixmap ( new SKImageInfo (codec.Info.Width, codec.Info.Height, codec.Info.ColorType), (IntPtr) decodedPtr ); } } // Return it so that we can visualize it in the workbook. pixmap; ``` ================================================ FILE: graphics/tiny-renderer/README.md ================================================ # TinyRenderer These workbooks are a port of an excellent [C++ series](https://github.com/ssloy/tinyrenderer/wiki) written by Dmitry Sokolov. We appreciate that original work is available under a license that allowed us to turn it into a Workbook. Hopefully, you will find it as fascinating and educational as we did. ================================================ FILE: graphics/tiny-renderer/Renderer/Listings/ListingTexture.cs ================================================ using System; using static Renderer.Geometry; using static Renderer.Utils; namespace Renderer { static class ListingTexture { static int width = 800, height = 800; static readonly Vec3f [] world = new Vec3f [3]; static readonly Vec3f [] screen = new Vec3f [3]; static readonly Vec3f light_dir = new Vec3f { x = 0, y = 0, z = -1 }; public static void Execute (Model model, Image texture) { var image = new Image (width, height, Format.BGR); Func map = v => new Vec3f { x = (int)Math.Round ((v.x + 1) * (image.Width - 1) / 2, MidpointRounding.AwayFromZero), y = (int)Math.Round ((v.y + 1) * (image.Height - 1) / 2, MidpointRounding.AwayFromZero), z = v.z }; Func uvMap = v => new Vec2f { x = v.x * (texture.Width - 1), y = v.y * (texture.Height - 1) }; var zbuffer = InitZBuffer (image); var uv = new Vec2f [3]; foreach (var face in model.Faces) { for (int i = 0; i < 3; i++) { var vIndex = face.Vertices [i]; world [i] = model.Vertices [vIndex]; screen [i] = map (world [i]); var tIndex = face.Textures [i]; uv [i] = uvMap (model.Textures [tIndex]); } Vec3f n = Cross (world [2] - world [0], world [1] - world [0]).Normalize (); var intensivity = Dot (n, light_dir); if (intensivity > 0) Triangle (image, screen, texture, uv, intensivity, zbuffer); } image.VerticalFlip (); image.WriteToFile ("texture-head.tga"); } } } ================================================ FILE: graphics/tiny-renderer/Renderer/Listings/ListingZBuffer.cs ================================================ using System; using static Renderer.Geometry; using static Renderer.Utils; namespace Renderer { static class ListingZBuffer { static int width = 800, height = 800; static readonly Vec3f[] world = new Vec3f [3]; static readonly Vec3f[] screen = new Vec3f [3]; static readonly Vec3f light_dir = new Vec3f { x = 0, y = 0, z = -1 }; public static void Execute (Model model) { var image = new Image (width, height, Format.BGR); Func map = v => new Vec3f { x = (int)Math.Round ((v.x + 1) * (image.Width - 1) / 2, MidpointRounding.AwayFromZero), y = (int)Math.Round ((v.y + 1) * (image.Height - 1) / 2, MidpointRounding.AwayFromZero), z = v.z }; var zbuffer = InitZBuffer (image); foreach (var face in model.Faces) { for (int i = 0; i < 3; i++) { var vIndex = face.Vertices [i]; world [i] = model.Vertices [vIndex]; screen [i] = map (world [i]); } Vec3f n = Cross (world [2] - world [0], world [1] - world [0]).Normalize (); var intensivity = Dot (n, light_dir); if (intensivity > 0) Triangle (image, screen, Color.White * intensivity, zbuffer); } image.VerticalFlip (); image.WriteToFile ("gray-head-zbuffer.tga"); } } } ================================================ FILE: graphics/tiny-renderer/Renderer/Program.cs ================================================ using System; using static Renderer.Geometry; using static Renderer.Utils; using static Renderer.MatrixHelpers; namespace Renderer { class MainClass { static int width = 800, height = 800; static readonly Image gridTexture = Image.Load ("../../../obj/grid.tga"); #region head static readonly Model headModel = Model.FromFile ("../../../obj/african_head.obj"); static readonly Image headTexture = Image.Load ("../../../obj/african_head_diffuse.tga"); static readonly Image headNormalMap = Image.Load ("../../../obj/african_head_nm.tga"); static readonly Image headTangentMap = Image.Load ("../../../obj/african_head_nm_tangent.tga"); static readonly Image headSpecularMap = Image.Load ("../../../obj/african_head_spec.tga"); #endregion #region diablo static readonly Model diabloModel = Model.FromFile ("../../../obj/diablo3_pose.obj"); static readonly Image diabloTexture = Image.Load ("../../../obj/diablo3_pose_diffuse.tga"); static readonly Image diabloNormalMap = Image.Load ("../../../obj/diablo3_pose_nm.tga"); static readonly Image diabloTangentMap = Image.Load ("../../../obj/diablo3_pose_nm_tangent.tga"); static readonly Image diabloSpecularMap = Image.Load ("../../../obj/diablo3_pose_spec.tga"); // Lesson 8 static readonly Image aoTexture = Image.Load ("../../../obj/diablo3-total-occlusion.tga"); #endregion static readonly Vec3f[] world = new Vec3f [3]; static readonly Vec3f[] screen = new Vec3f [3]; static readonly Vec2f[] uv = new Vec2f [3]; static readonly Vec3f light_dir = new Vec3f { x = 1, y = 1, z = 1 }; static readonly Vec3f eye = new Vec3f { x = 1, y = 1, z = 3 }; static readonly Vec3f center = new Vec3f { x = 0, y = 0, z = 0 }; static readonly Vec3f up = new Vec3f { x = 0, y = 1, z = 0 }; static readonly Matrix4 modelView = LookAt (eye, center, up); static readonly Matrix4 viewPort = Viewport (width / 8, height / 8, width * 3 / 4, height * 3 / 4); static readonly Matrix4 projection = Projection (-1f / (eye - center).Norm ()); static readonly Func map = v => { var t = viewPort * projection * modelView; var r = Project3D (Mult (t, Embed4D (v))); r.x = (int)Math.Round (r.x, MidpointRounding.AwayFromZero); r.y = (int)Math.Round (r.y, MidpointRounding.AwayFromZero); return r; }; static readonly Func uvMap = v => new Vec2f { x = v.x * (headTexture.Width - 1), y = v.y * (headTexture.Height - 1) }; public static void Main (string [] args) { headTexture.VerticalFlip (); headNormalMap.VerticalFlip (); headTangentMap.VerticalFlip (); headSpecularMap.VerticalFlip (); diabloTexture.VerticalFlip (); diabloNormalMap.VerticalFlip (); diabloTangentMap.VerticalFlip (); diabloSpecularMap.VerticalFlip (); // lesson 8 aoTexture.VerticalFlip (); //LightListing (); //ListingZBuffer.Execute (model); //ListingTexture.Execute (model, texture); //ProjectionListing (); //CameraMoveListing (); //GouraudShaderListing (); //GouraudShader6Listing (); //TextureShaderListing (); //NormalMapListing (); //SpecularShaderListing (); //TangetShaderListing (); DepthShaderListing (); //AmbientListing (); //AOShaderListing (); //ScreenSpaceAOListing (); } static void ScreenSpaceAOListing () { //var model = headModel; var model = diabloModel; var shader = new ZShader2 (model, viewPort, projection, modelView); var result = Render (model, shader); var image = result.Image; var zbuffer = result.ZBuffer; for (int x = 0; x < image.Width; x++) { for (int y = 0; y < image.Height; y++) { if (zbuffer [x + y * image.Width] < -1e5) continue; double total = 0; for (var a = 0.0; a < 2 * Math.PI - 0.001; a += Math.PI / 4) { total += Math.PI / 2 - MaxElevationAngle (zbuffer, new Vec2f { x = x, y = y }, new Vec2f { x = (float)Math.Cos (a), y = (float)Math.Sin (a) }, image.Width, image.Height); } total /= (Math.PI / 2) * 8; var v = (byte)(Math.Min (255, total * 255)); image [x, y] = new Color (v, v, v); } } image.VerticalFlip (); image.WriteToFile ("ao-screen-space.tga"); } static void AOShaderListing () { var shader = new AOShader (diabloModel, viewPort, projection, modelView, aoTexture); Render (diabloModel, shader, "ao-shader.tga"); } static void AmbientListing () { var rnd = new Random (); var screen_coords = new Vec4f [3]; var frame = new Image (width, height, Format.BGR); var shadowbuffer = InitZBuffer (frame); var zbuffer = InitZBuffer (frame); var total = new Image (1024, 1024, Format.BGR); var occl = new Image (1024, 1024, Format.BGR); const int nrenders = 1; for (int iter = 1; iter <= nrenders; iter++) { for (int i = 0; i < shadowbuffer.Length; i++) { shadowbuffer [i] = 0; zbuffer [i] = 0; } var vUp = new Vec3f { x = (float)rnd.NextDouble (), y = (float)rnd.NextDouble (), z = (float)rnd.NextDouble () }; var spLocation = RandPointOnUnitSphere (); spLocation.y = Math.Abs (spLocation.y); frame.Clear (); var mvM = LookAt (spLocation, center, vUp); var pM = Projection (0); var zshader = new ZShader (diabloModel, viewPort, pM, mvM); foreach (var face in diabloModel.Faces) { for (int i = 0; i < 3; i++) screen_coords [i] = zshader.Vertex (face, i); Triangle (frame, screen_coords, zshader, shadowbuffer); } //frame.VerticalFlip (); //frame.WriteToFile ("framebuffer.tga"); occl.Clear (); var shader = new OcclusionShader (diabloModel, viewPort, pM, mvM, occl, shadowbuffer, frame.Width); foreach (var face in diabloModel.Faces) { for (int i = 0; i < 3; i++) screen_coords [i] = shader.Vertex (face, i); Triangle (frame, screen_coords, shader, zbuffer); } for (int i = 0; i < total.Width; i++) { for (int j = 0; j < total.Height; j++) { float prev = total [i, j] [0]; float curr = occl [i, j] [0]; var val = (byte)((prev * (iter - 1) + curr) / iter + 0.5f); total [i, j] = new Color (val, val, val); } } } total.VerticalFlip (); total.WriteToFile ("total-occlusion.tga"); } static void DepthShaderListing () { var model = diabloModel; var M = viewPort * Projection (0) * LookAt (light_dir, center, up); var depthShader = new DepthShader (model, M); var step1 = Render (model, depthShader, "diablo-depth-shader.tga"); var shadowM = M * Inverse (viewPort * projection * modelView); var shader = new ShadowShader (model, viewPort, projection, modelView, shadowM, light_dir, diabloTexture, diabloNormalMap, diabloSpecularMap, step1.ZBuffer, width); Render (model, shader, "diablo-shadow-shader.tga"); } static void TangetShaderListing () { var model = headModel; var shader = new TangentShader (model, viewPort, projection, modelView, light_dir, headTexture /*gridTexture*/, headTangentMap /*normalMap*/); Render (model, shader, "tanget-shader.tga"); } static void SpecularShaderListing () { RunSpec (headModel, headTexture, headNormalMap, headSpecularMap, "specular-shader.tga"); RunSpec (diabloModel, diabloTexture, diabloNormalMap, diabloSpecularMap, "diablo-specular-shader.tga"); } static void RunSpec (Model model, Image texture, Image nm, Image sm, string path) { var shader = new SpecularShader (model, viewPort, projection, modelView, light_dir, texture, nm, sm); Render (model, shader, path); } static void NormalMapListing () { var shader = new NormalMapShader (headModel, viewPort, projection, modelView, light_dir, headTexture, headNormalMap); Render (headModel, shader, "normal-map-shader.tga"); } static void TextureShaderListing () { var shader = new TextureShader (headModel, viewPort, projection, modelView, light_dir, headTexture); Render (headModel, shader, "texture-shader.tga"); } static void GouraudShader6Listing () { var shader = new GouraudShader6 (headModel, viewPort, projection, modelView, light_dir); Render (headModel, shader, "gouraud-shader6.tga"); } static void GouraudShaderListing () { var shader = new GouraudShader (headModel, viewPort, projection, modelView, light_dir); Render (headModel, shader, "gouraud-shader.tga"); } static RenderResult Render (Model model, IShader shader, string path) { var result = Render (model, shader); result.Image.VerticalFlip (); result.Image.WriteToFile (path); return result; } static RenderResult Render (Model model, IShader shader) { var image = new Image (width, height, Format.BGR); var zbuffer = InitZBuffer (image); var screen_coords = new Vec4f [3]; foreach (var face in model.Faces) { for (int i = 0; i < 3; i++) screen_coords [i] = shader.Vertex (face, i); Triangle (image, screen_coords, shader, zbuffer); } return new RenderResult { Image = image, ZBuffer = zbuffer }; } class RenderResult { public Image Image { get; set; } public float [] ZBuffer { get; set; } } static void CameraMoveListing () { var image = new Image (width, height, Format.BGR); var zbuffer = InitZBuffer (image); foreach (var face in headModel.Faces) { for (int i = 0; i < 3; i++) { var vIndex = face.Vertices [i]; world [i] = headModel.Vertices [vIndex]; screen [i] = map (world [i]); var tIndex = face.Textures [i]; uv [i] = uvMap (headModel.Textures [tIndex]); } Vec3f n = Cross (world [2] - world [0], world [1] - world [0]).Normalize (); var intensivity = Dot (n, light_dir); if (intensivity > 0) Triangle (image, screen, headTexture, uv, intensivity, zbuffer); } image.VerticalFlip (); image.WriteToFile ("camera-moved.tga"); } static void ProjectionListing () { var image = new Image (width, height, Format.BGR); var camera = new Vec3f { z = 3 }; var projection = Projection (-1 / camera.z); var viewPort = Viewport (width / 8, height / 8, width * 3 / 4, height * 3 / 4); var zbuffer = InitZBuffer (image); foreach (var face in headModel.Faces) { for (int i = 0; i < 3; i++) { var vIndex = face.Vertices [i]; world [i] = headModel.Vertices [vIndex]; screen [i] = map (world [i]); var tIndex = face.Textures [i]; uv [i] = uvMap (headModel.Textures [tIndex]); } var n = Cross (world [2] - world [0], world [1] - world [0]).Normalize (); var intensivity = Dot (n, light_dir); if (intensivity > 0) Triangle (image, screen, headTexture, uv, intensivity, zbuffer); } image.VerticalFlip (); image.WriteToFile ("project-head.tga"); } static void LightListing () { var image = new Image (width, height, Format.BGR); Func map = v => new Vec3f { x = (int)((v.x + 1) * image.Width / 2), y = (int)((v.y + 1) * image.Height / 2) }; var light_dir = new Vec3f { x = 0, y = 0, z = -1 }; foreach (var face in headModel.Faces) { for (int i = 0; i < 3; i++) { var vIndex = face.Vertices [i]; world [i] = headModel.Vertices [vIndex]; screen [i] = map (world [i]); } var n = Cross (world [2] - world [0], world [1] - world [0]).Normalize (); var intensivity = Dot (n, light_dir); if (intensivity > 0) Triangle (image, screen, Color.White * intensivity); } image.VerticalFlip (); image.WriteToFile ("gray-head.tga"); } static void TriangleListing () { var image = new Image (200, 200, Format.BGR); Vec3f [] coordinates = { new Vec3f {x=10, y=10}, new Vec3f {x=100, y=30}, new Vec3f {x=190, y=160} }; Triangle (image, coordinates, Color.Red); image.VerticalFlip (); image.WriteToFile ("red-triangle.tga"); } } } ================================================ FILE: graphics/tiny-renderer/Renderer/Properties/AssemblyInfo.cs ================================================ using System.Reflection; using System.Runtime.CompilerServices; // Information about this assembly is defined by the following attributes. // Change them to the values specific to your project. [assembly: AssemblyTitle ("Renderer")] [assembly: AssemblyDescription ("")] [assembly: AssemblyConfiguration ("")] [assembly: AssemblyCompany ("")] [assembly: AssemblyProduct ("")] [assembly: AssemblyCopyright ("rzaitov")] [assembly: AssemblyTrademark ("")] [assembly: AssemblyCulture ("")] // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". // The form "{Major}.{Minor}.*" will automatically update the build and revision, // and "{Major}.{Minor}.{Build}.*" will update just the revision. [assembly: AssemblyVersion ("1.0.*")] // The following attributes are used to specify the signing key for the assembly, // if desired. See the Mono documentation for more information about signing. //[assembly: AssemblyDelaySign(false)] //[assembly: AssemblyKeyFile("")] ================================================ FILE: graphics/tiny-renderer/Renderer/Renderer.csproj ================================================ Debug x86 {E3C10096-CCF5-4853-B868-1C7969DAFDD2} Exe Renderer Renderer v4.5 true full false bin\Debug DEBUG; prompt 4 true x86 true bin\Release prompt 4 true x86 packages\NUnit.3.5.0\lib\net45\nunit.framework.dll ================================================ FILE: graphics/tiny-renderer/Renderer/Renderer.sln ================================================ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2012 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Renderer", "Renderer.csproj", "{E3C10096-CCF5-4853-B868-1C7969DAFDD2}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x86 = Debug|x86 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {E3C10096-CCF5-4853-B868-1C7969DAFDD2}.Debug|x86.ActiveCfg = Debug|x86 {E3C10096-CCF5-4853-B868-1C7969DAFDD2}.Debug|x86.Build.0 = Debug|x86 {E3C10096-CCF5-4853-B868-1C7969DAFDD2}.Release|x86.ActiveCfg = Release|x86 {E3C10096-CCF5-4853-B868-1C7969DAFDD2}.Release|x86.Build.0 = Release|x86 EndGlobalSection EndGlobal ================================================ FILE: graphics/tiny-renderer/Renderer/Tests/GouraudShaderFixture.cs ================================================ using System; using NUnit.Framework; using static Renderer.Utils; using static Renderer.MatrixHelpers; using static Renderer.Geometry; namespace Renderer { [TestFixture] public class GouraudShaderFixture { static int width = 800, height = 800; static readonly Vec3f eye = new Vec3f { x = 1, y = 1, z = 3 }; static readonly Vec3f center = new Vec3f { x = 0, y = 0, z = 0 }; static readonly Vec3f up = new Vec3f { x = 0, y = 1, z = 0 }; [Test] public void Vertex () { var model = ModelUtils.GetModel1 (); var ligthdir = new Vec3f { z = 3 }; var I = Matrix4.Identity (); //var viewPort = I; //var projection = I; //var modelView = I; var modelView = LookAt (eye, center, up); var viewPort = Viewport (width / 8, height / 8, width * 3 / 4, height * 3 / 4); var projection = Projection (-1f / (eye - center).Norm ()); var shader = new GouraudShader (model, viewPort, projection, modelView, ligthdir); var face = model.Faces [0]; var sc0 = shader.Vertex (face, 0); //sc0 = sc0 / sc0.h; var sc1 = shader.Vertex (face, 1); //sc1 = sc1 / sc1.h; var sc2 = shader.Vertex (face, 2); //sc2 = sc2 / sc2.h; Func map = v => { var transformation = viewPort * projection * modelView; var r = Project3D (Mult (transformation, Embed4D (v))); //r.x = (int)Math.Round (r.x, MidpointRounding.AwayFromZero); //r.y = (int)Math.Round (r.y, MidpointRounding.AwayFromZero); return r; }; var v0 = model.Vertices [face.Vertices [0]]; var v1 = model.Vertices [face.Vertices [1]]; var v2 = model.Vertices [face.Vertices [2]]; var t0 = map (v0); var t1 = map (v1); var t2 = map (v2); Assert.True (Math.Abs (sc0.x - t0.x) < 0.0001f); Assert.True (Math.Abs (sc0.y - t0.y) < 0.0001f); Assert.True (Math.Abs (sc0.z - t0.z) < 0.0001f); Assert.True (Math.Abs (sc1.x - t1.x) < 0.0001f); Assert.True (Math.Abs (sc1.y - t1.y) < 0.0001f); Assert.True (Math.Abs (sc1.z - t1.z) < 0.0001f); Assert.True (Math.Abs (sc2.x - t2.x) < 0.0001f); Assert.True (Math.Abs (sc2.y - t2.y) < 0.0001f); Assert.True (Math.Abs (sc2.z - t2.z) < 0.0001f); } } } ================================================ FILE: graphics/tiny-renderer/Renderer/Tests/MatrixFixture.cs ================================================ using System; using NUnit.Framework; using static Renderer.MatrixHelpers; namespace Renderer { [TestFixture] public class MatrixFixture { [Test] public void InverseIdentity () { var identity = Matrix4.Identity (); var ti = TransposeInverse (identity); Console.WriteLine (ti); } } } ================================================ FILE: graphics/tiny-renderer/Renderer/Tests/ModelFixture.cs ================================================ using System; using NUnit.Framework; namespace Renderer { static class ModelUtils { const string text = @" v 0 0 0 v 0 1 0 v 1 0 0 vn 0 0 1 vn 0 0 2 vn 0 0 3 f 1/-1/1 2/-1/2 3/-1/3 "; public static Model GetModel1 () { return Model.FromText (text); } } [TestFixture] public class ModelFixture { [Test] public void Normal () { var model = ModelUtils.GetModel1 (); var face = model.Faces [0]; var n1 = model.Normal (face, 0); Assert.AreEqual (1, n1.z); var n2 = model.Normal (face, 1); Assert.AreEqual (2, n2.z); var n3 = model.Normal (face, 2); Assert.AreEqual (3, n3.z); } } } ================================================ FILE: graphics/tiny-renderer/Renderer/Tests/VectorFixture.cs ================================================ using System; using NUnit.Framework; namespace Renderer { [TestFixture] public class VectorFixture { [Test] public void Project3D () { var v4 = new Vec4f { x = 10, y = 11, z = 12, h = 13 }; var v3 = Geometry.Project3D (v4); Assert.AreEqual (v4.x, v3.x); Assert.AreEqual (v4.y, v3.y); Assert.AreEqual (v4.z, v3.z); } [Test] public void Embed4D_DefaultValue () { var v3 = new Vec3f { x = 10, y = 11, z = 12 }; var v4 = Geometry.Embed4D (v3); Assert.AreEqual (v3.x, v4.x); Assert.AreEqual (v3.y, v4.y); Assert.AreEqual (v3.z, v4.z); Assert.AreEqual (1, v4.h); } [Test] public void Embed4D () { var v3 = new Vec3f { x = 10, y = 11, z = 12 }; var v4 = Geometry.Embed4D (v3, 777); Assert.AreEqual (v3.x, v4.x); Assert.AreEqual (v3.y, v4.y); Assert.AreEqual (v3.z, v4.z); Assert.AreEqual (777, v4.h); } [Test] public void VectorIndexer () { float x = 10f, y = 11f, z = 12f, h = 13f; var v4 = new Vec4f (); v4 [0] = x; v4 [1] = y; v4 [2] = z; v4 [3] = h; Assert.AreEqual (x, v4 [0]); Assert.AreEqual (y, v4 [1]); Assert.AreEqual (z, v4 [2]); Assert.AreEqual (h, v4 [3]); v4 = new Vec4f (); v4.x = x; v4.y = y; v4.z = z; v4.h = h; Assert.AreEqual (x, v4.x); Assert.AreEqual (y, v4.y); Assert.AreEqual (z, v4.z); Assert.AreEqual (h, v4.h); } [Test] public void Vector4_Divide () { var v4 = new Vec4f { x = 10, y = 20, z = 30, h = 40 }; var r4 = v4 / 10; Assert.AreEqual (1, r4.x); Assert.AreEqual (2, r4.y); Assert.AreEqual (3, r4.z); Assert.AreEqual (4, r4.h); } [Test] public void Vector4_Sub () { var a4 = new Vec4f { x = 10, y = 20, z = 30, h = 40 }; var b4 = new Vec4f { x = 1, y = 2, z = 3, h = 4 }; var r = a4 - b4; Assert.AreEqual (9, r.x); Assert.AreEqual (18, r.y); Assert.AreEqual (27, r.z); Assert.AreEqual (36, r.h); } [Test] public void Vector4_Norm () { var b4 = new Vec4f { x = 1, y = 2, z = 3, h = 4 }; var len = b4.Norm (); Assert.True (Math.Abs (Math.Sqrt (30) - len) <= 0.001); } [Test] public void Vector4_Normalize () { var b4 = new Vec4f { x = 1, y = 2, z = 3, h = 4 }; var len = b4.Norm (); var n = b4.Normalize (); Assert.True (Math.Abs (n.x - 1f / len) <= 0.001); Assert.True (Math.Abs (n.y - 2f / len) <= 0.001); Assert.True (Math.Abs (n.z - 3f / len) <= 0.001); Assert.True (Math.Abs (n.h - 4f / len) <= 0.001); } } } ================================================ FILE: graphics/tiny-renderer/Renderer/WorkbookItems/Geometry.cs ================================================ using System; namespace Renderer { struct Vec2f { public float x; public float y; public float this [int i] { get { if (i == 0) return x; if (i == 1) return y; throw new InvalidOperationException (); } set { if (i == 0) x = value; else if (i == 1) y = value; else throw new InvalidOperationException (); } } public Vec2f Normalize () { return this / Norm (); } public float Norm () { return (float)Math.Sqrt (x * x + y * y); } public static Vec2f operator / (Vec2f v, float num) { v.x /= num; v.y /= num; return v; } public static Vec2f operator * (Vec2f v, float num) { v.x *= num; v.y *= num; return v; } public static Vec2f operator - (Vec2f a, Vec2f b) { return new Vec2f { x = a.x - b.x, y = a.y - b.y }; } public static Vec2f operator + (Vec2f a, Vec2f b) { return new Vec2f { x = a.x + b.x, y = a.y + b.y }; } } public struct Vec3f { public float x; public float y; public float z; public float this [int i] { get { switch (i) { case 0: return x; case 1: return y; case 2: return z; default: throw new InvalidOperationException (); } } set { switch (i) { case 0: x = value; break; case 1: y = value; break; case 2: z = value; break; default: throw new InvalidOperationException (); } } } public Vec3f Normalize () { return this / Norm (); } public float Norm () { return (float)Math.Sqrt (x * x + y * y + z * z); } public static Vec3f operator - (Vec3f a, Vec3f b) { return new Vec3f { x = a.x - b.x, y = a.y - b.y, z = a.z - b.z }; } public static Vec3f operator / (Vec3f v, float num) { v.x /= num; v.y /= num; v.z /= num; return v; } public static Vec3f operator * (Vec3f v, float num) { v.x *= num; v.y *= num; v.z *= num; return v; } } struct Vec4f { public float x; public float y; public float z; public float h; public float this [int i] { get { switch (i) { case 0: return x; case 1: return y; case 2: return z; case 3: return h; default: throw new InvalidOperationException (); } } set { switch (i) { case 0: x = value; break; case 1: y = value; break; case 2: z = value; break; case 3: h = value; break; default: throw new InvalidOperationException (); } } } public Vec4f Normalize () { var len = Norm (); return this / len; } public float Norm () { return (float)Math.Sqrt (x * x + y * y + z * z + h * h); } public static Vec4f operator - (Vec4f a, Vec4f b) { return new Vec4f { x = a.x - b.x, y = a.y - b.y, z = a.z - b.z, h = a.h - b.h }; } public static Vec4f operator / (Vec4f v, float num) { v.x /= num; v.y /= num; v.z /= num; v.h /= num; return v; } } struct Vec2i { public int x; public int y; public static Vec2i operator - (Vec2i a, Vec2i b) { return new Vec2i { x = a.x - b.x, y = a.y - b.y }; } } struct Vec3i { public int x; public int y; public int z; public static Vec3i operator - (Vec3i a, Vec3i b) { return new Vec3i { x = a.x - b.x, y = a.y - b.y, z = a.z - b.z }; } } static class Geometry { public static Vec3f Cross (Vec3f l, Vec3f r) { return new Vec3f { x = l.y * r.z - l.z * r.y, y = l.z * r.x - l.x * r.z, z = l.x * r.y - l.y * r.x }; } public static float Dot (Vec3f l, Vec3f r) { return l.x * r.x + l.y * r.y + l.z * r.z; } public static Vec4f Embed4D (Vec3f v, float fill = 1) { return new Vec4f { x = v.x, y = v.y, z = v.z, h = fill }; } public static Vec2f Project2D (Vec3f v) { return new Vec2f { x = v.x, y = v.y }; } public static Vec2f Project2D (Vec4f v) { return new Vec2f { x = v.x, y = v.y }; } public static Vec3f Project3D (Vec4f v) { return new Vec3f { x = v.x, y = v.y, z = v.z }; } } } ================================================ FILE: graphics/tiny-renderer/Renderer/WorkbookItems/Image.cs ================================================ using System; namespace Renderer { using System.IO; enum Format { GRAYSCALE = 1, BGR = 3, BGRA = 4 } struct Color { // the value stored as little endian: // ARGB -> BGRA // xRGB -> BGRx public readonly int value; public readonly Format format; public byte this [int offset] { get { if (offset > 3) // int has only 4 bytes (0, 1, 2, 3) throw new ArgumentOutOfRangeException (); return (byte)(value >> 8 * (3 - offset)); } } public static Color Red = new Color (red: 255, green: 0, blue: 0, alpha: 255); public static Color Green = new Color (red: 0, green: 255, blue: 0, alpha: 255); public static Color Blue = new Color (red: 0, green: 0, blue: 255, alpha: 255); public static Color Black = new Color (red: 0, green: 0, blue: 0, alpha: 255); public static Color White = new Color (red: 255, green: 255, blue: 255, alpha: 255); public static Color Yellow = new Color (red: 225, green: 225, blue: 0, alpha: 255); public Color (byte red, byte green, byte blue, byte alpha) : this ((blue << 24) | (green << 16) | (red << 8) | alpha, Format.BGRA) { } public Color (byte red, byte green, byte blue) : this ((blue << 24) | (green << 16) | (red << 8) | 0xFF, Format.BGR) { } public Color (byte value) : this (value, Format.GRAYSCALE) { } public Color (int value, Format format) { this.value = value; this.format = format; } public static Color operator * (Color color, float intensivity) { intensivity = Math.Max (0f, Math.Min (1f, intensivity)); var ch0 = (byte)(color [0] * intensivity); var ch1 = (byte)(color [1] * intensivity); var ch2 = (byte)(color [2] * intensivity); var ch3 = color [3]; return new Color (ch0 << 24 | ch1 << 16 | ch2 << 8 | ch3, color.format); } } class Image { internal byte [] buffer; public int Width { get; } public int Height { get; } public Format Format { get; } public int BytesPerRow { get { return Width * (int)Format; } } public Image (int width, int height, Format format) { Width = width; Height = height; Format = format; buffer = new byte [height * BytesPerRow]; } public void VerticalFlip () { var bpp = (int)Format; int bytesPerLine = Width * bpp; var half = Height >> 1; for (int l = 0; l < half; l++) { var l1 = l * bytesPerLine; var l2 = (Height - 1 - l) * bytesPerLine; for (int i = 0; i < bytesPerLine; i++) { byte pixel = buffer [l1 + i]; buffer [l1 + i] = buffer [l2 + i]; buffer [l2 + i] = pixel; } } } public void Clear () { for (int i = 0; i < buffer.Length; i++) buffer [i] = 0; } public Color this [int x, int y] { get { if (x < 0 || x >= Width) throw new ArgumentException ("x"); if (y < 0 || y >= Height) throw new ArgumentException ("y"); var offset = GetOffset (x, y); var len = (int)Format; int value = 0; for (var ch = 0; ch < 4; ch++) value = (value << 8) | (ch < len ? buffer [offset++] : 0xFF); return new Color (value, Format); } set { if (x < 0 || x >= Width) return; //throw new ArgumentException ($"{nameof(x)}={x} {nameof(Width)}={Width}"); if (y < 0 || y >= Height) return; // throw new ArgumentException ($"{nameof(y)}={y} {nameof(Height)}={Height}"); var offset = GetOffset (x, y); var v = value.value; var len = (int)Format; for (int ch = 0; ch < len; ch++) // 0123 buffer [offset++] = (byte)(v >> (3 - ch) * 8); // BGRA } } int GetOffset (int x, int y) { return y * BytesPerRow + x * (int)Format; } public bool WriteToFile (string path, bool rle = true) { var bpp = (int)Format; using (var writer = new BinaryWriter (File.Create (path))) { var header = new TGAHeader { IdLength = 0, // The IDLength set to 0 indicates that there is no image identification field in the TGA file ColorMapType = 0, // a value of 0 indicates that no palette is included BitsPerPixel = (byte)(bpp * 8), Width = (short)Width, Height = (short)Height, DataTypeCode = DataTypeFor (bpp, rle), ImageDescriptor = (byte)(0x20 | (Format == Format.BGRA ? 8 : 0)) // top-left origin }; WriteTo (writer, header); if (!rle) writer.Write (buffer); else UnloadRleData (writer); } return true; } public static Image Load (string path) { using (var reader = new BinaryReader (File.OpenRead (path))) { var header = ReadHeader (reader); var height = header.Height; var width = header.Width; var bytespp = header.BitsPerPixel >> 3; var format = (Format)bytespp; if (width <= 0 || height <= 0) throw new InvalidProgramException ($"bad image size: width={width} height={height}"); if (format != Format.BGR && format != Format.BGRA && format != Format.GRAYSCALE) throw new InvalidProgramException ($"unknown format {format}"); var img = new Image (width, height, format); switch (header.DataTypeCode) { case DataType.UncompressedTrueColorImage: case DataType.UncompressedBlackAndWhiteImage: reader.Read (img.buffer, 0, img.buffer.Length); break; case DataType.RleTrueColorImage: case DataType.RleBlackAndWhiteImage: img.LoadRleData (reader); break; default: throw new InvalidProgramException ($"unsupported image format {header.DataTypeCode}"); } if ((header.ImageDescriptor & 0x20) == 0) img.VerticalFlip (); return img; } } static void WriteTo (BinaryWriter writer, TGAHeader header) { writer.Write (header.IdLength); writer.Write (header.ColorMapType); writer.Write ((byte)header.DataTypeCode); writer.Write (header.ColorMapOrigin); writer.Write (header.ColorMapLength); writer.Write (header.ColorMapDepth); writer.Write (header.OriginX); writer.Write (header.OriginY); writer.Write (header.Width); writer.Write (header.Height); writer.Write (header.BitsPerPixel); writer.Write (header.ImageDescriptor); } static TGAHeader ReadHeader (BinaryReader reader) { var header = new TGAHeader { IdLength = reader.ReadByte (), ColorMapType = reader.ReadByte (), DataTypeCode = (DataType)reader.ReadByte (), ColorMapOrigin = reader.ReadInt16 (), ColorMapLength = reader.ReadInt16 (), ColorMapDepth = reader.ReadByte (), OriginX = reader.ReadInt16 (), OriginY = reader.ReadInt16 (), Width = reader.ReadInt16 (), Height = reader.ReadInt16 (), BitsPerPixel = reader.ReadByte (), ImageDescriptor = reader.ReadByte () }; return header; } bool UnloadRleData (BinaryWriter writer) { const int max_chunk_length = 128; int npixels = Width * Height; int curpix = 0; var bpp = (int)Format; while (curpix < npixels) { int chunkstart = curpix * bpp; int curbyte = curpix * bpp; int run_length = 1; bool literal = true; while (curpix + run_length < npixels && run_length < max_chunk_length && curpix + run_length < curpix + Width) { bool succ_eq = true; for (int t = 0; succ_eq && t < bpp; t++) succ_eq = (buffer [curbyte + t] == buffer [curbyte + t + bpp]); curbyte += bpp; if (1 == run_length) literal = !succ_eq; if (literal && succ_eq) { run_length--; break; } if (!literal && !succ_eq) break; run_length++; } curpix += run_length; writer.Write ((byte)(literal ? run_length - 1 : 128 + (run_length - 1))); writer.Write (buffer, chunkstart, literal ? run_length * bpp : bpp); } return true; } void LoadRleData (BinaryReader reader) { var pixelcount = Width * Height; var currentpixel = 0; var currentbyte = 0; var bytespp = (int)Format; var color = new byte [4]; do { var chunkheader = reader.ReadByte (); if (chunkheader < 128) { chunkheader++; for (int i = 0; i < chunkheader; i++) { for (int t = 0; t < bytespp; t++) buffer [currentbyte++] = reader.ReadByte (); currentpixel++; if (currentpixel > pixelcount) throw new InvalidProgramException ("Too many pixels read"); } } else { chunkheader -= 127; reader.Read (color, 0, bytespp); for (int i = 0; i < chunkheader; i++) { for (int t = 0; t < bytespp; t++) buffer [currentbyte++] = color [t]; currentpixel++; if (currentpixel > pixelcount) throw new InvalidProgramException ("Too many pixels read"); } } } while (currentpixel < pixelcount); } static DataType DataTypeFor (int bpp, bool rle) { var format = (Format)bpp; if (format == Format.GRAYSCALE) return rle ? DataType.RleBlackAndWhiteImage : DataType.UncompressedBlackAndWhiteImage; return rle ? DataType.RleTrueColorImage : DataType.UncompressedTrueColorImage; } } struct TGAHeader { public byte IdLength; public byte ColorMapType; public DataType DataTypeCode; // field #4. Color map specification public short ColorMapOrigin; // index of first color map entry that is included in the file public short ColorMapLength; // number of entries of the color map that are included in the file public byte ColorMapDepth; // number of bits per pixel // field #5. Image specification public short OriginX; // absolute coordinate of lower-left corner for displays where origin is at the lower left public short OriginY; // as for X-origin public short Width; // width in pixels public short Height; // height in pixels public byte BitsPerPixel; // pixel depth public byte ImageDescriptor; // bits 3-0 give the alpha channel depth, bits 5-4 give direction } public enum DataType : byte { NoImageData = 0, // no image data is present UncompressedColorMappedImage = 1, UncompressedTrueColorImage = 2, UncompressedBlackAndWhiteImage = 3, RleColorMappedImage = 9, // run-length encoded color-mapped image RleTrueColorImage = 10, // run-length encoded true-color image RleBlackAndWhiteImage = 11 // run-length encoded black-and-white (grayscale) image } } ================================================ FILE: graphics/tiny-renderer/Renderer/WorkbookItems/Matrix.cs ================================================ using System; namespace Renderer { public struct Matrix4 { public const int Len = 4; public float R0C0, R0C1, R0C2, R0C3; public float R1C0, R1C1, R1C2, R1C3; public float R2C0, R2C1, R2C2, R2C3; public float R3C0, R3C1, R3C2, R3C3; public float this [int row, int column] { get { switch (row) { case 0: switch (column) { case 0: return R0C0; case 1: return R0C1; case 2: return R0C2; case 3: return R0C3; } break; case 1: switch (column) { case 0: return R1C0; case 1: return R1C1; case 2: return R1C2; case 3: return R1C3; } break; case 2: switch (column) { case 0: return R2C0; case 1: return R2C1; case 2: return R2C2; case 3: return R2C3; } break; case 3: switch (column) { case 0: return R3C0; case 1: return R3C1; case 2: return R3C2; case 3: return R3C3; } break; } throw new IndexOutOfRangeException (); } set { switch (row) { case 0: switch (column) { case 0: R0C0 = value; return; case 1: R0C1 = value; return; case 2: R0C2 = value; return; case 3: R0C3 = value; return; } break; case 1: switch (column) { case 0: R1C0 = value; return; case 1: R1C1 = value; return; case 2: R1C2 = value; return; case 3: R1C3 = value; return; } break; case 2: switch (column) { case 0: R2C0 = value; return; case 1: R2C1 = value; return; case 2: R2C2 = value; return; case 3: R2C3 = value; return; } break; case 3: switch (column) { case 0: R3C0 = value; return; case 1: R3C1 = value; return; case 2: R3C2 = value; return; case 3: R3C3 = value; return; } break; } throw new IndexOutOfRangeException (); } } public Matrix4 Transpose () { return new Matrix4 { R0C0 = R0C0, R0C1 = R1C0, R0C2 = R2C0, R0C3 = R3C0, R1C0 = R0C1, R1C1 = R1C1, R1C2 = R2C1, R1C3 = R3C1, R2C0 = R0C2, R2C1 = R1C2, R2C2 = R2C2, R2C3 = R3C2, R3C0 = R0C3, R3C1 = R1C3, R3C2 = R2C3, R3C3 = R3C3 }; } public static Matrix4 Identity () { return new Matrix4 { R0C0 = 1, R1C1 = 1, R2C2 = 1, R3C3 = 1 }; } public static Matrix4 Zoom (float scale) { return new Matrix4 { R0C0 = scale, R1C1 = scale, R2C2 = scale, R3C3 = scale }; } public static Matrix4 RotationZ (float angle) { var cosangle = (float)Math.Cos (angle); var sinangle = (float)Math.Sin (angle); var R = Identity (); R [0, 0] = R [1, 1] = cosangle; R [0, 1] = -sinangle; R [1, 0] = sinangle; return R; } public static Matrix4 operator * (Matrix4 l, Matrix4 r) { var result = new Matrix4 (); for (int i = 0; i < Len; i++) { for (int j = 0; j < Len; j++) { result [i, j] = 0; for (int k = 0; k < Len; k++) { result [i, j] += l [i, k] * r [k, j]; } } } return result; } public override string ToString () { var sb = new System.Text.StringBuilder (); for (int r = 0; r < Len; r++) { for (int c = 0; c < Len; c++) sb.Append (this[r, c]).Append (" "); sb.AppendLine (); } return sb.ToString (); } } public struct Matrix3 { public const int Len = 3; public float R0C0, R0C1, R0C2; public float R1C0, R1C1, R1C2; public float R2C0, R2C1, R2C2; public float this [int row, int column] { get { switch (row) { case 0: switch (column) { case 0: return R0C0; case 1: return R0C1; case 2: return R0C2; } break; case 1: switch (column) { case 0: return R1C0; case 1: return R1C1; case 2: return R1C2; } break; case 2: switch (column) { case 0: return R2C0; case 1: return R2C1; case 2: return R2C2; } break; } throw new IndexOutOfRangeException (); } set { switch (row) { case 0: switch (column) { case 0: R0C0 = value; return; case 1: R0C1 = value; return; case 2: R0C2 = value; return; } break; case 1: switch (column) { case 0: R1C0 = value; return; case 1: R1C1 = value; return; case 2: R1C2 = value; return; } break; case 2: switch (column) { case 0: R2C0 = value; return; case 1: R2C1 = value; return; case 2: R2C2 = value; return; } break; } throw new IndexOutOfRangeException (); } } public Matrix3 Transpose () { return new Matrix3 { R0C0 = R0C0, R0C1 = R1C0, R0C2 = R2C0, R1C0 = R0C1, R1C1 = R1C1, R1C2 = R2C1, R2C0 = R0C2, R2C1 = R1C2, R2C2 = R2C2 }; } public void SetColumn (int col, Vec3f v) { this [0, col] = v.x; this [1, col] = v.y; this [2, col] = v.z; } public void SetRow (int row, Vec3f v) { this [row, 0] = v.x; this [row, 1] = v.y; this [row, 2] = v.z; } public override string ToString () { var sb = new System.Text.StringBuilder (); for (int r = 0; r < Len; r++) { for (int c = 0; c < Len; c++) sb.Append (this [r, c]).Append (" "); sb.AppendLine (); } return sb.ToString (); } } public struct Matrix2 { public const int Len = 2; public float R0C0, R0C1; public float R1C0, R1C1; public float this [int row, int column] { get { switch (row) { case 0: switch (column) { case 0: return R0C0; case 1: return R0C1; } break; case 1: switch (column) { case 0: return R1C0; case 1: return R1C1; } break; } throw new IndexOutOfRangeException (); } set { switch (row) { case 0: switch (column) { case 0: R0C0 = value; return; case 1: R0C1 = value; return; } break; case 1: switch (column) { case 0: R1C0 = value; return; case 1: R1C1 = value; return; } break; } throw new IndexOutOfRangeException (); } } } // methods from this class should be placed in workbooks // we don't want to declare them in Matrix because we don't need them in lesson which introduces Matrix class static class MatrixHelpers { /* // how to calc inverse Matrix https://en.wikipedia.org/w/index.php?title=Invertible_matrix§ion=4#In_relation_to_its_adjugate public static Matrix TransposeInverse (Matrix m) { // returns Transpose(Inverse(m)) // where Inverse(m) = Transpose(cofactor) / det(m) // Transpose(Inverse(m)) = Transpose(Transpose(cofactor) / det(m)) = cofactor / det(m) var cofactor = Cofactor (m); float det = 0; for (int i = 0; i < m.Rows; i++) det += m [0, i] * cofactor[0, i]; for (int r = 0; r < cofactor.Rows; r++) { for (int c = 0; c < cofactor.Cols; c++) cofactor [r, c] /= det; } return cofactor; } static Matrix Cofactor (Matrix m) { var r = new Matrix (m.Rows, m.Cols); for (int row = 0; row < m.Rows; row++) { for (int col = 0; col < m.Cols; col++) r [row, col] = Cofactor(m, row, col); } return r; } static float Cofactor (Matrix m, int row, int col) { int sign = ((row + col) % 2 == 0) ? 1 : -1; return Det (Minor (m, row, col)) * sign; } static Matrix Minor (Matrix m, int row, int col) { var minor = new Matrix (m.Rows - 1, m.Cols - 1); for (int r = 0; r < minor.Rows; r++) { for (int c = 0; c < minor.Cols; c++) { int y = (r < row) ? r : r + 1; int x = (c < col) ? c : c + 1; minor [r, c] = m [y, x]; } } return minor; } static float Det (Matrix m) { if (m.Rows == 1 && m.Cols == 1) return m [0, 0]; float det = 0; for (int col = 0; col < m.Cols; col++) det += m [0, col] * Cofactor (m, 0, col); return det; } */ // For Matrix4 // how to calc inverse Matrix https://en.wikipedia.org/w/index.php?title=Invertible_matrix§ion=4#In_relation_to_its_adjugate public static Matrix4 TransposeInverse (Matrix4 m) { // returns Transpose(Inverse(m)) // where Inverse(m) = Transpose(cofactor) / det(m) // Transpose(Inverse(m)) = Transpose(Transpose(cofactor) / det(m)) = cofactor / det(m) var cofactor = Cofactor (m); float det = 0; for (int i = 0; i < Matrix4.Len; i++) det += m [0, i] * cofactor [0, i]; for (int r = 0; r < Matrix4.Len; r++) { for (int c = 0; c < Matrix4.Len; c++) cofactor [r, c] /= det; } return cofactor; } public static Matrix4 Inverse (Matrix4 m) { // where Inverse(m) = Transpose(Cofactor(m)) / det(m) var cofactor = Cofactor (m); int len = Matrix4.Len; float det = 0; for (int i = 0; i < len; i++) det += m [0, i] * cofactor [0, i]; cofactor = cofactor.Transpose (); for (int r = 0; r < len; r++) { for (int c = 0; c < len; c++) cofactor [r, c] /= det; } return cofactor; } public static Matrix3 Inverse (Matrix3 m) { // where Inverse(m) = Transpose(Cofactor(m)) / det(m) var cofactor = Cofactor (m); int len = Matrix3.Len; float det = 0; for (int i = 0; i < len; i++) det += m [0, i] * cofactor [0, i]; cofactor = cofactor.Transpose (); for (int r = 0; r < len; r++) { for (int c = 0; c < len; c++) cofactor [r, c] /= det; } return cofactor; } static Matrix4 Cofactor (Matrix4 m) { var r = new Matrix4 (); for (int row = 0; row < Matrix4.Len; row++) { for (int col = 0; col < Matrix4.Len; col++) r [row, col] = Cofactor (m, row, col); } return r; } static Matrix3 Cofactor (Matrix3 m) { var r = new Matrix3 (); for (int row = 0; row < Matrix3.Len; row++) { for (int col = 0; col < Matrix3.Len; col++) r [row, col] = Cofactor (m, row, col); } return r; } static float Cofactor (Matrix4 m, int row, int col) { int sign = ((row + col) % 2 == 0) ? 1 : -1; return Det (Minor (m, row, col)) * sign; } static float Cofactor (Matrix3 m, int row, int col) { int sign = ((row + col) % 2 == 0) ? 1 : -1; return Det (Minor (m, row, col)) * sign; } static Matrix3 Minor (Matrix4 m, int row, int col) { var minor = new Matrix3 (); for (int r = 0; r < Matrix3.Len; r++) { for (int c = 0; c < Matrix3.Len; c++) { int y = (r < row) ? r : r + 1; int x = (c < col) ? c : c + 1; minor [r, c] = m [y, x]; } } return minor; } static Matrix2 Minor (Matrix3 m, int row, int col) { var minor = new Matrix2 (); for (int r = 0; r < Matrix2.Len; r++) { for (int c = 0; c < Matrix2.Len; c++) { int y = (r < row) ? r : r + 1; int x = (c < col) ? c : c + 1; minor [r, c] = m [y, x]; } } return minor; } static float Det (Matrix3 m) { float det = 0; det += m [0, 0] * (m [1, 1] * m [2, 2] - m [1, 2] * m [2, 1]); det -= m [0, 1] * (m [1, 0] * m [2, 2] - m [1, 2] * m [2, 0]); det += m [0, 2] * (m [1, 0] * m [2, 1] - m [1, 1] * m [2, 0]); return det; } static float Det (Matrix2 m) { return m [0, 0] * m [1, 1] - m [0, 1] * m [1, 0]; } public static Vec3f Mult (Matrix3 m, Vec3f v) { return new Vec3f { x = m.R0C0 * v.x + m.R0C1 * v.y + m.R0C2 * v.z, y = m.R1C0 * v.x + m.R1C1 * v.y + m.R1C2 * v.z, z = m.R2C0 * v.x + m.R2C1 * v.y + m.R2C2 * v.z }; } public static Vec4f Mult (Matrix4 m, Vec4f v) { return new Vec4f { x = m.R0C0*v.x + m.R0C1*v.y + m.R0C2*v.z + m.R0C3*v.h, y = m.R1C0*v.x + m.R1C1*v.y + m.R1C2*v.z + m.R1C3*v.h, z = m.R2C0*v.x + m.R2C1*v.y + m.R2C2*v.z + m.R2C3*v.h, h = m.R3C0*v.x + m.R3C1*v.y + m.R3C2*v.z + m.R3C3*v.h }; } } } ================================================ FILE: graphics/tiny-renderer/Renderer/WorkbookItems/Model.cs ================================================ using System; namespace Renderer { using System.Collections.Generic; using System.Linq; struct Face { public int [] Vertices; public int [] Textures; public int [] Normals; } class Model { public List Vertices { get; } = new List (); public List Faces { get; } = new List (); public List Textures { get; } = new List (); public List Normals { get; } = new List (); public static Model FromFile (string path) { var model = new Model (); string line; using (var reader = new System.IO.StreamReader (path)) { while ((line = reader.ReadLine ()) != null) model.ParseLine (line); } Console.WriteLine ($"v#{model.Vertices.Count} f#{model.Faces.Count}"); return model; } public static Model FromText (string text) { var model = new Model (); var lines = text.Split (new char [] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); foreach (var line in lines) model.ParseLine (line); Console.WriteLine ($"v#{model.Vertices.Count} f#{model.Faces.Count}"); return model; } void ParseLine (string line) { Func parseV3f = strItems => new Vec3f { x = float.Parse (strItems [1]), y = float.Parse (strItems [2]), z = float.Parse (strItems [3]) }; var items = line.Split (new char [] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (line.StartsWith ("v ", StringComparison.InvariantCulture)) { Vertices.Add (parseV3f (items)); } else if (line.StartsWith ("vt ", StringComparison.InvariantCulture)) { Textures.Add (parseV3f (items)); } else if (line.StartsWith ("vn ", StringComparison.InvariantCulture)) { Normals.Add (parseV3f (items)); } else if (line.StartsWith ("f ", StringComparison.InvariantCulture)) { var indexes = items.Skip (1) .SelectMany (s => s.Split (new char [] { '/', ' ' }, StringSplitOptions.RemoveEmptyEntries)) .Select (s => int.Parse (s) - 1) // in wavefront obj all indices start at 1, not zero .ToArray (); Faces.Add (new Face { Vertices = indexes.Where ((v, index) => index % 3 == 0).ToArray (), Textures = indexes.Where ((v, index) => index % 3 == 1).ToArray (), Normals = indexes.Where ((v, index) => index % 3 == 2).ToArray () }); } } public Vec3f Normal (Face face, int nthvert) { int idx = face.Normals [nthvert]; return Normals [idx]; } public Vec3f Vertex (Face face, int nthvert) { int idx = face.Vertices [nthvert]; return Vertices [idx]; } public Vec3f GetUV (Face face, int nthvert) { int idx = face.Textures [nthvert]; return Textures [idx]; } } } ================================================ FILE: graphics/tiny-renderer/Renderer/WorkbookItems/Shaders.cs ================================================ using System; using static Renderer.Geometry; using static Renderer.MatrixHelpers; using static Renderer.ShaderUtils; namespace Renderer { // lesson6 interface IShader { Vec4f Vertex (Face face, int nthvert); bool Fragment (Vec3f fragment, Vec3f bar, out Color color); }; // lesson6 class GouraudShader : IShader { readonly Model model; readonly Vec3f lightDir; // written by vertex shader, read by fragment shader protected Vec3f varyingIntensity = new Vec3f (); readonly Matrix4 transformation; public GouraudShader (Model model, Matrix4 viewPort, Matrix4 projection, Matrix4 modelView, Vec3f lightDir) { this.model = model; transformation = viewPort * projection * modelView; this.lightDir = lightDir.Normalize (); } public virtual Vec4f Vertex (Face face, int nthvert) { var n = model.Normal (face, nthvert).Normalize (); varyingIntensity [nthvert] = Math.Max (0, Dot (n, lightDir)); // get diffuse lighting intensity return TransformFace (model, face, nthvert, transformation); } public virtual bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { var intensity = Dot (varyingIntensity, bar); // interpolate intensity for the current pixel color = Color.White * intensity; // well duh return false; } } class GouraudShader6 : GouraudShader { public GouraudShader6 (Model model, Matrix4 viewPort, Matrix4 projection, Matrix4 modelView, Vec3f lightDir) : base (model, viewPort, projection, modelView, lightDir) { } public override bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { var intensity = Dot (varyingIntensity, bar); if (intensity > 0.85f) intensity = 1; else if (intensity > 0.60f) intensity = 0.80f; else if (intensity > 0.45f) intensity = 0.60f; else if (intensity > 0.30f) intensity = 0.45f; else if (intensity > 0.15f) intensity = 0.30f; else intensity = 0; color = new Color (255, 155, 0) * intensity; return false; } } class TextureShader : IShader { readonly Model model; readonly Vec3f lightDir; readonly Matrix4 transformation; readonly Image texture; // written by vertex shader, read by fragment shader Vec3f varyingIntensity = new Vec3f (); Vec3f varyingU = new Vec3f (); Vec3f varyingV = new Vec3f (); public TextureShader (Model model, Matrix4 viewPort, Matrix4 projection, Matrix4 modelView, Vec3f lightDir, Image texture) { this.model = model; transformation = viewPort * projection * modelView; this.lightDir = lightDir.Normalize (); this.texture = texture; } public Vec4f Vertex (Face face, int nthvert) { UpdateVarayingUV (model, face, nthvert, ref varyingU, ref varyingV); var n = model.Normal (face, nthvert).Normalize (); varyingIntensity [nthvert] = Math.Max (0, Dot (n, lightDir)); // get diffuse lighting intensity return TransformFace (model, face, nthvert, transformation); } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { // interpolate intensity for the current pixel var intensity = Dot (varyingIntensity, bar); // interpolate uv for the current pixel var uvf = CalcUV (varyingU, varyingV, bar); color = GetColor (texture, uvf) * intensity; return false; } } class NormalMapShader : IShader { Vec3f varyingU = new Vec3f (); Vec3f varyingV = new Vec3f (); readonly Model model; readonly Vec3f lightDir; readonly Matrix4 uniformM; readonly Matrix4 uniformMIT; readonly Matrix4 transformation; readonly Image texture; readonly Image normalMap; public NormalMapShader (Model model, Matrix4 viewport, Matrix4 projection, Matrix4 modelView, Vec3f lightDir, Image texture, Image normalMap) { this.model = model; this.lightDir = lightDir.Normalize (); this.texture = texture; this.normalMap = normalMap; uniformM = projection * modelView; uniformMIT = TransposeInverse (uniformM); transformation = viewport * uniformM; } public Vec4f Vertex (Face face, int nthvert) { UpdateVarayingUV (model, face, nthvert, ref varyingU, ref varyingV); return TransformFace (model, face, nthvert, transformation); } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { var uv = CalcUV (varyingU, varyingV, bar); var n = Transform (uniformMIT, Normal (normalMap, uv)).Normalize (); var l = Transform (uniformM, lightDir).Normalize (); var intensity = Math.Max (0f, Dot (n, l)); color = GetColor (texture, uv) * intensity; return false; } } class SpecularShader : IShader { Vec3f varyingU = new Vec3f (); Vec3f varyingV = new Vec3f (); readonly Model model; readonly Vec3f lightDir; readonly Matrix4 uniformM; readonly Matrix4 uniformMIT; readonly Matrix4 transformation; readonly Image texture; readonly Image normalMap; readonly Image specularMap; public SpecularShader (Model model, Matrix4 viewport, Matrix4 projection, Matrix4 modelView, Vec3f lightDir, Image texture, Image normalMap, Image specularMap) { this.model = model; this.lightDir = lightDir.Normalize (); this.texture = texture; this.normalMap = normalMap; this.specularMap = specularMap; uniformM = projection * modelView; uniformMIT = TransposeInverse (uniformM); transformation = viewport * uniformM; } public Vec4f Vertex (Face face, int nthvert) { UpdateVarayingUV (model, face, nthvert, ref varyingU, ref varyingV); return TransformFace (model, face, nthvert, transformation); } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { var uv = CalcUV (varyingU, varyingV, bar); var n = Transform (uniformMIT, Normal (normalMap, uv)).Normalize (); var l = Transform (uniformM, lightDir).Normalize (); var r = (n * (2 * Dot (n, l)) - l).Normalize (); var diff = Math.Max (0f, Dot (n, l)); var specular = Math.Pow (Math.Max (0f, r.z), Specular (specularMap, uv) + 15); color = GetColor (texture, uv); int v = 0; for (int i = 0; i < 4; i++) v = (v << 8) | (byte)Math.Min (255, (int)(5 + color [i] * (diff + 1.3f * specular))); color = new Color (v, color.format); return false; } } class TangentShader : IShader { // triangle uv coordinates, written by the vertex shader, read by the fragment shader Vec3f varyingU = new Vec3f (); Vec3f varyingV = new Vec3f (); // normal per vertex to be interpolated by FS Matrix3 varyingNrm = new Matrix3 (); readonly Model model; readonly Vec3f lightDir; readonly Matrix4 uniformM; readonly Matrix4 uniformMIT; // do not need for starting poing readonly Matrix4 transformation; readonly Vec3f[] ndcTri = new Vec3f[3]; // triangle in normalized device coordinates readonly Image texture; // do not need for starting poing readonly Image normalMap; // use this commit for 6bis lesson: // https://github.com/xamarin/private-samples/commit/ddad38f7787d5e9c065afc91547730ad38e51fd1#diff-8603c43660c04f4d430053b29c80ed15R253 public TangentShader (Model model, Matrix4 viewport, Matrix4 projection, Matrix4 modelView, Vec3f lightDir, Image texture, Image normalMap) { this.model = model; this.lightDir = lightDir.Normalize (); this.texture = texture; // do not need for starting poing this.normalMap = normalMap; // this.specularMap = specularMap; uniformM = projection * modelView; uniformMIT = TransposeInverse (uniformM); transformation = viewport * uniformM; } public Vec4f Vertex (Face face, int nthvert) { UpdateVarayingUV (model, face, nthvert, ref varyingU, ref varyingV); var normal = Project3D (Mult (uniformMIT, Embed4D (model.Normal (face, nthvert)))); varyingNrm.SetColumn (nthvert, normal); var glVertex = TransformFace (model, face, nthvert, transformation); ndcTri[nthvert] = Project3D (glVertex / glVertex.h); return glVertex; } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { var bn = Mult(varyingNrm, bar).Normalize (); var uv = CalcUV (varyingU, varyingV, bar); var A = new Matrix3 (); A.SetRow (0, ndcTri [1] - ndcTri [0]); A.SetRow (1, ndcTri [2] - ndcTri [0]); A.SetRow (2, bn); var AI = Inverse (A); var i = Mult (AI, new Vec3f { x = varyingU.y - varyingU.x, y = varyingU.z - varyingU.x }); var j = Mult (AI, new Vec3f { x = varyingV.y - varyingV.x, y = varyingV.z - varyingV.x }); var B = new Matrix3 (); B.SetColumn (0, i.Normalize ()); B.SetColumn (1, j.Normalize ()); B.SetColumn (2, bn); var n = Mult (B, Normal (normalMap, uv)).Normalize (); var l = Transform (uniformM, lightDir).Normalize (); var diff = Math.Max (0f, Dot (n, l)); color = GetColor (texture, uv) * diff; return false; } } class DepthShader : IShader { const float depth = 255f; Matrix3 varyingTri; readonly Model model; readonly Matrix4 transformation; public DepthShader (Model model, Matrix4 transformation) { this.model = model; this.transformation = transformation; } public Vec4f Vertex (Face face, int nthvert) { var glVertex = TransformFace (model, face, nthvert, transformation); varyingTri.SetColumn (nthvert, Project3D (glVertex / glVertex.h)); return glVertex; } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { var p = Mult (varyingTri, bar); color = Color.White * (p.z / depth); return false; } }; class ShadowShader : IShader { Vec3f varyingU = new Vec3f (); Vec3f varyingV = new Vec3f (); Matrix3 varyingTri; readonly Model model; readonly Vec3f lightDir; readonly Matrix4 uniformM; readonly Matrix4 uniformMIT; readonly Matrix4 uniformShadow; // transform framebuffer screen coordinates to shadowbuffer screen coordinates readonly Matrix4 transformation; readonly Image texture; readonly Image normalMap; readonly Image specularMap; readonly float[] shadowbuffer; readonly int width; public ShadowShader (Model model, Matrix4 viewport, Matrix4 projection, Matrix4 modelView, Matrix4 uniformShadow, Vec3f lightDir, Image texture, Image normalMap, Image specularMap, float[] shadowbuffer, int width) { this.model = model; this.lightDir = lightDir.Normalize (); this.texture = texture; this.normalMap = normalMap; this.specularMap = specularMap; this.shadowbuffer = shadowbuffer; this.width = width; uniformM = projection * modelView; uniformMIT = TransposeInverse (uniformM); transformation = viewport * uniformM; this.uniformShadow = uniformShadow; } public Vec4f Vertex (Face face, int nthvert) { UpdateVarayingUV (model, face, nthvert, ref varyingU, ref varyingV); var glVertex = TransformFace (model, face, nthvert, transformation); varyingTri.SetColumn (nthvert, Project3D (glVertex / glVertex.h)); return glVertex; } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { var sb_p = Mult (uniformShadow, Embed4D (Mult (varyingTri, bar))); // corresponding point in the shadow buffer sb_p = sb_p / sb_p.h; int idx = (int)sb_p.x + (int)sb_p.y * width; // index in the shadowbuffer array // z-fighting: sb_p.z + 3.5f float shadow = 0.3f + 0.7f * (shadowbuffer [idx] < (sb_p.z + 3.5f) ? 1f : 0f); var uv = CalcUV (varyingU, varyingV, bar); var n = Transform (uniformMIT, Normal (normalMap, uv)).Normalize (); var l = Transform (uniformM, lightDir).Normalize (); var r = (n * (2 * Dot (n, l)) - l).Normalize (); var diff = Math.Max (0f, Dot (n, l)); var specular = Math.Pow (Math.Max (0f, r.z), Specular (specularMap, uv) + 15); color = GetColor (texture, uv); int v = 0; for (int i = 0; i < 4; i++) v = (v <<= 8) | (byte)Math.Min (255, (int)(5 + color [i] * shadow * (diff + 1.3f * specular))); color = new Color (v, color.format); return false; } } #region Lesson9 class ZShader : IShader { const float depth = 255f; readonly Model model; readonly Matrix4 transformation; public ZShader (Model model, Matrix4 viewport, Matrix4 projection, Matrix4 modelView) { this.model = model; transformation = viewport * projection * modelView; } public Vec4f Vertex (Face face, int nthvert) { return TransformFace (model, face, nthvert, transformation); } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { color = Color.White * (fragment.z / depth); return false; } } class OcclusionShader : IShader { Vec3f varyingU = new Vec3f (); Vec3f varyingV = new Vec3f (); readonly Model model; readonly Matrix4 transformation; readonly Image occlusion; readonly float [] shadowbuffer; readonly int width; public OcclusionShader (Model model, Matrix4 viewport, Matrix4 projection, Matrix4 modelView, Image occlusion, float [] shadowbuffer, int width) { this.model = model; this.occlusion = occlusion; this.shadowbuffer = shadowbuffer; this.width = width; transformation = viewport * projection * modelView; } public Vec4f Vertex (Face face, int nthvert) { UpdateVarayingUV (model, face, nthvert, ref varyingU, ref varyingV); return TransformFace (model, face, nthvert, transformation); } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { var uvf = CalcUV (varyingU, varyingV, bar); var uvi = CalcXY (occlusion, uvf); var index = (int)(fragment.x + fragment.y * width); if (Math.Abs(shadowbuffer [index] - (byte)fragment.z) <= 1e-2) occlusion [uvi.x, uvi.y] = Color.White; color = Color.White; return false; } } class AOShader : IShader { Vec3f varyingU = new Vec3f (); Vec3f varyingV = new Vec3f (); readonly Model model; readonly Matrix4 transformation; readonly Image aoImage; public AOShader (Model model, Matrix4 viewport, Matrix4 projection, Matrix4 modelView, Image aoImage) { this.model = model; this.aoImage = aoImage; transformation = viewport * projection * modelView; } public Vec4f Vertex (Face face, int nthvert) { UpdateVarayingUV (model, face, nthvert, ref varyingU, ref varyingV); return TransformFace (model, face, nthvert, transformation); } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { var uvf = CalcUV (varyingU, varyingV, bar); var uvi = CalcXY (aoImage, uvf); var t = aoImage [uvi.x, uvi.y] [0]; color = new Color (t, t, t); return false; } }; // Name it ZShader in wb (redefine class) class ZShader2 : IShader { readonly Model model; readonly Matrix4 transformation; public ZShader2 (Model model, Matrix4 viewport, Matrix4 projection, Matrix4 modelView) { this.model = model; transformation = viewport * projection * modelView; } public Vec4f Vertex (Face face, int nthvert) { return TransformFace (model, face, nthvert, transformation); } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { color = Color.Black; return false; } }; #endregion static class ShaderUtils { // lesson6 public static Vec4f TransformFace (Model model, Face face, int nthvert, Matrix4 t) { var v = model.Vertex (face, nthvert); // read the vertex from model var glVertex = Embed4D (v); return Mult (t, glVertex); // transform it to screen coordinates } // lesson6 public static void UpdateVarayingUV (Model model, Face face, int nthvert, ref Vec3f varyingU, ref Vec3f varyingV) { var vt = model.GetUV (face, nthvert); varyingU [nthvert] = vt.x; varyingV [nthvert] = vt.y; } // lesson6 public static Vec2f CalcUV (Vec3f varU, Vec3f varV, Vec3f bar) { return new Vec2f { x = Dot (varU, bar), y = Dot (varV, bar) }; } // lesson6 public static Color GetColor (Image texture, Vec2f uvf) { var uvi = CalcXY(texture, uvf); return texture [uvi.x, uvi.y]; } public static Vec3f Transform (Matrix4 t, Vec3f v) { var v4d = Mult (t, Embed4D (v)); return Project3D (v4d); } // lesson6 public static Vec3f Normal (Image normalMap, Vec2f uvf) { // RGB values as xyz. But Color stores data as BGR (zyx) var c = GetColor (normalMap, uvf); return new Vec3f { x = (c [2] / 255f) * 2 - 1, y = (c [1] / 255f) * 2 - 1, z = (c [0] / 255f) * 2 - 1 }; } // lesson6 public static float Specular (Image specularMap, Vec2f uvf) { var uvi = CalcXY (specularMap, uvf); var color = specularMap [uvi.x, uvi.y]; return color[0]; } // lesson6 public static Vec2i CalcXY (Image texture, Vec2f uvf) { return new Vec2i { x = (int)(uvf.x * texture.Width), y = (int)(uvf.y * texture.Height) }; } } } ================================================ FILE: graphics/tiny-renderer/Renderer/WorkbookItems/Utils.cs ================================================ using System; using static Renderer.Geometry; namespace Renderer { static class Utils { public static Vec3f Barycentric (Vec3f a, Vec3f b, Vec3f c, Vec2i p) { var pixel = new Vec3f { x = p.x + 0.5f, y = p.y + 0.5f }; var ab = b - a; var ac = c - a; var pa = a - pixel; var r = Cross (new Vec3f { x = ab.x, y = ac.x, z = pa.x }, new Vec3f { x = ab.y, y = ac.y, z = pa.y }); // triangle is degenerate, in this case return smth with negative coordinates if (Math.Abs (r.z) < 1) return new Vec3f { x = -1, y = 1, z = 1 }; return new Vec3f { x = 1 - r.x / r.z - r.y / r.z, y = r.x / r.z, z = r.y / r.z }; } public static void Triangle (Image image, Vec3f [] coordinates, Color color) { var t0 = coordinates [0]; var t1 = coordinates [1]; var t2 = coordinates [2]; var pMax = new Vec2i { x = (int)Math.Max (0, Math.Max (t0.x, Math.Max (t1.x, t2.x))), y = (int)Math.Max (0, Math.Max (t0.y, Math.Max (t1.y, t2.y))) }; var pMin = new Vec2i { x = (int)Math.Min (image.Width, Math.Min (t0.x, Math.Min (t1.x, t2.x))), y = (int)Math.Min (image.Height, Math.Min (t0.y, Math.Min (t1.y, t2.y))) }; Vec2i p; for (p.x = pMin.x; p.x <= pMax.x; p.x++) { for (p.y = pMin.y; p.y <= pMax.y; p.y++) { var bc = Barycentric (t0, t1, t2, p); if (bc.x < 0 || bc.y < 0 || bc.z < 0) continue; image [p.x, p.y] = color; } } } // lesson 3 public static Vec3f Barycentric (Vec2f a, Vec2f b, Vec2f c, Vec2f p) { var ab = b - a; var ac = c - a; var pa = a - p; var r = Cross (new Vec3f { x = ab.x, y = ac.x, z = pa.x }, new Vec3f { x = ab.y, y = ac.y, z = pa.y }); // triangle is degenerate, in this case return smth with negative coordinates // dont forget that r.z is integer. If it is zero then triangle ABC is degenerate if ((int)r.z == 0) return new Vec3f { x = -1, y = 1, z = 1 }; return new Vec3f { x = 1 - (r.x + r.y) / r.z, y = r.x / r.z, z = r.y / r.z }; } // lesson 3 public static void Triangle (Image image, Vec3f [] coordinates, Color color, float [] zbuffer) { Vec3f t0 = coordinates [0]; Vec3f t1 = coordinates [1]; Vec3f t2 = coordinates [2]; var pMax = new Vec2i { x = (int)Math.Max (0, Math.Max (t0.x, Math.Max (t1.x, t2.x))), y = (int)Math.Max (0, Math.Max (t0.y, Math.Max (t1.y, t2.y))) }; var pMin = new Vec2i { x = (int)Math.Min (image.Width, Math.Min (t0.x, Math.Min (t1.x, t2.x))), y = (int)Math.Min (image.Height, Math.Min (t0.y, Math.Min (t1.y, t2.y))) }; for (int x = pMin.x; x <= pMax.x; x++) { for (int y = pMin.y; y <= pMax.y; y++) { var pixelCenter = new Vec2f { x = x + 0.5f, y = y + 0.5f }; var bc = Barycentric (Project2D (t0), Project2D (t1), Project2D (t2), pixelCenter); if (bc.x < 0 || bc.y < 0 || bc.z < 0) continue; var z = t0.z * bc.x + t1.z * bc.y + t2.z * bc.z; var idx = x + y * image.Width; if (zbuffer [idx] < z) { zbuffer [idx] = z; image [x, y] = color; } } } } // lesson3 public static float [] InitZBuffer (Image image) { var zbuffer = new float [image.Width * image.Height]; for (int idx = 0; idx < zbuffer.Length; idx++) zbuffer [idx] = float.NegativeInfinity; return zbuffer; } // lesson3 public static void Triangle (Image image, Vec3f [] coordinates, Image texture, Vec2f [] uv, float intensivity, float [] zbuffer) { Vec3f t0 = coordinates [0]; Vec3f t1 = coordinates [1]; Vec3f t2 = coordinates [2]; var pMax = new Vec2i { x = (int)Math.Max (0, Math.Max (t0.x, Math.Max (t1.x, t2.x))), y = (int)Math.Max (0, Math.Max (t0.y, Math.Max (t1.y, t2.y))) }; var pMin = new Vec2i { x = (int)Math.Min (image.Width, Math.Min (t0.x, Math.Min (t1.x, t2.x))), y = (int)Math.Min (image.Height, Math.Min (t0.y, Math.Min (t1.y, t2.y))) }; for (int x = pMin.x; x <= pMax.x; x++) { for (int y = pMin.y; y <= pMax.y; y++) { var pixelCenter = new Vec2f { x = x + 0.5f, y = y + 0.5f }; var bc = Barycentric (Project2D(t0), Project2D(t1), Project2D(t2), pixelCenter); if (bc.x < 0 || bc.y < 0 || bc.z < 0) continue; var z = t0.z * bc.x + t1.z * bc.y + t2.z * bc.z; var u = (int)(uv [0].x * bc.x + uv [1].x * bc.y + uv [2].x * bc.z); var v = (int)(uv [0].y * bc.x + uv [1].y * bc.y + uv [2].y * bc.z); var idx = x + y * image.Width; if (zbuffer [idx] < z) { zbuffer [idx] = z; var color = texture [u, v]; image [x, y] = color * intensivity; } } } } public static void Box (Vec4f [] pts, out Vec2i pMin, out Vec2i pMax) { pMax = new Vec2i { x = int.MinValue, y = int.MinValue }; pMin = new Vec2i { x = int.MaxValue, y = int.MaxValue }; for (int i = 0; i < 3; i++) { pMax.x = (int)Math.Max (pMax.x, pts [i].x / pts [i].h); pMax.y = (int)Math.Max (pMax.y, pts [i].y / pts [i].h); pMin.x = (int)Math.Min (pMin.x, pts [i].x / pts [i].h); pMin.y = (int)Math.Min (pMin.y, pts [i].y / pts [i].h); } } public static void Triangle (Image image, Vec4f [] pts, IShader shader, float [] zbuffer) { Vec2i pMin, pMax; Box (pts, out pMin, out pMax); Color color; for (int x = pMin.x; x <= pMax.x; x++) { for (int y = pMin.y; y <= pMax.y; y++) { var pixelCenter = new Vec2f { x = x + 0.5f, y = y + 0.5f }; var bc = Barycentric (Project2D (pts [0] / pts [0].h), Project2D (pts [1] / pts [1].h), Project2D (pts [2] / pts [2].h), pixelCenter); var z = pts [0].z * bc.x + pts [1].z * bc.y + pts [2].z * bc.z; // z [0..255] var w = pts [0].h * bc.x + pts [1].h * bc.y + pts [2].h * bc.z; var frag_depth = z / w; var idx = x + y * image.Width; if (bc.x < 0 || bc.y < 0 || bc.z < 0 || zbuffer[idx] > frag_depth) continue; var discard = shader.Fragment (new Vec3f { x = x, y = y, z = frag_depth }, bc, out color); if (!discard) { zbuffer [idx] = frag_depth; image [x, y] = color; } } } } // lesson4 public static float DegToRad (float degAngle) { return degAngle * (float)Math.PI / 180; } // lesson4 public static Matrix4 Viewport (int x, int y, int w, int h) { var depth = 255f; var m = Matrix4.Identity (); m [0, 3] = x + w / 2f; m [1, 3] = y + h / 2f; m [2, 3] = depth / 2f; m [0, 0] = w / 2f; m [1, 1] = h / 2f; m [2, 2] = depth / 2f; return m; } // lesson4 public static Matrix4 Projection (float coeff) { var projection = Matrix4.Identity (); projection [3, 2] = coeff; return projection; } // lesson4 public static Matrix4 LookAt (Vec3f eye, Vec3f center, Vec3f up) { var z = (eye - center).Normalize (); var x = Cross (up, z).Normalize (); var y = Cross (z, x).Normalize (); var Minv = Matrix4.Identity (); Minv [0, 0] = x.x; Minv [0, 1] = x.y; Minv [0, 2] = x.z; Minv [1, 0] = y.x; Minv [1, 1] = y.y; Minv [1, 2] = y.z; Minv [2, 0] = z.x; Minv [2, 1] = z.y; Minv [2, 2] = z.z; var Tr = Matrix4.Identity (); Tr [0, 3] = -center.x; Tr [1, 3] = -center.y; Tr [2, 3] = -center.y; return Minv * Tr; } public static Vec3f RandPointOnUnitSphere () { var rnd = new Random (); var u = rnd.NextDouble (); var v = rnd.NextDouble (); var theta = 2 * Math.PI * u; var phi = Math.Acos(2 * v - 1); return new Vec3f { x = (float)(Math.Sin (phi) * Math.Cos (theta)), y = (float)(Math.Sin (phi) * Math.Sin (theta)), z = (float)Math.Cos (phi) }; } public static float MaxElevationAngle (float [] zbuffer, Vec2f p, Vec2f dir, int width, int height) { float maxangle = 0; for (float t = 0; t < 1000; t += 1) { Vec2f cur = p + dir * t; if (cur.x >= width || cur.y >= height || cur.x < 0 || cur.y < 0) return maxangle; var distance = (p - cur).Norm (); if (distance < 1) continue; float elevation = zbuffer [(int)cur.x + (int)cur.y * width] - zbuffer [(int)p.x + (int)p.y * width]; maxangle = (float)Math.Max (maxangle, Math.Atan (elevation / distance)); } return maxangle; } } } ================================================ FILE: graphics/tiny-renderer/Renderer/packages.config ================================================  ================================================ FILE: graphics/tiny-renderer/lesson1.workbook/Geometry.csx ================================================ struct Vec2f { public float x; public float y; public float this [int i] { get { if (i == 0) return x; if (i == 1) return y; throw new InvalidOperationException (); } set { if (i == 0) x = value; else if (i == 1) y = value; else throw new InvalidOperationException (); } } public Vec2f Normalize () { return this / Norm (); } public float Norm () { return (float)Math.Sqrt (x * x + y * y); } public static Vec2f operator / (Vec2f v, float num) { v.x /= num; v.y /= num; return v; } public static Vec2f operator * (Vec2f v, float num) { v.x *= num; v.y *= num; return v; } public static Vec2f operator - (Vec2f a, Vec2f b) { return new Vec2f { x = a.x - b.x, y = a.y - b.y }; } public static Vec2f operator + (Vec2f a, Vec2f b) { return new Vec2f { x = a.x + b.x, y = a.y + b.y }; } } public struct Vec3f { public float x; public float y; public float z; public float this [int i] { get { switch (i) { case 0: return x; case 1: return y; case 2: return z; default: throw new InvalidOperationException (); } } set { switch (i) { case 0: x = value; break; case 1: y = value; break; case 2: z = value; break; default: throw new InvalidOperationException (); } } } public Vec3f Normalize () { return this / Norm (); } public float Norm () { return (float)Math.Sqrt (x * x + y * y + z * z); } public static Vec3f operator - (Vec3f a, Vec3f b) { return new Vec3f { x = a.x - b.x, y = a.y - b.y, z = a.z - b.z }; } public static Vec3f operator / (Vec3f v, float num) { v.x /= num; v.y /= num; v.z /= num; return v; } public static Vec3f operator * (Vec3f v, float num) { v.x *= num; v.y *= num; v.z *= num; return v; } } struct Vec4f { public float x; public float y; public float z; public float h; public float this [int i] { get { switch (i) { case 0: return x; case 1: return y; case 2: return z; case 3: return h; default: throw new InvalidOperationException (); } } set { switch (i) { case 0: x = value; break; case 1: y = value; break; case 2: z = value; break; case 3: h = value; break; default: throw new InvalidOperationException (); } } } public Vec4f Normalize () { var len = Norm (); return this / len; } public float Norm () { return (float)Math.Sqrt (x * x + y * y + z * z + h * h); } public static Vec4f operator - (Vec4f a, Vec4f b) { return new Vec4f { x = a.x - b.x, y = a.y - b.y, z = a.z - b.z, h = a.h - b.h }; } public static Vec4f operator / (Vec4f v, float num) { v.x /= num; v.y /= num; v.z /= num; v.h /= num; return v; } } struct Vec2i { public int x; public int y; public static Vec2i operator - (Vec2i a, Vec2i b) { return new Vec2i { x = a.x - b.x, y = a.y - b.y }; } } struct Vec3i { public int x; public int y; public int z; public static Vec3i operator - (Vec3i a, Vec3i b) { return new Vec3i { x = a.x - b.x, y = a.y - b.y, z = a.z - b.z }; } } static class Geometry { public static Vec3f Cross (Vec3f l, Vec3f r) { return new Vec3f { x = l.y * r.z - l.z * r.y, y = l.z * r.x - l.x * r.z, z = l.x * r.y - l.y * r.x }; } public static float Dot (Vec3f l, Vec3f r) { return l.x * r.x + l.y * r.y + l.z * r.z; } public static Vec4f Embed4D (Vec3f v, float fill = 1) { return new Vec4f { x = v.x, y = v.y, z = v.z, h = fill }; } public static Vec2f Project2D (Vec3f v) { return new Vec2f { x = v.x, y = v.y }; } public static Vec2f Project2D (Vec4f v) { return new Vec2f { x = v.x, y = v.y }; } public static Vec3f Project3D (Vec4f v) { return new Vec3f { x = v.x, y = v.y, z = v.z }; } } ================================================ FILE: graphics/tiny-renderer/lesson1.workbook/Image.csx ================================================ using System.IO; enum Format { GRAYSCALE = 1, BGR = 3, BGRA = 4 } struct Color { // the value stored as little endian: // ARGB -> BGRA // xRGB -> BGRx public readonly int value; public readonly Format format; public byte this [int offset] { get { if (offset > 3) // int has only 4 bytes (0, 1, 2, 3) throw new ArgumentOutOfRangeException (); return (byte)(value >> 8 * (3 - offset)); } } public static Color Red = new Color (red: 255, green: 0, blue: 0, alpha: 255); public static Color Green = new Color (red: 0, green: 255, blue: 0, alpha: 255); public static Color Blue = new Color (red: 0, green: 0, blue: 255, alpha: 255); public static Color Black = new Color (red: 0, green: 0, blue: 0, alpha: 255); public static Color White = new Color (red: 255, green: 255, blue: 255, alpha: 255); public static Color Yellow = new Color (red: 225, green: 225, blue: 0, alpha: 255); public Color (byte red, byte green, byte blue, byte alpha) : this ((blue << 24) | (green << 16) | (red << 8) | alpha, Format.BGRA) { } public Color (byte red, byte green, byte blue) : this ((blue << 24) | (green << 16) | (red << 8) | 0xFF, Format.BGR) { } public Color (byte value) : this (value, Format.GRAYSCALE) { } public Color (int value, Format format) { this.value = value; this.format = format; } public static Color operator * (Color color, float intensivity) { intensivity = Math.Max (0f, Math.Min (1f, intensivity)); var ch0 = (byte)(color [0] * intensivity); var ch1 = (byte)(color [1] * intensivity); var ch2 = (byte)(color [2] * intensivity); var ch3 = color [3]; return new Color (ch0 << 24 | ch1 << 16 | ch2 << 8 | ch3, color.format); } } class Image { internal byte [] buffer; public int Width { get; } public int Height { get; } public Format Format { get; } public int BytesPerRow { get { return Width * (int)Format; } } public Image (int width, int height, Format format) { Width = width; Height = height; Format = format; buffer = new byte [height * BytesPerRow]; } public void VerticalFlip () { var bpp = (int)Format; int bytesPerLine = Width * bpp; var half = Height >> 1; for (int l = 0; l < half; l++) { var l1 = l * bytesPerLine; var l2 = (Height - 1 - l) * bytesPerLine; for (int i = 0; i < bytesPerLine; i++) { byte pixel = buffer [l1 + i]; buffer [l1 + i] = buffer [l2 + i]; buffer [l2 + i] = pixel; } } } public void Clear () { for (int i = 0; i < buffer.Length; i++) buffer [i] = 0; } public Color this [int x, int y] { get { if (x < 0 || x >= Width) throw new ArgumentException ("x"); if (y < 0 || y >= Height) throw new ArgumentException ("y"); var offset = GetOffset (x, y); var len = (int)Format; int value = 0; for (var ch = 0; ch < 4; ch++) value = (value << 8) | (ch < len ? buffer [offset++] : 0xFF); return new Color (value, Format); } set { if (x < 0 || x >= Width) return; //throw new ArgumentException ($"{nameof(x)}={x} {nameof(Width)}={Width}"); if (y < 0 || y >= Height) return; // throw new ArgumentException ($"{nameof(y)}={y} {nameof(Height)}={Height}"); var offset = GetOffset (x, y); var v = value.value; var len = (int)Format; for (int ch = 0; ch < len; ch++) // 0123 buffer [offset++] = (byte)(v >> (3 - ch) * 8); // BGRA } } int GetOffset (int x, int y) { return y * BytesPerRow + x * (int)Format; } public bool WriteToFile (string path, bool rle = true) { var bpp = (int)Format; using (var writer = new BinaryWriter (File.Create (path))) { var header = new TGAHeader { IdLength = 0, // The IDLength set to 0 indicates that there is no image identification field in the TGA file ColorMapType = 0, // a value of 0 indicates that no palette is included BitsPerPixel = (byte)(bpp * 8), Width = (short)Width, Height = (short)Height, DataTypeCode = DataTypeFor (bpp, rle), ImageDescriptor = (byte)(0x20 | (Format == Format.BGRA ? 8 : 0)) // top-left origin }; WriteTo (writer, header); if (!rle) writer.Write (buffer); else UnloadRleData (writer); } return true; } public static Image Load (string path) { using (var reader = new BinaryReader (File.OpenRead (path))) { var header = ReadHeader (reader); var height = header.Height; var width = header.Width; var bytespp = header.BitsPerPixel >> 3; var format = (Format)bytespp; if (width <= 0 || height <= 0) throw new InvalidProgramException ($"bad image size: width={width} height={height}"); if (format != Format.BGR && format != Format.BGRA && format != Format.GRAYSCALE) throw new InvalidProgramException ($"unknown format {format}"); var img = new Image (width, height, format); switch (header.DataTypeCode) { case DataType.UncompressedTrueColorImage: case DataType.UncompressedBlackAndWhiteImage: reader.Read (img.buffer, 0, img.buffer.Length); break; case DataType.RleTrueColorImage: case DataType.RleBlackAndWhiteImage: img.LoadRleData (reader); break; default: throw new InvalidProgramException ($"unsupported image format {header.DataTypeCode}"); } if ((header.ImageDescriptor & 0x20) == 0) img.VerticalFlip (); return img; } } static void WriteTo (BinaryWriter writer, TGAHeader header) { writer.Write (header.IdLength); writer.Write (header.ColorMapType); writer.Write ((byte)header.DataTypeCode); writer.Write (header.ColorMapOrigin); writer.Write (header.ColorMapLength); writer.Write (header.ColorMapDepth); writer.Write (header.OriginX); writer.Write (header.OriginY); writer.Write (header.Width); writer.Write (header.Height); writer.Write (header.BitsPerPixel); writer.Write (header.ImageDescriptor); } static TGAHeader ReadHeader (BinaryReader reader) { var header = new TGAHeader { IdLength = reader.ReadByte (), ColorMapType = reader.ReadByte (), DataTypeCode = (DataType)reader.ReadByte (), ColorMapOrigin = reader.ReadInt16 (), ColorMapLength = reader.ReadInt16 (), ColorMapDepth = reader.ReadByte (), OriginX = reader.ReadInt16 (), OriginY = reader.ReadInt16 (), Width = reader.ReadInt16 (), Height = reader.ReadInt16 (), BitsPerPixel = reader.ReadByte (), ImageDescriptor = reader.ReadByte () }; return header; } bool UnloadRleData (BinaryWriter writer) { const int max_chunk_length = 128; int npixels = Width * Height; int curpix = 0; var bpp = (int)Format; while (curpix < npixels) { int chunkstart = curpix * bpp; int curbyte = curpix * bpp; int run_length = 1; bool literal = true; while (curpix + run_length < npixels && run_length < max_chunk_length && curpix + run_length < curpix + Width) { bool succ_eq = true; for (int t = 0; succ_eq && t < bpp; t++) succ_eq = (buffer [curbyte + t] == buffer [curbyte + t + bpp]); curbyte += bpp; if (1 == run_length) literal = !succ_eq; if (literal && succ_eq) { run_length--; break; } if (!literal && !succ_eq) break; run_length++; } curpix += run_length; writer.Write ((byte)(literal ? run_length - 1 : 128 + (run_length - 1))); writer.Write (buffer, chunkstart, literal ? run_length * bpp : bpp); } return true; } void LoadRleData (BinaryReader reader) { var pixelcount = Width * Height; var currentpixel = 0; var currentbyte = 0; var bytespp = (int)Format; var color = new byte [4]; do { var chunkheader = reader.ReadByte (); if (chunkheader < 128) { chunkheader++; for (int i = 0; i < chunkheader; i++) { for (int t = 0; t < bytespp; t++) buffer [currentbyte++] = reader.ReadByte (); currentpixel++; if (currentpixel > pixelcount) throw new InvalidProgramException ("Too many pixels read"); } } else { chunkheader -= 127; reader.Read (color, 0, bytespp); for (int i = 0; i < chunkheader; i++) { for (int t = 0; t < bytespp; t++) buffer [currentbyte++] = color [t]; currentpixel++; if (currentpixel > pixelcount) throw new InvalidProgramException ("Too many pixels read"); } } } while (currentpixel < pixelcount); } static DataType DataTypeFor (int bpp, bool rle) { var format = (Format)bpp; if (format == Format.GRAYSCALE) return rle ? DataType.RleBlackAndWhiteImage : DataType.UncompressedBlackAndWhiteImage; return rle ? DataType.RleTrueColorImage : DataType.UncompressedTrueColorImage; } } struct TGAHeader { public byte IdLength; public byte ColorMapType; public DataType DataTypeCode; // field #4. Color map specification public short ColorMapOrigin; // index of first color map entry that is included in the file public short ColorMapLength; // number of entries of the color map that are included in the file public byte ColorMapDepth; // number of bits per pixel // field #5. Image specification public short OriginX; // absolute coordinate of lower-left corner for displays where origin is at the lower left public short OriginY; // as for X-origin public short Width; // width in pixels public short Height; // height in pixels public byte BitsPerPixel; // pixel depth public byte ImageDescriptor; // bits 3-0 give the alpha channel depth, bits 5-4 give direction } public enum DataType : byte { NoImageData = 0, // no image data is present UncompressedColorMappedImage = 1, UncompressedTrueColorImage = 2, UncompressedBlackAndWhiteImage = 3, RleColorMappedImage = 9, // run-length encoded color-mapped image RleTrueColorImage = 10, // run-length encoded true-color image RleBlackAndWhiteImage = 11 // run-length encoded black-and-white (grayscale) image } ================================================ FILE: graphics/tiny-renderer/lesson1.workbook/ImageResultHandler.csx ================================================ using XIR = Xamarin.Interactive.Representations; InteractiveAgent.RepresentationManager.AddProvider (img => { XIR.ImageFormat format; switch (img.Format) { case Format.BGRA: format = XIR.ImageFormat.Bgra32; break; case Format.BGR: format = XIR.ImageFormat.Bgr24; break; default: return null; } return new XIR.Image (format, img.buffer, img.Width, img.Height); }); ================================================ FILE: graphics/tiny-renderer/lesson1.workbook/LICENSE.txt ================================================ Tiny Renderer, https://github.com/ssloy/tinyrenderer Copyright Dmitry V. Sokolov This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. ================================================ FILE: graphics/tiny-renderer/lesson1.workbook/Matrix.csx ================================================ using System; public struct Matrix4 { public const int Len = 4; public float R0C0, R0C1, R0C2, R0C3; public float R1C0, R1C1, R1C2, R1C3; public float R2C0, R2C1, R2C2, R2C3; public float R3C0, R3C1, R3C2, R3C3; public float this [int row, int column] { get { switch (row) { case 0: switch (column) { case 0: return R0C0; case 1: return R0C1; case 2: return R0C2; case 3: return R0C3; } break; case 1: switch (column) { case 0: return R1C0; case 1: return R1C1; case 2: return R1C2; case 3: return R1C3; } break; case 2: switch (column) { case 0: return R2C0; case 1: return R2C1; case 2: return R2C2; case 3: return R2C3; } break; case 3: switch (column) { case 0: return R3C0; case 1: return R3C1; case 2: return R3C2; case 3: return R3C3; } break; } throw new IndexOutOfRangeException (); } set { switch (row) { case 0: switch (column) { case 0: R0C0 = value; return; case 1: R0C1 = value; return; case 2: R0C2 = value; return; case 3: R0C3 = value; return; } break; case 1: switch (column) { case 0: R1C0 = value; return; case 1: R1C1 = value; return; case 2: R1C2 = value; return; case 3: R1C3 = value; return; } break; case 2: switch (column) { case 0: R2C0 = value; return; case 1: R2C1 = value; return; case 2: R2C2 = value; return; case 3: R2C3 = value; return; } break; case 3: switch (column) { case 0: R3C0 = value; return; case 1: R3C1 = value; return; case 2: R3C2 = value; return; case 3: R3C3 = value; return; } break; } throw new IndexOutOfRangeException (); } } public Matrix4 Transpose () { return new Matrix4 { R0C0 = R0C0, R0C1 = R1C0, R0C2 = R2C0, R0C3 = R3C0, R1C0 = R0C1, R1C1 = R1C1, R1C2 = R2C1, R1C3 = R3C1, R2C0 = R0C2, R2C1 = R1C2, R2C2 = R2C2, R2C3 = R3C2, R3C0 = R0C3, R3C1 = R1C3, R3C2 = R2C3, R3C3 = R3C3 }; } public static Matrix4 Identity () { return new Matrix4 { R0C0 = 1, R1C1 = 1, R2C2 = 1, R3C3 = 1 }; } public static Matrix4 Zoom (float scale) { return new Matrix4 { R0C0 = scale, R1C1 = scale, R2C2 = scale, R3C3 = scale }; } public static Matrix4 RotationZ (float angle) { var cosangle = (float)Math.Cos (angle); var sinangle = (float)Math.Sin (angle); var R = Identity (); R [0, 0] = R [1, 1] = cosangle; R [0, 1] = -sinangle; R [1, 0] = sinangle; return R; } public static Matrix4 operator * (Matrix4 l, Matrix4 r) { var result = new Matrix4 (); for (int i = 0; i < Len; i++) { for (int j = 0; j < Len; j++) { result [i, j] = 0; for (int k = 0; k < Len; k++) { result [i, j] += l [i, k] * r [k, j]; } } } return result; } public override string ToString () { var sb = new System.Text.StringBuilder (); for (int r = 0; r < Len; r++) { for (int c = 0; c < Len; c++) sb.Append (this[r, c]).Append (" "); sb.AppendLine (); } return sb.ToString (); } } public struct Matrix3 { public const int Len = 3; public float R0C0, R0C1, R0C2; public float R1C0, R1C1, R1C2; public float R2C0, R2C1, R2C2; public float this [int row, int column] { get { switch (row) { case 0: switch (column) { case 0: return R0C0; case 1: return R0C1; case 2: return R0C2; } break; case 1: switch (column) { case 0: return R1C0; case 1: return R1C1; case 2: return R1C2; } break; case 2: switch (column) { case 0: return R2C0; case 1: return R2C1; case 2: return R2C2; } break; } throw new IndexOutOfRangeException (); } set { switch (row) { case 0: switch (column) { case 0: R0C0 = value; return; case 1: R0C1 = value; return; case 2: R0C2 = value; return; } break; case 1: switch (column) { case 0: R1C0 = value; return; case 1: R1C1 = value; return; case 2: R1C2 = value; return; } break; case 2: switch (column) { case 0: R2C0 = value; return; case 1: R2C1 = value; return; case 2: R2C2 = value; return; } break; } throw new IndexOutOfRangeException (); } } public Matrix3 Transpose () { return new Matrix3 { R0C0 = R0C0, R0C1 = R1C0, R0C2 = R2C0, R1C0 = R0C1, R1C1 = R1C1, R1C2 = R2C1, R2C0 = R0C2, R2C1 = R1C2, R2C2 = R2C2 }; } public void SetColumn (int col, Vec3f v) { this [0, col] = v.x; this [1, col] = v.y; this [2, col] = v.z; } public void SetRow (int row, Vec3f v) { this [row, 0] = v.x; this [row, 1] = v.y; this [row, 2] = v.z; } public override string ToString () { var sb = new System.Text.StringBuilder (); for (int r = 0; r < Len; r++) { for (int c = 0; c < Len; c++) sb.Append (this [r, c]).Append (" "); sb.AppendLine (); } return sb.ToString (); } } public struct Matrix2 { public const int Len = 2; public float R0C0, R0C1; public float R1C0, R1C1; public float this [int row, int column] { get { switch (row) { case 0: switch (column) { case 0: return R0C0; case 1: return R0C1; } break; case 1: switch (column) { case 0: return R1C0; case 1: return R1C1; } break; } throw new IndexOutOfRangeException (); } set { switch (row) { case 0: switch (column) { case 0: R0C0 = value; return; case 1: R0C1 = value; return; } break; case 1: switch (column) { case 0: R1C0 = value; return; case 1: R1C1 = value; return; } break; } throw new IndexOutOfRangeException (); } } } // we don't want to declare them in Matrix because we don't need them in lesson which introduces Matrix class static class MatrixHelpers { // For Matrix4 // how to calc inverse Matrix https://en.wikipedia.org/w/index.php?title=Invertible_matrix§ion=4#In_relation_to_its_adjugate public static Matrix4 TransposeInverse (Matrix4 m) { // returns Transpose(Inverse(m)) // where Inverse(m) = Transpose(cofactor) / det(m) // Transpose(Inverse(m)) = Transpose(Transpose(cofactor) / det(m)) = cofactor / det(m) var cofactor = Cofactor (m); float det = 0; for (int i = 0; i < Matrix4.Len; i++) det += m [0, i] * cofactor [0, i]; for (int r = 0; r < Matrix4.Len; r++) { for (int c = 0; c < Matrix4.Len; c++) cofactor [r, c] /= det; } return cofactor; } public static Matrix4 Inverse (Matrix4 m) { // where Inverse(m) = Transpose(Cofactor(m)) / det(m) var cofactor = Cofactor (m); int len = Matrix4.Len; float det = 0; for (int i = 0; i < len; i++) det += m [0, i] * cofactor [0, i]; cofactor = cofactor.Transpose (); for (int r = 0; r < len; r++) { for (int c = 0; c < len; c++) cofactor [r, c] /= det; } return cofactor; } public static Matrix3 Inverse (Matrix3 m) { // where Inverse(m) = Transpose(Cofactor(m)) / det(m) var cofactor = Cofactor (m); int len = Matrix3.Len; float det = 0; for (int i = 0; i < len; i++) det += m [0, i] * cofactor [0, i]; cofactor = cofactor.Transpose (); for (int r = 0; r < len; r++) { for (int c = 0; c < len; c++) cofactor [r, c] /= det; } return cofactor; } static Matrix4 Cofactor (Matrix4 m) { var r = new Matrix4 (); for (int row = 0; row < Matrix4.Len; row++) { for (int col = 0; col < Matrix4.Len; col++) r [row, col] = Cofactor (m, row, col); } return r; } static Matrix3 Cofactor (Matrix3 m) { var r = new Matrix3 (); for (int row = 0; row < Matrix3.Len; row++) { for (int col = 0; col < Matrix3.Len; col++) r [row, col] = Cofactor (m, row, col); } return r; } static float Cofactor (Matrix4 m, int row, int col) { int sign = ((row + col) % 2 == 0) ? 1 : -1; return Det (Minor (m, row, col)) * sign; } static float Cofactor (Matrix3 m, int row, int col) { int sign = ((row + col) % 2 == 0) ? 1 : -1; return Det (Minor (m, row, col)) * sign; } static Matrix3 Minor (Matrix4 m, int row, int col) { var minor = new Matrix3 (); for (int r = 0; r < Matrix3.Len; r++) { for (int c = 0; c < Matrix3.Len; c++) { int y = (r < row) ? r : r + 1; int x = (c < col) ? c : c + 1; minor [r, c] = m [y, x]; } } return minor; } static Matrix2 Minor (Matrix3 m, int row, int col) { var minor = new Matrix2 (); for (int r = 0; r < Matrix2.Len; r++) { for (int c = 0; c < Matrix2.Len; c++) { int y = (r < row) ? r : r + 1; int x = (c < col) ? c : c + 1; minor [r, c] = m [y, x]; } } return minor; } static float Det (Matrix3 m) { float det = 0; det += m [0, 0] * (m [1, 1] * m [2, 2] - m [1, 2] * m [2, 1]); det -= m [0, 1] * (m [1, 0] * m [2, 2] - m [1, 2] * m [2, 0]); det += m [0, 2] * (m [1, 0] * m [2, 1] - m [1, 1] * m [2, 0]); return det; } static float Det (Matrix2 m) { return m [0, 0] * m [1, 1] - m [0, 1] * m [1, 0]; } public static Vec3f Mult (Matrix3 m, Vec3f v) { return new Vec3f { x = m.R0C0 * v.x + m.R0C1 * v.y + m.R0C2 * v.z, y = m.R1C0 * v.x + m.R1C1 * v.y + m.R1C2 * v.z, z = m.R2C0 * v.x + m.R2C1 * v.y + m.R2C2 * v.z }; } public static Vec4f Mult (Matrix4 m, Vec4f v) { return new Vec4f { x = m.R0C0*v.x + m.R0C1*v.y + m.R0C2*v.z + m.R0C3*v.h, y = m.R1C0*v.x + m.R1C1*v.y + m.R1C2*v.z + m.R1C3*v.h, z = m.R2C0*v.x + m.R2C1*v.y + m.R2C2*v.z + m.R2C3*v.h, h = m.R3C0*v.x + m.R3C1*v.y + m.R3C2*v.z + m.R3C3*v.h }; } } ================================================ FILE: graphics/tiny-renderer/lesson1.workbook/Model.csx ================================================ using System.Collections.Generic; using System.Globalization; using System.Linq; struct Face { public int [] Vertices; public int [] Textures; public int [] Normals; } class Model { public List Vertices { get; } = new List (); public List Faces { get; } = new List (); public List Textures { get; } = new List (); public List Normals { get; } = new List (); public static Model FromFile (string path) { var model = new Model (); string line; using (var reader = new System.IO.StreamReader (path)) { while ((line = reader.ReadLine ()) != null) model.ParseLine (line); } Console.WriteLine ($"v#{model.Vertices.Count} f#{model.Faces.Count}"); return model; } public static Model FromText (string text) { var model = new Model (); var lines = text.Split (new char [] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); foreach (var line in lines) model.ParseLine (line); Console.WriteLine ($"v#{model.Vertices.Count} f#{model.Faces.Count}"); return model; } void ParseLine (string line) { Func parseV3f = strItems => new Vec3f { x = float.Parse (strItems [1], CultureInfo.InvariantCulture.NumberFormat), y = float.Parse (strItems [2], CultureInfo.InvariantCulture.NumberFormat), z = float.Parse (strItems [3], CultureInfo.InvariantCulture.NumberFormat) }; var items = line.Split (new char [] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (line.StartsWith ("v ", StringComparison.InvariantCulture)) { Vertices.Add (parseV3f (items)); } else if (line.StartsWith ("vt ", StringComparison.InvariantCulture)) { Textures.Add (parseV3f (items)); } else if (line.StartsWith ("vn ", StringComparison.InvariantCulture)) { Normals.Add (parseV3f (items)); } else if (line.StartsWith ("f ", StringComparison.InvariantCulture)) { var indexes = items.Skip (1) .SelectMany (s => s.Split (new char [] { '/', ' ' }, StringSplitOptions.RemoveEmptyEntries)) .Select (s => int.Parse (s) - 1) // in wavefront obj all indices start at 1, not zero .ToArray (); Faces.Add (new Face { Vertices = indexes.Where ((v, index) => index % 3 == 0).ToArray (), Textures = indexes.Where ((v, index) => index % 3 == 1).ToArray (), Normals = indexes.Where ((v, index) => index % 3 == 2).ToArray () }); } } public Vec3f Normal (Face face, int nthvert) { int idx = face.Normals [nthvert]; return Normals [idx]; } public Vec3f Vertex (Face face, int nthvert) { int idx = face.Vertices [nthvert]; return Vertices [idx]; } public Vec3f GetUV (Face face, int nthvert) { int idx = face.Textures [nthvert]; return Textures [idx]; } } ================================================ FILE: graphics/tiny-renderer/lesson1.workbook/WpfImageResultHandler.csx ================================================ using System; using System.IO; using System.Windows.Media; using System.Windows.Media.Imaging; using XIR = Xamarin.Interactive.Representations; static PixelFormat ConvertFormat (Format format) { switch (format) { case Format.BGRA: return PixelFormats.Bgra32; case Format.GRAYSCALE: return PixelFormats.Gray8; case Format.BGR: default: return PixelFormats.Bgr24; } } InteractiveAgent.RepresentationManager.AddProvider (img => { var source = BitmapSource.Create (img.Width, img.Height, 96, 96, ConvertFormat (img.Format), null, img.buffer, img.BytesPerRow); var encoder = new PngBitmapEncoder (); var outputFrame = BitmapFrame.Create (source); encoder.Frames.Add (outputFrame); using (var memory = new MemoryStream ()) { encoder.Save (memory); return XIR.Image.FromPng (memory.GetBuffer (), img.Width, img.Height); } }); ================================================ FILE: graphics/tiny-renderer/lesson1.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" ``` # **Lesson 1: Bresenham’s Line Drawing Algorithm** > ℹ️ This workbook is a port of an [excellent C++ series](https://github.com/ssloy/tinyrenderer/wiki) written by Dmitry Sokolov. We appreciate that original work is available under a license that allowed us to turn it into a Workbook. # First attempt The goal of the first lesson is to render the wire mesh. To do this, we should learn how to draw line segments. We can simply read what Bresenham’s line algorithm is, but let’s write code ourselves. How does the simplest code that draws a line segment between `(x0, y0)` and `(x1, y1)` points look like? Apparently, something like this: ```csharp Image Line (Image image, int x0, int y0, int x1, int y1, Color color) { for (double t = 0; t < 1; t += 0.01) { int x = (int) (x0 * (1-t) + x1 * t); int y = (int) (y0 * (1-t) + y1 * t); image [x, y] = color; } return image; } Line (new Image (100, 100, Format.BGR), x0: 13, y0: 20, x1: 80, y1: 40, color: Color.White); ``` # Second attempt The problem with this code (in addition to efficiency) is the choice of the constant, which I took equal to .01. If we take it equal to .1, our line segment will look like this: ```csharp Image Line (Image image, int x0, int y0, int x1, int y1, Color color) { for (int x = x0; x <= x1; x++) { double t = (x-x0)/(double)(x1-x0); int y = (int)(y0*(1-t) + y1*t); image [x, y] = color; } return image; } Line (new Image (100, 100, Format.BGR), x0: 13, y0: 20, x1: 80, y1: 40, color: Color.White); ``` Caution! The first source of errors in such code of my students is the integer division, like: `(x-x0)/(x1-x0)`. Then, if we try to draw the following lines with this code: ```csharp var image = new Image (100, 100, Format.BGR); Line(image, x0: 13, y0: 20, x1: 80, y1: 40, color: Color.White); Line(image, x0: 20, y0: 13, x1: 40, y1: 80, color: Color.Red); Line(image, x0: 80, y0: 40, x1: 13, y1: 20, color: Color.Red); ``` It turns out that one line is good, the second one is with holes, and there’s no third line at all. Note that the first and the third lines (in the code) draw the same line in different colors, and in different directions (with the source and target points flipped). We have already seen the white one, it is drawn well. I was hoping to change the color of the white line to red, but could not do it. It’s a test for symmetry: the result of drawing a line segment should not depend on the order of points: the `(a,b)` line segment should be exactly the same as the `(b,a)` line segment. # Third attempt We fix the missing red line by swapping the points so `x0` is always lower than `x1`. There are holes in one of the line segments due to the fact that its height is greater than the width. My students often suggest the following fix: `if (dx > dy) { for (int x) } else { for (int y) }` Holy cow! ```csharp static void Swap(ref T x, ref T y) { T t = y; y = x; x = t; } static void Swap(T[] arr, int x, int y) { T t = arr[y]; arr[y] = arr[x]; arr[x] = t; } Image Line (Image image, int x0, int y0, int x1, int y1, Color color) { bool steep = false; // if the line is steep, we transpose the image if (Math.Abs (x0-x1) < Math.Abs (y0-y1)) { Swap (ref x0, ref y0); Swap (ref x1, ref y1); steep = true; } if (x0 > x1) { // make it left to right Swap (ref x0, ref x1); Swap (ref y0, ref y1); } // (x0, y0) == (x1, y1) if(x0 == x1) { image [x0, y0] = color; } else { for (int x = x0; x <= x1; x++) { double t = (x-x0) / (double)(x1-x0); int y = (int)Math.Round(y0*(1-t) + y1*t); if (steep) image [y, x] = color; else image [x, y] = color; } } return image; } Line(image, x0: 13, y0: 20, x1: 80, y1: 40, color: Color.White); Line(image, x0: 20, y0: 13, x1: 40, y1: 80, color: Color.Red); Line(image, x0: 80, y0: 40, x1: 13, y1: 20, color: Color.Red); ``` # Wireframe rendering So now we are ready to create a wire render. You can find the snapshot of the code and the test model here. I used the [wavefront obj](http://en.wikipedia.org/wiki/Wavefront_.obj_file) format of the file to store model. All we need for the render is read from the file the array of vertices of the following type: `v 0.608654 -0.568839 -0.416318` are `x,y,z` coordinates, one vertex per file line and faces `f 1193/1240/1193 1180/1227/1180 1179/1226/1179` ```csharp int width = 800, height = 800; var headModel = Model.FromFile ("obj/african_head.obj"); var image = new Image(width, height, Format.BGR); foreach(var face in headModel.Faces) { for(int j=0; j<3; j++) { var v0 = headModel.Vertices[face.Vertices [j]]; var v1 = headModel.Vertices[face.Vertices [(j+1) % 3]]; // scale x from [-1..1] to [0..w] // scale y from [-1..1] to [0..h] int x0 = (int)((v0.x + 1) * width / 2); int y0 = (int)((v0.y + 1) * height / 2); int x1 = (int)((v1.x + 1) * width / 2); int y1 = (int)((v1.y + 1) * height / 2); Line(image, x0, y0, x1, y1, Color.White); } } image.VerticalFlip (); image ``` ================================================ FILE: graphics/tiny-renderer/lesson1.workbook/lesson1.csx ================================================ int width = 800; int height = 800; var headModel = Model.FromFile ("obj/african_head.obj"); static void Swap(ref T x, ref T y) { T t = y; y = x; x = t; } static void Swap(T[] arr, int x, int y) { T t = arr[y]; arr[y] = arr[x]; arr[x] = t; } Image Line (Image image, int x0, int y0, int x1, int y1, Color color) { bool steep = false; // if the line is steep, we transpose the image if (Math.Abs (x0-x1) < Math.Abs (y0-y1)) { Swap (ref x0, ref y0); Swap (ref x1, ref y1); steep = true; } if (x0 > x1) { // make it left to right Swap (ref x0, ref x1); Swap (ref y0, ref y1); } // (x0, y0) == (x1, y1) if(x0 == x1) { image [x0, y0] = color; } else { for (int x = x0; x <= x1; x++) { double t = (x-x0) / (double)(x1-x0); int y = (int)Math.Round(y0*(1-t) + y1*t); if (steep) image [y, x] = color; else image [x, y] = color; } } return image; } ================================================ FILE: graphics/tiny-renderer/lesson1.workbook/obj/african_head.obj ================================================ v -0.000581696 -0.734665 -0.623267 v 0.000283538 -1 0.286843 v -0.117277 -0.973564 0.306907 v -0.382144 -0.890788 0.221243 v -0.247144 -0.942602 0.276051 v -0.656078 -0.718512 -0.109025 v -0.609847 -0.786562 0.0198068 v -0.66248 -0.632053 -0.244271 v -0.511812 -0.845392 0.127809 v -0.609326 -0.569868 -0.41571 v -0.426949 -0.649767 -0.567143 v -0.201076 -0.720822 -0.633205 v 0.117382 -0.973645 0.306766 v 0.382454 -0.890869 0.221097 v 0.247512 -0.942667 0.275986 v 0.656371 -0.718624 -0.109224 v 0.610273 -0.786562 0.0197893 v 0.66248 -0.631463 -0.244119 v 0.511631 -0.845357 0.127832 v 0.608654 -0.568839 -0.416318 v 0.424663 -0.649937 -0.567418 v 0.198972 -0.720968 -0.633141 v 0.153371 -0.140519 0.477416 v 0.134781 -0.14723 0.48805 v 0.131261 -0.132153 0.49872 v 0.14749 -0.135105 0.489565 v 0.000686924 -0.0534984 0.505694 v 0.075062 -0.0473306 0.49955 v 0.0695841 -0.0997942 0.550277 v 0.0302569 -0.0971868 0.55389 v 0.0745124 -0.135953 0.523215 v 0.0354892 -0.12785 0.535159 v 0.0389268 -0.109557 0.550558 v 0.0734835 -0.11538 0.538029 v 0.106386 -0.125623 0.51513 v 0.107415 -0.144295 0.5047 v 0.15968 -0.130861 0.484794 v 0.156224 -0.123705 0.486735 v 0.15792 -0.107798 0.4677 v 0.163784 -0.126996 0.470144 v 0.154687 -0.134655 0.486373 v 0.160668 -0.135649 0.476189 v 0.143433 -0.119034 0.499854 v 0.131606 -0.0726738 0.476148 v -0.000260156 -0.124553 0.539058 v -0.000646004 -0.110651 0.55444 v 0.100423 -0.10574 0.537643 v 0.126128 -0.115784 0.515598 v 0.250944 -0.275583 0.380381 v 0.221602 -0.335752 0.330174 v 0.275434 -0.301318 0.24751 v 0.307699 -0.239869 0.292356 v 0.332124 -0.0415605 0.412962 v 0.319444 0.00732526 0.451091 v 0.28667 -0.025805 0.481549 v 0.297006 -0.0758717 0.454242 v 0.357953 -0.159928 -0.223225 v 0.303981 -0.144611 -0.343644 v 0.296386 -0.0547553 -0.357792 v 0.357339 -0.0633433 -0.24278 v 0.45086 0.331215 0.047962 v 0.438899 0.336167 0.131147 v 0.447405 0.226107 0.139349 v 0.455613 0.205353 0.0827643 v 0.197493 -0.411308 0.138256 v 0.204911 -0.353378 0.2082 v 0.102001 -0.419375 0.24969 v 0.0995867 -0.475697 0.20834 v 0.150133 -0.372261 0.431226 v 0.176423 -0.362054 0.392056 v 0.196019 -0.326474 0.426929 v 0.154611 -0.348549 0.463444 v 0.0892273 -0.391968 0.303592 v 0.159013 -0.363737 0.305077 v 0.455712 0.508986 -0.0641442 v 0.432146 0.648411 -0.0417475 v 0.417051 0.611568 0.0817295 v 0.44205 0.483438 0.0478626 v 0.3446 0.43288 0.398633 v 0.372358 0.383369 0.353998 v 0.388341 0.404485 0.306953 v 0.355059 0.467372 0.356967 v 0.305162 0.338815 0.458112 v 0.298579 0.319803 0.456627 v 0.313422 0.304568 0.427776 v 0.323711 0.315968 0.429291 v 0.33161 0.397557 0.430226 v 0.354427 0.359727 0.390478 v 0.304162 0.291952 0.432377 v 0.292662 0.309771 0.452991 v 0.282934 0.292496 0.4562 v 0.292025 0.281663 0.435178 v 0.397344 0.565249 0.192585 v 0.42257 0.455996 0.145494 v 0.317848 0.364866 0.448834 v 0.340595 0.337517 0.417978 v 0.243227 0.479439 0.494236 v 0.250155 0.546138 0.465934 v 0.179019 0.560251 0.511681 v 0.170173 0.4781 0.536229 v 0.162386 0.410407 0.547009 v 0.235031 0.427051 0.517018 v 0.271745 0.634415 0.42162 v 0.196896 0.657291 0.472505 v 0.186589 0.312952 0.511073 v 0.189518 0.32493 0.514165 v 0.146286 0.31277 0.509009 v 0.144959 0.300178 0.501713 v 0.143965 0.300412 0.49409 v 0.187203 0.310596 0.506407 v 0.157744 0.364614 0.528804 v 0.216697 0.382527 0.516083 v 0.194441 0.332425 0.515989 v 0.204286 0.349818 0.516732 v 0.156254 0.334062 0.519579 v 0.151565 0.320341 0.513961 v 0.0431068 0.071791 0.618005 v 0.0477954 0.0867105 0.593486 v 0.0780844 0.0816652 0.602518 v 0.0574124 0.0746147 0.621185 v 0.448253 0.130656 0.149533 v 0.431801 0.159355 0.215905 v 0.422792 0.0771637 0.237185 v 0.428691 0.0348783 0.166914 v 0.365073 -0.0526507 0.316126 v 0.326974 -0.104793 0.373068 v 0.312773 -0.172965 0.33446 v 0.368107 -0.126698 0.269222 v 0.203695 -0.131796 0.523934 v 0.180463 -0.136479 0.525396 v 0.182848 -0.14892 0.516989 v 0.204163 -0.152533 0.514914 v 0.39379 0.00616771 0.269368 v 0.40177 -0.0591341 0.209048 v 0.26083 -0.0996422 0.484274 v 0.250406 -0.0552171 0.50321 v 0.15851 -0.136292 0.498474 v 0.155032 -0.134684 0.502964 v 0.145006 -0.133819 0.514504 v 0.171033 -0.12032 0.538263 v 0.158849 -0.127938 0.534943 v 0.167969 -0.138075 0.523788 v 0.232061 -0.151474 0.497024 v 0.23074 -0.117128 0.507191 v 0.365798 0.221617 0.362743 v 0.342501 0.235507 0.392185 v 0.325951 0.202558 0.415114 v 0.359268 0.178677 0.383229 v 0.352369 0.0489033 0.417452 v 0.322262 0.0907619 0.44953 v 0.295322 0.04895 0.483251 v 0.367108 0.00328555 0.369771 v 0.138972 -0.18796 0.555521 v 0.161562 -0.177794 0.535913 v 0.154015 -0.155093 0.536392 v 0.136131 -0.156414 0.558491 v 0.220263 -0.08194 0.518603 v 0.202088 -0.0486753 0.52791 v 0.17564 -0.0814314 0.545822 v 0.193131 -0.106435 0.533575 v 0.199492 -0.169714 0.509722 v 0.190033 -0.188183 0.514668 v 0.207302 -0.213011 0.492721 v 0.222415 -0.183044 0.489617 v 0.125088 -0.132884 0.551294 v 0.144497 -0.139192 0.530254 v 0.135014 0.119128 0.544717 v 0.119534 0.149685 0.554253 v 0.096915 0.171211 0.569382 v 0.112553 0.137432 0.569616 v 0.0878476 0.217858 0.555667 v 0.0649773 0.232128 0.568628 v 0.073466 0.185119 0.584571 v 0.116359 0.191199 0.548932 v 0.111419 0.228591 0.524951 v 0.0858774 0.255408 0.530312 v 0.301408 0.0368718 -0.387812 v 0.366839 0.037626 -0.269538 v 0.272125 -0.199781 0.399533 v 0.246349 -0.195514 0.453266 v 0.223339 -0.243049 0.450553 v 0.364021 -0.197455 0.21335 v 0.411416 -0.124798 0.140589 v 0.431568 -0.0028997 0.0907502 v 0.449346 0.11075 0.0889086 v 0.0649948 0.777167 0.432594 v 0.133465 0.770619 0.418569 v 0.14341 0.869244 0.301253 v 0.0689586 0.877043 0.315395 v 0.305372 0.809321 0.22043 v 0.289307 0.723856 0.335524 v 0.355187 0.660735 0.264773 v 0.372264 0.728258 0.148528 v 0.382308 0.7766 0.0116631 v 0.0971488 0.470588 0.557912 v 0.110788 0.565185 0.534317 v 0.100113 0.277828 0.510938 v 0.10966 0.248679 0.503771 v 0.0443988 0.240822 0.58581 v 0.0522151 0.193614 0.604337 v 0.052601 0.564735 0.541859 v 0.123726 0.667896 0.498907 v 0.0597976 0.671147 0.508711 v 0.0466729 0.466215 0.561034 v 0.000423846 0.462807 0.558988 v -0.00017831 0.388326 0.563478 v 0.0352086 0.389069 0.560584 v 0.000833078 0.56384 0.544139 v 0.295773 0.426823 0.470722 v 0.301706 0.464689 0.451056 v 0.189957 0.181465 0.501181 v 0.186163 0.208931 0.491956 v 0.141574 0.222722 0.500509 v 0.146526 0.195338 0.518293 v 0.111986 0.0116865 0.562811 v 0.111343 0.0404672 0.565769 v 0.0577164 0.0420398 0.577988 v 0.0656438 -0.00796249 0.596918 v 0.147695 0.0440509 0.537258 v 0.144778 0.0631738 0.538491 v 0.0268719 -0.0140834 0.602378 v 0.0270356 -0.0372401 0.622027 v 0.0876429 -0.0456996 0.601127 v 0.183093 0.146552 0.519439 v 0.148589 0.164593 0.536819 v 0.147344 0.131095 0.542934 v 0.176733 0.112264 0.532435 v -0.000394618 -0.0441035 0.617625 v -0.000260156 -0.0187662 0.600677 v 0.165058 0.0770935 0.530856 v 0.148554 0.0982976 0.535562 v 0.116476 0.272829 0.494797 v 0.119084 0.26261 0.493569 v 0.120873 0.268971 0.480883 v 0.11761 0.27287 0.484221 v 0.224695 0.848444 0.271198 v 0.231324 0.918189 0.121063 v 0.14614 0.9439 0.150241 v 0.241894 0.945736 -0.185803 v 0.156043 0.976475 -0.183418 v 0.146906 0.980702 -0.0177607 v 0.23195 0.948285 -0.0402158 v 0.0684324 0.995189 -0.00981573 v 0.0682103 0.955014 0.162933 v 0.0891571 0.383649 0.555118 v 0.110613 0.336412 0.528863 v 0.122749 0.310759 0.512914 v 0.147081 -0.111919 0.55631 v 0.158656 -0.0994551 0.55786 v 0.0939743 0.0869969 0.616333 v 0.101206 0.119326 0.615532 v 0.0670469 0.122121 0.645885 v 0.0560853 0.0831385 0.640601 v 0.0795284 0.0820978 0.567845 v 0.0337354 0.0564741 0.595059 v 0.0854448 -0.103577 0.606979 v 0.0826211 -0.0671141 0.612931 v 0.0280704 -0.0555854 0.637736 v 0.0319698 -0.0970874 0.628212 v 0.0789964 -0.121811 0.579602 v 0.0327415 -0.116959 0.594106 v 0.0216981 0.0173339 0.585915 v -0.00123062 -0.095585 0.625704 v -0.000511542 -0.0598999 0.637227 v -0.00157555 -0.115643 0.593966 v -0.000219233 -0.0988881 0.554498 v 0.0291929 0.0853015 0.665324 v 0.0352671 0.124524 0.666125 v 0.0371846 0.159004 0.648446 v 0.0654158 0.154462 0.629171 v 0.0280178 0.19967 0.620548 v 0.0221015 0.245843 0.59797 v 0.0432997 0.281499 0.556866 v 0.0222008 0.28717 0.567459 v -0.000400465 0.125745 0.673871 v -0.00057585 0.0822265 0.675105 v -0.000347849 0.160916 0.656029 v 0.367195 0.315074 0.363767 v 0.346658 0.302744 0.393991 v 0.344389 0.266656 0.384439 v 0.371726 0.266504 0.352507 v 0.40246 0.429197 0.234116 v 0.422126 0.335763 0.207276 v 0.393316 0.264083 0.313887 v 0.387102 0.325737 0.325369 v 0.3274 0.295928 0.408636 v 0.316392 0.29076 0.418709 v 0.3085 0.274624 0.423199 v 0.323636 0.272379 0.406602 v 0.429381 0.244458 0.204002 v 0.407084 0.332408 0.277313 v 0.410597 0.257869 0.266264 v -0.0012657 -0.456867 0.290093 v -0.00137093 -0.520579 0.266159 v 0.154137 -0.304206 0.500479 v 0.193482 -0.282873 0.473493 v 0.186367 -0.242201 0.509588 v 0.148993 -0.26399 0.525367 v 0.110332 -0.274916 0.545857 v 0.099347 -0.233134 0.560204 v 0.0558865 -0.227615 0.569605 v 0.0659185 -0.270006 0.563817 v 0.154687 -0.142577 0.51838 v 0.159498 -0.143009 0.513072 v 0.154646 -0.138239 0.502496 v 0.149045 -0.137596 0.50639 v 0.15958 -0.138174 0.517463 v 0.161574 -0.141559 0.511657 v 0.0940387 -0.129288 0.582226 v 0.109215 -0.12609 0.531844 v 0.0782715 -0.117578 0.557129 v 0.264817 0.0151299 0.501573 v 0.280122 0.127096 0.47057 v 0.262508 0.0886748 0.494464 v 0.187613 0.050926 0.529248 v 0.207829 0.0868157 0.523449 v 0.231821 -0.0170182 0.518246 v 0.304138 0.164985 0.443485 v 0.343004 0.132813 0.418235 v 0.313621 0.250742 0.418382 v 0.290815 0.22492 0.444303 v 0.355269 -0.194146 0.0276407 v 0.388534 -0.179618 0.0746089 v 0.336544 -0.25083 0.156379 v 0.29365 -0.279868 0.104617 v 0.389288 0.153006 0.345258 v 0.39155 0.205715 0.320166 v 0.127262 0.566927 -0.64996 v 0.000868155 0.562946 -0.661419 v 0.000850617 0.724441 -0.605705 v 0.118774 0.725955 -0.596105 v 0.21095 0.754513 0.387525 v 0.133734 -0.133188 0.514651 v 0.131302 -0.13393 0.53047 v 0.0671053 -0.326445 0.551902 v 0.0661056 -0.374553 0.504765 v 0.117289 -0.365439 0.489939 v 0.116552 -0.318792 0.528974 v 0.288249 -0.135286 0.424736 v 0.39393 0.0544045 0.33225 v 0.374655 0.0965379 0.38044 v 0.000792155 1 -0.0074948 v 0.0731795 0.993937 -0.182792 v 0.000868155 0.999152 -0.181886 v 0.179405 0.936399 -0.330549 v 0.0842755 0.953459 -0.338026 v 0.141767 0.271455 0.486238 v 0.139978 0.267433 0.490862 v 0.175908 0.259465 0.501362 v 0.175312 0.263359 0.495861 v 0.181597 0.230187 0.495539 v 0.140253 0.240576 0.495341 v 0.336982 0.587763 0.356927 v 0.312043 0.518258 0.416183 v 0.259971 0.350203 0.495411 v 0.250763 0.331028 0.496036 v 0.114179 0.255893 0.495902 v 0.111069 0.276518 0.499456 v 0.125433 0.293116 0.500415 v 0.124965 0.282353 0.489968 v 0.13906 0.254928 0.497457 v 0.17737 0.2462 0.50062 v 0.121796 0.272327 0.47658 v 0.149548 0.0847578 0.549377 v 0.142825 -0.226381 0.544992 v 0.106181 -0.197232 0.576871 v 0.258193 -0.146669 0.465227 v 0.2105 0.0188071 0.525711 v 0.181041 -0.0155508 0.531721 v 0.173453 -0.168949 0.5218 v 0.180322 -0.15877 0.514949 v 0.168554 -0.150118 0.516667 v 0.163082 -0.153579 0.523344 v 0.139124 -0.128733 0.545343 v 0.152348 -0.134468 0.527471 v 0.416192 -0.0714636 0.0335278 v 0.0220956 0.0520719 0.640232 v 0.0361615 0.0619695 0.628476 v -0.000283541 0.202056 0.62768 v 0.0869063 -0.0493125 -0.489641 v 0.192289 -0.0534399 -0.447186 v 0.192003 -0.134672 -0.429197 v 0.0851642 -0.130335 -0.46373 v 0.236434 0.310245 0.495686 v 0.237714 0.31211 0.497539 v 0.244636 0.32534 0.496212 v 0.121253 0.281932 0.477293 v 0.173149 -0.207241 0.528208 v -0.000242618 0.247989 0.603612 v -0.00037708 0.28838 0.571697 v 0.108496 -0.160507 0.588207 v 0.0613995 -0.166388 0.620127 v 0.0634222 -0.199565 0.59462 v 0.0893734 0.151176 0.600127 v 0.122124 0.0729427 0.596088 v 0.0993528 0.072475 0.584781 v 0.108315 0.0599584 0.583916 v 0.133524 0.0551528 0.575778 v 0.13315 0.107517 0.580426 v 0.274937 0.384257 0.485735 v 0.170606 -0.145383 0.517205 v 0.0464391 -0.130399 0.611931 v 0.0392892 -0.113439 0.575094 v -0.00161647 -0.112428 0.579865 v -0.00351648 -0.131685 0.617859 v 0.0194356 0.03489 0.601858 v -0.000564158 0.0478802 0.644208 v -2.04632e-05 0.0350303 0.598835 v 0.222163 0.246884 0.4972 v 0.217802 0.257547 0.498129 v 0.293159 0.278716 0.430419 v 0.302852 0.281932 0.427367 v 0.285209 0.277366 0.434932 v 0.289307 0.275834 0.436551 v 0.290061 0.280494 0.427963 v -0.000225079 -0.384287 0.444245 v 0.0651001 -0.383883 0.440585 v -0.000891543 -0.364076 0.502426 v 0.116576 -0.381784 0.436341 v 0.363734 0.712842 -0.467571 v 0.32166 0.832542 -0.392653 v 0.376508 0.821429 -0.265451 v 0.427095 0.698004 -0.319575 v 0.27178 0.90956 -0.29643 v 0.310423 0.901357 -0.210644 v 0.441869 0.677005 -0.175175 v 0.389019 0.807076 -0.128411 v 0.313311 0.894506 -0.0788532 v 0.12783 -0.376125 0.378248 v 0.0722266 -0.391483 0.37664 v 0.125579 0.302411 0.505741 v 0.101656 0.861358 -0.486525 v 0.214084 0.849981 -0.463327 v 0.2467 0.723207 -0.559263 v 0.104913 0.117397 -0.600268 v 0.221579 0.117865 -0.555159 v 0.200848 0.0268164 -0.488992 v 0.0944011 0.0271204 -0.539134 v 0.391141 0.144178 -0.303545 v 0.331241 0.130393 -0.444613 v 0.360829 0.250357 -0.491155 v 0.424003 0.258021 -0.333419 v 0.000868155 0.23912 -0.655479 v 0.00089154 0.393909 -0.675105 v 0.125626 0.397949 -0.664716 v 0.115418 0.240453 -0.645617 v 0.452175 0.547687 -0.348309 v 0.450217 0.395605 -0.350776 v 0.383015 0.40193 -0.511868 v 0.3854 0.562496 -0.506472 v 0.464078 0.52881 -0.195929 v 0.311698 0.866351 0.071908 v -9.64635e-05 -0.406882 0.376985 v 0.373883 -0.18312 -0.115123 v 0.389189 -0.0789467 -0.141776 v 0.247109 0.197607 0.47589 v 0.22891 0.231497 0.489717 v 0.121077 -0.116725 0.574393 v 0.125626 -0.0895459 0.583057 v 0.110548 -0.128452 0.555428 v 0.000710309 0.959638 0.167019 v 0.000710309 0.881206 0.320973 v 0.224163 0.124079 0.505215 v 0.255305 0.260798 0.480649 v 0.25188 0.263516 0.478322 v 0.214891 0.26119 0.49413 v 0.116476 0.273741 0.475423 v 0.290704 0.283902 0.433377 v 0.29641 0.299523 0.422813 v 0.29406 0.288222 0.418078 v 0.142655 0.263364 0.482467 v 0.121638 0.267831 0.470296 v 0.171711 0.256898 0.489693 v 0.246864 0.257401 0.473821 v 0.274311 0.271648 0.453301 v 0.274539 0.26862 0.446654 v 0.233686 0.331104 0.49074 v 0.187548 0.326632 0.49682 v 0.296971 0.273928 0.433476 v 0.134067 -0.0744861 0.577333 v 0.237434 0.052867 0.514604 v 0.0637905 0.27076 0.54346 v 0.375421 0.514218 0.287328 v 0.353808 -0.333437 -0.190615 v 0.349365 -0.276331 -0.333858 v 0.323337 -0.214946 -0.338453 v 0.356725 -0.247925 -0.205557 v -0.000330311 -0.581268 0.237302 v 0.092922 -0.548418 0.185458 v 0.394783 -0.0876049 -0.0664009 v 0.358315 -0.197624 -0.02995 v 0.292785 -0.321493 0.0377429 v 0.395175 -0.0904345 -0.0143524 v 0.243385 0.243183 -0.602957 v 0.000587539 -0.0451091 -0.498205 v 0.000751232 0.030862 -0.55154 v 0.000809694 0.11928 -0.61144 v 0.000850617 0.862837 -0.491295 v 0.000868155 0.958527 -0.339277 v 0.000423846 -0.128189 -0.469085 v 0.264186 0.56961 -0.608026 v 0.35127 -0.283317 -0.0863656 v 0.196201 -0.209591 -0.418785 v 0.0873097 -0.206341 -0.44839 v 0.000488154 -0.206259 -0.449945 v 0.263397 0.402579 -0.621226 v 0.456683 0.384813 -0.0591516 v 0.457776 0.372302 -0.191281 v 0.000850617 0.671351 0.512487 v 0.000809694 0.77919 0.437668 v 0.408656 0.116286 0.298547 v 0.295913 0.259781 0.439334 v 0.285355 0.265481 0.449775 v 0.278766 0.270035 0.454663 v 0.128946 -0.0227065 0.564741 v 0.16203 0.016989 0.534633 v 0.0985987 0.0583799 0.58087 v 0.0538462 0.323165 0.543729 v 0.0794758 0.301522 0.528465 v -0.00330601 -0.197759 0.600525 v -0.000511542 -0.225551 0.572931 v -0.00456879 -0.164231 0.628277 v -0.000336157 -0.26392 0.574381 v -0.000768774 -0.325515 0.55686 v 0.269921 0.242499 0.464742 v 0.260573 0.253022 0.476072 v 0.235066 0.15963 0.493271 v 0.411369 0.186119 0.273583 v 0.000178307 0.0131539 0.584682 v 0.153436 -0.0554568 0.55786 v 0.0264569 0.331747 0.554112 v -0.000342003 0.332998 0.557743 v 0.285589 0.277974 0.428156 v 0.184795 -0.499655 0.1217 v 0.332808 -0.386298 -0.0699261 v 0.20739 -0.274419 -0.415909 v 0.0927467 -0.274308 -0.43723 v 0.278029 -0.438791 0.0475586 v 0.000505693 -0.27722 -0.43768 v 0.438191 0.12488 -0.0367783 v 0.460214 0.163208 -0.055258 v 0.485388 0.177437 -0.0277343 v 0.472304 0.161641 -0.00367724 v 0.496244 0.232684 -0.0170708 v 0.477425 0.247036 0.00446648 v 0.517015 0.298681 -0.0523876 v 0.492233 0.31788 -0.0441737 v 0.53425 0.316407 -0.124009 v 0.511491 0.332595 -0.129276 v 0.535904 0.290111 -0.170685 v 0.511128 0.30365 -0.186838 v 0.538611 0.228878 -0.193017 v 0.511286 0.231199 -0.218992 v 0.520242 0.128838 -0.191421 v 0.490433 0.122168 -0.208603 v 0.487562 0.00951757 -0.0819458 v 0.472286 -0.00658864 -0.0930419 v 0.47079 0.0399937 -0.154257 v 0.496437 0.0472722 -0.136917 v 0.485142 -0.0247586 -0.0238758 v 0.46129 -0.0429694 -0.0334343 v 0.474888 0.238927 -0.0419989 v 0.495232 0.289088 -0.0628581 v 0.508398 0.299996 -0.11766 v 0.51311 0.283323 -0.158478 v 0.514642 0.235303 -0.176531 v 0.501751 0.136134 -0.181559 v 0.486025 0.0533522 -0.11859 v 0.486451 0.0268164 -0.067155 v 0.482529 0.0136625 -0.0120607 v 0.464265 0.0280383 0.0249515 v 0.457519 -0.0185791 0.0196256 v 0.442769 0.0582571 -0.0293244 v 0.45632 0.0847169 -0.0600578 v 0.442465 0.0842785 -0.0209644 v 0.459612 0.268106 0.0209995 v 0.458559 0.182857 0.0414318 v 0.463026 0.318488 -0.0446005 v 0.470222 0.311835 -0.142898 v 0.455063 0.232836 -0.195221 v 0.43839 0.13186 -0.191088 v 0.424564 0.0473131 -0.148417 v 0.423447 -0.00471202 -0.0897563 v 0.425377 -0.0292075 -0.0262143 v 0.430714 -0.0102191 0.0297161 v 0.446335 0.0345567 0.0460036 v 0.475607 0.129364 -0.0864649 v 0.482611 0.0600636 -0.0525396 v 0.481517 0.0827175 -0.101349 v 0.470503 0.0444835 -0.0133527 v 0.479278 0.0776957 0.00471786 v 0.504692 0.223938 -0.101723 v 0.50375 0.131866 -0.1473 v 0.45452 0.100016 0.0450097 v 0.403623 0.0251386 -0.16934 v 0.414719 0.138607 -0.218957 v 0.435461 0.249632 -0.229924 v -0.000201695 -0.407876 0.310666 v 0.000347846 -0.171521 0.505794 v 0.0884205 -0.186598 0.484028 v 0.141147 -0.173807 0.465513 v 0.159878 -0.142255 0.458644 v 0.152483 -0.116468 0.431278 v 0.0708352 0.0121893 0.376371 v 0.128069 -0.116368 0.360528 v 0.143994 -0.166791 0.41184 v 0.0748398 -0.218144 0.372349 v 0.280941 0.292858 0.454897 v 0.281356 0.319879 0.451494 v 0.127268 0.269088 0.455435 v 0.116921 0.284697 0.447653 v 0.119996 0.274998 0.469126 v 0.15699 0.254759 0.466326 v 0.265916 0.273601 0.421176 v 0.214885 0.253946 0.455259 v 0.141223 0.313133 0.482117 v 0.211436 0.255823 0.486852 v 0.277135 0.302686 0.410799 v 0.252505 0.333881 0.433599 v 0.202023 0.342182 0.464578 v 0.11989 0.295816 0.471196 v 0.146526 0.322539 0.455943 v 0.126292 0.301838 0.454973 v 0.119744 0.284878 0.469419 v 0.00103185 0.0191579 0.374711 v 0.000909079 -0.205715 0.379849 v 0.0536357 -0.100847 0.27211 v 0.00103185 -0.098929 0.27128 v 0.255463 -0.398733 -0.446098 v 0.412907 -0.372688 -0.332858 v 0.452596 -0.41557 -0.353559 v 0.293329 -0.465367 -0.476007 v 0.0815337 -0.637104 0.176286 v 0.0726358 -0.738524 0.179519 v 0.174763 -0.714911 0.155526 v 0.172032 -0.601823 0.129884 v 0.380782 -0.504069 -0.184377 v 0.357368 -0.419095 -0.180384 v 0.337538 -0.494803 -0.0548371 v 0.372989 -0.619402 -0.0373571 v 0.453578 -0.652661 -0.0939539 v 0.452351 -0.545892 -0.196981 v 0.173576 -0.814197 0.195654 v 0.0739044 -0.845866 0.20734 v 0.0964414 -0.904976 0.254455 v 0.197703 -0.864562 0.243353 v 0.519564 -0.487407 -0.384801 v 0.555004 -0.584226 -0.219366 v 0.451357 -0.731555 -0.0215899 v 0.382594 -0.74824 0.0443666 v 0.439805 -0.799196 0.0975376 v 0.519108 -0.768071 -0.00769357 v 0.274837 -0.806199 0.115503 v 0.320508 -0.838061 0.183769 v 0.354533 -0.544232 -0.525256 v 0.162503 -0.604343 -0.559076 v 0.131098 -0.496837 -0.498761 v 0.115161 -0.410103 -0.457756 v -0.00017831 -0.492774 -0.504192 v 2.046e-05 -0.40666 -0.465186 v -0.000482311 -0.600531 -0.555322 v 0.546217 -0.696736 -0.117257 v 0.22746 -0.332063 -0.424345 v 0.101627 -0.33885 -0.437002 v 0.280193 -0.554165 0.0658922 v 0.274843 -0.684891 0.0781517 v 0.000347846 -0.34199 -0.438165 v 0.000733693 -0.746364 0.176765 v 0.000312769 -0.874904 0.179121 v 0.378648 -0.322586 -0.326994 v -0.000114002 -0.940246 0.234262 v 0.000979233 -0.650317 0.207112 v -0.130513 -0.13217 0.498924 v -0.133687 -0.14723 0.488109 v -0.15222 -0.140519 0.477457 v -0.14666 -0.13514 0.489746 v -0.0697653 -0.0999404 0.550318 v -0.0736414 -0.0473131 0.499649 v -0.0305784 -0.0972511 0.55389 v -0.0396517 -0.109762 0.550014 v -0.0358517 -0.127727 0.53534 v -0.0742493 -0.135994 0.523315 v -0.0733373 -0.115561 0.537643 v -0.106766 -0.144336 0.504823 v -0.106281 -0.125786 0.515779 v -0.156505 -0.107798 0.467782 v -0.155611 -0.123682 0.486899 v -0.159311 -0.130796 0.484958 v -0.162872 -0.126996 0.470243 v -0.159919 -0.135625 0.47627 v -0.154055 -0.134696 0.486513 v -0.142597 -0.118993 0.499994 v -0.130051 -0.0726738 0.476189 v -0.10054 -0.105798 0.538111 v -0.125684 -0.115824 0.51596 v -0.274604 -0.301394 0.247527 v -0.220831 -0.335775 0.330215 v -0.250102 -0.275554 0.380393 v -0.3066 -0.239804 0.292309 v -0.284302 -0.0258401 0.479772 v -0.319479 0.00809111 0.449577 v -0.331873 -0.0412272 0.412243 v -0.293674 -0.0747667 0.452418 v -0.294668 -0.0547787 -0.357622 v -0.302063 -0.144319 -0.34334 v -0.356012 -0.159916 -0.223184 v -0.355474 -0.0633082 -0.24271 v -0.447241 0.22613 0.139332 v -0.437922 0.336149 0.131124 v -0.449486 0.331215 0.047962 v -0.454982 0.205353 0.0827818 v -0.103311 -0.419241 0.249936 v -0.203701 -0.353384 0.208147 v -0.196966 -0.411506 0.138841 v -0.101797 -0.475733 0.208638 v -0.196499 -0.327216 0.427455 v -0.176283 -0.362363 0.392138 v -0.150331 -0.372548 0.431378 v -0.155575 -0.349484 0.46435 v -0.0890109 -0.391945 0.303855 v -0.158306 -0.363848 0.305182 v -0.415613 0.611627 0.0817705 v -0.430808 0.648493 -0.0417066 v -0.45411 0.508986 -0.0641209 v -0.440308 0.483438 0.0478393 v -0.389808 0.40462 0.306977 v -0.375935 0.38348 0.354021 v -0.34643 0.433026 0.398499 v -0.354807 0.467378 0.356891 v -0.317409 0.30382 0.429121 v -0.30173 0.320499 0.456861 v -0.309295 0.339493 0.457756 v -0.328406 0.316144 0.429519 v -0.358297 0.360101 0.389344 v -0.335684 0.397733 0.427864 v -0.285156 0.29304 0.457387 v -0.294212 0.310695 0.451757 v -0.307675 0.294425 0.430781 v -0.29475 0.281949 0.435698 v -0.421091 0.455996 0.145494 v -0.395403 0.565208 0.19252 v -0.321999 0.364421 0.449238 v -0.345494 0.336792 0.417218 v -0.178165 0.560672 0.512335 v -0.249354 0.546354 0.466589 v -0.243286 0.479638 0.494943 v -0.170168 0.4781 0.536796 v -0.164123 0.410647 0.547114 v -0.236966 0.427297 0.516007 v -0.270669 0.634748 0.422187 v -0.195815 0.657882 0.47347 v -0.14597 0.313039 0.508126 v -0.18946 0.324971 0.513312 v -0.186823 0.312829 0.511757 v -0.144895 0.300213 0.501871 v -0.186911 0.310514 0.506612 v -0.143462 0.300341 0.494353 v -0.160048 0.365076 0.528073 v -0.219468 0.382854 0.516404 v -0.15782 0.334506 0.520076 v -0.205952 0.349935 0.517012 v -0.195236 0.332495 0.516264 v -0.151653 0.320785 0.513142 v -0.0805691 0.0827468 0.603261 v -0.0493739 0.08878 0.593591 v -0.0448723 0.0732117 0.617958 v -0.0594819 0.0761932 0.621314 v -0.422927 0.0771812 0.237185 v -0.432205 0.159355 0.215905 v -0.448112 0.130656 0.149516 v -0.4282 0.0348607 0.166897 v -0.311779 -0.172912 0.334378 v -0.324787 -0.103758 0.371735 v -0.364851 -0.052639 0.316097 v -0.367254 -0.126698 0.269146 v -0.183918 -0.149136 0.51793 v -0.182024 -0.137865 0.527822 v -0.205163 -0.131463 0.524127 v -0.205514 -0.152071 0.514943 v -0.39379 0.00614433 0.269368 v -0.400951 -0.0591282 0.208995 v -0.261011 -0.0993382 0.483865 v -0.25102 -0.0551177 0.50328 v -0.158849 -0.136444 0.499199 v -0.155155 -0.134784 0.503397 v -0.145304 -0.133848 0.514902 v -0.160802 -0.128394 0.536919 v -0.173424 -0.121349 0.541327 v -0.169156 -0.138478 0.524928 v -0.232096 -0.116964 0.50767 v -0.232727 -0.151188 0.49696 v -0.326085 0.202611 0.415651 v -0.34094 0.235683 0.392156 v -0.367727 0.221336 0.359031 v -0.358829 0.177595 0.3841 v -0.295603 0.0501836 0.478632 v -0.32232 0.0902006 0.449922 v -0.351843 0.04895 0.416686 v -0.367248 0.00336155 0.369624 v -0.156137 -0.154941 0.536878 v -0.165134 -0.177028 0.538193 v -0.144573 -0.187364 0.558725 v -0.140533 -0.155882 0.559046 v -0.17761 -0.0804258 0.547933 v -0.201667 -0.0484356 0.526945 v -0.22024 -0.0817529 0.517585 v -0.195826 -0.106131 0.536439 v -0.207794 -0.213087 0.493049 v -0.191711 -0.188305 0.515551 v -0.201111 -0.170071 0.510745 v -0.223385 -0.183243 0.490178 v -0.128595 -0.132761 0.551212 v -0.145777 -0.139513 0.530605 v -0.0971664 0.171538 0.569909 v -0.120048 0.150182 0.555387 v -0.13557 0.119437 0.545004 v -0.113103 0.137432 0.569453 v -0.0653573 0.232432 0.569575 v -0.08745 0.217992 0.556468 v -0.0739395 0.185388 0.584933 v -0.0855266 0.255554 0.53095 v -0.110583 0.228714 0.525501 v -0.115915 0.191404 0.5495 v -0.300099 0.0366964 -0.387999 v -0.364734 0.0377897 -0.269357 v -0.223181 -0.243207 0.45081 v -0.246139 -0.195666 0.45347 v -0.271201 -0.199869 0.399446 v -0.362846 -0.197443 0.213286 v -0.410176 -0.124757 0.140565 v -0.430404 -0.00290555 0.0907385 v -0.448779 0.11075 0.0889086 v -0.142135 0.869847 0.301633 v -0.132167 0.771303 0.419317 v -0.0633989 0.777407 0.43288 v -0.0675789 0.877324 0.315577 v -0.353469 0.660735 0.264732 v -0.2875 0.723792 0.335465 v -0.30353 0.809117 0.220313 v -0.37099 0.728422 0.148627 v -0.381016 0.776764 0.0117274 v -0.0996744 0.472587 0.557146 v -0.109525 0.565325 0.53475 v -0.100294 0.277787 0.511248 v -0.108689 0.248457 0.503268 v -0.0528874 0.193947 0.604898 v -0.0453926 0.241125 0.586705 v -0.12255 0.668732 0.500514 v -0.0511336 0.564922 0.542589 v -0.0582191 0.671655 0.50974 v -0.0440363 0.465776 0.561151 v -0.0361966 0.388923 0.562367 v -0.301894 0.466338 0.448542 v -0.295831 0.424807 0.472166 v -0.140867 0.22264 0.499754 v -0.185742 0.209381 0.492394 v -0.186338 0.179495 0.502724 v -0.145859 0.19535 0.519018 v -0.0600022 0.0437294 0.578309 v -0.113337 0.0407946 0.564875 v -0.114196 0.0121659 0.564255 v -0.0686019 -0.00676987 0.598064 v -0.143661 0.0637116 0.537807 v -0.147607 0.0440217 0.535469 v -0.0907706 -0.0459919 0.600525 v -0.0300113 -0.0346152 0.623594 v -0.028047 -0.0138554 0.603173 v -0.148028 0.131527 0.5437 v -0.148519 0.164868 0.537322 v -0.183164 0.146873 0.520193 v -0.176978 0.112363 0.532908 v -0.147823 0.0979234 0.535574 v -0.165064 0.0766492 0.532955 v -0.120107 0.268649 0.480825 v -0.118558 0.262394 0.493353 v -0.115979 0.27287 0.494434 v -0.116476 0.272952 0.483859 v -0.229115 0.916634 0.120496 v -0.223379 0.848952 0.271461 v -0.145146 0.945128 0.150709 v -0.145409 0.980883 -0.0176788 v -0.154278 0.976311 -0.1834 v -0.240088 0.945514 -0.185786 v -0.230512 0.948548 -0.0401515 v -0.0669533 0.995411 -0.00979819 v -0.0669124 0.955581 0.163097 v -0.0891746 0.383199 0.554861 v -0.112226 0.336757 0.527307 v -0.123381 0.311174 0.513382 v -0.149484 -0.111966 0.558549 v -0.160264 -0.0991219 0.559216 v -0.0695139 0.122828 0.646821 v -0.103574 0.1197 0.616608 v -0.0967747 0.0873945 0.617683 v -0.0583127 0.0845006 0.640951 v -0.0810075 0.0824603 0.567973 v -0.0347818 0.058339 0.594989 v -0.031812 -0.0520134 0.636181 v -0.0876079 -0.0656701 0.61341 v -0.0905251 -0.101683 0.607529 v -0.0378686 -0.0937434 0.629054 v -0.0836617 -0.122507 0.579642 v -0.0385351 -0.11728 0.594673 v -0.0223295 0.0177081 0.586652 v -0.0307538 0.0864766 0.665646 v -0.0369098 0.125196 0.667078 v -0.0659946 0.154643 0.629212 v -0.0379446 0.159028 0.648136 v -0.0287544 0.19984 0.620642 v -0.0228205 0.245931 0.598298 v -0.0444456 0.281523 0.558544 v -0.0233467 0.287164 0.569581 v -0.348774 0.267521 0.384632 v -0.352083 0.30296 0.39367 v -0.371253 0.315308 0.363077 v -0.374871 0.266369 0.352501 v -0.422202 0.335746 0.207253 v -0.401928 0.429197 0.234116 v -0.395345 0.264083 0.313998 v -0.391071 0.32586 0.325679 v -0.312703 0.275793 0.421661 v -0.320315 0.291642 0.417107 v -0.332077 0.295173 0.409057 v -0.327599 0.271742 0.406824 v -0.429802 0.244434 0.203979 v -0.409282 0.332454 0.277442 v -0.411848 0.257886 0.266369 v -0.187414 -0.242265 0.510307 v -0.193763 -0.283183 0.474066 v -0.155254 -0.304954 0.501777 v -0.149998 -0.264183 0.526518 v -0.0567108 -0.227311 0.569523 v -0.101124 -0.233508 0.561461 v -0.11039 -0.27508 0.546021 v -0.066205 -0.270351 0.564711 v -0.154225 -0.138052 0.502391 v -0.159867 -0.142787 0.513271 v -0.15533 -0.142366 0.518626 v -0.148566 -0.137426 0.506285 v -0.160416 -0.138344 0.518258 v -0.161965 -0.141513 0.511996 v -0.110811 -0.126394 0.533276 v -0.10089 -0.129879 0.583501 v -0.0809374 -0.117865 0.558397 v -0.263876 0.014785 0.500935 v -0.26083 0.088932 0.49537 v -0.279702 0.127055 0.470506 v -0.207764 0.0867397 0.523776 v -0.187729 0.0509786 0.529558 v -0.232096 -0.0167025 0.518065 v -0.344056 0.133304 0.417078 v -0.302046 0.166376 0.445239 v -0.292551 0.225429 0.44414 v -0.316041 0.250468 0.418475 v -0.335386 -0.250836 0.156385 v -0.387207 -0.179618 0.074568 v -0.353755 -0.194151 0.0276524 v -0.292388 -0.279891 0.104617 v -0.392211 0.205733 0.320201 v -0.386651 0.150025 0.344942 v -0.126064 0.567371 -0.651942 v -0.117096 0.725914 -0.596082 v -0.209068 0.754227 0.387245 v -0.134091 -0.133281 0.515294 v -0.132384 -0.133778 0.530774 v -0.118289 -0.366228 0.490722 v -0.0673742 -0.375085 0.505343 v -0.0685259 -0.327012 0.553422 v -0.117722 -0.319453 0.530388 v -0.287793 -0.13528 0.424643 v -0.375234 0.0965671 0.380457 v -0.394351 0.054463 0.33218 v -0.0714373 0.993797 -0.182751 v -0.0825568 0.953558 -0.338084 v -0.177458 0.935674 -0.330221 v -0.176961 0.259482 0.501637 v -0.139651 0.267463 0.490903 v -0.141176 0.271537 0.486156 v -0.175792 0.263446 0.495797 v -0.139621 0.240295 0.49489 v -0.181918 0.230053 0.49499 v -0.335299 0.587722 0.356851 v -0.311189 0.51838 0.416464 v -0.263028 0.350391 0.495528 v -0.252435 0.331198 0.496568 v -0.111168 0.276448 0.500608 v -0.113553 0.255671 0.49582 v -0.124754 0.293525 0.500263 v -0.124275 0.282616 0.489933 v -0.138587 0.254671 0.496603 v -0.17851 0.246346 0.500783 v -0.120744 0.272286 0.476557 v -0.150635 0.0843194 0.549231 v -0.110981 -0.197039 0.578654 v -0.145877 -0.226522 0.547184 v -0.257825 -0.146365 0.464946 v -0.181813 -0.015013 0.533586 v -0.21057 0.0188715 0.525811 v -0.169226 -0.14996 0.516989 v -0.181743 -0.1588 0.515902 v -0.175376 -0.168545 0.522911 v -0.163813 -0.153415 0.52335 v -0.140253 -0.128364 0.545887 v -0.153091 -0.134363 0.527834 v -0.414608 -0.0714286 0.0335337 v -0.0376523 0.063203 0.628721 v -0.0232707 0.0530365 0.640016 v -0.190483 -0.134521 -0.42891 v -0.190425 -0.0530365 -0.446291 v -0.0856669 -0.0492716 -0.489617 v -0.0841703 -0.13027 -0.463549 v -0.238743 0.312729 0.498784 v -0.236568 0.310718 0.495914 v -0.245034 0.325784 0.495083 v -0.120311 0.281967 0.47734 v -0.176107 -0.207054 0.530523 v -0.114635 -0.15994 0.588938 v -0.0702155 -0.19877 0.595006 v -0.0735478 -0.165324 0.619338 v -0.0899814 0.151661 0.600396 v -0.111016 0.0572925 0.58557 v -0.101867 0.0715163 0.586237 v -0.127064 0.0733753 0.597824 v -0.136833 0.0543987 0.574241 v -0.135833 0.107312 0.581379 v -0.278287 0.38386 0.485911 v -0.171226 -0.145371 0.517737 v -0.0426215 -0.114106 0.575498 v -0.0575293 -0.131258 0.610721 v -0.0203535 0.0339429 0.602828 v -0.224215 0.246978 0.496697 v -0.219644 0.257664 0.498129 v -0.308126 0.284604 0.426215 v -0.296275 0.279026 0.430641 v -0.291721 0.275554 0.437358 v -0.286612 0.276705 0.435172 v -0.291949 0.280143 0.428238 v -0.065825 -0.384532 0.440825 v -0.11702 -0.382428 0.436651 v -0.374667 0.821265 -0.265393 v -0.3198 0.831958 -0.392208 v -0.362179 0.712818 -0.467507 v -0.425879 0.698185 -0.319692 v -0.269938 0.909215 -0.296313 v -0.308015 0.900609 -0.210562 v -0.440407 0.677046 -0.175192 v -0.387417 0.807117 -0.128411 v -0.312037 0.894728 -0.0788123 v -0.0720161 -0.391612 0.376675 v -0.127765 -0.376523 0.378341 v -0.124801 0.303066 0.504835 v -0.0997913 0.860855 -0.486022 v -0.212687 0.850449 -0.463771 v -0.245244 0.723306 -0.559461 v -0.199083 0.0271847 -0.488407 v -0.21986 0.118005 -0.554936 v -0.10327 0.117479 -0.600127 v -0.0928636 0.0273016 -0.53883 v -0.389259 0.144254 -0.303446 v -0.329178 0.130557 -0.444432 v -0.359227 0.250316 -0.491237 v -0.422325 0.258021 -0.333419 v -0.123907 0.397932 -0.664658 v -0.113699 0.240517 -0.645459 v -0.381641 0.401913 -0.512072 v -0.448592 0.395605 -0.3508 v -0.450574 0.547705 -0.348333 v -0.384366 0.562601 -0.506817 v -0.462722 0.528827 -0.195952 v -0.310604 0.866976 0.0721301 v -0.372013 -0.183143 -0.115123 v -0.387686 -0.0789994 -0.141781 v -0.2476 0.197566 0.475487 v -0.230342 0.231532 0.488372 v -0.129238 -0.0890256 0.584927 v -0.123544 -0.115971 0.574872 v -0.114588 -0.128867 0.557082 v -0.221702 0.122764 0.506442 v -0.216107 0.26119 0.49413 v -0.253242 0.263207 0.478422 v -0.256568 0.260547 0.479737 v -0.115342 0.273619 0.475323 v -0.298743 0.299903 0.422953 v -0.291698 0.283732 0.432722 v -0.295854 0.288181 0.418253 v -0.142059 0.263388 0.482491 v -0.120428 0.267802 0.470325 v -0.172108 0.256934 0.489641 v -0.275083 0.271584 0.453242 v -0.248582 0.25684 0.473757 v -0.275001 0.268573 0.446274 v -0.234253 0.331396 0.490634 v -0.187624 0.326819 0.49717 v -0.300292 0.274694 0.432944 v -0.135658 -0.0739483 0.577444 v -0.237428 0.052791 0.514919 v -0.0645564 0.270789 0.544612 v -0.373819 0.514195 0.287264 v -0.321852 -0.214718 -0.338184 v -0.348166 -0.27584 -0.333396 v -0.352171 -0.333378 -0.190533 v -0.354936 -0.247872 -0.205511 v -0.0936937 -0.549137 0.186785 v -0.35669 -0.197653 -0.0299733 v -0.393228 -0.0876225 -0.0664009 v -0.29161 -0.321499 0.0380294 v -0.393638 -0.0904403 -0.014329 v -0.241608 0.243201 -0.602916 v -0.263209 0.569914 -0.609242 v -0.349441 -0.283282 -0.0863831 v -0.194821 -0.209504 -0.418674 v -0.0862925 -0.206323 -0.448413 v -0.261795 0.402579 -0.621448 v -0.456233 0.372302 -0.191263 v -0.455245 0.384813 -0.0591282 v -0.408072 0.116608 0.297155 v -0.298661 0.260278 0.439147 v -0.287606 0.265861 0.450068 v -0.279696 0.270216 0.454289 v -0.162731 0.0172638 0.536515 v -0.13087 -0.0222973 0.565699 v -0.101475 0.0572691 0.580946 v -0.0809198 0.301049 0.528407 v -0.0556351 0.322972 0.54498 v -0.272306 0.242932 0.464508 v -0.262964 0.253017 0.476001 v -0.233067 0.158607 0.487893 v -0.412053 0.186142 0.273695 v -0.154815 -0.0532762 0.55793 v -0.0277489 0.331782 0.556427 v -0.286179 0.277611 0.427928 v -0.183941 -0.499632 0.122144 v -0.331493 -0.386257 -0.0698735 v -0.206238 -0.274279 -0.416026 v -0.0915482 -0.274332 -0.437317 v -0.277193 -0.438779 0.0481257 v -0.484037 0.177414 -0.0276816 v -0.458618 0.163319 -0.0553633 v -0.437233 0.124752 -0.0367315 v -0.471526 0.1616 -0.00366555 v -0.476232 0.247018 0.00445479 v -0.494987 0.232631 -0.0169773 v -0.491035 0.317921 -0.0441971 v -0.515688 0.298728 -0.0523583 v -0.510175 0.332513 -0.1293 v -0.532917 0.316524 -0.12405 v -0.50993 0.303592 -0.186815 v -0.534671 0.290233 -0.170849 v -0.510152 0.231181 -0.21891 v -0.537459 0.228895 -0.193058 v -0.48934 0.122068 -0.20872 v -0.519208 0.128879 -0.191363 v -0.469632 0.0399528 -0.15424 v -0.470766 -0.00661202 -0.0930419 v -0.486142 0.00947665 -0.0819458 v -0.495221 0.0472722 -0.1369 v -0.459705 -0.0431682 -0.033446 v -0.483546 -0.0248521 -0.0238816 v -0.494011 0.289082 -0.0628932 v -0.473502 0.238904 -0.0420457 v -0.507246 0.300137 -0.117724 v -0.512134 0.2833 -0.158502 v -0.513712 0.235303 -0.176549 v -0.50102 0.136093 -0.181582 v -0.485095 0.0532704 -0.118549 v -0.485253 0.0267755 -0.0671726 v -0.481172 0.0136801 -0.012201 v -0.456127 -0.0187428 0.0196958 v -0.462909 0.027933 0.024969 v -0.454923 0.0845591 -0.060163 v -0.441284 0.0577602 -0.0294063 v -0.440921 0.0840388 -0.0210813 v -0.457712 0.18288 0.0414318 v -0.458378 0.268123 0.0210228 v -0.461588 0.318505 -0.044618 v -0.468843 0.311858 -0.142898 v -0.453707 0.232836 -0.195204 v -0.436969 0.13182 -0.191047 v -0.423167 0.0473306 -0.148288 v -0.421945 -0.00467109 -0.089692 v -0.423991 -0.0291198 -0.0260915 v -0.429434 -0.0102776 0.0297746 v -0.445242 0.0345158 0.0460211 v -0.481617 0.0602039 -0.0524227 v -0.474104 0.129276 -0.0866754 v -0.480325 0.0824545 -0.101285 v -0.469474 0.0446648 -0.013376 v -0.478167 0.0776431 0.00467109 v -0.503592 0.223961 -0.101887 v -0.502575 0.131983 -0.147242 v -0.453707 0.0999988 0.0450097 v -0.413357 0.138549 -0.218945 v -0.402232 0.0251035 -0.169299 v -0.434023 0.249632 -0.229901 v -0.0871226 -0.186639 0.484069 v -0.139686 -0.173807 0.465537 v -0.158481 -0.142278 0.458685 v -0.0688299 0.0121893 0.376371 v -0.150805 -0.116468 0.431278 v -0.126228 -0.116368 0.360528 v -0.142316 -0.166791 0.41184 v -0.0730392 -0.218144 0.372349 v -0.282087 0.293548 0.454716 v -0.283513 0.320341 0.45129 v -0.124398 0.285323 0.452968 v -0.126795 0.269175 0.455978 v -0.119353 0.275057 0.469524 v -0.156265 0.2548 0.466332 v -0.265074 0.27356 0.421036 v -0.214762 0.253899 0.455218 v -0.141855 0.312577 0.484315 v -0.212745 0.255776 0.486875 v -0.277117 0.302621 0.410811 v -0.252014 0.333887 0.433371 v -0.20141 0.342405 0.464461 v -0.120767 0.295565 0.473184 v -0.145333 0.322832 0.456154 v -0.126041 0.301873 0.455785 v -0.119879 0.284837 0.470541 v -0.0516539 -0.100847 0.27211 v -0.454245 -0.41571 -0.353027 v -0.413392 -0.372097 -0.332203 v -0.255785 -0.398019 -0.4467 v -0.294685 -0.464338 -0.476902 v -0.174388 -0.714777 0.156607 v -0.0715543 -0.738454 0.180284 v -0.0798266 -0.636725 0.177765 v -0.171536 -0.601788 0.131147 v -0.337345 -0.494639 -0.0546091 v -0.355094 -0.419334 -0.180442 v -0.379665 -0.504905 -0.184915 v -0.373053 -0.619338 -0.0373044 v -0.45328 -0.545816 -0.197379 v -0.454128 -0.653065 -0.0942754 v -0.0965876 -0.904778 0.254759 v -0.0736004 -0.845567 0.20775 v -0.172974 -0.81408 0.195975 v -0.1973 -0.864375 0.243622 v -0.520961 -0.488138 -0.3841 v -0.556272 -0.584635 -0.21946 v -0.439238 -0.799155 0.0975785 v -0.381694 -0.748264 0.0442672 v -0.45103 -0.731883 -0.0219173 v -0.519067 -0.768135 -0.0077988 v -0.273785 -0.806328 0.115322 v -0.319391 -0.83802 0.183769 v -0.163088 -0.604103 -0.559421 v -0.356672 -0.543712 -0.525361 v -0.131226 -0.496761 -0.498854 v -0.114629 -0.410074 -0.45775 v -0.546533 -0.697291 -0.117619 v -0.100633 -0.33885 -0.437013 v -0.22677 -0.331835 -0.424707 v -0.274931 -0.684651 0.0790578 v -0.28021 -0.553908 0.0669913 v -0.378028 -0.321668 -0.326088 v 0.172833 0.300014 0.41564 v -0.171097 0.299996 0.415616 # 1258 vertices vt 0.532 0.923 0.000 vt 0.535 0.917 0.000 vt 0.542 0.923 0.000 vt 0.541 0.929 0.000 vt 0.521 0.984 0.000 vt 0.521 0.996 0.000 vt 0.505 0.998 0.000 vt 0.500 0.985 0.000 vt 0.504 0.917 0.000 vt 0.507 0.910 0.000 vt 0.516 0.910 0.000 vt 0.515 0.918 0.000 vt 0.523 0.921 0.000 vt 0.525 0.913 0.000 vt 0.549 0.958 0.000 vt 0.538 0.954 0.000 vt 0.544 0.942 0.000 vt 0.550 0.946 0.000 vt 0.545 0.935 0.000 vt 0.550 0.932 0.000 vt 0.547 0.974 0.000 vt 0.533 0.967 0.000 vt 0.500 0.917 0.000 vt 0.500 0.910 0.000 vt 0.542 0.987 0.000 vt 0.533 0.994 0.000 vt 0.616 0.254 0.000 vt 0.653 0.261 0.000 vt 0.658 0.307 0.000 vt 0.619 0.292 0.000 vt 0.636 0.438 0.000 vt 0.620 0.419 0.000 vt 0.627 0.396 0.000 vt 0.647 0.414 0.000 vt 0.886 0.312 0.000 vt 0.897 0.370 0.000 vt 0.860 0.369 0.000 vt 0.844 0.308 0.000 vt 0.740 0.593 0.000 vt 0.741 0.542 0.000 vt 0.759 0.541 0.000 vt 0.768 0.598 0.000 vt 0.644 0.213 0.000 vt 0.561 0.175 0.000 vt 0.566 0.146 0.000 vt 0.644 0.174 0.000 vt 0.580 0.254 0.000 vt 0.585 0.277 0.000 vt 0.565 0.268 0.000 vt 0.565 0.256 0.000 vt 0.590 0.217 0.000 vt 0.544 0.195 0.000 vt 0.771 0.721 0.000 vt 0.736 0.712 0.000 vt 0.758 0.653 0.000 vt 0.794 0.663 0.000 vt 0.669 0.622 0.000 vt 0.685 0.632 0.000 vt 0.665 0.669 0.000 vt 0.652 0.651 0.000 vt 0.623 0.588 0.000 vt 0.632 0.582 0.000 vt 0.639 0.590 0.000 vt 0.627 0.599 0.000 vt 0.641 0.632 0.000 vt 0.657 0.612 0.000 vt 0.619 0.580 0.000 vt 0.617 0.575 0.000 vt 0.623 0.573 0.000 vt 0.627 0.576 0.000 vt 0.708 0.702 0.000 vt 0.729 0.646 0.000 vt 0.633 0.614 0.000 vt 0.647 0.601 0.000 vt 0.604 0.718 0.000 vt 0.574 0.725 0.000 vt 0.567 0.686 0.000 vt 0.596 0.682 0.000 vt 0.562 0.648 0.000 vt 0.590 0.649 0.000 vt 0.618 0.756 0.000 vt 0.584 0.769 0.000 vt 0.586 0.587 0.000 vt 0.566 0.586 0.000 vt 0.568 0.579 0.000 vt 0.586 0.580 0.000 vt 0.569 0.574 0.000 vt 0.586 0.573 0.000 vt 0.562 0.627 0.000 vt 0.587 0.627 0.000 vt 0.587 0.610 0.000 vt 0.563 0.608 0.000 vt 0.565 0.595 0.000 vt 0.587 0.596 0.000 vt 0.521 0.441 0.000 vt 0.526 0.450 0.000 vt 0.520 0.450 0.000 vt 0.517 0.445 0.000 vt 0.720 0.504 0.000 vt 0.709 0.467 0.000 vt 0.727 0.446 0.000 vt 0.738 0.494 0.000 vt 0.656 0.383 0.000 vt 0.660 0.348 0.000 vt 0.684 0.368 0.000 vt 0.673 0.403 0.000 vt 0.572 0.371 0.000 vt 0.573 0.365 0.000 vt 0.581 0.364 0.000 vt 0.581 0.374 0.000 vt 0.708 0.400 0.000 vt 0.693 0.431 0.000 vt 0.604 0.401 0.000 vt 0.609 0.383 0.000 vt 0.557 0.364 0.000 vt 0.559 0.365 0.000 vt 0.557 0.366 0.000 vt 0.556 0.364 0.000 vt 0.552 0.367 0.000 vt 0.552 0.364 0.000 vt 0.568 0.377 0.000 vt 0.561 0.374 0.000 vt 0.566 0.370 0.000 vt 0.594 0.377 0.000 vt 0.594 0.363 0.000 vt 0.653 0.551 0.000 vt 0.644 0.534 0.000 vt 0.658 0.523 0.000 vt 0.666 0.545 0.000 vt 0.637 0.480 0.000 vt 0.625 0.458 0.000 vt 0.649 0.459 0.000 vt 0.662 0.434 0.000 vt 0.557 0.345 0.000 vt 0.553 0.353 0.000 vt 0.543 0.349 0.000 vt 0.546 0.337 0.000 vt 0.586 0.403 0.000 vt 0.573 0.392 0.000 vt 0.579 0.382 0.000 vt 0.591 0.389 0.000 vt 0.572 0.343 0.000 vt 0.584 0.331 0.000 vt 0.590 0.347 0.000 vt 0.578 0.353 0.000 vt 0.553 0.358 0.000 vt 0.543 0.355 0.000 vt 0.553 0.499 0.000 vt 0.541 0.507 0.000 vt 0.542 0.484 0.000 vt 0.553 0.477 0.000 vt 0.539 0.532 0.000 vt 0.529 0.541 0.000 vt 0.531 0.513 0.000 vt 0.551 0.538 0.000 vt 0.538 0.552 0.000 vt 0.552 0.521 0.000 vt 0.908 0.437 0.000 vt 0.876 0.429 0.000 vt 0.608 0.340 0.000 vt 0.599 0.314 0.000 vt 0.629 0.336 0.000 vt 0.691 0.326 0.000 vt 0.723 0.365 0.000 vt 0.748 0.426 0.000 vt 0.755 0.489 0.000 vt 0.564 0.825 0.000 vt 0.590 0.868 0.000 vt 0.558 0.886 0.000 vt 0.533 0.834 0.000 vt 0.637 0.789 0.000 vt 0.673 0.755 0.000 vt 0.702 0.774 0.000 vt 0.665 0.817 0.000 vt 0.740 0.787 0.000 vt 0.545 0.727 0.000 vt 0.540 0.686 0.000 vt 0.551 0.550 0.000 vt 0.538 0.572 0.000 vt 0.520 0.546 0.000 vt 0.522 0.517 0.000 vt 0.552 0.775 0.000 vt 0.524 0.777 0.000 vt 0.521 0.728 0.000 vt 0.500 0.687 0.000 vt 0.500 0.651 0.000 vt 0.515 0.650 0.000 vt 0.518 0.687 0.000 vt 0.500 0.727 0.000 vt 0.625 0.671 0.000 vt 0.618 0.644 0.000 vt 0.591 0.533 0.000 vt 0.571 0.539 0.000 vt 0.569 0.527 0.000 vt 0.589 0.518 0.000 vt 0.545 0.436 0.000 vt 0.525 0.427 0.000 vt 0.528 0.413 0.000 vt 0.549 0.425 0.000 vt 0.556 0.449 0.000 vt 0.563 0.439 0.000 vt 0.514 0.395 0.000 vt 0.532 0.396 0.000 vt 0.513 0.409 0.000 vt 0.566 0.511 0.000 vt 0.564 0.490 0.000 vt 0.577 0.478 0.000 vt 0.584 0.500 0.000 vt 0.500 0.408 0.000 vt 0.500 0.394 0.000 vt 0.571 0.457 0.000 vt 0.561 0.468 0.000 vt 0.554 0.561 0.000 vt 0.557 0.563 0.000 vt 0.552 0.569 0.000 vt 0.548 0.569 0.000 vt 0.627 0.847 0.000 vt 0.674 0.871 0.000 vt 0.645 0.898 0.000 vt 0.776 0.920 0.000 vt 0.709 0.921 0.000 vt 0.729 0.888 0.000 vt 0.783 0.887 0.000 vt 0.693 0.947 0.000 vt 0.621 0.920 0.000 vt 0.535 0.642 0.000 vt 0.542 0.618 0.000 vt 0.545 0.599 0.000 vt 0.559 0.383 0.000 vt 0.552 0.377 0.000 vt 0.531 0.470 0.000 vt 0.520 0.472 0.000 vt 0.517 0.456 0.000 vt 0.528 0.457 0.000 vt 0.530 0.438 0.000 vt 0.517 0.436 0.000 vt 0.528 0.383 0.000 vt 0.513 0.384 0.000 vt 0.512 0.374 0.000 vt 0.526 0.374 0.000 vt 0.512 0.367 0.000 vt 0.526 0.366 0.000 vt 0.512 0.362 0.000 vt 0.526 0.362 0.000 vt 0.511 0.422 0.000 vt 0.500 0.384 0.000 vt 0.500 0.375 0.000 vt 0.500 0.362 0.000 vt 0.500 0.367 0.000 vt 0.511 0.472 0.000 vt 0.508 0.457 0.000 vt 0.521 0.491 0.000 vt 0.512 0.519 0.000 vt 0.512 0.491 0.000 vt 0.511 0.550 0.000 vt 0.520 0.576 0.000 vt 0.510 0.583 0.000 vt 0.500 0.457 0.000 vt 0.500 0.472 0.000 vt 0.500 0.491 0.000 vt 0.654 0.584 0.000 vt 0.656 0.568 0.000 vt 0.669 0.567 0.000 vt 0.666 0.589 0.000 vt 0.705 0.639 0.000 vt 0.718 0.591 0.000 vt 0.684 0.563 0.000 vt 0.680 0.592 0.000 vt 0.637 0.575 0.000 vt 0.636 0.566 0.000 vt 0.645 0.567 0.000 vt 0.645 0.579 0.000 vt 0.723 0.546 0.000 vt 0.697 0.592 0.000 vt 0.702 0.554 0.000 vt 0.500 0.163 0.000 vt 0.500 0.137 0.000 vt 0.579 0.298 0.000 vt 0.570 0.317 0.000 vt 0.554 0.307 0.000 vt 0.560 0.287 0.000 vt 0.534 0.318 0.000 vt 0.517 0.314 0.000 vt 0.519 0.296 0.000 vt 0.538 0.300 0.000 vt 0.562 0.362 0.000 vt 0.559 0.363 0.000 vt 0.557 0.362 0.000 vt 0.559 0.360 0.000 vt 0.563 0.365 0.000 vt 0.561 0.368 0.000 vt 0.543 0.360 0.000 vt 0.531 0.358 0.000 vt 0.531 0.351 0.000 vt 0.611 0.437 0.000 vt 0.613 0.475 0.000 vt 0.624 0.497 0.000 vt 0.580 0.445 0.000 vt 0.590 0.466 0.000 vt 0.598 0.418 0.000 vt 0.648 0.501 0.000 vt 0.633 0.516 0.000 vt 0.641 0.554 0.000 vt 0.630 0.541 0.000 vt 0.733 0.331 0.000 vt 0.696 0.288 0.000 vt 0.706 0.252 0.000 vt 0.751 0.313 0.000 vt 0.683 0.535 0.000 vt 0.674 0.508 0.000 vt 0.999 0.696 0.000 vt 0.986 0.778 0.000 vt 0.950 0.772 0.000 vt 0.967 0.695 0.000 vt 0.600 0.811 0.000 vt 0.552 0.361 0.000 vt 0.547 0.367 0.000 vt 0.546 0.364 0.000 vt 0.525 0.254 0.000 vt 0.546 0.261 0.000 vt 0.542 0.280 0.000 vt 0.522 0.274 0.000 vt 0.631 0.369 0.000 vt 0.678 0.460 0.000 vt 0.662 0.482 0.000 vt 0.770 0.948 0.000 vt 0.762 0.981 0.000 vt 0.676 0.977 0.000 vt 0.845 0.915 0.000 vt 0.835 0.891 0.000 vt 0.569 0.560 0.000 vt 0.582 0.558 0.000 vt 0.580 0.563 0.000 vt 0.569 0.564 0.000 vt 0.590 0.544 0.000 vt 0.571 0.548 0.000 vt 0.635 0.701 0.000 vt 0.651 0.731 0.000 vt 0.607 0.593 0.000 vt 0.609 0.606 0.000 vt 0.543 0.570 0.000 vt 0.553 0.556 0.000 vt 0.552 0.580 0.000 vt 0.556 0.574 0.000 vt 0.569 0.554 0.000 vt 0.585 0.551 0.000 vt 0.559 0.566 0.000 vt 0.550 0.458 0.000 vt 0.532 0.330 0.000 vt 0.549 0.325 0.000 vt 0.610 0.364 0.000 vt 0.589 0.432 0.000 vt 0.578 0.417 0.000 vt 0.570 0.357 0.000 vt 0.565 0.360 0.000 vt 0.562 0.356 0.000 vt 0.565 0.351 0.000 vt 0.557 0.364 0.000 vt 0.556 0.364 0.000 vt 0.548 0.371 0.000 vt 0.557 0.371 0.000 vt 0.762 0.385 0.000 vt 0.513 0.445 0.000 vt 0.508 0.444 0.000 vt 0.500 0.520 0.000 vt 0.939 0.378 0.000 vt 0.932 0.316 0.000 vt 0.972 0.321 0.000 vt 0.974 0.384 0.000 vt 0.605 0.572 0.000 vt 0.605 0.578 0.000 vt 0.605 0.584 0.000 vt 0.559 0.571 0.000 vt 0.562 0.333 0.000 vt 0.500 0.552 0.000 vt 0.500 0.585 0.000 vt 0.531 0.343 0.000 vt 0.514 0.338 0.000 vt 0.516 0.324 0.000 vt 0.532 0.488 0.000 vt 0.534 0.448 0.000 vt 0.540 0.446 0.000 vt 0.545 0.448 0.000 vt 0.538 0.455 0.000 vt 0.541 0.466 0.000 vt 0.612 0.623 0.000 vt 0.567 0.366 0.000 vt 0.513 0.356 0.000 vt 0.500 0.355 0.000 vt 0.500 0.346 0.000 vt 0.514 0.348 0.000 vt 0.543 0.363 0.000 vt 0.552 0.364 0.000 vt 0.531 0.362 0.000 vt 0.512 0.361 0.000 vt 0.509 0.433 0.000 vt 0.500 0.444 0.000 vt 0.500 0.432 0.000 vt 0.603 0.551 0.000 vt 0.599 0.557 0.000 vt 0.627 0.570 0.000 vt 0.631 0.571 0.000 vt 0.625 0.566 0.000 vt 0.622 0.569 0.000 vt 0.621 0.567 0.000 vt 0.529 0.234 0.000 vt 0.500 0.249 0.000 vt 0.500 0.227 0.000 vt 0.550 0.245 0.000 vt 0.857 0.816 0.000 vt 0.825 0.804 0.000 vt 0.851 0.737 0.000 vt 0.886 0.748 0.000 vt 0.821 0.866 0.000 vt 0.798 0.856 0.000 vt 0.783 0.797 0.000 vt 0.810 0.729 0.000 vt 0.755 0.848 0.000 vt 0.534 0.215 0.000 vt 0.563 0.233 0.000 vt 0.548 0.588 0.000 vt 0.884 0.835 0.000 vt 0.908 0.854 0.000 vt 0.919 0.761 0.000 vt 0.947 0.512 0.000 vt 0.944 0.446 0.000 vt 0.974 0.452 0.000 vt 0.974 0.519 0.000 vt 0.915 0.504 0.000 vt 0.887 0.498 0.000 vt 0.917 0.564 0.000 vt 0.890 0.556 0.000 vt 0.999 0.634 0.000 vt 0.973 0.633 0.000 vt 0.975 0.577 0.000 vt 0.999 0.579 0.000 vt 0.882 0.614 0.000 vt 0.911 0.622 0.000 vt 0.901 0.679 0.000 vt 0.868 0.671 0.000 vt 0.833 0.667 0.000 vt 0.708 0.836 0.000 vt 0.500 0.205 0.000 vt 0.826 0.364 0.000 vt 0.801 0.303 0.000 vt 0.613 0.529 0.000 vt 0.607 0.544 0.000 vt 0.541 0.380 0.000 vt 0.538 0.372 0.000 vt 0.537 0.366 0.000 vt 0.537 0.363 0.000 vt 0.598 0.945 0.000 vt 0.524 0.902 0.000 vt 0.599 0.489 0.000 vt 0.609 0.563 0.000 vt 0.596 0.563 0.000 vt 0.612 0.559 0.000 vt 0.557 0.569 0.000 vt 0.620 0.571 0.000 vt 0.616 0.569 0.000 vt 0.618 0.569 0.000 vt 0.569 0.568 0.000 vt 0.561 0.568 0.000 vt 0.579 0.567 0.000 vt 0.616 0.564 0.000 vt 0.613 0.567 0.000 vt 0.607 0.567 0.000 vt 0.587 0.568 0.000 vt 0.606 0.568 0.000 vt 0.630 0.565 0.000 vt 0.548 0.389 0.000 vt 0.601 0.452 0.000 vt 0.529 0.566 0.000 vt 0.684 0.686 0.000 vt 0.872 0.222 0.000 vt 0.876 0.265 0.000 vt 0.825 0.258 0.000 vt 0.821 0.214 0.000 vt 0.561 0.119 0.000 vt 0.500 0.114 0.000 vt 0.771 0.304 0.000 vt 0.797 0.363 0.000 vt 0.726 0.227 0.000 vt 0.777 0.371 0.000 vt 0.947 0.571 0.000 vt 0.999 0.388 0.000 vt 0.999 0.456 0.000 vt 0.999 0.524 0.000 vt 0.936 0.877 0.000 vt 0.856 0.945 0.000 vt 0.999 0.323 0.000 vt 0.935 0.689 0.000 vt 0.776 0.240 0.000 vt 0.928 0.265 0.000 vt 0.969 0.264 0.000 vt 0.999 0.267 0.000 vt 0.943 0.628 0.000 vt 0.806 0.622 0.000 vt 0.851 0.611 0.000 vt 0.500 0.777 0.000 vt 0.500 0.839 0.000 vt 0.692 0.489 0.000 vt 0.631 0.558 0.000 vt 0.622 0.562 0.000 vt 0.626 0.560 0.000 vt 0.555 0.413 0.000 vt 0.570 0.429 0.000 vt 0.539 0.440 0.000 vt 0.524 0.607 0.000 vt 0.531 0.591 0.000 vt 0.500 0.361 0.000 vt 0.500 0.321 0.000 vt 0.500 0.312 0.000 vt 0.500 0.336 0.000 vt 0.500 0.294 0.000 vt 0.500 0.273 0.000 vt 0.622 0.549 0.000 vt 0.616 0.554 0.000 vt 0.607 0.509 0.000 vt 0.701 0.520 0.000 vt 0.500 0.421 0.000 vt 0.564 0.403 0.000 vt 0.511 0.615 0.000 vt 0.500 0.618 0.000 vt 0.617 0.568 0.000 vt 0.636 0.139 0.000 vt 0.764 0.192 0.000 vt 0.921 0.220 0.000 vt 0.967 0.219 0.000 vt 0.708 0.168 0.000 vt 0.999 0.218 0.000 vt 0.803 0.523 0.000 vt 0.794 0.535 0.000 vt 0.783 0.527 0.000 vt 0.791 0.508 0.000 vt 0.789 0.571 0.000 vt 0.797 0.562 0.000 vt 0.813 0.591 0.000 vt 0.815 0.578 0.000 vt 0.839 0.583 0.000 vt 0.835 0.574 0.000 vt 0.850 0.569 0.000 vt 0.845 0.560 0.000 vt 0.855 0.539 0.000 vt 0.847 0.535 0.000 vt 0.850 0.501 0.000 vt 0.841 0.502 0.000 vt 0.814 0.438 0.000 vt 0.836 0.464 0.000 vt 0.828 0.472 0.000 vt 0.809 0.452 0.000 vt 0.792 0.427 0.000 vt 0.790 0.441 0.000 vt 0.818 0.567 0.000 vt 0.807 0.550 0.000 vt 0.831 0.561 0.000 vt 0.839 0.553 0.000 vt 0.837 0.534 0.000 vt 0.831 0.505 0.000 vt 0.820 0.479 0.000 vt 0.804 0.465 0.000 vt 0.786 0.460 0.000 vt 0.773 0.456 0.000 vt 0.779 0.433 0.000 vt 0.797 0.489 0.000 vt 0.785 0.495 0.000 vt 0.789 0.486 0.000 vt 0.772 0.537 0.000 vt 0.781 0.583 0.000 vt 0.812 0.602 0.000 vt 0.848 0.587 0.000 vt 0.862 0.546 0.000 vt 0.859 0.500 0.000 vt 0.820 0.412 0.000 vt 0.843 0.450 0.000 vt 0.791 0.404 0.000 vt 0.773 0.417 0.000 vt 0.764 0.447 0.000 vt 0.801 0.477 0.000 vt 0.813 0.487 0.000 vt 0.806 0.496 0.000 vt 0.787 0.478 0.000 vt 0.778 0.489 0.000 vt 0.822 0.538 0.000 vt 0.822 0.510 0.000 vt 0.767 0.492 0.000 vt 0.870 0.496 0.000 vt 0.851 0.425 0.000 vt 0.872 0.552 0.000 vt 0.500 0.183 0.000 vt 0.516 0.930 0.000 vt 0.500 0.928 0.000 vt 0.528 0.934 0.000 vt 0.537 0.938 0.000 vt 0.516 0.970 0.000 vt 0.520 0.955 0.000 vt 0.530 0.952 0.000 vt 0.522 0.944 0.000 vt 0.512 0.942 0.000 vt 0.615 0.572 0.000 vt 0.612 0.569 0.000 vt 0.576 0.968 0.000 vt 0.573 0.973 0.000 vt 0.562 0.969 0.000 vt 0.563 0.961 0.000 vt 0.571 0.956 0.000 vt 0.582 0.961 0.000 vt 0.611 0.961 0.000 vt 0.606 0.967 0.000 vt 0.595 0.960 0.000 vt 0.601 0.955 0.000 vt 0.570 0.569 0.000 vt 0.595 0.566 0.000 vt 0.616 0.967 0.000 vt 0.617 0.975 0.000 vt 0.607 0.978 0.000 vt 0.614 0.982 0.000 vt 0.605 0.991 0.000 vt 0.599 0.986 0.000 vt 0.593 0.996 0.000 vt 0.589 0.989 0.000 vt 0.562 0.570 0.000 vt 0.573 0.994 0.000 vt 0.579 0.987 0.000 vt 0.584 0.996 0.000 vt 0.581 0.953 0.000 vt 0.592 0.953 0.000 vt 0.561 0.988 0.000 vt 0.572 0.981 0.000 vt 0.563 0.978 0.000 vt 0.500 0.970 0.000 vt 0.500 0.943 0.000 vt 0.511 0.956 0.000 vt 0.500 0.956 0.000 vt 0.868 0.132 0.000 vt 0.867 0.090 0.000 vt 0.916 0.092 0.000 vt 0.918 0.133 0.000 vt 0.554 0.066 0.000 vt 0.612 0.070 0.000 vt 0.619 0.103 0.000 vt 0.558 0.095 0.000 vt 0.815 0.169 0.000 vt 0.758 0.148 0.000 vt 0.747 0.102 0.000 vt 0.814 0.126 0.000 vt 0.770 0.072 0.000 vt 0.817 0.087 0.000 vt 0.552 0.038 0.000 vt 0.551 0.020 0.000 vt 0.602 0.021 0.000 vt 0.605 0.039 0.000 vt 0.821 0.050 0.000 vt 0.867 0.055 0.000 vt 0.712 0.053 0.000 vt 0.700 0.022 0.000 vt 0.739 0.023 0.000 vt 0.740 0.052 0.000 vt 0.652 0.022 0.000 vt 0.659 0.043 0.000 vt 0.913 0.055 0.000 vt 0.959 0.055 0.000 vt 0.960 0.091 0.000 vt 0.999 0.089 0.000 vt 0.999 0.131 0.000 vt 0.962 0.133 0.000 vt 0.999 0.053 0.000 vt 0.778 0.038 0.000 vt 0.917 0.177 0.000 vt 0.965 0.178 0.000 vt 0.674 0.083 0.000 vt 0.685 0.124 0.000 vt 0.999 0.175 0.000 vt 0.500 0.037 0.000 vt 0.500 0.066 0.000 vt 0.871 0.175 0.000 vt 0.500 0.019 0.000 vt 0.500 0.092 0.000 vt 0.999 0.002 0.000 vt 0.958 0.002 0.000 vt 0.867 0.002 0.000 vt 0.823 0.002 0.000 vt 0.908 0.002 0.000 vt 0.601 0.002 0.000 vt 0.550 0.002 0.000 vt 0.697 0.002 0.000 vt 0.650 0.002 0.000 vt 0.782 0.002 0.000 vt 0.740 0.002 0.000 vt 0.500 0.002 0.000 vt 0.468 0.923 0.000 vt 0.459 0.929 0.000 vt 0.458 0.923 0.000 vt 0.465 0.917 0.000 vt 0.479 0.984 0.000 vt 0.495 0.998 0.000 vt 0.479 0.996 0.000 vt 0.496 0.917 0.000 vt 0.485 0.918 0.000 vt 0.484 0.910 0.000 vt 0.493 0.910 0.000 vt 0.477 0.921 0.000 vt 0.475 0.913 0.000 vt 0.451 0.958 0.000 vt 0.450 0.946 0.000 vt 0.456 0.942 0.000 vt 0.462 0.954 0.000 vt 0.455 0.935 0.000 vt 0.450 0.932 0.000 vt 0.467 0.967 0.000 vt 0.453 0.974 0.000 vt 0.467 0.994 0.000 vt 0.458 0.987 0.000 vt 0.384 0.254 0.000 vt 0.381 0.292 0.000 vt 0.342 0.307 0.000 vt 0.347 0.261 0.000 vt 0.364 0.438 0.000 vt 0.353 0.414 0.000 vt 0.373 0.396 0.000 vt 0.380 0.419 0.000 vt 0.114 0.312 0.000 vt 0.156 0.308 0.000 vt 0.140 0.369 0.000 vt 0.103 0.370 0.000 vt 0.260 0.593 0.000 vt 0.232 0.598 0.000 vt 0.241 0.541 0.000 vt 0.259 0.542 0.000 vt 0.356 0.213 0.000 vt 0.356 0.174 0.000 vt 0.434 0.146 0.000 vt 0.439 0.175 0.000 vt 0.420 0.254 0.000 vt 0.435 0.256 0.000 vt 0.435 0.268 0.000 vt 0.415 0.277 0.000 vt 0.456 0.195 0.000 vt 0.410 0.217 0.000 vt 0.229 0.721 0.000 vt 0.206 0.663 0.000 vt 0.242 0.653 0.000 vt 0.264 0.712 0.000 vt 0.331 0.622 0.000 vt 0.348 0.651 0.000 vt 0.335 0.669 0.000 vt 0.315 0.632 0.000 vt 0.377 0.588 0.000 vt 0.373 0.599 0.000 vt 0.361 0.590 0.000 vt 0.368 0.582 0.000 vt 0.359 0.632 0.000 vt 0.343 0.612 0.000 vt 0.381 0.580 0.000 vt 0.373 0.576 0.000 vt 0.377 0.573 0.000 vt 0.383 0.575 0.000 vt 0.292 0.702 0.000 vt 0.271 0.646 0.000 vt 0.353 0.601 0.000 vt 0.367 0.614 0.000 vt 0.396 0.718 0.000 vt 0.404 0.682 0.000 vt 0.433 0.686 0.000 vt 0.426 0.725 0.000 vt 0.410 0.649 0.000 vt 0.438 0.648 0.000 vt 0.416 0.769 0.000 vt 0.382 0.756 0.000 vt 0.414 0.587 0.000 vt 0.414 0.580 0.000 vt 0.432 0.579 0.000 vt 0.434 0.586 0.000 vt 0.431 0.574 0.000 vt 0.414 0.573 0.000 vt 0.413 0.627 0.000 vt 0.438 0.627 0.000 vt 0.413 0.610 0.000 vt 0.413 0.596 0.000 vt 0.435 0.595 0.000 vt 0.437 0.608 0.000 vt 0.479 0.441 0.000 vt 0.483 0.445 0.000 vt 0.480 0.450 0.000 vt 0.474 0.450 0.000 vt 0.280 0.504 0.000 vt 0.262 0.494 0.000 vt 0.273 0.446 0.000 vt 0.291 0.467 0.000 vt 0.344 0.383 0.000 vt 0.327 0.403 0.000 vt 0.316 0.368 0.000 vt 0.340 0.348 0.000 vt 0.428 0.371 0.000 vt 0.419 0.374 0.000 vt 0.419 0.364 0.000 vt 0.427 0.365 0.000 vt 0.307 0.431 0.000 vt 0.292 0.400 0.000 vt 0.391 0.383 0.000 vt 0.396 0.401 0.000 vt 0.443 0.364 0.000 vt 0.444 0.364 0.000 vt 0.443 0.366 0.000 vt 0.441 0.365 0.000 vt 0.448 0.367 0.000 vt 0.448 0.364 0.000 vt 0.432 0.377 0.000 vt 0.434 0.370 0.000 vt 0.439 0.374 0.000 vt 0.406 0.377 0.000 vt 0.406 0.363 0.000 vt 0.347 0.551 0.000 vt 0.334 0.545 0.000 vt 0.342 0.523 0.000 vt 0.356 0.534 0.000 vt 0.363 0.480 0.000 vt 0.351 0.459 0.000 vt 0.375 0.458 0.000 vt 0.338 0.434 0.000 vt 0.443 0.345 0.000 vt 0.454 0.337 0.000 vt 0.457 0.349 0.000 vt 0.447 0.353 0.000 vt 0.414 0.403 0.000 vt 0.409 0.389 0.000 vt 0.421 0.382 0.000 vt 0.427 0.392 0.000 vt 0.428 0.343 0.000 vt 0.422 0.353 0.000 vt 0.410 0.347 0.000 vt 0.416 0.331 0.000 vt 0.457 0.355 0.000 vt 0.447 0.358 0.000 vt 0.447 0.499 0.000 vt 0.447 0.477 0.000 vt 0.458 0.484 0.000 vt 0.459 0.507 0.000 vt 0.461 0.532 0.000 vt 0.469 0.513 0.000 vt 0.471 0.541 0.000 vt 0.449 0.538 0.000 vt 0.448 0.521 0.000 vt 0.462 0.552 0.000 vt 0.124 0.429 0.000 vt 0.092 0.437 0.000 vt 0.392 0.340 0.000 vt 0.371 0.336 0.000 vt 0.401 0.314 0.000 vt 0.309 0.326 0.000 vt 0.252 0.426 0.000 vt 0.277 0.365 0.000 vt 0.245 0.489 0.000 vt 0.436 0.825 0.000 vt 0.467 0.834 0.000 vt 0.442 0.886 0.000 vt 0.410 0.868 0.000 vt 0.363 0.789 0.000 vt 0.335 0.817 0.000 vt 0.298 0.774 0.000 vt 0.327 0.755 0.000 vt 0.260 0.787 0.000 vt 0.460 0.686 0.000 vt 0.455 0.727 0.000 vt 0.462 0.572 0.000 vt 0.449 0.550 0.000 vt 0.480 0.546 0.000 vt 0.478 0.517 0.000 vt 0.479 0.728 0.000 vt 0.476 0.777 0.000 vt 0.448 0.775 0.000 vt 0.482 0.687 0.000 vt 0.485 0.650 0.000 vt 0.375 0.671 0.000 vt 0.382 0.644 0.000 vt 0.409 0.533 0.000 vt 0.411 0.518 0.000 vt 0.431 0.527 0.000 vt 0.429 0.539 0.000 vt 0.455 0.436 0.000 vt 0.451 0.425 0.000 vt 0.472 0.413 0.000 vt 0.475 0.427 0.000 vt 0.444 0.449 0.000 vt 0.437 0.439 0.000 vt 0.486 0.395 0.000 vt 0.487 0.409 0.000 vt 0.468 0.396 0.000 vt 0.434 0.511 0.000 vt 0.416 0.500 0.000 vt 0.423 0.478 0.000 vt 0.436 0.490 0.000 vt 0.429 0.457 0.000 vt 0.439 0.468 0.000 vt 0.446 0.561 0.000 vt 0.452 0.569 0.000 vt 0.448 0.569 0.000 vt 0.443 0.563 0.000 vt 0.373 0.847 0.000 vt 0.355 0.898 0.000 vt 0.326 0.871 0.000 vt 0.224 0.920 0.000 vt 0.217 0.887 0.000 vt 0.271 0.888 0.000 vt 0.291 0.921 0.000 vt 0.379 0.920 0.000 vt 0.307 0.947 0.000 vt 0.465 0.642 0.000 vt 0.455 0.599 0.000 vt 0.458 0.618 0.000 vt 0.448 0.377 0.000 vt 0.441 0.383 0.000 vt 0.469 0.470 0.000 vt 0.472 0.457 0.000 vt 0.483 0.456 0.000 vt 0.480 0.472 0.000 vt 0.470 0.438 0.000 vt 0.483 0.436 0.000 vt 0.472 0.383 0.000 vt 0.474 0.374 0.000 vt 0.488 0.374 0.000 vt 0.487 0.384 0.000 vt 0.474 0.366 0.000 vt 0.488 0.367 0.000 vt 0.474 0.362 0.000 vt 0.488 0.362 0.000 vt 0.489 0.422 0.000 vt 0.492 0.457 0.000 vt 0.489 0.472 0.000 vt 0.479 0.491 0.000 vt 0.488 0.491 0.000 vt 0.488 0.519 0.000 vt 0.489 0.550 0.000 vt 0.490 0.583 0.000 vt 0.480 0.576 0.000 vt 0.346 0.584 0.000 vt 0.334 0.589 0.000 vt 0.331 0.567 0.000 vt 0.344 0.568 0.000 vt 0.295 0.639 0.000 vt 0.282 0.591 0.000 vt 0.320 0.592 0.000 vt 0.316 0.563 0.000 vt 0.363 0.575 0.000 vt 0.355 0.579 0.000 vt 0.355 0.567 0.000 vt 0.364 0.566 0.000 vt 0.277 0.546 0.000 vt 0.298 0.554 0.000 vt 0.303 0.592 0.000 vt 0.421 0.298 0.000 vt 0.440 0.287 0.000 vt 0.446 0.307 0.000 vt 0.430 0.317 0.000 vt 0.466 0.318 0.000 vt 0.462 0.300 0.000 vt 0.481 0.296 0.000 vt 0.483 0.314 0.000 vt 0.438 0.362 0.000 vt 0.441 0.360 0.000 vt 0.443 0.362 0.000 vt 0.441 0.363 0.000 vt 0.439 0.368 0.000 vt 0.437 0.365 0.000 vt 0.469 0.351 0.000 vt 0.469 0.358 0.000 vt 0.457 0.360 0.000 vt 0.389 0.437 0.000 vt 0.387 0.475 0.000 vt 0.376 0.497 0.000 vt 0.420 0.445 0.000 vt 0.410 0.466 0.000 vt 0.402 0.418 0.000 vt 0.352 0.501 0.000 vt 0.367 0.516 0.000 vt 0.359 0.554 0.000 vt 0.370 0.541 0.000 vt 0.267 0.331 0.000 vt 0.249 0.313 0.000 vt 0.294 0.252 0.000 vt 0.304 0.288 0.000 vt 0.317 0.535 0.000 vt 0.326 0.508 0.000 vt 0.001 0.696 0.000 vt 0.033 0.695 0.000 vt 0.050 0.772 0.000 vt 0.014 0.778 0.000 vt 0.400 0.811 0.000 vt 0.448 0.361 0.000 vt 0.454 0.364 0.000 vt 0.453 0.367 0.000 vt 0.475 0.254 0.000 vt 0.478 0.274 0.000 vt 0.458 0.280 0.000 vt 0.454 0.261 0.000 vt 0.369 0.369 0.000 vt 0.322 0.460 0.000 vt 0.338 0.482 0.000 vt 0.324 0.977 0.000 vt 0.238 0.981 0.000 vt 0.230 0.948 0.000 vt 0.155 0.915 0.000 vt 0.165 0.891 0.000 vt 0.431 0.560 0.000 vt 0.431 0.564 0.000 vt 0.420 0.563 0.000 vt 0.418 0.558 0.000 vt 0.410 0.544 0.000 vt 0.429 0.548 0.000 vt 0.349 0.731 0.000 vt 0.365 0.701 0.000 vt 0.391 0.606 0.000 vt 0.393 0.593 0.000 vt 0.457 0.570 0.000 vt 0.447 0.556 0.000 vt 0.444 0.574 0.000 vt 0.448 0.580 0.000 vt 0.415 0.551 0.000 vt 0.431 0.554 0.000 vt 0.441 0.566 0.000 vt 0.450 0.458 0.000 vt 0.451 0.325 0.000 vt 0.468 0.330 0.000 vt 0.390 0.364 0.000 vt 0.411 0.432 0.000 vt 0.422 0.417 0.000 vt 0.430 0.357 0.000 vt 0.435 0.351 0.000 vt 0.438 0.356 0.000 vt 0.435 0.360 0.000 vt 0.443 0.364 0.000 vt 0.444 0.364 0.000 vt 0.443 0.371 0.000 vt 0.452 0.371 0.000 vt 0.238 0.385 0.000 vt 0.487 0.445 0.000 vt 0.492 0.444 0.000 vt 0.061 0.378 0.000 vt 0.026 0.384 0.000 vt 0.028 0.321 0.000 vt 0.068 0.316 0.000 vt 0.395 0.572 0.000 vt 0.395 0.578 0.000 vt 0.395 0.584 0.000 vt 0.441 0.571 0.000 vt 0.438 0.333 0.000 vt 0.469 0.343 0.000 vt 0.486 0.338 0.000 vt 0.484 0.324 0.000 vt 0.468 0.488 0.000 vt 0.466 0.448 0.000 vt 0.462 0.455 0.000 vt 0.455 0.448 0.000 vt 0.460 0.446 0.000 vt 0.459 0.466 0.000 vt 0.388 0.623 0.000 vt 0.433 0.366 0.000 vt 0.487 0.356 0.000 vt 0.486 0.348 0.000 vt 0.457 0.363 0.000 vt 0.448 0.364 0.000 vt 0.469 0.362 0.000 vt 0.488 0.361 0.000 vt 0.491 0.433 0.000 vt 0.401 0.557 0.000 vt 0.397 0.551 0.000 vt 0.373 0.570 0.000 vt 0.369 0.571 0.000 vt 0.375 0.566 0.000 vt 0.379 0.567 0.000 vt 0.378 0.569 0.000 vt 0.471 0.234 0.000 vt 0.450 0.245 0.000 vt 0.143 0.816 0.000 vt 0.114 0.748 0.000 vt 0.149 0.737 0.000 vt 0.175 0.804 0.000 vt 0.202 0.856 0.000 vt 0.179 0.866 0.000 vt 0.190 0.729 0.000 vt 0.217 0.797 0.000 vt 0.245 0.848 0.000 vt 0.466 0.215 0.000 vt 0.437 0.233 0.000 vt 0.452 0.588 0.000 vt 0.092 0.854 0.000 vt 0.116 0.835 0.000 vt 0.081 0.761 0.000 vt 0.053 0.512 0.000 vt 0.026 0.519 0.000 vt 0.026 0.452 0.000 vt 0.056 0.446 0.000 vt 0.113 0.498 0.000 vt 0.085 0.504 0.000 vt 0.110 0.556 0.000 vt 0.083 0.564 0.000 vt 0.001 0.634 0.000 vt 0.001 0.579 0.000 vt 0.025 0.577 0.000 vt 0.027 0.633 0.000 vt 0.118 0.614 0.000 vt 0.132 0.671 0.000 vt 0.099 0.679 0.000 vt 0.089 0.622 0.000 vt 0.167 0.667 0.000 vt 0.292 0.836 0.000 vt 0.199 0.303 0.000 vt 0.174 0.364 0.000 vt 0.393 0.544 0.000 vt 0.387 0.529 0.000 vt 0.459 0.380 0.000 vt 0.462 0.372 0.000 vt 0.463 0.366 0.000 vt 0.463 0.363 0.000 vt 0.402 0.945 0.000 vt 0.476 0.902 0.000 vt 0.401 0.489 0.000 vt 0.391 0.563 0.000 vt 0.388 0.559 0.000 vt 0.404 0.563 0.000 vt 0.443 0.569 0.000 vt 0.380 0.571 0.000 vt 0.382 0.569 0.000 vt 0.384 0.569 0.000 vt 0.439 0.568 0.000 vt 0.431 0.568 0.000 vt 0.421 0.567 0.000 vt 0.393 0.567 0.000 vt 0.387 0.567 0.000 vt 0.384 0.564 0.000 vt 0.394 0.568 0.000 vt 0.413 0.568 0.000 vt 0.370 0.565 0.000 vt 0.452 0.389 0.000 vt 0.399 0.452 0.000 vt 0.471 0.566 0.000 vt 0.316 0.686 0.000 vt 0.128 0.222 0.000 vt 0.179 0.214 0.000 vt 0.175 0.258 0.000 vt 0.124 0.265 0.000 vt 0.439 0.119 0.000 vt 0.229 0.304 0.000 vt 0.203 0.363 0.000 vt 0.274 0.227 0.000 vt 0.223 0.371 0.000 vt 0.053 0.571 0.000 vt 0.001 0.388 0.000 vt 0.001 0.456 0.000 vt 0.001 0.524 0.000 vt 0.064 0.877 0.000 vt 0.144 0.945 0.000 vt 0.001 0.323 0.000 vt 0.065 0.689 0.000 vt 0.224 0.240 0.000 vt 0.072 0.265 0.000 vt 0.001 0.267 0.000 vt 0.031 0.264 0.000 vt 0.057 0.628 0.000 vt 0.194 0.622 0.000 vt 0.149 0.611 0.000 vt 0.308 0.489 0.000 vt 0.369 0.558 0.000 vt 0.374 0.560 0.000 vt 0.378 0.562 0.000 vt 0.445 0.413 0.000 vt 0.430 0.429 0.000 vt 0.461 0.440 0.000 vt 0.476 0.607 0.000 vt 0.469 0.591 0.000 vt 0.378 0.549 0.000 vt 0.384 0.554 0.000 vt 0.393 0.509 0.000 vt 0.299 0.520 0.000 vt 0.436 0.403 0.000 vt 0.489 0.615 0.000 vt 0.383 0.568 0.000 vt 0.364 0.139 0.000 vt 0.236 0.192 0.000 vt 0.033 0.219 0.000 vt 0.079 0.220 0.000 vt 0.292 0.168 0.000 vt 0.001 0.218 0.000 vt 0.197 0.523 0.000 vt 0.209 0.508 0.000 vt 0.217 0.527 0.000 vt 0.206 0.535 0.000 vt 0.211 0.571 0.000 vt 0.203 0.562 0.000 vt 0.187 0.591 0.000 vt 0.185 0.578 0.000 vt 0.161 0.583 0.000 vt 0.165 0.574 0.000 vt 0.150 0.569 0.000 vt 0.155 0.560 0.000 vt 0.145 0.539 0.000 vt 0.153 0.535 0.000 vt 0.150 0.501 0.000 vt 0.159 0.502 0.000 vt 0.186 0.438 0.000 vt 0.191 0.452 0.000 vt 0.172 0.472 0.000 vt 0.164 0.464 0.000 vt 0.208 0.427 0.000 vt 0.210 0.441 0.000 vt 0.182 0.567 0.000 vt 0.193 0.550 0.000 vt 0.169 0.561 0.000 vt 0.161 0.553 0.000 vt 0.163 0.534 0.000 vt 0.169 0.505 0.000 vt 0.196 0.465 0.000 vt 0.180 0.479 0.000 vt 0.214 0.460 0.000 vt 0.227 0.456 0.000 vt 0.221 0.433 0.000 vt 0.203 0.489 0.000 vt 0.211 0.486 0.000 vt 0.215 0.495 0.000 vt 0.228 0.537 0.000 vt 0.219 0.583 0.000 vt 0.188 0.602 0.000 vt 0.152 0.587 0.000 vt 0.138 0.546 0.000 vt 0.141 0.500 0.000 vt 0.157 0.450 0.000 vt 0.180 0.412 0.000 vt 0.209 0.404 0.000 vt 0.227 0.417 0.000 vt 0.236 0.447 0.000 vt 0.194 0.496 0.000 vt 0.187 0.487 0.000 vt 0.199 0.477 0.000 vt 0.213 0.478 0.000 vt 0.222 0.489 0.000 vt 0.178 0.538 0.000 vt 0.178 0.510 0.000 vt 0.233 0.492 0.000 vt 0.130 0.496 0.000 vt 0.149 0.425 0.000 vt 0.128 0.552 0.000 vt 0.484 0.930 0.000 vt 0.472 0.934 0.000 vt 0.463 0.938 0.000 vt 0.470 0.952 0.000 vt 0.480 0.955 0.000 vt 0.484 0.970 0.000 vt 0.488 0.942 0.000 vt 0.478 0.944 0.000 vt 0.388 0.569 0.000 vt 0.385 0.572 0.000 vt 0.424 0.968 0.000 vt 0.437 0.961 0.000 vt 0.438 0.969 0.000 vt 0.427 0.973 0.000 vt 0.418 0.961 0.000 vt 0.429 0.956 0.000 vt 0.389 0.961 0.000 vt 0.399 0.955 0.000 vt 0.405 0.960 0.000 vt 0.394 0.967 0.000 vt 0.429 0.569 0.000 vt 0.405 0.566 0.000 vt 0.393 0.978 0.000 vt 0.383 0.975 0.000 vt 0.384 0.967 0.000 vt 0.401 0.986 0.000 vt 0.395 0.991 0.000 vt 0.386 0.982 0.000 vt 0.411 0.989 0.000 vt 0.407 0.996 0.000 vt 0.438 0.570 0.000 vt 0.427 0.994 0.000 vt 0.416 0.996 0.000 vt 0.421 0.987 0.000 vt 0.419 0.953 0.000 vt 0.408 0.953 0.000 vt 0.439 0.988 0.000 vt 0.428 0.981 0.000 vt 0.437 0.978 0.000 vt 0.489 0.956 0.000 vt 0.132 0.132 0.000 vt 0.082 0.133 0.000 vt 0.084 0.092 0.000 vt 0.133 0.090 0.000 vt 0.446 0.066 0.000 vt 0.442 0.095 0.000 vt 0.381 0.103 0.000 vt 0.388 0.070 0.000 vt 0.185 0.169 0.000 vt 0.186 0.126 0.000 vt 0.253 0.102 0.000 vt 0.242 0.148 0.000 vt 0.230 0.072 0.000 vt 0.183 0.087 0.000 vt 0.448 0.038 0.000 vt 0.395 0.039 0.000 vt 0.398 0.021 0.000 vt 0.449 0.020 0.000 vt 0.133 0.055 0.000 vt 0.179 0.050 0.000 vt 0.288 0.053 0.000 vt 0.260 0.052 0.000 vt 0.261 0.023 0.000 vt 0.300 0.022 0.000 vt 0.341 0.043 0.000 vt 0.348 0.022 0.000 vt 0.087 0.055 0.000 vt 0.040 0.091 0.000 vt 0.041 0.055 0.000 vt 0.038 0.133 0.000 vt 0.001 0.131 0.000 vt 0.001 0.089 0.000 vt 0.001 0.053 0.000 vt 0.222 0.038 0.000 vt 0.083 0.177 0.000 vt 0.035 0.178 0.000 vt 0.326 0.083 0.000 vt 0.315 0.124 0.000 vt 0.001 0.175 0.000 vt 0.129 0.175 0.000 vt 0.001 0.002 0.000 vt 0.042 0.002 0.000 vt 0.133 0.002 0.000 vt 0.177 0.002 0.000 vt 0.092 0.002 0.000 vt 0.399 0.002 0.000 vt 0.450 0.002 0.000 vt 0.303 0.002 0.000 vt 0.350 0.002 0.000 vt 0.218 0.002 0.000 vt 0.260 0.002 0.000 vt 0.558 0.967 0.000 vt 0.557 0.976 0.000 vt 0.500 0.997 0.000 vt 0.588 0.975 0.000 vt 0.442 0.967 0.000 vt 0.443 0.976 0.000 vt 0.412 0.975 0.000 # 1339 texture vertices vn 0.001 0.482 -0.876 vn -0.001 0.661 0.751 vn 0.136 0.595 0.792 vn -0.203 0.679 0.706 vn -0.092 0.474 0.876 vn -0.184 0.792 0.581 vn -0.098 0.863 0.495 vn -0.449 0.820 0.356 vn -0.220 0.748 0.626 vn -0.560 0.798 -0.222 vn -0.233 0.531 -0.815 vn 0.001 0.534 -0.845 vn -0.135 0.596 0.791 vn 0.203 0.676 0.708 vn 0.091 0.476 0.875 vn 0.189 0.792 0.581 vn 0.099 0.862 0.496 vn 0.444 0.821 0.360 vn 0.221 0.747 0.627 vn 0.556 0.801 -0.221 vn 0.228 0.532 -0.815 vn -0.002 0.536 -0.844 vn -0.574 0.744 -0.343 vn -0.485 0.523 -0.701 vn -0.121 0.869 -0.480 vn -0.215 0.930 -0.298 vn -0.000 -0.806 -0.591 vn -0.277 -0.779 -0.562 vn -0.258 -0.731 -0.632 vn -0.046 -0.809 -0.586 vn -0.210 0.565 -0.798 vn -0.094 0.624 -0.775 vn 0.015 0.952 -0.307 vn 0.045 0.919 -0.392 vn -0.099 0.857 -0.505 vn -0.379 0.493 -0.783 vn -0.947 0.285 -0.149 vn -0.809 -0.421 -0.411 vn -0.895 -0.443 -0.043 vn -0.999 -0.020 0.035 vn -0.359 0.933 -0.019 vn -0.809 0.586 0.047 vn -0.667 -0.516 -0.538 vn -0.726 -0.626 -0.285 vn -0.001 0.671 -0.741 vn -0.001 0.945 -0.327 vn -0.531 -0.632 -0.565 vn -0.618 -0.566 -0.546 vn 0.800 -0.473 0.369 vn 0.618 -0.771 0.151 vn 0.693 -0.711 0.116 vn 0.818 -0.467 0.335 vn 0.849 -0.259 0.460 vn 0.775 -0.130 0.619 vn 0.667 -0.132 0.733 vn 0.775 -0.270 0.571 vn 0.958 -0.057 -0.280 vn 0.763 0.033 -0.646 vn 0.763 -0.153 -0.628 vn 0.911 -0.129 -0.391 vn 0.990 0.067 0.126 vn 0.979 0.090 0.185 vn 0.981 0.057 0.184 vn 0.996 0.020 0.090 vn 0.770 -0.392 0.504 vn 0.657 -0.721 0.219 vn 0.478 -0.656 0.584 vn 0.599 -0.389 0.700 vn 0.498 -0.846 0.192 vn 0.537 -0.840 0.082 vn 0.740 -0.557 0.378 vn 0.668 -0.570 0.479 vn 0.280 -0.914 0.294 vn 0.421 -0.898 0.126 vn 0.991 0.084 0.103 vn 0.964 0.223 0.143 vn 0.960 0.189 0.207 vn 0.979 0.103 0.175 vn 0.868 0.172 0.465 vn 0.907 0.085 0.413 vn 0.938 0.144 0.316 vn 0.897 0.178 0.405 vn 0.662 -0.174 0.729 vn 0.583 -0.417 0.697 vn 0.627 -0.449 0.637 vn 0.685 -0.405 0.605 vn 0.827 0.091 0.555 vn 0.890 0.018 0.455 vn 0.663 -0.395 0.636 vn 0.606 -0.428 0.671 vn 0.313 -0.735 0.602 vn -0.136 -0.864 0.485 vn 0.951 0.158 0.267 vn 0.964 0.113 0.241 vn 0.731 -0.036 0.681 vn 0.819 -0.134 0.558 vn 0.546 0.270 0.793 vn 0.602 0.237 0.763 vn 0.444 0.233 0.865 vn 0.353 0.173 0.920 vn 0.240 -0.093 0.966 vn 0.498 0.051 0.866 vn 0.675 0.338 0.656 vn 0.480 0.400 0.780 vn 0.064 -0.572 0.818 vn 0.126 -0.313 0.941 vn 0.207 -0.613 0.763 vn 0.221 -0.810 0.544 vn 0.598 -0.694 -0.401 vn 0.124 -0.977 -0.175 vn 0.218 -0.333 0.917 vn 0.377 -0.161 0.912 vn 0.142 -0.210 0.967 vn 0.256 -0.155 0.954 vn 0.111 -0.351 0.930 vn 0.107 -0.480 0.871 vn 0.675 -0.732 -0.096 vn 0.496 -0.844 0.206 vn -0.016 -0.986 0.167 vn 0.304 -0.948 0.097 vn 0.982 -0.082 0.171 vn 0.963 -0.002 0.269 vn 0.967 -0.134 0.216 vn 0.969 -0.177 0.175 vn 0.916 -0.244 0.319 vn 0.853 -0.341 0.394 vn 0.837 -0.365 0.407 vn 0.886 -0.281 0.368 vn 0.422 -0.292 0.858 vn 0.039 -0.571 0.820 vn -0.011 -0.399 0.917 vn 0.333 -0.349 0.876 vn 0.935 -0.237 0.263 vn 0.949 -0.159 0.273 vn 0.697 -0.213 0.685 vn 0.568 -0.123 0.814 vn -0.938 0.322 0.130 vn -0.609 -0.738 -0.291 vn -0.447 -0.857 -0.258 vn 0.259 -0.528 0.809 vn 0.137 -0.704 0.697 vn -0.107 -0.741 0.663 vn 0.647 -0.296 0.703 vn 0.603 -0.168 0.780 vn 0.836 0.072 0.545 vn 0.744 0.114 0.659 vn 0.701 0.149 0.698 vn 0.802 0.157 0.577 vn 0.823 -0.080 0.562 vn 0.690 0.142 0.710 vn 0.628 0.036 0.778 vn 0.894 -0.247 0.373 vn 0.624 -0.153 0.766 vn 0.661 0.110 0.742 vn 0.712 0.424 0.559 vn 0.701 0.284 0.654 vn 0.504 -0.050 0.862 vn 0.413 0.027 0.910 vn 0.569 0.046 0.821 vn 0.488 -0.134 0.862 vn 0.411 -0.180 0.894 vn 0.610 -0.024 0.792 vn 0.747 -0.250 0.616 vn 0.672 -0.313 0.671 vn 0.536 0.762 0.363 vn 0.559 0.768 0.312 vn 0.802 0.272 0.531 vn 0.618 0.206 0.759 vn 0.717 0.383 0.583 vn 0.780 0.464 0.420 vn 0.617 0.401 0.678 vn 0.658 0.397 0.640 vn 0.672 0.440 0.596 vn 0.501 0.314 0.807 vn 0.612 0.527 0.589 vn 0.679 0.320 0.661 vn 0.732 -0.406 -0.547 vn 0.885 -0.261 -0.386 vn 0.842 -0.347 0.414 vn 0.782 -0.349 0.517 vn 0.784 -0.368 0.500 vn 0.858 -0.453 0.244 vn 0.953 -0.279 0.118 vn 0.977 -0.189 0.104 vn 0.989 -0.110 0.102 vn 0.142 0.669 0.730 vn 0.300 0.652 0.696 vn 0.291 0.792 0.536 vn 0.143 0.821 0.553 vn 0.737 0.561 0.378 vn 0.716 0.470 0.515 vn 0.884 0.306 0.353 vn 0.898 0.354 0.263 vn 0.890 0.423 0.171 vn 0.174 0.078 0.982 vn 0.219 0.254 0.942 vn 0.665 -0.104 0.739 vn 0.671 0.390 0.631 vn 0.596 0.435 0.675 vn 0.636 0.467 0.614 vn 0.076 0.244 0.967 vn 0.261 0.437 0.861 vn 0.107 0.440 0.892 vn 0.011 0.082 0.997 vn 0.005 0.082 0.997 vn 0.028 -0.027 0.999 vn 0.073 -0.057 0.996 vn 0.006 0.228 0.974 vn 0.683 0.140 0.717 vn 0.724 0.233 0.650 vn 0.400 0.338 0.852 vn 0.270 0.126 0.955 vn 0.357 0.433 0.828 vn 0.503 0.485 0.716 vn 0.536 0.133 0.834 vn 0.416 -0.306 0.856 vn 0.337 0.097 0.937 vn 0.262 0.372 0.891 vn 0.425 0.075 0.902 vn 0.701 -0.147 0.698 vn -0.056 0.558 0.828 vn 0.005 0.605 0.796 vn 0.483 0.327 0.812 vn 0.497 0.276 0.823 vn 0.505 0.283 0.815 vn 0.340 -0.030 0.940 vn 0.332 0.066 0.941 vn 0.026 0.644 0.765 vn 0.021 0.538 0.843 vn 0.170 -0.012 0.985 vn 0.365 -0.067 0.929 vn 0.826 -0.173 0.537 vn 0.320 0.415 0.852 vn 0.384 0.739 0.554 vn 0.987 -0.013 0.160 vn 0.495 0.720 0.487 vn 0.490 0.830 0.268 vn 0.279 0.906 0.317 vn 0.431 0.899 -0.074 vn 0.267 0.957 -0.112 vn 0.283 0.953 0.107 vn 0.471 0.877 0.092 vn 0.132 0.985 0.113 vn 0.135 0.931 0.339 vn 0.190 -0.184 0.964 vn 0.292 -0.372 0.881 vn 0.307 -0.447 0.840 vn 0.393 -0.580 0.713 vn 0.524 -0.286 0.802 vn 0.380 -0.582 0.719 vn 0.697 0.212 0.685 vn 0.603 0.070 0.795 vn 0.558 -0.571 0.602 vn -0.089 -0.701 0.707 vn 0.794 -0.345 0.500 vn 0.345 -0.517 0.783 vn 0.481 0.101 0.871 vn 0.134 0.283 0.950 vn 0.113 -0.558 0.822 vn -0.073 -0.993 0.089 vn -0.041 -0.994 0.103 vn 0.084 -0.038 0.996 vn -0.012 -0.622 0.783 vn -0.002 0.254 0.967 vn 0.004 -0.997 0.079 vn 0.001 -0.832 -0.555 vn 0.477 -0.363 0.801 vn 0.414 0.160 0.896 vn 0.395 0.485 0.780 vn 0.611 0.484 0.627 vn 0.406 0.510 0.758 vn 0.375 0.498 0.782 vn 0.555 0.314 0.770 vn 0.349 0.411 0.842 vn 0.012 0.247 0.969 vn 0.002 -0.369 0.930 vn -0.003 0.509 0.861 vn 0.876 -0.041 0.481 vn 0.757 -0.214 0.618 vn 0.737 -0.048 0.674 vn 0.840 -0.012 0.542 vn 0.960 0.137 0.243 vn 0.969 0.103 0.226 vn 0.909 0.015 0.417 vn 0.906 0.015 0.423 vn 0.676 -0.276 0.683 vn 0.688 -0.223 0.691 vn 0.691 0.035 0.722 vn 0.719 -0.082 0.691 vn 0.964 0.062 0.260 vn 0.956 0.070 0.286 vn 0.953 0.037 0.300 vn -0.003 -0.415 0.910 vn -0.001 -0.380 0.925 vn 0.658 -0.419 0.625 vn 0.735 -0.421 0.532 vn 0.663 -0.303 0.685 vn 0.550 -0.321 0.771 vn 0.423 -0.236 0.875 vn 0.326 -0.294 0.899 vn 0.124 -0.396 0.910 vn 0.218 -0.177 0.960 vn 0.530 0.781 0.331 vn 0.167 0.827 0.537 vn 0.094 0.948 0.303 vn 0.313 0.934 0.171 vn -0.406 -0.892 0.201 vn -0.743 0.107 0.661 vn 0.455 0.704 0.546 vn 0.288 0.957 0.025 vn 0.245 0.958 0.150 vn 0.532 -0.027 0.846 vn 0.566 0.213 0.796 vn 0.508 0.208 0.836 vn 0.173 0.028 0.984 vn 0.371 0.122 0.921 vn 0.429 -0.045 0.902 vn 0.614 0.165 0.772 vn 0.737 0.157 0.657 vn 0.726 0.057 0.685 vn 0.662 0.061 0.747 vn 0.845 -0.523 -0.112 vn 0.845 -0.501 -0.185 vn 0.744 -0.668 0.009 vn 0.773 -0.630 0.079 vn 0.889 0.108 0.445 vn 0.899 0.077 0.430 vn 0.184 0.204 -0.961 vn 0.005 0.202 -0.979 vn -0.000 0.485 -0.875 vn 0.159 0.484 -0.861 vn 0.499 0.592 0.633 vn 0.305 0.950 0.065 vn -0.274 -0.953 -0.127 vn 0.245 -0.456 0.856 vn 0.083 -0.881 0.465 vn 0.435 -0.739 0.515 vn 0.504 -0.429 0.750 vn 0.818 -0.367 0.443 vn 0.933 -0.162 0.322 vn 0.872 0.029 0.489 vn 0.002 0.994 0.113 vn 0.133 0.983 -0.126 vn -0.001 0.992 -0.127 vn 0.280 0.892 -0.356 vn 0.126 0.916 -0.381 vn 0.210 0.974 -0.083 vn -0.082 0.663 0.745 vn -0.059 0.391 0.919 vn 0.111 0.992 -0.055 vn 0.081 -0.190 0.978 vn 0.035 0.076 0.996 vn 0.852 0.236 0.467 vn 0.775 0.219 0.593 vn 0.505 -0.109 0.856 vn 0.446 -0.314 0.838 vn 0.511 0.200 0.836 vn 0.623 -0.242 0.744 vn 0.436 -0.554 0.709 vn 0.599 -0.742 0.300 vn -0.036 0.177 0.984 vn -0.039 -0.159 0.987 vn 0.308 0.942 -0.135 vn 0.989 0.093 -0.111 vn 0.477 -0.259 0.840 vn 0.473 -0.423 0.773 vn 0.774 -0.329 0.541 vn 0.285 0.019 0.958 vn 0.350 0.101 0.931 vn 0.579 0.261 0.773 vn 0.298 0.015 0.954 vn 0.165 0.336 0.927 vn 0.577 0.511 0.636 vn 0.254 -0.834 0.490 vn -0.114 -0.925 0.363 vn 0.941 -0.280 -0.188 vn 0.460 -0.738 0.493 vn 0.740 -0.635 0.221 vn 0.003 0.529 0.849 vn 0.206 -0.427 -0.881 vn 0.497 -0.316 -0.808 vn 0.457 -0.144 -0.878 vn 0.179 -0.244 -0.953 vn -0.182 -0.980 -0.078 vn 0.342 -0.427 0.837 vn 0.424 -0.296 0.856 vn 0.896 -0.357 -0.264 vn 0.594 -0.104 0.798 vn 0.012 0.528 0.849 vn 0.042 0.469 0.882 vn 0.624 0.102 0.775 vn 0.324 -0.123 0.938 vn 0.202 -0.638 0.743 vn 0.714 0.512 0.477 vn 0.433 -0.511 0.742 vn -0.350 -0.708 0.613 vn 0.095 -0.410 0.907 vn 0.622 -0.593 0.512 vn 0.846 0.304 0.437 vn 0.582 -0.043 0.812 vn -0.226 -0.380 0.897 vn 0.215 0.644 0.734 vn 0.123 0.952 0.280 vn -0.004 0.956 0.293 vn -0.005 0.635 0.772 vn 0.325 -0.730 0.601 vn -0.017 -0.840 0.543 vn 0.017 -0.788 0.616 vn 0.294 -0.138 0.946 vn 0.214 0.401 0.891 vn -0.150 0.490 0.859 vn 0.573 -0.125 0.810 vn -0.134 0.957 0.258 vn 0.252 0.828 0.501 vn -0.673 0.643 0.364 vn 0.004 -0.960 0.279 vn 0.032 -0.991 0.133 vn 0.006 -0.908 0.419 vn 0.180 -0.980 0.086 vn 0.740 0.403 -0.538 vn 0.627 0.652 -0.426 vn 0.814 0.561 -0.149 vn 0.925 0.321 -0.206 vn 0.492 0.825 -0.280 vn 0.649 0.757 -0.076 vn 0.966 0.258 0.022 vn 0.864 0.501 0.053 vn 0.680 0.729 0.077 vn 0.272 -0.962 -0.032 vn 0.225 -0.968 0.111 vn 0.288 -0.510 0.810 vn 0.126 0.748 -0.651 vn 0.340 0.725 -0.598 vn 0.421 0.466 -0.778 vn 0.205 -0.458 -0.865 vn 0.489 -0.479 -0.729 vn 0.500 -0.523 -0.690 vn 0.210 -0.566 -0.798 vn 0.895 -0.322 -0.309 vn 0.759 -0.434 -0.485 vn 0.797 -0.287 -0.532 vn 0.937 -0.248 -0.245 vn -0.001 -0.238 -0.971 vn -0.000 -0.025 -1.000 vn 0.194 -0.025 -0.981 vn 0.201 -0.248 -0.948 vn 0.969 0.094 -0.229 vn 0.968 -0.101 -0.228 vn 0.814 -0.088 -0.575 vn 0.800 0.142 -0.583 vn 0.998 0.061 -0.010 vn 0.726 0.657 0.205 vn 0.000 -0.985 0.174 vn 0.985 -0.166 0.038 vn 0.955 -0.220 -0.200 vn 0.472 0.076 0.879 vn 0.343 -0.235 0.909 vn 0.464 -0.641 0.612 vn 0.578 -0.186 0.795 vn -0.189 -0.982 0.010 vn 0.004 0.938 0.345 vn 0.002 0.829 0.559 vn 0.445 0.232 0.865 vn 0.463 0.340 0.818 vn -0.116 0.983 0.143 vn 0.004 0.995 0.102 vn 0.978 0.204 0.044 vn -0.967 -0.216 -0.137 vn -0.911 -0.347 0.224 vn -0.728 0.350 0.590 vn 0.426 0.738 -0.523 vn 0.618 0.786 0.011 vn 0.151 0.857 -0.493 vn -0.333 0.912 -0.241 vn -0.277 0.956 0.095 vn -0.569 0.822 -0.032 vn -0.341 -0.671 -0.658 vn 0.161 -0.736 -0.657 vn 0.528 0.432 0.731 vn 0.586 0.105 0.803 vn 0.436 0.074 0.897 vn 0.621 0.267 0.737 vn 0.936 0.153 0.316 vn 0.999 -0.010 0.042 vn 0.826 0.281 -0.489 vn 0.775 0.178 -0.606 vn 0.995 -0.039 -0.095 vn 0.005 -0.414 0.910 vn 0.580 -0.243 0.778 vn 0.938 -0.339 -0.068 vn 0.925 -0.371 0.080 vn 0.888 -0.269 0.373 vn 0.923 -0.371 -0.106 vn 0.494 -0.274 -0.825 vn -0.001 -0.456 -0.890 vn -0.002 -0.569 -0.822 vn -0.001 -0.452 -0.892 vn -0.003 0.749 -0.663 vn -0.000 0.920 -0.391 vn -0.001 -0.280 -0.960 vn 0.470 0.194 -0.861 vn 0.965 -0.123 0.234 vn 0.400 -0.039 -0.916 vn 0.142 -0.166 -0.976 vn -0.000 -0.194 -0.981 vn 0.497 -0.049 -0.867 vn 0.998 0.042 0.045 vn 0.996 -0.037 -0.082 vn 0.009 0.433 0.901 vn 0.004 0.669 0.743 vn 0.955 0.004 0.296 vn 0.737 -0.001 0.675 vn 0.707 0.177 0.684 vn 0.484 0.627 0.610 vn 0.515 0.250 0.820 vn 0.360 0.121 0.925 vn -0.544 -0.573 0.613 vn 0.382 -0.114 0.917 vn 0.489 -0.108 0.866 vn -0.002 -0.670 0.742 vn 0.002 -0.394 0.919 vn -0.004 -0.168 0.986 vn 0.007 -0.109 0.994 vn 0.009 -0.519 0.855 vn 0.660 -0.118 0.742 vn 0.621 -0.127 0.774 vn 0.416 0.220 0.882 vn 0.946 0.046 0.322 vn 0.014 0.006 1.000 vn 0.569 0.184 0.802 vn 0.218 0.013 0.976 vn 0.044 0.087 0.995 vn -0.419 0.862 0.284 vn 0.647 -0.120 0.753 vn 0.954 -0.017 0.301 vn 0.352 0.140 -0.926 vn 0.095 -0.050 -0.994 vn 0.770 0.025 0.638 vn 0.000 -0.078 -0.997 vn 0.985 -0.172 0.009 vn 0.920 -0.340 0.195 vn 0.929 -0.331 -0.163 vn 0.969 -0.237 0.074 vn 0.969 -0.183 0.165 vn 0.801 0.160 0.577 vn 0.954 -0.021 0.301 vn 0.293 0.803 0.520 vn 0.977 0.170 0.129 vn 0.134 0.985 -0.104 vn 0.994 0.106 -0.036 vn 0.099 0.675 -0.731 vn 0.997 -0.079 -0.000 vn 0.197 0.126 -0.972 vn 0.978 -0.175 -0.110 vn 0.110 -0.321 -0.941 vn 0.939 -0.332 -0.089 vn 0.400 -0.789 -0.467 vn 0.171 -0.673 -0.720 vn 0.931 -0.336 -0.144 vn 0.854 -0.500 0.146 vn 0.161 -0.985 -0.069 vn 0.931 -0.304 -0.200 vn 0.813 -0.565 -0.143 vn 0.823 -0.546 0.154 vn 0.795 -0.387 0.467 vn 0.809 -0.168 0.563 vn 0.826 0.053 0.562 vn 0.925 0.261 0.275 vn 0.990 0.071 0.119 vn 0.951 0.129 0.281 vn 0.810 -0.147 0.568 vn 0.383 -0.603 0.699 vn 0.769 0.635 0.079 vn 0.786 0.352 0.508 vn 0.919 0.082 -0.386 vn 0.937 0.163 0.310 vn 0.974 -0.026 0.224 vn 0.787 0.550 0.279 vn 0.517 0.758 -0.397 vn 0.337 0.112 -0.935 vn 0.221 -0.300 -0.928 vn 0.395 -0.578 -0.714 vn 0.521 -0.711 -0.472 vn 0.432 -0.901 -0.043 vn 0.826 -0.520 0.218 vn 0.885 -0.217 0.412 vn 0.786 -0.107 0.609 vn 0.864 0.400 0.304 vn 0.954 0.061 0.293 vn 0.949 0.313 0.046 vn 0.991 0.028 -0.131 vn 0.945 -0.116 0.305 vn 0.970 -0.241 0.032 vn 0.946 -0.038 0.322 vn 0.886 -0.270 -0.376 vn 0.855 -0.272 -0.441 vn 0.952 -0.122 -0.281 vn 0.002 -0.883 0.469 vn -0.001 0.792 -0.611 vn -0.180 0.823 -0.539 vn -0.642 0.677 -0.360 vn -0.957 0.288 -0.031 vn -0.912 -0.300 0.281 vn -0.454 -0.866 0.207 vn -0.855 -0.043 0.517 vn -0.834 0.460 0.305 vn -0.242 0.911 0.334 vn -0.720 -0.667 -0.192 vn -0.762 -0.580 -0.288 vn 0.452 0.774 0.444 vn 0.857 0.048 0.513 vn 0.966 0.131 0.225 vn 0.211 0.953 0.219 vn -0.108 0.726 0.679 vn 0.021 0.946 0.324 vn 0.566 -0.691 -0.450 vn -0.068 0.939 -0.338 vn -0.261 -0.298 0.918 vn -0.200 -0.891 0.407 vn 0.124 -0.991 0.059 vn 0.913 -0.350 -0.211 vn 0.488 -0.838 0.244 vn 0.738 -0.593 0.322 vn 0.994 -0.060 -0.087 vn -0.000 -0.981 0.193 vn 0.000 0.974 0.227 vn -0.350 -0.016 0.936 vn 0.000 -0.017 1.000 vn 0.252 0.455 -0.854 vn 0.774 0.620 -0.127 vn 0.634 0.759 -0.148 vn 0.192 0.569 -0.800 vn 0.405 -0.094 0.909 vn 0.031 0.149 0.988 vn 0.360 0.283 0.889 vn 0.469 0.080 0.880 vn 0.769 0.452 0.452 vn 0.946 0.185 0.266 vn 0.893 0.181 0.413 vn 0.654 0.429 0.623 vn 0.506 0.610 0.610 vn 0.436 0.659 0.613 vn 0.160 0.558 0.814 vn -0.285 0.396 0.873 vn -0.223 0.539 0.812 vn 0.037 0.570 0.821 vn 0.623 0.727 -0.289 vn 0.456 0.738 0.497 vn 0.382 0.656 0.651 vn 0.278 0.687 0.671 vn 0.213 0.798 0.563 vn 0.171 0.844 0.508 vn 0.300 0.690 0.659 vn 0.144 0.793 0.591 vn 0.204 0.541 -0.816 vn -0.001 0.494 -0.870 vn 0.029 0.458 -0.888 vn 0.060 0.366 -0.929 vn 0.000 0.421 -0.907 vn 0.000 0.386 -0.922 vn 0.001 0.455 -0.891 vn 0.264 0.718 0.644 vn 0.307 0.317 -0.897 vn 0.056 0.164 -0.985 vn 0.717 0.079 0.693 vn 0.638 0.188 0.746 vn 0.000 0.202 -0.979 vn 0.006 -0.044 0.999 vn 0.001 0.405 0.914 vn 0.805 0.560 -0.194 vn 0.002 0.627 0.779 vn 0.010 -0.298 0.954 vn 0.124 0.870 -0.477 vn 0.488 0.530 -0.693 vn 0.566 0.756 -0.329 vn 0.213 0.932 -0.294 vn 0.245 -0.741 -0.626 vn 0.275 -0.782 -0.559 vn 0.044 -0.811 -0.584 vn -0.012 0.949 -0.315 vn 0.097 0.621 -0.778 vn 0.215 0.561 -0.799 vn -0.030 0.913 -0.407 vn 0.378 0.505 -0.776 vn 0.084 0.865 -0.495 vn 0.892 -0.451 -0.026 vn 0.803 -0.447 -0.394 vn 0.954 0.274 -0.123 vn 0.998 -0.024 0.066 vn 0.806 0.588 0.057 vn 0.351 0.936 -0.012 vn 0.662 -0.536 -0.524 vn 0.725 -0.630 -0.278 vn 0.524 -0.662 -0.536 vn 0.620 -0.585 -0.522 vn -0.694 -0.711 0.115 vn -0.621 -0.770 0.148 vn -0.805 -0.470 0.362 vn -0.819 -0.465 0.335 vn -0.680 -0.145 0.719 vn -0.763 -0.140 0.631 vn -0.840 -0.272 0.470 vn -0.773 -0.256 0.580 vn -0.763 -0.155 -0.627 vn -0.763 0.034 -0.645 vn -0.958 -0.057 -0.281 vn -0.910 -0.129 -0.393 vn -0.983 0.060 0.175 vn -0.980 0.096 0.177 vn -0.990 0.069 0.123 vn -0.996 0.023 0.083 vn -0.484 -0.649 0.587 vn -0.662 -0.717 0.220 vn -0.775 -0.388 0.499 vn -0.606 -0.384 0.697 vn -0.748 -0.556 0.363 vn -0.539 -0.840 0.071 vn -0.496 -0.849 0.183 vn -0.668 -0.580 0.467 vn -0.280 -0.913 0.296 vn -0.424 -0.897 0.125 vn -0.960 0.187 0.209 vn -0.965 0.222 0.143 vn -0.991 0.084 0.104 vn -0.979 0.104 0.175 vn -0.940 0.170 0.295 vn -0.909 0.107 0.404 vn -0.862 0.204 0.464 vn -0.896 0.204 0.395 vn -0.570 -0.493 0.658 vn -0.531 -0.465 0.709 vn -0.651 -0.181 0.737 vn -0.688 -0.376 0.620 vn -0.892 0.030 0.452 vn -0.827 0.122 0.549 vn -0.345 -0.706 0.619 vn -0.566 -0.461 0.684 vn -0.543 -0.393 0.742 vn -0.097 -0.841 0.533 vn -0.964 0.119 0.237 vn -0.950 0.158 0.268 vn -0.733 -0.024 0.679 vn -0.825 -0.117 0.552 vn -0.442 0.232 0.866 vn -0.605 0.237 0.760 vn -0.556 0.267 0.787 vn -0.350 0.172 0.921 vn -0.239 -0.096 0.966 vn -0.501 0.068 0.863 vn -0.679 0.342 0.650 vn -0.486 0.403 0.776 vn -0.211 -0.600 0.772 vn -0.123 -0.334 0.934 vn -0.052 -0.530 0.847 vn -0.176 -0.798 0.577 vn -0.131 -0.968 -0.212 vn -0.598 -0.684 -0.418 vn -0.205 -0.329 0.922 vn -0.374 -0.151 0.915 vn -0.117 -0.376 0.919 vn -0.246 -0.160 0.956 vn -0.126 -0.268 0.955 vn -0.137 -0.531 0.837 vn 0.062 -0.980 0.190 vn -0.478 -0.855 0.203 vn -0.669 -0.734 -0.114 vn -0.286 -0.955 0.083 vn -0.967 -0.136 0.215 vn -0.965 -0.005 0.263 vn -0.983 -0.085 0.164 vn -0.969 -0.182 0.170 vn -0.840 -0.358 0.408 vn -0.857 -0.341 0.386 vn -0.910 -0.256 0.326 vn -0.884 -0.284 0.371 vn 0.022 -0.449 0.893 vn -0.046 -0.611 0.791 vn -0.478 -0.294 0.827 vn -0.375 -0.338 0.863 vn -0.935 -0.243 0.259 vn -0.949 -0.164 0.269 vn -0.736 -0.207 0.645 vn -0.587 -0.108 0.802 vn 0.945 0.284 0.163 vn 0.592 -0.756 -0.279 vn 0.442 -0.866 -0.236 vn -0.053 -0.740 0.670 vn -0.228 -0.529 0.817 vn 0.170 -0.772 0.613 vn -0.609 -0.162 0.777 vn -0.663 -0.292 0.690 vn -0.713 0.145 0.686 vn -0.759 0.059 0.648 vn -0.825 0.047 0.564 vn -0.809 0.158 0.566 vn -0.637 0.025 0.770 vn -0.687 0.129 0.715 vn -0.821 -0.086 0.564 vn -0.891 -0.252 0.378 vn -0.721 0.489 0.490 vn -0.698 0.164 0.697 vn -0.646 -0.143 0.750 vn -0.712 0.352 0.608 vn -0.567 0.074 0.821 vn -0.464 0.032 0.885 vn -0.518 -0.023 0.855 vn -0.550 -0.128 0.825 vn -0.756 -0.260 0.601 vn -0.645 -0.025 0.764 vn -0.437 -0.158 0.885 vn -0.687 -0.310 0.657 vn -0.541 0.781 0.313 vn -0.565 0.780 0.270 vn -0.712 0.385 0.587 vn -0.611 0.201 0.765 vn -0.859 0.335 0.388 vn -0.775 0.474 0.417 vn -0.673 0.387 0.630 vn -0.628 0.400 0.668 vn -0.676 0.438 0.592 vn -0.698 0.309 0.646 vn -0.622 0.535 0.573 vn -0.511 0.327 0.795 vn -0.733 -0.405 -0.547 vn -0.884 -0.261 -0.388 vn -0.791 -0.366 0.490 vn -0.793 -0.344 0.502 vn -0.844 -0.347 0.408 vn -0.858 -0.453 0.243 vn -0.953 -0.280 0.116 vn -0.976 -0.193 0.100 vn -0.989 -0.113 0.096 vn -0.289 0.792 0.537 vn -0.301 0.654 0.693 vn -0.134 0.672 0.728 vn -0.137 0.821 0.554 vn -0.884 0.305 0.354 vn -0.716 0.471 0.515 vn -0.736 0.562 0.377 vn -0.897 0.355 0.265 vn -0.890 0.422 0.171 vn -0.179 0.082 0.981 vn -0.216 0.250 0.944 vn -0.661 -0.125 0.740 vn -0.679 0.371 0.633 vn -0.636 0.460 0.620 vn -0.594 0.426 0.682 vn -0.258 0.436 0.862 vn -0.070 0.240 0.968 vn -0.095 0.440 0.893 vn -0.011 0.089 0.996 vn -0.069 -0.049 0.996 vn -0.719 0.247 0.649 vn -0.673 0.172 0.719 vn -0.353 0.447 0.822 vn -0.270 0.134 0.954 vn -0.440 0.328 0.836 vn -0.511 0.490 0.706 vn -0.342 0.114 0.933 vn -0.435 -0.298 0.849 vn -0.552 0.158 0.818 vn -0.273 0.369 0.888 vn -0.705 -0.192 0.683 vn -0.357 0.088 0.930 vn -0.499 0.346 0.795 vn 0.009 0.585 0.811 vn 0.086 0.584 0.807 vn -0.348 -0.035 0.937 vn -0.516 0.299 0.803 vn -0.512 0.295 0.806 vn -0.339 0.070 0.938 vn -0.348 -0.070 0.935 vn -0.148 -0.003 0.989 vn -0.349 0.750 0.561 vn -0.322 0.418 0.849 vn -0.890 -0.163 0.425 vn -0.990 -0.001 0.144 vn -0.500 0.824 0.267 vn -0.501 0.717 0.484 vn -0.285 0.905 0.315 vn -0.282 0.954 0.103 vn -0.268 0.957 -0.114 vn -0.433 0.898 -0.078 vn -0.473 0.876 0.093 vn -0.131 0.985 0.111 vn -0.127 0.932 0.339 vn -0.211 -0.186 0.960 vn -0.293 -0.359 0.886 vn -0.344 -0.465 0.816 vn -0.382 -0.591 0.710 vn -0.525 -0.255 0.812 vn -0.598 0.089 0.796 vn -0.688 0.244 0.683 vn -0.344 -0.576 0.742 vn -0.544 -0.583 0.603 vn 0.098 -0.695 0.712 vn -0.805 -0.326 0.496 vn -0.132 0.306 0.943 vn -0.485 0.160 0.860 vn -0.351 -0.498 0.793 vn -0.141 -0.499 0.855 vn 0.065 -0.990 0.123 vn 0.037 -0.989 0.143 vn -0.065 -0.055 0.996 vn -0.473 -0.369 0.800 vn -0.396 0.179 0.900 vn -0.600 0.505 0.620 vn -0.387 0.499 0.776 vn -0.398 0.505 0.766 vn -0.358 0.488 0.796 vn -0.570 0.304 0.763 vn -0.317 0.412 0.854 vn -0.742 -0.129 0.658 vn -0.771 -0.207 0.602 vn -0.881 -0.036 0.472 vn -0.841 -0.052 0.538 vn -0.972 0.111 0.208 vn -0.961 0.151 0.230 vn -0.916 -0.004 0.402 vn -0.913 0.013 0.408 vn -0.689 0.026 0.724 vn -0.641 -0.316 0.699 vn -0.647 -0.304 0.699 vn -0.697 -0.094 0.711 vn -0.966 0.063 0.249 vn -0.963 0.075 0.259 vn -0.958 0.031 0.287 vn -0.681 -0.315 0.661 vn -0.745 -0.412 0.525 vn -0.666 -0.413 0.621 vn -0.548 -0.335 0.767 vn -0.107 -0.395 0.913 vn -0.299 -0.320 0.899 vn -0.418 -0.236 0.877 vn -0.210 -0.169 0.963 vn -0.090 0.952 0.291 vn -0.166 0.838 0.520 vn -0.523 0.797 0.302 vn -0.302 0.941 0.154 vn 0.408 -0.888 0.211 vn 0.735 0.117 0.668 vn -0.279 0.960 0.001 vn -0.468 0.706 0.531 vn -0.232 0.964 0.131 vn -0.555 -0.033 0.831 vn -0.517 0.199 0.833 vn -0.549 0.222 0.806 vn -0.376 0.125 0.918 vn -0.210 0.031 0.977 vn -0.435 -0.045 0.899 vn -0.739 0.154 0.656 vn -0.610 0.153 0.777 vn -0.663 0.041 0.748 vn -0.733 0.013 0.681 vn -0.744 -0.668 0.007 vn -0.845 -0.501 -0.187 vn -0.845 -0.522 -0.114 vn -0.774 -0.629 0.079 vn -0.897 0.040 0.440 vn -0.896 0.094 0.434 vn -0.179 0.204 -0.962 vn -0.157 0.488 -0.858 vn -0.506 0.590 0.630 vn -0.305 0.951 0.047 vn 0.267 -0.958 -0.102 vn -0.432 -0.745 0.509 vn -0.075 -0.883 0.463 vn -0.236 -0.454 0.859 vn -0.504 -0.423 0.753 vn -0.821 -0.351 0.449 vn -0.876 0.033 0.481 vn -0.934 -0.155 0.322 vn -0.134 0.983 -0.126 vn -0.128 0.916 -0.381 vn -0.284 0.891 -0.353 vn 0.055 0.396 0.917 vn 0.092 0.644 0.760 vn -0.199 0.976 -0.093 vn -0.109 0.991 -0.072 vn -0.039 0.079 0.996 vn -0.081 -0.191 0.978 vn -0.854 0.239 0.462 vn -0.774 0.223 0.593 vn -0.502 -0.119 0.856 vn -0.403 -0.420 0.813 vn -0.680 -0.255 0.687 vn -0.525 0.172 0.834 vn -0.376 -0.531 0.759 vn -0.576 -0.754 0.316 vn 0.040 0.159 0.986 vn 0.036 -0.180 0.983 vn -0.308 0.943 -0.129 vn -0.983 0.074 -0.170 vn -0.456 -0.445 0.771 vn -0.476 -0.297 0.828 vn -0.788 -0.316 0.528 vn -0.393 0.095 0.915 vn -0.308 0.018 0.951 vn -0.125 0.331 0.935 vn -0.283 0.033 0.959 vn -0.598 0.322 0.734 vn -0.575 0.559 0.598 vn -0.216 -0.852 0.476 vn 0.156 -0.927 0.342 vn -0.941 -0.282 -0.189 vn -0.739 -0.637 0.221 vn -0.469 -0.731 0.495 vn -0.458 -0.139 -0.878 vn -0.498 -0.315 -0.808 vn -0.210 -0.426 -0.880 vn -0.182 -0.243 -0.953 vn -0.334 -0.402 0.853 vn 0.221 -0.960 -0.173 vn -0.414 -0.366 0.834 vn -0.902 -0.373 -0.218 vn -0.632 -0.114 0.767 vn -0.642 0.122 0.757 vn -0.194 -0.651 0.734 vn -0.351 -0.095 0.931 vn -0.707 0.530 0.467 vn -0.087 -0.550 0.831 vn 0.352 -0.710 0.610 vn -0.500 -0.482 0.720 vn -0.653 -0.626 0.427 vn -0.856 0.328 0.399 vn -0.578 -0.029 0.816 vn 0.275 -0.432 0.859 vn -0.123 0.953 0.277 vn -0.228 0.657 0.719 vn -0.298 -0.735 0.609 vn -0.300 -0.179 0.937 vn -0.219 0.400 0.890 vn -0.587 -0.175 0.791 vn 0.175 0.460 0.870 vn -0.179 0.856 0.485 vn 0.114 0.959 0.259 vn 0.664 0.620 0.418 vn -0.026 -0.991 0.129 vn -0.184 -0.979 0.082 vn -0.810 0.566 -0.151 vn -0.628 0.654 -0.422 vn -0.741 0.405 -0.536 vn -0.924 0.322 -0.207 vn -0.493 0.823 -0.280 vn -0.648 0.758 -0.080 vn -0.966 0.258 0.022 vn -0.864 0.501 0.051 vn -0.679 0.730 0.075 vn -0.221 -0.970 0.105 vn -0.271 -0.962 -0.038 vn -0.376 -0.516 0.769 vn -0.124 0.748 -0.652 vn -0.339 0.727 -0.598 vn -0.420 0.469 -0.777 vn -0.500 -0.524 -0.690 vn -0.489 -0.481 -0.728 vn -0.206 -0.458 -0.865 vn -0.212 -0.565 -0.797 vn -0.893 -0.325 -0.312 vn -0.759 -0.435 -0.485 vn -0.796 -0.289 -0.532 vn -0.937 -0.249 -0.246 vn -0.193 -0.029 -0.981 vn -0.202 -0.249 -0.947 vn -0.814 -0.090 -0.574 vn -0.969 -0.102 -0.227 vn -0.969 0.093 -0.229 vn -0.801 0.142 -0.581 vn -0.998 0.061 -0.010 vn -0.718 0.664 0.209 vn -0.985 -0.168 0.036 vn -0.954 -0.222 -0.201 vn -0.451 0.039 0.891 vn -0.341 -0.253 0.905 vn -0.604 -0.144 0.784 vn -0.472 -0.641 0.606 vn 0.107 -0.991 0.080 vn -0.463 0.274 0.843 vn -0.002 0.997 0.081 vn 0.083 0.977 0.195 vn -0.466 0.366 0.805 vn -0.977 0.200 0.072 vn 0.916 -0.331 0.226 vn 0.929 -0.364 -0.067 vn 0.728 0.359 0.584 vn -0.419 0.737 -0.531 vn -0.638 0.769 0.043 vn -0.146 0.857 -0.494 vn 0.280 0.954 0.105 vn 0.343 0.909 -0.237 vn 0.546 0.838 -0.008 vn 0.342 -0.678 -0.651 vn -0.159 -0.734 -0.660 vn -0.545 0.363 0.756 vn -0.599 0.165 0.783 vn -0.447 0.066 0.892 vn -0.645 0.255 0.721 vn -0.936 0.164 0.311 vn -0.776 0.182 -0.604 vn -0.827 0.285 -0.485 vn -0.999 -0.012 0.041 vn -0.995 -0.037 -0.093 vn -0.586 -0.252 0.770 vn -0.926 -0.370 0.079 vn -0.938 -0.339 -0.067 vn -0.889 -0.266 0.372 vn -0.922 -0.372 -0.106 vn -0.493 -0.275 -0.825 vn -0.473 0.194 -0.860 vn -0.965 -0.122 0.231 vn -0.401 -0.036 -0.915 vn -0.143 -0.164 -0.976 vn -0.496 -0.052 -0.867 vn -0.996 -0.037 -0.083 vn -0.998 0.042 0.045 vn -0.950 0.012 0.313 vn -0.733 -0.008 0.681 vn -0.670 0.247 0.700 vn -0.408 0.697 0.589 vn -0.330 0.155 0.931 vn -0.517 0.244 0.821 vn 0.568 -0.625 0.535 vn -0.512 -0.108 0.852 vn -0.414 -0.112 0.903 vn -0.654 -0.140 0.743 vn -0.608 -0.086 0.789 vn -0.422 0.215 0.881 vn -0.943 0.031 0.332 vn -0.549 0.190 0.814 vn -0.193 0.018 0.981 vn 0.358 0.872 0.335 vn -0.651 -0.118 0.750 vn -0.954 -0.010 0.300 vn -0.352 0.145 -0.925 vn -0.095 -0.049 -0.994 vn -0.769 0.031 0.639 vn -0.929 -0.329 -0.171 vn -0.923 -0.336 0.190 vn -0.985 -0.174 0.005 vn -0.970 -0.234 0.068 vn -0.801 0.162 0.576 vn -0.969 -0.184 0.166 vn -0.293 0.803 0.519 vn -0.954 -0.019 0.300 vn -0.133 0.986 -0.105 vn -0.976 0.175 0.130 vn -0.098 0.675 -0.732 vn -0.993 0.112 -0.041 vn -0.197 0.127 -0.972 vn -0.997 -0.077 -0.003 vn -0.112 -0.322 -0.940 vn -0.978 -0.176 -0.109 vn -0.171 -0.674 -0.719 vn -0.397 -0.789 -0.468 vn -0.937 -0.337 -0.091 vn -0.929 -0.341 -0.146 vn -0.158 -0.985 -0.070 vn -0.854 -0.500 0.145 vn -0.814 -0.564 -0.141 vn -0.931 -0.306 -0.199 vn -0.824 -0.545 0.156 vn -0.797 -0.383 0.466 vn -0.811 -0.165 0.562 vn -0.824 0.053 0.564 vn -0.926 0.257 0.275 vn -0.991 0.062 0.118 vn -0.952 0.122 0.281 vn -0.383 -0.604 0.699 vn -0.810 -0.150 0.567 vn -0.784 0.355 0.509 vn -0.761 0.645 0.076 vn -0.920 0.079 -0.385 vn -0.975 -0.023 0.222 vn -0.937 0.166 0.308 vn -0.787 0.551 0.279 vn -0.517 0.758 -0.396 vn -0.337 0.112 -0.935 vn -0.221 -0.301 -0.928 vn -0.395 -0.579 -0.714 vn -0.520 -0.711 -0.473 vn -0.426 -0.904 -0.044 vn -0.824 -0.523 0.219 vn -0.886 -0.220 0.409 vn -0.863 0.404 0.303 vn -0.782 -0.104 0.615 vn -0.953 0.066 0.297 vn -0.949 0.312 0.046 vn -0.991 0.025 -0.134 vn -0.944 -0.116 0.308 vn -0.971 -0.237 0.041 vn -0.947 -0.041 0.318 vn -0.854 -0.274 -0.443 vn -0.885 -0.271 -0.378 vn -0.952 -0.121 -0.282 vn 0.180 0.824 -0.537 vn 0.642 0.679 -0.355 vn 0.956 0.291 -0.021 vn 0.453 -0.867 0.208 vn 0.910 -0.301 0.285 vn 0.854 -0.043 0.518 vn 0.833 0.459 0.308 vn 0.241 0.911 0.334 vn 0.731 -0.650 -0.206 vn 0.760 -0.585 -0.282 vn -0.814 0.019 0.580 vn -0.563 0.638 0.526 vn -0.925 -0.012 0.381 vn -0.214 0.952 0.217 vn 0.096 0.721 0.686 vn -0.027 0.945 0.325 vn -0.555 -0.678 -0.481 vn 0.062 0.937 -0.343 vn 0.240 -0.291 0.926 vn 0.184 -0.889 0.419 vn -0.126 -0.990 0.061 vn -0.889 -0.369 -0.271 vn -0.506 -0.832 0.229 vn -0.808 -0.443 0.388 vn -0.993 -0.084 0.087 vn 0.350 -0.016 0.937 vn -0.636 0.759 -0.140 vn -0.771 0.626 -0.115 vn -0.250 0.462 -0.851 vn -0.192 0.568 -0.801 vn -0.359 0.279 0.891 vn -0.026 0.144 0.989 vn -0.398 -0.100 0.912 vn -0.465 0.084 0.881 vn -0.895 0.186 0.405 vn -0.947 0.184 0.264 vn -0.761 0.459 0.458 vn -0.657 0.429 0.620 vn -0.426 0.660 0.618 vn -0.505 0.610 0.611 vn 0.223 0.536 0.814 vn 0.285 0.393 0.874 vn -0.163 0.555 0.815 vn -0.038 0.570 0.821 vn -0.628 0.723 -0.288 vn -0.458 0.737 0.497 vn -0.212 0.799 0.563 vn -0.278 0.687 0.672 vn -0.380 0.657 0.651 vn -0.170 0.846 0.506 vn -0.305 0.687 0.660 vn -0.144 0.795 0.589 vn 0.001 0.494 -0.870 vn -0.208 0.539 -0.816 vn -0.027 0.458 -0.888 vn -0.057 0.367 -0.929 vn -0.262 0.718 0.645 vn -0.054 0.163 -0.985 vn -0.306 0.325 -0.895 vn -0.643 0.181 0.744 vn -0.717 0.083 0.692 vn -0.800 0.573 -0.178 vn 0.296 -0.070 0.953 vn -0.319 -0.065 0.946 # 1258 vertex normals g head s 1 f 24/1/24 25/2/25 26/3/26 f 24/1/24 26/3/26 23/4/23 f 28/5/28 29/6/29 30/7/30 f 28/5/28 30/7/30 27/8/27 f 32/9/32 33/10/33 34/11/34 f 32/9/32 34/11/34 31/12/31 f 36/13/36 31/12/31 34/11/34 f 36/13/36 34/11/34 35/14/35 f 36/13/36 35/14/35 25/2/25 f 36/13/36 25/2/25 24/1/24 f 38/15/38 39/16/39 40/17/40 f 38/15/38 40/17/40 37/18/37 f 42/19/42 23/4/23 26/3/26 f 42/19/42 26/3/26 41/20/41 f 40/17/40 42/19/42 41/20/41 f 40/17/40 41/20/41 37/18/37 f 38/15/38 43/21/43 44/22/44 f 38/15/38 44/22/44 39/16/39 f 32/9/32 45/23/45 46/24/46 f 32/9/32 46/24/46 33/10/33 f 28/5/28 44/22/44 48/25/48 f 28/5/28 48/25/48 47/26/47 f 50/27/50 51/28/51 52/29/52 f 50/27/50 52/29/52 49/30/49 f 54/31/54 55/32/55 56/33/56 f 54/31/54 56/33/56 53/34/53 f 58/35/58 59/36/59 60/37/60 f 58/35/58 60/37/60 57/38/57 f 62/39/62 63/40/63 64/41/64 f 62/39/62 64/41/64 61/42/61 f 66/43/66 67/44/67 68/45/68 f 66/43/66 68/45/68 65/46/65 f 70/47/70 71/48/71 72/49/72 f 70/47/70 72/49/72 69/50/69 f 67/44/67 66/43/66 74/51/74 f 67/44/67 74/51/74 73/52/73 f 66/43/66 51/28/51 50/27/50 f 66/43/66 50/27/50 74/51/74 f 76/53/76 77/54/77 78/55/78 f 76/53/76 78/55/78 75/56/75 f 80/57/80 81/58/81 82/59/82 f 80/57/80 82/59/82 79/60/79 f 84/61/84 85/62/85 86/63/86 f 84/61/84 86/63/86 83/64/83 f 87/65/87 88/66/88 80/57/80 f 87/65/87 80/57/80 79/60/79 f 90/67/90 91/68/91 92/69/92 f 90/67/90 92/69/92 89/70/89 f 93/71/93 94/72/94 78/55/78 f 93/71/93 78/55/78 77/54/77 f 87/65/87 95/73/95 96/74/96 f 87/65/87 96/74/96 88/66/88 f 98/75/98 99/76/99 100/77/100 f 98/75/98 100/77/100 97/78/97 f 100/77/100 101/79/101 102/80/102 f 100/77/100 102/80/102 97/78/97 f 98/75/98 103/81/103 104/82/104 f 98/75/98 104/82/104 99/76/99 f 106/83/106 107/84/107 108/85/108 f 106/83/106 108/85/108 105/86/105 f 109/87/109 110/88/110 105/86/105 f 109/87/109 105/86/105 108/85/108 f 101/79/101 111/89/111 112/90/112 f 101/79/101 112/90/112 102/80/102 f 114/91/114 115/92/115 116/93/116 f 114/91/114 116/93/116 113/94/113 f 118/95/118 119/96/119 120/97/120 f 118/95/118 120/97/120 117/98/117 f 122/99/122 123/100/123 124/101/124 f 122/99/122 124/101/124 121/102/121 f 126/103/126 127/104/127 128/105/128 f 126/103/126 128/105/128 125/106/125 f 130/107/130 131/108/131 132/109/132 f 130/107/130 132/109/132 129/110/129 f 125/106/125 128/105/128 134/111/134 f 125/106/125 134/111/134 133/112/133 f 56/33/56 55/32/55 136/113/136 f 56/33/56 136/113/136 135/114/135 f 37/115/37 137/116/137 138/117/138 f 37/115/37 138/117/138 38/118/38 f 139/119/139 43/120/43 38/118/38 f 139/119/139 38/118/38 138/117/138 f 140/121/140 141/122/141 142/123/142 f 140/121/140 142/123/142 130/107/130 f 144/124/144 129/110/129 132/109/132 f 144/124/144 132/109/132 143/125/143 f 146/126/146 147/127/147 148/128/148 f 146/126/146 148/128/148 145/129/145 f 150/130/150 151/131/151 54/31/54 f 150/130/150 54/31/54 149/132/149 f 54/31/54 53/34/53 152/133/152 f 54/31/54 152/133/152 149/132/149 f 154/134/154 155/135/155 156/136/156 f 154/134/154 156/136/156 153/137/153 f 158/138/158 159/139/159 160/140/160 f 158/138/158 160/140/160 157/141/157 f 162/142/162 163/143/163 164/144/164 f 162/142/162 164/144/164 161/145/161 f 129/110/129 144/124/144 157/141/157 f 129/110/129 157/141/157 160/140/160 f 156/136/156 155/135/155 166/146/166 f 156/136/156 166/146/166 165/147/165 f 168/148/168 169/149/169 170/150/170 f 168/148/168 170/150/170 167/151/167 f 171/152/171 172/153/172 173/154/173 f 171/152/171 173/154/173 169/149/169 f 175/155/175 176/156/176 171/152/171 f 175/155/175 171/152/171 174/157/174 f 59/36/59 177/158/177 178/159/178 f 59/36/59 178/159/178 60/37/60 f 180/160/180 181/161/181 49/30/49 f 180/160/180 49/30/49 179/162/179 f 127/104/127 52/29/52 182/163/182 f 127/104/127 182/163/182 128/105/128 f 134/111/134 183/164/183 184/165/184 f 134/111/134 184/165/184 124/101/124 f 185/166/185 121/102/121 124/101/124 f 185/166/185 124/101/124 184/165/184 f 187/167/187 188/168/188 189/169/189 f 187/167/187 189/169/189 186/170/186 f 191/171/191 192/172/192 193/173/193 f 191/171/191 193/173/193 190/174/190 f 76/53/76 194/175/194 193/173/193 f 76/53/76 193/173/193 77/54/77 f 100/77/100 99/76/99 196/176/196 f 100/77/100 196/176/196 195/177/195 f 176/156/176 175/155/175 198/178/198 f 176/156/176 198/178/198 197/179/197 f 199/180/199 200/181/200 173/154/173 f 199/180/199 173/154/173 172/153/172 f 196/176/196 202/182/202 203/183/203 f 196/176/196 203/183/203 201/184/201 f 205/185/205 206/186/206 207/187/207 f 205/185/205 207/187/207 204/188/204 f 208/189/208 205/185/205 204/188/204 f 208/189/208 204/188/204 201/184/201 f 210/190/210 97/78/97 102/80/102 f 210/190/210 102/80/102 209/191/209 f 79/60/79 210/190/210 209/191/209 f 79/60/79 209/191/209 87/65/87 f 212/192/212 213/193/213 214/194/214 f 212/192/212 214/194/214 211/195/211 f 216/196/216 217/197/217 218/198/218 f 216/196/216 218/198/218 215/199/215 f 220/200/220 216/196/216 215/199/215 f 220/200/220 215/199/215 219/201/219 f 222/202/222 223/203/223 218/198/218 f 222/202/222 218/198/218 221/204/221 f 225/205/225 226/206/226 227/207/227 f 225/205/225 227/207/227 224/208/224 f 222/202/222 221/204/221 229/209/229 f 222/202/222 229/209/229 228/210/228 f 230/211/230 231/212/231 220/200/220 f 230/211/230 220/200/220 219/201/219 f 227/207/227 226/206/226 231/212/231 f 227/207/227 231/212/231 230/211/230 f 233/213/233 234/214/234 235/215/235 f 233/213/233 235/215/235 232/216/232 f 186/170/186 203/183/203 202/182/202 f 186/170/186 202/182/202 187/167/187 f 236/217/236 237/218/237 238/219/238 f 236/217/236 238/219/238 188/168/188 f 240/220/240 241/221/241 242/222/242 f 240/220/240 242/222/242 239/223/239 f 241/221/241 243/224/243 244/225/244 f 241/221/241 244/225/244 238/219/238 f 245/226/245 101/79/101 100/77/100 f 245/226/245 100/77/100 195/177/195 f 195/177/195 204/188/204 207/187/207 f 195/177/195 207/187/207 245/226/245 f 111/89/111 246/227/246 247/228/247 f 111/89/111 247/228/247 115/92/115 f 141/122/141 140/121/140 249/229/249 f 141/122/141 249/229/249 248/230/248 f 251/231/251 252/232/252 253/233/253 f 251/231/251 253/233/253 250/234/250 f 254/235/254 118/95/118 255/236/255 f 254/235/254 255/236/255 217/197/217 f 257/237/257 258/238/258 259/239/259 f 257/237/257 259/239/259 256/240/256 f 256/240/256 259/239/259 261/241/261 f 256/240/256 261/241/261 260/242/260 f 260/242/260 261/241/261 30/243/30 f 260/242/260 30/243/30 29/244/29 f 218/198/218 217/197/217 262/245/262 f 218/198/218 262/245/262 221/204/221 f 259/239/259 258/238/258 264/246/264 f 259/239/259 264/246/264 263/247/263 f 266/248/266 30/243/30 261/241/261 f 266/248/266 261/241/261 265/249/265 f 253/233/253 252/232/252 268/250/268 f 253/233/253 268/250/268 267/251/267 f 270/252/270 200/181/200 271/253/271 f 270/252/270 271/253/271 269/254/269 f 199/180/199 272/255/272 271/253/271 f 199/180/199 271/253/271 200/181/200 f 199/180/199 273/256/273 274/257/274 f 199/180/199 274/257/274 272/255/272 f 276/258/276 267/251/267 268/250/268 f 276/258/276 268/250/268 275/259/275 f 275/259/275 268/250/268 269/254/269 f 275/259/275 269/254/269 277/260/277 f 93/71/93 77/54/77 193/173/193 f 93/71/93 193/173/193 192/172/192 f 279/261/279 280/262/280 281/263/281 f 279/261/279 281/263/281 278/264/278 f 278/264/278 88/66/88 96/74/96 f 278/264/278 96/74/96 279/261/279 f 282/265/282 283/266/283 62/39/62 f 282/265/282 62/39/62 94/72/94 f 281/263/281 284/267/284 285/268/285 f 281/263/281 285/268/285 278/264/278 f 287/269/287 288/270/288 289/271/289 f 287/269/287 289/271/289 286/272/286 f 63/40/63 62/39/62 283/266/283 f 63/40/63 283/266/283 290/273/290 f 283/266/283 291/274/291 292/275/292 f 283/266/283 292/275/292 290/273/290 f 293/276/293 294/277/294 68/45/68 f 293/276/293 68/45/68 67/44/67 f 296/278/296 297/279/297 298/280/298 f 296/278/296 298/280/298 295/281/295 f 300/282/300 301/283/301 302/284/302 f 300/282/300 302/284/302 299/285/299 f 304/286/304 305/287/305 306/288/306 f 304/286/304 306/288/306 303/289/303 f 138/117/138 137/116/137 308/290/308 f 138/117/138 308/290/308 307/291/307 f 165/147/165 310/292/310 311/293/311 f 165/147/165 311/293/311 309/294/309 f 312/295/312 55/32/55 54/31/54 f 312/295/312 54/31/54 151/131/151 f 314/296/314 151/131/151 150/130/150 f 314/296/314 150/130/150 313/297/313 f 315/298/315 316/299/316 227/207/227 f 315/298/315 227/207/227 230/211/230 f 136/113/136 317/300/317 158/138/158 f 136/113/136 158/138/158 157/141/157 f 319/301/319 148/128/148 147/127/147 f 319/301/319 147/127/147 318/302/318 f 320/303/320 321/304/321 147/127/147 f 320/303/320 147/127/147 146/126/146 f 323/305/323 324/306/324 325/307/325 f 323/305/323 325/307/325 322/308/322 f 80/57/80 88/66/88 278/264/278 f 80/57/80 278/264/278 285/268/285 f 327/309/327 145/129/145 148/128/148 f 327/309/327 148/128/148 326/310/326 f 279/261/279 286/272/286 289/271/289 f 279/261/279 289/271/289 280/262/280 f 329/311/329 330/312/330 331/313/331 f 329/311/329 331/313/331 328/314/328 f 187/167/187 202/182/202 104/82/104 f 187/167/187 104/82/104 332/315/332 f 236/217/236 332/315/332 191/171/191 f 236/217/236 191/171/191 190/174/190 f 165/147/165 166/146/166 333/316/333 f 165/147/165 333/316/333 310/292/310 f 139/119/139 334/317/334 48/318/48 f 139/119/139 48/318/48 43/120/43 f 336/319/336 337/320/337 338/321/338 f 336/319/336 338/321/338 335/322/335 f 51/28/51 324/306/324 182/163/182 f 51/28/51 182/163/182 52/29/52 f 339/323/339 126/103/126 53/34/53 f 339/323/339 53/34/53 56/33/56 f 340/324/340 341/325/341 149/132/149 f 340/324/340 149/132/149 152/133/152 f 243/224/243 343/326/343 344/327/344 f 243/224/243 344/327/344 342/328/342 f 346/329/346 343/326/343 240/220/240 f 346/329/346 240/220/240 345/330/345 f 348/331/348 349/332/349 350/333/350 f 348/331/348 350/333/350 347/334/347 f 351/335/351 352/336/352 213/193/213 f 351/335/351 213/193/213 212/192/212 f 128/105/128 182/163/182 183/164/183 f 128/105/128 183/164/183 134/111/134 f 103/81/103 98/75/98 354/337/354 f 103/81/103 354/337/354 353/338/353 f 114/91/114 113/94/113 356/339/356 f 114/91/114 356/339/356 355/340/355 f 358/341/358 197/179/197 198/178/198 f 358/341/358 198/178/198 357/342/357 f 107/84/107 359/343/359 360/344/360 f 107/84/107 360/344/360 108/85/108 f 348/331/348 361/345/361 362/346/362 f 348/331/348 362/346/362 349/332/349 f 347/334/347 363/347/363 234/214/234 f 347/334/347 234/214/234 348/331/348 f 220/200/220 231/212/231 167/151/167 f 220/200/220 167/151/167 364/348/364 f 153/137/153 366/349/366 300/282/300 f 153/137/153 300/282/300 365/350/365 f 295/281/295 72/49/72 71/48/71 f 295/281/295 71/48/71 296/278/296 f 179/162/179 339/323/339 367/351/367 f 179/162/179 367/351/367 180/160/180 f 368/352/368 369/353/369 158/138/158 f 368/352/368 158/138/158 317/300/317 f 317/300/317 136/113/136 55/32/55 f 317/300/317 55/32/55 312/295/312 f 371/354/371 372/355/372 373/356/373 f 371/354/371 373/356/373 370/357/370 f 41/358/41 26/359/26 306/288/306 f 41/358/41 306/288/306 305/287/305 f 305/287/305 137/116/137 37/115/37 f 305/287/305 37/115/37 41/358/41 f 248/230/248 374/360/374 375/361/375 f 248/230/248 375/361/375 141/122/141 f 66/43/66 325/307/325 324/306/324 f 66/43/66 324/306/324 51/28/51 f 183/164/183 323/305/323 376/362/376 f 183/164/183 376/362/376 184/165/184 f 378/363/378 253/233/253 267/251/267 f 378/363/378 267/251/267 377/364/377 f 269/254/269 271/253/271 379/365/379 f 269/254/269 379/365/379 277/260/277 f 381/366/381 382/367/382 383/368/383 f 381/366/381 383/368/383 380/369/380 f 384/370/384 385/371/385 105/86/105 f 384/370/384 105/86/105 110/88/110 f 105/86/105 385/371/385 386/372/386 f 105/86/105 386/372/386 106/83/106 f 360/344/360 387/373/387 109/87/109 f 360/344/360 109/87/109 108/85/108 f 181/161/181 180/160/180 164/144/164 f 181/161/181 164/144/164 163/143/163 f 365/350/365 388/374/388 154/134/154 f 365/350/365 154/134/154 153/137/153 f 168/148/168 167/151/167 231/212/231 f 168/148/168 231/212/231 226/206/226 f 81/58/81 291/274/291 283/266/283 f 81/58/81 283/266/283 282/265/282 f 272/255/272 389/375/389 379/365/379 f 272/255/272 379/365/379 271/253/271 f 274/257/274 390/376/390 389/375/389 f 274/257/274 389/375/389 272/255/272 f 139/119/139 375/361/375 374/360/374 f 139/119/139 374/360/374 334/317/334 f 391/377/391 366/349/366 153/137/153 f 391/377/391 153/137/153 156/136/156 f 392/378/392 393/379/393 366/349/366 f 392/378/392 366/349/366 391/377/391 f 173/154/173 200/181/200 270/252/270 f 173/154/173 270/252/270 394/380/394 f 301/283/301 300/282/300 366/349/366 f 301/283/301 366/349/366 393/379/393 f 396/381/396 397/382/397 398/383/398 f 396/381/396 398/383/398 395/384/395 f 399/385/399 364/348/364 167/151/167 f 399/385/399 167/151/167 170/150/170 f 394/380/394 251/231/251 399/385/399 f 394/380/394 399/385/399 170/150/170 f 270/252/270 252/232/252 251/231/251 f 270/252/270 251/231/251 394/380/394 f 102/80/102 112/90/112 400/386/400 f 102/80/102 400/386/400 209/191/209 f 131/108/131 401/387/401 372/355/372 f 131/108/131 372/355/372 371/354/371 f 391/377/391 156/136/156 165/147/165 f 391/377/391 165/147/165 309/294/309 f 403/388/403 404/389/404 405/390/405 f 403/388/403 405/390/405 402/391/402 f 402/391/402 392/378/392 391/377/391 f 402/391/402 391/377/391 309/294/309 f 35/392/35 310/292/310 333/316/333 f 35/392/35 333/316/333 25/393/25 f 35/392/35 34/394/34 311/293/311 f 35/392/35 311/293/311 310/292/310 f 34/394/34 33/395/33 403/388/403 f 34/394/34 403/388/403 311/293/311 f 406/396/406 262/245/262 217/197/217 f 406/396/406 217/197/217 255/236/255 f 377/364/377 407/397/407 408/398/408 f 377/364/377 408/398/408 406/396/406 f 117/98/117 378/363/378 255/236/255 f 117/98/117 255/236/255 118/95/118 f 270/252/270 269/254/269 268/250/268 f 270/252/270 268/250/268 252/232/252 f 304/286/304 303/289/303 373/356/373 f 304/286/304 373/356/373 372/355/372 f 362/346/362 409/399/409 410/400/410 f 362/346/362 410/400/410 349/332/349 f 411/401/411 412/402/412 89/70/89 f 411/401/411 89/70/89 92/69/92 f 414/403/414 411/401/411 415/404/415 f 414/403/414 415/404/415 413/405/413 f 417/406/417 336/319/336 418/407/418 f 417/406/417 418/407/418 416/408/416 f 337/320/337 419/409/419 69/50/69 f 337/320/337 69/50/69 72/49/72 f 421/410/421 422/411/422 423/412/423 f 421/410/421 423/412/423 420/413/420 f 421/410/421 424/414/424 425/415/425 f 421/410/421 425/415/425 422/411/422 f 423/412/423 422/411/422 427/416/427 f 423/412/423 427/416/427 426/417/426 f 239/223/239 242/222/242 428/418/428 f 239/223/239 428/418/428 425/415/425 f 430/419/430 73/52/73 74/51/74 f 430/419/430 74/51/74 429/420/429 f 70/47/70 69/50/69 419/409/419 f 70/47/70 419/409/419 429/420/429 f 247/228/247 431/421/431 116/93/116 f 247/228/247 116/93/116 115/92/115 f 346/329/346 345/330/345 433/422/433 f 346/329/346 433/422/433 432/423/432 f 433/422/433 421/410/421 420/413/420 f 433/422/433 420/413/420 434/424/434 f 436/425/436 437/426/437 438/427/438 f 436/425/436 438/427/438 435/428/435 f 437/426/437 381/366/381 380/369/380 f 437/426/437 380/369/380 438/427/438 f 178/159/178 177/158/177 440/429/440 f 178/159/178 440/429/440 439/430/439 f 440/429/440 441/431/441 442/432/442 f 440/429/440 442/432/442 439/430/439 f 444/433/444 445/434/445 446/435/446 f 444/433/444 446/435/446 443/436/443 f 324/306/324 323/305/323 183/164/183 f 324/306/324 183/164/183 182/163/182 f 213/193/213 352/336/352 357/342/357 f 213/193/213 357/342/357 198/178/198 f 214/194/214 175/155/175 174/157/174 f 214/194/214 174/157/174 225/205/225 f 448/437/448 449/438/449 450/439/450 f 448/437/448 450/439/450 447/440/447 f 423/412/423 426/417/426 451/441/451 f 423/412/423 451/441/451 447/440/447 f 75/56/75 451/441/451 426/417/426 f 75/56/75 426/417/426 76/53/76 f 78/55/78 94/72/94 62/39/62 f 78/55/78 62/39/62 61/42/61 f 286/272/286 86/63/86 85/62/85 f 286/272/286 85/62/85 287/269/287 f 95/73/95 87/65/87 209/191/209 f 95/73/95 209/191/209 400/386/400 f 237/218/237 452/442/452 428/418/428 f 237/218/237 428/418/428 242/222/242 f 190/174/190 193/173/193 194/175/194 f 190/174/190 194/175/194 452/442/452 f 237/218/237 236/217/236 190/174/190 f 237/218/237 190/174/190 452/442/452 f 79/60/79 82/59/82 354/337/354 f 79/60/79 354/337/354 210/190/210 f 286/272/286 279/261/279 96/74/96 f 286/272/286 96/74/96 86/63/86 f 430/419/430 417/406/417 416/408/416 f 430/419/430 416/408/416 453/443/453 f 338/321/338 295/281/295 298/280/298 f 338/321/338 298/280/298 299/285/299 f 57/38/57 60/37/60 455/444/455 f 57/38/57 455/444/455 454/445/454 f 212/192/212 456/446/456 457/447/457 f 212/192/212 457/447/457 351/335/351 f 83/64/83 355/340/355 356/339/356 f 83/64/83 356/339/356 84/61/84 f 142/123/142 141/122/141 375/361/375 f 142/123/142 375/361/375 307/291/307 f 401/387/401 142/123/142 307/291/307 f 401/387/401 307/291/307 308/290/308 f 459/448/459 257/237/257 256/240/256 f 459/448/459 256/240/256 458/449/458 f 228/210/228 264/246/264 258/238/258 f 228/210/228 258/238/258 222/202/222 f 256/240/256 260/242/260 460/450/460 f 256/240/256 460/450/460 458/449/458 f 460/450/460 260/242/260 29/244/29 f 460/450/460 29/244/29 47/451/47 f 263/247/263 265/249/265 261/241/261 f 263/247/263 261/241/261 259/239/259 f 461/452/461 462/453/462 189/169/189 f 461/452/461 189/169/189 244/225/244 f 227/207/227 316/299/316 463/454/463 f 227/207/227 463/454/463 224/208/224 f 465/455/465 466/456/466 410/400/410 f 465/455/465 410/400/410 464/457/464 f 90/67/90 386/372/386 385/371/385 f 90/67/90 385/371/385 91/68/91 f 233/213/233 361/345/361 348/331/348 f 233/213/233 348/331/348 234/214/234 f 235/215/235 234/214/234 363/347/363 f 235/215/235 363/347/363 467/458/467 f 338/321/338 337/320/337 72/49/72 f 338/321/338 72/49/72 295/281/295 f 338/321/338 299/285/299 302/284/302 f 338/321/338 302/284/302 335/322/335 f 468/459/468 469/460/469 470/461/470 f 468/459/468 470/461/470 415/404/415 f 347/334/347 471/462/471 472/463/472 f 347/334/347 472/463/472 363/347/363 f 471/462/471 347/334/347 350/333/350 f 471/462/471 350/333/350 473/464/473 f 465/455/465 475/465/475 476/466/476 f 465/455/465 476/466/476 474/467/474 f 384/370/384 110/88/110 478/468/478 f 384/370/384 478/468/478 477/469/477 f 414/403/414 479/470/479 412/402/412 f 414/403/414 412/402/412 411/401/411 f 288/270/288 287/269/287 412/402/412 f 288/270/288 412/402/412 479/470/479 f 85/62/85 84/61/84 90/67/90 f 85/62/85 90/67/90 89/70/89 f 386/372/386 356/339/356 113/94/113 f 386/372/386 113/94/113 106/83/106 f 232/216/232 358/341/358 357/342/357 f 232/216/232 357/342/357 233/213/233 f 297/279/297 296/278/296 181/161/181 f 297/279/297 181/161/181 163/143/163 f 419/409/419 337/320/337 336/319/336 f 419/409/419 336/319/336 417/406/417 f 49/30/49 52/29/52 127/104/127 f 49/30/49 127/104/127 179/162/179 f 26/359/26 25/393/25 333/316/333 f 26/359/26 333/316/333 306/288/306 f 371/354/371 370/357/370 162/142/162 f 371/354/371 162/142/162 161/145/161 f 258/238/258 257/237/257 223/203/223 f 258/238/258 223/203/223 222/202/222 f 257/237/257 459/448/459 480/471/480 f 257/237/257 480/471/480 223/203/223 f 211/195/211 214/194/214 225/205/225 f 211/195/211 225/205/225 224/208/224 f 316/299/316 481/472/481 314/296/314 f 316/299/316 314/296/314 463/454/463 f 171/152/171 169/149/169 168/148/168 f 171/152/171 168/148/168 174/157/174 f 273/256/273 199/180/199 172/153/172 f 273/256/273 172/153/172 482/473/482 f 168/148/168 226/206/226 225/205/225 f 168/148/168 225/205/225 174/157/174 f 245/226/245 246/227/246 111/89/111 f 245/226/245 111/89/111 101/79/101 f 114/91/114 112/90/112 111/89/111 f 114/91/114 111/89/111 115/92/115 f 210/190/210 354/337/354 98/75/98 f 210/190/210 98/75/98 97/78/97 f 431/421/431 358/341/358 232/216/232 f 431/421/431 232/216/232 359/343/359 f 235/215/235 360/344/360 359/343/359 f 235/215/235 359/343/359 232/216/232 f 360/344/360 235/215/235 467/458/467 f 360/344/360 467/458/467 387/373/387 f 81/58/81 282/265/282 483/474/483 f 81/58/81 483/474/483 82/59/82 f 485/475/485 486/476/486 487/477/487 f 485/475/485 487/477/487 484/478/484 f 489/479/489 68/45/68 294/277/294 f 489/479/489 294/277/294 488/480/488 f 491/481/491 454/445/454 455/444/455 f 491/481/491 455/444/455 490/482/490 f 154/134/154 370/357/370 373/356/373 f 154/134/154 373/356/373 155/135/155 f 491/481/491 322/308/322 325/307/325 f 491/481/491 325/307/325 492/483/492 f 491/481/491 490/482/490 493/484/493 f 491/481/491 493/484/493 322/308/322 f 436/425/436 435/428/435 446/435/446 f 436/425/436 446/435/446 494/485/494 f 495/486/495 496/487/496 438/427/438 f 495/486/495 438/427/438 380/369/380 f 496/487/496 497/488/497 435/428/435 f 496/487/496 435/428/435 438/427/438 f 331/313/331 330/312/330 498/489/498 f 331/313/331 498/489/498 432/423/432 f 499/490/499 346/329/346 432/423/432 f 499/490/499 432/423/432 498/489/498 f 380/369/380 383/368/383 500/491/500 f 380/369/380 500/491/500 495/486/495 f 501/492/501 328/314/328 331/313/331 f 501/492/501 331/313/331 434/424/434 f 499/490/499 344/327/344 343/326/343 f 499/490/499 343/326/343 346/329/346 f 492/483/492 502/493/502 454/445/454 f 492/483/492 454/445/454 491/481/491 f 454/445/454 502/493/502 487/477/487 f 454/445/454 487/477/487 57/38/57 f 486/476/486 58/35/58 57/38/57 f 486/476/486 57/38/57 487/477/487 f 58/35/58 486/476/486 503/494/503 f 58/35/58 503/494/503 382/367/382 f 383/368/383 504/495/504 505/496/505 f 383/368/383 505/496/505 500/491/500 f 447/440/447 450/439/450 420/413/420 f 447/440/447 420/413/420 423/412/423 f 329/311/329 328/314/328 445/434/445 f 329/311/329 445/434/445 444/433/444 f 450/439/450 449/438/449 506/497/506 f 450/439/450 506/497/506 501/492/501 f 507/498/507 508/499/508 451/441/451 f 507/498/507 451/441/451 75/56/75 f 99/76/99 104/82/104 202/182/202 f 99/76/99 202/182/202 196/176/196 f 509/500/509 208/189/208 201/184/201 f 509/500/509 201/184/201 203/183/203 f 201/184/201 204/188/204 195/177/195 f 201/184/201 195/177/195 196/176/196 f 462/453/462 510/501/510 186/170/186 f 462/453/462 186/170/186 189/169/189 f 203/183/203 186/170/186 510/501/510 f 203/183/203 510/501/510 509/500/509 f 148/128/148 319/301/319 341/325/341 f 148/128/148 341/325/341 326/310/326 f 326/310/326 341/325/341 340/324/340 f 326/310/326 340/324/340 511/502/511 f 123/100/123 511/502/511 340/324/340 f 123/100/123 340/324/340 133/112/133 f 71/48/71 49/30/49 181/161/181 f 71/48/71 181/161/181 296/278/296 f 154/134/154 388/374/388 162/142/162 f 154/134/154 162/142/162 370/357/370 f 155/135/155 373/356/373 303/289/303 f 155/135/155 303/289/303 166/146/166 f 166/146/166 303/289/303 306/288/306 f 166/146/166 306/288/306 333/316/333 f 512/503/512 320/303/320 289/271/289 f 512/503/512 289/271/289 288/270/288 f 479/470/479 414/403/414 514/504/514 f 479/470/479 514/504/514 513/505/513 f 414/403/414 413/405/413 475/465/475 f 414/403/414 475/465/475 514/504/514 f 513/505/513 512/503/512 288/270/288 f 513/505/513 288/270/288 479/470/479 f 191/171/191 103/81/103 353/338/353 f 191/171/191 353/338/353 192/172/192 f 332/315/332 104/82/104 103/81/103 f 332/315/332 103/81/103 191/171/191 f 82/59/82 483/474/483 353/338/353 f 82/59/82 353/338/353 354/337/354 f 83/64/83 86/63/86 96/74/96 f 83/64/83 96/74/96 95/73/95 f 83/64/83 95/73/95 400/386/400 f 83/64/83 400/386/400 355/340/355 f 355/340/355 400/386/400 112/90/112 f 355/340/355 112/90/112 114/91/114 f 144/124/144 135/114/135 136/113/136 f 144/124/144 136/113/136 157/141/157 f 298/280/298 365/350/365 300/282/300 f 298/280/298 300/282/300 299/285/299 f 298/280/298 297/279/297 388/374/388 f 298/280/298 388/374/388 365/350/365 f 367/351/367 143/125/143 164/144/164 f 367/351/367 164/144/164 180/160/180 f 515/506/515 516/507/516 219/201/219 f 515/506/515 219/201/219 215/199/215 f 254/235/254 217/197/217 216/196/216 f 254/235/254 216/196/216 517/508/517 f 398/383/398 364/348/364 399/385/399 f 398/383/398 399/385/399 395/384/395 f 398/383/398 397/382/397 517/508/517 f 398/383/398 517/508/517 216/196/216 f 518/509/518 519/510/519 246/227/246 f 518/509/518 246/227/246 245/226/245 f 319/301/319 150/130/150 149/132/149 f 319/301/319 149/132/149 341/325/341 f 429/420/429 419/409/419 417/406/417 f 429/420/429 417/406/417 430/419/430 f 33/395/33 46/511/46 404/389/404 f 33/395/33 404/389/404 403/388/403 f 403/388/403 402/391/402 309/294/309 f 403/388/403 309/294/309 311/293/311 f 393/379/393 520/512/520 521/513/521 f 393/379/393 521/513/521 301/283/301 f 522/514/522 520/512/520 393/379/393 f 522/514/522 393/379/393 392/378/392 f 302/284/302 301/283/301 521/513/521 f 302/284/302 521/513/521 523/515/523 f 302/284/302 523/515/523 524/516/524 f 302/284/302 524/516/524 335/322/335 f 321/304/321 456/446/456 318/302/318 f 321/304/321 318/302/318 147/127/147 f 456/446/456 321/304/321 525/517/525 f 456/446/456 525/517/525 457/447/457 f 410/400/410 409/399/409 526/518/526 f 410/400/410 526/518/526 464/457/464 f 410/400/410 466/456/466 350/333/350 f 410/400/410 350/333/350 349/332/349 f 456/446/456 212/192/212 211/195/211 f 456/446/456 211/195/211 527/519/527 f 211/195/211 224/208/224 463/454/463 f 211/195/211 463/454/463 527/519/527 f 407/397/407 377/364/377 267/251/267 f 407/397/407 267/251/267 276/258/276 f 378/363/378 377/364/377 406/396/406 f 378/363/378 406/396/406 255/236/255 f 175/155/175 214/194/214 213/193/213 f 175/155/175 213/193/213 198/178/198 f 386/372/386 90/67/90 84/61/84 f 386/372/386 84/61/84 356/339/356 f 409/399/409 362/346/362 351/335/351 f 409/399/409 351/335/351 457/447/457 f 85/62/85 89/70/89 412/402/412 f 85/62/85 412/402/412 287/269/287 f 361/345/361 233/213/233 357/342/357 f 361/345/361 357/342/357 352/336/352 f 116/93/116 431/421/431 359/343/359 f 116/93/116 359/343/359 107/84/107 f 116/93/116 107/84/107 106/83/106 f 116/93/116 106/83/106 113/94/113 f 352/336/352 351/335/351 362/346/362 f 352/336/352 362/346/362 361/345/361 f 513/505/513 514/504/514 464/457/464 f 513/505/513 464/457/464 526/518/526 f 526/518/526 409/399/409 457/447/457 f 526/518/526 457/447/457 525/517/525 f 514/504/514 475/465/475 465/455/465 f 514/504/514 465/455/465 464/457/464 f 358/341/358 431/421/431 247/228/247 f 358/341/358 247/228/247 197/179/197 f 176/156/176 482/473/482 172/153/172 f 176/156/176 172/153/172 171/152/171 f 396/381/396 395/384/395 250/234/250 f 396/381/396 250/234/250 119/96/119 f 395/384/395 399/385/399 251/231/251 f 395/384/395 251/231/251 250/234/250 f 291/274/291 81/58/81 80/57/80 f 291/274/291 80/57/80 285/268/285 f 284/267/284 292/275/292 291/274/291 f 284/267/284 291/274/291 285/268/285 f 528/520/528 327/309/327 326/310/326 f 528/520/528 326/310/326 511/502/511 f 126/103/126 125/106/125 152/133/152 f 126/103/126 152/133/152 53/34/53 f 152/133/152 125/106/125 133/112/133 f 152/133/152 133/112/133 340/324/340 f 127/104/127 126/103/126 339/323/339 f 127/104/127 339/323/339 179/162/179 f 56/33/56 135/114/135 367/351/367 f 56/33/56 367/351/367 339/323/339 f 124/101/124 123/100/123 133/112/133 f 124/101/124 133/112/133 134/111/134 f 143/125/143 367/351/367 135/114/135 f 143/125/143 135/114/135 144/124/144 f 164/144/164 143/125/143 132/109/132 f 164/144/164 132/109/132 161/145/161 f 401/387/401 131/108/131 130/107/130 f 401/387/401 130/107/130 142/123/142 f 292/275/292 528/520/528 122/99/122 f 292/275/292 122/99/122 290/273/290 f 61/42/61 507/498/507 75/56/75 f 61/42/61 75/56/75 78/55/78 f 320/303/320 512/503/512 525/517/525 f 320/303/320 525/517/525 321/304/321 f 512/503/512 513/505/513 526/518/526 f 512/503/512 526/518/526 525/517/525 f 123/100/123 122/99/122 528/520/528 f 123/100/123 528/520/528 511/502/511 f 262/245/262 529/521/529 229/209/229 f 262/245/262 229/209/229 221/204/221 f 316/299/316 315/298/315 368/352/368 f 316/299/316 368/352/368 481/472/481 f 516/507/516 315/298/315 230/211/230 f 516/507/516 230/211/230 219/201/219 f 515/506/515 530/522/530 369/353/369 f 515/506/515 369/353/369 516/507/516 f 530/522/530 515/506/515 223/203/223 f 530/522/530 223/203/223 480/471/480 f 215/199/215 218/198/218 223/203/223 f 215/199/215 223/203/223 515/506/515 f 459/448/459 458/449/458 374/360/374 f 459/448/459 374/360/374 248/230/248 f 458/449/458 460/450/460 334/317/334 f 458/449/458 334/317/334 374/360/374 f 334/317/334 460/450/460 47/451/47 f 334/317/334 47/451/47 48/318/48 f 459/448/459 248/230/248 249/229/249 f 459/448/459 249/229/249 480/471/480 f 253/233/253 120/97/120 119/96/119 f 253/233/253 119/96/119 250/234/250 f 394/380/394 170/150/170 169/149/169 f 394/380/394 169/149/169 173/154/173 f 519/510/519 482/473/482 176/156/176 f 519/510/519 176/156/176 197/179/197 f 518/509/518 273/256/273 482/473/482 f 518/509/518 482/473/482 519/510/519 f 531/523/531 274/257/274 273/256/273 f 531/523/531 273/256/273 518/509/518 f 532/524/532 390/376/390 274/257/274 f 532/524/532 274/257/274 531/523/531 f 343/326/343 243/224/243 241/221/241 f 343/326/343 241/221/241 240/220/240 f 188/168/188 238/219/238 244/225/244 f 188/168/188 244/225/244 189/169/189 f 187/167/187 332/315/332 236/217/236 f 187/167/187 236/217/236 188/168/188 f 447/440/447 451/441/451 508/499/508 f 447/440/447 508/499/508 448/437/448 f 162/142/162 388/374/388 297/279/297 f 162/142/162 297/279/297 163/143/163 f 392/378/392 402/391/402 405/390/405 f 392/378/392 405/390/405 522/514/522 f 533/525/533 413/405/413 415/404/415 f 533/525/533 415/404/415 470/461/470 f 534/526/534 65/46/65 68/45/68 f 534/526/534 68/45/68 489/479/489 f 502/493/502 535/527/535 484/478/484 f 502/493/502 484/478/484 487/477/487 f 503/494/503 536/528/536 537/529/537 f 503/494/503 537/529/537 504/495/504 f 492/483/492 538/530/538 535/527/535 f 492/483/492 535/527/535 502/493/502 f 492/483/492 325/307/325 66/43/66 f 492/483/492 66/43/66 65/46/65 f 504/495/504 537/529/537 539/531/539 f 504/495/504 539/531/539 505/496/505 f 239/223/239 424/414/424 345/330/345 f 239/223/239 345/330/345 240/220/240 f 59/36/59 58/35/58 382/367/382 f 59/36/59 382/367/382 381/366/381 f 432/423/432 433/422/433 434/424/434 f 432/423/432 434/424/434 331/313/331 f 437/426/437 436/425/436 440/429/440 f 437/426/437 440/429/440 177/158/177 f 381/366/381 437/426/437 177/158/177 f 381/366/381 177/158/177 59/36/59 f 449/438/449 441/431/441 494/485/494 f 449/438/449 494/485/494 506/497/506 f 450/439/450 501/492/501 434/424/434 f 450/439/450 434/424/434 420/413/420 f 382/367/382 503/494/503 504/495/504 f 382/367/382 504/495/504 383/368/383 f 501/492/501 506/497/506 445/434/445 f 501/492/501 445/434/445 328/314/328 f 536/528/536 503/494/503 486/476/486 f 536/528/536 486/476/486 485/475/485 f 313/297/313 150/130/150 319/301/319 f 313/297/313 319/301/319 318/302/318 f 327/309/327 284/267/284 281/263/281 f 327/309/327 281/263/281 145/129/145 f 483/474/483 93/71/93 192/172/192 f 483/474/483 192/172/192 353/338/353 f 483/474/483 282/265/282 94/72/94 f 483/474/483 94/72/94 93/71/93 f 422/411/422 425/415/425 428/418/428 f 422/411/422 428/418/428 427/416/427 f 421/410/421 433/422/433 345/330/345 f 421/410/421 345/330/345 424/414/424 f 463/454/463 314/296/314 313/297/313 f 463/454/463 313/297/313 527/519/527 f 315/298/315 516/507/516 369/353/369 f 315/298/315 369/353/369 368/352/368 f 314/296/314 481/472/481 312/295/312 f 314/296/314 312/295/312 151/131/151 f 368/352/368 317/300/317 312/295/312 f 368/352/368 312/295/312 481/472/481 f 369/353/369 530/522/530 159/139/159 f 369/353/369 159/139/159 158/138/158 f 480/471/480 249/229/249 159/139/159 f 480/471/480 159/139/159 530/522/530 f 262/245/262 406/396/406 408/398/408 f 262/245/262 408/398/408 529/521/529 f 398/383/398 216/196/216 220/200/220 f 398/383/398 220/200/220 364/348/364 f 541/532/541 542/533/542 543/534/543 f 541/532/541 543/534/543 540/535/540 f 545/536/545 543/534/543 542/533/542 f 545/536/545 542/533/542 544/537/544 f 547/538/547 545/536/545 544/537/544 f 547/538/547 544/537/544 546/539/546 f 549/540/549 547/538/547 546/539/546 f 549/540/549 546/539/546 548/541/548 f 551/542/551 549/540/549 548/541/548 f 551/542/551 548/541/548 550/543/550 f 553/544/553 551/542/551 550/543/550 f 553/544/553 550/543/550 552/545/552 f 555/546/555 553/544/553 552/545/552 f 555/546/555 552/545/552 554/547/554 f 557/548/557 558/549/558 559/550/559 f 557/548/557 559/550/559 556/551/556 f 561/552/561 557/548/557 556/551/556 f 561/552/561 556/551/556 560/553/560 f 563/554/563 546/539/546 544/537/544 f 563/554/563 544/537/544 562/555/562 f 564/556/564 548/541/548 546/539/546 f 564/556/564 546/539/546 563/554/563 f 565/557/565 550/543/550 548/541/548 f 565/557/565 548/541/548 564/556/564 f 566/558/566 552/545/552 550/543/550 f 566/558/566 550/543/550 565/557/565 f 552/545/552 566/558/566 567/559/567 f 552/545/552 567/559/567 554/547/554 f 559/550/559 568/560/568 569/561/569 f 559/550/559 569/561/569 556/551/556 f 570/562/570 560/553/560 556/551/556 f 570/562/570 556/551/556 569/561/569 f 571/563/571 572/564/572 560/553/560 f 571/563/571 560/553/560 570/562/570 f 574/565/574 540/535/540 575/566/575 f 574/565/574 575/566/575 573/567/573 f 577/568/577 543/534/543 545/536/545 f 577/568/577 545/536/545 576/569/576 f 545/536/545 547/538/547 578/570/578 f 545/536/545 578/570/578 576/569/576 f 579/571/579 578/570/578 547/538/547 f 579/571/579 547/538/547 549/540/549 f 580/572/580 579/571/579 551/542/551 f 580/572/580 551/542/551 553/544/553 f 580/572/580 553/544/553 555/546/555 f 580/572/580 555/546/555 581/573/581 f 558/549/558 557/548/557 583/574/583 f 558/549/558 583/574/583 582/575/582 f 561/552/561 584/576/584 583/574/583 f 561/552/561 583/574/583 557/548/557 f 561/552/561 572/564/572 585/577/585 f 561/552/561 585/577/585 584/576/584 f 571/563/571 586/578/586 585/577/585 f 571/563/571 585/577/585 572/564/572 f 544/537/544 542/533/542 541/532/541 f 544/537/544 541/532/541 562/555/562 f 574/565/574 588/579/588 589/580/589 f 574/565/574 589/580/589 587/581/587 f 574/565/574 573/567/573 590/582/590 f 574/565/574 590/582/590 588/579/588 f 590/582/590 573/567/573 575/566/575 f 590/582/590 575/566/575 591/583/591 f 575/566/575 540/535/540 543/534/543 f 575/566/575 543/534/543 591/583/591 f 564/556/564 592/584/592 566/558/566 f 564/556/564 566/558/566 565/557/565 f 592/584/592 593/585/593 567/559/567 f 592/584/592 567/559/567 566/558/566 f 568/560/568 559/550/559 554/547/554 f 568/560/568 554/547/554 567/559/567 f 554/547/554 559/550/559 558/549/558 f 554/547/554 558/549/558 555/546/555 f 582/575/582 581/573/581 555/546/555 f 582/575/582 555/546/555 558/549/558 f 592/584/592 564/556/564 563/554/563 f 592/584/592 563/554/563 562/555/562 f 589/580/589 568/560/568 567/559/567 f 589/580/589 567/559/567 593/585/593 f 540/535/540 574/565/574 587/581/587 f 540/535/540 587/581/587 541/532/541 f 571/563/571 570/562/570 590/582/590 f 571/563/571 590/582/590 591/583/591 f 589/580/589 588/579/588 569/561/569 f 589/580/589 569/561/569 568/560/568 f 543/534/543 577/568/577 594/586/594 f 543/534/543 594/586/594 591/583/591 f 594/586/594 586/578/586 571/563/571 f 594/586/594 571/563/571 591/583/591 f 596/587/596 581/573/581 582/575/582 f 596/587/596 582/575/582 595/588/595 f 596/587/596 597/589/597 580/572/580 f 596/587/596 580/572/580 581/573/581 f 583/574/583 490/482/490 455/444/455 f 583/574/583 455/444/455 595/588/595 f 583/574/583 584/576/584 493/484/493 f 583/574/583 493/484/493 490/482/490 f 597/589/597 508/499/508 579/571/579 f 597/589/597 579/571/579 580/572/580 f 442/432/442 448/437/448 508/499/508 f 442/432/442 508/499/508 597/589/597 f 60/37/60 178/159/178 595/588/595 f 60/37/60 595/588/595 455/444/455 f 178/159/178 439/430/439 596/587/596 f 178/159/178 596/587/596 595/588/595 f 577/568/577 64/41/64 185/166/185 f 577/568/577 185/166/185 594/586/594 f 586/578/586 184/165/184 376/362/376 f 586/578/586 376/362/376 585/577/585 f 590/582/590 570/562/570 569/561/569 f 590/582/590 569/561/569 588/579/588 f 61/42/61 576/569/576 578/570/578 f 61/42/61 578/570/578 507/498/507 f 585/577/585 376/362/376 493/484/493 f 585/577/585 493/484/493 584/576/584 f 453/443/453 598/590/598 73/52/73 f 453/443/453 73/52/73 430/419/430 f 519/510/519 197/179/197 247/228/247 f 519/510/519 247/228/247 246/227/246 f 281/263/281 280/262/280 146/126/146 f 281/263/281 146/126/146 145/129/145 f 64/41/64 63/40/63 121/102/121 f 64/41/64 121/102/121 185/166/185 f 284/267/284 327/309/327 528/520/528 f 284/267/284 528/520/528 292/275/292 f 290/273/290 122/99/122 121/102/121 f 290/273/290 121/102/121 63/40/63 f 280/262/280 289/271/289 320/303/320 f 280/262/280 320/303/320 146/126/146 f 184/165/184 586/578/586 594/586/594 f 184/165/184 594/586/594 185/166/185 f 253/233/253 378/363/378 117/98/117 f 253/233/253 117/98/117 120/97/120 f 249/229/249 140/121/140 160/140/160 f 249/229/249 160/140/160 159/139/159 f 129/110/129 160/140/160 140/121/140 f 129/110/129 140/121/140 130/107/130 f 161/145/161 132/109/132 131/108/131 f 161/145/161 131/108/131 371/354/371 f 313/297/313 318/302/318 456/446/456 f 313/297/313 456/446/456 527/519/527 f 492/483/492 65/46/65 534/526/534 f 492/483/492 534/526/534 538/530/538 f 441/431/441 449/438/449 448/437/448 f 441/431/441 448/437/448 442/432/442 f 443/436/443 446/435/446 435/428/435 f 443/436/443 435/428/435 497/488/497 f 446/435/446 445/434/445 506/497/506 f 446/435/446 506/497/506 494/485/494 f 441/431/441 440/429/440 436/425/436 f 441/431/441 436/425/436 494/485/494 f 596/587/596 439/430/439 442/432/442 f 596/587/596 442/432/442 597/589/597 f 577/568/577 576/569/576 61/42/61 f 577/568/577 61/42/61 64/41/64 f 238/219/238 237/218/237 242/222/242 f 238/219/238 242/222/242 241/221/241 f 194/175/194 76/53/76 426/417/426 f 194/175/194 426/417/426 427/416/427 f 452/442/452 194/175/194 427/416/427 f 452/442/452 427/416/427 428/418/428 f 461/452/461 244/225/244 243/224/243 f 461/452/461 243/224/243 342/328/342 f 508/499/508 507/498/507 578/570/578 f 508/499/508 578/570/578 579/571/579 f 245/226/245 207/187/207 531/523/531 f 245/226/245 531/523/531 518/509/518 f 206/186/206 532/524/532 531/523/531 f 206/186/206 531/523/531 207/187/207 f 32/9/32 31/12/31 600/591/600 f 32/9/32 600/591/600 599/592/599 f 601/593/601 600/591/600 36/13/36 f 601/593/601 36/13/36 24/1/24 f 602/594/602 601/593/601 24/1/24 f 602/594/602 24/1/24 23/4/23 f 40/17/40 602/594/602 23/4/23 f 40/17/40 23/4/23 42/19/42 f 44/22/44 604/595/604 605/596/605 f 44/22/44 605/596/605 603/597/603 f 39/16/39 603/597/603 602/594/602 f 39/16/39 602/594/602 40/17/40 f 601/593/601 606/598/606 607/599/607 f 601/593/601 607/599/607 600/591/600 f 468/459/468 608/600/608 609/601/609 f 468/459/468 609/601/609 469/460/469 f 477/469/477 609/601/609 608/600/608 f 477/469/477 608/600/608 384/370/384 f 610/602/610 611/603/611 612/604/612 f 610/602/610 612/604/612 472/605/472 f 610/602/610 472/605/472 471/606/471 f 610/602/610 471/606/471 613/607/613 f 476/608/476 614/609/614 615/610/615 f 476/608/476 615/610/615 474/611/474 f 478/468/478 110/88/110 109/87/109 f 478/468/478 109/87/109 616/612/616 f 466/456/466 465/455/465 474/467/474 f 466/456/466 474/467/474 617/613/617 f 466/456/466 617/613/617 473/464/473 f 466/456/466 473/464/473 350/333/350 f 614/609/614 533/614/533 470/615/470 f 614/609/614 470/615/470 618/616/618 f 475/465/475 413/405/413 533/525/533 f 475/465/475 533/525/533 476/466/476 f 618/616/618 469/617/469 609/618/609 f 618/616/618 609/618/609 619/619/619 f 619/619/619 609/618/609 477/620/477 f 619/619/619 477/620/477 620/621/620 f 387/373/387 621/622/621 616/612/616 f 387/373/387 616/612/616 109/87/109 f 616/623/616 622/624/622 620/621/620 f 616/623/616 620/621/620 478/625/478 f 473/626/473 617/627/617 615/610/615 f 473/626/473 615/610/615 613/607/613 f 621/628/621 623/629/623 622/624/622 f 621/628/621 622/624/622 616/623/616 f 624/630/624 612/604/612 611/603/611 f 624/630/624 611/603/611 623/629/623 f 49/30/49 71/48/71 70/47/70 f 49/30/49 70/47/70 50/27/50 f 336/319/336 335/322/335 524/516/524 f 336/319/336 524/516/524 418/407/418 f 598/590/598 293/276/293 67/44/67 f 598/590/598 67/44/67 73/52/73 f 50/27/50 70/47/70 429/420/429 f 50/27/50 429/420/429 74/51/74 f 322/308/322 493/484/493 376/362/376 f 322/308/322 376/362/376 323/305/323 f 589/580/589 593/585/593 592/584/592 f 589/580/589 592/584/592 587/581/587 f 396/381/396 119/96/119 118/95/118 f 396/381/396 118/95/118 254/235/254 f 517/508/517 397/382/397 396/381/396 f 517/508/517 396/381/396 254/235/254 f 28/5/28 27/8/27 625/631/625 f 28/5/28 625/631/625 604/595/604 f 600/591/600 607/599/607 626/632/626 f 600/591/600 626/632/626 599/592/599 f 607/599/607 627/633/627 628/634/628 f 607/599/607 628/634/628 626/632/626 f 604/595/604 625/631/625 628/634/628 f 604/595/604 628/634/628 627/633/627 f 630/635/630 631/636/631 632/637/632 f 630/635/630 632/637/632 629/638/629 f 634/639/634 635/640/635 636/641/636 f 634/639/634 636/641/636 633/642/633 f 638/643/638 639/644/639 640/645/640 f 638/643/638 640/645/640 637/646/637 f 641/647/641 642/648/642 637/646/637 f 641/647/641 637/646/637 640/645/640 f 644/649/644 645/650/645 646/651/646 f 644/649/644 646/651/646 643/652/643 f 631/636/631 642/648/642 648/653/648 f 631/636/631 648/653/648 647/654/647 f 650/655/650 651/656/651 652/657/652 f 650/655/650 652/657/652 649/658/649 f 643/652/643 646/651/646 654/659/654 f 643/652/643 654/659/654 653/660/653 f 654/659/654 651/656/651 650/655/650 f 654/659/654 650/655/650 653/660/653 f 655/661/655 656/662/656 657/663/657 f 655/661/655 657/663/657 632/637/632 f 657/663/657 659/664/659 660/665/660 f 657/663/657 660/665/660 658/666/658 f 661/667/661 659/664/659 657/663/657 f 661/667/661 657/663/657 656/662/656 f 631/636/631 647/654/647 655/661/655 f 631/636/631 655/661/655 632/637/632 f 637/646/637 642/648/642 631/636/631 f 637/646/637 631/636/631 630/635/630 f 640/645/640 650/655/650 649/658/649 f 640/645/640 649/658/649 641/647/641 f 652/657/652 662/668/662 641/647/641 f 652/657/652 641/647/641 649/658/649 f 648/653/648 642/648/642 641/647/641 f 648/653/648 641/647/641 662/668/662 f 663/669/663 664/670/664 537/529/537 f 663/669/663 537/529/537 536/528/536 f 666/671/666 640/645/640 639/644/639 f 666/671/666 639/644/639 665/672/665 f 666/671/666 665/672/665 636/641/636 f 666/671/666 636/641/636 635/640/635 f 667/673/667 539/531/539 537/529/537 f 667/673/667 537/529/537 664/670/664 f 634/639/634 644/649/644 643/652/643 f 634/639/634 643/652/643 635/640/635 f 653/660/653 650/655/650 640/645/640 f 653/660/653 640/645/640 666/671/666 f 666/671/666 635/640/635 643/652/643 f 666/671/666 643/652/643 653/660/653 f 669/674/669 644/649/644 634/639/634 f 669/674/669 634/639/634 668/675/668 f 638/643/638 637/646/637 630/635/630 f 638/643/638 630/635/630 670/676/670 f 645/650/645 644/649/644 669/674/669 f 645/650/645 669/674/669 671/677/671 f 638/643/638 670/676/670 485/475/485 f 638/643/638 485/475/485 484/478/484 f 672/678/672 633/642/633 489/479/489 f 672/678/672 489/479/489 488/480/488 f 632/637/632 657/663/657 658/666/658 f 632/637/632 658/666/658 629/638/629 f 670/676/670 663/669/663 536/528/536 f 670/676/670 536/528/536 485/475/485 f 633/642/633 636/641/636 534/526/534 f 633/642/633 534/526/534 489/479/489 f 484/478/484 535/527/535 639/644/639 f 484/478/484 639/644/639 638/643/638 f 629/638/629 658/666/658 664/670/664 f 629/638/629 664/670/664 663/669/663 f 665/672/665 639/644/639 535/527/535 f 665/672/665 535/527/535 538/530/538 f 636/641/636 665/672/665 538/530/538 f 636/641/636 538/530/538 534/526/534 f 660/665/660 667/673/667 664/670/664 f 660/665/660 664/670/664 658/666/658 f 668/675/668 634/639/634 633/642/633 f 668/675/668 633/642/633 672/678/672 f 630/635/630 629/638/629 663/669/663 f 630/635/630 663/669/663 670/676/670 f 1/679/1 661/667/661 656/662/656 f 1/679/1 656/662/656 22/680/22 f 20/681/20 647/654/647 648/653/648 f 20/681/20 648/653/648 18/682/18 f 647/654/647 20/681/20 21/683/21 f 647/654/647 21/683/21 655/661/655 f 15/684/15 646/651/646 645/650/645 f 15/684/15 645/650/645 13/685/13 f 19/686/19 651/656/651 654/659/654 f 19/686/19 654/659/654 14/687/14 f 648/653/648 662/668/662 16/688/16 f 648/653/648 16/688/16 18/682/18 f 17/689/17 652/657/652 651/656/651 f 17/689/17 651/656/651 19/686/19 f 21/683/21 22/680/22 656/662/656 f 21/683/21 656/662/656 655/661/655 f 13/685/13 645/650/645 671/677/671 f 13/685/13 671/677/671 2/690/2 f 646/651/646 15/684/15 14/687/14 f 646/651/646 14/687/14 654/659/654 f 17/689/17 16/688/16 662/668/662 f 17/689/17 662/668/662 652/657/652 f 608/600/608 91/68/91 385/371/385 f 608/600/608 385/371/385 384/370/384 f 304/286/304 372/355/372 401/387/401 f 304/286/304 401/387/401 308/290/308 f 468/459/468 415/404/415 411/401/411 f 468/459/468 411/401/411 92/69/92 f 602/594/602 603/597/603 606/598/606 f 602/594/602 606/598/606 601/593/601 f 608/600/608 468/459/468 92/69/92 f 608/600/608 92/69/92 91/68/91 f 305/287/305 304/286/304 308/290/308 f 305/287/305 308/290/308 137/116/137 f 139/119/139 138/117/138 307/291/307 f 139/119/139 307/291/307 375/361/375 f 674/691/674 675/692/675 676/693/676 f 674/691/674 676/693/676 673/694/673 f 678/695/678 27/8/27 679/696/679 f 678/695/678 679/696/679 677/697/677 f 681/698/681 682/699/682 683/700/683 f 681/698/681 683/700/683 680/701/680 f 684/702/684 685/703/685 683/700/683 f 684/702/684 683/700/683 682/699/682 f 684/702/684 674/691/674 673/694/673 f 684/702/684 673/694/673 685/703/685 f 687/704/687 688/705/688 689/706/689 f 687/704/687 689/706/689 686/707/686 f 690/708/690 691/709/691 676/693/676 f 690/708/690 676/693/676 675/692/675 f 689/706/689 688/705/688 691/709/691 f 689/706/689 691/709/691 690/708/690 f 687/704/687 686/707/686 693/710/693 f 687/704/687 693/710/693 692/711/692 f 681/698/681 680/701/680 46/24/46 f 681/698/681 46/24/46 45/23/45 f 678/695/678 694/712/694 695/713/695 f 678/695/678 695/713/695 693/710/693 f 697/714/697 698/715/698 699/716/699 f 697/714/697 699/716/699 696/717/696 f 701/718/701 702/719/702 703/720/703 f 701/718/701 703/720/703 700/721/700 f 705/722/705 706/723/706 707/724/707 f 705/722/705 707/724/707 704/725/704 f 709/726/709 710/727/710 711/728/711 f 709/726/709 711/728/711 708/729/708 f 713/730/713 714/731/714 715/732/715 f 713/730/713 715/732/715 712/733/712 f 717/734/717 718/735/718 719/736/719 f 717/734/717 719/736/719 716/737/716 f 712/733/712 720/738/720 721/739/721 f 712/733/712 721/739/721 713/730/713 f 713/730/713 721/739/721 697/714/697 f 713/730/713 697/714/697 696/717/696 f 723/740/723 724/741/724 725/742/725 f 723/740/723 725/742/725 722/743/722 f 727/744/727 728/745/728 729/746/729 f 727/744/727 729/746/729 726/747/726 f 731/748/731 732/749/732 733/750/733 f 731/748/731 733/750/733 730/751/730 f 735/752/735 728/745/728 727/744/727 f 735/752/735 727/744/727 734/753/734 f 737/754/737 738/755/738 739/756/739 f 737/754/737 739/756/739 736/757/736 f 741/758/741 722/743/722 725/742/725 f 741/758/741 725/742/725 740/759/740 f 735/752/735 734/753/734 743/760/743 f 735/752/735 743/760/743 742/761/742 f 745/762/745 746/763/746 747/764/747 f 745/762/745 747/764/747 744/765/744 f 747/764/747 746/763/746 749/766/749 f 747/764/747 749/766/749 748/767/748 f 745/762/745 744/765/744 751/768/751 f 745/762/745 751/768/751 750/769/750 f 753/770/753 754/771/754 755/772/755 f 753/770/753 755/772/755 752/773/752 f 757/774/757 755/772/755 754/771/754 f 757/774/757 754/771/754 756/775/756 f 748/767/748 749/766/749 759/776/759 f 748/767/748 759/776/759 758/777/758 f 761/778/761 762/779/762 763/780/763 f 761/778/761 763/780/763 760/781/760 f 765/782/765 766/783/766 767/784/767 f 765/782/765 767/784/767 764/785/764 f 769/786/769 770/787/770 771/788/771 f 769/786/769 771/788/771 768/789/768 f 773/790/773 774/791/774 775/792/775 f 773/790/773 775/792/775 772/793/772 f 777/794/777 778/795/778 779/796/779 f 777/794/777 779/796/779 776/797/776 f 774/791/774 780/798/780 781/799/781 f 774/791/774 781/799/781 775/792/775 f 703/720/703 782/800/782 783/801/783 f 703/720/703 783/801/783 700/721/700 f 688/802/688 687/803/687 785/804/785 f 688/802/688 785/804/785 784/805/784 f 786/806/786 785/804/785 687/803/687 f 786/806/786 687/803/687 692/807/692 f 788/808/788 777/794/777 789/809/789 f 788/808/788 789/809/789 787/810/787 f 790/811/790 791/812/791 779/796/779 f 790/811/790 779/796/779 778/795/778 f 793/813/793 794/814/794 795/815/795 f 793/813/793 795/815/795 792/816/792 f 797/817/797 798/818/798 701/718/701 f 797/817/797 701/718/701 796/819/796 f 701/718/701 798/818/798 799/820/799 f 701/718/701 799/820/799 702/719/702 f 801/821/801 802/822/802 803/823/803 f 801/821/801 803/823/803 800/824/800 f 805/825/805 806/826/806 807/827/807 f 805/825/805 807/827/807 804/828/804 f 809/829/809 810/830/810 811/831/811 f 809/829/809 811/831/811 808/832/808 f 778/795/778 807/827/807 806/826/806 f 778/795/778 806/826/806 790/811/790 f 803/823/803 812/833/812 813/834/813 f 803/823/803 813/834/813 800/824/800 f 815/835/815 816/836/816 817/837/817 f 815/835/815 817/837/817 814/838/814 f 819/839/819 814/838/814 820/840/820 f 819/839/819 820/840/820 818/841/818 f 822/842/822 823/843/823 819/839/819 f 822/842/822 819/839/819 821/844/821 f 704/725/704 707/724/707 825/845/825 f 704/725/704 825/845/825 824/846/824 f 827/847/827 828/848/828 698/715/698 f 827/847/827 698/715/698 826/849/826 f 772/793/772 775/792/775 829/850/829 f 772/793/772 829/850/829 699/716/699 f 781/799/781 771/788/771 831/851/831 f 781/799/781 831/851/831 830/852/830 f 832/853/832 831/851/831 771/788/771 f 832/853/832 771/788/771 770/787/770 f 834/854/834 835/855/835 836/856/836 f 834/854/834 836/856/836 833/857/833 f 838/858/838 839/859/839 840/860/840 f 838/858/838 840/860/840 837/861/837 f 723/740/723 722/743/722 840/860/840 f 723/740/723 840/860/840 841/862/841 f 747/764/747 842/863/842 843/864/843 f 747/764/747 843/864/843 744/765/744 f 821/844/821 844/865/844 845/866/845 f 821/844/821 845/866/845 822/842/822 f 847/867/847 818/841/818 820/840/820 f 847/867/847 820/840/820 846/868/846 f 843/864/843 849/869/849 850/870/850 f 843/864/843 850/870/850 848/871/848 f 205/185/205 851/872/851 852/873/852 f 205/185/205 852/873/852 206/186/206 f 208/189/208 849/869/849 851/872/851 f 208/189/208 851/872/851 205/185/205 f 853/874/853 854/875/854 749/766/749 f 853/874/853 749/766/749 746/763/746 f 728/745/728 735/752/735 854/875/854 f 728/745/728 854/875/854 853/874/853 f 856/876/856 857/877/857 858/878/858 f 856/876/856 858/878/858 855/879/855 f 860/880/860 861/881/861 862/882/862 f 860/880/860 862/882/862 859/883/859 f 863/884/863 864/885/864 861/881/861 f 863/884/863 861/881/861 860/880/860 f 866/886/866 867/887/867 862/882/862 f 866/886/866 862/882/862 865/888/865 f 869/889/869 870/890/870 871/891/871 f 869/889/869 871/891/871 868/892/868 f 866/886/866 228/210/228 229/209/229 f 866/886/866 229/209/229 867/887/867 f 873/893/873 864/885/864 863/884/863 f 873/893/873 863/884/863 872/894/872 f 871/891/871 873/893/873 872/894/872 f 871/891/871 872/894/872 868/892/868 f 875/895/875 876/896/876 877/897/877 f 875/895/875 877/897/877 874/898/874 f 835/855/835 834/854/834 848/871/848 f 835/855/835 848/871/848 850/870/850 f 879/899/879 833/857/833 880/900/880 f 879/899/879 880/900/880 878/901/878 f 882/902/882 883/903/883 884/904/884 f 882/902/882 884/904/884 881/905/881 f 881/905/881 880/900/880 886/906/886 f 881/905/881 886/906/886 885/907/885 f 887/908/887 842/863/842 747/764/747 f 887/908/887 747/764/747 748/767/748 f 842/863/842 887/908/887 852/873/852 f 842/863/842 852/873/852 851/872/851 f 758/777/758 760/781/760 889/909/889 f 758/777/758 889/909/889 888/910/888 f 787/810/787 890/911/890 891/912/891 f 787/810/787 891/912/891 788/808/788 f 893/913/893 894/914/894 895/915/895 f 893/913/893 895/915/895 892/916/892 f 896/917/896 859/883/859 897/918/897 f 896/917/896 897/918/897 765/782/765 f 899/919/899 900/920/900 901/921/901 f 899/919/899 901/921/901 898/922/898 f 900/920/900 902/923/902 903/924/903 f 900/920/900 903/924/903 901/921/901 f 902/923/902 677/925/677 679/926/679 f 902/923/902 679/926/679 903/924/903 f 862/882/862 867/887/867 904/927/904 f 862/882/862 904/927/904 859/883/859 f 901/921/901 263/247/263 264/246/264 f 901/921/901 264/246/264 898/922/898 f 266/248/266 265/249/265 903/924/903 f 266/248/266 903/924/903 679/926/679 f 895/915/895 905/928/905 906/929/906 f 895/915/895 906/929/906 892/916/892 f 907/930/907 908/931/908 909/932/909 f 907/930/907 909/932/909 846/868/846 f 847/867/847 846/868/846 909/932/909 f 847/867/847 909/932/909 910/933/910 f 847/867/847 910/933/910 912/934/912 f 847/867/847 912/934/912 911/935/911 f 276/258/276 275/259/275 906/929/906 f 276/258/276 906/929/906 905/928/905 f 275/259/275 277/260/277 908/931/908 f 275/259/275 908/931/908 906/929/906 f 741/758/741 837/861/837 840/860/840 f 741/758/741 840/860/840 722/743/722 f 914/936/914 915/937/915 916/938/916 f 914/936/914 916/938/916 913/939/913 f 915/937/915 914/936/914 743/760/743 f 915/937/915 743/760/743 734/753/734 f 918/940/918 740/759/740 709/726/709 f 918/940/918 709/726/709 917/941/917 f 916/938/916 915/937/915 920/942/920 f 916/938/916 920/942/920 919/943/919 f 922/944/922 923/945/923 924/946/924 f 922/944/922 924/946/924 921/947/921 f 708/729/708 925/948/925 917/941/917 f 708/729/708 917/941/917 709/726/709 f 917/941/917 925/948/925 927/949/927 f 917/941/917 927/949/927 926/950/926 f 293/276/293 712/733/712 715/732/715 f 293/276/293 715/732/715 294/277/294 f 929/951/929 930/952/930 931/953/931 f 929/951/929 931/953/931 928/954/928 f 933/955/933 934/956/934 935/957/935 f 933/955/933 935/957/935 932/958/932 f 937/959/937 938/960/938 939/961/939 f 937/959/937 939/961/939 936/962/936 f 785/804/785 940/963/940 941/964/941 f 785/804/785 941/964/941 784/805/784 f 812/833/812 943/965/943 944/966/944 f 812/833/812 944/966/944 942/967/942 f 945/968/945 796/819/796 701/718/701 f 945/968/945 701/718/701 700/721/700 f 946/969/946 947/970/947 797/817/797 f 946/969/946 797/817/797 796/819/796 f 949/971/949 873/893/873 871/891/871 f 949/971/949 871/891/871 948/972/948 f 783/801/783 806/826/806 805/825/805 f 783/801/783 805/825/805 950/973/950 f 951/974/951 952/975/952 792/816/792 f 951/974/951 792/816/792 795/815/795 f 954/976/954 793/813/793 792/816/792 f 954/976/954 792/816/792 953/977/953 f 956/978/956 957/979/957 958/980/958 f 956/978/956 958/980/958 955/981/955 f 727/744/727 920/942/920 915/937/915 f 727/744/727 915/937/915 734/753/734 f 959/982/959 960/983/960 795/815/795 f 959/982/959 795/815/795 794/814/794 f 914/936/914 913/939/913 924/946/924 f 914/936/914 924/946/924 923/945/923 f 329/984/329 961/985/961 962/986/962 f 329/984/329 962/986/962 330/987/330 f 834/854/834 963/988/963 751/768/751 f 834/854/834 751/768/751 848/871/848 f 879/899/879 839/859/839 838/858/838 f 879/899/879 838/858/838 963/988/963 f 812/833/812 942/967/942 964/989/964 f 812/833/812 964/989/964 813/834/813 f 786/806/786 692/807/692 695/990/695 f 786/806/786 695/990/695 965/991/965 f 967/992/967 968/993/968 969/994/969 f 967/992/967 969/994/969 966/995/966 f 696/717/696 699/716/699 829/850/829 f 696/717/696 829/850/829 955/981/955 f 970/996/970 703/720/703 702/719/702 f 970/996/970 702/719/702 773/790/773 f 972/997/972 799/820/799 798/818/798 f 972/997/972 798/818/798 971/998/971 f 885/907/885 342/999/342 344/1000/344 f 885/907/885 344/1000/344 973/1001/973 f 974/1002/974 975/1003/975 882/902/882 f 974/1002/974 882/902/882 973/1001/973 f 977/1004/977 978/1005/978 979/1006/979 f 977/1004/977 979/1006/979 976/1007/976 f 981/1008/981 856/876/856 855/879/855 f 981/1008/981 855/879/855 980/1009/980 f 775/792/775 781/799/781 830/852/830 f 775/792/775 830/852/830 829/850/829 f 750/769/750 982/1010/982 983/1011/983 f 750/769/750 983/1011/983 745/762/745 f 761/778/761 984/1012/984 985/1013/985 f 761/778/761 985/1013/985 762/779/762 f 986/1014/986 987/1015/987 845/866/845 f 986/1014/986 845/866/845 844/865/844 f 752/773/752 755/772/755 989/1016/989 f 752/773/752 989/1016/989 988/1017/988 f 977/1004/977 976/1007/976 991/1018/991 f 977/1004/977 991/1018/991 990/1019/990 f 978/1005/978 977/1004/977 874/898/874 f 978/1005/978 874/898/874 992/1020/992 f 863/884/863 993/1021/993 816/836/816 f 863/884/863 816/836/816 872/894/872 f 802/822/802 995/1022/995 933/955/933 f 802/822/802 933/955/933 994/1023/994 f 930/952/930 929/951/929 716/737/716 f 930/952/930 716/737/716 719/736/719 f 828/848/828 827/847/827 996/1024/996 f 828/848/828 996/1024/996 970/996/970 f 998/1025/998 950/973/950 805/825/805 f 998/1025/998 805/825/805 997/1026/997 f 950/973/950 945/968/945 700/721/700 f 950/973/950 700/721/700 783/801/783 f 1000/1027/1000 1001/1028/1001 1002/1029/1002 f 1000/1027/1000 1002/1029/1002 999/1030/999 f 691/1031/691 936/962/936 939/961/939 f 691/1031/691 939/961/939 676/1032/676 f 936/962/936 691/1031/691 688/802/688 f 936/962/936 688/802/688 784/805/784 f 890/911/890 787/810/787 1004/1033/1004 f 890/911/890 1004/1033/1004 1003/1034/1003 f 713/730/713 696/717/696 955/981/955 f 713/730/713 955/981/955 958/980/958 f 830/852/830 831/851/831 1005/1035/1005 f 830/852/830 1005/1035/1005 956/978/956 f 1006/1036/1006 1007/1037/1007 905/928/905 f 1006/1036/1006 905/928/905 895/915/895 f 908/931/908 277/260/277 379/365/379 f 908/931/908 379/365/379 909/932/909 f 1009/1038/1009 1010/1039/1010 1011/1040/1011 f 1009/1038/1009 1011/1040/1011 1008/1041/1008 f 1013/1042/1013 756/775/756 754/771/754 f 1013/1042/1013 754/771/754 1012/1043/1012 f 754/771/754 753/770/753 1014/1044/1014 f 754/771/754 1014/1044/1014 1012/1043/1012 f 989/1016/989 755/772/755 757/774/757 f 989/1016/989 757/774/757 1015/1045/1015 f 826/849/826 808/832/808 811/831/811 f 826/849/826 811/831/811 827/847/827 f 995/1022/995 802/822/802 801/821/801 f 995/1022/995 801/821/801 1016/1046/1016 f 815/835/815 868/892/868 872/894/872 f 815/835/815 872/894/872 816/836/816 f 726/747/726 918/940/918 917/941/917 f 726/747/726 917/941/917 926/950/926 f 910/933/910 909/932/909 379/365/379 f 910/933/910 379/365/379 389/375/389 f 912/934/912 910/933/910 389/375/389 f 912/934/912 389/375/389 390/376/390 f 786/806/786 965/991/965 1003/1034/1003 f 786/806/786 1003/1034/1003 1004/1033/1004 f 1017/1047/1017 803/823/803 802/822/802 f 1017/1047/1017 802/822/802 994/1023/994 f 1019/1048/1019 1017/1047/1017 994/1023/994 f 1019/1048/1019 994/1023/994 1018/1049/1018 f 820/840/820 1020/1050/1020 907/930/907 f 820/840/820 907/930/907 846/868/846 f 932/958/932 1018/1049/1018 994/1023/994 f 932/958/932 994/1023/994 933/955/933 f 1022/1051/1022 1023/1052/1023 1024/1053/1024 f 1022/1051/1022 1024/1053/1024 1021/1054/1021 f 1025/1055/1025 817/837/817 816/836/816 f 1025/1055/1025 816/836/816 993/1021/993 f 1020/1050/1020 817/837/817 1025/1055/1025 f 1020/1050/1020 1025/1055/1025 893/913/893 f 907/930/907 1020/1050/1020 893/913/893 f 907/930/907 893/913/893 892/916/892 f 749/766/749 854/875/854 1026/1056/1026 f 749/766/749 1026/1056/1026 759/776/759 f 776/797/776 1000/1027/1000 999/1030/999 f 776/797/776 999/1030/999 1027/1057/1027 f 1017/1047/1017 943/965/943 812/833/812 f 1017/1047/1017 812/833/812 803/823/803 f 1028/1058/1028 1029/1059/1029 405/390/405 f 1028/1058/1028 405/390/405 404/389/404 f 1029/1059/1029 943/965/943 1017/1047/1017 f 1029/1059/1029 1017/1047/1017 1019/1048/1019 f 685/1060/685 673/1061/673 964/989/964 f 685/1060/685 964/989/964 942/967/942 f 685/1060/685 942/967/942 944/966/944 f 685/1060/685 944/966/944 683/1062/683 f 683/1062/683 944/966/944 1028/1058/1028 f 683/1062/683 1028/1058/1028 680/1063/680 f 1030/1064/1030 897/918/897 859/883/859 f 1030/1064/1030 859/883/859 904/927/904 f 1007/1037/1007 1030/1064/1030 408/398/408 f 1007/1037/1007 408/398/408 407/397/407 f 766/783/766 765/782/765 897/918/897 f 766/783/766 897/918/897 1006/1036/1006 f 907/930/907 892/916/892 906/929/906 f 907/930/907 906/929/906 908/931/908 f 937/959/937 999/1030/999 1002/1029/1002 f 937/959/937 1002/1029/1002 938/960/938 f 991/1018/991 976/1007/976 1032/1065/1032 f 991/1018/991 1032/1065/1032 1031/1066/1031 f 1034/1067/1034 739/756/739 738/755/738 f 1034/1067/1034 738/755/738 1033/1068/1033 f 1035/1069/1035 1036/1070/1036 1037/1071/1037 f 1035/1069/1035 1037/1071/1037 1034/1067/1034 f 1038/1072/1038 416/408/416 418/407/418 f 1038/1072/1038 418/407/418 967/992/967 f 966/995/966 719/736/719 718/735/718 f 966/995/966 718/735/718 1039/1073/1039 f 1041/1074/1041 1042/1075/1042 1043/1076/1043 f 1041/1074/1041 1043/1076/1043 1040/1077/1040 f 1041/1074/1041 1040/1077/1040 1045/1078/1045 f 1041/1074/1041 1045/1078/1045 1044/1079/1044 f 1043/1076/1043 1046/1080/1046 1047/1081/1047 f 1043/1076/1043 1047/1081/1047 1040/1077/1040 f 883/903/883 1045/1078/1045 1048/1082/1048 f 883/903/883 1048/1082/1048 884/904/884 f 1049/1083/1049 1050/1084/1050 721/739/721 f 1049/1083/1049 721/739/721 720/738/720 f 717/734/717 1050/1084/1050 1039/1073/1039 f 717/734/717 1039/1073/1039 718/735/718 f 889/909/889 760/781/760 763/780/763 f 889/909/889 763/780/763 1051/1085/1051 f 974/1002/974 1052/1086/1052 1053/1087/1053 f 974/1002/974 1053/1087/1053 975/1003/975 f 1053/1087/1053 1054/1088/1054 1042/1075/1042 f 1053/1087/1053 1042/1075/1042 1041/1074/1041 f 1056/1089/1056 1057/1090/1057 1058/1091/1058 f 1056/1089/1056 1058/1091/1058 1055/1092/1055 f 1055/1092/1055 1058/1091/1058 1010/1039/1010 f 1055/1092/1055 1010/1039/1010 1009/1038/1009 f 825/845/825 1059/1093/1059 1060/1094/1060 f 825/845/825 1060/1094/1060 824/846/824 f 1060/1094/1060 1059/1093/1059 1062/1095/1062 f 1060/1094/1060 1062/1095/1062 1061/1096/1061 f 444/1097/444 443/1098/443 1064/1099/1064 f 444/1097/444 1064/1099/1064 1063/1100/1063 f 955/981/955 829/850/829 830/852/830 f 955/981/955 830/852/830 956/978/956 f 855/879/855 845/866/845 987/1015/987 f 855/879/855 987/1015/987 980/1009/980 f 858/878/858 869/889/869 823/843/823 f 858/878/858 823/843/823 822/842/822 f 1066/1101/1066 1067/1102/1067 1068/1103/1068 f 1066/1101/1066 1068/1103/1068 1065/1104/1065 f 1043/1076/1043 1067/1102/1067 1069/1105/1069 f 1043/1076/1043 1069/1105/1069 1046/1080/1046 f 724/741/724 723/740/723 1046/1080/1046 f 724/741/724 1046/1080/1046 1069/1105/1069 f 725/742/725 710/727/710 709/726/709 f 725/742/725 709/726/709 740/759/740 f 923/945/923 922/944/922 730/751/730 f 923/945/923 730/751/730 733/750/733 f 742/761/742 1026/1056/1026 854/875/854 f 742/761/742 854/875/854 735/752/735 f 878/901/878 884/904/884 1048/1082/1048 f 878/901/878 1048/1082/1048 1070/1106/1070 f 839/859/839 1070/1106/1070 841/862/841 f 839/859/839 841/862/841 840/860/840 f 878/901/878 1070/1106/1070 839/859/839 f 878/901/878 839/859/839 879/899/879 f 728/745/728 853/874/853 983/1011/983 f 728/745/728 983/1011/983 729/746/729 f 923/945/923 733/750/733 743/760/743 f 923/945/923 743/760/743 914/936/914 f 1049/1083/1049 453/443/453 416/408/416 f 1049/1083/1049 416/408/416 1038/1072/1038 f 969/994/969 934/956/934 931/953/931 f 969/994/969 931/953/931 930/952/930 f 706/723/706 1071/1107/1071 1072/1108/1072 f 706/723/706 1072/1108/1072 707/724/707 f 856/876/856 981/1008/981 1074/1109/1074 f 856/876/856 1074/1109/1074 1073/1110/1073 f 732/749/732 731/748/731 985/1013/985 f 732/749/732 985/1013/985 984/1012/984 f 789/809/789 940/963/940 1004/1033/1004 f 789/809/789 1004/1033/1004 787/810/787 f 1027/1057/1027 941/964/941 940/963/940 f 1027/1057/1027 940/963/940 789/809/789 f 1075/1111/1075 1076/1112/1076 900/920/900 f 1075/1111/1075 900/920/900 899/919/899 f 228/210/228 866/886/866 898/922/898 f 228/210/228 898/922/898 264/246/264 f 900/920/900 1076/1112/1076 1077/1113/1077 f 900/920/900 1077/1113/1077 902/923/902 f 1077/1113/1077 694/1114/694 677/925/677 f 1077/1113/1077 677/925/677 902/923/902 f 263/247/263 901/921/901 903/924/903 f 263/247/263 903/924/903 265/249/265 f 461/1115/461 886/906/886 836/856/836 f 461/1115/461 836/856/836 462/1116/462 f 871/891/871 870/890/870 1078/1117/1078 f 871/891/871 1078/1117/1078 948/972/948 f 1080/1118/1080 1081/1119/1081 1032/1065/1032 f 1080/1118/1080 1032/1065/1032 1079/1120/1079 f 737/754/737 736/757/736 1012/1043/1012 f 737/754/737 1012/1043/1012 1014/1044/1014 f 875/895/875 874/898/874 977/1004/977 f 875/895/875 977/1004/977 990/1019/990 f 877/897/877 1082/1121/1082 992/1020/992 f 877/897/877 992/1020/992 874/898/874 f 969/994/969 930/952/930 719/736/719 f 969/994/969 719/736/719 966/995/966 f 969/994/969 968/993/968 935/957/935 f 969/994/969 935/957/935 934/956/934 f 1084/1122/1084 1037/1071/1037 1085/1123/1085 f 1084/1122/1084 1085/1123/1085 1083/1124/1083 f 978/1005/978 992/1020/992 1087/1125/1087 f 978/1005/978 1087/1125/1087 1086/1126/1086 f 1086/1126/1086 1088/1127/1088 979/1006/979 f 1086/1126/1086 979/1006/979 978/1005/978 f 1080/1118/1080 1090/1128/1090 1091/1129/1091 f 1080/1118/1080 1091/1129/1091 1089/1130/1089 f 1013/1042/1013 1092/1131/1092 1093/1132/1093 f 1013/1042/1013 1093/1132/1093 756/775/756 f 1035/1069/1035 1034/1067/1034 1033/1068/1033 f 1035/1069/1035 1033/1068/1033 1094/1133/1094 f 921/947/921 1094/1133/1094 1033/1068/1033 f 921/947/921 1033/1068/1033 922/944/922 f 730/751/730 738/755/738 737/754/737 f 730/751/730 737/754/737 731/748/731 f 1014/1044/1014 753/770/753 762/779/762 f 1014/1044/1014 762/779/762 985/1013/985 f 876/896/876 875/895/875 987/1015/987 f 876/896/876 987/1015/987 986/1014/986 f 928/954/928 808/832/808 826/849/826 f 928/954/928 826/849/826 929/951/929 f 1039/1073/1039 1038/1072/1038 967/992/967 f 1039/1073/1039 967/992/967 966/995/966 f 698/715/698 828/848/828 772/793/772 f 698/715/698 772/793/772 699/716/699 f 676/1032/676 939/961/939 964/989/964 f 676/1032/676 964/989/964 673/1061/673 f 1000/1027/1000 810/830/810 809/829/809 f 1000/1027/1000 809/829/809 1001/1028/1001 f 898/922/898 866/886/866 865/888/865 f 898/922/898 865/888/865 899/919/899 f 899/919/899 865/888/865 1095/1134/1095 f 899/919/899 1095/1134/1095 1075/1111/1075 f 857/877/857 870/890/870 869/889/869 f 857/877/857 869/889/869 858/878/858 f 948/972/948 1078/1117/1078 946/969/946 f 948/972/948 946/969/946 1096/1135/1096 f 819/839/819 823/843/823 815/835/815 f 819/839/819 815/835/815 814/838/814 f 911/935/911 1097/1136/1097 818/841/818 f 911/935/911 818/841/818 847/867/847 f 815/835/815 823/843/823 869/889/869 f 815/835/815 869/889/869 868/892/868 f 887/908/887 748/767/748 758/777/758 f 887/908/887 758/777/758 888/910/888 f 761/778/761 760/781/760 758/777/758 f 761/778/761 758/777/758 759/776/759 f 853/874/853 746/763/746 745/762/745 f 853/874/853 745/762/745 983/1011/983 f 1051/1085/1051 988/1017/988 876/896/876 f 1051/1085/1051 876/896/876 986/1014/986 f 877/897/877 876/896/876 988/1017/988 f 877/897/877 988/1017/988 989/1016/989 f 989/1016/989 1015/1045/1015 1082/1121/1082 f 989/1016/989 1082/1121/1082 877/897/877 f 726/747/726 729/746/729 1098/1137/1098 f 726/747/726 1098/1137/1098 918/940/918 f 1100/1138/1100 1101/1139/1101 1102/1140/1102 f 1100/1138/1100 1102/1140/1102 1099/1141/1099 f 1103/1142/1103 488/480/488 294/277/294 f 1103/1142/1103 294/277/294 715/732/715 f 1104/1143/1104 1105/1144/1105 1072/1108/1072 f 1104/1143/1104 1072/1108/1072 1071/1107/1071 f 801/821/801 800/824/800 1002/1029/1002 f 801/821/801 1002/1029/1002 1001/1028/1001 f 1104/1143/1104 1106/1145/1106 958/980/958 f 1104/1143/1104 958/980/958 957/979/957 f 1104/1143/1104 957/979/957 1107/1146/1107 f 1104/1143/1104 1107/1146/1107 1105/1144/1105 f 1056/1089/1056 1108/1147/1108 1064/1099/1064 f 1056/1089/1056 1064/1099/1064 1057/1090/1057 f 495/1148/495 1010/1039/1010 1058/1091/1058 f 495/1148/495 1058/1091/1058 496/1149/496 f 496/1149/496 1058/1091/1058 1057/1090/1057 f 496/1149/496 1057/1090/1057 497/1150/497 f 962/986/962 1052/1086/1052 498/1151/498 f 962/986/962 498/1151/498 330/987/330 f 499/1152/499 498/1151/498 1052/1086/1052 f 499/1152/499 1052/1086/1052 974/1002/974 f 1010/1039/1010 495/1148/495 500/1153/500 f 1010/1039/1010 500/1153/500 1011/1040/1011 f 1109/1154/1109 1054/1088/1054 962/986/962 f 1109/1154/1109 962/986/962 961/985/961 f 499/1152/499 974/1002/974 973/1001/973 f 499/1152/499 973/1001/973 344/1000/344 f 1106/1145/1106 1104/1143/1104 1071/1107/1071 f 1106/1145/1106 1071/1107/1071 1110/1155/1110 f 1071/1107/1071 706/723/706 1102/1140/1102 f 1071/1107/1071 1102/1140/1102 1110/1155/1110 f 1099/1141/1099 1102/1140/1102 706/723/706 f 1099/1141/1099 706/723/706 705/722/705 f 705/722/705 1008/1041/1008 1111/1156/1111 f 705/722/705 1111/1156/1111 1099/1141/1099 f 1011/1040/1011 500/1153/500 505/1157/505 f 1011/1040/1011 505/1157/505 1112/1158/1112 f 1067/1102/1067 1043/1076/1043 1042/1075/1042 f 1067/1102/1067 1042/1075/1042 1068/1103/1068 f 329/984/329 444/1097/444 1063/1100/1063 f 329/984/329 1063/1100/1063 961/985/961 f 1068/1103/1068 1109/1154/1109 1113/1159/1113 f 1068/1103/1068 1113/1159/1113 1065/1104/1065 f 1115/1160/1115 724/741/724 1069/1105/1069 f 1115/1160/1115 1069/1105/1069 1114/1161/1114 f 744/765/744 843/864/843 848/871/848 f 744/765/744 848/871/848 751/768/751 f 509/500/509 850/870/850 849/869/849 f 509/500/509 849/869/849 208/189/208 f 849/869/849 843/864/843 842/863/842 f 849/869/849 842/863/842 851/872/851 f 462/1116/462 836/856/836 835/855/835 f 462/1116/462 835/855/835 510/501/510 f 850/870/850 509/500/509 510/501/510 f 850/870/850 510/501/510 835/855/835 f 795/815/795 960/983/960 971/998/971 f 795/815/795 971/998/971 951/974/951 f 960/983/960 1116/1162/1116 972/997/972 f 960/983/960 972/997/972 971/998/971 f 768/789/768 780/798/780 972/997/972 f 768/789/768 972/997/972 1116/1162/1116 f 716/737/716 929/951/929 826/849/826 f 716/737/716 826/849/826 698/715/698 f 801/821/801 1001/1028/1001 809/829/809 f 801/821/801 809/829/809 1016/1046/1016 f 800/824/800 813/834/813 938/960/938 f 800/824/800 938/960/938 1002/1029/1002 f 813/834/813 964/989/964 939/961/939 f 813/834/813 939/961/939 938/960/938 f 1117/1163/1117 921/947/921 924/946/924 f 1117/1163/1117 924/946/924 954/976/954 f 1094/1133/1094 1118/1164/1118 1119/1165/1119 f 1094/1133/1094 1119/1165/1119 1035/1069/1035 f 1035/1069/1035 1119/1165/1119 1089/1130/1089 f 1035/1069/1035 1089/1130/1089 1036/1070/1036 f 1118/1164/1118 1094/1133/1094 921/947/921 f 1118/1164/1118 921/947/921 1117/1163/1117 f 838/858/838 837/861/837 982/1010/982 f 838/858/838 982/1010/982 750/769/750 f 963/988/963 838/858/838 750/769/750 f 963/988/963 750/769/750 751/768/751 f 729/746/729 983/1011/983 982/1010/982 f 729/746/729 982/1010/982 1098/1137/1098 f 732/749/732 742/761/742 743/760/743 f 732/749/732 743/760/743 733/750/733 f 732/749/732 984/1012/984 1026/1056/1026 f 732/749/732 1026/1056/1026 742/761/742 f 984/1012/984 761/778/761 759/776/759 f 984/1012/984 759/776/759 1026/1056/1026 f 790/811/790 806/826/806 783/801/783 f 790/811/790 783/801/783 782/800/782 f 931/953/931 934/956/934 933/955/933 f 931/953/931 933/955/933 995/1022/995 f 931/953/931 995/1022/995 1016/1046/1016 f 931/953/931 1016/1046/1016 928/954/928 f 996/1024/996 827/847/827 811/831/811 f 996/1024/996 811/831/811 791/812/791 f 1121/1166/1121 861/881/861 864/885/864 f 1121/1166/1121 864/885/864 1120/1167/1120 f 896/917/896 1122/1168/1122 860/880/860 f 896/917/896 860/880/860 859/883/859 f 1024/1053/1024 1023/1052/1023 1025/1055/1025 f 1024/1053/1024 1025/1055/1025 993/1021/993 f 1024/1053/1024 860/880/860 1122/1168/1122 f 1024/1053/1024 1122/1168/1122 1021/1054/1021 f 1124/1169/1124 887/908/887 888/910/888 f 1124/1169/1124 888/910/888 1123/1170/1123 f 951/974/951 971/998/971 798/818/798 f 951/974/951 798/818/798 797/817/797 f 1050/1084/1050 1049/1083/1049 1038/1072/1038 f 1050/1084/1050 1038/1072/1038 1039/1073/1039 f 680/1063/680 1028/1058/1028 404/389/404 f 680/1063/680 404/389/404 46/511/46 f 1028/1058/1028 944/966/944 943/965/943 f 1028/1058/1028 943/965/943 1029/1059/1029 f 1018/1049/1018 932/958/932 521/513/521 f 1018/1049/1018 521/513/521 520/512/520 f 522/514/522 1019/1048/1019 1018/1049/1018 f 522/514/522 1018/1049/1018 520/512/520 f 935/957/935 523/515/523 521/513/521 f 935/957/935 521/513/521 932/958/932 f 935/957/935 968/993/968 524/516/524 f 935/957/935 524/516/524 523/515/523 f 953/977/953 792/816/792 952/975/952 f 953/977/953 952/975/952 1073/1110/1073 f 1073/1110/1073 1074/1109/1074 1125/1171/1125 f 1073/1110/1073 1125/1171/1125 953/977/953 f 1032/1065/1032 1081/1119/1081 1126/1172/1126 f 1032/1065/1032 1126/1172/1126 1031/1066/1031 f 1032/1065/1032 976/1007/976 979/1006/979 f 1032/1065/1032 979/1006/979 1079/1120/1079 f 1073/1110/1073 1127/1173/1127 857/877/857 f 1073/1110/1073 857/877/857 856/876/856 f 857/877/857 1127/1173/1127 1078/1117/1078 f 857/877/857 1078/1117/1078 870/890/870 f 407/397/407 276/258/276 905/928/905 f 407/397/407 905/928/905 1007/1037/1007 f 1006/1036/1006 897/918/897 1030/1064/1030 f 1006/1036/1006 1030/1064/1030 1007/1037/1007 f 822/842/822 845/866/845 855/879/855 f 822/842/822 855/879/855 858/878/858 f 1014/1044/1014 985/1013/985 731/748/731 f 1014/1044/1014 731/748/731 737/754/737 f 1031/1066/1031 1074/1109/1074 981/1008/981 f 1031/1066/1031 981/1008/981 991/1018/991 f 730/751/730 922/944/922 1033/1068/1033 f 730/751/730 1033/1068/1033 738/755/738 f 990/1019/990 980/1009/980 987/1015/987 f 990/1019/990 987/1015/987 875/895/875 f 763/780/763 752/773/752 988/1017/988 f 763/780/763 988/1017/988 1051/1085/1051 f 763/780/763 762/779/762 753/770/753 f 763/780/763 753/770/753 752/773/752 f 980/1009/980 990/1019/990 991/1018/991 f 980/1009/980 991/1018/991 981/1008/981 f 1118/1164/1118 1126/1172/1126 1081/1119/1081 f 1118/1164/1118 1081/1119/1081 1119/1165/1119 f 1126/1172/1126 1125/1171/1125 1074/1109/1074 f 1126/1172/1126 1074/1109/1074 1031/1066/1031 f 1119/1165/1119 1081/1119/1081 1080/1118/1080 f 1119/1165/1119 1080/1118/1080 1089/1130/1089 f 986/1014/986 844/865/844 889/909/889 f 986/1014/986 889/909/889 1051/1085/1051 f 821/844/821 819/839/819 818/841/818 f 821/844/821 818/841/818 1097/1136/1097 f 1022/1051/1022 764/785/764 894/914/894 f 1022/1051/1022 894/914/894 1023/1052/1023 f 1023/1052/1023 894/914/894 893/913/893 f 1023/1052/1023 893/913/893 1025/1055/1025 f 926/950/926 920/942/920 727/744/727 f 926/950/926 727/744/727 726/747/726 f 919/943/919 920/942/920 926/950/926 f 919/943/919 926/950/926 927/949/927 f 1128/1174/1128 1116/1162/1116 960/983/960 f 1128/1174/1128 960/983/960 959/982/959 f 773/790/773 702/719/702 799/820/799 f 773/790/773 799/820/799 774/791/774 f 799/820/799 972/997/972 780/798/780 f 799/820/799 780/798/780 774/791/774 f 772/793/772 828/848/828 970/996/970 f 772/793/772 970/996/970 773/790/773 f 703/720/703 970/996/970 996/1024/996 f 703/720/703 996/1024/996 782/800/782 f 771/788/771 781/799/781 780/798/780 f 771/788/771 780/798/780 768/789/768 f 791/812/791 790/811/790 782/800/782 f 791/812/791 782/800/782 996/1024/996 f 811/831/811 810/830/810 779/796/779 f 811/831/811 779/796/779 791/812/791 f 1027/1057/1027 789/809/789 777/794/777 f 1027/1057/1027 777/794/777 776/797/776 f 927/949/927 925/948/925 769/786/769 f 927/949/927 769/786/769 1128/1174/1128 f 710/727/710 725/742/725 724/741/724 f 710/727/710 724/741/724 1115/1160/1115 f 954/976/954 953/977/953 1125/1171/1125 f 954/976/954 1125/1171/1125 1117/1163/1117 f 1117/1163/1117 1125/1171/1125 1126/1172/1126 f 1117/1163/1117 1126/1172/1126 1118/1164/1118 f 768/789/768 1116/1162/1116 1128/1174/1128 f 768/789/768 1128/1174/1128 769/786/769 f 904/927/904 867/887/867 229/209/229 f 904/927/904 229/209/229 529/521/529 f 948/972/948 1096/1135/1096 998/1025/998 f 948/972/948 998/1025/998 949/971/949 f 1120/1167/1120 864/885/864 873/893/873 f 1120/1167/1120 873/893/873 949/971/949 f 1121/1166/1121 1120/1167/1120 997/1026/997 f 1121/1166/1121 997/1026/997 1129/1175/1129 f 1129/1175/1129 1095/1134/1095 865/888/865 f 1129/1175/1129 865/888/865 1121/1166/1121 f 861/881/861 1121/1166/1121 865/888/865 f 861/881/861 865/888/865 862/882/862 f 1075/1111/1075 890/911/890 1003/1034/1003 f 1075/1111/1075 1003/1034/1003 1076/1112/1076 f 1076/1112/1076 1003/1034/1003 965/991/965 f 1076/1112/1076 965/991/965 1077/1113/1077 f 965/991/965 695/990/695 694/1114/694 f 965/991/965 694/1114/694 1077/1113/1077 f 1075/1111/1075 1095/1134/1095 891/912/891 f 1075/1111/1075 891/912/891 890/911/890 f 895/915/895 894/914/894 764/785/764 f 895/915/895 764/785/764 767/784/767 f 1020/1050/1020 820/840/820 814/838/814 f 1020/1050/1020 814/838/814 817/837/817 f 1123/1170/1123 844/865/844 821/844/821 f 1123/1170/1123 821/844/821 1097/1136/1097 f 1124/1169/1124 1123/1170/1123 1097/1136/1097 f 1124/1169/1124 1097/1136/1097 911/935/911 f 1130/1176/1130 1124/1169/1124 911/935/911 f 1130/1176/1130 911/935/911 912/934/912 f 532/524/532 1130/1176/1130 912/934/912 f 532/524/532 912/934/912 390/376/390 f 973/1001/973 882/902/882 881/905/881 f 973/1001/973 881/905/881 885/907/885 f 833/857/833 836/856/836 886/906/886 f 833/857/833 886/906/886 880/900/880 f 834/854/834 833/857/833 879/899/879 f 834/854/834 879/899/879 963/988/963 f 1067/1102/1067 1066/1101/1066 1114/1161/1114 f 1067/1102/1067 1114/1161/1114 1069/1105/1069 f 809/829/809 808/832/808 928/954/928 f 809/829/809 928/954/928 1016/1046/1016 f 1019/1048/1019 522/514/522 405/390/405 f 1019/1048/1019 405/390/405 1029/1059/1029 f 1131/1177/1131 1085/1123/1085 1037/1071/1037 f 1131/1177/1131 1037/1071/1037 1036/1070/1036 f 1132/1178/1132 1103/1142/1103 715/732/715 f 1132/1178/1132 715/732/715 714/731/714 f 1110/1155/1110 1102/1140/1102 1101/1139/1101 f 1110/1155/1110 1101/1139/1101 1133/1179/1133 f 1111/1156/1111 1112/1158/1112 1135/1180/1135 f 1111/1156/1111 1135/1180/1135 1134/1181/1134 f 1106/1145/1106 1110/1155/1110 1133/1179/1133 f 1106/1145/1106 1133/1179/1133 1136/1182/1136 f 1106/1145/1106 714/731/714 713/730/713 f 1106/1145/1106 713/730/713 958/980/958 f 1112/1158/1112 505/1157/505 539/1183/539 f 1112/1158/1112 539/1183/539 1135/1180/1135 f 883/903/883 882/902/882 975/1003/975 f 883/903/883 975/1003/975 1044/1079/1044 f 704/725/704 1009/1038/1009 1008/1041/1008 f 704/725/704 1008/1041/1008 705/722/705 f 1052/1086/1052 962/986/962 1054/1088/1054 f 1052/1086/1052 1054/1088/1054 1053/1087/1053 f 1055/1092/1055 824/846/824 1060/1094/1060 f 1055/1092/1055 1060/1094/1060 1056/1089/1056 f 1009/1038/1009 704/725/704 824/846/824 f 1009/1038/1009 824/846/824 1055/1092/1055 f 1065/1104/1065 1113/1159/1113 1108/1147/1108 f 1065/1104/1065 1108/1147/1108 1061/1096/1061 f 1068/1103/1068 1042/1075/1042 1054/1088/1054 f 1068/1103/1068 1054/1088/1054 1109/1154/1109 f 1008/1041/1008 1011/1040/1011 1112/1158/1112 f 1008/1041/1008 1112/1158/1112 1111/1156/1111 f 1109/1154/1109 961/985/961 1063/1100/1063 f 1109/1154/1109 1063/1100/1063 1113/1159/1113 f 1134/1181/1134 1100/1138/1100 1099/1141/1099 f 1134/1181/1134 1099/1141/1099 1111/1156/1111 f 947/970/947 952/975/952 951/974/951 f 947/970/947 951/974/951 797/817/797 f 959/982/959 794/814/794 916/938/916 f 959/982/959 916/938/916 919/943/919 f 1098/1137/1098 982/1010/982 837/861/837 f 1098/1137/1098 837/861/837 741/758/741 f 1098/1137/1098 741/758/741 740/759/740 f 1098/1137/1098 740/759/740 918/940/918 f 1040/1077/1040 1047/1081/1047 1048/1082/1048 f 1040/1077/1040 1048/1082/1048 1045/1078/1045 f 1041/1074/1041 1044/1079/1044 975/1003/975 f 1041/1074/1041 975/1003/975 1053/1087/1053 f 1078/1117/1078 1127/1173/1127 947/970/947 f 1078/1117/1078 947/970/947 946/969/946 f 949/971/949 998/1025/998 997/1026/997 f 949/971/949 997/1026/997 1120/1167/1120 f 946/969/946 796/819/796 945/968/945 f 946/969/946 945/968/945 1096/1135/1096 f 998/1025/998 1096/1135/1096 945/968/945 f 998/1025/998 945/968/945 950/973/950 f 997/1026/997 805/825/805 804/828/804 f 997/1026/997 804/828/804 1129/1175/1129 f 1095/1134/1095 1129/1175/1129 804/828/804 f 1095/1134/1095 804/828/804 891/912/891 f 904/927/904 529/521/529 408/398/408 f 904/927/904 408/398/408 1030/1064/1030 f 1024/1053/1024 993/1021/993 863/884/863 f 1024/1053/1024 863/884/863 860/880/860 f 1138/1184/1138 1139/1185/1139 1140/1186/1140 f 1138/1184/1138 1140/1186/1140 1137/1187/1137 f 1141/1188/1141 1142/1189/1142 1137/1187/1137 f 1141/1188/1141 1137/1187/1137 1140/1186/1140 f 1143/1190/1143 1144/1191/1144 1142/1189/1142 f 1143/1190/1143 1142/1189/1142 1141/1188/1141 f 1145/1192/1145 1146/1193/1146 1144/1191/1144 f 1145/1192/1145 1144/1191/1144 1143/1190/1143 f 1147/1194/1147 1148/1195/1148 1146/1193/1146 f 1147/1194/1147 1146/1193/1146 1145/1192/1145 f 1149/1196/1149 1150/1197/1150 1148/1195/1148 f 1149/1196/1149 1148/1195/1148 1147/1194/1147 f 1151/1198/1151 1152/1199/1152 1150/1197/1150 f 1151/1198/1151 1150/1197/1150 1149/1196/1149 f 1154/1200/1154 1155/1201/1155 1156/1202/1156 f 1154/1200/1154 1156/1202/1156 1153/1203/1153 f 1157/1204/1157 1158/1205/1158 1155/1201/1155 f 1157/1204/1157 1155/1201/1155 1154/1200/1154 f 1159/1206/1159 1160/1207/1160 1142/1189/1142 f 1159/1206/1159 1142/1189/1142 1144/1191/1144 f 1161/1208/1161 1159/1206/1159 1144/1191/1144 f 1161/1208/1161 1144/1191/1144 1146/1193/1146 f 1162/1209/1162 1161/1208/1161 1146/1193/1146 f 1162/1209/1162 1146/1193/1146 1148/1195/1148 f 1163/1210/1163 1162/1209/1162 1148/1195/1148 f 1163/1210/1163 1148/1195/1148 1150/1197/1150 f 1150/1197/1150 1152/1199/1152 1164/1211/1164 f 1150/1197/1150 1164/1211/1164 1163/1210/1163 f 1156/1202/1156 1155/1201/1155 1166/1212/1166 f 1156/1202/1156 1166/1212/1166 1165/1213/1165 f 1167/1214/1167 1166/1212/1166 1155/1201/1155 f 1167/1214/1167 1155/1201/1155 1158/1205/1158 f 1169/1215/1169 1167/1214/1167 1158/1205/1158 f 1169/1215/1169 1158/1205/1158 1168/1216/1168 f 1170/1217/1170 1171/1218/1171 1172/1219/1172 f 1170/1217/1170 1172/1219/1172 1139/1185/1139 f 1173/1220/1173 1174/1221/1174 1141/1188/1141 f 1173/1220/1173 1141/1188/1141 1140/1186/1140 f 1141/1188/1141 1174/1221/1174 1175/1222/1175 f 1141/1188/1141 1175/1222/1175 1143/1190/1143 f 1176/1223/1176 1145/1192/1145 1143/1190/1143 f 1176/1223/1176 1143/1190/1143 1175/1222/1175 f 1177/1224/1177 1149/1196/1149 1147/1194/1147 f 1177/1224/1177 1147/1194/1147 1176/1223/1176 f 1177/1224/1177 1178/1225/1178 1151/1198/1151 f 1177/1224/1177 1151/1198/1151 1149/1196/1149 f 1153/1203/1153 1179/1226/1179 1180/1227/1180 f 1153/1203/1153 1180/1227/1180 1154/1200/1154 f 1157/1204/1157 1154/1200/1154 1180/1227/1180 f 1157/1204/1157 1180/1227/1180 1181/1228/1181 f 1157/1204/1157 1181/1228/1181 1182/1229/1182 f 1157/1204/1157 1182/1229/1182 1168/1216/1168 f 1169/1215/1169 1168/1216/1168 1182/1229/1182 f 1169/1215/1169 1182/1229/1182 1183/1230/1183 f 1142/1189/1142 1160/1207/1160 1138/1184/1138 f 1142/1189/1142 1138/1184/1138 1137/1187/1137 f 1170/1217/1170 1185/1231/1185 1186/1232/1186 f 1170/1217/1170 1186/1232/1186 1184/1233/1184 f 1170/1217/1170 1184/1233/1184 1187/1234/1187 f 1170/1217/1170 1187/1234/1187 1171/1218/1171 f 1187/1234/1187 1188/1235/1188 1172/1219/1172 f 1187/1234/1187 1172/1219/1172 1171/1218/1171 f 1172/1219/1172 1188/1235/1188 1140/1186/1140 f 1172/1219/1172 1140/1186/1140 1139/1185/1139 f 1161/1208/1161 1162/1209/1162 1163/1210/1163 f 1161/1208/1161 1163/1210/1163 1189/1236/1189 f 1189/1236/1189 1163/1210/1163 1164/1211/1164 f 1189/1236/1189 1164/1211/1164 1190/1237/1190 f 1165/1213/1165 1164/1211/1164 1152/1199/1152 f 1165/1213/1165 1152/1199/1152 1156/1202/1156 f 1152/1199/1152 1151/1198/1151 1153/1203/1153 f 1152/1199/1152 1153/1203/1153 1156/1202/1156 f 1179/1226/1179 1153/1203/1153 1151/1198/1151 f 1179/1226/1179 1151/1198/1151 1178/1225/1178 f 1189/1236/1189 1160/1207/1160 1159/1206/1159 f 1189/1236/1189 1159/1206/1159 1161/1208/1161 f 1186/1232/1186 1190/1237/1190 1164/1211/1164 f 1186/1232/1186 1164/1211/1164 1165/1213/1165 f 1139/1185/1139 1138/1184/1138 1185/1231/1185 f 1139/1185/1139 1185/1231/1185 1170/1217/1170 f 1169/1215/1169 1188/1235/1188 1187/1234/1187 f 1169/1215/1169 1187/1234/1187 1167/1214/1167 f 1186/1232/1186 1165/1213/1165 1166/1212/1166 f 1186/1232/1186 1166/1212/1166 1184/1233/1184 f 1140/1186/1140 1188/1235/1188 1191/1238/1191 f 1140/1186/1140 1191/1238/1191 1173/1220/1173 f 1191/1238/1191 1188/1235/1188 1169/1215/1169 f 1191/1238/1191 1169/1215/1169 1183/1230/1183 f 1192/1239/1192 1193/1240/1193 1179/1226/1179 f 1192/1239/1192 1179/1226/1179 1178/1225/1178 f 1192/1239/1192 1178/1225/1178 1177/1224/1177 f 1192/1239/1192 1177/1224/1177 1194/1241/1194 f 1180/1227/1180 1193/1240/1193 1072/1108/1072 f 1180/1227/1180 1072/1108/1072 1105/1144/1105 f 1180/1227/1180 1105/1144/1105 1107/1146/1107 f 1180/1227/1180 1107/1146/1107 1181/1228/1181 f 1194/1241/1194 1177/1224/1177 1176/1223/1176 f 1194/1241/1194 1176/1223/1176 1114/1161/1114 f 1062/1095/1062 1194/1241/1194 1114/1161/1114 f 1062/1095/1062 1114/1161/1114 1066/1101/1066 f 707/724/707 1072/1108/1072 1193/1240/1193 f 707/724/707 1193/1240/1193 825/845/825 f 825/845/825 1193/1240/1193 1192/1239/1192 f 825/845/825 1192/1239/1192 1059/1093/1059 f 1173/1220/1173 1191/1238/1191 832/853/832 f 1173/1220/1173 832/853/832 711/728/711 f 1183/1230/1183 1182/1229/1182 1005/1035/1005 f 1183/1230/1183 1005/1035/1005 831/851/831 f 1187/1234/1187 1184/1233/1184 1166/1212/1166 f 1187/1234/1187 1166/1212/1166 1167/1214/1167 f 710/727/710 1115/1160/1115 1175/1222/1175 f 710/727/710 1175/1222/1175 1174/1221/1174 f 1182/1229/1182 1181/1228/1181 1107/1146/1107 f 1182/1229/1182 1107/1146/1107 1005/1035/1005 f 453/443/453 1049/1083/1049 720/738/720 f 453/443/453 720/738/720 598/590/598 f 1123/1170/1123 888/910/888 889/909/889 f 1123/1170/1123 889/909/889 844/865/844 f 916/938/916 794/814/794 793/813/793 f 916/938/916 793/813/793 913/939/913 f 711/728/711 832/853/832 770/787/770 f 711/728/711 770/787/770 708/729/708 f 919/943/919 927/949/927 1128/1174/1128 f 919/943/919 1128/1174/1128 959/982/959 f 925/948/925 708/729/708 770/787/770 f 925/948/925 770/787/770 769/786/769 f 913/939/913 793/813/793 954/976/954 f 913/939/913 954/976/954 924/946/924 f 831/851/831 832/853/832 1191/1238/1191 f 831/851/831 1191/1238/1191 1183/1230/1183 f 895/915/895 767/784/767 766/783/766 f 895/915/895 766/783/766 1006/1036/1006 f 891/912/891 804/828/804 807/827/807 f 891/912/891 807/827/807 788/808/788 f 778/795/778 777/794/777 788/808/788 f 778/795/778 788/808/788 807/827/807 f 810/830/810 1000/1027/1000 776/797/776 f 810/830/810 776/797/776 779/796/779 f 947/970/947 1127/1173/1127 1073/1110/1073 f 947/970/947 1073/1110/1073 952/975/952 f 1106/1145/1106 1136/1182/1136 1132/1178/1132 f 1106/1145/1106 1132/1178/1132 714/731/714 f 1061/1096/1061 1062/1095/1062 1066/1101/1066 f 1061/1096/1061 1066/1101/1066 1065/1104/1065 f 443/1098/443 497/1150/497 1057/1090/1057 f 443/1098/443 1057/1090/1057 1064/1099/1064 f 1064/1099/1064 1108/1147/1108 1113/1159/1113 f 1064/1099/1064 1113/1159/1113 1063/1100/1063 f 1061/1096/1061 1108/1147/1108 1056/1089/1056 f 1061/1096/1061 1056/1089/1056 1060/1094/1060 f 1192/1239/1192 1194/1241/1194 1062/1095/1062 f 1192/1239/1192 1062/1095/1062 1059/1093/1059 f 1173/1220/1173 711/728/711 710/727/710 f 1173/1220/1173 710/727/710 1174/1221/1174 f 880/900/880 881/905/881 884/904/884 f 880/900/880 884/904/884 878/901/878 f 841/862/841 1047/1081/1047 1046/1080/1046 f 841/862/841 1046/1080/1046 723/740/723 f 1070/1106/1070 1048/1082/1048 1047/1081/1047 f 1070/1106/1070 1047/1081/1047 841/862/841 f 461/1115/461 342/999/342 885/907/885 f 461/1115/461 885/907/885 886/906/886 f 1114/1161/1114 1176/1223/1176 1175/1222/1175 f 1114/1161/1114 1175/1222/1175 1115/1160/1115 f 887/908/887 1124/1169/1124 1130/1176/1130 f 887/908/887 1130/1176/1130 852/873/852 f 206/186/206 852/873/852 1130/1176/1130 f 206/186/206 1130/1176/1130 532/524/532 f 681/698/681 599/592/599 1195/1242/1195 f 681/698/681 1195/1242/1195 682/699/682 f 1196/1243/1196 674/691/674 684/702/684 f 1196/1243/1196 684/702/684 1195/1242/1195 f 1197/1244/1197 675/692/675 674/691/674 f 1197/1244/1197 674/691/674 1196/1243/1196 f 689/706/689 690/708/690 675/692/675 f 689/706/689 675/692/675 1197/1244/1197 f 693/710/693 1199/1245/1199 1200/1246/1200 f 693/710/693 1200/1246/1200 1198/1247/1198 f 686/707/686 689/706/689 1197/1244/1197 f 686/707/686 1197/1244/1197 1199/1245/1199 f 1196/1243/1196 1195/1242/1195 1202/1248/1202 f 1196/1243/1196 1202/1248/1202 1201/1249/1201 f 1084/1122/1084 1083/1124/1083 1204/1250/1204 f 1084/1122/1084 1204/1250/1204 1203/1251/1203 f 1092/1131/1092 1013/1042/1013 1203/1251/1203 f 1092/1131/1092 1203/1251/1203 1204/1250/1204 f 1206/1252/1206 1087/1253/1087 1207/1254/1207 f 1206/1252/1206 1207/1254/1207 1205/1255/1205 f 1206/1252/1206 1208/1256/1208 1086/1257/1086 f 1206/1252/1206 1086/1257/1086 1087/1253/1087 f 1091/1258/1091 1090/1259/1090 1210/1260/1210 f 1091/1258/1091 1210/1260/1210 1209/1261/1209 f 1093/1132/1093 1211/1262/1211 757/774/757 f 1093/1132/1093 757/774/757 756/775/756 f 1079/1120/1079 1212/1263/1212 1090/1128/1090 f 1079/1120/1079 1090/1128/1090 1080/1118/1080 f 1079/1120/1079 979/1006/979 1088/1127/1088 f 1079/1120/1079 1088/1127/1088 1212/1263/1212 f 1209/1261/1209 1213/1264/1213 1085/1265/1085 f 1209/1261/1209 1085/1265/1085 1131/1266/1131 f 1089/1130/1089 1091/1129/1091 1131/1177/1131 f 1089/1130/1089 1131/1177/1131 1036/1070/1036 f 1213/1264/1213 1214/1267/1214 1204/1268/1204 f 1213/1264/1213 1204/1268/1204 1083/1269/1083 f 1214/1267/1214 1215/1270/1215 1092/1271/1092 f 1214/1267/1214 1092/1271/1092 1204/1268/1204 f 1015/1045/1015 757/774/757 1211/1262/1211 f 1015/1045/1015 1211/1262/1211 1216/1272/1216 f 1211/1273/1211 1093/1274/1093 1215/1270/1215 f 1211/1273/1211 1215/1270/1215 1217/1275/1217 f 1088/1276/1088 1208/1256/1208 1210/1260/1210 f 1088/1276/1088 1210/1260/1210 1212/1277/1212 f 1216/1278/1216 1211/1273/1211 1217/1275/1217 f 1216/1278/1216 1217/1275/1217 1218/1279/1218 f 1219/1280/1219 1218/1279/1218 1205/1255/1205 f 1219/1280/1219 1205/1255/1205 1207/1254/1207 f 698/715/698 697/714/697 717/734/717 f 698/715/698 717/734/717 716/737/716 f 967/992/967 418/407/418 524/516/524 f 967/992/967 524/516/524 968/993/968 f 598/590/598 720/738/720 712/733/712 f 598/590/598 712/733/712 293/276/293 f 697/714/697 721/739/721 1050/1084/1050 f 697/714/697 1050/1084/1050 717/734/717 f 957/979/957 956/978/956 1005/1035/1005 f 957/979/957 1005/1035/1005 1107/1146/1107 f 1186/1232/1186 1185/1231/1185 1189/1236/1189 f 1186/1232/1186 1189/1236/1189 1190/1237/1190 f 1022/1051/1022 896/917/896 765/782/765 f 1022/1051/1022 765/782/765 764/785/764 f 1122/1168/1122 896/917/896 1022/1051/1022 f 1122/1168/1122 1022/1051/1022 1021/1054/1021 f 678/695/678 1198/1247/1198 625/631/625 f 678/695/678 625/631/625 27/8/27 f 1195/1242/1195 599/592/599 626/632/626 f 1195/1242/1195 626/632/626 1202/1248/1202 f 1202/1248/1202 626/632/626 628/634/628 f 1202/1248/1202 628/634/628 1220/1281/1220 f 1198/1247/1198 1220/1281/1220 628/634/628 f 1198/1247/1198 628/634/628 625/631/625 f 1222/1282/1222 1223/1283/1223 1224/1284/1224 f 1222/1282/1222 1224/1284/1224 1221/1285/1221 f 1226/1286/1226 1227/1287/1227 1228/1288/1228 f 1226/1286/1226 1228/1288/1228 1225/1289/1225 f 1230/1290/1230 1231/1291/1231 1232/1292/1232 f 1230/1290/1230 1232/1292/1232 1229/1293/1229 f 1234/1294/1234 1232/1292/1232 1231/1291/1231 f 1234/1294/1234 1231/1291/1231 1233/1295/1233 f 1236/1296/1236 1237/1297/1237 1238/1298/1238 f 1236/1296/1236 1238/1298/1238 1235/1299/1235 f 1221/1285/1221 1239/1300/1239 1240/1301/1240 f 1221/1285/1221 1240/1301/1240 1233/1295/1233 f 1242/1302/1242 1243/1303/1243 1244/1304/1244 f 1242/1302/1242 1244/1304/1244 1241/1305/1241 f 1237/1297/1237 1245/1306/1245 1246/1307/1246 f 1237/1297/1237 1246/1307/1246 1238/1298/1238 f 1246/1307/1246 1245/1306/1245 1242/1302/1242 f 1246/1307/1246 1242/1302/1242 1241/1305/1241 f 1248/1308/1248 1224/1284/1224 1249/1309/1249 f 1248/1308/1248 1249/1309/1249 1247/1310/1247 f 1249/1309/1249 1250/1311/1250 660/1312/660 f 1249/1309/1249 660/1312/660 659/1313/659 f 661/1314/661 1247/1310/1247 1249/1309/1249 f 661/1314/661 1249/1309/1249 659/1313/659 f 1221/1285/1221 1224/1284/1224 1248/1308/1248 f 1221/1285/1221 1248/1308/1248 1239/1300/1239 f 1231/1291/1231 1222/1282/1222 1221/1285/1221 f 1231/1291/1231 1221/1285/1221 1233/1295/1233 f 1232/1292/1232 1234/1294/1234 1243/1303/1243 f 1232/1292/1232 1243/1303/1243 1242/1302/1242 f 1244/1304/1244 1243/1303/1243 1234/1294/1234 f 1244/1304/1244 1234/1294/1234 1251/1315/1251 f 1240/1301/1240 1251/1315/1251 1234/1294/1234 f 1240/1301/1240 1234/1294/1234 1233/1295/1233 f 1253/1316/1253 1134/1181/1134 1135/1180/1135 f 1253/1316/1253 1135/1180/1135 1252/1317/1252 f 1254/1318/1254 1255/1319/1255 1229/1293/1229 f 1254/1318/1254 1229/1293/1229 1232/1292/1232 f 1254/1318/1254 1225/1289/1225 1228/1288/1228 f 1254/1318/1254 1228/1288/1228 1255/1319/1255 f 667/1320/667 1252/1317/1252 1135/1180/1135 f 667/1320/667 1135/1180/1135 539/1183/539 f 1226/1286/1226 1225/1289/1225 1237/1297/1237 f 1226/1286/1226 1237/1297/1237 1236/1296/1236 f 1245/1306/1245 1254/1318/1254 1232/1292/1232 f 1245/1306/1245 1232/1292/1232 1242/1302/1242 f 1254/1318/1254 1245/1306/1245 1237/1297/1237 f 1254/1318/1254 1237/1297/1237 1225/1289/1225 f 669/674/669 668/675/668 1226/1286/1226 f 669/674/669 1226/1286/1226 1236/1296/1236 f 1230/1290/1230 1256/1321/1256 1222/1282/1222 f 1230/1290/1230 1222/1282/1222 1231/1291/1231 f 1235/1299/1235 671/677/671 669/674/669 f 1235/1299/1235 669/674/669 1236/1296/1236 f 1230/1290/1230 1101/1139/1101 1100/1138/1100 f 1230/1290/1230 1100/1138/1100 1256/1321/1256 f 672/678/672 488/480/488 1103/1142/1103 f 672/678/672 1103/1142/1103 1227/1287/1227 f 1224/1284/1224 1223/1283/1223 1250/1311/1250 f 1224/1284/1224 1250/1311/1250 1249/1309/1249 f 1256/1321/1256 1100/1138/1100 1134/1181/1134 f 1256/1321/1256 1134/1181/1134 1253/1316/1253 f 1227/1287/1227 1103/1142/1103 1132/1178/1132 f 1227/1287/1227 1132/1178/1132 1228/1288/1228 f 1101/1139/1101 1230/1290/1230 1229/1293/1229 f 1101/1139/1101 1229/1293/1229 1133/1179/1133 f 1223/1283/1223 1253/1316/1253 1252/1317/1252 f 1223/1283/1223 1252/1317/1252 1250/1311/1250 f 1255/1319/1255 1136/1182/1136 1133/1179/1133 f 1255/1319/1255 1133/1179/1133 1229/1293/1229 f 1228/1288/1228 1132/1178/1132 1136/1182/1136 f 1228/1288/1228 1136/1182/1136 1255/1319/1255 f 660/1312/660 1250/1311/1250 1252/1317/1252 f 660/1312/660 1252/1317/1252 667/1320/667 f 668/675/668 672/678/672 1227/1287/1227 f 668/675/668 1227/1287/1227 1226/1286/1226 f 1222/1282/1222 1256/1321/1256 1253/1316/1253 f 1222/1282/1222 1253/1316/1253 1223/1283/1223 f 1/1322/1 12/1323/12 1247/1310/1247 f 1/1322/1 1247/1310/1247 661/1314/661 f 10/1324/10 8/1325/8 1240/1301/1240 f 10/1324/10 1240/1301/1240 1239/1300/1239 f 1239/1300/1239 1248/1308/1248 11/1326/11 f 1239/1300/1239 11/1326/11 10/1324/10 f 5/1327/5 3/1328/3 1235/1299/1235 f 5/1327/5 1235/1299/1235 1238/1298/1238 f 9/1329/9 4/1330/4 1246/1307/1246 f 9/1329/9 1246/1307/1246 1241/1305/1241 f 1240/1301/1240 8/1325/8 6/1331/6 f 1240/1301/1240 6/1331/6 1251/1315/1251 f 7/1332/7 9/1329/9 1241/1305/1241 f 7/1332/7 1241/1305/1241 1244/1304/1244 f 11/1326/11 1248/1308/1248 1247/1310/1247 f 11/1326/11 1247/1310/1247 12/1323/12 f 3/1328/3 2/690/2 671/677/671 f 3/1328/3 671/677/671 1235/1299/1235 f 1238/1298/1238 1246/1307/1246 4/1330/4 f 1238/1298/1238 4/1330/4 5/1327/5 f 7/1332/7 1244/1304/1244 1251/1315/1251 f 7/1332/7 1251/1315/1251 6/1331/6 f 1203/1251/1203 1013/1042/1013 1012/1043/1012 f 1203/1251/1203 1012/1043/1012 736/757/736 f 937/959/937 941/964/941 1027/1057/1027 f 937/959/937 1027/1057/1027 999/1030/999 f 1084/1122/1084 739/756/739 1034/1067/1034 f 1084/1122/1084 1034/1067/1034 1037/1071/1037 f 1197/1244/1197 1196/1243/1196 1201/1249/1201 f 1197/1244/1197 1201/1249/1201 1199/1245/1199 f 1203/1251/1203 736/757/736 739/756/739 f 1203/1251/1203 739/756/739 1084/1122/1084 f 936/962/936 784/805/784 941/964/941 f 936/962/936 941/964/941 937/959/937 f 786/806/786 1004/1033/1004 940/963/940 f 786/806/786 940/963/940 785/804/785 f 467/1333/467 612/604/612 387/1334/387 f 612/604/612 624/630/624 387/1334/387 f 621/628/621 387/1334/387 624/630/624 f 604/595/604 44/22/44 28/5/28 f 472/605/472 612/604/612 467/1333/467 f 29/6/29 28/5/28 47/26/47 f 43/21/43 48/25/48 44/22/44 f 30/7/30 266/1335/266 27/8/27 f 424/414/424 239/223/239 425/415/425 f 467/458/467 363/347/363 472/463/472 f 561/552/561 560/553/560 572/564/572 f 549/540/549 551/542/551 579/571/579 f 583/574/583 595/588/595 582/575/582 f 31/12/31 36/13/36 600/591/600 f 39/16/39 44/22/44 603/597/603 f 32/9/32 599/592/599 45/23/45 f 473/626/473 613/607/613 471/606/471 f 477/620/477 478/625/478 620/621/620 f 474/611/474 615/610/615 617/627/617 f 1257/1336/1257 614/609/614 618/616/618 f 1257/1336/1257 620/621/620 622/624/622 f 1257/1336/1257 618/616/618 619/619/619 f 1257/1336/1257 613/607/613 615/610/615 f 614/609/614 1257/1336/1257 615/610/615 f 622/624/622 623/629/623 1257/1336/1257 f 1257/1336/1257 623/629/623 611/603/611 f 624/630/624 623/629/623 621/628/621 f 469/617/469 618/616/618 470/615/470 f 614/609/614 476/608/476 533/614/533 f 610/602/610 1257/1336/1257 611/603/611 f 613/607/613 1257/1336/1257 610/602/610 f 620/621/620 1257/1336/1257 619/619/619 f 541/532/541 592/584/592 562/555/562 f 541/532/541 587/581/587 592/584/592 f 627/633/627 607/599/607 605/596/605 f 627/633/627 605/596/605 604/595/604 f 605/596/605 606/598/606 603/597/603 f 607/599/607 606/598/606 605/596/605 f 1207/1254/1207 1082/1337/1082 1015/1338/1015 f 1219/1280/1219 1207/1254/1207 1015/1338/1015 f 1015/1338/1015 1216/1278/1216 1219/1280/1219 f 693/710/693 1198/1247/1198 678/695/678 f 1207/1254/1207 1087/1253/1087 1082/1337/1082 f 678/695/678 677/697/677 694/712/694 f 695/713/695 692/711/692 693/710/693 f 266/1335/266 679/696/679 27/8/27 f 883/903/883 1044/1079/1044 1045/1078/1045 f 992/1020/992 1082/1121/1082 1087/1125/1087 f 1158/1205/1158 1157/1204/1157 1168/1216/1168 f 1147/1194/1147 1145/1192/1145 1176/1223/1176 f 1193/1240/1193 1180/1227/1180 1179/1226/1179 f 684/702/684 682/699/682 1195/1242/1195 f 693/710/693 686/707/686 1199/1245/1199 f 599/592/599 681/698/681 45/23/45 f 1208/1256/1208 1088/1276/1088 1086/1257/1086 f 1093/1274/1093 1092/1271/1092 1215/1270/1215 f 1210/1260/1210 1090/1259/1090 1212/1277/1212 f 1209/1261/1209 1258/1339/1258 1213/1264/1213 f 1215/1270/1215 1258/1339/1258 1217/1275/1217 f 1213/1264/1213 1258/1339/1258 1214/1267/1214 f 1208/1256/1208 1258/1339/1258 1210/1260/1210 f 1258/1339/1258 1209/1261/1209 1210/1260/1210 f 1218/1279/1218 1217/1275/1217 1258/1339/1258 f 1218/1279/1218 1258/1339/1258 1205/1255/1205 f 1218/1279/1218 1219/1280/1219 1216/1278/1216 f 1213/1264/1213 1083/1269/1083 1085/1265/1085 f 1091/1258/1091 1209/1261/1209 1131/1266/1131 f 1258/1339/1258 1206/1252/1206 1205/1255/1205 f 1258/1339/1258 1208/1256/1208 1206/1252/1206 f 1258/1339/1258 1215/1270/1215 1214/1267/1214 f 1189/1236/1189 1138/1184/1138 1160/1207/1160 f 1185/1231/1185 1138/1184/1138 1189/1236/1189 f 1202/1248/1202 1220/1281/1220 1200/1246/1200 f 1200/1246/1200 1220/1281/1220 1198/1247/1198 f 1201/1249/1201 1200/1246/1200 1199/1245/1199 f 1201/1249/1201 1202/1248/1202 1200/1246/1200 # 2492 faces ================================================ FILE: graphics/tiny-renderer/lesson2.workbook/Geometry.csx ================================================ struct Vec2f { public float x; public float y; public float this [int i] { get { if (i == 0) return x; if (i == 1) return y; throw new InvalidOperationException (); } set { if (i == 0) x = value; else if (i == 1) y = value; else throw new InvalidOperationException (); } } public Vec2f Normalize () { return this / Norm (); } public float Norm () { return (float)Math.Sqrt (x * x + y * y); } public static Vec2f operator / (Vec2f v, float num) { v.x /= num; v.y /= num; return v; } public static Vec2f operator * (Vec2f v, float num) { v.x *= num; v.y *= num; return v; } public static Vec2f operator - (Vec2f a, Vec2f b) { return new Vec2f { x = a.x - b.x, y = a.y - b.y }; } public static Vec2f operator + (Vec2f a, Vec2f b) { return new Vec2f { x = a.x + b.x, y = a.y + b.y }; } } public struct Vec3f { public float x; public float y; public float z; public float this [int i] { get { switch (i) { case 0: return x; case 1: return y; case 2: return z; default: throw new InvalidOperationException (); } } set { switch (i) { case 0: x = value; break; case 1: y = value; break; case 2: z = value; break; default: throw new InvalidOperationException (); } } } public Vec3f Normalize () { return this / Norm (); } public float Norm () { return (float)Math.Sqrt (x * x + y * y + z * z); } public static Vec3f operator - (Vec3f a, Vec3f b) { return new Vec3f { x = a.x - b.x, y = a.y - b.y, z = a.z - b.z }; } public static Vec3f operator / (Vec3f v, float num) { v.x /= num; v.y /= num; v.z /= num; return v; } public static Vec3f operator * (Vec3f v, float num) { v.x *= num; v.y *= num; v.z *= num; return v; } } struct Vec4f { public float x; public float y; public float z; public float h; public float this [int i] { get { switch (i) { case 0: return x; case 1: return y; case 2: return z; case 3: return h; default: throw new InvalidOperationException (); } } set { switch (i) { case 0: x = value; break; case 1: y = value; break; case 2: z = value; break; case 3: h = value; break; default: throw new InvalidOperationException (); } } } public Vec4f Normalize () { var len = Norm (); return this / len; } public float Norm () { return (float)Math.Sqrt (x * x + y * y + z * z + h * h); } public static Vec4f operator - (Vec4f a, Vec4f b) { return new Vec4f { x = a.x - b.x, y = a.y - b.y, z = a.z - b.z, h = a.h - b.h }; } public static Vec4f operator / (Vec4f v, float num) { v.x /= num; v.y /= num; v.z /= num; v.h /= num; return v; } } struct Vec2i { public int x; public int y; public static Vec2i operator - (Vec2i a, Vec2i b) { return new Vec2i { x = a.x - b.x, y = a.y - b.y }; } } struct Vec3i { public int x; public int y; public int z; public static Vec3i operator - (Vec3i a, Vec3i b) { return new Vec3i { x = a.x - b.x, y = a.y - b.y, z = a.z - b.z }; } } static class Geometry { public static Vec3f Cross (Vec3f l, Vec3f r) { return new Vec3f { x = l.y * r.z - l.z * r.y, y = l.z * r.x - l.x * r.z, z = l.x * r.y - l.y * r.x }; } public static float Dot (Vec3f l, Vec3f r) { return l.x * r.x + l.y * r.y + l.z * r.z; } public static Vec4f Embed4D (Vec3f v, float fill = 1) { return new Vec4f { x = v.x, y = v.y, z = v.z, h = fill }; } public static Vec2f Project2D (Vec3f v) { return new Vec2f { x = v.x, y = v.y }; } public static Vec2f Project2D (Vec4f v) { return new Vec2f { x = v.x, y = v.y }; } public static Vec3f Project3D (Vec4f v) { return new Vec3f { x = v.x, y = v.y, z = v.z }; } } ================================================ FILE: graphics/tiny-renderer/lesson2.workbook/Image.csx ================================================ using System.IO; enum Format { GRAYSCALE = 1, BGR = 3, BGRA = 4 } struct Color { // the value stored as little endian: // ARGB -> BGRA // xRGB -> BGRx public readonly int value; public readonly Format format; public byte this [int offset] { get { if (offset > 3) // int has only 4 bytes (0, 1, 2, 3) throw new ArgumentOutOfRangeException (); return (byte)(value >> 8 * (3 - offset)); } } public static Color Red = new Color (red: 255, green: 0, blue: 0, alpha: 255); public static Color Green = new Color (red: 0, green: 255, blue: 0, alpha: 255); public static Color Blue = new Color (red: 0, green: 0, blue: 255, alpha: 255); public static Color Black = new Color (red: 0, green: 0, blue: 0, alpha: 255); public static Color White = new Color (red: 255, green: 255, blue: 255, alpha: 255); public static Color Yellow = new Color (red: 225, green: 225, blue: 0, alpha: 255); public Color (byte red, byte green, byte blue, byte alpha) : this ((blue << 24) | (green << 16) | (red << 8) | alpha, Format.BGRA) { } public Color (byte red, byte green, byte blue) : this ((blue << 24) | (green << 16) | (red << 8) | 0xFF, Format.BGR) { } public Color (byte value) : this (value, Format.GRAYSCALE) { } public Color (int value, Format format) { this.value = value; this.format = format; } public static Color operator * (Color color, float intensivity) { intensivity = Math.Max (0f, Math.Min (1f, intensivity)); var ch0 = (byte)(color [0] * intensivity); var ch1 = (byte)(color [1] * intensivity); var ch2 = (byte)(color [2] * intensivity); var ch3 = color [3]; return new Color (ch0 << 24 | ch1 << 16 | ch2 << 8 | ch3, color.format); } } class Image { internal byte [] buffer; public int Width { get; } public int Height { get; } public Format Format { get; } public int BytesPerRow { get { return Width * (int)Format; } } public Image (int width, int height, Format format) { Width = width; Height = height; Format = format; buffer = new byte [height * BytesPerRow]; } public void VerticalFlip () { var bpp = (int)Format; int bytesPerLine = Width * bpp; var half = Height >> 1; for (int l = 0; l < half; l++) { var l1 = l * bytesPerLine; var l2 = (Height - 1 - l) * bytesPerLine; for (int i = 0; i < bytesPerLine; i++) { byte pixel = buffer [l1 + i]; buffer [l1 + i] = buffer [l2 + i]; buffer [l2 + i] = pixel; } } } public void Clear () { for (int i = 0; i < buffer.Length; i++) buffer [i] = 0; } public Color this [int x, int y] { get { if (x < 0 || x >= Width) throw new ArgumentException ("x"); if (y < 0 || y >= Height) throw new ArgumentException ("y"); var offset = GetOffset (x, y); var len = (int)Format; int value = 0; for (var ch = 0; ch < 4; ch++) value = (value << 8) | (ch < len ? buffer [offset++] : 0xFF); return new Color (value, Format); } set { if (x < 0 || x >= Width) return; //throw new ArgumentException ($"{nameof(x)}={x} {nameof(Width)}={Width}"); if (y < 0 || y >= Height) return; // throw new ArgumentException ($"{nameof(y)}={y} {nameof(Height)}={Height}"); var offset = GetOffset (x, y); var v = value.value; var len = (int)Format; for (int ch = 0; ch < len; ch++) // 0123 buffer [offset++] = (byte)(v >> (3 - ch) * 8); // BGRA } } int GetOffset (int x, int y) { return y * BytesPerRow + x * (int)Format; } public bool WriteToFile (string path, bool rle = true) { var bpp = (int)Format; using (var writer = new BinaryWriter (File.Create (path))) { var header = new TGAHeader { IdLength = 0, // The IDLength set to 0 indicates that there is no image identification field in the TGA file ColorMapType = 0, // a value of 0 indicates that no palette is included BitsPerPixel = (byte)(bpp * 8), Width = (short)Width, Height = (short)Height, DataTypeCode = DataTypeFor (bpp, rle), ImageDescriptor = (byte)(0x20 | (Format == Format.BGRA ? 8 : 0)) // top-left origin }; WriteTo (writer, header); if (!rle) writer.Write (buffer); else UnloadRleData (writer); } return true; } public static Image Load (string path) { using (var reader = new BinaryReader (File.OpenRead (path))) { var header = ReadHeader (reader); var height = header.Height; var width = header.Width; var bytespp = header.BitsPerPixel >> 3; var format = (Format)bytespp; if (width <= 0 || height <= 0) throw new InvalidProgramException ($"bad image size: width={width} height={height}"); if (format != Format.BGR && format != Format.BGRA && format != Format.GRAYSCALE) throw new InvalidProgramException ($"unknown format {format}"); var img = new Image (width, height, format); switch (header.DataTypeCode) { case DataType.UncompressedTrueColorImage: case DataType.UncompressedBlackAndWhiteImage: reader.Read (img.buffer, 0, img.buffer.Length); break; case DataType.RleTrueColorImage: case DataType.RleBlackAndWhiteImage: img.LoadRleData (reader); break; default: throw new InvalidProgramException ($"unsupported image format {header.DataTypeCode}"); } if ((header.ImageDescriptor & 0x20) == 0) img.VerticalFlip (); return img; } } static void WriteTo (BinaryWriter writer, TGAHeader header) { writer.Write (header.IdLength); writer.Write (header.ColorMapType); writer.Write ((byte)header.DataTypeCode); writer.Write (header.ColorMapOrigin); writer.Write (header.ColorMapLength); writer.Write (header.ColorMapDepth); writer.Write (header.OriginX); writer.Write (header.OriginY); writer.Write (header.Width); writer.Write (header.Height); writer.Write (header.BitsPerPixel); writer.Write (header.ImageDescriptor); } static TGAHeader ReadHeader (BinaryReader reader) { var header = new TGAHeader { IdLength = reader.ReadByte (), ColorMapType = reader.ReadByte (), DataTypeCode = (DataType)reader.ReadByte (), ColorMapOrigin = reader.ReadInt16 (), ColorMapLength = reader.ReadInt16 (), ColorMapDepth = reader.ReadByte (), OriginX = reader.ReadInt16 (), OriginY = reader.ReadInt16 (), Width = reader.ReadInt16 (), Height = reader.ReadInt16 (), BitsPerPixel = reader.ReadByte (), ImageDescriptor = reader.ReadByte () }; return header; } bool UnloadRleData (BinaryWriter writer) { const int max_chunk_length = 128; int npixels = Width * Height; int curpix = 0; var bpp = (int)Format; while (curpix < npixels) { int chunkstart = curpix * bpp; int curbyte = curpix * bpp; int run_length = 1; bool literal = true; while (curpix + run_length < npixels && run_length < max_chunk_length && curpix + run_length < curpix + Width) { bool succ_eq = true; for (int t = 0; succ_eq && t < bpp; t++) succ_eq = (buffer [curbyte + t] == buffer [curbyte + t + bpp]); curbyte += bpp; if (1 == run_length) literal = !succ_eq; if (literal && succ_eq) { run_length--; break; } if (!literal && !succ_eq) break; run_length++; } curpix += run_length; writer.Write ((byte)(literal ? run_length - 1 : 128 + (run_length - 1))); writer.Write (buffer, chunkstart, literal ? run_length * bpp : bpp); } return true; } void LoadRleData (BinaryReader reader) { var pixelcount = Width * Height; var currentpixel = 0; var currentbyte = 0; var bytespp = (int)Format; var color = new byte [4]; do { var chunkheader = reader.ReadByte (); if (chunkheader < 128) { chunkheader++; for (int i = 0; i < chunkheader; i++) { for (int t = 0; t < bytespp; t++) buffer [currentbyte++] = reader.ReadByte (); currentpixel++; if (currentpixel > pixelcount) throw new InvalidProgramException ("Too many pixels read"); } } else { chunkheader -= 127; reader.Read (color, 0, bytespp); for (int i = 0; i < chunkheader; i++) { for (int t = 0; t < bytespp; t++) buffer [currentbyte++] = color [t]; currentpixel++; if (currentpixel > pixelcount) throw new InvalidProgramException ("Too many pixels read"); } } } while (currentpixel < pixelcount); } static DataType DataTypeFor (int bpp, bool rle) { var format = (Format)bpp; if (format == Format.GRAYSCALE) return rle ? DataType.RleBlackAndWhiteImage : DataType.UncompressedBlackAndWhiteImage; return rle ? DataType.RleTrueColorImage : DataType.UncompressedTrueColorImage; } } struct TGAHeader { public byte IdLength; public byte ColorMapType; public DataType DataTypeCode; // field #4. Color map specification public short ColorMapOrigin; // index of first color map entry that is included in the file public short ColorMapLength; // number of entries of the color map that are included in the file public byte ColorMapDepth; // number of bits per pixel // field #5. Image specification public short OriginX; // absolute coordinate of lower-left corner for displays where origin is at the lower left public short OriginY; // as for X-origin public short Width; // width in pixels public short Height; // height in pixels public byte BitsPerPixel; // pixel depth public byte ImageDescriptor; // bits 3-0 give the alpha channel depth, bits 5-4 give direction } public enum DataType : byte { NoImageData = 0, // no image data is present UncompressedColorMappedImage = 1, UncompressedTrueColorImage = 2, UncompressedBlackAndWhiteImage = 3, RleColorMappedImage = 9, // run-length encoded color-mapped image RleTrueColorImage = 10, // run-length encoded true-color image RleBlackAndWhiteImage = 11 // run-length encoded black-and-white (grayscale) image } ================================================ FILE: graphics/tiny-renderer/lesson2.workbook/ImageResultHandler.csx ================================================ using XIR = Xamarin.Interactive.Representations; InteractiveAgent.RepresentationManager.AddProvider (img => { XIR.ImageFormat format; switch (img.Format) { case Format.BGRA: format = XIR.ImageFormat.Bgra32; break; case Format.BGR: format = XIR.ImageFormat.Bgr24; break; default: return null; } return new XIR.Image (format, img.buffer, img.Width, img.Height); }); ================================================ FILE: graphics/tiny-renderer/lesson2.workbook/LICENSE.txt ================================================ Tiny Renderer, https://github.com/ssloy/tinyrenderer Copyright Dmitry V. Sokolov This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. ================================================ FILE: graphics/tiny-renderer/lesson2.workbook/Matrix.csx ================================================ using System; public struct Matrix4 { public const int Len = 4; public float R0C0, R0C1, R0C2, R0C3; public float R1C0, R1C1, R1C2, R1C3; public float R2C0, R2C1, R2C2, R2C3; public float R3C0, R3C1, R3C2, R3C3; public float this [int row, int column] { get { switch (row) { case 0: switch (column) { case 0: return R0C0; case 1: return R0C1; case 2: return R0C2; case 3: return R0C3; } break; case 1: switch (column) { case 0: return R1C0; case 1: return R1C1; case 2: return R1C2; case 3: return R1C3; } break; case 2: switch (column) { case 0: return R2C0; case 1: return R2C1; case 2: return R2C2; case 3: return R2C3; } break; case 3: switch (column) { case 0: return R3C0; case 1: return R3C1; case 2: return R3C2; case 3: return R3C3; } break; } throw new IndexOutOfRangeException (); } set { switch (row) { case 0: switch (column) { case 0: R0C0 = value; return; case 1: R0C1 = value; return; case 2: R0C2 = value; return; case 3: R0C3 = value; return; } break; case 1: switch (column) { case 0: R1C0 = value; return; case 1: R1C1 = value; return; case 2: R1C2 = value; return; case 3: R1C3 = value; return; } break; case 2: switch (column) { case 0: R2C0 = value; return; case 1: R2C1 = value; return; case 2: R2C2 = value; return; case 3: R2C3 = value; return; } break; case 3: switch (column) { case 0: R3C0 = value; return; case 1: R3C1 = value; return; case 2: R3C2 = value; return; case 3: R3C3 = value; return; } break; } throw new IndexOutOfRangeException (); } } public Matrix4 Transpose () { return new Matrix4 { R0C0 = R0C0, R0C1 = R1C0, R0C2 = R2C0, R0C3 = R3C0, R1C0 = R0C1, R1C1 = R1C1, R1C2 = R2C1, R1C3 = R3C1, R2C0 = R0C2, R2C1 = R1C2, R2C2 = R2C2, R2C3 = R3C2, R3C0 = R0C3, R3C1 = R1C3, R3C2 = R2C3, R3C3 = R3C3 }; } public static Matrix4 Identity () { return new Matrix4 { R0C0 = 1, R1C1 = 1, R2C2 = 1, R3C3 = 1 }; } public static Matrix4 Zoom (float scale) { return new Matrix4 { R0C0 = scale, R1C1 = scale, R2C2 = scale, R3C3 = scale }; } public static Matrix4 RotationZ (float angle) { var cosangle = (float)Math.Cos (angle); var sinangle = (float)Math.Sin (angle); var R = Identity (); R [0, 0] = R [1, 1] = cosangle; R [0, 1] = -sinangle; R [1, 0] = sinangle; return R; } public static Matrix4 operator * (Matrix4 l, Matrix4 r) { var result = new Matrix4 (); for (int i = 0; i < Len; i++) { for (int j = 0; j < Len; j++) { result [i, j] = 0; for (int k = 0; k < Len; k++) { result [i, j] += l [i, k] * r [k, j]; } } } return result; } public override string ToString () { var sb = new System.Text.StringBuilder (); for (int r = 0; r < Len; r++) { for (int c = 0; c < Len; c++) sb.Append (this[r, c]).Append (" "); sb.AppendLine (); } return sb.ToString (); } } public struct Matrix3 { public const int Len = 3; public float R0C0, R0C1, R0C2; public float R1C0, R1C1, R1C2; public float R2C0, R2C1, R2C2; public float this [int row, int column] { get { switch (row) { case 0: switch (column) { case 0: return R0C0; case 1: return R0C1; case 2: return R0C2; } break; case 1: switch (column) { case 0: return R1C0; case 1: return R1C1; case 2: return R1C2; } break; case 2: switch (column) { case 0: return R2C0; case 1: return R2C1; case 2: return R2C2; } break; } throw new IndexOutOfRangeException (); } set { switch (row) { case 0: switch (column) { case 0: R0C0 = value; return; case 1: R0C1 = value; return; case 2: R0C2 = value; return; } break; case 1: switch (column) { case 0: R1C0 = value; return; case 1: R1C1 = value; return; case 2: R1C2 = value; return; } break; case 2: switch (column) { case 0: R2C0 = value; return; case 1: R2C1 = value; return; case 2: R2C2 = value; return; } break; } throw new IndexOutOfRangeException (); } } public Matrix3 Transpose () { return new Matrix3 { R0C0 = R0C0, R0C1 = R1C0, R0C2 = R2C0, R1C0 = R0C1, R1C1 = R1C1, R1C2 = R2C1, R2C0 = R0C2, R2C1 = R1C2, R2C2 = R2C2 }; } public void SetColumn (int col, Vec3f v) { this [0, col] = v.x; this [1, col] = v.y; this [2, col] = v.z; } public void SetRow (int row, Vec3f v) { this [row, 0] = v.x; this [row, 1] = v.y; this [row, 2] = v.z; } public override string ToString () { var sb = new System.Text.StringBuilder (); for (int r = 0; r < Len; r++) { for (int c = 0; c < Len; c++) sb.Append (this [r, c]).Append (" "); sb.AppendLine (); } return sb.ToString (); } } public struct Matrix2 { public const int Len = 2; public float R0C0, R0C1; public float R1C0, R1C1; public float this [int row, int column] { get { switch (row) { case 0: switch (column) { case 0: return R0C0; case 1: return R0C1; } break; case 1: switch (column) { case 0: return R1C0; case 1: return R1C1; } break; } throw new IndexOutOfRangeException (); } set { switch (row) { case 0: switch (column) { case 0: R0C0 = value; return; case 1: R0C1 = value; return; } break; case 1: switch (column) { case 0: R1C0 = value; return; case 1: R1C1 = value; return; } break; } throw new IndexOutOfRangeException (); } } } // we don't want to declare them in Matrix because we don't need them in lesson which introduces Matrix class static class MatrixHelpers { // For Matrix4 // how to calc inverse Matrix https://en.wikipedia.org/w/index.php?title=Invertible_matrix§ion=4#In_relation_to_its_adjugate public static Matrix4 TransposeInverse (Matrix4 m) { // returns Transpose(Inverse(m)) // where Inverse(m) = Transpose(cofactor) / det(m) // Transpose(Inverse(m)) = Transpose(Transpose(cofactor) / det(m)) = cofactor / det(m) var cofactor = Cofactor (m); float det = 0; for (int i = 0; i < Matrix4.Len; i++) det += m [0, i] * cofactor [0, i]; for (int r = 0; r < Matrix4.Len; r++) { for (int c = 0; c < Matrix4.Len; c++) cofactor [r, c] /= det; } return cofactor; } public static Matrix4 Inverse (Matrix4 m) { // where Inverse(m) = Transpose(Cofactor(m)) / det(m) var cofactor = Cofactor (m); int len = Matrix4.Len; float det = 0; for (int i = 0; i < len; i++) det += m [0, i] * cofactor [0, i]; cofactor = cofactor.Transpose (); for (int r = 0; r < len; r++) { for (int c = 0; c < len; c++) cofactor [r, c] /= det; } return cofactor; } public static Matrix3 Inverse (Matrix3 m) { // where Inverse(m) = Transpose(Cofactor(m)) / det(m) var cofactor = Cofactor (m); int len = Matrix3.Len; float det = 0; for (int i = 0; i < len; i++) det += m [0, i] * cofactor [0, i]; cofactor = cofactor.Transpose (); for (int r = 0; r < len; r++) { for (int c = 0; c < len; c++) cofactor [r, c] /= det; } return cofactor; } static Matrix4 Cofactor (Matrix4 m) { var r = new Matrix4 (); for (int row = 0; row < Matrix4.Len; row++) { for (int col = 0; col < Matrix4.Len; col++) r [row, col] = Cofactor (m, row, col); } return r; } static Matrix3 Cofactor (Matrix3 m) { var r = new Matrix3 (); for (int row = 0; row < Matrix3.Len; row++) { for (int col = 0; col < Matrix3.Len; col++) r [row, col] = Cofactor (m, row, col); } return r; } static float Cofactor (Matrix4 m, int row, int col) { int sign = ((row + col) % 2 == 0) ? 1 : -1; return Det (Minor (m, row, col)) * sign; } static float Cofactor (Matrix3 m, int row, int col) { int sign = ((row + col) % 2 == 0) ? 1 : -1; return Det (Minor (m, row, col)) * sign; } static Matrix3 Minor (Matrix4 m, int row, int col) { var minor = new Matrix3 (); for (int r = 0; r < Matrix3.Len; r++) { for (int c = 0; c < Matrix3.Len; c++) { int y = (r < row) ? r : r + 1; int x = (c < col) ? c : c + 1; minor [r, c] = m [y, x]; } } return minor; } static Matrix2 Minor (Matrix3 m, int row, int col) { var minor = new Matrix2 (); for (int r = 0; r < Matrix2.Len; r++) { for (int c = 0; c < Matrix2.Len; c++) { int y = (r < row) ? r : r + 1; int x = (c < col) ? c : c + 1; minor [r, c] = m [y, x]; } } return minor; } static float Det (Matrix3 m) { float det = 0; det += m [0, 0] * (m [1, 1] * m [2, 2] - m [1, 2] * m [2, 1]); det -= m [0, 1] * (m [1, 0] * m [2, 2] - m [1, 2] * m [2, 0]); det += m [0, 2] * (m [1, 0] * m [2, 1] - m [1, 1] * m [2, 0]); return det; } static float Det (Matrix2 m) { return m [0, 0] * m [1, 1] - m [0, 1] * m [1, 0]; } public static Vec3f Mult (Matrix3 m, Vec3f v) { return new Vec3f { x = m.R0C0 * v.x + m.R0C1 * v.y + m.R0C2 * v.z, y = m.R1C0 * v.x + m.R1C1 * v.y + m.R1C2 * v.z, z = m.R2C0 * v.x + m.R2C1 * v.y + m.R2C2 * v.z }; } public static Vec4f Mult (Matrix4 m, Vec4f v) { return new Vec4f { x = m.R0C0*v.x + m.R0C1*v.y + m.R0C2*v.z + m.R0C3*v.h, y = m.R1C0*v.x + m.R1C1*v.y + m.R1C2*v.z + m.R1C3*v.h, z = m.R2C0*v.x + m.R2C1*v.y + m.R2C2*v.z + m.R2C3*v.h, h = m.R3C0*v.x + m.R3C1*v.y + m.R3C2*v.z + m.R3C3*v.h }; } } ================================================ FILE: graphics/tiny-renderer/lesson2.workbook/Model.csx ================================================ using System.Collections.Generic; using System.Linq; struct Face { public int [] Vertices; public int [] Textures; public int [] Normals; } class Model { public List Vertices { get; } = new List (); public List Faces { get; } = new List (); public List Textures { get; } = new List (); public List Normals { get; } = new List (); public static Model FromFile (string path) { var model = new Model (); string line; using (var reader = new System.IO.StreamReader (path)) { while ((line = reader.ReadLine ()) != null) model.ParseLine (line); } Console.WriteLine ($"v#{model.Vertices.Count} f#{model.Faces.Count}"); return model; } public static Model FromText (string text) { var model = new Model (); var lines = text.Split (new char [] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); foreach (var line in lines) model.ParseLine (line); Console.WriteLine ($"v#{model.Vertices.Count} f#{model.Faces.Count}"); return model; } void ParseLine (string line) { Func parseV3f = strItems => new Vec3f { x = float.Parse (strItems [1]), y = float.Parse (strItems [2]), z = float.Parse (strItems [3]) }; var items = line.Split (new char [] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (line.StartsWith ("v ", StringComparison.InvariantCulture)) { Vertices.Add (parseV3f (items)); } else if (line.StartsWith ("vt ", StringComparison.InvariantCulture)) { Textures.Add (parseV3f (items)); } else if (line.StartsWith ("vn ", StringComparison.InvariantCulture)) { Normals.Add (parseV3f (items)); } else if (line.StartsWith ("f ", StringComparison.InvariantCulture)) { var indexes = items.Skip (1) .SelectMany (s => s.Split (new char [] { '/', ' ' }, StringSplitOptions.RemoveEmptyEntries)) .Select (s => int.Parse (s) - 1) // in wavefront obj all indices start at 1, not zero .ToArray (); Faces.Add (new Face { Vertices = indexes.Where ((v, index) => index % 3 == 0).ToArray (), Textures = indexes.Where ((v, index) => index % 3 == 1).ToArray (), Normals = indexes.Where ((v, index) => index % 3 == 2).ToArray () }); } } public Vec3f Normal (Face face, int nthvert) { int idx = face.Normals [nthvert]; return Normals [idx]; } public Vec3f Vertex (Face face, int nthvert) { int idx = face.Vertices [nthvert]; return Vertices [idx]; } public Vec3f GetUV (Face face, int nthvert) { int idx = face.Textures [nthvert]; return Textures [idx]; } } ================================================ FILE: graphics/tiny-renderer/lesson2.workbook/WpfImageResultHandler.csx ================================================ using System; using System.IO; using System.Windows.Media; using System.Windows.Media.Imaging; using XIR = Xamarin.Interactive.Representations; static PixelFormat ConvertFormat (Format format) { switch (format) { case Format.BGRA: return PixelFormats.Bgra32; case Format.GRAYSCALE: return PixelFormats.Gray8; case Format.BGR: default: return PixelFormats.Bgr24; } } InteractiveAgent.RepresentationManager.AddProvider (img => { var source = BitmapSource.Create (img.Width, img.Height, 96, 96, ConvertFormat (img.Format), null, img.buffer, img.BytesPerRow); var encoder = new PngBitmapEncoder (); var outputFrame = BitmapFrame.Create (source); encoder.Frames.Add (outputFrame); using (var memory = new MemoryStream ()) { encoder.Save (memory); return XIR.Image.FromPng (memory.GetBuffer (), img.Width, img.Height); } }); ================================================ FILE: graphics/tiny-renderer/lesson2.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" #load "lesson1.csx" using static Geometry; ``` # Lesson 2: Triangle rasterization and back face culling > ℹ️ This workbook is a port of an [excellent C++ series](https://github.com/ssloy/tinyrenderer/wiki) written by Dmitry Sokolov. We appreciate that original work is available under a license that allowed us to turn it into a Workbook. # Old-school method: Line sweeping Thus, the task is to draw two-dimensional triangles. For motivated students it normally takes a couple of hours, even if they are bad programmers. Last time we saw Bresenham’s line drawing algorithm. Today’s task is to draw a filled triangle. Funny enough, but this task is not trivial. I don’t know why, but I know that it’s true. Most of my students struggle with this simple task. So, the initial stub will look like this: ```csharp void Line (Image image, Vec2i p1, Vec2i p2, Color color) { Line(image, p1.x, p1.y, p2.x, p2.y, color); } void Line (Image image, Vec3f p1, Vec3f p2, Color color) { Line(image, (int)p1.x, (int)p1.y, (int)p2.x, (int)p2.y, color); } void Triangle (Image image, Vec2i[] t, Color color) { Line(image, t[0], t[1], color); Line(image, t[1], t[2], color); Line(image, t[2], t[0], color); } Vec2i[] t0 = { new Vec2i { x = 10, y = 70 }, new Vec2i { x = 50, y = 160 }, new Vec2i { x = 70, y = 80 } }; Vec2i[] t1 = { new Vec2i { x = 180, y = 50 }, new Vec2i { x = 150, y = 1 }, new Vec2i { x = 70, y = 180 } }; Vec2i[] t2 = { new Vec2i { x = 180, y = 150 }, new Vec2i { x = 120, y = 160 }, new Vec2i { x = 130, y = 180 } }; var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); image.VerticalFlip (); image ``` The code is simple: I provide three triangles for the initial debugging of your code. If we invoke `Line` inside the triangle function, we’ll get the contour of the triangle. How to draw a filled triangle? A good method of drawing a triangle must have the following features: * It should be (surprise!) simple and fast. * It should be symmetrical: the picture should not depend on the order of vertices passed to the drawing function. * If two triangles have two common vertices, there should be no holes between them because of rasterization rounding. We could add more requirements, but let’s do with these ones. Traditionally a line sweeping is used: 1. Sort vertices of the triangle by their y-coordinates 2. Rasterize simultaneously the left and the right sides of the triangle 3. Draw a horizontal line segment between the left and the right boundary points At this point my students start to lose the firm ground: which segment is the left one, which one is right? Besides, there are three segments in a triangle... Usually, after this introduction I leave my students for about an hour: once again, reading my code is much less valuable than comparing your own code with mine. `[One hour passes]` How do I draw a triangle? Once again, if you have a better method, I’d be glad to adopt it. Let us assume that we have three points of the triangle: `t0`, `t1`, `t2`, they are sorted in ascending order by the y-coordinate. Then, the boundary A is between `t0` and `t2`, boundary B is between `t0` and `t1`, and then between `t1` and `t2`. ```csharp void OrderByY (Vec2i[] t) { if(t[0].y > t[1].y) Swap(t, 0, 1); if(t[1].y > t[2].y) Swap(t, 1, 2); if(t[0].y > t[1].y) Swap(t, 0, 1); } void Triangle (Image image, Vec2i[] t, Color color) { OrderByY(t); Line(image, t[0], t[1], Color.Green); Line(image, t[1], t[2], Color.Green); Line(image, t[2], t[0], Color.Red); } var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); // Here boundary A is red, and boundary B is green. image.VerticalFlip (); image ``` Unfortunately, boundary B is made of two parts. Let us draw the bottom half of the triangle by cutting it horizontally: ```csharp void Triangle (Image image, Vec2i[] t, Color color) { OrderByY(t); float height_10 = t[1].y - t[0].y; float height_20 = t[2].y - t[0].y; for(int y=t[0].y; y<=t[1].y; y++) { var alpha = (y-t[0].y) / height_20; var beta = (y-t[0].y) / height_10; // be careful with divisions by zero Vec2i A = new Vec2i { x = t[0].x + (int)((t[2].x-t[0].x)*alpha), y = y}; Vec2i B = new Vec2i { x = t[0].x + (int)((t[1].x-t[0].x)*beta), y = y}; image[A.x, y] = Color.Red; image[B.x, y] = Color.Green; } } var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); image.VerticalFlip (); image ``` Note that the segments are not continuous. Last time when we drew straight lines we struggled to get continuous segments and here I did not bother with rotating the image (remember the xy swapping?). Why? We fill the triangles aftewards, that’s why. If we connect the corresponding pairs of points by horizontal lines, the gaps disappear: ```csharp void Triangle (Image image, Vec2i[] t, Color color) { OrderByY(t); float height_10 = t[1].y - t[0].y; float height_20 = t[2].y - t[0].y; for(int y=t[0].y; y<=t[1].y; y++) { var alpha = (y-t[0].y) / height_20; var beta = (y-t[0].y) / height_10; // be careful with divisions by zero Vec2i A = new Vec2i { x = t[0].x + (int)((t[2].x-t[0].x)*alpha), y = y}; Vec2i B = new Vec2i { x = t[0].x + (int)((t[1].x-t[0].x)*beta), y = y}; Line(image, A, B, Color.White); image[B.x, y] = Color.Green; image[A.x, y] = Color.Red; } } var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); image.VerticalFlip (); image ``` Now, let us draw the second (upper) half of the triangle. We can do this by adding a second loop: ```csharp void Triangle (Image image, Vec2i[] t, Color color) { OrderByY(t); float height_10 = t[1].y - t[0].y; float height_20 = t[2].y - t[0].y; for(int y=t[0].y; y<=t[1].y; y++) { var alpha = (y-t[0].y) / height_20; var beta = (y-t[0].y) / height_10; // be careful with divisions by zero Vec2i A = new Vec2i { x = t[0].x + (int)((t[2].x-t[0].x)*alpha), y = y}; Vec2i B = new Vec2i { x = t[0].x + (int)((t[1].x-t[0].x)*beta), y = y}; if(A.x > B.x) Swap(ref A, ref B); for (int j=A.x; j<=B.x; j++) image[j, y] = color; } float height_21 = t[2].y - t[1].y; for(int y=t[1].y; y<=t[2].y; y++) { var alpha = (y-t[0].y) / height_20; var beta = (y-t[1].y) / height_21; // be careful with divisions by zero Vec2i A = new Vec2i { x = t[0].x + (int)((t[2].x-t[0].x)*alpha), y = y}; Vec2i B = new Vec2i { x = t[1].x + (int)((t[2].x-t[1].x)*beta), y = y}; if(A.x > B.x) Swap(ref A, ref B); for (int j=A.x; j<=B.x; j++) image[j, y] = color; } } var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); image.VerticalFlip (); image ``` This could be enough, but I dislike to see the same code twice. That is why we will make it a bit less readable, but more handy for modifications/maintaining: ```csharp void Triangle (Image image, Vec2i[] t, Color color) { // I dont care about degenerate triangles if(t[0].y == t[1].y && t[1].y == t[2].y) return; OrderByY(t); float height_10 = t[1].y - t[0].y; float total_height = t[2].y - t[0].y; for(int i=0; i t[1].y - t[0].y || t[1].y == t[0].y; float segment_height = second_half ? t[2].y-t[1].y : t[1].y-t[0].y; var alpha = i / total_height; // be careful with divisions by zero var beta = (i - (second_half ? t[1].y-t[0].y : 0)) / segment_height; Vec2i A = new Vec2i { x = t[0].x + (int)((t[2].x-t[0].x)*alpha), y = t[0].y + i }; Vec2i B = new Vec2i { x = second_half ? t[1].x + (int)((t[2].x-t[1].x)*beta) : t[0].x + (int)((t[1].x-t[0].x)*beta), y = t[0].y + i }; if(A.x > B.x) Swap(ref A, ref B); for (int j=A.x; j<=B.x; j++) image[j, t[0].y + i] = color; } } var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); image.VerticalFlip (); image ``` # The method I adopt for my code While not being really complicated, the source code for the line sweeping is a bit messy. Moreover, it is really an old-school approach designed for mono-thread CPU programming. Let us take a look at the following pseudo-code: ```csharp // triangle(Vec2i[] points) { // Vec2i bbox[2] = find_bounding_box(points); // for (each pixel in the bounding box) { // if (inside(points, pixel)) { // put_pixel(pixel); // } // } // } ``` Do you like it? I do. It is really easy to find a bounding box. It is certainly no problem to check whether a point belongs a 2D triangle (or any convex polygon). *Off Topic: if I have to implement some code to check whether a point belongs to a polygon, and this program will run on a plane, I will never get on this plane. Turns out, it is a surprisingly difficult task to solve this problem reliably. But here we just painting pixels. I am okay with that.* There is another thing I like about this pseudocode: a neophyte in programming accepts it with enthusiasm, more experienced programmers often chuckle: “*What an idiot wrote it?*”. And an expert in computer graphics programming will shrug his shoulders and say: “*Well, that’s how it works in real life*”. Massively parallel computations in thousands of threads (i’m talking about regular consumer computers here) change the way of thinking. Okay, let us start: first of all we need to know what the [barycentric coordinates](https://en.wikipedia.org/wiki/Barycentric_coordinate_system) are. Given a 2D triangle ABC and a point P, all in old good Cartesian coordinates `(xy)`. Our goal is to find barycentric coordinates of the point P with respect to the triangle ABC. It means that we look for three numbers `(1 − u − v,u,v)` such that we can find the point P as follows: ![ ](./img/lesson2_f1.png) While being a bit frightening at the first glance, it is really simple: imagine that we put three weights `(1−u−v,u,v)` at the vertices A, B and C, respectively. Then the barycenter of the system is exactly in the point P. We can say the same thing with other words: the point P has coordinates `(u,v)` in the (oblique) basis (A,![](./img/lesson2_ab.png),![](./img/lesson2_ac.png)): ![ ](./img/lesson2_f2.png) So, we have vectors ![](./img/lesson2_ab.png), ![](./img/lesson2_ac.png) and ![](./img/lesson2_ap.png), we need to find two real numbers u and v respecting the following constraint: ![ ](./img/lesson2_f3.png) It is a simple vector equation, or a linear system of two equations with two variables: ![ ](./img/lesson2_f4.png) I am lazy and do not want to solve linear systems in a scholar way. Let us write it in matrix form: ![ ](./img/lesson2_f5.png) It means that we are looking for a vector `(u,v,1)` that is orthogonal to `(ABx,ACx,PAx)` and `(ABy,ACy,PAy)` *at the same time*! I hope you see [where I am heading](https://en.wikipedia.org/wiki/Cross_product). That is a small hint: to find an intersection of two straight lines in a plane (that is exactly what we did here), it is sufficient to compute one cross product. By the way, test yourself: how do we find an equation of a line passing through two given points? So, let us program our new rasterization routine: we iterate through all pixels of a bounding box for a given triangle. For each pixel we compute its barycentric coordinates. If it has at least one negative component, then the pixel is outside of the triangle. Probably it is more clear to see the program directly: ```csharp Vec3f Barycentric (Vec3f a, Vec3f b, Vec3f c, Vec2i p) { var pixel = new Vec3f { x = p.x + 0.5f, y = p.y + 0.5f }; var ab = b - a; var ac = c - a; var pa = a - pixel; var r = Cross (new Vec3f { x = ab.x, y = ac.x, z = pa.x }, new Vec3f { x = ab.y, y = ac.y, z = pa.y }); // triangle is degenerate, in this case return smth with negative coordinates if (Math.Abs (r.z) < 1) return new Vec3f { x = -1, y = 1, z = 1 }; return new Vec3f { x = 1 - r.x / r.z - r.y / r.z, y = r.x / r.z, z = r.y / r.z }; } void Triangle (Image image, Vec3f [] coordinates, Color color) { var t0 = coordinates [0]; var t1 = coordinates [1]; var t2 = coordinates [2]; var pMax = new Vec2i { x = (int)Math.Max (0, Math.Max (t0.x, Math.Max (t1.x, t2.x))), y = (int)Math.Max (0, Math.Max (t0.y, Math.Max (t1.y, t2.y))) }; var pMin = new Vec2i { x = (int)Math.Min (image.Width, Math.Min (t0.x, Math.Min (t1.x, t2.x))), y = (int)Math.Min (image.Height, Math.Min (t0.y, Math.Min (t1.y, t2.y))) }; Vec2i p; for (p.x = pMin.x; p.x <= pMax.x; p.x++) { for (p.y = pMin.y; p.y <= pMax.y; p.y++) { var bc = Barycentric (t0, t1, t2, p); if (bc.x < 0 || bc.y < 0 || bc.z < 0) continue; image [p.x, p.y] = color; } } } ``` # Flat shading render We already know how to draw a model with empty triangles. Let us fill them with a random color. This will help us to see how well we have encoded filling of triangles. Here is the code: ```csharp var image = new Image(width, height, Format.BGR); // Map world coordinates [-1..-1] to screen coordinates [0..width] Func map = v => new Vec3f { x = (int)((v.x+1)*image.Width/2), y = (int)((v.y+1)*image.Height/2) }; var rnd = new Random(); Func rndByte = () => (byte)rnd.Next(255); Func rndColor = () => new Color(rndByte(), rndByte(), rndByte()); var coordinates = new Vec3f[3]; foreach(var face in headModel.Faces) { for(int i=0; i<3; i++) { var vIndex = face.Vertices[i]; var v = headModel.Vertices[vIndex]; coordinates[i] = map(v); } Triangle(image, coordinates, rndColor()); } image.VerticalFlip (); image ``` Let us get rid of these clown-colors and put some lighting. Captain Obvious: ”*At the same light intensity, the polygon is illuminated most brightly when it is orthogonal to the light direction.*” Let us compare: ![ ](./img/lesson2_light1.jpeg) ![](./img/lesson2_light2.jpeg) We get zero illumination if the polygon is parallel to the vector of light. To paraphrase: the intensity of illumination is equal to the scalar product of the light vector and the normal to the given triangle. The normal to the triangle can be calculated simply as the [cross product](https://en.wikipedia.org/wiki/Cross_product) of its two sides. As a side note, at this course we will perform linear computations on the colors. However `(128,128,128)` color is not half as bright as `(255, 255, 255)`. We are going to ignore gamma correction and tolerate the incorrectness of the brightness of our colors. ```csharp var image = new Image (width, height, Format.BGR); var light_dir = new Vec3f { x = 0, y = 0, z = -1 }; var world = new Vec3f [3]; var screen = new Vec3f [3]; foreach (var face in headModel.Faces) { for (int i = 0; i < 3; i++) { var vIndex = face.Vertices [i]; world [i] = headModel.Vertices [vIndex]; screen [i] = map (world [i]); } var n = Cross (world [2] - world [0], world [1] - world [0]).Normalize (); var intensivity = Dot (n, light_dir); if (intensivity > 0) Triangle (image, screen, Color.White * intensivity); } image.VerticalFlip (); image ``` ================================================ FILE: graphics/tiny-renderer/lesson2.workbook/lesson1.csx ================================================ int width = 800; int height = 800; var headModel = Model.FromFile ("obj/african_head.obj"); static void Swap(ref T x, ref T y) { T t = y; y = x; x = t; } static void Swap(T[] arr, int x, int y) { T t = arr[y]; arr[y] = arr[x]; arr[x] = t; } Image Line (Image image, int x0, int y0, int x1, int y1, Color color) { bool steep = false; // if the line is steep, we transpose the image if (Math.Abs (x0-x1) < Math.Abs (y0-y1)) { Swap (ref x0, ref y0); Swap (ref x1, ref y1); steep = true; } if (x0 > x1) { // make it left to right Swap (ref x0, ref x1); Swap (ref y0, ref y1); } // (x0, y0) == (x1, y1) if(x0 == x1) { image [x0, y0] = color; } else { for (int x = x0; x <= x1; x++) { double t = (x-x0) / (double)(x1-x0); int y = (int)Math.Round(y0*(1-t) + y1*t); if (steep) image [y, x] = color; else image [x, y] = color; } } return image; } ================================================ FILE: graphics/tiny-renderer/lesson2.workbook/lesson1.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" ``` # **Lesson 1: Bresenham’s Line Drawing Algorithm** # First attempt The goal of the first lesson is to render the wire mesh. To do this, we should learn how to draw line segments. We can simply read what Bresenham’s line algorithm is, but let’s write code ourselves. How does the simplest code that draws a line segment between `(x0, y0)` and `(x1, y1)` points look like? Apparently, something like this: ```csharp Image Line (Image image, int x0, int y0, int x1, int y1, Color color) { for (double t = 0; t < 1; t += 0.01) { int x = (int) (x0 * (1-t) + x1 * t); int y = (int) (y0 * (1-t) + y1 * t); image [x, y] = color; } return image; } Line (new Image (100, 100, Format.BGR), x0: 13, y0: 20, x1: 80, y1: 40, color: Color.White); ``` # Second attempt The problem with this code (in addition to efficiency) is the choice of the constant, which I took equal to .01. If we take it equal to .1, our line segment will look like this: ```csharp Image Line (Image image, int x0, int y0, int x1, int y1, Color color) { for (int x = x0; x <= x1; x++) { double t = (x-x0)/(double)(x1-x0); int y = (int)(y0*(1-t) + y1*t); image [x, y] = color; } return image; } Line (new Image (100, 100, Format.BGR), x0: 13, y0: 20, x1: 80, y1: 40, color: Color.White); ``` Caution! The first source of errors in such code of my students is the integer division, like: `(x-x0)/(x1-x0)`. Then, if we try to draw the following lines with this code: ```csharp var image = new Image (100, 100, Format.BGR); Line(image, x0: 13, y0: 20, x1: 80, y1: 40, color: Color.White); Line(image, x0: 20, y0: 13, x1: 40, y1: 80, color: Color.Red); Line(image, x0: 80, y0: 40, x1: 13, y1: 20, color: Color.Red); ``` It turns out that one line is good, the second one is with holes, and there’s no third line at all. Note that the first and the third lines (in the code) draw the same line in different colors, and in different directions (with the source and target points flipped). We have already seen the white one, it is drawn well. I was hoping to change the color of the white line to red, but could not do it. It’s a test for symmetry: the result of drawing a line segment should not depend on the order of points: the `(a,b)` line segment should be exactly the same as the `(b,a)` line segment. # Third attempt We fix the missing red line by swapping the points so `x0` is always lower than `x1`. There are holes in one of the line segments due to the fact that its height is greater than the width. My students often suggest the following fix: `if (dx > dy) { for (int x) } else { for (int y) }` Holy cow! ```csharp static void Swap(ref T x, ref T y) { T t = y; y = x; x = t; } static void Swap(T[] arr, int x, int y) { T t = arr[y]; arr[y] = arr[x]; arr[x] = t; } Image Line (Image image, int x0, int y0, int x1, int y1, Color color) { bool steep = false; // if the line is steep, we transpose the image if (Math.Abs (x0-x1) < Math.Abs (y0-y1)) { Swap (ref x0, ref y0); Swap (ref x1, ref y1); steep = true; } if (x0 > x1) { // make it left to right Swap (ref x0, ref x1); Swap (ref y0, ref y1); } // (x0, y0) == (x1, y1) if(x0 == x1) { image [x0, y0] = color; } else { for (int x = x0; x <= x1; x++) { double t = (x-x0) / (double)(x1-x0); int y = (int)Math.Round(y0*(1-t) + y1*t); if (steep) image [y, x] = color; else image [x, y] = color; } } return image; } Line(image, x0: 13, y0: 20, x1: 80, y1: 40, color: Color.White); Line(image, x0: 20, y0: 13, x1: 40, y1: 80, color: Color.Red); Line(image, x0: 80, y0: 40, x1: 13, y1: 20, color: Color.Red); ``` # Wireframe rendering So now we are ready to create a wire render. You can find the snapshot of the code and the test model here. I used the [wavefront obj](http://en.wikipedia.org/wiki/Wavefront_.obj_file) format of the file to store model. All we need for the render is read from the file the array of vertices of the following type: `v 0.608654 -0.568839 -0.416318` are `x,y,z` coordinates, one vertex per file line and faces `f 1193/1240/1193 1180/1227/1180 1179/1226/1179` ```csharp int width = 800, height = 800; var headModel = Model.FromFile ("obj/african_head.obj"); var image = new Image(width, height, Format.BGR); foreach(var face in headModel.Faces) { for(int j=0; j<3; j++) { var v0 = headModel.Vertices[face.Vertices [j]]; var v1 = headModel.Vertices[face.Vertices [(j+1) % 3]]; // scale x from [-1..1] to [0..w] // scale y from [-1..1] to [0..h] int x0 = (int)((v0.x + 1) * width / 2); int y0 = (int)((v0.y + 1) * height / 2); int x1 = (int)((v1.x + 1) * width / 2); int y1 = (int)((v1.y + 1) * height / 2); Line(image, x0, y0, x1, y1, Color.White); } } image.VerticalFlip (); image ``` ================================================ FILE: graphics/tiny-renderer/lesson2.workbook/lesson2.csx ================================================ using static Geometry; var light_dir = new Vec3f { x = 0, y = 0, z = -1 }; var world = new Vec3f [3]; var screen = new Vec3f [3]; void Line (Image image, Vec2i p1, Vec2i p2, Color color) { Line(image, p1.x, p1.y, p2.x, p2.y, color); } void Line (Image image, Vec3f p1, Vec3f p2, Color color) { Line(image, (int)p1.x, (int)p1.y, (int)p2.x, (int)p2.y, color); } void Triangle (Image image, Vec2i[] t, Color color) { Line(image, t[0], t[1], color); Line(image, t[1], t[2], color); Line(image, t[2], t[0], color); } Vec3f Barycentric (Vec3f a, Vec3f b, Vec3f c, Vec2i p) { var pixel = new Vec3f { x = p.x + 0.5f, y = p.y + 0.5f }; var ab = b - a; var ac = c - a; var pa = a - pixel; var r = Cross (new Vec3f { x = ab.x, y = ac.x, z = pa.x }, new Vec3f { x = ab.y, y = ac.y, z = pa.y }); // triangle is degenerate, in this case return smth with negative coordinates if (Math.Abs (r.z) < 1) return new Vec3f { x = -1, y = 1, z = 1 }; return new Vec3f { x = 1 - r.x / r.z - r.y / r.z, y = r.x / r.z, z = r.y / r.z }; } void Triangle (Image image, Vec3f [] coordinates, Color color) { var t0 = coordinates [0]; var t1 = coordinates [1]; var t2 = coordinates [2]; var pMax = new Vec2i { x = (int)Math.Max (0, Math.Max (t0.x, Math.Max (t1.x, t2.x))), y = (int)Math.Max (0, Math.Max (t0.y, Math.Max (t1.y, t2.y))) }; var pMin = new Vec2i { x = (int)Math.Min (image.Width, Math.Min (t0.x, Math.Min (t1.x, t2.x))), y = (int)Math.Min (image.Height, Math.Min (t0.y, Math.Min (t1.y, t2.y))) }; Vec2i p; for (p.x = pMin.x; p.x <= pMax.x; p.x++) { for (p.y = pMin.y; p.y <= pMax.y; p.y++) { var bc = Barycentric (t0, t1, t2, p); if (bc.x < 0 || bc.y < 0 || bc.z < 0) continue; image [p.x, p.y] = color; } } } ================================================ FILE: graphics/tiny-renderer/lesson2.workbook/obj/african_head.obj ================================================ v -0.000581696 -0.734665 -0.623267 v 0.000283538 -1 0.286843 v -0.117277 -0.973564 0.306907 v -0.382144 -0.890788 0.221243 v -0.247144 -0.942602 0.276051 v -0.656078 -0.718512 -0.109025 v -0.609847 -0.786562 0.0198068 v -0.66248 -0.632053 -0.244271 v -0.511812 -0.845392 0.127809 v -0.609326 -0.569868 -0.41571 v -0.426949 -0.649767 -0.567143 v -0.201076 -0.720822 -0.633205 v 0.117382 -0.973645 0.306766 v 0.382454 -0.890869 0.221097 v 0.247512 -0.942667 0.275986 v 0.656371 -0.718624 -0.109224 v 0.610273 -0.786562 0.0197893 v 0.66248 -0.631463 -0.244119 v 0.511631 -0.845357 0.127832 v 0.608654 -0.568839 -0.416318 v 0.424663 -0.649937 -0.567418 v 0.198972 -0.720968 -0.633141 v 0.153371 -0.140519 0.477416 v 0.134781 -0.14723 0.48805 v 0.131261 -0.132153 0.49872 v 0.14749 -0.135105 0.489565 v 0.000686924 -0.0534984 0.505694 v 0.075062 -0.0473306 0.49955 v 0.0695841 -0.0997942 0.550277 v 0.0302569 -0.0971868 0.55389 v 0.0745124 -0.135953 0.523215 v 0.0354892 -0.12785 0.535159 v 0.0389268 -0.109557 0.550558 v 0.0734835 -0.11538 0.538029 v 0.106386 -0.125623 0.51513 v 0.107415 -0.144295 0.5047 v 0.15968 -0.130861 0.484794 v 0.156224 -0.123705 0.486735 v 0.15792 -0.107798 0.4677 v 0.163784 -0.126996 0.470144 v 0.154687 -0.134655 0.486373 v 0.160668 -0.135649 0.476189 v 0.143433 -0.119034 0.499854 v 0.131606 -0.0726738 0.476148 v -0.000260156 -0.124553 0.539058 v -0.000646004 -0.110651 0.55444 v 0.100423 -0.10574 0.537643 v 0.126128 -0.115784 0.515598 v 0.250944 -0.275583 0.380381 v 0.221602 -0.335752 0.330174 v 0.275434 -0.301318 0.24751 v 0.307699 -0.239869 0.292356 v 0.332124 -0.0415605 0.412962 v 0.319444 0.00732526 0.451091 v 0.28667 -0.025805 0.481549 v 0.297006 -0.0758717 0.454242 v 0.357953 -0.159928 -0.223225 v 0.303981 -0.144611 -0.343644 v 0.296386 -0.0547553 -0.357792 v 0.357339 -0.0633433 -0.24278 v 0.45086 0.331215 0.047962 v 0.438899 0.336167 0.131147 v 0.447405 0.226107 0.139349 v 0.455613 0.205353 0.0827643 v 0.197493 -0.411308 0.138256 v 0.204911 -0.353378 0.2082 v 0.102001 -0.419375 0.24969 v 0.0995867 -0.475697 0.20834 v 0.150133 -0.372261 0.431226 v 0.176423 -0.362054 0.392056 v 0.196019 -0.326474 0.426929 v 0.154611 -0.348549 0.463444 v 0.0892273 -0.391968 0.303592 v 0.159013 -0.363737 0.305077 v 0.455712 0.508986 -0.0641442 v 0.432146 0.648411 -0.0417475 v 0.417051 0.611568 0.0817295 v 0.44205 0.483438 0.0478626 v 0.3446 0.43288 0.398633 v 0.372358 0.383369 0.353998 v 0.388341 0.404485 0.306953 v 0.355059 0.467372 0.356967 v 0.305162 0.338815 0.458112 v 0.298579 0.319803 0.456627 v 0.313422 0.304568 0.427776 v 0.323711 0.315968 0.429291 v 0.33161 0.397557 0.430226 v 0.354427 0.359727 0.390478 v 0.304162 0.291952 0.432377 v 0.292662 0.309771 0.452991 v 0.282934 0.292496 0.4562 v 0.292025 0.281663 0.435178 v 0.397344 0.565249 0.192585 v 0.42257 0.455996 0.145494 v 0.317848 0.364866 0.448834 v 0.340595 0.337517 0.417978 v 0.243227 0.479439 0.494236 v 0.250155 0.546138 0.465934 v 0.179019 0.560251 0.511681 v 0.170173 0.4781 0.536229 v 0.162386 0.410407 0.547009 v 0.235031 0.427051 0.517018 v 0.271745 0.634415 0.42162 v 0.196896 0.657291 0.472505 v 0.186589 0.312952 0.511073 v 0.189518 0.32493 0.514165 v 0.146286 0.31277 0.509009 v 0.144959 0.300178 0.501713 v 0.143965 0.300412 0.49409 v 0.187203 0.310596 0.506407 v 0.157744 0.364614 0.528804 v 0.216697 0.382527 0.516083 v 0.194441 0.332425 0.515989 v 0.204286 0.349818 0.516732 v 0.156254 0.334062 0.519579 v 0.151565 0.320341 0.513961 v 0.0431068 0.071791 0.618005 v 0.0477954 0.0867105 0.593486 v 0.0780844 0.0816652 0.602518 v 0.0574124 0.0746147 0.621185 v 0.448253 0.130656 0.149533 v 0.431801 0.159355 0.215905 v 0.422792 0.0771637 0.237185 v 0.428691 0.0348783 0.166914 v 0.365073 -0.0526507 0.316126 v 0.326974 -0.104793 0.373068 v 0.312773 -0.172965 0.33446 v 0.368107 -0.126698 0.269222 v 0.203695 -0.131796 0.523934 v 0.180463 -0.136479 0.525396 v 0.182848 -0.14892 0.516989 v 0.204163 -0.152533 0.514914 v 0.39379 0.00616771 0.269368 v 0.40177 -0.0591341 0.209048 v 0.26083 -0.0996422 0.484274 v 0.250406 -0.0552171 0.50321 v 0.15851 -0.136292 0.498474 v 0.155032 -0.134684 0.502964 v 0.145006 -0.133819 0.514504 v 0.171033 -0.12032 0.538263 v 0.158849 -0.127938 0.534943 v 0.167969 -0.138075 0.523788 v 0.232061 -0.151474 0.497024 v 0.23074 -0.117128 0.507191 v 0.365798 0.221617 0.362743 v 0.342501 0.235507 0.392185 v 0.325951 0.202558 0.415114 v 0.359268 0.178677 0.383229 v 0.352369 0.0489033 0.417452 v 0.322262 0.0907619 0.44953 v 0.295322 0.04895 0.483251 v 0.367108 0.00328555 0.369771 v 0.138972 -0.18796 0.555521 v 0.161562 -0.177794 0.535913 v 0.154015 -0.155093 0.536392 v 0.136131 -0.156414 0.558491 v 0.220263 -0.08194 0.518603 v 0.202088 -0.0486753 0.52791 v 0.17564 -0.0814314 0.545822 v 0.193131 -0.106435 0.533575 v 0.199492 -0.169714 0.509722 v 0.190033 -0.188183 0.514668 v 0.207302 -0.213011 0.492721 v 0.222415 -0.183044 0.489617 v 0.125088 -0.132884 0.551294 v 0.144497 -0.139192 0.530254 v 0.135014 0.119128 0.544717 v 0.119534 0.149685 0.554253 v 0.096915 0.171211 0.569382 v 0.112553 0.137432 0.569616 v 0.0878476 0.217858 0.555667 v 0.0649773 0.232128 0.568628 v 0.073466 0.185119 0.584571 v 0.116359 0.191199 0.548932 v 0.111419 0.228591 0.524951 v 0.0858774 0.255408 0.530312 v 0.301408 0.0368718 -0.387812 v 0.366839 0.037626 -0.269538 v 0.272125 -0.199781 0.399533 v 0.246349 -0.195514 0.453266 v 0.223339 -0.243049 0.450553 v 0.364021 -0.197455 0.21335 v 0.411416 -0.124798 0.140589 v 0.431568 -0.0028997 0.0907502 v 0.449346 0.11075 0.0889086 v 0.0649948 0.777167 0.432594 v 0.133465 0.770619 0.418569 v 0.14341 0.869244 0.301253 v 0.0689586 0.877043 0.315395 v 0.305372 0.809321 0.22043 v 0.289307 0.723856 0.335524 v 0.355187 0.660735 0.264773 v 0.372264 0.728258 0.148528 v 0.382308 0.7766 0.0116631 v 0.0971488 0.470588 0.557912 v 0.110788 0.565185 0.534317 v 0.100113 0.277828 0.510938 v 0.10966 0.248679 0.503771 v 0.0443988 0.240822 0.58581 v 0.0522151 0.193614 0.604337 v 0.052601 0.564735 0.541859 v 0.123726 0.667896 0.498907 v 0.0597976 0.671147 0.508711 v 0.0466729 0.466215 0.561034 v 0.000423846 0.462807 0.558988 v -0.00017831 0.388326 0.563478 v 0.0352086 0.389069 0.560584 v 0.000833078 0.56384 0.544139 v 0.295773 0.426823 0.470722 v 0.301706 0.464689 0.451056 v 0.189957 0.181465 0.501181 v 0.186163 0.208931 0.491956 v 0.141574 0.222722 0.500509 v 0.146526 0.195338 0.518293 v 0.111986 0.0116865 0.562811 v 0.111343 0.0404672 0.565769 v 0.0577164 0.0420398 0.577988 v 0.0656438 -0.00796249 0.596918 v 0.147695 0.0440509 0.537258 v 0.144778 0.0631738 0.538491 v 0.0268719 -0.0140834 0.602378 v 0.0270356 -0.0372401 0.622027 v 0.0876429 -0.0456996 0.601127 v 0.183093 0.146552 0.519439 v 0.148589 0.164593 0.536819 v 0.147344 0.131095 0.542934 v 0.176733 0.112264 0.532435 v -0.000394618 -0.0441035 0.617625 v -0.000260156 -0.0187662 0.600677 v 0.165058 0.0770935 0.530856 v 0.148554 0.0982976 0.535562 v 0.116476 0.272829 0.494797 v 0.119084 0.26261 0.493569 v 0.120873 0.268971 0.480883 v 0.11761 0.27287 0.484221 v 0.224695 0.848444 0.271198 v 0.231324 0.918189 0.121063 v 0.14614 0.9439 0.150241 v 0.241894 0.945736 -0.185803 v 0.156043 0.976475 -0.183418 v 0.146906 0.980702 -0.0177607 v 0.23195 0.948285 -0.0402158 v 0.0684324 0.995189 -0.00981573 v 0.0682103 0.955014 0.162933 v 0.0891571 0.383649 0.555118 v 0.110613 0.336412 0.528863 v 0.122749 0.310759 0.512914 v 0.147081 -0.111919 0.55631 v 0.158656 -0.0994551 0.55786 v 0.0939743 0.0869969 0.616333 v 0.101206 0.119326 0.615532 v 0.0670469 0.122121 0.645885 v 0.0560853 0.0831385 0.640601 v 0.0795284 0.0820978 0.567845 v 0.0337354 0.0564741 0.595059 v 0.0854448 -0.103577 0.606979 v 0.0826211 -0.0671141 0.612931 v 0.0280704 -0.0555854 0.637736 v 0.0319698 -0.0970874 0.628212 v 0.0789964 -0.121811 0.579602 v 0.0327415 -0.116959 0.594106 v 0.0216981 0.0173339 0.585915 v -0.00123062 -0.095585 0.625704 v -0.000511542 -0.0598999 0.637227 v -0.00157555 -0.115643 0.593966 v -0.000219233 -0.0988881 0.554498 v 0.0291929 0.0853015 0.665324 v 0.0352671 0.124524 0.666125 v 0.0371846 0.159004 0.648446 v 0.0654158 0.154462 0.629171 v 0.0280178 0.19967 0.620548 v 0.0221015 0.245843 0.59797 v 0.0432997 0.281499 0.556866 v 0.0222008 0.28717 0.567459 v -0.000400465 0.125745 0.673871 v -0.00057585 0.0822265 0.675105 v -0.000347849 0.160916 0.656029 v 0.367195 0.315074 0.363767 v 0.346658 0.302744 0.393991 v 0.344389 0.266656 0.384439 v 0.371726 0.266504 0.352507 v 0.40246 0.429197 0.234116 v 0.422126 0.335763 0.207276 v 0.393316 0.264083 0.313887 v 0.387102 0.325737 0.325369 v 0.3274 0.295928 0.408636 v 0.316392 0.29076 0.418709 v 0.3085 0.274624 0.423199 v 0.323636 0.272379 0.406602 v 0.429381 0.244458 0.204002 v 0.407084 0.332408 0.277313 v 0.410597 0.257869 0.266264 v -0.0012657 -0.456867 0.290093 v -0.00137093 -0.520579 0.266159 v 0.154137 -0.304206 0.500479 v 0.193482 -0.282873 0.473493 v 0.186367 -0.242201 0.509588 v 0.148993 -0.26399 0.525367 v 0.110332 -0.274916 0.545857 v 0.099347 -0.233134 0.560204 v 0.0558865 -0.227615 0.569605 v 0.0659185 -0.270006 0.563817 v 0.154687 -0.142577 0.51838 v 0.159498 -0.143009 0.513072 v 0.154646 -0.138239 0.502496 v 0.149045 -0.137596 0.50639 v 0.15958 -0.138174 0.517463 v 0.161574 -0.141559 0.511657 v 0.0940387 -0.129288 0.582226 v 0.109215 -0.12609 0.531844 v 0.0782715 -0.117578 0.557129 v 0.264817 0.0151299 0.501573 v 0.280122 0.127096 0.47057 v 0.262508 0.0886748 0.494464 v 0.187613 0.050926 0.529248 v 0.207829 0.0868157 0.523449 v 0.231821 -0.0170182 0.518246 v 0.304138 0.164985 0.443485 v 0.343004 0.132813 0.418235 v 0.313621 0.250742 0.418382 v 0.290815 0.22492 0.444303 v 0.355269 -0.194146 0.0276407 v 0.388534 -0.179618 0.0746089 v 0.336544 -0.25083 0.156379 v 0.29365 -0.279868 0.104617 v 0.389288 0.153006 0.345258 v 0.39155 0.205715 0.320166 v 0.127262 0.566927 -0.64996 v 0.000868155 0.562946 -0.661419 v 0.000850617 0.724441 -0.605705 v 0.118774 0.725955 -0.596105 v 0.21095 0.754513 0.387525 v 0.133734 -0.133188 0.514651 v 0.131302 -0.13393 0.53047 v 0.0671053 -0.326445 0.551902 v 0.0661056 -0.374553 0.504765 v 0.117289 -0.365439 0.489939 v 0.116552 -0.318792 0.528974 v 0.288249 -0.135286 0.424736 v 0.39393 0.0544045 0.33225 v 0.374655 0.0965379 0.38044 v 0.000792155 1 -0.0074948 v 0.0731795 0.993937 -0.182792 v 0.000868155 0.999152 -0.181886 v 0.179405 0.936399 -0.330549 v 0.0842755 0.953459 -0.338026 v 0.141767 0.271455 0.486238 v 0.139978 0.267433 0.490862 v 0.175908 0.259465 0.501362 v 0.175312 0.263359 0.495861 v 0.181597 0.230187 0.495539 v 0.140253 0.240576 0.495341 v 0.336982 0.587763 0.356927 v 0.312043 0.518258 0.416183 v 0.259971 0.350203 0.495411 v 0.250763 0.331028 0.496036 v 0.114179 0.255893 0.495902 v 0.111069 0.276518 0.499456 v 0.125433 0.293116 0.500415 v 0.124965 0.282353 0.489968 v 0.13906 0.254928 0.497457 v 0.17737 0.2462 0.50062 v 0.121796 0.272327 0.47658 v 0.149548 0.0847578 0.549377 v 0.142825 -0.226381 0.544992 v 0.106181 -0.197232 0.576871 v 0.258193 -0.146669 0.465227 v 0.2105 0.0188071 0.525711 v 0.181041 -0.0155508 0.531721 v 0.173453 -0.168949 0.5218 v 0.180322 -0.15877 0.514949 v 0.168554 -0.150118 0.516667 v 0.163082 -0.153579 0.523344 v 0.139124 -0.128733 0.545343 v 0.152348 -0.134468 0.527471 v 0.416192 -0.0714636 0.0335278 v 0.0220956 0.0520719 0.640232 v 0.0361615 0.0619695 0.628476 v -0.000283541 0.202056 0.62768 v 0.0869063 -0.0493125 -0.489641 v 0.192289 -0.0534399 -0.447186 v 0.192003 -0.134672 -0.429197 v 0.0851642 -0.130335 -0.46373 v 0.236434 0.310245 0.495686 v 0.237714 0.31211 0.497539 v 0.244636 0.32534 0.496212 v 0.121253 0.281932 0.477293 v 0.173149 -0.207241 0.528208 v -0.000242618 0.247989 0.603612 v -0.00037708 0.28838 0.571697 v 0.108496 -0.160507 0.588207 v 0.0613995 -0.166388 0.620127 v 0.0634222 -0.199565 0.59462 v 0.0893734 0.151176 0.600127 v 0.122124 0.0729427 0.596088 v 0.0993528 0.072475 0.584781 v 0.108315 0.0599584 0.583916 v 0.133524 0.0551528 0.575778 v 0.13315 0.107517 0.580426 v 0.274937 0.384257 0.485735 v 0.170606 -0.145383 0.517205 v 0.0464391 -0.130399 0.611931 v 0.0392892 -0.113439 0.575094 v -0.00161647 -0.112428 0.579865 v -0.00351648 -0.131685 0.617859 v 0.0194356 0.03489 0.601858 v -0.000564158 0.0478802 0.644208 v -2.04632e-05 0.0350303 0.598835 v 0.222163 0.246884 0.4972 v 0.217802 0.257547 0.498129 v 0.293159 0.278716 0.430419 v 0.302852 0.281932 0.427367 v 0.285209 0.277366 0.434932 v 0.289307 0.275834 0.436551 v 0.290061 0.280494 0.427963 v -0.000225079 -0.384287 0.444245 v 0.0651001 -0.383883 0.440585 v -0.000891543 -0.364076 0.502426 v 0.116576 -0.381784 0.436341 v 0.363734 0.712842 -0.467571 v 0.32166 0.832542 -0.392653 v 0.376508 0.821429 -0.265451 v 0.427095 0.698004 -0.319575 v 0.27178 0.90956 -0.29643 v 0.310423 0.901357 -0.210644 v 0.441869 0.677005 -0.175175 v 0.389019 0.807076 -0.128411 v 0.313311 0.894506 -0.0788532 v 0.12783 -0.376125 0.378248 v 0.0722266 -0.391483 0.37664 v 0.125579 0.302411 0.505741 v 0.101656 0.861358 -0.486525 v 0.214084 0.849981 -0.463327 v 0.2467 0.723207 -0.559263 v 0.104913 0.117397 -0.600268 v 0.221579 0.117865 -0.555159 v 0.200848 0.0268164 -0.488992 v 0.0944011 0.0271204 -0.539134 v 0.391141 0.144178 -0.303545 v 0.331241 0.130393 -0.444613 v 0.360829 0.250357 -0.491155 v 0.424003 0.258021 -0.333419 v 0.000868155 0.23912 -0.655479 v 0.00089154 0.393909 -0.675105 v 0.125626 0.397949 -0.664716 v 0.115418 0.240453 -0.645617 v 0.452175 0.547687 -0.348309 v 0.450217 0.395605 -0.350776 v 0.383015 0.40193 -0.511868 v 0.3854 0.562496 -0.506472 v 0.464078 0.52881 -0.195929 v 0.311698 0.866351 0.071908 v -9.64635e-05 -0.406882 0.376985 v 0.373883 -0.18312 -0.115123 v 0.389189 -0.0789467 -0.141776 v 0.247109 0.197607 0.47589 v 0.22891 0.231497 0.489717 v 0.121077 -0.116725 0.574393 v 0.125626 -0.0895459 0.583057 v 0.110548 -0.128452 0.555428 v 0.000710309 0.959638 0.167019 v 0.000710309 0.881206 0.320973 v 0.224163 0.124079 0.505215 v 0.255305 0.260798 0.480649 v 0.25188 0.263516 0.478322 v 0.214891 0.26119 0.49413 v 0.116476 0.273741 0.475423 v 0.290704 0.283902 0.433377 v 0.29641 0.299523 0.422813 v 0.29406 0.288222 0.418078 v 0.142655 0.263364 0.482467 v 0.121638 0.267831 0.470296 v 0.171711 0.256898 0.489693 v 0.246864 0.257401 0.473821 v 0.274311 0.271648 0.453301 v 0.274539 0.26862 0.446654 v 0.233686 0.331104 0.49074 v 0.187548 0.326632 0.49682 v 0.296971 0.273928 0.433476 v 0.134067 -0.0744861 0.577333 v 0.237434 0.052867 0.514604 v 0.0637905 0.27076 0.54346 v 0.375421 0.514218 0.287328 v 0.353808 -0.333437 -0.190615 v 0.349365 -0.276331 -0.333858 v 0.323337 -0.214946 -0.338453 v 0.356725 -0.247925 -0.205557 v -0.000330311 -0.581268 0.237302 v 0.092922 -0.548418 0.185458 v 0.394783 -0.0876049 -0.0664009 v 0.358315 -0.197624 -0.02995 v 0.292785 -0.321493 0.0377429 v 0.395175 -0.0904345 -0.0143524 v 0.243385 0.243183 -0.602957 v 0.000587539 -0.0451091 -0.498205 v 0.000751232 0.030862 -0.55154 v 0.000809694 0.11928 -0.61144 v 0.000850617 0.862837 -0.491295 v 0.000868155 0.958527 -0.339277 v 0.000423846 -0.128189 -0.469085 v 0.264186 0.56961 -0.608026 v 0.35127 -0.283317 -0.0863656 v 0.196201 -0.209591 -0.418785 v 0.0873097 -0.206341 -0.44839 v 0.000488154 -0.206259 -0.449945 v 0.263397 0.402579 -0.621226 v 0.456683 0.384813 -0.0591516 v 0.457776 0.372302 -0.191281 v 0.000850617 0.671351 0.512487 v 0.000809694 0.77919 0.437668 v 0.408656 0.116286 0.298547 v 0.295913 0.259781 0.439334 v 0.285355 0.265481 0.449775 v 0.278766 0.270035 0.454663 v 0.128946 -0.0227065 0.564741 v 0.16203 0.016989 0.534633 v 0.0985987 0.0583799 0.58087 v 0.0538462 0.323165 0.543729 v 0.0794758 0.301522 0.528465 v -0.00330601 -0.197759 0.600525 v -0.000511542 -0.225551 0.572931 v -0.00456879 -0.164231 0.628277 v -0.000336157 -0.26392 0.574381 v -0.000768774 -0.325515 0.55686 v 0.269921 0.242499 0.464742 v 0.260573 0.253022 0.476072 v 0.235066 0.15963 0.493271 v 0.411369 0.186119 0.273583 v 0.000178307 0.0131539 0.584682 v 0.153436 -0.0554568 0.55786 v 0.0264569 0.331747 0.554112 v -0.000342003 0.332998 0.557743 v 0.285589 0.277974 0.428156 v 0.184795 -0.499655 0.1217 v 0.332808 -0.386298 -0.0699261 v 0.20739 -0.274419 -0.415909 v 0.0927467 -0.274308 -0.43723 v 0.278029 -0.438791 0.0475586 v 0.000505693 -0.27722 -0.43768 v 0.438191 0.12488 -0.0367783 v 0.460214 0.163208 -0.055258 v 0.485388 0.177437 -0.0277343 v 0.472304 0.161641 -0.00367724 v 0.496244 0.232684 -0.0170708 v 0.477425 0.247036 0.00446648 v 0.517015 0.298681 -0.0523876 v 0.492233 0.31788 -0.0441737 v 0.53425 0.316407 -0.124009 v 0.511491 0.332595 -0.129276 v 0.535904 0.290111 -0.170685 v 0.511128 0.30365 -0.186838 v 0.538611 0.228878 -0.193017 v 0.511286 0.231199 -0.218992 v 0.520242 0.128838 -0.191421 v 0.490433 0.122168 -0.208603 v 0.487562 0.00951757 -0.0819458 v 0.472286 -0.00658864 -0.0930419 v 0.47079 0.0399937 -0.154257 v 0.496437 0.0472722 -0.136917 v 0.485142 -0.0247586 -0.0238758 v 0.46129 -0.0429694 -0.0334343 v 0.474888 0.238927 -0.0419989 v 0.495232 0.289088 -0.0628581 v 0.508398 0.299996 -0.11766 v 0.51311 0.283323 -0.158478 v 0.514642 0.235303 -0.176531 v 0.501751 0.136134 -0.181559 v 0.486025 0.0533522 -0.11859 v 0.486451 0.0268164 -0.067155 v 0.482529 0.0136625 -0.0120607 v 0.464265 0.0280383 0.0249515 v 0.457519 -0.0185791 0.0196256 v 0.442769 0.0582571 -0.0293244 v 0.45632 0.0847169 -0.0600578 v 0.442465 0.0842785 -0.0209644 v 0.459612 0.268106 0.0209995 v 0.458559 0.182857 0.0414318 v 0.463026 0.318488 -0.0446005 v 0.470222 0.311835 -0.142898 v 0.455063 0.232836 -0.195221 v 0.43839 0.13186 -0.191088 v 0.424564 0.0473131 -0.148417 v 0.423447 -0.00471202 -0.0897563 v 0.425377 -0.0292075 -0.0262143 v 0.430714 -0.0102191 0.0297161 v 0.446335 0.0345567 0.0460036 v 0.475607 0.129364 -0.0864649 v 0.482611 0.0600636 -0.0525396 v 0.481517 0.0827175 -0.101349 v 0.470503 0.0444835 -0.0133527 v 0.479278 0.0776957 0.00471786 v 0.504692 0.223938 -0.101723 v 0.50375 0.131866 -0.1473 v 0.45452 0.100016 0.0450097 v 0.403623 0.0251386 -0.16934 v 0.414719 0.138607 -0.218957 v 0.435461 0.249632 -0.229924 v -0.000201695 -0.407876 0.310666 v 0.000347846 -0.171521 0.505794 v 0.0884205 -0.186598 0.484028 v 0.141147 -0.173807 0.465513 v 0.159878 -0.142255 0.458644 v 0.152483 -0.116468 0.431278 v 0.0708352 0.0121893 0.376371 v 0.128069 -0.116368 0.360528 v 0.143994 -0.166791 0.41184 v 0.0748398 -0.218144 0.372349 v 0.280941 0.292858 0.454897 v 0.281356 0.319879 0.451494 v 0.127268 0.269088 0.455435 v 0.116921 0.284697 0.447653 v 0.119996 0.274998 0.469126 v 0.15699 0.254759 0.466326 v 0.265916 0.273601 0.421176 v 0.214885 0.253946 0.455259 v 0.141223 0.313133 0.482117 v 0.211436 0.255823 0.486852 v 0.277135 0.302686 0.410799 v 0.252505 0.333881 0.433599 v 0.202023 0.342182 0.464578 v 0.11989 0.295816 0.471196 v 0.146526 0.322539 0.455943 v 0.126292 0.301838 0.454973 v 0.119744 0.284878 0.469419 v 0.00103185 0.0191579 0.374711 v 0.000909079 -0.205715 0.379849 v 0.0536357 -0.100847 0.27211 v 0.00103185 -0.098929 0.27128 v 0.255463 -0.398733 -0.446098 v 0.412907 -0.372688 -0.332858 v 0.452596 -0.41557 -0.353559 v 0.293329 -0.465367 -0.476007 v 0.0815337 -0.637104 0.176286 v 0.0726358 -0.738524 0.179519 v 0.174763 -0.714911 0.155526 v 0.172032 -0.601823 0.129884 v 0.380782 -0.504069 -0.184377 v 0.357368 -0.419095 -0.180384 v 0.337538 -0.494803 -0.0548371 v 0.372989 -0.619402 -0.0373571 v 0.453578 -0.652661 -0.0939539 v 0.452351 -0.545892 -0.196981 v 0.173576 -0.814197 0.195654 v 0.0739044 -0.845866 0.20734 v 0.0964414 -0.904976 0.254455 v 0.197703 -0.864562 0.243353 v 0.519564 -0.487407 -0.384801 v 0.555004 -0.584226 -0.219366 v 0.451357 -0.731555 -0.0215899 v 0.382594 -0.74824 0.0443666 v 0.439805 -0.799196 0.0975376 v 0.519108 -0.768071 -0.00769357 v 0.274837 -0.806199 0.115503 v 0.320508 -0.838061 0.183769 v 0.354533 -0.544232 -0.525256 v 0.162503 -0.604343 -0.559076 v 0.131098 -0.496837 -0.498761 v 0.115161 -0.410103 -0.457756 v -0.00017831 -0.492774 -0.504192 v 2.046e-05 -0.40666 -0.465186 v -0.000482311 -0.600531 -0.555322 v 0.546217 -0.696736 -0.117257 v 0.22746 -0.332063 -0.424345 v 0.101627 -0.33885 -0.437002 v 0.280193 -0.554165 0.0658922 v 0.274843 -0.684891 0.0781517 v 0.000347846 -0.34199 -0.438165 v 0.000733693 -0.746364 0.176765 v 0.000312769 -0.874904 0.179121 v 0.378648 -0.322586 -0.326994 v -0.000114002 -0.940246 0.234262 v 0.000979233 -0.650317 0.207112 v -0.130513 -0.13217 0.498924 v -0.133687 -0.14723 0.488109 v -0.15222 -0.140519 0.477457 v -0.14666 -0.13514 0.489746 v -0.0697653 -0.0999404 0.550318 v -0.0736414 -0.0473131 0.499649 v -0.0305784 -0.0972511 0.55389 v -0.0396517 -0.109762 0.550014 v -0.0358517 -0.127727 0.53534 v -0.0742493 -0.135994 0.523315 v -0.0733373 -0.115561 0.537643 v -0.106766 -0.144336 0.504823 v -0.106281 -0.125786 0.515779 v -0.156505 -0.107798 0.467782 v -0.155611 -0.123682 0.486899 v -0.159311 -0.130796 0.484958 v -0.162872 -0.126996 0.470243 v -0.159919 -0.135625 0.47627 v -0.154055 -0.134696 0.486513 v -0.142597 -0.118993 0.499994 v -0.130051 -0.0726738 0.476189 v -0.10054 -0.105798 0.538111 v -0.125684 -0.115824 0.51596 v -0.274604 -0.301394 0.247527 v -0.220831 -0.335775 0.330215 v -0.250102 -0.275554 0.380393 v -0.3066 -0.239804 0.292309 v -0.284302 -0.0258401 0.479772 v -0.319479 0.00809111 0.449577 v -0.331873 -0.0412272 0.412243 v -0.293674 -0.0747667 0.452418 v -0.294668 -0.0547787 -0.357622 v -0.302063 -0.144319 -0.34334 v -0.356012 -0.159916 -0.223184 v -0.355474 -0.0633082 -0.24271 v -0.447241 0.22613 0.139332 v -0.437922 0.336149 0.131124 v -0.449486 0.331215 0.047962 v -0.454982 0.205353 0.0827818 v -0.103311 -0.419241 0.249936 v -0.203701 -0.353384 0.208147 v -0.196966 -0.411506 0.138841 v -0.101797 -0.475733 0.208638 v -0.196499 -0.327216 0.427455 v -0.176283 -0.362363 0.392138 v -0.150331 -0.372548 0.431378 v -0.155575 -0.349484 0.46435 v -0.0890109 -0.391945 0.303855 v -0.158306 -0.363848 0.305182 v -0.415613 0.611627 0.0817705 v -0.430808 0.648493 -0.0417066 v -0.45411 0.508986 -0.0641209 v -0.440308 0.483438 0.0478393 v -0.389808 0.40462 0.306977 v -0.375935 0.38348 0.354021 v -0.34643 0.433026 0.398499 v -0.354807 0.467378 0.356891 v -0.317409 0.30382 0.429121 v -0.30173 0.320499 0.456861 v -0.309295 0.339493 0.457756 v -0.328406 0.316144 0.429519 v -0.358297 0.360101 0.389344 v -0.335684 0.397733 0.427864 v -0.285156 0.29304 0.457387 v -0.294212 0.310695 0.451757 v -0.307675 0.294425 0.430781 v -0.29475 0.281949 0.435698 v -0.421091 0.455996 0.145494 v -0.395403 0.565208 0.19252 v -0.321999 0.364421 0.449238 v -0.345494 0.336792 0.417218 v -0.178165 0.560672 0.512335 v -0.249354 0.546354 0.466589 v -0.243286 0.479638 0.494943 v -0.170168 0.4781 0.536796 v -0.164123 0.410647 0.547114 v -0.236966 0.427297 0.516007 v -0.270669 0.634748 0.422187 v -0.195815 0.657882 0.47347 v -0.14597 0.313039 0.508126 v -0.18946 0.324971 0.513312 v -0.186823 0.312829 0.511757 v -0.144895 0.300213 0.501871 v -0.186911 0.310514 0.506612 v -0.143462 0.300341 0.494353 v -0.160048 0.365076 0.528073 v -0.219468 0.382854 0.516404 v -0.15782 0.334506 0.520076 v -0.205952 0.349935 0.517012 v -0.195236 0.332495 0.516264 v -0.151653 0.320785 0.513142 v -0.0805691 0.0827468 0.603261 v -0.0493739 0.08878 0.593591 v -0.0448723 0.0732117 0.617958 v -0.0594819 0.0761932 0.621314 v -0.422927 0.0771812 0.237185 v -0.432205 0.159355 0.215905 v -0.448112 0.130656 0.149516 v -0.4282 0.0348607 0.166897 v -0.311779 -0.172912 0.334378 v -0.324787 -0.103758 0.371735 v -0.364851 -0.052639 0.316097 v -0.367254 -0.126698 0.269146 v -0.183918 -0.149136 0.51793 v -0.182024 -0.137865 0.527822 v -0.205163 -0.131463 0.524127 v -0.205514 -0.152071 0.514943 v -0.39379 0.00614433 0.269368 v -0.400951 -0.0591282 0.208995 v -0.261011 -0.0993382 0.483865 v -0.25102 -0.0551177 0.50328 v -0.158849 -0.136444 0.499199 v -0.155155 -0.134784 0.503397 v -0.145304 -0.133848 0.514902 v -0.160802 -0.128394 0.536919 v -0.173424 -0.121349 0.541327 v -0.169156 -0.138478 0.524928 v -0.232096 -0.116964 0.50767 v -0.232727 -0.151188 0.49696 v -0.326085 0.202611 0.415651 v -0.34094 0.235683 0.392156 v -0.367727 0.221336 0.359031 v -0.358829 0.177595 0.3841 v -0.295603 0.0501836 0.478632 v -0.32232 0.0902006 0.449922 v -0.351843 0.04895 0.416686 v -0.367248 0.00336155 0.369624 v -0.156137 -0.154941 0.536878 v -0.165134 -0.177028 0.538193 v -0.144573 -0.187364 0.558725 v -0.140533 -0.155882 0.559046 v -0.17761 -0.0804258 0.547933 v -0.201667 -0.0484356 0.526945 v -0.22024 -0.0817529 0.517585 v -0.195826 -0.106131 0.536439 v -0.207794 -0.213087 0.493049 v -0.191711 -0.188305 0.515551 v -0.201111 -0.170071 0.510745 v -0.223385 -0.183243 0.490178 v -0.128595 -0.132761 0.551212 v -0.145777 -0.139513 0.530605 v -0.0971664 0.171538 0.569909 v -0.120048 0.150182 0.555387 v -0.13557 0.119437 0.545004 v -0.113103 0.137432 0.569453 v -0.0653573 0.232432 0.569575 v -0.08745 0.217992 0.556468 v -0.0739395 0.185388 0.584933 v -0.0855266 0.255554 0.53095 v -0.110583 0.228714 0.525501 v -0.115915 0.191404 0.5495 v -0.300099 0.0366964 -0.387999 v -0.364734 0.0377897 -0.269357 v -0.223181 -0.243207 0.45081 v -0.246139 -0.195666 0.45347 v -0.271201 -0.199869 0.399446 v -0.362846 -0.197443 0.213286 v -0.410176 -0.124757 0.140565 v -0.430404 -0.00290555 0.0907385 v -0.448779 0.11075 0.0889086 v -0.142135 0.869847 0.301633 v -0.132167 0.771303 0.419317 v -0.0633989 0.777407 0.43288 v -0.0675789 0.877324 0.315577 v -0.353469 0.660735 0.264732 v -0.2875 0.723792 0.335465 v -0.30353 0.809117 0.220313 v -0.37099 0.728422 0.148627 v -0.381016 0.776764 0.0117274 v -0.0996744 0.472587 0.557146 v -0.109525 0.565325 0.53475 v -0.100294 0.277787 0.511248 v -0.108689 0.248457 0.503268 v -0.0528874 0.193947 0.604898 v -0.0453926 0.241125 0.586705 v -0.12255 0.668732 0.500514 v -0.0511336 0.564922 0.542589 v -0.0582191 0.671655 0.50974 v -0.0440363 0.465776 0.561151 v -0.0361966 0.388923 0.562367 v -0.301894 0.466338 0.448542 v -0.295831 0.424807 0.472166 v -0.140867 0.22264 0.499754 v -0.185742 0.209381 0.492394 v -0.186338 0.179495 0.502724 v -0.145859 0.19535 0.519018 v -0.0600022 0.0437294 0.578309 v -0.113337 0.0407946 0.564875 v -0.114196 0.0121659 0.564255 v -0.0686019 -0.00676987 0.598064 v -0.143661 0.0637116 0.537807 v -0.147607 0.0440217 0.535469 v -0.0907706 -0.0459919 0.600525 v -0.0300113 -0.0346152 0.623594 v -0.028047 -0.0138554 0.603173 v -0.148028 0.131527 0.5437 v -0.148519 0.164868 0.537322 v -0.183164 0.146873 0.520193 v -0.176978 0.112363 0.532908 v -0.147823 0.0979234 0.535574 v -0.165064 0.0766492 0.532955 v -0.120107 0.268649 0.480825 v -0.118558 0.262394 0.493353 v -0.115979 0.27287 0.494434 v -0.116476 0.272952 0.483859 v -0.229115 0.916634 0.120496 v -0.223379 0.848952 0.271461 v -0.145146 0.945128 0.150709 v -0.145409 0.980883 -0.0176788 v -0.154278 0.976311 -0.1834 v -0.240088 0.945514 -0.185786 v -0.230512 0.948548 -0.0401515 v -0.0669533 0.995411 -0.00979819 v -0.0669124 0.955581 0.163097 v -0.0891746 0.383199 0.554861 v -0.112226 0.336757 0.527307 v -0.123381 0.311174 0.513382 v -0.149484 -0.111966 0.558549 v -0.160264 -0.0991219 0.559216 v -0.0695139 0.122828 0.646821 v -0.103574 0.1197 0.616608 v -0.0967747 0.0873945 0.617683 v -0.0583127 0.0845006 0.640951 v -0.0810075 0.0824603 0.567973 v -0.0347818 0.058339 0.594989 v -0.031812 -0.0520134 0.636181 v -0.0876079 -0.0656701 0.61341 v -0.0905251 -0.101683 0.607529 v -0.0378686 -0.0937434 0.629054 v -0.0836617 -0.122507 0.579642 v -0.0385351 -0.11728 0.594673 v -0.0223295 0.0177081 0.586652 v -0.0307538 0.0864766 0.665646 v -0.0369098 0.125196 0.667078 v -0.0659946 0.154643 0.629212 v -0.0379446 0.159028 0.648136 v -0.0287544 0.19984 0.620642 v -0.0228205 0.245931 0.598298 v -0.0444456 0.281523 0.558544 v -0.0233467 0.287164 0.569581 v -0.348774 0.267521 0.384632 v -0.352083 0.30296 0.39367 v -0.371253 0.315308 0.363077 v -0.374871 0.266369 0.352501 v -0.422202 0.335746 0.207253 v -0.401928 0.429197 0.234116 v -0.395345 0.264083 0.313998 v -0.391071 0.32586 0.325679 v -0.312703 0.275793 0.421661 v -0.320315 0.291642 0.417107 v -0.332077 0.295173 0.409057 v -0.327599 0.271742 0.406824 v -0.429802 0.244434 0.203979 v -0.409282 0.332454 0.277442 v -0.411848 0.257886 0.266369 v -0.187414 -0.242265 0.510307 v -0.193763 -0.283183 0.474066 v -0.155254 -0.304954 0.501777 v -0.149998 -0.264183 0.526518 v -0.0567108 -0.227311 0.569523 v -0.101124 -0.233508 0.561461 v -0.11039 -0.27508 0.546021 v -0.066205 -0.270351 0.564711 v -0.154225 -0.138052 0.502391 v -0.159867 -0.142787 0.513271 v -0.15533 -0.142366 0.518626 v -0.148566 -0.137426 0.506285 v -0.160416 -0.138344 0.518258 v -0.161965 -0.141513 0.511996 v -0.110811 -0.126394 0.533276 v -0.10089 -0.129879 0.583501 v -0.0809374 -0.117865 0.558397 v -0.263876 0.014785 0.500935 v -0.26083 0.088932 0.49537 v -0.279702 0.127055 0.470506 v -0.207764 0.0867397 0.523776 v -0.187729 0.0509786 0.529558 v -0.232096 -0.0167025 0.518065 v -0.344056 0.133304 0.417078 v -0.302046 0.166376 0.445239 v -0.292551 0.225429 0.44414 v -0.316041 0.250468 0.418475 v -0.335386 -0.250836 0.156385 v -0.387207 -0.179618 0.074568 v -0.353755 -0.194151 0.0276524 v -0.292388 -0.279891 0.104617 v -0.392211 0.205733 0.320201 v -0.386651 0.150025 0.344942 v -0.126064 0.567371 -0.651942 v -0.117096 0.725914 -0.596082 v -0.209068 0.754227 0.387245 v -0.134091 -0.133281 0.515294 v -0.132384 -0.133778 0.530774 v -0.118289 -0.366228 0.490722 v -0.0673742 -0.375085 0.505343 v -0.0685259 -0.327012 0.553422 v -0.117722 -0.319453 0.530388 v -0.287793 -0.13528 0.424643 v -0.375234 0.0965671 0.380457 v -0.394351 0.054463 0.33218 v -0.0714373 0.993797 -0.182751 v -0.0825568 0.953558 -0.338084 v -0.177458 0.935674 -0.330221 v -0.176961 0.259482 0.501637 v -0.139651 0.267463 0.490903 v -0.141176 0.271537 0.486156 v -0.175792 0.263446 0.495797 v -0.139621 0.240295 0.49489 v -0.181918 0.230053 0.49499 v -0.335299 0.587722 0.356851 v -0.311189 0.51838 0.416464 v -0.263028 0.350391 0.495528 v -0.252435 0.331198 0.496568 v -0.111168 0.276448 0.500608 v -0.113553 0.255671 0.49582 v -0.124754 0.293525 0.500263 v -0.124275 0.282616 0.489933 v -0.138587 0.254671 0.496603 v -0.17851 0.246346 0.500783 v -0.120744 0.272286 0.476557 v -0.150635 0.0843194 0.549231 v -0.110981 -0.197039 0.578654 v -0.145877 -0.226522 0.547184 v -0.257825 -0.146365 0.464946 v -0.181813 -0.015013 0.533586 v -0.21057 0.0188715 0.525811 v -0.169226 -0.14996 0.516989 v -0.181743 -0.1588 0.515902 v -0.175376 -0.168545 0.522911 v -0.163813 -0.153415 0.52335 v -0.140253 -0.128364 0.545887 v -0.153091 -0.134363 0.527834 v -0.414608 -0.0714286 0.0335337 v -0.0376523 0.063203 0.628721 v -0.0232707 0.0530365 0.640016 v -0.190483 -0.134521 -0.42891 v -0.190425 -0.0530365 -0.446291 v -0.0856669 -0.0492716 -0.489617 v -0.0841703 -0.13027 -0.463549 v -0.238743 0.312729 0.498784 v -0.236568 0.310718 0.495914 v -0.245034 0.325784 0.495083 v -0.120311 0.281967 0.47734 v -0.176107 -0.207054 0.530523 v -0.114635 -0.15994 0.588938 v -0.0702155 -0.19877 0.595006 v -0.0735478 -0.165324 0.619338 v -0.0899814 0.151661 0.600396 v -0.111016 0.0572925 0.58557 v -0.101867 0.0715163 0.586237 v -0.127064 0.0733753 0.597824 v -0.136833 0.0543987 0.574241 v -0.135833 0.107312 0.581379 v -0.278287 0.38386 0.485911 v -0.171226 -0.145371 0.517737 v -0.0426215 -0.114106 0.575498 v -0.0575293 -0.131258 0.610721 v -0.0203535 0.0339429 0.602828 v -0.224215 0.246978 0.496697 v -0.219644 0.257664 0.498129 v -0.308126 0.284604 0.426215 v -0.296275 0.279026 0.430641 v -0.291721 0.275554 0.437358 v -0.286612 0.276705 0.435172 v -0.291949 0.280143 0.428238 v -0.065825 -0.384532 0.440825 v -0.11702 -0.382428 0.436651 v -0.374667 0.821265 -0.265393 v -0.3198 0.831958 -0.392208 v -0.362179 0.712818 -0.467507 v -0.425879 0.698185 -0.319692 v -0.269938 0.909215 -0.296313 v -0.308015 0.900609 -0.210562 v -0.440407 0.677046 -0.175192 v -0.387417 0.807117 -0.128411 v -0.312037 0.894728 -0.0788123 v -0.0720161 -0.391612 0.376675 v -0.127765 -0.376523 0.378341 v -0.124801 0.303066 0.504835 v -0.0997913 0.860855 -0.486022 v -0.212687 0.850449 -0.463771 v -0.245244 0.723306 -0.559461 v -0.199083 0.0271847 -0.488407 v -0.21986 0.118005 -0.554936 v -0.10327 0.117479 -0.600127 v -0.0928636 0.0273016 -0.53883 v -0.389259 0.144254 -0.303446 v -0.329178 0.130557 -0.444432 v -0.359227 0.250316 -0.491237 v -0.422325 0.258021 -0.333419 v -0.123907 0.397932 -0.664658 v -0.113699 0.240517 -0.645459 v -0.381641 0.401913 -0.512072 v -0.448592 0.395605 -0.3508 v -0.450574 0.547705 -0.348333 v -0.384366 0.562601 -0.506817 v -0.462722 0.528827 -0.195952 v -0.310604 0.866976 0.0721301 v -0.372013 -0.183143 -0.115123 v -0.387686 -0.0789994 -0.141781 v -0.2476 0.197566 0.475487 v -0.230342 0.231532 0.488372 v -0.129238 -0.0890256 0.584927 v -0.123544 -0.115971 0.574872 v -0.114588 -0.128867 0.557082 v -0.221702 0.122764 0.506442 v -0.216107 0.26119 0.49413 v -0.253242 0.263207 0.478422 v -0.256568 0.260547 0.479737 v -0.115342 0.273619 0.475323 v -0.298743 0.299903 0.422953 v -0.291698 0.283732 0.432722 v -0.295854 0.288181 0.418253 v -0.142059 0.263388 0.482491 v -0.120428 0.267802 0.470325 v -0.172108 0.256934 0.489641 v -0.275083 0.271584 0.453242 v -0.248582 0.25684 0.473757 v -0.275001 0.268573 0.446274 v -0.234253 0.331396 0.490634 v -0.187624 0.326819 0.49717 v -0.300292 0.274694 0.432944 v -0.135658 -0.0739483 0.577444 v -0.237428 0.052791 0.514919 v -0.0645564 0.270789 0.544612 v -0.373819 0.514195 0.287264 v -0.321852 -0.214718 -0.338184 v -0.348166 -0.27584 -0.333396 v -0.352171 -0.333378 -0.190533 v -0.354936 -0.247872 -0.205511 v -0.0936937 -0.549137 0.186785 v -0.35669 -0.197653 -0.0299733 v -0.393228 -0.0876225 -0.0664009 v -0.29161 -0.321499 0.0380294 v -0.393638 -0.0904403 -0.014329 v -0.241608 0.243201 -0.602916 v -0.263209 0.569914 -0.609242 v -0.349441 -0.283282 -0.0863831 v -0.194821 -0.209504 -0.418674 v -0.0862925 -0.206323 -0.448413 v -0.261795 0.402579 -0.621448 v -0.456233 0.372302 -0.191263 v -0.455245 0.384813 -0.0591282 v -0.408072 0.116608 0.297155 v -0.298661 0.260278 0.439147 v -0.287606 0.265861 0.450068 v -0.279696 0.270216 0.454289 v -0.162731 0.0172638 0.536515 v -0.13087 -0.0222973 0.565699 v -0.101475 0.0572691 0.580946 v -0.0809198 0.301049 0.528407 v -0.0556351 0.322972 0.54498 v -0.272306 0.242932 0.464508 v -0.262964 0.253017 0.476001 v -0.233067 0.158607 0.487893 v -0.412053 0.186142 0.273695 v -0.154815 -0.0532762 0.55793 v -0.0277489 0.331782 0.556427 v -0.286179 0.277611 0.427928 v -0.183941 -0.499632 0.122144 v -0.331493 -0.386257 -0.0698735 v -0.206238 -0.274279 -0.416026 v -0.0915482 -0.274332 -0.437317 v -0.277193 -0.438779 0.0481257 v -0.484037 0.177414 -0.0276816 v -0.458618 0.163319 -0.0553633 v -0.437233 0.124752 -0.0367315 v -0.471526 0.1616 -0.00366555 v -0.476232 0.247018 0.00445479 v -0.494987 0.232631 -0.0169773 v -0.491035 0.317921 -0.0441971 v -0.515688 0.298728 -0.0523583 v -0.510175 0.332513 -0.1293 v -0.532917 0.316524 -0.12405 v -0.50993 0.303592 -0.186815 v -0.534671 0.290233 -0.170849 v -0.510152 0.231181 -0.21891 v -0.537459 0.228895 -0.193058 v -0.48934 0.122068 -0.20872 v -0.519208 0.128879 -0.191363 v -0.469632 0.0399528 -0.15424 v -0.470766 -0.00661202 -0.0930419 v -0.486142 0.00947665 -0.0819458 v -0.495221 0.0472722 -0.1369 v -0.459705 -0.0431682 -0.033446 v -0.483546 -0.0248521 -0.0238816 v -0.494011 0.289082 -0.0628932 v -0.473502 0.238904 -0.0420457 v -0.507246 0.300137 -0.117724 v -0.512134 0.2833 -0.158502 v -0.513712 0.235303 -0.176549 v -0.50102 0.136093 -0.181582 v -0.485095 0.0532704 -0.118549 v -0.485253 0.0267755 -0.0671726 v -0.481172 0.0136801 -0.012201 v -0.456127 -0.0187428 0.0196958 v -0.462909 0.027933 0.024969 v -0.454923 0.0845591 -0.060163 v -0.441284 0.0577602 -0.0294063 v -0.440921 0.0840388 -0.0210813 v -0.457712 0.18288 0.0414318 v -0.458378 0.268123 0.0210228 v -0.461588 0.318505 -0.044618 v -0.468843 0.311858 -0.142898 v -0.453707 0.232836 -0.195204 v -0.436969 0.13182 -0.191047 v -0.423167 0.0473306 -0.148288 v -0.421945 -0.00467109 -0.089692 v -0.423991 -0.0291198 -0.0260915 v -0.429434 -0.0102776 0.0297746 v -0.445242 0.0345158 0.0460211 v -0.481617 0.0602039 -0.0524227 v -0.474104 0.129276 -0.0866754 v -0.480325 0.0824545 -0.101285 v -0.469474 0.0446648 -0.013376 v -0.478167 0.0776431 0.00467109 v -0.503592 0.223961 -0.101887 v -0.502575 0.131983 -0.147242 v -0.453707 0.0999988 0.0450097 v -0.413357 0.138549 -0.218945 v -0.402232 0.0251035 -0.169299 v -0.434023 0.249632 -0.229901 v -0.0871226 -0.186639 0.484069 v -0.139686 -0.173807 0.465537 v -0.158481 -0.142278 0.458685 v -0.0688299 0.0121893 0.376371 v -0.150805 -0.116468 0.431278 v -0.126228 -0.116368 0.360528 v -0.142316 -0.166791 0.41184 v -0.0730392 -0.218144 0.372349 v -0.282087 0.293548 0.454716 v -0.283513 0.320341 0.45129 v -0.124398 0.285323 0.452968 v -0.126795 0.269175 0.455978 v -0.119353 0.275057 0.469524 v -0.156265 0.2548 0.466332 v -0.265074 0.27356 0.421036 v -0.214762 0.253899 0.455218 v -0.141855 0.312577 0.484315 v -0.212745 0.255776 0.486875 v -0.277117 0.302621 0.410811 v -0.252014 0.333887 0.433371 v -0.20141 0.342405 0.464461 v -0.120767 0.295565 0.473184 v -0.145333 0.322832 0.456154 v -0.126041 0.301873 0.455785 v -0.119879 0.284837 0.470541 v -0.0516539 -0.100847 0.27211 v -0.454245 -0.41571 -0.353027 v -0.413392 -0.372097 -0.332203 v -0.255785 -0.398019 -0.4467 v -0.294685 -0.464338 -0.476902 v -0.174388 -0.714777 0.156607 v -0.0715543 -0.738454 0.180284 v -0.0798266 -0.636725 0.177765 v -0.171536 -0.601788 0.131147 v -0.337345 -0.494639 -0.0546091 v -0.355094 -0.419334 -0.180442 v -0.379665 -0.504905 -0.184915 v -0.373053 -0.619338 -0.0373044 v -0.45328 -0.545816 -0.197379 v -0.454128 -0.653065 -0.0942754 v -0.0965876 -0.904778 0.254759 v -0.0736004 -0.845567 0.20775 v -0.172974 -0.81408 0.195975 v -0.1973 -0.864375 0.243622 v -0.520961 -0.488138 -0.3841 v -0.556272 -0.584635 -0.21946 v -0.439238 -0.799155 0.0975785 v -0.381694 -0.748264 0.0442672 v -0.45103 -0.731883 -0.0219173 v -0.519067 -0.768135 -0.0077988 v -0.273785 -0.806328 0.115322 v -0.319391 -0.83802 0.183769 v -0.163088 -0.604103 -0.559421 v -0.356672 -0.543712 -0.525361 v -0.131226 -0.496761 -0.498854 v -0.114629 -0.410074 -0.45775 v -0.546533 -0.697291 -0.117619 v -0.100633 -0.33885 -0.437013 v -0.22677 -0.331835 -0.424707 v -0.274931 -0.684651 0.0790578 v -0.28021 -0.553908 0.0669913 v -0.378028 -0.321668 -0.326088 v 0.172833 0.300014 0.41564 v -0.171097 0.299996 0.415616 # 1258 vertices vt 0.532 0.923 0.000 vt 0.535 0.917 0.000 vt 0.542 0.923 0.000 vt 0.541 0.929 0.000 vt 0.521 0.984 0.000 vt 0.521 0.996 0.000 vt 0.505 0.998 0.000 vt 0.500 0.985 0.000 vt 0.504 0.917 0.000 vt 0.507 0.910 0.000 vt 0.516 0.910 0.000 vt 0.515 0.918 0.000 vt 0.523 0.921 0.000 vt 0.525 0.913 0.000 vt 0.549 0.958 0.000 vt 0.538 0.954 0.000 vt 0.544 0.942 0.000 vt 0.550 0.946 0.000 vt 0.545 0.935 0.000 vt 0.550 0.932 0.000 vt 0.547 0.974 0.000 vt 0.533 0.967 0.000 vt 0.500 0.917 0.000 vt 0.500 0.910 0.000 vt 0.542 0.987 0.000 vt 0.533 0.994 0.000 vt 0.616 0.254 0.000 vt 0.653 0.261 0.000 vt 0.658 0.307 0.000 vt 0.619 0.292 0.000 vt 0.636 0.438 0.000 vt 0.620 0.419 0.000 vt 0.627 0.396 0.000 vt 0.647 0.414 0.000 vt 0.886 0.312 0.000 vt 0.897 0.370 0.000 vt 0.860 0.369 0.000 vt 0.844 0.308 0.000 vt 0.740 0.593 0.000 vt 0.741 0.542 0.000 vt 0.759 0.541 0.000 vt 0.768 0.598 0.000 vt 0.644 0.213 0.000 vt 0.561 0.175 0.000 vt 0.566 0.146 0.000 vt 0.644 0.174 0.000 vt 0.580 0.254 0.000 vt 0.585 0.277 0.000 vt 0.565 0.268 0.000 vt 0.565 0.256 0.000 vt 0.590 0.217 0.000 vt 0.544 0.195 0.000 vt 0.771 0.721 0.000 vt 0.736 0.712 0.000 vt 0.758 0.653 0.000 vt 0.794 0.663 0.000 vt 0.669 0.622 0.000 vt 0.685 0.632 0.000 vt 0.665 0.669 0.000 vt 0.652 0.651 0.000 vt 0.623 0.588 0.000 vt 0.632 0.582 0.000 vt 0.639 0.590 0.000 vt 0.627 0.599 0.000 vt 0.641 0.632 0.000 vt 0.657 0.612 0.000 vt 0.619 0.580 0.000 vt 0.617 0.575 0.000 vt 0.623 0.573 0.000 vt 0.627 0.576 0.000 vt 0.708 0.702 0.000 vt 0.729 0.646 0.000 vt 0.633 0.614 0.000 vt 0.647 0.601 0.000 vt 0.604 0.718 0.000 vt 0.574 0.725 0.000 vt 0.567 0.686 0.000 vt 0.596 0.682 0.000 vt 0.562 0.648 0.000 vt 0.590 0.649 0.000 vt 0.618 0.756 0.000 vt 0.584 0.769 0.000 vt 0.586 0.587 0.000 vt 0.566 0.586 0.000 vt 0.568 0.579 0.000 vt 0.586 0.580 0.000 vt 0.569 0.574 0.000 vt 0.586 0.573 0.000 vt 0.562 0.627 0.000 vt 0.587 0.627 0.000 vt 0.587 0.610 0.000 vt 0.563 0.608 0.000 vt 0.565 0.595 0.000 vt 0.587 0.596 0.000 vt 0.521 0.441 0.000 vt 0.526 0.450 0.000 vt 0.520 0.450 0.000 vt 0.517 0.445 0.000 vt 0.720 0.504 0.000 vt 0.709 0.467 0.000 vt 0.727 0.446 0.000 vt 0.738 0.494 0.000 vt 0.656 0.383 0.000 vt 0.660 0.348 0.000 vt 0.684 0.368 0.000 vt 0.673 0.403 0.000 vt 0.572 0.371 0.000 vt 0.573 0.365 0.000 vt 0.581 0.364 0.000 vt 0.581 0.374 0.000 vt 0.708 0.400 0.000 vt 0.693 0.431 0.000 vt 0.604 0.401 0.000 vt 0.609 0.383 0.000 vt 0.557 0.364 0.000 vt 0.559 0.365 0.000 vt 0.557 0.366 0.000 vt 0.556 0.364 0.000 vt 0.552 0.367 0.000 vt 0.552 0.364 0.000 vt 0.568 0.377 0.000 vt 0.561 0.374 0.000 vt 0.566 0.370 0.000 vt 0.594 0.377 0.000 vt 0.594 0.363 0.000 vt 0.653 0.551 0.000 vt 0.644 0.534 0.000 vt 0.658 0.523 0.000 vt 0.666 0.545 0.000 vt 0.637 0.480 0.000 vt 0.625 0.458 0.000 vt 0.649 0.459 0.000 vt 0.662 0.434 0.000 vt 0.557 0.345 0.000 vt 0.553 0.353 0.000 vt 0.543 0.349 0.000 vt 0.546 0.337 0.000 vt 0.586 0.403 0.000 vt 0.573 0.392 0.000 vt 0.579 0.382 0.000 vt 0.591 0.389 0.000 vt 0.572 0.343 0.000 vt 0.584 0.331 0.000 vt 0.590 0.347 0.000 vt 0.578 0.353 0.000 vt 0.553 0.358 0.000 vt 0.543 0.355 0.000 vt 0.553 0.499 0.000 vt 0.541 0.507 0.000 vt 0.542 0.484 0.000 vt 0.553 0.477 0.000 vt 0.539 0.532 0.000 vt 0.529 0.541 0.000 vt 0.531 0.513 0.000 vt 0.551 0.538 0.000 vt 0.538 0.552 0.000 vt 0.552 0.521 0.000 vt 0.908 0.437 0.000 vt 0.876 0.429 0.000 vt 0.608 0.340 0.000 vt 0.599 0.314 0.000 vt 0.629 0.336 0.000 vt 0.691 0.326 0.000 vt 0.723 0.365 0.000 vt 0.748 0.426 0.000 vt 0.755 0.489 0.000 vt 0.564 0.825 0.000 vt 0.590 0.868 0.000 vt 0.558 0.886 0.000 vt 0.533 0.834 0.000 vt 0.637 0.789 0.000 vt 0.673 0.755 0.000 vt 0.702 0.774 0.000 vt 0.665 0.817 0.000 vt 0.740 0.787 0.000 vt 0.545 0.727 0.000 vt 0.540 0.686 0.000 vt 0.551 0.550 0.000 vt 0.538 0.572 0.000 vt 0.520 0.546 0.000 vt 0.522 0.517 0.000 vt 0.552 0.775 0.000 vt 0.524 0.777 0.000 vt 0.521 0.728 0.000 vt 0.500 0.687 0.000 vt 0.500 0.651 0.000 vt 0.515 0.650 0.000 vt 0.518 0.687 0.000 vt 0.500 0.727 0.000 vt 0.625 0.671 0.000 vt 0.618 0.644 0.000 vt 0.591 0.533 0.000 vt 0.571 0.539 0.000 vt 0.569 0.527 0.000 vt 0.589 0.518 0.000 vt 0.545 0.436 0.000 vt 0.525 0.427 0.000 vt 0.528 0.413 0.000 vt 0.549 0.425 0.000 vt 0.556 0.449 0.000 vt 0.563 0.439 0.000 vt 0.514 0.395 0.000 vt 0.532 0.396 0.000 vt 0.513 0.409 0.000 vt 0.566 0.511 0.000 vt 0.564 0.490 0.000 vt 0.577 0.478 0.000 vt 0.584 0.500 0.000 vt 0.500 0.408 0.000 vt 0.500 0.394 0.000 vt 0.571 0.457 0.000 vt 0.561 0.468 0.000 vt 0.554 0.561 0.000 vt 0.557 0.563 0.000 vt 0.552 0.569 0.000 vt 0.548 0.569 0.000 vt 0.627 0.847 0.000 vt 0.674 0.871 0.000 vt 0.645 0.898 0.000 vt 0.776 0.920 0.000 vt 0.709 0.921 0.000 vt 0.729 0.888 0.000 vt 0.783 0.887 0.000 vt 0.693 0.947 0.000 vt 0.621 0.920 0.000 vt 0.535 0.642 0.000 vt 0.542 0.618 0.000 vt 0.545 0.599 0.000 vt 0.559 0.383 0.000 vt 0.552 0.377 0.000 vt 0.531 0.470 0.000 vt 0.520 0.472 0.000 vt 0.517 0.456 0.000 vt 0.528 0.457 0.000 vt 0.530 0.438 0.000 vt 0.517 0.436 0.000 vt 0.528 0.383 0.000 vt 0.513 0.384 0.000 vt 0.512 0.374 0.000 vt 0.526 0.374 0.000 vt 0.512 0.367 0.000 vt 0.526 0.366 0.000 vt 0.512 0.362 0.000 vt 0.526 0.362 0.000 vt 0.511 0.422 0.000 vt 0.500 0.384 0.000 vt 0.500 0.375 0.000 vt 0.500 0.362 0.000 vt 0.500 0.367 0.000 vt 0.511 0.472 0.000 vt 0.508 0.457 0.000 vt 0.521 0.491 0.000 vt 0.512 0.519 0.000 vt 0.512 0.491 0.000 vt 0.511 0.550 0.000 vt 0.520 0.576 0.000 vt 0.510 0.583 0.000 vt 0.500 0.457 0.000 vt 0.500 0.472 0.000 vt 0.500 0.491 0.000 vt 0.654 0.584 0.000 vt 0.656 0.568 0.000 vt 0.669 0.567 0.000 vt 0.666 0.589 0.000 vt 0.705 0.639 0.000 vt 0.718 0.591 0.000 vt 0.684 0.563 0.000 vt 0.680 0.592 0.000 vt 0.637 0.575 0.000 vt 0.636 0.566 0.000 vt 0.645 0.567 0.000 vt 0.645 0.579 0.000 vt 0.723 0.546 0.000 vt 0.697 0.592 0.000 vt 0.702 0.554 0.000 vt 0.500 0.163 0.000 vt 0.500 0.137 0.000 vt 0.579 0.298 0.000 vt 0.570 0.317 0.000 vt 0.554 0.307 0.000 vt 0.560 0.287 0.000 vt 0.534 0.318 0.000 vt 0.517 0.314 0.000 vt 0.519 0.296 0.000 vt 0.538 0.300 0.000 vt 0.562 0.362 0.000 vt 0.559 0.363 0.000 vt 0.557 0.362 0.000 vt 0.559 0.360 0.000 vt 0.563 0.365 0.000 vt 0.561 0.368 0.000 vt 0.543 0.360 0.000 vt 0.531 0.358 0.000 vt 0.531 0.351 0.000 vt 0.611 0.437 0.000 vt 0.613 0.475 0.000 vt 0.624 0.497 0.000 vt 0.580 0.445 0.000 vt 0.590 0.466 0.000 vt 0.598 0.418 0.000 vt 0.648 0.501 0.000 vt 0.633 0.516 0.000 vt 0.641 0.554 0.000 vt 0.630 0.541 0.000 vt 0.733 0.331 0.000 vt 0.696 0.288 0.000 vt 0.706 0.252 0.000 vt 0.751 0.313 0.000 vt 0.683 0.535 0.000 vt 0.674 0.508 0.000 vt 0.999 0.696 0.000 vt 0.986 0.778 0.000 vt 0.950 0.772 0.000 vt 0.967 0.695 0.000 vt 0.600 0.811 0.000 vt 0.552 0.361 0.000 vt 0.547 0.367 0.000 vt 0.546 0.364 0.000 vt 0.525 0.254 0.000 vt 0.546 0.261 0.000 vt 0.542 0.280 0.000 vt 0.522 0.274 0.000 vt 0.631 0.369 0.000 vt 0.678 0.460 0.000 vt 0.662 0.482 0.000 vt 0.770 0.948 0.000 vt 0.762 0.981 0.000 vt 0.676 0.977 0.000 vt 0.845 0.915 0.000 vt 0.835 0.891 0.000 vt 0.569 0.560 0.000 vt 0.582 0.558 0.000 vt 0.580 0.563 0.000 vt 0.569 0.564 0.000 vt 0.590 0.544 0.000 vt 0.571 0.548 0.000 vt 0.635 0.701 0.000 vt 0.651 0.731 0.000 vt 0.607 0.593 0.000 vt 0.609 0.606 0.000 vt 0.543 0.570 0.000 vt 0.553 0.556 0.000 vt 0.552 0.580 0.000 vt 0.556 0.574 0.000 vt 0.569 0.554 0.000 vt 0.585 0.551 0.000 vt 0.559 0.566 0.000 vt 0.550 0.458 0.000 vt 0.532 0.330 0.000 vt 0.549 0.325 0.000 vt 0.610 0.364 0.000 vt 0.589 0.432 0.000 vt 0.578 0.417 0.000 vt 0.570 0.357 0.000 vt 0.565 0.360 0.000 vt 0.562 0.356 0.000 vt 0.565 0.351 0.000 vt 0.557 0.364 0.000 vt 0.556 0.364 0.000 vt 0.548 0.371 0.000 vt 0.557 0.371 0.000 vt 0.762 0.385 0.000 vt 0.513 0.445 0.000 vt 0.508 0.444 0.000 vt 0.500 0.520 0.000 vt 0.939 0.378 0.000 vt 0.932 0.316 0.000 vt 0.972 0.321 0.000 vt 0.974 0.384 0.000 vt 0.605 0.572 0.000 vt 0.605 0.578 0.000 vt 0.605 0.584 0.000 vt 0.559 0.571 0.000 vt 0.562 0.333 0.000 vt 0.500 0.552 0.000 vt 0.500 0.585 0.000 vt 0.531 0.343 0.000 vt 0.514 0.338 0.000 vt 0.516 0.324 0.000 vt 0.532 0.488 0.000 vt 0.534 0.448 0.000 vt 0.540 0.446 0.000 vt 0.545 0.448 0.000 vt 0.538 0.455 0.000 vt 0.541 0.466 0.000 vt 0.612 0.623 0.000 vt 0.567 0.366 0.000 vt 0.513 0.356 0.000 vt 0.500 0.355 0.000 vt 0.500 0.346 0.000 vt 0.514 0.348 0.000 vt 0.543 0.363 0.000 vt 0.552 0.364 0.000 vt 0.531 0.362 0.000 vt 0.512 0.361 0.000 vt 0.509 0.433 0.000 vt 0.500 0.444 0.000 vt 0.500 0.432 0.000 vt 0.603 0.551 0.000 vt 0.599 0.557 0.000 vt 0.627 0.570 0.000 vt 0.631 0.571 0.000 vt 0.625 0.566 0.000 vt 0.622 0.569 0.000 vt 0.621 0.567 0.000 vt 0.529 0.234 0.000 vt 0.500 0.249 0.000 vt 0.500 0.227 0.000 vt 0.550 0.245 0.000 vt 0.857 0.816 0.000 vt 0.825 0.804 0.000 vt 0.851 0.737 0.000 vt 0.886 0.748 0.000 vt 0.821 0.866 0.000 vt 0.798 0.856 0.000 vt 0.783 0.797 0.000 vt 0.810 0.729 0.000 vt 0.755 0.848 0.000 vt 0.534 0.215 0.000 vt 0.563 0.233 0.000 vt 0.548 0.588 0.000 vt 0.884 0.835 0.000 vt 0.908 0.854 0.000 vt 0.919 0.761 0.000 vt 0.947 0.512 0.000 vt 0.944 0.446 0.000 vt 0.974 0.452 0.000 vt 0.974 0.519 0.000 vt 0.915 0.504 0.000 vt 0.887 0.498 0.000 vt 0.917 0.564 0.000 vt 0.890 0.556 0.000 vt 0.999 0.634 0.000 vt 0.973 0.633 0.000 vt 0.975 0.577 0.000 vt 0.999 0.579 0.000 vt 0.882 0.614 0.000 vt 0.911 0.622 0.000 vt 0.901 0.679 0.000 vt 0.868 0.671 0.000 vt 0.833 0.667 0.000 vt 0.708 0.836 0.000 vt 0.500 0.205 0.000 vt 0.826 0.364 0.000 vt 0.801 0.303 0.000 vt 0.613 0.529 0.000 vt 0.607 0.544 0.000 vt 0.541 0.380 0.000 vt 0.538 0.372 0.000 vt 0.537 0.366 0.000 vt 0.537 0.363 0.000 vt 0.598 0.945 0.000 vt 0.524 0.902 0.000 vt 0.599 0.489 0.000 vt 0.609 0.563 0.000 vt 0.596 0.563 0.000 vt 0.612 0.559 0.000 vt 0.557 0.569 0.000 vt 0.620 0.571 0.000 vt 0.616 0.569 0.000 vt 0.618 0.569 0.000 vt 0.569 0.568 0.000 vt 0.561 0.568 0.000 vt 0.579 0.567 0.000 vt 0.616 0.564 0.000 vt 0.613 0.567 0.000 vt 0.607 0.567 0.000 vt 0.587 0.568 0.000 vt 0.606 0.568 0.000 vt 0.630 0.565 0.000 vt 0.548 0.389 0.000 vt 0.601 0.452 0.000 vt 0.529 0.566 0.000 vt 0.684 0.686 0.000 vt 0.872 0.222 0.000 vt 0.876 0.265 0.000 vt 0.825 0.258 0.000 vt 0.821 0.214 0.000 vt 0.561 0.119 0.000 vt 0.500 0.114 0.000 vt 0.771 0.304 0.000 vt 0.797 0.363 0.000 vt 0.726 0.227 0.000 vt 0.777 0.371 0.000 vt 0.947 0.571 0.000 vt 0.999 0.388 0.000 vt 0.999 0.456 0.000 vt 0.999 0.524 0.000 vt 0.936 0.877 0.000 vt 0.856 0.945 0.000 vt 0.999 0.323 0.000 vt 0.935 0.689 0.000 vt 0.776 0.240 0.000 vt 0.928 0.265 0.000 vt 0.969 0.264 0.000 vt 0.999 0.267 0.000 vt 0.943 0.628 0.000 vt 0.806 0.622 0.000 vt 0.851 0.611 0.000 vt 0.500 0.777 0.000 vt 0.500 0.839 0.000 vt 0.692 0.489 0.000 vt 0.631 0.558 0.000 vt 0.622 0.562 0.000 vt 0.626 0.560 0.000 vt 0.555 0.413 0.000 vt 0.570 0.429 0.000 vt 0.539 0.440 0.000 vt 0.524 0.607 0.000 vt 0.531 0.591 0.000 vt 0.500 0.361 0.000 vt 0.500 0.321 0.000 vt 0.500 0.312 0.000 vt 0.500 0.336 0.000 vt 0.500 0.294 0.000 vt 0.500 0.273 0.000 vt 0.622 0.549 0.000 vt 0.616 0.554 0.000 vt 0.607 0.509 0.000 vt 0.701 0.520 0.000 vt 0.500 0.421 0.000 vt 0.564 0.403 0.000 vt 0.511 0.615 0.000 vt 0.500 0.618 0.000 vt 0.617 0.568 0.000 vt 0.636 0.139 0.000 vt 0.764 0.192 0.000 vt 0.921 0.220 0.000 vt 0.967 0.219 0.000 vt 0.708 0.168 0.000 vt 0.999 0.218 0.000 vt 0.803 0.523 0.000 vt 0.794 0.535 0.000 vt 0.783 0.527 0.000 vt 0.791 0.508 0.000 vt 0.789 0.571 0.000 vt 0.797 0.562 0.000 vt 0.813 0.591 0.000 vt 0.815 0.578 0.000 vt 0.839 0.583 0.000 vt 0.835 0.574 0.000 vt 0.850 0.569 0.000 vt 0.845 0.560 0.000 vt 0.855 0.539 0.000 vt 0.847 0.535 0.000 vt 0.850 0.501 0.000 vt 0.841 0.502 0.000 vt 0.814 0.438 0.000 vt 0.836 0.464 0.000 vt 0.828 0.472 0.000 vt 0.809 0.452 0.000 vt 0.792 0.427 0.000 vt 0.790 0.441 0.000 vt 0.818 0.567 0.000 vt 0.807 0.550 0.000 vt 0.831 0.561 0.000 vt 0.839 0.553 0.000 vt 0.837 0.534 0.000 vt 0.831 0.505 0.000 vt 0.820 0.479 0.000 vt 0.804 0.465 0.000 vt 0.786 0.460 0.000 vt 0.773 0.456 0.000 vt 0.779 0.433 0.000 vt 0.797 0.489 0.000 vt 0.785 0.495 0.000 vt 0.789 0.486 0.000 vt 0.772 0.537 0.000 vt 0.781 0.583 0.000 vt 0.812 0.602 0.000 vt 0.848 0.587 0.000 vt 0.862 0.546 0.000 vt 0.859 0.500 0.000 vt 0.820 0.412 0.000 vt 0.843 0.450 0.000 vt 0.791 0.404 0.000 vt 0.773 0.417 0.000 vt 0.764 0.447 0.000 vt 0.801 0.477 0.000 vt 0.813 0.487 0.000 vt 0.806 0.496 0.000 vt 0.787 0.478 0.000 vt 0.778 0.489 0.000 vt 0.822 0.538 0.000 vt 0.822 0.510 0.000 vt 0.767 0.492 0.000 vt 0.870 0.496 0.000 vt 0.851 0.425 0.000 vt 0.872 0.552 0.000 vt 0.500 0.183 0.000 vt 0.516 0.930 0.000 vt 0.500 0.928 0.000 vt 0.528 0.934 0.000 vt 0.537 0.938 0.000 vt 0.516 0.970 0.000 vt 0.520 0.955 0.000 vt 0.530 0.952 0.000 vt 0.522 0.944 0.000 vt 0.512 0.942 0.000 vt 0.615 0.572 0.000 vt 0.612 0.569 0.000 vt 0.576 0.968 0.000 vt 0.573 0.973 0.000 vt 0.562 0.969 0.000 vt 0.563 0.961 0.000 vt 0.571 0.956 0.000 vt 0.582 0.961 0.000 vt 0.611 0.961 0.000 vt 0.606 0.967 0.000 vt 0.595 0.960 0.000 vt 0.601 0.955 0.000 vt 0.570 0.569 0.000 vt 0.595 0.566 0.000 vt 0.616 0.967 0.000 vt 0.617 0.975 0.000 vt 0.607 0.978 0.000 vt 0.614 0.982 0.000 vt 0.605 0.991 0.000 vt 0.599 0.986 0.000 vt 0.593 0.996 0.000 vt 0.589 0.989 0.000 vt 0.562 0.570 0.000 vt 0.573 0.994 0.000 vt 0.579 0.987 0.000 vt 0.584 0.996 0.000 vt 0.581 0.953 0.000 vt 0.592 0.953 0.000 vt 0.561 0.988 0.000 vt 0.572 0.981 0.000 vt 0.563 0.978 0.000 vt 0.500 0.970 0.000 vt 0.500 0.943 0.000 vt 0.511 0.956 0.000 vt 0.500 0.956 0.000 vt 0.868 0.132 0.000 vt 0.867 0.090 0.000 vt 0.916 0.092 0.000 vt 0.918 0.133 0.000 vt 0.554 0.066 0.000 vt 0.612 0.070 0.000 vt 0.619 0.103 0.000 vt 0.558 0.095 0.000 vt 0.815 0.169 0.000 vt 0.758 0.148 0.000 vt 0.747 0.102 0.000 vt 0.814 0.126 0.000 vt 0.770 0.072 0.000 vt 0.817 0.087 0.000 vt 0.552 0.038 0.000 vt 0.551 0.020 0.000 vt 0.602 0.021 0.000 vt 0.605 0.039 0.000 vt 0.821 0.050 0.000 vt 0.867 0.055 0.000 vt 0.712 0.053 0.000 vt 0.700 0.022 0.000 vt 0.739 0.023 0.000 vt 0.740 0.052 0.000 vt 0.652 0.022 0.000 vt 0.659 0.043 0.000 vt 0.913 0.055 0.000 vt 0.959 0.055 0.000 vt 0.960 0.091 0.000 vt 0.999 0.089 0.000 vt 0.999 0.131 0.000 vt 0.962 0.133 0.000 vt 0.999 0.053 0.000 vt 0.778 0.038 0.000 vt 0.917 0.177 0.000 vt 0.965 0.178 0.000 vt 0.674 0.083 0.000 vt 0.685 0.124 0.000 vt 0.999 0.175 0.000 vt 0.500 0.037 0.000 vt 0.500 0.066 0.000 vt 0.871 0.175 0.000 vt 0.500 0.019 0.000 vt 0.500 0.092 0.000 vt 0.999 0.002 0.000 vt 0.958 0.002 0.000 vt 0.867 0.002 0.000 vt 0.823 0.002 0.000 vt 0.908 0.002 0.000 vt 0.601 0.002 0.000 vt 0.550 0.002 0.000 vt 0.697 0.002 0.000 vt 0.650 0.002 0.000 vt 0.782 0.002 0.000 vt 0.740 0.002 0.000 vt 0.500 0.002 0.000 vt 0.468 0.923 0.000 vt 0.459 0.929 0.000 vt 0.458 0.923 0.000 vt 0.465 0.917 0.000 vt 0.479 0.984 0.000 vt 0.495 0.998 0.000 vt 0.479 0.996 0.000 vt 0.496 0.917 0.000 vt 0.485 0.918 0.000 vt 0.484 0.910 0.000 vt 0.493 0.910 0.000 vt 0.477 0.921 0.000 vt 0.475 0.913 0.000 vt 0.451 0.958 0.000 vt 0.450 0.946 0.000 vt 0.456 0.942 0.000 vt 0.462 0.954 0.000 vt 0.455 0.935 0.000 vt 0.450 0.932 0.000 vt 0.467 0.967 0.000 vt 0.453 0.974 0.000 vt 0.467 0.994 0.000 vt 0.458 0.987 0.000 vt 0.384 0.254 0.000 vt 0.381 0.292 0.000 vt 0.342 0.307 0.000 vt 0.347 0.261 0.000 vt 0.364 0.438 0.000 vt 0.353 0.414 0.000 vt 0.373 0.396 0.000 vt 0.380 0.419 0.000 vt 0.114 0.312 0.000 vt 0.156 0.308 0.000 vt 0.140 0.369 0.000 vt 0.103 0.370 0.000 vt 0.260 0.593 0.000 vt 0.232 0.598 0.000 vt 0.241 0.541 0.000 vt 0.259 0.542 0.000 vt 0.356 0.213 0.000 vt 0.356 0.174 0.000 vt 0.434 0.146 0.000 vt 0.439 0.175 0.000 vt 0.420 0.254 0.000 vt 0.435 0.256 0.000 vt 0.435 0.268 0.000 vt 0.415 0.277 0.000 vt 0.456 0.195 0.000 vt 0.410 0.217 0.000 vt 0.229 0.721 0.000 vt 0.206 0.663 0.000 vt 0.242 0.653 0.000 vt 0.264 0.712 0.000 vt 0.331 0.622 0.000 vt 0.348 0.651 0.000 vt 0.335 0.669 0.000 vt 0.315 0.632 0.000 vt 0.377 0.588 0.000 vt 0.373 0.599 0.000 vt 0.361 0.590 0.000 vt 0.368 0.582 0.000 vt 0.359 0.632 0.000 vt 0.343 0.612 0.000 vt 0.381 0.580 0.000 vt 0.373 0.576 0.000 vt 0.377 0.573 0.000 vt 0.383 0.575 0.000 vt 0.292 0.702 0.000 vt 0.271 0.646 0.000 vt 0.353 0.601 0.000 vt 0.367 0.614 0.000 vt 0.396 0.718 0.000 vt 0.404 0.682 0.000 vt 0.433 0.686 0.000 vt 0.426 0.725 0.000 vt 0.410 0.649 0.000 vt 0.438 0.648 0.000 vt 0.416 0.769 0.000 vt 0.382 0.756 0.000 vt 0.414 0.587 0.000 vt 0.414 0.580 0.000 vt 0.432 0.579 0.000 vt 0.434 0.586 0.000 vt 0.431 0.574 0.000 vt 0.414 0.573 0.000 vt 0.413 0.627 0.000 vt 0.438 0.627 0.000 vt 0.413 0.610 0.000 vt 0.413 0.596 0.000 vt 0.435 0.595 0.000 vt 0.437 0.608 0.000 vt 0.479 0.441 0.000 vt 0.483 0.445 0.000 vt 0.480 0.450 0.000 vt 0.474 0.450 0.000 vt 0.280 0.504 0.000 vt 0.262 0.494 0.000 vt 0.273 0.446 0.000 vt 0.291 0.467 0.000 vt 0.344 0.383 0.000 vt 0.327 0.403 0.000 vt 0.316 0.368 0.000 vt 0.340 0.348 0.000 vt 0.428 0.371 0.000 vt 0.419 0.374 0.000 vt 0.419 0.364 0.000 vt 0.427 0.365 0.000 vt 0.307 0.431 0.000 vt 0.292 0.400 0.000 vt 0.391 0.383 0.000 vt 0.396 0.401 0.000 vt 0.443 0.364 0.000 vt 0.444 0.364 0.000 vt 0.443 0.366 0.000 vt 0.441 0.365 0.000 vt 0.448 0.367 0.000 vt 0.448 0.364 0.000 vt 0.432 0.377 0.000 vt 0.434 0.370 0.000 vt 0.439 0.374 0.000 vt 0.406 0.377 0.000 vt 0.406 0.363 0.000 vt 0.347 0.551 0.000 vt 0.334 0.545 0.000 vt 0.342 0.523 0.000 vt 0.356 0.534 0.000 vt 0.363 0.480 0.000 vt 0.351 0.459 0.000 vt 0.375 0.458 0.000 vt 0.338 0.434 0.000 vt 0.443 0.345 0.000 vt 0.454 0.337 0.000 vt 0.457 0.349 0.000 vt 0.447 0.353 0.000 vt 0.414 0.403 0.000 vt 0.409 0.389 0.000 vt 0.421 0.382 0.000 vt 0.427 0.392 0.000 vt 0.428 0.343 0.000 vt 0.422 0.353 0.000 vt 0.410 0.347 0.000 vt 0.416 0.331 0.000 vt 0.457 0.355 0.000 vt 0.447 0.358 0.000 vt 0.447 0.499 0.000 vt 0.447 0.477 0.000 vt 0.458 0.484 0.000 vt 0.459 0.507 0.000 vt 0.461 0.532 0.000 vt 0.469 0.513 0.000 vt 0.471 0.541 0.000 vt 0.449 0.538 0.000 vt 0.448 0.521 0.000 vt 0.462 0.552 0.000 vt 0.124 0.429 0.000 vt 0.092 0.437 0.000 vt 0.392 0.340 0.000 vt 0.371 0.336 0.000 vt 0.401 0.314 0.000 vt 0.309 0.326 0.000 vt 0.252 0.426 0.000 vt 0.277 0.365 0.000 vt 0.245 0.489 0.000 vt 0.436 0.825 0.000 vt 0.467 0.834 0.000 vt 0.442 0.886 0.000 vt 0.410 0.868 0.000 vt 0.363 0.789 0.000 vt 0.335 0.817 0.000 vt 0.298 0.774 0.000 vt 0.327 0.755 0.000 vt 0.260 0.787 0.000 vt 0.460 0.686 0.000 vt 0.455 0.727 0.000 vt 0.462 0.572 0.000 vt 0.449 0.550 0.000 vt 0.480 0.546 0.000 vt 0.478 0.517 0.000 vt 0.479 0.728 0.000 vt 0.476 0.777 0.000 vt 0.448 0.775 0.000 vt 0.482 0.687 0.000 vt 0.485 0.650 0.000 vt 0.375 0.671 0.000 vt 0.382 0.644 0.000 vt 0.409 0.533 0.000 vt 0.411 0.518 0.000 vt 0.431 0.527 0.000 vt 0.429 0.539 0.000 vt 0.455 0.436 0.000 vt 0.451 0.425 0.000 vt 0.472 0.413 0.000 vt 0.475 0.427 0.000 vt 0.444 0.449 0.000 vt 0.437 0.439 0.000 vt 0.486 0.395 0.000 vt 0.487 0.409 0.000 vt 0.468 0.396 0.000 vt 0.434 0.511 0.000 vt 0.416 0.500 0.000 vt 0.423 0.478 0.000 vt 0.436 0.490 0.000 vt 0.429 0.457 0.000 vt 0.439 0.468 0.000 vt 0.446 0.561 0.000 vt 0.452 0.569 0.000 vt 0.448 0.569 0.000 vt 0.443 0.563 0.000 vt 0.373 0.847 0.000 vt 0.355 0.898 0.000 vt 0.326 0.871 0.000 vt 0.224 0.920 0.000 vt 0.217 0.887 0.000 vt 0.271 0.888 0.000 vt 0.291 0.921 0.000 vt 0.379 0.920 0.000 vt 0.307 0.947 0.000 vt 0.465 0.642 0.000 vt 0.455 0.599 0.000 vt 0.458 0.618 0.000 vt 0.448 0.377 0.000 vt 0.441 0.383 0.000 vt 0.469 0.470 0.000 vt 0.472 0.457 0.000 vt 0.483 0.456 0.000 vt 0.480 0.472 0.000 vt 0.470 0.438 0.000 vt 0.483 0.436 0.000 vt 0.472 0.383 0.000 vt 0.474 0.374 0.000 vt 0.488 0.374 0.000 vt 0.487 0.384 0.000 vt 0.474 0.366 0.000 vt 0.488 0.367 0.000 vt 0.474 0.362 0.000 vt 0.488 0.362 0.000 vt 0.489 0.422 0.000 vt 0.492 0.457 0.000 vt 0.489 0.472 0.000 vt 0.479 0.491 0.000 vt 0.488 0.491 0.000 vt 0.488 0.519 0.000 vt 0.489 0.550 0.000 vt 0.490 0.583 0.000 vt 0.480 0.576 0.000 vt 0.346 0.584 0.000 vt 0.334 0.589 0.000 vt 0.331 0.567 0.000 vt 0.344 0.568 0.000 vt 0.295 0.639 0.000 vt 0.282 0.591 0.000 vt 0.320 0.592 0.000 vt 0.316 0.563 0.000 vt 0.363 0.575 0.000 vt 0.355 0.579 0.000 vt 0.355 0.567 0.000 vt 0.364 0.566 0.000 vt 0.277 0.546 0.000 vt 0.298 0.554 0.000 vt 0.303 0.592 0.000 vt 0.421 0.298 0.000 vt 0.440 0.287 0.000 vt 0.446 0.307 0.000 vt 0.430 0.317 0.000 vt 0.466 0.318 0.000 vt 0.462 0.300 0.000 vt 0.481 0.296 0.000 vt 0.483 0.314 0.000 vt 0.438 0.362 0.000 vt 0.441 0.360 0.000 vt 0.443 0.362 0.000 vt 0.441 0.363 0.000 vt 0.439 0.368 0.000 vt 0.437 0.365 0.000 vt 0.469 0.351 0.000 vt 0.469 0.358 0.000 vt 0.457 0.360 0.000 vt 0.389 0.437 0.000 vt 0.387 0.475 0.000 vt 0.376 0.497 0.000 vt 0.420 0.445 0.000 vt 0.410 0.466 0.000 vt 0.402 0.418 0.000 vt 0.352 0.501 0.000 vt 0.367 0.516 0.000 vt 0.359 0.554 0.000 vt 0.370 0.541 0.000 vt 0.267 0.331 0.000 vt 0.249 0.313 0.000 vt 0.294 0.252 0.000 vt 0.304 0.288 0.000 vt 0.317 0.535 0.000 vt 0.326 0.508 0.000 vt 0.001 0.696 0.000 vt 0.033 0.695 0.000 vt 0.050 0.772 0.000 vt 0.014 0.778 0.000 vt 0.400 0.811 0.000 vt 0.448 0.361 0.000 vt 0.454 0.364 0.000 vt 0.453 0.367 0.000 vt 0.475 0.254 0.000 vt 0.478 0.274 0.000 vt 0.458 0.280 0.000 vt 0.454 0.261 0.000 vt 0.369 0.369 0.000 vt 0.322 0.460 0.000 vt 0.338 0.482 0.000 vt 0.324 0.977 0.000 vt 0.238 0.981 0.000 vt 0.230 0.948 0.000 vt 0.155 0.915 0.000 vt 0.165 0.891 0.000 vt 0.431 0.560 0.000 vt 0.431 0.564 0.000 vt 0.420 0.563 0.000 vt 0.418 0.558 0.000 vt 0.410 0.544 0.000 vt 0.429 0.548 0.000 vt 0.349 0.731 0.000 vt 0.365 0.701 0.000 vt 0.391 0.606 0.000 vt 0.393 0.593 0.000 vt 0.457 0.570 0.000 vt 0.447 0.556 0.000 vt 0.444 0.574 0.000 vt 0.448 0.580 0.000 vt 0.415 0.551 0.000 vt 0.431 0.554 0.000 vt 0.441 0.566 0.000 vt 0.450 0.458 0.000 vt 0.451 0.325 0.000 vt 0.468 0.330 0.000 vt 0.390 0.364 0.000 vt 0.411 0.432 0.000 vt 0.422 0.417 0.000 vt 0.430 0.357 0.000 vt 0.435 0.351 0.000 vt 0.438 0.356 0.000 vt 0.435 0.360 0.000 vt 0.443 0.364 0.000 vt 0.444 0.364 0.000 vt 0.443 0.371 0.000 vt 0.452 0.371 0.000 vt 0.238 0.385 0.000 vt 0.487 0.445 0.000 vt 0.492 0.444 0.000 vt 0.061 0.378 0.000 vt 0.026 0.384 0.000 vt 0.028 0.321 0.000 vt 0.068 0.316 0.000 vt 0.395 0.572 0.000 vt 0.395 0.578 0.000 vt 0.395 0.584 0.000 vt 0.441 0.571 0.000 vt 0.438 0.333 0.000 vt 0.469 0.343 0.000 vt 0.486 0.338 0.000 vt 0.484 0.324 0.000 vt 0.468 0.488 0.000 vt 0.466 0.448 0.000 vt 0.462 0.455 0.000 vt 0.455 0.448 0.000 vt 0.460 0.446 0.000 vt 0.459 0.466 0.000 vt 0.388 0.623 0.000 vt 0.433 0.366 0.000 vt 0.487 0.356 0.000 vt 0.486 0.348 0.000 vt 0.457 0.363 0.000 vt 0.448 0.364 0.000 vt 0.469 0.362 0.000 vt 0.488 0.361 0.000 vt 0.491 0.433 0.000 vt 0.401 0.557 0.000 vt 0.397 0.551 0.000 vt 0.373 0.570 0.000 vt 0.369 0.571 0.000 vt 0.375 0.566 0.000 vt 0.379 0.567 0.000 vt 0.378 0.569 0.000 vt 0.471 0.234 0.000 vt 0.450 0.245 0.000 vt 0.143 0.816 0.000 vt 0.114 0.748 0.000 vt 0.149 0.737 0.000 vt 0.175 0.804 0.000 vt 0.202 0.856 0.000 vt 0.179 0.866 0.000 vt 0.190 0.729 0.000 vt 0.217 0.797 0.000 vt 0.245 0.848 0.000 vt 0.466 0.215 0.000 vt 0.437 0.233 0.000 vt 0.452 0.588 0.000 vt 0.092 0.854 0.000 vt 0.116 0.835 0.000 vt 0.081 0.761 0.000 vt 0.053 0.512 0.000 vt 0.026 0.519 0.000 vt 0.026 0.452 0.000 vt 0.056 0.446 0.000 vt 0.113 0.498 0.000 vt 0.085 0.504 0.000 vt 0.110 0.556 0.000 vt 0.083 0.564 0.000 vt 0.001 0.634 0.000 vt 0.001 0.579 0.000 vt 0.025 0.577 0.000 vt 0.027 0.633 0.000 vt 0.118 0.614 0.000 vt 0.132 0.671 0.000 vt 0.099 0.679 0.000 vt 0.089 0.622 0.000 vt 0.167 0.667 0.000 vt 0.292 0.836 0.000 vt 0.199 0.303 0.000 vt 0.174 0.364 0.000 vt 0.393 0.544 0.000 vt 0.387 0.529 0.000 vt 0.459 0.380 0.000 vt 0.462 0.372 0.000 vt 0.463 0.366 0.000 vt 0.463 0.363 0.000 vt 0.402 0.945 0.000 vt 0.476 0.902 0.000 vt 0.401 0.489 0.000 vt 0.391 0.563 0.000 vt 0.388 0.559 0.000 vt 0.404 0.563 0.000 vt 0.443 0.569 0.000 vt 0.380 0.571 0.000 vt 0.382 0.569 0.000 vt 0.384 0.569 0.000 vt 0.439 0.568 0.000 vt 0.431 0.568 0.000 vt 0.421 0.567 0.000 vt 0.393 0.567 0.000 vt 0.387 0.567 0.000 vt 0.384 0.564 0.000 vt 0.394 0.568 0.000 vt 0.413 0.568 0.000 vt 0.370 0.565 0.000 vt 0.452 0.389 0.000 vt 0.399 0.452 0.000 vt 0.471 0.566 0.000 vt 0.316 0.686 0.000 vt 0.128 0.222 0.000 vt 0.179 0.214 0.000 vt 0.175 0.258 0.000 vt 0.124 0.265 0.000 vt 0.439 0.119 0.000 vt 0.229 0.304 0.000 vt 0.203 0.363 0.000 vt 0.274 0.227 0.000 vt 0.223 0.371 0.000 vt 0.053 0.571 0.000 vt 0.001 0.388 0.000 vt 0.001 0.456 0.000 vt 0.001 0.524 0.000 vt 0.064 0.877 0.000 vt 0.144 0.945 0.000 vt 0.001 0.323 0.000 vt 0.065 0.689 0.000 vt 0.224 0.240 0.000 vt 0.072 0.265 0.000 vt 0.001 0.267 0.000 vt 0.031 0.264 0.000 vt 0.057 0.628 0.000 vt 0.194 0.622 0.000 vt 0.149 0.611 0.000 vt 0.308 0.489 0.000 vt 0.369 0.558 0.000 vt 0.374 0.560 0.000 vt 0.378 0.562 0.000 vt 0.445 0.413 0.000 vt 0.430 0.429 0.000 vt 0.461 0.440 0.000 vt 0.476 0.607 0.000 vt 0.469 0.591 0.000 vt 0.378 0.549 0.000 vt 0.384 0.554 0.000 vt 0.393 0.509 0.000 vt 0.299 0.520 0.000 vt 0.436 0.403 0.000 vt 0.489 0.615 0.000 vt 0.383 0.568 0.000 vt 0.364 0.139 0.000 vt 0.236 0.192 0.000 vt 0.033 0.219 0.000 vt 0.079 0.220 0.000 vt 0.292 0.168 0.000 vt 0.001 0.218 0.000 vt 0.197 0.523 0.000 vt 0.209 0.508 0.000 vt 0.217 0.527 0.000 vt 0.206 0.535 0.000 vt 0.211 0.571 0.000 vt 0.203 0.562 0.000 vt 0.187 0.591 0.000 vt 0.185 0.578 0.000 vt 0.161 0.583 0.000 vt 0.165 0.574 0.000 vt 0.150 0.569 0.000 vt 0.155 0.560 0.000 vt 0.145 0.539 0.000 vt 0.153 0.535 0.000 vt 0.150 0.501 0.000 vt 0.159 0.502 0.000 vt 0.186 0.438 0.000 vt 0.191 0.452 0.000 vt 0.172 0.472 0.000 vt 0.164 0.464 0.000 vt 0.208 0.427 0.000 vt 0.210 0.441 0.000 vt 0.182 0.567 0.000 vt 0.193 0.550 0.000 vt 0.169 0.561 0.000 vt 0.161 0.553 0.000 vt 0.163 0.534 0.000 vt 0.169 0.505 0.000 vt 0.196 0.465 0.000 vt 0.180 0.479 0.000 vt 0.214 0.460 0.000 vt 0.227 0.456 0.000 vt 0.221 0.433 0.000 vt 0.203 0.489 0.000 vt 0.211 0.486 0.000 vt 0.215 0.495 0.000 vt 0.228 0.537 0.000 vt 0.219 0.583 0.000 vt 0.188 0.602 0.000 vt 0.152 0.587 0.000 vt 0.138 0.546 0.000 vt 0.141 0.500 0.000 vt 0.157 0.450 0.000 vt 0.180 0.412 0.000 vt 0.209 0.404 0.000 vt 0.227 0.417 0.000 vt 0.236 0.447 0.000 vt 0.194 0.496 0.000 vt 0.187 0.487 0.000 vt 0.199 0.477 0.000 vt 0.213 0.478 0.000 vt 0.222 0.489 0.000 vt 0.178 0.538 0.000 vt 0.178 0.510 0.000 vt 0.233 0.492 0.000 vt 0.130 0.496 0.000 vt 0.149 0.425 0.000 vt 0.128 0.552 0.000 vt 0.484 0.930 0.000 vt 0.472 0.934 0.000 vt 0.463 0.938 0.000 vt 0.470 0.952 0.000 vt 0.480 0.955 0.000 vt 0.484 0.970 0.000 vt 0.488 0.942 0.000 vt 0.478 0.944 0.000 vt 0.388 0.569 0.000 vt 0.385 0.572 0.000 vt 0.424 0.968 0.000 vt 0.437 0.961 0.000 vt 0.438 0.969 0.000 vt 0.427 0.973 0.000 vt 0.418 0.961 0.000 vt 0.429 0.956 0.000 vt 0.389 0.961 0.000 vt 0.399 0.955 0.000 vt 0.405 0.960 0.000 vt 0.394 0.967 0.000 vt 0.429 0.569 0.000 vt 0.405 0.566 0.000 vt 0.393 0.978 0.000 vt 0.383 0.975 0.000 vt 0.384 0.967 0.000 vt 0.401 0.986 0.000 vt 0.395 0.991 0.000 vt 0.386 0.982 0.000 vt 0.411 0.989 0.000 vt 0.407 0.996 0.000 vt 0.438 0.570 0.000 vt 0.427 0.994 0.000 vt 0.416 0.996 0.000 vt 0.421 0.987 0.000 vt 0.419 0.953 0.000 vt 0.408 0.953 0.000 vt 0.439 0.988 0.000 vt 0.428 0.981 0.000 vt 0.437 0.978 0.000 vt 0.489 0.956 0.000 vt 0.132 0.132 0.000 vt 0.082 0.133 0.000 vt 0.084 0.092 0.000 vt 0.133 0.090 0.000 vt 0.446 0.066 0.000 vt 0.442 0.095 0.000 vt 0.381 0.103 0.000 vt 0.388 0.070 0.000 vt 0.185 0.169 0.000 vt 0.186 0.126 0.000 vt 0.253 0.102 0.000 vt 0.242 0.148 0.000 vt 0.230 0.072 0.000 vt 0.183 0.087 0.000 vt 0.448 0.038 0.000 vt 0.395 0.039 0.000 vt 0.398 0.021 0.000 vt 0.449 0.020 0.000 vt 0.133 0.055 0.000 vt 0.179 0.050 0.000 vt 0.288 0.053 0.000 vt 0.260 0.052 0.000 vt 0.261 0.023 0.000 vt 0.300 0.022 0.000 vt 0.341 0.043 0.000 vt 0.348 0.022 0.000 vt 0.087 0.055 0.000 vt 0.040 0.091 0.000 vt 0.041 0.055 0.000 vt 0.038 0.133 0.000 vt 0.001 0.131 0.000 vt 0.001 0.089 0.000 vt 0.001 0.053 0.000 vt 0.222 0.038 0.000 vt 0.083 0.177 0.000 vt 0.035 0.178 0.000 vt 0.326 0.083 0.000 vt 0.315 0.124 0.000 vt 0.001 0.175 0.000 vt 0.129 0.175 0.000 vt 0.001 0.002 0.000 vt 0.042 0.002 0.000 vt 0.133 0.002 0.000 vt 0.177 0.002 0.000 vt 0.092 0.002 0.000 vt 0.399 0.002 0.000 vt 0.450 0.002 0.000 vt 0.303 0.002 0.000 vt 0.350 0.002 0.000 vt 0.218 0.002 0.000 vt 0.260 0.002 0.000 vt 0.558 0.967 0.000 vt 0.557 0.976 0.000 vt 0.500 0.997 0.000 vt 0.588 0.975 0.000 vt 0.442 0.967 0.000 vt 0.443 0.976 0.000 vt 0.412 0.975 0.000 # 1339 texture vertices vn 0.001 0.482 -0.876 vn -0.001 0.661 0.751 vn 0.136 0.595 0.792 vn -0.203 0.679 0.706 vn -0.092 0.474 0.876 vn -0.184 0.792 0.581 vn -0.098 0.863 0.495 vn -0.449 0.820 0.356 vn -0.220 0.748 0.626 vn -0.560 0.798 -0.222 vn -0.233 0.531 -0.815 vn 0.001 0.534 -0.845 vn -0.135 0.596 0.791 vn 0.203 0.676 0.708 vn 0.091 0.476 0.875 vn 0.189 0.792 0.581 vn 0.099 0.862 0.496 vn 0.444 0.821 0.360 vn 0.221 0.747 0.627 vn 0.556 0.801 -0.221 vn 0.228 0.532 -0.815 vn -0.002 0.536 -0.844 vn -0.574 0.744 -0.343 vn -0.485 0.523 -0.701 vn -0.121 0.869 -0.480 vn -0.215 0.930 -0.298 vn -0.000 -0.806 -0.591 vn -0.277 -0.779 -0.562 vn -0.258 -0.731 -0.632 vn -0.046 -0.809 -0.586 vn -0.210 0.565 -0.798 vn -0.094 0.624 -0.775 vn 0.015 0.952 -0.307 vn 0.045 0.919 -0.392 vn -0.099 0.857 -0.505 vn -0.379 0.493 -0.783 vn -0.947 0.285 -0.149 vn -0.809 -0.421 -0.411 vn -0.895 -0.443 -0.043 vn -0.999 -0.020 0.035 vn -0.359 0.933 -0.019 vn -0.809 0.586 0.047 vn -0.667 -0.516 -0.538 vn -0.726 -0.626 -0.285 vn -0.001 0.671 -0.741 vn -0.001 0.945 -0.327 vn -0.531 -0.632 -0.565 vn -0.618 -0.566 -0.546 vn 0.800 -0.473 0.369 vn 0.618 -0.771 0.151 vn 0.693 -0.711 0.116 vn 0.818 -0.467 0.335 vn 0.849 -0.259 0.460 vn 0.775 -0.130 0.619 vn 0.667 -0.132 0.733 vn 0.775 -0.270 0.571 vn 0.958 -0.057 -0.280 vn 0.763 0.033 -0.646 vn 0.763 -0.153 -0.628 vn 0.911 -0.129 -0.391 vn 0.990 0.067 0.126 vn 0.979 0.090 0.185 vn 0.981 0.057 0.184 vn 0.996 0.020 0.090 vn 0.770 -0.392 0.504 vn 0.657 -0.721 0.219 vn 0.478 -0.656 0.584 vn 0.599 -0.389 0.700 vn 0.498 -0.846 0.192 vn 0.537 -0.840 0.082 vn 0.740 -0.557 0.378 vn 0.668 -0.570 0.479 vn 0.280 -0.914 0.294 vn 0.421 -0.898 0.126 vn 0.991 0.084 0.103 vn 0.964 0.223 0.143 vn 0.960 0.189 0.207 vn 0.979 0.103 0.175 vn 0.868 0.172 0.465 vn 0.907 0.085 0.413 vn 0.938 0.144 0.316 vn 0.897 0.178 0.405 vn 0.662 -0.174 0.729 vn 0.583 -0.417 0.697 vn 0.627 -0.449 0.637 vn 0.685 -0.405 0.605 vn 0.827 0.091 0.555 vn 0.890 0.018 0.455 vn 0.663 -0.395 0.636 vn 0.606 -0.428 0.671 vn 0.313 -0.735 0.602 vn -0.136 -0.864 0.485 vn 0.951 0.158 0.267 vn 0.964 0.113 0.241 vn 0.731 -0.036 0.681 vn 0.819 -0.134 0.558 vn 0.546 0.270 0.793 vn 0.602 0.237 0.763 vn 0.444 0.233 0.865 vn 0.353 0.173 0.920 vn 0.240 -0.093 0.966 vn 0.498 0.051 0.866 vn 0.675 0.338 0.656 vn 0.480 0.400 0.780 vn 0.064 -0.572 0.818 vn 0.126 -0.313 0.941 vn 0.207 -0.613 0.763 vn 0.221 -0.810 0.544 vn 0.598 -0.694 -0.401 vn 0.124 -0.977 -0.175 vn 0.218 -0.333 0.917 vn 0.377 -0.161 0.912 vn 0.142 -0.210 0.967 vn 0.256 -0.155 0.954 vn 0.111 -0.351 0.930 vn 0.107 -0.480 0.871 vn 0.675 -0.732 -0.096 vn 0.496 -0.844 0.206 vn -0.016 -0.986 0.167 vn 0.304 -0.948 0.097 vn 0.982 -0.082 0.171 vn 0.963 -0.002 0.269 vn 0.967 -0.134 0.216 vn 0.969 -0.177 0.175 vn 0.916 -0.244 0.319 vn 0.853 -0.341 0.394 vn 0.837 -0.365 0.407 vn 0.886 -0.281 0.368 vn 0.422 -0.292 0.858 vn 0.039 -0.571 0.820 vn -0.011 -0.399 0.917 vn 0.333 -0.349 0.876 vn 0.935 -0.237 0.263 vn 0.949 -0.159 0.273 vn 0.697 -0.213 0.685 vn 0.568 -0.123 0.814 vn -0.938 0.322 0.130 vn -0.609 -0.738 -0.291 vn -0.447 -0.857 -0.258 vn 0.259 -0.528 0.809 vn 0.137 -0.704 0.697 vn -0.107 -0.741 0.663 vn 0.647 -0.296 0.703 vn 0.603 -0.168 0.780 vn 0.836 0.072 0.545 vn 0.744 0.114 0.659 vn 0.701 0.149 0.698 vn 0.802 0.157 0.577 vn 0.823 -0.080 0.562 vn 0.690 0.142 0.710 vn 0.628 0.036 0.778 vn 0.894 -0.247 0.373 vn 0.624 -0.153 0.766 vn 0.661 0.110 0.742 vn 0.712 0.424 0.559 vn 0.701 0.284 0.654 vn 0.504 -0.050 0.862 vn 0.413 0.027 0.910 vn 0.569 0.046 0.821 vn 0.488 -0.134 0.862 vn 0.411 -0.180 0.894 vn 0.610 -0.024 0.792 vn 0.747 -0.250 0.616 vn 0.672 -0.313 0.671 vn 0.536 0.762 0.363 vn 0.559 0.768 0.312 vn 0.802 0.272 0.531 vn 0.618 0.206 0.759 vn 0.717 0.383 0.583 vn 0.780 0.464 0.420 vn 0.617 0.401 0.678 vn 0.658 0.397 0.640 vn 0.672 0.440 0.596 vn 0.501 0.314 0.807 vn 0.612 0.527 0.589 vn 0.679 0.320 0.661 vn 0.732 -0.406 -0.547 vn 0.885 -0.261 -0.386 vn 0.842 -0.347 0.414 vn 0.782 -0.349 0.517 vn 0.784 -0.368 0.500 vn 0.858 -0.453 0.244 vn 0.953 -0.279 0.118 vn 0.977 -0.189 0.104 vn 0.989 -0.110 0.102 vn 0.142 0.669 0.730 vn 0.300 0.652 0.696 vn 0.291 0.792 0.536 vn 0.143 0.821 0.553 vn 0.737 0.561 0.378 vn 0.716 0.470 0.515 vn 0.884 0.306 0.353 vn 0.898 0.354 0.263 vn 0.890 0.423 0.171 vn 0.174 0.078 0.982 vn 0.219 0.254 0.942 vn 0.665 -0.104 0.739 vn 0.671 0.390 0.631 vn 0.596 0.435 0.675 vn 0.636 0.467 0.614 vn 0.076 0.244 0.967 vn 0.261 0.437 0.861 vn 0.107 0.440 0.892 vn 0.011 0.082 0.997 vn 0.005 0.082 0.997 vn 0.028 -0.027 0.999 vn 0.073 -0.057 0.996 vn 0.006 0.228 0.974 vn 0.683 0.140 0.717 vn 0.724 0.233 0.650 vn 0.400 0.338 0.852 vn 0.270 0.126 0.955 vn 0.357 0.433 0.828 vn 0.503 0.485 0.716 vn 0.536 0.133 0.834 vn 0.416 -0.306 0.856 vn 0.337 0.097 0.937 vn 0.262 0.372 0.891 vn 0.425 0.075 0.902 vn 0.701 -0.147 0.698 vn -0.056 0.558 0.828 vn 0.005 0.605 0.796 vn 0.483 0.327 0.812 vn 0.497 0.276 0.823 vn 0.505 0.283 0.815 vn 0.340 -0.030 0.940 vn 0.332 0.066 0.941 vn 0.026 0.644 0.765 vn 0.021 0.538 0.843 vn 0.170 -0.012 0.985 vn 0.365 -0.067 0.929 vn 0.826 -0.173 0.537 vn 0.320 0.415 0.852 vn 0.384 0.739 0.554 vn 0.987 -0.013 0.160 vn 0.495 0.720 0.487 vn 0.490 0.830 0.268 vn 0.279 0.906 0.317 vn 0.431 0.899 -0.074 vn 0.267 0.957 -0.112 vn 0.283 0.953 0.107 vn 0.471 0.877 0.092 vn 0.132 0.985 0.113 vn 0.135 0.931 0.339 vn 0.190 -0.184 0.964 vn 0.292 -0.372 0.881 vn 0.307 -0.447 0.840 vn 0.393 -0.580 0.713 vn 0.524 -0.286 0.802 vn 0.380 -0.582 0.719 vn 0.697 0.212 0.685 vn 0.603 0.070 0.795 vn 0.558 -0.571 0.602 vn -0.089 -0.701 0.707 vn 0.794 -0.345 0.500 vn 0.345 -0.517 0.783 vn 0.481 0.101 0.871 vn 0.134 0.283 0.950 vn 0.113 -0.558 0.822 vn -0.073 -0.993 0.089 vn -0.041 -0.994 0.103 vn 0.084 -0.038 0.996 vn -0.012 -0.622 0.783 vn -0.002 0.254 0.967 vn 0.004 -0.997 0.079 vn 0.001 -0.832 -0.555 vn 0.477 -0.363 0.801 vn 0.414 0.160 0.896 vn 0.395 0.485 0.780 vn 0.611 0.484 0.627 vn 0.406 0.510 0.758 vn 0.375 0.498 0.782 vn 0.555 0.314 0.770 vn 0.349 0.411 0.842 vn 0.012 0.247 0.969 vn 0.002 -0.369 0.930 vn -0.003 0.509 0.861 vn 0.876 -0.041 0.481 vn 0.757 -0.214 0.618 vn 0.737 -0.048 0.674 vn 0.840 -0.012 0.542 vn 0.960 0.137 0.243 vn 0.969 0.103 0.226 vn 0.909 0.015 0.417 vn 0.906 0.015 0.423 vn 0.676 -0.276 0.683 vn 0.688 -0.223 0.691 vn 0.691 0.035 0.722 vn 0.719 -0.082 0.691 vn 0.964 0.062 0.260 vn 0.956 0.070 0.286 vn 0.953 0.037 0.300 vn -0.003 -0.415 0.910 vn -0.001 -0.380 0.925 vn 0.658 -0.419 0.625 vn 0.735 -0.421 0.532 vn 0.663 -0.303 0.685 vn 0.550 -0.321 0.771 vn 0.423 -0.236 0.875 vn 0.326 -0.294 0.899 vn 0.124 -0.396 0.910 vn 0.218 -0.177 0.960 vn 0.530 0.781 0.331 vn 0.167 0.827 0.537 vn 0.094 0.948 0.303 vn 0.313 0.934 0.171 vn -0.406 -0.892 0.201 vn -0.743 0.107 0.661 vn 0.455 0.704 0.546 vn 0.288 0.957 0.025 vn 0.245 0.958 0.150 vn 0.532 -0.027 0.846 vn 0.566 0.213 0.796 vn 0.508 0.208 0.836 vn 0.173 0.028 0.984 vn 0.371 0.122 0.921 vn 0.429 -0.045 0.902 vn 0.614 0.165 0.772 vn 0.737 0.157 0.657 vn 0.726 0.057 0.685 vn 0.662 0.061 0.747 vn 0.845 -0.523 -0.112 vn 0.845 -0.501 -0.185 vn 0.744 -0.668 0.009 vn 0.773 -0.630 0.079 vn 0.889 0.108 0.445 vn 0.899 0.077 0.430 vn 0.184 0.204 -0.961 vn 0.005 0.202 -0.979 vn -0.000 0.485 -0.875 vn 0.159 0.484 -0.861 vn 0.499 0.592 0.633 vn 0.305 0.950 0.065 vn -0.274 -0.953 -0.127 vn 0.245 -0.456 0.856 vn 0.083 -0.881 0.465 vn 0.435 -0.739 0.515 vn 0.504 -0.429 0.750 vn 0.818 -0.367 0.443 vn 0.933 -0.162 0.322 vn 0.872 0.029 0.489 vn 0.002 0.994 0.113 vn 0.133 0.983 -0.126 vn -0.001 0.992 -0.127 vn 0.280 0.892 -0.356 vn 0.126 0.916 -0.381 vn 0.210 0.974 -0.083 vn -0.082 0.663 0.745 vn -0.059 0.391 0.919 vn 0.111 0.992 -0.055 vn 0.081 -0.190 0.978 vn 0.035 0.076 0.996 vn 0.852 0.236 0.467 vn 0.775 0.219 0.593 vn 0.505 -0.109 0.856 vn 0.446 -0.314 0.838 vn 0.511 0.200 0.836 vn 0.623 -0.242 0.744 vn 0.436 -0.554 0.709 vn 0.599 -0.742 0.300 vn -0.036 0.177 0.984 vn -0.039 -0.159 0.987 vn 0.308 0.942 -0.135 vn 0.989 0.093 -0.111 vn 0.477 -0.259 0.840 vn 0.473 -0.423 0.773 vn 0.774 -0.329 0.541 vn 0.285 0.019 0.958 vn 0.350 0.101 0.931 vn 0.579 0.261 0.773 vn 0.298 0.015 0.954 vn 0.165 0.336 0.927 vn 0.577 0.511 0.636 vn 0.254 -0.834 0.490 vn -0.114 -0.925 0.363 vn 0.941 -0.280 -0.188 vn 0.460 -0.738 0.493 vn 0.740 -0.635 0.221 vn 0.003 0.529 0.849 vn 0.206 -0.427 -0.881 vn 0.497 -0.316 -0.808 vn 0.457 -0.144 -0.878 vn 0.179 -0.244 -0.953 vn -0.182 -0.980 -0.078 vn 0.342 -0.427 0.837 vn 0.424 -0.296 0.856 vn 0.896 -0.357 -0.264 vn 0.594 -0.104 0.798 vn 0.012 0.528 0.849 vn 0.042 0.469 0.882 vn 0.624 0.102 0.775 vn 0.324 -0.123 0.938 vn 0.202 -0.638 0.743 vn 0.714 0.512 0.477 vn 0.433 -0.511 0.742 vn -0.350 -0.708 0.613 vn 0.095 -0.410 0.907 vn 0.622 -0.593 0.512 vn 0.846 0.304 0.437 vn 0.582 -0.043 0.812 vn -0.226 -0.380 0.897 vn 0.215 0.644 0.734 vn 0.123 0.952 0.280 vn -0.004 0.956 0.293 vn -0.005 0.635 0.772 vn 0.325 -0.730 0.601 vn -0.017 -0.840 0.543 vn 0.017 -0.788 0.616 vn 0.294 -0.138 0.946 vn 0.214 0.401 0.891 vn -0.150 0.490 0.859 vn 0.573 -0.125 0.810 vn -0.134 0.957 0.258 vn 0.252 0.828 0.501 vn -0.673 0.643 0.364 vn 0.004 -0.960 0.279 vn 0.032 -0.991 0.133 vn 0.006 -0.908 0.419 vn 0.180 -0.980 0.086 vn 0.740 0.403 -0.538 vn 0.627 0.652 -0.426 vn 0.814 0.561 -0.149 vn 0.925 0.321 -0.206 vn 0.492 0.825 -0.280 vn 0.649 0.757 -0.076 vn 0.966 0.258 0.022 vn 0.864 0.501 0.053 vn 0.680 0.729 0.077 vn 0.272 -0.962 -0.032 vn 0.225 -0.968 0.111 vn 0.288 -0.510 0.810 vn 0.126 0.748 -0.651 vn 0.340 0.725 -0.598 vn 0.421 0.466 -0.778 vn 0.205 -0.458 -0.865 vn 0.489 -0.479 -0.729 vn 0.500 -0.523 -0.690 vn 0.210 -0.566 -0.798 vn 0.895 -0.322 -0.309 vn 0.759 -0.434 -0.485 vn 0.797 -0.287 -0.532 vn 0.937 -0.248 -0.245 vn -0.001 -0.238 -0.971 vn -0.000 -0.025 -1.000 vn 0.194 -0.025 -0.981 vn 0.201 -0.248 -0.948 vn 0.969 0.094 -0.229 vn 0.968 -0.101 -0.228 vn 0.814 -0.088 -0.575 vn 0.800 0.142 -0.583 vn 0.998 0.061 -0.010 vn 0.726 0.657 0.205 vn 0.000 -0.985 0.174 vn 0.985 -0.166 0.038 vn 0.955 -0.220 -0.200 vn 0.472 0.076 0.879 vn 0.343 -0.235 0.909 vn 0.464 -0.641 0.612 vn 0.578 -0.186 0.795 vn -0.189 -0.982 0.010 vn 0.004 0.938 0.345 vn 0.002 0.829 0.559 vn 0.445 0.232 0.865 vn 0.463 0.340 0.818 vn -0.116 0.983 0.143 vn 0.004 0.995 0.102 vn 0.978 0.204 0.044 vn -0.967 -0.216 -0.137 vn -0.911 -0.347 0.224 vn -0.728 0.350 0.590 vn 0.426 0.738 -0.523 vn 0.618 0.786 0.011 vn 0.151 0.857 -0.493 vn -0.333 0.912 -0.241 vn -0.277 0.956 0.095 vn -0.569 0.822 -0.032 vn -0.341 -0.671 -0.658 vn 0.161 -0.736 -0.657 vn 0.528 0.432 0.731 vn 0.586 0.105 0.803 vn 0.436 0.074 0.897 vn 0.621 0.267 0.737 vn 0.936 0.153 0.316 vn 0.999 -0.010 0.042 vn 0.826 0.281 -0.489 vn 0.775 0.178 -0.606 vn 0.995 -0.039 -0.095 vn 0.005 -0.414 0.910 vn 0.580 -0.243 0.778 vn 0.938 -0.339 -0.068 vn 0.925 -0.371 0.080 vn 0.888 -0.269 0.373 vn 0.923 -0.371 -0.106 vn 0.494 -0.274 -0.825 vn -0.001 -0.456 -0.890 vn -0.002 -0.569 -0.822 vn -0.001 -0.452 -0.892 vn -0.003 0.749 -0.663 vn -0.000 0.920 -0.391 vn -0.001 -0.280 -0.960 vn 0.470 0.194 -0.861 vn 0.965 -0.123 0.234 vn 0.400 -0.039 -0.916 vn 0.142 -0.166 -0.976 vn -0.000 -0.194 -0.981 vn 0.497 -0.049 -0.867 vn 0.998 0.042 0.045 vn 0.996 -0.037 -0.082 vn 0.009 0.433 0.901 vn 0.004 0.669 0.743 vn 0.955 0.004 0.296 vn 0.737 -0.001 0.675 vn 0.707 0.177 0.684 vn 0.484 0.627 0.610 vn 0.515 0.250 0.820 vn 0.360 0.121 0.925 vn -0.544 -0.573 0.613 vn 0.382 -0.114 0.917 vn 0.489 -0.108 0.866 vn -0.002 -0.670 0.742 vn 0.002 -0.394 0.919 vn -0.004 -0.168 0.986 vn 0.007 -0.109 0.994 vn 0.009 -0.519 0.855 vn 0.660 -0.118 0.742 vn 0.621 -0.127 0.774 vn 0.416 0.220 0.882 vn 0.946 0.046 0.322 vn 0.014 0.006 1.000 vn 0.569 0.184 0.802 vn 0.218 0.013 0.976 vn 0.044 0.087 0.995 vn -0.419 0.862 0.284 vn 0.647 -0.120 0.753 vn 0.954 -0.017 0.301 vn 0.352 0.140 -0.926 vn 0.095 -0.050 -0.994 vn 0.770 0.025 0.638 vn 0.000 -0.078 -0.997 vn 0.985 -0.172 0.009 vn 0.920 -0.340 0.195 vn 0.929 -0.331 -0.163 vn 0.969 -0.237 0.074 vn 0.969 -0.183 0.165 vn 0.801 0.160 0.577 vn 0.954 -0.021 0.301 vn 0.293 0.803 0.520 vn 0.977 0.170 0.129 vn 0.134 0.985 -0.104 vn 0.994 0.106 -0.036 vn 0.099 0.675 -0.731 vn 0.997 -0.079 -0.000 vn 0.197 0.126 -0.972 vn 0.978 -0.175 -0.110 vn 0.110 -0.321 -0.941 vn 0.939 -0.332 -0.089 vn 0.400 -0.789 -0.467 vn 0.171 -0.673 -0.720 vn 0.931 -0.336 -0.144 vn 0.854 -0.500 0.146 vn 0.161 -0.985 -0.069 vn 0.931 -0.304 -0.200 vn 0.813 -0.565 -0.143 vn 0.823 -0.546 0.154 vn 0.795 -0.387 0.467 vn 0.809 -0.168 0.563 vn 0.826 0.053 0.562 vn 0.925 0.261 0.275 vn 0.990 0.071 0.119 vn 0.951 0.129 0.281 vn 0.810 -0.147 0.568 vn 0.383 -0.603 0.699 vn 0.769 0.635 0.079 vn 0.786 0.352 0.508 vn 0.919 0.082 -0.386 vn 0.937 0.163 0.310 vn 0.974 -0.026 0.224 vn 0.787 0.550 0.279 vn 0.517 0.758 -0.397 vn 0.337 0.112 -0.935 vn 0.221 -0.300 -0.928 vn 0.395 -0.578 -0.714 vn 0.521 -0.711 -0.472 vn 0.432 -0.901 -0.043 vn 0.826 -0.520 0.218 vn 0.885 -0.217 0.412 vn 0.786 -0.107 0.609 vn 0.864 0.400 0.304 vn 0.954 0.061 0.293 vn 0.949 0.313 0.046 vn 0.991 0.028 -0.131 vn 0.945 -0.116 0.305 vn 0.970 -0.241 0.032 vn 0.946 -0.038 0.322 vn 0.886 -0.270 -0.376 vn 0.855 -0.272 -0.441 vn 0.952 -0.122 -0.281 vn 0.002 -0.883 0.469 vn -0.001 0.792 -0.611 vn -0.180 0.823 -0.539 vn -0.642 0.677 -0.360 vn -0.957 0.288 -0.031 vn -0.912 -0.300 0.281 vn -0.454 -0.866 0.207 vn -0.855 -0.043 0.517 vn -0.834 0.460 0.305 vn -0.242 0.911 0.334 vn -0.720 -0.667 -0.192 vn -0.762 -0.580 -0.288 vn 0.452 0.774 0.444 vn 0.857 0.048 0.513 vn 0.966 0.131 0.225 vn 0.211 0.953 0.219 vn -0.108 0.726 0.679 vn 0.021 0.946 0.324 vn 0.566 -0.691 -0.450 vn -0.068 0.939 -0.338 vn -0.261 -0.298 0.918 vn -0.200 -0.891 0.407 vn 0.124 -0.991 0.059 vn 0.913 -0.350 -0.211 vn 0.488 -0.838 0.244 vn 0.738 -0.593 0.322 vn 0.994 -0.060 -0.087 vn -0.000 -0.981 0.193 vn 0.000 0.974 0.227 vn -0.350 -0.016 0.936 vn 0.000 -0.017 1.000 vn 0.252 0.455 -0.854 vn 0.774 0.620 -0.127 vn 0.634 0.759 -0.148 vn 0.192 0.569 -0.800 vn 0.405 -0.094 0.909 vn 0.031 0.149 0.988 vn 0.360 0.283 0.889 vn 0.469 0.080 0.880 vn 0.769 0.452 0.452 vn 0.946 0.185 0.266 vn 0.893 0.181 0.413 vn 0.654 0.429 0.623 vn 0.506 0.610 0.610 vn 0.436 0.659 0.613 vn 0.160 0.558 0.814 vn -0.285 0.396 0.873 vn -0.223 0.539 0.812 vn 0.037 0.570 0.821 vn 0.623 0.727 -0.289 vn 0.456 0.738 0.497 vn 0.382 0.656 0.651 vn 0.278 0.687 0.671 vn 0.213 0.798 0.563 vn 0.171 0.844 0.508 vn 0.300 0.690 0.659 vn 0.144 0.793 0.591 vn 0.204 0.541 -0.816 vn -0.001 0.494 -0.870 vn 0.029 0.458 -0.888 vn 0.060 0.366 -0.929 vn 0.000 0.421 -0.907 vn 0.000 0.386 -0.922 vn 0.001 0.455 -0.891 vn 0.264 0.718 0.644 vn 0.307 0.317 -0.897 vn 0.056 0.164 -0.985 vn 0.717 0.079 0.693 vn 0.638 0.188 0.746 vn 0.000 0.202 -0.979 vn 0.006 -0.044 0.999 vn 0.001 0.405 0.914 vn 0.805 0.560 -0.194 vn 0.002 0.627 0.779 vn 0.010 -0.298 0.954 vn 0.124 0.870 -0.477 vn 0.488 0.530 -0.693 vn 0.566 0.756 -0.329 vn 0.213 0.932 -0.294 vn 0.245 -0.741 -0.626 vn 0.275 -0.782 -0.559 vn 0.044 -0.811 -0.584 vn -0.012 0.949 -0.315 vn 0.097 0.621 -0.778 vn 0.215 0.561 -0.799 vn -0.030 0.913 -0.407 vn 0.378 0.505 -0.776 vn 0.084 0.865 -0.495 vn 0.892 -0.451 -0.026 vn 0.803 -0.447 -0.394 vn 0.954 0.274 -0.123 vn 0.998 -0.024 0.066 vn 0.806 0.588 0.057 vn 0.351 0.936 -0.012 vn 0.662 -0.536 -0.524 vn 0.725 -0.630 -0.278 vn 0.524 -0.662 -0.536 vn 0.620 -0.585 -0.522 vn -0.694 -0.711 0.115 vn -0.621 -0.770 0.148 vn -0.805 -0.470 0.362 vn -0.819 -0.465 0.335 vn -0.680 -0.145 0.719 vn -0.763 -0.140 0.631 vn -0.840 -0.272 0.470 vn -0.773 -0.256 0.580 vn -0.763 -0.155 -0.627 vn -0.763 0.034 -0.645 vn -0.958 -0.057 -0.281 vn -0.910 -0.129 -0.393 vn -0.983 0.060 0.175 vn -0.980 0.096 0.177 vn -0.990 0.069 0.123 vn -0.996 0.023 0.083 vn -0.484 -0.649 0.587 vn -0.662 -0.717 0.220 vn -0.775 -0.388 0.499 vn -0.606 -0.384 0.697 vn -0.748 -0.556 0.363 vn -0.539 -0.840 0.071 vn -0.496 -0.849 0.183 vn -0.668 -0.580 0.467 vn -0.280 -0.913 0.296 vn -0.424 -0.897 0.125 vn -0.960 0.187 0.209 vn -0.965 0.222 0.143 vn -0.991 0.084 0.104 vn -0.979 0.104 0.175 vn -0.940 0.170 0.295 vn -0.909 0.107 0.404 vn -0.862 0.204 0.464 vn -0.896 0.204 0.395 vn -0.570 -0.493 0.658 vn -0.531 -0.465 0.709 vn -0.651 -0.181 0.737 vn -0.688 -0.376 0.620 vn -0.892 0.030 0.452 vn -0.827 0.122 0.549 vn -0.345 -0.706 0.619 vn -0.566 -0.461 0.684 vn -0.543 -0.393 0.742 vn -0.097 -0.841 0.533 vn -0.964 0.119 0.237 vn -0.950 0.158 0.268 vn -0.733 -0.024 0.679 vn -0.825 -0.117 0.552 vn -0.442 0.232 0.866 vn -0.605 0.237 0.760 vn -0.556 0.267 0.787 vn -0.350 0.172 0.921 vn -0.239 -0.096 0.966 vn -0.501 0.068 0.863 vn -0.679 0.342 0.650 vn -0.486 0.403 0.776 vn -0.211 -0.600 0.772 vn -0.123 -0.334 0.934 vn -0.052 -0.530 0.847 vn -0.176 -0.798 0.577 vn -0.131 -0.968 -0.212 vn -0.598 -0.684 -0.418 vn -0.205 -0.329 0.922 vn -0.374 -0.151 0.915 vn -0.117 -0.376 0.919 vn -0.246 -0.160 0.956 vn -0.126 -0.268 0.955 vn -0.137 -0.531 0.837 vn 0.062 -0.980 0.190 vn -0.478 -0.855 0.203 vn -0.669 -0.734 -0.114 vn -0.286 -0.955 0.083 vn -0.967 -0.136 0.215 vn -0.965 -0.005 0.263 vn -0.983 -0.085 0.164 vn -0.969 -0.182 0.170 vn -0.840 -0.358 0.408 vn -0.857 -0.341 0.386 vn -0.910 -0.256 0.326 vn -0.884 -0.284 0.371 vn 0.022 -0.449 0.893 vn -0.046 -0.611 0.791 vn -0.478 -0.294 0.827 vn -0.375 -0.338 0.863 vn -0.935 -0.243 0.259 vn -0.949 -0.164 0.269 vn -0.736 -0.207 0.645 vn -0.587 -0.108 0.802 vn 0.945 0.284 0.163 vn 0.592 -0.756 -0.279 vn 0.442 -0.866 -0.236 vn -0.053 -0.740 0.670 vn -0.228 -0.529 0.817 vn 0.170 -0.772 0.613 vn -0.609 -0.162 0.777 vn -0.663 -0.292 0.690 vn -0.713 0.145 0.686 vn -0.759 0.059 0.648 vn -0.825 0.047 0.564 vn -0.809 0.158 0.566 vn -0.637 0.025 0.770 vn -0.687 0.129 0.715 vn -0.821 -0.086 0.564 vn -0.891 -0.252 0.378 vn -0.721 0.489 0.490 vn -0.698 0.164 0.697 vn -0.646 -0.143 0.750 vn -0.712 0.352 0.608 vn -0.567 0.074 0.821 vn -0.464 0.032 0.885 vn -0.518 -0.023 0.855 vn -0.550 -0.128 0.825 vn -0.756 -0.260 0.601 vn -0.645 -0.025 0.764 vn -0.437 -0.158 0.885 vn -0.687 -0.310 0.657 vn -0.541 0.781 0.313 vn -0.565 0.780 0.270 vn -0.712 0.385 0.587 vn -0.611 0.201 0.765 vn -0.859 0.335 0.388 vn -0.775 0.474 0.417 vn -0.673 0.387 0.630 vn -0.628 0.400 0.668 vn -0.676 0.438 0.592 vn -0.698 0.309 0.646 vn -0.622 0.535 0.573 vn -0.511 0.327 0.795 vn -0.733 -0.405 -0.547 vn -0.884 -0.261 -0.388 vn -0.791 -0.366 0.490 vn -0.793 -0.344 0.502 vn -0.844 -0.347 0.408 vn -0.858 -0.453 0.243 vn -0.953 -0.280 0.116 vn -0.976 -0.193 0.100 vn -0.989 -0.113 0.096 vn -0.289 0.792 0.537 vn -0.301 0.654 0.693 vn -0.134 0.672 0.728 vn -0.137 0.821 0.554 vn -0.884 0.305 0.354 vn -0.716 0.471 0.515 vn -0.736 0.562 0.377 vn -0.897 0.355 0.265 vn -0.890 0.422 0.171 vn -0.179 0.082 0.981 vn -0.216 0.250 0.944 vn -0.661 -0.125 0.740 vn -0.679 0.371 0.633 vn -0.636 0.460 0.620 vn -0.594 0.426 0.682 vn -0.258 0.436 0.862 vn -0.070 0.240 0.968 vn -0.095 0.440 0.893 vn -0.011 0.089 0.996 vn -0.069 -0.049 0.996 vn -0.719 0.247 0.649 vn -0.673 0.172 0.719 vn -0.353 0.447 0.822 vn -0.270 0.134 0.954 vn -0.440 0.328 0.836 vn -0.511 0.490 0.706 vn -0.342 0.114 0.933 vn -0.435 -0.298 0.849 vn -0.552 0.158 0.818 vn -0.273 0.369 0.888 vn -0.705 -0.192 0.683 vn -0.357 0.088 0.930 vn -0.499 0.346 0.795 vn 0.009 0.585 0.811 vn 0.086 0.584 0.807 vn -0.348 -0.035 0.937 vn -0.516 0.299 0.803 vn -0.512 0.295 0.806 vn -0.339 0.070 0.938 vn -0.348 -0.070 0.935 vn -0.148 -0.003 0.989 vn -0.349 0.750 0.561 vn -0.322 0.418 0.849 vn -0.890 -0.163 0.425 vn -0.990 -0.001 0.144 vn -0.500 0.824 0.267 vn -0.501 0.717 0.484 vn -0.285 0.905 0.315 vn -0.282 0.954 0.103 vn -0.268 0.957 -0.114 vn -0.433 0.898 -0.078 vn -0.473 0.876 0.093 vn -0.131 0.985 0.111 vn -0.127 0.932 0.339 vn -0.211 -0.186 0.960 vn -0.293 -0.359 0.886 vn -0.344 -0.465 0.816 vn -0.382 -0.591 0.710 vn -0.525 -0.255 0.812 vn -0.598 0.089 0.796 vn -0.688 0.244 0.683 vn -0.344 -0.576 0.742 vn -0.544 -0.583 0.603 vn 0.098 -0.695 0.712 vn -0.805 -0.326 0.496 vn -0.132 0.306 0.943 vn -0.485 0.160 0.860 vn -0.351 -0.498 0.793 vn -0.141 -0.499 0.855 vn 0.065 -0.990 0.123 vn 0.037 -0.989 0.143 vn -0.065 -0.055 0.996 vn -0.473 -0.369 0.800 vn -0.396 0.179 0.900 vn -0.600 0.505 0.620 vn -0.387 0.499 0.776 vn -0.398 0.505 0.766 vn -0.358 0.488 0.796 vn -0.570 0.304 0.763 vn -0.317 0.412 0.854 vn -0.742 -0.129 0.658 vn -0.771 -0.207 0.602 vn -0.881 -0.036 0.472 vn -0.841 -0.052 0.538 vn -0.972 0.111 0.208 vn -0.961 0.151 0.230 vn -0.916 -0.004 0.402 vn -0.913 0.013 0.408 vn -0.689 0.026 0.724 vn -0.641 -0.316 0.699 vn -0.647 -0.304 0.699 vn -0.697 -0.094 0.711 vn -0.966 0.063 0.249 vn -0.963 0.075 0.259 vn -0.958 0.031 0.287 vn -0.681 -0.315 0.661 vn -0.745 -0.412 0.525 vn -0.666 -0.413 0.621 vn -0.548 -0.335 0.767 vn -0.107 -0.395 0.913 vn -0.299 -0.320 0.899 vn -0.418 -0.236 0.877 vn -0.210 -0.169 0.963 vn -0.090 0.952 0.291 vn -0.166 0.838 0.520 vn -0.523 0.797 0.302 vn -0.302 0.941 0.154 vn 0.408 -0.888 0.211 vn 0.735 0.117 0.668 vn -0.279 0.960 0.001 vn -0.468 0.706 0.531 vn -0.232 0.964 0.131 vn -0.555 -0.033 0.831 vn -0.517 0.199 0.833 vn -0.549 0.222 0.806 vn -0.376 0.125 0.918 vn -0.210 0.031 0.977 vn -0.435 -0.045 0.899 vn -0.739 0.154 0.656 vn -0.610 0.153 0.777 vn -0.663 0.041 0.748 vn -0.733 0.013 0.681 vn -0.744 -0.668 0.007 vn -0.845 -0.501 -0.187 vn -0.845 -0.522 -0.114 vn -0.774 -0.629 0.079 vn -0.897 0.040 0.440 vn -0.896 0.094 0.434 vn -0.179 0.204 -0.962 vn -0.157 0.488 -0.858 vn -0.506 0.590 0.630 vn -0.305 0.951 0.047 vn 0.267 -0.958 -0.102 vn -0.432 -0.745 0.509 vn -0.075 -0.883 0.463 vn -0.236 -0.454 0.859 vn -0.504 -0.423 0.753 vn -0.821 -0.351 0.449 vn -0.876 0.033 0.481 vn -0.934 -0.155 0.322 vn -0.134 0.983 -0.126 vn -0.128 0.916 -0.381 vn -0.284 0.891 -0.353 vn 0.055 0.396 0.917 vn 0.092 0.644 0.760 vn -0.199 0.976 -0.093 vn -0.109 0.991 -0.072 vn -0.039 0.079 0.996 vn -0.081 -0.191 0.978 vn -0.854 0.239 0.462 vn -0.774 0.223 0.593 vn -0.502 -0.119 0.856 vn -0.403 -0.420 0.813 vn -0.680 -0.255 0.687 vn -0.525 0.172 0.834 vn -0.376 -0.531 0.759 vn -0.576 -0.754 0.316 vn 0.040 0.159 0.986 vn 0.036 -0.180 0.983 vn -0.308 0.943 -0.129 vn -0.983 0.074 -0.170 vn -0.456 -0.445 0.771 vn -0.476 -0.297 0.828 vn -0.788 -0.316 0.528 vn -0.393 0.095 0.915 vn -0.308 0.018 0.951 vn -0.125 0.331 0.935 vn -0.283 0.033 0.959 vn -0.598 0.322 0.734 vn -0.575 0.559 0.598 vn -0.216 -0.852 0.476 vn 0.156 -0.927 0.342 vn -0.941 -0.282 -0.189 vn -0.739 -0.637 0.221 vn -0.469 -0.731 0.495 vn -0.458 -0.139 -0.878 vn -0.498 -0.315 -0.808 vn -0.210 -0.426 -0.880 vn -0.182 -0.243 -0.953 vn -0.334 -0.402 0.853 vn 0.221 -0.960 -0.173 vn -0.414 -0.366 0.834 vn -0.902 -0.373 -0.218 vn -0.632 -0.114 0.767 vn -0.642 0.122 0.757 vn -0.194 -0.651 0.734 vn -0.351 -0.095 0.931 vn -0.707 0.530 0.467 vn -0.087 -0.550 0.831 vn 0.352 -0.710 0.610 vn -0.500 -0.482 0.720 vn -0.653 -0.626 0.427 vn -0.856 0.328 0.399 vn -0.578 -0.029 0.816 vn 0.275 -0.432 0.859 vn -0.123 0.953 0.277 vn -0.228 0.657 0.719 vn -0.298 -0.735 0.609 vn -0.300 -0.179 0.937 vn -0.219 0.400 0.890 vn -0.587 -0.175 0.791 vn 0.175 0.460 0.870 vn -0.179 0.856 0.485 vn 0.114 0.959 0.259 vn 0.664 0.620 0.418 vn -0.026 -0.991 0.129 vn -0.184 -0.979 0.082 vn -0.810 0.566 -0.151 vn -0.628 0.654 -0.422 vn -0.741 0.405 -0.536 vn -0.924 0.322 -0.207 vn -0.493 0.823 -0.280 vn -0.648 0.758 -0.080 vn -0.966 0.258 0.022 vn -0.864 0.501 0.051 vn -0.679 0.730 0.075 vn -0.221 -0.970 0.105 vn -0.271 -0.962 -0.038 vn -0.376 -0.516 0.769 vn -0.124 0.748 -0.652 vn -0.339 0.727 -0.598 vn -0.420 0.469 -0.777 vn -0.500 -0.524 -0.690 vn -0.489 -0.481 -0.728 vn -0.206 -0.458 -0.865 vn -0.212 -0.565 -0.797 vn -0.893 -0.325 -0.312 vn -0.759 -0.435 -0.485 vn -0.796 -0.289 -0.532 vn -0.937 -0.249 -0.246 vn -0.193 -0.029 -0.981 vn -0.202 -0.249 -0.947 vn -0.814 -0.090 -0.574 vn -0.969 -0.102 -0.227 vn -0.969 0.093 -0.229 vn -0.801 0.142 -0.581 vn -0.998 0.061 -0.010 vn -0.718 0.664 0.209 vn -0.985 -0.168 0.036 vn -0.954 -0.222 -0.201 vn -0.451 0.039 0.891 vn -0.341 -0.253 0.905 vn -0.604 -0.144 0.784 vn -0.472 -0.641 0.606 vn 0.107 -0.991 0.080 vn -0.463 0.274 0.843 vn -0.002 0.997 0.081 vn 0.083 0.977 0.195 vn -0.466 0.366 0.805 vn -0.977 0.200 0.072 vn 0.916 -0.331 0.226 vn 0.929 -0.364 -0.067 vn 0.728 0.359 0.584 vn -0.419 0.737 -0.531 vn -0.638 0.769 0.043 vn -0.146 0.857 -0.494 vn 0.280 0.954 0.105 vn 0.343 0.909 -0.237 vn 0.546 0.838 -0.008 vn 0.342 -0.678 -0.651 vn -0.159 -0.734 -0.660 vn -0.545 0.363 0.756 vn -0.599 0.165 0.783 vn -0.447 0.066 0.892 vn -0.645 0.255 0.721 vn -0.936 0.164 0.311 vn -0.776 0.182 -0.604 vn -0.827 0.285 -0.485 vn -0.999 -0.012 0.041 vn -0.995 -0.037 -0.093 vn -0.586 -0.252 0.770 vn -0.926 -0.370 0.079 vn -0.938 -0.339 -0.067 vn -0.889 -0.266 0.372 vn -0.922 -0.372 -0.106 vn -0.493 -0.275 -0.825 vn -0.473 0.194 -0.860 vn -0.965 -0.122 0.231 vn -0.401 -0.036 -0.915 vn -0.143 -0.164 -0.976 vn -0.496 -0.052 -0.867 vn -0.996 -0.037 -0.083 vn -0.998 0.042 0.045 vn -0.950 0.012 0.313 vn -0.733 -0.008 0.681 vn -0.670 0.247 0.700 vn -0.408 0.697 0.589 vn -0.330 0.155 0.931 vn -0.517 0.244 0.821 vn 0.568 -0.625 0.535 vn -0.512 -0.108 0.852 vn -0.414 -0.112 0.903 vn -0.654 -0.140 0.743 vn -0.608 -0.086 0.789 vn -0.422 0.215 0.881 vn -0.943 0.031 0.332 vn -0.549 0.190 0.814 vn -0.193 0.018 0.981 vn 0.358 0.872 0.335 vn -0.651 -0.118 0.750 vn -0.954 -0.010 0.300 vn -0.352 0.145 -0.925 vn -0.095 -0.049 -0.994 vn -0.769 0.031 0.639 vn -0.929 -0.329 -0.171 vn -0.923 -0.336 0.190 vn -0.985 -0.174 0.005 vn -0.970 -0.234 0.068 vn -0.801 0.162 0.576 vn -0.969 -0.184 0.166 vn -0.293 0.803 0.519 vn -0.954 -0.019 0.300 vn -0.133 0.986 -0.105 vn -0.976 0.175 0.130 vn -0.098 0.675 -0.732 vn -0.993 0.112 -0.041 vn -0.197 0.127 -0.972 vn -0.997 -0.077 -0.003 vn -0.112 -0.322 -0.940 vn -0.978 -0.176 -0.109 vn -0.171 -0.674 -0.719 vn -0.397 -0.789 -0.468 vn -0.937 -0.337 -0.091 vn -0.929 -0.341 -0.146 vn -0.158 -0.985 -0.070 vn -0.854 -0.500 0.145 vn -0.814 -0.564 -0.141 vn -0.931 -0.306 -0.199 vn -0.824 -0.545 0.156 vn -0.797 -0.383 0.466 vn -0.811 -0.165 0.562 vn -0.824 0.053 0.564 vn -0.926 0.257 0.275 vn -0.991 0.062 0.118 vn -0.952 0.122 0.281 vn -0.383 -0.604 0.699 vn -0.810 -0.150 0.567 vn -0.784 0.355 0.509 vn -0.761 0.645 0.076 vn -0.920 0.079 -0.385 vn -0.975 -0.023 0.222 vn -0.937 0.166 0.308 vn -0.787 0.551 0.279 vn -0.517 0.758 -0.396 vn -0.337 0.112 -0.935 vn -0.221 -0.301 -0.928 vn -0.395 -0.579 -0.714 vn -0.520 -0.711 -0.473 vn -0.426 -0.904 -0.044 vn -0.824 -0.523 0.219 vn -0.886 -0.220 0.409 vn -0.863 0.404 0.303 vn -0.782 -0.104 0.615 vn -0.953 0.066 0.297 vn -0.949 0.312 0.046 vn -0.991 0.025 -0.134 vn -0.944 -0.116 0.308 vn -0.971 -0.237 0.041 vn -0.947 -0.041 0.318 vn -0.854 -0.274 -0.443 vn -0.885 -0.271 -0.378 vn -0.952 -0.121 -0.282 vn 0.180 0.824 -0.537 vn 0.642 0.679 -0.355 vn 0.956 0.291 -0.021 vn 0.453 -0.867 0.208 vn 0.910 -0.301 0.285 vn 0.854 -0.043 0.518 vn 0.833 0.459 0.308 vn 0.241 0.911 0.334 vn 0.731 -0.650 -0.206 vn 0.760 -0.585 -0.282 vn -0.814 0.019 0.580 vn -0.563 0.638 0.526 vn -0.925 -0.012 0.381 vn -0.214 0.952 0.217 vn 0.096 0.721 0.686 vn -0.027 0.945 0.325 vn -0.555 -0.678 -0.481 vn 0.062 0.937 -0.343 vn 0.240 -0.291 0.926 vn 0.184 -0.889 0.419 vn -0.126 -0.990 0.061 vn -0.889 -0.369 -0.271 vn -0.506 -0.832 0.229 vn -0.808 -0.443 0.388 vn -0.993 -0.084 0.087 vn 0.350 -0.016 0.937 vn -0.636 0.759 -0.140 vn -0.771 0.626 -0.115 vn -0.250 0.462 -0.851 vn -0.192 0.568 -0.801 vn -0.359 0.279 0.891 vn -0.026 0.144 0.989 vn -0.398 -0.100 0.912 vn -0.465 0.084 0.881 vn -0.895 0.186 0.405 vn -0.947 0.184 0.264 vn -0.761 0.459 0.458 vn -0.657 0.429 0.620 vn -0.426 0.660 0.618 vn -0.505 0.610 0.611 vn 0.223 0.536 0.814 vn 0.285 0.393 0.874 vn -0.163 0.555 0.815 vn -0.038 0.570 0.821 vn -0.628 0.723 -0.288 vn -0.458 0.737 0.497 vn -0.212 0.799 0.563 vn -0.278 0.687 0.672 vn -0.380 0.657 0.651 vn -0.170 0.846 0.506 vn -0.305 0.687 0.660 vn -0.144 0.795 0.589 vn 0.001 0.494 -0.870 vn -0.208 0.539 -0.816 vn -0.027 0.458 -0.888 vn -0.057 0.367 -0.929 vn -0.262 0.718 0.645 vn -0.054 0.163 -0.985 vn -0.306 0.325 -0.895 vn -0.643 0.181 0.744 vn -0.717 0.083 0.692 vn -0.800 0.573 -0.178 vn 0.296 -0.070 0.953 vn -0.319 -0.065 0.946 # 1258 vertex normals g head s 1 f 24/1/24 25/2/25 26/3/26 f 24/1/24 26/3/26 23/4/23 f 28/5/28 29/6/29 30/7/30 f 28/5/28 30/7/30 27/8/27 f 32/9/32 33/10/33 34/11/34 f 32/9/32 34/11/34 31/12/31 f 36/13/36 31/12/31 34/11/34 f 36/13/36 34/11/34 35/14/35 f 36/13/36 35/14/35 25/2/25 f 36/13/36 25/2/25 24/1/24 f 38/15/38 39/16/39 40/17/40 f 38/15/38 40/17/40 37/18/37 f 42/19/42 23/4/23 26/3/26 f 42/19/42 26/3/26 41/20/41 f 40/17/40 42/19/42 41/20/41 f 40/17/40 41/20/41 37/18/37 f 38/15/38 43/21/43 44/22/44 f 38/15/38 44/22/44 39/16/39 f 32/9/32 45/23/45 46/24/46 f 32/9/32 46/24/46 33/10/33 f 28/5/28 44/22/44 48/25/48 f 28/5/28 48/25/48 47/26/47 f 50/27/50 51/28/51 52/29/52 f 50/27/50 52/29/52 49/30/49 f 54/31/54 55/32/55 56/33/56 f 54/31/54 56/33/56 53/34/53 f 58/35/58 59/36/59 60/37/60 f 58/35/58 60/37/60 57/38/57 f 62/39/62 63/40/63 64/41/64 f 62/39/62 64/41/64 61/42/61 f 66/43/66 67/44/67 68/45/68 f 66/43/66 68/45/68 65/46/65 f 70/47/70 71/48/71 72/49/72 f 70/47/70 72/49/72 69/50/69 f 67/44/67 66/43/66 74/51/74 f 67/44/67 74/51/74 73/52/73 f 66/43/66 51/28/51 50/27/50 f 66/43/66 50/27/50 74/51/74 f 76/53/76 77/54/77 78/55/78 f 76/53/76 78/55/78 75/56/75 f 80/57/80 81/58/81 82/59/82 f 80/57/80 82/59/82 79/60/79 f 84/61/84 85/62/85 86/63/86 f 84/61/84 86/63/86 83/64/83 f 87/65/87 88/66/88 80/57/80 f 87/65/87 80/57/80 79/60/79 f 90/67/90 91/68/91 92/69/92 f 90/67/90 92/69/92 89/70/89 f 93/71/93 94/72/94 78/55/78 f 93/71/93 78/55/78 77/54/77 f 87/65/87 95/73/95 96/74/96 f 87/65/87 96/74/96 88/66/88 f 98/75/98 99/76/99 100/77/100 f 98/75/98 100/77/100 97/78/97 f 100/77/100 101/79/101 102/80/102 f 100/77/100 102/80/102 97/78/97 f 98/75/98 103/81/103 104/82/104 f 98/75/98 104/82/104 99/76/99 f 106/83/106 107/84/107 108/85/108 f 106/83/106 108/85/108 105/86/105 f 109/87/109 110/88/110 105/86/105 f 109/87/109 105/86/105 108/85/108 f 101/79/101 111/89/111 112/90/112 f 101/79/101 112/90/112 102/80/102 f 114/91/114 115/92/115 116/93/116 f 114/91/114 116/93/116 113/94/113 f 118/95/118 119/96/119 120/97/120 f 118/95/118 120/97/120 117/98/117 f 122/99/122 123/100/123 124/101/124 f 122/99/122 124/101/124 121/102/121 f 126/103/126 127/104/127 128/105/128 f 126/103/126 128/105/128 125/106/125 f 130/107/130 131/108/131 132/109/132 f 130/107/130 132/109/132 129/110/129 f 125/106/125 128/105/128 134/111/134 f 125/106/125 134/111/134 133/112/133 f 56/33/56 55/32/55 136/113/136 f 56/33/56 136/113/136 135/114/135 f 37/115/37 137/116/137 138/117/138 f 37/115/37 138/117/138 38/118/38 f 139/119/139 43/120/43 38/118/38 f 139/119/139 38/118/38 138/117/138 f 140/121/140 141/122/141 142/123/142 f 140/121/140 142/123/142 130/107/130 f 144/124/144 129/110/129 132/109/132 f 144/124/144 132/109/132 143/125/143 f 146/126/146 147/127/147 148/128/148 f 146/126/146 148/128/148 145/129/145 f 150/130/150 151/131/151 54/31/54 f 150/130/150 54/31/54 149/132/149 f 54/31/54 53/34/53 152/133/152 f 54/31/54 152/133/152 149/132/149 f 154/134/154 155/135/155 156/136/156 f 154/134/154 156/136/156 153/137/153 f 158/138/158 159/139/159 160/140/160 f 158/138/158 160/140/160 157/141/157 f 162/142/162 163/143/163 164/144/164 f 162/142/162 164/144/164 161/145/161 f 129/110/129 144/124/144 157/141/157 f 129/110/129 157/141/157 160/140/160 f 156/136/156 155/135/155 166/146/166 f 156/136/156 166/146/166 165/147/165 f 168/148/168 169/149/169 170/150/170 f 168/148/168 170/150/170 167/151/167 f 171/152/171 172/153/172 173/154/173 f 171/152/171 173/154/173 169/149/169 f 175/155/175 176/156/176 171/152/171 f 175/155/175 171/152/171 174/157/174 f 59/36/59 177/158/177 178/159/178 f 59/36/59 178/159/178 60/37/60 f 180/160/180 181/161/181 49/30/49 f 180/160/180 49/30/49 179/162/179 f 127/104/127 52/29/52 182/163/182 f 127/104/127 182/163/182 128/105/128 f 134/111/134 183/164/183 184/165/184 f 134/111/134 184/165/184 124/101/124 f 185/166/185 121/102/121 124/101/124 f 185/166/185 124/101/124 184/165/184 f 187/167/187 188/168/188 189/169/189 f 187/167/187 189/169/189 186/170/186 f 191/171/191 192/172/192 193/173/193 f 191/171/191 193/173/193 190/174/190 f 76/53/76 194/175/194 193/173/193 f 76/53/76 193/173/193 77/54/77 f 100/77/100 99/76/99 196/176/196 f 100/77/100 196/176/196 195/177/195 f 176/156/176 175/155/175 198/178/198 f 176/156/176 198/178/198 197/179/197 f 199/180/199 200/181/200 173/154/173 f 199/180/199 173/154/173 172/153/172 f 196/176/196 202/182/202 203/183/203 f 196/176/196 203/183/203 201/184/201 f 205/185/205 206/186/206 207/187/207 f 205/185/205 207/187/207 204/188/204 f 208/189/208 205/185/205 204/188/204 f 208/189/208 204/188/204 201/184/201 f 210/190/210 97/78/97 102/80/102 f 210/190/210 102/80/102 209/191/209 f 79/60/79 210/190/210 209/191/209 f 79/60/79 209/191/209 87/65/87 f 212/192/212 213/193/213 214/194/214 f 212/192/212 214/194/214 211/195/211 f 216/196/216 217/197/217 218/198/218 f 216/196/216 218/198/218 215/199/215 f 220/200/220 216/196/216 215/199/215 f 220/200/220 215/199/215 219/201/219 f 222/202/222 223/203/223 218/198/218 f 222/202/222 218/198/218 221/204/221 f 225/205/225 226/206/226 227/207/227 f 225/205/225 227/207/227 224/208/224 f 222/202/222 221/204/221 229/209/229 f 222/202/222 229/209/229 228/210/228 f 230/211/230 231/212/231 220/200/220 f 230/211/230 220/200/220 219/201/219 f 227/207/227 226/206/226 231/212/231 f 227/207/227 231/212/231 230/211/230 f 233/213/233 234/214/234 235/215/235 f 233/213/233 235/215/235 232/216/232 f 186/170/186 203/183/203 202/182/202 f 186/170/186 202/182/202 187/167/187 f 236/217/236 237/218/237 238/219/238 f 236/217/236 238/219/238 188/168/188 f 240/220/240 241/221/241 242/222/242 f 240/220/240 242/222/242 239/223/239 f 241/221/241 243/224/243 244/225/244 f 241/221/241 244/225/244 238/219/238 f 245/226/245 101/79/101 100/77/100 f 245/226/245 100/77/100 195/177/195 f 195/177/195 204/188/204 207/187/207 f 195/177/195 207/187/207 245/226/245 f 111/89/111 246/227/246 247/228/247 f 111/89/111 247/228/247 115/92/115 f 141/122/141 140/121/140 249/229/249 f 141/122/141 249/229/249 248/230/248 f 251/231/251 252/232/252 253/233/253 f 251/231/251 253/233/253 250/234/250 f 254/235/254 118/95/118 255/236/255 f 254/235/254 255/236/255 217/197/217 f 257/237/257 258/238/258 259/239/259 f 257/237/257 259/239/259 256/240/256 f 256/240/256 259/239/259 261/241/261 f 256/240/256 261/241/261 260/242/260 f 260/242/260 261/241/261 30/243/30 f 260/242/260 30/243/30 29/244/29 f 218/198/218 217/197/217 262/245/262 f 218/198/218 262/245/262 221/204/221 f 259/239/259 258/238/258 264/246/264 f 259/239/259 264/246/264 263/247/263 f 266/248/266 30/243/30 261/241/261 f 266/248/266 261/241/261 265/249/265 f 253/233/253 252/232/252 268/250/268 f 253/233/253 268/250/268 267/251/267 f 270/252/270 200/181/200 271/253/271 f 270/252/270 271/253/271 269/254/269 f 199/180/199 272/255/272 271/253/271 f 199/180/199 271/253/271 200/181/200 f 199/180/199 273/256/273 274/257/274 f 199/180/199 274/257/274 272/255/272 f 276/258/276 267/251/267 268/250/268 f 276/258/276 268/250/268 275/259/275 f 275/259/275 268/250/268 269/254/269 f 275/259/275 269/254/269 277/260/277 f 93/71/93 77/54/77 193/173/193 f 93/71/93 193/173/193 192/172/192 f 279/261/279 280/262/280 281/263/281 f 279/261/279 281/263/281 278/264/278 f 278/264/278 88/66/88 96/74/96 f 278/264/278 96/74/96 279/261/279 f 282/265/282 283/266/283 62/39/62 f 282/265/282 62/39/62 94/72/94 f 281/263/281 284/267/284 285/268/285 f 281/263/281 285/268/285 278/264/278 f 287/269/287 288/270/288 289/271/289 f 287/269/287 289/271/289 286/272/286 f 63/40/63 62/39/62 283/266/283 f 63/40/63 283/266/283 290/273/290 f 283/266/283 291/274/291 292/275/292 f 283/266/283 292/275/292 290/273/290 f 293/276/293 294/277/294 68/45/68 f 293/276/293 68/45/68 67/44/67 f 296/278/296 297/279/297 298/280/298 f 296/278/296 298/280/298 295/281/295 f 300/282/300 301/283/301 302/284/302 f 300/282/300 302/284/302 299/285/299 f 304/286/304 305/287/305 306/288/306 f 304/286/304 306/288/306 303/289/303 f 138/117/138 137/116/137 308/290/308 f 138/117/138 308/290/308 307/291/307 f 165/147/165 310/292/310 311/293/311 f 165/147/165 311/293/311 309/294/309 f 312/295/312 55/32/55 54/31/54 f 312/295/312 54/31/54 151/131/151 f 314/296/314 151/131/151 150/130/150 f 314/296/314 150/130/150 313/297/313 f 315/298/315 316/299/316 227/207/227 f 315/298/315 227/207/227 230/211/230 f 136/113/136 317/300/317 158/138/158 f 136/113/136 158/138/158 157/141/157 f 319/301/319 148/128/148 147/127/147 f 319/301/319 147/127/147 318/302/318 f 320/303/320 321/304/321 147/127/147 f 320/303/320 147/127/147 146/126/146 f 323/305/323 324/306/324 325/307/325 f 323/305/323 325/307/325 322/308/322 f 80/57/80 88/66/88 278/264/278 f 80/57/80 278/264/278 285/268/285 f 327/309/327 145/129/145 148/128/148 f 327/309/327 148/128/148 326/310/326 f 279/261/279 286/272/286 289/271/289 f 279/261/279 289/271/289 280/262/280 f 329/311/329 330/312/330 331/313/331 f 329/311/329 331/313/331 328/314/328 f 187/167/187 202/182/202 104/82/104 f 187/167/187 104/82/104 332/315/332 f 236/217/236 332/315/332 191/171/191 f 236/217/236 191/171/191 190/174/190 f 165/147/165 166/146/166 333/316/333 f 165/147/165 333/316/333 310/292/310 f 139/119/139 334/317/334 48/318/48 f 139/119/139 48/318/48 43/120/43 f 336/319/336 337/320/337 338/321/338 f 336/319/336 338/321/338 335/322/335 f 51/28/51 324/306/324 182/163/182 f 51/28/51 182/163/182 52/29/52 f 339/323/339 126/103/126 53/34/53 f 339/323/339 53/34/53 56/33/56 f 340/324/340 341/325/341 149/132/149 f 340/324/340 149/132/149 152/133/152 f 243/224/243 343/326/343 344/327/344 f 243/224/243 344/327/344 342/328/342 f 346/329/346 343/326/343 240/220/240 f 346/329/346 240/220/240 345/330/345 f 348/331/348 349/332/349 350/333/350 f 348/331/348 350/333/350 347/334/347 f 351/335/351 352/336/352 213/193/213 f 351/335/351 213/193/213 212/192/212 f 128/105/128 182/163/182 183/164/183 f 128/105/128 183/164/183 134/111/134 f 103/81/103 98/75/98 354/337/354 f 103/81/103 354/337/354 353/338/353 f 114/91/114 113/94/113 356/339/356 f 114/91/114 356/339/356 355/340/355 f 358/341/358 197/179/197 198/178/198 f 358/341/358 198/178/198 357/342/357 f 107/84/107 359/343/359 360/344/360 f 107/84/107 360/344/360 108/85/108 f 348/331/348 361/345/361 362/346/362 f 348/331/348 362/346/362 349/332/349 f 347/334/347 363/347/363 234/214/234 f 347/334/347 234/214/234 348/331/348 f 220/200/220 231/212/231 167/151/167 f 220/200/220 167/151/167 364/348/364 f 153/137/153 366/349/366 300/282/300 f 153/137/153 300/282/300 365/350/365 f 295/281/295 72/49/72 71/48/71 f 295/281/295 71/48/71 296/278/296 f 179/162/179 339/323/339 367/351/367 f 179/162/179 367/351/367 180/160/180 f 368/352/368 369/353/369 158/138/158 f 368/352/368 158/138/158 317/300/317 f 317/300/317 136/113/136 55/32/55 f 317/300/317 55/32/55 312/295/312 f 371/354/371 372/355/372 373/356/373 f 371/354/371 373/356/373 370/357/370 f 41/358/41 26/359/26 306/288/306 f 41/358/41 306/288/306 305/287/305 f 305/287/305 137/116/137 37/115/37 f 305/287/305 37/115/37 41/358/41 f 248/230/248 374/360/374 375/361/375 f 248/230/248 375/361/375 141/122/141 f 66/43/66 325/307/325 324/306/324 f 66/43/66 324/306/324 51/28/51 f 183/164/183 323/305/323 376/362/376 f 183/164/183 376/362/376 184/165/184 f 378/363/378 253/233/253 267/251/267 f 378/363/378 267/251/267 377/364/377 f 269/254/269 271/253/271 379/365/379 f 269/254/269 379/365/379 277/260/277 f 381/366/381 382/367/382 383/368/383 f 381/366/381 383/368/383 380/369/380 f 384/370/384 385/371/385 105/86/105 f 384/370/384 105/86/105 110/88/110 f 105/86/105 385/371/385 386/372/386 f 105/86/105 386/372/386 106/83/106 f 360/344/360 387/373/387 109/87/109 f 360/344/360 109/87/109 108/85/108 f 181/161/181 180/160/180 164/144/164 f 181/161/181 164/144/164 163/143/163 f 365/350/365 388/374/388 154/134/154 f 365/350/365 154/134/154 153/137/153 f 168/148/168 167/151/167 231/212/231 f 168/148/168 231/212/231 226/206/226 f 81/58/81 291/274/291 283/266/283 f 81/58/81 283/266/283 282/265/282 f 272/255/272 389/375/389 379/365/379 f 272/255/272 379/365/379 271/253/271 f 274/257/274 390/376/390 389/375/389 f 274/257/274 389/375/389 272/255/272 f 139/119/139 375/361/375 374/360/374 f 139/119/139 374/360/374 334/317/334 f 391/377/391 366/349/366 153/137/153 f 391/377/391 153/137/153 156/136/156 f 392/378/392 393/379/393 366/349/366 f 392/378/392 366/349/366 391/377/391 f 173/154/173 200/181/200 270/252/270 f 173/154/173 270/252/270 394/380/394 f 301/283/301 300/282/300 366/349/366 f 301/283/301 366/349/366 393/379/393 f 396/381/396 397/382/397 398/383/398 f 396/381/396 398/383/398 395/384/395 f 399/385/399 364/348/364 167/151/167 f 399/385/399 167/151/167 170/150/170 f 394/380/394 251/231/251 399/385/399 f 394/380/394 399/385/399 170/150/170 f 270/252/270 252/232/252 251/231/251 f 270/252/270 251/231/251 394/380/394 f 102/80/102 112/90/112 400/386/400 f 102/80/102 400/386/400 209/191/209 f 131/108/131 401/387/401 372/355/372 f 131/108/131 372/355/372 371/354/371 f 391/377/391 156/136/156 165/147/165 f 391/377/391 165/147/165 309/294/309 f 403/388/403 404/389/404 405/390/405 f 403/388/403 405/390/405 402/391/402 f 402/391/402 392/378/392 391/377/391 f 402/391/402 391/377/391 309/294/309 f 35/392/35 310/292/310 333/316/333 f 35/392/35 333/316/333 25/393/25 f 35/392/35 34/394/34 311/293/311 f 35/392/35 311/293/311 310/292/310 f 34/394/34 33/395/33 403/388/403 f 34/394/34 403/388/403 311/293/311 f 406/396/406 262/245/262 217/197/217 f 406/396/406 217/197/217 255/236/255 f 377/364/377 407/397/407 408/398/408 f 377/364/377 408/398/408 406/396/406 f 117/98/117 378/363/378 255/236/255 f 117/98/117 255/236/255 118/95/118 f 270/252/270 269/254/269 268/250/268 f 270/252/270 268/250/268 252/232/252 f 304/286/304 303/289/303 373/356/373 f 304/286/304 373/356/373 372/355/372 f 362/346/362 409/399/409 410/400/410 f 362/346/362 410/400/410 349/332/349 f 411/401/411 412/402/412 89/70/89 f 411/401/411 89/70/89 92/69/92 f 414/403/414 411/401/411 415/404/415 f 414/403/414 415/404/415 413/405/413 f 417/406/417 336/319/336 418/407/418 f 417/406/417 418/407/418 416/408/416 f 337/320/337 419/409/419 69/50/69 f 337/320/337 69/50/69 72/49/72 f 421/410/421 422/411/422 423/412/423 f 421/410/421 423/412/423 420/413/420 f 421/410/421 424/414/424 425/415/425 f 421/410/421 425/415/425 422/411/422 f 423/412/423 422/411/422 427/416/427 f 423/412/423 427/416/427 426/417/426 f 239/223/239 242/222/242 428/418/428 f 239/223/239 428/418/428 425/415/425 f 430/419/430 73/52/73 74/51/74 f 430/419/430 74/51/74 429/420/429 f 70/47/70 69/50/69 419/409/419 f 70/47/70 419/409/419 429/420/429 f 247/228/247 431/421/431 116/93/116 f 247/228/247 116/93/116 115/92/115 f 346/329/346 345/330/345 433/422/433 f 346/329/346 433/422/433 432/423/432 f 433/422/433 421/410/421 420/413/420 f 433/422/433 420/413/420 434/424/434 f 436/425/436 437/426/437 438/427/438 f 436/425/436 438/427/438 435/428/435 f 437/426/437 381/366/381 380/369/380 f 437/426/437 380/369/380 438/427/438 f 178/159/178 177/158/177 440/429/440 f 178/159/178 440/429/440 439/430/439 f 440/429/440 441/431/441 442/432/442 f 440/429/440 442/432/442 439/430/439 f 444/433/444 445/434/445 446/435/446 f 444/433/444 446/435/446 443/436/443 f 324/306/324 323/305/323 183/164/183 f 324/306/324 183/164/183 182/163/182 f 213/193/213 352/336/352 357/342/357 f 213/193/213 357/342/357 198/178/198 f 214/194/214 175/155/175 174/157/174 f 214/194/214 174/157/174 225/205/225 f 448/437/448 449/438/449 450/439/450 f 448/437/448 450/439/450 447/440/447 f 423/412/423 426/417/426 451/441/451 f 423/412/423 451/441/451 447/440/447 f 75/56/75 451/441/451 426/417/426 f 75/56/75 426/417/426 76/53/76 f 78/55/78 94/72/94 62/39/62 f 78/55/78 62/39/62 61/42/61 f 286/272/286 86/63/86 85/62/85 f 286/272/286 85/62/85 287/269/287 f 95/73/95 87/65/87 209/191/209 f 95/73/95 209/191/209 400/386/400 f 237/218/237 452/442/452 428/418/428 f 237/218/237 428/418/428 242/222/242 f 190/174/190 193/173/193 194/175/194 f 190/174/190 194/175/194 452/442/452 f 237/218/237 236/217/236 190/174/190 f 237/218/237 190/174/190 452/442/452 f 79/60/79 82/59/82 354/337/354 f 79/60/79 354/337/354 210/190/210 f 286/272/286 279/261/279 96/74/96 f 286/272/286 96/74/96 86/63/86 f 430/419/430 417/406/417 416/408/416 f 430/419/430 416/408/416 453/443/453 f 338/321/338 295/281/295 298/280/298 f 338/321/338 298/280/298 299/285/299 f 57/38/57 60/37/60 455/444/455 f 57/38/57 455/444/455 454/445/454 f 212/192/212 456/446/456 457/447/457 f 212/192/212 457/447/457 351/335/351 f 83/64/83 355/340/355 356/339/356 f 83/64/83 356/339/356 84/61/84 f 142/123/142 141/122/141 375/361/375 f 142/123/142 375/361/375 307/291/307 f 401/387/401 142/123/142 307/291/307 f 401/387/401 307/291/307 308/290/308 f 459/448/459 257/237/257 256/240/256 f 459/448/459 256/240/256 458/449/458 f 228/210/228 264/246/264 258/238/258 f 228/210/228 258/238/258 222/202/222 f 256/240/256 260/242/260 460/450/460 f 256/240/256 460/450/460 458/449/458 f 460/450/460 260/242/260 29/244/29 f 460/450/460 29/244/29 47/451/47 f 263/247/263 265/249/265 261/241/261 f 263/247/263 261/241/261 259/239/259 f 461/452/461 462/453/462 189/169/189 f 461/452/461 189/169/189 244/225/244 f 227/207/227 316/299/316 463/454/463 f 227/207/227 463/454/463 224/208/224 f 465/455/465 466/456/466 410/400/410 f 465/455/465 410/400/410 464/457/464 f 90/67/90 386/372/386 385/371/385 f 90/67/90 385/371/385 91/68/91 f 233/213/233 361/345/361 348/331/348 f 233/213/233 348/331/348 234/214/234 f 235/215/235 234/214/234 363/347/363 f 235/215/235 363/347/363 467/458/467 f 338/321/338 337/320/337 72/49/72 f 338/321/338 72/49/72 295/281/295 f 338/321/338 299/285/299 302/284/302 f 338/321/338 302/284/302 335/322/335 f 468/459/468 469/460/469 470/461/470 f 468/459/468 470/461/470 415/404/415 f 347/334/347 471/462/471 472/463/472 f 347/334/347 472/463/472 363/347/363 f 471/462/471 347/334/347 350/333/350 f 471/462/471 350/333/350 473/464/473 f 465/455/465 475/465/475 476/466/476 f 465/455/465 476/466/476 474/467/474 f 384/370/384 110/88/110 478/468/478 f 384/370/384 478/468/478 477/469/477 f 414/403/414 479/470/479 412/402/412 f 414/403/414 412/402/412 411/401/411 f 288/270/288 287/269/287 412/402/412 f 288/270/288 412/402/412 479/470/479 f 85/62/85 84/61/84 90/67/90 f 85/62/85 90/67/90 89/70/89 f 386/372/386 356/339/356 113/94/113 f 386/372/386 113/94/113 106/83/106 f 232/216/232 358/341/358 357/342/357 f 232/216/232 357/342/357 233/213/233 f 297/279/297 296/278/296 181/161/181 f 297/279/297 181/161/181 163/143/163 f 419/409/419 337/320/337 336/319/336 f 419/409/419 336/319/336 417/406/417 f 49/30/49 52/29/52 127/104/127 f 49/30/49 127/104/127 179/162/179 f 26/359/26 25/393/25 333/316/333 f 26/359/26 333/316/333 306/288/306 f 371/354/371 370/357/370 162/142/162 f 371/354/371 162/142/162 161/145/161 f 258/238/258 257/237/257 223/203/223 f 258/238/258 223/203/223 222/202/222 f 257/237/257 459/448/459 480/471/480 f 257/237/257 480/471/480 223/203/223 f 211/195/211 214/194/214 225/205/225 f 211/195/211 225/205/225 224/208/224 f 316/299/316 481/472/481 314/296/314 f 316/299/316 314/296/314 463/454/463 f 171/152/171 169/149/169 168/148/168 f 171/152/171 168/148/168 174/157/174 f 273/256/273 199/180/199 172/153/172 f 273/256/273 172/153/172 482/473/482 f 168/148/168 226/206/226 225/205/225 f 168/148/168 225/205/225 174/157/174 f 245/226/245 246/227/246 111/89/111 f 245/226/245 111/89/111 101/79/101 f 114/91/114 112/90/112 111/89/111 f 114/91/114 111/89/111 115/92/115 f 210/190/210 354/337/354 98/75/98 f 210/190/210 98/75/98 97/78/97 f 431/421/431 358/341/358 232/216/232 f 431/421/431 232/216/232 359/343/359 f 235/215/235 360/344/360 359/343/359 f 235/215/235 359/343/359 232/216/232 f 360/344/360 235/215/235 467/458/467 f 360/344/360 467/458/467 387/373/387 f 81/58/81 282/265/282 483/474/483 f 81/58/81 483/474/483 82/59/82 f 485/475/485 486/476/486 487/477/487 f 485/475/485 487/477/487 484/478/484 f 489/479/489 68/45/68 294/277/294 f 489/479/489 294/277/294 488/480/488 f 491/481/491 454/445/454 455/444/455 f 491/481/491 455/444/455 490/482/490 f 154/134/154 370/357/370 373/356/373 f 154/134/154 373/356/373 155/135/155 f 491/481/491 322/308/322 325/307/325 f 491/481/491 325/307/325 492/483/492 f 491/481/491 490/482/490 493/484/493 f 491/481/491 493/484/493 322/308/322 f 436/425/436 435/428/435 446/435/446 f 436/425/436 446/435/446 494/485/494 f 495/486/495 496/487/496 438/427/438 f 495/486/495 438/427/438 380/369/380 f 496/487/496 497/488/497 435/428/435 f 496/487/496 435/428/435 438/427/438 f 331/313/331 330/312/330 498/489/498 f 331/313/331 498/489/498 432/423/432 f 499/490/499 346/329/346 432/423/432 f 499/490/499 432/423/432 498/489/498 f 380/369/380 383/368/383 500/491/500 f 380/369/380 500/491/500 495/486/495 f 501/492/501 328/314/328 331/313/331 f 501/492/501 331/313/331 434/424/434 f 499/490/499 344/327/344 343/326/343 f 499/490/499 343/326/343 346/329/346 f 492/483/492 502/493/502 454/445/454 f 492/483/492 454/445/454 491/481/491 f 454/445/454 502/493/502 487/477/487 f 454/445/454 487/477/487 57/38/57 f 486/476/486 58/35/58 57/38/57 f 486/476/486 57/38/57 487/477/487 f 58/35/58 486/476/486 503/494/503 f 58/35/58 503/494/503 382/367/382 f 383/368/383 504/495/504 505/496/505 f 383/368/383 505/496/505 500/491/500 f 447/440/447 450/439/450 420/413/420 f 447/440/447 420/413/420 423/412/423 f 329/311/329 328/314/328 445/434/445 f 329/311/329 445/434/445 444/433/444 f 450/439/450 449/438/449 506/497/506 f 450/439/450 506/497/506 501/492/501 f 507/498/507 508/499/508 451/441/451 f 507/498/507 451/441/451 75/56/75 f 99/76/99 104/82/104 202/182/202 f 99/76/99 202/182/202 196/176/196 f 509/500/509 208/189/208 201/184/201 f 509/500/509 201/184/201 203/183/203 f 201/184/201 204/188/204 195/177/195 f 201/184/201 195/177/195 196/176/196 f 462/453/462 510/501/510 186/170/186 f 462/453/462 186/170/186 189/169/189 f 203/183/203 186/170/186 510/501/510 f 203/183/203 510/501/510 509/500/509 f 148/128/148 319/301/319 341/325/341 f 148/128/148 341/325/341 326/310/326 f 326/310/326 341/325/341 340/324/340 f 326/310/326 340/324/340 511/502/511 f 123/100/123 511/502/511 340/324/340 f 123/100/123 340/324/340 133/112/133 f 71/48/71 49/30/49 181/161/181 f 71/48/71 181/161/181 296/278/296 f 154/134/154 388/374/388 162/142/162 f 154/134/154 162/142/162 370/357/370 f 155/135/155 373/356/373 303/289/303 f 155/135/155 303/289/303 166/146/166 f 166/146/166 303/289/303 306/288/306 f 166/146/166 306/288/306 333/316/333 f 512/503/512 320/303/320 289/271/289 f 512/503/512 289/271/289 288/270/288 f 479/470/479 414/403/414 514/504/514 f 479/470/479 514/504/514 513/505/513 f 414/403/414 413/405/413 475/465/475 f 414/403/414 475/465/475 514/504/514 f 513/505/513 512/503/512 288/270/288 f 513/505/513 288/270/288 479/470/479 f 191/171/191 103/81/103 353/338/353 f 191/171/191 353/338/353 192/172/192 f 332/315/332 104/82/104 103/81/103 f 332/315/332 103/81/103 191/171/191 f 82/59/82 483/474/483 353/338/353 f 82/59/82 353/338/353 354/337/354 f 83/64/83 86/63/86 96/74/96 f 83/64/83 96/74/96 95/73/95 f 83/64/83 95/73/95 400/386/400 f 83/64/83 400/386/400 355/340/355 f 355/340/355 400/386/400 112/90/112 f 355/340/355 112/90/112 114/91/114 f 144/124/144 135/114/135 136/113/136 f 144/124/144 136/113/136 157/141/157 f 298/280/298 365/350/365 300/282/300 f 298/280/298 300/282/300 299/285/299 f 298/280/298 297/279/297 388/374/388 f 298/280/298 388/374/388 365/350/365 f 367/351/367 143/125/143 164/144/164 f 367/351/367 164/144/164 180/160/180 f 515/506/515 516/507/516 219/201/219 f 515/506/515 219/201/219 215/199/215 f 254/235/254 217/197/217 216/196/216 f 254/235/254 216/196/216 517/508/517 f 398/383/398 364/348/364 399/385/399 f 398/383/398 399/385/399 395/384/395 f 398/383/398 397/382/397 517/508/517 f 398/383/398 517/508/517 216/196/216 f 518/509/518 519/510/519 246/227/246 f 518/509/518 246/227/246 245/226/245 f 319/301/319 150/130/150 149/132/149 f 319/301/319 149/132/149 341/325/341 f 429/420/429 419/409/419 417/406/417 f 429/420/429 417/406/417 430/419/430 f 33/395/33 46/511/46 404/389/404 f 33/395/33 404/389/404 403/388/403 f 403/388/403 402/391/402 309/294/309 f 403/388/403 309/294/309 311/293/311 f 393/379/393 520/512/520 521/513/521 f 393/379/393 521/513/521 301/283/301 f 522/514/522 520/512/520 393/379/393 f 522/514/522 393/379/393 392/378/392 f 302/284/302 301/283/301 521/513/521 f 302/284/302 521/513/521 523/515/523 f 302/284/302 523/515/523 524/516/524 f 302/284/302 524/516/524 335/322/335 f 321/304/321 456/446/456 318/302/318 f 321/304/321 318/302/318 147/127/147 f 456/446/456 321/304/321 525/517/525 f 456/446/456 525/517/525 457/447/457 f 410/400/410 409/399/409 526/518/526 f 410/400/410 526/518/526 464/457/464 f 410/400/410 466/456/466 350/333/350 f 410/400/410 350/333/350 349/332/349 f 456/446/456 212/192/212 211/195/211 f 456/446/456 211/195/211 527/519/527 f 211/195/211 224/208/224 463/454/463 f 211/195/211 463/454/463 527/519/527 f 407/397/407 377/364/377 267/251/267 f 407/397/407 267/251/267 276/258/276 f 378/363/378 377/364/377 406/396/406 f 378/363/378 406/396/406 255/236/255 f 175/155/175 214/194/214 213/193/213 f 175/155/175 213/193/213 198/178/198 f 386/372/386 90/67/90 84/61/84 f 386/372/386 84/61/84 356/339/356 f 409/399/409 362/346/362 351/335/351 f 409/399/409 351/335/351 457/447/457 f 85/62/85 89/70/89 412/402/412 f 85/62/85 412/402/412 287/269/287 f 361/345/361 233/213/233 357/342/357 f 361/345/361 357/342/357 352/336/352 f 116/93/116 431/421/431 359/343/359 f 116/93/116 359/343/359 107/84/107 f 116/93/116 107/84/107 106/83/106 f 116/93/116 106/83/106 113/94/113 f 352/336/352 351/335/351 362/346/362 f 352/336/352 362/346/362 361/345/361 f 513/505/513 514/504/514 464/457/464 f 513/505/513 464/457/464 526/518/526 f 526/518/526 409/399/409 457/447/457 f 526/518/526 457/447/457 525/517/525 f 514/504/514 475/465/475 465/455/465 f 514/504/514 465/455/465 464/457/464 f 358/341/358 431/421/431 247/228/247 f 358/341/358 247/228/247 197/179/197 f 176/156/176 482/473/482 172/153/172 f 176/156/176 172/153/172 171/152/171 f 396/381/396 395/384/395 250/234/250 f 396/381/396 250/234/250 119/96/119 f 395/384/395 399/385/399 251/231/251 f 395/384/395 251/231/251 250/234/250 f 291/274/291 81/58/81 80/57/80 f 291/274/291 80/57/80 285/268/285 f 284/267/284 292/275/292 291/274/291 f 284/267/284 291/274/291 285/268/285 f 528/520/528 327/309/327 326/310/326 f 528/520/528 326/310/326 511/502/511 f 126/103/126 125/106/125 152/133/152 f 126/103/126 152/133/152 53/34/53 f 152/133/152 125/106/125 133/112/133 f 152/133/152 133/112/133 340/324/340 f 127/104/127 126/103/126 339/323/339 f 127/104/127 339/323/339 179/162/179 f 56/33/56 135/114/135 367/351/367 f 56/33/56 367/351/367 339/323/339 f 124/101/124 123/100/123 133/112/133 f 124/101/124 133/112/133 134/111/134 f 143/125/143 367/351/367 135/114/135 f 143/125/143 135/114/135 144/124/144 f 164/144/164 143/125/143 132/109/132 f 164/144/164 132/109/132 161/145/161 f 401/387/401 131/108/131 130/107/130 f 401/387/401 130/107/130 142/123/142 f 292/275/292 528/520/528 122/99/122 f 292/275/292 122/99/122 290/273/290 f 61/42/61 507/498/507 75/56/75 f 61/42/61 75/56/75 78/55/78 f 320/303/320 512/503/512 525/517/525 f 320/303/320 525/517/525 321/304/321 f 512/503/512 513/505/513 526/518/526 f 512/503/512 526/518/526 525/517/525 f 123/100/123 122/99/122 528/520/528 f 123/100/123 528/520/528 511/502/511 f 262/245/262 529/521/529 229/209/229 f 262/245/262 229/209/229 221/204/221 f 316/299/316 315/298/315 368/352/368 f 316/299/316 368/352/368 481/472/481 f 516/507/516 315/298/315 230/211/230 f 516/507/516 230/211/230 219/201/219 f 515/506/515 530/522/530 369/353/369 f 515/506/515 369/353/369 516/507/516 f 530/522/530 515/506/515 223/203/223 f 530/522/530 223/203/223 480/471/480 f 215/199/215 218/198/218 223/203/223 f 215/199/215 223/203/223 515/506/515 f 459/448/459 458/449/458 374/360/374 f 459/448/459 374/360/374 248/230/248 f 458/449/458 460/450/460 334/317/334 f 458/449/458 334/317/334 374/360/374 f 334/317/334 460/450/460 47/451/47 f 334/317/334 47/451/47 48/318/48 f 459/448/459 248/230/248 249/229/249 f 459/448/459 249/229/249 480/471/480 f 253/233/253 120/97/120 119/96/119 f 253/233/253 119/96/119 250/234/250 f 394/380/394 170/150/170 169/149/169 f 394/380/394 169/149/169 173/154/173 f 519/510/519 482/473/482 176/156/176 f 519/510/519 176/156/176 197/179/197 f 518/509/518 273/256/273 482/473/482 f 518/509/518 482/473/482 519/510/519 f 531/523/531 274/257/274 273/256/273 f 531/523/531 273/256/273 518/509/518 f 532/524/532 390/376/390 274/257/274 f 532/524/532 274/257/274 531/523/531 f 343/326/343 243/224/243 241/221/241 f 343/326/343 241/221/241 240/220/240 f 188/168/188 238/219/238 244/225/244 f 188/168/188 244/225/244 189/169/189 f 187/167/187 332/315/332 236/217/236 f 187/167/187 236/217/236 188/168/188 f 447/440/447 451/441/451 508/499/508 f 447/440/447 508/499/508 448/437/448 f 162/142/162 388/374/388 297/279/297 f 162/142/162 297/279/297 163/143/163 f 392/378/392 402/391/402 405/390/405 f 392/378/392 405/390/405 522/514/522 f 533/525/533 413/405/413 415/404/415 f 533/525/533 415/404/415 470/461/470 f 534/526/534 65/46/65 68/45/68 f 534/526/534 68/45/68 489/479/489 f 502/493/502 535/527/535 484/478/484 f 502/493/502 484/478/484 487/477/487 f 503/494/503 536/528/536 537/529/537 f 503/494/503 537/529/537 504/495/504 f 492/483/492 538/530/538 535/527/535 f 492/483/492 535/527/535 502/493/502 f 492/483/492 325/307/325 66/43/66 f 492/483/492 66/43/66 65/46/65 f 504/495/504 537/529/537 539/531/539 f 504/495/504 539/531/539 505/496/505 f 239/223/239 424/414/424 345/330/345 f 239/223/239 345/330/345 240/220/240 f 59/36/59 58/35/58 382/367/382 f 59/36/59 382/367/382 381/366/381 f 432/423/432 433/422/433 434/424/434 f 432/423/432 434/424/434 331/313/331 f 437/426/437 436/425/436 440/429/440 f 437/426/437 440/429/440 177/158/177 f 381/366/381 437/426/437 177/158/177 f 381/366/381 177/158/177 59/36/59 f 449/438/449 441/431/441 494/485/494 f 449/438/449 494/485/494 506/497/506 f 450/439/450 501/492/501 434/424/434 f 450/439/450 434/424/434 420/413/420 f 382/367/382 503/494/503 504/495/504 f 382/367/382 504/495/504 383/368/383 f 501/492/501 506/497/506 445/434/445 f 501/492/501 445/434/445 328/314/328 f 536/528/536 503/494/503 486/476/486 f 536/528/536 486/476/486 485/475/485 f 313/297/313 150/130/150 319/301/319 f 313/297/313 319/301/319 318/302/318 f 327/309/327 284/267/284 281/263/281 f 327/309/327 281/263/281 145/129/145 f 483/474/483 93/71/93 192/172/192 f 483/474/483 192/172/192 353/338/353 f 483/474/483 282/265/282 94/72/94 f 483/474/483 94/72/94 93/71/93 f 422/411/422 425/415/425 428/418/428 f 422/411/422 428/418/428 427/416/427 f 421/410/421 433/422/433 345/330/345 f 421/410/421 345/330/345 424/414/424 f 463/454/463 314/296/314 313/297/313 f 463/454/463 313/297/313 527/519/527 f 315/298/315 516/507/516 369/353/369 f 315/298/315 369/353/369 368/352/368 f 314/296/314 481/472/481 312/295/312 f 314/296/314 312/295/312 151/131/151 f 368/352/368 317/300/317 312/295/312 f 368/352/368 312/295/312 481/472/481 f 369/353/369 530/522/530 159/139/159 f 369/353/369 159/139/159 158/138/158 f 480/471/480 249/229/249 159/139/159 f 480/471/480 159/139/159 530/522/530 f 262/245/262 406/396/406 408/398/408 f 262/245/262 408/398/408 529/521/529 f 398/383/398 216/196/216 220/200/220 f 398/383/398 220/200/220 364/348/364 f 541/532/541 542/533/542 543/534/543 f 541/532/541 543/534/543 540/535/540 f 545/536/545 543/534/543 542/533/542 f 545/536/545 542/533/542 544/537/544 f 547/538/547 545/536/545 544/537/544 f 547/538/547 544/537/544 546/539/546 f 549/540/549 547/538/547 546/539/546 f 549/540/549 546/539/546 548/541/548 f 551/542/551 549/540/549 548/541/548 f 551/542/551 548/541/548 550/543/550 f 553/544/553 551/542/551 550/543/550 f 553/544/553 550/543/550 552/545/552 f 555/546/555 553/544/553 552/545/552 f 555/546/555 552/545/552 554/547/554 f 557/548/557 558/549/558 559/550/559 f 557/548/557 559/550/559 556/551/556 f 561/552/561 557/548/557 556/551/556 f 561/552/561 556/551/556 560/553/560 f 563/554/563 546/539/546 544/537/544 f 563/554/563 544/537/544 562/555/562 f 564/556/564 548/541/548 546/539/546 f 564/556/564 546/539/546 563/554/563 f 565/557/565 550/543/550 548/541/548 f 565/557/565 548/541/548 564/556/564 f 566/558/566 552/545/552 550/543/550 f 566/558/566 550/543/550 565/557/565 f 552/545/552 566/558/566 567/559/567 f 552/545/552 567/559/567 554/547/554 f 559/550/559 568/560/568 569/561/569 f 559/550/559 569/561/569 556/551/556 f 570/562/570 560/553/560 556/551/556 f 570/562/570 556/551/556 569/561/569 f 571/563/571 572/564/572 560/553/560 f 571/563/571 560/553/560 570/562/570 f 574/565/574 540/535/540 575/566/575 f 574/565/574 575/566/575 573/567/573 f 577/568/577 543/534/543 545/536/545 f 577/568/577 545/536/545 576/569/576 f 545/536/545 547/538/547 578/570/578 f 545/536/545 578/570/578 576/569/576 f 579/571/579 578/570/578 547/538/547 f 579/571/579 547/538/547 549/540/549 f 580/572/580 579/571/579 551/542/551 f 580/572/580 551/542/551 553/544/553 f 580/572/580 553/544/553 555/546/555 f 580/572/580 555/546/555 581/573/581 f 558/549/558 557/548/557 583/574/583 f 558/549/558 583/574/583 582/575/582 f 561/552/561 584/576/584 583/574/583 f 561/552/561 583/574/583 557/548/557 f 561/552/561 572/564/572 585/577/585 f 561/552/561 585/577/585 584/576/584 f 571/563/571 586/578/586 585/577/585 f 571/563/571 585/577/585 572/564/572 f 544/537/544 542/533/542 541/532/541 f 544/537/544 541/532/541 562/555/562 f 574/565/574 588/579/588 589/580/589 f 574/565/574 589/580/589 587/581/587 f 574/565/574 573/567/573 590/582/590 f 574/565/574 590/582/590 588/579/588 f 590/582/590 573/567/573 575/566/575 f 590/582/590 575/566/575 591/583/591 f 575/566/575 540/535/540 543/534/543 f 575/566/575 543/534/543 591/583/591 f 564/556/564 592/584/592 566/558/566 f 564/556/564 566/558/566 565/557/565 f 592/584/592 593/585/593 567/559/567 f 592/584/592 567/559/567 566/558/566 f 568/560/568 559/550/559 554/547/554 f 568/560/568 554/547/554 567/559/567 f 554/547/554 559/550/559 558/549/558 f 554/547/554 558/549/558 555/546/555 f 582/575/582 581/573/581 555/546/555 f 582/575/582 555/546/555 558/549/558 f 592/584/592 564/556/564 563/554/563 f 592/584/592 563/554/563 562/555/562 f 589/580/589 568/560/568 567/559/567 f 589/580/589 567/559/567 593/585/593 f 540/535/540 574/565/574 587/581/587 f 540/535/540 587/581/587 541/532/541 f 571/563/571 570/562/570 590/582/590 f 571/563/571 590/582/590 591/583/591 f 589/580/589 588/579/588 569/561/569 f 589/580/589 569/561/569 568/560/568 f 543/534/543 577/568/577 594/586/594 f 543/534/543 594/586/594 591/583/591 f 594/586/594 586/578/586 571/563/571 f 594/586/594 571/563/571 591/583/591 f 596/587/596 581/573/581 582/575/582 f 596/587/596 582/575/582 595/588/595 f 596/587/596 597/589/597 580/572/580 f 596/587/596 580/572/580 581/573/581 f 583/574/583 490/482/490 455/444/455 f 583/574/583 455/444/455 595/588/595 f 583/574/583 584/576/584 493/484/493 f 583/574/583 493/484/493 490/482/490 f 597/589/597 508/499/508 579/571/579 f 597/589/597 579/571/579 580/572/580 f 442/432/442 448/437/448 508/499/508 f 442/432/442 508/499/508 597/589/597 f 60/37/60 178/159/178 595/588/595 f 60/37/60 595/588/595 455/444/455 f 178/159/178 439/430/439 596/587/596 f 178/159/178 596/587/596 595/588/595 f 577/568/577 64/41/64 185/166/185 f 577/568/577 185/166/185 594/586/594 f 586/578/586 184/165/184 376/362/376 f 586/578/586 376/362/376 585/577/585 f 590/582/590 570/562/570 569/561/569 f 590/582/590 569/561/569 588/579/588 f 61/42/61 576/569/576 578/570/578 f 61/42/61 578/570/578 507/498/507 f 585/577/585 376/362/376 493/484/493 f 585/577/585 493/484/493 584/576/584 f 453/443/453 598/590/598 73/52/73 f 453/443/453 73/52/73 430/419/430 f 519/510/519 197/179/197 247/228/247 f 519/510/519 247/228/247 246/227/246 f 281/263/281 280/262/280 146/126/146 f 281/263/281 146/126/146 145/129/145 f 64/41/64 63/40/63 121/102/121 f 64/41/64 121/102/121 185/166/185 f 284/267/284 327/309/327 528/520/528 f 284/267/284 528/520/528 292/275/292 f 290/273/290 122/99/122 121/102/121 f 290/273/290 121/102/121 63/40/63 f 280/262/280 289/271/289 320/303/320 f 280/262/280 320/303/320 146/126/146 f 184/165/184 586/578/586 594/586/594 f 184/165/184 594/586/594 185/166/185 f 253/233/253 378/363/378 117/98/117 f 253/233/253 117/98/117 120/97/120 f 249/229/249 140/121/140 160/140/160 f 249/229/249 160/140/160 159/139/159 f 129/110/129 160/140/160 140/121/140 f 129/110/129 140/121/140 130/107/130 f 161/145/161 132/109/132 131/108/131 f 161/145/161 131/108/131 371/354/371 f 313/297/313 318/302/318 456/446/456 f 313/297/313 456/446/456 527/519/527 f 492/483/492 65/46/65 534/526/534 f 492/483/492 534/526/534 538/530/538 f 441/431/441 449/438/449 448/437/448 f 441/431/441 448/437/448 442/432/442 f 443/436/443 446/435/446 435/428/435 f 443/436/443 435/428/435 497/488/497 f 446/435/446 445/434/445 506/497/506 f 446/435/446 506/497/506 494/485/494 f 441/431/441 440/429/440 436/425/436 f 441/431/441 436/425/436 494/485/494 f 596/587/596 439/430/439 442/432/442 f 596/587/596 442/432/442 597/589/597 f 577/568/577 576/569/576 61/42/61 f 577/568/577 61/42/61 64/41/64 f 238/219/238 237/218/237 242/222/242 f 238/219/238 242/222/242 241/221/241 f 194/175/194 76/53/76 426/417/426 f 194/175/194 426/417/426 427/416/427 f 452/442/452 194/175/194 427/416/427 f 452/442/452 427/416/427 428/418/428 f 461/452/461 244/225/244 243/224/243 f 461/452/461 243/224/243 342/328/342 f 508/499/508 507/498/507 578/570/578 f 508/499/508 578/570/578 579/571/579 f 245/226/245 207/187/207 531/523/531 f 245/226/245 531/523/531 518/509/518 f 206/186/206 532/524/532 531/523/531 f 206/186/206 531/523/531 207/187/207 f 32/9/32 31/12/31 600/591/600 f 32/9/32 600/591/600 599/592/599 f 601/593/601 600/591/600 36/13/36 f 601/593/601 36/13/36 24/1/24 f 602/594/602 601/593/601 24/1/24 f 602/594/602 24/1/24 23/4/23 f 40/17/40 602/594/602 23/4/23 f 40/17/40 23/4/23 42/19/42 f 44/22/44 604/595/604 605/596/605 f 44/22/44 605/596/605 603/597/603 f 39/16/39 603/597/603 602/594/602 f 39/16/39 602/594/602 40/17/40 f 601/593/601 606/598/606 607/599/607 f 601/593/601 607/599/607 600/591/600 f 468/459/468 608/600/608 609/601/609 f 468/459/468 609/601/609 469/460/469 f 477/469/477 609/601/609 608/600/608 f 477/469/477 608/600/608 384/370/384 f 610/602/610 611/603/611 612/604/612 f 610/602/610 612/604/612 472/605/472 f 610/602/610 472/605/472 471/606/471 f 610/602/610 471/606/471 613/607/613 f 476/608/476 614/609/614 615/610/615 f 476/608/476 615/610/615 474/611/474 f 478/468/478 110/88/110 109/87/109 f 478/468/478 109/87/109 616/612/616 f 466/456/466 465/455/465 474/467/474 f 466/456/466 474/467/474 617/613/617 f 466/456/466 617/613/617 473/464/473 f 466/456/466 473/464/473 350/333/350 f 614/609/614 533/614/533 470/615/470 f 614/609/614 470/615/470 618/616/618 f 475/465/475 413/405/413 533/525/533 f 475/465/475 533/525/533 476/466/476 f 618/616/618 469/617/469 609/618/609 f 618/616/618 609/618/609 619/619/619 f 619/619/619 609/618/609 477/620/477 f 619/619/619 477/620/477 620/621/620 f 387/373/387 621/622/621 616/612/616 f 387/373/387 616/612/616 109/87/109 f 616/623/616 622/624/622 620/621/620 f 616/623/616 620/621/620 478/625/478 f 473/626/473 617/627/617 615/610/615 f 473/626/473 615/610/615 613/607/613 f 621/628/621 623/629/623 622/624/622 f 621/628/621 622/624/622 616/623/616 f 624/630/624 612/604/612 611/603/611 f 624/630/624 611/603/611 623/629/623 f 49/30/49 71/48/71 70/47/70 f 49/30/49 70/47/70 50/27/50 f 336/319/336 335/322/335 524/516/524 f 336/319/336 524/516/524 418/407/418 f 598/590/598 293/276/293 67/44/67 f 598/590/598 67/44/67 73/52/73 f 50/27/50 70/47/70 429/420/429 f 50/27/50 429/420/429 74/51/74 f 322/308/322 493/484/493 376/362/376 f 322/308/322 376/362/376 323/305/323 f 589/580/589 593/585/593 592/584/592 f 589/580/589 592/584/592 587/581/587 f 396/381/396 119/96/119 118/95/118 f 396/381/396 118/95/118 254/235/254 f 517/508/517 397/382/397 396/381/396 f 517/508/517 396/381/396 254/235/254 f 28/5/28 27/8/27 625/631/625 f 28/5/28 625/631/625 604/595/604 f 600/591/600 607/599/607 626/632/626 f 600/591/600 626/632/626 599/592/599 f 607/599/607 627/633/627 628/634/628 f 607/599/607 628/634/628 626/632/626 f 604/595/604 625/631/625 628/634/628 f 604/595/604 628/634/628 627/633/627 f 630/635/630 631/636/631 632/637/632 f 630/635/630 632/637/632 629/638/629 f 634/639/634 635/640/635 636/641/636 f 634/639/634 636/641/636 633/642/633 f 638/643/638 639/644/639 640/645/640 f 638/643/638 640/645/640 637/646/637 f 641/647/641 642/648/642 637/646/637 f 641/647/641 637/646/637 640/645/640 f 644/649/644 645/650/645 646/651/646 f 644/649/644 646/651/646 643/652/643 f 631/636/631 642/648/642 648/653/648 f 631/636/631 648/653/648 647/654/647 f 650/655/650 651/656/651 652/657/652 f 650/655/650 652/657/652 649/658/649 f 643/652/643 646/651/646 654/659/654 f 643/652/643 654/659/654 653/660/653 f 654/659/654 651/656/651 650/655/650 f 654/659/654 650/655/650 653/660/653 f 655/661/655 656/662/656 657/663/657 f 655/661/655 657/663/657 632/637/632 f 657/663/657 659/664/659 660/665/660 f 657/663/657 660/665/660 658/666/658 f 661/667/661 659/664/659 657/663/657 f 661/667/661 657/663/657 656/662/656 f 631/636/631 647/654/647 655/661/655 f 631/636/631 655/661/655 632/637/632 f 637/646/637 642/648/642 631/636/631 f 637/646/637 631/636/631 630/635/630 f 640/645/640 650/655/650 649/658/649 f 640/645/640 649/658/649 641/647/641 f 652/657/652 662/668/662 641/647/641 f 652/657/652 641/647/641 649/658/649 f 648/653/648 642/648/642 641/647/641 f 648/653/648 641/647/641 662/668/662 f 663/669/663 664/670/664 537/529/537 f 663/669/663 537/529/537 536/528/536 f 666/671/666 640/645/640 639/644/639 f 666/671/666 639/644/639 665/672/665 f 666/671/666 665/672/665 636/641/636 f 666/671/666 636/641/636 635/640/635 f 667/673/667 539/531/539 537/529/537 f 667/673/667 537/529/537 664/670/664 f 634/639/634 644/649/644 643/652/643 f 634/639/634 643/652/643 635/640/635 f 653/660/653 650/655/650 640/645/640 f 653/660/653 640/645/640 666/671/666 f 666/671/666 635/640/635 643/652/643 f 666/671/666 643/652/643 653/660/653 f 669/674/669 644/649/644 634/639/634 f 669/674/669 634/639/634 668/675/668 f 638/643/638 637/646/637 630/635/630 f 638/643/638 630/635/630 670/676/670 f 645/650/645 644/649/644 669/674/669 f 645/650/645 669/674/669 671/677/671 f 638/643/638 670/676/670 485/475/485 f 638/643/638 485/475/485 484/478/484 f 672/678/672 633/642/633 489/479/489 f 672/678/672 489/479/489 488/480/488 f 632/637/632 657/663/657 658/666/658 f 632/637/632 658/666/658 629/638/629 f 670/676/670 663/669/663 536/528/536 f 670/676/670 536/528/536 485/475/485 f 633/642/633 636/641/636 534/526/534 f 633/642/633 534/526/534 489/479/489 f 484/478/484 535/527/535 639/644/639 f 484/478/484 639/644/639 638/643/638 f 629/638/629 658/666/658 664/670/664 f 629/638/629 664/670/664 663/669/663 f 665/672/665 639/644/639 535/527/535 f 665/672/665 535/527/535 538/530/538 f 636/641/636 665/672/665 538/530/538 f 636/641/636 538/530/538 534/526/534 f 660/665/660 667/673/667 664/670/664 f 660/665/660 664/670/664 658/666/658 f 668/675/668 634/639/634 633/642/633 f 668/675/668 633/642/633 672/678/672 f 630/635/630 629/638/629 663/669/663 f 630/635/630 663/669/663 670/676/670 f 1/679/1 661/667/661 656/662/656 f 1/679/1 656/662/656 22/680/22 f 20/681/20 647/654/647 648/653/648 f 20/681/20 648/653/648 18/682/18 f 647/654/647 20/681/20 21/683/21 f 647/654/647 21/683/21 655/661/655 f 15/684/15 646/651/646 645/650/645 f 15/684/15 645/650/645 13/685/13 f 19/686/19 651/656/651 654/659/654 f 19/686/19 654/659/654 14/687/14 f 648/653/648 662/668/662 16/688/16 f 648/653/648 16/688/16 18/682/18 f 17/689/17 652/657/652 651/656/651 f 17/689/17 651/656/651 19/686/19 f 21/683/21 22/680/22 656/662/656 f 21/683/21 656/662/656 655/661/655 f 13/685/13 645/650/645 671/677/671 f 13/685/13 671/677/671 2/690/2 f 646/651/646 15/684/15 14/687/14 f 646/651/646 14/687/14 654/659/654 f 17/689/17 16/688/16 662/668/662 f 17/689/17 662/668/662 652/657/652 f 608/600/608 91/68/91 385/371/385 f 608/600/608 385/371/385 384/370/384 f 304/286/304 372/355/372 401/387/401 f 304/286/304 401/387/401 308/290/308 f 468/459/468 415/404/415 411/401/411 f 468/459/468 411/401/411 92/69/92 f 602/594/602 603/597/603 606/598/606 f 602/594/602 606/598/606 601/593/601 f 608/600/608 468/459/468 92/69/92 f 608/600/608 92/69/92 91/68/91 f 305/287/305 304/286/304 308/290/308 f 305/287/305 308/290/308 137/116/137 f 139/119/139 138/117/138 307/291/307 f 139/119/139 307/291/307 375/361/375 f 674/691/674 675/692/675 676/693/676 f 674/691/674 676/693/676 673/694/673 f 678/695/678 27/8/27 679/696/679 f 678/695/678 679/696/679 677/697/677 f 681/698/681 682/699/682 683/700/683 f 681/698/681 683/700/683 680/701/680 f 684/702/684 685/703/685 683/700/683 f 684/702/684 683/700/683 682/699/682 f 684/702/684 674/691/674 673/694/673 f 684/702/684 673/694/673 685/703/685 f 687/704/687 688/705/688 689/706/689 f 687/704/687 689/706/689 686/707/686 f 690/708/690 691/709/691 676/693/676 f 690/708/690 676/693/676 675/692/675 f 689/706/689 688/705/688 691/709/691 f 689/706/689 691/709/691 690/708/690 f 687/704/687 686/707/686 693/710/693 f 687/704/687 693/710/693 692/711/692 f 681/698/681 680/701/680 46/24/46 f 681/698/681 46/24/46 45/23/45 f 678/695/678 694/712/694 695/713/695 f 678/695/678 695/713/695 693/710/693 f 697/714/697 698/715/698 699/716/699 f 697/714/697 699/716/699 696/717/696 f 701/718/701 702/719/702 703/720/703 f 701/718/701 703/720/703 700/721/700 f 705/722/705 706/723/706 707/724/707 f 705/722/705 707/724/707 704/725/704 f 709/726/709 710/727/710 711/728/711 f 709/726/709 711/728/711 708/729/708 f 713/730/713 714/731/714 715/732/715 f 713/730/713 715/732/715 712/733/712 f 717/734/717 718/735/718 719/736/719 f 717/734/717 719/736/719 716/737/716 f 712/733/712 720/738/720 721/739/721 f 712/733/712 721/739/721 713/730/713 f 713/730/713 721/739/721 697/714/697 f 713/730/713 697/714/697 696/717/696 f 723/740/723 724/741/724 725/742/725 f 723/740/723 725/742/725 722/743/722 f 727/744/727 728/745/728 729/746/729 f 727/744/727 729/746/729 726/747/726 f 731/748/731 732/749/732 733/750/733 f 731/748/731 733/750/733 730/751/730 f 735/752/735 728/745/728 727/744/727 f 735/752/735 727/744/727 734/753/734 f 737/754/737 738/755/738 739/756/739 f 737/754/737 739/756/739 736/757/736 f 741/758/741 722/743/722 725/742/725 f 741/758/741 725/742/725 740/759/740 f 735/752/735 734/753/734 743/760/743 f 735/752/735 743/760/743 742/761/742 f 745/762/745 746/763/746 747/764/747 f 745/762/745 747/764/747 744/765/744 f 747/764/747 746/763/746 749/766/749 f 747/764/747 749/766/749 748/767/748 f 745/762/745 744/765/744 751/768/751 f 745/762/745 751/768/751 750/769/750 f 753/770/753 754/771/754 755/772/755 f 753/770/753 755/772/755 752/773/752 f 757/774/757 755/772/755 754/771/754 f 757/774/757 754/771/754 756/775/756 f 748/767/748 749/766/749 759/776/759 f 748/767/748 759/776/759 758/777/758 f 761/778/761 762/779/762 763/780/763 f 761/778/761 763/780/763 760/781/760 f 765/782/765 766/783/766 767/784/767 f 765/782/765 767/784/767 764/785/764 f 769/786/769 770/787/770 771/788/771 f 769/786/769 771/788/771 768/789/768 f 773/790/773 774/791/774 775/792/775 f 773/790/773 775/792/775 772/793/772 f 777/794/777 778/795/778 779/796/779 f 777/794/777 779/796/779 776/797/776 f 774/791/774 780/798/780 781/799/781 f 774/791/774 781/799/781 775/792/775 f 703/720/703 782/800/782 783/801/783 f 703/720/703 783/801/783 700/721/700 f 688/802/688 687/803/687 785/804/785 f 688/802/688 785/804/785 784/805/784 f 786/806/786 785/804/785 687/803/687 f 786/806/786 687/803/687 692/807/692 f 788/808/788 777/794/777 789/809/789 f 788/808/788 789/809/789 787/810/787 f 790/811/790 791/812/791 779/796/779 f 790/811/790 779/796/779 778/795/778 f 793/813/793 794/814/794 795/815/795 f 793/813/793 795/815/795 792/816/792 f 797/817/797 798/818/798 701/718/701 f 797/817/797 701/718/701 796/819/796 f 701/718/701 798/818/798 799/820/799 f 701/718/701 799/820/799 702/719/702 f 801/821/801 802/822/802 803/823/803 f 801/821/801 803/823/803 800/824/800 f 805/825/805 806/826/806 807/827/807 f 805/825/805 807/827/807 804/828/804 f 809/829/809 810/830/810 811/831/811 f 809/829/809 811/831/811 808/832/808 f 778/795/778 807/827/807 806/826/806 f 778/795/778 806/826/806 790/811/790 f 803/823/803 812/833/812 813/834/813 f 803/823/803 813/834/813 800/824/800 f 815/835/815 816/836/816 817/837/817 f 815/835/815 817/837/817 814/838/814 f 819/839/819 814/838/814 820/840/820 f 819/839/819 820/840/820 818/841/818 f 822/842/822 823/843/823 819/839/819 f 822/842/822 819/839/819 821/844/821 f 704/725/704 707/724/707 825/845/825 f 704/725/704 825/845/825 824/846/824 f 827/847/827 828/848/828 698/715/698 f 827/847/827 698/715/698 826/849/826 f 772/793/772 775/792/775 829/850/829 f 772/793/772 829/850/829 699/716/699 f 781/799/781 771/788/771 831/851/831 f 781/799/781 831/851/831 830/852/830 f 832/853/832 831/851/831 771/788/771 f 832/853/832 771/788/771 770/787/770 f 834/854/834 835/855/835 836/856/836 f 834/854/834 836/856/836 833/857/833 f 838/858/838 839/859/839 840/860/840 f 838/858/838 840/860/840 837/861/837 f 723/740/723 722/743/722 840/860/840 f 723/740/723 840/860/840 841/862/841 f 747/764/747 842/863/842 843/864/843 f 747/764/747 843/864/843 744/765/744 f 821/844/821 844/865/844 845/866/845 f 821/844/821 845/866/845 822/842/822 f 847/867/847 818/841/818 820/840/820 f 847/867/847 820/840/820 846/868/846 f 843/864/843 849/869/849 850/870/850 f 843/864/843 850/870/850 848/871/848 f 205/185/205 851/872/851 852/873/852 f 205/185/205 852/873/852 206/186/206 f 208/189/208 849/869/849 851/872/851 f 208/189/208 851/872/851 205/185/205 f 853/874/853 854/875/854 749/766/749 f 853/874/853 749/766/749 746/763/746 f 728/745/728 735/752/735 854/875/854 f 728/745/728 854/875/854 853/874/853 f 856/876/856 857/877/857 858/878/858 f 856/876/856 858/878/858 855/879/855 f 860/880/860 861/881/861 862/882/862 f 860/880/860 862/882/862 859/883/859 f 863/884/863 864/885/864 861/881/861 f 863/884/863 861/881/861 860/880/860 f 866/886/866 867/887/867 862/882/862 f 866/886/866 862/882/862 865/888/865 f 869/889/869 870/890/870 871/891/871 f 869/889/869 871/891/871 868/892/868 f 866/886/866 228/210/228 229/209/229 f 866/886/866 229/209/229 867/887/867 f 873/893/873 864/885/864 863/884/863 f 873/893/873 863/884/863 872/894/872 f 871/891/871 873/893/873 872/894/872 f 871/891/871 872/894/872 868/892/868 f 875/895/875 876/896/876 877/897/877 f 875/895/875 877/897/877 874/898/874 f 835/855/835 834/854/834 848/871/848 f 835/855/835 848/871/848 850/870/850 f 879/899/879 833/857/833 880/900/880 f 879/899/879 880/900/880 878/901/878 f 882/902/882 883/903/883 884/904/884 f 882/902/882 884/904/884 881/905/881 f 881/905/881 880/900/880 886/906/886 f 881/905/881 886/906/886 885/907/885 f 887/908/887 842/863/842 747/764/747 f 887/908/887 747/764/747 748/767/748 f 842/863/842 887/908/887 852/873/852 f 842/863/842 852/873/852 851/872/851 f 758/777/758 760/781/760 889/909/889 f 758/777/758 889/909/889 888/910/888 f 787/810/787 890/911/890 891/912/891 f 787/810/787 891/912/891 788/808/788 f 893/913/893 894/914/894 895/915/895 f 893/913/893 895/915/895 892/916/892 f 896/917/896 859/883/859 897/918/897 f 896/917/896 897/918/897 765/782/765 f 899/919/899 900/920/900 901/921/901 f 899/919/899 901/921/901 898/922/898 f 900/920/900 902/923/902 903/924/903 f 900/920/900 903/924/903 901/921/901 f 902/923/902 677/925/677 679/926/679 f 902/923/902 679/926/679 903/924/903 f 862/882/862 867/887/867 904/927/904 f 862/882/862 904/927/904 859/883/859 f 901/921/901 263/247/263 264/246/264 f 901/921/901 264/246/264 898/922/898 f 266/248/266 265/249/265 903/924/903 f 266/248/266 903/924/903 679/926/679 f 895/915/895 905/928/905 906/929/906 f 895/915/895 906/929/906 892/916/892 f 907/930/907 908/931/908 909/932/909 f 907/930/907 909/932/909 846/868/846 f 847/867/847 846/868/846 909/932/909 f 847/867/847 909/932/909 910/933/910 f 847/867/847 910/933/910 912/934/912 f 847/867/847 912/934/912 911/935/911 f 276/258/276 275/259/275 906/929/906 f 276/258/276 906/929/906 905/928/905 f 275/259/275 277/260/277 908/931/908 f 275/259/275 908/931/908 906/929/906 f 741/758/741 837/861/837 840/860/840 f 741/758/741 840/860/840 722/743/722 f 914/936/914 915/937/915 916/938/916 f 914/936/914 916/938/916 913/939/913 f 915/937/915 914/936/914 743/760/743 f 915/937/915 743/760/743 734/753/734 f 918/940/918 740/759/740 709/726/709 f 918/940/918 709/726/709 917/941/917 f 916/938/916 915/937/915 920/942/920 f 916/938/916 920/942/920 919/943/919 f 922/944/922 923/945/923 924/946/924 f 922/944/922 924/946/924 921/947/921 f 708/729/708 925/948/925 917/941/917 f 708/729/708 917/941/917 709/726/709 f 917/941/917 925/948/925 927/949/927 f 917/941/917 927/949/927 926/950/926 f 293/276/293 712/733/712 715/732/715 f 293/276/293 715/732/715 294/277/294 f 929/951/929 930/952/930 931/953/931 f 929/951/929 931/953/931 928/954/928 f 933/955/933 934/956/934 935/957/935 f 933/955/933 935/957/935 932/958/932 f 937/959/937 938/960/938 939/961/939 f 937/959/937 939/961/939 936/962/936 f 785/804/785 940/963/940 941/964/941 f 785/804/785 941/964/941 784/805/784 f 812/833/812 943/965/943 944/966/944 f 812/833/812 944/966/944 942/967/942 f 945/968/945 796/819/796 701/718/701 f 945/968/945 701/718/701 700/721/700 f 946/969/946 947/970/947 797/817/797 f 946/969/946 797/817/797 796/819/796 f 949/971/949 873/893/873 871/891/871 f 949/971/949 871/891/871 948/972/948 f 783/801/783 806/826/806 805/825/805 f 783/801/783 805/825/805 950/973/950 f 951/974/951 952/975/952 792/816/792 f 951/974/951 792/816/792 795/815/795 f 954/976/954 793/813/793 792/816/792 f 954/976/954 792/816/792 953/977/953 f 956/978/956 957/979/957 958/980/958 f 956/978/956 958/980/958 955/981/955 f 727/744/727 920/942/920 915/937/915 f 727/744/727 915/937/915 734/753/734 f 959/982/959 960/983/960 795/815/795 f 959/982/959 795/815/795 794/814/794 f 914/936/914 913/939/913 924/946/924 f 914/936/914 924/946/924 923/945/923 f 329/984/329 961/985/961 962/986/962 f 329/984/329 962/986/962 330/987/330 f 834/854/834 963/988/963 751/768/751 f 834/854/834 751/768/751 848/871/848 f 879/899/879 839/859/839 838/858/838 f 879/899/879 838/858/838 963/988/963 f 812/833/812 942/967/942 964/989/964 f 812/833/812 964/989/964 813/834/813 f 786/806/786 692/807/692 695/990/695 f 786/806/786 695/990/695 965/991/965 f 967/992/967 968/993/968 969/994/969 f 967/992/967 969/994/969 966/995/966 f 696/717/696 699/716/699 829/850/829 f 696/717/696 829/850/829 955/981/955 f 970/996/970 703/720/703 702/719/702 f 970/996/970 702/719/702 773/790/773 f 972/997/972 799/820/799 798/818/798 f 972/997/972 798/818/798 971/998/971 f 885/907/885 342/999/342 344/1000/344 f 885/907/885 344/1000/344 973/1001/973 f 974/1002/974 975/1003/975 882/902/882 f 974/1002/974 882/902/882 973/1001/973 f 977/1004/977 978/1005/978 979/1006/979 f 977/1004/977 979/1006/979 976/1007/976 f 981/1008/981 856/876/856 855/879/855 f 981/1008/981 855/879/855 980/1009/980 f 775/792/775 781/799/781 830/852/830 f 775/792/775 830/852/830 829/850/829 f 750/769/750 982/1010/982 983/1011/983 f 750/769/750 983/1011/983 745/762/745 f 761/778/761 984/1012/984 985/1013/985 f 761/778/761 985/1013/985 762/779/762 f 986/1014/986 987/1015/987 845/866/845 f 986/1014/986 845/866/845 844/865/844 f 752/773/752 755/772/755 989/1016/989 f 752/773/752 989/1016/989 988/1017/988 f 977/1004/977 976/1007/976 991/1018/991 f 977/1004/977 991/1018/991 990/1019/990 f 978/1005/978 977/1004/977 874/898/874 f 978/1005/978 874/898/874 992/1020/992 f 863/884/863 993/1021/993 816/836/816 f 863/884/863 816/836/816 872/894/872 f 802/822/802 995/1022/995 933/955/933 f 802/822/802 933/955/933 994/1023/994 f 930/952/930 929/951/929 716/737/716 f 930/952/930 716/737/716 719/736/719 f 828/848/828 827/847/827 996/1024/996 f 828/848/828 996/1024/996 970/996/970 f 998/1025/998 950/973/950 805/825/805 f 998/1025/998 805/825/805 997/1026/997 f 950/973/950 945/968/945 700/721/700 f 950/973/950 700/721/700 783/801/783 f 1000/1027/1000 1001/1028/1001 1002/1029/1002 f 1000/1027/1000 1002/1029/1002 999/1030/999 f 691/1031/691 936/962/936 939/961/939 f 691/1031/691 939/961/939 676/1032/676 f 936/962/936 691/1031/691 688/802/688 f 936/962/936 688/802/688 784/805/784 f 890/911/890 787/810/787 1004/1033/1004 f 890/911/890 1004/1033/1004 1003/1034/1003 f 713/730/713 696/717/696 955/981/955 f 713/730/713 955/981/955 958/980/958 f 830/852/830 831/851/831 1005/1035/1005 f 830/852/830 1005/1035/1005 956/978/956 f 1006/1036/1006 1007/1037/1007 905/928/905 f 1006/1036/1006 905/928/905 895/915/895 f 908/931/908 277/260/277 379/365/379 f 908/931/908 379/365/379 909/932/909 f 1009/1038/1009 1010/1039/1010 1011/1040/1011 f 1009/1038/1009 1011/1040/1011 1008/1041/1008 f 1013/1042/1013 756/775/756 754/771/754 f 1013/1042/1013 754/771/754 1012/1043/1012 f 754/771/754 753/770/753 1014/1044/1014 f 754/771/754 1014/1044/1014 1012/1043/1012 f 989/1016/989 755/772/755 757/774/757 f 989/1016/989 757/774/757 1015/1045/1015 f 826/849/826 808/832/808 811/831/811 f 826/849/826 811/831/811 827/847/827 f 995/1022/995 802/822/802 801/821/801 f 995/1022/995 801/821/801 1016/1046/1016 f 815/835/815 868/892/868 872/894/872 f 815/835/815 872/894/872 816/836/816 f 726/747/726 918/940/918 917/941/917 f 726/747/726 917/941/917 926/950/926 f 910/933/910 909/932/909 379/365/379 f 910/933/910 379/365/379 389/375/389 f 912/934/912 910/933/910 389/375/389 f 912/934/912 389/375/389 390/376/390 f 786/806/786 965/991/965 1003/1034/1003 f 786/806/786 1003/1034/1003 1004/1033/1004 f 1017/1047/1017 803/823/803 802/822/802 f 1017/1047/1017 802/822/802 994/1023/994 f 1019/1048/1019 1017/1047/1017 994/1023/994 f 1019/1048/1019 994/1023/994 1018/1049/1018 f 820/840/820 1020/1050/1020 907/930/907 f 820/840/820 907/930/907 846/868/846 f 932/958/932 1018/1049/1018 994/1023/994 f 932/958/932 994/1023/994 933/955/933 f 1022/1051/1022 1023/1052/1023 1024/1053/1024 f 1022/1051/1022 1024/1053/1024 1021/1054/1021 f 1025/1055/1025 817/837/817 816/836/816 f 1025/1055/1025 816/836/816 993/1021/993 f 1020/1050/1020 817/837/817 1025/1055/1025 f 1020/1050/1020 1025/1055/1025 893/913/893 f 907/930/907 1020/1050/1020 893/913/893 f 907/930/907 893/913/893 892/916/892 f 749/766/749 854/875/854 1026/1056/1026 f 749/766/749 1026/1056/1026 759/776/759 f 776/797/776 1000/1027/1000 999/1030/999 f 776/797/776 999/1030/999 1027/1057/1027 f 1017/1047/1017 943/965/943 812/833/812 f 1017/1047/1017 812/833/812 803/823/803 f 1028/1058/1028 1029/1059/1029 405/390/405 f 1028/1058/1028 405/390/405 404/389/404 f 1029/1059/1029 943/965/943 1017/1047/1017 f 1029/1059/1029 1017/1047/1017 1019/1048/1019 f 685/1060/685 673/1061/673 964/989/964 f 685/1060/685 964/989/964 942/967/942 f 685/1060/685 942/967/942 944/966/944 f 685/1060/685 944/966/944 683/1062/683 f 683/1062/683 944/966/944 1028/1058/1028 f 683/1062/683 1028/1058/1028 680/1063/680 f 1030/1064/1030 897/918/897 859/883/859 f 1030/1064/1030 859/883/859 904/927/904 f 1007/1037/1007 1030/1064/1030 408/398/408 f 1007/1037/1007 408/398/408 407/397/407 f 766/783/766 765/782/765 897/918/897 f 766/783/766 897/918/897 1006/1036/1006 f 907/930/907 892/916/892 906/929/906 f 907/930/907 906/929/906 908/931/908 f 937/959/937 999/1030/999 1002/1029/1002 f 937/959/937 1002/1029/1002 938/960/938 f 991/1018/991 976/1007/976 1032/1065/1032 f 991/1018/991 1032/1065/1032 1031/1066/1031 f 1034/1067/1034 739/756/739 738/755/738 f 1034/1067/1034 738/755/738 1033/1068/1033 f 1035/1069/1035 1036/1070/1036 1037/1071/1037 f 1035/1069/1035 1037/1071/1037 1034/1067/1034 f 1038/1072/1038 416/408/416 418/407/418 f 1038/1072/1038 418/407/418 967/992/967 f 966/995/966 719/736/719 718/735/718 f 966/995/966 718/735/718 1039/1073/1039 f 1041/1074/1041 1042/1075/1042 1043/1076/1043 f 1041/1074/1041 1043/1076/1043 1040/1077/1040 f 1041/1074/1041 1040/1077/1040 1045/1078/1045 f 1041/1074/1041 1045/1078/1045 1044/1079/1044 f 1043/1076/1043 1046/1080/1046 1047/1081/1047 f 1043/1076/1043 1047/1081/1047 1040/1077/1040 f 883/903/883 1045/1078/1045 1048/1082/1048 f 883/903/883 1048/1082/1048 884/904/884 f 1049/1083/1049 1050/1084/1050 721/739/721 f 1049/1083/1049 721/739/721 720/738/720 f 717/734/717 1050/1084/1050 1039/1073/1039 f 717/734/717 1039/1073/1039 718/735/718 f 889/909/889 760/781/760 763/780/763 f 889/909/889 763/780/763 1051/1085/1051 f 974/1002/974 1052/1086/1052 1053/1087/1053 f 974/1002/974 1053/1087/1053 975/1003/975 f 1053/1087/1053 1054/1088/1054 1042/1075/1042 f 1053/1087/1053 1042/1075/1042 1041/1074/1041 f 1056/1089/1056 1057/1090/1057 1058/1091/1058 f 1056/1089/1056 1058/1091/1058 1055/1092/1055 f 1055/1092/1055 1058/1091/1058 1010/1039/1010 f 1055/1092/1055 1010/1039/1010 1009/1038/1009 f 825/845/825 1059/1093/1059 1060/1094/1060 f 825/845/825 1060/1094/1060 824/846/824 f 1060/1094/1060 1059/1093/1059 1062/1095/1062 f 1060/1094/1060 1062/1095/1062 1061/1096/1061 f 444/1097/444 443/1098/443 1064/1099/1064 f 444/1097/444 1064/1099/1064 1063/1100/1063 f 955/981/955 829/850/829 830/852/830 f 955/981/955 830/852/830 956/978/956 f 855/879/855 845/866/845 987/1015/987 f 855/879/855 987/1015/987 980/1009/980 f 858/878/858 869/889/869 823/843/823 f 858/878/858 823/843/823 822/842/822 f 1066/1101/1066 1067/1102/1067 1068/1103/1068 f 1066/1101/1066 1068/1103/1068 1065/1104/1065 f 1043/1076/1043 1067/1102/1067 1069/1105/1069 f 1043/1076/1043 1069/1105/1069 1046/1080/1046 f 724/741/724 723/740/723 1046/1080/1046 f 724/741/724 1046/1080/1046 1069/1105/1069 f 725/742/725 710/727/710 709/726/709 f 725/742/725 709/726/709 740/759/740 f 923/945/923 922/944/922 730/751/730 f 923/945/923 730/751/730 733/750/733 f 742/761/742 1026/1056/1026 854/875/854 f 742/761/742 854/875/854 735/752/735 f 878/901/878 884/904/884 1048/1082/1048 f 878/901/878 1048/1082/1048 1070/1106/1070 f 839/859/839 1070/1106/1070 841/862/841 f 839/859/839 841/862/841 840/860/840 f 878/901/878 1070/1106/1070 839/859/839 f 878/901/878 839/859/839 879/899/879 f 728/745/728 853/874/853 983/1011/983 f 728/745/728 983/1011/983 729/746/729 f 923/945/923 733/750/733 743/760/743 f 923/945/923 743/760/743 914/936/914 f 1049/1083/1049 453/443/453 416/408/416 f 1049/1083/1049 416/408/416 1038/1072/1038 f 969/994/969 934/956/934 931/953/931 f 969/994/969 931/953/931 930/952/930 f 706/723/706 1071/1107/1071 1072/1108/1072 f 706/723/706 1072/1108/1072 707/724/707 f 856/876/856 981/1008/981 1074/1109/1074 f 856/876/856 1074/1109/1074 1073/1110/1073 f 732/749/732 731/748/731 985/1013/985 f 732/749/732 985/1013/985 984/1012/984 f 789/809/789 940/963/940 1004/1033/1004 f 789/809/789 1004/1033/1004 787/810/787 f 1027/1057/1027 941/964/941 940/963/940 f 1027/1057/1027 940/963/940 789/809/789 f 1075/1111/1075 1076/1112/1076 900/920/900 f 1075/1111/1075 900/920/900 899/919/899 f 228/210/228 866/886/866 898/922/898 f 228/210/228 898/922/898 264/246/264 f 900/920/900 1076/1112/1076 1077/1113/1077 f 900/920/900 1077/1113/1077 902/923/902 f 1077/1113/1077 694/1114/694 677/925/677 f 1077/1113/1077 677/925/677 902/923/902 f 263/247/263 901/921/901 903/924/903 f 263/247/263 903/924/903 265/249/265 f 461/1115/461 886/906/886 836/856/836 f 461/1115/461 836/856/836 462/1116/462 f 871/891/871 870/890/870 1078/1117/1078 f 871/891/871 1078/1117/1078 948/972/948 f 1080/1118/1080 1081/1119/1081 1032/1065/1032 f 1080/1118/1080 1032/1065/1032 1079/1120/1079 f 737/754/737 736/757/736 1012/1043/1012 f 737/754/737 1012/1043/1012 1014/1044/1014 f 875/895/875 874/898/874 977/1004/977 f 875/895/875 977/1004/977 990/1019/990 f 877/897/877 1082/1121/1082 992/1020/992 f 877/897/877 992/1020/992 874/898/874 f 969/994/969 930/952/930 719/736/719 f 969/994/969 719/736/719 966/995/966 f 969/994/969 968/993/968 935/957/935 f 969/994/969 935/957/935 934/956/934 f 1084/1122/1084 1037/1071/1037 1085/1123/1085 f 1084/1122/1084 1085/1123/1085 1083/1124/1083 f 978/1005/978 992/1020/992 1087/1125/1087 f 978/1005/978 1087/1125/1087 1086/1126/1086 f 1086/1126/1086 1088/1127/1088 979/1006/979 f 1086/1126/1086 979/1006/979 978/1005/978 f 1080/1118/1080 1090/1128/1090 1091/1129/1091 f 1080/1118/1080 1091/1129/1091 1089/1130/1089 f 1013/1042/1013 1092/1131/1092 1093/1132/1093 f 1013/1042/1013 1093/1132/1093 756/775/756 f 1035/1069/1035 1034/1067/1034 1033/1068/1033 f 1035/1069/1035 1033/1068/1033 1094/1133/1094 f 921/947/921 1094/1133/1094 1033/1068/1033 f 921/947/921 1033/1068/1033 922/944/922 f 730/751/730 738/755/738 737/754/737 f 730/751/730 737/754/737 731/748/731 f 1014/1044/1014 753/770/753 762/779/762 f 1014/1044/1014 762/779/762 985/1013/985 f 876/896/876 875/895/875 987/1015/987 f 876/896/876 987/1015/987 986/1014/986 f 928/954/928 808/832/808 826/849/826 f 928/954/928 826/849/826 929/951/929 f 1039/1073/1039 1038/1072/1038 967/992/967 f 1039/1073/1039 967/992/967 966/995/966 f 698/715/698 828/848/828 772/793/772 f 698/715/698 772/793/772 699/716/699 f 676/1032/676 939/961/939 964/989/964 f 676/1032/676 964/989/964 673/1061/673 f 1000/1027/1000 810/830/810 809/829/809 f 1000/1027/1000 809/829/809 1001/1028/1001 f 898/922/898 866/886/866 865/888/865 f 898/922/898 865/888/865 899/919/899 f 899/919/899 865/888/865 1095/1134/1095 f 899/919/899 1095/1134/1095 1075/1111/1075 f 857/877/857 870/890/870 869/889/869 f 857/877/857 869/889/869 858/878/858 f 948/972/948 1078/1117/1078 946/969/946 f 948/972/948 946/969/946 1096/1135/1096 f 819/839/819 823/843/823 815/835/815 f 819/839/819 815/835/815 814/838/814 f 911/935/911 1097/1136/1097 818/841/818 f 911/935/911 818/841/818 847/867/847 f 815/835/815 823/843/823 869/889/869 f 815/835/815 869/889/869 868/892/868 f 887/908/887 748/767/748 758/777/758 f 887/908/887 758/777/758 888/910/888 f 761/778/761 760/781/760 758/777/758 f 761/778/761 758/777/758 759/776/759 f 853/874/853 746/763/746 745/762/745 f 853/874/853 745/762/745 983/1011/983 f 1051/1085/1051 988/1017/988 876/896/876 f 1051/1085/1051 876/896/876 986/1014/986 f 877/897/877 876/896/876 988/1017/988 f 877/897/877 988/1017/988 989/1016/989 f 989/1016/989 1015/1045/1015 1082/1121/1082 f 989/1016/989 1082/1121/1082 877/897/877 f 726/747/726 729/746/729 1098/1137/1098 f 726/747/726 1098/1137/1098 918/940/918 f 1100/1138/1100 1101/1139/1101 1102/1140/1102 f 1100/1138/1100 1102/1140/1102 1099/1141/1099 f 1103/1142/1103 488/480/488 294/277/294 f 1103/1142/1103 294/277/294 715/732/715 f 1104/1143/1104 1105/1144/1105 1072/1108/1072 f 1104/1143/1104 1072/1108/1072 1071/1107/1071 f 801/821/801 800/824/800 1002/1029/1002 f 801/821/801 1002/1029/1002 1001/1028/1001 f 1104/1143/1104 1106/1145/1106 958/980/958 f 1104/1143/1104 958/980/958 957/979/957 f 1104/1143/1104 957/979/957 1107/1146/1107 f 1104/1143/1104 1107/1146/1107 1105/1144/1105 f 1056/1089/1056 1108/1147/1108 1064/1099/1064 f 1056/1089/1056 1064/1099/1064 1057/1090/1057 f 495/1148/495 1010/1039/1010 1058/1091/1058 f 495/1148/495 1058/1091/1058 496/1149/496 f 496/1149/496 1058/1091/1058 1057/1090/1057 f 496/1149/496 1057/1090/1057 497/1150/497 f 962/986/962 1052/1086/1052 498/1151/498 f 962/986/962 498/1151/498 330/987/330 f 499/1152/499 498/1151/498 1052/1086/1052 f 499/1152/499 1052/1086/1052 974/1002/974 f 1010/1039/1010 495/1148/495 500/1153/500 f 1010/1039/1010 500/1153/500 1011/1040/1011 f 1109/1154/1109 1054/1088/1054 962/986/962 f 1109/1154/1109 962/986/962 961/985/961 f 499/1152/499 974/1002/974 973/1001/973 f 499/1152/499 973/1001/973 344/1000/344 f 1106/1145/1106 1104/1143/1104 1071/1107/1071 f 1106/1145/1106 1071/1107/1071 1110/1155/1110 f 1071/1107/1071 706/723/706 1102/1140/1102 f 1071/1107/1071 1102/1140/1102 1110/1155/1110 f 1099/1141/1099 1102/1140/1102 706/723/706 f 1099/1141/1099 706/723/706 705/722/705 f 705/722/705 1008/1041/1008 1111/1156/1111 f 705/722/705 1111/1156/1111 1099/1141/1099 f 1011/1040/1011 500/1153/500 505/1157/505 f 1011/1040/1011 505/1157/505 1112/1158/1112 f 1067/1102/1067 1043/1076/1043 1042/1075/1042 f 1067/1102/1067 1042/1075/1042 1068/1103/1068 f 329/984/329 444/1097/444 1063/1100/1063 f 329/984/329 1063/1100/1063 961/985/961 f 1068/1103/1068 1109/1154/1109 1113/1159/1113 f 1068/1103/1068 1113/1159/1113 1065/1104/1065 f 1115/1160/1115 724/741/724 1069/1105/1069 f 1115/1160/1115 1069/1105/1069 1114/1161/1114 f 744/765/744 843/864/843 848/871/848 f 744/765/744 848/871/848 751/768/751 f 509/500/509 850/870/850 849/869/849 f 509/500/509 849/869/849 208/189/208 f 849/869/849 843/864/843 842/863/842 f 849/869/849 842/863/842 851/872/851 f 462/1116/462 836/856/836 835/855/835 f 462/1116/462 835/855/835 510/501/510 f 850/870/850 509/500/509 510/501/510 f 850/870/850 510/501/510 835/855/835 f 795/815/795 960/983/960 971/998/971 f 795/815/795 971/998/971 951/974/951 f 960/983/960 1116/1162/1116 972/997/972 f 960/983/960 972/997/972 971/998/971 f 768/789/768 780/798/780 972/997/972 f 768/789/768 972/997/972 1116/1162/1116 f 716/737/716 929/951/929 826/849/826 f 716/737/716 826/849/826 698/715/698 f 801/821/801 1001/1028/1001 809/829/809 f 801/821/801 809/829/809 1016/1046/1016 f 800/824/800 813/834/813 938/960/938 f 800/824/800 938/960/938 1002/1029/1002 f 813/834/813 964/989/964 939/961/939 f 813/834/813 939/961/939 938/960/938 f 1117/1163/1117 921/947/921 924/946/924 f 1117/1163/1117 924/946/924 954/976/954 f 1094/1133/1094 1118/1164/1118 1119/1165/1119 f 1094/1133/1094 1119/1165/1119 1035/1069/1035 f 1035/1069/1035 1119/1165/1119 1089/1130/1089 f 1035/1069/1035 1089/1130/1089 1036/1070/1036 f 1118/1164/1118 1094/1133/1094 921/947/921 f 1118/1164/1118 921/947/921 1117/1163/1117 f 838/858/838 837/861/837 982/1010/982 f 838/858/838 982/1010/982 750/769/750 f 963/988/963 838/858/838 750/769/750 f 963/988/963 750/769/750 751/768/751 f 729/746/729 983/1011/983 982/1010/982 f 729/746/729 982/1010/982 1098/1137/1098 f 732/749/732 742/761/742 743/760/743 f 732/749/732 743/760/743 733/750/733 f 732/749/732 984/1012/984 1026/1056/1026 f 732/749/732 1026/1056/1026 742/761/742 f 984/1012/984 761/778/761 759/776/759 f 984/1012/984 759/776/759 1026/1056/1026 f 790/811/790 806/826/806 783/801/783 f 790/811/790 783/801/783 782/800/782 f 931/953/931 934/956/934 933/955/933 f 931/953/931 933/955/933 995/1022/995 f 931/953/931 995/1022/995 1016/1046/1016 f 931/953/931 1016/1046/1016 928/954/928 f 996/1024/996 827/847/827 811/831/811 f 996/1024/996 811/831/811 791/812/791 f 1121/1166/1121 861/881/861 864/885/864 f 1121/1166/1121 864/885/864 1120/1167/1120 f 896/917/896 1122/1168/1122 860/880/860 f 896/917/896 860/880/860 859/883/859 f 1024/1053/1024 1023/1052/1023 1025/1055/1025 f 1024/1053/1024 1025/1055/1025 993/1021/993 f 1024/1053/1024 860/880/860 1122/1168/1122 f 1024/1053/1024 1122/1168/1122 1021/1054/1021 f 1124/1169/1124 887/908/887 888/910/888 f 1124/1169/1124 888/910/888 1123/1170/1123 f 951/974/951 971/998/971 798/818/798 f 951/974/951 798/818/798 797/817/797 f 1050/1084/1050 1049/1083/1049 1038/1072/1038 f 1050/1084/1050 1038/1072/1038 1039/1073/1039 f 680/1063/680 1028/1058/1028 404/389/404 f 680/1063/680 404/389/404 46/511/46 f 1028/1058/1028 944/966/944 943/965/943 f 1028/1058/1028 943/965/943 1029/1059/1029 f 1018/1049/1018 932/958/932 521/513/521 f 1018/1049/1018 521/513/521 520/512/520 f 522/514/522 1019/1048/1019 1018/1049/1018 f 522/514/522 1018/1049/1018 520/512/520 f 935/957/935 523/515/523 521/513/521 f 935/957/935 521/513/521 932/958/932 f 935/957/935 968/993/968 524/516/524 f 935/957/935 524/516/524 523/515/523 f 953/977/953 792/816/792 952/975/952 f 953/977/953 952/975/952 1073/1110/1073 f 1073/1110/1073 1074/1109/1074 1125/1171/1125 f 1073/1110/1073 1125/1171/1125 953/977/953 f 1032/1065/1032 1081/1119/1081 1126/1172/1126 f 1032/1065/1032 1126/1172/1126 1031/1066/1031 f 1032/1065/1032 976/1007/976 979/1006/979 f 1032/1065/1032 979/1006/979 1079/1120/1079 f 1073/1110/1073 1127/1173/1127 857/877/857 f 1073/1110/1073 857/877/857 856/876/856 f 857/877/857 1127/1173/1127 1078/1117/1078 f 857/877/857 1078/1117/1078 870/890/870 f 407/397/407 276/258/276 905/928/905 f 407/397/407 905/928/905 1007/1037/1007 f 1006/1036/1006 897/918/897 1030/1064/1030 f 1006/1036/1006 1030/1064/1030 1007/1037/1007 f 822/842/822 845/866/845 855/879/855 f 822/842/822 855/879/855 858/878/858 f 1014/1044/1014 985/1013/985 731/748/731 f 1014/1044/1014 731/748/731 737/754/737 f 1031/1066/1031 1074/1109/1074 981/1008/981 f 1031/1066/1031 981/1008/981 991/1018/991 f 730/751/730 922/944/922 1033/1068/1033 f 730/751/730 1033/1068/1033 738/755/738 f 990/1019/990 980/1009/980 987/1015/987 f 990/1019/990 987/1015/987 875/895/875 f 763/780/763 752/773/752 988/1017/988 f 763/780/763 988/1017/988 1051/1085/1051 f 763/780/763 762/779/762 753/770/753 f 763/780/763 753/770/753 752/773/752 f 980/1009/980 990/1019/990 991/1018/991 f 980/1009/980 991/1018/991 981/1008/981 f 1118/1164/1118 1126/1172/1126 1081/1119/1081 f 1118/1164/1118 1081/1119/1081 1119/1165/1119 f 1126/1172/1126 1125/1171/1125 1074/1109/1074 f 1126/1172/1126 1074/1109/1074 1031/1066/1031 f 1119/1165/1119 1081/1119/1081 1080/1118/1080 f 1119/1165/1119 1080/1118/1080 1089/1130/1089 f 986/1014/986 844/865/844 889/909/889 f 986/1014/986 889/909/889 1051/1085/1051 f 821/844/821 819/839/819 818/841/818 f 821/844/821 818/841/818 1097/1136/1097 f 1022/1051/1022 764/785/764 894/914/894 f 1022/1051/1022 894/914/894 1023/1052/1023 f 1023/1052/1023 894/914/894 893/913/893 f 1023/1052/1023 893/913/893 1025/1055/1025 f 926/950/926 920/942/920 727/744/727 f 926/950/926 727/744/727 726/747/726 f 919/943/919 920/942/920 926/950/926 f 919/943/919 926/950/926 927/949/927 f 1128/1174/1128 1116/1162/1116 960/983/960 f 1128/1174/1128 960/983/960 959/982/959 f 773/790/773 702/719/702 799/820/799 f 773/790/773 799/820/799 774/791/774 f 799/820/799 972/997/972 780/798/780 f 799/820/799 780/798/780 774/791/774 f 772/793/772 828/848/828 970/996/970 f 772/793/772 970/996/970 773/790/773 f 703/720/703 970/996/970 996/1024/996 f 703/720/703 996/1024/996 782/800/782 f 771/788/771 781/799/781 780/798/780 f 771/788/771 780/798/780 768/789/768 f 791/812/791 790/811/790 782/800/782 f 791/812/791 782/800/782 996/1024/996 f 811/831/811 810/830/810 779/796/779 f 811/831/811 779/796/779 791/812/791 f 1027/1057/1027 789/809/789 777/794/777 f 1027/1057/1027 777/794/777 776/797/776 f 927/949/927 925/948/925 769/786/769 f 927/949/927 769/786/769 1128/1174/1128 f 710/727/710 725/742/725 724/741/724 f 710/727/710 724/741/724 1115/1160/1115 f 954/976/954 953/977/953 1125/1171/1125 f 954/976/954 1125/1171/1125 1117/1163/1117 f 1117/1163/1117 1125/1171/1125 1126/1172/1126 f 1117/1163/1117 1126/1172/1126 1118/1164/1118 f 768/789/768 1116/1162/1116 1128/1174/1128 f 768/789/768 1128/1174/1128 769/786/769 f 904/927/904 867/887/867 229/209/229 f 904/927/904 229/209/229 529/521/529 f 948/972/948 1096/1135/1096 998/1025/998 f 948/972/948 998/1025/998 949/971/949 f 1120/1167/1120 864/885/864 873/893/873 f 1120/1167/1120 873/893/873 949/971/949 f 1121/1166/1121 1120/1167/1120 997/1026/997 f 1121/1166/1121 997/1026/997 1129/1175/1129 f 1129/1175/1129 1095/1134/1095 865/888/865 f 1129/1175/1129 865/888/865 1121/1166/1121 f 861/881/861 1121/1166/1121 865/888/865 f 861/881/861 865/888/865 862/882/862 f 1075/1111/1075 890/911/890 1003/1034/1003 f 1075/1111/1075 1003/1034/1003 1076/1112/1076 f 1076/1112/1076 1003/1034/1003 965/991/965 f 1076/1112/1076 965/991/965 1077/1113/1077 f 965/991/965 695/990/695 694/1114/694 f 965/991/965 694/1114/694 1077/1113/1077 f 1075/1111/1075 1095/1134/1095 891/912/891 f 1075/1111/1075 891/912/891 890/911/890 f 895/915/895 894/914/894 764/785/764 f 895/915/895 764/785/764 767/784/767 f 1020/1050/1020 820/840/820 814/838/814 f 1020/1050/1020 814/838/814 817/837/817 f 1123/1170/1123 844/865/844 821/844/821 f 1123/1170/1123 821/844/821 1097/1136/1097 f 1124/1169/1124 1123/1170/1123 1097/1136/1097 f 1124/1169/1124 1097/1136/1097 911/935/911 f 1130/1176/1130 1124/1169/1124 911/935/911 f 1130/1176/1130 911/935/911 912/934/912 f 532/524/532 1130/1176/1130 912/934/912 f 532/524/532 912/934/912 390/376/390 f 973/1001/973 882/902/882 881/905/881 f 973/1001/973 881/905/881 885/907/885 f 833/857/833 836/856/836 886/906/886 f 833/857/833 886/906/886 880/900/880 f 834/854/834 833/857/833 879/899/879 f 834/854/834 879/899/879 963/988/963 f 1067/1102/1067 1066/1101/1066 1114/1161/1114 f 1067/1102/1067 1114/1161/1114 1069/1105/1069 f 809/829/809 808/832/808 928/954/928 f 809/829/809 928/954/928 1016/1046/1016 f 1019/1048/1019 522/514/522 405/390/405 f 1019/1048/1019 405/390/405 1029/1059/1029 f 1131/1177/1131 1085/1123/1085 1037/1071/1037 f 1131/1177/1131 1037/1071/1037 1036/1070/1036 f 1132/1178/1132 1103/1142/1103 715/732/715 f 1132/1178/1132 715/732/715 714/731/714 f 1110/1155/1110 1102/1140/1102 1101/1139/1101 f 1110/1155/1110 1101/1139/1101 1133/1179/1133 f 1111/1156/1111 1112/1158/1112 1135/1180/1135 f 1111/1156/1111 1135/1180/1135 1134/1181/1134 f 1106/1145/1106 1110/1155/1110 1133/1179/1133 f 1106/1145/1106 1133/1179/1133 1136/1182/1136 f 1106/1145/1106 714/731/714 713/730/713 f 1106/1145/1106 713/730/713 958/980/958 f 1112/1158/1112 505/1157/505 539/1183/539 f 1112/1158/1112 539/1183/539 1135/1180/1135 f 883/903/883 882/902/882 975/1003/975 f 883/903/883 975/1003/975 1044/1079/1044 f 704/725/704 1009/1038/1009 1008/1041/1008 f 704/725/704 1008/1041/1008 705/722/705 f 1052/1086/1052 962/986/962 1054/1088/1054 f 1052/1086/1052 1054/1088/1054 1053/1087/1053 f 1055/1092/1055 824/846/824 1060/1094/1060 f 1055/1092/1055 1060/1094/1060 1056/1089/1056 f 1009/1038/1009 704/725/704 824/846/824 f 1009/1038/1009 824/846/824 1055/1092/1055 f 1065/1104/1065 1113/1159/1113 1108/1147/1108 f 1065/1104/1065 1108/1147/1108 1061/1096/1061 f 1068/1103/1068 1042/1075/1042 1054/1088/1054 f 1068/1103/1068 1054/1088/1054 1109/1154/1109 f 1008/1041/1008 1011/1040/1011 1112/1158/1112 f 1008/1041/1008 1112/1158/1112 1111/1156/1111 f 1109/1154/1109 961/985/961 1063/1100/1063 f 1109/1154/1109 1063/1100/1063 1113/1159/1113 f 1134/1181/1134 1100/1138/1100 1099/1141/1099 f 1134/1181/1134 1099/1141/1099 1111/1156/1111 f 947/970/947 952/975/952 951/974/951 f 947/970/947 951/974/951 797/817/797 f 959/982/959 794/814/794 916/938/916 f 959/982/959 916/938/916 919/943/919 f 1098/1137/1098 982/1010/982 837/861/837 f 1098/1137/1098 837/861/837 741/758/741 f 1098/1137/1098 741/758/741 740/759/740 f 1098/1137/1098 740/759/740 918/940/918 f 1040/1077/1040 1047/1081/1047 1048/1082/1048 f 1040/1077/1040 1048/1082/1048 1045/1078/1045 f 1041/1074/1041 1044/1079/1044 975/1003/975 f 1041/1074/1041 975/1003/975 1053/1087/1053 f 1078/1117/1078 1127/1173/1127 947/970/947 f 1078/1117/1078 947/970/947 946/969/946 f 949/971/949 998/1025/998 997/1026/997 f 949/971/949 997/1026/997 1120/1167/1120 f 946/969/946 796/819/796 945/968/945 f 946/969/946 945/968/945 1096/1135/1096 f 998/1025/998 1096/1135/1096 945/968/945 f 998/1025/998 945/968/945 950/973/950 f 997/1026/997 805/825/805 804/828/804 f 997/1026/997 804/828/804 1129/1175/1129 f 1095/1134/1095 1129/1175/1129 804/828/804 f 1095/1134/1095 804/828/804 891/912/891 f 904/927/904 529/521/529 408/398/408 f 904/927/904 408/398/408 1030/1064/1030 f 1024/1053/1024 993/1021/993 863/884/863 f 1024/1053/1024 863/884/863 860/880/860 f 1138/1184/1138 1139/1185/1139 1140/1186/1140 f 1138/1184/1138 1140/1186/1140 1137/1187/1137 f 1141/1188/1141 1142/1189/1142 1137/1187/1137 f 1141/1188/1141 1137/1187/1137 1140/1186/1140 f 1143/1190/1143 1144/1191/1144 1142/1189/1142 f 1143/1190/1143 1142/1189/1142 1141/1188/1141 f 1145/1192/1145 1146/1193/1146 1144/1191/1144 f 1145/1192/1145 1144/1191/1144 1143/1190/1143 f 1147/1194/1147 1148/1195/1148 1146/1193/1146 f 1147/1194/1147 1146/1193/1146 1145/1192/1145 f 1149/1196/1149 1150/1197/1150 1148/1195/1148 f 1149/1196/1149 1148/1195/1148 1147/1194/1147 f 1151/1198/1151 1152/1199/1152 1150/1197/1150 f 1151/1198/1151 1150/1197/1150 1149/1196/1149 f 1154/1200/1154 1155/1201/1155 1156/1202/1156 f 1154/1200/1154 1156/1202/1156 1153/1203/1153 f 1157/1204/1157 1158/1205/1158 1155/1201/1155 f 1157/1204/1157 1155/1201/1155 1154/1200/1154 f 1159/1206/1159 1160/1207/1160 1142/1189/1142 f 1159/1206/1159 1142/1189/1142 1144/1191/1144 f 1161/1208/1161 1159/1206/1159 1144/1191/1144 f 1161/1208/1161 1144/1191/1144 1146/1193/1146 f 1162/1209/1162 1161/1208/1161 1146/1193/1146 f 1162/1209/1162 1146/1193/1146 1148/1195/1148 f 1163/1210/1163 1162/1209/1162 1148/1195/1148 f 1163/1210/1163 1148/1195/1148 1150/1197/1150 f 1150/1197/1150 1152/1199/1152 1164/1211/1164 f 1150/1197/1150 1164/1211/1164 1163/1210/1163 f 1156/1202/1156 1155/1201/1155 1166/1212/1166 f 1156/1202/1156 1166/1212/1166 1165/1213/1165 f 1167/1214/1167 1166/1212/1166 1155/1201/1155 f 1167/1214/1167 1155/1201/1155 1158/1205/1158 f 1169/1215/1169 1167/1214/1167 1158/1205/1158 f 1169/1215/1169 1158/1205/1158 1168/1216/1168 f 1170/1217/1170 1171/1218/1171 1172/1219/1172 f 1170/1217/1170 1172/1219/1172 1139/1185/1139 f 1173/1220/1173 1174/1221/1174 1141/1188/1141 f 1173/1220/1173 1141/1188/1141 1140/1186/1140 f 1141/1188/1141 1174/1221/1174 1175/1222/1175 f 1141/1188/1141 1175/1222/1175 1143/1190/1143 f 1176/1223/1176 1145/1192/1145 1143/1190/1143 f 1176/1223/1176 1143/1190/1143 1175/1222/1175 f 1177/1224/1177 1149/1196/1149 1147/1194/1147 f 1177/1224/1177 1147/1194/1147 1176/1223/1176 f 1177/1224/1177 1178/1225/1178 1151/1198/1151 f 1177/1224/1177 1151/1198/1151 1149/1196/1149 f 1153/1203/1153 1179/1226/1179 1180/1227/1180 f 1153/1203/1153 1180/1227/1180 1154/1200/1154 f 1157/1204/1157 1154/1200/1154 1180/1227/1180 f 1157/1204/1157 1180/1227/1180 1181/1228/1181 f 1157/1204/1157 1181/1228/1181 1182/1229/1182 f 1157/1204/1157 1182/1229/1182 1168/1216/1168 f 1169/1215/1169 1168/1216/1168 1182/1229/1182 f 1169/1215/1169 1182/1229/1182 1183/1230/1183 f 1142/1189/1142 1160/1207/1160 1138/1184/1138 f 1142/1189/1142 1138/1184/1138 1137/1187/1137 f 1170/1217/1170 1185/1231/1185 1186/1232/1186 f 1170/1217/1170 1186/1232/1186 1184/1233/1184 f 1170/1217/1170 1184/1233/1184 1187/1234/1187 f 1170/1217/1170 1187/1234/1187 1171/1218/1171 f 1187/1234/1187 1188/1235/1188 1172/1219/1172 f 1187/1234/1187 1172/1219/1172 1171/1218/1171 f 1172/1219/1172 1188/1235/1188 1140/1186/1140 f 1172/1219/1172 1140/1186/1140 1139/1185/1139 f 1161/1208/1161 1162/1209/1162 1163/1210/1163 f 1161/1208/1161 1163/1210/1163 1189/1236/1189 f 1189/1236/1189 1163/1210/1163 1164/1211/1164 f 1189/1236/1189 1164/1211/1164 1190/1237/1190 f 1165/1213/1165 1164/1211/1164 1152/1199/1152 f 1165/1213/1165 1152/1199/1152 1156/1202/1156 f 1152/1199/1152 1151/1198/1151 1153/1203/1153 f 1152/1199/1152 1153/1203/1153 1156/1202/1156 f 1179/1226/1179 1153/1203/1153 1151/1198/1151 f 1179/1226/1179 1151/1198/1151 1178/1225/1178 f 1189/1236/1189 1160/1207/1160 1159/1206/1159 f 1189/1236/1189 1159/1206/1159 1161/1208/1161 f 1186/1232/1186 1190/1237/1190 1164/1211/1164 f 1186/1232/1186 1164/1211/1164 1165/1213/1165 f 1139/1185/1139 1138/1184/1138 1185/1231/1185 f 1139/1185/1139 1185/1231/1185 1170/1217/1170 f 1169/1215/1169 1188/1235/1188 1187/1234/1187 f 1169/1215/1169 1187/1234/1187 1167/1214/1167 f 1186/1232/1186 1165/1213/1165 1166/1212/1166 f 1186/1232/1186 1166/1212/1166 1184/1233/1184 f 1140/1186/1140 1188/1235/1188 1191/1238/1191 f 1140/1186/1140 1191/1238/1191 1173/1220/1173 f 1191/1238/1191 1188/1235/1188 1169/1215/1169 f 1191/1238/1191 1169/1215/1169 1183/1230/1183 f 1192/1239/1192 1193/1240/1193 1179/1226/1179 f 1192/1239/1192 1179/1226/1179 1178/1225/1178 f 1192/1239/1192 1178/1225/1178 1177/1224/1177 f 1192/1239/1192 1177/1224/1177 1194/1241/1194 f 1180/1227/1180 1193/1240/1193 1072/1108/1072 f 1180/1227/1180 1072/1108/1072 1105/1144/1105 f 1180/1227/1180 1105/1144/1105 1107/1146/1107 f 1180/1227/1180 1107/1146/1107 1181/1228/1181 f 1194/1241/1194 1177/1224/1177 1176/1223/1176 f 1194/1241/1194 1176/1223/1176 1114/1161/1114 f 1062/1095/1062 1194/1241/1194 1114/1161/1114 f 1062/1095/1062 1114/1161/1114 1066/1101/1066 f 707/724/707 1072/1108/1072 1193/1240/1193 f 707/724/707 1193/1240/1193 825/845/825 f 825/845/825 1193/1240/1193 1192/1239/1192 f 825/845/825 1192/1239/1192 1059/1093/1059 f 1173/1220/1173 1191/1238/1191 832/853/832 f 1173/1220/1173 832/853/832 711/728/711 f 1183/1230/1183 1182/1229/1182 1005/1035/1005 f 1183/1230/1183 1005/1035/1005 831/851/831 f 1187/1234/1187 1184/1233/1184 1166/1212/1166 f 1187/1234/1187 1166/1212/1166 1167/1214/1167 f 710/727/710 1115/1160/1115 1175/1222/1175 f 710/727/710 1175/1222/1175 1174/1221/1174 f 1182/1229/1182 1181/1228/1181 1107/1146/1107 f 1182/1229/1182 1107/1146/1107 1005/1035/1005 f 453/443/453 1049/1083/1049 720/738/720 f 453/443/453 720/738/720 598/590/598 f 1123/1170/1123 888/910/888 889/909/889 f 1123/1170/1123 889/909/889 844/865/844 f 916/938/916 794/814/794 793/813/793 f 916/938/916 793/813/793 913/939/913 f 711/728/711 832/853/832 770/787/770 f 711/728/711 770/787/770 708/729/708 f 919/943/919 927/949/927 1128/1174/1128 f 919/943/919 1128/1174/1128 959/982/959 f 925/948/925 708/729/708 770/787/770 f 925/948/925 770/787/770 769/786/769 f 913/939/913 793/813/793 954/976/954 f 913/939/913 954/976/954 924/946/924 f 831/851/831 832/853/832 1191/1238/1191 f 831/851/831 1191/1238/1191 1183/1230/1183 f 895/915/895 767/784/767 766/783/766 f 895/915/895 766/783/766 1006/1036/1006 f 891/912/891 804/828/804 807/827/807 f 891/912/891 807/827/807 788/808/788 f 778/795/778 777/794/777 788/808/788 f 778/795/778 788/808/788 807/827/807 f 810/830/810 1000/1027/1000 776/797/776 f 810/830/810 776/797/776 779/796/779 f 947/970/947 1127/1173/1127 1073/1110/1073 f 947/970/947 1073/1110/1073 952/975/952 f 1106/1145/1106 1136/1182/1136 1132/1178/1132 f 1106/1145/1106 1132/1178/1132 714/731/714 f 1061/1096/1061 1062/1095/1062 1066/1101/1066 f 1061/1096/1061 1066/1101/1066 1065/1104/1065 f 443/1098/443 497/1150/497 1057/1090/1057 f 443/1098/443 1057/1090/1057 1064/1099/1064 f 1064/1099/1064 1108/1147/1108 1113/1159/1113 f 1064/1099/1064 1113/1159/1113 1063/1100/1063 f 1061/1096/1061 1108/1147/1108 1056/1089/1056 f 1061/1096/1061 1056/1089/1056 1060/1094/1060 f 1192/1239/1192 1194/1241/1194 1062/1095/1062 f 1192/1239/1192 1062/1095/1062 1059/1093/1059 f 1173/1220/1173 711/728/711 710/727/710 f 1173/1220/1173 710/727/710 1174/1221/1174 f 880/900/880 881/905/881 884/904/884 f 880/900/880 884/904/884 878/901/878 f 841/862/841 1047/1081/1047 1046/1080/1046 f 841/862/841 1046/1080/1046 723/740/723 f 1070/1106/1070 1048/1082/1048 1047/1081/1047 f 1070/1106/1070 1047/1081/1047 841/862/841 f 461/1115/461 342/999/342 885/907/885 f 461/1115/461 885/907/885 886/906/886 f 1114/1161/1114 1176/1223/1176 1175/1222/1175 f 1114/1161/1114 1175/1222/1175 1115/1160/1115 f 887/908/887 1124/1169/1124 1130/1176/1130 f 887/908/887 1130/1176/1130 852/873/852 f 206/186/206 852/873/852 1130/1176/1130 f 206/186/206 1130/1176/1130 532/524/532 f 681/698/681 599/592/599 1195/1242/1195 f 681/698/681 1195/1242/1195 682/699/682 f 1196/1243/1196 674/691/674 684/702/684 f 1196/1243/1196 684/702/684 1195/1242/1195 f 1197/1244/1197 675/692/675 674/691/674 f 1197/1244/1197 674/691/674 1196/1243/1196 f 689/706/689 690/708/690 675/692/675 f 689/706/689 675/692/675 1197/1244/1197 f 693/710/693 1199/1245/1199 1200/1246/1200 f 693/710/693 1200/1246/1200 1198/1247/1198 f 686/707/686 689/706/689 1197/1244/1197 f 686/707/686 1197/1244/1197 1199/1245/1199 f 1196/1243/1196 1195/1242/1195 1202/1248/1202 f 1196/1243/1196 1202/1248/1202 1201/1249/1201 f 1084/1122/1084 1083/1124/1083 1204/1250/1204 f 1084/1122/1084 1204/1250/1204 1203/1251/1203 f 1092/1131/1092 1013/1042/1013 1203/1251/1203 f 1092/1131/1092 1203/1251/1203 1204/1250/1204 f 1206/1252/1206 1087/1253/1087 1207/1254/1207 f 1206/1252/1206 1207/1254/1207 1205/1255/1205 f 1206/1252/1206 1208/1256/1208 1086/1257/1086 f 1206/1252/1206 1086/1257/1086 1087/1253/1087 f 1091/1258/1091 1090/1259/1090 1210/1260/1210 f 1091/1258/1091 1210/1260/1210 1209/1261/1209 f 1093/1132/1093 1211/1262/1211 757/774/757 f 1093/1132/1093 757/774/757 756/775/756 f 1079/1120/1079 1212/1263/1212 1090/1128/1090 f 1079/1120/1079 1090/1128/1090 1080/1118/1080 f 1079/1120/1079 979/1006/979 1088/1127/1088 f 1079/1120/1079 1088/1127/1088 1212/1263/1212 f 1209/1261/1209 1213/1264/1213 1085/1265/1085 f 1209/1261/1209 1085/1265/1085 1131/1266/1131 f 1089/1130/1089 1091/1129/1091 1131/1177/1131 f 1089/1130/1089 1131/1177/1131 1036/1070/1036 f 1213/1264/1213 1214/1267/1214 1204/1268/1204 f 1213/1264/1213 1204/1268/1204 1083/1269/1083 f 1214/1267/1214 1215/1270/1215 1092/1271/1092 f 1214/1267/1214 1092/1271/1092 1204/1268/1204 f 1015/1045/1015 757/774/757 1211/1262/1211 f 1015/1045/1015 1211/1262/1211 1216/1272/1216 f 1211/1273/1211 1093/1274/1093 1215/1270/1215 f 1211/1273/1211 1215/1270/1215 1217/1275/1217 f 1088/1276/1088 1208/1256/1208 1210/1260/1210 f 1088/1276/1088 1210/1260/1210 1212/1277/1212 f 1216/1278/1216 1211/1273/1211 1217/1275/1217 f 1216/1278/1216 1217/1275/1217 1218/1279/1218 f 1219/1280/1219 1218/1279/1218 1205/1255/1205 f 1219/1280/1219 1205/1255/1205 1207/1254/1207 f 698/715/698 697/714/697 717/734/717 f 698/715/698 717/734/717 716/737/716 f 967/992/967 418/407/418 524/516/524 f 967/992/967 524/516/524 968/993/968 f 598/590/598 720/738/720 712/733/712 f 598/590/598 712/733/712 293/276/293 f 697/714/697 721/739/721 1050/1084/1050 f 697/714/697 1050/1084/1050 717/734/717 f 957/979/957 956/978/956 1005/1035/1005 f 957/979/957 1005/1035/1005 1107/1146/1107 f 1186/1232/1186 1185/1231/1185 1189/1236/1189 f 1186/1232/1186 1189/1236/1189 1190/1237/1190 f 1022/1051/1022 896/917/896 765/782/765 f 1022/1051/1022 765/782/765 764/785/764 f 1122/1168/1122 896/917/896 1022/1051/1022 f 1122/1168/1122 1022/1051/1022 1021/1054/1021 f 678/695/678 1198/1247/1198 625/631/625 f 678/695/678 625/631/625 27/8/27 f 1195/1242/1195 599/592/599 626/632/626 f 1195/1242/1195 626/632/626 1202/1248/1202 f 1202/1248/1202 626/632/626 628/634/628 f 1202/1248/1202 628/634/628 1220/1281/1220 f 1198/1247/1198 1220/1281/1220 628/634/628 f 1198/1247/1198 628/634/628 625/631/625 f 1222/1282/1222 1223/1283/1223 1224/1284/1224 f 1222/1282/1222 1224/1284/1224 1221/1285/1221 f 1226/1286/1226 1227/1287/1227 1228/1288/1228 f 1226/1286/1226 1228/1288/1228 1225/1289/1225 f 1230/1290/1230 1231/1291/1231 1232/1292/1232 f 1230/1290/1230 1232/1292/1232 1229/1293/1229 f 1234/1294/1234 1232/1292/1232 1231/1291/1231 f 1234/1294/1234 1231/1291/1231 1233/1295/1233 f 1236/1296/1236 1237/1297/1237 1238/1298/1238 f 1236/1296/1236 1238/1298/1238 1235/1299/1235 f 1221/1285/1221 1239/1300/1239 1240/1301/1240 f 1221/1285/1221 1240/1301/1240 1233/1295/1233 f 1242/1302/1242 1243/1303/1243 1244/1304/1244 f 1242/1302/1242 1244/1304/1244 1241/1305/1241 f 1237/1297/1237 1245/1306/1245 1246/1307/1246 f 1237/1297/1237 1246/1307/1246 1238/1298/1238 f 1246/1307/1246 1245/1306/1245 1242/1302/1242 f 1246/1307/1246 1242/1302/1242 1241/1305/1241 f 1248/1308/1248 1224/1284/1224 1249/1309/1249 f 1248/1308/1248 1249/1309/1249 1247/1310/1247 f 1249/1309/1249 1250/1311/1250 660/1312/660 f 1249/1309/1249 660/1312/660 659/1313/659 f 661/1314/661 1247/1310/1247 1249/1309/1249 f 661/1314/661 1249/1309/1249 659/1313/659 f 1221/1285/1221 1224/1284/1224 1248/1308/1248 f 1221/1285/1221 1248/1308/1248 1239/1300/1239 f 1231/1291/1231 1222/1282/1222 1221/1285/1221 f 1231/1291/1231 1221/1285/1221 1233/1295/1233 f 1232/1292/1232 1234/1294/1234 1243/1303/1243 f 1232/1292/1232 1243/1303/1243 1242/1302/1242 f 1244/1304/1244 1243/1303/1243 1234/1294/1234 f 1244/1304/1244 1234/1294/1234 1251/1315/1251 f 1240/1301/1240 1251/1315/1251 1234/1294/1234 f 1240/1301/1240 1234/1294/1234 1233/1295/1233 f 1253/1316/1253 1134/1181/1134 1135/1180/1135 f 1253/1316/1253 1135/1180/1135 1252/1317/1252 f 1254/1318/1254 1255/1319/1255 1229/1293/1229 f 1254/1318/1254 1229/1293/1229 1232/1292/1232 f 1254/1318/1254 1225/1289/1225 1228/1288/1228 f 1254/1318/1254 1228/1288/1228 1255/1319/1255 f 667/1320/667 1252/1317/1252 1135/1180/1135 f 667/1320/667 1135/1180/1135 539/1183/539 f 1226/1286/1226 1225/1289/1225 1237/1297/1237 f 1226/1286/1226 1237/1297/1237 1236/1296/1236 f 1245/1306/1245 1254/1318/1254 1232/1292/1232 f 1245/1306/1245 1232/1292/1232 1242/1302/1242 f 1254/1318/1254 1245/1306/1245 1237/1297/1237 f 1254/1318/1254 1237/1297/1237 1225/1289/1225 f 669/674/669 668/675/668 1226/1286/1226 f 669/674/669 1226/1286/1226 1236/1296/1236 f 1230/1290/1230 1256/1321/1256 1222/1282/1222 f 1230/1290/1230 1222/1282/1222 1231/1291/1231 f 1235/1299/1235 671/677/671 669/674/669 f 1235/1299/1235 669/674/669 1236/1296/1236 f 1230/1290/1230 1101/1139/1101 1100/1138/1100 f 1230/1290/1230 1100/1138/1100 1256/1321/1256 f 672/678/672 488/480/488 1103/1142/1103 f 672/678/672 1103/1142/1103 1227/1287/1227 f 1224/1284/1224 1223/1283/1223 1250/1311/1250 f 1224/1284/1224 1250/1311/1250 1249/1309/1249 f 1256/1321/1256 1100/1138/1100 1134/1181/1134 f 1256/1321/1256 1134/1181/1134 1253/1316/1253 f 1227/1287/1227 1103/1142/1103 1132/1178/1132 f 1227/1287/1227 1132/1178/1132 1228/1288/1228 f 1101/1139/1101 1230/1290/1230 1229/1293/1229 f 1101/1139/1101 1229/1293/1229 1133/1179/1133 f 1223/1283/1223 1253/1316/1253 1252/1317/1252 f 1223/1283/1223 1252/1317/1252 1250/1311/1250 f 1255/1319/1255 1136/1182/1136 1133/1179/1133 f 1255/1319/1255 1133/1179/1133 1229/1293/1229 f 1228/1288/1228 1132/1178/1132 1136/1182/1136 f 1228/1288/1228 1136/1182/1136 1255/1319/1255 f 660/1312/660 1250/1311/1250 1252/1317/1252 f 660/1312/660 1252/1317/1252 667/1320/667 f 668/675/668 672/678/672 1227/1287/1227 f 668/675/668 1227/1287/1227 1226/1286/1226 f 1222/1282/1222 1256/1321/1256 1253/1316/1253 f 1222/1282/1222 1253/1316/1253 1223/1283/1223 f 1/1322/1 12/1323/12 1247/1310/1247 f 1/1322/1 1247/1310/1247 661/1314/661 f 10/1324/10 8/1325/8 1240/1301/1240 f 10/1324/10 1240/1301/1240 1239/1300/1239 f 1239/1300/1239 1248/1308/1248 11/1326/11 f 1239/1300/1239 11/1326/11 10/1324/10 f 5/1327/5 3/1328/3 1235/1299/1235 f 5/1327/5 1235/1299/1235 1238/1298/1238 f 9/1329/9 4/1330/4 1246/1307/1246 f 9/1329/9 1246/1307/1246 1241/1305/1241 f 1240/1301/1240 8/1325/8 6/1331/6 f 1240/1301/1240 6/1331/6 1251/1315/1251 f 7/1332/7 9/1329/9 1241/1305/1241 f 7/1332/7 1241/1305/1241 1244/1304/1244 f 11/1326/11 1248/1308/1248 1247/1310/1247 f 11/1326/11 1247/1310/1247 12/1323/12 f 3/1328/3 2/690/2 671/677/671 f 3/1328/3 671/677/671 1235/1299/1235 f 1238/1298/1238 1246/1307/1246 4/1330/4 f 1238/1298/1238 4/1330/4 5/1327/5 f 7/1332/7 1244/1304/1244 1251/1315/1251 f 7/1332/7 1251/1315/1251 6/1331/6 f 1203/1251/1203 1013/1042/1013 1012/1043/1012 f 1203/1251/1203 1012/1043/1012 736/757/736 f 937/959/937 941/964/941 1027/1057/1027 f 937/959/937 1027/1057/1027 999/1030/999 f 1084/1122/1084 739/756/739 1034/1067/1034 f 1084/1122/1084 1034/1067/1034 1037/1071/1037 f 1197/1244/1197 1196/1243/1196 1201/1249/1201 f 1197/1244/1197 1201/1249/1201 1199/1245/1199 f 1203/1251/1203 736/757/736 739/756/739 f 1203/1251/1203 739/756/739 1084/1122/1084 f 936/962/936 784/805/784 941/964/941 f 936/962/936 941/964/941 937/959/937 f 786/806/786 1004/1033/1004 940/963/940 f 786/806/786 940/963/940 785/804/785 f 467/1333/467 612/604/612 387/1334/387 f 612/604/612 624/630/624 387/1334/387 f 621/628/621 387/1334/387 624/630/624 f 604/595/604 44/22/44 28/5/28 f 472/605/472 612/604/612 467/1333/467 f 29/6/29 28/5/28 47/26/47 f 43/21/43 48/25/48 44/22/44 f 30/7/30 266/1335/266 27/8/27 f 424/414/424 239/223/239 425/415/425 f 467/458/467 363/347/363 472/463/472 f 561/552/561 560/553/560 572/564/572 f 549/540/549 551/542/551 579/571/579 f 583/574/583 595/588/595 582/575/582 f 31/12/31 36/13/36 600/591/600 f 39/16/39 44/22/44 603/597/603 f 32/9/32 599/592/599 45/23/45 f 473/626/473 613/607/613 471/606/471 f 477/620/477 478/625/478 620/621/620 f 474/611/474 615/610/615 617/627/617 f 1257/1336/1257 614/609/614 618/616/618 f 1257/1336/1257 620/621/620 622/624/622 f 1257/1336/1257 618/616/618 619/619/619 f 1257/1336/1257 613/607/613 615/610/615 f 614/609/614 1257/1336/1257 615/610/615 f 622/624/622 623/629/623 1257/1336/1257 f 1257/1336/1257 623/629/623 611/603/611 f 624/630/624 623/629/623 621/628/621 f 469/617/469 618/616/618 470/615/470 f 614/609/614 476/608/476 533/614/533 f 610/602/610 1257/1336/1257 611/603/611 f 613/607/613 1257/1336/1257 610/602/610 f 620/621/620 1257/1336/1257 619/619/619 f 541/532/541 592/584/592 562/555/562 f 541/532/541 587/581/587 592/584/592 f 627/633/627 607/599/607 605/596/605 f 627/633/627 605/596/605 604/595/604 f 605/596/605 606/598/606 603/597/603 f 607/599/607 606/598/606 605/596/605 f 1207/1254/1207 1082/1337/1082 1015/1338/1015 f 1219/1280/1219 1207/1254/1207 1015/1338/1015 f 1015/1338/1015 1216/1278/1216 1219/1280/1219 f 693/710/693 1198/1247/1198 678/695/678 f 1207/1254/1207 1087/1253/1087 1082/1337/1082 f 678/695/678 677/697/677 694/712/694 f 695/713/695 692/711/692 693/710/693 f 266/1335/266 679/696/679 27/8/27 f 883/903/883 1044/1079/1044 1045/1078/1045 f 992/1020/992 1082/1121/1082 1087/1125/1087 f 1158/1205/1158 1157/1204/1157 1168/1216/1168 f 1147/1194/1147 1145/1192/1145 1176/1223/1176 f 1193/1240/1193 1180/1227/1180 1179/1226/1179 f 684/702/684 682/699/682 1195/1242/1195 f 693/710/693 686/707/686 1199/1245/1199 f 599/592/599 681/698/681 45/23/45 f 1208/1256/1208 1088/1276/1088 1086/1257/1086 f 1093/1274/1093 1092/1271/1092 1215/1270/1215 f 1210/1260/1210 1090/1259/1090 1212/1277/1212 f 1209/1261/1209 1258/1339/1258 1213/1264/1213 f 1215/1270/1215 1258/1339/1258 1217/1275/1217 f 1213/1264/1213 1258/1339/1258 1214/1267/1214 f 1208/1256/1208 1258/1339/1258 1210/1260/1210 f 1258/1339/1258 1209/1261/1209 1210/1260/1210 f 1218/1279/1218 1217/1275/1217 1258/1339/1258 f 1218/1279/1218 1258/1339/1258 1205/1255/1205 f 1218/1279/1218 1219/1280/1219 1216/1278/1216 f 1213/1264/1213 1083/1269/1083 1085/1265/1085 f 1091/1258/1091 1209/1261/1209 1131/1266/1131 f 1258/1339/1258 1206/1252/1206 1205/1255/1205 f 1258/1339/1258 1208/1256/1208 1206/1252/1206 f 1258/1339/1258 1215/1270/1215 1214/1267/1214 f 1189/1236/1189 1138/1184/1138 1160/1207/1160 f 1185/1231/1185 1138/1184/1138 1189/1236/1189 f 1202/1248/1202 1220/1281/1220 1200/1246/1200 f 1200/1246/1200 1220/1281/1220 1198/1247/1198 f 1201/1249/1201 1200/1246/1200 1199/1245/1199 f 1201/1249/1201 1202/1248/1202 1200/1246/1200 # 2492 faces ================================================ FILE: graphics/tiny-renderer/lesson3.workbook/Geometry.csx ================================================ struct Vec2f { public float x; public float y; public float this [int i] { get { if (i == 0) return x; if (i == 1) return y; throw new InvalidOperationException (); } set { if (i == 0) x = value; else if (i == 1) y = value; else throw new InvalidOperationException (); } } public Vec2f Normalize () { return this / Norm (); } public float Norm () { return (float)Math.Sqrt (x * x + y * y); } public static Vec2f operator / (Vec2f v, float num) { v.x /= num; v.y /= num; return v; } public static Vec2f operator * (Vec2f v, float num) { v.x *= num; v.y *= num; return v; } public static Vec2f operator - (Vec2f a, Vec2f b) { return new Vec2f { x = a.x - b.x, y = a.y - b.y }; } public static Vec2f operator + (Vec2f a, Vec2f b) { return new Vec2f { x = a.x + b.x, y = a.y + b.y }; } } public struct Vec3f { public float x; public float y; public float z; public float this [int i] { get { switch (i) { case 0: return x; case 1: return y; case 2: return z; default: throw new InvalidOperationException (); } } set { switch (i) { case 0: x = value; break; case 1: y = value; break; case 2: z = value; break; default: throw new InvalidOperationException (); } } } public Vec3f Normalize () { return this / Norm (); } public float Norm () { return (float)Math.Sqrt (x * x + y * y + z * z); } public static Vec3f operator - (Vec3f a, Vec3f b) { return new Vec3f { x = a.x - b.x, y = a.y - b.y, z = a.z - b.z }; } public static Vec3f operator / (Vec3f v, float num) { v.x /= num; v.y /= num; v.z /= num; return v; } public static Vec3f operator * (Vec3f v, float num) { v.x *= num; v.y *= num; v.z *= num; return v; } } struct Vec4f { public float x; public float y; public float z; public float h; public float this [int i] { get { switch (i) { case 0: return x; case 1: return y; case 2: return z; case 3: return h; default: throw new InvalidOperationException (); } } set { switch (i) { case 0: x = value; break; case 1: y = value; break; case 2: z = value; break; case 3: h = value; break; default: throw new InvalidOperationException (); } } } public Vec4f Normalize () { var len = Norm (); return this / len; } public float Norm () { return (float)Math.Sqrt (x * x + y * y + z * z + h * h); } public static Vec4f operator - (Vec4f a, Vec4f b) { return new Vec4f { x = a.x - b.x, y = a.y - b.y, z = a.z - b.z, h = a.h - b.h }; } public static Vec4f operator / (Vec4f v, float num) { v.x /= num; v.y /= num; v.z /= num; v.h /= num; return v; } } struct Vec2i { public int x; public int y; public static Vec2i operator - (Vec2i a, Vec2i b) { return new Vec2i { x = a.x - b.x, y = a.y - b.y }; } } struct Vec3i { public int x; public int y; public int z; public static Vec3i operator - (Vec3i a, Vec3i b) { return new Vec3i { x = a.x - b.x, y = a.y - b.y, z = a.z - b.z }; } } static class Geometry { public static Vec3f Cross (Vec3f l, Vec3f r) { return new Vec3f { x = l.y * r.z - l.z * r.y, y = l.z * r.x - l.x * r.z, z = l.x * r.y - l.y * r.x }; } public static float Dot (Vec3f l, Vec3f r) { return l.x * r.x + l.y * r.y + l.z * r.z; } public static Vec4f Embed4D (Vec3f v, float fill = 1) { return new Vec4f { x = v.x, y = v.y, z = v.z, h = fill }; } public static Vec2f Project2D (Vec3f v) { return new Vec2f { x = v.x, y = v.y }; } public static Vec2f Project2D (Vec4f v) { return new Vec2f { x = v.x, y = v.y }; } public static Vec3f Project3D (Vec4f v) { return new Vec3f { x = v.x, y = v.y, z = v.z }; } } ================================================ FILE: graphics/tiny-renderer/lesson3.workbook/Image.csx ================================================ using System.IO; enum Format { GRAYSCALE = 1, BGR = 3, BGRA = 4 } struct Color { // the value stored as little endian: // ARGB -> BGRA // xRGB -> BGRx public readonly int value; public readonly Format format; public byte this [int offset] { get { if (offset > 3) // int has only 4 bytes (0, 1, 2, 3) throw new ArgumentOutOfRangeException (); return (byte)(value >> 8 * (3 - offset)); } } public static Color Red = new Color (red: 255, green: 0, blue: 0, alpha: 255); public static Color Green = new Color (red: 0, green: 255, blue: 0, alpha: 255); public static Color Blue = new Color (red: 0, green: 0, blue: 255, alpha: 255); public static Color Black = new Color (red: 0, green: 0, blue: 0, alpha: 255); public static Color White = new Color (red: 255, green: 255, blue: 255, alpha: 255); public static Color Yellow = new Color (red: 225, green: 225, blue: 0, alpha: 255); public Color (byte red, byte green, byte blue, byte alpha) : this ((blue << 24) | (green << 16) | (red << 8) | alpha, Format.BGRA) { } public Color (byte red, byte green, byte blue) : this ((blue << 24) | (green << 16) | (red << 8) | 0xFF, Format.BGR) { } public Color (byte value) : this (value, Format.GRAYSCALE) { } public Color (int value, Format format) { this.value = value; this.format = format; } public static Color operator * (Color color, float intensivity) { intensivity = Math.Max (0f, Math.Min (1f, intensivity)); var ch0 = (byte)(color [0] * intensivity); var ch1 = (byte)(color [1] * intensivity); var ch2 = (byte)(color [2] * intensivity); var ch3 = color [3]; return new Color (ch0 << 24 | ch1 << 16 | ch2 << 8 | ch3, color.format); } } class Image { internal byte [] buffer; public int Width { get; } public int Height { get; } public Format Format { get; } public int BytesPerRow { get { return Width * (int)Format; } } public Image (int width, int height, Format format) { Width = width; Height = height; Format = format; buffer = new byte [height * BytesPerRow]; } public void VerticalFlip () { var bpp = (int)Format; int bytesPerLine = Width * bpp; var half = Height >> 1; for (int l = 0; l < half; l++) { var l1 = l * bytesPerLine; var l2 = (Height - 1 - l) * bytesPerLine; for (int i = 0; i < bytesPerLine; i++) { byte pixel = buffer [l1 + i]; buffer [l1 + i] = buffer [l2 + i]; buffer [l2 + i] = pixel; } } } public void Clear () { for (int i = 0; i < buffer.Length; i++) buffer [i] = 0; } public Color this [int x, int y] { get { if (x < 0 || x >= Width) throw new ArgumentException ("x"); if (y < 0 || y >= Height) throw new ArgumentException ("y"); var offset = GetOffset (x, y); var len = (int)Format; int value = 0; for (var ch = 0; ch < 4; ch++) value = (value << 8) | (ch < len ? buffer [offset++] : 0xFF); return new Color (value, Format); } set { if (x < 0 || x >= Width) return; //throw new ArgumentException ($"{nameof(x)}={x} {nameof(Width)}={Width}"); if (y < 0 || y >= Height) return; // throw new ArgumentException ($"{nameof(y)}={y} {nameof(Height)}={Height}"); var offset = GetOffset (x, y); var v = value.value; var len = (int)Format; for (int ch = 0; ch < len; ch++) // 0123 buffer [offset++] = (byte)(v >> (3 - ch) * 8); // BGRA } } int GetOffset (int x, int y) { return y * BytesPerRow + x * (int)Format; } public bool WriteToFile (string path, bool rle = true) { var bpp = (int)Format; using (var writer = new BinaryWriter (File.Create (path))) { var header = new TGAHeader { IdLength = 0, // The IDLength set to 0 indicates that there is no image identification field in the TGA file ColorMapType = 0, // a value of 0 indicates that no palette is included BitsPerPixel = (byte)(bpp * 8), Width = (short)Width, Height = (short)Height, DataTypeCode = DataTypeFor (bpp, rle), ImageDescriptor = (byte)(0x20 | (Format == Format.BGRA ? 8 : 0)) // top-left origin }; WriteTo (writer, header); if (!rle) writer.Write (buffer); else UnloadRleData (writer); } return true; } public static Image Load (string path) { using (var reader = new BinaryReader (File.OpenRead (path))) { var header = ReadHeader (reader); var height = header.Height; var width = header.Width; var bytespp = header.BitsPerPixel >> 3; var format = (Format)bytespp; if (width <= 0 || height <= 0) throw new InvalidProgramException ($"bad image size: width={width} height={height}"); if (format != Format.BGR && format != Format.BGRA && format != Format.GRAYSCALE) throw new InvalidProgramException ($"unknown format {format}"); var img = new Image (width, height, format); switch (header.DataTypeCode) { case DataType.UncompressedTrueColorImage: case DataType.UncompressedBlackAndWhiteImage: reader.Read (img.buffer, 0, img.buffer.Length); break; case DataType.RleTrueColorImage: case DataType.RleBlackAndWhiteImage: img.LoadRleData (reader); break; default: throw new InvalidProgramException ($"unsupported image format {header.DataTypeCode}"); } if ((header.ImageDescriptor & 0x20) == 0) img.VerticalFlip (); return img; } } static void WriteTo (BinaryWriter writer, TGAHeader header) { writer.Write (header.IdLength); writer.Write (header.ColorMapType); writer.Write ((byte)header.DataTypeCode); writer.Write (header.ColorMapOrigin); writer.Write (header.ColorMapLength); writer.Write (header.ColorMapDepth); writer.Write (header.OriginX); writer.Write (header.OriginY); writer.Write (header.Width); writer.Write (header.Height); writer.Write (header.BitsPerPixel); writer.Write (header.ImageDescriptor); } static TGAHeader ReadHeader (BinaryReader reader) { var header = new TGAHeader { IdLength = reader.ReadByte (), ColorMapType = reader.ReadByte (), DataTypeCode = (DataType)reader.ReadByte (), ColorMapOrigin = reader.ReadInt16 (), ColorMapLength = reader.ReadInt16 (), ColorMapDepth = reader.ReadByte (), OriginX = reader.ReadInt16 (), OriginY = reader.ReadInt16 (), Width = reader.ReadInt16 (), Height = reader.ReadInt16 (), BitsPerPixel = reader.ReadByte (), ImageDescriptor = reader.ReadByte () }; return header; } bool UnloadRleData (BinaryWriter writer) { const int max_chunk_length = 128; int npixels = Width * Height; int curpix = 0; var bpp = (int)Format; while (curpix < npixels) { int chunkstart = curpix * bpp; int curbyte = curpix * bpp; int run_length = 1; bool literal = true; while (curpix + run_length < npixels && run_length < max_chunk_length && curpix + run_length < curpix + Width) { bool succ_eq = true; for (int t = 0; succ_eq && t < bpp; t++) succ_eq = (buffer [curbyte + t] == buffer [curbyte + t + bpp]); curbyte += bpp; if (1 == run_length) literal = !succ_eq; if (literal && succ_eq) { run_length--; break; } if (!literal && !succ_eq) break; run_length++; } curpix += run_length; writer.Write ((byte)(literal ? run_length - 1 : 128 + (run_length - 1))); writer.Write (buffer, chunkstart, literal ? run_length * bpp : bpp); } return true; } void LoadRleData (BinaryReader reader) { var pixelcount = Width * Height; var currentpixel = 0; var currentbyte = 0; var bytespp = (int)Format; var color = new byte [4]; do { var chunkheader = reader.ReadByte (); if (chunkheader < 128) { chunkheader++; for (int i = 0; i < chunkheader; i++) { for (int t = 0; t < bytespp; t++) buffer [currentbyte++] = reader.ReadByte (); currentpixel++; if (currentpixel > pixelcount) throw new InvalidProgramException ("Too many pixels read"); } } else { chunkheader -= 127; reader.Read (color, 0, bytespp); for (int i = 0; i < chunkheader; i++) { for (int t = 0; t < bytespp; t++) buffer [currentbyte++] = color [t]; currentpixel++; if (currentpixel > pixelcount) throw new InvalidProgramException ("Too many pixels read"); } } } while (currentpixel < pixelcount); } static DataType DataTypeFor (int bpp, bool rle) { var format = (Format)bpp; if (format == Format.GRAYSCALE) return rle ? DataType.RleBlackAndWhiteImage : DataType.UncompressedBlackAndWhiteImage; return rle ? DataType.RleTrueColorImage : DataType.UncompressedTrueColorImage; } } struct TGAHeader { public byte IdLength; public byte ColorMapType; public DataType DataTypeCode; // field #4. Color map specification public short ColorMapOrigin; // index of first color map entry that is included in the file public short ColorMapLength; // number of entries of the color map that are included in the file public byte ColorMapDepth; // number of bits per pixel // field #5. Image specification public short OriginX; // absolute coordinate of lower-left corner for displays where origin is at the lower left public short OriginY; // as for X-origin public short Width; // width in pixels public short Height; // height in pixels public byte BitsPerPixel; // pixel depth public byte ImageDescriptor; // bits 3-0 give the alpha channel depth, bits 5-4 give direction } public enum DataType : byte { NoImageData = 0, // no image data is present UncompressedColorMappedImage = 1, UncompressedTrueColorImage = 2, UncompressedBlackAndWhiteImage = 3, RleColorMappedImage = 9, // run-length encoded color-mapped image RleTrueColorImage = 10, // run-length encoded true-color image RleBlackAndWhiteImage = 11 // run-length encoded black-and-white (grayscale) image } ================================================ FILE: graphics/tiny-renderer/lesson3.workbook/ImageResultHandler.csx ================================================ using XIR = Xamarin.Interactive.Representations; InteractiveAgent.RepresentationManager.AddProvider (img => { XIR.ImageFormat format; switch (img.Format) { case Format.BGRA: format = XIR.ImageFormat.Bgra32; break; case Format.BGR: format = XIR.ImageFormat.Bgr24; break; default: return null; } return new XIR.Image (format, img.buffer, img.Width, img.Height); }); ================================================ FILE: graphics/tiny-renderer/lesson3.workbook/LICENSE.txt ================================================ Tiny Renderer, https://github.com/ssloy/tinyrenderer Copyright Dmitry V. Sokolov This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. ================================================ FILE: graphics/tiny-renderer/lesson3.workbook/Matrix.csx ================================================ using System; public struct Matrix4 { public const int Len = 4; public float R0C0, R0C1, R0C2, R0C3; public float R1C0, R1C1, R1C2, R1C3; public float R2C0, R2C1, R2C2, R2C3; public float R3C0, R3C1, R3C2, R3C3; public float this [int row, int column] { get { switch (row) { case 0: switch (column) { case 0: return R0C0; case 1: return R0C1; case 2: return R0C2; case 3: return R0C3; } break; case 1: switch (column) { case 0: return R1C0; case 1: return R1C1; case 2: return R1C2; case 3: return R1C3; } break; case 2: switch (column) { case 0: return R2C0; case 1: return R2C1; case 2: return R2C2; case 3: return R2C3; } break; case 3: switch (column) { case 0: return R3C0; case 1: return R3C1; case 2: return R3C2; case 3: return R3C3; } break; } throw new IndexOutOfRangeException (); } set { switch (row) { case 0: switch (column) { case 0: R0C0 = value; return; case 1: R0C1 = value; return; case 2: R0C2 = value; return; case 3: R0C3 = value; return; } break; case 1: switch (column) { case 0: R1C0 = value; return; case 1: R1C1 = value; return; case 2: R1C2 = value; return; case 3: R1C3 = value; return; } break; case 2: switch (column) { case 0: R2C0 = value; return; case 1: R2C1 = value; return; case 2: R2C2 = value; return; case 3: R2C3 = value; return; } break; case 3: switch (column) { case 0: R3C0 = value; return; case 1: R3C1 = value; return; case 2: R3C2 = value; return; case 3: R3C3 = value; return; } break; } throw new IndexOutOfRangeException (); } } public Matrix4 Transpose () { return new Matrix4 { R0C0 = R0C0, R0C1 = R1C0, R0C2 = R2C0, R0C3 = R3C0, R1C0 = R0C1, R1C1 = R1C1, R1C2 = R2C1, R1C3 = R3C1, R2C0 = R0C2, R2C1 = R1C2, R2C2 = R2C2, R2C3 = R3C2, R3C0 = R0C3, R3C1 = R1C3, R3C2 = R2C3, R3C3 = R3C3 }; } public static Matrix4 Identity () { return new Matrix4 { R0C0 = 1, R1C1 = 1, R2C2 = 1, R3C3 = 1 }; } public static Matrix4 Zoom (float scale) { return new Matrix4 { R0C0 = scale, R1C1 = scale, R2C2 = scale, R3C3 = scale }; } public static Matrix4 RotationZ (float angle) { var cosangle = (float)Math.Cos (angle); var sinangle = (float)Math.Sin (angle); var R = Identity (); R [0, 0] = R [1, 1] = cosangle; R [0, 1] = -sinangle; R [1, 0] = sinangle; return R; } public static Matrix4 operator * (Matrix4 l, Matrix4 r) { var result = new Matrix4 (); for (int i = 0; i < Len; i++) { for (int j = 0; j < Len; j++) { result [i, j] = 0; for (int k = 0; k < Len; k++) { result [i, j] += l [i, k] * r [k, j]; } } } return result; } public override string ToString () { var sb = new System.Text.StringBuilder (); for (int r = 0; r < Len; r++) { for (int c = 0; c < Len; c++) sb.Append (this[r, c]).Append (" "); sb.AppendLine (); } return sb.ToString (); } } public struct Matrix3 { public const int Len = 3; public float R0C0, R0C1, R0C2; public float R1C0, R1C1, R1C2; public float R2C0, R2C1, R2C2; public float this [int row, int column] { get { switch (row) { case 0: switch (column) { case 0: return R0C0; case 1: return R0C1; case 2: return R0C2; } break; case 1: switch (column) { case 0: return R1C0; case 1: return R1C1; case 2: return R1C2; } break; case 2: switch (column) { case 0: return R2C0; case 1: return R2C1; case 2: return R2C2; } break; } throw new IndexOutOfRangeException (); } set { switch (row) { case 0: switch (column) { case 0: R0C0 = value; return; case 1: R0C1 = value; return; case 2: R0C2 = value; return; } break; case 1: switch (column) { case 0: R1C0 = value; return; case 1: R1C1 = value; return; case 2: R1C2 = value; return; } break; case 2: switch (column) { case 0: R2C0 = value; return; case 1: R2C1 = value; return; case 2: R2C2 = value; return; } break; } throw new IndexOutOfRangeException (); } } public Matrix3 Transpose () { return new Matrix3 { R0C0 = R0C0, R0C1 = R1C0, R0C2 = R2C0, R1C0 = R0C1, R1C1 = R1C1, R1C2 = R2C1, R2C0 = R0C2, R2C1 = R1C2, R2C2 = R2C2 }; } public void SetColumn (int col, Vec3f v) { this [0, col] = v.x; this [1, col] = v.y; this [2, col] = v.z; } public void SetRow (int row, Vec3f v) { this [row, 0] = v.x; this [row, 1] = v.y; this [row, 2] = v.z; } public override string ToString () { var sb = new System.Text.StringBuilder (); for (int r = 0; r < Len; r++) { for (int c = 0; c < Len; c++) sb.Append (this [r, c]).Append (" "); sb.AppendLine (); } return sb.ToString (); } } public struct Matrix2 { public const int Len = 2; public float R0C0, R0C1; public float R1C0, R1C1; public float this [int row, int column] { get { switch (row) { case 0: switch (column) { case 0: return R0C0; case 1: return R0C1; } break; case 1: switch (column) { case 0: return R1C0; case 1: return R1C1; } break; } throw new IndexOutOfRangeException (); } set { switch (row) { case 0: switch (column) { case 0: R0C0 = value; return; case 1: R0C1 = value; return; } break; case 1: switch (column) { case 0: R1C0 = value; return; case 1: R1C1 = value; return; } break; } throw new IndexOutOfRangeException (); } } } // we don't want to declare them in Matrix because we don't need them in lesson which introduces Matrix class static class MatrixHelpers { // For Matrix4 // how to calc inverse Matrix https://en.wikipedia.org/w/index.php?title=Invertible_matrix§ion=4#In_relation_to_its_adjugate public static Matrix4 TransposeInverse (Matrix4 m) { // returns Transpose(Inverse(m)) // where Inverse(m) = Transpose(cofactor) / det(m) // Transpose(Inverse(m)) = Transpose(Transpose(cofactor) / det(m)) = cofactor / det(m) var cofactor = Cofactor (m); float det = 0; for (int i = 0; i < Matrix4.Len; i++) det += m [0, i] * cofactor [0, i]; for (int r = 0; r < Matrix4.Len; r++) { for (int c = 0; c < Matrix4.Len; c++) cofactor [r, c] /= det; } return cofactor; } public static Matrix4 Inverse (Matrix4 m) { // where Inverse(m) = Transpose(Cofactor(m)) / det(m) var cofactor = Cofactor (m); int len = Matrix4.Len; float det = 0; for (int i = 0; i < len; i++) det += m [0, i] * cofactor [0, i]; cofactor = cofactor.Transpose (); for (int r = 0; r < len; r++) { for (int c = 0; c < len; c++) cofactor [r, c] /= det; } return cofactor; } public static Matrix3 Inverse (Matrix3 m) { // where Inverse(m) = Transpose(Cofactor(m)) / det(m) var cofactor = Cofactor (m); int len = Matrix3.Len; float det = 0; for (int i = 0; i < len; i++) det += m [0, i] * cofactor [0, i]; cofactor = cofactor.Transpose (); for (int r = 0; r < len; r++) { for (int c = 0; c < len; c++) cofactor [r, c] /= det; } return cofactor; } static Matrix4 Cofactor (Matrix4 m) { var r = new Matrix4 (); for (int row = 0; row < Matrix4.Len; row++) { for (int col = 0; col < Matrix4.Len; col++) r [row, col] = Cofactor (m, row, col); } return r; } static Matrix3 Cofactor (Matrix3 m) { var r = new Matrix3 (); for (int row = 0; row < Matrix3.Len; row++) { for (int col = 0; col < Matrix3.Len; col++) r [row, col] = Cofactor (m, row, col); } return r; } static float Cofactor (Matrix4 m, int row, int col) { int sign = ((row + col) % 2 == 0) ? 1 : -1; return Det (Minor (m, row, col)) * sign; } static float Cofactor (Matrix3 m, int row, int col) { int sign = ((row + col) % 2 == 0) ? 1 : -1; return Det (Minor (m, row, col)) * sign; } static Matrix3 Minor (Matrix4 m, int row, int col) { var minor = new Matrix3 (); for (int r = 0; r < Matrix3.Len; r++) { for (int c = 0; c < Matrix3.Len; c++) { int y = (r < row) ? r : r + 1; int x = (c < col) ? c : c + 1; minor [r, c] = m [y, x]; } } return minor; } static Matrix2 Minor (Matrix3 m, int row, int col) { var minor = new Matrix2 (); for (int r = 0; r < Matrix2.Len; r++) { for (int c = 0; c < Matrix2.Len; c++) { int y = (r < row) ? r : r + 1; int x = (c < col) ? c : c + 1; minor [r, c] = m [y, x]; } } return minor; } static float Det (Matrix3 m) { float det = 0; det += m [0, 0] * (m [1, 1] * m [2, 2] - m [1, 2] * m [2, 1]); det -= m [0, 1] * (m [1, 0] * m [2, 2] - m [1, 2] * m [2, 0]); det += m [0, 2] * (m [1, 0] * m [2, 1] - m [1, 1] * m [2, 0]); return det; } static float Det (Matrix2 m) { return m [0, 0] * m [1, 1] - m [0, 1] * m [1, 0]; } public static Vec3f Mult (Matrix3 m, Vec3f v) { return new Vec3f { x = m.R0C0 * v.x + m.R0C1 * v.y + m.R0C2 * v.z, y = m.R1C0 * v.x + m.R1C1 * v.y + m.R1C2 * v.z, z = m.R2C0 * v.x + m.R2C1 * v.y + m.R2C2 * v.z }; } public static Vec4f Mult (Matrix4 m, Vec4f v) { return new Vec4f { x = m.R0C0*v.x + m.R0C1*v.y + m.R0C2*v.z + m.R0C3*v.h, y = m.R1C0*v.x + m.R1C1*v.y + m.R1C2*v.z + m.R1C3*v.h, z = m.R2C0*v.x + m.R2C1*v.y + m.R2C2*v.z + m.R2C3*v.h, h = m.R3C0*v.x + m.R3C1*v.y + m.R3C2*v.z + m.R3C3*v.h }; } } ================================================ FILE: graphics/tiny-renderer/lesson3.workbook/Model.csx ================================================ using System.Collections.Generic; using System.Linq; struct Face { public int [] Vertices; public int [] Textures; public int [] Normals; } class Model { public List Vertices { get; } = new List (); public List Faces { get; } = new List (); public List Textures { get; } = new List (); public List Normals { get; } = new List (); public static Model FromFile (string path) { var model = new Model (); string line; using (var reader = new System.IO.StreamReader (path)) { while ((line = reader.ReadLine ()) != null) model.ParseLine (line); } Console.WriteLine ($"v#{model.Vertices.Count} f#{model.Faces.Count}"); return model; } public static Model FromText (string text) { var model = new Model (); var lines = text.Split (new char [] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); foreach (var line in lines) model.ParseLine (line); Console.WriteLine ($"v#{model.Vertices.Count} f#{model.Faces.Count}"); return model; } void ParseLine (string line) { Func parseV3f = strItems => new Vec3f { x = float.Parse (strItems [1]), y = float.Parse (strItems [2]), z = float.Parse (strItems [3]) }; var items = line.Split (new char [] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (line.StartsWith ("v ", StringComparison.InvariantCulture)) { Vertices.Add (parseV3f (items)); } else if (line.StartsWith ("vt ", StringComparison.InvariantCulture)) { Textures.Add (parseV3f (items)); } else if (line.StartsWith ("vn ", StringComparison.InvariantCulture)) { Normals.Add (parseV3f (items)); } else if (line.StartsWith ("f ", StringComparison.InvariantCulture)) { var indexes = items.Skip (1) .SelectMany (s => s.Split (new char [] { '/', ' ' }, StringSplitOptions.RemoveEmptyEntries)) .Select (s => int.Parse (s) - 1) // in wavefront obj all indices start at 1, not zero .ToArray (); Faces.Add (new Face { Vertices = indexes.Where ((v, index) => index % 3 == 0).ToArray (), Textures = indexes.Where ((v, index) => index % 3 == 1).ToArray (), Normals = indexes.Where ((v, index) => index % 3 == 2).ToArray () }); } } public Vec3f Normal (Face face, int nthvert) { int idx = face.Normals [nthvert]; return Normals [idx]; } public Vec3f Vertex (Face face, int nthvert) { int idx = face.Vertices [nthvert]; return Vertices [idx]; } public Vec3f GetUV (Face face, int nthvert) { int idx = face.Textures [nthvert]; return Textures [idx]; } } ================================================ FILE: graphics/tiny-renderer/lesson3.workbook/WpfImageResultHandler.csx ================================================ using System; using System.IO; using System.Windows.Media; using System.Windows.Media.Imaging; using XIR = Xamarin.Interactive.Representations; static PixelFormat ConvertFormat (Format format) { switch (format) { case Format.BGRA: return PixelFormats.Bgra32; case Format.GRAYSCALE: return PixelFormats.Gray8; case Format.BGR: default: return PixelFormats.Bgr24; } } InteractiveAgent.RepresentationManager.AddProvider (img => { var source = BitmapSource.Create (img.Width, img.Height, 96, 96, ConvertFormat (img.Format), null, img.buffer, img.BytesPerRow); var encoder = new PngBitmapEncoder (); var outputFrame = BitmapFrame.Create (source); encoder.Frames.Add (outputFrame); using (var memory = new MemoryStream ()) { encoder.Save (memory); return XIR.Image.FromPng (memory.GetBuffer (), img.Width, img.Height); } }); ================================================ FILE: graphics/tiny-renderer/lesson3.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" #load "lesson1.csx" #load "lesson2.csx" using static Geometry; ``` # **Lesson 3: Hidden faces removal (z buffer)** > ℹ️ This workbook is a port of an [excellent C++ series](https://github.com/ssloy/tinyrenderer/wiki) written by Dmitry Sokolov. We appreciate that original work is available under a license that allowed us to turn it into a Workbook. # Introduction Hello, let me introduce you my friend z-buffer of a black guy. He will help us get rid of the visual artifacts of the hidden faces removal we had during the last lesson. ![](./img/lesson3_face1.png) By the way, i'd like to mention that this model i use heavily in the course is created by [Vidar Rapp](https://se.linkedin.com/in/vidarrapp). He kindely granted me a permission to use it for teaching rendering basics and i vandalized it, but i promise you to give back the eyes to the guy. Well, back to the topic, in theory we could just draw all the triangles without discarding any. If we do it properly starting rear-to-front, the front facets will erase the back ones. It is called the [painter's algorithm](http://en.wikipedia.org/wiki/Painter%27s_algorithm). Unfortunately, it comes along with a high computational cost: for each camera movement we need to re-sort all the scene. And then there are dynamic scenes... And this is not even the main problem. The main problem is it is not always possible to determine the correct order. # **Let us try to render a simple scene** Imagine a simple scene made of three triangles: the camera looks up-to-down, we project the colored triangles onto the white screen: ![ ](./img/lesson3_scene1.png) The render should look like this: ![ ](./img/lesson3_scene2.png) Blue facet - is it behind or in front of the red one? The painter's algorithm does not work here. It is possible to split blue facet in two (one in front of the red facet and one behind). And then the one in front of the red one is to be split in two - one in front of the green triangle and one behind... I think you get the problem: in scenes with millions of triangles it is really expensive to compute. It is possible to use [BSP trees](https://en.wikipedia.org/wiki/Binary_space_partitioning) to get it done. By the way, this data structure is constant for moving camera, but it is really messy. And the life is too short to get it messy. # **Even simpler: let us lose a dimension. Y-buffer!** Let us lose a dimension for a while and to cut the above scene along the yellow plane: ![ ](./img/lesson3_scene3.png) I mean, now our scene is made of three line segments (intersection of the yellow plane and each of the triangles), and the final render has a normal width but 1 pixel height: ![ ](./img/lesson3_scene4.png) Our scene is two-dimensional, so it is easy to draw it using the line() function we programmed in the very first lesson. ```csharp var scene = new Image (800, 500, Format.BGR); // scene "2d mesh" Line(scene, new Vec2i {x=20, y=34}, new Vec2i {x=744, y=400}, Color.Red); Line(scene, new Vec2i {x=120, y=434}, new Vec2i {x=444, y=400}, Color.Green); Line(scene, new Vec2i {x=330, y=463}, new Vec2i {x=594, y=200}, Color.Blue); // screen line Line(scene, new Vec2i {x=10, y=10}, new Vec2i{x=790, y=10}, Color.White); scene.VerticalFlip(); // I want to have the origin at the left bottom corner of the image scene // This is how our 2D scene looks like if we look at it sideways: ``` Let us render it. Recall that the render is 1 pixel height. In my source code I create images 16 pixels height for the ease of reading on high resolution screens. `Rasterize()` function writes only in the first line of the image `render` ```csharp void Rasterize(Image image, Vec2i p0, Vec2i p1, int[] ybuffer, Color color) { if (p0.x>p1.x) Swap(ref p0, ref p1); for (int x=p0.x; x<=p1.x; x++) { float t = (x-p0.x)/(float)(p1.x-p0.x); var y = (int)(p0.y*(1-t) + p1.y*t); if (ybuffer[x] < y) { ybuffer[x] = y; image[x, 0] = color; } } } var ybuffer = new int [width]; for (int i = 0; i < width; i++) ybuffer[i] = int.MinValue; var render = new Image (width, 16, Format.BGR); Rasterize(render, new Vec2i{x=20,y=34}, new Vec2i{x=744, y=400}, ybuffer, Color.Red); Rasterize(render, new Vec2i{x=120, y=434}, new Vec2i{x=444,y=400}, ybuffer, Color.Green); Rasterize(render, new Vec2i{x=330, y=463}, new Vec2i{x=594,y=200}, ybuffer, Color.Blue); render ``` It is really-really simple: I iterate through all x-coordinates between `p0.x` and `p1.x` and compute the corresponding y-coordinate of the segment. Then I check what we got in our array `ybuffer` with current `x` index. If the current `y`-value is closer to the camera than the value in the `ybuffer`, then I draw it on the screen and update the `ybuffer`. Let us see it step-by-step. After calling `Rasterize()` on the first (red) segment this is our memory: screen:![](./img/lesson3_rasterize1.png) ybuffer: ![ ](./img/lesson3_rasterize2.png) Here the magenta color indicates the minus infinity, those are places corresponding to the screen we did not touch. All the rest is shown in the shades of gray: clear colors are close to the camera, dark colors far from the camera. Then we draw the green segment. screen:![ ](./img/lesson3_rasterize3.png) ybuffer:![ ](./img/lesson3_rasterize4.png) And finally the blue one. screen:![ ](./img/lesson3_rasterize5.png) ybuffer:![ ](./img/lesson3_rasterize6.png) Congratulations, we just drew a 2D scene on a 1D screen! Let us admire once again the render: ![ ](./img/lesson3_rasterize7.png) # Back to 3D So, for drawing on a 2D screen the z-buffer must be two-dimensional: `var zbuffer = new int[width * height];` Personally I pack a two-dimensional buffer into a one-dimensional, the conversion is trivial: `var idx = x + y* width;` and the back one: `var x = idx % width;`\ `var y = idx % width;` Then in the code I simply iterate through all the triangles and call the rasterizer function with current triangle and a reference to the z-buffer. The only difficulty is how to compute the z-value of a pixel we want to draw. Let us recall how we computed the y-value in the y-buffer example: `int y = p0.y*(1-t) + p1.y*t;` What is the nature of the `t` variable? It turns out that `(1-t, t)` are barycentric coordinates of the point `(x,y)` with respect to the segment `p0, p1: (x,y) = p0*(1-t) + p1*t`. So the idea is to take the barycentric coordinates version of triangle rasterization, and for every pixel we want to draw simply to multiply its barycentric coordinates by the z-values of the vertices of the triangle we rasterize: ```csharp Vec3f Barycentric (Vec2f a, Vec2f b, Vec2f c, Vec2f p) { var ab = b - a; var ac = c - a; var pa = a - p; var r = Cross (new Vec3f { x = ab.x, y = ac.x, z = pa.x }, new Vec3f { x = ab.y, y = ac.y, z = pa.y }); // triangle is degenerate, in this case return smth with negative coordinates // dont forget that r.z is integer. If it is zero then triangle ABC is degenerate if ((int)r.z == 0) return new Vec3f { x = -1, y = 1, z = 1 }; return new Vec3f { x = 1 - (r.x + r.y) / r.z, y = r.x / r.z, z = r.y / r.z }; } void Triangle (Image image, Vec3f [] coordinates, Color color, float [] zbuffer) { Vec3f t0 = coordinates [0]; Vec3f t1 = coordinates [1]; Vec3f t2 = coordinates [2]; var pMax = new Vec2i { x = (int)Math.Max (0, Math.Max (t0.x, Math.Max (t1.x, t2.x))), y = (int)Math.Max (0, Math.Max (t0.y, Math.Max (t1.y, t2.y))) }; var pMin = new Vec2i { x = (int)Math.Min (image.Width, Math.Min (t0.x, Math.Min (t1.x, t2.x))), y = (int)Math.Min (image.Height, Math.Min (t0.y, Math.Min (t1.y, t2.y))) }; for (int x = pMin.x; x <= pMax.x; x++) { for (int y = pMin.y; y <= pMax.y; y++) { var pixelCenter = new Vec2f { x = x + 0.5f, y = y + 0.5f }; var bc = Barycentric (Project2D (t0), Project2D (t1), Project2D (t2), pixelCenter); if (bc.x < 0 || bc.y < 0 || bc.z < 0) continue; var z = t0.z * bc.x + t1.z * bc.y + t2.z * bc.z; var idx = x + y * image.Width; if (zbuffer [idx] < z) { zbuffer [idx] = z; image [x, y] = color; } } } } float [] InitZBuffer (Image image) { var zbuffer = new float [image.Width * image.Height]; for (int idx = 0; idx < zbuffer.Length; idx++) zbuffer [idx] = float.NegativeInfinity; return zbuffer; } var image = new Image(width, height, Format.BGR); Func map = v => new Vec3f { x = (int)((v.x+1)*(image.Width-1)/2 + 0.5f), y = (int)((v.y+1)*(image.Height-1)/2 + 0.5f), z = v.z }; var zbuffer = InitZBuffer(image); foreach(var face in headModel.Faces) { for(int i=0; i<3; i++) { var vIndex = face.Vertices[i]; world[i] = headModel.Vertices[vIndex]; screen[i] = map(world[i]); } Vec3f n = Cross(world[2] - world[0], world[1] - world[0]).Normalize (); var intensivity = Dot(n, light_dir); if(intensivity > 0) Triangle(image, screen, Color.White * intensivity, zbuffer); } image.VerticalFlip (); image ``` # Okay, we just interpolated the z-values. What else can we do? Texture! In the `.obj` file we have lines starting with `vt u v`, they give an array of texture coordinates. The number in the middle (between the slashes) in the facet lines\ `f x/x/x x/x/x x/x/x` are the texture coordinates of this vertex of this triangle. Interpolate it inside the triangle, multiply by the width-height of the texture image and you will get the color to put in your render. ```csharp void Triangle (Image image, Vec3f [] coordinates, Image texture, Vec2f [] uv, float intensivity, float [] zbuffer) { Vec3f t0 = coordinates [0]; Vec3f t1 = coordinates [1]; Vec3f t2 = coordinates [2]; var pMax = new Vec2i { x = (int)Math.Max (0, Math.Max (t0.x, Math.Max (t1.x, t2.x))), y = (int)Math.Max (0, Math.Max (t0.y, Math.Max (t1.y, t2.y))) }; var pMin = new Vec2i { x = (int)Math.Min (image.Width, Math.Min (t0.x, Math.Min (t1.x, t2.x))), y = (int)Math.Min (image.Height, Math.Min (t0.y, Math.Min (t1.y, t2.y))) }; for (int x = pMin.x; x <= pMax.x; x++) { for (int y = pMin.y; y <= pMax.y; y++) { var pixelCenter = new Vec2f { x = x + 0.5f, y = y + 0.5f }; var bc = Barycentric (Project2D(t0), Project2D(t1), Project2D(t2), pixelCenter); if (bc.x < 0 || bc.y < 0 || bc.z < 0) continue; var z = t0.z * bc.x + t1.z * bc.y + t2.z * bc.z; var u = (int)(uv [0].x * bc.x + uv [1].x * bc.y + uv [2].x * bc.z); var v = (int)(uv [0].y * bc.x + uv [1].y * bc.y + uv [2].y * bc.z); var idx = x + y * image.Width; if (zbuffer [idx] < z) { zbuffer [idx] = z; var color = texture [u, v]; image [x, y] = color * intensivity; } } } } var image = new Image(width, height, Format.BGR); var headTexture = Image.Load ("obj/african_head_diffuse.tga"); headTexture.VerticalFlip (); Func uvMap = v => new Vec2f { x = v.x * (headTexture.Width - 1), y = v.y * (headTexture.Height - 1) }; var zbuffer = InitZBuffer(image); var uv = new Vec2f[3]; var model = headModel; foreach(var face in model.Faces) { for(int i=0; i<3; i++) { var vIndex = face.Vertices[i]; world[i] = model.Vertices[vIndex]; screen[i] = map(world[i]); var tIndex = face.Textures[i]; uv[i] = uvMap(model.Textures[tIndex]); } Vec3f n = Cross(world[2] - world[0], world[1] - world[0]).Normalize (); var intensivity = Dot(n, light_dir); if(intensivity > 0) Triangle(image, screen, headTexture, uv, intensivity, zbuffer); } image.VerticalFlip (); image ``` ================================================ FILE: graphics/tiny-renderer/lesson3.workbook/lesson1.csx ================================================ int width = 800; int height = 800; var headModel = Model.FromFile ("obj/african_head.obj"); static void Swap(ref T x, ref T y) { T t = y; y = x; x = t; } static void Swap(T[] arr, int x, int y) { T t = arr[y]; arr[y] = arr[x]; arr[x] = t; } Image Line (Image image, int x0, int y0, int x1, int y1, Color color) { bool steep = false; // if the line is steep, we transpose the image if (Math.Abs (x0-x1) < Math.Abs (y0-y1)) { Swap (ref x0, ref y0); Swap (ref x1, ref y1); steep = true; } if (x0 > x1) { // make it left to right Swap (ref x0, ref x1); Swap (ref y0, ref y1); } // (x0, y0) == (x1, y1) if(x0 == x1) { image [x0, y0] = color; } else { for (int x = x0; x <= x1; x++) { double t = (x-x0) / (double)(x1-x0); int y = (int)Math.Round(y0*(1-t) + y1*t); if (steep) image [y, x] = color; else image [x, y] = color; } } return image; } ================================================ FILE: graphics/tiny-renderer/lesson3.workbook/lesson1.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" ``` # **Lesson 1: Bresenham’s Line Drawing Algorithm** # First attempt The goal of the first lesson is to render the wire mesh. To do this, we should learn how to draw line segments. We can simply read what Bresenham’s line algorithm is, but let’s write code ourselves. How does the simplest code that draws a line segment between `(x0, y0)` and `(x1, y1)` points look like? Apparently, something like this: ```csharp Image Line (Image image, int x0, int y0, int x1, int y1, Color color) { for (double t = 0; t < 1; t += 0.01) { int x = (int) (x0 * (1-t) + x1 * t); int y = (int) (y0 * (1-t) + y1 * t); image [x, y] = color; } return image; } Line (new Image (100, 100, Format.BGR), x0: 13, y0: 20, x1: 80, y1: 40, color: Color.White); ``` # Second attempt The problem with this code (in addition to efficiency) is the choice of the constant, which I took equal to .01. If we take it equal to .1, our line segment will look like this: ```csharp Image Line (Image image, int x0, int y0, int x1, int y1, Color color) { for (int x = x0; x <= x1; x++) { double t = (x-x0)/(double)(x1-x0); int y = (int)(y0*(1-t) + y1*t); image [x, y] = color; } return image; } Line (new Image (100, 100, Format.BGR), x0: 13, y0: 20, x1: 80, y1: 40, color: Color.White); ``` Caution! The first source of errors in such code of my students is the integer division, like: `(x-x0)/(x1-x0)`. Then, if we try to draw the following lines with this code: ```csharp var image = new Image (100, 100, Format.BGR); Line(image, x0: 13, y0: 20, x1: 80, y1: 40, color: Color.White); Line(image, x0: 20, y0: 13, x1: 40, y1: 80, color: Color.Red); Line(image, x0: 80, y0: 40, x1: 13, y1: 20, color: Color.Red); ``` It turns out that one line is good, the second one is with holes, and there’s no third line at all. Note that the first and the third lines (in the code) draw the same line in different colors, and in different directions (with the source and target points flipped). We have already seen the white one, it is drawn well. I was hoping to change the color of the white line to red, but could not do it. It’s a test for symmetry: the result of drawing a line segment should not depend on the order of points: the `(a,b)` line segment should be exactly the same as the `(b,a)` line segment. # Third attempt We fix the missing red line by swapping the points so `x0` is always lower than `x1`. There are holes in one of the line segments due to the fact that its height is greater than the width. My students often suggest the following fix: `if (dx > dy) { for (int x) } else { for (int y) }` Holy cow! ```csharp static void Swap(ref T x, ref T y) { T t = y; y = x; x = t; } static void Swap(T[] arr, int x, int y) { T t = arr[y]; arr[y] = arr[x]; arr[x] = t; } Image Line (Image image, int x0, int y0, int x1, int y1, Color color) { bool steep = false; // if the line is steep, we transpose the image if (Math.Abs (x0-x1) < Math.Abs (y0-y1)) { Swap (ref x0, ref y0); Swap (ref x1, ref y1); steep = true; } if (x0 > x1) { // make it left to right Swap (ref x0, ref x1); Swap (ref y0, ref y1); } // (x0, y0) == (x1, y1) if(x0 == x1) { image [x0, y0] = color; } else { for (int x = x0; x <= x1; x++) { double t = (x-x0) / (double)(x1-x0); int y = (int)Math.Round(y0*(1-t) + y1*t); if (steep) image [y, x] = color; else image [x, y] = color; } } return image; } Line(image, x0: 13, y0: 20, x1: 80, y1: 40, color: Color.White); Line(image, x0: 20, y0: 13, x1: 40, y1: 80, color: Color.Red); Line(image, x0: 80, y0: 40, x1: 13, y1: 20, color: Color.Red); ``` # Wireframe rendering So now we are ready to create a wire render. You can find the snapshot of the code and the test model here. I used the [wavefront obj](http://en.wikipedia.org/wiki/Wavefront_.obj_file) format of the file to store model. All we need for the render is read from the file the array of vertices of the following type: `v 0.608654 -0.568839 -0.416318` are `x,y,z` coordinates, one vertex per file line and faces `f 1193/1240/1193 1180/1227/1180 1179/1226/1179` ```csharp int width = 800, height = 800; var headModel = Model.FromFile ("obj/african_head.obj"); var image = new Image(width, height, Format.BGR); foreach(var face in headModel.Faces) { for(int j=0; j<3; j++) { var v0 = headModel.Vertices[face.Vertices [j]]; var v1 = headModel.Vertices[face.Vertices [(j+1) % 3]]; // scale x from [-1..1] to [0..w] // scale y from [-1..1] to [0..h] int x0 = (int)((v0.x + 1) * width / 2); int y0 = (int)((v0.y + 1) * height / 2); int x1 = (int)((v1.x + 1) * width / 2); int y1 = (int)((v1.y + 1) * height / 2); Line(image, x0, y0, x1, y1, Color.White); } } image.VerticalFlip (); image ``` ================================================ FILE: graphics/tiny-renderer/lesson3.workbook/lesson2.csx ================================================ using static Geometry; var light_dir = new Vec3f { x = 0, y = 0, z = -1 }; var world = new Vec3f [3]; var screen = new Vec3f [3]; void Line (Image image, Vec2i p1, Vec2i p2, Color color) { Line(image, p1.x, p1.y, p2.x, p2.y, color); } void Line (Image image, Vec3f p1, Vec3f p2, Color color) { Line(image, (int)p1.x, (int)p1.y, (int)p2.x, (int)p2.y, color); } void Triangle (Image image, Vec2i[] t, Color color) { Line(image, t[0], t[1], color); Line(image, t[1], t[2], color); Line(image, t[2], t[0], color); } Vec3f Barycentric (Vec3f a, Vec3f b, Vec3f c, Vec2i p) { var pixel = new Vec3f { x = p.x + 0.5f, y = p.y + 0.5f }; var ab = b - a; var ac = c - a; var pa = a - pixel; var r = Cross (new Vec3f { x = ab.x, y = ac.x, z = pa.x }, new Vec3f { x = ab.y, y = ac.y, z = pa.y }); // triangle is degenerate, in this case return smth with negative coordinates if (Math.Abs (r.z) < 1) return new Vec3f { x = -1, y = 1, z = 1 }; return new Vec3f { x = 1 - r.x / r.z - r.y / r.z, y = r.x / r.z, z = r.y / r.z }; } void Triangle (Image image, Vec3f [] coordinates, Color color) { var t0 = coordinates [0]; var t1 = coordinates [1]; var t2 = coordinates [2]; var pMax = new Vec2i { x = (int)Math.Max (0, Math.Max (t0.x, Math.Max (t1.x, t2.x))), y = (int)Math.Max (0, Math.Max (t0.y, Math.Max (t1.y, t2.y))) }; var pMin = new Vec2i { x = (int)Math.Min (image.Width, Math.Min (t0.x, Math.Min (t1.x, t2.x))), y = (int)Math.Min (image.Height, Math.Min (t0.y, Math.Min (t1.y, t2.y))) }; Vec2i p; for (p.x = pMin.x; p.x <= pMax.x; p.x++) { for (p.y = pMin.y; p.y <= pMax.y; p.y++) { var bc = Barycentric (t0, t1, t2, p); if (bc.x < 0 || bc.y < 0 || bc.z < 0) continue; image [p.x, p.y] = color; } } } ================================================ FILE: graphics/tiny-renderer/lesson3.workbook/lesson2.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" #load "lesson1.csx" using static Geometry; ``` # Lesson 2: Triangle rasterization and back face culling # Old-school method: Line sweeping Thus, the task is to draw two-dimensional triangles. For motivated students it normally takes a couple of hours, even if they are bad programmers. Last time we saw Bresenham’s line drawing algorithm. Today’s task is to draw a filled triangle. Funny enough, but this task is not trivial. I don’t know why, but I know that it’s true. Most of my students struggle with this simple task. So, the initial stub will look like this: ```csharp void Line (Image image, Vec2i p1, Vec2i p2, Color color) { Line(image, p1.x, p1.y, p2.x, p2.y, color); } void Line (Image image, Vec3f p1, Vec3f p2, Color color) { Line(image, (int)p1.x, (int)p1.y, (int)p2.x, (int)p2.y, color); } void Triangle (Image image, Vec2i[] t, Color color) { Line(image, t[0], t[1], color); Line(image, t[1], t[2], color); Line(image, t[2], t[0], color); } Vec2i[] t0 = { new Vec2i { x = 10, y = 70 }, new Vec2i { x = 50, y = 160 }, new Vec2i { x = 70, y = 80 } }; Vec2i[] t1 = { new Vec2i { x = 180, y = 50 }, new Vec2i { x = 150, y = 1 }, new Vec2i { x = 70, y = 180 } }; Vec2i[] t2 = { new Vec2i { x = 180, y = 150 }, new Vec2i { x = 120, y = 160 }, new Vec2i { x = 130, y = 180 } }; var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); image.VerticalFlip (); image ``` The code is simple: I provide three triangles for the initial debugging of your code. If we invoke `Line` inside the triangle function, we’ll get the contour of the triangle. How to draw a filled triangle? A good method of drawing a triangle must have the following features: * It should be (surprise!) simple and fast. * It should be symmetrical: the picture should not depend on the order of vertices passed to the drawing function. * If two triangles have two common vertices, there should be no holes between them because of rasterization rounding. We could add more requirements, but let’s do with these ones. Traditionally a line sweeping is used: 1. Sort vertices of the triangle by their y-coordinates 2. Rasterize simultaneously the left and the right sides of the triangle 3. Draw a horizontal line segment between the left and the right boundary points At this point my students start to lose the firm ground: which segment is the left one, which one is right? Besides, there are three segments in a triangle... Usually, after this introduction I leave my students for about an hour: once again, reading my code is much less valuable than comparing your own code with mine. `[One hour passes]` How do I draw a triangle? Once again, if you have a better method, I’d be glad to adopt it. Let us assume that we have three points of the triangle: `t0`, `t1`, `t2`, they are sorted in ascending order by the y-coordinate. Then, the boundary A is between `t0` and `t2`, boundary B is between `t0` and `t1`, and then between `t1` and `t2`. ```csharp void OrderByY (Vec2i[] t) { if(t[0].y > t[1].y) Swap(t, 0, 1); if(t[1].y > t[2].y) Swap(t, 1, 2); if(t[0].y > t[1].y) Swap(t, 0, 1); } void Triangle (Image image, Vec2i[] t, Color color) { OrderByY(t); Line(image, t[0], t[1], Color.Green); Line(image, t[1], t[2], Color.Green); Line(image, t[2], t[0], Color.Red); } var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); // Here boundary A is red, and boundary B is green. image.VerticalFlip (); image ``` Unfortunately, boundary B is made of two parts. Let us draw the bottom half of the triangle by cutting it horizontally: ```csharp void Triangle (Image image, Vec2i[] t, Color color) { OrderByY(t); float height_10 = t[1].y - t[0].y; float height_20 = t[2].y - t[0].y; for(int y=t[0].y; y<=t[1].y; y++) { var alpha = (y-t[0].y) / height_20; var beta = (y-t[0].y) / height_10; // be careful with divisions by zero Vec2i A = new Vec2i { x = t[0].x + (int)((t[2].x-t[0].x)*alpha), y = y}; Vec2i B = new Vec2i { x = t[0].x + (int)((t[1].x-t[0].x)*beta), y = y}; image[A.x, y] = Color.Red; image[B.x, y] = Color.Green; } } var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); image.VerticalFlip (); image ``` Note that the segments are not continuous. Last time when we drew straight lines we struggled to get continuous segments and here I did not bother with rotating the image (remember the xy swapping?). Why? We fill the triangles aftewards, that’s why. If we connect the corresponding pairs of points by horizontal lines, the gaps disappear: ```csharp void Triangle (Image image, Vec2i[] t, Color color) { OrderByY(t); float height_10 = t[1].y - t[0].y; float height_20 = t[2].y - t[0].y; for(int y=t[0].y; y<=t[1].y; y++) { var alpha = (y-t[0].y) / height_20; var beta = (y-t[0].y) / height_10; // be careful with divisions by zero Vec2i A = new Vec2i { x = t[0].x + (int)((t[2].x-t[0].x)*alpha), y = y}; Vec2i B = new Vec2i { x = t[0].x + (int)((t[1].x-t[0].x)*beta), y = y}; Line(image, A, B, Color.White); image[B.x, y] = Color.Green; image[A.x, y] = Color.Red; } } var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); image.VerticalFlip (); image ``` Now, let us draw the second (upper) half of the triangle. We can do this by adding a second loop: ```csharp void Triangle (Image image, Vec2i[] t, Color color) { OrderByY(t); float height_10 = t[1].y - t[0].y; float height_20 = t[2].y - t[0].y; for(int y=t[0].y; y<=t[1].y; y++) { var alpha = (y-t[0].y) / height_20; var beta = (y-t[0].y) / height_10; // be careful with divisions by zero Vec2i A = new Vec2i { x = t[0].x + (int)((t[2].x-t[0].x)*alpha), y = y}; Vec2i B = new Vec2i { x = t[0].x + (int)((t[1].x-t[0].x)*beta), y = y}; if(A.x > B.x) Swap(ref A, ref B); for (int j=A.x; j<=B.x; j++) image[j, y] = color; } float height_21 = t[2].y - t[1].y; for(int y=t[1].y; y<=t[2].y; y++) { var alpha = (y-t[0].y) / height_20; var beta = (y-t[1].y) / height_21; // be careful with divisions by zero Vec2i A = new Vec2i { x = t[0].x + (int)((t[2].x-t[0].x)*alpha), y = y}; Vec2i B = new Vec2i { x = t[1].x + (int)((t[2].x-t[1].x)*beta), y = y}; if(A.x > B.x) Swap(ref A, ref B); for (int j=A.x; j<=B.x; j++) image[j, y] = color; } } var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); image.VerticalFlip (); image ``` This could be enough, but I dislike to see the same code twice. That is why we will make it a bit less readable, but more handy for modifications/maintaining: ```csharp void Triangle (Image image, Vec2i[] t, Color color) { // I dont care about degenerate triangles if(t[0].y == t[1].y && t[1].y == t[2].y) return; OrderByY(t); float height_10 = t[1].y - t[0].y; float total_height = t[2].y - t[0].y; for(int i=0; i t[1].y - t[0].y || t[1].y == t[0].y; float segment_height = second_half ? t[2].y-t[1].y : t[1].y-t[0].y; var alpha = i / total_height; // be careful with divisions by zero var beta = (i - (second_half ? t[1].y-t[0].y : 0)) / segment_height; Vec2i A = new Vec2i { x = t[0].x + (int)((t[2].x-t[0].x)*alpha), y = t[0].y + i }; Vec2i B = new Vec2i { x = second_half ? t[1].x + (int)((t[2].x-t[1].x)*beta) : t[0].x + (int)((t[1].x-t[0].x)*beta), y = t[0].y + i }; if(A.x > B.x) Swap(ref A, ref B); for (int j=A.x; j<=B.x; j++) image[j, t[0].y + i] = color; } } var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); image.VerticalFlip (); image ``` # The method I adopt for my code While not being really complicated, the source code for the line sweeping is a bit messy. Moreover, it is really an old-school approach designed for mono-thread CPU programming. Let us take a look at the following pseudo-code: ```csharp // triangle(Vec2i[] points) { // Vec2i bbox[2] = find_bounding_box(points); // for (each pixel in the bounding box) { // if (inside(points, pixel)) { // put_pixel(pixel); // } // } // } ``` Do you like it? I do. It is really easy to find a bounding box. It is certainly no problem to check whether a point belongs a 2D triangle (or any convex polygon). *Off Topic: if I have to implement some code to check whether a point belongs to a polygon, and this program will run on a plane, I will never get on this plane. Turns out, it is a surprisingly difficult task to solve this problem reliably. But here we just painting pixels. I am okay with that.* There is another thing I like about this pseudocode: a neophyte in programming accepts it with enthusiasm, more experienced programmers often chuckle: “*What an idiot wrote it?*”. And an expert in computer graphics programming will shrug his shoulders and say: “*Well, that’s how it works in real life*”. Massively parallel computations in thousands of threads (i’m talking about regular consumer computers here) change the way of thinking. Okay, let us start: first of all we need to know what the [barycentric coordinates](https://en.wikipedia.org/wiki/Barycentric_coordinate_system) are. Given a 2D triangle ABC and a point P, all in old good Cartesian coordinates `(xy)`. Our goal is to find barycentric coordinates of the point P with respect to the triangle ABC. It means that we look for three numbers `(1 − u − v,u,v)` such that we can find the point P as follows: ![ ](./img/lesson2_f1.png) While being a bit frightening at the first glance, it is really simple: imagine that we put three weights `(1−u−v,u,v)` at the vertices A, B and C, respectively. Then the barycenter of the system is exactly in the point P. We can say the same thing with other words: the point P has coordinates `(u,v)` in the (oblique) basis (A,![](./img/lesson2_ab.png),![](./img/lesson2_ac.png)): ![ ](./img/lesson2_f2.png) So, we have vectors ![](./img/lesson2_ab.png), ![](./img/lesson2_ac.png) and ![](./img/lesson2_ap.png), we need to find two real numbers u and v respecting the following constraint: ![ ](./img/lesson2_f3.png) It is a simple vector equation, or a linear system of two equations with two variables: ![ ](./img/lesson2_f4.png) I am lazy and do not want to solve linear systems in a scholar way. Let us write it in matrix form: ![ ](./img/lesson2_f5.png) It means that we are looking for a vector `(u,v,1)` that is orthogonal to `(ABx,ACx,PAx)` and `(ABy,ACy,PAy)` *at the same time*! I hope you see [where I am heading](https://en.wikipedia.org/wiki/Cross_product). That is a small hint: to find an intersection of two straight lines in a plane (that is exactly what we did here), it is sufficient to compute one cross product. By the way, test yourself: how do we find an equation of a line passing through two given points? So, let us program our new rasterization routine: we iterate through all pixels of a bounding box for a given triangle. For each pixel we compute its barycentric coordinates. If it has at least one negative component, then the pixel is outside of the triangle. Probably it is more clear to see the program directly: ```csharp Vec3f Barycentric (Vec3f a, Vec3f b, Vec3f c, Vec2i p) { var pixel = new Vec3f { x = p.x + 0.5f, y = p.y + 0.5f }; var ab = b - a; var ac = c - a; var pa = a - pixel; var r = Cross (new Vec3f { x = ab.x, y = ac.x, z = pa.x }, new Vec3f { x = ab.y, y = ac.y, z = pa.y }); // triangle is degenerate, in this case return smth with negative coordinates if (Math.Abs (r.z) < 1) return new Vec3f { x = -1, y = 1, z = 1 }; return new Vec3f { x = 1 - r.x / r.z - r.y / r.z, y = r.x / r.z, z = r.y / r.z }; } void Triangle (Image image, Vec3f [] coordinates, Color color) { var t0 = coordinates [0]; var t1 = coordinates [1]; var t2 = coordinates [2]; var pMax = new Vec2i { x = (int)Math.Max (0, Math.Max (t0.x, Math.Max (t1.x, t2.x))), y = (int)Math.Max (0, Math.Max (t0.y, Math.Max (t1.y, t2.y))) }; var pMin = new Vec2i { x = (int)Math.Min (image.Width, Math.Min (t0.x, Math.Min (t1.x, t2.x))), y = (int)Math.Min (image.Height, Math.Min (t0.y, Math.Min (t1.y, t2.y))) }; Vec2i p; for (p.x = pMin.x; p.x <= pMax.x; p.x++) { for (p.y = pMin.y; p.y <= pMax.y; p.y++) { var bc = Barycentric (t0, t1, t2, p); if (bc.x < 0 || bc.y < 0 || bc.z < 0) continue; image [p.x, p.y] = color; } } } ``` # Flat shading render We already know how to draw a model with empty triangles. Let us fill them with a random color. This will help us to see how well we have encoded filling of triangles. Here is the code: ```csharp var image = new Image(width, height, Format.BGR); // Map world coordinates [-1..-1] to screen coordinates [0..width] Func map = v => new Vec3f { x = (int)((v.x+1)*image.Width/2), y = (int)((v.y+1)*image.Height/2) }; var rnd = new Random(); Func rndByte = () => (byte)rnd.Next(255); Func rndColor = () => new Color(rndByte(), rndByte(), rndByte()); var coordinates = new Vec3f[3]; foreach(var face in headModel.Faces) { for(int i=0; i<3; i++) { var vIndex = face.Vertices[i]; var v = headModel.Vertices[vIndex]; coordinates[i] = map(v); } Triangle(image, coordinates, rndColor()); } image.VerticalFlip (); image ``` Let us get rid of these clown-colors and put some lighting. Captain Obvious: ”*At the same light intensity, the polygon is illuminated most brightly when it is orthogonal to the light direction.*” Let us compare: ![ ](./img/lesson2_light1.jpeg) ![](./img/lesson2_light2.jpeg) We get zero illumination if the polygon is parallel to the vector of light. To paraphrase: the intensity of illumination is equal to the scalar product of the light vector and the normal to the given triangle. The normal to the triangle can be calculated simply as the [cross product](https://en.wikipedia.org/wiki/Cross_product) of its two sides. As a side note, at this course we will perform linear computations on the colors. However `(128,128,128)` color is not half as bright as `(255, 255, 255)`. We are going to ignore gamma correction and tolerate the incorrectness of the brightness of our colors. ```csharp var image = new Image (width, height, Format.BGR); var light_dir = new Vec3f { x = 0, y = 0, z = -1 }; var world = new Vec3f [3]; var screen = new Vec3f [3]; foreach (var face in headModel.Faces) { for (int i = 0; i < 3; i++) { var vIndex = face.Vertices [i]; world [i] = headModel.Vertices [vIndex]; screen [i] = map (world [i]); } var n = Cross (world [2] - world [0], world [1] - world [0]).Normalize (); var intensivity = Dot (n, light_dir); if (intensivity > 0) Triangle (image, screen, Color.White * intensivity); } image.VerticalFlip (); image ``` ================================================ FILE: graphics/tiny-renderer/lesson3.workbook/lesson3.csx ================================================ using static Geometry; var headTexture = Image.Load ("obj/african_head_diffuse.tga"); headTexture.VerticalFlip (); float [] InitZBuffer (Image image) { var zbuffer = new float [image.Width * image.Height]; for (int idx = 0; idx < zbuffer.Length; idx++) zbuffer [idx] = float.NegativeInfinity; return zbuffer; } Vec3f Barycentric (Vec2f a, Vec2f b, Vec2f c, Vec2f p) { var ab = b - a; var ac = c - a; var pa = a - p; var r = Cross (new Vec3f { x = ab.x, y = ac.x, z = pa.x }, new Vec3f { x = ab.y, y = ac.y, z = pa.y }); // triangle is degenerate, in this case return smth with negative coordinates // dont forget that r.z is integer. If it is zero then triangle ABC is degenerate if ((int)r.z == 0) return new Vec3f { x = -1, y = 1, z = 1 }; return new Vec3f { x = 1 - (r.x + r.y) / r.z, y = r.x / r.z, z = r.y / r.z }; } void Triangle (Image image, Vec3f [] coordinates, Image texture, Vec2f [] uv, float intensivity, float [] zbuffer) { Vec3f t0 = coordinates [0]; Vec3f t1 = coordinates [1]; Vec3f t2 = coordinates [2]; var pMax = new Vec2i { x = (int)Math.Max (0, Math.Max (t0.x, Math.Max (t1.x, t2.x))), y = (int)Math.Max (0, Math.Max (t0.y, Math.Max (t1.y, t2.y))) }; var pMin = new Vec2i { x = (int)Math.Min (image.Width, Math.Min (t0.x, Math.Min (t1.x, t2.x))), y = (int)Math.Min (image.Height, Math.Min (t0.y, Math.Min (t1.y, t2.y))) }; for (int x = pMin.x; x <= pMax.x; x++) { for (int y = pMin.y; y <= pMax.y; y++) { var pixelCenter = new Vec2f { x = x + 0.5f, y = y + 0.5f }; var bc = Barycentric (Project2D(t0), Project2D(t1), Project2D(t2), pixelCenter); if (bc.x < 0 || bc.y < 0 || bc.z < 0) continue; var z = t0.z * bc.x + t1.z * bc.y + t2.z * bc.z; var u = (int)(uv [0].x * bc.x + uv [1].x * bc.y + uv [2].x * bc.z); var v = (int)(uv [0].y * bc.x + uv [1].y * bc.y + uv [2].y * bc.z); var idx = x + y * image.Width; if (zbuffer [idx] < z) { zbuffer [idx] = z; var color = texture [u, v]; image [x, y] = color * intensivity; } } } } ================================================ FILE: graphics/tiny-renderer/lesson3.workbook/obj/african_head.obj ================================================ v -0.000581696 -0.734665 -0.623267 v 0.000283538 -1 0.286843 v -0.117277 -0.973564 0.306907 v -0.382144 -0.890788 0.221243 v -0.247144 -0.942602 0.276051 v -0.656078 -0.718512 -0.109025 v -0.609847 -0.786562 0.0198068 v -0.66248 -0.632053 -0.244271 v -0.511812 -0.845392 0.127809 v -0.609326 -0.569868 -0.41571 v -0.426949 -0.649767 -0.567143 v -0.201076 -0.720822 -0.633205 v 0.117382 -0.973645 0.306766 v 0.382454 -0.890869 0.221097 v 0.247512 -0.942667 0.275986 v 0.656371 -0.718624 -0.109224 v 0.610273 -0.786562 0.0197893 v 0.66248 -0.631463 -0.244119 v 0.511631 -0.845357 0.127832 v 0.608654 -0.568839 -0.416318 v 0.424663 -0.649937 -0.567418 v 0.198972 -0.720968 -0.633141 v 0.153371 -0.140519 0.477416 v 0.134781 -0.14723 0.48805 v 0.131261 -0.132153 0.49872 v 0.14749 -0.135105 0.489565 v 0.000686924 -0.0534984 0.505694 v 0.075062 -0.0473306 0.49955 v 0.0695841 -0.0997942 0.550277 v 0.0302569 -0.0971868 0.55389 v 0.0745124 -0.135953 0.523215 v 0.0354892 -0.12785 0.535159 v 0.0389268 -0.109557 0.550558 v 0.0734835 -0.11538 0.538029 v 0.106386 -0.125623 0.51513 v 0.107415 -0.144295 0.5047 v 0.15968 -0.130861 0.484794 v 0.156224 -0.123705 0.486735 v 0.15792 -0.107798 0.4677 v 0.163784 -0.126996 0.470144 v 0.154687 -0.134655 0.486373 v 0.160668 -0.135649 0.476189 v 0.143433 -0.119034 0.499854 v 0.131606 -0.0726738 0.476148 v -0.000260156 -0.124553 0.539058 v -0.000646004 -0.110651 0.55444 v 0.100423 -0.10574 0.537643 v 0.126128 -0.115784 0.515598 v 0.250944 -0.275583 0.380381 v 0.221602 -0.335752 0.330174 v 0.275434 -0.301318 0.24751 v 0.307699 -0.239869 0.292356 v 0.332124 -0.0415605 0.412962 v 0.319444 0.00732526 0.451091 v 0.28667 -0.025805 0.481549 v 0.297006 -0.0758717 0.454242 v 0.357953 -0.159928 -0.223225 v 0.303981 -0.144611 -0.343644 v 0.296386 -0.0547553 -0.357792 v 0.357339 -0.0633433 -0.24278 v 0.45086 0.331215 0.047962 v 0.438899 0.336167 0.131147 v 0.447405 0.226107 0.139349 v 0.455613 0.205353 0.0827643 v 0.197493 -0.411308 0.138256 v 0.204911 -0.353378 0.2082 v 0.102001 -0.419375 0.24969 v 0.0995867 -0.475697 0.20834 v 0.150133 -0.372261 0.431226 v 0.176423 -0.362054 0.392056 v 0.196019 -0.326474 0.426929 v 0.154611 -0.348549 0.463444 v 0.0892273 -0.391968 0.303592 v 0.159013 -0.363737 0.305077 v 0.455712 0.508986 -0.0641442 v 0.432146 0.648411 -0.0417475 v 0.417051 0.611568 0.0817295 v 0.44205 0.483438 0.0478626 v 0.3446 0.43288 0.398633 v 0.372358 0.383369 0.353998 v 0.388341 0.404485 0.306953 v 0.355059 0.467372 0.356967 v 0.305162 0.338815 0.458112 v 0.298579 0.319803 0.456627 v 0.313422 0.304568 0.427776 v 0.323711 0.315968 0.429291 v 0.33161 0.397557 0.430226 v 0.354427 0.359727 0.390478 v 0.304162 0.291952 0.432377 v 0.292662 0.309771 0.452991 v 0.282934 0.292496 0.4562 v 0.292025 0.281663 0.435178 v 0.397344 0.565249 0.192585 v 0.42257 0.455996 0.145494 v 0.317848 0.364866 0.448834 v 0.340595 0.337517 0.417978 v 0.243227 0.479439 0.494236 v 0.250155 0.546138 0.465934 v 0.179019 0.560251 0.511681 v 0.170173 0.4781 0.536229 v 0.162386 0.410407 0.547009 v 0.235031 0.427051 0.517018 v 0.271745 0.634415 0.42162 v 0.196896 0.657291 0.472505 v 0.186589 0.312952 0.511073 v 0.189518 0.32493 0.514165 v 0.146286 0.31277 0.509009 v 0.144959 0.300178 0.501713 v 0.143965 0.300412 0.49409 v 0.187203 0.310596 0.506407 v 0.157744 0.364614 0.528804 v 0.216697 0.382527 0.516083 v 0.194441 0.332425 0.515989 v 0.204286 0.349818 0.516732 v 0.156254 0.334062 0.519579 v 0.151565 0.320341 0.513961 v 0.0431068 0.071791 0.618005 v 0.0477954 0.0867105 0.593486 v 0.0780844 0.0816652 0.602518 v 0.0574124 0.0746147 0.621185 v 0.448253 0.130656 0.149533 v 0.431801 0.159355 0.215905 v 0.422792 0.0771637 0.237185 v 0.428691 0.0348783 0.166914 v 0.365073 -0.0526507 0.316126 v 0.326974 -0.104793 0.373068 v 0.312773 -0.172965 0.33446 v 0.368107 -0.126698 0.269222 v 0.203695 -0.131796 0.523934 v 0.180463 -0.136479 0.525396 v 0.182848 -0.14892 0.516989 v 0.204163 -0.152533 0.514914 v 0.39379 0.00616771 0.269368 v 0.40177 -0.0591341 0.209048 v 0.26083 -0.0996422 0.484274 v 0.250406 -0.0552171 0.50321 v 0.15851 -0.136292 0.498474 v 0.155032 -0.134684 0.502964 v 0.145006 -0.133819 0.514504 v 0.171033 -0.12032 0.538263 v 0.158849 -0.127938 0.534943 v 0.167969 -0.138075 0.523788 v 0.232061 -0.151474 0.497024 v 0.23074 -0.117128 0.507191 v 0.365798 0.221617 0.362743 v 0.342501 0.235507 0.392185 v 0.325951 0.202558 0.415114 v 0.359268 0.178677 0.383229 v 0.352369 0.0489033 0.417452 v 0.322262 0.0907619 0.44953 v 0.295322 0.04895 0.483251 v 0.367108 0.00328555 0.369771 v 0.138972 -0.18796 0.555521 v 0.161562 -0.177794 0.535913 v 0.154015 -0.155093 0.536392 v 0.136131 -0.156414 0.558491 v 0.220263 -0.08194 0.518603 v 0.202088 -0.0486753 0.52791 v 0.17564 -0.0814314 0.545822 v 0.193131 -0.106435 0.533575 v 0.199492 -0.169714 0.509722 v 0.190033 -0.188183 0.514668 v 0.207302 -0.213011 0.492721 v 0.222415 -0.183044 0.489617 v 0.125088 -0.132884 0.551294 v 0.144497 -0.139192 0.530254 v 0.135014 0.119128 0.544717 v 0.119534 0.149685 0.554253 v 0.096915 0.171211 0.569382 v 0.112553 0.137432 0.569616 v 0.0878476 0.217858 0.555667 v 0.0649773 0.232128 0.568628 v 0.073466 0.185119 0.584571 v 0.116359 0.191199 0.548932 v 0.111419 0.228591 0.524951 v 0.0858774 0.255408 0.530312 v 0.301408 0.0368718 -0.387812 v 0.366839 0.037626 -0.269538 v 0.272125 -0.199781 0.399533 v 0.246349 -0.195514 0.453266 v 0.223339 -0.243049 0.450553 v 0.364021 -0.197455 0.21335 v 0.411416 -0.124798 0.140589 v 0.431568 -0.0028997 0.0907502 v 0.449346 0.11075 0.0889086 v 0.0649948 0.777167 0.432594 v 0.133465 0.770619 0.418569 v 0.14341 0.869244 0.301253 v 0.0689586 0.877043 0.315395 v 0.305372 0.809321 0.22043 v 0.289307 0.723856 0.335524 v 0.355187 0.660735 0.264773 v 0.372264 0.728258 0.148528 v 0.382308 0.7766 0.0116631 v 0.0971488 0.470588 0.557912 v 0.110788 0.565185 0.534317 v 0.100113 0.277828 0.510938 v 0.10966 0.248679 0.503771 v 0.0443988 0.240822 0.58581 v 0.0522151 0.193614 0.604337 v 0.052601 0.564735 0.541859 v 0.123726 0.667896 0.498907 v 0.0597976 0.671147 0.508711 v 0.0466729 0.466215 0.561034 v 0.000423846 0.462807 0.558988 v -0.00017831 0.388326 0.563478 v 0.0352086 0.389069 0.560584 v 0.000833078 0.56384 0.544139 v 0.295773 0.426823 0.470722 v 0.301706 0.464689 0.451056 v 0.189957 0.181465 0.501181 v 0.186163 0.208931 0.491956 v 0.141574 0.222722 0.500509 v 0.146526 0.195338 0.518293 v 0.111986 0.0116865 0.562811 v 0.111343 0.0404672 0.565769 v 0.0577164 0.0420398 0.577988 v 0.0656438 -0.00796249 0.596918 v 0.147695 0.0440509 0.537258 v 0.144778 0.0631738 0.538491 v 0.0268719 -0.0140834 0.602378 v 0.0270356 -0.0372401 0.622027 v 0.0876429 -0.0456996 0.601127 v 0.183093 0.146552 0.519439 v 0.148589 0.164593 0.536819 v 0.147344 0.131095 0.542934 v 0.176733 0.112264 0.532435 v -0.000394618 -0.0441035 0.617625 v -0.000260156 -0.0187662 0.600677 v 0.165058 0.0770935 0.530856 v 0.148554 0.0982976 0.535562 v 0.116476 0.272829 0.494797 v 0.119084 0.26261 0.493569 v 0.120873 0.268971 0.480883 v 0.11761 0.27287 0.484221 v 0.224695 0.848444 0.271198 v 0.231324 0.918189 0.121063 v 0.14614 0.9439 0.150241 v 0.241894 0.945736 -0.185803 v 0.156043 0.976475 -0.183418 v 0.146906 0.980702 -0.0177607 v 0.23195 0.948285 -0.0402158 v 0.0684324 0.995189 -0.00981573 v 0.0682103 0.955014 0.162933 v 0.0891571 0.383649 0.555118 v 0.110613 0.336412 0.528863 v 0.122749 0.310759 0.512914 v 0.147081 -0.111919 0.55631 v 0.158656 -0.0994551 0.55786 v 0.0939743 0.0869969 0.616333 v 0.101206 0.119326 0.615532 v 0.0670469 0.122121 0.645885 v 0.0560853 0.0831385 0.640601 v 0.0795284 0.0820978 0.567845 v 0.0337354 0.0564741 0.595059 v 0.0854448 -0.103577 0.606979 v 0.0826211 -0.0671141 0.612931 v 0.0280704 -0.0555854 0.637736 v 0.0319698 -0.0970874 0.628212 v 0.0789964 -0.121811 0.579602 v 0.0327415 -0.116959 0.594106 v 0.0216981 0.0173339 0.585915 v -0.00123062 -0.095585 0.625704 v -0.000511542 -0.0598999 0.637227 v -0.00157555 -0.115643 0.593966 v -0.000219233 -0.0988881 0.554498 v 0.0291929 0.0853015 0.665324 v 0.0352671 0.124524 0.666125 v 0.0371846 0.159004 0.648446 v 0.0654158 0.154462 0.629171 v 0.0280178 0.19967 0.620548 v 0.0221015 0.245843 0.59797 v 0.0432997 0.281499 0.556866 v 0.0222008 0.28717 0.567459 v -0.000400465 0.125745 0.673871 v -0.00057585 0.0822265 0.675105 v -0.000347849 0.160916 0.656029 v 0.367195 0.315074 0.363767 v 0.346658 0.302744 0.393991 v 0.344389 0.266656 0.384439 v 0.371726 0.266504 0.352507 v 0.40246 0.429197 0.234116 v 0.422126 0.335763 0.207276 v 0.393316 0.264083 0.313887 v 0.387102 0.325737 0.325369 v 0.3274 0.295928 0.408636 v 0.316392 0.29076 0.418709 v 0.3085 0.274624 0.423199 v 0.323636 0.272379 0.406602 v 0.429381 0.244458 0.204002 v 0.407084 0.332408 0.277313 v 0.410597 0.257869 0.266264 v -0.0012657 -0.456867 0.290093 v -0.00137093 -0.520579 0.266159 v 0.154137 -0.304206 0.500479 v 0.193482 -0.282873 0.473493 v 0.186367 -0.242201 0.509588 v 0.148993 -0.26399 0.525367 v 0.110332 -0.274916 0.545857 v 0.099347 -0.233134 0.560204 v 0.0558865 -0.227615 0.569605 v 0.0659185 -0.270006 0.563817 v 0.154687 -0.142577 0.51838 v 0.159498 -0.143009 0.513072 v 0.154646 -0.138239 0.502496 v 0.149045 -0.137596 0.50639 v 0.15958 -0.138174 0.517463 v 0.161574 -0.141559 0.511657 v 0.0940387 -0.129288 0.582226 v 0.109215 -0.12609 0.531844 v 0.0782715 -0.117578 0.557129 v 0.264817 0.0151299 0.501573 v 0.280122 0.127096 0.47057 v 0.262508 0.0886748 0.494464 v 0.187613 0.050926 0.529248 v 0.207829 0.0868157 0.523449 v 0.231821 -0.0170182 0.518246 v 0.304138 0.164985 0.443485 v 0.343004 0.132813 0.418235 v 0.313621 0.250742 0.418382 v 0.290815 0.22492 0.444303 v 0.355269 -0.194146 0.0276407 v 0.388534 -0.179618 0.0746089 v 0.336544 -0.25083 0.156379 v 0.29365 -0.279868 0.104617 v 0.389288 0.153006 0.345258 v 0.39155 0.205715 0.320166 v 0.127262 0.566927 -0.64996 v 0.000868155 0.562946 -0.661419 v 0.000850617 0.724441 -0.605705 v 0.118774 0.725955 -0.596105 v 0.21095 0.754513 0.387525 v 0.133734 -0.133188 0.514651 v 0.131302 -0.13393 0.53047 v 0.0671053 -0.326445 0.551902 v 0.0661056 -0.374553 0.504765 v 0.117289 -0.365439 0.489939 v 0.116552 -0.318792 0.528974 v 0.288249 -0.135286 0.424736 v 0.39393 0.0544045 0.33225 v 0.374655 0.0965379 0.38044 v 0.000792155 1 -0.0074948 v 0.0731795 0.993937 -0.182792 v 0.000868155 0.999152 -0.181886 v 0.179405 0.936399 -0.330549 v 0.0842755 0.953459 -0.338026 v 0.141767 0.271455 0.486238 v 0.139978 0.267433 0.490862 v 0.175908 0.259465 0.501362 v 0.175312 0.263359 0.495861 v 0.181597 0.230187 0.495539 v 0.140253 0.240576 0.495341 v 0.336982 0.587763 0.356927 v 0.312043 0.518258 0.416183 v 0.259971 0.350203 0.495411 v 0.250763 0.331028 0.496036 v 0.114179 0.255893 0.495902 v 0.111069 0.276518 0.499456 v 0.125433 0.293116 0.500415 v 0.124965 0.282353 0.489968 v 0.13906 0.254928 0.497457 v 0.17737 0.2462 0.50062 v 0.121796 0.272327 0.47658 v 0.149548 0.0847578 0.549377 v 0.142825 -0.226381 0.544992 v 0.106181 -0.197232 0.576871 v 0.258193 -0.146669 0.465227 v 0.2105 0.0188071 0.525711 v 0.181041 -0.0155508 0.531721 v 0.173453 -0.168949 0.5218 v 0.180322 -0.15877 0.514949 v 0.168554 -0.150118 0.516667 v 0.163082 -0.153579 0.523344 v 0.139124 -0.128733 0.545343 v 0.152348 -0.134468 0.527471 v 0.416192 -0.0714636 0.0335278 v 0.0220956 0.0520719 0.640232 v 0.0361615 0.0619695 0.628476 v -0.000283541 0.202056 0.62768 v 0.0869063 -0.0493125 -0.489641 v 0.192289 -0.0534399 -0.447186 v 0.192003 -0.134672 -0.429197 v 0.0851642 -0.130335 -0.46373 v 0.236434 0.310245 0.495686 v 0.237714 0.31211 0.497539 v 0.244636 0.32534 0.496212 v 0.121253 0.281932 0.477293 v 0.173149 -0.207241 0.528208 v -0.000242618 0.247989 0.603612 v -0.00037708 0.28838 0.571697 v 0.108496 -0.160507 0.588207 v 0.0613995 -0.166388 0.620127 v 0.0634222 -0.199565 0.59462 v 0.0893734 0.151176 0.600127 v 0.122124 0.0729427 0.596088 v 0.0993528 0.072475 0.584781 v 0.108315 0.0599584 0.583916 v 0.133524 0.0551528 0.575778 v 0.13315 0.107517 0.580426 v 0.274937 0.384257 0.485735 v 0.170606 -0.145383 0.517205 v 0.0464391 -0.130399 0.611931 v 0.0392892 -0.113439 0.575094 v -0.00161647 -0.112428 0.579865 v -0.00351648 -0.131685 0.617859 v 0.0194356 0.03489 0.601858 v -0.000564158 0.0478802 0.644208 v -2.04632e-05 0.0350303 0.598835 v 0.222163 0.246884 0.4972 v 0.217802 0.257547 0.498129 v 0.293159 0.278716 0.430419 v 0.302852 0.281932 0.427367 v 0.285209 0.277366 0.434932 v 0.289307 0.275834 0.436551 v 0.290061 0.280494 0.427963 v -0.000225079 -0.384287 0.444245 v 0.0651001 -0.383883 0.440585 v -0.000891543 -0.364076 0.502426 v 0.116576 -0.381784 0.436341 v 0.363734 0.712842 -0.467571 v 0.32166 0.832542 -0.392653 v 0.376508 0.821429 -0.265451 v 0.427095 0.698004 -0.319575 v 0.27178 0.90956 -0.29643 v 0.310423 0.901357 -0.210644 v 0.441869 0.677005 -0.175175 v 0.389019 0.807076 -0.128411 v 0.313311 0.894506 -0.0788532 v 0.12783 -0.376125 0.378248 v 0.0722266 -0.391483 0.37664 v 0.125579 0.302411 0.505741 v 0.101656 0.861358 -0.486525 v 0.214084 0.849981 -0.463327 v 0.2467 0.723207 -0.559263 v 0.104913 0.117397 -0.600268 v 0.221579 0.117865 -0.555159 v 0.200848 0.0268164 -0.488992 v 0.0944011 0.0271204 -0.539134 v 0.391141 0.144178 -0.303545 v 0.331241 0.130393 -0.444613 v 0.360829 0.250357 -0.491155 v 0.424003 0.258021 -0.333419 v 0.000868155 0.23912 -0.655479 v 0.00089154 0.393909 -0.675105 v 0.125626 0.397949 -0.664716 v 0.115418 0.240453 -0.645617 v 0.452175 0.547687 -0.348309 v 0.450217 0.395605 -0.350776 v 0.383015 0.40193 -0.511868 v 0.3854 0.562496 -0.506472 v 0.464078 0.52881 -0.195929 v 0.311698 0.866351 0.071908 v -9.64635e-05 -0.406882 0.376985 v 0.373883 -0.18312 -0.115123 v 0.389189 -0.0789467 -0.141776 v 0.247109 0.197607 0.47589 v 0.22891 0.231497 0.489717 v 0.121077 -0.116725 0.574393 v 0.125626 -0.0895459 0.583057 v 0.110548 -0.128452 0.555428 v 0.000710309 0.959638 0.167019 v 0.000710309 0.881206 0.320973 v 0.224163 0.124079 0.505215 v 0.255305 0.260798 0.480649 v 0.25188 0.263516 0.478322 v 0.214891 0.26119 0.49413 v 0.116476 0.273741 0.475423 v 0.290704 0.283902 0.433377 v 0.29641 0.299523 0.422813 v 0.29406 0.288222 0.418078 v 0.142655 0.263364 0.482467 v 0.121638 0.267831 0.470296 v 0.171711 0.256898 0.489693 v 0.246864 0.257401 0.473821 v 0.274311 0.271648 0.453301 v 0.274539 0.26862 0.446654 v 0.233686 0.331104 0.49074 v 0.187548 0.326632 0.49682 v 0.296971 0.273928 0.433476 v 0.134067 -0.0744861 0.577333 v 0.237434 0.052867 0.514604 v 0.0637905 0.27076 0.54346 v 0.375421 0.514218 0.287328 v 0.353808 -0.333437 -0.190615 v 0.349365 -0.276331 -0.333858 v 0.323337 -0.214946 -0.338453 v 0.356725 -0.247925 -0.205557 v -0.000330311 -0.581268 0.237302 v 0.092922 -0.548418 0.185458 v 0.394783 -0.0876049 -0.0664009 v 0.358315 -0.197624 -0.02995 v 0.292785 -0.321493 0.0377429 v 0.395175 -0.0904345 -0.0143524 v 0.243385 0.243183 -0.602957 v 0.000587539 -0.0451091 -0.498205 v 0.000751232 0.030862 -0.55154 v 0.000809694 0.11928 -0.61144 v 0.000850617 0.862837 -0.491295 v 0.000868155 0.958527 -0.339277 v 0.000423846 -0.128189 -0.469085 v 0.264186 0.56961 -0.608026 v 0.35127 -0.283317 -0.0863656 v 0.196201 -0.209591 -0.418785 v 0.0873097 -0.206341 -0.44839 v 0.000488154 -0.206259 -0.449945 v 0.263397 0.402579 -0.621226 v 0.456683 0.384813 -0.0591516 v 0.457776 0.372302 -0.191281 v 0.000850617 0.671351 0.512487 v 0.000809694 0.77919 0.437668 v 0.408656 0.116286 0.298547 v 0.295913 0.259781 0.439334 v 0.285355 0.265481 0.449775 v 0.278766 0.270035 0.454663 v 0.128946 -0.0227065 0.564741 v 0.16203 0.016989 0.534633 v 0.0985987 0.0583799 0.58087 v 0.0538462 0.323165 0.543729 v 0.0794758 0.301522 0.528465 v -0.00330601 -0.197759 0.600525 v -0.000511542 -0.225551 0.572931 v -0.00456879 -0.164231 0.628277 v -0.000336157 -0.26392 0.574381 v -0.000768774 -0.325515 0.55686 v 0.269921 0.242499 0.464742 v 0.260573 0.253022 0.476072 v 0.235066 0.15963 0.493271 v 0.411369 0.186119 0.273583 v 0.000178307 0.0131539 0.584682 v 0.153436 -0.0554568 0.55786 v 0.0264569 0.331747 0.554112 v -0.000342003 0.332998 0.557743 v 0.285589 0.277974 0.428156 v 0.184795 -0.499655 0.1217 v 0.332808 -0.386298 -0.0699261 v 0.20739 -0.274419 -0.415909 v 0.0927467 -0.274308 -0.43723 v 0.278029 -0.438791 0.0475586 v 0.000505693 -0.27722 -0.43768 v 0.438191 0.12488 -0.0367783 v 0.460214 0.163208 -0.055258 v 0.485388 0.177437 -0.0277343 v 0.472304 0.161641 -0.00367724 v 0.496244 0.232684 -0.0170708 v 0.477425 0.247036 0.00446648 v 0.517015 0.298681 -0.0523876 v 0.492233 0.31788 -0.0441737 v 0.53425 0.316407 -0.124009 v 0.511491 0.332595 -0.129276 v 0.535904 0.290111 -0.170685 v 0.511128 0.30365 -0.186838 v 0.538611 0.228878 -0.193017 v 0.511286 0.231199 -0.218992 v 0.520242 0.128838 -0.191421 v 0.490433 0.122168 -0.208603 v 0.487562 0.00951757 -0.0819458 v 0.472286 -0.00658864 -0.0930419 v 0.47079 0.0399937 -0.154257 v 0.496437 0.0472722 -0.136917 v 0.485142 -0.0247586 -0.0238758 v 0.46129 -0.0429694 -0.0334343 v 0.474888 0.238927 -0.0419989 v 0.495232 0.289088 -0.0628581 v 0.508398 0.299996 -0.11766 v 0.51311 0.283323 -0.158478 v 0.514642 0.235303 -0.176531 v 0.501751 0.136134 -0.181559 v 0.486025 0.0533522 -0.11859 v 0.486451 0.0268164 -0.067155 v 0.482529 0.0136625 -0.0120607 v 0.464265 0.0280383 0.0249515 v 0.457519 -0.0185791 0.0196256 v 0.442769 0.0582571 -0.0293244 v 0.45632 0.0847169 -0.0600578 v 0.442465 0.0842785 -0.0209644 v 0.459612 0.268106 0.0209995 v 0.458559 0.182857 0.0414318 v 0.463026 0.318488 -0.0446005 v 0.470222 0.311835 -0.142898 v 0.455063 0.232836 -0.195221 v 0.43839 0.13186 -0.191088 v 0.424564 0.0473131 -0.148417 v 0.423447 -0.00471202 -0.0897563 v 0.425377 -0.0292075 -0.0262143 v 0.430714 -0.0102191 0.0297161 v 0.446335 0.0345567 0.0460036 v 0.475607 0.129364 -0.0864649 v 0.482611 0.0600636 -0.0525396 v 0.481517 0.0827175 -0.101349 v 0.470503 0.0444835 -0.0133527 v 0.479278 0.0776957 0.00471786 v 0.504692 0.223938 -0.101723 v 0.50375 0.131866 -0.1473 v 0.45452 0.100016 0.0450097 v 0.403623 0.0251386 -0.16934 v 0.414719 0.138607 -0.218957 v 0.435461 0.249632 -0.229924 v -0.000201695 -0.407876 0.310666 v 0.000347846 -0.171521 0.505794 v 0.0884205 -0.186598 0.484028 v 0.141147 -0.173807 0.465513 v 0.159878 -0.142255 0.458644 v 0.152483 -0.116468 0.431278 v 0.0708352 0.0121893 0.376371 v 0.128069 -0.116368 0.360528 v 0.143994 -0.166791 0.41184 v 0.0748398 -0.218144 0.372349 v 0.280941 0.292858 0.454897 v 0.281356 0.319879 0.451494 v 0.127268 0.269088 0.455435 v 0.116921 0.284697 0.447653 v 0.119996 0.274998 0.469126 v 0.15699 0.254759 0.466326 v 0.265916 0.273601 0.421176 v 0.214885 0.253946 0.455259 v 0.141223 0.313133 0.482117 v 0.211436 0.255823 0.486852 v 0.277135 0.302686 0.410799 v 0.252505 0.333881 0.433599 v 0.202023 0.342182 0.464578 v 0.11989 0.295816 0.471196 v 0.146526 0.322539 0.455943 v 0.126292 0.301838 0.454973 v 0.119744 0.284878 0.469419 v 0.00103185 0.0191579 0.374711 v 0.000909079 -0.205715 0.379849 v 0.0536357 -0.100847 0.27211 v 0.00103185 -0.098929 0.27128 v 0.255463 -0.398733 -0.446098 v 0.412907 -0.372688 -0.332858 v 0.452596 -0.41557 -0.353559 v 0.293329 -0.465367 -0.476007 v 0.0815337 -0.637104 0.176286 v 0.0726358 -0.738524 0.179519 v 0.174763 -0.714911 0.155526 v 0.172032 -0.601823 0.129884 v 0.380782 -0.504069 -0.184377 v 0.357368 -0.419095 -0.180384 v 0.337538 -0.494803 -0.0548371 v 0.372989 -0.619402 -0.0373571 v 0.453578 -0.652661 -0.0939539 v 0.452351 -0.545892 -0.196981 v 0.173576 -0.814197 0.195654 v 0.0739044 -0.845866 0.20734 v 0.0964414 -0.904976 0.254455 v 0.197703 -0.864562 0.243353 v 0.519564 -0.487407 -0.384801 v 0.555004 -0.584226 -0.219366 v 0.451357 -0.731555 -0.0215899 v 0.382594 -0.74824 0.0443666 v 0.439805 -0.799196 0.0975376 v 0.519108 -0.768071 -0.00769357 v 0.274837 -0.806199 0.115503 v 0.320508 -0.838061 0.183769 v 0.354533 -0.544232 -0.525256 v 0.162503 -0.604343 -0.559076 v 0.131098 -0.496837 -0.498761 v 0.115161 -0.410103 -0.457756 v -0.00017831 -0.492774 -0.504192 v 2.046e-05 -0.40666 -0.465186 v -0.000482311 -0.600531 -0.555322 v 0.546217 -0.696736 -0.117257 v 0.22746 -0.332063 -0.424345 v 0.101627 -0.33885 -0.437002 v 0.280193 -0.554165 0.0658922 v 0.274843 -0.684891 0.0781517 v 0.000347846 -0.34199 -0.438165 v 0.000733693 -0.746364 0.176765 v 0.000312769 -0.874904 0.179121 v 0.378648 -0.322586 -0.326994 v -0.000114002 -0.940246 0.234262 v 0.000979233 -0.650317 0.207112 v -0.130513 -0.13217 0.498924 v -0.133687 -0.14723 0.488109 v -0.15222 -0.140519 0.477457 v -0.14666 -0.13514 0.489746 v -0.0697653 -0.0999404 0.550318 v -0.0736414 -0.0473131 0.499649 v -0.0305784 -0.0972511 0.55389 v -0.0396517 -0.109762 0.550014 v -0.0358517 -0.127727 0.53534 v -0.0742493 -0.135994 0.523315 v -0.0733373 -0.115561 0.537643 v -0.106766 -0.144336 0.504823 v -0.106281 -0.125786 0.515779 v -0.156505 -0.107798 0.467782 v -0.155611 -0.123682 0.486899 v -0.159311 -0.130796 0.484958 v -0.162872 -0.126996 0.470243 v -0.159919 -0.135625 0.47627 v -0.154055 -0.134696 0.486513 v -0.142597 -0.118993 0.499994 v -0.130051 -0.0726738 0.476189 v -0.10054 -0.105798 0.538111 v -0.125684 -0.115824 0.51596 v -0.274604 -0.301394 0.247527 v -0.220831 -0.335775 0.330215 v -0.250102 -0.275554 0.380393 v -0.3066 -0.239804 0.292309 v -0.284302 -0.0258401 0.479772 v -0.319479 0.00809111 0.449577 v -0.331873 -0.0412272 0.412243 v -0.293674 -0.0747667 0.452418 v -0.294668 -0.0547787 -0.357622 v -0.302063 -0.144319 -0.34334 v -0.356012 -0.159916 -0.223184 v -0.355474 -0.0633082 -0.24271 v -0.447241 0.22613 0.139332 v -0.437922 0.336149 0.131124 v -0.449486 0.331215 0.047962 v -0.454982 0.205353 0.0827818 v -0.103311 -0.419241 0.249936 v -0.203701 -0.353384 0.208147 v -0.196966 -0.411506 0.138841 v -0.101797 -0.475733 0.208638 v -0.196499 -0.327216 0.427455 v -0.176283 -0.362363 0.392138 v -0.150331 -0.372548 0.431378 v -0.155575 -0.349484 0.46435 v -0.0890109 -0.391945 0.303855 v -0.158306 -0.363848 0.305182 v -0.415613 0.611627 0.0817705 v -0.430808 0.648493 -0.0417066 v -0.45411 0.508986 -0.0641209 v -0.440308 0.483438 0.0478393 v -0.389808 0.40462 0.306977 v -0.375935 0.38348 0.354021 v -0.34643 0.433026 0.398499 v -0.354807 0.467378 0.356891 v -0.317409 0.30382 0.429121 v -0.30173 0.320499 0.456861 v -0.309295 0.339493 0.457756 v -0.328406 0.316144 0.429519 v -0.358297 0.360101 0.389344 v -0.335684 0.397733 0.427864 v -0.285156 0.29304 0.457387 v -0.294212 0.310695 0.451757 v -0.307675 0.294425 0.430781 v -0.29475 0.281949 0.435698 v -0.421091 0.455996 0.145494 v -0.395403 0.565208 0.19252 v -0.321999 0.364421 0.449238 v -0.345494 0.336792 0.417218 v -0.178165 0.560672 0.512335 v -0.249354 0.546354 0.466589 v -0.243286 0.479638 0.494943 v -0.170168 0.4781 0.536796 v -0.164123 0.410647 0.547114 v -0.236966 0.427297 0.516007 v -0.270669 0.634748 0.422187 v -0.195815 0.657882 0.47347 v -0.14597 0.313039 0.508126 v -0.18946 0.324971 0.513312 v -0.186823 0.312829 0.511757 v -0.144895 0.300213 0.501871 v -0.186911 0.310514 0.506612 v -0.143462 0.300341 0.494353 v -0.160048 0.365076 0.528073 v -0.219468 0.382854 0.516404 v -0.15782 0.334506 0.520076 v -0.205952 0.349935 0.517012 v -0.195236 0.332495 0.516264 v -0.151653 0.320785 0.513142 v -0.0805691 0.0827468 0.603261 v -0.0493739 0.08878 0.593591 v -0.0448723 0.0732117 0.617958 v -0.0594819 0.0761932 0.621314 v -0.422927 0.0771812 0.237185 v -0.432205 0.159355 0.215905 v -0.448112 0.130656 0.149516 v -0.4282 0.0348607 0.166897 v -0.311779 -0.172912 0.334378 v -0.324787 -0.103758 0.371735 v -0.364851 -0.052639 0.316097 v -0.367254 -0.126698 0.269146 v -0.183918 -0.149136 0.51793 v -0.182024 -0.137865 0.527822 v -0.205163 -0.131463 0.524127 v -0.205514 -0.152071 0.514943 v -0.39379 0.00614433 0.269368 v -0.400951 -0.0591282 0.208995 v -0.261011 -0.0993382 0.483865 v -0.25102 -0.0551177 0.50328 v -0.158849 -0.136444 0.499199 v -0.155155 -0.134784 0.503397 v -0.145304 -0.133848 0.514902 v -0.160802 -0.128394 0.536919 v -0.173424 -0.121349 0.541327 v -0.169156 -0.138478 0.524928 v -0.232096 -0.116964 0.50767 v -0.232727 -0.151188 0.49696 v -0.326085 0.202611 0.415651 v -0.34094 0.235683 0.392156 v -0.367727 0.221336 0.359031 v -0.358829 0.177595 0.3841 v -0.295603 0.0501836 0.478632 v -0.32232 0.0902006 0.449922 v -0.351843 0.04895 0.416686 v -0.367248 0.00336155 0.369624 v -0.156137 -0.154941 0.536878 v -0.165134 -0.177028 0.538193 v -0.144573 -0.187364 0.558725 v -0.140533 -0.155882 0.559046 v -0.17761 -0.0804258 0.547933 v -0.201667 -0.0484356 0.526945 v -0.22024 -0.0817529 0.517585 v -0.195826 -0.106131 0.536439 v -0.207794 -0.213087 0.493049 v -0.191711 -0.188305 0.515551 v -0.201111 -0.170071 0.510745 v -0.223385 -0.183243 0.490178 v -0.128595 -0.132761 0.551212 v -0.145777 -0.139513 0.530605 v -0.0971664 0.171538 0.569909 v -0.120048 0.150182 0.555387 v -0.13557 0.119437 0.545004 v -0.113103 0.137432 0.569453 v -0.0653573 0.232432 0.569575 v -0.08745 0.217992 0.556468 v -0.0739395 0.185388 0.584933 v -0.0855266 0.255554 0.53095 v -0.110583 0.228714 0.525501 v -0.115915 0.191404 0.5495 v -0.300099 0.0366964 -0.387999 v -0.364734 0.0377897 -0.269357 v -0.223181 -0.243207 0.45081 v -0.246139 -0.195666 0.45347 v -0.271201 -0.199869 0.399446 v -0.362846 -0.197443 0.213286 v -0.410176 -0.124757 0.140565 v -0.430404 -0.00290555 0.0907385 v -0.448779 0.11075 0.0889086 v -0.142135 0.869847 0.301633 v -0.132167 0.771303 0.419317 v -0.0633989 0.777407 0.43288 v -0.0675789 0.877324 0.315577 v -0.353469 0.660735 0.264732 v -0.2875 0.723792 0.335465 v -0.30353 0.809117 0.220313 v -0.37099 0.728422 0.148627 v -0.381016 0.776764 0.0117274 v -0.0996744 0.472587 0.557146 v -0.109525 0.565325 0.53475 v -0.100294 0.277787 0.511248 v -0.108689 0.248457 0.503268 v -0.0528874 0.193947 0.604898 v -0.0453926 0.241125 0.586705 v -0.12255 0.668732 0.500514 v -0.0511336 0.564922 0.542589 v -0.0582191 0.671655 0.50974 v -0.0440363 0.465776 0.561151 v -0.0361966 0.388923 0.562367 v -0.301894 0.466338 0.448542 v -0.295831 0.424807 0.472166 v -0.140867 0.22264 0.499754 v -0.185742 0.209381 0.492394 v -0.186338 0.179495 0.502724 v -0.145859 0.19535 0.519018 v -0.0600022 0.0437294 0.578309 v -0.113337 0.0407946 0.564875 v -0.114196 0.0121659 0.564255 v -0.0686019 -0.00676987 0.598064 v -0.143661 0.0637116 0.537807 v -0.147607 0.0440217 0.535469 v -0.0907706 -0.0459919 0.600525 v -0.0300113 -0.0346152 0.623594 v -0.028047 -0.0138554 0.603173 v -0.148028 0.131527 0.5437 v -0.148519 0.164868 0.537322 v -0.183164 0.146873 0.520193 v -0.176978 0.112363 0.532908 v -0.147823 0.0979234 0.535574 v -0.165064 0.0766492 0.532955 v -0.120107 0.268649 0.480825 v -0.118558 0.262394 0.493353 v -0.115979 0.27287 0.494434 v -0.116476 0.272952 0.483859 v -0.229115 0.916634 0.120496 v -0.223379 0.848952 0.271461 v -0.145146 0.945128 0.150709 v -0.145409 0.980883 -0.0176788 v -0.154278 0.976311 -0.1834 v -0.240088 0.945514 -0.185786 v -0.230512 0.948548 -0.0401515 v -0.0669533 0.995411 -0.00979819 v -0.0669124 0.955581 0.163097 v -0.0891746 0.383199 0.554861 v -0.112226 0.336757 0.527307 v -0.123381 0.311174 0.513382 v -0.149484 -0.111966 0.558549 v -0.160264 -0.0991219 0.559216 v -0.0695139 0.122828 0.646821 v -0.103574 0.1197 0.616608 v -0.0967747 0.0873945 0.617683 v -0.0583127 0.0845006 0.640951 v -0.0810075 0.0824603 0.567973 v -0.0347818 0.058339 0.594989 v -0.031812 -0.0520134 0.636181 v -0.0876079 -0.0656701 0.61341 v -0.0905251 -0.101683 0.607529 v -0.0378686 -0.0937434 0.629054 v -0.0836617 -0.122507 0.579642 v -0.0385351 -0.11728 0.594673 v -0.0223295 0.0177081 0.586652 v -0.0307538 0.0864766 0.665646 v -0.0369098 0.125196 0.667078 v -0.0659946 0.154643 0.629212 v -0.0379446 0.159028 0.648136 v -0.0287544 0.19984 0.620642 v -0.0228205 0.245931 0.598298 v -0.0444456 0.281523 0.558544 v -0.0233467 0.287164 0.569581 v -0.348774 0.267521 0.384632 v -0.352083 0.30296 0.39367 v -0.371253 0.315308 0.363077 v -0.374871 0.266369 0.352501 v -0.422202 0.335746 0.207253 v -0.401928 0.429197 0.234116 v -0.395345 0.264083 0.313998 v -0.391071 0.32586 0.325679 v -0.312703 0.275793 0.421661 v -0.320315 0.291642 0.417107 v -0.332077 0.295173 0.409057 v -0.327599 0.271742 0.406824 v -0.429802 0.244434 0.203979 v -0.409282 0.332454 0.277442 v -0.411848 0.257886 0.266369 v -0.187414 -0.242265 0.510307 v -0.193763 -0.283183 0.474066 v -0.155254 -0.304954 0.501777 v -0.149998 -0.264183 0.526518 v -0.0567108 -0.227311 0.569523 v -0.101124 -0.233508 0.561461 v -0.11039 -0.27508 0.546021 v -0.066205 -0.270351 0.564711 v -0.154225 -0.138052 0.502391 v -0.159867 -0.142787 0.513271 v -0.15533 -0.142366 0.518626 v -0.148566 -0.137426 0.506285 v -0.160416 -0.138344 0.518258 v -0.161965 -0.141513 0.511996 v -0.110811 -0.126394 0.533276 v -0.10089 -0.129879 0.583501 v -0.0809374 -0.117865 0.558397 v -0.263876 0.014785 0.500935 v -0.26083 0.088932 0.49537 v -0.279702 0.127055 0.470506 v -0.207764 0.0867397 0.523776 v -0.187729 0.0509786 0.529558 v -0.232096 -0.0167025 0.518065 v -0.344056 0.133304 0.417078 v -0.302046 0.166376 0.445239 v -0.292551 0.225429 0.44414 v -0.316041 0.250468 0.418475 v -0.335386 -0.250836 0.156385 v -0.387207 -0.179618 0.074568 v -0.353755 -0.194151 0.0276524 v -0.292388 -0.279891 0.104617 v -0.392211 0.205733 0.320201 v -0.386651 0.150025 0.344942 v -0.126064 0.567371 -0.651942 v -0.117096 0.725914 -0.596082 v -0.209068 0.754227 0.387245 v -0.134091 -0.133281 0.515294 v -0.132384 -0.133778 0.530774 v -0.118289 -0.366228 0.490722 v -0.0673742 -0.375085 0.505343 v -0.0685259 -0.327012 0.553422 v -0.117722 -0.319453 0.530388 v -0.287793 -0.13528 0.424643 v -0.375234 0.0965671 0.380457 v -0.394351 0.054463 0.33218 v -0.0714373 0.993797 -0.182751 v -0.0825568 0.953558 -0.338084 v -0.177458 0.935674 -0.330221 v -0.176961 0.259482 0.501637 v -0.139651 0.267463 0.490903 v -0.141176 0.271537 0.486156 v -0.175792 0.263446 0.495797 v -0.139621 0.240295 0.49489 v -0.181918 0.230053 0.49499 v -0.335299 0.587722 0.356851 v -0.311189 0.51838 0.416464 v -0.263028 0.350391 0.495528 v -0.252435 0.331198 0.496568 v -0.111168 0.276448 0.500608 v -0.113553 0.255671 0.49582 v -0.124754 0.293525 0.500263 v -0.124275 0.282616 0.489933 v -0.138587 0.254671 0.496603 v -0.17851 0.246346 0.500783 v -0.120744 0.272286 0.476557 v -0.150635 0.0843194 0.549231 v -0.110981 -0.197039 0.578654 v -0.145877 -0.226522 0.547184 v -0.257825 -0.146365 0.464946 v -0.181813 -0.015013 0.533586 v -0.21057 0.0188715 0.525811 v -0.169226 -0.14996 0.516989 v -0.181743 -0.1588 0.515902 v -0.175376 -0.168545 0.522911 v -0.163813 -0.153415 0.52335 v -0.140253 -0.128364 0.545887 v -0.153091 -0.134363 0.527834 v -0.414608 -0.0714286 0.0335337 v -0.0376523 0.063203 0.628721 v -0.0232707 0.0530365 0.640016 v -0.190483 -0.134521 -0.42891 v -0.190425 -0.0530365 -0.446291 v -0.0856669 -0.0492716 -0.489617 v -0.0841703 -0.13027 -0.463549 v -0.238743 0.312729 0.498784 v -0.236568 0.310718 0.495914 v -0.245034 0.325784 0.495083 v -0.120311 0.281967 0.47734 v -0.176107 -0.207054 0.530523 v -0.114635 -0.15994 0.588938 v -0.0702155 -0.19877 0.595006 v -0.0735478 -0.165324 0.619338 v -0.0899814 0.151661 0.600396 v -0.111016 0.0572925 0.58557 v -0.101867 0.0715163 0.586237 v -0.127064 0.0733753 0.597824 v -0.136833 0.0543987 0.574241 v -0.135833 0.107312 0.581379 v -0.278287 0.38386 0.485911 v -0.171226 -0.145371 0.517737 v -0.0426215 -0.114106 0.575498 v -0.0575293 -0.131258 0.610721 v -0.0203535 0.0339429 0.602828 v -0.224215 0.246978 0.496697 v -0.219644 0.257664 0.498129 v -0.308126 0.284604 0.426215 v -0.296275 0.279026 0.430641 v -0.291721 0.275554 0.437358 v -0.286612 0.276705 0.435172 v -0.291949 0.280143 0.428238 v -0.065825 -0.384532 0.440825 v -0.11702 -0.382428 0.436651 v -0.374667 0.821265 -0.265393 v -0.3198 0.831958 -0.392208 v -0.362179 0.712818 -0.467507 v -0.425879 0.698185 -0.319692 v -0.269938 0.909215 -0.296313 v -0.308015 0.900609 -0.210562 v -0.440407 0.677046 -0.175192 v -0.387417 0.807117 -0.128411 v -0.312037 0.894728 -0.0788123 v -0.0720161 -0.391612 0.376675 v -0.127765 -0.376523 0.378341 v -0.124801 0.303066 0.504835 v -0.0997913 0.860855 -0.486022 v -0.212687 0.850449 -0.463771 v -0.245244 0.723306 -0.559461 v -0.199083 0.0271847 -0.488407 v -0.21986 0.118005 -0.554936 v -0.10327 0.117479 -0.600127 v -0.0928636 0.0273016 -0.53883 v -0.389259 0.144254 -0.303446 v -0.329178 0.130557 -0.444432 v -0.359227 0.250316 -0.491237 v -0.422325 0.258021 -0.333419 v -0.123907 0.397932 -0.664658 v -0.113699 0.240517 -0.645459 v -0.381641 0.401913 -0.512072 v -0.448592 0.395605 -0.3508 v -0.450574 0.547705 -0.348333 v -0.384366 0.562601 -0.506817 v -0.462722 0.528827 -0.195952 v -0.310604 0.866976 0.0721301 v -0.372013 -0.183143 -0.115123 v -0.387686 -0.0789994 -0.141781 v -0.2476 0.197566 0.475487 v -0.230342 0.231532 0.488372 v -0.129238 -0.0890256 0.584927 v -0.123544 -0.115971 0.574872 v -0.114588 -0.128867 0.557082 v -0.221702 0.122764 0.506442 v -0.216107 0.26119 0.49413 v -0.253242 0.263207 0.478422 v -0.256568 0.260547 0.479737 v -0.115342 0.273619 0.475323 v -0.298743 0.299903 0.422953 v -0.291698 0.283732 0.432722 v -0.295854 0.288181 0.418253 v -0.142059 0.263388 0.482491 v -0.120428 0.267802 0.470325 v -0.172108 0.256934 0.489641 v -0.275083 0.271584 0.453242 v -0.248582 0.25684 0.473757 v -0.275001 0.268573 0.446274 v -0.234253 0.331396 0.490634 v -0.187624 0.326819 0.49717 v -0.300292 0.274694 0.432944 v -0.135658 -0.0739483 0.577444 v -0.237428 0.052791 0.514919 v -0.0645564 0.270789 0.544612 v -0.373819 0.514195 0.287264 v -0.321852 -0.214718 -0.338184 v -0.348166 -0.27584 -0.333396 v -0.352171 -0.333378 -0.190533 v -0.354936 -0.247872 -0.205511 v -0.0936937 -0.549137 0.186785 v -0.35669 -0.197653 -0.0299733 v -0.393228 -0.0876225 -0.0664009 v -0.29161 -0.321499 0.0380294 v -0.393638 -0.0904403 -0.014329 v -0.241608 0.243201 -0.602916 v -0.263209 0.569914 -0.609242 v -0.349441 -0.283282 -0.0863831 v -0.194821 -0.209504 -0.418674 v -0.0862925 -0.206323 -0.448413 v -0.261795 0.402579 -0.621448 v -0.456233 0.372302 -0.191263 v -0.455245 0.384813 -0.0591282 v -0.408072 0.116608 0.297155 v -0.298661 0.260278 0.439147 v -0.287606 0.265861 0.450068 v -0.279696 0.270216 0.454289 v -0.162731 0.0172638 0.536515 v -0.13087 -0.0222973 0.565699 v -0.101475 0.0572691 0.580946 v -0.0809198 0.301049 0.528407 v -0.0556351 0.322972 0.54498 v -0.272306 0.242932 0.464508 v -0.262964 0.253017 0.476001 v -0.233067 0.158607 0.487893 v -0.412053 0.186142 0.273695 v -0.154815 -0.0532762 0.55793 v -0.0277489 0.331782 0.556427 v -0.286179 0.277611 0.427928 v -0.183941 -0.499632 0.122144 v -0.331493 -0.386257 -0.0698735 v -0.206238 -0.274279 -0.416026 v -0.0915482 -0.274332 -0.437317 v -0.277193 -0.438779 0.0481257 v -0.484037 0.177414 -0.0276816 v -0.458618 0.163319 -0.0553633 v -0.437233 0.124752 -0.0367315 v -0.471526 0.1616 -0.00366555 v -0.476232 0.247018 0.00445479 v -0.494987 0.232631 -0.0169773 v -0.491035 0.317921 -0.0441971 v -0.515688 0.298728 -0.0523583 v -0.510175 0.332513 -0.1293 v -0.532917 0.316524 -0.12405 v -0.50993 0.303592 -0.186815 v -0.534671 0.290233 -0.170849 v -0.510152 0.231181 -0.21891 v -0.537459 0.228895 -0.193058 v -0.48934 0.122068 -0.20872 v -0.519208 0.128879 -0.191363 v -0.469632 0.0399528 -0.15424 v -0.470766 -0.00661202 -0.0930419 v -0.486142 0.00947665 -0.0819458 v -0.495221 0.0472722 -0.1369 v -0.459705 -0.0431682 -0.033446 v -0.483546 -0.0248521 -0.0238816 v -0.494011 0.289082 -0.0628932 v -0.473502 0.238904 -0.0420457 v -0.507246 0.300137 -0.117724 v -0.512134 0.2833 -0.158502 v -0.513712 0.235303 -0.176549 v -0.50102 0.136093 -0.181582 v -0.485095 0.0532704 -0.118549 v -0.485253 0.0267755 -0.0671726 v -0.481172 0.0136801 -0.012201 v -0.456127 -0.0187428 0.0196958 v -0.462909 0.027933 0.024969 v -0.454923 0.0845591 -0.060163 v -0.441284 0.0577602 -0.0294063 v -0.440921 0.0840388 -0.0210813 v -0.457712 0.18288 0.0414318 v -0.458378 0.268123 0.0210228 v -0.461588 0.318505 -0.044618 v -0.468843 0.311858 -0.142898 v -0.453707 0.232836 -0.195204 v -0.436969 0.13182 -0.191047 v -0.423167 0.0473306 -0.148288 v -0.421945 -0.00467109 -0.089692 v -0.423991 -0.0291198 -0.0260915 v -0.429434 -0.0102776 0.0297746 v -0.445242 0.0345158 0.0460211 v -0.481617 0.0602039 -0.0524227 v -0.474104 0.129276 -0.0866754 v -0.480325 0.0824545 -0.101285 v -0.469474 0.0446648 -0.013376 v -0.478167 0.0776431 0.00467109 v -0.503592 0.223961 -0.101887 v -0.502575 0.131983 -0.147242 v -0.453707 0.0999988 0.0450097 v -0.413357 0.138549 -0.218945 v -0.402232 0.0251035 -0.169299 v -0.434023 0.249632 -0.229901 v -0.0871226 -0.186639 0.484069 v -0.139686 -0.173807 0.465537 v -0.158481 -0.142278 0.458685 v -0.0688299 0.0121893 0.376371 v -0.150805 -0.116468 0.431278 v -0.126228 -0.116368 0.360528 v -0.142316 -0.166791 0.41184 v -0.0730392 -0.218144 0.372349 v -0.282087 0.293548 0.454716 v -0.283513 0.320341 0.45129 v -0.124398 0.285323 0.452968 v -0.126795 0.269175 0.455978 v -0.119353 0.275057 0.469524 v -0.156265 0.2548 0.466332 v -0.265074 0.27356 0.421036 v -0.214762 0.253899 0.455218 v -0.141855 0.312577 0.484315 v -0.212745 0.255776 0.486875 v -0.277117 0.302621 0.410811 v -0.252014 0.333887 0.433371 v -0.20141 0.342405 0.464461 v -0.120767 0.295565 0.473184 v -0.145333 0.322832 0.456154 v -0.126041 0.301873 0.455785 v -0.119879 0.284837 0.470541 v -0.0516539 -0.100847 0.27211 v -0.454245 -0.41571 -0.353027 v -0.413392 -0.372097 -0.332203 v -0.255785 -0.398019 -0.4467 v -0.294685 -0.464338 -0.476902 v -0.174388 -0.714777 0.156607 v -0.0715543 -0.738454 0.180284 v -0.0798266 -0.636725 0.177765 v -0.171536 -0.601788 0.131147 v -0.337345 -0.494639 -0.0546091 v -0.355094 -0.419334 -0.180442 v -0.379665 -0.504905 -0.184915 v -0.373053 -0.619338 -0.0373044 v -0.45328 -0.545816 -0.197379 v -0.454128 -0.653065 -0.0942754 v -0.0965876 -0.904778 0.254759 v -0.0736004 -0.845567 0.20775 v -0.172974 -0.81408 0.195975 v -0.1973 -0.864375 0.243622 v -0.520961 -0.488138 -0.3841 v -0.556272 -0.584635 -0.21946 v -0.439238 -0.799155 0.0975785 v -0.381694 -0.748264 0.0442672 v -0.45103 -0.731883 -0.0219173 v -0.519067 -0.768135 -0.0077988 v -0.273785 -0.806328 0.115322 v -0.319391 -0.83802 0.183769 v -0.163088 -0.604103 -0.559421 v -0.356672 -0.543712 -0.525361 v -0.131226 -0.496761 -0.498854 v -0.114629 -0.410074 -0.45775 v -0.546533 -0.697291 -0.117619 v -0.100633 -0.33885 -0.437013 v -0.22677 -0.331835 -0.424707 v -0.274931 -0.684651 0.0790578 v -0.28021 -0.553908 0.0669913 v -0.378028 -0.321668 -0.326088 v 0.172833 0.300014 0.41564 v -0.171097 0.299996 0.415616 # 1258 vertices vt 0.532 0.923 0.000 vt 0.535 0.917 0.000 vt 0.542 0.923 0.000 vt 0.541 0.929 0.000 vt 0.521 0.984 0.000 vt 0.521 0.996 0.000 vt 0.505 0.998 0.000 vt 0.500 0.985 0.000 vt 0.504 0.917 0.000 vt 0.507 0.910 0.000 vt 0.516 0.910 0.000 vt 0.515 0.918 0.000 vt 0.523 0.921 0.000 vt 0.525 0.913 0.000 vt 0.549 0.958 0.000 vt 0.538 0.954 0.000 vt 0.544 0.942 0.000 vt 0.550 0.946 0.000 vt 0.545 0.935 0.000 vt 0.550 0.932 0.000 vt 0.547 0.974 0.000 vt 0.533 0.967 0.000 vt 0.500 0.917 0.000 vt 0.500 0.910 0.000 vt 0.542 0.987 0.000 vt 0.533 0.994 0.000 vt 0.616 0.254 0.000 vt 0.653 0.261 0.000 vt 0.658 0.307 0.000 vt 0.619 0.292 0.000 vt 0.636 0.438 0.000 vt 0.620 0.419 0.000 vt 0.627 0.396 0.000 vt 0.647 0.414 0.000 vt 0.886 0.312 0.000 vt 0.897 0.370 0.000 vt 0.860 0.369 0.000 vt 0.844 0.308 0.000 vt 0.740 0.593 0.000 vt 0.741 0.542 0.000 vt 0.759 0.541 0.000 vt 0.768 0.598 0.000 vt 0.644 0.213 0.000 vt 0.561 0.175 0.000 vt 0.566 0.146 0.000 vt 0.644 0.174 0.000 vt 0.580 0.254 0.000 vt 0.585 0.277 0.000 vt 0.565 0.268 0.000 vt 0.565 0.256 0.000 vt 0.590 0.217 0.000 vt 0.544 0.195 0.000 vt 0.771 0.721 0.000 vt 0.736 0.712 0.000 vt 0.758 0.653 0.000 vt 0.794 0.663 0.000 vt 0.669 0.622 0.000 vt 0.685 0.632 0.000 vt 0.665 0.669 0.000 vt 0.652 0.651 0.000 vt 0.623 0.588 0.000 vt 0.632 0.582 0.000 vt 0.639 0.590 0.000 vt 0.627 0.599 0.000 vt 0.641 0.632 0.000 vt 0.657 0.612 0.000 vt 0.619 0.580 0.000 vt 0.617 0.575 0.000 vt 0.623 0.573 0.000 vt 0.627 0.576 0.000 vt 0.708 0.702 0.000 vt 0.729 0.646 0.000 vt 0.633 0.614 0.000 vt 0.647 0.601 0.000 vt 0.604 0.718 0.000 vt 0.574 0.725 0.000 vt 0.567 0.686 0.000 vt 0.596 0.682 0.000 vt 0.562 0.648 0.000 vt 0.590 0.649 0.000 vt 0.618 0.756 0.000 vt 0.584 0.769 0.000 vt 0.586 0.587 0.000 vt 0.566 0.586 0.000 vt 0.568 0.579 0.000 vt 0.586 0.580 0.000 vt 0.569 0.574 0.000 vt 0.586 0.573 0.000 vt 0.562 0.627 0.000 vt 0.587 0.627 0.000 vt 0.587 0.610 0.000 vt 0.563 0.608 0.000 vt 0.565 0.595 0.000 vt 0.587 0.596 0.000 vt 0.521 0.441 0.000 vt 0.526 0.450 0.000 vt 0.520 0.450 0.000 vt 0.517 0.445 0.000 vt 0.720 0.504 0.000 vt 0.709 0.467 0.000 vt 0.727 0.446 0.000 vt 0.738 0.494 0.000 vt 0.656 0.383 0.000 vt 0.660 0.348 0.000 vt 0.684 0.368 0.000 vt 0.673 0.403 0.000 vt 0.572 0.371 0.000 vt 0.573 0.365 0.000 vt 0.581 0.364 0.000 vt 0.581 0.374 0.000 vt 0.708 0.400 0.000 vt 0.693 0.431 0.000 vt 0.604 0.401 0.000 vt 0.609 0.383 0.000 vt 0.557 0.364 0.000 vt 0.559 0.365 0.000 vt 0.557 0.366 0.000 vt 0.556 0.364 0.000 vt 0.552 0.367 0.000 vt 0.552 0.364 0.000 vt 0.568 0.377 0.000 vt 0.561 0.374 0.000 vt 0.566 0.370 0.000 vt 0.594 0.377 0.000 vt 0.594 0.363 0.000 vt 0.653 0.551 0.000 vt 0.644 0.534 0.000 vt 0.658 0.523 0.000 vt 0.666 0.545 0.000 vt 0.637 0.480 0.000 vt 0.625 0.458 0.000 vt 0.649 0.459 0.000 vt 0.662 0.434 0.000 vt 0.557 0.345 0.000 vt 0.553 0.353 0.000 vt 0.543 0.349 0.000 vt 0.546 0.337 0.000 vt 0.586 0.403 0.000 vt 0.573 0.392 0.000 vt 0.579 0.382 0.000 vt 0.591 0.389 0.000 vt 0.572 0.343 0.000 vt 0.584 0.331 0.000 vt 0.590 0.347 0.000 vt 0.578 0.353 0.000 vt 0.553 0.358 0.000 vt 0.543 0.355 0.000 vt 0.553 0.499 0.000 vt 0.541 0.507 0.000 vt 0.542 0.484 0.000 vt 0.553 0.477 0.000 vt 0.539 0.532 0.000 vt 0.529 0.541 0.000 vt 0.531 0.513 0.000 vt 0.551 0.538 0.000 vt 0.538 0.552 0.000 vt 0.552 0.521 0.000 vt 0.908 0.437 0.000 vt 0.876 0.429 0.000 vt 0.608 0.340 0.000 vt 0.599 0.314 0.000 vt 0.629 0.336 0.000 vt 0.691 0.326 0.000 vt 0.723 0.365 0.000 vt 0.748 0.426 0.000 vt 0.755 0.489 0.000 vt 0.564 0.825 0.000 vt 0.590 0.868 0.000 vt 0.558 0.886 0.000 vt 0.533 0.834 0.000 vt 0.637 0.789 0.000 vt 0.673 0.755 0.000 vt 0.702 0.774 0.000 vt 0.665 0.817 0.000 vt 0.740 0.787 0.000 vt 0.545 0.727 0.000 vt 0.540 0.686 0.000 vt 0.551 0.550 0.000 vt 0.538 0.572 0.000 vt 0.520 0.546 0.000 vt 0.522 0.517 0.000 vt 0.552 0.775 0.000 vt 0.524 0.777 0.000 vt 0.521 0.728 0.000 vt 0.500 0.687 0.000 vt 0.500 0.651 0.000 vt 0.515 0.650 0.000 vt 0.518 0.687 0.000 vt 0.500 0.727 0.000 vt 0.625 0.671 0.000 vt 0.618 0.644 0.000 vt 0.591 0.533 0.000 vt 0.571 0.539 0.000 vt 0.569 0.527 0.000 vt 0.589 0.518 0.000 vt 0.545 0.436 0.000 vt 0.525 0.427 0.000 vt 0.528 0.413 0.000 vt 0.549 0.425 0.000 vt 0.556 0.449 0.000 vt 0.563 0.439 0.000 vt 0.514 0.395 0.000 vt 0.532 0.396 0.000 vt 0.513 0.409 0.000 vt 0.566 0.511 0.000 vt 0.564 0.490 0.000 vt 0.577 0.478 0.000 vt 0.584 0.500 0.000 vt 0.500 0.408 0.000 vt 0.500 0.394 0.000 vt 0.571 0.457 0.000 vt 0.561 0.468 0.000 vt 0.554 0.561 0.000 vt 0.557 0.563 0.000 vt 0.552 0.569 0.000 vt 0.548 0.569 0.000 vt 0.627 0.847 0.000 vt 0.674 0.871 0.000 vt 0.645 0.898 0.000 vt 0.776 0.920 0.000 vt 0.709 0.921 0.000 vt 0.729 0.888 0.000 vt 0.783 0.887 0.000 vt 0.693 0.947 0.000 vt 0.621 0.920 0.000 vt 0.535 0.642 0.000 vt 0.542 0.618 0.000 vt 0.545 0.599 0.000 vt 0.559 0.383 0.000 vt 0.552 0.377 0.000 vt 0.531 0.470 0.000 vt 0.520 0.472 0.000 vt 0.517 0.456 0.000 vt 0.528 0.457 0.000 vt 0.530 0.438 0.000 vt 0.517 0.436 0.000 vt 0.528 0.383 0.000 vt 0.513 0.384 0.000 vt 0.512 0.374 0.000 vt 0.526 0.374 0.000 vt 0.512 0.367 0.000 vt 0.526 0.366 0.000 vt 0.512 0.362 0.000 vt 0.526 0.362 0.000 vt 0.511 0.422 0.000 vt 0.500 0.384 0.000 vt 0.500 0.375 0.000 vt 0.500 0.362 0.000 vt 0.500 0.367 0.000 vt 0.511 0.472 0.000 vt 0.508 0.457 0.000 vt 0.521 0.491 0.000 vt 0.512 0.519 0.000 vt 0.512 0.491 0.000 vt 0.511 0.550 0.000 vt 0.520 0.576 0.000 vt 0.510 0.583 0.000 vt 0.500 0.457 0.000 vt 0.500 0.472 0.000 vt 0.500 0.491 0.000 vt 0.654 0.584 0.000 vt 0.656 0.568 0.000 vt 0.669 0.567 0.000 vt 0.666 0.589 0.000 vt 0.705 0.639 0.000 vt 0.718 0.591 0.000 vt 0.684 0.563 0.000 vt 0.680 0.592 0.000 vt 0.637 0.575 0.000 vt 0.636 0.566 0.000 vt 0.645 0.567 0.000 vt 0.645 0.579 0.000 vt 0.723 0.546 0.000 vt 0.697 0.592 0.000 vt 0.702 0.554 0.000 vt 0.500 0.163 0.000 vt 0.500 0.137 0.000 vt 0.579 0.298 0.000 vt 0.570 0.317 0.000 vt 0.554 0.307 0.000 vt 0.560 0.287 0.000 vt 0.534 0.318 0.000 vt 0.517 0.314 0.000 vt 0.519 0.296 0.000 vt 0.538 0.300 0.000 vt 0.562 0.362 0.000 vt 0.559 0.363 0.000 vt 0.557 0.362 0.000 vt 0.559 0.360 0.000 vt 0.563 0.365 0.000 vt 0.561 0.368 0.000 vt 0.543 0.360 0.000 vt 0.531 0.358 0.000 vt 0.531 0.351 0.000 vt 0.611 0.437 0.000 vt 0.613 0.475 0.000 vt 0.624 0.497 0.000 vt 0.580 0.445 0.000 vt 0.590 0.466 0.000 vt 0.598 0.418 0.000 vt 0.648 0.501 0.000 vt 0.633 0.516 0.000 vt 0.641 0.554 0.000 vt 0.630 0.541 0.000 vt 0.733 0.331 0.000 vt 0.696 0.288 0.000 vt 0.706 0.252 0.000 vt 0.751 0.313 0.000 vt 0.683 0.535 0.000 vt 0.674 0.508 0.000 vt 0.999 0.696 0.000 vt 0.986 0.778 0.000 vt 0.950 0.772 0.000 vt 0.967 0.695 0.000 vt 0.600 0.811 0.000 vt 0.552 0.361 0.000 vt 0.547 0.367 0.000 vt 0.546 0.364 0.000 vt 0.525 0.254 0.000 vt 0.546 0.261 0.000 vt 0.542 0.280 0.000 vt 0.522 0.274 0.000 vt 0.631 0.369 0.000 vt 0.678 0.460 0.000 vt 0.662 0.482 0.000 vt 0.770 0.948 0.000 vt 0.762 0.981 0.000 vt 0.676 0.977 0.000 vt 0.845 0.915 0.000 vt 0.835 0.891 0.000 vt 0.569 0.560 0.000 vt 0.582 0.558 0.000 vt 0.580 0.563 0.000 vt 0.569 0.564 0.000 vt 0.590 0.544 0.000 vt 0.571 0.548 0.000 vt 0.635 0.701 0.000 vt 0.651 0.731 0.000 vt 0.607 0.593 0.000 vt 0.609 0.606 0.000 vt 0.543 0.570 0.000 vt 0.553 0.556 0.000 vt 0.552 0.580 0.000 vt 0.556 0.574 0.000 vt 0.569 0.554 0.000 vt 0.585 0.551 0.000 vt 0.559 0.566 0.000 vt 0.550 0.458 0.000 vt 0.532 0.330 0.000 vt 0.549 0.325 0.000 vt 0.610 0.364 0.000 vt 0.589 0.432 0.000 vt 0.578 0.417 0.000 vt 0.570 0.357 0.000 vt 0.565 0.360 0.000 vt 0.562 0.356 0.000 vt 0.565 0.351 0.000 vt 0.557 0.364 0.000 vt 0.556 0.364 0.000 vt 0.548 0.371 0.000 vt 0.557 0.371 0.000 vt 0.762 0.385 0.000 vt 0.513 0.445 0.000 vt 0.508 0.444 0.000 vt 0.500 0.520 0.000 vt 0.939 0.378 0.000 vt 0.932 0.316 0.000 vt 0.972 0.321 0.000 vt 0.974 0.384 0.000 vt 0.605 0.572 0.000 vt 0.605 0.578 0.000 vt 0.605 0.584 0.000 vt 0.559 0.571 0.000 vt 0.562 0.333 0.000 vt 0.500 0.552 0.000 vt 0.500 0.585 0.000 vt 0.531 0.343 0.000 vt 0.514 0.338 0.000 vt 0.516 0.324 0.000 vt 0.532 0.488 0.000 vt 0.534 0.448 0.000 vt 0.540 0.446 0.000 vt 0.545 0.448 0.000 vt 0.538 0.455 0.000 vt 0.541 0.466 0.000 vt 0.612 0.623 0.000 vt 0.567 0.366 0.000 vt 0.513 0.356 0.000 vt 0.500 0.355 0.000 vt 0.500 0.346 0.000 vt 0.514 0.348 0.000 vt 0.543 0.363 0.000 vt 0.552 0.364 0.000 vt 0.531 0.362 0.000 vt 0.512 0.361 0.000 vt 0.509 0.433 0.000 vt 0.500 0.444 0.000 vt 0.500 0.432 0.000 vt 0.603 0.551 0.000 vt 0.599 0.557 0.000 vt 0.627 0.570 0.000 vt 0.631 0.571 0.000 vt 0.625 0.566 0.000 vt 0.622 0.569 0.000 vt 0.621 0.567 0.000 vt 0.529 0.234 0.000 vt 0.500 0.249 0.000 vt 0.500 0.227 0.000 vt 0.550 0.245 0.000 vt 0.857 0.816 0.000 vt 0.825 0.804 0.000 vt 0.851 0.737 0.000 vt 0.886 0.748 0.000 vt 0.821 0.866 0.000 vt 0.798 0.856 0.000 vt 0.783 0.797 0.000 vt 0.810 0.729 0.000 vt 0.755 0.848 0.000 vt 0.534 0.215 0.000 vt 0.563 0.233 0.000 vt 0.548 0.588 0.000 vt 0.884 0.835 0.000 vt 0.908 0.854 0.000 vt 0.919 0.761 0.000 vt 0.947 0.512 0.000 vt 0.944 0.446 0.000 vt 0.974 0.452 0.000 vt 0.974 0.519 0.000 vt 0.915 0.504 0.000 vt 0.887 0.498 0.000 vt 0.917 0.564 0.000 vt 0.890 0.556 0.000 vt 0.999 0.634 0.000 vt 0.973 0.633 0.000 vt 0.975 0.577 0.000 vt 0.999 0.579 0.000 vt 0.882 0.614 0.000 vt 0.911 0.622 0.000 vt 0.901 0.679 0.000 vt 0.868 0.671 0.000 vt 0.833 0.667 0.000 vt 0.708 0.836 0.000 vt 0.500 0.205 0.000 vt 0.826 0.364 0.000 vt 0.801 0.303 0.000 vt 0.613 0.529 0.000 vt 0.607 0.544 0.000 vt 0.541 0.380 0.000 vt 0.538 0.372 0.000 vt 0.537 0.366 0.000 vt 0.537 0.363 0.000 vt 0.598 0.945 0.000 vt 0.524 0.902 0.000 vt 0.599 0.489 0.000 vt 0.609 0.563 0.000 vt 0.596 0.563 0.000 vt 0.612 0.559 0.000 vt 0.557 0.569 0.000 vt 0.620 0.571 0.000 vt 0.616 0.569 0.000 vt 0.618 0.569 0.000 vt 0.569 0.568 0.000 vt 0.561 0.568 0.000 vt 0.579 0.567 0.000 vt 0.616 0.564 0.000 vt 0.613 0.567 0.000 vt 0.607 0.567 0.000 vt 0.587 0.568 0.000 vt 0.606 0.568 0.000 vt 0.630 0.565 0.000 vt 0.548 0.389 0.000 vt 0.601 0.452 0.000 vt 0.529 0.566 0.000 vt 0.684 0.686 0.000 vt 0.872 0.222 0.000 vt 0.876 0.265 0.000 vt 0.825 0.258 0.000 vt 0.821 0.214 0.000 vt 0.561 0.119 0.000 vt 0.500 0.114 0.000 vt 0.771 0.304 0.000 vt 0.797 0.363 0.000 vt 0.726 0.227 0.000 vt 0.777 0.371 0.000 vt 0.947 0.571 0.000 vt 0.999 0.388 0.000 vt 0.999 0.456 0.000 vt 0.999 0.524 0.000 vt 0.936 0.877 0.000 vt 0.856 0.945 0.000 vt 0.999 0.323 0.000 vt 0.935 0.689 0.000 vt 0.776 0.240 0.000 vt 0.928 0.265 0.000 vt 0.969 0.264 0.000 vt 0.999 0.267 0.000 vt 0.943 0.628 0.000 vt 0.806 0.622 0.000 vt 0.851 0.611 0.000 vt 0.500 0.777 0.000 vt 0.500 0.839 0.000 vt 0.692 0.489 0.000 vt 0.631 0.558 0.000 vt 0.622 0.562 0.000 vt 0.626 0.560 0.000 vt 0.555 0.413 0.000 vt 0.570 0.429 0.000 vt 0.539 0.440 0.000 vt 0.524 0.607 0.000 vt 0.531 0.591 0.000 vt 0.500 0.361 0.000 vt 0.500 0.321 0.000 vt 0.500 0.312 0.000 vt 0.500 0.336 0.000 vt 0.500 0.294 0.000 vt 0.500 0.273 0.000 vt 0.622 0.549 0.000 vt 0.616 0.554 0.000 vt 0.607 0.509 0.000 vt 0.701 0.520 0.000 vt 0.500 0.421 0.000 vt 0.564 0.403 0.000 vt 0.511 0.615 0.000 vt 0.500 0.618 0.000 vt 0.617 0.568 0.000 vt 0.636 0.139 0.000 vt 0.764 0.192 0.000 vt 0.921 0.220 0.000 vt 0.967 0.219 0.000 vt 0.708 0.168 0.000 vt 0.999 0.218 0.000 vt 0.803 0.523 0.000 vt 0.794 0.535 0.000 vt 0.783 0.527 0.000 vt 0.791 0.508 0.000 vt 0.789 0.571 0.000 vt 0.797 0.562 0.000 vt 0.813 0.591 0.000 vt 0.815 0.578 0.000 vt 0.839 0.583 0.000 vt 0.835 0.574 0.000 vt 0.850 0.569 0.000 vt 0.845 0.560 0.000 vt 0.855 0.539 0.000 vt 0.847 0.535 0.000 vt 0.850 0.501 0.000 vt 0.841 0.502 0.000 vt 0.814 0.438 0.000 vt 0.836 0.464 0.000 vt 0.828 0.472 0.000 vt 0.809 0.452 0.000 vt 0.792 0.427 0.000 vt 0.790 0.441 0.000 vt 0.818 0.567 0.000 vt 0.807 0.550 0.000 vt 0.831 0.561 0.000 vt 0.839 0.553 0.000 vt 0.837 0.534 0.000 vt 0.831 0.505 0.000 vt 0.820 0.479 0.000 vt 0.804 0.465 0.000 vt 0.786 0.460 0.000 vt 0.773 0.456 0.000 vt 0.779 0.433 0.000 vt 0.797 0.489 0.000 vt 0.785 0.495 0.000 vt 0.789 0.486 0.000 vt 0.772 0.537 0.000 vt 0.781 0.583 0.000 vt 0.812 0.602 0.000 vt 0.848 0.587 0.000 vt 0.862 0.546 0.000 vt 0.859 0.500 0.000 vt 0.820 0.412 0.000 vt 0.843 0.450 0.000 vt 0.791 0.404 0.000 vt 0.773 0.417 0.000 vt 0.764 0.447 0.000 vt 0.801 0.477 0.000 vt 0.813 0.487 0.000 vt 0.806 0.496 0.000 vt 0.787 0.478 0.000 vt 0.778 0.489 0.000 vt 0.822 0.538 0.000 vt 0.822 0.510 0.000 vt 0.767 0.492 0.000 vt 0.870 0.496 0.000 vt 0.851 0.425 0.000 vt 0.872 0.552 0.000 vt 0.500 0.183 0.000 vt 0.516 0.930 0.000 vt 0.500 0.928 0.000 vt 0.528 0.934 0.000 vt 0.537 0.938 0.000 vt 0.516 0.970 0.000 vt 0.520 0.955 0.000 vt 0.530 0.952 0.000 vt 0.522 0.944 0.000 vt 0.512 0.942 0.000 vt 0.615 0.572 0.000 vt 0.612 0.569 0.000 vt 0.576 0.968 0.000 vt 0.573 0.973 0.000 vt 0.562 0.969 0.000 vt 0.563 0.961 0.000 vt 0.571 0.956 0.000 vt 0.582 0.961 0.000 vt 0.611 0.961 0.000 vt 0.606 0.967 0.000 vt 0.595 0.960 0.000 vt 0.601 0.955 0.000 vt 0.570 0.569 0.000 vt 0.595 0.566 0.000 vt 0.616 0.967 0.000 vt 0.617 0.975 0.000 vt 0.607 0.978 0.000 vt 0.614 0.982 0.000 vt 0.605 0.991 0.000 vt 0.599 0.986 0.000 vt 0.593 0.996 0.000 vt 0.589 0.989 0.000 vt 0.562 0.570 0.000 vt 0.573 0.994 0.000 vt 0.579 0.987 0.000 vt 0.584 0.996 0.000 vt 0.581 0.953 0.000 vt 0.592 0.953 0.000 vt 0.561 0.988 0.000 vt 0.572 0.981 0.000 vt 0.563 0.978 0.000 vt 0.500 0.970 0.000 vt 0.500 0.943 0.000 vt 0.511 0.956 0.000 vt 0.500 0.956 0.000 vt 0.868 0.132 0.000 vt 0.867 0.090 0.000 vt 0.916 0.092 0.000 vt 0.918 0.133 0.000 vt 0.554 0.066 0.000 vt 0.612 0.070 0.000 vt 0.619 0.103 0.000 vt 0.558 0.095 0.000 vt 0.815 0.169 0.000 vt 0.758 0.148 0.000 vt 0.747 0.102 0.000 vt 0.814 0.126 0.000 vt 0.770 0.072 0.000 vt 0.817 0.087 0.000 vt 0.552 0.038 0.000 vt 0.551 0.020 0.000 vt 0.602 0.021 0.000 vt 0.605 0.039 0.000 vt 0.821 0.050 0.000 vt 0.867 0.055 0.000 vt 0.712 0.053 0.000 vt 0.700 0.022 0.000 vt 0.739 0.023 0.000 vt 0.740 0.052 0.000 vt 0.652 0.022 0.000 vt 0.659 0.043 0.000 vt 0.913 0.055 0.000 vt 0.959 0.055 0.000 vt 0.960 0.091 0.000 vt 0.999 0.089 0.000 vt 0.999 0.131 0.000 vt 0.962 0.133 0.000 vt 0.999 0.053 0.000 vt 0.778 0.038 0.000 vt 0.917 0.177 0.000 vt 0.965 0.178 0.000 vt 0.674 0.083 0.000 vt 0.685 0.124 0.000 vt 0.999 0.175 0.000 vt 0.500 0.037 0.000 vt 0.500 0.066 0.000 vt 0.871 0.175 0.000 vt 0.500 0.019 0.000 vt 0.500 0.092 0.000 vt 0.999 0.002 0.000 vt 0.958 0.002 0.000 vt 0.867 0.002 0.000 vt 0.823 0.002 0.000 vt 0.908 0.002 0.000 vt 0.601 0.002 0.000 vt 0.550 0.002 0.000 vt 0.697 0.002 0.000 vt 0.650 0.002 0.000 vt 0.782 0.002 0.000 vt 0.740 0.002 0.000 vt 0.500 0.002 0.000 vt 0.468 0.923 0.000 vt 0.459 0.929 0.000 vt 0.458 0.923 0.000 vt 0.465 0.917 0.000 vt 0.479 0.984 0.000 vt 0.495 0.998 0.000 vt 0.479 0.996 0.000 vt 0.496 0.917 0.000 vt 0.485 0.918 0.000 vt 0.484 0.910 0.000 vt 0.493 0.910 0.000 vt 0.477 0.921 0.000 vt 0.475 0.913 0.000 vt 0.451 0.958 0.000 vt 0.450 0.946 0.000 vt 0.456 0.942 0.000 vt 0.462 0.954 0.000 vt 0.455 0.935 0.000 vt 0.450 0.932 0.000 vt 0.467 0.967 0.000 vt 0.453 0.974 0.000 vt 0.467 0.994 0.000 vt 0.458 0.987 0.000 vt 0.384 0.254 0.000 vt 0.381 0.292 0.000 vt 0.342 0.307 0.000 vt 0.347 0.261 0.000 vt 0.364 0.438 0.000 vt 0.353 0.414 0.000 vt 0.373 0.396 0.000 vt 0.380 0.419 0.000 vt 0.114 0.312 0.000 vt 0.156 0.308 0.000 vt 0.140 0.369 0.000 vt 0.103 0.370 0.000 vt 0.260 0.593 0.000 vt 0.232 0.598 0.000 vt 0.241 0.541 0.000 vt 0.259 0.542 0.000 vt 0.356 0.213 0.000 vt 0.356 0.174 0.000 vt 0.434 0.146 0.000 vt 0.439 0.175 0.000 vt 0.420 0.254 0.000 vt 0.435 0.256 0.000 vt 0.435 0.268 0.000 vt 0.415 0.277 0.000 vt 0.456 0.195 0.000 vt 0.410 0.217 0.000 vt 0.229 0.721 0.000 vt 0.206 0.663 0.000 vt 0.242 0.653 0.000 vt 0.264 0.712 0.000 vt 0.331 0.622 0.000 vt 0.348 0.651 0.000 vt 0.335 0.669 0.000 vt 0.315 0.632 0.000 vt 0.377 0.588 0.000 vt 0.373 0.599 0.000 vt 0.361 0.590 0.000 vt 0.368 0.582 0.000 vt 0.359 0.632 0.000 vt 0.343 0.612 0.000 vt 0.381 0.580 0.000 vt 0.373 0.576 0.000 vt 0.377 0.573 0.000 vt 0.383 0.575 0.000 vt 0.292 0.702 0.000 vt 0.271 0.646 0.000 vt 0.353 0.601 0.000 vt 0.367 0.614 0.000 vt 0.396 0.718 0.000 vt 0.404 0.682 0.000 vt 0.433 0.686 0.000 vt 0.426 0.725 0.000 vt 0.410 0.649 0.000 vt 0.438 0.648 0.000 vt 0.416 0.769 0.000 vt 0.382 0.756 0.000 vt 0.414 0.587 0.000 vt 0.414 0.580 0.000 vt 0.432 0.579 0.000 vt 0.434 0.586 0.000 vt 0.431 0.574 0.000 vt 0.414 0.573 0.000 vt 0.413 0.627 0.000 vt 0.438 0.627 0.000 vt 0.413 0.610 0.000 vt 0.413 0.596 0.000 vt 0.435 0.595 0.000 vt 0.437 0.608 0.000 vt 0.479 0.441 0.000 vt 0.483 0.445 0.000 vt 0.480 0.450 0.000 vt 0.474 0.450 0.000 vt 0.280 0.504 0.000 vt 0.262 0.494 0.000 vt 0.273 0.446 0.000 vt 0.291 0.467 0.000 vt 0.344 0.383 0.000 vt 0.327 0.403 0.000 vt 0.316 0.368 0.000 vt 0.340 0.348 0.000 vt 0.428 0.371 0.000 vt 0.419 0.374 0.000 vt 0.419 0.364 0.000 vt 0.427 0.365 0.000 vt 0.307 0.431 0.000 vt 0.292 0.400 0.000 vt 0.391 0.383 0.000 vt 0.396 0.401 0.000 vt 0.443 0.364 0.000 vt 0.444 0.364 0.000 vt 0.443 0.366 0.000 vt 0.441 0.365 0.000 vt 0.448 0.367 0.000 vt 0.448 0.364 0.000 vt 0.432 0.377 0.000 vt 0.434 0.370 0.000 vt 0.439 0.374 0.000 vt 0.406 0.377 0.000 vt 0.406 0.363 0.000 vt 0.347 0.551 0.000 vt 0.334 0.545 0.000 vt 0.342 0.523 0.000 vt 0.356 0.534 0.000 vt 0.363 0.480 0.000 vt 0.351 0.459 0.000 vt 0.375 0.458 0.000 vt 0.338 0.434 0.000 vt 0.443 0.345 0.000 vt 0.454 0.337 0.000 vt 0.457 0.349 0.000 vt 0.447 0.353 0.000 vt 0.414 0.403 0.000 vt 0.409 0.389 0.000 vt 0.421 0.382 0.000 vt 0.427 0.392 0.000 vt 0.428 0.343 0.000 vt 0.422 0.353 0.000 vt 0.410 0.347 0.000 vt 0.416 0.331 0.000 vt 0.457 0.355 0.000 vt 0.447 0.358 0.000 vt 0.447 0.499 0.000 vt 0.447 0.477 0.000 vt 0.458 0.484 0.000 vt 0.459 0.507 0.000 vt 0.461 0.532 0.000 vt 0.469 0.513 0.000 vt 0.471 0.541 0.000 vt 0.449 0.538 0.000 vt 0.448 0.521 0.000 vt 0.462 0.552 0.000 vt 0.124 0.429 0.000 vt 0.092 0.437 0.000 vt 0.392 0.340 0.000 vt 0.371 0.336 0.000 vt 0.401 0.314 0.000 vt 0.309 0.326 0.000 vt 0.252 0.426 0.000 vt 0.277 0.365 0.000 vt 0.245 0.489 0.000 vt 0.436 0.825 0.000 vt 0.467 0.834 0.000 vt 0.442 0.886 0.000 vt 0.410 0.868 0.000 vt 0.363 0.789 0.000 vt 0.335 0.817 0.000 vt 0.298 0.774 0.000 vt 0.327 0.755 0.000 vt 0.260 0.787 0.000 vt 0.460 0.686 0.000 vt 0.455 0.727 0.000 vt 0.462 0.572 0.000 vt 0.449 0.550 0.000 vt 0.480 0.546 0.000 vt 0.478 0.517 0.000 vt 0.479 0.728 0.000 vt 0.476 0.777 0.000 vt 0.448 0.775 0.000 vt 0.482 0.687 0.000 vt 0.485 0.650 0.000 vt 0.375 0.671 0.000 vt 0.382 0.644 0.000 vt 0.409 0.533 0.000 vt 0.411 0.518 0.000 vt 0.431 0.527 0.000 vt 0.429 0.539 0.000 vt 0.455 0.436 0.000 vt 0.451 0.425 0.000 vt 0.472 0.413 0.000 vt 0.475 0.427 0.000 vt 0.444 0.449 0.000 vt 0.437 0.439 0.000 vt 0.486 0.395 0.000 vt 0.487 0.409 0.000 vt 0.468 0.396 0.000 vt 0.434 0.511 0.000 vt 0.416 0.500 0.000 vt 0.423 0.478 0.000 vt 0.436 0.490 0.000 vt 0.429 0.457 0.000 vt 0.439 0.468 0.000 vt 0.446 0.561 0.000 vt 0.452 0.569 0.000 vt 0.448 0.569 0.000 vt 0.443 0.563 0.000 vt 0.373 0.847 0.000 vt 0.355 0.898 0.000 vt 0.326 0.871 0.000 vt 0.224 0.920 0.000 vt 0.217 0.887 0.000 vt 0.271 0.888 0.000 vt 0.291 0.921 0.000 vt 0.379 0.920 0.000 vt 0.307 0.947 0.000 vt 0.465 0.642 0.000 vt 0.455 0.599 0.000 vt 0.458 0.618 0.000 vt 0.448 0.377 0.000 vt 0.441 0.383 0.000 vt 0.469 0.470 0.000 vt 0.472 0.457 0.000 vt 0.483 0.456 0.000 vt 0.480 0.472 0.000 vt 0.470 0.438 0.000 vt 0.483 0.436 0.000 vt 0.472 0.383 0.000 vt 0.474 0.374 0.000 vt 0.488 0.374 0.000 vt 0.487 0.384 0.000 vt 0.474 0.366 0.000 vt 0.488 0.367 0.000 vt 0.474 0.362 0.000 vt 0.488 0.362 0.000 vt 0.489 0.422 0.000 vt 0.492 0.457 0.000 vt 0.489 0.472 0.000 vt 0.479 0.491 0.000 vt 0.488 0.491 0.000 vt 0.488 0.519 0.000 vt 0.489 0.550 0.000 vt 0.490 0.583 0.000 vt 0.480 0.576 0.000 vt 0.346 0.584 0.000 vt 0.334 0.589 0.000 vt 0.331 0.567 0.000 vt 0.344 0.568 0.000 vt 0.295 0.639 0.000 vt 0.282 0.591 0.000 vt 0.320 0.592 0.000 vt 0.316 0.563 0.000 vt 0.363 0.575 0.000 vt 0.355 0.579 0.000 vt 0.355 0.567 0.000 vt 0.364 0.566 0.000 vt 0.277 0.546 0.000 vt 0.298 0.554 0.000 vt 0.303 0.592 0.000 vt 0.421 0.298 0.000 vt 0.440 0.287 0.000 vt 0.446 0.307 0.000 vt 0.430 0.317 0.000 vt 0.466 0.318 0.000 vt 0.462 0.300 0.000 vt 0.481 0.296 0.000 vt 0.483 0.314 0.000 vt 0.438 0.362 0.000 vt 0.441 0.360 0.000 vt 0.443 0.362 0.000 vt 0.441 0.363 0.000 vt 0.439 0.368 0.000 vt 0.437 0.365 0.000 vt 0.469 0.351 0.000 vt 0.469 0.358 0.000 vt 0.457 0.360 0.000 vt 0.389 0.437 0.000 vt 0.387 0.475 0.000 vt 0.376 0.497 0.000 vt 0.420 0.445 0.000 vt 0.410 0.466 0.000 vt 0.402 0.418 0.000 vt 0.352 0.501 0.000 vt 0.367 0.516 0.000 vt 0.359 0.554 0.000 vt 0.370 0.541 0.000 vt 0.267 0.331 0.000 vt 0.249 0.313 0.000 vt 0.294 0.252 0.000 vt 0.304 0.288 0.000 vt 0.317 0.535 0.000 vt 0.326 0.508 0.000 vt 0.001 0.696 0.000 vt 0.033 0.695 0.000 vt 0.050 0.772 0.000 vt 0.014 0.778 0.000 vt 0.400 0.811 0.000 vt 0.448 0.361 0.000 vt 0.454 0.364 0.000 vt 0.453 0.367 0.000 vt 0.475 0.254 0.000 vt 0.478 0.274 0.000 vt 0.458 0.280 0.000 vt 0.454 0.261 0.000 vt 0.369 0.369 0.000 vt 0.322 0.460 0.000 vt 0.338 0.482 0.000 vt 0.324 0.977 0.000 vt 0.238 0.981 0.000 vt 0.230 0.948 0.000 vt 0.155 0.915 0.000 vt 0.165 0.891 0.000 vt 0.431 0.560 0.000 vt 0.431 0.564 0.000 vt 0.420 0.563 0.000 vt 0.418 0.558 0.000 vt 0.410 0.544 0.000 vt 0.429 0.548 0.000 vt 0.349 0.731 0.000 vt 0.365 0.701 0.000 vt 0.391 0.606 0.000 vt 0.393 0.593 0.000 vt 0.457 0.570 0.000 vt 0.447 0.556 0.000 vt 0.444 0.574 0.000 vt 0.448 0.580 0.000 vt 0.415 0.551 0.000 vt 0.431 0.554 0.000 vt 0.441 0.566 0.000 vt 0.450 0.458 0.000 vt 0.451 0.325 0.000 vt 0.468 0.330 0.000 vt 0.390 0.364 0.000 vt 0.411 0.432 0.000 vt 0.422 0.417 0.000 vt 0.430 0.357 0.000 vt 0.435 0.351 0.000 vt 0.438 0.356 0.000 vt 0.435 0.360 0.000 vt 0.443 0.364 0.000 vt 0.444 0.364 0.000 vt 0.443 0.371 0.000 vt 0.452 0.371 0.000 vt 0.238 0.385 0.000 vt 0.487 0.445 0.000 vt 0.492 0.444 0.000 vt 0.061 0.378 0.000 vt 0.026 0.384 0.000 vt 0.028 0.321 0.000 vt 0.068 0.316 0.000 vt 0.395 0.572 0.000 vt 0.395 0.578 0.000 vt 0.395 0.584 0.000 vt 0.441 0.571 0.000 vt 0.438 0.333 0.000 vt 0.469 0.343 0.000 vt 0.486 0.338 0.000 vt 0.484 0.324 0.000 vt 0.468 0.488 0.000 vt 0.466 0.448 0.000 vt 0.462 0.455 0.000 vt 0.455 0.448 0.000 vt 0.460 0.446 0.000 vt 0.459 0.466 0.000 vt 0.388 0.623 0.000 vt 0.433 0.366 0.000 vt 0.487 0.356 0.000 vt 0.486 0.348 0.000 vt 0.457 0.363 0.000 vt 0.448 0.364 0.000 vt 0.469 0.362 0.000 vt 0.488 0.361 0.000 vt 0.491 0.433 0.000 vt 0.401 0.557 0.000 vt 0.397 0.551 0.000 vt 0.373 0.570 0.000 vt 0.369 0.571 0.000 vt 0.375 0.566 0.000 vt 0.379 0.567 0.000 vt 0.378 0.569 0.000 vt 0.471 0.234 0.000 vt 0.450 0.245 0.000 vt 0.143 0.816 0.000 vt 0.114 0.748 0.000 vt 0.149 0.737 0.000 vt 0.175 0.804 0.000 vt 0.202 0.856 0.000 vt 0.179 0.866 0.000 vt 0.190 0.729 0.000 vt 0.217 0.797 0.000 vt 0.245 0.848 0.000 vt 0.466 0.215 0.000 vt 0.437 0.233 0.000 vt 0.452 0.588 0.000 vt 0.092 0.854 0.000 vt 0.116 0.835 0.000 vt 0.081 0.761 0.000 vt 0.053 0.512 0.000 vt 0.026 0.519 0.000 vt 0.026 0.452 0.000 vt 0.056 0.446 0.000 vt 0.113 0.498 0.000 vt 0.085 0.504 0.000 vt 0.110 0.556 0.000 vt 0.083 0.564 0.000 vt 0.001 0.634 0.000 vt 0.001 0.579 0.000 vt 0.025 0.577 0.000 vt 0.027 0.633 0.000 vt 0.118 0.614 0.000 vt 0.132 0.671 0.000 vt 0.099 0.679 0.000 vt 0.089 0.622 0.000 vt 0.167 0.667 0.000 vt 0.292 0.836 0.000 vt 0.199 0.303 0.000 vt 0.174 0.364 0.000 vt 0.393 0.544 0.000 vt 0.387 0.529 0.000 vt 0.459 0.380 0.000 vt 0.462 0.372 0.000 vt 0.463 0.366 0.000 vt 0.463 0.363 0.000 vt 0.402 0.945 0.000 vt 0.476 0.902 0.000 vt 0.401 0.489 0.000 vt 0.391 0.563 0.000 vt 0.388 0.559 0.000 vt 0.404 0.563 0.000 vt 0.443 0.569 0.000 vt 0.380 0.571 0.000 vt 0.382 0.569 0.000 vt 0.384 0.569 0.000 vt 0.439 0.568 0.000 vt 0.431 0.568 0.000 vt 0.421 0.567 0.000 vt 0.393 0.567 0.000 vt 0.387 0.567 0.000 vt 0.384 0.564 0.000 vt 0.394 0.568 0.000 vt 0.413 0.568 0.000 vt 0.370 0.565 0.000 vt 0.452 0.389 0.000 vt 0.399 0.452 0.000 vt 0.471 0.566 0.000 vt 0.316 0.686 0.000 vt 0.128 0.222 0.000 vt 0.179 0.214 0.000 vt 0.175 0.258 0.000 vt 0.124 0.265 0.000 vt 0.439 0.119 0.000 vt 0.229 0.304 0.000 vt 0.203 0.363 0.000 vt 0.274 0.227 0.000 vt 0.223 0.371 0.000 vt 0.053 0.571 0.000 vt 0.001 0.388 0.000 vt 0.001 0.456 0.000 vt 0.001 0.524 0.000 vt 0.064 0.877 0.000 vt 0.144 0.945 0.000 vt 0.001 0.323 0.000 vt 0.065 0.689 0.000 vt 0.224 0.240 0.000 vt 0.072 0.265 0.000 vt 0.001 0.267 0.000 vt 0.031 0.264 0.000 vt 0.057 0.628 0.000 vt 0.194 0.622 0.000 vt 0.149 0.611 0.000 vt 0.308 0.489 0.000 vt 0.369 0.558 0.000 vt 0.374 0.560 0.000 vt 0.378 0.562 0.000 vt 0.445 0.413 0.000 vt 0.430 0.429 0.000 vt 0.461 0.440 0.000 vt 0.476 0.607 0.000 vt 0.469 0.591 0.000 vt 0.378 0.549 0.000 vt 0.384 0.554 0.000 vt 0.393 0.509 0.000 vt 0.299 0.520 0.000 vt 0.436 0.403 0.000 vt 0.489 0.615 0.000 vt 0.383 0.568 0.000 vt 0.364 0.139 0.000 vt 0.236 0.192 0.000 vt 0.033 0.219 0.000 vt 0.079 0.220 0.000 vt 0.292 0.168 0.000 vt 0.001 0.218 0.000 vt 0.197 0.523 0.000 vt 0.209 0.508 0.000 vt 0.217 0.527 0.000 vt 0.206 0.535 0.000 vt 0.211 0.571 0.000 vt 0.203 0.562 0.000 vt 0.187 0.591 0.000 vt 0.185 0.578 0.000 vt 0.161 0.583 0.000 vt 0.165 0.574 0.000 vt 0.150 0.569 0.000 vt 0.155 0.560 0.000 vt 0.145 0.539 0.000 vt 0.153 0.535 0.000 vt 0.150 0.501 0.000 vt 0.159 0.502 0.000 vt 0.186 0.438 0.000 vt 0.191 0.452 0.000 vt 0.172 0.472 0.000 vt 0.164 0.464 0.000 vt 0.208 0.427 0.000 vt 0.210 0.441 0.000 vt 0.182 0.567 0.000 vt 0.193 0.550 0.000 vt 0.169 0.561 0.000 vt 0.161 0.553 0.000 vt 0.163 0.534 0.000 vt 0.169 0.505 0.000 vt 0.196 0.465 0.000 vt 0.180 0.479 0.000 vt 0.214 0.460 0.000 vt 0.227 0.456 0.000 vt 0.221 0.433 0.000 vt 0.203 0.489 0.000 vt 0.211 0.486 0.000 vt 0.215 0.495 0.000 vt 0.228 0.537 0.000 vt 0.219 0.583 0.000 vt 0.188 0.602 0.000 vt 0.152 0.587 0.000 vt 0.138 0.546 0.000 vt 0.141 0.500 0.000 vt 0.157 0.450 0.000 vt 0.180 0.412 0.000 vt 0.209 0.404 0.000 vt 0.227 0.417 0.000 vt 0.236 0.447 0.000 vt 0.194 0.496 0.000 vt 0.187 0.487 0.000 vt 0.199 0.477 0.000 vt 0.213 0.478 0.000 vt 0.222 0.489 0.000 vt 0.178 0.538 0.000 vt 0.178 0.510 0.000 vt 0.233 0.492 0.000 vt 0.130 0.496 0.000 vt 0.149 0.425 0.000 vt 0.128 0.552 0.000 vt 0.484 0.930 0.000 vt 0.472 0.934 0.000 vt 0.463 0.938 0.000 vt 0.470 0.952 0.000 vt 0.480 0.955 0.000 vt 0.484 0.970 0.000 vt 0.488 0.942 0.000 vt 0.478 0.944 0.000 vt 0.388 0.569 0.000 vt 0.385 0.572 0.000 vt 0.424 0.968 0.000 vt 0.437 0.961 0.000 vt 0.438 0.969 0.000 vt 0.427 0.973 0.000 vt 0.418 0.961 0.000 vt 0.429 0.956 0.000 vt 0.389 0.961 0.000 vt 0.399 0.955 0.000 vt 0.405 0.960 0.000 vt 0.394 0.967 0.000 vt 0.429 0.569 0.000 vt 0.405 0.566 0.000 vt 0.393 0.978 0.000 vt 0.383 0.975 0.000 vt 0.384 0.967 0.000 vt 0.401 0.986 0.000 vt 0.395 0.991 0.000 vt 0.386 0.982 0.000 vt 0.411 0.989 0.000 vt 0.407 0.996 0.000 vt 0.438 0.570 0.000 vt 0.427 0.994 0.000 vt 0.416 0.996 0.000 vt 0.421 0.987 0.000 vt 0.419 0.953 0.000 vt 0.408 0.953 0.000 vt 0.439 0.988 0.000 vt 0.428 0.981 0.000 vt 0.437 0.978 0.000 vt 0.489 0.956 0.000 vt 0.132 0.132 0.000 vt 0.082 0.133 0.000 vt 0.084 0.092 0.000 vt 0.133 0.090 0.000 vt 0.446 0.066 0.000 vt 0.442 0.095 0.000 vt 0.381 0.103 0.000 vt 0.388 0.070 0.000 vt 0.185 0.169 0.000 vt 0.186 0.126 0.000 vt 0.253 0.102 0.000 vt 0.242 0.148 0.000 vt 0.230 0.072 0.000 vt 0.183 0.087 0.000 vt 0.448 0.038 0.000 vt 0.395 0.039 0.000 vt 0.398 0.021 0.000 vt 0.449 0.020 0.000 vt 0.133 0.055 0.000 vt 0.179 0.050 0.000 vt 0.288 0.053 0.000 vt 0.260 0.052 0.000 vt 0.261 0.023 0.000 vt 0.300 0.022 0.000 vt 0.341 0.043 0.000 vt 0.348 0.022 0.000 vt 0.087 0.055 0.000 vt 0.040 0.091 0.000 vt 0.041 0.055 0.000 vt 0.038 0.133 0.000 vt 0.001 0.131 0.000 vt 0.001 0.089 0.000 vt 0.001 0.053 0.000 vt 0.222 0.038 0.000 vt 0.083 0.177 0.000 vt 0.035 0.178 0.000 vt 0.326 0.083 0.000 vt 0.315 0.124 0.000 vt 0.001 0.175 0.000 vt 0.129 0.175 0.000 vt 0.001 0.002 0.000 vt 0.042 0.002 0.000 vt 0.133 0.002 0.000 vt 0.177 0.002 0.000 vt 0.092 0.002 0.000 vt 0.399 0.002 0.000 vt 0.450 0.002 0.000 vt 0.303 0.002 0.000 vt 0.350 0.002 0.000 vt 0.218 0.002 0.000 vt 0.260 0.002 0.000 vt 0.558 0.967 0.000 vt 0.557 0.976 0.000 vt 0.500 0.997 0.000 vt 0.588 0.975 0.000 vt 0.442 0.967 0.000 vt 0.443 0.976 0.000 vt 0.412 0.975 0.000 # 1339 texture vertices vn 0.001 0.482 -0.876 vn -0.001 0.661 0.751 vn 0.136 0.595 0.792 vn -0.203 0.679 0.706 vn -0.092 0.474 0.876 vn -0.184 0.792 0.581 vn -0.098 0.863 0.495 vn -0.449 0.820 0.356 vn -0.220 0.748 0.626 vn -0.560 0.798 -0.222 vn -0.233 0.531 -0.815 vn 0.001 0.534 -0.845 vn -0.135 0.596 0.791 vn 0.203 0.676 0.708 vn 0.091 0.476 0.875 vn 0.189 0.792 0.581 vn 0.099 0.862 0.496 vn 0.444 0.821 0.360 vn 0.221 0.747 0.627 vn 0.556 0.801 -0.221 vn 0.228 0.532 -0.815 vn -0.002 0.536 -0.844 vn -0.574 0.744 -0.343 vn -0.485 0.523 -0.701 vn -0.121 0.869 -0.480 vn -0.215 0.930 -0.298 vn -0.000 -0.806 -0.591 vn -0.277 -0.779 -0.562 vn -0.258 -0.731 -0.632 vn -0.046 -0.809 -0.586 vn -0.210 0.565 -0.798 vn -0.094 0.624 -0.775 vn 0.015 0.952 -0.307 vn 0.045 0.919 -0.392 vn -0.099 0.857 -0.505 vn -0.379 0.493 -0.783 vn -0.947 0.285 -0.149 vn -0.809 -0.421 -0.411 vn -0.895 -0.443 -0.043 vn -0.999 -0.020 0.035 vn -0.359 0.933 -0.019 vn -0.809 0.586 0.047 vn -0.667 -0.516 -0.538 vn -0.726 -0.626 -0.285 vn -0.001 0.671 -0.741 vn -0.001 0.945 -0.327 vn -0.531 -0.632 -0.565 vn -0.618 -0.566 -0.546 vn 0.800 -0.473 0.369 vn 0.618 -0.771 0.151 vn 0.693 -0.711 0.116 vn 0.818 -0.467 0.335 vn 0.849 -0.259 0.460 vn 0.775 -0.130 0.619 vn 0.667 -0.132 0.733 vn 0.775 -0.270 0.571 vn 0.958 -0.057 -0.280 vn 0.763 0.033 -0.646 vn 0.763 -0.153 -0.628 vn 0.911 -0.129 -0.391 vn 0.990 0.067 0.126 vn 0.979 0.090 0.185 vn 0.981 0.057 0.184 vn 0.996 0.020 0.090 vn 0.770 -0.392 0.504 vn 0.657 -0.721 0.219 vn 0.478 -0.656 0.584 vn 0.599 -0.389 0.700 vn 0.498 -0.846 0.192 vn 0.537 -0.840 0.082 vn 0.740 -0.557 0.378 vn 0.668 -0.570 0.479 vn 0.280 -0.914 0.294 vn 0.421 -0.898 0.126 vn 0.991 0.084 0.103 vn 0.964 0.223 0.143 vn 0.960 0.189 0.207 vn 0.979 0.103 0.175 vn 0.868 0.172 0.465 vn 0.907 0.085 0.413 vn 0.938 0.144 0.316 vn 0.897 0.178 0.405 vn 0.662 -0.174 0.729 vn 0.583 -0.417 0.697 vn 0.627 -0.449 0.637 vn 0.685 -0.405 0.605 vn 0.827 0.091 0.555 vn 0.890 0.018 0.455 vn 0.663 -0.395 0.636 vn 0.606 -0.428 0.671 vn 0.313 -0.735 0.602 vn -0.136 -0.864 0.485 vn 0.951 0.158 0.267 vn 0.964 0.113 0.241 vn 0.731 -0.036 0.681 vn 0.819 -0.134 0.558 vn 0.546 0.270 0.793 vn 0.602 0.237 0.763 vn 0.444 0.233 0.865 vn 0.353 0.173 0.920 vn 0.240 -0.093 0.966 vn 0.498 0.051 0.866 vn 0.675 0.338 0.656 vn 0.480 0.400 0.780 vn 0.064 -0.572 0.818 vn 0.126 -0.313 0.941 vn 0.207 -0.613 0.763 vn 0.221 -0.810 0.544 vn 0.598 -0.694 -0.401 vn 0.124 -0.977 -0.175 vn 0.218 -0.333 0.917 vn 0.377 -0.161 0.912 vn 0.142 -0.210 0.967 vn 0.256 -0.155 0.954 vn 0.111 -0.351 0.930 vn 0.107 -0.480 0.871 vn 0.675 -0.732 -0.096 vn 0.496 -0.844 0.206 vn -0.016 -0.986 0.167 vn 0.304 -0.948 0.097 vn 0.982 -0.082 0.171 vn 0.963 -0.002 0.269 vn 0.967 -0.134 0.216 vn 0.969 -0.177 0.175 vn 0.916 -0.244 0.319 vn 0.853 -0.341 0.394 vn 0.837 -0.365 0.407 vn 0.886 -0.281 0.368 vn 0.422 -0.292 0.858 vn 0.039 -0.571 0.820 vn -0.011 -0.399 0.917 vn 0.333 -0.349 0.876 vn 0.935 -0.237 0.263 vn 0.949 -0.159 0.273 vn 0.697 -0.213 0.685 vn 0.568 -0.123 0.814 vn -0.938 0.322 0.130 vn -0.609 -0.738 -0.291 vn -0.447 -0.857 -0.258 vn 0.259 -0.528 0.809 vn 0.137 -0.704 0.697 vn -0.107 -0.741 0.663 vn 0.647 -0.296 0.703 vn 0.603 -0.168 0.780 vn 0.836 0.072 0.545 vn 0.744 0.114 0.659 vn 0.701 0.149 0.698 vn 0.802 0.157 0.577 vn 0.823 -0.080 0.562 vn 0.690 0.142 0.710 vn 0.628 0.036 0.778 vn 0.894 -0.247 0.373 vn 0.624 -0.153 0.766 vn 0.661 0.110 0.742 vn 0.712 0.424 0.559 vn 0.701 0.284 0.654 vn 0.504 -0.050 0.862 vn 0.413 0.027 0.910 vn 0.569 0.046 0.821 vn 0.488 -0.134 0.862 vn 0.411 -0.180 0.894 vn 0.610 -0.024 0.792 vn 0.747 -0.250 0.616 vn 0.672 -0.313 0.671 vn 0.536 0.762 0.363 vn 0.559 0.768 0.312 vn 0.802 0.272 0.531 vn 0.618 0.206 0.759 vn 0.717 0.383 0.583 vn 0.780 0.464 0.420 vn 0.617 0.401 0.678 vn 0.658 0.397 0.640 vn 0.672 0.440 0.596 vn 0.501 0.314 0.807 vn 0.612 0.527 0.589 vn 0.679 0.320 0.661 vn 0.732 -0.406 -0.547 vn 0.885 -0.261 -0.386 vn 0.842 -0.347 0.414 vn 0.782 -0.349 0.517 vn 0.784 -0.368 0.500 vn 0.858 -0.453 0.244 vn 0.953 -0.279 0.118 vn 0.977 -0.189 0.104 vn 0.989 -0.110 0.102 vn 0.142 0.669 0.730 vn 0.300 0.652 0.696 vn 0.291 0.792 0.536 vn 0.143 0.821 0.553 vn 0.737 0.561 0.378 vn 0.716 0.470 0.515 vn 0.884 0.306 0.353 vn 0.898 0.354 0.263 vn 0.890 0.423 0.171 vn 0.174 0.078 0.982 vn 0.219 0.254 0.942 vn 0.665 -0.104 0.739 vn 0.671 0.390 0.631 vn 0.596 0.435 0.675 vn 0.636 0.467 0.614 vn 0.076 0.244 0.967 vn 0.261 0.437 0.861 vn 0.107 0.440 0.892 vn 0.011 0.082 0.997 vn 0.005 0.082 0.997 vn 0.028 -0.027 0.999 vn 0.073 -0.057 0.996 vn 0.006 0.228 0.974 vn 0.683 0.140 0.717 vn 0.724 0.233 0.650 vn 0.400 0.338 0.852 vn 0.270 0.126 0.955 vn 0.357 0.433 0.828 vn 0.503 0.485 0.716 vn 0.536 0.133 0.834 vn 0.416 -0.306 0.856 vn 0.337 0.097 0.937 vn 0.262 0.372 0.891 vn 0.425 0.075 0.902 vn 0.701 -0.147 0.698 vn -0.056 0.558 0.828 vn 0.005 0.605 0.796 vn 0.483 0.327 0.812 vn 0.497 0.276 0.823 vn 0.505 0.283 0.815 vn 0.340 -0.030 0.940 vn 0.332 0.066 0.941 vn 0.026 0.644 0.765 vn 0.021 0.538 0.843 vn 0.170 -0.012 0.985 vn 0.365 -0.067 0.929 vn 0.826 -0.173 0.537 vn 0.320 0.415 0.852 vn 0.384 0.739 0.554 vn 0.987 -0.013 0.160 vn 0.495 0.720 0.487 vn 0.490 0.830 0.268 vn 0.279 0.906 0.317 vn 0.431 0.899 -0.074 vn 0.267 0.957 -0.112 vn 0.283 0.953 0.107 vn 0.471 0.877 0.092 vn 0.132 0.985 0.113 vn 0.135 0.931 0.339 vn 0.190 -0.184 0.964 vn 0.292 -0.372 0.881 vn 0.307 -0.447 0.840 vn 0.393 -0.580 0.713 vn 0.524 -0.286 0.802 vn 0.380 -0.582 0.719 vn 0.697 0.212 0.685 vn 0.603 0.070 0.795 vn 0.558 -0.571 0.602 vn -0.089 -0.701 0.707 vn 0.794 -0.345 0.500 vn 0.345 -0.517 0.783 vn 0.481 0.101 0.871 vn 0.134 0.283 0.950 vn 0.113 -0.558 0.822 vn -0.073 -0.993 0.089 vn -0.041 -0.994 0.103 vn 0.084 -0.038 0.996 vn -0.012 -0.622 0.783 vn -0.002 0.254 0.967 vn 0.004 -0.997 0.079 vn 0.001 -0.832 -0.555 vn 0.477 -0.363 0.801 vn 0.414 0.160 0.896 vn 0.395 0.485 0.780 vn 0.611 0.484 0.627 vn 0.406 0.510 0.758 vn 0.375 0.498 0.782 vn 0.555 0.314 0.770 vn 0.349 0.411 0.842 vn 0.012 0.247 0.969 vn 0.002 -0.369 0.930 vn -0.003 0.509 0.861 vn 0.876 -0.041 0.481 vn 0.757 -0.214 0.618 vn 0.737 -0.048 0.674 vn 0.840 -0.012 0.542 vn 0.960 0.137 0.243 vn 0.969 0.103 0.226 vn 0.909 0.015 0.417 vn 0.906 0.015 0.423 vn 0.676 -0.276 0.683 vn 0.688 -0.223 0.691 vn 0.691 0.035 0.722 vn 0.719 -0.082 0.691 vn 0.964 0.062 0.260 vn 0.956 0.070 0.286 vn 0.953 0.037 0.300 vn -0.003 -0.415 0.910 vn -0.001 -0.380 0.925 vn 0.658 -0.419 0.625 vn 0.735 -0.421 0.532 vn 0.663 -0.303 0.685 vn 0.550 -0.321 0.771 vn 0.423 -0.236 0.875 vn 0.326 -0.294 0.899 vn 0.124 -0.396 0.910 vn 0.218 -0.177 0.960 vn 0.530 0.781 0.331 vn 0.167 0.827 0.537 vn 0.094 0.948 0.303 vn 0.313 0.934 0.171 vn -0.406 -0.892 0.201 vn -0.743 0.107 0.661 vn 0.455 0.704 0.546 vn 0.288 0.957 0.025 vn 0.245 0.958 0.150 vn 0.532 -0.027 0.846 vn 0.566 0.213 0.796 vn 0.508 0.208 0.836 vn 0.173 0.028 0.984 vn 0.371 0.122 0.921 vn 0.429 -0.045 0.902 vn 0.614 0.165 0.772 vn 0.737 0.157 0.657 vn 0.726 0.057 0.685 vn 0.662 0.061 0.747 vn 0.845 -0.523 -0.112 vn 0.845 -0.501 -0.185 vn 0.744 -0.668 0.009 vn 0.773 -0.630 0.079 vn 0.889 0.108 0.445 vn 0.899 0.077 0.430 vn 0.184 0.204 -0.961 vn 0.005 0.202 -0.979 vn -0.000 0.485 -0.875 vn 0.159 0.484 -0.861 vn 0.499 0.592 0.633 vn 0.305 0.950 0.065 vn -0.274 -0.953 -0.127 vn 0.245 -0.456 0.856 vn 0.083 -0.881 0.465 vn 0.435 -0.739 0.515 vn 0.504 -0.429 0.750 vn 0.818 -0.367 0.443 vn 0.933 -0.162 0.322 vn 0.872 0.029 0.489 vn 0.002 0.994 0.113 vn 0.133 0.983 -0.126 vn -0.001 0.992 -0.127 vn 0.280 0.892 -0.356 vn 0.126 0.916 -0.381 vn 0.210 0.974 -0.083 vn -0.082 0.663 0.745 vn -0.059 0.391 0.919 vn 0.111 0.992 -0.055 vn 0.081 -0.190 0.978 vn 0.035 0.076 0.996 vn 0.852 0.236 0.467 vn 0.775 0.219 0.593 vn 0.505 -0.109 0.856 vn 0.446 -0.314 0.838 vn 0.511 0.200 0.836 vn 0.623 -0.242 0.744 vn 0.436 -0.554 0.709 vn 0.599 -0.742 0.300 vn -0.036 0.177 0.984 vn -0.039 -0.159 0.987 vn 0.308 0.942 -0.135 vn 0.989 0.093 -0.111 vn 0.477 -0.259 0.840 vn 0.473 -0.423 0.773 vn 0.774 -0.329 0.541 vn 0.285 0.019 0.958 vn 0.350 0.101 0.931 vn 0.579 0.261 0.773 vn 0.298 0.015 0.954 vn 0.165 0.336 0.927 vn 0.577 0.511 0.636 vn 0.254 -0.834 0.490 vn -0.114 -0.925 0.363 vn 0.941 -0.280 -0.188 vn 0.460 -0.738 0.493 vn 0.740 -0.635 0.221 vn 0.003 0.529 0.849 vn 0.206 -0.427 -0.881 vn 0.497 -0.316 -0.808 vn 0.457 -0.144 -0.878 vn 0.179 -0.244 -0.953 vn -0.182 -0.980 -0.078 vn 0.342 -0.427 0.837 vn 0.424 -0.296 0.856 vn 0.896 -0.357 -0.264 vn 0.594 -0.104 0.798 vn 0.012 0.528 0.849 vn 0.042 0.469 0.882 vn 0.624 0.102 0.775 vn 0.324 -0.123 0.938 vn 0.202 -0.638 0.743 vn 0.714 0.512 0.477 vn 0.433 -0.511 0.742 vn -0.350 -0.708 0.613 vn 0.095 -0.410 0.907 vn 0.622 -0.593 0.512 vn 0.846 0.304 0.437 vn 0.582 -0.043 0.812 vn -0.226 -0.380 0.897 vn 0.215 0.644 0.734 vn 0.123 0.952 0.280 vn -0.004 0.956 0.293 vn -0.005 0.635 0.772 vn 0.325 -0.730 0.601 vn -0.017 -0.840 0.543 vn 0.017 -0.788 0.616 vn 0.294 -0.138 0.946 vn 0.214 0.401 0.891 vn -0.150 0.490 0.859 vn 0.573 -0.125 0.810 vn -0.134 0.957 0.258 vn 0.252 0.828 0.501 vn -0.673 0.643 0.364 vn 0.004 -0.960 0.279 vn 0.032 -0.991 0.133 vn 0.006 -0.908 0.419 vn 0.180 -0.980 0.086 vn 0.740 0.403 -0.538 vn 0.627 0.652 -0.426 vn 0.814 0.561 -0.149 vn 0.925 0.321 -0.206 vn 0.492 0.825 -0.280 vn 0.649 0.757 -0.076 vn 0.966 0.258 0.022 vn 0.864 0.501 0.053 vn 0.680 0.729 0.077 vn 0.272 -0.962 -0.032 vn 0.225 -0.968 0.111 vn 0.288 -0.510 0.810 vn 0.126 0.748 -0.651 vn 0.340 0.725 -0.598 vn 0.421 0.466 -0.778 vn 0.205 -0.458 -0.865 vn 0.489 -0.479 -0.729 vn 0.500 -0.523 -0.690 vn 0.210 -0.566 -0.798 vn 0.895 -0.322 -0.309 vn 0.759 -0.434 -0.485 vn 0.797 -0.287 -0.532 vn 0.937 -0.248 -0.245 vn -0.001 -0.238 -0.971 vn -0.000 -0.025 -1.000 vn 0.194 -0.025 -0.981 vn 0.201 -0.248 -0.948 vn 0.969 0.094 -0.229 vn 0.968 -0.101 -0.228 vn 0.814 -0.088 -0.575 vn 0.800 0.142 -0.583 vn 0.998 0.061 -0.010 vn 0.726 0.657 0.205 vn 0.000 -0.985 0.174 vn 0.985 -0.166 0.038 vn 0.955 -0.220 -0.200 vn 0.472 0.076 0.879 vn 0.343 -0.235 0.909 vn 0.464 -0.641 0.612 vn 0.578 -0.186 0.795 vn -0.189 -0.982 0.010 vn 0.004 0.938 0.345 vn 0.002 0.829 0.559 vn 0.445 0.232 0.865 vn 0.463 0.340 0.818 vn -0.116 0.983 0.143 vn 0.004 0.995 0.102 vn 0.978 0.204 0.044 vn -0.967 -0.216 -0.137 vn -0.911 -0.347 0.224 vn -0.728 0.350 0.590 vn 0.426 0.738 -0.523 vn 0.618 0.786 0.011 vn 0.151 0.857 -0.493 vn -0.333 0.912 -0.241 vn -0.277 0.956 0.095 vn -0.569 0.822 -0.032 vn -0.341 -0.671 -0.658 vn 0.161 -0.736 -0.657 vn 0.528 0.432 0.731 vn 0.586 0.105 0.803 vn 0.436 0.074 0.897 vn 0.621 0.267 0.737 vn 0.936 0.153 0.316 vn 0.999 -0.010 0.042 vn 0.826 0.281 -0.489 vn 0.775 0.178 -0.606 vn 0.995 -0.039 -0.095 vn 0.005 -0.414 0.910 vn 0.580 -0.243 0.778 vn 0.938 -0.339 -0.068 vn 0.925 -0.371 0.080 vn 0.888 -0.269 0.373 vn 0.923 -0.371 -0.106 vn 0.494 -0.274 -0.825 vn -0.001 -0.456 -0.890 vn -0.002 -0.569 -0.822 vn -0.001 -0.452 -0.892 vn -0.003 0.749 -0.663 vn -0.000 0.920 -0.391 vn -0.001 -0.280 -0.960 vn 0.470 0.194 -0.861 vn 0.965 -0.123 0.234 vn 0.400 -0.039 -0.916 vn 0.142 -0.166 -0.976 vn -0.000 -0.194 -0.981 vn 0.497 -0.049 -0.867 vn 0.998 0.042 0.045 vn 0.996 -0.037 -0.082 vn 0.009 0.433 0.901 vn 0.004 0.669 0.743 vn 0.955 0.004 0.296 vn 0.737 -0.001 0.675 vn 0.707 0.177 0.684 vn 0.484 0.627 0.610 vn 0.515 0.250 0.820 vn 0.360 0.121 0.925 vn -0.544 -0.573 0.613 vn 0.382 -0.114 0.917 vn 0.489 -0.108 0.866 vn -0.002 -0.670 0.742 vn 0.002 -0.394 0.919 vn -0.004 -0.168 0.986 vn 0.007 -0.109 0.994 vn 0.009 -0.519 0.855 vn 0.660 -0.118 0.742 vn 0.621 -0.127 0.774 vn 0.416 0.220 0.882 vn 0.946 0.046 0.322 vn 0.014 0.006 1.000 vn 0.569 0.184 0.802 vn 0.218 0.013 0.976 vn 0.044 0.087 0.995 vn -0.419 0.862 0.284 vn 0.647 -0.120 0.753 vn 0.954 -0.017 0.301 vn 0.352 0.140 -0.926 vn 0.095 -0.050 -0.994 vn 0.770 0.025 0.638 vn 0.000 -0.078 -0.997 vn 0.985 -0.172 0.009 vn 0.920 -0.340 0.195 vn 0.929 -0.331 -0.163 vn 0.969 -0.237 0.074 vn 0.969 -0.183 0.165 vn 0.801 0.160 0.577 vn 0.954 -0.021 0.301 vn 0.293 0.803 0.520 vn 0.977 0.170 0.129 vn 0.134 0.985 -0.104 vn 0.994 0.106 -0.036 vn 0.099 0.675 -0.731 vn 0.997 -0.079 -0.000 vn 0.197 0.126 -0.972 vn 0.978 -0.175 -0.110 vn 0.110 -0.321 -0.941 vn 0.939 -0.332 -0.089 vn 0.400 -0.789 -0.467 vn 0.171 -0.673 -0.720 vn 0.931 -0.336 -0.144 vn 0.854 -0.500 0.146 vn 0.161 -0.985 -0.069 vn 0.931 -0.304 -0.200 vn 0.813 -0.565 -0.143 vn 0.823 -0.546 0.154 vn 0.795 -0.387 0.467 vn 0.809 -0.168 0.563 vn 0.826 0.053 0.562 vn 0.925 0.261 0.275 vn 0.990 0.071 0.119 vn 0.951 0.129 0.281 vn 0.810 -0.147 0.568 vn 0.383 -0.603 0.699 vn 0.769 0.635 0.079 vn 0.786 0.352 0.508 vn 0.919 0.082 -0.386 vn 0.937 0.163 0.310 vn 0.974 -0.026 0.224 vn 0.787 0.550 0.279 vn 0.517 0.758 -0.397 vn 0.337 0.112 -0.935 vn 0.221 -0.300 -0.928 vn 0.395 -0.578 -0.714 vn 0.521 -0.711 -0.472 vn 0.432 -0.901 -0.043 vn 0.826 -0.520 0.218 vn 0.885 -0.217 0.412 vn 0.786 -0.107 0.609 vn 0.864 0.400 0.304 vn 0.954 0.061 0.293 vn 0.949 0.313 0.046 vn 0.991 0.028 -0.131 vn 0.945 -0.116 0.305 vn 0.970 -0.241 0.032 vn 0.946 -0.038 0.322 vn 0.886 -0.270 -0.376 vn 0.855 -0.272 -0.441 vn 0.952 -0.122 -0.281 vn 0.002 -0.883 0.469 vn -0.001 0.792 -0.611 vn -0.180 0.823 -0.539 vn -0.642 0.677 -0.360 vn -0.957 0.288 -0.031 vn -0.912 -0.300 0.281 vn -0.454 -0.866 0.207 vn -0.855 -0.043 0.517 vn -0.834 0.460 0.305 vn -0.242 0.911 0.334 vn -0.720 -0.667 -0.192 vn -0.762 -0.580 -0.288 vn 0.452 0.774 0.444 vn 0.857 0.048 0.513 vn 0.966 0.131 0.225 vn 0.211 0.953 0.219 vn -0.108 0.726 0.679 vn 0.021 0.946 0.324 vn 0.566 -0.691 -0.450 vn -0.068 0.939 -0.338 vn -0.261 -0.298 0.918 vn -0.200 -0.891 0.407 vn 0.124 -0.991 0.059 vn 0.913 -0.350 -0.211 vn 0.488 -0.838 0.244 vn 0.738 -0.593 0.322 vn 0.994 -0.060 -0.087 vn -0.000 -0.981 0.193 vn 0.000 0.974 0.227 vn -0.350 -0.016 0.936 vn 0.000 -0.017 1.000 vn 0.252 0.455 -0.854 vn 0.774 0.620 -0.127 vn 0.634 0.759 -0.148 vn 0.192 0.569 -0.800 vn 0.405 -0.094 0.909 vn 0.031 0.149 0.988 vn 0.360 0.283 0.889 vn 0.469 0.080 0.880 vn 0.769 0.452 0.452 vn 0.946 0.185 0.266 vn 0.893 0.181 0.413 vn 0.654 0.429 0.623 vn 0.506 0.610 0.610 vn 0.436 0.659 0.613 vn 0.160 0.558 0.814 vn -0.285 0.396 0.873 vn -0.223 0.539 0.812 vn 0.037 0.570 0.821 vn 0.623 0.727 -0.289 vn 0.456 0.738 0.497 vn 0.382 0.656 0.651 vn 0.278 0.687 0.671 vn 0.213 0.798 0.563 vn 0.171 0.844 0.508 vn 0.300 0.690 0.659 vn 0.144 0.793 0.591 vn 0.204 0.541 -0.816 vn -0.001 0.494 -0.870 vn 0.029 0.458 -0.888 vn 0.060 0.366 -0.929 vn 0.000 0.421 -0.907 vn 0.000 0.386 -0.922 vn 0.001 0.455 -0.891 vn 0.264 0.718 0.644 vn 0.307 0.317 -0.897 vn 0.056 0.164 -0.985 vn 0.717 0.079 0.693 vn 0.638 0.188 0.746 vn 0.000 0.202 -0.979 vn 0.006 -0.044 0.999 vn 0.001 0.405 0.914 vn 0.805 0.560 -0.194 vn 0.002 0.627 0.779 vn 0.010 -0.298 0.954 vn 0.124 0.870 -0.477 vn 0.488 0.530 -0.693 vn 0.566 0.756 -0.329 vn 0.213 0.932 -0.294 vn 0.245 -0.741 -0.626 vn 0.275 -0.782 -0.559 vn 0.044 -0.811 -0.584 vn -0.012 0.949 -0.315 vn 0.097 0.621 -0.778 vn 0.215 0.561 -0.799 vn -0.030 0.913 -0.407 vn 0.378 0.505 -0.776 vn 0.084 0.865 -0.495 vn 0.892 -0.451 -0.026 vn 0.803 -0.447 -0.394 vn 0.954 0.274 -0.123 vn 0.998 -0.024 0.066 vn 0.806 0.588 0.057 vn 0.351 0.936 -0.012 vn 0.662 -0.536 -0.524 vn 0.725 -0.630 -0.278 vn 0.524 -0.662 -0.536 vn 0.620 -0.585 -0.522 vn -0.694 -0.711 0.115 vn -0.621 -0.770 0.148 vn -0.805 -0.470 0.362 vn -0.819 -0.465 0.335 vn -0.680 -0.145 0.719 vn -0.763 -0.140 0.631 vn -0.840 -0.272 0.470 vn -0.773 -0.256 0.580 vn -0.763 -0.155 -0.627 vn -0.763 0.034 -0.645 vn -0.958 -0.057 -0.281 vn -0.910 -0.129 -0.393 vn -0.983 0.060 0.175 vn -0.980 0.096 0.177 vn -0.990 0.069 0.123 vn -0.996 0.023 0.083 vn -0.484 -0.649 0.587 vn -0.662 -0.717 0.220 vn -0.775 -0.388 0.499 vn -0.606 -0.384 0.697 vn -0.748 -0.556 0.363 vn -0.539 -0.840 0.071 vn -0.496 -0.849 0.183 vn -0.668 -0.580 0.467 vn -0.280 -0.913 0.296 vn -0.424 -0.897 0.125 vn -0.960 0.187 0.209 vn -0.965 0.222 0.143 vn -0.991 0.084 0.104 vn -0.979 0.104 0.175 vn -0.940 0.170 0.295 vn -0.909 0.107 0.404 vn -0.862 0.204 0.464 vn -0.896 0.204 0.395 vn -0.570 -0.493 0.658 vn -0.531 -0.465 0.709 vn -0.651 -0.181 0.737 vn -0.688 -0.376 0.620 vn -0.892 0.030 0.452 vn -0.827 0.122 0.549 vn -0.345 -0.706 0.619 vn -0.566 -0.461 0.684 vn -0.543 -0.393 0.742 vn -0.097 -0.841 0.533 vn -0.964 0.119 0.237 vn -0.950 0.158 0.268 vn -0.733 -0.024 0.679 vn -0.825 -0.117 0.552 vn -0.442 0.232 0.866 vn -0.605 0.237 0.760 vn -0.556 0.267 0.787 vn -0.350 0.172 0.921 vn -0.239 -0.096 0.966 vn -0.501 0.068 0.863 vn -0.679 0.342 0.650 vn -0.486 0.403 0.776 vn -0.211 -0.600 0.772 vn -0.123 -0.334 0.934 vn -0.052 -0.530 0.847 vn -0.176 -0.798 0.577 vn -0.131 -0.968 -0.212 vn -0.598 -0.684 -0.418 vn -0.205 -0.329 0.922 vn -0.374 -0.151 0.915 vn -0.117 -0.376 0.919 vn -0.246 -0.160 0.956 vn -0.126 -0.268 0.955 vn -0.137 -0.531 0.837 vn 0.062 -0.980 0.190 vn -0.478 -0.855 0.203 vn -0.669 -0.734 -0.114 vn -0.286 -0.955 0.083 vn -0.967 -0.136 0.215 vn -0.965 -0.005 0.263 vn -0.983 -0.085 0.164 vn -0.969 -0.182 0.170 vn -0.840 -0.358 0.408 vn -0.857 -0.341 0.386 vn -0.910 -0.256 0.326 vn -0.884 -0.284 0.371 vn 0.022 -0.449 0.893 vn -0.046 -0.611 0.791 vn -0.478 -0.294 0.827 vn -0.375 -0.338 0.863 vn -0.935 -0.243 0.259 vn -0.949 -0.164 0.269 vn -0.736 -0.207 0.645 vn -0.587 -0.108 0.802 vn 0.945 0.284 0.163 vn 0.592 -0.756 -0.279 vn 0.442 -0.866 -0.236 vn -0.053 -0.740 0.670 vn -0.228 -0.529 0.817 vn 0.170 -0.772 0.613 vn -0.609 -0.162 0.777 vn -0.663 -0.292 0.690 vn -0.713 0.145 0.686 vn -0.759 0.059 0.648 vn -0.825 0.047 0.564 vn -0.809 0.158 0.566 vn -0.637 0.025 0.770 vn -0.687 0.129 0.715 vn -0.821 -0.086 0.564 vn -0.891 -0.252 0.378 vn -0.721 0.489 0.490 vn -0.698 0.164 0.697 vn -0.646 -0.143 0.750 vn -0.712 0.352 0.608 vn -0.567 0.074 0.821 vn -0.464 0.032 0.885 vn -0.518 -0.023 0.855 vn -0.550 -0.128 0.825 vn -0.756 -0.260 0.601 vn -0.645 -0.025 0.764 vn -0.437 -0.158 0.885 vn -0.687 -0.310 0.657 vn -0.541 0.781 0.313 vn -0.565 0.780 0.270 vn -0.712 0.385 0.587 vn -0.611 0.201 0.765 vn -0.859 0.335 0.388 vn -0.775 0.474 0.417 vn -0.673 0.387 0.630 vn -0.628 0.400 0.668 vn -0.676 0.438 0.592 vn -0.698 0.309 0.646 vn -0.622 0.535 0.573 vn -0.511 0.327 0.795 vn -0.733 -0.405 -0.547 vn -0.884 -0.261 -0.388 vn -0.791 -0.366 0.490 vn -0.793 -0.344 0.502 vn -0.844 -0.347 0.408 vn -0.858 -0.453 0.243 vn -0.953 -0.280 0.116 vn -0.976 -0.193 0.100 vn -0.989 -0.113 0.096 vn -0.289 0.792 0.537 vn -0.301 0.654 0.693 vn -0.134 0.672 0.728 vn -0.137 0.821 0.554 vn -0.884 0.305 0.354 vn -0.716 0.471 0.515 vn -0.736 0.562 0.377 vn -0.897 0.355 0.265 vn -0.890 0.422 0.171 vn -0.179 0.082 0.981 vn -0.216 0.250 0.944 vn -0.661 -0.125 0.740 vn -0.679 0.371 0.633 vn -0.636 0.460 0.620 vn -0.594 0.426 0.682 vn -0.258 0.436 0.862 vn -0.070 0.240 0.968 vn -0.095 0.440 0.893 vn -0.011 0.089 0.996 vn -0.069 -0.049 0.996 vn -0.719 0.247 0.649 vn -0.673 0.172 0.719 vn -0.353 0.447 0.822 vn -0.270 0.134 0.954 vn -0.440 0.328 0.836 vn -0.511 0.490 0.706 vn -0.342 0.114 0.933 vn -0.435 -0.298 0.849 vn -0.552 0.158 0.818 vn -0.273 0.369 0.888 vn -0.705 -0.192 0.683 vn -0.357 0.088 0.930 vn -0.499 0.346 0.795 vn 0.009 0.585 0.811 vn 0.086 0.584 0.807 vn -0.348 -0.035 0.937 vn -0.516 0.299 0.803 vn -0.512 0.295 0.806 vn -0.339 0.070 0.938 vn -0.348 -0.070 0.935 vn -0.148 -0.003 0.989 vn -0.349 0.750 0.561 vn -0.322 0.418 0.849 vn -0.890 -0.163 0.425 vn -0.990 -0.001 0.144 vn -0.500 0.824 0.267 vn -0.501 0.717 0.484 vn -0.285 0.905 0.315 vn -0.282 0.954 0.103 vn -0.268 0.957 -0.114 vn -0.433 0.898 -0.078 vn -0.473 0.876 0.093 vn -0.131 0.985 0.111 vn -0.127 0.932 0.339 vn -0.211 -0.186 0.960 vn -0.293 -0.359 0.886 vn -0.344 -0.465 0.816 vn -0.382 -0.591 0.710 vn -0.525 -0.255 0.812 vn -0.598 0.089 0.796 vn -0.688 0.244 0.683 vn -0.344 -0.576 0.742 vn -0.544 -0.583 0.603 vn 0.098 -0.695 0.712 vn -0.805 -0.326 0.496 vn -0.132 0.306 0.943 vn -0.485 0.160 0.860 vn -0.351 -0.498 0.793 vn -0.141 -0.499 0.855 vn 0.065 -0.990 0.123 vn 0.037 -0.989 0.143 vn -0.065 -0.055 0.996 vn -0.473 -0.369 0.800 vn -0.396 0.179 0.900 vn -0.600 0.505 0.620 vn -0.387 0.499 0.776 vn -0.398 0.505 0.766 vn -0.358 0.488 0.796 vn -0.570 0.304 0.763 vn -0.317 0.412 0.854 vn -0.742 -0.129 0.658 vn -0.771 -0.207 0.602 vn -0.881 -0.036 0.472 vn -0.841 -0.052 0.538 vn -0.972 0.111 0.208 vn -0.961 0.151 0.230 vn -0.916 -0.004 0.402 vn -0.913 0.013 0.408 vn -0.689 0.026 0.724 vn -0.641 -0.316 0.699 vn -0.647 -0.304 0.699 vn -0.697 -0.094 0.711 vn -0.966 0.063 0.249 vn -0.963 0.075 0.259 vn -0.958 0.031 0.287 vn -0.681 -0.315 0.661 vn -0.745 -0.412 0.525 vn -0.666 -0.413 0.621 vn -0.548 -0.335 0.767 vn -0.107 -0.395 0.913 vn -0.299 -0.320 0.899 vn -0.418 -0.236 0.877 vn -0.210 -0.169 0.963 vn -0.090 0.952 0.291 vn -0.166 0.838 0.520 vn -0.523 0.797 0.302 vn -0.302 0.941 0.154 vn 0.408 -0.888 0.211 vn 0.735 0.117 0.668 vn -0.279 0.960 0.001 vn -0.468 0.706 0.531 vn -0.232 0.964 0.131 vn -0.555 -0.033 0.831 vn -0.517 0.199 0.833 vn -0.549 0.222 0.806 vn -0.376 0.125 0.918 vn -0.210 0.031 0.977 vn -0.435 -0.045 0.899 vn -0.739 0.154 0.656 vn -0.610 0.153 0.777 vn -0.663 0.041 0.748 vn -0.733 0.013 0.681 vn -0.744 -0.668 0.007 vn -0.845 -0.501 -0.187 vn -0.845 -0.522 -0.114 vn -0.774 -0.629 0.079 vn -0.897 0.040 0.440 vn -0.896 0.094 0.434 vn -0.179 0.204 -0.962 vn -0.157 0.488 -0.858 vn -0.506 0.590 0.630 vn -0.305 0.951 0.047 vn 0.267 -0.958 -0.102 vn -0.432 -0.745 0.509 vn -0.075 -0.883 0.463 vn -0.236 -0.454 0.859 vn -0.504 -0.423 0.753 vn -0.821 -0.351 0.449 vn -0.876 0.033 0.481 vn -0.934 -0.155 0.322 vn -0.134 0.983 -0.126 vn -0.128 0.916 -0.381 vn -0.284 0.891 -0.353 vn 0.055 0.396 0.917 vn 0.092 0.644 0.760 vn -0.199 0.976 -0.093 vn -0.109 0.991 -0.072 vn -0.039 0.079 0.996 vn -0.081 -0.191 0.978 vn -0.854 0.239 0.462 vn -0.774 0.223 0.593 vn -0.502 -0.119 0.856 vn -0.403 -0.420 0.813 vn -0.680 -0.255 0.687 vn -0.525 0.172 0.834 vn -0.376 -0.531 0.759 vn -0.576 -0.754 0.316 vn 0.040 0.159 0.986 vn 0.036 -0.180 0.983 vn -0.308 0.943 -0.129 vn -0.983 0.074 -0.170 vn -0.456 -0.445 0.771 vn -0.476 -0.297 0.828 vn -0.788 -0.316 0.528 vn -0.393 0.095 0.915 vn -0.308 0.018 0.951 vn -0.125 0.331 0.935 vn -0.283 0.033 0.959 vn -0.598 0.322 0.734 vn -0.575 0.559 0.598 vn -0.216 -0.852 0.476 vn 0.156 -0.927 0.342 vn -0.941 -0.282 -0.189 vn -0.739 -0.637 0.221 vn -0.469 -0.731 0.495 vn -0.458 -0.139 -0.878 vn -0.498 -0.315 -0.808 vn -0.210 -0.426 -0.880 vn -0.182 -0.243 -0.953 vn -0.334 -0.402 0.853 vn 0.221 -0.960 -0.173 vn -0.414 -0.366 0.834 vn -0.902 -0.373 -0.218 vn -0.632 -0.114 0.767 vn -0.642 0.122 0.757 vn -0.194 -0.651 0.734 vn -0.351 -0.095 0.931 vn -0.707 0.530 0.467 vn -0.087 -0.550 0.831 vn 0.352 -0.710 0.610 vn -0.500 -0.482 0.720 vn -0.653 -0.626 0.427 vn -0.856 0.328 0.399 vn -0.578 -0.029 0.816 vn 0.275 -0.432 0.859 vn -0.123 0.953 0.277 vn -0.228 0.657 0.719 vn -0.298 -0.735 0.609 vn -0.300 -0.179 0.937 vn -0.219 0.400 0.890 vn -0.587 -0.175 0.791 vn 0.175 0.460 0.870 vn -0.179 0.856 0.485 vn 0.114 0.959 0.259 vn 0.664 0.620 0.418 vn -0.026 -0.991 0.129 vn -0.184 -0.979 0.082 vn -0.810 0.566 -0.151 vn -0.628 0.654 -0.422 vn -0.741 0.405 -0.536 vn -0.924 0.322 -0.207 vn -0.493 0.823 -0.280 vn -0.648 0.758 -0.080 vn -0.966 0.258 0.022 vn -0.864 0.501 0.051 vn -0.679 0.730 0.075 vn -0.221 -0.970 0.105 vn -0.271 -0.962 -0.038 vn -0.376 -0.516 0.769 vn -0.124 0.748 -0.652 vn -0.339 0.727 -0.598 vn -0.420 0.469 -0.777 vn -0.500 -0.524 -0.690 vn -0.489 -0.481 -0.728 vn -0.206 -0.458 -0.865 vn -0.212 -0.565 -0.797 vn -0.893 -0.325 -0.312 vn -0.759 -0.435 -0.485 vn -0.796 -0.289 -0.532 vn -0.937 -0.249 -0.246 vn -0.193 -0.029 -0.981 vn -0.202 -0.249 -0.947 vn -0.814 -0.090 -0.574 vn -0.969 -0.102 -0.227 vn -0.969 0.093 -0.229 vn -0.801 0.142 -0.581 vn -0.998 0.061 -0.010 vn -0.718 0.664 0.209 vn -0.985 -0.168 0.036 vn -0.954 -0.222 -0.201 vn -0.451 0.039 0.891 vn -0.341 -0.253 0.905 vn -0.604 -0.144 0.784 vn -0.472 -0.641 0.606 vn 0.107 -0.991 0.080 vn -0.463 0.274 0.843 vn -0.002 0.997 0.081 vn 0.083 0.977 0.195 vn -0.466 0.366 0.805 vn -0.977 0.200 0.072 vn 0.916 -0.331 0.226 vn 0.929 -0.364 -0.067 vn 0.728 0.359 0.584 vn -0.419 0.737 -0.531 vn -0.638 0.769 0.043 vn -0.146 0.857 -0.494 vn 0.280 0.954 0.105 vn 0.343 0.909 -0.237 vn 0.546 0.838 -0.008 vn 0.342 -0.678 -0.651 vn -0.159 -0.734 -0.660 vn -0.545 0.363 0.756 vn -0.599 0.165 0.783 vn -0.447 0.066 0.892 vn -0.645 0.255 0.721 vn -0.936 0.164 0.311 vn -0.776 0.182 -0.604 vn -0.827 0.285 -0.485 vn -0.999 -0.012 0.041 vn -0.995 -0.037 -0.093 vn -0.586 -0.252 0.770 vn -0.926 -0.370 0.079 vn -0.938 -0.339 -0.067 vn -0.889 -0.266 0.372 vn -0.922 -0.372 -0.106 vn -0.493 -0.275 -0.825 vn -0.473 0.194 -0.860 vn -0.965 -0.122 0.231 vn -0.401 -0.036 -0.915 vn -0.143 -0.164 -0.976 vn -0.496 -0.052 -0.867 vn -0.996 -0.037 -0.083 vn -0.998 0.042 0.045 vn -0.950 0.012 0.313 vn -0.733 -0.008 0.681 vn -0.670 0.247 0.700 vn -0.408 0.697 0.589 vn -0.330 0.155 0.931 vn -0.517 0.244 0.821 vn 0.568 -0.625 0.535 vn -0.512 -0.108 0.852 vn -0.414 -0.112 0.903 vn -0.654 -0.140 0.743 vn -0.608 -0.086 0.789 vn -0.422 0.215 0.881 vn -0.943 0.031 0.332 vn -0.549 0.190 0.814 vn -0.193 0.018 0.981 vn 0.358 0.872 0.335 vn -0.651 -0.118 0.750 vn -0.954 -0.010 0.300 vn -0.352 0.145 -0.925 vn -0.095 -0.049 -0.994 vn -0.769 0.031 0.639 vn -0.929 -0.329 -0.171 vn -0.923 -0.336 0.190 vn -0.985 -0.174 0.005 vn -0.970 -0.234 0.068 vn -0.801 0.162 0.576 vn -0.969 -0.184 0.166 vn -0.293 0.803 0.519 vn -0.954 -0.019 0.300 vn -0.133 0.986 -0.105 vn -0.976 0.175 0.130 vn -0.098 0.675 -0.732 vn -0.993 0.112 -0.041 vn -0.197 0.127 -0.972 vn -0.997 -0.077 -0.003 vn -0.112 -0.322 -0.940 vn -0.978 -0.176 -0.109 vn -0.171 -0.674 -0.719 vn -0.397 -0.789 -0.468 vn -0.937 -0.337 -0.091 vn -0.929 -0.341 -0.146 vn -0.158 -0.985 -0.070 vn -0.854 -0.500 0.145 vn -0.814 -0.564 -0.141 vn -0.931 -0.306 -0.199 vn -0.824 -0.545 0.156 vn -0.797 -0.383 0.466 vn -0.811 -0.165 0.562 vn -0.824 0.053 0.564 vn -0.926 0.257 0.275 vn -0.991 0.062 0.118 vn -0.952 0.122 0.281 vn -0.383 -0.604 0.699 vn -0.810 -0.150 0.567 vn -0.784 0.355 0.509 vn -0.761 0.645 0.076 vn -0.920 0.079 -0.385 vn -0.975 -0.023 0.222 vn -0.937 0.166 0.308 vn -0.787 0.551 0.279 vn -0.517 0.758 -0.396 vn -0.337 0.112 -0.935 vn -0.221 -0.301 -0.928 vn -0.395 -0.579 -0.714 vn -0.520 -0.711 -0.473 vn -0.426 -0.904 -0.044 vn -0.824 -0.523 0.219 vn -0.886 -0.220 0.409 vn -0.863 0.404 0.303 vn -0.782 -0.104 0.615 vn -0.953 0.066 0.297 vn -0.949 0.312 0.046 vn -0.991 0.025 -0.134 vn -0.944 -0.116 0.308 vn -0.971 -0.237 0.041 vn -0.947 -0.041 0.318 vn -0.854 -0.274 -0.443 vn -0.885 -0.271 -0.378 vn -0.952 -0.121 -0.282 vn 0.180 0.824 -0.537 vn 0.642 0.679 -0.355 vn 0.956 0.291 -0.021 vn 0.453 -0.867 0.208 vn 0.910 -0.301 0.285 vn 0.854 -0.043 0.518 vn 0.833 0.459 0.308 vn 0.241 0.911 0.334 vn 0.731 -0.650 -0.206 vn 0.760 -0.585 -0.282 vn -0.814 0.019 0.580 vn -0.563 0.638 0.526 vn -0.925 -0.012 0.381 vn -0.214 0.952 0.217 vn 0.096 0.721 0.686 vn -0.027 0.945 0.325 vn -0.555 -0.678 -0.481 vn 0.062 0.937 -0.343 vn 0.240 -0.291 0.926 vn 0.184 -0.889 0.419 vn -0.126 -0.990 0.061 vn -0.889 -0.369 -0.271 vn -0.506 -0.832 0.229 vn -0.808 -0.443 0.388 vn -0.993 -0.084 0.087 vn 0.350 -0.016 0.937 vn -0.636 0.759 -0.140 vn -0.771 0.626 -0.115 vn -0.250 0.462 -0.851 vn -0.192 0.568 -0.801 vn -0.359 0.279 0.891 vn -0.026 0.144 0.989 vn -0.398 -0.100 0.912 vn -0.465 0.084 0.881 vn -0.895 0.186 0.405 vn -0.947 0.184 0.264 vn -0.761 0.459 0.458 vn -0.657 0.429 0.620 vn -0.426 0.660 0.618 vn -0.505 0.610 0.611 vn 0.223 0.536 0.814 vn 0.285 0.393 0.874 vn -0.163 0.555 0.815 vn -0.038 0.570 0.821 vn -0.628 0.723 -0.288 vn -0.458 0.737 0.497 vn -0.212 0.799 0.563 vn -0.278 0.687 0.672 vn -0.380 0.657 0.651 vn -0.170 0.846 0.506 vn -0.305 0.687 0.660 vn -0.144 0.795 0.589 vn 0.001 0.494 -0.870 vn -0.208 0.539 -0.816 vn -0.027 0.458 -0.888 vn -0.057 0.367 -0.929 vn -0.262 0.718 0.645 vn -0.054 0.163 -0.985 vn -0.306 0.325 -0.895 vn -0.643 0.181 0.744 vn -0.717 0.083 0.692 vn -0.800 0.573 -0.178 vn 0.296 -0.070 0.953 vn -0.319 -0.065 0.946 # 1258 vertex normals g head s 1 f 24/1/24 25/2/25 26/3/26 f 24/1/24 26/3/26 23/4/23 f 28/5/28 29/6/29 30/7/30 f 28/5/28 30/7/30 27/8/27 f 32/9/32 33/10/33 34/11/34 f 32/9/32 34/11/34 31/12/31 f 36/13/36 31/12/31 34/11/34 f 36/13/36 34/11/34 35/14/35 f 36/13/36 35/14/35 25/2/25 f 36/13/36 25/2/25 24/1/24 f 38/15/38 39/16/39 40/17/40 f 38/15/38 40/17/40 37/18/37 f 42/19/42 23/4/23 26/3/26 f 42/19/42 26/3/26 41/20/41 f 40/17/40 42/19/42 41/20/41 f 40/17/40 41/20/41 37/18/37 f 38/15/38 43/21/43 44/22/44 f 38/15/38 44/22/44 39/16/39 f 32/9/32 45/23/45 46/24/46 f 32/9/32 46/24/46 33/10/33 f 28/5/28 44/22/44 48/25/48 f 28/5/28 48/25/48 47/26/47 f 50/27/50 51/28/51 52/29/52 f 50/27/50 52/29/52 49/30/49 f 54/31/54 55/32/55 56/33/56 f 54/31/54 56/33/56 53/34/53 f 58/35/58 59/36/59 60/37/60 f 58/35/58 60/37/60 57/38/57 f 62/39/62 63/40/63 64/41/64 f 62/39/62 64/41/64 61/42/61 f 66/43/66 67/44/67 68/45/68 f 66/43/66 68/45/68 65/46/65 f 70/47/70 71/48/71 72/49/72 f 70/47/70 72/49/72 69/50/69 f 67/44/67 66/43/66 74/51/74 f 67/44/67 74/51/74 73/52/73 f 66/43/66 51/28/51 50/27/50 f 66/43/66 50/27/50 74/51/74 f 76/53/76 77/54/77 78/55/78 f 76/53/76 78/55/78 75/56/75 f 80/57/80 81/58/81 82/59/82 f 80/57/80 82/59/82 79/60/79 f 84/61/84 85/62/85 86/63/86 f 84/61/84 86/63/86 83/64/83 f 87/65/87 88/66/88 80/57/80 f 87/65/87 80/57/80 79/60/79 f 90/67/90 91/68/91 92/69/92 f 90/67/90 92/69/92 89/70/89 f 93/71/93 94/72/94 78/55/78 f 93/71/93 78/55/78 77/54/77 f 87/65/87 95/73/95 96/74/96 f 87/65/87 96/74/96 88/66/88 f 98/75/98 99/76/99 100/77/100 f 98/75/98 100/77/100 97/78/97 f 100/77/100 101/79/101 102/80/102 f 100/77/100 102/80/102 97/78/97 f 98/75/98 103/81/103 104/82/104 f 98/75/98 104/82/104 99/76/99 f 106/83/106 107/84/107 108/85/108 f 106/83/106 108/85/108 105/86/105 f 109/87/109 110/88/110 105/86/105 f 109/87/109 105/86/105 108/85/108 f 101/79/101 111/89/111 112/90/112 f 101/79/101 112/90/112 102/80/102 f 114/91/114 115/92/115 116/93/116 f 114/91/114 116/93/116 113/94/113 f 118/95/118 119/96/119 120/97/120 f 118/95/118 120/97/120 117/98/117 f 122/99/122 123/100/123 124/101/124 f 122/99/122 124/101/124 121/102/121 f 126/103/126 127/104/127 128/105/128 f 126/103/126 128/105/128 125/106/125 f 130/107/130 131/108/131 132/109/132 f 130/107/130 132/109/132 129/110/129 f 125/106/125 128/105/128 134/111/134 f 125/106/125 134/111/134 133/112/133 f 56/33/56 55/32/55 136/113/136 f 56/33/56 136/113/136 135/114/135 f 37/115/37 137/116/137 138/117/138 f 37/115/37 138/117/138 38/118/38 f 139/119/139 43/120/43 38/118/38 f 139/119/139 38/118/38 138/117/138 f 140/121/140 141/122/141 142/123/142 f 140/121/140 142/123/142 130/107/130 f 144/124/144 129/110/129 132/109/132 f 144/124/144 132/109/132 143/125/143 f 146/126/146 147/127/147 148/128/148 f 146/126/146 148/128/148 145/129/145 f 150/130/150 151/131/151 54/31/54 f 150/130/150 54/31/54 149/132/149 f 54/31/54 53/34/53 152/133/152 f 54/31/54 152/133/152 149/132/149 f 154/134/154 155/135/155 156/136/156 f 154/134/154 156/136/156 153/137/153 f 158/138/158 159/139/159 160/140/160 f 158/138/158 160/140/160 157/141/157 f 162/142/162 163/143/163 164/144/164 f 162/142/162 164/144/164 161/145/161 f 129/110/129 144/124/144 157/141/157 f 129/110/129 157/141/157 160/140/160 f 156/136/156 155/135/155 166/146/166 f 156/136/156 166/146/166 165/147/165 f 168/148/168 169/149/169 170/150/170 f 168/148/168 170/150/170 167/151/167 f 171/152/171 172/153/172 173/154/173 f 171/152/171 173/154/173 169/149/169 f 175/155/175 176/156/176 171/152/171 f 175/155/175 171/152/171 174/157/174 f 59/36/59 177/158/177 178/159/178 f 59/36/59 178/159/178 60/37/60 f 180/160/180 181/161/181 49/30/49 f 180/160/180 49/30/49 179/162/179 f 127/104/127 52/29/52 182/163/182 f 127/104/127 182/163/182 128/105/128 f 134/111/134 183/164/183 184/165/184 f 134/111/134 184/165/184 124/101/124 f 185/166/185 121/102/121 124/101/124 f 185/166/185 124/101/124 184/165/184 f 187/167/187 188/168/188 189/169/189 f 187/167/187 189/169/189 186/170/186 f 191/171/191 192/172/192 193/173/193 f 191/171/191 193/173/193 190/174/190 f 76/53/76 194/175/194 193/173/193 f 76/53/76 193/173/193 77/54/77 f 100/77/100 99/76/99 196/176/196 f 100/77/100 196/176/196 195/177/195 f 176/156/176 175/155/175 198/178/198 f 176/156/176 198/178/198 197/179/197 f 199/180/199 200/181/200 173/154/173 f 199/180/199 173/154/173 172/153/172 f 196/176/196 202/182/202 203/183/203 f 196/176/196 203/183/203 201/184/201 f 205/185/205 206/186/206 207/187/207 f 205/185/205 207/187/207 204/188/204 f 208/189/208 205/185/205 204/188/204 f 208/189/208 204/188/204 201/184/201 f 210/190/210 97/78/97 102/80/102 f 210/190/210 102/80/102 209/191/209 f 79/60/79 210/190/210 209/191/209 f 79/60/79 209/191/209 87/65/87 f 212/192/212 213/193/213 214/194/214 f 212/192/212 214/194/214 211/195/211 f 216/196/216 217/197/217 218/198/218 f 216/196/216 218/198/218 215/199/215 f 220/200/220 216/196/216 215/199/215 f 220/200/220 215/199/215 219/201/219 f 222/202/222 223/203/223 218/198/218 f 222/202/222 218/198/218 221/204/221 f 225/205/225 226/206/226 227/207/227 f 225/205/225 227/207/227 224/208/224 f 222/202/222 221/204/221 229/209/229 f 222/202/222 229/209/229 228/210/228 f 230/211/230 231/212/231 220/200/220 f 230/211/230 220/200/220 219/201/219 f 227/207/227 226/206/226 231/212/231 f 227/207/227 231/212/231 230/211/230 f 233/213/233 234/214/234 235/215/235 f 233/213/233 235/215/235 232/216/232 f 186/170/186 203/183/203 202/182/202 f 186/170/186 202/182/202 187/167/187 f 236/217/236 237/218/237 238/219/238 f 236/217/236 238/219/238 188/168/188 f 240/220/240 241/221/241 242/222/242 f 240/220/240 242/222/242 239/223/239 f 241/221/241 243/224/243 244/225/244 f 241/221/241 244/225/244 238/219/238 f 245/226/245 101/79/101 100/77/100 f 245/226/245 100/77/100 195/177/195 f 195/177/195 204/188/204 207/187/207 f 195/177/195 207/187/207 245/226/245 f 111/89/111 246/227/246 247/228/247 f 111/89/111 247/228/247 115/92/115 f 141/122/141 140/121/140 249/229/249 f 141/122/141 249/229/249 248/230/248 f 251/231/251 252/232/252 253/233/253 f 251/231/251 253/233/253 250/234/250 f 254/235/254 118/95/118 255/236/255 f 254/235/254 255/236/255 217/197/217 f 257/237/257 258/238/258 259/239/259 f 257/237/257 259/239/259 256/240/256 f 256/240/256 259/239/259 261/241/261 f 256/240/256 261/241/261 260/242/260 f 260/242/260 261/241/261 30/243/30 f 260/242/260 30/243/30 29/244/29 f 218/198/218 217/197/217 262/245/262 f 218/198/218 262/245/262 221/204/221 f 259/239/259 258/238/258 264/246/264 f 259/239/259 264/246/264 263/247/263 f 266/248/266 30/243/30 261/241/261 f 266/248/266 261/241/261 265/249/265 f 253/233/253 252/232/252 268/250/268 f 253/233/253 268/250/268 267/251/267 f 270/252/270 200/181/200 271/253/271 f 270/252/270 271/253/271 269/254/269 f 199/180/199 272/255/272 271/253/271 f 199/180/199 271/253/271 200/181/200 f 199/180/199 273/256/273 274/257/274 f 199/180/199 274/257/274 272/255/272 f 276/258/276 267/251/267 268/250/268 f 276/258/276 268/250/268 275/259/275 f 275/259/275 268/250/268 269/254/269 f 275/259/275 269/254/269 277/260/277 f 93/71/93 77/54/77 193/173/193 f 93/71/93 193/173/193 192/172/192 f 279/261/279 280/262/280 281/263/281 f 279/261/279 281/263/281 278/264/278 f 278/264/278 88/66/88 96/74/96 f 278/264/278 96/74/96 279/261/279 f 282/265/282 283/266/283 62/39/62 f 282/265/282 62/39/62 94/72/94 f 281/263/281 284/267/284 285/268/285 f 281/263/281 285/268/285 278/264/278 f 287/269/287 288/270/288 289/271/289 f 287/269/287 289/271/289 286/272/286 f 63/40/63 62/39/62 283/266/283 f 63/40/63 283/266/283 290/273/290 f 283/266/283 291/274/291 292/275/292 f 283/266/283 292/275/292 290/273/290 f 293/276/293 294/277/294 68/45/68 f 293/276/293 68/45/68 67/44/67 f 296/278/296 297/279/297 298/280/298 f 296/278/296 298/280/298 295/281/295 f 300/282/300 301/283/301 302/284/302 f 300/282/300 302/284/302 299/285/299 f 304/286/304 305/287/305 306/288/306 f 304/286/304 306/288/306 303/289/303 f 138/117/138 137/116/137 308/290/308 f 138/117/138 308/290/308 307/291/307 f 165/147/165 310/292/310 311/293/311 f 165/147/165 311/293/311 309/294/309 f 312/295/312 55/32/55 54/31/54 f 312/295/312 54/31/54 151/131/151 f 314/296/314 151/131/151 150/130/150 f 314/296/314 150/130/150 313/297/313 f 315/298/315 316/299/316 227/207/227 f 315/298/315 227/207/227 230/211/230 f 136/113/136 317/300/317 158/138/158 f 136/113/136 158/138/158 157/141/157 f 319/301/319 148/128/148 147/127/147 f 319/301/319 147/127/147 318/302/318 f 320/303/320 321/304/321 147/127/147 f 320/303/320 147/127/147 146/126/146 f 323/305/323 324/306/324 325/307/325 f 323/305/323 325/307/325 322/308/322 f 80/57/80 88/66/88 278/264/278 f 80/57/80 278/264/278 285/268/285 f 327/309/327 145/129/145 148/128/148 f 327/309/327 148/128/148 326/310/326 f 279/261/279 286/272/286 289/271/289 f 279/261/279 289/271/289 280/262/280 f 329/311/329 330/312/330 331/313/331 f 329/311/329 331/313/331 328/314/328 f 187/167/187 202/182/202 104/82/104 f 187/167/187 104/82/104 332/315/332 f 236/217/236 332/315/332 191/171/191 f 236/217/236 191/171/191 190/174/190 f 165/147/165 166/146/166 333/316/333 f 165/147/165 333/316/333 310/292/310 f 139/119/139 334/317/334 48/318/48 f 139/119/139 48/318/48 43/120/43 f 336/319/336 337/320/337 338/321/338 f 336/319/336 338/321/338 335/322/335 f 51/28/51 324/306/324 182/163/182 f 51/28/51 182/163/182 52/29/52 f 339/323/339 126/103/126 53/34/53 f 339/323/339 53/34/53 56/33/56 f 340/324/340 341/325/341 149/132/149 f 340/324/340 149/132/149 152/133/152 f 243/224/243 343/326/343 344/327/344 f 243/224/243 344/327/344 342/328/342 f 346/329/346 343/326/343 240/220/240 f 346/329/346 240/220/240 345/330/345 f 348/331/348 349/332/349 350/333/350 f 348/331/348 350/333/350 347/334/347 f 351/335/351 352/336/352 213/193/213 f 351/335/351 213/193/213 212/192/212 f 128/105/128 182/163/182 183/164/183 f 128/105/128 183/164/183 134/111/134 f 103/81/103 98/75/98 354/337/354 f 103/81/103 354/337/354 353/338/353 f 114/91/114 113/94/113 356/339/356 f 114/91/114 356/339/356 355/340/355 f 358/341/358 197/179/197 198/178/198 f 358/341/358 198/178/198 357/342/357 f 107/84/107 359/343/359 360/344/360 f 107/84/107 360/344/360 108/85/108 f 348/331/348 361/345/361 362/346/362 f 348/331/348 362/346/362 349/332/349 f 347/334/347 363/347/363 234/214/234 f 347/334/347 234/214/234 348/331/348 f 220/200/220 231/212/231 167/151/167 f 220/200/220 167/151/167 364/348/364 f 153/137/153 366/349/366 300/282/300 f 153/137/153 300/282/300 365/350/365 f 295/281/295 72/49/72 71/48/71 f 295/281/295 71/48/71 296/278/296 f 179/162/179 339/323/339 367/351/367 f 179/162/179 367/351/367 180/160/180 f 368/352/368 369/353/369 158/138/158 f 368/352/368 158/138/158 317/300/317 f 317/300/317 136/113/136 55/32/55 f 317/300/317 55/32/55 312/295/312 f 371/354/371 372/355/372 373/356/373 f 371/354/371 373/356/373 370/357/370 f 41/358/41 26/359/26 306/288/306 f 41/358/41 306/288/306 305/287/305 f 305/287/305 137/116/137 37/115/37 f 305/287/305 37/115/37 41/358/41 f 248/230/248 374/360/374 375/361/375 f 248/230/248 375/361/375 141/122/141 f 66/43/66 325/307/325 324/306/324 f 66/43/66 324/306/324 51/28/51 f 183/164/183 323/305/323 376/362/376 f 183/164/183 376/362/376 184/165/184 f 378/363/378 253/233/253 267/251/267 f 378/363/378 267/251/267 377/364/377 f 269/254/269 271/253/271 379/365/379 f 269/254/269 379/365/379 277/260/277 f 381/366/381 382/367/382 383/368/383 f 381/366/381 383/368/383 380/369/380 f 384/370/384 385/371/385 105/86/105 f 384/370/384 105/86/105 110/88/110 f 105/86/105 385/371/385 386/372/386 f 105/86/105 386/372/386 106/83/106 f 360/344/360 387/373/387 109/87/109 f 360/344/360 109/87/109 108/85/108 f 181/161/181 180/160/180 164/144/164 f 181/161/181 164/144/164 163/143/163 f 365/350/365 388/374/388 154/134/154 f 365/350/365 154/134/154 153/137/153 f 168/148/168 167/151/167 231/212/231 f 168/148/168 231/212/231 226/206/226 f 81/58/81 291/274/291 283/266/283 f 81/58/81 283/266/283 282/265/282 f 272/255/272 389/375/389 379/365/379 f 272/255/272 379/365/379 271/253/271 f 274/257/274 390/376/390 389/375/389 f 274/257/274 389/375/389 272/255/272 f 139/119/139 375/361/375 374/360/374 f 139/119/139 374/360/374 334/317/334 f 391/377/391 366/349/366 153/137/153 f 391/377/391 153/137/153 156/136/156 f 392/378/392 393/379/393 366/349/366 f 392/378/392 366/349/366 391/377/391 f 173/154/173 200/181/200 270/252/270 f 173/154/173 270/252/270 394/380/394 f 301/283/301 300/282/300 366/349/366 f 301/283/301 366/349/366 393/379/393 f 396/381/396 397/382/397 398/383/398 f 396/381/396 398/383/398 395/384/395 f 399/385/399 364/348/364 167/151/167 f 399/385/399 167/151/167 170/150/170 f 394/380/394 251/231/251 399/385/399 f 394/380/394 399/385/399 170/150/170 f 270/252/270 252/232/252 251/231/251 f 270/252/270 251/231/251 394/380/394 f 102/80/102 112/90/112 400/386/400 f 102/80/102 400/386/400 209/191/209 f 131/108/131 401/387/401 372/355/372 f 131/108/131 372/355/372 371/354/371 f 391/377/391 156/136/156 165/147/165 f 391/377/391 165/147/165 309/294/309 f 403/388/403 404/389/404 405/390/405 f 403/388/403 405/390/405 402/391/402 f 402/391/402 392/378/392 391/377/391 f 402/391/402 391/377/391 309/294/309 f 35/392/35 310/292/310 333/316/333 f 35/392/35 333/316/333 25/393/25 f 35/392/35 34/394/34 311/293/311 f 35/392/35 311/293/311 310/292/310 f 34/394/34 33/395/33 403/388/403 f 34/394/34 403/388/403 311/293/311 f 406/396/406 262/245/262 217/197/217 f 406/396/406 217/197/217 255/236/255 f 377/364/377 407/397/407 408/398/408 f 377/364/377 408/398/408 406/396/406 f 117/98/117 378/363/378 255/236/255 f 117/98/117 255/236/255 118/95/118 f 270/252/270 269/254/269 268/250/268 f 270/252/270 268/250/268 252/232/252 f 304/286/304 303/289/303 373/356/373 f 304/286/304 373/356/373 372/355/372 f 362/346/362 409/399/409 410/400/410 f 362/346/362 410/400/410 349/332/349 f 411/401/411 412/402/412 89/70/89 f 411/401/411 89/70/89 92/69/92 f 414/403/414 411/401/411 415/404/415 f 414/403/414 415/404/415 413/405/413 f 417/406/417 336/319/336 418/407/418 f 417/406/417 418/407/418 416/408/416 f 337/320/337 419/409/419 69/50/69 f 337/320/337 69/50/69 72/49/72 f 421/410/421 422/411/422 423/412/423 f 421/410/421 423/412/423 420/413/420 f 421/410/421 424/414/424 425/415/425 f 421/410/421 425/415/425 422/411/422 f 423/412/423 422/411/422 427/416/427 f 423/412/423 427/416/427 426/417/426 f 239/223/239 242/222/242 428/418/428 f 239/223/239 428/418/428 425/415/425 f 430/419/430 73/52/73 74/51/74 f 430/419/430 74/51/74 429/420/429 f 70/47/70 69/50/69 419/409/419 f 70/47/70 419/409/419 429/420/429 f 247/228/247 431/421/431 116/93/116 f 247/228/247 116/93/116 115/92/115 f 346/329/346 345/330/345 433/422/433 f 346/329/346 433/422/433 432/423/432 f 433/422/433 421/410/421 420/413/420 f 433/422/433 420/413/420 434/424/434 f 436/425/436 437/426/437 438/427/438 f 436/425/436 438/427/438 435/428/435 f 437/426/437 381/366/381 380/369/380 f 437/426/437 380/369/380 438/427/438 f 178/159/178 177/158/177 440/429/440 f 178/159/178 440/429/440 439/430/439 f 440/429/440 441/431/441 442/432/442 f 440/429/440 442/432/442 439/430/439 f 444/433/444 445/434/445 446/435/446 f 444/433/444 446/435/446 443/436/443 f 324/306/324 323/305/323 183/164/183 f 324/306/324 183/164/183 182/163/182 f 213/193/213 352/336/352 357/342/357 f 213/193/213 357/342/357 198/178/198 f 214/194/214 175/155/175 174/157/174 f 214/194/214 174/157/174 225/205/225 f 448/437/448 449/438/449 450/439/450 f 448/437/448 450/439/450 447/440/447 f 423/412/423 426/417/426 451/441/451 f 423/412/423 451/441/451 447/440/447 f 75/56/75 451/441/451 426/417/426 f 75/56/75 426/417/426 76/53/76 f 78/55/78 94/72/94 62/39/62 f 78/55/78 62/39/62 61/42/61 f 286/272/286 86/63/86 85/62/85 f 286/272/286 85/62/85 287/269/287 f 95/73/95 87/65/87 209/191/209 f 95/73/95 209/191/209 400/386/400 f 237/218/237 452/442/452 428/418/428 f 237/218/237 428/418/428 242/222/242 f 190/174/190 193/173/193 194/175/194 f 190/174/190 194/175/194 452/442/452 f 237/218/237 236/217/236 190/174/190 f 237/218/237 190/174/190 452/442/452 f 79/60/79 82/59/82 354/337/354 f 79/60/79 354/337/354 210/190/210 f 286/272/286 279/261/279 96/74/96 f 286/272/286 96/74/96 86/63/86 f 430/419/430 417/406/417 416/408/416 f 430/419/430 416/408/416 453/443/453 f 338/321/338 295/281/295 298/280/298 f 338/321/338 298/280/298 299/285/299 f 57/38/57 60/37/60 455/444/455 f 57/38/57 455/444/455 454/445/454 f 212/192/212 456/446/456 457/447/457 f 212/192/212 457/447/457 351/335/351 f 83/64/83 355/340/355 356/339/356 f 83/64/83 356/339/356 84/61/84 f 142/123/142 141/122/141 375/361/375 f 142/123/142 375/361/375 307/291/307 f 401/387/401 142/123/142 307/291/307 f 401/387/401 307/291/307 308/290/308 f 459/448/459 257/237/257 256/240/256 f 459/448/459 256/240/256 458/449/458 f 228/210/228 264/246/264 258/238/258 f 228/210/228 258/238/258 222/202/222 f 256/240/256 260/242/260 460/450/460 f 256/240/256 460/450/460 458/449/458 f 460/450/460 260/242/260 29/244/29 f 460/450/460 29/244/29 47/451/47 f 263/247/263 265/249/265 261/241/261 f 263/247/263 261/241/261 259/239/259 f 461/452/461 462/453/462 189/169/189 f 461/452/461 189/169/189 244/225/244 f 227/207/227 316/299/316 463/454/463 f 227/207/227 463/454/463 224/208/224 f 465/455/465 466/456/466 410/400/410 f 465/455/465 410/400/410 464/457/464 f 90/67/90 386/372/386 385/371/385 f 90/67/90 385/371/385 91/68/91 f 233/213/233 361/345/361 348/331/348 f 233/213/233 348/331/348 234/214/234 f 235/215/235 234/214/234 363/347/363 f 235/215/235 363/347/363 467/458/467 f 338/321/338 337/320/337 72/49/72 f 338/321/338 72/49/72 295/281/295 f 338/321/338 299/285/299 302/284/302 f 338/321/338 302/284/302 335/322/335 f 468/459/468 469/460/469 470/461/470 f 468/459/468 470/461/470 415/404/415 f 347/334/347 471/462/471 472/463/472 f 347/334/347 472/463/472 363/347/363 f 471/462/471 347/334/347 350/333/350 f 471/462/471 350/333/350 473/464/473 f 465/455/465 475/465/475 476/466/476 f 465/455/465 476/466/476 474/467/474 f 384/370/384 110/88/110 478/468/478 f 384/370/384 478/468/478 477/469/477 f 414/403/414 479/470/479 412/402/412 f 414/403/414 412/402/412 411/401/411 f 288/270/288 287/269/287 412/402/412 f 288/270/288 412/402/412 479/470/479 f 85/62/85 84/61/84 90/67/90 f 85/62/85 90/67/90 89/70/89 f 386/372/386 356/339/356 113/94/113 f 386/372/386 113/94/113 106/83/106 f 232/216/232 358/341/358 357/342/357 f 232/216/232 357/342/357 233/213/233 f 297/279/297 296/278/296 181/161/181 f 297/279/297 181/161/181 163/143/163 f 419/409/419 337/320/337 336/319/336 f 419/409/419 336/319/336 417/406/417 f 49/30/49 52/29/52 127/104/127 f 49/30/49 127/104/127 179/162/179 f 26/359/26 25/393/25 333/316/333 f 26/359/26 333/316/333 306/288/306 f 371/354/371 370/357/370 162/142/162 f 371/354/371 162/142/162 161/145/161 f 258/238/258 257/237/257 223/203/223 f 258/238/258 223/203/223 222/202/222 f 257/237/257 459/448/459 480/471/480 f 257/237/257 480/471/480 223/203/223 f 211/195/211 214/194/214 225/205/225 f 211/195/211 225/205/225 224/208/224 f 316/299/316 481/472/481 314/296/314 f 316/299/316 314/296/314 463/454/463 f 171/152/171 169/149/169 168/148/168 f 171/152/171 168/148/168 174/157/174 f 273/256/273 199/180/199 172/153/172 f 273/256/273 172/153/172 482/473/482 f 168/148/168 226/206/226 225/205/225 f 168/148/168 225/205/225 174/157/174 f 245/226/245 246/227/246 111/89/111 f 245/226/245 111/89/111 101/79/101 f 114/91/114 112/90/112 111/89/111 f 114/91/114 111/89/111 115/92/115 f 210/190/210 354/337/354 98/75/98 f 210/190/210 98/75/98 97/78/97 f 431/421/431 358/341/358 232/216/232 f 431/421/431 232/216/232 359/343/359 f 235/215/235 360/344/360 359/343/359 f 235/215/235 359/343/359 232/216/232 f 360/344/360 235/215/235 467/458/467 f 360/344/360 467/458/467 387/373/387 f 81/58/81 282/265/282 483/474/483 f 81/58/81 483/474/483 82/59/82 f 485/475/485 486/476/486 487/477/487 f 485/475/485 487/477/487 484/478/484 f 489/479/489 68/45/68 294/277/294 f 489/479/489 294/277/294 488/480/488 f 491/481/491 454/445/454 455/444/455 f 491/481/491 455/444/455 490/482/490 f 154/134/154 370/357/370 373/356/373 f 154/134/154 373/356/373 155/135/155 f 491/481/491 322/308/322 325/307/325 f 491/481/491 325/307/325 492/483/492 f 491/481/491 490/482/490 493/484/493 f 491/481/491 493/484/493 322/308/322 f 436/425/436 435/428/435 446/435/446 f 436/425/436 446/435/446 494/485/494 f 495/486/495 496/487/496 438/427/438 f 495/486/495 438/427/438 380/369/380 f 496/487/496 497/488/497 435/428/435 f 496/487/496 435/428/435 438/427/438 f 331/313/331 330/312/330 498/489/498 f 331/313/331 498/489/498 432/423/432 f 499/490/499 346/329/346 432/423/432 f 499/490/499 432/423/432 498/489/498 f 380/369/380 383/368/383 500/491/500 f 380/369/380 500/491/500 495/486/495 f 501/492/501 328/314/328 331/313/331 f 501/492/501 331/313/331 434/424/434 f 499/490/499 344/327/344 343/326/343 f 499/490/499 343/326/343 346/329/346 f 492/483/492 502/493/502 454/445/454 f 492/483/492 454/445/454 491/481/491 f 454/445/454 502/493/502 487/477/487 f 454/445/454 487/477/487 57/38/57 f 486/476/486 58/35/58 57/38/57 f 486/476/486 57/38/57 487/477/487 f 58/35/58 486/476/486 503/494/503 f 58/35/58 503/494/503 382/367/382 f 383/368/383 504/495/504 505/496/505 f 383/368/383 505/496/505 500/491/500 f 447/440/447 450/439/450 420/413/420 f 447/440/447 420/413/420 423/412/423 f 329/311/329 328/314/328 445/434/445 f 329/311/329 445/434/445 444/433/444 f 450/439/450 449/438/449 506/497/506 f 450/439/450 506/497/506 501/492/501 f 507/498/507 508/499/508 451/441/451 f 507/498/507 451/441/451 75/56/75 f 99/76/99 104/82/104 202/182/202 f 99/76/99 202/182/202 196/176/196 f 509/500/509 208/189/208 201/184/201 f 509/500/509 201/184/201 203/183/203 f 201/184/201 204/188/204 195/177/195 f 201/184/201 195/177/195 196/176/196 f 462/453/462 510/501/510 186/170/186 f 462/453/462 186/170/186 189/169/189 f 203/183/203 186/170/186 510/501/510 f 203/183/203 510/501/510 509/500/509 f 148/128/148 319/301/319 341/325/341 f 148/128/148 341/325/341 326/310/326 f 326/310/326 341/325/341 340/324/340 f 326/310/326 340/324/340 511/502/511 f 123/100/123 511/502/511 340/324/340 f 123/100/123 340/324/340 133/112/133 f 71/48/71 49/30/49 181/161/181 f 71/48/71 181/161/181 296/278/296 f 154/134/154 388/374/388 162/142/162 f 154/134/154 162/142/162 370/357/370 f 155/135/155 373/356/373 303/289/303 f 155/135/155 303/289/303 166/146/166 f 166/146/166 303/289/303 306/288/306 f 166/146/166 306/288/306 333/316/333 f 512/503/512 320/303/320 289/271/289 f 512/503/512 289/271/289 288/270/288 f 479/470/479 414/403/414 514/504/514 f 479/470/479 514/504/514 513/505/513 f 414/403/414 413/405/413 475/465/475 f 414/403/414 475/465/475 514/504/514 f 513/505/513 512/503/512 288/270/288 f 513/505/513 288/270/288 479/470/479 f 191/171/191 103/81/103 353/338/353 f 191/171/191 353/338/353 192/172/192 f 332/315/332 104/82/104 103/81/103 f 332/315/332 103/81/103 191/171/191 f 82/59/82 483/474/483 353/338/353 f 82/59/82 353/338/353 354/337/354 f 83/64/83 86/63/86 96/74/96 f 83/64/83 96/74/96 95/73/95 f 83/64/83 95/73/95 400/386/400 f 83/64/83 400/386/400 355/340/355 f 355/340/355 400/386/400 112/90/112 f 355/340/355 112/90/112 114/91/114 f 144/124/144 135/114/135 136/113/136 f 144/124/144 136/113/136 157/141/157 f 298/280/298 365/350/365 300/282/300 f 298/280/298 300/282/300 299/285/299 f 298/280/298 297/279/297 388/374/388 f 298/280/298 388/374/388 365/350/365 f 367/351/367 143/125/143 164/144/164 f 367/351/367 164/144/164 180/160/180 f 515/506/515 516/507/516 219/201/219 f 515/506/515 219/201/219 215/199/215 f 254/235/254 217/197/217 216/196/216 f 254/235/254 216/196/216 517/508/517 f 398/383/398 364/348/364 399/385/399 f 398/383/398 399/385/399 395/384/395 f 398/383/398 397/382/397 517/508/517 f 398/383/398 517/508/517 216/196/216 f 518/509/518 519/510/519 246/227/246 f 518/509/518 246/227/246 245/226/245 f 319/301/319 150/130/150 149/132/149 f 319/301/319 149/132/149 341/325/341 f 429/420/429 419/409/419 417/406/417 f 429/420/429 417/406/417 430/419/430 f 33/395/33 46/511/46 404/389/404 f 33/395/33 404/389/404 403/388/403 f 403/388/403 402/391/402 309/294/309 f 403/388/403 309/294/309 311/293/311 f 393/379/393 520/512/520 521/513/521 f 393/379/393 521/513/521 301/283/301 f 522/514/522 520/512/520 393/379/393 f 522/514/522 393/379/393 392/378/392 f 302/284/302 301/283/301 521/513/521 f 302/284/302 521/513/521 523/515/523 f 302/284/302 523/515/523 524/516/524 f 302/284/302 524/516/524 335/322/335 f 321/304/321 456/446/456 318/302/318 f 321/304/321 318/302/318 147/127/147 f 456/446/456 321/304/321 525/517/525 f 456/446/456 525/517/525 457/447/457 f 410/400/410 409/399/409 526/518/526 f 410/400/410 526/518/526 464/457/464 f 410/400/410 466/456/466 350/333/350 f 410/400/410 350/333/350 349/332/349 f 456/446/456 212/192/212 211/195/211 f 456/446/456 211/195/211 527/519/527 f 211/195/211 224/208/224 463/454/463 f 211/195/211 463/454/463 527/519/527 f 407/397/407 377/364/377 267/251/267 f 407/397/407 267/251/267 276/258/276 f 378/363/378 377/364/377 406/396/406 f 378/363/378 406/396/406 255/236/255 f 175/155/175 214/194/214 213/193/213 f 175/155/175 213/193/213 198/178/198 f 386/372/386 90/67/90 84/61/84 f 386/372/386 84/61/84 356/339/356 f 409/399/409 362/346/362 351/335/351 f 409/399/409 351/335/351 457/447/457 f 85/62/85 89/70/89 412/402/412 f 85/62/85 412/402/412 287/269/287 f 361/345/361 233/213/233 357/342/357 f 361/345/361 357/342/357 352/336/352 f 116/93/116 431/421/431 359/343/359 f 116/93/116 359/343/359 107/84/107 f 116/93/116 107/84/107 106/83/106 f 116/93/116 106/83/106 113/94/113 f 352/336/352 351/335/351 362/346/362 f 352/336/352 362/346/362 361/345/361 f 513/505/513 514/504/514 464/457/464 f 513/505/513 464/457/464 526/518/526 f 526/518/526 409/399/409 457/447/457 f 526/518/526 457/447/457 525/517/525 f 514/504/514 475/465/475 465/455/465 f 514/504/514 465/455/465 464/457/464 f 358/341/358 431/421/431 247/228/247 f 358/341/358 247/228/247 197/179/197 f 176/156/176 482/473/482 172/153/172 f 176/156/176 172/153/172 171/152/171 f 396/381/396 395/384/395 250/234/250 f 396/381/396 250/234/250 119/96/119 f 395/384/395 399/385/399 251/231/251 f 395/384/395 251/231/251 250/234/250 f 291/274/291 81/58/81 80/57/80 f 291/274/291 80/57/80 285/268/285 f 284/267/284 292/275/292 291/274/291 f 284/267/284 291/274/291 285/268/285 f 528/520/528 327/309/327 326/310/326 f 528/520/528 326/310/326 511/502/511 f 126/103/126 125/106/125 152/133/152 f 126/103/126 152/133/152 53/34/53 f 152/133/152 125/106/125 133/112/133 f 152/133/152 133/112/133 340/324/340 f 127/104/127 126/103/126 339/323/339 f 127/104/127 339/323/339 179/162/179 f 56/33/56 135/114/135 367/351/367 f 56/33/56 367/351/367 339/323/339 f 124/101/124 123/100/123 133/112/133 f 124/101/124 133/112/133 134/111/134 f 143/125/143 367/351/367 135/114/135 f 143/125/143 135/114/135 144/124/144 f 164/144/164 143/125/143 132/109/132 f 164/144/164 132/109/132 161/145/161 f 401/387/401 131/108/131 130/107/130 f 401/387/401 130/107/130 142/123/142 f 292/275/292 528/520/528 122/99/122 f 292/275/292 122/99/122 290/273/290 f 61/42/61 507/498/507 75/56/75 f 61/42/61 75/56/75 78/55/78 f 320/303/320 512/503/512 525/517/525 f 320/303/320 525/517/525 321/304/321 f 512/503/512 513/505/513 526/518/526 f 512/503/512 526/518/526 525/517/525 f 123/100/123 122/99/122 528/520/528 f 123/100/123 528/520/528 511/502/511 f 262/245/262 529/521/529 229/209/229 f 262/245/262 229/209/229 221/204/221 f 316/299/316 315/298/315 368/352/368 f 316/299/316 368/352/368 481/472/481 f 516/507/516 315/298/315 230/211/230 f 516/507/516 230/211/230 219/201/219 f 515/506/515 530/522/530 369/353/369 f 515/506/515 369/353/369 516/507/516 f 530/522/530 515/506/515 223/203/223 f 530/522/530 223/203/223 480/471/480 f 215/199/215 218/198/218 223/203/223 f 215/199/215 223/203/223 515/506/515 f 459/448/459 458/449/458 374/360/374 f 459/448/459 374/360/374 248/230/248 f 458/449/458 460/450/460 334/317/334 f 458/449/458 334/317/334 374/360/374 f 334/317/334 460/450/460 47/451/47 f 334/317/334 47/451/47 48/318/48 f 459/448/459 248/230/248 249/229/249 f 459/448/459 249/229/249 480/471/480 f 253/233/253 120/97/120 119/96/119 f 253/233/253 119/96/119 250/234/250 f 394/380/394 170/150/170 169/149/169 f 394/380/394 169/149/169 173/154/173 f 519/510/519 482/473/482 176/156/176 f 519/510/519 176/156/176 197/179/197 f 518/509/518 273/256/273 482/473/482 f 518/509/518 482/473/482 519/510/519 f 531/523/531 274/257/274 273/256/273 f 531/523/531 273/256/273 518/509/518 f 532/524/532 390/376/390 274/257/274 f 532/524/532 274/257/274 531/523/531 f 343/326/343 243/224/243 241/221/241 f 343/326/343 241/221/241 240/220/240 f 188/168/188 238/219/238 244/225/244 f 188/168/188 244/225/244 189/169/189 f 187/167/187 332/315/332 236/217/236 f 187/167/187 236/217/236 188/168/188 f 447/440/447 451/441/451 508/499/508 f 447/440/447 508/499/508 448/437/448 f 162/142/162 388/374/388 297/279/297 f 162/142/162 297/279/297 163/143/163 f 392/378/392 402/391/402 405/390/405 f 392/378/392 405/390/405 522/514/522 f 533/525/533 413/405/413 415/404/415 f 533/525/533 415/404/415 470/461/470 f 534/526/534 65/46/65 68/45/68 f 534/526/534 68/45/68 489/479/489 f 502/493/502 535/527/535 484/478/484 f 502/493/502 484/478/484 487/477/487 f 503/494/503 536/528/536 537/529/537 f 503/494/503 537/529/537 504/495/504 f 492/483/492 538/530/538 535/527/535 f 492/483/492 535/527/535 502/493/502 f 492/483/492 325/307/325 66/43/66 f 492/483/492 66/43/66 65/46/65 f 504/495/504 537/529/537 539/531/539 f 504/495/504 539/531/539 505/496/505 f 239/223/239 424/414/424 345/330/345 f 239/223/239 345/330/345 240/220/240 f 59/36/59 58/35/58 382/367/382 f 59/36/59 382/367/382 381/366/381 f 432/423/432 433/422/433 434/424/434 f 432/423/432 434/424/434 331/313/331 f 437/426/437 436/425/436 440/429/440 f 437/426/437 440/429/440 177/158/177 f 381/366/381 437/426/437 177/158/177 f 381/366/381 177/158/177 59/36/59 f 449/438/449 441/431/441 494/485/494 f 449/438/449 494/485/494 506/497/506 f 450/439/450 501/492/501 434/424/434 f 450/439/450 434/424/434 420/413/420 f 382/367/382 503/494/503 504/495/504 f 382/367/382 504/495/504 383/368/383 f 501/492/501 506/497/506 445/434/445 f 501/492/501 445/434/445 328/314/328 f 536/528/536 503/494/503 486/476/486 f 536/528/536 486/476/486 485/475/485 f 313/297/313 150/130/150 319/301/319 f 313/297/313 319/301/319 318/302/318 f 327/309/327 284/267/284 281/263/281 f 327/309/327 281/263/281 145/129/145 f 483/474/483 93/71/93 192/172/192 f 483/474/483 192/172/192 353/338/353 f 483/474/483 282/265/282 94/72/94 f 483/474/483 94/72/94 93/71/93 f 422/411/422 425/415/425 428/418/428 f 422/411/422 428/418/428 427/416/427 f 421/410/421 433/422/433 345/330/345 f 421/410/421 345/330/345 424/414/424 f 463/454/463 314/296/314 313/297/313 f 463/454/463 313/297/313 527/519/527 f 315/298/315 516/507/516 369/353/369 f 315/298/315 369/353/369 368/352/368 f 314/296/314 481/472/481 312/295/312 f 314/296/314 312/295/312 151/131/151 f 368/352/368 317/300/317 312/295/312 f 368/352/368 312/295/312 481/472/481 f 369/353/369 530/522/530 159/139/159 f 369/353/369 159/139/159 158/138/158 f 480/471/480 249/229/249 159/139/159 f 480/471/480 159/139/159 530/522/530 f 262/245/262 406/396/406 408/398/408 f 262/245/262 408/398/408 529/521/529 f 398/383/398 216/196/216 220/200/220 f 398/383/398 220/200/220 364/348/364 f 541/532/541 542/533/542 543/534/543 f 541/532/541 543/534/543 540/535/540 f 545/536/545 543/534/543 542/533/542 f 545/536/545 542/533/542 544/537/544 f 547/538/547 545/536/545 544/537/544 f 547/538/547 544/537/544 546/539/546 f 549/540/549 547/538/547 546/539/546 f 549/540/549 546/539/546 548/541/548 f 551/542/551 549/540/549 548/541/548 f 551/542/551 548/541/548 550/543/550 f 553/544/553 551/542/551 550/543/550 f 553/544/553 550/543/550 552/545/552 f 555/546/555 553/544/553 552/545/552 f 555/546/555 552/545/552 554/547/554 f 557/548/557 558/549/558 559/550/559 f 557/548/557 559/550/559 556/551/556 f 561/552/561 557/548/557 556/551/556 f 561/552/561 556/551/556 560/553/560 f 563/554/563 546/539/546 544/537/544 f 563/554/563 544/537/544 562/555/562 f 564/556/564 548/541/548 546/539/546 f 564/556/564 546/539/546 563/554/563 f 565/557/565 550/543/550 548/541/548 f 565/557/565 548/541/548 564/556/564 f 566/558/566 552/545/552 550/543/550 f 566/558/566 550/543/550 565/557/565 f 552/545/552 566/558/566 567/559/567 f 552/545/552 567/559/567 554/547/554 f 559/550/559 568/560/568 569/561/569 f 559/550/559 569/561/569 556/551/556 f 570/562/570 560/553/560 556/551/556 f 570/562/570 556/551/556 569/561/569 f 571/563/571 572/564/572 560/553/560 f 571/563/571 560/553/560 570/562/570 f 574/565/574 540/535/540 575/566/575 f 574/565/574 575/566/575 573/567/573 f 577/568/577 543/534/543 545/536/545 f 577/568/577 545/536/545 576/569/576 f 545/536/545 547/538/547 578/570/578 f 545/536/545 578/570/578 576/569/576 f 579/571/579 578/570/578 547/538/547 f 579/571/579 547/538/547 549/540/549 f 580/572/580 579/571/579 551/542/551 f 580/572/580 551/542/551 553/544/553 f 580/572/580 553/544/553 555/546/555 f 580/572/580 555/546/555 581/573/581 f 558/549/558 557/548/557 583/574/583 f 558/549/558 583/574/583 582/575/582 f 561/552/561 584/576/584 583/574/583 f 561/552/561 583/574/583 557/548/557 f 561/552/561 572/564/572 585/577/585 f 561/552/561 585/577/585 584/576/584 f 571/563/571 586/578/586 585/577/585 f 571/563/571 585/577/585 572/564/572 f 544/537/544 542/533/542 541/532/541 f 544/537/544 541/532/541 562/555/562 f 574/565/574 588/579/588 589/580/589 f 574/565/574 589/580/589 587/581/587 f 574/565/574 573/567/573 590/582/590 f 574/565/574 590/582/590 588/579/588 f 590/582/590 573/567/573 575/566/575 f 590/582/590 575/566/575 591/583/591 f 575/566/575 540/535/540 543/534/543 f 575/566/575 543/534/543 591/583/591 f 564/556/564 592/584/592 566/558/566 f 564/556/564 566/558/566 565/557/565 f 592/584/592 593/585/593 567/559/567 f 592/584/592 567/559/567 566/558/566 f 568/560/568 559/550/559 554/547/554 f 568/560/568 554/547/554 567/559/567 f 554/547/554 559/550/559 558/549/558 f 554/547/554 558/549/558 555/546/555 f 582/575/582 581/573/581 555/546/555 f 582/575/582 555/546/555 558/549/558 f 592/584/592 564/556/564 563/554/563 f 592/584/592 563/554/563 562/555/562 f 589/580/589 568/560/568 567/559/567 f 589/580/589 567/559/567 593/585/593 f 540/535/540 574/565/574 587/581/587 f 540/535/540 587/581/587 541/532/541 f 571/563/571 570/562/570 590/582/590 f 571/563/571 590/582/590 591/583/591 f 589/580/589 588/579/588 569/561/569 f 589/580/589 569/561/569 568/560/568 f 543/534/543 577/568/577 594/586/594 f 543/534/543 594/586/594 591/583/591 f 594/586/594 586/578/586 571/563/571 f 594/586/594 571/563/571 591/583/591 f 596/587/596 581/573/581 582/575/582 f 596/587/596 582/575/582 595/588/595 f 596/587/596 597/589/597 580/572/580 f 596/587/596 580/572/580 581/573/581 f 583/574/583 490/482/490 455/444/455 f 583/574/583 455/444/455 595/588/595 f 583/574/583 584/576/584 493/484/493 f 583/574/583 493/484/493 490/482/490 f 597/589/597 508/499/508 579/571/579 f 597/589/597 579/571/579 580/572/580 f 442/432/442 448/437/448 508/499/508 f 442/432/442 508/499/508 597/589/597 f 60/37/60 178/159/178 595/588/595 f 60/37/60 595/588/595 455/444/455 f 178/159/178 439/430/439 596/587/596 f 178/159/178 596/587/596 595/588/595 f 577/568/577 64/41/64 185/166/185 f 577/568/577 185/166/185 594/586/594 f 586/578/586 184/165/184 376/362/376 f 586/578/586 376/362/376 585/577/585 f 590/582/590 570/562/570 569/561/569 f 590/582/590 569/561/569 588/579/588 f 61/42/61 576/569/576 578/570/578 f 61/42/61 578/570/578 507/498/507 f 585/577/585 376/362/376 493/484/493 f 585/577/585 493/484/493 584/576/584 f 453/443/453 598/590/598 73/52/73 f 453/443/453 73/52/73 430/419/430 f 519/510/519 197/179/197 247/228/247 f 519/510/519 247/228/247 246/227/246 f 281/263/281 280/262/280 146/126/146 f 281/263/281 146/126/146 145/129/145 f 64/41/64 63/40/63 121/102/121 f 64/41/64 121/102/121 185/166/185 f 284/267/284 327/309/327 528/520/528 f 284/267/284 528/520/528 292/275/292 f 290/273/290 122/99/122 121/102/121 f 290/273/290 121/102/121 63/40/63 f 280/262/280 289/271/289 320/303/320 f 280/262/280 320/303/320 146/126/146 f 184/165/184 586/578/586 594/586/594 f 184/165/184 594/586/594 185/166/185 f 253/233/253 378/363/378 117/98/117 f 253/233/253 117/98/117 120/97/120 f 249/229/249 140/121/140 160/140/160 f 249/229/249 160/140/160 159/139/159 f 129/110/129 160/140/160 140/121/140 f 129/110/129 140/121/140 130/107/130 f 161/145/161 132/109/132 131/108/131 f 161/145/161 131/108/131 371/354/371 f 313/297/313 318/302/318 456/446/456 f 313/297/313 456/446/456 527/519/527 f 492/483/492 65/46/65 534/526/534 f 492/483/492 534/526/534 538/530/538 f 441/431/441 449/438/449 448/437/448 f 441/431/441 448/437/448 442/432/442 f 443/436/443 446/435/446 435/428/435 f 443/436/443 435/428/435 497/488/497 f 446/435/446 445/434/445 506/497/506 f 446/435/446 506/497/506 494/485/494 f 441/431/441 440/429/440 436/425/436 f 441/431/441 436/425/436 494/485/494 f 596/587/596 439/430/439 442/432/442 f 596/587/596 442/432/442 597/589/597 f 577/568/577 576/569/576 61/42/61 f 577/568/577 61/42/61 64/41/64 f 238/219/238 237/218/237 242/222/242 f 238/219/238 242/222/242 241/221/241 f 194/175/194 76/53/76 426/417/426 f 194/175/194 426/417/426 427/416/427 f 452/442/452 194/175/194 427/416/427 f 452/442/452 427/416/427 428/418/428 f 461/452/461 244/225/244 243/224/243 f 461/452/461 243/224/243 342/328/342 f 508/499/508 507/498/507 578/570/578 f 508/499/508 578/570/578 579/571/579 f 245/226/245 207/187/207 531/523/531 f 245/226/245 531/523/531 518/509/518 f 206/186/206 532/524/532 531/523/531 f 206/186/206 531/523/531 207/187/207 f 32/9/32 31/12/31 600/591/600 f 32/9/32 600/591/600 599/592/599 f 601/593/601 600/591/600 36/13/36 f 601/593/601 36/13/36 24/1/24 f 602/594/602 601/593/601 24/1/24 f 602/594/602 24/1/24 23/4/23 f 40/17/40 602/594/602 23/4/23 f 40/17/40 23/4/23 42/19/42 f 44/22/44 604/595/604 605/596/605 f 44/22/44 605/596/605 603/597/603 f 39/16/39 603/597/603 602/594/602 f 39/16/39 602/594/602 40/17/40 f 601/593/601 606/598/606 607/599/607 f 601/593/601 607/599/607 600/591/600 f 468/459/468 608/600/608 609/601/609 f 468/459/468 609/601/609 469/460/469 f 477/469/477 609/601/609 608/600/608 f 477/469/477 608/600/608 384/370/384 f 610/602/610 611/603/611 612/604/612 f 610/602/610 612/604/612 472/605/472 f 610/602/610 472/605/472 471/606/471 f 610/602/610 471/606/471 613/607/613 f 476/608/476 614/609/614 615/610/615 f 476/608/476 615/610/615 474/611/474 f 478/468/478 110/88/110 109/87/109 f 478/468/478 109/87/109 616/612/616 f 466/456/466 465/455/465 474/467/474 f 466/456/466 474/467/474 617/613/617 f 466/456/466 617/613/617 473/464/473 f 466/456/466 473/464/473 350/333/350 f 614/609/614 533/614/533 470/615/470 f 614/609/614 470/615/470 618/616/618 f 475/465/475 413/405/413 533/525/533 f 475/465/475 533/525/533 476/466/476 f 618/616/618 469/617/469 609/618/609 f 618/616/618 609/618/609 619/619/619 f 619/619/619 609/618/609 477/620/477 f 619/619/619 477/620/477 620/621/620 f 387/373/387 621/622/621 616/612/616 f 387/373/387 616/612/616 109/87/109 f 616/623/616 622/624/622 620/621/620 f 616/623/616 620/621/620 478/625/478 f 473/626/473 617/627/617 615/610/615 f 473/626/473 615/610/615 613/607/613 f 621/628/621 623/629/623 622/624/622 f 621/628/621 622/624/622 616/623/616 f 624/630/624 612/604/612 611/603/611 f 624/630/624 611/603/611 623/629/623 f 49/30/49 71/48/71 70/47/70 f 49/30/49 70/47/70 50/27/50 f 336/319/336 335/322/335 524/516/524 f 336/319/336 524/516/524 418/407/418 f 598/590/598 293/276/293 67/44/67 f 598/590/598 67/44/67 73/52/73 f 50/27/50 70/47/70 429/420/429 f 50/27/50 429/420/429 74/51/74 f 322/308/322 493/484/493 376/362/376 f 322/308/322 376/362/376 323/305/323 f 589/580/589 593/585/593 592/584/592 f 589/580/589 592/584/592 587/581/587 f 396/381/396 119/96/119 118/95/118 f 396/381/396 118/95/118 254/235/254 f 517/508/517 397/382/397 396/381/396 f 517/508/517 396/381/396 254/235/254 f 28/5/28 27/8/27 625/631/625 f 28/5/28 625/631/625 604/595/604 f 600/591/600 607/599/607 626/632/626 f 600/591/600 626/632/626 599/592/599 f 607/599/607 627/633/627 628/634/628 f 607/599/607 628/634/628 626/632/626 f 604/595/604 625/631/625 628/634/628 f 604/595/604 628/634/628 627/633/627 f 630/635/630 631/636/631 632/637/632 f 630/635/630 632/637/632 629/638/629 f 634/639/634 635/640/635 636/641/636 f 634/639/634 636/641/636 633/642/633 f 638/643/638 639/644/639 640/645/640 f 638/643/638 640/645/640 637/646/637 f 641/647/641 642/648/642 637/646/637 f 641/647/641 637/646/637 640/645/640 f 644/649/644 645/650/645 646/651/646 f 644/649/644 646/651/646 643/652/643 f 631/636/631 642/648/642 648/653/648 f 631/636/631 648/653/648 647/654/647 f 650/655/650 651/656/651 652/657/652 f 650/655/650 652/657/652 649/658/649 f 643/652/643 646/651/646 654/659/654 f 643/652/643 654/659/654 653/660/653 f 654/659/654 651/656/651 650/655/650 f 654/659/654 650/655/650 653/660/653 f 655/661/655 656/662/656 657/663/657 f 655/661/655 657/663/657 632/637/632 f 657/663/657 659/664/659 660/665/660 f 657/663/657 660/665/660 658/666/658 f 661/667/661 659/664/659 657/663/657 f 661/667/661 657/663/657 656/662/656 f 631/636/631 647/654/647 655/661/655 f 631/636/631 655/661/655 632/637/632 f 637/646/637 642/648/642 631/636/631 f 637/646/637 631/636/631 630/635/630 f 640/645/640 650/655/650 649/658/649 f 640/645/640 649/658/649 641/647/641 f 652/657/652 662/668/662 641/647/641 f 652/657/652 641/647/641 649/658/649 f 648/653/648 642/648/642 641/647/641 f 648/653/648 641/647/641 662/668/662 f 663/669/663 664/670/664 537/529/537 f 663/669/663 537/529/537 536/528/536 f 666/671/666 640/645/640 639/644/639 f 666/671/666 639/644/639 665/672/665 f 666/671/666 665/672/665 636/641/636 f 666/671/666 636/641/636 635/640/635 f 667/673/667 539/531/539 537/529/537 f 667/673/667 537/529/537 664/670/664 f 634/639/634 644/649/644 643/652/643 f 634/639/634 643/652/643 635/640/635 f 653/660/653 650/655/650 640/645/640 f 653/660/653 640/645/640 666/671/666 f 666/671/666 635/640/635 643/652/643 f 666/671/666 643/652/643 653/660/653 f 669/674/669 644/649/644 634/639/634 f 669/674/669 634/639/634 668/675/668 f 638/643/638 637/646/637 630/635/630 f 638/643/638 630/635/630 670/676/670 f 645/650/645 644/649/644 669/674/669 f 645/650/645 669/674/669 671/677/671 f 638/643/638 670/676/670 485/475/485 f 638/643/638 485/475/485 484/478/484 f 672/678/672 633/642/633 489/479/489 f 672/678/672 489/479/489 488/480/488 f 632/637/632 657/663/657 658/666/658 f 632/637/632 658/666/658 629/638/629 f 670/676/670 663/669/663 536/528/536 f 670/676/670 536/528/536 485/475/485 f 633/642/633 636/641/636 534/526/534 f 633/642/633 534/526/534 489/479/489 f 484/478/484 535/527/535 639/644/639 f 484/478/484 639/644/639 638/643/638 f 629/638/629 658/666/658 664/670/664 f 629/638/629 664/670/664 663/669/663 f 665/672/665 639/644/639 535/527/535 f 665/672/665 535/527/535 538/530/538 f 636/641/636 665/672/665 538/530/538 f 636/641/636 538/530/538 534/526/534 f 660/665/660 667/673/667 664/670/664 f 660/665/660 664/670/664 658/666/658 f 668/675/668 634/639/634 633/642/633 f 668/675/668 633/642/633 672/678/672 f 630/635/630 629/638/629 663/669/663 f 630/635/630 663/669/663 670/676/670 f 1/679/1 661/667/661 656/662/656 f 1/679/1 656/662/656 22/680/22 f 20/681/20 647/654/647 648/653/648 f 20/681/20 648/653/648 18/682/18 f 647/654/647 20/681/20 21/683/21 f 647/654/647 21/683/21 655/661/655 f 15/684/15 646/651/646 645/650/645 f 15/684/15 645/650/645 13/685/13 f 19/686/19 651/656/651 654/659/654 f 19/686/19 654/659/654 14/687/14 f 648/653/648 662/668/662 16/688/16 f 648/653/648 16/688/16 18/682/18 f 17/689/17 652/657/652 651/656/651 f 17/689/17 651/656/651 19/686/19 f 21/683/21 22/680/22 656/662/656 f 21/683/21 656/662/656 655/661/655 f 13/685/13 645/650/645 671/677/671 f 13/685/13 671/677/671 2/690/2 f 646/651/646 15/684/15 14/687/14 f 646/651/646 14/687/14 654/659/654 f 17/689/17 16/688/16 662/668/662 f 17/689/17 662/668/662 652/657/652 f 608/600/608 91/68/91 385/371/385 f 608/600/608 385/371/385 384/370/384 f 304/286/304 372/355/372 401/387/401 f 304/286/304 401/387/401 308/290/308 f 468/459/468 415/404/415 411/401/411 f 468/459/468 411/401/411 92/69/92 f 602/594/602 603/597/603 606/598/606 f 602/594/602 606/598/606 601/593/601 f 608/600/608 468/459/468 92/69/92 f 608/600/608 92/69/92 91/68/91 f 305/287/305 304/286/304 308/290/308 f 305/287/305 308/290/308 137/116/137 f 139/119/139 138/117/138 307/291/307 f 139/119/139 307/291/307 375/361/375 f 674/691/674 675/692/675 676/693/676 f 674/691/674 676/693/676 673/694/673 f 678/695/678 27/8/27 679/696/679 f 678/695/678 679/696/679 677/697/677 f 681/698/681 682/699/682 683/700/683 f 681/698/681 683/700/683 680/701/680 f 684/702/684 685/703/685 683/700/683 f 684/702/684 683/700/683 682/699/682 f 684/702/684 674/691/674 673/694/673 f 684/702/684 673/694/673 685/703/685 f 687/704/687 688/705/688 689/706/689 f 687/704/687 689/706/689 686/707/686 f 690/708/690 691/709/691 676/693/676 f 690/708/690 676/693/676 675/692/675 f 689/706/689 688/705/688 691/709/691 f 689/706/689 691/709/691 690/708/690 f 687/704/687 686/707/686 693/710/693 f 687/704/687 693/710/693 692/711/692 f 681/698/681 680/701/680 46/24/46 f 681/698/681 46/24/46 45/23/45 f 678/695/678 694/712/694 695/713/695 f 678/695/678 695/713/695 693/710/693 f 697/714/697 698/715/698 699/716/699 f 697/714/697 699/716/699 696/717/696 f 701/718/701 702/719/702 703/720/703 f 701/718/701 703/720/703 700/721/700 f 705/722/705 706/723/706 707/724/707 f 705/722/705 707/724/707 704/725/704 f 709/726/709 710/727/710 711/728/711 f 709/726/709 711/728/711 708/729/708 f 713/730/713 714/731/714 715/732/715 f 713/730/713 715/732/715 712/733/712 f 717/734/717 718/735/718 719/736/719 f 717/734/717 719/736/719 716/737/716 f 712/733/712 720/738/720 721/739/721 f 712/733/712 721/739/721 713/730/713 f 713/730/713 721/739/721 697/714/697 f 713/730/713 697/714/697 696/717/696 f 723/740/723 724/741/724 725/742/725 f 723/740/723 725/742/725 722/743/722 f 727/744/727 728/745/728 729/746/729 f 727/744/727 729/746/729 726/747/726 f 731/748/731 732/749/732 733/750/733 f 731/748/731 733/750/733 730/751/730 f 735/752/735 728/745/728 727/744/727 f 735/752/735 727/744/727 734/753/734 f 737/754/737 738/755/738 739/756/739 f 737/754/737 739/756/739 736/757/736 f 741/758/741 722/743/722 725/742/725 f 741/758/741 725/742/725 740/759/740 f 735/752/735 734/753/734 743/760/743 f 735/752/735 743/760/743 742/761/742 f 745/762/745 746/763/746 747/764/747 f 745/762/745 747/764/747 744/765/744 f 747/764/747 746/763/746 749/766/749 f 747/764/747 749/766/749 748/767/748 f 745/762/745 744/765/744 751/768/751 f 745/762/745 751/768/751 750/769/750 f 753/770/753 754/771/754 755/772/755 f 753/770/753 755/772/755 752/773/752 f 757/774/757 755/772/755 754/771/754 f 757/774/757 754/771/754 756/775/756 f 748/767/748 749/766/749 759/776/759 f 748/767/748 759/776/759 758/777/758 f 761/778/761 762/779/762 763/780/763 f 761/778/761 763/780/763 760/781/760 f 765/782/765 766/783/766 767/784/767 f 765/782/765 767/784/767 764/785/764 f 769/786/769 770/787/770 771/788/771 f 769/786/769 771/788/771 768/789/768 f 773/790/773 774/791/774 775/792/775 f 773/790/773 775/792/775 772/793/772 f 777/794/777 778/795/778 779/796/779 f 777/794/777 779/796/779 776/797/776 f 774/791/774 780/798/780 781/799/781 f 774/791/774 781/799/781 775/792/775 f 703/720/703 782/800/782 783/801/783 f 703/720/703 783/801/783 700/721/700 f 688/802/688 687/803/687 785/804/785 f 688/802/688 785/804/785 784/805/784 f 786/806/786 785/804/785 687/803/687 f 786/806/786 687/803/687 692/807/692 f 788/808/788 777/794/777 789/809/789 f 788/808/788 789/809/789 787/810/787 f 790/811/790 791/812/791 779/796/779 f 790/811/790 779/796/779 778/795/778 f 793/813/793 794/814/794 795/815/795 f 793/813/793 795/815/795 792/816/792 f 797/817/797 798/818/798 701/718/701 f 797/817/797 701/718/701 796/819/796 f 701/718/701 798/818/798 799/820/799 f 701/718/701 799/820/799 702/719/702 f 801/821/801 802/822/802 803/823/803 f 801/821/801 803/823/803 800/824/800 f 805/825/805 806/826/806 807/827/807 f 805/825/805 807/827/807 804/828/804 f 809/829/809 810/830/810 811/831/811 f 809/829/809 811/831/811 808/832/808 f 778/795/778 807/827/807 806/826/806 f 778/795/778 806/826/806 790/811/790 f 803/823/803 812/833/812 813/834/813 f 803/823/803 813/834/813 800/824/800 f 815/835/815 816/836/816 817/837/817 f 815/835/815 817/837/817 814/838/814 f 819/839/819 814/838/814 820/840/820 f 819/839/819 820/840/820 818/841/818 f 822/842/822 823/843/823 819/839/819 f 822/842/822 819/839/819 821/844/821 f 704/725/704 707/724/707 825/845/825 f 704/725/704 825/845/825 824/846/824 f 827/847/827 828/848/828 698/715/698 f 827/847/827 698/715/698 826/849/826 f 772/793/772 775/792/775 829/850/829 f 772/793/772 829/850/829 699/716/699 f 781/799/781 771/788/771 831/851/831 f 781/799/781 831/851/831 830/852/830 f 832/853/832 831/851/831 771/788/771 f 832/853/832 771/788/771 770/787/770 f 834/854/834 835/855/835 836/856/836 f 834/854/834 836/856/836 833/857/833 f 838/858/838 839/859/839 840/860/840 f 838/858/838 840/860/840 837/861/837 f 723/740/723 722/743/722 840/860/840 f 723/740/723 840/860/840 841/862/841 f 747/764/747 842/863/842 843/864/843 f 747/764/747 843/864/843 744/765/744 f 821/844/821 844/865/844 845/866/845 f 821/844/821 845/866/845 822/842/822 f 847/867/847 818/841/818 820/840/820 f 847/867/847 820/840/820 846/868/846 f 843/864/843 849/869/849 850/870/850 f 843/864/843 850/870/850 848/871/848 f 205/185/205 851/872/851 852/873/852 f 205/185/205 852/873/852 206/186/206 f 208/189/208 849/869/849 851/872/851 f 208/189/208 851/872/851 205/185/205 f 853/874/853 854/875/854 749/766/749 f 853/874/853 749/766/749 746/763/746 f 728/745/728 735/752/735 854/875/854 f 728/745/728 854/875/854 853/874/853 f 856/876/856 857/877/857 858/878/858 f 856/876/856 858/878/858 855/879/855 f 860/880/860 861/881/861 862/882/862 f 860/880/860 862/882/862 859/883/859 f 863/884/863 864/885/864 861/881/861 f 863/884/863 861/881/861 860/880/860 f 866/886/866 867/887/867 862/882/862 f 866/886/866 862/882/862 865/888/865 f 869/889/869 870/890/870 871/891/871 f 869/889/869 871/891/871 868/892/868 f 866/886/866 228/210/228 229/209/229 f 866/886/866 229/209/229 867/887/867 f 873/893/873 864/885/864 863/884/863 f 873/893/873 863/884/863 872/894/872 f 871/891/871 873/893/873 872/894/872 f 871/891/871 872/894/872 868/892/868 f 875/895/875 876/896/876 877/897/877 f 875/895/875 877/897/877 874/898/874 f 835/855/835 834/854/834 848/871/848 f 835/855/835 848/871/848 850/870/850 f 879/899/879 833/857/833 880/900/880 f 879/899/879 880/900/880 878/901/878 f 882/902/882 883/903/883 884/904/884 f 882/902/882 884/904/884 881/905/881 f 881/905/881 880/900/880 886/906/886 f 881/905/881 886/906/886 885/907/885 f 887/908/887 842/863/842 747/764/747 f 887/908/887 747/764/747 748/767/748 f 842/863/842 887/908/887 852/873/852 f 842/863/842 852/873/852 851/872/851 f 758/777/758 760/781/760 889/909/889 f 758/777/758 889/909/889 888/910/888 f 787/810/787 890/911/890 891/912/891 f 787/810/787 891/912/891 788/808/788 f 893/913/893 894/914/894 895/915/895 f 893/913/893 895/915/895 892/916/892 f 896/917/896 859/883/859 897/918/897 f 896/917/896 897/918/897 765/782/765 f 899/919/899 900/920/900 901/921/901 f 899/919/899 901/921/901 898/922/898 f 900/920/900 902/923/902 903/924/903 f 900/920/900 903/924/903 901/921/901 f 902/923/902 677/925/677 679/926/679 f 902/923/902 679/926/679 903/924/903 f 862/882/862 867/887/867 904/927/904 f 862/882/862 904/927/904 859/883/859 f 901/921/901 263/247/263 264/246/264 f 901/921/901 264/246/264 898/922/898 f 266/248/266 265/249/265 903/924/903 f 266/248/266 903/924/903 679/926/679 f 895/915/895 905/928/905 906/929/906 f 895/915/895 906/929/906 892/916/892 f 907/930/907 908/931/908 909/932/909 f 907/930/907 909/932/909 846/868/846 f 847/867/847 846/868/846 909/932/909 f 847/867/847 909/932/909 910/933/910 f 847/867/847 910/933/910 912/934/912 f 847/867/847 912/934/912 911/935/911 f 276/258/276 275/259/275 906/929/906 f 276/258/276 906/929/906 905/928/905 f 275/259/275 277/260/277 908/931/908 f 275/259/275 908/931/908 906/929/906 f 741/758/741 837/861/837 840/860/840 f 741/758/741 840/860/840 722/743/722 f 914/936/914 915/937/915 916/938/916 f 914/936/914 916/938/916 913/939/913 f 915/937/915 914/936/914 743/760/743 f 915/937/915 743/760/743 734/753/734 f 918/940/918 740/759/740 709/726/709 f 918/940/918 709/726/709 917/941/917 f 916/938/916 915/937/915 920/942/920 f 916/938/916 920/942/920 919/943/919 f 922/944/922 923/945/923 924/946/924 f 922/944/922 924/946/924 921/947/921 f 708/729/708 925/948/925 917/941/917 f 708/729/708 917/941/917 709/726/709 f 917/941/917 925/948/925 927/949/927 f 917/941/917 927/949/927 926/950/926 f 293/276/293 712/733/712 715/732/715 f 293/276/293 715/732/715 294/277/294 f 929/951/929 930/952/930 931/953/931 f 929/951/929 931/953/931 928/954/928 f 933/955/933 934/956/934 935/957/935 f 933/955/933 935/957/935 932/958/932 f 937/959/937 938/960/938 939/961/939 f 937/959/937 939/961/939 936/962/936 f 785/804/785 940/963/940 941/964/941 f 785/804/785 941/964/941 784/805/784 f 812/833/812 943/965/943 944/966/944 f 812/833/812 944/966/944 942/967/942 f 945/968/945 796/819/796 701/718/701 f 945/968/945 701/718/701 700/721/700 f 946/969/946 947/970/947 797/817/797 f 946/969/946 797/817/797 796/819/796 f 949/971/949 873/893/873 871/891/871 f 949/971/949 871/891/871 948/972/948 f 783/801/783 806/826/806 805/825/805 f 783/801/783 805/825/805 950/973/950 f 951/974/951 952/975/952 792/816/792 f 951/974/951 792/816/792 795/815/795 f 954/976/954 793/813/793 792/816/792 f 954/976/954 792/816/792 953/977/953 f 956/978/956 957/979/957 958/980/958 f 956/978/956 958/980/958 955/981/955 f 727/744/727 920/942/920 915/937/915 f 727/744/727 915/937/915 734/753/734 f 959/982/959 960/983/960 795/815/795 f 959/982/959 795/815/795 794/814/794 f 914/936/914 913/939/913 924/946/924 f 914/936/914 924/946/924 923/945/923 f 329/984/329 961/985/961 962/986/962 f 329/984/329 962/986/962 330/987/330 f 834/854/834 963/988/963 751/768/751 f 834/854/834 751/768/751 848/871/848 f 879/899/879 839/859/839 838/858/838 f 879/899/879 838/858/838 963/988/963 f 812/833/812 942/967/942 964/989/964 f 812/833/812 964/989/964 813/834/813 f 786/806/786 692/807/692 695/990/695 f 786/806/786 695/990/695 965/991/965 f 967/992/967 968/993/968 969/994/969 f 967/992/967 969/994/969 966/995/966 f 696/717/696 699/716/699 829/850/829 f 696/717/696 829/850/829 955/981/955 f 970/996/970 703/720/703 702/719/702 f 970/996/970 702/719/702 773/790/773 f 972/997/972 799/820/799 798/818/798 f 972/997/972 798/818/798 971/998/971 f 885/907/885 342/999/342 344/1000/344 f 885/907/885 344/1000/344 973/1001/973 f 974/1002/974 975/1003/975 882/902/882 f 974/1002/974 882/902/882 973/1001/973 f 977/1004/977 978/1005/978 979/1006/979 f 977/1004/977 979/1006/979 976/1007/976 f 981/1008/981 856/876/856 855/879/855 f 981/1008/981 855/879/855 980/1009/980 f 775/792/775 781/799/781 830/852/830 f 775/792/775 830/852/830 829/850/829 f 750/769/750 982/1010/982 983/1011/983 f 750/769/750 983/1011/983 745/762/745 f 761/778/761 984/1012/984 985/1013/985 f 761/778/761 985/1013/985 762/779/762 f 986/1014/986 987/1015/987 845/866/845 f 986/1014/986 845/866/845 844/865/844 f 752/773/752 755/772/755 989/1016/989 f 752/773/752 989/1016/989 988/1017/988 f 977/1004/977 976/1007/976 991/1018/991 f 977/1004/977 991/1018/991 990/1019/990 f 978/1005/978 977/1004/977 874/898/874 f 978/1005/978 874/898/874 992/1020/992 f 863/884/863 993/1021/993 816/836/816 f 863/884/863 816/836/816 872/894/872 f 802/822/802 995/1022/995 933/955/933 f 802/822/802 933/955/933 994/1023/994 f 930/952/930 929/951/929 716/737/716 f 930/952/930 716/737/716 719/736/719 f 828/848/828 827/847/827 996/1024/996 f 828/848/828 996/1024/996 970/996/970 f 998/1025/998 950/973/950 805/825/805 f 998/1025/998 805/825/805 997/1026/997 f 950/973/950 945/968/945 700/721/700 f 950/973/950 700/721/700 783/801/783 f 1000/1027/1000 1001/1028/1001 1002/1029/1002 f 1000/1027/1000 1002/1029/1002 999/1030/999 f 691/1031/691 936/962/936 939/961/939 f 691/1031/691 939/961/939 676/1032/676 f 936/962/936 691/1031/691 688/802/688 f 936/962/936 688/802/688 784/805/784 f 890/911/890 787/810/787 1004/1033/1004 f 890/911/890 1004/1033/1004 1003/1034/1003 f 713/730/713 696/717/696 955/981/955 f 713/730/713 955/981/955 958/980/958 f 830/852/830 831/851/831 1005/1035/1005 f 830/852/830 1005/1035/1005 956/978/956 f 1006/1036/1006 1007/1037/1007 905/928/905 f 1006/1036/1006 905/928/905 895/915/895 f 908/931/908 277/260/277 379/365/379 f 908/931/908 379/365/379 909/932/909 f 1009/1038/1009 1010/1039/1010 1011/1040/1011 f 1009/1038/1009 1011/1040/1011 1008/1041/1008 f 1013/1042/1013 756/775/756 754/771/754 f 1013/1042/1013 754/771/754 1012/1043/1012 f 754/771/754 753/770/753 1014/1044/1014 f 754/771/754 1014/1044/1014 1012/1043/1012 f 989/1016/989 755/772/755 757/774/757 f 989/1016/989 757/774/757 1015/1045/1015 f 826/849/826 808/832/808 811/831/811 f 826/849/826 811/831/811 827/847/827 f 995/1022/995 802/822/802 801/821/801 f 995/1022/995 801/821/801 1016/1046/1016 f 815/835/815 868/892/868 872/894/872 f 815/835/815 872/894/872 816/836/816 f 726/747/726 918/940/918 917/941/917 f 726/747/726 917/941/917 926/950/926 f 910/933/910 909/932/909 379/365/379 f 910/933/910 379/365/379 389/375/389 f 912/934/912 910/933/910 389/375/389 f 912/934/912 389/375/389 390/376/390 f 786/806/786 965/991/965 1003/1034/1003 f 786/806/786 1003/1034/1003 1004/1033/1004 f 1017/1047/1017 803/823/803 802/822/802 f 1017/1047/1017 802/822/802 994/1023/994 f 1019/1048/1019 1017/1047/1017 994/1023/994 f 1019/1048/1019 994/1023/994 1018/1049/1018 f 820/840/820 1020/1050/1020 907/930/907 f 820/840/820 907/930/907 846/868/846 f 932/958/932 1018/1049/1018 994/1023/994 f 932/958/932 994/1023/994 933/955/933 f 1022/1051/1022 1023/1052/1023 1024/1053/1024 f 1022/1051/1022 1024/1053/1024 1021/1054/1021 f 1025/1055/1025 817/837/817 816/836/816 f 1025/1055/1025 816/836/816 993/1021/993 f 1020/1050/1020 817/837/817 1025/1055/1025 f 1020/1050/1020 1025/1055/1025 893/913/893 f 907/930/907 1020/1050/1020 893/913/893 f 907/930/907 893/913/893 892/916/892 f 749/766/749 854/875/854 1026/1056/1026 f 749/766/749 1026/1056/1026 759/776/759 f 776/797/776 1000/1027/1000 999/1030/999 f 776/797/776 999/1030/999 1027/1057/1027 f 1017/1047/1017 943/965/943 812/833/812 f 1017/1047/1017 812/833/812 803/823/803 f 1028/1058/1028 1029/1059/1029 405/390/405 f 1028/1058/1028 405/390/405 404/389/404 f 1029/1059/1029 943/965/943 1017/1047/1017 f 1029/1059/1029 1017/1047/1017 1019/1048/1019 f 685/1060/685 673/1061/673 964/989/964 f 685/1060/685 964/989/964 942/967/942 f 685/1060/685 942/967/942 944/966/944 f 685/1060/685 944/966/944 683/1062/683 f 683/1062/683 944/966/944 1028/1058/1028 f 683/1062/683 1028/1058/1028 680/1063/680 f 1030/1064/1030 897/918/897 859/883/859 f 1030/1064/1030 859/883/859 904/927/904 f 1007/1037/1007 1030/1064/1030 408/398/408 f 1007/1037/1007 408/398/408 407/397/407 f 766/783/766 765/782/765 897/918/897 f 766/783/766 897/918/897 1006/1036/1006 f 907/930/907 892/916/892 906/929/906 f 907/930/907 906/929/906 908/931/908 f 937/959/937 999/1030/999 1002/1029/1002 f 937/959/937 1002/1029/1002 938/960/938 f 991/1018/991 976/1007/976 1032/1065/1032 f 991/1018/991 1032/1065/1032 1031/1066/1031 f 1034/1067/1034 739/756/739 738/755/738 f 1034/1067/1034 738/755/738 1033/1068/1033 f 1035/1069/1035 1036/1070/1036 1037/1071/1037 f 1035/1069/1035 1037/1071/1037 1034/1067/1034 f 1038/1072/1038 416/408/416 418/407/418 f 1038/1072/1038 418/407/418 967/992/967 f 966/995/966 719/736/719 718/735/718 f 966/995/966 718/735/718 1039/1073/1039 f 1041/1074/1041 1042/1075/1042 1043/1076/1043 f 1041/1074/1041 1043/1076/1043 1040/1077/1040 f 1041/1074/1041 1040/1077/1040 1045/1078/1045 f 1041/1074/1041 1045/1078/1045 1044/1079/1044 f 1043/1076/1043 1046/1080/1046 1047/1081/1047 f 1043/1076/1043 1047/1081/1047 1040/1077/1040 f 883/903/883 1045/1078/1045 1048/1082/1048 f 883/903/883 1048/1082/1048 884/904/884 f 1049/1083/1049 1050/1084/1050 721/739/721 f 1049/1083/1049 721/739/721 720/738/720 f 717/734/717 1050/1084/1050 1039/1073/1039 f 717/734/717 1039/1073/1039 718/735/718 f 889/909/889 760/781/760 763/780/763 f 889/909/889 763/780/763 1051/1085/1051 f 974/1002/974 1052/1086/1052 1053/1087/1053 f 974/1002/974 1053/1087/1053 975/1003/975 f 1053/1087/1053 1054/1088/1054 1042/1075/1042 f 1053/1087/1053 1042/1075/1042 1041/1074/1041 f 1056/1089/1056 1057/1090/1057 1058/1091/1058 f 1056/1089/1056 1058/1091/1058 1055/1092/1055 f 1055/1092/1055 1058/1091/1058 1010/1039/1010 f 1055/1092/1055 1010/1039/1010 1009/1038/1009 f 825/845/825 1059/1093/1059 1060/1094/1060 f 825/845/825 1060/1094/1060 824/846/824 f 1060/1094/1060 1059/1093/1059 1062/1095/1062 f 1060/1094/1060 1062/1095/1062 1061/1096/1061 f 444/1097/444 443/1098/443 1064/1099/1064 f 444/1097/444 1064/1099/1064 1063/1100/1063 f 955/981/955 829/850/829 830/852/830 f 955/981/955 830/852/830 956/978/956 f 855/879/855 845/866/845 987/1015/987 f 855/879/855 987/1015/987 980/1009/980 f 858/878/858 869/889/869 823/843/823 f 858/878/858 823/843/823 822/842/822 f 1066/1101/1066 1067/1102/1067 1068/1103/1068 f 1066/1101/1066 1068/1103/1068 1065/1104/1065 f 1043/1076/1043 1067/1102/1067 1069/1105/1069 f 1043/1076/1043 1069/1105/1069 1046/1080/1046 f 724/741/724 723/740/723 1046/1080/1046 f 724/741/724 1046/1080/1046 1069/1105/1069 f 725/742/725 710/727/710 709/726/709 f 725/742/725 709/726/709 740/759/740 f 923/945/923 922/944/922 730/751/730 f 923/945/923 730/751/730 733/750/733 f 742/761/742 1026/1056/1026 854/875/854 f 742/761/742 854/875/854 735/752/735 f 878/901/878 884/904/884 1048/1082/1048 f 878/901/878 1048/1082/1048 1070/1106/1070 f 839/859/839 1070/1106/1070 841/862/841 f 839/859/839 841/862/841 840/860/840 f 878/901/878 1070/1106/1070 839/859/839 f 878/901/878 839/859/839 879/899/879 f 728/745/728 853/874/853 983/1011/983 f 728/745/728 983/1011/983 729/746/729 f 923/945/923 733/750/733 743/760/743 f 923/945/923 743/760/743 914/936/914 f 1049/1083/1049 453/443/453 416/408/416 f 1049/1083/1049 416/408/416 1038/1072/1038 f 969/994/969 934/956/934 931/953/931 f 969/994/969 931/953/931 930/952/930 f 706/723/706 1071/1107/1071 1072/1108/1072 f 706/723/706 1072/1108/1072 707/724/707 f 856/876/856 981/1008/981 1074/1109/1074 f 856/876/856 1074/1109/1074 1073/1110/1073 f 732/749/732 731/748/731 985/1013/985 f 732/749/732 985/1013/985 984/1012/984 f 789/809/789 940/963/940 1004/1033/1004 f 789/809/789 1004/1033/1004 787/810/787 f 1027/1057/1027 941/964/941 940/963/940 f 1027/1057/1027 940/963/940 789/809/789 f 1075/1111/1075 1076/1112/1076 900/920/900 f 1075/1111/1075 900/920/900 899/919/899 f 228/210/228 866/886/866 898/922/898 f 228/210/228 898/922/898 264/246/264 f 900/920/900 1076/1112/1076 1077/1113/1077 f 900/920/900 1077/1113/1077 902/923/902 f 1077/1113/1077 694/1114/694 677/925/677 f 1077/1113/1077 677/925/677 902/923/902 f 263/247/263 901/921/901 903/924/903 f 263/247/263 903/924/903 265/249/265 f 461/1115/461 886/906/886 836/856/836 f 461/1115/461 836/856/836 462/1116/462 f 871/891/871 870/890/870 1078/1117/1078 f 871/891/871 1078/1117/1078 948/972/948 f 1080/1118/1080 1081/1119/1081 1032/1065/1032 f 1080/1118/1080 1032/1065/1032 1079/1120/1079 f 737/754/737 736/757/736 1012/1043/1012 f 737/754/737 1012/1043/1012 1014/1044/1014 f 875/895/875 874/898/874 977/1004/977 f 875/895/875 977/1004/977 990/1019/990 f 877/897/877 1082/1121/1082 992/1020/992 f 877/897/877 992/1020/992 874/898/874 f 969/994/969 930/952/930 719/736/719 f 969/994/969 719/736/719 966/995/966 f 969/994/969 968/993/968 935/957/935 f 969/994/969 935/957/935 934/956/934 f 1084/1122/1084 1037/1071/1037 1085/1123/1085 f 1084/1122/1084 1085/1123/1085 1083/1124/1083 f 978/1005/978 992/1020/992 1087/1125/1087 f 978/1005/978 1087/1125/1087 1086/1126/1086 f 1086/1126/1086 1088/1127/1088 979/1006/979 f 1086/1126/1086 979/1006/979 978/1005/978 f 1080/1118/1080 1090/1128/1090 1091/1129/1091 f 1080/1118/1080 1091/1129/1091 1089/1130/1089 f 1013/1042/1013 1092/1131/1092 1093/1132/1093 f 1013/1042/1013 1093/1132/1093 756/775/756 f 1035/1069/1035 1034/1067/1034 1033/1068/1033 f 1035/1069/1035 1033/1068/1033 1094/1133/1094 f 921/947/921 1094/1133/1094 1033/1068/1033 f 921/947/921 1033/1068/1033 922/944/922 f 730/751/730 738/755/738 737/754/737 f 730/751/730 737/754/737 731/748/731 f 1014/1044/1014 753/770/753 762/779/762 f 1014/1044/1014 762/779/762 985/1013/985 f 876/896/876 875/895/875 987/1015/987 f 876/896/876 987/1015/987 986/1014/986 f 928/954/928 808/832/808 826/849/826 f 928/954/928 826/849/826 929/951/929 f 1039/1073/1039 1038/1072/1038 967/992/967 f 1039/1073/1039 967/992/967 966/995/966 f 698/715/698 828/848/828 772/793/772 f 698/715/698 772/793/772 699/716/699 f 676/1032/676 939/961/939 964/989/964 f 676/1032/676 964/989/964 673/1061/673 f 1000/1027/1000 810/830/810 809/829/809 f 1000/1027/1000 809/829/809 1001/1028/1001 f 898/922/898 866/886/866 865/888/865 f 898/922/898 865/888/865 899/919/899 f 899/919/899 865/888/865 1095/1134/1095 f 899/919/899 1095/1134/1095 1075/1111/1075 f 857/877/857 870/890/870 869/889/869 f 857/877/857 869/889/869 858/878/858 f 948/972/948 1078/1117/1078 946/969/946 f 948/972/948 946/969/946 1096/1135/1096 f 819/839/819 823/843/823 815/835/815 f 819/839/819 815/835/815 814/838/814 f 911/935/911 1097/1136/1097 818/841/818 f 911/935/911 818/841/818 847/867/847 f 815/835/815 823/843/823 869/889/869 f 815/835/815 869/889/869 868/892/868 f 887/908/887 748/767/748 758/777/758 f 887/908/887 758/777/758 888/910/888 f 761/778/761 760/781/760 758/777/758 f 761/778/761 758/777/758 759/776/759 f 853/874/853 746/763/746 745/762/745 f 853/874/853 745/762/745 983/1011/983 f 1051/1085/1051 988/1017/988 876/896/876 f 1051/1085/1051 876/896/876 986/1014/986 f 877/897/877 876/896/876 988/1017/988 f 877/897/877 988/1017/988 989/1016/989 f 989/1016/989 1015/1045/1015 1082/1121/1082 f 989/1016/989 1082/1121/1082 877/897/877 f 726/747/726 729/746/729 1098/1137/1098 f 726/747/726 1098/1137/1098 918/940/918 f 1100/1138/1100 1101/1139/1101 1102/1140/1102 f 1100/1138/1100 1102/1140/1102 1099/1141/1099 f 1103/1142/1103 488/480/488 294/277/294 f 1103/1142/1103 294/277/294 715/732/715 f 1104/1143/1104 1105/1144/1105 1072/1108/1072 f 1104/1143/1104 1072/1108/1072 1071/1107/1071 f 801/821/801 800/824/800 1002/1029/1002 f 801/821/801 1002/1029/1002 1001/1028/1001 f 1104/1143/1104 1106/1145/1106 958/980/958 f 1104/1143/1104 958/980/958 957/979/957 f 1104/1143/1104 957/979/957 1107/1146/1107 f 1104/1143/1104 1107/1146/1107 1105/1144/1105 f 1056/1089/1056 1108/1147/1108 1064/1099/1064 f 1056/1089/1056 1064/1099/1064 1057/1090/1057 f 495/1148/495 1010/1039/1010 1058/1091/1058 f 495/1148/495 1058/1091/1058 496/1149/496 f 496/1149/496 1058/1091/1058 1057/1090/1057 f 496/1149/496 1057/1090/1057 497/1150/497 f 962/986/962 1052/1086/1052 498/1151/498 f 962/986/962 498/1151/498 330/987/330 f 499/1152/499 498/1151/498 1052/1086/1052 f 499/1152/499 1052/1086/1052 974/1002/974 f 1010/1039/1010 495/1148/495 500/1153/500 f 1010/1039/1010 500/1153/500 1011/1040/1011 f 1109/1154/1109 1054/1088/1054 962/986/962 f 1109/1154/1109 962/986/962 961/985/961 f 499/1152/499 974/1002/974 973/1001/973 f 499/1152/499 973/1001/973 344/1000/344 f 1106/1145/1106 1104/1143/1104 1071/1107/1071 f 1106/1145/1106 1071/1107/1071 1110/1155/1110 f 1071/1107/1071 706/723/706 1102/1140/1102 f 1071/1107/1071 1102/1140/1102 1110/1155/1110 f 1099/1141/1099 1102/1140/1102 706/723/706 f 1099/1141/1099 706/723/706 705/722/705 f 705/722/705 1008/1041/1008 1111/1156/1111 f 705/722/705 1111/1156/1111 1099/1141/1099 f 1011/1040/1011 500/1153/500 505/1157/505 f 1011/1040/1011 505/1157/505 1112/1158/1112 f 1067/1102/1067 1043/1076/1043 1042/1075/1042 f 1067/1102/1067 1042/1075/1042 1068/1103/1068 f 329/984/329 444/1097/444 1063/1100/1063 f 329/984/329 1063/1100/1063 961/985/961 f 1068/1103/1068 1109/1154/1109 1113/1159/1113 f 1068/1103/1068 1113/1159/1113 1065/1104/1065 f 1115/1160/1115 724/741/724 1069/1105/1069 f 1115/1160/1115 1069/1105/1069 1114/1161/1114 f 744/765/744 843/864/843 848/871/848 f 744/765/744 848/871/848 751/768/751 f 509/500/509 850/870/850 849/869/849 f 509/500/509 849/869/849 208/189/208 f 849/869/849 843/864/843 842/863/842 f 849/869/849 842/863/842 851/872/851 f 462/1116/462 836/856/836 835/855/835 f 462/1116/462 835/855/835 510/501/510 f 850/870/850 509/500/509 510/501/510 f 850/870/850 510/501/510 835/855/835 f 795/815/795 960/983/960 971/998/971 f 795/815/795 971/998/971 951/974/951 f 960/983/960 1116/1162/1116 972/997/972 f 960/983/960 972/997/972 971/998/971 f 768/789/768 780/798/780 972/997/972 f 768/789/768 972/997/972 1116/1162/1116 f 716/737/716 929/951/929 826/849/826 f 716/737/716 826/849/826 698/715/698 f 801/821/801 1001/1028/1001 809/829/809 f 801/821/801 809/829/809 1016/1046/1016 f 800/824/800 813/834/813 938/960/938 f 800/824/800 938/960/938 1002/1029/1002 f 813/834/813 964/989/964 939/961/939 f 813/834/813 939/961/939 938/960/938 f 1117/1163/1117 921/947/921 924/946/924 f 1117/1163/1117 924/946/924 954/976/954 f 1094/1133/1094 1118/1164/1118 1119/1165/1119 f 1094/1133/1094 1119/1165/1119 1035/1069/1035 f 1035/1069/1035 1119/1165/1119 1089/1130/1089 f 1035/1069/1035 1089/1130/1089 1036/1070/1036 f 1118/1164/1118 1094/1133/1094 921/947/921 f 1118/1164/1118 921/947/921 1117/1163/1117 f 838/858/838 837/861/837 982/1010/982 f 838/858/838 982/1010/982 750/769/750 f 963/988/963 838/858/838 750/769/750 f 963/988/963 750/769/750 751/768/751 f 729/746/729 983/1011/983 982/1010/982 f 729/746/729 982/1010/982 1098/1137/1098 f 732/749/732 742/761/742 743/760/743 f 732/749/732 743/760/743 733/750/733 f 732/749/732 984/1012/984 1026/1056/1026 f 732/749/732 1026/1056/1026 742/761/742 f 984/1012/984 761/778/761 759/776/759 f 984/1012/984 759/776/759 1026/1056/1026 f 790/811/790 806/826/806 783/801/783 f 790/811/790 783/801/783 782/800/782 f 931/953/931 934/956/934 933/955/933 f 931/953/931 933/955/933 995/1022/995 f 931/953/931 995/1022/995 1016/1046/1016 f 931/953/931 1016/1046/1016 928/954/928 f 996/1024/996 827/847/827 811/831/811 f 996/1024/996 811/831/811 791/812/791 f 1121/1166/1121 861/881/861 864/885/864 f 1121/1166/1121 864/885/864 1120/1167/1120 f 896/917/896 1122/1168/1122 860/880/860 f 896/917/896 860/880/860 859/883/859 f 1024/1053/1024 1023/1052/1023 1025/1055/1025 f 1024/1053/1024 1025/1055/1025 993/1021/993 f 1024/1053/1024 860/880/860 1122/1168/1122 f 1024/1053/1024 1122/1168/1122 1021/1054/1021 f 1124/1169/1124 887/908/887 888/910/888 f 1124/1169/1124 888/910/888 1123/1170/1123 f 951/974/951 971/998/971 798/818/798 f 951/974/951 798/818/798 797/817/797 f 1050/1084/1050 1049/1083/1049 1038/1072/1038 f 1050/1084/1050 1038/1072/1038 1039/1073/1039 f 680/1063/680 1028/1058/1028 404/389/404 f 680/1063/680 404/389/404 46/511/46 f 1028/1058/1028 944/966/944 943/965/943 f 1028/1058/1028 943/965/943 1029/1059/1029 f 1018/1049/1018 932/958/932 521/513/521 f 1018/1049/1018 521/513/521 520/512/520 f 522/514/522 1019/1048/1019 1018/1049/1018 f 522/514/522 1018/1049/1018 520/512/520 f 935/957/935 523/515/523 521/513/521 f 935/957/935 521/513/521 932/958/932 f 935/957/935 968/993/968 524/516/524 f 935/957/935 524/516/524 523/515/523 f 953/977/953 792/816/792 952/975/952 f 953/977/953 952/975/952 1073/1110/1073 f 1073/1110/1073 1074/1109/1074 1125/1171/1125 f 1073/1110/1073 1125/1171/1125 953/977/953 f 1032/1065/1032 1081/1119/1081 1126/1172/1126 f 1032/1065/1032 1126/1172/1126 1031/1066/1031 f 1032/1065/1032 976/1007/976 979/1006/979 f 1032/1065/1032 979/1006/979 1079/1120/1079 f 1073/1110/1073 1127/1173/1127 857/877/857 f 1073/1110/1073 857/877/857 856/876/856 f 857/877/857 1127/1173/1127 1078/1117/1078 f 857/877/857 1078/1117/1078 870/890/870 f 407/397/407 276/258/276 905/928/905 f 407/397/407 905/928/905 1007/1037/1007 f 1006/1036/1006 897/918/897 1030/1064/1030 f 1006/1036/1006 1030/1064/1030 1007/1037/1007 f 822/842/822 845/866/845 855/879/855 f 822/842/822 855/879/855 858/878/858 f 1014/1044/1014 985/1013/985 731/748/731 f 1014/1044/1014 731/748/731 737/754/737 f 1031/1066/1031 1074/1109/1074 981/1008/981 f 1031/1066/1031 981/1008/981 991/1018/991 f 730/751/730 922/944/922 1033/1068/1033 f 730/751/730 1033/1068/1033 738/755/738 f 990/1019/990 980/1009/980 987/1015/987 f 990/1019/990 987/1015/987 875/895/875 f 763/780/763 752/773/752 988/1017/988 f 763/780/763 988/1017/988 1051/1085/1051 f 763/780/763 762/779/762 753/770/753 f 763/780/763 753/770/753 752/773/752 f 980/1009/980 990/1019/990 991/1018/991 f 980/1009/980 991/1018/991 981/1008/981 f 1118/1164/1118 1126/1172/1126 1081/1119/1081 f 1118/1164/1118 1081/1119/1081 1119/1165/1119 f 1126/1172/1126 1125/1171/1125 1074/1109/1074 f 1126/1172/1126 1074/1109/1074 1031/1066/1031 f 1119/1165/1119 1081/1119/1081 1080/1118/1080 f 1119/1165/1119 1080/1118/1080 1089/1130/1089 f 986/1014/986 844/865/844 889/909/889 f 986/1014/986 889/909/889 1051/1085/1051 f 821/844/821 819/839/819 818/841/818 f 821/844/821 818/841/818 1097/1136/1097 f 1022/1051/1022 764/785/764 894/914/894 f 1022/1051/1022 894/914/894 1023/1052/1023 f 1023/1052/1023 894/914/894 893/913/893 f 1023/1052/1023 893/913/893 1025/1055/1025 f 926/950/926 920/942/920 727/744/727 f 926/950/926 727/744/727 726/747/726 f 919/943/919 920/942/920 926/950/926 f 919/943/919 926/950/926 927/949/927 f 1128/1174/1128 1116/1162/1116 960/983/960 f 1128/1174/1128 960/983/960 959/982/959 f 773/790/773 702/719/702 799/820/799 f 773/790/773 799/820/799 774/791/774 f 799/820/799 972/997/972 780/798/780 f 799/820/799 780/798/780 774/791/774 f 772/793/772 828/848/828 970/996/970 f 772/793/772 970/996/970 773/790/773 f 703/720/703 970/996/970 996/1024/996 f 703/720/703 996/1024/996 782/800/782 f 771/788/771 781/799/781 780/798/780 f 771/788/771 780/798/780 768/789/768 f 791/812/791 790/811/790 782/800/782 f 791/812/791 782/800/782 996/1024/996 f 811/831/811 810/830/810 779/796/779 f 811/831/811 779/796/779 791/812/791 f 1027/1057/1027 789/809/789 777/794/777 f 1027/1057/1027 777/794/777 776/797/776 f 927/949/927 925/948/925 769/786/769 f 927/949/927 769/786/769 1128/1174/1128 f 710/727/710 725/742/725 724/741/724 f 710/727/710 724/741/724 1115/1160/1115 f 954/976/954 953/977/953 1125/1171/1125 f 954/976/954 1125/1171/1125 1117/1163/1117 f 1117/1163/1117 1125/1171/1125 1126/1172/1126 f 1117/1163/1117 1126/1172/1126 1118/1164/1118 f 768/789/768 1116/1162/1116 1128/1174/1128 f 768/789/768 1128/1174/1128 769/786/769 f 904/927/904 867/887/867 229/209/229 f 904/927/904 229/209/229 529/521/529 f 948/972/948 1096/1135/1096 998/1025/998 f 948/972/948 998/1025/998 949/971/949 f 1120/1167/1120 864/885/864 873/893/873 f 1120/1167/1120 873/893/873 949/971/949 f 1121/1166/1121 1120/1167/1120 997/1026/997 f 1121/1166/1121 997/1026/997 1129/1175/1129 f 1129/1175/1129 1095/1134/1095 865/888/865 f 1129/1175/1129 865/888/865 1121/1166/1121 f 861/881/861 1121/1166/1121 865/888/865 f 861/881/861 865/888/865 862/882/862 f 1075/1111/1075 890/911/890 1003/1034/1003 f 1075/1111/1075 1003/1034/1003 1076/1112/1076 f 1076/1112/1076 1003/1034/1003 965/991/965 f 1076/1112/1076 965/991/965 1077/1113/1077 f 965/991/965 695/990/695 694/1114/694 f 965/991/965 694/1114/694 1077/1113/1077 f 1075/1111/1075 1095/1134/1095 891/912/891 f 1075/1111/1075 891/912/891 890/911/890 f 895/915/895 894/914/894 764/785/764 f 895/915/895 764/785/764 767/784/767 f 1020/1050/1020 820/840/820 814/838/814 f 1020/1050/1020 814/838/814 817/837/817 f 1123/1170/1123 844/865/844 821/844/821 f 1123/1170/1123 821/844/821 1097/1136/1097 f 1124/1169/1124 1123/1170/1123 1097/1136/1097 f 1124/1169/1124 1097/1136/1097 911/935/911 f 1130/1176/1130 1124/1169/1124 911/935/911 f 1130/1176/1130 911/935/911 912/934/912 f 532/524/532 1130/1176/1130 912/934/912 f 532/524/532 912/934/912 390/376/390 f 973/1001/973 882/902/882 881/905/881 f 973/1001/973 881/905/881 885/907/885 f 833/857/833 836/856/836 886/906/886 f 833/857/833 886/906/886 880/900/880 f 834/854/834 833/857/833 879/899/879 f 834/854/834 879/899/879 963/988/963 f 1067/1102/1067 1066/1101/1066 1114/1161/1114 f 1067/1102/1067 1114/1161/1114 1069/1105/1069 f 809/829/809 808/832/808 928/954/928 f 809/829/809 928/954/928 1016/1046/1016 f 1019/1048/1019 522/514/522 405/390/405 f 1019/1048/1019 405/390/405 1029/1059/1029 f 1131/1177/1131 1085/1123/1085 1037/1071/1037 f 1131/1177/1131 1037/1071/1037 1036/1070/1036 f 1132/1178/1132 1103/1142/1103 715/732/715 f 1132/1178/1132 715/732/715 714/731/714 f 1110/1155/1110 1102/1140/1102 1101/1139/1101 f 1110/1155/1110 1101/1139/1101 1133/1179/1133 f 1111/1156/1111 1112/1158/1112 1135/1180/1135 f 1111/1156/1111 1135/1180/1135 1134/1181/1134 f 1106/1145/1106 1110/1155/1110 1133/1179/1133 f 1106/1145/1106 1133/1179/1133 1136/1182/1136 f 1106/1145/1106 714/731/714 713/730/713 f 1106/1145/1106 713/730/713 958/980/958 f 1112/1158/1112 505/1157/505 539/1183/539 f 1112/1158/1112 539/1183/539 1135/1180/1135 f 883/903/883 882/902/882 975/1003/975 f 883/903/883 975/1003/975 1044/1079/1044 f 704/725/704 1009/1038/1009 1008/1041/1008 f 704/725/704 1008/1041/1008 705/722/705 f 1052/1086/1052 962/986/962 1054/1088/1054 f 1052/1086/1052 1054/1088/1054 1053/1087/1053 f 1055/1092/1055 824/846/824 1060/1094/1060 f 1055/1092/1055 1060/1094/1060 1056/1089/1056 f 1009/1038/1009 704/725/704 824/846/824 f 1009/1038/1009 824/846/824 1055/1092/1055 f 1065/1104/1065 1113/1159/1113 1108/1147/1108 f 1065/1104/1065 1108/1147/1108 1061/1096/1061 f 1068/1103/1068 1042/1075/1042 1054/1088/1054 f 1068/1103/1068 1054/1088/1054 1109/1154/1109 f 1008/1041/1008 1011/1040/1011 1112/1158/1112 f 1008/1041/1008 1112/1158/1112 1111/1156/1111 f 1109/1154/1109 961/985/961 1063/1100/1063 f 1109/1154/1109 1063/1100/1063 1113/1159/1113 f 1134/1181/1134 1100/1138/1100 1099/1141/1099 f 1134/1181/1134 1099/1141/1099 1111/1156/1111 f 947/970/947 952/975/952 951/974/951 f 947/970/947 951/974/951 797/817/797 f 959/982/959 794/814/794 916/938/916 f 959/982/959 916/938/916 919/943/919 f 1098/1137/1098 982/1010/982 837/861/837 f 1098/1137/1098 837/861/837 741/758/741 f 1098/1137/1098 741/758/741 740/759/740 f 1098/1137/1098 740/759/740 918/940/918 f 1040/1077/1040 1047/1081/1047 1048/1082/1048 f 1040/1077/1040 1048/1082/1048 1045/1078/1045 f 1041/1074/1041 1044/1079/1044 975/1003/975 f 1041/1074/1041 975/1003/975 1053/1087/1053 f 1078/1117/1078 1127/1173/1127 947/970/947 f 1078/1117/1078 947/970/947 946/969/946 f 949/971/949 998/1025/998 997/1026/997 f 949/971/949 997/1026/997 1120/1167/1120 f 946/969/946 796/819/796 945/968/945 f 946/969/946 945/968/945 1096/1135/1096 f 998/1025/998 1096/1135/1096 945/968/945 f 998/1025/998 945/968/945 950/973/950 f 997/1026/997 805/825/805 804/828/804 f 997/1026/997 804/828/804 1129/1175/1129 f 1095/1134/1095 1129/1175/1129 804/828/804 f 1095/1134/1095 804/828/804 891/912/891 f 904/927/904 529/521/529 408/398/408 f 904/927/904 408/398/408 1030/1064/1030 f 1024/1053/1024 993/1021/993 863/884/863 f 1024/1053/1024 863/884/863 860/880/860 f 1138/1184/1138 1139/1185/1139 1140/1186/1140 f 1138/1184/1138 1140/1186/1140 1137/1187/1137 f 1141/1188/1141 1142/1189/1142 1137/1187/1137 f 1141/1188/1141 1137/1187/1137 1140/1186/1140 f 1143/1190/1143 1144/1191/1144 1142/1189/1142 f 1143/1190/1143 1142/1189/1142 1141/1188/1141 f 1145/1192/1145 1146/1193/1146 1144/1191/1144 f 1145/1192/1145 1144/1191/1144 1143/1190/1143 f 1147/1194/1147 1148/1195/1148 1146/1193/1146 f 1147/1194/1147 1146/1193/1146 1145/1192/1145 f 1149/1196/1149 1150/1197/1150 1148/1195/1148 f 1149/1196/1149 1148/1195/1148 1147/1194/1147 f 1151/1198/1151 1152/1199/1152 1150/1197/1150 f 1151/1198/1151 1150/1197/1150 1149/1196/1149 f 1154/1200/1154 1155/1201/1155 1156/1202/1156 f 1154/1200/1154 1156/1202/1156 1153/1203/1153 f 1157/1204/1157 1158/1205/1158 1155/1201/1155 f 1157/1204/1157 1155/1201/1155 1154/1200/1154 f 1159/1206/1159 1160/1207/1160 1142/1189/1142 f 1159/1206/1159 1142/1189/1142 1144/1191/1144 f 1161/1208/1161 1159/1206/1159 1144/1191/1144 f 1161/1208/1161 1144/1191/1144 1146/1193/1146 f 1162/1209/1162 1161/1208/1161 1146/1193/1146 f 1162/1209/1162 1146/1193/1146 1148/1195/1148 f 1163/1210/1163 1162/1209/1162 1148/1195/1148 f 1163/1210/1163 1148/1195/1148 1150/1197/1150 f 1150/1197/1150 1152/1199/1152 1164/1211/1164 f 1150/1197/1150 1164/1211/1164 1163/1210/1163 f 1156/1202/1156 1155/1201/1155 1166/1212/1166 f 1156/1202/1156 1166/1212/1166 1165/1213/1165 f 1167/1214/1167 1166/1212/1166 1155/1201/1155 f 1167/1214/1167 1155/1201/1155 1158/1205/1158 f 1169/1215/1169 1167/1214/1167 1158/1205/1158 f 1169/1215/1169 1158/1205/1158 1168/1216/1168 f 1170/1217/1170 1171/1218/1171 1172/1219/1172 f 1170/1217/1170 1172/1219/1172 1139/1185/1139 f 1173/1220/1173 1174/1221/1174 1141/1188/1141 f 1173/1220/1173 1141/1188/1141 1140/1186/1140 f 1141/1188/1141 1174/1221/1174 1175/1222/1175 f 1141/1188/1141 1175/1222/1175 1143/1190/1143 f 1176/1223/1176 1145/1192/1145 1143/1190/1143 f 1176/1223/1176 1143/1190/1143 1175/1222/1175 f 1177/1224/1177 1149/1196/1149 1147/1194/1147 f 1177/1224/1177 1147/1194/1147 1176/1223/1176 f 1177/1224/1177 1178/1225/1178 1151/1198/1151 f 1177/1224/1177 1151/1198/1151 1149/1196/1149 f 1153/1203/1153 1179/1226/1179 1180/1227/1180 f 1153/1203/1153 1180/1227/1180 1154/1200/1154 f 1157/1204/1157 1154/1200/1154 1180/1227/1180 f 1157/1204/1157 1180/1227/1180 1181/1228/1181 f 1157/1204/1157 1181/1228/1181 1182/1229/1182 f 1157/1204/1157 1182/1229/1182 1168/1216/1168 f 1169/1215/1169 1168/1216/1168 1182/1229/1182 f 1169/1215/1169 1182/1229/1182 1183/1230/1183 f 1142/1189/1142 1160/1207/1160 1138/1184/1138 f 1142/1189/1142 1138/1184/1138 1137/1187/1137 f 1170/1217/1170 1185/1231/1185 1186/1232/1186 f 1170/1217/1170 1186/1232/1186 1184/1233/1184 f 1170/1217/1170 1184/1233/1184 1187/1234/1187 f 1170/1217/1170 1187/1234/1187 1171/1218/1171 f 1187/1234/1187 1188/1235/1188 1172/1219/1172 f 1187/1234/1187 1172/1219/1172 1171/1218/1171 f 1172/1219/1172 1188/1235/1188 1140/1186/1140 f 1172/1219/1172 1140/1186/1140 1139/1185/1139 f 1161/1208/1161 1162/1209/1162 1163/1210/1163 f 1161/1208/1161 1163/1210/1163 1189/1236/1189 f 1189/1236/1189 1163/1210/1163 1164/1211/1164 f 1189/1236/1189 1164/1211/1164 1190/1237/1190 f 1165/1213/1165 1164/1211/1164 1152/1199/1152 f 1165/1213/1165 1152/1199/1152 1156/1202/1156 f 1152/1199/1152 1151/1198/1151 1153/1203/1153 f 1152/1199/1152 1153/1203/1153 1156/1202/1156 f 1179/1226/1179 1153/1203/1153 1151/1198/1151 f 1179/1226/1179 1151/1198/1151 1178/1225/1178 f 1189/1236/1189 1160/1207/1160 1159/1206/1159 f 1189/1236/1189 1159/1206/1159 1161/1208/1161 f 1186/1232/1186 1190/1237/1190 1164/1211/1164 f 1186/1232/1186 1164/1211/1164 1165/1213/1165 f 1139/1185/1139 1138/1184/1138 1185/1231/1185 f 1139/1185/1139 1185/1231/1185 1170/1217/1170 f 1169/1215/1169 1188/1235/1188 1187/1234/1187 f 1169/1215/1169 1187/1234/1187 1167/1214/1167 f 1186/1232/1186 1165/1213/1165 1166/1212/1166 f 1186/1232/1186 1166/1212/1166 1184/1233/1184 f 1140/1186/1140 1188/1235/1188 1191/1238/1191 f 1140/1186/1140 1191/1238/1191 1173/1220/1173 f 1191/1238/1191 1188/1235/1188 1169/1215/1169 f 1191/1238/1191 1169/1215/1169 1183/1230/1183 f 1192/1239/1192 1193/1240/1193 1179/1226/1179 f 1192/1239/1192 1179/1226/1179 1178/1225/1178 f 1192/1239/1192 1178/1225/1178 1177/1224/1177 f 1192/1239/1192 1177/1224/1177 1194/1241/1194 f 1180/1227/1180 1193/1240/1193 1072/1108/1072 f 1180/1227/1180 1072/1108/1072 1105/1144/1105 f 1180/1227/1180 1105/1144/1105 1107/1146/1107 f 1180/1227/1180 1107/1146/1107 1181/1228/1181 f 1194/1241/1194 1177/1224/1177 1176/1223/1176 f 1194/1241/1194 1176/1223/1176 1114/1161/1114 f 1062/1095/1062 1194/1241/1194 1114/1161/1114 f 1062/1095/1062 1114/1161/1114 1066/1101/1066 f 707/724/707 1072/1108/1072 1193/1240/1193 f 707/724/707 1193/1240/1193 825/845/825 f 825/845/825 1193/1240/1193 1192/1239/1192 f 825/845/825 1192/1239/1192 1059/1093/1059 f 1173/1220/1173 1191/1238/1191 832/853/832 f 1173/1220/1173 832/853/832 711/728/711 f 1183/1230/1183 1182/1229/1182 1005/1035/1005 f 1183/1230/1183 1005/1035/1005 831/851/831 f 1187/1234/1187 1184/1233/1184 1166/1212/1166 f 1187/1234/1187 1166/1212/1166 1167/1214/1167 f 710/727/710 1115/1160/1115 1175/1222/1175 f 710/727/710 1175/1222/1175 1174/1221/1174 f 1182/1229/1182 1181/1228/1181 1107/1146/1107 f 1182/1229/1182 1107/1146/1107 1005/1035/1005 f 453/443/453 1049/1083/1049 720/738/720 f 453/443/453 720/738/720 598/590/598 f 1123/1170/1123 888/910/888 889/909/889 f 1123/1170/1123 889/909/889 844/865/844 f 916/938/916 794/814/794 793/813/793 f 916/938/916 793/813/793 913/939/913 f 711/728/711 832/853/832 770/787/770 f 711/728/711 770/787/770 708/729/708 f 919/943/919 927/949/927 1128/1174/1128 f 919/943/919 1128/1174/1128 959/982/959 f 925/948/925 708/729/708 770/787/770 f 925/948/925 770/787/770 769/786/769 f 913/939/913 793/813/793 954/976/954 f 913/939/913 954/976/954 924/946/924 f 831/851/831 832/853/832 1191/1238/1191 f 831/851/831 1191/1238/1191 1183/1230/1183 f 895/915/895 767/784/767 766/783/766 f 895/915/895 766/783/766 1006/1036/1006 f 891/912/891 804/828/804 807/827/807 f 891/912/891 807/827/807 788/808/788 f 778/795/778 777/794/777 788/808/788 f 778/795/778 788/808/788 807/827/807 f 810/830/810 1000/1027/1000 776/797/776 f 810/830/810 776/797/776 779/796/779 f 947/970/947 1127/1173/1127 1073/1110/1073 f 947/970/947 1073/1110/1073 952/975/952 f 1106/1145/1106 1136/1182/1136 1132/1178/1132 f 1106/1145/1106 1132/1178/1132 714/731/714 f 1061/1096/1061 1062/1095/1062 1066/1101/1066 f 1061/1096/1061 1066/1101/1066 1065/1104/1065 f 443/1098/443 497/1150/497 1057/1090/1057 f 443/1098/443 1057/1090/1057 1064/1099/1064 f 1064/1099/1064 1108/1147/1108 1113/1159/1113 f 1064/1099/1064 1113/1159/1113 1063/1100/1063 f 1061/1096/1061 1108/1147/1108 1056/1089/1056 f 1061/1096/1061 1056/1089/1056 1060/1094/1060 f 1192/1239/1192 1194/1241/1194 1062/1095/1062 f 1192/1239/1192 1062/1095/1062 1059/1093/1059 f 1173/1220/1173 711/728/711 710/727/710 f 1173/1220/1173 710/727/710 1174/1221/1174 f 880/900/880 881/905/881 884/904/884 f 880/900/880 884/904/884 878/901/878 f 841/862/841 1047/1081/1047 1046/1080/1046 f 841/862/841 1046/1080/1046 723/740/723 f 1070/1106/1070 1048/1082/1048 1047/1081/1047 f 1070/1106/1070 1047/1081/1047 841/862/841 f 461/1115/461 342/999/342 885/907/885 f 461/1115/461 885/907/885 886/906/886 f 1114/1161/1114 1176/1223/1176 1175/1222/1175 f 1114/1161/1114 1175/1222/1175 1115/1160/1115 f 887/908/887 1124/1169/1124 1130/1176/1130 f 887/908/887 1130/1176/1130 852/873/852 f 206/186/206 852/873/852 1130/1176/1130 f 206/186/206 1130/1176/1130 532/524/532 f 681/698/681 599/592/599 1195/1242/1195 f 681/698/681 1195/1242/1195 682/699/682 f 1196/1243/1196 674/691/674 684/702/684 f 1196/1243/1196 684/702/684 1195/1242/1195 f 1197/1244/1197 675/692/675 674/691/674 f 1197/1244/1197 674/691/674 1196/1243/1196 f 689/706/689 690/708/690 675/692/675 f 689/706/689 675/692/675 1197/1244/1197 f 693/710/693 1199/1245/1199 1200/1246/1200 f 693/710/693 1200/1246/1200 1198/1247/1198 f 686/707/686 689/706/689 1197/1244/1197 f 686/707/686 1197/1244/1197 1199/1245/1199 f 1196/1243/1196 1195/1242/1195 1202/1248/1202 f 1196/1243/1196 1202/1248/1202 1201/1249/1201 f 1084/1122/1084 1083/1124/1083 1204/1250/1204 f 1084/1122/1084 1204/1250/1204 1203/1251/1203 f 1092/1131/1092 1013/1042/1013 1203/1251/1203 f 1092/1131/1092 1203/1251/1203 1204/1250/1204 f 1206/1252/1206 1087/1253/1087 1207/1254/1207 f 1206/1252/1206 1207/1254/1207 1205/1255/1205 f 1206/1252/1206 1208/1256/1208 1086/1257/1086 f 1206/1252/1206 1086/1257/1086 1087/1253/1087 f 1091/1258/1091 1090/1259/1090 1210/1260/1210 f 1091/1258/1091 1210/1260/1210 1209/1261/1209 f 1093/1132/1093 1211/1262/1211 757/774/757 f 1093/1132/1093 757/774/757 756/775/756 f 1079/1120/1079 1212/1263/1212 1090/1128/1090 f 1079/1120/1079 1090/1128/1090 1080/1118/1080 f 1079/1120/1079 979/1006/979 1088/1127/1088 f 1079/1120/1079 1088/1127/1088 1212/1263/1212 f 1209/1261/1209 1213/1264/1213 1085/1265/1085 f 1209/1261/1209 1085/1265/1085 1131/1266/1131 f 1089/1130/1089 1091/1129/1091 1131/1177/1131 f 1089/1130/1089 1131/1177/1131 1036/1070/1036 f 1213/1264/1213 1214/1267/1214 1204/1268/1204 f 1213/1264/1213 1204/1268/1204 1083/1269/1083 f 1214/1267/1214 1215/1270/1215 1092/1271/1092 f 1214/1267/1214 1092/1271/1092 1204/1268/1204 f 1015/1045/1015 757/774/757 1211/1262/1211 f 1015/1045/1015 1211/1262/1211 1216/1272/1216 f 1211/1273/1211 1093/1274/1093 1215/1270/1215 f 1211/1273/1211 1215/1270/1215 1217/1275/1217 f 1088/1276/1088 1208/1256/1208 1210/1260/1210 f 1088/1276/1088 1210/1260/1210 1212/1277/1212 f 1216/1278/1216 1211/1273/1211 1217/1275/1217 f 1216/1278/1216 1217/1275/1217 1218/1279/1218 f 1219/1280/1219 1218/1279/1218 1205/1255/1205 f 1219/1280/1219 1205/1255/1205 1207/1254/1207 f 698/715/698 697/714/697 717/734/717 f 698/715/698 717/734/717 716/737/716 f 967/992/967 418/407/418 524/516/524 f 967/992/967 524/516/524 968/993/968 f 598/590/598 720/738/720 712/733/712 f 598/590/598 712/733/712 293/276/293 f 697/714/697 721/739/721 1050/1084/1050 f 697/714/697 1050/1084/1050 717/734/717 f 957/979/957 956/978/956 1005/1035/1005 f 957/979/957 1005/1035/1005 1107/1146/1107 f 1186/1232/1186 1185/1231/1185 1189/1236/1189 f 1186/1232/1186 1189/1236/1189 1190/1237/1190 f 1022/1051/1022 896/917/896 765/782/765 f 1022/1051/1022 765/782/765 764/785/764 f 1122/1168/1122 896/917/896 1022/1051/1022 f 1122/1168/1122 1022/1051/1022 1021/1054/1021 f 678/695/678 1198/1247/1198 625/631/625 f 678/695/678 625/631/625 27/8/27 f 1195/1242/1195 599/592/599 626/632/626 f 1195/1242/1195 626/632/626 1202/1248/1202 f 1202/1248/1202 626/632/626 628/634/628 f 1202/1248/1202 628/634/628 1220/1281/1220 f 1198/1247/1198 1220/1281/1220 628/634/628 f 1198/1247/1198 628/634/628 625/631/625 f 1222/1282/1222 1223/1283/1223 1224/1284/1224 f 1222/1282/1222 1224/1284/1224 1221/1285/1221 f 1226/1286/1226 1227/1287/1227 1228/1288/1228 f 1226/1286/1226 1228/1288/1228 1225/1289/1225 f 1230/1290/1230 1231/1291/1231 1232/1292/1232 f 1230/1290/1230 1232/1292/1232 1229/1293/1229 f 1234/1294/1234 1232/1292/1232 1231/1291/1231 f 1234/1294/1234 1231/1291/1231 1233/1295/1233 f 1236/1296/1236 1237/1297/1237 1238/1298/1238 f 1236/1296/1236 1238/1298/1238 1235/1299/1235 f 1221/1285/1221 1239/1300/1239 1240/1301/1240 f 1221/1285/1221 1240/1301/1240 1233/1295/1233 f 1242/1302/1242 1243/1303/1243 1244/1304/1244 f 1242/1302/1242 1244/1304/1244 1241/1305/1241 f 1237/1297/1237 1245/1306/1245 1246/1307/1246 f 1237/1297/1237 1246/1307/1246 1238/1298/1238 f 1246/1307/1246 1245/1306/1245 1242/1302/1242 f 1246/1307/1246 1242/1302/1242 1241/1305/1241 f 1248/1308/1248 1224/1284/1224 1249/1309/1249 f 1248/1308/1248 1249/1309/1249 1247/1310/1247 f 1249/1309/1249 1250/1311/1250 660/1312/660 f 1249/1309/1249 660/1312/660 659/1313/659 f 661/1314/661 1247/1310/1247 1249/1309/1249 f 661/1314/661 1249/1309/1249 659/1313/659 f 1221/1285/1221 1224/1284/1224 1248/1308/1248 f 1221/1285/1221 1248/1308/1248 1239/1300/1239 f 1231/1291/1231 1222/1282/1222 1221/1285/1221 f 1231/1291/1231 1221/1285/1221 1233/1295/1233 f 1232/1292/1232 1234/1294/1234 1243/1303/1243 f 1232/1292/1232 1243/1303/1243 1242/1302/1242 f 1244/1304/1244 1243/1303/1243 1234/1294/1234 f 1244/1304/1244 1234/1294/1234 1251/1315/1251 f 1240/1301/1240 1251/1315/1251 1234/1294/1234 f 1240/1301/1240 1234/1294/1234 1233/1295/1233 f 1253/1316/1253 1134/1181/1134 1135/1180/1135 f 1253/1316/1253 1135/1180/1135 1252/1317/1252 f 1254/1318/1254 1255/1319/1255 1229/1293/1229 f 1254/1318/1254 1229/1293/1229 1232/1292/1232 f 1254/1318/1254 1225/1289/1225 1228/1288/1228 f 1254/1318/1254 1228/1288/1228 1255/1319/1255 f 667/1320/667 1252/1317/1252 1135/1180/1135 f 667/1320/667 1135/1180/1135 539/1183/539 f 1226/1286/1226 1225/1289/1225 1237/1297/1237 f 1226/1286/1226 1237/1297/1237 1236/1296/1236 f 1245/1306/1245 1254/1318/1254 1232/1292/1232 f 1245/1306/1245 1232/1292/1232 1242/1302/1242 f 1254/1318/1254 1245/1306/1245 1237/1297/1237 f 1254/1318/1254 1237/1297/1237 1225/1289/1225 f 669/674/669 668/675/668 1226/1286/1226 f 669/674/669 1226/1286/1226 1236/1296/1236 f 1230/1290/1230 1256/1321/1256 1222/1282/1222 f 1230/1290/1230 1222/1282/1222 1231/1291/1231 f 1235/1299/1235 671/677/671 669/674/669 f 1235/1299/1235 669/674/669 1236/1296/1236 f 1230/1290/1230 1101/1139/1101 1100/1138/1100 f 1230/1290/1230 1100/1138/1100 1256/1321/1256 f 672/678/672 488/480/488 1103/1142/1103 f 672/678/672 1103/1142/1103 1227/1287/1227 f 1224/1284/1224 1223/1283/1223 1250/1311/1250 f 1224/1284/1224 1250/1311/1250 1249/1309/1249 f 1256/1321/1256 1100/1138/1100 1134/1181/1134 f 1256/1321/1256 1134/1181/1134 1253/1316/1253 f 1227/1287/1227 1103/1142/1103 1132/1178/1132 f 1227/1287/1227 1132/1178/1132 1228/1288/1228 f 1101/1139/1101 1230/1290/1230 1229/1293/1229 f 1101/1139/1101 1229/1293/1229 1133/1179/1133 f 1223/1283/1223 1253/1316/1253 1252/1317/1252 f 1223/1283/1223 1252/1317/1252 1250/1311/1250 f 1255/1319/1255 1136/1182/1136 1133/1179/1133 f 1255/1319/1255 1133/1179/1133 1229/1293/1229 f 1228/1288/1228 1132/1178/1132 1136/1182/1136 f 1228/1288/1228 1136/1182/1136 1255/1319/1255 f 660/1312/660 1250/1311/1250 1252/1317/1252 f 660/1312/660 1252/1317/1252 667/1320/667 f 668/675/668 672/678/672 1227/1287/1227 f 668/675/668 1227/1287/1227 1226/1286/1226 f 1222/1282/1222 1256/1321/1256 1253/1316/1253 f 1222/1282/1222 1253/1316/1253 1223/1283/1223 f 1/1322/1 12/1323/12 1247/1310/1247 f 1/1322/1 1247/1310/1247 661/1314/661 f 10/1324/10 8/1325/8 1240/1301/1240 f 10/1324/10 1240/1301/1240 1239/1300/1239 f 1239/1300/1239 1248/1308/1248 11/1326/11 f 1239/1300/1239 11/1326/11 10/1324/10 f 5/1327/5 3/1328/3 1235/1299/1235 f 5/1327/5 1235/1299/1235 1238/1298/1238 f 9/1329/9 4/1330/4 1246/1307/1246 f 9/1329/9 1246/1307/1246 1241/1305/1241 f 1240/1301/1240 8/1325/8 6/1331/6 f 1240/1301/1240 6/1331/6 1251/1315/1251 f 7/1332/7 9/1329/9 1241/1305/1241 f 7/1332/7 1241/1305/1241 1244/1304/1244 f 11/1326/11 1248/1308/1248 1247/1310/1247 f 11/1326/11 1247/1310/1247 12/1323/12 f 3/1328/3 2/690/2 671/677/671 f 3/1328/3 671/677/671 1235/1299/1235 f 1238/1298/1238 1246/1307/1246 4/1330/4 f 1238/1298/1238 4/1330/4 5/1327/5 f 7/1332/7 1244/1304/1244 1251/1315/1251 f 7/1332/7 1251/1315/1251 6/1331/6 f 1203/1251/1203 1013/1042/1013 1012/1043/1012 f 1203/1251/1203 1012/1043/1012 736/757/736 f 937/959/937 941/964/941 1027/1057/1027 f 937/959/937 1027/1057/1027 999/1030/999 f 1084/1122/1084 739/756/739 1034/1067/1034 f 1084/1122/1084 1034/1067/1034 1037/1071/1037 f 1197/1244/1197 1196/1243/1196 1201/1249/1201 f 1197/1244/1197 1201/1249/1201 1199/1245/1199 f 1203/1251/1203 736/757/736 739/756/739 f 1203/1251/1203 739/756/739 1084/1122/1084 f 936/962/936 784/805/784 941/964/941 f 936/962/936 941/964/941 937/959/937 f 786/806/786 1004/1033/1004 940/963/940 f 786/806/786 940/963/940 785/804/785 f 467/1333/467 612/604/612 387/1334/387 f 612/604/612 624/630/624 387/1334/387 f 621/628/621 387/1334/387 624/630/624 f 604/595/604 44/22/44 28/5/28 f 472/605/472 612/604/612 467/1333/467 f 29/6/29 28/5/28 47/26/47 f 43/21/43 48/25/48 44/22/44 f 30/7/30 266/1335/266 27/8/27 f 424/414/424 239/223/239 425/415/425 f 467/458/467 363/347/363 472/463/472 f 561/552/561 560/553/560 572/564/572 f 549/540/549 551/542/551 579/571/579 f 583/574/583 595/588/595 582/575/582 f 31/12/31 36/13/36 600/591/600 f 39/16/39 44/22/44 603/597/603 f 32/9/32 599/592/599 45/23/45 f 473/626/473 613/607/613 471/606/471 f 477/620/477 478/625/478 620/621/620 f 474/611/474 615/610/615 617/627/617 f 1257/1336/1257 614/609/614 618/616/618 f 1257/1336/1257 620/621/620 622/624/622 f 1257/1336/1257 618/616/618 619/619/619 f 1257/1336/1257 613/607/613 615/610/615 f 614/609/614 1257/1336/1257 615/610/615 f 622/624/622 623/629/623 1257/1336/1257 f 1257/1336/1257 623/629/623 611/603/611 f 624/630/624 623/629/623 621/628/621 f 469/617/469 618/616/618 470/615/470 f 614/609/614 476/608/476 533/614/533 f 610/602/610 1257/1336/1257 611/603/611 f 613/607/613 1257/1336/1257 610/602/610 f 620/621/620 1257/1336/1257 619/619/619 f 541/532/541 592/584/592 562/555/562 f 541/532/541 587/581/587 592/584/592 f 627/633/627 607/599/607 605/596/605 f 627/633/627 605/596/605 604/595/604 f 605/596/605 606/598/606 603/597/603 f 607/599/607 606/598/606 605/596/605 f 1207/1254/1207 1082/1337/1082 1015/1338/1015 f 1219/1280/1219 1207/1254/1207 1015/1338/1015 f 1015/1338/1015 1216/1278/1216 1219/1280/1219 f 693/710/693 1198/1247/1198 678/695/678 f 1207/1254/1207 1087/1253/1087 1082/1337/1082 f 678/695/678 677/697/677 694/712/694 f 695/713/695 692/711/692 693/710/693 f 266/1335/266 679/696/679 27/8/27 f 883/903/883 1044/1079/1044 1045/1078/1045 f 992/1020/992 1082/1121/1082 1087/1125/1087 f 1158/1205/1158 1157/1204/1157 1168/1216/1168 f 1147/1194/1147 1145/1192/1145 1176/1223/1176 f 1193/1240/1193 1180/1227/1180 1179/1226/1179 f 684/702/684 682/699/682 1195/1242/1195 f 693/710/693 686/707/686 1199/1245/1199 f 599/592/599 681/698/681 45/23/45 f 1208/1256/1208 1088/1276/1088 1086/1257/1086 f 1093/1274/1093 1092/1271/1092 1215/1270/1215 f 1210/1260/1210 1090/1259/1090 1212/1277/1212 f 1209/1261/1209 1258/1339/1258 1213/1264/1213 f 1215/1270/1215 1258/1339/1258 1217/1275/1217 f 1213/1264/1213 1258/1339/1258 1214/1267/1214 f 1208/1256/1208 1258/1339/1258 1210/1260/1210 f 1258/1339/1258 1209/1261/1209 1210/1260/1210 f 1218/1279/1218 1217/1275/1217 1258/1339/1258 f 1218/1279/1218 1258/1339/1258 1205/1255/1205 f 1218/1279/1218 1219/1280/1219 1216/1278/1216 f 1213/1264/1213 1083/1269/1083 1085/1265/1085 f 1091/1258/1091 1209/1261/1209 1131/1266/1131 f 1258/1339/1258 1206/1252/1206 1205/1255/1205 f 1258/1339/1258 1208/1256/1208 1206/1252/1206 f 1258/1339/1258 1215/1270/1215 1214/1267/1214 f 1189/1236/1189 1138/1184/1138 1160/1207/1160 f 1185/1231/1185 1138/1184/1138 1189/1236/1189 f 1202/1248/1202 1220/1281/1220 1200/1246/1200 f 1200/1246/1200 1220/1281/1220 1198/1247/1198 f 1201/1249/1201 1200/1246/1200 1199/1245/1199 f 1201/1249/1201 1202/1248/1202 1200/1246/1200 # 2492 faces ================================================ FILE: graphics/tiny-renderer/lesson4.workbook/Geometry.csx ================================================ struct Vec2f { public float x; public float y; public float this [int i] { get { if (i == 0) return x; if (i == 1) return y; throw new InvalidOperationException (); } set { if (i == 0) x = value; else if (i == 1) y = value; else throw new InvalidOperationException (); } } public Vec2f Normalize () { return this / Norm (); } public float Norm () { return (float)Math.Sqrt (x * x + y * y); } public static Vec2f operator / (Vec2f v, float num) { v.x /= num; v.y /= num; return v; } public static Vec2f operator * (Vec2f v, float num) { v.x *= num; v.y *= num; return v; } public static Vec2f operator - (Vec2f a, Vec2f b) { return new Vec2f { x = a.x - b.x, y = a.y - b.y }; } public static Vec2f operator + (Vec2f a, Vec2f b) { return new Vec2f { x = a.x + b.x, y = a.y + b.y }; } } public struct Vec3f { public float x; public float y; public float z; public float this [int i] { get { switch (i) { case 0: return x; case 1: return y; case 2: return z; default: throw new InvalidOperationException (); } } set { switch (i) { case 0: x = value; break; case 1: y = value; break; case 2: z = value; break; default: throw new InvalidOperationException (); } } } public Vec3f Normalize () { return this / Norm (); } public float Norm () { return (float)Math.Sqrt (x * x + y * y + z * z); } public static Vec3f operator - (Vec3f a, Vec3f b) { return new Vec3f { x = a.x - b.x, y = a.y - b.y, z = a.z - b.z }; } public static Vec3f operator / (Vec3f v, float num) { v.x /= num; v.y /= num; v.z /= num; return v; } public static Vec3f operator * (Vec3f v, float num) { v.x *= num; v.y *= num; v.z *= num; return v; } } struct Vec4f { public float x; public float y; public float z; public float h; public float this [int i] { get { switch (i) { case 0: return x; case 1: return y; case 2: return z; case 3: return h; default: throw new InvalidOperationException (); } } set { switch (i) { case 0: x = value; break; case 1: y = value; break; case 2: z = value; break; case 3: h = value; break; default: throw new InvalidOperationException (); } } } public Vec4f Normalize () { var len = Norm (); return this / len; } public float Norm () { return (float)Math.Sqrt (x * x + y * y + z * z + h * h); } public static Vec4f operator - (Vec4f a, Vec4f b) { return new Vec4f { x = a.x - b.x, y = a.y - b.y, z = a.z - b.z, h = a.h - b.h }; } public static Vec4f operator / (Vec4f v, float num) { v.x /= num; v.y /= num; v.z /= num; v.h /= num; return v; } } struct Vec2i { public int x; public int y; public static Vec2i operator - (Vec2i a, Vec2i b) { return new Vec2i { x = a.x - b.x, y = a.y - b.y }; } } struct Vec3i { public int x; public int y; public int z; public static Vec3i operator - (Vec3i a, Vec3i b) { return new Vec3i { x = a.x - b.x, y = a.y - b.y, z = a.z - b.z }; } } static class Geometry { public static Vec3f Cross (Vec3f l, Vec3f r) { return new Vec3f { x = l.y * r.z - l.z * r.y, y = l.z * r.x - l.x * r.z, z = l.x * r.y - l.y * r.x }; } public static float Dot (Vec3f l, Vec3f r) { return l.x * r.x + l.y * r.y + l.z * r.z; } public static Vec4f Embed4D (Vec3f v, float fill = 1) { return new Vec4f { x = v.x, y = v.y, z = v.z, h = fill }; } public static Vec2f Project2D (Vec3f v) { return new Vec2f { x = v.x, y = v.y }; } public static Vec2f Project2D (Vec4f v) { return new Vec2f { x = v.x, y = v.y }; } public static Vec3f Project3D (Vec4f v) { return new Vec3f { x = v.x, y = v.y, z = v.z }; } } ================================================ FILE: graphics/tiny-renderer/lesson4.workbook/Image.csx ================================================ using System.IO; enum Format { GRAYSCALE = 1, BGR = 3, BGRA = 4 } struct Color { // the value stored as little endian: // ARGB -> BGRA // xRGB -> BGRx public readonly int value; public readonly Format format; public byte this [int offset] { get { if (offset > 3) // int has only 4 bytes (0, 1, 2, 3) throw new ArgumentOutOfRangeException (); return (byte)(value >> 8 * (3 - offset)); } } public static Color Red = new Color (red: 255, green: 0, blue: 0, alpha: 255); public static Color Green = new Color (red: 0, green: 255, blue: 0, alpha: 255); public static Color Blue = new Color (red: 0, green: 0, blue: 255, alpha: 255); public static Color Black = new Color (red: 0, green: 0, blue: 0, alpha: 255); public static Color White = new Color (red: 255, green: 255, blue: 255, alpha: 255); public static Color Yellow = new Color (red: 225, green: 225, blue: 0, alpha: 255); public Color (byte red, byte green, byte blue, byte alpha) : this ((blue << 24) | (green << 16) | (red << 8) | alpha, Format.BGRA) { } public Color (byte red, byte green, byte blue) : this ((blue << 24) | (green << 16) | (red << 8) | 0xFF, Format.BGR) { } public Color (byte value) : this (value, Format.GRAYSCALE) { } public Color (int value, Format format) { this.value = value; this.format = format; } public static Color operator * (Color color, float intensivity) { intensivity = Math.Max (0f, Math.Min (1f, intensivity)); var ch0 = (byte)(color [0] * intensivity); var ch1 = (byte)(color [1] * intensivity); var ch2 = (byte)(color [2] * intensivity); var ch3 = color [3]; return new Color (ch0 << 24 | ch1 << 16 | ch2 << 8 | ch3, color.format); } } class Image { internal byte [] buffer; public int Width { get; } public int Height { get; } public Format Format { get; } public int BytesPerRow { get { return Width * (int)Format; } } public Image (int width, int height, Format format) { Width = width; Height = height; Format = format; buffer = new byte [height * BytesPerRow]; } public void VerticalFlip () { var bpp = (int)Format; int bytesPerLine = Width * bpp; var half = Height >> 1; for (int l = 0; l < half; l++) { var l1 = l * bytesPerLine; var l2 = (Height - 1 - l) * bytesPerLine; for (int i = 0; i < bytesPerLine; i++) { byte pixel = buffer [l1 + i]; buffer [l1 + i] = buffer [l2 + i]; buffer [l2 + i] = pixel; } } } public void Clear () { for (int i = 0; i < buffer.Length; i++) buffer [i] = 0; } public Color this [int x, int y] { get { if (x < 0 || x >= Width) throw new ArgumentException ("x"); if (y < 0 || y >= Height) throw new ArgumentException ("y"); var offset = GetOffset (x, y); var len = (int)Format; int value = 0; for (var ch = 0; ch < 4; ch++) value = (value << 8) | (ch < len ? buffer [offset++] : 0xFF); return new Color (value, Format); } set { if (x < 0 || x >= Width) return; //throw new ArgumentException ($"{nameof(x)}={x} {nameof(Width)}={Width}"); if (y < 0 || y >= Height) return; // throw new ArgumentException ($"{nameof(y)}={y} {nameof(Height)}={Height}"); var offset = GetOffset (x, y); var v = value.value; var len = (int)Format; for (int ch = 0; ch < len; ch++) // 0123 buffer [offset++] = (byte)(v >> (3 - ch) * 8); // BGRA } } int GetOffset (int x, int y) { return y * BytesPerRow + x * (int)Format; } public bool WriteToFile (string path, bool rle = true) { var bpp = (int)Format; using (var writer = new BinaryWriter (File.Create (path))) { var header = new TGAHeader { IdLength = 0, // The IDLength set to 0 indicates that there is no image identification field in the TGA file ColorMapType = 0, // a value of 0 indicates that no palette is included BitsPerPixel = (byte)(bpp * 8), Width = (short)Width, Height = (short)Height, DataTypeCode = DataTypeFor (bpp, rle), ImageDescriptor = (byte)(0x20 | (Format == Format.BGRA ? 8 : 0)) // top-left origin }; WriteTo (writer, header); if (!rle) writer.Write (buffer); else UnloadRleData (writer); } return true; } public static Image Load (string path) { using (var reader = new BinaryReader (File.OpenRead (path))) { var header = ReadHeader (reader); var height = header.Height; var width = header.Width; var bytespp = header.BitsPerPixel >> 3; var format = (Format)bytespp; if (width <= 0 || height <= 0) throw new InvalidProgramException ($"bad image size: width={width} height={height}"); if (format != Format.BGR && format != Format.BGRA && format != Format.GRAYSCALE) throw new InvalidProgramException ($"unknown format {format}"); var img = new Image (width, height, format); switch (header.DataTypeCode) { case DataType.UncompressedTrueColorImage: case DataType.UncompressedBlackAndWhiteImage: reader.Read (img.buffer, 0, img.buffer.Length); break; case DataType.RleTrueColorImage: case DataType.RleBlackAndWhiteImage: img.LoadRleData (reader); break; default: throw new InvalidProgramException ($"unsupported image format {header.DataTypeCode}"); } if ((header.ImageDescriptor & 0x20) == 0) img.VerticalFlip (); return img; } } static void WriteTo (BinaryWriter writer, TGAHeader header) { writer.Write (header.IdLength); writer.Write (header.ColorMapType); writer.Write ((byte)header.DataTypeCode); writer.Write (header.ColorMapOrigin); writer.Write (header.ColorMapLength); writer.Write (header.ColorMapDepth); writer.Write (header.OriginX); writer.Write (header.OriginY); writer.Write (header.Width); writer.Write (header.Height); writer.Write (header.BitsPerPixel); writer.Write (header.ImageDescriptor); } static TGAHeader ReadHeader (BinaryReader reader) { var header = new TGAHeader { IdLength = reader.ReadByte (), ColorMapType = reader.ReadByte (), DataTypeCode = (DataType)reader.ReadByte (), ColorMapOrigin = reader.ReadInt16 (), ColorMapLength = reader.ReadInt16 (), ColorMapDepth = reader.ReadByte (), OriginX = reader.ReadInt16 (), OriginY = reader.ReadInt16 (), Width = reader.ReadInt16 (), Height = reader.ReadInt16 (), BitsPerPixel = reader.ReadByte (), ImageDescriptor = reader.ReadByte () }; return header; } bool UnloadRleData (BinaryWriter writer) { const int max_chunk_length = 128; int npixels = Width * Height; int curpix = 0; var bpp = (int)Format; while (curpix < npixels) { int chunkstart = curpix * bpp; int curbyte = curpix * bpp; int run_length = 1; bool literal = true; while (curpix + run_length < npixels && run_length < max_chunk_length && curpix + run_length < curpix + Width) { bool succ_eq = true; for (int t = 0; succ_eq && t < bpp; t++) succ_eq = (buffer [curbyte + t] == buffer [curbyte + t + bpp]); curbyte += bpp; if (1 == run_length) literal = !succ_eq; if (literal && succ_eq) { run_length--; break; } if (!literal && !succ_eq) break; run_length++; } curpix += run_length; writer.Write ((byte)(literal ? run_length - 1 : 128 + (run_length - 1))); writer.Write (buffer, chunkstart, literal ? run_length * bpp : bpp); } return true; } void LoadRleData (BinaryReader reader) { var pixelcount = Width * Height; var currentpixel = 0; var currentbyte = 0; var bytespp = (int)Format; var color = new byte [4]; do { var chunkheader = reader.ReadByte (); if (chunkheader < 128) { chunkheader++; for (int i = 0; i < chunkheader; i++) { for (int t = 0; t < bytespp; t++) buffer [currentbyte++] = reader.ReadByte (); currentpixel++; if (currentpixel > pixelcount) throw new InvalidProgramException ("Too many pixels read"); } } else { chunkheader -= 127; reader.Read (color, 0, bytespp); for (int i = 0; i < chunkheader; i++) { for (int t = 0; t < bytespp; t++) buffer [currentbyte++] = color [t]; currentpixel++; if (currentpixel > pixelcount) throw new InvalidProgramException ("Too many pixels read"); } } } while (currentpixel < pixelcount); } static DataType DataTypeFor (int bpp, bool rle) { var format = (Format)bpp; if (format == Format.GRAYSCALE) return rle ? DataType.RleBlackAndWhiteImage : DataType.UncompressedBlackAndWhiteImage; return rle ? DataType.RleTrueColorImage : DataType.UncompressedTrueColorImage; } } struct TGAHeader { public byte IdLength; public byte ColorMapType; public DataType DataTypeCode; // field #4. Color map specification public short ColorMapOrigin; // index of first color map entry that is included in the file public short ColorMapLength; // number of entries of the color map that are included in the file public byte ColorMapDepth; // number of bits per pixel // field #5. Image specification public short OriginX; // absolute coordinate of lower-left corner for displays where origin is at the lower left public short OriginY; // as for X-origin public short Width; // width in pixels public short Height; // height in pixels public byte BitsPerPixel; // pixel depth public byte ImageDescriptor; // bits 3-0 give the alpha channel depth, bits 5-4 give direction } public enum DataType : byte { NoImageData = 0, // no image data is present UncompressedColorMappedImage = 1, UncompressedTrueColorImage = 2, UncompressedBlackAndWhiteImage = 3, RleColorMappedImage = 9, // run-length encoded color-mapped image RleTrueColorImage = 10, // run-length encoded true-color image RleBlackAndWhiteImage = 11 // run-length encoded black-and-white (grayscale) image } ================================================ FILE: graphics/tiny-renderer/lesson4.workbook/ImageResultHandler.csx ================================================ using XIR = Xamarin.Interactive.Representations; InteractiveAgent.RepresentationManager.AddProvider (img => { XIR.ImageFormat format; switch (img.Format) { case Format.BGRA: format = XIR.ImageFormat.Bgra32; break; case Format.BGR: format = XIR.ImageFormat.Bgr24; break; default: return null; } return new XIR.Image (format, img.buffer, img.Width, img.Height); }); ================================================ FILE: graphics/tiny-renderer/lesson4.workbook/LICENSE.txt ================================================ Tiny Renderer, https://github.com/ssloy/tinyrenderer Copyright Dmitry V. Sokolov This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. ================================================ FILE: graphics/tiny-renderer/lesson4.workbook/Matrix.csx ================================================ using System; public struct Matrix4 { public const int Len = 4; public float R0C0, R0C1, R0C2, R0C3; public float R1C0, R1C1, R1C2, R1C3; public float R2C0, R2C1, R2C2, R2C3; public float R3C0, R3C1, R3C2, R3C3; public float this [int row, int column] { get { switch (row) { case 0: switch (column) { case 0: return R0C0; case 1: return R0C1; case 2: return R0C2; case 3: return R0C3; } break; case 1: switch (column) { case 0: return R1C0; case 1: return R1C1; case 2: return R1C2; case 3: return R1C3; } break; case 2: switch (column) { case 0: return R2C0; case 1: return R2C1; case 2: return R2C2; case 3: return R2C3; } break; case 3: switch (column) { case 0: return R3C0; case 1: return R3C1; case 2: return R3C2; case 3: return R3C3; } break; } throw new IndexOutOfRangeException (); } set { switch (row) { case 0: switch (column) { case 0: R0C0 = value; return; case 1: R0C1 = value; return; case 2: R0C2 = value; return; case 3: R0C3 = value; return; } break; case 1: switch (column) { case 0: R1C0 = value; return; case 1: R1C1 = value; return; case 2: R1C2 = value; return; case 3: R1C3 = value; return; } break; case 2: switch (column) { case 0: R2C0 = value; return; case 1: R2C1 = value; return; case 2: R2C2 = value; return; case 3: R2C3 = value; return; } break; case 3: switch (column) { case 0: R3C0 = value; return; case 1: R3C1 = value; return; case 2: R3C2 = value; return; case 3: R3C3 = value; return; } break; } throw new IndexOutOfRangeException (); } } public Matrix4 Transpose () { return new Matrix4 { R0C0 = R0C0, R0C1 = R1C0, R0C2 = R2C0, R0C3 = R3C0, R1C0 = R0C1, R1C1 = R1C1, R1C2 = R2C1, R1C3 = R3C1, R2C0 = R0C2, R2C1 = R1C2, R2C2 = R2C2, R2C3 = R3C2, R3C0 = R0C3, R3C1 = R1C3, R3C2 = R2C3, R3C3 = R3C3 }; } public static Matrix4 Identity () { return new Matrix4 { R0C0 = 1, R1C1 = 1, R2C2 = 1, R3C3 = 1 }; } public static Matrix4 Zoom (float scale) { return new Matrix4 { R0C0 = scale, R1C1 = scale, R2C2 = scale, R3C3 = scale }; } public static Matrix4 RotationZ (float angle) { var cosangle = (float)Math.Cos (angle); var sinangle = (float)Math.Sin (angle); var R = Identity (); R [0, 0] = R [1, 1] = cosangle; R [0, 1] = -sinangle; R [1, 0] = sinangle; return R; } public static Matrix4 operator * (Matrix4 l, Matrix4 r) { var result = new Matrix4 (); for (int i = 0; i < Len; i++) { for (int j = 0; j < Len; j++) { result [i, j] = 0; for (int k = 0; k < Len; k++) { result [i, j] += l [i, k] * r [k, j]; } } } return result; } public override string ToString () { var sb = new System.Text.StringBuilder (); for (int r = 0; r < Len; r++) { for (int c = 0; c < Len; c++) sb.Append (this[r, c]).Append (" "); sb.AppendLine (); } return sb.ToString (); } } public struct Matrix3 { public const int Len = 3; public float R0C0, R0C1, R0C2; public float R1C0, R1C1, R1C2; public float R2C0, R2C1, R2C2; public float this [int row, int column] { get { switch (row) { case 0: switch (column) { case 0: return R0C0; case 1: return R0C1; case 2: return R0C2; } break; case 1: switch (column) { case 0: return R1C0; case 1: return R1C1; case 2: return R1C2; } break; case 2: switch (column) { case 0: return R2C0; case 1: return R2C1; case 2: return R2C2; } break; } throw new IndexOutOfRangeException (); } set { switch (row) { case 0: switch (column) { case 0: R0C0 = value; return; case 1: R0C1 = value; return; case 2: R0C2 = value; return; } break; case 1: switch (column) { case 0: R1C0 = value; return; case 1: R1C1 = value; return; case 2: R1C2 = value; return; } break; case 2: switch (column) { case 0: R2C0 = value; return; case 1: R2C1 = value; return; case 2: R2C2 = value; return; } break; } throw new IndexOutOfRangeException (); } } public Matrix3 Transpose () { return new Matrix3 { R0C0 = R0C0, R0C1 = R1C0, R0C2 = R2C0, R1C0 = R0C1, R1C1 = R1C1, R1C2 = R2C1, R2C0 = R0C2, R2C1 = R1C2, R2C2 = R2C2 }; } public void SetColumn (int col, Vec3f v) { this [0, col] = v.x; this [1, col] = v.y; this [2, col] = v.z; } public void SetRow (int row, Vec3f v) { this [row, 0] = v.x; this [row, 1] = v.y; this [row, 2] = v.z; } public override string ToString () { var sb = new System.Text.StringBuilder (); for (int r = 0; r < Len; r++) { for (int c = 0; c < Len; c++) sb.Append (this [r, c]).Append (" "); sb.AppendLine (); } return sb.ToString (); } } public struct Matrix2 { public const int Len = 2; public float R0C0, R0C1; public float R1C0, R1C1; public float this [int row, int column] { get { switch (row) { case 0: switch (column) { case 0: return R0C0; case 1: return R0C1; } break; case 1: switch (column) { case 0: return R1C0; case 1: return R1C1; } break; } throw new IndexOutOfRangeException (); } set { switch (row) { case 0: switch (column) { case 0: R0C0 = value; return; case 1: R0C1 = value; return; } break; case 1: switch (column) { case 0: R1C0 = value; return; case 1: R1C1 = value; return; } break; } throw new IndexOutOfRangeException (); } } } // we don't want to declare them in Matrix because we don't need them in lesson which introduces Matrix class static class MatrixHelpers { // For Matrix4 // how to calc inverse Matrix https://en.wikipedia.org/w/index.php?title=Invertible_matrix§ion=4#In_relation_to_its_adjugate public static Matrix4 TransposeInverse (Matrix4 m) { // returns Transpose(Inverse(m)) // where Inverse(m) = Transpose(cofactor) / det(m) // Transpose(Inverse(m)) = Transpose(Transpose(cofactor) / det(m)) = cofactor / det(m) var cofactor = Cofactor (m); float det = 0; for (int i = 0; i < Matrix4.Len; i++) det += m [0, i] * cofactor [0, i]; for (int r = 0; r < Matrix4.Len; r++) { for (int c = 0; c < Matrix4.Len; c++) cofactor [r, c] /= det; } return cofactor; } public static Matrix4 Inverse (Matrix4 m) { // where Inverse(m) = Transpose(Cofactor(m)) / det(m) var cofactor = Cofactor (m); int len = Matrix4.Len; float det = 0; for (int i = 0; i < len; i++) det += m [0, i] * cofactor [0, i]; cofactor = cofactor.Transpose (); for (int r = 0; r < len; r++) { for (int c = 0; c < len; c++) cofactor [r, c] /= det; } return cofactor; } public static Matrix3 Inverse (Matrix3 m) { // where Inverse(m) = Transpose(Cofactor(m)) / det(m) var cofactor = Cofactor (m); int len = Matrix3.Len; float det = 0; for (int i = 0; i < len; i++) det += m [0, i] * cofactor [0, i]; cofactor = cofactor.Transpose (); for (int r = 0; r < len; r++) { for (int c = 0; c < len; c++) cofactor [r, c] /= det; } return cofactor; } static Matrix4 Cofactor (Matrix4 m) { var r = new Matrix4 (); for (int row = 0; row < Matrix4.Len; row++) { for (int col = 0; col < Matrix4.Len; col++) r [row, col] = Cofactor (m, row, col); } return r; } static Matrix3 Cofactor (Matrix3 m) { var r = new Matrix3 (); for (int row = 0; row < Matrix3.Len; row++) { for (int col = 0; col < Matrix3.Len; col++) r [row, col] = Cofactor (m, row, col); } return r; } static float Cofactor (Matrix4 m, int row, int col) { int sign = ((row + col) % 2 == 0) ? 1 : -1; return Det (Minor (m, row, col)) * sign; } static float Cofactor (Matrix3 m, int row, int col) { int sign = ((row + col) % 2 == 0) ? 1 : -1; return Det (Minor (m, row, col)) * sign; } static Matrix3 Minor (Matrix4 m, int row, int col) { var minor = new Matrix3 (); for (int r = 0; r < Matrix3.Len; r++) { for (int c = 0; c < Matrix3.Len; c++) { int y = (r < row) ? r : r + 1; int x = (c < col) ? c : c + 1; minor [r, c] = m [y, x]; } } return minor; } static Matrix2 Minor (Matrix3 m, int row, int col) { var minor = new Matrix2 (); for (int r = 0; r < Matrix2.Len; r++) { for (int c = 0; c < Matrix2.Len; c++) { int y = (r < row) ? r : r + 1; int x = (c < col) ? c : c + 1; minor [r, c] = m [y, x]; } } return minor; } static float Det (Matrix3 m) { float det = 0; det += m [0, 0] * (m [1, 1] * m [2, 2] - m [1, 2] * m [2, 1]); det -= m [0, 1] * (m [1, 0] * m [2, 2] - m [1, 2] * m [2, 0]); det += m [0, 2] * (m [1, 0] * m [2, 1] - m [1, 1] * m [2, 0]); return det; } static float Det (Matrix2 m) { return m [0, 0] * m [1, 1] - m [0, 1] * m [1, 0]; } public static Vec3f Mult (Matrix3 m, Vec3f v) { return new Vec3f { x = m.R0C0 * v.x + m.R0C1 * v.y + m.R0C2 * v.z, y = m.R1C0 * v.x + m.R1C1 * v.y + m.R1C2 * v.z, z = m.R2C0 * v.x + m.R2C1 * v.y + m.R2C2 * v.z }; } public static Vec4f Mult (Matrix4 m, Vec4f v) { return new Vec4f { x = m.R0C0*v.x + m.R0C1*v.y + m.R0C2*v.z + m.R0C3*v.h, y = m.R1C0*v.x + m.R1C1*v.y + m.R1C2*v.z + m.R1C3*v.h, z = m.R2C0*v.x + m.R2C1*v.y + m.R2C2*v.z + m.R2C3*v.h, h = m.R3C0*v.x + m.R3C1*v.y + m.R3C2*v.z + m.R3C3*v.h }; } } ================================================ FILE: graphics/tiny-renderer/lesson4.workbook/Model.csx ================================================ using System.Collections.Generic; using System.Linq; struct Face { public int [] Vertices; public int [] Textures; public int [] Normals; } class Model { public List Vertices { get; } = new List (); public List Faces { get; } = new List (); public List Textures { get; } = new List (); public List Normals { get; } = new List (); public static Model FromFile (string path) { var model = new Model (); string line; using (var reader = new System.IO.StreamReader (path)) { while ((line = reader.ReadLine ()) != null) model.ParseLine (line); } Console.WriteLine ($"v#{model.Vertices.Count} f#{model.Faces.Count}"); return model; } public static Model FromText (string text) { var model = new Model (); var lines = text.Split (new char [] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); foreach (var line in lines) model.ParseLine (line); Console.WriteLine ($"v#{model.Vertices.Count} f#{model.Faces.Count}"); return model; } void ParseLine (string line) { Func parseV3f = strItems => new Vec3f { x = float.Parse (strItems [1]), y = float.Parse (strItems [2]), z = float.Parse (strItems [3]) }; var items = line.Split (new char [] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (line.StartsWith ("v ", StringComparison.InvariantCulture)) { Vertices.Add (parseV3f (items)); } else if (line.StartsWith ("vt ", StringComparison.InvariantCulture)) { Textures.Add (parseV3f (items)); } else if (line.StartsWith ("vn ", StringComparison.InvariantCulture)) { Normals.Add (parseV3f (items)); } else if (line.StartsWith ("f ", StringComparison.InvariantCulture)) { var indexes = items.Skip (1) .SelectMany (s => s.Split (new char [] { '/', ' ' }, StringSplitOptions.RemoveEmptyEntries)) .Select (s => int.Parse (s) - 1) // in wavefront obj all indices start at 1, not zero .ToArray (); Faces.Add (new Face { Vertices = indexes.Where ((v, index) => index % 3 == 0).ToArray (), Textures = indexes.Where ((v, index) => index % 3 == 1).ToArray (), Normals = indexes.Where ((v, index) => index % 3 == 2).ToArray () }); } } public Vec3f Normal (Face face, int nthvert) { int idx = face.Normals [nthvert]; return Normals [idx]; } public Vec3f Vertex (Face face, int nthvert) { int idx = face.Vertices [nthvert]; return Vertices [idx]; } public Vec3f GetUV (Face face, int nthvert) { int idx = face.Textures [nthvert]; return Textures [idx]; } } ================================================ FILE: graphics/tiny-renderer/lesson4.workbook/WpfImageResultHandler.csx ================================================ using System; using System.IO; using System.Windows.Media; using System.Windows.Media.Imaging; using XIR = Xamarin.Interactive.Representations; static PixelFormat ConvertFormat (Format format) { switch (format) { case Format.BGRA: return PixelFormats.Bgra32; case Format.GRAYSCALE: return PixelFormats.Gray8; case Format.BGR: default: return PixelFormats.Bgr24; } } InteractiveAgent.RepresentationManager.AddProvider (img => { var source = BitmapSource.Create (img.Width, img.Height, 96, 96, ConvertFormat (img.Format), null, img.buffer, img.BytesPerRow); var encoder = new PngBitmapEncoder (); var outputFrame = BitmapFrame.Create (source); encoder.Frames.Add (outputFrame); using (var memory = new MemoryStream ()) { encoder.Save (memory); return XIR.Image.FromPng (memory.GetBuffer (), img.Width, img.Height); } }); ================================================ FILE: graphics/tiny-renderer/lesson4.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Matrix.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" #load "lesson1.csx" #load "lesson2.csx" #load "lesson3.csx" using static Geometry; using static MatrixHelpers; ``` # **Lesson 4: Perspective projection** > ℹ️ This workbook is a port of an [excellent C++ series](https://github.com/ssloy/tinyrenderer/wiki) written by Dmitry Sokolov. We appreciate that original work is available under a license that allowed us to turn it into a Workbook. # The goal In previous lessons we rendered our model in orthographic projection by simply forgetting the z-coordinate. The goal for today is to learn how to draw in perspective: ![ ](./img/lesson4_the_goal.png) # 2D geometry: Linear transformations A linear transformation on a plane can be represented by a corresponding matrix. If we take a point `(x,y)` then its transformation can be written as follows: ![ ](./img/lesson4_formula1.svg) The simplest (not degenerate) transformation is the identity, it does not move any point: ![ ](./img/lesson4_formula_2d_identity.svg) Diagonal coefficients of the matrix give scaling along coordinate axes. Let us illustrate it, if we take the following transformation: ![ ](./img/lesson4_formula_2d_scale.svg) Then the white object (the white square with one corner chopped) will be transformed into the yellow one. Red and green line segments give unit length vectors aligned with `x` and `y`, respectively. All the images for this article were generated using this code: ```csharp Matrix4 Viewport (int x, int y, int w, int h) { var depth = 255f; var m = Matrix4.Identity (); m [0, 3] = x + w / 2f; m [1, 3] = y + h / 2f; m [2, 3] = depth / 2f; m [0, 0] = w / 2f; m [1, 1] = h / 2f; m [2, 2] = depth / 2f; return m; } Matrix4 Projection (float coeff) { var projection = Matrix4.Identity (); projection [3, 2] = coeff; return projection; } Vec4f Embed4D (Vec3f v, float fill = 1) { return new Vec4f { x = v.x, y = v.y, z = v.z, h = fill }; } Vec3f Project3D (Vec4f v) { return new Vec3f { x = v.x, y = v.y, z = v.z }; } Func map = v => Project3D(v/v.h); void RenderAxes (Image image) { var w = image.Width; var h = image.Height; var vp = Viewport(w/4, w/4, w/2, h/2); // draw the axes var x = new Vec3f { x = 1 }; var y = new Vec3f { y = 1 }; var o = new Vec3f (); o = map(Mult(vp, Embed4D(o))); x = map(Mult(vp, Embed4D(x))); y = map(Mult(vp, Embed4D(y))); Line(image, o, x, Color.Red); Line(image, o, y, Color.Green); } var cube = Model.FromFile("obj/cube.obj"); void RenderCube(Image image, Matrix4 deformation, Color color) { var w = image.Width; var h = image.Height; var vp = Viewport(w/4, w/4, w/2, h/2); var face = cube.Faces[0]; var faceLen = face.Vertices.Length; for(int j=0; j x/(c-z) = x'/c. In other words: ![ ](./img/lesson4_formula_x.svg) By doing the same reasoning for triangles CPB and CP'D, it is easy to find the following expression: ![](./img/lesson4_formula_y.svg) It is really similar to the result we put aside few moments ago, but there we got the result by a single matrix multiplication. We got the law for the coefficient: `r = -1/c` # Let us sum up: the main formula for today *If you simply copy-paste this formula without understanding the above material, I hate you.* So, if we want to compute a central projection with a camera **(important!) camera located on the z-axis with distance c from the origin**, then we embed the point into 4D by augmenting it with 1, then we multiply it with the following matrix, and retro-project it into 3D. ![ ](./img/lesson4_formula_last.svg) We deformed our object in a way, that simply forgetting its z-coordinate we will get a drawing in a perspective. If we want to use the z-buffer, then, naturally, do not forget the z: ```csharp var image = new Image(width, height, Format.BGR); var camera = new Vec3f { z = 3 }; var projection = Projection(-1/camera.z); var viewPort = Viewport(width/8, height/8, width*3/4, height*3/4); Func map = v => { var r4 = Mult (viewPort * projection, Embed4D (v)); var r = Project3D (r4 / r4.h); r.x = (int)(r.x + 0.5f); r.y = (int)(r.y + 0.5f); return r; }; Func uvMap = (texture, v) => new Vec2f { x = v.x * (texture.Width - 1), y = v.y * (texture.Height - 1) }; var model = headModel; var zbuffer = InitZBuffer(image); Vec2f[] uv = new Vec2f [3]; foreach(var face in model.Faces) { for(int i=0; i<3; i++) { var vIndex = face.Vertices[i]; world[i] = model.Vertices[vIndex]; screen[i] = map(world[i]); var tIndex = face.Textures[i]; uv[i] = uvMap(headTexture, model.Textures[tIndex]); } Vec3f n = Cross(world[2] - world[0], world[1] - world[0]).Normalize (); var intensivity = Dot(n, light_dir); if(intensivity > 0) Triangle(image, screen, headTexture, uv, intensivity, zbuffer); } image.VerticalFlip (); image ``` ================================================ FILE: graphics/tiny-renderer/lesson4.workbook/lesson1.csx ================================================ int width = 800; int height = 800; var headModel = Model.FromFile ("obj/african_head.obj"); static void Swap(ref T x, ref T y) { T t = y; y = x; x = t; } static void Swap(T[] arr, int x, int y) { T t = arr[y]; arr[y] = arr[x]; arr[x] = t; } Image Line (Image image, int x0, int y0, int x1, int y1, Color color) { bool steep = false; // if the line is steep, we transpose the image if (Math.Abs (x0-x1) < Math.Abs (y0-y1)) { Swap (ref x0, ref y0); Swap (ref x1, ref y1); steep = true; } if (x0 > x1) { // make it left to right Swap (ref x0, ref x1); Swap (ref y0, ref y1); } // (x0, y0) == (x1, y1) if(x0 == x1) { image [x0, y0] = color; } else { for (int x = x0; x <= x1; x++) { double t = (x-x0) / (double)(x1-x0); int y = (int)Math.Round(y0*(1-t) + y1*t); if (steep) image [y, x] = color; else image [x, y] = color; } } return image; } ================================================ FILE: graphics/tiny-renderer/lesson4.workbook/lesson1.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" ``` # **Lesson 1: Bresenham’s Line Drawing Algorithm** # First attempt The goal of the first lesson is to render the wire mesh. To do this, we should learn how to draw line segments. We can simply read what Bresenham’s line algorithm is, but let’s write code ourselves. How does the simplest code that draws a line segment between `(x0, y0)` and `(x1, y1)` points look like? Apparently, something like this: ```csharp Image Line (Image image, int x0, int y0, int x1, int y1, Color color) { for (double t = 0; t < 1; t += 0.01) { int x = (int) (x0 * (1-t) + x1 * t); int y = (int) (y0 * (1-t) + y1 * t); image [x, y] = color; } return image; } Line (new Image (100, 100, Format.BGR), x0: 13, y0: 20, x1: 80, y1: 40, color: Color.White); ``` # Second attempt The problem with this code (in addition to efficiency) is the choice of the constant, which I took equal to .01. If we take it equal to .1, our line segment will look like this: ```csharp Image Line (Image image, int x0, int y0, int x1, int y1, Color color) { for (int x = x0; x <= x1; x++) { double t = (x-x0)/(double)(x1-x0); int y = (int)(y0*(1-t) + y1*t); image [x, y] = color; } return image; } Line (new Image (100, 100, Format.BGR), x0: 13, y0: 20, x1: 80, y1: 40, color: Color.White); ``` Caution! The first source of errors in such code of my students is the integer division, like: `(x-x0)/(x1-x0)`. Then, if we try to draw the following lines with this code: ```csharp var image = new Image (100, 100, Format.BGR); Line(image, x0: 13, y0: 20, x1: 80, y1: 40, color: Color.White); Line(image, x0: 20, y0: 13, x1: 40, y1: 80, color: Color.Red); Line(image, x0: 80, y0: 40, x1: 13, y1: 20, color: Color.Red); ``` It turns out that one line is good, the second one is with holes, and there’s no third line at all. Note that the first and the third lines (in the code) draw the same line in different colors, and in different directions (with the source and target points flipped). We have already seen the white one, it is drawn well. I was hoping to change the color of the white line to red, but could not do it. It’s a test for symmetry: the result of drawing a line segment should not depend on the order of points: the `(a,b)` line segment should be exactly the same as the `(b,a)` line segment. # Third attempt We fix the missing red line by swapping the points so `x0` is always lower than `x1`. There are holes in one of the line segments due to the fact that its height is greater than the width. My students often suggest the following fix: `if (dx > dy) { for (int x) } else { for (int y) }` Holy cow! ```csharp static void Swap(ref T x, ref T y) { T t = y; y = x; x = t; } static void Swap(T[] arr, int x, int y) { T t = arr[y]; arr[y] = arr[x]; arr[x] = t; } Image Line (Image image, int x0, int y0, int x1, int y1, Color color) { bool steep = false; // if the line is steep, we transpose the image if (Math.Abs (x0-x1) < Math.Abs (y0-y1)) { Swap (ref x0, ref y0); Swap (ref x1, ref y1); steep = true; } if (x0 > x1) { // make it left to right Swap (ref x0, ref x1); Swap (ref y0, ref y1); } // (x0, y0) == (x1, y1) if(x0 == x1) { image [x0, y0] = color; } else { for (int x = x0; x <= x1; x++) { double t = (x-x0) / (double)(x1-x0); int y = (int)Math.Round(y0*(1-t) + y1*t); if (steep) image [y, x] = color; else image [x, y] = color; } } return image; } Line(image, x0: 13, y0: 20, x1: 80, y1: 40, color: Color.White); Line(image, x0: 20, y0: 13, x1: 40, y1: 80, color: Color.Red); Line(image, x0: 80, y0: 40, x1: 13, y1: 20, color: Color.Red); ``` # Wireframe rendering So now we are ready to create a wire render. You can find the snapshot of the code and the test model here. I used the [wavefront obj](http://en.wikipedia.org/wiki/Wavefront_.obj_file) format of the file to store model. All we need for the render is read from the file the array of vertices of the following type: `v 0.608654 -0.568839 -0.416318` are `x,y,z` coordinates, one vertex per file line and faces `f 1193/1240/1193 1180/1227/1180 1179/1226/1179` ```csharp int width = 800, height = 800; var headModel = Model.FromFile ("obj/african_head.obj"); var image = new Image(width, height, Format.BGR); foreach(var face in headModel.Faces) { for(int j=0; j<3; j++) { var v0 = headModel.Vertices[face.Vertices [j]]; var v1 = headModel.Vertices[face.Vertices [(j+1) % 3]]; // scale x from [-1..1] to [0..w] // scale y from [-1..1] to [0..h] int x0 = (int)((v0.x + 1) * width / 2); int y0 = (int)((v0.y + 1) * height / 2); int x1 = (int)((v1.x + 1) * width / 2); int y1 = (int)((v1.y + 1) * height / 2); Line(image, x0, y0, x1, y1, Color.White); } } image.VerticalFlip (); image ``` ================================================ FILE: graphics/tiny-renderer/lesson4.workbook/lesson2.csx ================================================ using static Geometry; var light_dir = new Vec3f { x = 0, y = 0, z = -1 }; var world = new Vec3f [3]; var screen = new Vec3f [3]; void Line (Image image, Vec2i p1, Vec2i p2, Color color) { Line(image, p1.x, p1.y, p2.x, p2.y, color); } void Line (Image image, Vec3f p1, Vec3f p2, Color color) { Line(image, (int)p1.x, (int)p1.y, (int)p2.x, (int)p2.y, color); } void Triangle (Image image, Vec2i[] t, Color color) { Line(image, t[0], t[1], color); Line(image, t[1], t[2], color); Line(image, t[2], t[0], color); } Vec3f Barycentric (Vec3f a, Vec3f b, Vec3f c, Vec2i p) { var pixel = new Vec3f { x = p.x + 0.5f, y = p.y + 0.5f }; var ab = b - a; var ac = c - a; var pa = a - pixel; var r = Cross (new Vec3f { x = ab.x, y = ac.x, z = pa.x }, new Vec3f { x = ab.y, y = ac.y, z = pa.y }); // triangle is degenerate, in this case return smth with negative coordinates if (Math.Abs (r.z) < 1) return new Vec3f { x = -1, y = 1, z = 1 }; return new Vec3f { x = 1 - r.x / r.z - r.y / r.z, y = r.x / r.z, z = r.y / r.z }; } void Triangle (Image image, Vec3f [] coordinates, Color color) { var t0 = coordinates [0]; var t1 = coordinates [1]; var t2 = coordinates [2]; var pMax = new Vec2i { x = (int)Math.Max (0, Math.Max (t0.x, Math.Max (t1.x, t2.x))), y = (int)Math.Max (0, Math.Max (t0.y, Math.Max (t1.y, t2.y))) }; var pMin = new Vec2i { x = (int)Math.Min (image.Width, Math.Min (t0.x, Math.Min (t1.x, t2.x))), y = (int)Math.Min (image.Height, Math.Min (t0.y, Math.Min (t1.y, t2.y))) }; Vec2i p; for (p.x = pMin.x; p.x <= pMax.x; p.x++) { for (p.y = pMin.y; p.y <= pMax.y; p.y++) { var bc = Barycentric (t0, t1, t2, p); if (bc.x < 0 || bc.y < 0 || bc.z < 0) continue; image [p.x, p.y] = color; } } } ================================================ FILE: graphics/tiny-renderer/lesson4.workbook/lesson2.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" #load "lesson1.csx" using static Geometry; ``` # Lesson 2: Triangle rasterization and back face culling # Old-school method: Line sweeping Thus, the task is to draw two-dimensional triangles. For motivated students it normally takes a couple of hours, even if they are bad programmers. Last time we saw Bresenham’s line drawing algorithm. Today’s task is to draw a filled triangle. Funny enough, but this task is not trivial. I don’t know why, but I know that it’s true. Most of my students struggle with this simple task. So, the initial stub will look like this: ```csharp void Line (Image image, Vec2i p1, Vec2i p2, Color color) { Line(image, p1.x, p1.y, p2.x, p2.y, color); } void Line (Image image, Vec3f p1, Vec3f p2, Color color) { Line(image, (int)p1.x, (int)p1.y, (int)p2.x, (int)p2.y, color); } void Triangle (Image image, Vec2i[] t, Color color) { Line(image, t[0], t[1], color); Line(image, t[1], t[2], color); Line(image, t[2], t[0], color); } Vec2i[] t0 = { new Vec2i { x = 10, y = 70 }, new Vec2i { x = 50, y = 160 }, new Vec2i { x = 70, y = 80 } }; Vec2i[] t1 = { new Vec2i { x = 180, y = 50 }, new Vec2i { x = 150, y = 1 }, new Vec2i { x = 70, y = 180 } }; Vec2i[] t2 = { new Vec2i { x = 180, y = 150 }, new Vec2i { x = 120, y = 160 }, new Vec2i { x = 130, y = 180 } }; var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); image.VerticalFlip (); image ``` The code is simple: I provide three triangles for the initial debugging of your code. If we invoke `Line` inside the triangle function, we’ll get the contour of the triangle. How to draw a filled triangle? A good method of drawing a triangle must have the following features: * It should be (surprise!) simple and fast. * It should be symmetrical: the picture should not depend on the order of vertices passed to the drawing function. * If two triangles have two common vertices, there should be no holes between them because of rasterization rounding. We could add more requirements, but let’s do with these ones. Traditionally a line sweeping is used: 1. Sort vertices of the triangle by their y-coordinates 2. Rasterize simultaneously the left and the right sides of the triangle 3. Draw a horizontal line segment between the left and the right boundary points At this point my students start to lose the firm ground: which segment is the left one, which one is right? Besides, there are three segments in a triangle... Usually, after this introduction I leave my students for about an hour: once again, reading my code is much less valuable than comparing your own code with mine. `[One hour passes]` How do I draw a triangle? Once again, if you have a better method, I’d be glad to adopt it. Let us assume that we have three points of the triangle: `t0`, `t1`, `t2`, they are sorted in ascending order by the y-coordinate. Then, the boundary A is between `t0` and `t2`, boundary B is between `t0` and `t1`, and then between `t1` and `t2`. ```csharp void OrderByY (Vec2i[] t) { if(t[0].y > t[1].y) Swap(t, 0, 1); if(t[1].y > t[2].y) Swap(t, 1, 2); if(t[0].y > t[1].y) Swap(t, 0, 1); } void Triangle (Image image, Vec2i[] t, Color color) { OrderByY(t); Line(image, t[0], t[1], Color.Green); Line(image, t[1], t[2], Color.Green); Line(image, t[2], t[0], Color.Red); } var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); // Here boundary A is red, and boundary B is green. image.VerticalFlip (); image ``` Unfortunately, boundary B is made of two parts. Let us draw the bottom half of the triangle by cutting it horizontally: ```csharp void Triangle (Image image, Vec2i[] t, Color color) { OrderByY(t); float height_10 = t[1].y - t[0].y; float height_20 = t[2].y - t[0].y; for(int y=t[0].y; y<=t[1].y; y++) { var alpha = (y-t[0].y) / height_20; var beta = (y-t[0].y) / height_10; // be careful with divisions by zero Vec2i A = new Vec2i { x = t[0].x + (int)((t[2].x-t[0].x)*alpha), y = y}; Vec2i B = new Vec2i { x = t[0].x + (int)((t[1].x-t[0].x)*beta), y = y}; image[A.x, y] = Color.Red; image[B.x, y] = Color.Green; } } var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); image.VerticalFlip (); image ``` Note that the segments are not continuous. Last time when we drew straight lines we struggled to get continuous segments and here I did not bother with rotating the image (remember the xy swapping?). Why? We fill the triangles aftewards, that’s why. If we connect the corresponding pairs of points by horizontal lines, the gaps disappear: ```csharp void Triangle (Image image, Vec2i[] t, Color color) { OrderByY(t); float height_10 = t[1].y - t[0].y; float height_20 = t[2].y - t[0].y; for(int y=t[0].y; y<=t[1].y; y++) { var alpha = (y-t[0].y) / height_20; var beta = (y-t[0].y) / height_10; // be careful with divisions by zero Vec2i A = new Vec2i { x = t[0].x + (int)((t[2].x-t[0].x)*alpha), y = y}; Vec2i B = new Vec2i { x = t[0].x + (int)((t[1].x-t[0].x)*beta), y = y}; Line(image, A, B, Color.White); image[B.x, y] = Color.Green; image[A.x, y] = Color.Red; } } var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); image.VerticalFlip (); image ``` Now, let us draw the second (upper) half of the triangle. We can do this by adding a second loop: ```csharp void Triangle (Image image, Vec2i[] t, Color color) { OrderByY(t); float height_10 = t[1].y - t[0].y; float height_20 = t[2].y - t[0].y; for(int y=t[0].y; y<=t[1].y; y++) { var alpha = (y-t[0].y) / height_20; var beta = (y-t[0].y) / height_10; // be careful with divisions by zero Vec2i A = new Vec2i { x = t[0].x + (int)((t[2].x-t[0].x)*alpha), y = y}; Vec2i B = new Vec2i { x = t[0].x + (int)((t[1].x-t[0].x)*beta), y = y}; if(A.x > B.x) Swap(ref A, ref B); for (int j=A.x; j<=B.x; j++) image[j, y] = color; } float height_21 = t[2].y - t[1].y; for(int y=t[1].y; y<=t[2].y; y++) { var alpha = (y-t[0].y) / height_20; var beta = (y-t[1].y) / height_21; // be careful with divisions by zero Vec2i A = new Vec2i { x = t[0].x + (int)((t[2].x-t[0].x)*alpha), y = y}; Vec2i B = new Vec2i { x = t[1].x + (int)((t[2].x-t[1].x)*beta), y = y}; if(A.x > B.x) Swap(ref A, ref B); for (int j=A.x; j<=B.x; j++) image[j, y] = color; } } var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); image.VerticalFlip (); image ``` This could be enough, but I dislike to see the same code twice. That is why we will make it a bit less readable, but more handy for modifications/maintaining: ```csharp void Triangle (Image image, Vec2i[] t, Color color) { // I dont care about degenerate triangles if(t[0].y == t[1].y && t[1].y == t[2].y) return; OrderByY(t); float height_10 = t[1].y - t[0].y; float total_height = t[2].y - t[0].y; for(int i=0; i t[1].y - t[0].y || t[1].y == t[0].y; float segment_height = second_half ? t[2].y-t[1].y : t[1].y-t[0].y; var alpha = i / total_height; // be careful with divisions by zero var beta = (i - (second_half ? t[1].y-t[0].y : 0)) / segment_height; Vec2i A = new Vec2i { x = t[0].x + (int)((t[2].x-t[0].x)*alpha), y = t[0].y + i }; Vec2i B = new Vec2i { x = second_half ? t[1].x + (int)((t[2].x-t[1].x)*beta) : t[0].x + (int)((t[1].x-t[0].x)*beta), y = t[0].y + i }; if(A.x > B.x) Swap(ref A, ref B); for (int j=A.x; j<=B.x; j++) image[j, t[0].y + i] = color; } } var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); image.VerticalFlip (); image ``` # The method I adopt for my code While not being really complicated, the source code for the line sweeping is a bit messy. Moreover, it is really an old-school approach designed for mono-thread CPU programming. Let us take a look at the following pseudo-code: ```csharp // triangle(Vec2i[] points) { // Vec2i bbox[2] = find_bounding_box(points); // for (each pixel in the bounding box) { // if (inside(points, pixel)) { // put_pixel(pixel); // } // } // } ``` Do you like it? I do. It is really easy to find a bounding box. It is certainly no problem to check whether a point belongs a 2D triangle (or any convex polygon). *Off Topic: if I have to implement some code to check whether a point belongs to a polygon, and this program will run on a plane, I will never get on this plane. Turns out, it is a surprisingly difficult task to solve this problem reliably. But here we just painting pixels. I am okay with that.* There is another thing I like about this pseudocode: a neophyte in programming accepts it with enthusiasm, more experienced programmers often chuckle: “*What an idiot wrote it?*”. And an expert in computer graphics programming will shrug his shoulders and say: “*Well, that’s how it works in real life*”. Massively parallel computations in thousands of threads (i’m talking about regular consumer computers here) change the way of thinking. Okay, let us start: first of all we need to know what the [barycentric coordinates](https://en.wikipedia.org/wiki/Barycentric_coordinate_system) are. Given a 2D triangle ABC and a point P, all in old good Cartesian coordinates `(xy)`. Our goal is to find barycentric coordinates of the point P with respect to the triangle ABC. It means that we look for three numbers `(1 − u − v,u,v)` such that we can find the point P as follows: ![ ](./img/lesson2_f1.png) While being a bit frightening at the first glance, it is really simple: imagine that we put three weights `(1−u−v,u,v)` at the vertices A, B and C, respectively. Then the barycenter of the system is exactly in the point P. We can say the same thing with other words: the point P has coordinates `(u,v)` in the (oblique) basis (A,![](./img/lesson2_ab.png),![](./img/lesson2_ac.png)): ![ ](./img/lesson2_f2.png) So, we have vectors ![](./img/lesson2_ab.png), ![](./img/lesson2_ac.png) and ![](./img/lesson2_ap.png), we need to find two real numbers u and v respecting the following constraint: ![ ](./img/lesson2_f3.png) It is a simple vector equation, or a linear system of two equations with two variables: ![ ](./img/lesson2_f4.png) I am lazy and do not want to solve linear systems in a scholar way. Let us write it in matrix form: ![ ](./img/lesson2_f5.png) It means that we are looking for a vector `(u,v,1)` that is orthogonal to `(ABx,ACx,PAx)` and `(ABy,ACy,PAy)` *at the same time*! I hope you see [where I am heading](https://en.wikipedia.org/wiki/Cross_product). That is a small hint: to find an intersection of two straight lines in a plane (that is exactly what we did here), it is sufficient to compute one cross product. By the way, test yourself: how do we find an equation of a line passing through two given points? So, let us program our new rasterization routine: we iterate through all pixels of a bounding box for a given triangle. For each pixel we compute its barycentric coordinates. If it has at least one negative component, then the pixel is outside of the triangle. Probably it is more clear to see the program directly: ```csharp Vec3f Barycentric (Vec3f a, Vec3f b, Vec3f c, Vec2i p) { var pixel = new Vec3f { x = p.x + 0.5f, y = p.y + 0.5f }; var ab = b - a; var ac = c - a; var pa = a - pixel; var r = Cross (new Vec3f { x = ab.x, y = ac.x, z = pa.x }, new Vec3f { x = ab.y, y = ac.y, z = pa.y }); // triangle is degenerate, in this case return smth with negative coordinates if (Math.Abs (r.z) < 1) return new Vec3f { x = -1, y = 1, z = 1 }; return new Vec3f { x = 1 - r.x / r.z - r.y / r.z, y = r.x / r.z, z = r.y / r.z }; } void Triangle (Image image, Vec3f [] coordinates, Color color) { var t0 = coordinates [0]; var t1 = coordinates [1]; var t2 = coordinates [2]; var pMax = new Vec2i { x = (int)Math.Max (0, Math.Max (t0.x, Math.Max (t1.x, t2.x))), y = (int)Math.Max (0, Math.Max (t0.y, Math.Max (t1.y, t2.y))) }; var pMin = new Vec2i { x = (int)Math.Min (image.Width, Math.Min (t0.x, Math.Min (t1.x, t2.x))), y = (int)Math.Min (image.Height, Math.Min (t0.y, Math.Min (t1.y, t2.y))) }; Vec2i p; for (p.x = pMin.x; p.x <= pMax.x; p.x++) { for (p.y = pMin.y; p.y <= pMax.y; p.y++) { var bc = Barycentric (t0, t1, t2, p); if (bc.x < 0 || bc.y < 0 || bc.z < 0) continue; image [p.x, p.y] = color; } } } ``` # Flat shading render We already know how to draw a model with empty triangles. Let us fill them with a random color. This will help us to see how well we have encoded filling of triangles. Here is the code: ```csharp var image = new Image(width, height, Format.BGR); // Map world coordinates [-1..-1] to screen coordinates [0..width] Func map = v => new Vec3f { x = (int)((v.x+1)*image.Width/2), y = (int)((v.y+1)*image.Height/2) }; var rnd = new Random(); Func rndByte = () => (byte)rnd.Next(255); Func rndColor = () => new Color(rndByte(), rndByte(), rndByte()); var coordinates = new Vec3f[3]; foreach(var face in headModel.Faces) { for(int i=0; i<3; i++) { var vIndex = face.Vertices[i]; var v = headModel.Vertices[vIndex]; coordinates[i] = map(v); } Triangle(image, coordinates, rndColor()); } image.VerticalFlip (); image ``` Let us get rid of these clown-colors and put some lighting. Captain Obvious: ”*At the same light intensity, the polygon is illuminated most brightly when it is orthogonal to the light direction.*” Let us compare: ![ ](./img/lesson2_light1.jpeg) ![](./img/lesson2_light2.jpeg) We get zero illumination if the polygon is parallel to the vector of light. To paraphrase: the intensity of illumination is equal to the scalar product of the light vector and the normal to the given triangle. The normal to the triangle can be calculated simply as the [cross product](https://en.wikipedia.org/wiki/Cross_product) of its two sides. As a side note, at this course we will perform linear computations on the colors. However `(128,128,128)` color is not half as bright as `(255, 255, 255)`. We are going to ignore gamma correction and tolerate the incorrectness of the brightness of our colors. ```csharp var image = new Image (width, height, Format.BGR); var light_dir = new Vec3f { x = 0, y = 0, z = -1 }; var world = new Vec3f [3]; var screen = new Vec3f [3]; foreach (var face in headModel.Faces) { for (int i = 0; i < 3; i++) { var vIndex = face.Vertices [i]; world [i] = headModel.Vertices [vIndex]; screen [i] = map (world [i]); } var n = Cross (world [2] - world [0], world [1] - world [0]).Normalize (); var intensivity = Dot (n, light_dir); if (intensivity > 0) Triangle (image, screen, Color.White * intensivity); } image.VerticalFlip (); image ``` ================================================ FILE: graphics/tiny-renderer/lesson4.workbook/lesson3.csx ================================================ using static Geometry; var headTexture = Image.Load ("obj/african_head_diffuse.tga"); headTexture.VerticalFlip (); float [] InitZBuffer (Image image) { var zbuffer = new float [image.Width * image.Height]; for (int idx = 0; idx < zbuffer.Length; idx++) zbuffer [idx] = float.NegativeInfinity; return zbuffer; } Vec3f Barycentric (Vec2f a, Vec2f b, Vec2f c, Vec2f p) { var ab = b - a; var ac = c - a; var pa = a - p; var r = Cross (new Vec3f { x = ab.x, y = ac.x, z = pa.x }, new Vec3f { x = ab.y, y = ac.y, z = pa.y }); // triangle is degenerate, in this case return smth with negative coordinates // dont forget that r.z is integer. If it is zero then triangle ABC is degenerate if ((int)r.z == 0) return new Vec3f { x = -1, y = 1, z = 1 }; return new Vec3f { x = 1 - (r.x + r.y) / r.z, y = r.x / r.z, z = r.y / r.z }; } void Triangle (Image image, Vec3f [] coordinates, Image texture, Vec2f [] uv, float intensivity, float [] zbuffer) { Vec3f t0 = coordinates [0]; Vec3f t1 = coordinates [1]; Vec3f t2 = coordinates [2]; var pMax = new Vec2i { x = (int)Math.Max (0, Math.Max (t0.x, Math.Max (t1.x, t2.x))), y = (int)Math.Max (0, Math.Max (t0.y, Math.Max (t1.y, t2.y))) }; var pMin = new Vec2i { x = (int)Math.Min (image.Width, Math.Min (t0.x, Math.Min (t1.x, t2.x))), y = (int)Math.Min (image.Height, Math.Min (t0.y, Math.Min (t1.y, t2.y))) }; for (int x = pMin.x; x <= pMax.x; x++) { for (int y = pMin.y; y <= pMax.y; y++) { var pixelCenter = new Vec2f { x = x + 0.5f, y = y + 0.5f }; var bc = Barycentric (Project2D(t0), Project2D(t1), Project2D(t2), pixelCenter); if (bc.x < 0 || bc.y < 0 || bc.z < 0) continue; var z = t0.z * bc.x + t1.z * bc.y + t2.z * bc.z; var u = (int)(uv [0].x * bc.x + uv [1].x * bc.y + uv [2].x * bc.z); var v = (int)(uv [0].y * bc.x + uv [1].y * bc.y + uv [2].y * bc.z); var idx = x + y * image.Width; if (zbuffer [idx] < z) { zbuffer [idx] = z; var color = texture [u, v]; image [x, y] = color * intensivity; } } } } ================================================ FILE: graphics/tiny-renderer/lesson4.workbook/lesson3.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" #load "lesson1.csx" #load "lesson2.csx" using static Geometry; ``` # **Lesson 3: Hidden faces removal (z buffer)** # Introduction Hello, let me introduce you my friend z-buffer of a black guy. He will help us get rid of the visual artifacts of the hidden faces removal we had during the last lesson. ![](./img/lesson3_face1.png) By the way, i'd like to mention that this model i use heavily in the course is created by [Vidar Rapp](https://se.linkedin.com/in/vidarrapp). He kindely granted me a permission to use it for teaching rendering basics and i vandalized it, but i promise you to give back the eyes to the guy. Well, back to the topic, in theory we could just draw all the triangles without discarding any. If we do it properly starting rear-to-front, the front facets will erase the back ones. It is called the [painter's algorithm](http://en.wikipedia.org/wiki/Painter%27s_algorithm). Unfortunately, it comes along with a high computational cost: for each camera movement we need to re-sort all the scene. And then there are dynamic scenes... And this is not even the main problem. The main problem is it is not always possible to determine the correct order. # **Let us try to render a simple scene** Imagine a simple scene made of three triangles: the camera looks up-to-down, we project the colored triangles onto the white screen: ![ ](./img/lesson3_scene1.png) The render should look like this: ![ ](./img/lesson3_scene2.png) Blue facet - is it behind or in front of the red one? The painter's algorithm does not work here. It is possible to split blue facet in two (one in front of the red facet and one behind). And then the one in front of the red one is to be split in two - one in front of the green triangle and one behind... I think you get the problem: in scenes with millions of triangles it is really expensive to compute. It is possible to use [BSP trees](https://en.wikipedia.org/wiki/Binary_space_partitioning) to get it done. By the way, this data structure is constant for moving camera, but it is really messy. And the life is too short to get it messy. # **Even simpler: let us lose a dimension. Y-buffer!** Let us lose a dimension for a while and to cut the above scene along the yellow plane: ![ ](./img/lesson3_scene3.png) I mean, now our scene is made of three line segments (intersection of the yellow plane and each of the triangles), and the final render has a normal width but 1 pixel height: ![ ](./img/lesson3_scene4.png) Our scene is two-dimensional, so it is easy to draw it using the line() function we programmed in the very first lesson. ```csharp var scene = new Image (800, 500, Format.BGR); // scene "2d mesh" Line(scene, new Vec2i {x=20, y=34}, new Vec2i {x=744, y=400}, Color.Red); Line(scene, new Vec2i {x=120, y=434}, new Vec2i {x=444, y=400}, Color.Green); Line(scene, new Vec2i {x=330, y=463}, new Vec2i {x=594, y=200}, Color.Blue); // screen line Line(scene, new Vec2i {x=10, y=10}, new Vec2i{x=790, y=10}, Color.White); scene.VerticalFlip(); // I want to have the origin at the left bottom corner of the image scene // This is how our 2D scene looks like if we look at it sideways: ``` Let us render it. Recall that the render is 1 pixel height. In my source code I create images 16 pixels height for the ease of reading on high resolution screens. `Rasterize()` function writes only in the first line of the image `render` ```csharp void Rasterize(Image image, Vec2i p0, Vec2i p1, int[] ybuffer, Color color) { if (p0.x>p1.x) Swap(ref p0, ref p1); for (int x=p0.x; x<=p1.x; x++) { float t = (x-p0.x)/(float)(p1.x-p0.x); var y = (int)(p0.y*(1-t) + p1.y*t); if (ybuffer[x] < y) { ybuffer[x] = y; image[x, 0] = color; } } } var ybuffer = new int [width]; for (int i = 0; i < width; i++) ybuffer[i] = int.MinValue; var render = new Image (width, 16, Format.BGR); Rasterize(render, new Vec2i{x=20,y=34}, new Vec2i{x=744, y=400}, ybuffer, Color.Red); Rasterize(render, new Vec2i{x=120, y=434}, new Vec2i{x=444,y=400}, ybuffer, Color.Green); Rasterize(render, new Vec2i{x=330, y=463}, new Vec2i{x=594,y=200}, ybuffer, Color.Blue); render ``` It is really-really simple: I iterate through all x-coordinates between `p0.x` and `p1.x` and compute the corresponding y-coordinate of the segment. Then I check what we got in our array `ybuffer` with current `x` index. If the current `y`-value is closer to the camera than the value in the `ybuffer`, then I draw it on the screen and update the `ybuffer`. Let us see it step-by-step. After calling `Rasterize()` on the first (red) segment this is our memory: screen:![](./img/lesson3_rasterize1.png) ybuffer: ![ ](./img/lesson3_rasterize2.png) Here the magenta color indicates the minus infinity, those are places corresponding to the screen we did not touch. All the rest is shown in the shades of gray: clear colors are close to the camera, dark colors far from the camera. Then we draw the green segment. screen:![ ](./img/lesson3_rasterize3.png) ybuffer:![ ](./img/lesson3_rasterize4.png) And finally the blue one. screen:![ ](./img/lesson3_rasterize5.png) ybuffer:![ ](./img/lesson3_rasterize6.png) Congratulations, we just drew a 2D scene on a 1D screen! Let us admire once again the render: ![ ](./img/lesson3_rasterize7.png) # Back to 3D So, for drawing on a 2D screen the z-buffer must be two-dimensional: `var zbuffer = new int[width * height];` Personally I pack a two-dimensional buffer into a one-dimensional, the conversion is trivial: `var idx = x + y* width;` and the back one: `var x = idx % width;`\ `var y = idx % width;` Then in the code I simply iterate through all the triangles and call the rasterizer function with current triangle and a reference to the z-buffer. The only difficulty is how to compute the z-value of a pixel we want to draw. Let us recall how we computed the y-value in the y-buffer example: `int y = p0.y*(1-t) + p1.y*t;` What is the nature of the `t` variable? It turns out that `(1-t, t)` are barycentric coordinates of the point `(x,y)` with respect to the segment `p0, p1: (x,y) = p0*(1-t) + p1*t`. So the idea is to take the barycentric coordinates version of triangle rasterization, and for every pixel we want to draw simply to multiply its barycentric coordinates by the z-values of the vertices of the triangle we rasterize: ```csharp Vec3f Barycentric (Vec2f a, Vec2f b, Vec2f c, Vec2f p) { var ab = b - a; var ac = c - a; var pa = a - p; var r = Cross (new Vec3f { x = ab.x, y = ac.x, z = pa.x }, new Vec3f { x = ab.y, y = ac.y, z = pa.y }); // triangle is degenerate, in this case return smth with negative coordinates // dont forget that r.z is integer. If it is zero then triangle ABC is degenerate if ((int)r.z == 0) return new Vec3f { x = -1, y = 1, z = 1 }; return new Vec3f { x = 1 - (r.x + r.y) / r.z, y = r.x / r.z, z = r.y / r.z }; } void Triangle (Image image, Vec3f [] coordinates, Color color, float [] zbuffer) { Vec3f t0 = coordinates [0]; Vec3f t1 = coordinates [1]; Vec3f t2 = coordinates [2]; var pMax = new Vec2i { x = (int)Math.Max (0, Math.Max (t0.x, Math.Max (t1.x, t2.x))), y = (int)Math.Max (0, Math.Max (t0.y, Math.Max (t1.y, t2.y))) }; var pMin = new Vec2i { x = (int)Math.Min (image.Width, Math.Min (t0.x, Math.Min (t1.x, t2.x))), y = (int)Math.Min (image.Height, Math.Min (t0.y, Math.Min (t1.y, t2.y))) }; for (int x = pMin.x; x <= pMax.x; x++) { for (int y = pMin.y; y <= pMax.y; y++) { var pixelCenter = new Vec2f { x = x + 0.5f, y = y + 0.5f }; var bc = Barycentric (Project2D (t0), Project2D (t1), Project2D (t2), pixelCenter); if (bc.x < 0 || bc.y < 0 || bc.z < 0) continue; var z = t0.z * bc.x + t1.z * bc.y + t2.z * bc.z; var idx = x + y * image.Width; if (zbuffer [idx] < z) { zbuffer [idx] = z; image [x, y] = color; } } } } float [] InitZBuffer (Image image) { var zbuffer = new float [image.Width * image.Height]; for (int idx = 0; idx < zbuffer.Length; idx++) zbuffer [idx] = float.NegativeInfinity; return zbuffer; } var image = new Image(width, height, Format.BGR); Func map = v => new Vec3f { x = (int)((v.x+1)*(image.Width-1)/2 + 0.5f), y = (int)((v.y+1)*(image.Height-1)/2 + 0.5f), z = v.z }; var zbuffer = InitZBuffer(image); foreach(var face in headModel.Faces) { for(int i=0; i<3; i++) { var vIndex = face.Vertices[i]; world[i] = headModel.Vertices[vIndex]; screen[i] = map(world[i]); } Vec3f n = Cross(world[2] - world[0], world[1] - world[0]).Normalize (); var intensivity = Dot(n, light_dir); if(intensivity > 0) Triangle(image, screen, Color.White * intensivity, zbuffer); } image.VerticalFlip (); image ``` # Okay, we just interpolated the z-values. What else can we do? Texture! In the `.obj` file we have lines starting with `vt u v`, they give an array of texture coordinates. The number in the middle (between the slashes) in the facet lines\ `f x/x/x x/x/x x/x/x` are the texture coordinates of this vertex of this triangle. Interpolate it inside the triangle, multiply by the width-height of the texture image and you will get the color to put in your render. ```csharp void Triangle (Image image, Vec3f [] coordinates, Image texture, Vec2f [] uv, float intensivity, float [] zbuffer) { Vec3f t0 = coordinates [0]; Vec3f t1 = coordinates [1]; Vec3f t2 = coordinates [2]; var pMax = new Vec2i { x = (int)Math.Max (0, Math.Max (t0.x, Math.Max (t1.x, t2.x))), y = (int)Math.Max (0, Math.Max (t0.y, Math.Max (t1.y, t2.y))) }; var pMin = new Vec2i { x = (int)Math.Min (image.Width, Math.Min (t0.x, Math.Min (t1.x, t2.x))), y = (int)Math.Min (image.Height, Math.Min (t0.y, Math.Min (t1.y, t2.y))) }; for (int x = pMin.x; x <= pMax.x; x++) { for (int y = pMin.y; y <= pMax.y; y++) { var pixelCenter = new Vec2f { x = x + 0.5f, y = y + 0.5f }; var bc = Barycentric (Project2D(t0), Project2D(t1), Project2D(t2), pixelCenter); if (bc.x < 0 || bc.y < 0 || bc.z < 0) continue; var z = t0.z * bc.x + t1.z * bc.y + t2.z * bc.z; var u = (int)(uv [0].x * bc.x + uv [1].x * bc.y + uv [2].x * bc.z); var v = (int)(uv [0].y * bc.x + uv [1].y * bc.y + uv [2].y * bc.z); var idx = x + y * image.Width; if (zbuffer [idx] < z) { zbuffer [idx] = z; var color = texture [u, v]; image [x, y] = color * intensivity; } } } } var image = new Image(width, height, Format.BGR); var headTexture = Image.Load ("obj/african_head_diffuse.tga"); headTexture.VerticalFlip (); Func uvMap = v => new Vec2f { x = v.x * (headTexture.Width - 1), y = v.y * (headTexture.Height - 1) }; var zbuffer = InitZBuffer(image); var uv = new Vec2f[3]; var model = headModel; foreach(var face in model.Faces) { for(int i=0; i<3; i++) { var vIndex = face.Vertices[i]; world[i] = model.Vertices[vIndex]; screen[i] = map(world[i]); var tIndex = face.Textures[i]; uv[i] = uvMap(model.Textures[tIndex]); } Vec3f n = Cross(world[2] - world[0], world[1] - world[0]).Normalize (); var intensivity = Dot(n, light_dir); if(intensivity > 0) Triangle(image, screen, headTexture, uv, intensivity, zbuffer); } image.VerticalFlip (); image ``` ================================================ FILE: graphics/tiny-renderer/lesson4.workbook/lesson4.csx ================================================ Vec2f[] uv = new Vec2f [3]; Func uvMap = (texture, v) => new Vec2f { x = v.x * (texture.Width - 1), y = v.y * (texture.Height - 1) }; Matrix4 Viewport (int x, int y, int w, int h) { var depth = 255f; var m = Matrix4.Identity (); m [0, 3] = x + w / 2f; m [1, 3] = y + h / 2f; m [2, 3] = depth / 2f; m [0, 0] = w / 2f; m [1, 1] = h / 2f; m [2, 2] = depth / 2f; return m; } Matrix4 Projection (float coeff) { var projection = Matrix4.Identity (); projection [3, 2] = coeff; return projection; } ================================================ FILE: graphics/tiny-renderer/lesson4.workbook/obj/cube.obj ================================================ v -1 -1 1 v 1 -1 1 v 1 0 1 v 0 1 1 v -1 1 1 v 1 1 0 v -1 -1 -1 v 1 -1 -1 v 1 1 -1 v -1 1 -1 f 1/-1/-1 2/-1/-1 3/-1/-1 4/-1/-1 5/-1/-1 f 4/-1/-1 3/-1/-1 6/-1/-1 f 1/-1/-1 7/-1/-1 8/-1/-1 2/-1/-1 f 1/-1/-1 5/-1/-1 10/-1/-1 7/-1/-1 f 5/-1/-1 4/-1/-1 6/-1/-1 9/-1/-1 10/-1/-1 f 2/-1/-1 8/-1/-1 9/-1/-1 6/-1/-1 3/-1/-1 f 7/-1/-1 10/-1/-1 9/-1/-1 8/-1/-1 ================================================ FILE: graphics/tiny-renderer/lesson5.workbook/Geometry.csx ================================================ struct Vec2f { public float x; public float y; public float this [int i] { get { if (i == 0) return x; if (i == 1) return y; throw new InvalidOperationException (); } set { if (i == 0) x = value; else if (i == 1) y = value; else throw new InvalidOperationException (); } } public Vec2f Normalize () { return this / Norm (); } public float Norm () { return (float)Math.Sqrt (x * x + y * y); } public static Vec2f operator / (Vec2f v, float num) { v.x /= num; v.y /= num; return v; } public static Vec2f operator * (Vec2f v, float num) { v.x *= num; v.y *= num; return v; } public static Vec2f operator - (Vec2f a, Vec2f b) { return new Vec2f { x = a.x - b.x, y = a.y - b.y }; } public static Vec2f operator + (Vec2f a, Vec2f b) { return new Vec2f { x = a.x + b.x, y = a.y + b.y }; } } public struct Vec3f { public float x; public float y; public float z; public float this [int i] { get { switch (i) { case 0: return x; case 1: return y; case 2: return z; default: throw new InvalidOperationException (); } } set { switch (i) { case 0: x = value; break; case 1: y = value; break; case 2: z = value; break; default: throw new InvalidOperationException (); } } } public Vec3f Normalize () { return this / Norm (); } public float Norm () { return (float)Math.Sqrt (x * x + y * y + z * z); } public static Vec3f operator - (Vec3f a, Vec3f b) { return new Vec3f { x = a.x - b.x, y = a.y - b.y, z = a.z - b.z }; } public static Vec3f operator / (Vec3f v, float num) { v.x /= num; v.y /= num; v.z /= num; return v; } public static Vec3f operator * (Vec3f v, float num) { v.x *= num; v.y *= num; v.z *= num; return v; } } struct Vec4f { public float x; public float y; public float z; public float h; public float this [int i] { get { switch (i) { case 0: return x; case 1: return y; case 2: return z; case 3: return h; default: throw new InvalidOperationException (); } } set { switch (i) { case 0: x = value; break; case 1: y = value; break; case 2: z = value; break; case 3: h = value; break; default: throw new InvalidOperationException (); } } } public Vec4f Normalize () { var len = Norm (); return this / len; } public float Norm () { return (float)Math.Sqrt (x * x + y * y + z * z + h * h); } public static Vec4f operator - (Vec4f a, Vec4f b) { return new Vec4f { x = a.x - b.x, y = a.y - b.y, z = a.z - b.z, h = a.h - b.h }; } public static Vec4f operator / (Vec4f v, float num) { v.x /= num; v.y /= num; v.z /= num; v.h /= num; return v; } } struct Vec2i { public int x; public int y; public static Vec2i operator - (Vec2i a, Vec2i b) { return new Vec2i { x = a.x - b.x, y = a.y - b.y }; } } struct Vec3i { public int x; public int y; public int z; public static Vec3i operator - (Vec3i a, Vec3i b) { return new Vec3i { x = a.x - b.x, y = a.y - b.y, z = a.z - b.z }; } } static class Geometry { public static Vec3f Cross (Vec3f l, Vec3f r) { return new Vec3f { x = l.y * r.z - l.z * r.y, y = l.z * r.x - l.x * r.z, z = l.x * r.y - l.y * r.x }; } public static float Dot (Vec3f l, Vec3f r) { return l.x * r.x + l.y * r.y + l.z * r.z; } public static Vec4f Embed4D (Vec3f v, float fill = 1) { return new Vec4f { x = v.x, y = v.y, z = v.z, h = fill }; } public static Vec2f Project2D (Vec3f v) { return new Vec2f { x = v.x, y = v.y }; } public static Vec2f Project2D (Vec4f v) { return new Vec2f { x = v.x, y = v.y }; } public static Vec3f Project3D (Vec4f v) { return new Vec3f { x = v.x, y = v.y, z = v.z }; } } ================================================ FILE: graphics/tiny-renderer/lesson5.workbook/Image.csx ================================================ using System.IO; enum Format { GRAYSCALE = 1, BGR = 3, BGRA = 4 } struct Color { // the value stored as little endian: // ARGB -> BGRA // xRGB -> BGRx public readonly int value; public readonly Format format; public byte this [int offset] { get { if (offset > 3) // int has only 4 bytes (0, 1, 2, 3) throw new ArgumentOutOfRangeException (); return (byte)(value >> 8 * (3 - offset)); } } public static Color Red = new Color (red: 255, green: 0, blue: 0, alpha: 255); public static Color Green = new Color (red: 0, green: 255, blue: 0, alpha: 255); public static Color Blue = new Color (red: 0, green: 0, blue: 255, alpha: 255); public static Color Black = new Color (red: 0, green: 0, blue: 0, alpha: 255); public static Color White = new Color (red: 255, green: 255, blue: 255, alpha: 255); public static Color Yellow = new Color (red: 225, green: 225, blue: 0, alpha: 255); public Color (byte red, byte green, byte blue, byte alpha) : this ((blue << 24) | (green << 16) | (red << 8) | alpha, Format.BGRA) { } public Color (byte red, byte green, byte blue) : this ((blue << 24) | (green << 16) | (red << 8) | 0xFF, Format.BGR) { } public Color (byte value) : this (value, Format.GRAYSCALE) { } public Color (int value, Format format) { this.value = value; this.format = format; } public static Color operator * (Color color, float intensivity) { intensivity = Math.Max (0f, Math.Min (1f, intensivity)); var ch0 = (byte)(color [0] * intensivity); var ch1 = (byte)(color [1] * intensivity); var ch2 = (byte)(color [2] * intensivity); var ch3 = color [3]; return new Color (ch0 << 24 | ch1 << 16 | ch2 << 8 | ch3, color.format); } } class Image { internal byte [] buffer; public int Width { get; } public int Height { get; } public Format Format { get; } public int BytesPerRow { get { return Width * (int)Format; } } public Image (int width, int height, Format format) { Width = width; Height = height; Format = format; buffer = new byte [height * BytesPerRow]; } public void VerticalFlip () { var bpp = (int)Format; int bytesPerLine = Width * bpp; var half = Height >> 1; for (int l = 0; l < half; l++) { var l1 = l * bytesPerLine; var l2 = (Height - 1 - l) * bytesPerLine; for (int i = 0; i < bytesPerLine; i++) { byte pixel = buffer [l1 + i]; buffer [l1 + i] = buffer [l2 + i]; buffer [l2 + i] = pixel; } } } public void Clear () { for (int i = 0; i < buffer.Length; i++) buffer [i] = 0; } public Color this [int x, int y] { get { if (x < 0 || x >= Width) throw new ArgumentException ("x"); if (y < 0 || y >= Height) throw new ArgumentException ("y"); var offset = GetOffset (x, y); var len = (int)Format; int value = 0; for (var ch = 0; ch < 4; ch++) value = (value << 8) | (ch < len ? buffer [offset++] : 0xFF); return new Color (value, Format); } set { if (x < 0 || x >= Width) return; //throw new ArgumentException ($"{nameof(x)}={x} {nameof(Width)}={Width}"); if (y < 0 || y >= Height) return; // throw new ArgumentException ($"{nameof(y)}={y} {nameof(Height)}={Height}"); var offset = GetOffset (x, y); var v = value.value; var len = (int)Format; for (int ch = 0; ch < len; ch++) // 0123 buffer [offset++] = (byte)(v >> (3 - ch) * 8); // BGRA } } int GetOffset (int x, int y) { return y * BytesPerRow + x * (int)Format; } public bool WriteToFile (string path, bool rle = true) { var bpp = (int)Format; using (var writer = new BinaryWriter (File.Create (path))) { var header = new TGAHeader { IdLength = 0, // The IDLength set to 0 indicates that there is no image identification field in the TGA file ColorMapType = 0, // a value of 0 indicates that no palette is included BitsPerPixel = (byte)(bpp * 8), Width = (short)Width, Height = (short)Height, DataTypeCode = DataTypeFor (bpp, rle), ImageDescriptor = (byte)(0x20 | (Format == Format.BGRA ? 8 : 0)) // top-left origin }; WriteTo (writer, header); if (!rle) writer.Write (buffer); else UnloadRleData (writer); } return true; } public static Image Load (string path) { using (var reader = new BinaryReader (File.OpenRead (path))) { var header = ReadHeader (reader); var height = header.Height; var width = header.Width; var bytespp = header.BitsPerPixel >> 3; var format = (Format)bytespp; if (width <= 0 || height <= 0) throw new InvalidProgramException ($"bad image size: width={width} height={height}"); if (format != Format.BGR && format != Format.BGRA && format != Format.GRAYSCALE) throw new InvalidProgramException ($"unknown format {format}"); var img = new Image (width, height, format); switch (header.DataTypeCode) { case DataType.UncompressedTrueColorImage: case DataType.UncompressedBlackAndWhiteImage: reader.Read (img.buffer, 0, img.buffer.Length); break; case DataType.RleTrueColorImage: case DataType.RleBlackAndWhiteImage: img.LoadRleData (reader); break; default: throw new InvalidProgramException ($"unsupported image format {header.DataTypeCode}"); } if ((header.ImageDescriptor & 0x20) == 0) img.VerticalFlip (); return img; } } static void WriteTo (BinaryWriter writer, TGAHeader header) { writer.Write (header.IdLength); writer.Write (header.ColorMapType); writer.Write ((byte)header.DataTypeCode); writer.Write (header.ColorMapOrigin); writer.Write (header.ColorMapLength); writer.Write (header.ColorMapDepth); writer.Write (header.OriginX); writer.Write (header.OriginY); writer.Write (header.Width); writer.Write (header.Height); writer.Write (header.BitsPerPixel); writer.Write (header.ImageDescriptor); } static TGAHeader ReadHeader (BinaryReader reader) { var header = new TGAHeader { IdLength = reader.ReadByte (), ColorMapType = reader.ReadByte (), DataTypeCode = (DataType)reader.ReadByte (), ColorMapOrigin = reader.ReadInt16 (), ColorMapLength = reader.ReadInt16 (), ColorMapDepth = reader.ReadByte (), OriginX = reader.ReadInt16 (), OriginY = reader.ReadInt16 (), Width = reader.ReadInt16 (), Height = reader.ReadInt16 (), BitsPerPixel = reader.ReadByte (), ImageDescriptor = reader.ReadByte () }; return header; } bool UnloadRleData (BinaryWriter writer) { const int max_chunk_length = 128; int npixels = Width * Height; int curpix = 0; var bpp = (int)Format; while (curpix < npixels) { int chunkstart = curpix * bpp; int curbyte = curpix * bpp; int run_length = 1; bool literal = true; while (curpix + run_length < npixels && run_length < max_chunk_length && curpix + run_length < curpix + Width) { bool succ_eq = true; for (int t = 0; succ_eq && t < bpp; t++) succ_eq = (buffer [curbyte + t] == buffer [curbyte + t + bpp]); curbyte += bpp; if (1 == run_length) literal = !succ_eq; if (literal && succ_eq) { run_length--; break; } if (!literal && !succ_eq) break; run_length++; } curpix += run_length; writer.Write ((byte)(literal ? run_length - 1 : 128 + (run_length - 1))); writer.Write (buffer, chunkstart, literal ? run_length * bpp : bpp); } return true; } void LoadRleData (BinaryReader reader) { var pixelcount = Width * Height; var currentpixel = 0; var currentbyte = 0; var bytespp = (int)Format; var color = new byte [4]; do { var chunkheader = reader.ReadByte (); if (chunkheader < 128) { chunkheader++; for (int i = 0; i < chunkheader; i++) { for (int t = 0; t < bytespp; t++) buffer [currentbyte++] = reader.ReadByte (); currentpixel++; if (currentpixel > pixelcount) throw new InvalidProgramException ("Too many pixels read"); } } else { chunkheader -= 127; reader.Read (color, 0, bytespp); for (int i = 0; i < chunkheader; i++) { for (int t = 0; t < bytespp; t++) buffer [currentbyte++] = color [t]; currentpixel++; if (currentpixel > pixelcount) throw new InvalidProgramException ("Too many pixels read"); } } } while (currentpixel < pixelcount); } static DataType DataTypeFor (int bpp, bool rle) { var format = (Format)bpp; if (format == Format.GRAYSCALE) return rle ? DataType.RleBlackAndWhiteImage : DataType.UncompressedBlackAndWhiteImage; return rle ? DataType.RleTrueColorImage : DataType.UncompressedTrueColorImage; } } struct TGAHeader { public byte IdLength; public byte ColorMapType; public DataType DataTypeCode; // field #4. Color map specification public short ColorMapOrigin; // index of first color map entry that is included in the file public short ColorMapLength; // number of entries of the color map that are included in the file public byte ColorMapDepth; // number of bits per pixel // field #5. Image specification public short OriginX; // absolute coordinate of lower-left corner for displays where origin is at the lower left public short OriginY; // as for X-origin public short Width; // width in pixels public short Height; // height in pixels public byte BitsPerPixel; // pixel depth public byte ImageDescriptor; // bits 3-0 give the alpha channel depth, bits 5-4 give direction } public enum DataType : byte { NoImageData = 0, // no image data is present UncompressedColorMappedImage = 1, UncompressedTrueColorImage = 2, UncompressedBlackAndWhiteImage = 3, RleColorMappedImage = 9, // run-length encoded color-mapped image RleTrueColorImage = 10, // run-length encoded true-color image RleBlackAndWhiteImage = 11 // run-length encoded black-and-white (grayscale) image } ================================================ FILE: graphics/tiny-renderer/lesson5.workbook/ImageResultHandler.csx ================================================ using XIR = Xamarin.Interactive.Representations; InteractiveAgent.RepresentationManager.AddProvider (img => { XIR.ImageFormat format; switch (img.Format) { case Format.BGRA: format = XIR.ImageFormat.Bgra32; break; case Format.BGR: format = XIR.ImageFormat.Bgr24; break; default: return null; } return new XIR.Image (format, img.buffer, img.Width, img.Height); }); ================================================ FILE: graphics/tiny-renderer/lesson5.workbook/LICENSE.txt ================================================ Tiny Renderer, https://github.com/ssloy/tinyrenderer Copyright Dmitry V. Sokolov This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. ================================================ FILE: graphics/tiny-renderer/lesson5.workbook/Matrix.csx ================================================ using System; public struct Matrix4 { public const int Len = 4; public float R0C0, R0C1, R0C2, R0C3; public float R1C0, R1C1, R1C2, R1C3; public float R2C0, R2C1, R2C2, R2C3; public float R3C0, R3C1, R3C2, R3C3; public float this [int row, int column] { get { switch (row) { case 0: switch (column) { case 0: return R0C0; case 1: return R0C1; case 2: return R0C2; case 3: return R0C3; } break; case 1: switch (column) { case 0: return R1C0; case 1: return R1C1; case 2: return R1C2; case 3: return R1C3; } break; case 2: switch (column) { case 0: return R2C0; case 1: return R2C1; case 2: return R2C2; case 3: return R2C3; } break; case 3: switch (column) { case 0: return R3C0; case 1: return R3C1; case 2: return R3C2; case 3: return R3C3; } break; } throw new IndexOutOfRangeException (); } set { switch (row) { case 0: switch (column) { case 0: R0C0 = value; return; case 1: R0C1 = value; return; case 2: R0C2 = value; return; case 3: R0C3 = value; return; } break; case 1: switch (column) { case 0: R1C0 = value; return; case 1: R1C1 = value; return; case 2: R1C2 = value; return; case 3: R1C3 = value; return; } break; case 2: switch (column) { case 0: R2C0 = value; return; case 1: R2C1 = value; return; case 2: R2C2 = value; return; case 3: R2C3 = value; return; } break; case 3: switch (column) { case 0: R3C0 = value; return; case 1: R3C1 = value; return; case 2: R3C2 = value; return; case 3: R3C3 = value; return; } break; } throw new IndexOutOfRangeException (); } } public Matrix4 Transpose () { return new Matrix4 { R0C0 = R0C0, R0C1 = R1C0, R0C2 = R2C0, R0C3 = R3C0, R1C0 = R0C1, R1C1 = R1C1, R1C2 = R2C1, R1C3 = R3C1, R2C0 = R0C2, R2C1 = R1C2, R2C2 = R2C2, R2C3 = R3C2, R3C0 = R0C3, R3C1 = R1C3, R3C2 = R2C3, R3C3 = R3C3 }; } public static Matrix4 Identity () { return new Matrix4 { R0C0 = 1, R1C1 = 1, R2C2 = 1, R3C3 = 1 }; } public static Matrix4 Zoom (float scale) { return new Matrix4 { R0C0 = scale, R1C1 = scale, R2C2 = scale, R3C3 = scale }; } public static Matrix4 RotationZ (float angle) { var cosangle = (float)Math.Cos (angle); var sinangle = (float)Math.Sin (angle); var R = Identity (); R [0, 0] = R [1, 1] = cosangle; R [0, 1] = -sinangle; R [1, 0] = sinangle; return R; } public static Matrix4 operator * (Matrix4 l, Matrix4 r) { var result = new Matrix4 (); for (int i = 0; i < Len; i++) { for (int j = 0; j < Len; j++) { result [i, j] = 0; for (int k = 0; k < Len; k++) { result [i, j] += l [i, k] * r [k, j]; } } } return result; } public override string ToString () { var sb = new System.Text.StringBuilder (); for (int r = 0; r < Len; r++) { for (int c = 0; c < Len; c++) sb.Append (this[r, c]).Append (" "); sb.AppendLine (); } return sb.ToString (); } } public struct Matrix3 { public const int Len = 3; public float R0C0, R0C1, R0C2; public float R1C0, R1C1, R1C2; public float R2C0, R2C1, R2C2; public float this [int row, int column] { get { switch (row) { case 0: switch (column) { case 0: return R0C0; case 1: return R0C1; case 2: return R0C2; } break; case 1: switch (column) { case 0: return R1C0; case 1: return R1C1; case 2: return R1C2; } break; case 2: switch (column) { case 0: return R2C0; case 1: return R2C1; case 2: return R2C2; } break; } throw new IndexOutOfRangeException (); } set { switch (row) { case 0: switch (column) { case 0: R0C0 = value; return; case 1: R0C1 = value; return; case 2: R0C2 = value; return; } break; case 1: switch (column) { case 0: R1C0 = value; return; case 1: R1C1 = value; return; case 2: R1C2 = value; return; } break; case 2: switch (column) { case 0: R2C0 = value; return; case 1: R2C1 = value; return; case 2: R2C2 = value; return; } break; } throw new IndexOutOfRangeException (); } } public Matrix3 Transpose () { return new Matrix3 { R0C0 = R0C0, R0C1 = R1C0, R0C2 = R2C0, R1C0 = R0C1, R1C1 = R1C1, R1C2 = R2C1, R2C0 = R0C2, R2C1 = R1C2, R2C2 = R2C2 }; } public void SetColumn (int col, Vec3f v) { this [0, col] = v.x; this [1, col] = v.y; this [2, col] = v.z; } public void SetRow (int row, Vec3f v) { this [row, 0] = v.x; this [row, 1] = v.y; this [row, 2] = v.z; } public override string ToString () { var sb = new System.Text.StringBuilder (); for (int r = 0; r < Len; r++) { for (int c = 0; c < Len; c++) sb.Append (this [r, c]).Append (" "); sb.AppendLine (); } return sb.ToString (); } } public struct Matrix2 { public const int Len = 2; public float R0C0, R0C1; public float R1C0, R1C1; public float this [int row, int column] { get { switch (row) { case 0: switch (column) { case 0: return R0C0; case 1: return R0C1; } break; case 1: switch (column) { case 0: return R1C0; case 1: return R1C1; } break; } throw new IndexOutOfRangeException (); } set { switch (row) { case 0: switch (column) { case 0: R0C0 = value; return; case 1: R0C1 = value; return; } break; case 1: switch (column) { case 0: R1C0 = value; return; case 1: R1C1 = value; return; } break; } throw new IndexOutOfRangeException (); } } } // we don't want to declare them in Matrix because we don't need them in lesson which introduces Matrix class static class MatrixHelpers { // For Matrix4 // how to calc inverse Matrix https://en.wikipedia.org/w/index.php?title=Invertible_matrix§ion=4#In_relation_to_its_adjugate public static Matrix4 TransposeInverse (Matrix4 m) { // returns Transpose(Inverse(m)) // where Inverse(m) = Transpose(cofactor) / det(m) // Transpose(Inverse(m)) = Transpose(Transpose(cofactor) / det(m)) = cofactor / det(m) var cofactor = Cofactor (m); float det = 0; for (int i = 0; i < Matrix4.Len; i++) det += m [0, i] * cofactor [0, i]; for (int r = 0; r < Matrix4.Len; r++) { for (int c = 0; c < Matrix4.Len; c++) cofactor [r, c] /= det; } return cofactor; } public static Matrix4 Inverse (Matrix4 m) { // where Inverse(m) = Transpose(Cofactor(m)) / det(m) var cofactor = Cofactor (m); int len = Matrix4.Len; float det = 0; for (int i = 0; i < len; i++) det += m [0, i] * cofactor [0, i]; cofactor = cofactor.Transpose (); for (int r = 0; r < len; r++) { for (int c = 0; c < len; c++) cofactor [r, c] /= det; } return cofactor; } public static Matrix3 Inverse (Matrix3 m) { // where Inverse(m) = Transpose(Cofactor(m)) / det(m) var cofactor = Cofactor (m); int len = Matrix3.Len; float det = 0; for (int i = 0; i < len; i++) det += m [0, i] * cofactor [0, i]; cofactor = cofactor.Transpose (); for (int r = 0; r < len; r++) { for (int c = 0; c < len; c++) cofactor [r, c] /= det; } return cofactor; } static Matrix4 Cofactor (Matrix4 m) { var r = new Matrix4 (); for (int row = 0; row < Matrix4.Len; row++) { for (int col = 0; col < Matrix4.Len; col++) r [row, col] = Cofactor (m, row, col); } return r; } static Matrix3 Cofactor (Matrix3 m) { var r = new Matrix3 (); for (int row = 0; row < Matrix3.Len; row++) { for (int col = 0; col < Matrix3.Len; col++) r [row, col] = Cofactor (m, row, col); } return r; } static float Cofactor (Matrix4 m, int row, int col) { int sign = ((row + col) % 2 == 0) ? 1 : -1; return Det (Minor (m, row, col)) * sign; } static float Cofactor (Matrix3 m, int row, int col) { int sign = ((row + col) % 2 == 0) ? 1 : -1; return Det (Minor (m, row, col)) * sign; } static Matrix3 Minor (Matrix4 m, int row, int col) { var minor = new Matrix3 (); for (int r = 0; r < Matrix3.Len; r++) { for (int c = 0; c < Matrix3.Len; c++) { int y = (r < row) ? r : r + 1; int x = (c < col) ? c : c + 1; minor [r, c] = m [y, x]; } } return minor; } static Matrix2 Minor (Matrix3 m, int row, int col) { var minor = new Matrix2 (); for (int r = 0; r < Matrix2.Len; r++) { for (int c = 0; c < Matrix2.Len; c++) { int y = (r < row) ? r : r + 1; int x = (c < col) ? c : c + 1; minor [r, c] = m [y, x]; } } return minor; } static float Det (Matrix3 m) { float det = 0; det += m [0, 0] * (m [1, 1] * m [2, 2] - m [1, 2] * m [2, 1]); det -= m [0, 1] * (m [1, 0] * m [2, 2] - m [1, 2] * m [2, 0]); det += m [0, 2] * (m [1, 0] * m [2, 1] - m [1, 1] * m [2, 0]); return det; } static float Det (Matrix2 m) { return m [0, 0] * m [1, 1] - m [0, 1] * m [1, 0]; } public static Vec3f Mult (Matrix3 m, Vec3f v) { return new Vec3f { x = m.R0C0 * v.x + m.R0C1 * v.y + m.R0C2 * v.z, y = m.R1C0 * v.x + m.R1C1 * v.y + m.R1C2 * v.z, z = m.R2C0 * v.x + m.R2C1 * v.y + m.R2C2 * v.z }; } public static Vec4f Mult (Matrix4 m, Vec4f v) { return new Vec4f { x = m.R0C0*v.x + m.R0C1*v.y + m.R0C2*v.z + m.R0C3*v.h, y = m.R1C0*v.x + m.R1C1*v.y + m.R1C2*v.z + m.R1C3*v.h, z = m.R2C0*v.x + m.R2C1*v.y + m.R2C2*v.z + m.R2C3*v.h, h = m.R3C0*v.x + m.R3C1*v.y + m.R3C2*v.z + m.R3C3*v.h }; } } ================================================ FILE: graphics/tiny-renderer/lesson5.workbook/Model.csx ================================================ using System.Collections.Generic; using System.Linq; struct Face { public int [] Vertices; public int [] Textures; public int [] Normals; } class Model { public List Vertices { get; } = new List (); public List Faces { get; } = new List (); public List Textures { get; } = new List (); public List Normals { get; } = new List (); public static Model FromFile (string path) { var model = new Model (); string line; using (var reader = new System.IO.StreamReader (path)) { while ((line = reader.ReadLine ()) != null) model.ParseLine (line); } Console.WriteLine ($"v#{model.Vertices.Count} f#{model.Faces.Count}"); return model; } public static Model FromText (string text) { var model = new Model (); var lines = text.Split (new char [] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); foreach (var line in lines) model.ParseLine (line); Console.WriteLine ($"v#{model.Vertices.Count} f#{model.Faces.Count}"); return model; } void ParseLine (string line) { Func parseV3f = strItems => new Vec3f { x = float.Parse (strItems [1]), y = float.Parse (strItems [2]), z = float.Parse (strItems [3]) }; var items = line.Split (new char [] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (line.StartsWith ("v ", StringComparison.InvariantCulture)) { Vertices.Add (parseV3f (items)); } else if (line.StartsWith ("vt ", StringComparison.InvariantCulture)) { Textures.Add (parseV3f (items)); } else if (line.StartsWith ("vn ", StringComparison.InvariantCulture)) { Normals.Add (parseV3f (items)); } else if (line.StartsWith ("f ", StringComparison.InvariantCulture)) { var indexes = items.Skip (1) .SelectMany (s => s.Split (new char [] { '/', ' ' }, StringSplitOptions.RemoveEmptyEntries)) .Select (s => int.Parse (s) - 1) // in wavefront obj all indices start at 1, not zero .ToArray (); Faces.Add (new Face { Vertices = indexes.Where ((v, index) => index % 3 == 0).ToArray (), Textures = indexes.Where ((v, index) => index % 3 == 1).ToArray (), Normals = indexes.Where ((v, index) => index % 3 == 2).ToArray () }); } } public Vec3f Normal (Face face, int nthvert) { int idx = face.Normals [nthvert]; return Normals [idx]; } public Vec3f Vertex (Face face, int nthvert) { int idx = face.Vertices [nthvert]; return Vertices [idx]; } public Vec3f GetUV (Face face, int nthvert) { int idx = face.Textures [nthvert]; return Textures [idx]; } } ================================================ FILE: graphics/tiny-renderer/lesson5.workbook/WpfImageResultHandler.csx ================================================ using System; using System.IO; using System.Windows.Media; using System.Windows.Media.Imaging; using XIR = Xamarin.Interactive.Representations; static PixelFormat ConvertFormat (Format format) { switch (format) { case Format.BGRA: return PixelFormats.Bgra32; case Format.GRAYSCALE: return PixelFormats.Gray8; case Format.BGR: default: return PixelFormats.Bgr24; } } InteractiveAgent.RepresentationManager.AddProvider (img => { var source = BitmapSource.Create (img.Width, img.Height, 96, 96, ConvertFormat (img.Format), null, img.buffer, img.BytesPerRow); var encoder = new PngBitmapEncoder (); var outputFrame = BitmapFrame.Create (source); encoder.Frames.Add (outputFrame); using (var memory = new MemoryStream ()) { encoder.Save (memory); return XIR.Image.FromPng (memory.GetBuffer (), img.Width, img.Height); } }); ================================================ FILE: graphics/tiny-renderer/lesson5.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Matrix.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" #load "lesson1.csx" #load "lesson2.csx" #load "lesson3.csx" #load "lesson4.csx" using static Geometry; using static MatrixHelpers; ``` # Lesson 5: Moving the camera > ℹ️ This workbook is a port of an [excellent C++ series](https://github.com/ssloy/tinyrenderer/wiki) written by Dmitry Sokolov. We appreciate that original work is available under a license that allowed us to turn it into a Workbook. # Change of basis in 3D space In Euclidean space coordinates can be given by a point (the origin) and a basis. What does it mean that point P has coordinates `(x,y,z)` in the frame `(O, i,j,k)`? It means that the vector OP can be expressed as follows: ![ ](./img/lesson5_basis.svg) Now image that we have another frame `(O', i',j',k')`. How do we transform coordinates given in one frame to another? First of all let us note that since `(i,j,k)` and `(i',j',k')` are bases of 3D, there exists a (non degenerate) matrix M such that: ![ ](./img/lesson5_new_basis.svg) Let us draw an illustration: ![](./img/lesson5_sketch1.png) Then let us re-express the vector OP: ![ ](./img/lesson5_change_basis1.svg) Now let us substitute `(i',j',k')` in the right part with the change of basis matrix: ![ ](./img/lesson5_change_basis2.svg) And it gives us the formula to transform coordinates from one frame to another: ![ ](./img/lesson5_change_basis3.svg) # Let us create our own gluLookAt OpenGL and, as a consequence, our tiny renderer are able to draw scenes **only with the camera located on the z-axis.** If we want to move the camera, no problem, we can move all the scene, leaving the camera immobile. Let us put the problem this way: we want to draw a scene with a camera situated in point **e**(eye), the camera should be pointed to the point **c** (center) in such way that a given vector **u**(up) is to be vertical in the final render. Here is an illustration: ![ ](./img/lesson5_change_basis4.png) ```csharp Matrix4 LookAt (Vec3f eye, Vec3f center, Vec3f up) { var z = (eye - center).Normalize (); var x = Cross (up, z).Normalize (); var y = Cross (z, x).Normalize (); var Minv = Matrix4.Identity (); Minv [0, 0] = x.x; Minv [0, 1] = x.y; Minv [0, 2] = x.z; Minv [1, 0] = y.x; Minv [1, 1] = y.y; Minv [1, 2] = y.z; Minv [2, 0] = z.x; Minv [2, 1] = z.y; Minv [2, 2] = z.z; var Tr = Matrix4.Identity (); Tr [0, 3] = -center.x; Tr [1, 3] = -center.y; Tr [2, 3] = -center.y; return Minv * Tr; } ``` Note that `z'` is given by the vector **`ce`** (do not forget to normalize it, it helps later). How do we compute `x'`? Simply by a cross product between **`u`** and **`z'`**. Then we compute `y'`, such that it is orthogonal to already calculated `x'` and `z'` (let me remind you that in our problem settings \*\*`ce` \*\*and **`u`** are not necessarily orthogonal). The very last step is a translation of the origin to the center **c** and our transformation matrix is ready. Now it suffices to get any point with coordinates `(x,y,z,1)` in the model frame, multiply it by the matrix ModelView and we get the coordinates in the camera frame! By the way, the name ModelView comes from OpenGL terminology. # Viewport If you followed this course from the beginning, you should remember strange lines like this one: ```csharp // x = (v.x+1)*(width-1)/2 // y = (v.y+1)*(height-1)/2 ``` What does it mean? It means that i have a point Vec2f v, it belongs to the square \[-1,1\]\*\[-1,1\]. I want to draw it in the image of (width, height) dimensions. Value (v.x\+1) is varying between 0 and 2, (v.x\+1)/2 between 0 and 1, and (v.x\+1)\*width/2 sweeps all the image. Thus we effectively mapped the bi-unit square onto the image. But now we are getting rid of these ugly constructs, and i want to rewrite all the computiations in the matrix form. Let us consider the following C# code: ```csharp /* Matrix4 Viewport (int x, int y, int w, int h) { var depth = 255f; var m = Matrix4.Identity (); m [0, 3] = x + w / 2f; m [1, 3] = y + h / 2f; m [2, 3] = depth / 2f; m [0, 0] = w / 2f; m [1, 1] = h / 2f; m [2, 2] = depth / 2f; return m; } */ ``` This code creates this matrix: ![ ](./img/lesson5_viewport.svg) It means that the bi-unit cube \[-1,1\]*\[-1,1\]*\[-1,1\] is mapped onto the screen cube \[0,w\]*\[0,h\]*\[0,d\]. Right, cube, and not a rectangle, this is because of the depth computations with the z-buffer. Here d is the resolution of the z-buffer. I like to have it equal to 255 because of simplicity of dumping black-and-white images of the z-buffer for debugging. In the OpenGL terminology this matrix is called viewport matrix. # Chain of coordinate transformations So, let us sum up. Our models (characters, for example) are created in their own local frame (**object coordinates**). They are inserted into a scene expressed in **world coordinates**. The transformation from one to another is made with matrix **Model**. Then, we want to express it in the camera frame (**eye coordinates**), the transformation is called **View**. Then, we deform the scene to create a perspective deformation with **Projection** matrix (lesson 4), this matrix transforms the scene to so-called **clip coordinates**. Finally, we draw the scene, and the matrix transforming clip coordinates to the **screen coordinates** is called **Viewport**. Again, if we read a point **v** from the .obj file, then to draw it on the screen it undergoes the following chain of transformations: Viewport \* Projection \* View \* Model \* v As i draw a single object only, the matrix Model is equal to identity, and i merged it with the matrix View: ```csharp var eye = new Vec3f { x = 1, y = 1, z = 3 }; var center = new Vec3f { x = 0, y = 0, z = 0 }; var up = new Vec3f { x = 0, y = 1, z = 0 }; // draw the model var modelView = LookAt(eye, center, up); var viewPort = Viewport(width/8, height/8, width*3/4, height*3/4); var projection = Projection(-1/(eye-center).Norm()); Func map = v => { var r4 = Mult (viewPort * projection * modelView, Embed4D (v)); var r = Project3D (r4 / r4.h); r.x = (int)(r.x + 0.5f); r.y = (int)(r.y + 0.5f); return r; }; var image = new Image(width, height, Format.BGR); var model = headModel; var zbuffer = InitZBuffer(image); foreach(var face in model.Faces) { for(int i=0; i<3; i++) { var vIndex = face.Vertices[i]; world[i] = model.Vertices[vIndex]; screen[i] = map(world[i]); var tIndex = face.Textures[i]; uv[i] = uvMap(headTexture, model.Textures[tIndex]); } Vec3f n = Cross(world[2] - world[0], world[1] - world[0]).Normalize (); var intensivity = Dot(n, light_dir); if(intensivity > 0) Triangle(image, screen, headTexture, uv, intensivity, zbuffer); } image.VerticalFlip (); image ``` # Transformation of normal vectors There is a widely-known fact: * If we have a model and its normal vectors are given by the artist AND this model is transformed with an affine mapping, then normal vectors are to be transformed with a mapping, equal to the transposition of the inverse matrix of the original mapping matrix What-what-what?! I met quite a few programmers who know this fact, but it remains a black magic for them. In fact, it is not so complicated. Take a pencil and draw a 2D triangle `(0,0)`, `(0,1)`, `(1,0)` and a vector **n**, normal to the hypothenuse. Naturally, **n** is equal to `(1,1)`. Then let us stretch all the y-coordinates by a factor of 2, leaving x-coordinates intact. Thus, our triangle becomes `(0,0)`, `(0,2)`, `(1,0)`. If we transform the vector **n** in the same way, it becomes `(1, 2)` and it is no longer orthogonal to the transformed edge of the triangle. Thus, to remove all the black magic fog, we need to understand one simple thing: **we do not need to simply transform normal vectors (as they can become not normal anymore), we need to compute (new) normal vectors to the transformed model.** Back to 3D, we have a vector **n** = (A,B,C). We know that the plane passing through the origin and having **n** for its normal, has an equation `Ax+By+Cz=0`. Let us write it in the matrix form (i do it in homogeneous coordinates from the beginning): ![ ](./img/lesson5_transform_normal1.png) Recall that `(A,B,C)` - is a vector, so we augment it with 0 when embedding into the 4D, and `(x,y,z)` is augmented with 1 since it is a point. Let us insert an identity matrix in between (inverse to M multiplied by M is equal to identity): ![ ](./img/lesson5_transform_normal2.png) The expression in right parentheses - are for the transformed points of the object. In the left - are for normal vectors to the transformed object! In standard convention we usually write coordinates as columns (please let us not raise all the stuff about contra- and co-variant vectors), so we can rewrite the previous expression as follows: ![ ](./img/lesson5_transform_normal2.png) And the left parentheses tell us that a normal to the transformed object can be computed from the old normal by applying the inverse transpose matrix of the affine mapping. Please note that if our transformation matrix M is a composition of uniform scalings, rotations and translations, then M is equal to its inverse transpose, since inverse and transpose are cancelling each other in this case. But since our matrices include perspective deformations, usually this trick does not help. In the current code we do not use the transformation of normal vectors, but in the next lesson it will be very, very handy. Happy coding! ================================================ FILE: graphics/tiny-renderer/lesson5.workbook/lesson1.csx ================================================ int width = 800; int height = 800; var headModel = Model.FromFile ("obj/african_head.obj"); static void Swap(ref T x, ref T y) { T t = y; y = x; x = t; } static void Swap(T[] arr, int x, int y) { T t = arr[y]; arr[y] = arr[x]; arr[x] = t; } Image Line (Image image, int x0, int y0, int x1, int y1, Color color) { bool steep = false; // if the line is steep, we transpose the image if (Math.Abs (x0-x1) < Math.Abs (y0-y1)) { Swap (ref x0, ref y0); Swap (ref x1, ref y1); steep = true; } if (x0 > x1) { // make it left to right Swap (ref x0, ref x1); Swap (ref y0, ref y1); } // (x0, y0) == (x1, y1) if(x0 == x1) { image [x0, y0] = color; } else { for (int x = x0; x <= x1; x++) { double t = (x-x0) / (double)(x1-x0); int y = (int)Math.Round(y0*(1-t) + y1*t); if (steep) image [y, x] = color; else image [x, y] = color; } } return image; } ================================================ FILE: graphics/tiny-renderer/lesson5.workbook/lesson1.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" ``` # **Lesson 1: Bresenham’s Line Drawing Algorithm** # First attempt The goal of the first lesson is to render the wire mesh. To do this, we should learn how to draw line segments. We can simply read what Bresenham’s line algorithm is, but let’s write code ourselves. How does the simplest code that draws a line segment between `(x0, y0)` and `(x1, y1)` points look like? Apparently, something like this: ```csharp Image Line (Image image, int x0, int y0, int x1, int y1, Color color) { for (double t = 0; t < 1; t += 0.01) { int x = (int) (x0 * (1-t) + x1 * t); int y = (int) (y0 * (1-t) + y1 * t); image [x, y] = color; } return image; } Line (new Image (100, 100, Format.BGR), x0: 13, y0: 20, x1: 80, y1: 40, color: Color.White); ``` # Second attempt The problem with this code (in addition to efficiency) is the choice of the constant, which I took equal to .01. If we take it equal to .1, our line segment will look like this: ```csharp Image Line (Image image, int x0, int y0, int x1, int y1, Color color) { for (int x = x0; x <= x1; x++) { double t = (x-x0)/(double)(x1-x0); int y = (int)(y0*(1-t) + y1*t); image [x, y] = color; } return image; } Line (new Image (100, 100, Format.BGR), x0: 13, y0: 20, x1: 80, y1: 40, color: Color.White); ``` Caution! The first source of errors in such code of my students is the integer division, like: `(x-x0)/(x1-x0)`. Then, if we try to draw the following lines with this code: ```csharp var image = new Image (100, 100, Format.BGR); Line(image, x0: 13, y0: 20, x1: 80, y1: 40, color: Color.White); Line(image, x0: 20, y0: 13, x1: 40, y1: 80, color: Color.Red); Line(image, x0: 80, y0: 40, x1: 13, y1: 20, color: Color.Red); ``` It turns out that one line is good, the second one is with holes, and there’s no third line at all. Note that the first and the third lines (in the code) draw the same line in different colors, and in different directions (with the source and target points flipped). We have already seen the white one, it is drawn well. I was hoping to change the color of the white line to red, but could not do it. It’s a test for symmetry: the result of drawing a line segment should not depend on the order of points: the `(a,b)` line segment should be exactly the same as the `(b,a)` line segment. # Third attempt We fix the missing red line by swapping the points so `x0` is always lower than `x1`. There are holes in one of the line segments due to the fact that its height is greater than the width. My students often suggest the following fix: `if (dx > dy) { for (int x) } else { for (int y) }` Holy cow! ```csharp static void Swap(ref T x, ref T y) { T t = y; y = x; x = t; } static void Swap(T[] arr, int x, int y) { T t = arr[y]; arr[y] = arr[x]; arr[x] = t; } Image Line (Image image, int x0, int y0, int x1, int y1, Color color) { bool steep = false; // if the line is steep, we transpose the image if (Math.Abs (x0-x1) < Math.Abs (y0-y1)) { Swap (ref x0, ref y0); Swap (ref x1, ref y1); steep = true; } if (x0 > x1) { // make it left to right Swap (ref x0, ref x1); Swap (ref y0, ref y1); } // (x0, y0) == (x1, y1) if(x0 == x1) { image [x0, y0] = color; } else { for (int x = x0; x <= x1; x++) { double t = (x-x0) / (double)(x1-x0); int y = (int)Math.Round(y0*(1-t) + y1*t); if (steep) image [y, x] = color; else image [x, y] = color; } } return image; } Line(image, x0: 13, y0: 20, x1: 80, y1: 40, color: Color.White); Line(image, x0: 20, y0: 13, x1: 40, y1: 80, color: Color.Red); Line(image, x0: 80, y0: 40, x1: 13, y1: 20, color: Color.Red); ``` # Wireframe rendering So now we are ready to create a wire render. You can find the snapshot of the code and the test model here. I used the [wavefront obj](http://en.wikipedia.org/wiki/Wavefront_.obj_file) format of the file to store model. All we need for the render is read from the file the array of vertices of the following type: `v 0.608654 -0.568839 -0.416318` are `x,y,z` coordinates, one vertex per file line and faces `f 1193/1240/1193 1180/1227/1180 1179/1226/1179` ```csharp int width = 800, height = 800; var headModel = Model.FromFile ("obj/african_head.obj"); var image = new Image(width, height, Format.BGR); foreach(var face in headModel.Faces) { for(int j=0; j<3; j++) { var v0 = headModel.Vertices[face.Vertices [j]]; var v1 = headModel.Vertices[face.Vertices [(j+1) % 3]]; // scale x from [-1..1] to [0..w] // scale y from [-1..1] to [0..h] int x0 = (int)((v0.x + 1) * width / 2); int y0 = (int)((v0.y + 1) * height / 2); int x1 = (int)((v1.x + 1) * width / 2); int y1 = (int)((v1.y + 1) * height / 2); Line(image, x0, y0, x1, y1, Color.White); } } image.VerticalFlip (); image ``` ================================================ FILE: graphics/tiny-renderer/lesson5.workbook/lesson2.csx ================================================ using static Geometry; var light_dir = new Vec3f { x = 0, y = 0, z = -1 }; var world = new Vec3f [3]; var screen = new Vec3f [3]; void Line (Image image, Vec2i p1, Vec2i p2, Color color) { Line(image, p1.x, p1.y, p2.x, p2.y, color); } void Line (Image image, Vec3f p1, Vec3f p2, Color color) { Line(image, (int)p1.x, (int)p1.y, (int)p2.x, (int)p2.y, color); } void Triangle (Image image, Vec2i[] t, Color color) { Line(image, t[0], t[1], color); Line(image, t[1], t[2], color); Line(image, t[2], t[0], color); } Vec3f Barycentric (Vec3f a, Vec3f b, Vec3f c, Vec2i p) { var pixel = new Vec3f { x = p.x + 0.5f, y = p.y + 0.5f }; var ab = b - a; var ac = c - a; var pa = a - pixel; var r = Cross (new Vec3f { x = ab.x, y = ac.x, z = pa.x }, new Vec3f { x = ab.y, y = ac.y, z = pa.y }); // triangle is degenerate, in this case return smth with negative coordinates if (Math.Abs (r.z) < 1) return new Vec3f { x = -1, y = 1, z = 1 }; return new Vec3f { x = 1 - r.x / r.z - r.y / r.z, y = r.x / r.z, z = r.y / r.z }; } void Triangle (Image image, Vec3f [] coordinates, Color color) { var t0 = coordinates [0]; var t1 = coordinates [1]; var t2 = coordinates [2]; var pMax = new Vec2i { x = (int)Math.Max (0, Math.Max (t0.x, Math.Max (t1.x, t2.x))), y = (int)Math.Max (0, Math.Max (t0.y, Math.Max (t1.y, t2.y))) }; var pMin = new Vec2i { x = (int)Math.Min (image.Width, Math.Min (t0.x, Math.Min (t1.x, t2.x))), y = (int)Math.Min (image.Height, Math.Min (t0.y, Math.Min (t1.y, t2.y))) }; Vec2i p; for (p.x = pMin.x; p.x <= pMax.x; p.x++) { for (p.y = pMin.y; p.y <= pMax.y; p.y++) { var bc = Barycentric (t0, t1, t2, p); if (bc.x < 0 || bc.y < 0 || bc.z < 0) continue; image [p.x, p.y] = color; } } } ================================================ FILE: graphics/tiny-renderer/lesson5.workbook/lesson2.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" #load "lesson1.csx" using static Geometry; ``` # Lesson 2: Triangle rasterization and back face culling # Old-school method: Line sweeping Thus, the task is to draw two-dimensional triangles. For motivated students it normally takes a couple of hours, even if they are bad programmers. Last time we saw Bresenham’s line drawing algorithm. Today’s task is to draw a filled triangle. Funny enough, but this task is not trivial. I don’t know why, but I know that it’s true. Most of my students struggle with this simple task. So, the initial stub will look like this: ```csharp void Line (Image image, Vec2i p1, Vec2i p2, Color color) { Line(image, p1.x, p1.y, p2.x, p2.y, color); } void Line (Image image, Vec3f p1, Vec3f p2, Color color) { Line(image, (int)p1.x, (int)p1.y, (int)p2.x, (int)p2.y, color); } void Triangle (Image image, Vec2i[] t, Color color) { Line(image, t[0], t[1], color); Line(image, t[1], t[2], color); Line(image, t[2], t[0], color); } Vec2i[] t0 = { new Vec2i { x = 10, y = 70 }, new Vec2i { x = 50, y = 160 }, new Vec2i { x = 70, y = 80 } }; Vec2i[] t1 = { new Vec2i { x = 180, y = 50 }, new Vec2i { x = 150, y = 1 }, new Vec2i { x = 70, y = 180 } }; Vec2i[] t2 = { new Vec2i { x = 180, y = 150 }, new Vec2i { x = 120, y = 160 }, new Vec2i { x = 130, y = 180 } }; var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); image.VerticalFlip (); image ``` The code is simple: I provide three triangles for the initial debugging of your code. If we invoke `Line` inside the triangle function, we’ll get the contour of the triangle. How to draw a filled triangle? A good method of drawing a triangle must have the following features: * It should be (surprise!) simple and fast. * It should be symmetrical: the picture should not depend on the order of vertices passed to the drawing function. * If two triangles have two common vertices, there should be no holes between them because of rasterization rounding. We could add more requirements, but let’s do with these ones. Traditionally a line sweeping is used: 1. Sort vertices of the triangle by their y-coordinates 2. Rasterize simultaneously the left and the right sides of the triangle 3. Draw a horizontal line segment between the left and the right boundary points At this point my students start to lose the firm ground: which segment is the left one, which one is right? Besides, there are three segments in a triangle... Usually, after this introduction I leave my students for about an hour: once again, reading my code is much less valuable than comparing your own code with mine. `[One hour passes]` How do I draw a triangle? Once again, if you have a better method, I’d be glad to adopt it. Let us assume that we have three points of the triangle: `t0`, `t1`, `t2`, they are sorted in ascending order by the y-coordinate. Then, the boundary A is between `t0` and `t2`, boundary B is between `t0` and `t1`, and then between `t1` and `t2`. ```csharp void OrderByY (Vec2i[] t) { if(t[0].y > t[1].y) Swap(t, 0, 1); if(t[1].y > t[2].y) Swap(t, 1, 2); if(t[0].y > t[1].y) Swap(t, 0, 1); } void Triangle (Image image, Vec2i[] t, Color color) { OrderByY(t); Line(image, t[0], t[1], Color.Green); Line(image, t[1], t[2], Color.Green); Line(image, t[2], t[0], Color.Red); } var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); // Here boundary A is red, and boundary B is green. image.VerticalFlip (); image ``` Unfortunately, boundary B is made of two parts. Let us draw the bottom half of the triangle by cutting it horizontally: ```csharp void Triangle (Image image, Vec2i[] t, Color color) { OrderByY(t); float height_10 = t[1].y - t[0].y; float height_20 = t[2].y - t[0].y; for(int y=t[0].y; y<=t[1].y; y++) { var alpha = (y-t[0].y) / height_20; var beta = (y-t[0].y) / height_10; // be careful with divisions by zero Vec2i A = new Vec2i { x = t[0].x + (int)((t[2].x-t[0].x)*alpha), y = y}; Vec2i B = new Vec2i { x = t[0].x + (int)((t[1].x-t[0].x)*beta), y = y}; image[A.x, y] = Color.Red; image[B.x, y] = Color.Green; } } var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); image.VerticalFlip (); image ``` Note that the segments are not continuous. Last time when we drew straight lines we struggled to get continuous segments and here I did not bother with rotating the image (remember the xy swapping?). Why? We fill the triangles aftewards, that’s why. If we connect the corresponding pairs of points by horizontal lines, the gaps disappear: ```csharp void Triangle (Image image, Vec2i[] t, Color color) { OrderByY(t); float height_10 = t[1].y - t[0].y; float height_20 = t[2].y - t[0].y; for(int y=t[0].y; y<=t[1].y; y++) { var alpha = (y-t[0].y) / height_20; var beta = (y-t[0].y) / height_10; // be careful with divisions by zero Vec2i A = new Vec2i { x = t[0].x + (int)((t[2].x-t[0].x)*alpha), y = y}; Vec2i B = new Vec2i { x = t[0].x + (int)((t[1].x-t[0].x)*beta), y = y}; Line(image, A, B, Color.White); image[B.x, y] = Color.Green; image[A.x, y] = Color.Red; } } var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); image.VerticalFlip (); image ``` Now, let us draw the second (upper) half of the triangle. We can do this by adding a second loop: ```csharp void Triangle (Image image, Vec2i[] t, Color color) { OrderByY(t); float height_10 = t[1].y - t[0].y; float height_20 = t[2].y - t[0].y; for(int y=t[0].y; y<=t[1].y; y++) { var alpha = (y-t[0].y) / height_20; var beta = (y-t[0].y) / height_10; // be careful with divisions by zero Vec2i A = new Vec2i { x = t[0].x + (int)((t[2].x-t[0].x)*alpha), y = y}; Vec2i B = new Vec2i { x = t[0].x + (int)((t[1].x-t[0].x)*beta), y = y}; if(A.x > B.x) Swap(ref A, ref B); for (int j=A.x; j<=B.x; j++) image[j, y] = color; } float height_21 = t[2].y - t[1].y; for(int y=t[1].y; y<=t[2].y; y++) { var alpha = (y-t[0].y) / height_20; var beta = (y-t[1].y) / height_21; // be careful with divisions by zero Vec2i A = new Vec2i { x = t[0].x + (int)((t[2].x-t[0].x)*alpha), y = y}; Vec2i B = new Vec2i { x = t[1].x + (int)((t[2].x-t[1].x)*beta), y = y}; if(A.x > B.x) Swap(ref A, ref B); for (int j=A.x; j<=B.x; j++) image[j, y] = color; } } var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); image.VerticalFlip (); image ``` This could be enough, but I dislike to see the same code twice. That is why we will make it a bit less readable, but more handy for modifications/maintaining: ```csharp void Triangle (Image image, Vec2i[] t, Color color) { // I dont care about degenerate triangles if(t[0].y == t[1].y && t[1].y == t[2].y) return; OrderByY(t); float height_10 = t[1].y - t[0].y; float total_height = t[2].y - t[0].y; for(int i=0; i t[1].y - t[0].y || t[1].y == t[0].y; float segment_height = second_half ? t[2].y-t[1].y : t[1].y-t[0].y; var alpha = i / total_height; // be careful with divisions by zero var beta = (i - (second_half ? t[1].y-t[0].y : 0)) / segment_height; Vec2i A = new Vec2i { x = t[0].x + (int)((t[2].x-t[0].x)*alpha), y = t[0].y + i }; Vec2i B = new Vec2i { x = second_half ? t[1].x + (int)((t[2].x-t[1].x)*beta) : t[0].x + (int)((t[1].x-t[0].x)*beta), y = t[0].y + i }; if(A.x > B.x) Swap(ref A, ref B); for (int j=A.x; j<=B.x; j++) image[j, t[0].y + i] = color; } } var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); image.VerticalFlip (); image ``` # The method I adopt for my code While not being really complicated, the source code for the line sweeping is a bit messy. Moreover, it is really an old-school approach designed for mono-thread CPU programming. Let us take a look at the following pseudo-code: ```csharp // triangle(Vec2i[] points) { // Vec2i bbox[2] = find_bounding_box(points); // for (each pixel in the bounding box) { // if (inside(points, pixel)) { // put_pixel(pixel); // } // } // } ``` Do you like it? I do. It is really easy to find a bounding box. It is certainly no problem to check whether a point belongs a 2D triangle (or any convex polygon). *Off Topic: if I have to implement some code to check whether a point belongs to a polygon, and this program will run on a plane, I will never get on this plane. Turns out, it is a surprisingly difficult task to solve this problem reliably. But here we just painting pixels. I am okay with that.* There is another thing I like about this pseudocode: a neophyte in programming accepts it with enthusiasm, more experienced programmers often chuckle: “*What an idiot wrote it?*”. And an expert in computer graphics programming will shrug his shoulders and say: “*Well, that’s how it works in real life*”. Massively parallel computations in thousands of threads (i’m talking about regular consumer computers here) change the way of thinking. Okay, let us start: first of all we need to know what the [barycentric coordinates](https://en.wikipedia.org/wiki/Barycentric_coordinate_system) are. Given a 2D triangle ABC and a point P, all in old good Cartesian coordinates `(xy)`. Our goal is to find barycentric coordinates of the point P with respect to the triangle ABC. It means that we look for three numbers `(1 − u − v,u,v)` such that we can find the point P as follows: ![ ](./img/lesson2_f1.png) While being a bit frightening at the first glance, it is really simple: imagine that we put three weights `(1−u−v,u,v)` at the vertices A, B and C, respectively. Then the barycenter of the system is exactly in the point P. We can say the same thing with other words: the point P has coordinates `(u,v)` in the (oblique) basis (A,![](./img/lesson2_ab.png),![](./img/lesson2_ac.png)): ![ ](./img/lesson2_f2.png) So, we have vectors ![](./img/lesson2_ab.png), ![](./img/lesson2_ac.png) and ![](./img/lesson2_ap.png), we need to find two real numbers u and v respecting the following constraint: ![ ](./img/lesson2_f3.png) It is a simple vector equation, or a linear system of two equations with two variables: ![ ](./img/lesson2_f4.png) I am lazy and do not want to solve linear systems in a scholar way. Let us write it in matrix form: ![ ](./img/lesson2_f5.png) It means that we are looking for a vector `(u,v,1)` that is orthogonal to `(ABx,ACx,PAx)` and `(ABy,ACy,PAy)` *at the same time*! I hope you see [where I am heading](https://en.wikipedia.org/wiki/Cross_product). That is a small hint: to find an intersection of two straight lines in a plane (that is exactly what we did here), it is sufficient to compute one cross product. By the way, test yourself: how do we find an equation of a line passing through two given points? So, let us program our new rasterization routine: we iterate through all pixels of a bounding box for a given triangle. For each pixel we compute its barycentric coordinates. If it has at least one negative component, then the pixel is outside of the triangle. Probably it is more clear to see the program directly: ```csharp Vec3f Barycentric (Vec3f a, Vec3f b, Vec3f c, Vec2i p) { var pixel = new Vec3f { x = p.x + 0.5f, y = p.y + 0.5f }; var ab = b - a; var ac = c - a; var pa = a - pixel; var r = Cross (new Vec3f { x = ab.x, y = ac.x, z = pa.x }, new Vec3f { x = ab.y, y = ac.y, z = pa.y }); // triangle is degenerate, in this case return smth with negative coordinates if (Math.Abs (r.z) < 1) return new Vec3f { x = -1, y = 1, z = 1 }; return new Vec3f { x = 1 - r.x / r.z - r.y / r.z, y = r.x / r.z, z = r.y / r.z }; } void Triangle (Image image, Vec3f [] coordinates, Color color) { var t0 = coordinates [0]; var t1 = coordinates [1]; var t2 = coordinates [2]; var pMax = new Vec2i { x = (int)Math.Max (0, Math.Max (t0.x, Math.Max (t1.x, t2.x))), y = (int)Math.Max (0, Math.Max (t0.y, Math.Max (t1.y, t2.y))) }; var pMin = new Vec2i { x = (int)Math.Min (image.Width, Math.Min (t0.x, Math.Min (t1.x, t2.x))), y = (int)Math.Min (image.Height, Math.Min (t0.y, Math.Min (t1.y, t2.y))) }; Vec2i p; for (p.x = pMin.x; p.x <= pMax.x; p.x++) { for (p.y = pMin.y; p.y <= pMax.y; p.y++) { var bc = Barycentric (t0, t1, t2, p); if (bc.x < 0 || bc.y < 0 || bc.z < 0) continue; image [p.x, p.y] = color; } } } ``` # Flat shading render We already know how to draw a model with empty triangles. Let us fill them with a random color. This will help us to see how well we have encoded filling of triangles. Here is the code: ```csharp var image = new Image(width, height, Format.BGR); // Map world coordinates [-1..-1] to screen coordinates [0..width] Func map = v => new Vec3f { x = (int)((v.x+1)*image.Width/2), y = (int)((v.y+1)*image.Height/2) }; var rnd = new Random(); Func rndByte = () => (byte)rnd.Next(255); Func rndColor = () => new Color(rndByte(), rndByte(), rndByte()); var coordinates = new Vec3f[3]; foreach(var face in headModel.Faces) { for(int i=0; i<3; i++) { var vIndex = face.Vertices[i]; var v = headModel.Vertices[vIndex]; coordinates[i] = map(v); } Triangle(image, coordinates, rndColor()); } image.VerticalFlip (); image ``` Let us get rid of these clown-colors and put some lighting. Captain Obvious: ”*At the same light intensity, the polygon is illuminated most brightly when it is orthogonal to the light direction.*” Let us compare: ![ ](./img/lesson2_light1.jpeg) ![](./img/lesson2_light2.jpeg) We get zero illumination if the polygon is parallel to the vector of light. To paraphrase: the intensity of illumination is equal to the scalar product of the light vector and the normal to the given triangle. The normal to the triangle can be calculated simply as the [cross product](https://en.wikipedia.org/wiki/Cross_product) of its two sides. As a side note, at this course we will perform linear computations on the colors. However `(128,128,128)` color is not half as bright as `(255, 255, 255)`. We are going to ignore gamma correction and tolerate the incorrectness of the brightness of our colors. ```csharp var image = new Image (width, height, Format.BGR); var light_dir = new Vec3f { x = 0, y = 0, z = -1 }; var world = new Vec3f [3]; var screen = new Vec3f [3]; foreach (var face in headModel.Faces) { for (int i = 0; i < 3; i++) { var vIndex = face.Vertices [i]; world [i] = headModel.Vertices [vIndex]; screen [i] = map (world [i]); } var n = Cross (world [2] - world [0], world [1] - world [0]).Normalize (); var intensivity = Dot (n, light_dir); if (intensivity > 0) Triangle (image, screen, Color.White * intensivity); } image.VerticalFlip (); image ``` ================================================ FILE: graphics/tiny-renderer/lesson5.workbook/lesson3.csx ================================================ using static Geometry; var headTexture = Image.Load ("obj/african_head_diffuse.tga"); headTexture.VerticalFlip (); float [] InitZBuffer (Image image) { var zbuffer = new float [image.Width * image.Height]; for (int idx = 0; idx < zbuffer.Length; idx++) zbuffer [idx] = float.NegativeInfinity; return zbuffer; } Vec3f Barycentric (Vec2f a, Vec2f b, Vec2f c, Vec2f p) { var ab = b - a; var ac = c - a; var pa = a - p; var r = Cross (new Vec3f { x = ab.x, y = ac.x, z = pa.x }, new Vec3f { x = ab.y, y = ac.y, z = pa.y }); // triangle is degenerate, in this case return smth with negative coordinates // dont forget that r.z is integer. If it is zero then triangle ABC is degenerate if ((int)r.z == 0) return new Vec3f { x = -1, y = 1, z = 1 }; return new Vec3f { x = 1 - (r.x + r.y) / r.z, y = r.x / r.z, z = r.y / r.z }; } void Triangle (Image image, Vec3f [] coordinates, Image texture, Vec2f [] uv, float intensivity, float [] zbuffer) { Vec3f t0 = coordinates [0]; Vec3f t1 = coordinates [1]; Vec3f t2 = coordinates [2]; var pMax = new Vec2i { x = (int)Math.Max (0, Math.Max (t0.x, Math.Max (t1.x, t2.x))), y = (int)Math.Max (0, Math.Max (t0.y, Math.Max (t1.y, t2.y))) }; var pMin = new Vec2i { x = (int)Math.Min (image.Width, Math.Min (t0.x, Math.Min (t1.x, t2.x))), y = (int)Math.Min (image.Height, Math.Min (t0.y, Math.Min (t1.y, t2.y))) }; for (int x = pMin.x; x <= pMax.x; x++) { for (int y = pMin.y; y <= pMax.y; y++) { var pixelCenter = new Vec2f { x = x + 0.5f, y = y + 0.5f }; var bc = Barycentric (Project2D(t0), Project2D(t1), Project2D(t2), pixelCenter); if (bc.x < 0 || bc.y < 0 || bc.z < 0) continue; var z = t0.z * bc.x + t1.z * bc.y + t2.z * bc.z; var u = (int)(uv [0].x * bc.x + uv [1].x * bc.y + uv [2].x * bc.z); var v = (int)(uv [0].y * bc.x + uv [1].y * bc.y + uv [2].y * bc.z); var idx = x + y * image.Width; if (zbuffer [idx] < z) { zbuffer [idx] = z; var color = texture [u, v]; image [x, y] = color * intensivity; } } } } ================================================ FILE: graphics/tiny-renderer/lesson5.workbook/lesson3.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" #load "lesson1.csx" #load "lesson2.csx" using static Geometry; ``` # **Lesson 3: Hidden faces removal (z buffer)** # Introduction Hello, let me introduce you my friend z-buffer of a black guy. He will help us get rid of the visual artifacts of the hidden faces removal we had during the last lesson. ![](./img/lesson3_face1.png) By the way, i'd like to mention that this model i use heavily in the course is created by [Vidar Rapp](https://se.linkedin.com/in/vidarrapp). He kindely granted me a permission to use it for teaching rendering basics and i vandalized it, but i promise you to give back the eyes to the guy. Well, back to the topic, in theory we could just draw all the triangles without discarding any. If we do it properly starting rear-to-front, the front facets will erase the back ones. It is called the [painter's algorithm](http://en.wikipedia.org/wiki/Painter%27s_algorithm). Unfortunately, it comes along with a high computational cost: for each camera movement we need to re-sort all the scene. And then there are dynamic scenes... And this is not even the main problem. The main problem is it is not always possible to determine the correct order. # **Let us try to render a simple scene** Imagine a simple scene made of three triangles: the camera looks up-to-down, we project the colored triangles onto the white screen: ![ ](./img/lesson3_scene1.png) The render should look like this: ![ ](./img/lesson3_scene2.png) Blue facet - is it behind or in front of the red one? The painter's algorithm does not work here. It is possible to split blue facet in two (one in front of the red facet and one behind). And then the one in front of the red one is to be split in two - one in front of the green triangle and one behind... I think you get the problem: in scenes with millions of triangles it is really expensive to compute. It is possible to use [BSP trees](https://en.wikipedia.org/wiki/Binary_space_partitioning) to get it done. By the way, this data structure is constant for moving camera, but it is really messy. And the life is too short to get it messy. # **Even simpler: let us lose a dimension. Y-buffer!** Let us lose a dimension for a while and to cut the above scene along the yellow plane: ![ ](./img/lesson3_scene3.png) I mean, now our scene is made of three line segments (intersection of the yellow plane and each of the triangles), and the final render has a normal width but 1 pixel height: ![ ](./img/lesson3_scene4.png) Our scene is two-dimensional, so it is easy to draw it using the line() function we programmed in the very first lesson. ```csharp var scene = new Image (800, 500, Format.BGR); // scene "2d mesh" Line(scene, new Vec2i {x=20, y=34}, new Vec2i {x=744, y=400}, Color.Red); Line(scene, new Vec2i {x=120, y=434}, new Vec2i {x=444, y=400}, Color.Green); Line(scene, new Vec2i {x=330, y=463}, new Vec2i {x=594, y=200}, Color.Blue); // screen line Line(scene, new Vec2i {x=10, y=10}, new Vec2i{x=790, y=10}, Color.White); scene.VerticalFlip(); // I want to have the origin at the left bottom corner of the image scene // This is how our 2D scene looks like if we look at it sideways: ``` Let us render it. Recall that the render is 1 pixel height. In my source code I create images 16 pixels height for the ease of reading on high resolution screens. `Rasterize()` function writes only in the first line of the image `render` ```csharp void Rasterize(Image image, Vec2i p0, Vec2i p1, int[] ybuffer, Color color) { if (p0.x>p1.x) Swap(ref p0, ref p1); for (int x=p0.x; x<=p1.x; x++) { float t = (x-p0.x)/(float)(p1.x-p0.x); var y = (int)(p0.y*(1-t) + p1.y*t); if (ybuffer[x] < y) { ybuffer[x] = y; image[x, 0] = color; } } } var ybuffer = new int [width]; for (int i = 0; i < width; i++) ybuffer[i] = int.MinValue; var render = new Image (width, 16, Format.BGR); Rasterize(render, new Vec2i{x=20,y=34}, new Vec2i{x=744, y=400}, ybuffer, Color.Red); Rasterize(render, new Vec2i{x=120, y=434}, new Vec2i{x=444,y=400}, ybuffer, Color.Green); Rasterize(render, new Vec2i{x=330, y=463}, new Vec2i{x=594,y=200}, ybuffer, Color.Blue); render ``` It is really-really simple: I iterate through all x-coordinates between `p0.x` and `p1.x` and compute the corresponding y-coordinate of the segment. Then I check what we got in our array `ybuffer` with current `x` index. If the current `y`-value is closer to the camera than the value in the `ybuffer`, then I draw it on the screen and update the `ybuffer`. Let us see it step-by-step. After calling `Rasterize()` on the first (red) segment this is our memory: screen:![](./img/lesson3_rasterize1.png) ybuffer: ![ ](./img/lesson3_rasterize2.png) Here the magenta color indicates the minus infinity, those are places corresponding to the screen we did not touch. All the rest is shown in the shades of gray: clear colors are close to the camera, dark colors far from the camera. Then we draw the green segment. screen:![ ](./img/lesson3_rasterize3.png) ybuffer:![ ](./img/lesson3_rasterize4.png) And finally the blue one. screen:![ ](./img/lesson3_rasterize5.png) ybuffer:![ ](./img/lesson3_rasterize6.png) Congratulations, we just drew a 2D scene on a 1D screen! Let us admire once again the render: ![ ](./img/lesson3_rasterize7.png) # Back to 3D So, for drawing on a 2D screen the z-buffer must be two-dimensional: `var zbuffer = new int[width * height];` Personally I pack a two-dimensional buffer into a one-dimensional, the conversion is trivial: `var idx = x + y* width;` and the back one: `var x = idx % width;`\ `var y = idx % width;` Then in the code I simply iterate through all the triangles and call the rasterizer function with current triangle and a reference to the z-buffer. The only difficulty is how to compute the z-value of a pixel we want to draw. Let us recall how we computed the y-value in the y-buffer example: `int y = p0.y*(1-t) + p1.y*t;` What is the nature of the `t` variable? It turns out that `(1-t, t)` are barycentric coordinates of the point `(x,y)` with respect to the segment `p0, p1: (x,y) = p0*(1-t) + p1*t`. So the idea is to take the barycentric coordinates version of triangle rasterization, and for every pixel we want to draw simply to multiply its barycentric coordinates by the z-values of the vertices of the triangle we rasterize: ```csharp Vec3f Barycentric (Vec2f a, Vec2f b, Vec2f c, Vec2f p) { var ab = b - a; var ac = c - a; var pa = a - p; var r = Cross (new Vec3f { x = ab.x, y = ac.x, z = pa.x }, new Vec3f { x = ab.y, y = ac.y, z = pa.y }); // triangle is degenerate, in this case return smth with negative coordinates // dont forget that r.z is integer. If it is zero then triangle ABC is degenerate if ((int)r.z == 0) return new Vec3f { x = -1, y = 1, z = 1 }; return new Vec3f { x = 1 - (r.x + r.y) / r.z, y = r.x / r.z, z = r.y / r.z }; } void Triangle (Image image, Vec3f [] coordinates, Color color, float [] zbuffer) { Vec3f t0 = coordinates [0]; Vec3f t1 = coordinates [1]; Vec3f t2 = coordinates [2]; var pMax = new Vec2i { x = (int)Math.Max (0, Math.Max (t0.x, Math.Max (t1.x, t2.x))), y = (int)Math.Max (0, Math.Max (t0.y, Math.Max (t1.y, t2.y))) }; var pMin = new Vec2i { x = (int)Math.Min (image.Width, Math.Min (t0.x, Math.Min (t1.x, t2.x))), y = (int)Math.Min (image.Height, Math.Min (t0.y, Math.Min (t1.y, t2.y))) }; for (int x = pMin.x; x <= pMax.x; x++) { for (int y = pMin.y; y <= pMax.y; y++) { var pixelCenter = new Vec2f { x = x + 0.5f, y = y + 0.5f }; var bc = Barycentric (Project2D (t0), Project2D (t1), Project2D (t2), pixelCenter); if (bc.x < 0 || bc.y < 0 || bc.z < 0) continue; var z = t0.z * bc.x + t1.z * bc.y + t2.z * bc.z; var idx = x + y * image.Width; if (zbuffer [idx] < z) { zbuffer [idx] = z; image [x, y] = color; } } } } float [] InitZBuffer (Image image) { var zbuffer = new float [image.Width * image.Height]; for (int idx = 0; idx < zbuffer.Length; idx++) zbuffer [idx] = float.NegativeInfinity; return zbuffer; } var image = new Image(width, height, Format.BGR); Func map = v => new Vec3f { x = (int)((v.x+1)*(image.Width-1)/2 + 0.5f), y = (int)((v.y+1)*(image.Height-1)/2 + 0.5f), z = v.z }; var zbuffer = InitZBuffer(image); foreach(var face in headModel.Faces) { for(int i=0; i<3; i++) { var vIndex = face.Vertices[i]; world[i] = headModel.Vertices[vIndex]; screen[i] = map(world[i]); } Vec3f n = Cross(world[2] - world[0], world[1] - world[0]).Normalize (); var intensivity = Dot(n, light_dir); if(intensivity > 0) Triangle(image, screen, Color.White * intensivity, zbuffer); } image.VerticalFlip (); image ``` # Okay, we just interpolated the z-values. What else can we do? Texture! In the `.obj` file we have lines starting with `vt u v`, they give an array of texture coordinates. The number in the middle (between the slashes) in the facet lines\ `f x/x/x x/x/x x/x/x` are the texture coordinates of this vertex of this triangle. Interpolate it inside the triangle, multiply by the width-height of the texture image and you will get the color to put in your render. ```csharp void Triangle (Image image, Vec3f [] coordinates, Image texture, Vec2f [] uv, float intensivity, float [] zbuffer) { Vec3f t0 = coordinates [0]; Vec3f t1 = coordinates [1]; Vec3f t2 = coordinates [2]; var pMax = new Vec2i { x = (int)Math.Max (0, Math.Max (t0.x, Math.Max (t1.x, t2.x))), y = (int)Math.Max (0, Math.Max (t0.y, Math.Max (t1.y, t2.y))) }; var pMin = new Vec2i { x = (int)Math.Min (image.Width, Math.Min (t0.x, Math.Min (t1.x, t2.x))), y = (int)Math.Min (image.Height, Math.Min (t0.y, Math.Min (t1.y, t2.y))) }; for (int x = pMin.x; x <= pMax.x; x++) { for (int y = pMin.y; y <= pMax.y; y++) { var pixelCenter = new Vec2f { x = x + 0.5f, y = y + 0.5f }; var bc = Barycentric (Project2D(t0), Project2D(t1), Project2D(t2), pixelCenter); if (bc.x < 0 || bc.y < 0 || bc.z < 0) continue; var z = t0.z * bc.x + t1.z * bc.y + t2.z * bc.z; var u = (int)(uv [0].x * bc.x + uv [1].x * bc.y + uv [2].x * bc.z); var v = (int)(uv [0].y * bc.x + uv [1].y * bc.y + uv [2].y * bc.z); var idx = x + y * image.Width; if (zbuffer [idx] < z) { zbuffer [idx] = z; var color = texture [u, v]; image [x, y] = color * intensivity; } } } } var image = new Image(width, height, Format.BGR); var headTexture = Image.Load ("obj/african_head_diffuse.tga"); headTexture.VerticalFlip (); Func uvMap = v => new Vec2f { x = v.x * (headTexture.Width - 1), y = v.y * (headTexture.Height - 1) }; var zbuffer = InitZBuffer(image); var uv = new Vec2f[3]; var model = headModel; foreach(var face in model.Faces) { for(int i=0; i<3; i++) { var vIndex = face.Vertices[i]; world[i] = model.Vertices[vIndex]; screen[i] = map(world[i]); var tIndex = face.Textures[i]; uv[i] = uvMap(model.Textures[tIndex]); } Vec3f n = Cross(world[2] - world[0], world[1] - world[0]).Normalize (); var intensivity = Dot(n, light_dir); if(intensivity > 0) Triangle(image, screen, headTexture, uv, intensivity, zbuffer); } image.VerticalFlip (); image ``` ================================================ FILE: graphics/tiny-renderer/lesson5.workbook/lesson4.csx ================================================ Vec2f[] uv = new Vec2f [3]; Func uvMap = (texture, v) => new Vec2f { x = v.x * (texture.Width - 1), y = v.y * (texture.Height - 1) }; Matrix4 Viewport (int x, int y, int w, int h) { var depth = 255f; var m = Matrix4.Identity (); m [0, 3] = x + w / 2f; m [1, 3] = y + h / 2f; m [2, 3] = depth / 2f; m [0, 0] = w / 2f; m [1, 1] = h / 2f; m [2, 2] = depth / 2f; return m; } Matrix4 Projection (float coeff) { var projection = Matrix4.Identity (); projection [3, 2] = coeff; return projection; } ================================================ FILE: graphics/tiny-renderer/lesson5.workbook/lesson4.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Matrix.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" #load "lesson1.csx" #load "lesson2.csx" #load "lesson3.csx" using static Geometry; using static MatrixHelpers; ``` # **Lesson 4: Perspective projection** # The goal In previous lessons we rendered our model in orthographic projection by simply forgetting the z-coordinate. The goal for today is to learn how to draw in perspective: ![ ](./img/lesson4_the_goal.png) # 2D geometry: Linear transformations A linear transformation on a plane can be represented by a corresponding matrix. If we take a point `(x,y)` then its transformation can be written as follows: ![ ](./img/lesson4_formula1.svg) The simplest (not degenerate) transformation is the identity, it does not move any point: ![ ](./img/lesson4_formula_2d_identity.svg) Diagonal coefficients of the matrix give scaling along coordinate axes. Let us illustrate it, if we take the following transformation: ![ ](./img/lesson4_formula_2d_scale.svg) Then the white object (the white square with one corner chopped) will be transformed into the yellow one. Red and green line segments give unit length vectors aligned with `x` and `y`, respectively. All the images for this article were generated using this code: ```csharp Matrix4 Viewport (int x, int y, int w, int h) { var depth = 255f; var m = Matrix4.Identity (); m [0, 3] = x + w / 2f; m [1, 3] = y + h / 2f; m [2, 3] = depth / 2f; m [0, 0] = w / 2f; m [1, 1] = h / 2f; m [2, 2] = depth / 2f; return m; } Matrix4 Projection (float coeff) { var projection = Matrix4.Identity (); projection [3, 2] = coeff; return projection; } Vec4f Embed4D (Vec3f v, float fill = 1) { return new Vec4f { x = v.x, y = v.y, z = v.z, h = fill }; } Vec3f Project3D (Vec4f v) { return new Vec3f { x = v.x, y = v.y, z = v.z }; } Func map = v => Project3D(v/v.h); void RenderAxes (Image image) { var w = image.Width; var h = image.Height; var vp = Viewport(w/4, w/4, w/2, h/2); // draw the axes var x = new Vec3f { x = 1 }; var y = new Vec3f { y = 1 }; var o = new Vec3f (); o = map(Mult(vp, Embed4D(o))); x = map(Mult(vp, Embed4D(x))); y = map(Mult(vp, Embed4D(y))); Line(image, o, x, Color.Red); Line(image, o, y, Color.Green); } var cube = Model.FromFile("obj/cube.obj"); void RenderCube(Image image, Matrix4 deformation, Color color) { var w = image.Width; var h = image.Height; var vp = Viewport(w/4, w/4, w/2, h/2); var face = cube.Faces[0]; var faceLen = face.Vertices.Length; for(int j=0; j x/(c-z) = x'/c. In other words: ![ ](./img/lesson4_formula_x.svg) By doing the same reasoning for triangles CPB and CP'D, it is easy to find the following expression: ![](./img/lesson4_formula_y.svg) It is really similar to the result we put aside few moments ago, but there we got the result by a single matrix multiplication. We got the law for the coefficient: `r = -1/c` # Let us sum up: the main formula for today *If you simply copy-paste this formula without understanding the above material, I hate you.* So, if we want to compute a central projection with a camera **(important!) camera located on the z-axis with distance c from the origin**, then we embed the point into 4D by augmenting it with 1, then we multiply it with the following matrix, and retro-project it into 3D. ![ ](./img/lesson4_formula_last.svg) We deformed our object in a way, that simply forgetting its z-coordinate we will get a drawing in a perspective. If we want to use the z-buffer, then, naturally, do not forget the z: ```csharp var image = new Image(width, height, Format.BGR); var camera = new Vec3f { z = 3 }; var projection = Projection(-1/camera.z); var viewPort = Viewport(width/8, height/8, width*3/4, height*3/4); Func map = v => { var r4 = Mult (viewPort * projection, Embed4D (v)); var r = Project3D (r4 / r4.h); r.x = (int)(r.x + 0.5f); r.y = (int)(r.y + 0.5f); return r; }; Func uvMap = (texture, v) => new Vec2f { x = v.x * (texture.Width - 1), y = v.y * (texture.Height - 1) }; var model = headModel; var zbuffer = InitZBuffer(image); Vec2f[] uv = new Vec2f [3]; foreach(var face in model.Faces) { for(int i=0; i<3; i++) { var vIndex = face.Vertices[i]; world[i] = model.Vertices[vIndex]; screen[i] = map(world[i]); var tIndex = face.Textures[i]; uv[i] = uvMap(headTexture, model.Textures[tIndex]); } Vec3f n = Cross(world[2] - world[0], world[1] - world[0]).Normalize (); var intensivity = Dot(n, light_dir); if(intensivity > 0) Triangle(image, screen, headTexture, uv, intensivity, zbuffer); } image.VerticalFlip (); image ``` ================================================ FILE: graphics/tiny-renderer/lesson5.workbook/lesson5.csx ================================================ using static Geometry; var eye = new Vec3f { x = 1, y = 1, z = 3 }; var center = new Vec3f { x = 0, y = 0, z = 0 }; var up = new Vec3f { x = 0, y = 1, z = 0 }; Matrix4 LookAt (Vec3f eye, Vec3f center, Vec3f up) { var z = (eye - center).Normalize (); var x = Cross (up, z).Normalize (); var y = Cross (z, x).Normalize (); var Minv = Matrix4.Identity (); Minv [0, 0] = x.x; Minv [0, 1] = x.y; Minv [0, 2] = x.z; Minv [1, 0] = y.x; Minv [1, 1] = y.y; Minv [1, 2] = y.z; Minv [2, 0] = z.x; Minv [2, 1] = z.y; Minv [2, 2] = z.z; var Tr = Matrix4.Identity (); Tr [0, 3] = -center.x; Tr [1, 3] = -center.y; Tr [2, 3] = -center.y; return Minv * Tr; } ================================================ FILE: graphics/tiny-renderer/lesson5.workbook/obj/african_head.obj ================================================ v -0.000581696 -0.734665 -0.623267 v 0.000283538 -1 0.286843 v -0.117277 -0.973564 0.306907 v -0.382144 -0.890788 0.221243 v -0.247144 -0.942602 0.276051 v -0.656078 -0.718512 -0.109025 v -0.609847 -0.786562 0.0198068 v -0.66248 -0.632053 -0.244271 v -0.511812 -0.845392 0.127809 v -0.609326 -0.569868 -0.41571 v -0.426949 -0.649767 -0.567143 v -0.201076 -0.720822 -0.633205 v 0.117382 -0.973645 0.306766 v 0.382454 -0.890869 0.221097 v 0.247512 -0.942667 0.275986 v 0.656371 -0.718624 -0.109224 v 0.610273 -0.786562 0.0197893 v 0.66248 -0.631463 -0.244119 v 0.511631 -0.845357 0.127832 v 0.608654 -0.568839 -0.416318 v 0.424663 -0.649937 -0.567418 v 0.198972 -0.720968 -0.633141 v 0.153371 -0.140519 0.477416 v 0.134781 -0.14723 0.48805 v 0.131261 -0.132153 0.49872 v 0.14749 -0.135105 0.489565 v 0.000686924 -0.0534984 0.505694 v 0.075062 -0.0473306 0.49955 v 0.0695841 -0.0997942 0.550277 v 0.0302569 -0.0971868 0.55389 v 0.0745124 -0.135953 0.523215 v 0.0354892 -0.12785 0.535159 v 0.0389268 -0.109557 0.550558 v 0.0734835 -0.11538 0.538029 v 0.106386 -0.125623 0.51513 v 0.107415 -0.144295 0.5047 v 0.15968 -0.130861 0.484794 v 0.156224 -0.123705 0.486735 v 0.15792 -0.107798 0.4677 v 0.163784 -0.126996 0.470144 v 0.154687 -0.134655 0.486373 v 0.160668 -0.135649 0.476189 v 0.143433 -0.119034 0.499854 v 0.131606 -0.0726738 0.476148 v -0.000260156 -0.124553 0.539058 v -0.000646004 -0.110651 0.55444 v 0.100423 -0.10574 0.537643 v 0.126128 -0.115784 0.515598 v 0.250944 -0.275583 0.380381 v 0.221602 -0.335752 0.330174 v 0.275434 -0.301318 0.24751 v 0.307699 -0.239869 0.292356 v 0.332124 -0.0415605 0.412962 v 0.319444 0.00732526 0.451091 v 0.28667 -0.025805 0.481549 v 0.297006 -0.0758717 0.454242 v 0.357953 -0.159928 -0.223225 v 0.303981 -0.144611 -0.343644 v 0.296386 -0.0547553 -0.357792 v 0.357339 -0.0633433 -0.24278 v 0.45086 0.331215 0.047962 v 0.438899 0.336167 0.131147 v 0.447405 0.226107 0.139349 v 0.455613 0.205353 0.0827643 v 0.197493 -0.411308 0.138256 v 0.204911 -0.353378 0.2082 v 0.102001 -0.419375 0.24969 v 0.0995867 -0.475697 0.20834 v 0.150133 -0.372261 0.431226 v 0.176423 -0.362054 0.392056 v 0.196019 -0.326474 0.426929 v 0.154611 -0.348549 0.463444 v 0.0892273 -0.391968 0.303592 v 0.159013 -0.363737 0.305077 v 0.455712 0.508986 -0.0641442 v 0.432146 0.648411 -0.0417475 v 0.417051 0.611568 0.0817295 v 0.44205 0.483438 0.0478626 v 0.3446 0.43288 0.398633 v 0.372358 0.383369 0.353998 v 0.388341 0.404485 0.306953 v 0.355059 0.467372 0.356967 v 0.305162 0.338815 0.458112 v 0.298579 0.319803 0.456627 v 0.313422 0.304568 0.427776 v 0.323711 0.315968 0.429291 v 0.33161 0.397557 0.430226 v 0.354427 0.359727 0.390478 v 0.304162 0.291952 0.432377 v 0.292662 0.309771 0.452991 v 0.282934 0.292496 0.4562 v 0.292025 0.281663 0.435178 v 0.397344 0.565249 0.192585 v 0.42257 0.455996 0.145494 v 0.317848 0.364866 0.448834 v 0.340595 0.337517 0.417978 v 0.243227 0.479439 0.494236 v 0.250155 0.546138 0.465934 v 0.179019 0.560251 0.511681 v 0.170173 0.4781 0.536229 v 0.162386 0.410407 0.547009 v 0.235031 0.427051 0.517018 v 0.271745 0.634415 0.42162 v 0.196896 0.657291 0.472505 v 0.186589 0.312952 0.511073 v 0.189518 0.32493 0.514165 v 0.146286 0.31277 0.509009 v 0.144959 0.300178 0.501713 v 0.143965 0.300412 0.49409 v 0.187203 0.310596 0.506407 v 0.157744 0.364614 0.528804 v 0.216697 0.382527 0.516083 v 0.194441 0.332425 0.515989 v 0.204286 0.349818 0.516732 v 0.156254 0.334062 0.519579 v 0.151565 0.320341 0.513961 v 0.0431068 0.071791 0.618005 v 0.0477954 0.0867105 0.593486 v 0.0780844 0.0816652 0.602518 v 0.0574124 0.0746147 0.621185 v 0.448253 0.130656 0.149533 v 0.431801 0.159355 0.215905 v 0.422792 0.0771637 0.237185 v 0.428691 0.0348783 0.166914 v 0.365073 -0.0526507 0.316126 v 0.326974 -0.104793 0.373068 v 0.312773 -0.172965 0.33446 v 0.368107 -0.126698 0.269222 v 0.203695 -0.131796 0.523934 v 0.180463 -0.136479 0.525396 v 0.182848 -0.14892 0.516989 v 0.204163 -0.152533 0.514914 v 0.39379 0.00616771 0.269368 v 0.40177 -0.0591341 0.209048 v 0.26083 -0.0996422 0.484274 v 0.250406 -0.0552171 0.50321 v 0.15851 -0.136292 0.498474 v 0.155032 -0.134684 0.502964 v 0.145006 -0.133819 0.514504 v 0.171033 -0.12032 0.538263 v 0.158849 -0.127938 0.534943 v 0.167969 -0.138075 0.523788 v 0.232061 -0.151474 0.497024 v 0.23074 -0.117128 0.507191 v 0.365798 0.221617 0.362743 v 0.342501 0.235507 0.392185 v 0.325951 0.202558 0.415114 v 0.359268 0.178677 0.383229 v 0.352369 0.0489033 0.417452 v 0.322262 0.0907619 0.44953 v 0.295322 0.04895 0.483251 v 0.367108 0.00328555 0.369771 v 0.138972 -0.18796 0.555521 v 0.161562 -0.177794 0.535913 v 0.154015 -0.155093 0.536392 v 0.136131 -0.156414 0.558491 v 0.220263 -0.08194 0.518603 v 0.202088 -0.0486753 0.52791 v 0.17564 -0.0814314 0.545822 v 0.193131 -0.106435 0.533575 v 0.199492 -0.169714 0.509722 v 0.190033 -0.188183 0.514668 v 0.207302 -0.213011 0.492721 v 0.222415 -0.183044 0.489617 v 0.125088 -0.132884 0.551294 v 0.144497 -0.139192 0.530254 v 0.135014 0.119128 0.544717 v 0.119534 0.149685 0.554253 v 0.096915 0.171211 0.569382 v 0.112553 0.137432 0.569616 v 0.0878476 0.217858 0.555667 v 0.0649773 0.232128 0.568628 v 0.073466 0.185119 0.584571 v 0.116359 0.191199 0.548932 v 0.111419 0.228591 0.524951 v 0.0858774 0.255408 0.530312 v 0.301408 0.0368718 -0.387812 v 0.366839 0.037626 -0.269538 v 0.272125 -0.199781 0.399533 v 0.246349 -0.195514 0.453266 v 0.223339 -0.243049 0.450553 v 0.364021 -0.197455 0.21335 v 0.411416 -0.124798 0.140589 v 0.431568 -0.0028997 0.0907502 v 0.449346 0.11075 0.0889086 v 0.0649948 0.777167 0.432594 v 0.133465 0.770619 0.418569 v 0.14341 0.869244 0.301253 v 0.0689586 0.877043 0.315395 v 0.305372 0.809321 0.22043 v 0.289307 0.723856 0.335524 v 0.355187 0.660735 0.264773 v 0.372264 0.728258 0.148528 v 0.382308 0.7766 0.0116631 v 0.0971488 0.470588 0.557912 v 0.110788 0.565185 0.534317 v 0.100113 0.277828 0.510938 v 0.10966 0.248679 0.503771 v 0.0443988 0.240822 0.58581 v 0.0522151 0.193614 0.604337 v 0.052601 0.564735 0.541859 v 0.123726 0.667896 0.498907 v 0.0597976 0.671147 0.508711 v 0.0466729 0.466215 0.561034 v 0.000423846 0.462807 0.558988 v -0.00017831 0.388326 0.563478 v 0.0352086 0.389069 0.560584 v 0.000833078 0.56384 0.544139 v 0.295773 0.426823 0.470722 v 0.301706 0.464689 0.451056 v 0.189957 0.181465 0.501181 v 0.186163 0.208931 0.491956 v 0.141574 0.222722 0.500509 v 0.146526 0.195338 0.518293 v 0.111986 0.0116865 0.562811 v 0.111343 0.0404672 0.565769 v 0.0577164 0.0420398 0.577988 v 0.0656438 -0.00796249 0.596918 v 0.147695 0.0440509 0.537258 v 0.144778 0.0631738 0.538491 v 0.0268719 -0.0140834 0.602378 v 0.0270356 -0.0372401 0.622027 v 0.0876429 -0.0456996 0.601127 v 0.183093 0.146552 0.519439 v 0.148589 0.164593 0.536819 v 0.147344 0.131095 0.542934 v 0.176733 0.112264 0.532435 v -0.000394618 -0.0441035 0.617625 v -0.000260156 -0.0187662 0.600677 v 0.165058 0.0770935 0.530856 v 0.148554 0.0982976 0.535562 v 0.116476 0.272829 0.494797 v 0.119084 0.26261 0.493569 v 0.120873 0.268971 0.480883 v 0.11761 0.27287 0.484221 v 0.224695 0.848444 0.271198 v 0.231324 0.918189 0.121063 v 0.14614 0.9439 0.150241 v 0.241894 0.945736 -0.185803 v 0.156043 0.976475 -0.183418 v 0.146906 0.980702 -0.0177607 v 0.23195 0.948285 -0.0402158 v 0.0684324 0.995189 -0.00981573 v 0.0682103 0.955014 0.162933 v 0.0891571 0.383649 0.555118 v 0.110613 0.336412 0.528863 v 0.122749 0.310759 0.512914 v 0.147081 -0.111919 0.55631 v 0.158656 -0.0994551 0.55786 v 0.0939743 0.0869969 0.616333 v 0.101206 0.119326 0.615532 v 0.0670469 0.122121 0.645885 v 0.0560853 0.0831385 0.640601 v 0.0795284 0.0820978 0.567845 v 0.0337354 0.0564741 0.595059 v 0.0854448 -0.103577 0.606979 v 0.0826211 -0.0671141 0.612931 v 0.0280704 -0.0555854 0.637736 v 0.0319698 -0.0970874 0.628212 v 0.0789964 -0.121811 0.579602 v 0.0327415 -0.116959 0.594106 v 0.0216981 0.0173339 0.585915 v -0.00123062 -0.095585 0.625704 v -0.000511542 -0.0598999 0.637227 v -0.00157555 -0.115643 0.593966 v -0.000219233 -0.0988881 0.554498 v 0.0291929 0.0853015 0.665324 v 0.0352671 0.124524 0.666125 v 0.0371846 0.159004 0.648446 v 0.0654158 0.154462 0.629171 v 0.0280178 0.19967 0.620548 v 0.0221015 0.245843 0.59797 v 0.0432997 0.281499 0.556866 v 0.0222008 0.28717 0.567459 v -0.000400465 0.125745 0.673871 v -0.00057585 0.0822265 0.675105 v -0.000347849 0.160916 0.656029 v 0.367195 0.315074 0.363767 v 0.346658 0.302744 0.393991 v 0.344389 0.266656 0.384439 v 0.371726 0.266504 0.352507 v 0.40246 0.429197 0.234116 v 0.422126 0.335763 0.207276 v 0.393316 0.264083 0.313887 v 0.387102 0.325737 0.325369 v 0.3274 0.295928 0.408636 v 0.316392 0.29076 0.418709 v 0.3085 0.274624 0.423199 v 0.323636 0.272379 0.406602 v 0.429381 0.244458 0.204002 v 0.407084 0.332408 0.277313 v 0.410597 0.257869 0.266264 v -0.0012657 -0.456867 0.290093 v -0.00137093 -0.520579 0.266159 v 0.154137 -0.304206 0.500479 v 0.193482 -0.282873 0.473493 v 0.186367 -0.242201 0.509588 v 0.148993 -0.26399 0.525367 v 0.110332 -0.274916 0.545857 v 0.099347 -0.233134 0.560204 v 0.0558865 -0.227615 0.569605 v 0.0659185 -0.270006 0.563817 v 0.154687 -0.142577 0.51838 v 0.159498 -0.143009 0.513072 v 0.154646 -0.138239 0.502496 v 0.149045 -0.137596 0.50639 v 0.15958 -0.138174 0.517463 v 0.161574 -0.141559 0.511657 v 0.0940387 -0.129288 0.582226 v 0.109215 -0.12609 0.531844 v 0.0782715 -0.117578 0.557129 v 0.264817 0.0151299 0.501573 v 0.280122 0.127096 0.47057 v 0.262508 0.0886748 0.494464 v 0.187613 0.050926 0.529248 v 0.207829 0.0868157 0.523449 v 0.231821 -0.0170182 0.518246 v 0.304138 0.164985 0.443485 v 0.343004 0.132813 0.418235 v 0.313621 0.250742 0.418382 v 0.290815 0.22492 0.444303 v 0.355269 -0.194146 0.0276407 v 0.388534 -0.179618 0.0746089 v 0.336544 -0.25083 0.156379 v 0.29365 -0.279868 0.104617 v 0.389288 0.153006 0.345258 v 0.39155 0.205715 0.320166 v 0.127262 0.566927 -0.64996 v 0.000868155 0.562946 -0.661419 v 0.000850617 0.724441 -0.605705 v 0.118774 0.725955 -0.596105 v 0.21095 0.754513 0.387525 v 0.133734 -0.133188 0.514651 v 0.131302 -0.13393 0.53047 v 0.0671053 -0.326445 0.551902 v 0.0661056 -0.374553 0.504765 v 0.117289 -0.365439 0.489939 v 0.116552 -0.318792 0.528974 v 0.288249 -0.135286 0.424736 v 0.39393 0.0544045 0.33225 v 0.374655 0.0965379 0.38044 v 0.000792155 1 -0.0074948 v 0.0731795 0.993937 -0.182792 v 0.000868155 0.999152 -0.181886 v 0.179405 0.936399 -0.330549 v 0.0842755 0.953459 -0.338026 v 0.141767 0.271455 0.486238 v 0.139978 0.267433 0.490862 v 0.175908 0.259465 0.501362 v 0.175312 0.263359 0.495861 v 0.181597 0.230187 0.495539 v 0.140253 0.240576 0.495341 v 0.336982 0.587763 0.356927 v 0.312043 0.518258 0.416183 v 0.259971 0.350203 0.495411 v 0.250763 0.331028 0.496036 v 0.114179 0.255893 0.495902 v 0.111069 0.276518 0.499456 v 0.125433 0.293116 0.500415 v 0.124965 0.282353 0.489968 v 0.13906 0.254928 0.497457 v 0.17737 0.2462 0.50062 v 0.121796 0.272327 0.47658 v 0.149548 0.0847578 0.549377 v 0.142825 -0.226381 0.544992 v 0.106181 -0.197232 0.576871 v 0.258193 -0.146669 0.465227 v 0.2105 0.0188071 0.525711 v 0.181041 -0.0155508 0.531721 v 0.173453 -0.168949 0.5218 v 0.180322 -0.15877 0.514949 v 0.168554 -0.150118 0.516667 v 0.163082 -0.153579 0.523344 v 0.139124 -0.128733 0.545343 v 0.152348 -0.134468 0.527471 v 0.416192 -0.0714636 0.0335278 v 0.0220956 0.0520719 0.640232 v 0.0361615 0.0619695 0.628476 v -0.000283541 0.202056 0.62768 v 0.0869063 -0.0493125 -0.489641 v 0.192289 -0.0534399 -0.447186 v 0.192003 -0.134672 -0.429197 v 0.0851642 -0.130335 -0.46373 v 0.236434 0.310245 0.495686 v 0.237714 0.31211 0.497539 v 0.244636 0.32534 0.496212 v 0.121253 0.281932 0.477293 v 0.173149 -0.207241 0.528208 v -0.000242618 0.247989 0.603612 v -0.00037708 0.28838 0.571697 v 0.108496 -0.160507 0.588207 v 0.0613995 -0.166388 0.620127 v 0.0634222 -0.199565 0.59462 v 0.0893734 0.151176 0.600127 v 0.122124 0.0729427 0.596088 v 0.0993528 0.072475 0.584781 v 0.108315 0.0599584 0.583916 v 0.133524 0.0551528 0.575778 v 0.13315 0.107517 0.580426 v 0.274937 0.384257 0.485735 v 0.170606 -0.145383 0.517205 v 0.0464391 -0.130399 0.611931 v 0.0392892 -0.113439 0.575094 v -0.00161647 -0.112428 0.579865 v -0.00351648 -0.131685 0.617859 v 0.0194356 0.03489 0.601858 v -0.000564158 0.0478802 0.644208 v -2.04632e-05 0.0350303 0.598835 v 0.222163 0.246884 0.4972 v 0.217802 0.257547 0.498129 v 0.293159 0.278716 0.430419 v 0.302852 0.281932 0.427367 v 0.285209 0.277366 0.434932 v 0.289307 0.275834 0.436551 v 0.290061 0.280494 0.427963 v -0.000225079 -0.384287 0.444245 v 0.0651001 -0.383883 0.440585 v -0.000891543 -0.364076 0.502426 v 0.116576 -0.381784 0.436341 v 0.363734 0.712842 -0.467571 v 0.32166 0.832542 -0.392653 v 0.376508 0.821429 -0.265451 v 0.427095 0.698004 -0.319575 v 0.27178 0.90956 -0.29643 v 0.310423 0.901357 -0.210644 v 0.441869 0.677005 -0.175175 v 0.389019 0.807076 -0.128411 v 0.313311 0.894506 -0.0788532 v 0.12783 -0.376125 0.378248 v 0.0722266 -0.391483 0.37664 v 0.125579 0.302411 0.505741 v 0.101656 0.861358 -0.486525 v 0.214084 0.849981 -0.463327 v 0.2467 0.723207 -0.559263 v 0.104913 0.117397 -0.600268 v 0.221579 0.117865 -0.555159 v 0.200848 0.0268164 -0.488992 v 0.0944011 0.0271204 -0.539134 v 0.391141 0.144178 -0.303545 v 0.331241 0.130393 -0.444613 v 0.360829 0.250357 -0.491155 v 0.424003 0.258021 -0.333419 v 0.000868155 0.23912 -0.655479 v 0.00089154 0.393909 -0.675105 v 0.125626 0.397949 -0.664716 v 0.115418 0.240453 -0.645617 v 0.452175 0.547687 -0.348309 v 0.450217 0.395605 -0.350776 v 0.383015 0.40193 -0.511868 v 0.3854 0.562496 -0.506472 v 0.464078 0.52881 -0.195929 v 0.311698 0.866351 0.071908 v -9.64635e-05 -0.406882 0.376985 v 0.373883 -0.18312 -0.115123 v 0.389189 -0.0789467 -0.141776 v 0.247109 0.197607 0.47589 v 0.22891 0.231497 0.489717 v 0.121077 -0.116725 0.574393 v 0.125626 -0.0895459 0.583057 v 0.110548 -0.128452 0.555428 v 0.000710309 0.959638 0.167019 v 0.000710309 0.881206 0.320973 v 0.224163 0.124079 0.505215 v 0.255305 0.260798 0.480649 v 0.25188 0.263516 0.478322 v 0.214891 0.26119 0.49413 v 0.116476 0.273741 0.475423 v 0.290704 0.283902 0.433377 v 0.29641 0.299523 0.422813 v 0.29406 0.288222 0.418078 v 0.142655 0.263364 0.482467 v 0.121638 0.267831 0.470296 v 0.171711 0.256898 0.489693 v 0.246864 0.257401 0.473821 v 0.274311 0.271648 0.453301 v 0.274539 0.26862 0.446654 v 0.233686 0.331104 0.49074 v 0.187548 0.326632 0.49682 v 0.296971 0.273928 0.433476 v 0.134067 -0.0744861 0.577333 v 0.237434 0.052867 0.514604 v 0.0637905 0.27076 0.54346 v 0.375421 0.514218 0.287328 v 0.353808 -0.333437 -0.190615 v 0.349365 -0.276331 -0.333858 v 0.323337 -0.214946 -0.338453 v 0.356725 -0.247925 -0.205557 v -0.000330311 -0.581268 0.237302 v 0.092922 -0.548418 0.185458 v 0.394783 -0.0876049 -0.0664009 v 0.358315 -0.197624 -0.02995 v 0.292785 -0.321493 0.0377429 v 0.395175 -0.0904345 -0.0143524 v 0.243385 0.243183 -0.602957 v 0.000587539 -0.0451091 -0.498205 v 0.000751232 0.030862 -0.55154 v 0.000809694 0.11928 -0.61144 v 0.000850617 0.862837 -0.491295 v 0.000868155 0.958527 -0.339277 v 0.000423846 -0.128189 -0.469085 v 0.264186 0.56961 -0.608026 v 0.35127 -0.283317 -0.0863656 v 0.196201 -0.209591 -0.418785 v 0.0873097 -0.206341 -0.44839 v 0.000488154 -0.206259 -0.449945 v 0.263397 0.402579 -0.621226 v 0.456683 0.384813 -0.0591516 v 0.457776 0.372302 -0.191281 v 0.000850617 0.671351 0.512487 v 0.000809694 0.77919 0.437668 v 0.408656 0.116286 0.298547 v 0.295913 0.259781 0.439334 v 0.285355 0.265481 0.449775 v 0.278766 0.270035 0.454663 v 0.128946 -0.0227065 0.564741 v 0.16203 0.016989 0.534633 v 0.0985987 0.0583799 0.58087 v 0.0538462 0.323165 0.543729 v 0.0794758 0.301522 0.528465 v -0.00330601 -0.197759 0.600525 v -0.000511542 -0.225551 0.572931 v -0.00456879 -0.164231 0.628277 v -0.000336157 -0.26392 0.574381 v -0.000768774 -0.325515 0.55686 v 0.269921 0.242499 0.464742 v 0.260573 0.253022 0.476072 v 0.235066 0.15963 0.493271 v 0.411369 0.186119 0.273583 v 0.000178307 0.0131539 0.584682 v 0.153436 -0.0554568 0.55786 v 0.0264569 0.331747 0.554112 v -0.000342003 0.332998 0.557743 v 0.285589 0.277974 0.428156 v 0.184795 -0.499655 0.1217 v 0.332808 -0.386298 -0.0699261 v 0.20739 -0.274419 -0.415909 v 0.0927467 -0.274308 -0.43723 v 0.278029 -0.438791 0.0475586 v 0.000505693 -0.27722 -0.43768 v 0.438191 0.12488 -0.0367783 v 0.460214 0.163208 -0.055258 v 0.485388 0.177437 -0.0277343 v 0.472304 0.161641 -0.00367724 v 0.496244 0.232684 -0.0170708 v 0.477425 0.247036 0.00446648 v 0.517015 0.298681 -0.0523876 v 0.492233 0.31788 -0.0441737 v 0.53425 0.316407 -0.124009 v 0.511491 0.332595 -0.129276 v 0.535904 0.290111 -0.170685 v 0.511128 0.30365 -0.186838 v 0.538611 0.228878 -0.193017 v 0.511286 0.231199 -0.218992 v 0.520242 0.128838 -0.191421 v 0.490433 0.122168 -0.208603 v 0.487562 0.00951757 -0.0819458 v 0.472286 -0.00658864 -0.0930419 v 0.47079 0.0399937 -0.154257 v 0.496437 0.0472722 -0.136917 v 0.485142 -0.0247586 -0.0238758 v 0.46129 -0.0429694 -0.0334343 v 0.474888 0.238927 -0.0419989 v 0.495232 0.289088 -0.0628581 v 0.508398 0.299996 -0.11766 v 0.51311 0.283323 -0.158478 v 0.514642 0.235303 -0.176531 v 0.501751 0.136134 -0.181559 v 0.486025 0.0533522 -0.11859 v 0.486451 0.0268164 -0.067155 v 0.482529 0.0136625 -0.0120607 v 0.464265 0.0280383 0.0249515 v 0.457519 -0.0185791 0.0196256 v 0.442769 0.0582571 -0.0293244 v 0.45632 0.0847169 -0.0600578 v 0.442465 0.0842785 -0.0209644 v 0.459612 0.268106 0.0209995 v 0.458559 0.182857 0.0414318 v 0.463026 0.318488 -0.0446005 v 0.470222 0.311835 -0.142898 v 0.455063 0.232836 -0.195221 v 0.43839 0.13186 -0.191088 v 0.424564 0.0473131 -0.148417 v 0.423447 -0.00471202 -0.0897563 v 0.425377 -0.0292075 -0.0262143 v 0.430714 -0.0102191 0.0297161 v 0.446335 0.0345567 0.0460036 v 0.475607 0.129364 -0.0864649 v 0.482611 0.0600636 -0.0525396 v 0.481517 0.0827175 -0.101349 v 0.470503 0.0444835 -0.0133527 v 0.479278 0.0776957 0.00471786 v 0.504692 0.223938 -0.101723 v 0.50375 0.131866 -0.1473 v 0.45452 0.100016 0.0450097 v 0.403623 0.0251386 -0.16934 v 0.414719 0.138607 -0.218957 v 0.435461 0.249632 -0.229924 v -0.000201695 -0.407876 0.310666 v 0.000347846 -0.171521 0.505794 v 0.0884205 -0.186598 0.484028 v 0.141147 -0.173807 0.465513 v 0.159878 -0.142255 0.458644 v 0.152483 -0.116468 0.431278 v 0.0708352 0.0121893 0.376371 v 0.128069 -0.116368 0.360528 v 0.143994 -0.166791 0.41184 v 0.0748398 -0.218144 0.372349 v 0.280941 0.292858 0.454897 v 0.281356 0.319879 0.451494 v 0.127268 0.269088 0.455435 v 0.116921 0.284697 0.447653 v 0.119996 0.274998 0.469126 v 0.15699 0.254759 0.466326 v 0.265916 0.273601 0.421176 v 0.214885 0.253946 0.455259 v 0.141223 0.313133 0.482117 v 0.211436 0.255823 0.486852 v 0.277135 0.302686 0.410799 v 0.252505 0.333881 0.433599 v 0.202023 0.342182 0.464578 v 0.11989 0.295816 0.471196 v 0.146526 0.322539 0.455943 v 0.126292 0.301838 0.454973 v 0.119744 0.284878 0.469419 v 0.00103185 0.0191579 0.374711 v 0.000909079 -0.205715 0.379849 v 0.0536357 -0.100847 0.27211 v 0.00103185 -0.098929 0.27128 v 0.255463 -0.398733 -0.446098 v 0.412907 -0.372688 -0.332858 v 0.452596 -0.41557 -0.353559 v 0.293329 -0.465367 -0.476007 v 0.0815337 -0.637104 0.176286 v 0.0726358 -0.738524 0.179519 v 0.174763 -0.714911 0.155526 v 0.172032 -0.601823 0.129884 v 0.380782 -0.504069 -0.184377 v 0.357368 -0.419095 -0.180384 v 0.337538 -0.494803 -0.0548371 v 0.372989 -0.619402 -0.0373571 v 0.453578 -0.652661 -0.0939539 v 0.452351 -0.545892 -0.196981 v 0.173576 -0.814197 0.195654 v 0.0739044 -0.845866 0.20734 v 0.0964414 -0.904976 0.254455 v 0.197703 -0.864562 0.243353 v 0.519564 -0.487407 -0.384801 v 0.555004 -0.584226 -0.219366 v 0.451357 -0.731555 -0.0215899 v 0.382594 -0.74824 0.0443666 v 0.439805 -0.799196 0.0975376 v 0.519108 -0.768071 -0.00769357 v 0.274837 -0.806199 0.115503 v 0.320508 -0.838061 0.183769 v 0.354533 -0.544232 -0.525256 v 0.162503 -0.604343 -0.559076 v 0.131098 -0.496837 -0.498761 v 0.115161 -0.410103 -0.457756 v -0.00017831 -0.492774 -0.504192 v 2.046e-05 -0.40666 -0.465186 v -0.000482311 -0.600531 -0.555322 v 0.546217 -0.696736 -0.117257 v 0.22746 -0.332063 -0.424345 v 0.101627 -0.33885 -0.437002 v 0.280193 -0.554165 0.0658922 v 0.274843 -0.684891 0.0781517 v 0.000347846 -0.34199 -0.438165 v 0.000733693 -0.746364 0.176765 v 0.000312769 -0.874904 0.179121 v 0.378648 -0.322586 -0.326994 v -0.000114002 -0.940246 0.234262 v 0.000979233 -0.650317 0.207112 v -0.130513 -0.13217 0.498924 v -0.133687 -0.14723 0.488109 v -0.15222 -0.140519 0.477457 v -0.14666 -0.13514 0.489746 v -0.0697653 -0.0999404 0.550318 v -0.0736414 -0.0473131 0.499649 v -0.0305784 -0.0972511 0.55389 v -0.0396517 -0.109762 0.550014 v -0.0358517 -0.127727 0.53534 v -0.0742493 -0.135994 0.523315 v -0.0733373 -0.115561 0.537643 v -0.106766 -0.144336 0.504823 v -0.106281 -0.125786 0.515779 v -0.156505 -0.107798 0.467782 v -0.155611 -0.123682 0.486899 v -0.159311 -0.130796 0.484958 v -0.162872 -0.126996 0.470243 v -0.159919 -0.135625 0.47627 v -0.154055 -0.134696 0.486513 v -0.142597 -0.118993 0.499994 v -0.130051 -0.0726738 0.476189 v -0.10054 -0.105798 0.538111 v -0.125684 -0.115824 0.51596 v -0.274604 -0.301394 0.247527 v -0.220831 -0.335775 0.330215 v -0.250102 -0.275554 0.380393 v -0.3066 -0.239804 0.292309 v -0.284302 -0.0258401 0.479772 v -0.319479 0.00809111 0.449577 v -0.331873 -0.0412272 0.412243 v -0.293674 -0.0747667 0.452418 v -0.294668 -0.0547787 -0.357622 v -0.302063 -0.144319 -0.34334 v -0.356012 -0.159916 -0.223184 v -0.355474 -0.0633082 -0.24271 v -0.447241 0.22613 0.139332 v -0.437922 0.336149 0.131124 v -0.449486 0.331215 0.047962 v -0.454982 0.205353 0.0827818 v -0.103311 -0.419241 0.249936 v -0.203701 -0.353384 0.208147 v -0.196966 -0.411506 0.138841 v -0.101797 -0.475733 0.208638 v -0.196499 -0.327216 0.427455 v -0.176283 -0.362363 0.392138 v -0.150331 -0.372548 0.431378 v -0.155575 -0.349484 0.46435 v -0.0890109 -0.391945 0.303855 v -0.158306 -0.363848 0.305182 v -0.415613 0.611627 0.0817705 v -0.430808 0.648493 -0.0417066 v -0.45411 0.508986 -0.0641209 v -0.440308 0.483438 0.0478393 v -0.389808 0.40462 0.306977 v -0.375935 0.38348 0.354021 v -0.34643 0.433026 0.398499 v -0.354807 0.467378 0.356891 v -0.317409 0.30382 0.429121 v -0.30173 0.320499 0.456861 v -0.309295 0.339493 0.457756 v -0.328406 0.316144 0.429519 v -0.358297 0.360101 0.389344 v -0.335684 0.397733 0.427864 v -0.285156 0.29304 0.457387 v -0.294212 0.310695 0.451757 v -0.307675 0.294425 0.430781 v -0.29475 0.281949 0.435698 v -0.421091 0.455996 0.145494 v -0.395403 0.565208 0.19252 v -0.321999 0.364421 0.449238 v -0.345494 0.336792 0.417218 v -0.178165 0.560672 0.512335 v -0.249354 0.546354 0.466589 v -0.243286 0.479638 0.494943 v -0.170168 0.4781 0.536796 v -0.164123 0.410647 0.547114 v -0.236966 0.427297 0.516007 v -0.270669 0.634748 0.422187 v -0.195815 0.657882 0.47347 v -0.14597 0.313039 0.508126 v -0.18946 0.324971 0.513312 v -0.186823 0.312829 0.511757 v -0.144895 0.300213 0.501871 v -0.186911 0.310514 0.506612 v -0.143462 0.300341 0.494353 v -0.160048 0.365076 0.528073 v -0.219468 0.382854 0.516404 v -0.15782 0.334506 0.520076 v -0.205952 0.349935 0.517012 v -0.195236 0.332495 0.516264 v -0.151653 0.320785 0.513142 v -0.0805691 0.0827468 0.603261 v -0.0493739 0.08878 0.593591 v -0.0448723 0.0732117 0.617958 v -0.0594819 0.0761932 0.621314 v -0.422927 0.0771812 0.237185 v -0.432205 0.159355 0.215905 v -0.448112 0.130656 0.149516 v -0.4282 0.0348607 0.166897 v -0.311779 -0.172912 0.334378 v -0.324787 -0.103758 0.371735 v -0.364851 -0.052639 0.316097 v -0.367254 -0.126698 0.269146 v -0.183918 -0.149136 0.51793 v -0.182024 -0.137865 0.527822 v -0.205163 -0.131463 0.524127 v -0.205514 -0.152071 0.514943 v -0.39379 0.00614433 0.269368 v -0.400951 -0.0591282 0.208995 v -0.261011 -0.0993382 0.483865 v -0.25102 -0.0551177 0.50328 v -0.158849 -0.136444 0.499199 v -0.155155 -0.134784 0.503397 v -0.145304 -0.133848 0.514902 v -0.160802 -0.128394 0.536919 v -0.173424 -0.121349 0.541327 v -0.169156 -0.138478 0.524928 v -0.232096 -0.116964 0.50767 v -0.232727 -0.151188 0.49696 v -0.326085 0.202611 0.415651 v -0.34094 0.235683 0.392156 v -0.367727 0.221336 0.359031 v -0.358829 0.177595 0.3841 v -0.295603 0.0501836 0.478632 v -0.32232 0.0902006 0.449922 v -0.351843 0.04895 0.416686 v -0.367248 0.00336155 0.369624 v -0.156137 -0.154941 0.536878 v -0.165134 -0.177028 0.538193 v -0.144573 -0.187364 0.558725 v -0.140533 -0.155882 0.559046 v -0.17761 -0.0804258 0.547933 v -0.201667 -0.0484356 0.526945 v -0.22024 -0.0817529 0.517585 v -0.195826 -0.106131 0.536439 v -0.207794 -0.213087 0.493049 v -0.191711 -0.188305 0.515551 v -0.201111 -0.170071 0.510745 v -0.223385 -0.183243 0.490178 v -0.128595 -0.132761 0.551212 v -0.145777 -0.139513 0.530605 v -0.0971664 0.171538 0.569909 v -0.120048 0.150182 0.555387 v -0.13557 0.119437 0.545004 v -0.113103 0.137432 0.569453 v -0.0653573 0.232432 0.569575 v -0.08745 0.217992 0.556468 v -0.0739395 0.185388 0.584933 v -0.0855266 0.255554 0.53095 v -0.110583 0.228714 0.525501 v -0.115915 0.191404 0.5495 v -0.300099 0.0366964 -0.387999 v -0.364734 0.0377897 -0.269357 v -0.223181 -0.243207 0.45081 v -0.246139 -0.195666 0.45347 v -0.271201 -0.199869 0.399446 v -0.362846 -0.197443 0.213286 v -0.410176 -0.124757 0.140565 v -0.430404 -0.00290555 0.0907385 v -0.448779 0.11075 0.0889086 v -0.142135 0.869847 0.301633 v -0.132167 0.771303 0.419317 v -0.0633989 0.777407 0.43288 v -0.0675789 0.877324 0.315577 v -0.353469 0.660735 0.264732 v -0.2875 0.723792 0.335465 v -0.30353 0.809117 0.220313 v -0.37099 0.728422 0.148627 v -0.381016 0.776764 0.0117274 v -0.0996744 0.472587 0.557146 v -0.109525 0.565325 0.53475 v -0.100294 0.277787 0.511248 v -0.108689 0.248457 0.503268 v -0.0528874 0.193947 0.604898 v -0.0453926 0.241125 0.586705 v -0.12255 0.668732 0.500514 v -0.0511336 0.564922 0.542589 v -0.0582191 0.671655 0.50974 v -0.0440363 0.465776 0.561151 v -0.0361966 0.388923 0.562367 v -0.301894 0.466338 0.448542 v -0.295831 0.424807 0.472166 v -0.140867 0.22264 0.499754 v -0.185742 0.209381 0.492394 v -0.186338 0.179495 0.502724 v -0.145859 0.19535 0.519018 v -0.0600022 0.0437294 0.578309 v -0.113337 0.0407946 0.564875 v -0.114196 0.0121659 0.564255 v -0.0686019 -0.00676987 0.598064 v -0.143661 0.0637116 0.537807 v -0.147607 0.0440217 0.535469 v -0.0907706 -0.0459919 0.600525 v -0.0300113 -0.0346152 0.623594 v -0.028047 -0.0138554 0.603173 v -0.148028 0.131527 0.5437 v -0.148519 0.164868 0.537322 v -0.183164 0.146873 0.520193 v -0.176978 0.112363 0.532908 v -0.147823 0.0979234 0.535574 v -0.165064 0.0766492 0.532955 v -0.120107 0.268649 0.480825 v -0.118558 0.262394 0.493353 v -0.115979 0.27287 0.494434 v -0.116476 0.272952 0.483859 v -0.229115 0.916634 0.120496 v -0.223379 0.848952 0.271461 v -0.145146 0.945128 0.150709 v -0.145409 0.980883 -0.0176788 v -0.154278 0.976311 -0.1834 v -0.240088 0.945514 -0.185786 v -0.230512 0.948548 -0.0401515 v -0.0669533 0.995411 -0.00979819 v -0.0669124 0.955581 0.163097 v -0.0891746 0.383199 0.554861 v -0.112226 0.336757 0.527307 v -0.123381 0.311174 0.513382 v -0.149484 -0.111966 0.558549 v -0.160264 -0.0991219 0.559216 v -0.0695139 0.122828 0.646821 v -0.103574 0.1197 0.616608 v -0.0967747 0.0873945 0.617683 v -0.0583127 0.0845006 0.640951 v -0.0810075 0.0824603 0.567973 v -0.0347818 0.058339 0.594989 v -0.031812 -0.0520134 0.636181 v -0.0876079 -0.0656701 0.61341 v -0.0905251 -0.101683 0.607529 v -0.0378686 -0.0937434 0.629054 v -0.0836617 -0.122507 0.579642 v -0.0385351 -0.11728 0.594673 v -0.0223295 0.0177081 0.586652 v -0.0307538 0.0864766 0.665646 v -0.0369098 0.125196 0.667078 v -0.0659946 0.154643 0.629212 v -0.0379446 0.159028 0.648136 v -0.0287544 0.19984 0.620642 v -0.0228205 0.245931 0.598298 v -0.0444456 0.281523 0.558544 v -0.0233467 0.287164 0.569581 v -0.348774 0.267521 0.384632 v -0.352083 0.30296 0.39367 v -0.371253 0.315308 0.363077 v -0.374871 0.266369 0.352501 v -0.422202 0.335746 0.207253 v -0.401928 0.429197 0.234116 v -0.395345 0.264083 0.313998 v -0.391071 0.32586 0.325679 v -0.312703 0.275793 0.421661 v -0.320315 0.291642 0.417107 v -0.332077 0.295173 0.409057 v -0.327599 0.271742 0.406824 v -0.429802 0.244434 0.203979 v -0.409282 0.332454 0.277442 v -0.411848 0.257886 0.266369 v -0.187414 -0.242265 0.510307 v -0.193763 -0.283183 0.474066 v -0.155254 -0.304954 0.501777 v -0.149998 -0.264183 0.526518 v -0.0567108 -0.227311 0.569523 v -0.101124 -0.233508 0.561461 v -0.11039 -0.27508 0.546021 v -0.066205 -0.270351 0.564711 v -0.154225 -0.138052 0.502391 v -0.159867 -0.142787 0.513271 v -0.15533 -0.142366 0.518626 v -0.148566 -0.137426 0.506285 v -0.160416 -0.138344 0.518258 v -0.161965 -0.141513 0.511996 v -0.110811 -0.126394 0.533276 v -0.10089 -0.129879 0.583501 v -0.0809374 -0.117865 0.558397 v -0.263876 0.014785 0.500935 v -0.26083 0.088932 0.49537 v -0.279702 0.127055 0.470506 v -0.207764 0.0867397 0.523776 v -0.187729 0.0509786 0.529558 v -0.232096 -0.0167025 0.518065 v -0.344056 0.133304 0.417078 v -0.302046 0.166376 0.445239 v -0.292551 0.225429 0.44414 v -0.316041 0.250468 0.418475 v -0.335386 -0.250836 0.156385 v -0.387207 -0.179618 0.074568 v -0.353755 -0.194151 0.0276524 v -0.292388 -0.279891 0.104617 v -0.392211 0.205733 0.320201 v -0.386651 0.150025 0.344942 v -0.126064 0.567371 -0.651942 v -0.117096 0.725914 -0.596082 v -0.209068 0.754227 0.387245 v -0.134091 -0.133281 0.515294 v -0.132384 -0.133778 0.530774 v -0.118289 -0.366228 0.490722 v -0.0673742 -0.375085 0.505343 v -0.0685259 -0.327012 0.553422 v -0.117722 -0.319453 0.530388 v -0.287793 -0.13528 0.424643 v -0.375234 0.0965671 0.380457 v -0.394351 0.054463 0.33218 v -0.0714373 0.993797 -0.182751 v -0.0825568 0.953558 -0.338084 v -0.177458 0.935674 -0.330221 v -0.176961 0.259482 0.501637 v -0.139651 0.267463 0.490903 v -0.141176 0.271537 0.486156 v -0.175792 0.263446 0.495797 v -0.139621 0.240295 0.49489 v -0.181918 0.230053 0.49499 v -0.335299 0.587722 0.356851 v -0.311189 0.51838 0.416464 v -0.263028 0.350391 0.495528 v -0.252435 0.331198 0.496568 v -0.111168 0.276448 0.500608 v -0.113553 0.255671 0.49582 v -0.124754 0.293525 0.500263 v -0.124275 0.282616 0.489933 v -0.138587 0.254671 0.496603 v -0.17851 0.246346 0.500783 v -0.120744 0.272286 0.476557 v -0.150635 0.0843194 0.549231 v -0.110981 -0.197039 0.578654 v -0.145877 -0.226522 0.547184 v -0.257825 -0.146365 0.464946 v -0.181813 -0.015013 0.533586 v -0.21057 0.0188715 0.525811 v -0.169226 -0.14996 0.516989 v -0.181743 -0.1588 0.515902 v -0.175376 -0.168545 0.522911 v -0.163813 -0.153415 0.52335 v -0.140253 -0.128364 0.545887 v -0.153091 -0.134363 0.527834 v -0.414608 -0.0714286 0.0335337 v -0.0376523 0.063203 0.628721 v -0.0232707 0.0530365 0.640016 v -0.190483 -0.134521 -0.42891 v -0.190425 -0.0530365 -0.446291 v -0.0856669 -0.0492716 -0.489617 v -0.0841703 -0.13027 -0.463549 v -0.238743 0.312729 0.498784 v -0.236568 0.310718 0.495914 v -0.245034 0.325784 0.495083 v -0.120311 0.281967 0.47734 v -0.176107 -0.207054 0.530523 v -0.114635 -0.15994 0.588938 v -0.0702155 -0.19877 0.595006 v -0.0735478 -0.165324 0.619338 v -0.0899814 0.151661 0.600396 v -0.111016 0.0572925 0.58557 v -0.101867 0.0715163 0.586237 v -0.127064 0.0733753 0.597824 v -0.136833 0.0543987 0.574241 v -0.135833 0.107312 0.581379 v -0.278287 0.38386 0.485911 v -0.171226 -0.145371 0.517737 v -0.0426215 -0.114106 0.575498 v -0.0575293 -0.131258 0.610721 v -0.0203535 0.0339429 0.602828 v -0.224215 0.246978 0.496697 v -0.219644 0.257664 0.498129 v -0.308126 0.284604 0.426215 v -0.296275 0.279026 0.430641 v -0.291721 0.275554 0.437358 v -0.286612 0.276705 0.435172 v -0.291949 0.280143 0.428238 v -0.065825 -0.384532 0.440825 v -0.11702 -0.382428 0.436651 v -0.374667 0.821265 -0.265393 v -0.3198 0.831958 -0.392208 v -0.362179 0.712818 -0.467507 v -0.425879 0.698185 -0.319692 v -0.269938 0.909215 -0.296313 v -0.308015 0.900609 -0.210562 v -0.440407 0.677046 -0.175192 v -0.387417 0.807117 -0.128411 v -0.312037 0.894728 -0.0788123 v -0.0720161 -0.391612 0.376675 v -0.127765 -0.376523 0.378341 v -0.124801 0.303066 0.504835 v -0.0997913 0.860855 -0.486022 v -0.212687 0.850449 -0.463771 v -0.245244 0.723306 -0.559461 v -0.199083 0.0271847 -0.488407 v -0.21986 0.118005 -0.554936 v -0.10327 0.117479 -0.600127 v -0.0928636 0.0273016 -0.53883 v -0.389259 0.144254 -0.303446 v -0.329178 0.130557 -0.444432 v -0.359227 0.250316 -0.491237 v -0.422325 0.258021 -0.333419 v -0.123907 0.397932 -0.664658 v -0.113699 0.240517 -0.645459 v -0.381641 0.401913 -0.512072 v -0.448592 0.395605 -0.3508 v -0.450574 0.547705 -0.348333 v -0.384366 0.562601 -0.506817 v -0.462722 0.528827 -0.195952 v -0.310604 0.866976 0.0721301 v -0.372013 -0.183143 -0.115123 v -0.387686 -0.0789994 -0.141781 v -0.2476 0.197566 0.475487 v -0.230342 0.231532 0.488372 v -0.129238 -0.0890256 0.584927 v -0.123544 -0.115971 0.574872 v -0.114588 -0.128867 0.557082 v -0.221702 0.122764 0.506442 v -0.216107 0.26119 0.49413 v -0.253242 0.263207 0.478422 v -0.256568 0.260547 0.479737 v -0.115342 0.273619 0.475323 v -0.298743 0.299903 0.422953 v -0.291698 0.283732 0.432722 v -0.295854 0.288181 0.418253 v -0.142059 0.263388 0.482491 v -0.120428 0.267802 0.470325 v -0.172108 0.256934 0.489641 v -0.275083 0.271584 0.453242 v -0.248582 0.25684 0.473757 v -0.275001 0.268573 0.446274 v -0.234253 0.331396 0.490634 v -0.187624 0.326819 0.49717 v -0.300292 0.274694 0.432944 v -0.135658 -0.0739483 0.577444 v -0.237428 0.052791 0.514919 v -0.0645564 0.270789 0.544612 v -0.373819 0.514195 0.287264 v -0.321852 -0.214718 -0.338184 v -0.348166 -0.27584 -0.333396 v -0.352171 -0.333378 -0.190533 v -0.354936 -0.247872 -0.205511 v -0.0936937 -0.549137 0.186785 v -0.35669 -0.197653 -0.0299733 v -0.393228 -0.0876225 -0.0664009 v -0.29161 -0.321499 0.0380294 v -0.393638 -0.0904403 -0.014329 v -0.241608 0.243201 -0.602916 v -0.263209 0.569914 -0.609242 v -0.349441 -0.283282 -0.0863831 v -0.194821 -0.209504 -0.418674 v -0.0862925 -0.206323 -0.448413 v -0.261795 0.402579 -0.621448 v -0.456233 0.372302 -0.191263 v -0.455245 0.384813 -0.0591282 v -0.408072 0.116608 0.297155 v -0.298661 0.260278 0.439147 v -0.287606 0.265861 0.450068 v -0.279696 0.270216 0.454289 v -0.162731 0.0172638 0.536515 v -0.13087 -0.0222973 0.565699 v -0.101475 0.0572691 0.580946 v -0.0809198 0.301049 0.528407 v -0.0556351 0.322972 0.54498 v -0.272306 0.242932 0.464508 v -0.262964 0.253017 0.476001 v -0.233067 0.158607 0.487893 v -0.412053 0.186142 0.273695 v -0.154815 -0.0532762 0.55793 v -0.0277489 0.331782 0.556427 v -0.286179 0.277611 0.427928 v -0.183941 -0.499632 0.122144 v -0.331493 -0.386257 -0.0698735 v -0.206238 -0.274279 -0.416026 v -0.0915482 -0.274332 -0.437317 v -0.277193 -0.438779 0.0481257 v -0.484037 0.177414 -0.0276816 v -0.458618 0.163319 -0.0553633 v -0.437233 0.124752 -0.0367315 v -0.471526 0.1616 -0.00366555 v -0.476232 0.247018 0.00445479 v -0.494987 0.232631 -0.0169773 v -0.491035 0.317921 -0.0441971 v -0.515688 0.298728 -0.0523583 v -0.510175 0.332513 -0.1293 v -0.532917 0.316524 -0.12405 v -0.50993 0.303592 -0.186815 v -0.534671 0.290233 -0.170849 v -0.510152 0.231181 -0.21891 v -0.537459 0.228895 -0.193058 v -0.48934 0.122068 -0.20872 v -0.519208 0.128879 -0.191363 v -0.469632 0.0399528 -0.15424 v -0.470766 -0.00661202 -0.0930419 v -0.486142 0.00947665 -0.0819458 v -0.495221 0.0472722 -0.1369 v -0.459705 -0.0431682 -0.033446 v -0.483546 -0.0248521 -0.0238816 v -0.494011 0.289082 -0.0628932 v -0.473502 0.238904 -0.0420457 v -0.507246 0.300137 -0.117724 v -0.512134 0.2833 -0.158502 v -0.513712 0.235303 -0.176549 v -0.50102 0.136093 -0.181582 v -0.485095 0.0532704 -0.118549 v -0.485253 0.0267755 -0.0671726 v -0.481172 0.0136801 -0.012201 v -0.456127 -0.0187428 0.0196958 v -0.462909 0.027933 0.024969 v -0.454923 0.0845591 -0.060163 v -0.441284 0.0577602 -0.0294063 v -0.440921 0.0840388 -0.0210813 v -0.457712 0.18288 0.0414318 v -0.458378 0.268123 0.0210228 v -0.461588 0.318505 -0.044618 v -0.468843 0.311858 -0.142898 v -0.453707 0.232836 -0.195204 v -0.436969 0.13182 -0.191047 v -0.423167 0.0473306 -0.148288 v -0.421945 -0.00467109 -0.089692 v -0.423991 -0.0291198 -0.0260915 v -0.429434 -0.0102776 0.0297746 v -0.445242 0.0345158 0.0460211 v -0.481617 0.0602039 -0.0524227 v -0.474104 0.129276 -0.0866754 v -0.480325 0.0824545 -0.101285 v -0.469474 0.0446648 -0.013376 v -0.478167 0.0776431 0.00467109 v -0.503592 0.223961 -0.101887 v -0.502575 0.131983 -0.147242 v -0.453707 0.0999988 0.0450097 v -0.413357 0.138549 -0.218945 v -0.402232 0.0251035 -0.169299 v -0.434023 0.249632 -0.229901 v -0.0871226 -0.186639 0.484069 v -0.139686 -0.173807 0.465537 v -0.158481 -0.142278 0.458685 v -0.0688299 0.0121893 0.376371 v -0.150805 -0.116468 0.431278 v -0.126228 -0.116368 0.360528 v -0.142316 -0.166791 0.41184 v -0.0730392 -0.218144 0.372349 v -0.282087 0.293548 0.454716 v -0.283513 0.320341 0.45129 v -0.124398 0.285323 0.452968 v -0.126795 0.269175 0.455978 v -0.119353 0.275057 0.469524 v -0.156265 0.2548 0.466332 v -0.265074 0.27356 0.421036 v -0.214762 0.253899 0.455218 v -0.141855 0.312577 0.484315 v -0.212745 0.255776 0.486875 v -0.277117 0.302621 0.410811 v -0.252014 0.333887 0.433371 v -0.20141 0.342405 0.464461 v -0.120767 0.295565 0.473184 v -0.145333 0.322832 0.456154 v -0.126041 0.301873 0.455785 v -0.119879 0.284837 0.470541 v -0.0516539 -0.100847 0.27211 v -0.454245 -0.41571 -0.353027 v -0.413392 -0.372097 -0.332203 v -0.255785 -0.398019 -0.4467 v -0.294685 -0.464338 -0.476902 v -0.174388 -0.714777 0.156607 v -0.0715543 -0.738454 0.180284 v -0.0798266 -0.636725 0.177765 v -0.171536 -0.601788 0.131147 v -0.337345 -0.494639 -0.0546091 v -0.355094 -0.419334 -0.180442 v -0.379665 -0.504905 -0.184915 v -0.373053 -0.619338 -0.0373044 v -0.45328 -0.545816 -0.197379 v -0.454128 -0.653065 -0.0942754 v -0.0965876 -0.904778 0.254759 v -0.0736004 -0.845567 0.20775 v -0.172974 -0.81408 0.195975 v -0.1973 -0.864375 0.243622 v -0.520961 -0.488138 -0.3841 v -0.556272 -0.584635 -0.21946 v -0.439238 -0.799155 0.0975785 v -0.381694 -0.748264 0.0442672 v -0.45103 -0.731883 -0.0219173 v -0.519067 -0.768135 -0.0077988 v -0.273785 -0.806328 0.115322 v -0.319391 -0.83802 0.183769 v -0.163088 -0.604103 -0.559421 v -0.356672 -0.543712 -0.525361 v -0.131226 -0.496761 -0.498854 v -0.114629 -0.410074 -0.45775 v -0.546533 -0.697291 -0.117619 v -0.100633 -0.33885 -0.437013 v -0.22677 -0.331835 -0.424707 v -0.274931 -0.684651 0.0790578 v -0.28021 -0.553908 0.0669913 v -0.378028 -0.321668 -0.326088 v 0.172833 0.300014 0.41564 v -0.171097 0.299996 0.415616 # 1258 vertices vt 0.532 0.923 0.000 vt 0.535 0.917 0.000 vt 0.542 0.923 0.000 vt 0.541 0.929 0.000 vt 0.521 0.984 0.000 vt 0.521 0.996 0.000 vt 0.505 0.998 0.000 vt 0.500 0.985 0.000 vt 0.504 0.917 0.000 vt 0.507 0.910 0.000 vt 0.516 0.910 0.000 vt 0.515 0.918 0.000 vt 0.523 0.921 0.000 vt 0.525 0.913 0.000 vt 0.549 0.958 0.000 vt 0.538 0.954 0.000 vt 0.544 0.942 0.000 vt 0.550 0.946 0.000 vt 0.545 0.935 0.000 vt 0.550 0.932 0.000 vt 0.547 0.974 0.000 vt 0.533 0.967 0.000 vt 0.500 0.917 0.000 vt 0.500 0.910 0.000 vt 0.542 0.987 0.000 vt 0.533 0.994 0.000 vt 0.616 0.254 0.000 vt 0.653 0.261 0.000 vt 0.658 0.307 0.000 vt 0.619 0.292 0.000 vt 0.636 0.438 0.000 vt 0.620 0.419 0.000 vt 0.627 0.396 0.000 vt 0.647 0.414 0.000 vt 0.886 0.312 0.000 vt 0.897 0.370 0.000 vt 0.860 0.369 0.000 vt 0.844 0.308 0.000 vt 0.740 0.593 0.000 vt 0.741 0.542 0.000 vt 0.759 0.541 0.000 vt 0.768 0.598 0.000 vt 0.644 0.213 0.000 vt 0.561 0.175 0.000 vt 0.566 0.146 0.000 vt 0.644 0.174 0.000 vt 0.580 0.254 0.000 vt 0.585 0.277 0.000 vt 0.565 0.268 0.000 vt 0.565 0.256 0.000 vt 0.590 0.217 0.000 vt 0.544 0.195 0.000 vt 0.771 0.721 0.000 vt 0.736 0.712 0.000 vt 0.758 0.653 0.000 vt 0.794 0.663 0.000 vt 0.669 0.622 0.000 vt 0.685 0.632 0.000 vt 0.665 0.669 0.000 vt 0.652 0.651 0.000 vt 0.623 0.588 0.000 vt 0.632 0.582 0.000 vt 0.639 0.590 0.000 vt 0.627 0.599 0.000 vt 0.641 0.632 0.000 vt 0.657 0.612 0.000 vt 0.619 0.580 0.000 vt 0.617 0.575 0.000 vt 0.623 0.573 0.000 vt 0.627 0.576 0.000 vt 0.708 0.702 0.000 vt 0.729 0.646 0.000 vt 0.633 0.614 0.000 vt 0.647 0.601 0.000 vt 0.604 0.718 0.000 vt 0.574 0.725 0.000 vt 0.567 0.686 0.000 vt 0.596 0.682 0.000 vt 0.562 0.648 0.000 vt 0.590 0.649 0.000 vt 0.618 0.756 0.000 vt 0.584 0.769 0.000 vt 0.586 0.587 0.000 vt 0.566 0.586 0.000 vt 0.568 0.579 0.000 vt 0.586 0.580 0.000 vt 0.569 0.574 0.000 vt 0.586 0.573 0.000 vt 0.562 0.627 0.000 vt 0.587 0.627 0.000 vt 0.587 0.610 0.000 vt 0.563 0.608 0.000 vt 0.565 0.595 0.000 vt 0.587 0.596 0.000 vt 0.521 0.441 0.000 vt 0.526 0.450 0.000 vt 0.520 0.450 0.000 vt 0.517 0.445 0.000 vt 0.720 0.504 0.000 vt 0.709 0.467 0.000 vt 0.727 0.446 0.000 vt 0.738 0.494 0.000 vt 0.656 0.383 0.000 vt 0.660 0.348 0.000 vt 0.684 0.368 0.000 vt 0.673 0.403 0.000 vt 0.572 0.371 0.000 vt 0.573 0.365 0.000 vt 0.581 0.364 0.000 vt 0.581 0.374 0.000 vt 0.708 0.400 0.000 vt 0.693 0.431 0.000 vt 0.604 0.401 0.000 vt 0.609 0.383 0.000 vt 0.557 0.364 0.000 vt 0.559 0.365 0.000 vt 0.557 0.366 0.000 vt 0.556 0.364 0.000 vt 0.552 0.367 0.000 vt 0.552 0.364 0.000 vt 0.568 0.377 0.000 vt 0.561 0.374 0.000 vt 0.566 0.370 0.000 vt 0.594 0.377 0.000 vt 0.594 0.363 0.000 vt 0.653 0.551 0.000 vt 0.644 0.534 0.000 vt 0.658 0.523 0.000 vt 0.666 0.545 0.000 vt 0.637 0.480 0.000 vt 0.625 0.458 0.000 vt 0.649 0.459 0.000 vt 0.662 0.434 0.000 vt 0.557 0.345 0.000 vt 0.553 0.353 0.000 vt 0.543 0.349 0.000 vt 0.546 0.337 0.000 vt 0.586 0.403 0.000 vt 0.573 0.392 0.000 vt 0.579 0.382 0.000 vt 0.591 0.389 0.000 vt 0.572 0.343 0.000 vt 0.584 0.331 0.000 vt 0.590 0.347 0.000 vt 0.578 0.353 0.000 vt 0.553 0.358 0.000 vt 0.543 0.355 0.000 vt 0.553 0.499 0.000 vt 0.541 0.507 0.000 vt 0.542 0.484 0.000 vt 0.553 0.477 0.000 vt 0.539 0.532 0.000 vt 0.529 0.541 0.000 vt 0.531 0.513 0.000 vt 0.551 0.538 0.000 vt 0.538 0.552 0.000 vt 0.552 0.521 0.000 vt 0.908 0.437 0.000 vt 0.876 0.429 0.000 vt 0.608 0.340 0.000 vt 0.599 0.314 0.000 vt 0.629 0.336 0.000 vt 0.691 0.326 0.000 vt 0.723 0.365 0.000 vt 0.748 0.426 0.000 vt 0.755 0.489 0.000 vt 0.564 0.825 0.000 vt 0.590 0.868 0.000 vt 0.558 0.886 0.000 vt 0.533 0.834 0.000 vt 0.637 0.789 0.000 vt 0.673 0.755 0.000 vt 0.702 0.774 0.000 vt 0.665 0.817 0.000 vt 0.740 0.787 0.000 vt 0.545 0.727 0.000 vt 0.540 0.686 0.000 vt 0.551 0.550 0.000 vt 0.538 0.572 0.000 vt 0.520 0.546 0.000 vt 0.522 0.517 0.000 vt 0.552 0.775 0.000 vt 0.524 0.777 0.000 vt 0.521 0.728 0.000 vt 0.500 0.687 0.000 vt 0.500 0.651 0.000 vt 0.515 0.650 0.000 vt 0.518 0.687 0.000 vt 0.500 0.727 0.000 vt 0.625 0.671 0.000 vt 0.618 0.644 0.000 vt 0.591 0.533 0.000 vt 0.571 0.539 0.000 vt 0.569 0.527 0.000 vt 0.589 0.518 0.000 vt 0.545 0.436 0.000 vt 0.525 0.427 0.000 vt 0.528 0.413 0.000 vt 0.549 0.425 0.000 vt 0.556 0.449 0.000 vt 0.563 0.439 0.000 vt 0.514 0.395 0.000 vt 0.532 0.396 0.000 vt 0.513 0.409 0.000 vt 0.566 0.511 0.000 vt 0.564 0.490 0.000 vt 0.577 0.478 0.000 vt 0.584 0.500 0.000 vt 0.500 0.408 0.000 vt 0.500 0.394 0.000 vt 0.571 0.457 0.000 vt 0.561 0.468 0.000 vt 0.554 0.561 0.000 vt 0.557 0.563 0.000 vt 0.552 0.569 0.000 vt 0.548 0.569 0.000 vt 0.627 0.847 0.000 vt 0.674 0.871 0.000 vt 0.645 0.898 0.000 vt 0.776 0.920 0.000 vt 0.709 0.921 0.000 vt 0.729 0.888 0.000 vt 0.783 0.887 0.000 vt 0.693 0.947 0.000 vt 0.621 0.920 0.000 vt 0.535 0.642 0.000 vt 0.542 0.618 0.000 vt 0.545 0.599 0.000 vt 0.559 0.383 0.000 vt 0.552 0.377 0.000 vt 0.531 0.470 0.000 vt 0.520 0.472 0.000 vt 0.517 0.456 0.000 vt 0.528 0.457 0.000 vt 0.530 0.438 0.000 vt 0.517 0.436 0.000 vt 0.528 0.383 0.000 vt 0.513 0.384 0.000 vt 0.512 0.374 0.000 vt 0.526 0.374 0.000 vt 0.512 0.367 0.000 vt 0.526 0.366 0.000 vt 0.512 0.362 0.000 vt 0.526 0.362 0.000 vt 0.511 0.422 0.000 vt 0.500 0.384 0.000 vt 0.500 0.375 0.000 vt 0.500 0.362 0.000 vt 0.500 0.367 0.000 vt 0.511 0.472 0.000 vt 0.508 0.457 0.000 vt 0.521 0.491 0.000 vt 0.512 0.519 0.000 vt 0.512 0.491 0.000 vt 0.511 0.550 0.000 vt 0.520 0.576 0.000 vt 0.510 0.583 0.000 vt 0.500 0.457 0.000 vt 0.500 0.472 0.000 vt 0.500 0.491 0.000 vt 0.654 0.584 0.000 vt 0.656 0.568 0.000 vt 0.669 0.567 0.000 vt 0.666 0.589 0.000 vt 0.705 0.639 0.000 vt 0.718 0.591 0.000 vt 0.684 0.563 0.000 vt 0.680 0.592 0.000 vt 0.637 0.575 0.000 vt 0.636 0.566 0.000 vt 0.645 0.567 0.000 vt 0.645 0.579 0.000 vt 0.723 0.546 0.000 vt 0.697 0.592 0.000 vt 0.702 0.554 0.000 vt 0.500 0.163 0.000 vt 0.500 0.137 0.000 vt 0.579 0.298 0.000 vt 0.570 0.317 0.000 vt 0.554 0.307 0.000 vt 0.560 0.287 0.000 vt 0.534 0.318 0.000 vt 0.517 0.314 0.000 vt 0.519 0.296 0.000 vt 0.538 0.300 0.000 vt 0.562 0.362 0.000 vt 0.559 0.363 0.000 vt 0.557 0.362 0.000 vt 0.559 0.360 0.000 vt 0.563 0.365 0.000 vt 0.561 0.368 0.000 vt 0.543 0.360 0.000 vt 0.531 0.358 0.000 vt 0.531 0.351 0.000 vt 0.611 0.437 0.000 vt 0.613 0.475 0.000 vt 0.624 0.497 0.000 vt 0.580 0.445 0.000 vt 0.590 0.466 0.000 vt 0.598 0.418 0.000 vt 0.648 0.501 0.000 vt 0.633 0.516 0.000 vt 0.641 0.554 0.000 vt 0.630 0.541 0.000 vt 0.733 0.331 0.000 vt 0.696 0.288 0.000 vt 0.706 0.252 0.000 vt 0.751 0.313 0.000 vt 0.683 0.535 0.000 vt 0.674 0.508 0.000 vt 0.999 0.696 0.000 vt 0.986 0.778 0.000 vt 0.950 0.772 0.000 vt 0.967 0.695 0.000 vt 0.600 0.811 0.000 vt 0.552 0.361 0.000 vt 0.547 0.367 0.000 vt 0.546 0.364 0.000 vt 0.525 0.254 0.000 vt 0.546 0.261 0.000 vt 0.542 0.280 0.000 vt 0.522 0.274 0.000 vt 0.631 0.369 0.000 vt 0.678 0.460 0.000 vt 0.662 0.482 0.000 vt 0.770 0.948 0.000 vt 0.762 0.981 0.000 vt 0.676 0.977 0.000 vt 0.845 0.915 0.000 vt 0.835 0.891 0.000 vt 0.569 0.560 0.000 vt 0.582 0.558 0.000 vt 0.580 0.563 0.000 vt 0.569 0.564 0.000 vt 0.590 0.544 0.000 vt 0.571 0.548 0.000 vt 0.635 0.701 0.000 vt 0.651 0.731 0.000 vt 0.607 0.593 0.000 vt 0.609 0.606 0.000 vt 0.543 0.570 0.000 vt 0.553 0.556 0.000 vt 0.552 0.580 0.000 vt 0.556 0.574 0.000 vt 0.569 0.554 0.000 vt 0.585 0.551 0.000 vt 0.559 0.566 0.000 vt 0.550 0.458 0.000 vt 0.532 0.330 0.000 vt 0.549 0.325 0.000 vt 0.610 0.364 0.000 vt 0.589 0.432 0.000 vt 0.578 0.417 0.000 vt 0.570 0.357 0.000 vt 0.565 0.360 0.000 vt 0.562 0.356 0.000 vt 0.565 0.351 0.000 vt 0.557 0.364 0.000 vt 0.556 0.364 0.000 vt 0.548 0.371 0.000 vt 0.557 0.371 0.000 vt 0.762 0.385 0.000 vt 0.513 0.445 0.000 vt 0.508 0.444 0.000 vt 0.500 0.520 0.000 vt 0.939 0.378 0.000 vt 0.932 0.316 0.000 vt 0.972 0.321 0.000 vt 0.974 0.384 0.000 vt 0.605 0.572 0.000 vt 0.605 0.578 0.000 vt 0.605 0.584 0.000 vt 0.559 0.571 0.000 vt 0.562 0.333 0.000 vt 0.500 0.552 0.000 vt 0.500 0.585 0.000 vt 0.531 0.343 0.000 vt 0.514 0.338 0.000 vt 0.516 0.324 0.000 vt 0.532 0.488 0.000 vt 0.534 0.448 0.000 vt 0.540 0.446 0.000 vt 0.545 0.448 0.000 vt 0.538 0.455 0.000 vt 0.541 0.466 0.000 vt 0.612 0.623 0.000 vt 0.567 0.366 0.000 vt 0.513 0.356 0.000 vt 0.500 0.355 0.000 vt 0.500 0.346 0.000 vt 0.514 0.348 0.000 vt 0.543 0.363 0.000 vt 0.552 0.364 0.000 vt 0.531 0.362 0.000 vt 0.512 0.361 0.000 vt 0.509 0.433 0.000 vt 0.500 0.444 0.000 vt 0.500 0.432 0.000 vt 0.603 0.551 0.000 vt 0.599 0.557 0.000 vt 0.627 0.570 0.000 vt 0.631 0.571 0.000 vt 0.625 0.566 0.000 vt 0.622 0.569 0.000 vt 0.621 0.567 0.000 vt 0.529 0.234 0.000 vt 0.500 0.249 0.000 vt 0.500 0.227 0.000 vt 0.550 0.245 0.000 vt 0.857 0.816 0.000 vt 0.825 0.804 0.000 vt 0.851 0.737 0.000 vt 0.886 0.748 0.000 vt 0.821 0.866 0.000 vt 0.798 0.856 0.000 vt 0.783 0.797 0.000 vt 0.810 0.729 0.000 vt 0.755 0.848 0.000 vt 0.534 0.215 0.000 vt 0.563 0.233 0.000 vt 0.548 0.588 0.000 vt 0.884 0.835 0.000 vt 0.908 0.854 0.000 vt 0.919 0.761 0.000 vt 0.947 0.512 0.000 vt 0.944 0.446 0.000 vt 0.974 0.452 0.000 vt 0.974 0.519 0.000 vt 0.915 0.504 0.000 vt 0.887 0.498 0.000 vt 0.917 0.564 0.000 vt 0.890 0.556 0.000 vt 0.999 0.634 0.000 vt 0.973 0.633 0.000 vt 0.975 0.577 0.000 vt 0.999 0.579 0.000 vt 0.882 0.614 0.000 vt 0.911 0.622 0.000 vt 0.901 0.679 0.000 vt 0.868 0.671 0.000 vt 0.833 0.667 0.000 vt 0.708 0.836 0.000 vt 0.500 0.205 0.000 vt 0.826 0.364 0.000 vt 0.801 0.303 0.000 vt 0.613 0.529 0.000 vt 0.607 0.544 0.000 vt 0.541 0.380 0.000 vt 0.538 0.372 0.000 vt 0.537 0.366 0.000 vt 0.537 0.363 0.000 vt 0.598 0.945 0.000 vt 0.524 0.902 0.000 vt 0.599 0.489 0.000 vt 0.609 0.563 0.000 vt 0.596 0.563 0.000 vt 0.612 0.559 0.000 vt 0.557 0.569 0.000 vt 0.620 0.571 0.000 vt 0.616 0.569 0.000 vt 0.618 0.569 0.000 vt 0.569 0.568 0.000 vt 0.561 0.568 0.000 vt 0.579 0.567 0.000 vt 0.616 0.564 0.000 vt 0.613 0.567 0.000 vt 0.607 0.567 0.000 vt 0.587 0.568 0.000 vt 0.606 0.568 0.000 vt 0.630 0.565 0.000 vt 0.548 0.389 0.000 vt 0.601 0.452 0.000 vt 0.529 0.566 0.000 vt 0.684 0.686 0.000 vt 0.872 0.222 0.000 vt 0.876 0.265 0.000 vt 0.825 0.258 0.000 vt 0.821 0.214 0.000 vt 0.561 0.119 0.000 vt 0.500 0.114 0.000 vt 0.771 0.304 0.000 vt 0.797 0.363 0.000 vt 0.726 0.227 0.000 vt 0.777 0.371 0.000 vt 0.947 0.571 0.000 vt 0.999 0.388 0.000 vt 0.999 0.456 0.000 vt 0.999 0.524 0.000 vt 0.936 0.877 0.000 vt 0.856 0.945 0.000 vt 0.999 0.323 0.000 vt 0.935 0.689 0.000 vt 0.776 0.240 0.000 vt 0.928 0.265 0.000 vt 0.969 0.264 0.000 vt 0.999 0.267 0.000 vt 0.943 0.628 0.000 vt 0.806 0.622 0.000 vt 0.851 0.611 0.000 vt 0.500 0.777 0.000 vt 0.500 0.839 0.000 vt 0.692 0.489 0.000 vt 0.631 0.558 0.000 vt 0.622 0.562 0.000 vt 0.626 0.560 0.000 vt 0.555 0.413 0.000 vt 0.570 0.429 0.000 vt 0.539 0.440 0.000 vt 0.524 0.607 0.000 vt 0.531 0.591 0.000 vt 0.500 0.361 0.000 vt 0.500 0.321 0.000 vt 0.500 0.312 0.000 vt 0.500 0.336 0.000 vt 0.500 0.294 0.000 vt 0.500 0.273 0.000 vt 0.622 0.549 0.000 vt 0.616 0.554 0.000 vt 0.607 0.509 0.000 vt 0.701 0.520 0.000 vt 0.500 0.421 0.000 vt 0.564 0.403 0.000 vt 0.511 0.615 0.000 vt 0.500 0.618 0.000 vt 0.617 0.568 0.000 vt 0.636 0.139 0.000 vt 0.764 0.192 0.000 vt 0.921 0.220 0.000 vt 0.967 0.219 0.000 vt 0.708 0.168 0.000 vt 0.999 0.218 0.000 vt 0.803 0.523 0.000 vt 0.794 0.535 0.000 vt 0.783 0.527 0.000 vt 0.791 0.508 0.000 vt 0.789 0.571 0.000 vt 0.797 0.562 0.000 vt 0.813 0.591 0.000 vt 0.815 0.578 0.000 vt 0.839 0.583 0.000 vt 0.835 0.574 0.000 vt 0.850 0.569 0.000 vt 0.845 0.560 0.000 vt 0.855 0.539 0.000 vt 0.847 0.535 0.000 vt 0.850 0.501 0.000 vt 0.841 0.502 0.000 vt 0.814 0.438 0.000 vt 0.836 0.464 0.000 vt 0.828 0.472 0.000 vt 0.809 0.452 0.000 vt 0.792 0.427 0.000 vt 0.790 0.441 0.000 vt 0.818 0.567 0.000 vt 0.807 0.550 0.000 vt 0.831 0.561 0.000 vt 0.839 0.553 0.000 vt 0.837 0.534 0.000 vt 0.831 0.505 0.000 vt 0.820 0.479 0.000 vt 0.804 0.465 0.000 vt 0.786 0.460 0.000 vt 0.773 0.456 0.000 vt 0.779 0.433 0.000 vt 0.797 0.489 0.000 vt 0.785 0.495 0.000 vt 0.789 0.486 0.000 vt 0.772 0.537 0.000 vt 0.781 0.583 0.000 vt 0.812 0.602 0.000 vt 0.848 0.587 0.000 vt 0.862 0.546 0.000 vt 0.859 0.500 0.000 vt 0.820 0.412 0.000 vt 0.843 0.450 0.000 vt 0.791 0.404 0.000 vt 0.773 0.417 0.000 vt 0.764 0.447 0.000 vt 0.801 0.477 0.000 vt 0.813 0.487 0.000 vt 0.806 0.496 0.000 vt 0.787 0.478 0.000 vt 0.778 0.489 0.000 vt 0.822 0.538 0.000 vt 0.822 0.510 0.000 vt 0.767 0.492 0.000 vt 0.870 0.496 0.000 vt 0.851 0.425 0.000 vt 0.872 0.552 0.000 vt 0.500 0.183 0.000 vt 0.516 0.930 0.000 vt 0.500 0.928 0.000 vt 0.528 0.934 0.000 vt 0.537 0.938 0.000 vt 0.516 0.970 0.000 vt 0.520 0.955 0.000 vt 0.530 0.952 0.000 vt 0.522 0.944 0.000 vt 0.512 0.942 0.000 vt 0.615 0.572 0.000 vt 0.612 0.569 0.000 vt 0.576 0.968 0.000 vt 0.573 0.973 0.000 vt 0.562 0.969 0.000 vt 0.563 0.961 0.000 vt 0.571 0.956 0.000 vt 0.582 0.961 0.000 vt 0.611 0.961 0.000 vt 0.606 0.967 0.000 vt 0.595 0.960 0.000 vt 0.601 0.955 0.000 vt 0.570 0.569 0.000 vt 0.595 0.566 0.000 vt 0.616 0.967 0.000 vt 0.617 0.975 0.000 vt 0.607 0.978 0.000 vt 0.614 0.982 0.000 vt 0.605 0.991 0.000 vt 0.599 0.986 0.000 vt 0.593 0.996 0.000 vt 0.589 0.989 0.000 vt 0.562 0.570 0.000 vt 0.573 0.994 0.000 vt 0.579 0.987 0.000 vt 0.584 0.996 0.000 vt 0.581 0.953 0.000 vt 0.592 0.953 0.000 vt 0.561 0.988 0.000 vt 0.572 0.981 0.000 vt 0.563 0.978 0.000 vt 0.500 0.970 0.000 vt 0.500 0.943 0.000 vt 0.511 0.956 0.000 vt 0.500 0.956 0.000 vt 0.868 0.132 0.000 vt 0.867 0.090 0.000 vt 0.916 0.092 0.000 vt 0.918 0.133 0.000 vt 0.554 0.066 0.000 vt 0.612 0.070 0.000 vt 0.619 0.103 0.000 vt 0.558 0.095 0.000 vt 0.815 0.169 0.000 vt 0.758 0.148 0.000 vt 0.747 0.102 0.000 vt 0.814 0.126 0.000 vt 0.770 0.072 0.000 vt 0.817 0.087 0.000 vt 0.552 0.038 0.000 vt 0.551 0.020 0.000 vt 0.602 0.021 0.000 vt 0.605 0.039 0.000 vt 0.821 0.050 0.000 vt 0.867 0.055 0.000 vt 0.712 0.053 0.000 vt 0.700 0.022 0.000 vt 0.739 0.023 0.000 vt 0.740 0.052 0.000 vt 0.652 0.022 0.000 vt 0.659 0.043 0.000 vt 0.913 0.055 0.000 vt 0.959 0.055 0.000 vt 0.960 0.091 0.000 vt 0.999 0.089 0.000 vt 0.999 0.131 0.000 vt 0.962 0.133 0.000 vt 0.999 0.053 0.000 vt 0.778 0.038 0.000 vt 0.917 0.177 0.000 vt 0.965 0.178 0.000 vt 0.674 0.083 0.000 vt 0.685 0.124 0.000 vt 0.999 0.175 0.000 vt 0.500 0.037 0.000 vt 0.500 0.066 0.000 vt 0.871 0.175 0.000 vt 0.500 0.019 0.000 vt 0.500 0.092 0.000 vt 0.999 0.002 0.000 vt 0.958 0.002 0.000 vt 0.867 0.002 0.000 vt 0.823 0.002 0.000 vt 0.908 0.002 0.000 vt 0.601 0.002 0.000 vt 0.550 0.002 0.000 vt 0.697 0.002 0.000 vt 0.650 0.002 0.000 vt 0.782 0.002 0.000 vt 0.740 0.002 0.000 vt 0.500 0.002 0.000 vt 0.468 0.923 0.000 vt 0.459 0.929 0.000 vt 0.458 0.923 0.000 vt 0.465 0.917 0.000 vt 0.479 0.984 0.000 vt 0.495 0.998 0.000 vt 0.479 0.996 0.000 vt 0.496 0.917 0.000 vt 0.485 0.918 0.000 vt 0.484 0.910 0.000 vt 0.493 0.910 0.000 vt 0.477 0.921 0.000 vt 0.475 0.913 0.000 vt 0.451 0.958 0.000 vt 0.450 0.946 0.000 vt 0.456 0.942 0.000 vt 0.462 0.954 0.000 vt 0.455 0.935 0.000 vt 0.450 0.932 0.000 vt 0.467 0.967 0.000 vt 0.453 0.974 0.000 vt 0.467 0.994 0.000 vt 0.458 0.987 0.000 vt 0.384 0.254 0.000 vt 0.381 0.292 0.000 vt 0.342 0.307 0.000 vt 0.347 0.261 0.000 vt 0.364 0.438 0.000 vt 0.353 0.414 0.000 vt 0.373 0.396 0.000 vt 0.380 0.419 0.000 vt 0.114 0.312 0.000 vt 0.156 0.308 0.000 vt 0.140 0.369 0.000 vt 0.103 0.370 0.000 vt 0.260 0.593 0.000 vt 0.232 0.598 0.000 vt 0.241 0.541 0.000 vt 0.259 0.542 0.000 vt 0.356 0.213 0.000 vt 0.356 0.174 0.000 vt 0.434 0.146 0.000 vt 0.439 0.175 0.000 vt 0.420 0.254 0.000 vt 0.435 0.256 0.000 vt 0.435 0.268 0.000 vt 0.415 0.277 0.000 vt 0.456 0.195 0.000 vt 0.410 0.217 0.000 vt 0.229 0.721 0.000 vt 0.206 0.663 0.000 vt 0.242 0.653 0.000 vt 0.264 0.712 0.000 vt 0.331 0.622 0.000 vt 0.348 0.651 0.000 vt 0.335 0.669 0.000 vt 0.315 0.632 0.000 vt 0.377 0.588 0.000 vt 0.373 0.599 0.000 vt 0.361 0.590 0.000 vt 0.368 0.582 0.000 vt 0.359 0.632 0.000 vt 0.343 0.612 0.000 vt 0.381 0.580 0.000 vt 0.373 0.576 0.000 vt 0.377 0.573 0.000 vt 0.383 0.575 0.000 vt 0.292 0.702 0.000 vt 0.271 0.646 0.000 vt 0.353 0.601 0.000 vt 0.367 0.614 0.000 vt 0.396 0.718 0.000 vt 0.404 0.682 0.000 vt 0.433 0.686 0.000 vt 0.426 0.725 0.000 vt 0.410 0.649 0.000 vt 0.438 0.648 0.000 vt 0.416 0.769 0.000 vt 0.382 0.756 0.000 vt 0.414 0.587 0.000 vt 0.414 0.580 0.000 vt 0.432 0.579 0.000 vt 0.434 0.586 0.000 vt 0.431 0.574 0.000 vt 0.414 0.573 0.000 vt 0.413 0.627 0.000 vt 0.438 0.627 0.000 vt 0.413 0.610 0.000 vt 0.413 0.596 0.000 vt 0.435 0.595 0.000 vt 0.437 0.608 0.000 vt 0.479 0.441 0.000 vt 0.483 0.445 0.000 vt 0.480 0.450 0.000 vt 0.474 0.450 0.000 vt 0.280 0.504 0.000 vt 0.262 0.494 0.000 vt 0.273 0.446 0.000 vt 0.291 0.467 0.000 vt 0.344 0.383 0.000 vt 0.327 0.403 0.000 vt 0.316 0.368 0.000 vt 0.340 0.348 0.000 vt 0.428 0.371 0.000 vt 0.419 0.374 0.000 vt 0.419 0.364 0.000 vt 0.427 0.365 0.000 vt 0.307 0.431 0.000 vt 0.292 0.400 0.000 vt 0.391 0.383 0.000 vt 0.396 0.401 0.000 vt 0.443 0.364 0.000 vt 0.444 0.364 0.000 vt 0.443 0.366 0.000 vt 0.441 0.365 0.000 vt 0.448 0.367 0.000 vt 0.448 0.364 0.000 vt 0.432 0.377 0.000 vt 0.434 0.370 0.000 vt 0.439 0.374 0.000 vt 0.406 0.377 0.000 vt 0.406 0.363 0.000 vt 0.347 0.551 0.000 vt 0.334 0.545 0.000 vt 0.342 0.523 0.000 vt 0.356 0.534 0.000 vt 0.363 0.480 0.000 vt 0.351 0.459 0.000 vt 0.375 0.458 0.000 vt 0.338 0.434 0.000 vt 0.443 0.345 0.000 vt 0.454 0.337 0.000 vt 0.457 0.349 0.000 vt 0.447 0.353 0.000 vt 0.414 0.403 0.000 vt 0.409 0.389 0.000 vt 0.421 0.382 0.000 vt 0.427 0.392 0.000 vt 0.428 0.343 0.000 vt 0.422 0.353 0.000 vt 0.410 0.347 0.000 vt 0.416 0.331 0.000 vt 0.457 0.355 0.000 vt 0.447 0.358 0.000 vt 0.447 0.499 0.000 vt 0.447 0.477 0.000 vt 0.458 0.484 0.000 vt 0.459 0.507 0.000 vt 0.461 0.532 0.000 vt 0.469 0.513 0.000 vt 0.471 0.541 0.000 vt 0.449 0.538 0.000 vt 0.448 0.521 0.000 vt 0.462 0.552 0.000 vt 0.124 0.429 0.000 vt 0.092 0.437 0.000 vt 0.392 0.340 0.000 vt 0.371 0.336 0.000 vt 0.401 0.314 0.000 vt 0.309 0.326 0.000 vt 0.252 0.426 0.000 vt 0.277 0.365 0.000 vt 0.245 0.489 0.000 vt 0.436 0.825 0.000 vt 0.467 0.834 0.000 vt 0.442 0.886 0.000 vt 0.410 0.868 0.000 vt 0.363 0.789 0.000 vt 0.335 0.817 0.000 vt 0.298 0.774 0.000 vt 0.327 0.755 0.000 vt 0.260 0.787 0.000 vt 0.460 0.686 0.000 vt 0.455 0.727 0.000 vt 0.462 0.572 0.000 vt 0.449 0.550 0.000 vt 0.480 0.546 0.000 vt 0.478 0.517 0.000 vt 0.479 0.728 0.000 vt 0.476 0.777 0.000 vt 0.448 0.775 0.000 vt 0.482 0.687 0.000 vt 0.485 0.650 0.000 vt 0.375 0.671 0.000 vt 0.382 0.644 0.000 vt 0.409 0.533 0.000 vt 0.411 0.518 0.000 vt 0.431 0.527 0.000 vt 0.429 0.539 0.000 vt 0.455 0.436 0.000 vt 0.451 0.425 0.000 vt 0.472 0.413 0.000 vt 0.475 0.427 0.000 vt 0.444 0.449 0.000 vt 0.437 0.439 0.000 vt 0.486 0.395 0.000 vt 0.487 0.409 0.000 vt 0.468 0.396 0.000 vt 0.434 0.511 0.000 vt 0.416 0.500 0.000 vt 0.423 0.478 0.000 vt 0.436 0.490 0.000 vt 0.429 0.457 0.000 vt 0.439 0.468 0.000 vt 0.446 0.561 0.000 vt 0.452 0.569 0.000 vt 0.448 0.569 0.000 vt 0.443 0.563 0.000 vt 0.373 0.847 0.000 vt 0.355 0.898 0.000 vt 0.326 0.871 0.000 vt 0.224 0.920 0.000 vt 0.217 0.887 0.000 vt 0.271 0.888 0.000 vt 0.291 0.921 0.000 vt 0.379 0.920 0.000 vt 0.307 0.947 0.000 vt 0.465 0.642 0.000 vt 0.455 0.599 0.000 vt 0.458 0.618 0.000 vt 0.448 0.377 0.000 vt 0.441 0.383 0.000 vt 0.469 0.470 0.000 vt 0.472 0.457 0.000 vt 0.483 0.456 0.000 vt 0.480 0.472 0.000 vt 0.470 0.438 0.000 vt 0.483 0.436 0.000 vt 0.472 0.383 0.000 vt 0.474 0.374 0.000 vt 0.488 0.374 0.000 vt 0.487 0.384 0.000 vt 0.474 0.366 0.000 vt 0.488 0.367 0.000 vt 0.474 0.362 0.000 vt 0.488 0.362 0.000 vt 0.489 0.422 0.000 vt 0.492 0.457 0.000 vt 0.489 0.472 0.000 vt 0.479 0.491 0.000 vt 0.488 0.491 0.000 vt 0.488 0.519 0.000 vt 0.489 0.550 0.000 vt 0.490 0.583 0.000 vt 0.480 0.576 0.000 vt 0.346 0.584 0.000 vt 0.334 0.589 0.000 vt 0.331 0.567 0.000 vt 0.344 0.568 0.000 vt 0.295 0.639 0.000 vt 0.282 0.591 0.000 vt 0.320 0.592 0.000 vt 0.316 0.563 0.000 vt 0.363 0.575 0.000 vt 0.355 0.579 0.000 vt 0.355 0.567 0.000 vt 0.364 0.566 0.000 vt 0.277 0.546 0.000 vt 0.298 0.554 0.000 vt 0.303 0.592 0.000 vt 0.421 0.298 0.000 vt 0.440 0.287 0.000 vt 0.446 0.307 0.000 vt 0.430 0.317 0.000 vt 0.466 0.318 0.000 vt 0.462 0.300 0.000 vt 0.481 0.296 0.000 vt 0.483 0.314 0.000 vt 0.438 0.362 0.000 vt 0.441 0.360 0.000 vt 0.443 0.362 0.000 vt 0.441 0.363 0.000 vt 0.439 0.368 0.000 vt 0.437 0.365 0.000 vt 0.469 0.351 0.000 vt 0.469 0.358 0.000 vt 0.457 0.360 0.000 vt 0.389 0.437 0.000 vt 0.387 0.475 0.000 vt 0.376 0.497 0.000 vt 0.420 0.445 0.000 vt 0.410 0.466 0.000 vt 0.402 0.418 0.000 vt 0.352 0.501 0.000 vt 0.367 0.516 0.000 vt 0.359 0.554 0.000 vt 0.370 0.541 0.000 vt 0.267 0.331 0.000 vt 0.249 0.313 0.000 vt 0.294 0.252 0.000 vt 0.304 0.288 0.000 vt 0.317 0.535 0.000 vt 0.326 0.508 0.000 vt 0.001 0.696 0.000 vt 0.033 0.695 0.000 vt 0.050 0.772 0.000 vt 0.014 0.778 0.000 vt 0.400 0.811 0.000 vt 0.448 0.361 0.000 vt 0.454 0.364 0.000 vt 0.453 0.367 0.000 vt 0.475 0.254 0.000 vt 0.478 0.274 0.000 vt 0.458 0.280 0.000 vt 0.454 0.261 0.000 vt 0.369 0.369 0.000 vt 0.322 0.460 0.000 vt 0.338 0.482 0.000 vt 0.324 0.977 0.000 vt 0.238 0.981 0.000 vt 0.230 0.948 0.000 vt 0.155 0.915 0.000 vt 0.165 0.891 0.000 vt 0.431 0.560 0.000 vt 0.431 0.564 0.000 vt 0.420 0.563 0.000 vt 0.418 0.558 0.000 vt 0.410 0.544 0.000 vt 0.429 0.548 0.000 vt 0.349 0.731 0.000 vt 0.365 0.701 0.000 vt 0.391 0.606 0.000 vt 0.393 0.593 0.000 vt 0.457 0.570 0.000 vt 0.447 0.556 0.000 vt 0.444 0.574 0.000 vt 0.448 0.580 0.000 vt 0.415 0.551 0.000 vt 0.431 0.554 0.000 vt 0.441 0.566 0.000 vt 0.450 0.458 0.000 vt 0.451 0.325 0.000 vt 0.468 0.330 0.000 vt 0.390 0.364 0.000 vt 0.411 0.432 0.000 vt 0.422 0.417 0.000 vt 0.430 0.357 0.000 vt 0.435 0.351 0.000 vt 0.438 0.356 0.000 vt 0.435 0.360 0.000 vt 0.443 0.364 0.000 vt 0.444 0.364 0.000 vt 0.443 0.371 0.000 vt 0.452 0.371 0.000 vt 0.238 0.385 0.000 vt 0.487 0.445 0.000 vt 0.492 0.444 0.000 vt 0.061 0.378 0.000 vt 0.026 0.384 0.000 vt 0.028 0.321 0.000 vt 0.068 0.316 0.000 vt 0.395 0.572 0.000 vt 0.395 0.578 0.000 vt 0.395 0.584 0.000 vt 0.441 0.571 0.000 vt 0.438 0.333 0.000 vt 0.469 0.343 0.000 vt 0.486 0.338 0.000 vt 0.484 0.324 0.000 vt 0.468 0.488 0.000 vt 0.466 0.448 0.000 vt 0.462 0.455 0.000 vt 0.455 0.448 0.000 vt 0.460 0.446 0.000 vt 0.459 0.466 0.000 vt 0.388 0.623 0.000 vt 0.433 0.366 0.000 vt 0.487 0.356 0.000 vt 0.486 0.348 0.000 vt 0.457 0.363 0.000 vt 0.448 0.364 0.000 vt 0.469 0.362 0.000 vt 0.488 0.361 0.000 vt 0.491 0.433 0.000 vt 0.401 0.557 0.000 vt 0.397 0.551 0.000 vt 0.373 0.570 0.000 vt 0.369 0.571 0.000 vt 0.375 0.566 0.000 vt 0.379 0.567 0.000 vt 0.378 0.569 0.000 vt 0.471 0.234 0.000 vt 0.450 0.245 0.000 vt 0.143 0.816 0.000 vt 0.114 0.748 0.000 vt 0.149 0.737 0.000 vt 0.175 0.804 0.000 vt 0.202 0.856 0.000 vt 0.179 0.866 0.000 vt 0.190 0.729 0.000 vt 0.217 0.797 0.000 vt 0.245 0.848 0.000 vt 0.466 0.215 0.000 vt 0.437 0.233 0.000 vt 0.452 0.588 0.000 vt 0.092 0.854 0.000 vt 0.116 0.835 0.000 vt 0.081 0.761 0.000 vt 0.053 0.512 0.000 vt 0.026 0.519 0.000 vt 0.026 0.452 0.000 vt 0.056 0.446 0.000 vt 0.113 0.498 0.000 vt 0.085 0.504 0.000 vt 0.110 0.556 0.000 vt 0.083 0.564 0.000 vt 0.001 0.634 0.000 vt 0.001 0.579 0.000 vt 0.025 0.577 0.000 vt 0.027 0.633 0.000 vt 0.118 0.614 0.000 vt 0.132 0.671 0.000 vt 0.099 0.679 0.000 vt 0.089 0.622 0.000 vt 0.167 0.667 0.000 vt 0.292 0.836 0.000 vt 0.199 0.303 0.000 vt 0.174 0.364 0.000 vt 0.393 0.544 0.000 vt 0.387 0.529 0.000 vt 0.459 0.380 0.000 vt 0.462 0.372 0.000 vt 0.463 0.366 0.000 vt 0.463 0.363 0.000 vt 0.402 0.945 0.000 vt 0.476 0.902 0.000 vt 0.401 0.489 0.000 vt 0.391 0.563 0.000 vt 0.388 0.559 0.000 vt 0.404 0.563 0.000 vt 0.443 0.569 0.000 vt 0.380 0.571 0.000 vt 0.382 0.569 0.000 vt 0.384 0.569 0.000 vt 0.439 0.568 0.000 vt 0.431 0.568 0.000 vt 0.421 0.567 0.000 vt 0.393 0.567 0.000 vt 0.387 0.567 0.000 vt 0.384 0.564 0.000 vt 0.394 0.568 0.000 vt 0.413 0.568 0.000 vt 0.370 0.565 0.000 vt 0.452 0.389 0.000 vt 0.399 0.452 0.000 vt 0.471 0.566 0.000 vt 0.316 0.686 0.000 vt 0.128 0.222 0.000 vt 0.179 0.214 0.000 vt 0.175 0.258 0.000 vt 0.124 0.265 0.000 vt 0.439 0.119 0.000 vt 0.229 0.304 0.000 vt 0.203 0.363 0.000 vt 0.274 0.227 0.000 vt 0.223 0.371 0.000 vt 0.053 0.571 0.000 vt 0.001 0.388 0.000 vt 0.001 0.456 0.000 vt 0.001 0.524 0.000 vt 0.064 0.877 0.000 vt 0.144 0.945 0.000 vt 0.001 0.323 0.000 vt 0.065 0.689 0.000 vt 0.224 0.240 0.000 vt 0.072 0.265 0.000 vt 0.001 0.267 0.000 vt 0.031 0.264 0.000 vt 0.057 0.628 0.000 vt 0.194 0.622 0.000 vt 0.149 0.611 0.000 vt 0.308 0.489 0.000 vt 0.369 0.558 0.000 vt 0.374 0.560 0.000 vt 0.378 0.562 0.000 vt 0.445 0.413 0.000 vt 0.430 0.429 0.000 vt 0.461 0.440 0.000 vt 0.476 0.607 0.000 vt 0.469 0.591 0.000 vt 0.378 0.549 0.000 vt 0.384 0.554 0.000 vt 0.393 0.509 0.000 vt 0.299 0.520 0.000 vt 0.436 0.403 0.000 vt 0.489 0.615 0.000 vt 0.383 0.568 0.000 vt 0.364 0.139 0.000 vt 0.236 0.192 0.000 vt 0.033 0.219 0.000 vt 0.079 0.220 0.000 vt 0.292 0.168 0.000 vt 0.001 0.218 0.000 vt 0.197 0.523 0.000 vt 0.209 0.508 0.000 vt 0.217 0.527 0.000 vt 0.206 0.535 0.000 vt 0.211 0.571 0.000 vt 0.203 0.562 0.000 vt 0.187 0.591 0.000 vt 0.185 0.578 0.000 vt 0.161 0.583 0.000 vt 0.165 0.574 0.000 vt 0.150 0.569 0.000 vt 0.155 0.560 0.000 vt 0.145 0.539 0.000 vt 0.153 0.535 0.000 vt 0.150 0.501 0.000 vt 0.159 0.502 0.000 vt 0.186 0.438 0.000 vt 0.191 0.452 0.000 vt 0.172 0.472 0.000 vt 0.164 0.464 0.000 vt 0.208 0.427 0.000 vt 0.210 0.441 0.000 vt 0.182 0.567 0.000 vt 0.193 0.550 0.000 vt 0.169 0.561 0.000 vt 0.161 0.553 0.000 vt 0.163 0.534 0.000 vt 0.169 0.505 0.000 vt 0.196 0.465 0.000 vt 0.180 0.479 0.000 vt 0.214 0.460 0.000 vt 0.227 0.456 0.000 vt 0.221 0.433 0.000 vt 0.203 0.489 0.000 vt 0.211 0.486 0.000 vt 0.215 0.495 0.000 vt 0.228 0.537 0.000 vt 0.219 0.583 0.000 vt 0.188 0.602 0.000 vt 0.152 0.587 0.000 vt 0.138 0.546 0.000 vt 0.141 0.500 0.000 vt 0.157 0.450 0.000 vt 0.180 0.412 0.000 vt 0.209 0.404 0.000 vt 0.227 0.417 0.000 vt 0.236 0.447 0.000 vt 0.194 0.496 0.000 vt 0.187 0.487 0.000 vt 0.199 0.477 0.000 vt 0.213 0.478 0.000 vt 0.222 0.489 0.000 vt 0.178 0.538 0.000 vt 0.178 0.510 0.000 vt 0.233 0.492 0.000 vt 0.130 0.496 0.000 vt 0.149 0.425 0.000 vt 0.128 0.552 0.000 vt 0.484 0.930 0.000 vt 0.472 0.934 0.000 vt 0.463 0.938 0.000 vt 0.470 0.952 0.000 vt 0.480 0.955 0.000 vt 0.484 0.970 0.000 vt 0.488 0.942 0.000 vt 0.478 0.944 0.000 vt 0.388 0.569 0.000 vt 0.385 0.572 0.000 vt 0.424 0.968 0.000 vt 0.437 0.961 0.000 vt 0.438 0.969 0.000 vt 0.427 0.973 0.000 vt 0.418 0.961 0.000 vt 0.429 0.956 0.000 vt 0.389 0.961 0.000 vt 0.399 0.955 0.000 vt 0.405 0.960 0.000 vt 0.394 0.967 0.000 vt 0.429 0.569 0.000 vt 0.405 0.566 0.000 vt 0.393 0.978 0.000 vt 0.383 0.975 0.000 vt 0.384 0.967 0.000 vt 0.401 0.986 0.000 vt 0.395 0.991 0.000 vt 0.386 0.982 0.000 vt 0.411 0.989 0.000 vt 0.407 0.996 0.000 vt 0.438 0.570 0.000 vt 0.427 0.994 0.000 vt 0.416 0.996 0.000 vt 0.421 0.987 0.000 vt 0.419 0.953 0.000 vt 0.408 0.953 0.000 vt 0.439 0.988 0.000 vt 0.428 0.981 0.000 vt 0.437 0.978 0.000 vt 0.489 0.956 0.000 vt 0.132 0.132 0.000 vt 0.082 0.133 0.000 vt 0.084 0.092 0.000 vt 0.133 0.090 0.000 vt 0.446 0.066 0.000 vt 0.442 0.095 0.000 vt 0.381 0.103 0.000 vt 0.388 0.070 0.000 vt 0.185 0.169 0.000 vt 0.186 0.126 0.000 vt 0.253 0.102 0.000 vt 0.242 0.148 0.000 vt 0.230 0.072 0.000 vt 0.183 0.087 0.000 vt 0.448 0.038 0.000 vt 0.395 0.039 0.000 vt 0.398 0.021 0.000 vt 0.449 0.020 0.000 vt 0.133 0.055 0.000 vt 0.179 0.050 0.000 vt 0.288 0.053 0.000 vt 0.260 0.052 0.000 vt 0.261 0.023 0.000 vt 0.300 0.022 0.000 vt 0.341 0.043 0.000 vt 0.348 0.022 0.000 vt 0.087 0.055 0.000 vt 0.040 0.091 0.000 vt 0.041 0.055 0.000 vt 0.038 0.133 0.000 vt 0.001 0.131 0.000 vt 0.001 0.089 0.000 vt 0.001 0.053 0.000 vt 0.222 0.038 0.000 vt 0.083 0.177 0.000 vt 0.035 0.178 0.000 vt 0.326 0.083 0.000 vt 0.315 0.124 0.000 vt 0.001 0.175 0.000 vt 0.129 0.175 0.000 vt 0.001 0.002 0.000 vt 0.042 0.002 0.000 vt 0.133 0.002 0.000 vt 0.177 0.002 0.000 vt 0.092 0.002 0.000 vt 0.399 0.002 0.000 vt 0.450 0.002 0.000 vt 0.303 0.002 0.000 vt 0.350 0.002 0.000 vt 0.218 0.002 0.000 vt 0.260 0.002 0.000 vt 0.558 0.967 0.000 vt 0.557 0.976 0.000 vt 0.500 0.997 0.000 vt 0.588 0.975 0.000 vt 0.442 0.967 0.000 vt 0.443 0.976 0.000 vt 0.412 0.975 0.000 # 1339 texture vertices vn 0.001 0.482 -0.876 vn -0.001 0.661 0.751 vn 0.136 0.595 0.792 vn -0.203 0.679 0.706 vn -0.092 0.474 0.876 vn -0.184 0.792 0.581 vn -0.098 0.863 0.495 vn -0.449 0.820 0.356 vn -0.220 0.748 0.626 vn -0.560 0.798 -0.222 vn -0.233 0.531 -0.815 vn 0.001 0.534 -0.845 vn -0.135 0.596 0.791 vn 0.203 0.676 0.708 vn 0.091 0.476 0.875 vn 0.189 0.792 0.581 vn 0.099 0.862 0.496 vn 0.444 0.821 0.360 vn 0.221 0.747 0.627 vn 0.556 0.801 -0.221 vn 0.228 0.532 -0.815 vn -0.002 0.536 -0.844 vn -0.574 0.744 -0.343 vn -0.485 0.523 -0.701 vn -0.121 0.869 -0.480 vn -0.215 0.930 -0.298 vn -0.000 -0.806 -0.591 vn -0.277 -0.779 -0.562 vn -0.258 -0.731 -0.632 vn -0.046 -0.809 -0.586 vn -0.210 0.565 -0.798 vn -0.094 0.624 -0.775 vn 0.015 0.952 -0.307 vn 0.045 0.919 -0.392 vn -0.099 0.857 -0.505 vn -0.379 0.493 -0.783 vn -0.947 0.285 -0.149 vn -0.809 -0.421 -0.411 vn -0.895 -0.443 -0.043 vn -0.999 -0.020 0.035 vn -0.359 0.933 -0.019 vn -0.809 0.586 0.047 vn -0.667 -0.516 -0.538 vn -0.726 -0.626 -0.285 vn -0.001 0.671 -0.741 vn -0.001 0.945 -0.327 vn -0.531 -0.632 -0.565 vn -0.618 -0.566 -0.546 vn 0.800 -0.473 0.369 vn 0.618 -0.771 0.151 vn 0.693 -0.711 0.116 vn 0.818 -0.467 0.335 vn 0.849 -0.259 0.460 vn 0.775 -0.130 0.619 vn 0.667 -0.132 0.733 vn 0.775 -0.270 0.571 vn 0.958 -0.057 -0.280 vn 0.763 0.033 -0.646 vn 0.763 -0.153 -0.628 vn 0.911 -0.129 -0.391 vn 0.990 0.067 0.126 vn 0.979 0.090 0.185 vn 0.981 0.057 0.184 vn 0.996 0.020 0.090 vn 0.770 -0.392 0.504 vn 0.657 -0.721 0.219 vn 0.478 -0.656 0.584 vn 0.599 -0.389 0.700 vn 0.498 -0.846 0.192 vn 0.537 -0.840 0.082 vn 0.740 -0.557 0.378 vn 0.668 -0.570 0.479 vn 0.280 -0.914 0.294 vn 0.421 -0.898 0.126 vn 0.991 0.084 0.103 vn 0.964 0.223 0.143 vn 0.960 0.189 0.207 vn 0.979 0.103 0.175 vn 0.868 0.172 0.465 vn 0.907 0.085 0.413 vn 0.938 0.144 0.316 vn 0.897 0.178 0.405 vn 0.662 -0.174 0.729 vn 0.583 -0.417 0.697 vn 0.627 -0.449 0.637 vn 0.685 -0.405 0.605 vn 0.827 0.091 0.555 vn 0.890 0.018 0.455 vn 0.663 -0.395 0.636 vn 0.606 -0.428 0.671 vn 0.313 -0.735 0.602 vn -0.136 -0.864 0.485 vn 0.951 0.158 0.267 vn 0.964 0.113 0.241 vn 0.731 -0.036 0.681 vn 0.819 -0.134 0.558 vn 0.546 0.270 0.793 vn 0.602 0.237 0.763 vn 0.444 0.233 0.865 vn 0.353 0.173 0.920 vn 0.240 -0.093 0.966 vn 0.498 0.051 0.866 vn 0.675 0.338 0.656 vn 0.480 0.400 0.780 vn 0.064 -0.572 0.818 vn 0.126 -0.313 0.941 vn 0.207 -0.613 0.763 vn 0.221 -0.810 0.544 vn 0.598 -0.694 -0.401 vn 0.124 -0.977 -0.175 vn 0.218 -0.333 0.917 vn 0.377 -0.161 0.912 vn 0.142 -0.210 0.967 vn 0.256 -0.155 0.954 vn 0.111 -0.351 0.930 vn 0.107 -0.480 0.871 vn 0.675 -0.732 -0.096 vn 0.496 -0.844 0.206 vn -0.016 -0.986 0.167 vn 0.304 -0.948 0.097 vn 0.982 -0.082 0.171 vn 0.963 -0.002 0.269 vn 0.967 -0.134 0.216 vn 0.969 -0.177 0.175 vn 0.916 -0.244 0.319 vn 0.853 -0.341 0.394 vn 0.837 -0.365 0.407 vn 0.886 -0.281 0.368 vn 0.422 -0.292 0.858 vn 0.039 -0.571 0.820 vn -0.011 -0.399 0.917 vn 0.333 -0.349 0.876 vn 0.935 -0.237 0.263 vn 0.949 -0.159 0.273 vn 0.697 -0.213 0.685 vn 0.568 -0.123 0.814 vn -0.938 0.322 0.130 vn -0.609 -0.738 -0.291 vn -0.447 -0.857 -0.258 vn 0.259 -0.528 0.809 vn 0.137 -0.704 0.697 vn -0.107 -0.741 0.663 vn 0.647 -0.296 0.703 vn 0.603 -0.168 0.780 vn 0.836 0.072 0.545 vn 0.744 0.114 0.659 vn 0.701 0.149 0.698 vn 0.802 0.157 0.577 vn 0.823 -0.080 0.562 vn 0.690 0.142 0.710 vn 0.628 0.036 0.778 vn 0.894 -0.247 0.373 vn 0.624 -0.153 0.766 vn 0.661 0.110 0.742 vn 0.712 0.424 0.559 vn 0.701 0.284 0.654 vn 0.504 -0.050 0.862 vn 0.413 0.027 0.910 vn 0.569 0.046 0.821 vn 0.488 -0.134 0.862 vn 0.411 -0.180 0.894 vn 0.610 -0.024 0.792 vn 0.747 -0.250 0.616 vn 0.672 -0.313 0.671 vn 0.536 0.762 0.363 vn 0.559 0.768 0.312 vn 0.802 0.272 0.531 vn 0.618 0.206 0.759 vn 0.717 0.383 0.583 vn 0.780 0.464 0.420 vn 0.617 0.401 0.678 vn 0.658 0.397 0.640 vn 0.672 0.440 0.596 vn 0.501 0.314 0.807 vn 0.612 0.527 0.589 vn 0.679 0.320 0.661 vn 0.732 -0.406 -0.547 vn 0.885 -0.261 -0.386 vn 0.842 -0.347 0.414 vn 0.782 -0.349 0.517 vn 0.784 -0.368 0.500 vn 0.858 -0.453 0.244 vn 0.953 -0.279 0.118 vn 0.977 -0.189 0.104 vn 0.989 -0.110 0.102 vn 0.142 0.669 0.730 vn 0.300 0.652 0.696 vn 0.291 0.792 0.536 vn 0.143 0.821 0.553 vn 0.737 0.561 0.378 vn 0.716 0.470 0.515 vn 0.884 0.306 0.353 vn 0.898 0.354 0.263 vn 0.890 0.423 0.171 vn 0.174 0.078 0.982 vn 0.219 0.254 0.942 vn 0.665 -0.104 0.739 vn 0.671 0.390 0.631 vn 0.596 0.435 0.675 vn 0.636 0.467 0.614 vn 0.076 0.244 0.967 vn 0.261 0.437 0.861 vn 0.107 0.440 0.892 vn 0.011 0.082 0.997 vn 0.005 0.082 0.997 vn 0.028 -0.027 0.999 vn 0.073 -0.057 0.996 vn 0.006 0.228 0.974 vn 0.683 0.140 0.717 vn 0.724 0.233 0.650 vn 0.400 0.338 0.852 vn 0.270 0.126 0.955 vn 0.357 0.433 0.828 vn 0.503 0.485 0.716 vn 0.536 0.133 0.834 vn 0.416 -0.306 0.856 vn 0.337 0.097 0.937 vn 0.262 0.372 0.891 vn 0.425 0.075 0.902 vn 0.701 -0.147 0.698 vn -0.056 0.558 0.828 vn 0.005 0.605 0.796 vn 0.483 0.327 0.812 vn 0.497 0.276 0.823 vn 0.505 0.283 0.815 vn 0.340 -0.030 0.940 vn 0.332 0.066 0.941 vn 0.026 0.644 0.765 vn 0.021 0.538 0.843 vn 0.170 -0.012 0.985 vn 0.365 -0.067 0.929 vn 0.826 -0.173 0.537 vn 0.320 0.415 0.852 vn 0.384 0.739 0.554 vn 0.987 -0.013 0.160 vn 0.495 0.720 0.487 vn 0.490 0.830 0.268 vn 0.279 0.906 0.317 vn 0.431 0.899 -0.074 vn 0.267 0.957 -0.112 vn 0.283 0.953 0.107 vn 0.471 0.877 0.092 vn 0.132 0.985 0.113 vn 0.135 0.931 0.339 vn 0.190 -0.184 0.964 vn 0.292 -0.372 0.881 vn 0.307 -0.447 0.840 vn 0.393 -0.580 0.713 vn 0.524 -0.286 0.802 vn 0.380 -0.582 0.719 vn 0.697 0.212 0.685 vn 0.603 0.070 0.795 vn 0.558 -0.571 0.602 vn -0.089 -0.701 0.707 vn 0.794 -0.345 0.500 vn 0.345 -0.517 0.783 vn 0.481 0.101 0.871 vn 0.134 0.283 0.950 vn 0.113 -0.558 0.822 vn -0.073 -0.993 0.089 vn -0.041 -0.994 0.103 vn 0.084 -0.038 0.996 vn -0.012 -0.622 0.783 vn -0.002 0.254 0.967 vn 0.004 -0.997 0.079 vn 0.001 -0.832 -0.555 vn 0.477 -0.363 0.801 vn 0.414 0.160 0.896 vn 0.395 0.485 0.780 vn 0.611 0.484 0.627 vn 0.406 0.510 0.758 vn 0.375 0.498 0.782 vn 0.555 0.314 0.770 vn 0.349 0.411 0.842 vn 0.012 0.247 0.969 vn 0.002 -0.369 0.930 vn -0.003 0.509 0.861 vn 0.876 -0.041 0.481 vn 0.757 -0.214 0.618 vn 0.737 -0.048 0.674 vn 0.840 -0.012 0.542 vn 0.960 0.137 0.243 vn 0.969 0.103 0.226 vn 0.909 0.015 0.417 vn 0.906 0.015 0.423 vn 0.676 -0.276 0.683 vn 0.688 -0.223 0.691 vn 0.691 0.035 0.722 vn 0.719 -0.082 0.691 vn 0.964 0.062 0.260 vn 0.956 0.070 0.286 vn 0.953 0.037 0.300 vn -0.003 -0.415 0.910 vn -0.001 -0.380 0.925 vn 0.658 -0.419 0.625 vn 0.735 -0.421 0.532 vn 0.663 -0.303 0.685 vn 0.550 -0.321 0.771 vn 0.423 -0.236 0.875 vn 0.326 -0.294 0.899 vn 0.124 -0.396 0.910 vn 0.218 -0.177 0.960 vn 0.530 0.781 0.331 vn 0.167 0.827 0.537 vn 0.094 0.948 0.303 vn 0.313 0.934 0.171 vn -0.406 -0.892 0.201 vn -0.743 0.107 0.661 vn 0.455 0.704 0.546 vn 0.288 0.957 0.025 vn 0.245 0.958 0.150 vn 0.532 -0.027 0.846 vn 0.566 0.213 0.796 vn 0.508 0.208 0.836 vn 0.173 0.028 0.984 vn 0.371 0.122 0.921 vn 0.429 -0.045 0.902 vn 0.614 0.165 0.772 vn 0.737 0.157 0.657 vn 0.726 0.057 0.685 vn 0.662 0.061 0.747 vn 0.845 -0.523 -0.112 vn 0.845 -0.501 -0.185 vn 0.744 -0.668 0.009 vn 0.773 -0.630 0.079 vn 0.889 0.108 0.445 vn 0.899 0.077 0.430 vn 0.184 0.204 -0.961 vn 0.005 0.202 -0.979 vn -0.000 0.485 -0.875 vn 0.159 0.484 -0.861 vn 0.499 0.592 0.633 vn 0.305 0.950 0.065 vn -0.274 -0.953 -0.127 vn 0.245 -0.456 0.856 vn 0.083 -0.881 0.465 vn 0.435 -0.739 0.515 vn 0.504 -0.429 0.750 vn 0.818 -0.367 0.443 vn 0.933 -0.162 0.322 vn 0.872 0.029 0.489 vn 0.002 0.994 0.113 vn 0.133 0.983 -0.126 vn -0.001 0.992 -0.127 vn 0.280 0.892 -0.356 vn 0.126 0.916 -0.381 vn 0.210 0.974 -0.083 vn -0.082 0.663 0.745 vn -0.059 0.391 0.919 vn 0.111 0.992 -0.055 vn 0.081 -0.190 0.978 vn 0.035 0.076 0.996 vn 0.852 0.236 0.467 vn 0.775 0.219 0.593 vn 0.505 -0.109 0.856 vn 0.446 -0.314 0.838 vn 0.511 0.200 0.836 vn 0.623 -0.242 0.744 vn 0.436 -0.554 0.709 vn 0.599 -0.742 0.300 vn -0.036 0.177 0.984 vn -0.039 -0.159 0.987 vn 0.308 0.942 -0.135 vn 0.989 0.093 -0.111 vn 0.477 -0.259 0.840 vn 0.473 -0.423 0.773 vn 0.774 -0.329 0.541 vn 0.285 0.019 0.958 vn 0.350 0.101 0.931 vn 0.579 0.261 0.773 vn 0.298 0.015 0.954 vn 0.165 0.336 0.927 vn 0.577 0.511 0.636 vn 0.254 -0.834 0.490 vn -0.114 -0.925 0.363 vn 0.941 -0.280 -0.188 vn 0.460 -0.738 0.493 vn 0.740 -0.635 0.221 vn 0.003 0.529 0.849 vn 0.206 -0.427 -0.881 vn 0.497 -0.316 -0.808 vn 0.457 -0.144 -0.878 vn 0.179 -0.244 -0.953 vn -0.182 -0.980 -0.078 vn 0.342 -0.427 0.837 vn 0.424 -0.296 0.856 vn 0.896 -0.357 -0.264 vn 0.594 -0.104 0.798 vn 0.012 0.528 0.849 vn 0.042 0.469 0.882 vn 0.624 0.102 0.775 vn 0.324 -0.123 0.938 vn 0.202 -0.638 0.743 vn 0.714 0.512 0.477 vn 0.433 -0.511 0.742 vn -0.350 -0.708 0.613 vn 0.095 -0.410 0.907 vn 0.622 -0.593 0.512 vn 0.846 0.304 0.437 vn 0.582 -0.043 0.812 vn -0.226 -0.380 0.897 vn 0.215 0.644 0.734 vn 0.123 0.952 0.280 vn -0.004 0.956 0.293 vn -0.005 0.635 0.772 vn 0.325 -0.730 0.601 vn -0.017 -0.840 0.543 vn 0.017 -0.788 0.616 vn 0.294 -0.138 0.946 vn 0.214 0.401 0.891 vn -0.150 0.490 0.859 vn 0.573 -0.125 0.810 vn -0.134 0.957 0.258 vn 0.252 0.828 0.501 vn -0.673 0.643 0.364 vn 0.004 -0.960 0.279 vn 0.032 -0.991 0.133 vn 0.006 -0.908 0.419 vn 0.180 -0.980 0.086 vn 0.740 0.403 -0.538 vn 0.627 0.652 -0.426 vn 0.814 0.561 -0.149 vn 0.925 0.321 -0.206 vn 0.492 0.825 -0.280 vn 0.649 0.757 -0.076 vn 0.966 0.258 0.022 vn 0.864 0.501 0.053 vn 0.680 0.729 0.077 vn 0.272 -0.962 -0.032 vn 0.225 -0.968 0.111 vn 0.288 -0.510 0.810 vn 0.126 0.748 -0.651 vn 0.340 0.725 -0.598 vn 0.421 0.466 -0.778 vn 0.205 -0.458 -0.865 vn 0.489 -0.479 -0.729 vn 0.500 -0.523 -0.690 vn 0.210 -0.566 -0.798 vn 0.895 -0.322 -0.309 vn 0.759 -0.434 -0.485 vn 0.797 -0.287 -0.532 vn 0.937 -0.248 -0.245 vn -0.001 -0.238 -0.971 vn -0.000 -0.025 -1.000 vn 0.194 -0.025 -0.981 vn 0.201 -0.248 -0.948 vn 0.969 0.094 -0.229 vn 0.968 -0.101 -0.228 vn 0.814 -0.088 -0.575 vn 0.800 0.142 -0.583 vn 0.998 0.061 -0.010 vn 0.726 0.657 0.205 vn 0.000 -0.985 0.174 vn 0.985 -0.166 0.038 vn 0.955 -0.220 -0.200 vn 0.472 0.076 0.879 vn 0.343 -0.235 0.909 vn 0.464 -0.641 0.612 vn 0.578 -0.186 0.795 vn -0.189 -0.982 0.010 vn 0.004 0.938 0.345 vn 0.002 0.829 0.559 vn 0.445 0.232 0.865 vn 0.463 0.340 0.818 vn -0.116 0.983 0.143 vn 0.004 0.995 0.102 vn 0.978 0.204 0.044 vn -0.967 -0.216 -0.137 vn -0.911 -0.347 0.224 vn -0.728 0.350 0.590 vn 0.426 0.738 -0.523 vn 0.618 0.786 0.011 vn 0.151 0.857 -0.493 vn -0.333 0.912 -0.241 vn -0.277 0.956 0.095 vn -0.569 0.822 -0.032 vn -0.341 -0.671 -0.658 vn 0.161 -0.736 -0.657 vn 0.528 0.432 0.731 vn 0.586 0.105 0.803 vn 0.436 0.074 0.897 vn 0.621 0.267 0.737 vn 0.936 0.153 0.316 vn 0.999 -0.010 0.042 vn 0.826 0.281 -0.489 vn 0.775 0.178 -0.606 vn 0.995 -0.039 -0.095 vn 0.005 -0.414 0.910 vn 0.580 -0.243 0.778 vn 0.938 -0.339 -0.068 vn 0.925 -0.371 0.080 vn 0.888 -0.269 0.373 vn 0.923 -0.371 -0.106 vn 0.494 -0.274 -0.825 vn -0.001 -0.456 -0.890 vn -0.002 -0.569 -0.822 vn -0.001 -0.452 -0.892 vn -0.003 0.749 -0.663 vn -0.000 0.920 -0.391 vn -0.001 -0.280 -0.960 vn 0.470 0.194 -0.861 vn 0.965 -0.123 0.234 vn 0.400 -0.039 -0.916 vn 0.142 -0.166 -0.976 vn -0.000 -0.194 -0.981 vn 0.497 -0.049 -0.867 vn 0.998 0.042 0.045 vn 0.996 -0.037 -0.082 vn 0.009 0.433 0.901 vn 0.004 0.669 0.743 vn 0.955 0.004 0.296 vn 0.737 -0.001 0.675 vn 0.707 0.177 0.684 vn 0.484 0.627 0.610 vn 0.515 0.250 0.820 vn 0.360 0.121 0.925 vn -0.544 -0.573 0.613 vn 0.382 -0.114 0.917 vn 0.489 -0.108 0.866 vn -0.002 -0.670 0.742 vn 0.002 -0.394 0.919 vn -0.004 -0.168 0.986 vn 0.007 -0.109 0.994 vn 0.009 -0.519 0.855 vn 0.660 -0.118 0.742 vn 0.621 -0.127 0.774 vn 0.416 0.220 0.882 vn 0.946 0.046 0.322 vn 0.014 0.006 1.000 vn 0.569 0.184 0.802 vn 0.218 0.013 0.976 vn 0.044 0.087 0.995 vn -0.419 0.862 0.284 vn 0.647 -0.120 0.753 vn 0.954 -0.017 0.301 vn 0.352 0.140 -0.926 vn 0.095 -0.050 -0.994 vn 0.770 0.025 0.638 vn 0.000 -0.078 -0.997 vn 0.985 -0.172 0.009 vn 0.920 -0.340 0.195 vn 0.929 -0.331 -0.163 vn 0.969 -0.237 0.074 vn 0.969 -0.183 0.165 vn 0.801 0.160 0.577 vn 0.954 -0.021 0.301 vn 0.293 0.803 0.520 vn 0.977 0.170 0.129 vn 0.134 0.985 -0.104 vn 0.994 0.106 -0.036 vn 0.099 0.675 -0.731 vn 0.997 -0.079 -0.000 vn 0.197 0.126 -0.972 vn 0.978 -0.175 -0.110 vn 0.110 -0.321 -0.941 vn 0.939 -0.332 -0.089 vn 0.400 -0.789 -0.467 vn 0.171 -0.673 -0.720 vn 0.931 -0.336 -0.144 vn 0.854 -0.500 0.146 vn 0.161 -0.985 -0.069 vn 0.931 -0.304 -0.200 vn 0.813 -0.565 -0.143 vn 0.823 -0.546 0.154 vn 0.795 -0.387 0.467 vn 0.809 -0.168 0.563 vn 0.826 0.053 0.562 vn 0.925 0.261 0.275 vn 0.990 0.071 0.119 vn 0.951 0.129 0.281 vn 0.810 -0.147 0.568 vn 0.383 -0.603 0.699 vn 0.769 0.635 0.079 vn 0.786 0.352 0.508 vn 0.919 0.082 -0.386 vn 0.937 0.163 0.310 vn 0.974 -0.026 0.224 vn 0.787 0.550 0.279 vn 0.517 0.758 -0.397 vn 0.337 0.112 -0.935 vn 0.221 -0.300 -0.928 vn 0.395 -0.578 -0.714 vn 0.521 -0.711 -0.472 vn 0.432 -0.901 -0.043 vn 0.826 -0.520 0.218 vn 0.885 -0.217 0.412 vn 0.786 -0.107 0.609 vn 0.864 0.400 0.304 vn 0.954 0.061 0.293 vn 0.949 0.313 0.046 vn 0.991 0.028 -0.131 vn 0.945 -0.116 0.305 vn 0.970 -0.241 0.032 vn 0.946 -0.038 0.322 vn 0.886 -0.270 -0.376 vn 0.855 -0.272 -0.441 vn 0.952 -0.122 -0.281 vn 0.002 -0.883 0.469 vn -0.001 0.792 -0.611 vn -0.180 0.823 -0.539 vn -0.642 0.677 -0.360 vn -0.957 0.288 -0.031 vn -0.912 -0.300 0.281 vn -0.454 -0.866 0.207 vn -0.855 -0.043 0.517 vn -0.834 0.460 0.305 vn -0.242 0.911 0.334 vn -0.720 -0.667 -0.192 vn -0.762 -0.580 -0.288 vn 0.452 0.774 0.444 vn 0.857 0.048 0.513 vn 0.966 0.131 0.225 vn 0.211 0.953 0.219 vn -0.108 0.726 0.679 vn 0.021 0.946 0.324 vn 0.566 -0.691 -0.450 vn -0.068 0.939 -0.338 vn -0.261 -0.298 0.918 vn -0.200 -0.891 0.407 vn 0.124 -0.991 0.059 vn 0.913 -0.350 -0.211 vn 0.488 -0.838 0.244 vn 0.738 -0.593 0.322 vn 0.994 -0.060 -0.087 vn -0.000 -0.981 0.193 vn 0.000 0.974 0.227 vn -0.350 -0.016 0.936 vn 0.000 -0.017 1.000 vn 0.252 0.455 -0.854 vn 0.774 0.620 -0.127 vn 0.634 0.759 -0.148 vn 0.192 0.569 -0.800 vn 0.405 -0.094 0.909 vn 0.031 0.149 0.988 vn 0.360 0.283 0.889 vn 0.469 0.080 0.880 vn 0.769 0.452 0.452 vn 0.946 0.185 0.266 vn 0.893 0.181 0.413 vn 0.654 0.429 0.623 vn 0.506 0.610 0.610 vn 0.436 0.659 0.613 vn 0.160 0.558 0.814 vn -0.285 0.396 0.873 vn -0.223 0.539 0.812 vn 0.037 0.570 0.821 vn 0.623 0.727 -0.289 vn 0.456 0.738 0.497 vn 0.382 0.656 0.651 vn 0.278 0.687 0.671 vn 0.213 0.798 0.563 vn 0.171 0.844 0.508 vn 0.300 0.690 0.659 vn 0.144 0.793 0.591 vn 0.204 0.541 -0.816 vn -0.001 0.494 -0.870 vn 0.029 0.458 -0.888 vn 0.060 0.366 -0.929 vn 0.000 0.421 -0.907 vn 0.000 0.386 -0.922 vn 0.001 0.455 -0.891 vn 0.264 0.718 0.644 vn 0.307 0.317 -0.897 vn 0.056 0.164 -0.985 vn 0.717 0.079 0.693 vn 0.638 0.188 0.746 vn 0.000 0.202 -0.979 vn 0.006 -0.044 0.999 vn 0.001 0.405 0.914 vn 0.805 0.560 -0.194 vn 0.002 0.627 0.779 vn 0.010 -0.298 0.954 vn 0.124 0.870 -0.477 vn 0.488 0.530 -0.693 vn 0.566 0.756 -0.329 vn 0.213 0.932 -0.294 vn 0.245 -0.741 -0.626 vn 0.275 -0.782 -0.559 vn 0.044 -0.811 -0.584 vn -0.012 0.949 -0.315 vn 0.097 0.621 -0.778 vn 0.215 0.561 -0.799 vn -0.030 0.913 -0.407 vn 0.378 0.505 -0.776 vn 0.084 0.865 -0.495 vn 0.892 -0.451 -0.026 vn 0.803 -0.447 -0.394 vn 0.954 0.274 -0.123 vn 0.998 -0.024 0.066 vn 0.806 0.588 0.057 vn 0.351 0.936 -0.012 vn 0.662 -0.536 -0.524 vn 0.725 -0.630 -0.278 vn 0.524 -0.662 -0.536 vn 0.620 -0.585 -0.522 vn -0.694 -0.711 0.115 vn -0.621 -0.770 0.148 vn -0.805 -0.470 0.362 vn -0.819 -0.465 0.335 vn -0.680 -0.145 0.719 vn -0.763 -0.140 0.631 vn -0.840 -0.272 0.470 vn -0.773 -0.256 0.580 vn -0.763 -0.155 -0.627 vn -0.763 0.034 -0.645 vn -0.958 -0.057 -0.281 vn -0.910 -0.129 -0.393 vn -0.983 0.060 0.175 vn -0.980 0.096 0.177 vn -0.990 0.069 0.123 vn -0.996 0.023 0.083 vn -0.484 -0.649 0.587 vn -0.662 -0.717 0.220 vn -0.775 -0.388 0.499 vn -0.606 -0.384 0.697 vn -0.748 -0.556 0.363 vn -0.539 -0.840 0.071 vn -0.496 -0.849 0.183 vn -0.668 -0.580 0.467 vn -0.280 -0.913 0.296 vn -0.424 -0.897 0.125 vn -0.960 0.187 0.209 vn -0.965 0.222 0.143 vn -0.991 0.084 0.104 vn -0.979 0.104 0.175 vn -0.940 0.170 0.295 vn -0.909 0.107 0.404 vn -0.862 0.204 0.464 vn -0.896 0.204 0.395 vn -0.570 -0.493 0.658 vn -0.531 -0.465 0.709 vn -0.651 -0.181 0.737 vn -0.688 -0.376 0.620 vn -0.892 0.030 0.452 vn -0.827 0.122 0.549 vn -0.345 -0.706 0.619 vn -0.566 -0.461 0.684 vn -0.543 -0.393 0.742 vn -0.097 -0.841 0.533 vn -0.964 0.119 0.237 vn -0.950 0.158 0.268 vn -0.733 -0.024 0.679 vn -0.825 -0.117 0.552 vn -0.442 0.232 0.866 vn -0.605 0.237 0.760 vn -0.556 0.267 0.787 vn -0.350 0.172 0.921 vn -0.239 -0.096 0.966 vn -0.501 0.068 0.863 vn -0.679 0.342 0.650 vn -0.486 0.403 0.776 vn -0.211 -0.600 0.772 vn -0.123 -0.334 0.934 vn -0.052 -0.530 0.847 vn -0.176 -0.798 0.577 vn -0.131 -0.968 -0.212 vn -0.598 -0.684 -0.418 vn -0.205 -0.329 0.922 vn -0.374 -0.151 0.915 vn -0.117 -0.376 0.919 vn -0.246 -0.160 0.956 vn -0.126 -0.268 0.955 vn -0.137 -0.531 0.837 vn 0.062 -0.980 0.190 vn -0.478 -0.855 0.203 vn -0.669 -0.734 -0.114 vn -0.286 -0.955 0.083 vn -0.967 -0.136 0.215 vn -0.965 -0.005 0.263 vn -0.983 -0.085 0.164 vn -0.969 -0.182 0.170 vn -0.840 -0.358 0.408 vn -0.857 -0.341 0.386 vn -0.910 -0.256 0.326 vn -0.884 -0.284 0.371 vn 0.022 -0.449 0.893 vn -0.046 -0.611 0.791 vn -0.478 -0.294 0.827 vn -0.375 -0.338 0.863 vn -0.935 -0.243 0.259 vn -0.949 -0.164 0.269 vn -0.736 -0.207 0.645 vn -0.587 -0.108 0.802 vn 0.945 0.284 0.163 vn 0.592 -0.756 -0.279 vn 0.442 -0.866 -0.236 vn -0.053 -0.740 0.670 vn -0.228 -0.529 0.817 vn 0.170 -0.772 0.613 vn -0.609 -0.162 0.777 vn -0.663 -0.292 0.690 vn -0.713 0.145 0.686 vn -0.759 0.059 0.648 vn -0.825 0.047 0.564 vn -0.809 0.158 0.566 vn -0.637 0.025 0.770 vn -0.687 0.129 0.715 vn -0.821 -0.086 0.564 vn -0.891 -0.252 0.378 vn -0.721 0.489 0.490 vn -0.698 0.164 0.697 vn -0.646 -0.143 0.750 vn -0.712 0.352 0.608 vn -0.567 0.074 0.821 vn -0.464 0.032 0.885 vn -0.518 -0.023 0.855 vn -0.550 -0.128 0.825 vn -0.756 -0.260 0.601 vn -0.645 -0.025 0.764 vn -0.437 -0.158 0.885 vn -0.687 -0.310 0.657 vn -0.541 0.781 0.313 vn -0.565 0.780 0.270 vn -0.712 0.385 0.587 vn -0.611 0.201 0.765 vn -0.859 0.335 0.388 vn -0.775 0.474 0.417 vn -0.673 0.387 0.630 vn -0.628 0.400 0.668 vn -0.676 0.438 0.592 vn -0.698 0.309 0.646 vn -0.622 0.535 0.573 vn -0.511 0.327 0.795 vn -0.733 -0.405 -0.547 vn -0.884 -0.261 -0.388 vn -0.791 -0.366 0.490 vn -0.793 -0.344 0.502 vn -0.844 -0.347 0.408 vn -0.858 -0.453 0.243 vn -0.953 -0.280 0.116 vn -0.976 -0.193 0.100 vn -0.989 -0.113 0.096 vn -0.289 0.792 0.537 vn -0.301 0.654 0.693 vn -0.134 0.672 0.728 vn -0.137 0.821 0.554 vn -0.884 0.305 0.354 vn -0.716 0.471 0.515 vn -0.736 0.562 0.377 vn -0.897 0.355 0.265 vn -0.890 0.422 0.171 vn -0.179 0.082 0.981 vn -0.216 0.250 0.944 vn -0.661 -0.125 0.740 vn -0.679 0.371 0.633 vn -0.636 0.460 0.620 vn -0.594 0.426 0.682 vn -0.258 0.436 0.862 vn -0.070 0.240 0.968 vn -0.095 0.440 0.893 vn -0.011 0.089 0.996 vn -0.069 -0.049 0.996 vn -0.719 0.247 0.649 vn -0.673 0.172 0.719 vn -0.353 0.447 0.822 vn -0.270 0.134 0.954 vn -0.440 0.328 0.836 vn -0.511 0.490 0.706 vn -0.342 0.114 0.933 vn -0.435 -0.298 0.849 vn -0.552 0.158 0.818 vn -0.273 0.369 0.888 vn -0.705 -0.192 0.683 vn -0.357 0.088 0.930 vn -0.499 0.346 0.795 vn 0.009 0.585 0.811 vn 0.086 0.584 0.807 vn -0.348 -0.035 0.937 vn -0.516 0.299 0.803 vn -0.512 0.295 0.806 vn -0.339 0.070 0.938 vn -0.348 -0.070 0.935 vn -0.148 -0.003 0.989 vn -0.349 0.750 0.561 vn -0.322 0.418 0.849 vn -0.890 -0.163 0.425 vn -0.990 -0.001 0.144 vn -0.500 0.824 0.267 vn -0.501 0.717 0.484 vn -0.285 0.905 0.315 vn -0.282 0.954 0.103 vn -0.268 0.957 -0.114 vn -0.433 0.898 -0.078 vn -0.473 0.876 0.093 vn -0.131 0.985 0.111 vn -0.127 0.932 0.339 vn -0.211 -0.186 0.960 vn -0.293 -0.359 0.886 vn -0.344 -0.465 0.816 vn -0.382 -0.591 0.710 vn -0.525 -0.255 0.812 vn -0.598 0.089 0.796 vn -0.688 0.244 0.683 vn -0.344 -0.576 0.742 vn -0.544 -0.583 0.603 vn 0.098 -0.695 0.712 vn -0.805 -0.326 0.496 vn -0.132 0.306 0.943 vn -0.485 0.160 0.860 vn -0.351 -0.498 0.793 vn -0.141 -0.499 0.855 vn 0.065 -0.990 0.123 vn 0.037 -0.989 0.143 vn -0.065 -0.055 0.996 vn -0.473 -0.369 0.800 vn -0.396 0.179 0.900 vn -0.600 0.505 0.620 vn -0.387 0.499 0.776 vn -0.398 0.505 0.766 vn -0.358 0.488 0.796 vn -0.570 0.304 0.763 vn -0.317 0.412 0.854 vn -0.742 -0.129 0.658 vn -0.771 -0.207 0.602 vn -0.881 -0.036 0.472 vn -0.841 -0.052 0.538 vn -0.972 0.111 0.208 vn -0.961 0.151 0.230 vn -0.916 -0.004 0.402 vn -0.913 0.013 0.408 vn -0.689 0.026 0.724 vn -0.641 -0.316 0.699 vn -0.647 -0.304 0.699 vn -0.697 -0.094 0.711 vn -0.966 0.063 0.249 vn -0.963 0.075 0.259 vn -0.958 0.031 0.287 vn -0.681 -0.315 0.661 vn -0.745 -0.412 0.525 vn -0.666 -0.413 0.621 vn -0.548 -0.335 0.767 vn -0.107 -0.395 0.913 vn -0.299 -0.320 0.899 vn -0.418 -0.236 0.877 vn -0.210 -0.169 0.963 vn -0.090 0.952 0.291 vn -0.166 0.838 0.520 vn -0.523 0.797 0.302 vn -0.302 0.941 0.154 vn 0.408 -0.888 0.211 vn 0.735 0.117 0.668 vn -0.279 0.960 0.001 vn -0.468 0.706 0.531 vn -0.232 0.964 0.131 vn -0.555 -0.033 0.831 vn -0.517 0.199 0.833 vn -0.549 0.222 0.806 vn -0.376 0.125 0.918 vn -0.210 0.031 0.977 vn -0.435 -0.045 0.899 vn -0.739 0.154 0.656 vn -0.610 0.153 0.777 vn -0.663 0.041 0.748 vn -0.733 0.013 0.681 vn -0.744 -0.668 0.007 vn -0.845 -0.501 -0.187 vn -0.845 -0.522 -0.114 vn -0.774 -0.629 0.079 vn -0.897 0.040 0.440 vn -0.896 0.094 0.434 vn -0.179 0.204 -0.962 vn -0.157 0.488 -0.858 vn -0.506 0.590 0.630 vn -0.305 0.951 0.047 vn 0.267 -0.958 -0.102 vn -0.432 -0.745 0.509 vn -0.075 -0.883 0.463 vn -0.236 -0.454 0.859 vn -0.504 -0.423 0.753 vn -0.821 -0.351 0.449 vn -0.876 0.033 0.481 vn -0.934 -0.155 0.322 vn -0.134 0.983 -0.126 vn -0.128 0.916 -0.381 vn -0.284 0.891 -0.353 vn 0.055 0.396 0.917 vn 0.092 0.644 0.760 vn -0.199 0.976 -0.093 vn -0.109 0.991 -0.072 vn -0.039 0.079 0.996 vn -0.081 -0.191 0.978 vn -0.854 0.239 0.462 vn -0.774 0.223 0.593 vn -0.502 -0.119 0.856 vn -0.403 -0.420 0.813 vn -0.680 -0.255 0.687 vn -0.525 0.172 0.834 vn -0.376 -0.531 0.759 vn -0.576 -0.754 0.316 vn 0.040 0.159 0.986 vn 0.036 -0.180 0.983 vn -0.308 0.943 -0.129 vn -0.983 0.074 -0.170 vn -0.456 -0.445 0.771 vn -0.476 -0.297 0.828 vn -0.788 -0.316 0.528 vn -0.393 0.095 0.915 vn -0.308 0.018 0.951 vn -0.125 0.331 0.935 vn -0.283 0.033 0.959 vn -0.598 0.322 0.734 vn -0.575 0.559 0.598 vn -0.216 -0.852 0.476 vn 0.156 -0.927 0.342 vn -0.941 -0.282 -0.189 vn -0.739 -0.637 0.221 vn -0.469 -0.731 0.495 vn -0.458 -0.139 -0.878 vn -0.498 -0.315 -0.808 vn -0.210 -0.426 -0.880 vn -0.182 -0.243 -0.953 vn -0.334 -0.402 0.853 vn 0.221 -0.960 -0.173 vn -0.414 -0.366 0.834 vn -0.902 -0.373 -0.218 vn -0.632 -0.114 0.767 vn -0.642 0.122 0.757 vn -0.194 -0.651 0.734 vn -0.351 -0.095 0.931 vn -0.707 0.530 0.467 vn -0.087 -0.550 0.831 vn 0.352 -0.710 0.610 vn -0.500 -0.482 0.720 vn -0.653 -0.626 0.427 vn -0.856 0.328 0.399 vn -0.578 -0.029 0.816 vn 0.275 -0.432 0.859 vn -0.123 0.953 0.277 vn -0.228 0.657 0.719 vn -0.298 -0.735 0.609 vn -0.300 -0.179 0.937 vn -0.219 0.400 0.890 vn -0.587 -0.175 0.791 vn 0.175 0.460 0.870 vn -0.179 0.856 0.485 vn 0.114 0.959 0.259 vn 0.664 0.620 0.418 vn -0.026 -0.991 0.129 vn -0.184 -0.979 0.082 vn -0.810 0.566 -0.151 vn -0.628 0.654 -0.422 vn -0.741 0.405 -0.536 vn -0.924 0.322 -0.207 vn -0.493 0.823 -0.280 vn -0.648 0.758 -0.080 vn -0.966 0.258 0.022 vn -0.864 0.501 0.051 vn -0.679 0.730 0.075 vn -0.221 -0.970 0.105 vn -0.271 -0.962 -0.038 vn -0.376 -0.516 0.769 vn -0.124 0.748 -0.652 vn -0.339 0.727 -0.598 vn -0.420 0.469 -0.777 vn -0.500 -0.524 -0.690 vn -0.489 -0.481 -0.728 vn -0.206 -0.458 -0.865 vn -0.212 -0.565 -0.797 vn -0.893 -0.325 -0.312 vn -0.759 -0.435 -0.485 vn -0.796 -0.289 -0.532 vn -0.937 -0.249 -0.246 vn -0.193 -0.029 -0.981 vn -0.202 -0.249 -0.947 vn -0.814 -0.090 -0.574 vn -0.969 -0.102 -0.227 vn -0.969 0.093 -0.229 vn -0.801 0.142 -0.581 vn -0.998 0.061 -0.010 vn -0.718 0.664 0.209 vn -0.985 -0.168 0.036 vn -0.954 -0.222 -0.201 vn -0.451 0.039 0.891 vn -0.341 -0.253 0.905 vn -0.604 -0.144 0.784 vn -0.472 -0.641 0.606 vn 0.107 -0.991 0.080 vn -0.463 0.274 0.843 vn -0.002 0.997 0.081 vn 0.083 0.977 0.195 vn -0.466 0.366 0.805 vn -0.977 0.200 0.072 vn 0.916 -0.331 0.226 vn 0.929 -0.364 -0.067 vn 0.728 0.359 0.584 vn -0.419 0.737 -0.531 vn -0.638 0.769 0.043 vn -0.146 0.857 -0.494 vn 0.280 0.954 0.105 vn 0.343 0.909 -0.237 vn 0.546 0.838 -0.008 vn 0.342 -0.678 -0.651 vn -0.159 -0.734 -0.660 vn -0.545 0.363 0.756 vn -0.599 0.165 0.783 vn -0.447 0.066 0.892 vn -0.645 0.255 0.721 vn -0.936 0.164 0.311 vn -0.776 0.182 -0.604 vn -0.827 0.285 -0.485 vn -0.999 -0.012 0.041 vn -0.995 -0.037 -0.093 vn -0.586 -0.252 0.770 vn -0.926 -0.370 0.079 vn -0.938 -0.339 -0.067 vn -0.889 -0.266 0.372 vn -0.922 -0.372 -0.106 vn -0.493 -0.275 -0.825 vn -0.473 0.194 -0.860 vn -0.965 -0.122 0.231 vn -0.401 -0.036 -0.915 vn -0.143 -0.164 -0.976 vn -0.496 -0.052 -0.867 vn -0.996 -0.037 -0.083 vn -0.998 0.042 0.045 vn -0.950 0.012 0.313 vn -0.733 -0.008 0.681 vn -0.670 0.247 0.700 vn -0.408 0.697 0.589 vn -0.330 0.155 0.931 vn -0.517 0.244 0.821 vn 0.568 -0.625 0.535 vn -0.512 -0.108 0.852 vn -0.414 -0.112 0.903 vn -0.654 -0.140 0.743 vn -0.608 -0.086 0.789 vn -0.422 0.215 0.881 vn -0.943 0.031 0.332 vn -0.549 0.190 0.814 vn -0.193 0.018 0.981 vn 0.358 0.872 0.335 vn -0.651 -0.118 0.750 vn -0.954 -0.010 0.300 vn -0.352 0.145 -0.925 vn -0.095 -0.049 -0.994 vn -0.769 0.031 0.639 vn -0.929 -0.329 -0.171 vn -0.923 -0.336 0.190 vn -0.985 -0.174 0.005 vn -0.970 -0.234 0.068 vn -0.801 0.162 0.576 vn -0.969 -0.184 0.166 vn -0.293 0.803 0.519 vn -0.954 -0.019 0.300 vn -0.133 0.986 -0.105 vn -0.976 0.175 0.130 vn -0.098 0.675 -0.732 vn -0.993 0.112 -0.041 vn -0.197 0.127 -0.972 vn -0.997 -0.077 -0.003 vn -0.112 -0.322 -0.940 vn -0.978 -0.176 -0.109 vn -0.171 -0.674 -0.719 vn -0.397 -0.789 -0.468 vn -0.937 -0.337 -0.091 vn -0.929 -0.341 -0.146 vn -0.158 -0.985 -0.070 vn -0.854 -0.500 0.145 vn -0.814 -0.564 -0.141 vn -0.931 -0.306 -0.199 vn -0.824 -0.545 0.156 vn -0.797 -0.383 0.466 vn -0.811 -0.165 0.562 vn -0.824 0.053 0.564 vn -0.926 0.257 0.275 vn -0.991 0.062 0.118 vn -0.952 0.122 0.281 vn -0.383 -0.604 0.699 vn -0.810 -0.150 0.567 vn -0.784 0.355 0.509 vn -0.761 0.645 0.076 vn -0.920 0.079 -0.385 vn -0.975 -0.023 0.222 vn -0.937 0.166 0.308 vn -0.787 0.551 0.279 vn -0.517 0.758 -0.396 vn -0.337 0.112 -0.935 vn -0.221 -0.301 -0.928 vn -0.395 -0.579 -0.714 vn -0.520 -0.711 -0.473 vn -0.426 -0.904 -0.044 vn -0.824 -0.523 0.219 vn -0.886 -0.220 0.409 vn -0.863 0.404 0.303 vn -0.782 -0.104 0.615 vn -0.953 0.066 0.297 vn -0.949 0.312 0.046 vn -0.991 0.025 -0.134 vn -0.944 -0.116 0.308 vn -0.971 -0.237 0.041 vn -0.947 -0.041 0.318 vn -0.854 -0.274 -0.443 vn -0.885 -0.271 -0.378 vn -0.952 -0.121 -0.282 vn 0.180 0.824 -0.537 vn 0.642 0.679 -0.355 vn 0.956 0.291 -0.021 vn 0.453 -0.867 0.208 vn 0.910 -0.301 0.285 vn 0.854 -0.043 0.518 vn 0.833 0.459 0.308 vn 0.241 0.911 0.334 vn 0.731 -0.650 -0.206 vn 0.760 -0.585 -0.282 vn -0.814 0.019 0.580 vn -0.563 0.638 0.526 vn -0.925 -0.012 0.381 vn -0.214 0.952 0.217 vn 0.096 0.721 0.686 vn -0.027 0.945 0.325 vn -0.555 -0.678 -0.481 vn 0.062 0.937 -0.343 vn 0.240 -0.291 0.926 vn 0.184 -0.889 0.419 vn -0.126 -0.990 0.061 vn -0.889 -0.369 -0.271 vn -0.506 -0.832 0.229 vn -0.808 -0.443 0.388 vn -0.993 -0.084 0.087 vn 0.350 -0.016 0.937 vn -0.636 0.759 -0.140 vn -0.771 0.626 -0.115 vn -0.250 0.462 -0.851 vn -0.192 0.568 -0.801 vn -0.359 0.279 0.891 vn -0.026 0.144 0.989 vn -0.398 -0.100 0.912 vn -0.465 0.084 0.881 vn -0.895 0.186 0.405 vn -0.947 0.184 0.264 vn -0.761 0.459 0.458 vn -0.657 0.429 0.620 vn -0.426 0.660 0.618 vn -0.505 0.610 0.611 vn 0.223 0.536 0.814 vn 0.285 0.393 0.874 vn -0.163 0.555 0.815 vn -0.038 0.570 0.821 vn -0.628 0.723 -0.288 vn -0.458 0.737 0.497 vn -0.212 0.799 0.563 vn -0.278 0.687 0.672 vn -0.380 0.657 0.651 vn -0.170 0.846 0.506 vn -0.305 0.687 0.660 vn -0.144 0.795 0.589 vn 0.001 0.494 -0.870 vn -0.208 0.539 -0.816 vn -0.027 0.458 -0.888 vn -0.057 0.367 -0.929 vn -0.262 0.718 0.645 vn -0.054 0.163 -0.985 vn -0.306 0.325 -0.895 vn -0.643 0.181 0.744 vn -0.717 0.083 0.692 vn -0.800 0.573 -0.178 vn 0.296 -0.070 0.953 vn -0.319 -0.065 0.946 # 1258 vertex normals g head s 1 f 24/1/24 25/2/25 26/3/26 f 24/1/24 26/3/26 23/4/23 f 28/5/28 29/6/29 30/7/30 f 28/5/28 30/7/30 27/8/27 f 32/9/32 33/10/33 34/11/34 f 32/9/32 34/11/34 31/12/31 f 36/13/36 31/12/31 34/11/34 f 36/13/36 34/11/34 35/14/35 f 36/13/36 35/14/35 25/2/25 f 36/13/36 25/2/25 24/1/24 f 38/15/38 39/16/39 40/17/40 f 38/15/38 40/17/40 37/18/37 f 42/19/42 23/4/23 26/3/26 f 42/19/42 26/3/26 41/20/41 f 40/17/40 42/19/42 41/20/41 f 40/17/40 41/20/41 37/18/37 f 38/15/38 43/21/43 44/22/44 f 38/15/38 44/22/44 39/16/39 f 32/9/32 45/23/45 46/24/46 f 32/9/32 46/24/46 33/10/33 f 28/5/28 44/22/44 48/25/48 f 28/5/28 48/25/48 47/26/47 f 50/27/50 51/28/51 52/29/52 f 50/27/50 52/29/52 49/30/49 f 54/31/54 55/32/55 56/33/56 f 54/31/54 56/33/56 53/34/53 f 58/35/58 59/36/59 60/37/60 f 58/35/58 60/37/60 57/38/57 f 62/39/62 63/40/63 64/41/64 f 62/39/62 64/41/64 61/42/61 f 66/43/66 67/44/67 68/45/68 f 66/43/66 68/45/68 65/46/65 f 70/47/70 71/48/71 72/49/72 f 70/47/70 72/49/72 69/50/69 f 67/44/67 66/43/66 74/51/74 f 67/44/67 74/51/74 73/52/73 f 66/43/66 51/28/51 50/27/50 f 66/43/66 50/27/50 74/51/74 f 76/53/76 77/54/77 78/55/78 f 76/53/76 78/55/78 75/56/75 f 80/57/80 81/58/81 82/59/82 f 80/57/80 82/59/82 79/60/79 f 84/61/84 85/62/85 86/63/86 f 84/61/84 86/63/86 83/64/83 f 87/65/87 88/66/88 80/57/80 f 87/65/87 80/57/80 79/60/79 f 90/67/90 91/68/91 92/69/92 f 90/67/90 92/69/92 89/70/89 f 93/71/93 94/72/94 78/55/78 f 93/71/93 78/55/78 77/54/77 f 87/65/87 95/73/95 96/74/96 f 87/65/87 96/74/96 88/66/88 f 98/75/98 99/76/99 100/77/100 f 98/75/98 100/77/100 97/78/97 f 100/77/100 101/79/101 102/80/102 f 100/77/100 102/80/102 97/78/97 f 98/75/98 103/81/103 104/82/104 f 98/75/98 104/82/104 99/76/99 f 106/83/106 107/84/107 108/85/108 f 106/83/106 108/85/108 105/86/105 f 109/87/109 110/88/110 105/86/105 f 109/87/109 105/86/105 108/85/108 f 101/79/101 111/89/111 112/90/112 f 101/79/101 112/90/112 102/80/102 f 114/91/114 115/92/115 116/93/116 f 114/91/114 116/93/116 113/94/113 f 118/95/118 119/96/119 120/97/120 f 118/95/118 120/97/120 117/98/117 f 122/99/122 123/100/123 124/101/124 f 122/99/122 124/101/124 121/102/121 f 126/103/126 127/104/127 128/105/128 f 126/103/126 128/105/128 125/106/125 f 130/107/130 131/108/131 132/109/132 f 130/107/130 132/109/132 129/110/129 f 125/106/125 128/105/128 134/111/134 f 125/106/125 134/111/134 133/112/133 f 56/33/56 55/32/55 136/113/136 f 56/33/56 136/113/136 135/114/135 f 37/115/37 137/116/137 138/117/138 f 37/115/37 138/117/138 38/118/38 f 139/119/139 43/120/43 38/118/38 f 139/119/139 38/118/38 138/117/138 f 140/121/140 141/122/141 142/123/142 f 140/121/140 142/123/142 130/107/130 f 144/124/144 129/110/129 132/109/132 f 144/124/144 132/109/132 143/125/143 f 146/126/146 147/127/147 148/128/148 f 146/126/146 148/128/148 145/129/145 f 150/130/150 151/131/151 54/31/54 f 150/130/150 54/31/54 149/132/149 f 54/31/54 53/34/53 152/133/152 f 54/31/54 152/133/152 149/132/149 f 154/134/154 155/135/155 156/136/156 f 154/134/154 156/136/156 153/137/153 f 158/138/158 159/139/159 160/140/160 f 158/138/158 160/140/160 157/141/157 f 162/142/162 163/143/163 164/144/164 f 162/142/162 164/144/164 161/145/161 f 129/110/129 144/124/144 157/141/157 f 129/110/129 157/141/157 160/140/160 f 156/136/156 155/135/155 166/146/166 f 156/136/156 166/146/166 165/147/165 f 168/148/168 169/149/169 170/150/170 f 168/148/168 170/150/170 167/151/167 f 171/152/171 172/153/172 173/154/173 f 171/152/171 173/154/173 169/149/169 f 175/155/175 176/156/176 171/152/171 f 175/155/175 171/152/171 174/157/174 f 59/36/59 177/158/177 178/159/178 f 59/36/59 178/159/178 60/37/60 f 180/160/180 181/161/181 49/30/49 f 180/160/180 49/30/49 179/162/179 f 127/104/127 52/29/52 182/163/182 f 127/104/127 182/163/182 128/105/128 f 134/111/134 183/164/183 184/165/184 f 134/111/134 184/165/184 124/101/124 f 185/166/185 121/102/121 124/101/124 f 185/166/185 124/101/124 184/165/184 f 187/167/187 188/168/188 189/169/189 f 187/167/187 189/169/189 186/170/186 f 191/171/191 192/172/192 193/173/193 f 191/171/191 193/173/193 190/174/190 f 76/53/76 194/175/194 193/173/193 f 76/53/76 193/173/193 77/54/77 f 100/77/100 99/76/99 196/176/196 f 100/77/100 196/176/196 195/177/195 f 176/156/176 175/155/175 198/178/198 f 176/156/176 198/178/198 197/179/197 f 199/180/199 200/181/200 173/154/173 f 199/180/199 173/154/173 172/153/172 f 196/176/196 202/182/202 203/183/203 f 196/176/196 203/183/203 201/184/201 f 205/185/205 206/186/206 207/187/207 f 205/185/205 207/187/207 204/188/204 f 208/189/208 205/185/205 204/188/204 f 208/189/208 204/188/204 201/184/201 f 210/190/210 97/78/97 102/80/102 f 210/190/210 102/80/102 209/191/209 f 79/60/79 210/190/210 209/191/209 f 79/60/79 209/191/209 87/65/87 f 212/192/212 213/193/213 214/194/214 f 212/192/212 214/194/214 211/195/211 f 216/196/216 217/197/217 218/198/218 f 216/196/216 218/198/218 215/199/215 f 220/200/220 216/196/216 215/199/215 f 220/200/220 215/199/215 219/201/219 f 222/202/222 223/203/223 218/198/218 f 222/202/222 218/198/218 221/204/221 f 225/205/225 226/206/226 227/207/227 f 225/205/225 227/207/227 224/208/224 f 222/202/222 221/204/221 229/209/229 f 222/202/222 229/209/229 228/210/228 f 230/211/230 231/212/231 220/200/220 f 230/211/230 220/200/220 219/201/219 f 227/207/227 226/206/226 231/212/231 f 227/207/227 231/212/231 230/211/230 f 233/213/233 234/214/234 235/215/235 f 233/213/233 235/215/235 232/216/232 f 186/170/186 203/183/203 202/182/202 f 186/170/186 202/182/202 187/167/187 f 236/217/236 237/218/237 238/219/238 f 236/217/236 238/219/238 188/168/188 f 240/220/240 241/221/241 242/222/242 f 240/220/240 242/222/242 239/223/239 f 241/221/241 243/224/243 244/225/244 f 241/221/241 244/225/244 238/219/238 f 245/226/245 101/79/101 100/77/100 f 245/226/245 100/77/100 195/177/195 f 195/177/195 204/188/204 207/187/207 f 195/177/195 207/187/207 245/226/245 f 111/89/111 246/227/246 247/228/247 f 111/89/111 247/228/247 115/92/115 f 141/122/141 140/121/140 249/229/249 f 141/122/141 249/229/249 248/230/248 f 251/231/251 252/232/252 253/233/253 f 251/231/251 253/233/253 250/234/250 f 254/235/254 118/95/118 255/236/255 f 254/235/254 255/236/255 217/197/217 f 257/237/257 258/238/258 259/239/259 f 257/237/257 259/239/259 256/240/256 f 256/240/256 259/239/259 261/241/261 f 256/240/256 261/241/261 260/242/260 f 260/242/260 261/241/261 30/243/30 f 260/242/260 30/243/30 29/244/29 f 218/198/218 217/197/217 262/245/262 f 218/198/218 262/245/262 221/204/221 f 259/239/259 258/238/258 264/246/264 f 259/239/259 264/246/264 263/247/263 f 266/248/266 30/243/30 261/241/261 f 266/248/266 261/241/261 265/249/265 f 253/233/253 252/232/252 268/250/268 f 253/233/253 268/250/268 267/251/267 f 270/252/270 200/181/200 271/253/271 f 270/252/270 271/253/271 269/254/269 f 199/180/199 272/255/272 271/253/271 f 199/180/199 271/253/271 200/181/200 f 199/180/199 273/256/273 274/257/274 f 199/180/199 274/257/274 272/255/272 f 276/258/276 267/251/267 268/250/268 f 276/258/276 268/250/268 275/259/275 f 275/259/275 268/250/268 269/254/269 f 275/259/275 269/254/269 277/260/277 f 93/71/93 77/54/77 193/173/193 f 93/71/93 193/173/193 192/172/192 f 279/261/279 280/262/280 281/263/281 f 279/261/279 281/263/281 278/264/278 f 278/264/278 88/66/88 96/74/96 f 278/264/278 96/74/96 279/261/279 f 282/265/282 283/266/283 62/39/62 f 282/265/282 62/39/62 94/72/94 f 281/263/281 284/267/284 285/268/285 f 281/263/281 285/268/285 278/264/278 f 287/269/287 288/270/288 289/271/289 f 287/269/287 289/271/289 286/272/286 f 63/40/63 62/39/62 283/266/283 f 63/40/63 283/266/283 290/273/290 f 283/266/283 291/274/291 292/275/292 f 283/266/283 292/275/292 290/273/290 f 293/276/293 294/277/294 68/45/68 f 293/276/293 68/45/68 67/44/67 f 296/278/296 297/279/297 298/280/298 f 296/278/296 298/280/298 295/281/295 f 300/282/300 301/283/301 302/284/302 f 300/282/300 302/284/302 299/285/299 f 304/286/304 305/287/305 306/288/306 f 304/286/304 306/288/306 303/289/303 f 138/117/138 137/116/137 308/290/308 f 138/117/138 308/290/308 307/291/307 f 165/147/165 310/292/310 311/293/311 f 165/147/165 311/293/311 309/294/309 f 312/295/312 55/32/55 54/31/54 f 312/295/312 54/31/54 151/131/151 f 314/296/314 151/131/151 150/130/150 f 314/296/314 150/130/150 313/297/313 f 315/298/315 316/299/316 227/207/227 f 315/298/315 227/207/227 230/211/230 f 136/113/136 317/300/317 158/138/158 f 136/113/136 158/138/158 157/141/157 f 319/301/319 148/128/148 147/127/147 f 319/301/319 147/127/147 318/302/318 f 320/303/320 321/304/321 147/127/147 f 320/303/320 147/127/147 146/126/146 f 323/305/323 324/306/324 325/307/325 f 323/305/323 325/307/325 322/308/322 f 80/57/80 88/66/88 278/264/278 f 80/57/80 278/264/278 285/268/285 f 327/309/327 145/129/145 148/128/148 f 327/309/327 148/128/148 326/310/326 f 279/261/279 286/272/286 289/271/289 f 279/261/279 289/271/289 280/262/280 f 329/311/329 330/312/330 331/313/331 f 329/311/329 331/313/331 328/314/328 f 187/167/187 202/182/202 104/82/104 f 187/167/187 104/82/104 332/315/332 f 236/217/236 332/315/332 191/171/191 f 236/217/236 191/171/191 190/174/190 f 165/147/165 166/146/166 333/316/333 f 165/147/165 333/316/333 310/292/310 f 139/119/139 334/317/334 48/318/48 f 139/119/139 48/318/48 43/120/43 f 336/319/336 337/320/337 338/321/338 f 336/319/336 338/321/338 335/322/335 f 51/28/51 324/306/324 182/163/182 f 51/28/51 182/163/182 52/29/52 f 339/323/339 126/103/126 53/34/53 f 339/323/339 53/34/53 56/33/56 f 340/324/340 341/325/341 149/132/149 f 340/324/340 149/132/149 152/133/152 f 243/224/243 343/326/343 344/327/344 f 243/224/243 344/327/344 342/328/342 f 346/329/346 343/326/343 240/220/240 f 346/329/346 240/220/240 345/330/345 f 348/331/348 349/332/349 350/333/350 f 348/331/348 350/333/350 347/334/347 f 351/335/351 352/336/352 213/193/213 f 351/335/351 213/193/213 212/192/212 f 128/105/128 182/163/182 183/164/183 f 128/105/128 183/164/183 134/111/134 f 103/81/103 98/75/98 354/337/354 f 103/81/103 354/337/354 353/338/353 f 114/91/114 113/94/113 356/339/356 f 114/91/114 356/339/356 355/340/355 f 358/341/358 197/179/197 198/178/198 f 358/341/358 198/178/198 357/342/357 f 107/84/107 359/343/359 360/344/360 f 107/84/107 360/344/360 108/85/108 f 348/331/348 361/345/361 362/346/362 f 348/331/348 362/346/362 349/332/349 f 347/334/347 363/347/363 234/214/234 f 347/334/347 234/214/234 348/331/348 f 220/200/220 231/212/231 167/151/167 f 220/200/220 167/151/167 364/348/364 f 153/137/153 366/349/366 300/282/300 f 153/137/153 300/282/300 365/350/365 f 295/281/295 72/49/72 71/48/71 f 295/281/295 71/48/71 296/278/296 f 179/162/179 339/323/339 367/351/367 f 179/162/179 367/351/367 180/160/180 f 368/352/368 369/353/369 158/138/158 f 368/352/368 158/138/158 317/300/317 f 317/300/317 136/113/136 55/32/55 f 317/300/317 55/32/55 312/295/312 f 371/354/371 372/355/372 373/356/373 f 371/354/371 373/356/373 370/357/370 f 41/358/41 26/359/26 306/288/306 f 41/358/41 306/288/306 305/287/305 f 305/287/305 137/116/137 37/115/37 f 305/287/305 37/115/37 41/358/41 f 248/230/248 374/360/374 375/361/375 f 248/230/248 375/361/375 141/122/141 f 66/43/66 325/307/325 324/306/324 f 66/43/66 324/306/324 51/28/51 f 183/164/183 323/305/323 376/362/376 f 183/164/183 376/362/376 184/165/184 f 378/363/378 253/233/253 267/251/267 f 378/363/378 267/251/267 377/364/377 f 269/254/269 271/253/271 379/365/379 f 269/254/269 379/365/379 277/260/277 f 381/366/381 382/367/382 383/368/383 f 381/366/381 383/368/383 380/369/380 f 384/370/384 385/371/385 105/86/105 f 384/370/384 105/86/105 110/88/110 f 105/86/105 385/371/385 386/372/386 f 105/86/105 386/372/386 106/83/106 f 360/344/360 387/373/387 109/87/109 f 360/344/360 109/87/109 108/85/108 f 181/161/181 180/160/180 164/144/164 f 181/161/181 164/144/164 163/143/163 f 365/350/365 388/374/388 154/134/154 f 365/350/365 154/134/154 153/137/153 f 168/148/168 167/151/167 231/212/231 f 168/148/168 231/212/231 226/206/226 f 81/58/81 291/274/291 283/266/283 f 81/58/81 283/266/283 282/265/282 f 272/255/272 389/375/389 379/365/379 f 272/255/272 379/365/379 271/253/271 f 274/257/274 390/376/390 389/375/389 f 274/257/274 389/375/389 272/255/272 f 139/119/139 375/361/375 374/360/374 f 139/119/139 374/360/374 334/317/334 f 391/377/391 366/349/366 153/137/153 f 391/377/391 153/137/153 156/136/156 f 392/378/392 393/379/393 366/349/366 f 392/378/392 366/349/366 391/377/391 f 173/154/173 200/181/200 270/252/270 f 173/154/173 270/252/270 394/380/394 f 301/283/301 300/282/300 366/349/366 f 301/283/301 366/349/366 393/379/393 f 396/381/396 397/382/397 398/383/398 f 396/381/396 398/383/398 395/384/395 f 399/385/399 364/348/364 167/151/167 f 399/385/399 167/151/167 170/150/170 f 394/380/394 251/231/251 399/385/399 f 394/380/394 399/385/399 170/150/170 f 270/252/270 252/232/252 251/231/251 f 270/252/270 251/231/251 394/380/394 f 102/80/102 112/90/112 400/386/400 f 102/80/102 400/386/400 209/191/209 f 131/108/131 401/387/401 372/355/372 f 131/108/131 372/355/372 371/354/371 f 391/377/391 156/136/156 165/147/165 f 391/377/391 165/147/165 309/294/309 f 403/388/403 404/389/404 405/390/405 f 403/388/403 405/390/405 402/391/402 f 402/391/402 392/378/392 391/377/391 f 402/391/402 391/377/391 309/294/309 f 35/392/35 310/292/310 333/316/333 f 35/392/35 333/316/333 25/393/25 f 35/392/35 34/394/34 311/293/311 f 35/392/35 311/293/311 310/292/310 f 34/394/34 33/395/33 403/388/403 f 34/394/34 403/388/403 311/293/311 f 406/396/406 262/245/262 217/197/217 f 406/396/406 217/197/217 255/236/255 f 377/364/377 407/397/407 408/398/408 f 377/364/377 408/398/408 406/396/406 f 117/98/117 378/363/378 255/236/255 f 117/98/117 255/236/255 118/95/118 f 270/252/270 269/254/269 268/250/268 f 270/252/270 268/250/268 252/232/252 f 304/286/304 303/289/303 373/356/373 f 304/286/304 373/356/373 372/355/372 f 362/346/362 409/399/409 410/400/410 f 362/346/362 410/400/410 349/332/349 f 411/401/411 412/402/412 89/70/89 f 411/401/411 89/70/89 92/69/92 f 414/403/414 411/401/411 415/404/415 f 414/403/414 415/404/415 413/405/413 f 417/406/417 336/319/336 418/407/418 f 417/406/417 418/407/418 416/408/416 f 337/320/337 419/409/419 69/50/69 f 337/320/337 69/50/69 72/49/72 f 421/410/421 422/411/422 423/412/423 f 421/410/421 423/412/423 420/413/420 f 421/410/421 424/414/424 425/415/425 f 421/410/421 425/415/425 422/411/422 f 423/412/423 422/411/422 427/416/427 f 423/412/423 427/416/427 426/417/426 f 239/223/239 242/222/242 428/418/428 f 239/223/239 428/418/428 425/415/425 f 430/419/430 73/52/73 74/51/74 f 430/419/430 74/51/74 429/420/429 f 70/47/70 69/50/69 419/409/419 f 70/47/70 419/409/419 429/420/429 f 247/228/247 431/421/431 116/93/116 f 247/228/247 116/93/116 115/92/115 f 346/329/346 345/330/345 433/422/433 f 346/329/346 433/422/433 432/423/432 f 433/422/433 421/410/421 420/413/420 f 433/422/433 420/413/420 434/424/434 f 436/425/436 437/426/437 438/427/438 f 436/425/436 438/427/438 435/428/435 f 437/426/437 381/366/381 380/369/380 f 437/426/437 380/369/380 438/427/438 f 178/159/178 177/158/177 440/429/440 f 178/159/178 440/429/440 439/430/439 f 440/429/440 441/431/441 442/432/442 f 440/429/440 442/432/442 439/430/439 f 444/433/444 445/434/445 446/435/446 f 444/433/444 446/435/446 443/436/443 f 324/306/324 323/305/323 183/164/183 f 324/306/324 183/164/183 182/163/182 f 213/193/213 352/336/352 357/342/357 f 213/193/213 357/342/357 198/178/198 f 214/194/214 175/155/175 174/157/174 f 214/194/214 174/157/174 225/205/225 f 448/437/448 449/438/449 450/439/450 f 448/437/448 450/439/450 447/440/447 f 423/412/423 426/417/426 451/441/451 f 423/412/423 451/441/451 447/440/447 f 75/56/75 451/441/451 426/417/426 f 75/56/75 426/417/426 76/53/76 f 78/55/78 94/72/94 62/39/62 f 78/55/78 62/39/62 61/42/61 f 286/272/286 86/63/86 85/62/85 f 286/272/286 85/62/85 287/269/287 f 95/73/95 87/65/87 209/191/209 f 95/73/95 209/191/209 400/386/400 f 237/218/237 452/442/452 428/418/428 f 237/218/237 428/418/428 242/222/242 f 190/174/190 193/173/193 194/175/194 f 190/174/190 194/175/194 452/442/452 f 237/218/237 236/217/236 190/174/190 f 237/218/237 190/174/190 452/442/452 f 79/60/79 82/59/82 354/337/354 f 79/60/79 354/337/354 210/190/210 f 286/272/286 279/261/279 96/74/96 f 286/272/286 96/74/96 86/63/86 f 430/419/430 417/406/417 416/408/416 f 430/419/430 416/408/416 453/443/453 f 338/321/338 295/281/295 298/280/298 f 338/321/338 298/280/298 299/285/299 f 57/38/57 60/37/60 455/444/455 f 57/38/57 455/444/455 454/445/454 f 212/192/212 456/446/456 457/447/457 f 212/192/212 457/447/457 351/335/351 f 83/64/83 355/340/355 356/339/356 f 83/64/83 356/339/356 84/61/84 f 142/123/142 141/122/141 375/361/375 f 142/123/142 375/361/375 307/291/307 f 401/387/401 142/123/142 307/291/307 f 401/387/401 307/291/307 308/290/308 f 459/448/459 257/237/257 256/240/256 f 459/448/459 256/240/256 458/449/458 f 228/210/228 264/246/264 258/238/258 f 228/210/228 258/238/258 222/202/222 f 256/240/256 260/242/260 460/450/460 f 256/240/256 460/450/460 458/449/458 f 460/450/460 260/242/260 29/244/29 f 460/450/460 29/244/29 47/451/47 f 263/247/263 265/249/265 261/241/261 f 263/247/263 261/241/261 259/239/259 f 461/452/461 462/453/462 189/169/189 f 461/452/461 189/169/189 244/225/244 f 227/207/227 316/299/316 463/454/463 f 227/207/227 463/454/463 224/208/224 f 465/455/465 466/456/466 410/400/410 f 465/455/465 410/400/410 464/457/464 f 90/67/90 386/372/386 385/371/385 f 90/67/90 385/371/385 91/68/91 f 233/213/233 361/345/361 348/331/348 f 233/213/233 348/331/348 234/214/234 f 235/215/235 234/214/234 363/347/363 f 235/215/235 363/347/363 467/458/467 f 338/321/338 337/320/337 72/49/72 f 338/321/338 72/49/72 295/281/295 f 338/321/338 299/285/299 302/284/302 f 338/321/338 302/284/302 335/322/335 f 468/459/468 469/460/469 470/461/470 f 468/459/468 470/461/470 415/404/415 f 347/334/347 471/462/471 472/463/472 f 347/334/347 472/463/472 363/347/363 f 471/462/471 347/334/347 350/333/350 f 471/462/471 350/333/350 473/464/473 f 465/455/465 475/465/475 476/466/476 f 465/455/465 476/466/476 474/467/474 f 384/370/384 110/88/110 478/468/478 f 384/370/384 478/468/478 477/469/477 f 414/403/414 479/470/479 412/402/412 f 414/403/414 412/402/412 411/401/411 f 288/270/288 287/269/287 412/402/412 f 288/270/288 412/402/412 479/470/479 f 85/62/85 84/61/84 90/67/90 f 85/62/85 90/67/90 89/70/89 f 386/372/386 356/339/356 113/94/113 f 386/372/386 113/94/113 106/83/106 f 232/216/232 358/341/358 357/342/357 f 232/216/232 357/342/357 233/213/233 f 297/279/297 296/278/296 181/161/181 f 297/279/297 181/161/181 163/143/163 f 419/409/419 337/320/337 336/319/336 f 419/409/419 336/319/336 417/406/417 f 49/30/49 52/29/52 127/104/127 f 49/30/49 127/104/127 179/162/179 f 26/359/26 25/393/25 333/316/333 f 26/359/26 333/316/333 306/288/306 f 371/354/371 370/357/370 162/142/162 f 371/354/371 162/142/162 161/145/161 f 258/238/258 257/237/257 223/203/223 f 258/238/258 223/203/223 222/202/222 f 257/237/257 459/448/459 480/471/480 f 257/237/257 480/471/480 223/203/223 f 211/195/211 214/194/214 225/205/225 f 211/195/211 225/205/225 224/208/224 f 316/299/316 481/472/481 314/296/314 f 316/299/316 314/296/314 463/454/463 f 171/152/171 169/149/169 168/148/168 f 171/152/171 168/148/168 174/157/174 f 273/256/273 199/180/199 172/153/172 f 273/256/273 172/153/172 482/473/482 f 168/148/168 226/206/226 225/205/225 f 168/148/168 225/205/225 174/157/174 f 245/226/245 246/227/246 111/89/111 f 245/226/245 111/89/111 101/79/101 f 114/91/114 112/90/112 111/89/111 f 114/91/114 111/89/111 115/92/115 f 210/190/210 354/337/354 98/75/98 f 210/190/210 98/75/98 97/78/97 f 431/421/431 358/341/358 232/216/232 f 431/421/431 232/216/232 359/343/359 f 235/215/235 360/344/360 359/343/359 f 235/215/235 359/343/359 232/216/232 f 360/344/360 235/215/235 467/458/467 f 360/344/360 467/458/467 387/373/387 f 81/58/81 282/265/282 483/474/483 f 81/58/81 483/474/483 82/59/82 f 485/475/485 486/476/486 487/477/487 f 485/475/485 487/477/487 484/478/484 f 489/479/489 68/45/68 294/277/294 f 489/479/489 294/277/294 488/480/488 f 491/481/491 454/445/454 455/444/455 f 491/481/491 455/444/455 490/482/490 f 154/134/154 370/357/370 373/356/373 f 154/134/154 373/356/373 155/135/155 f 491/481/491 322/308/322 325/307/325 f 491/481/491 325/307/325 492/483/492 f 491/481/491 490/482/490 493/484/493 f 491/481/491 493/484/493 322/308/322 f 436/425/436 435/428/435 446/435/446 f 436/425/436 446/435/446 494/485/494 f 495/486/495 496/487/496 438/427/438 f 495/486/495 438/427/438 380/369/380 f 496/487/496 497/488/497 435/428/435 f 496/487/496 435/428/435 438/427/438 f 331/313/331 330/312/330 498/489/498 f 331/313/331 498/489/498 432/423/432 f 499/490/499 346/329/346 432/423/432 f 499/490/499 432/423/432 498/489/498 f 380/369/380 383/368/383 500/491/500 f 380/369/380 500/491/500 495/486/495 f 501/492/501 328/314/328 331/313/331 f 501/492/501 331/313/331 434/424/434 f 499/490/499 344/327/344 343/326/343 f 499/490/499 343/326/343 346/329/346 f 492/483/492 502/493/502 454/445/454 f 492/483/492 454/445/454 491/481/491 f 454/445/454 502/493/502 487/477/487 f 454/445/454 487/477/487 57/38/57 f 486/476/486 58/35/58 57/38/57 f 486/476/486 57/38/57 487/477/487 f 58/35/58 486/476/486 503/494/503 f 58/35/58 503/494/503 382/367/382 f 383/368/383 504/495/504 505/496/505 f 383/368/383 505/496/505 500/491/500 f 447/440/447 450/439/450 420/413/420 f 447/440/447 420/413/420 423/412/423 f 329/311/329 328/314/328 445/434/445 f 329/311/329 445/434/445 444/433/444 f 450/439/450 449/438/449 506/497/506 f 450/439/450 506/497/506 501/492/501 f 507/498/507 508/499/508 451/441/451 f 507/498/507 451/441/451 75/56/75 f 99/76/99 104/82/104 202/182/202 f 99/76/99 202/182/202 196/176/196 f 509/500/509 208/189/208 201/184/201 f 509/500/509 201/184/201 203/183/203 f 201/184/201 204/188/204 195/177/195 f 201/184/201 195/177/195 196/176/196 f 462/453/462 510/501/510 186/170/186 f 462/453/462 186/170/186 189/169/189 f 203/183/203 186/170/186 510/501/510 f 203/183/203 510/501/510 509/500/509 f 148/128/148 319/301/319 341/325/341 f 148/128/148 341/325/341 326/310/326 f 326/310/326 341/325/341 340/324/340 f 326/310/326 340/324/340 511/502/511 f 123/100/123 511/502/511 340/324/340 f 123/100/123 340/324/340 133/112/133 f 71/48/71 49/30/49 181/161/181 f 71/48/71 181/161/181 296/278/296 f 154/134/154 388/374/388 162/142/162 f 154/134/154 162/142/162 370/357/370 f 155/135/155 373/356/373 303/289/303 f 155/135/155 303/289/303 166/146/166 f 166/146/166 303/289/303 306/288/306 f 166/146/166 306/288/306 333/316/333 f 512/503/512 320/303/320 289/271/289 f 512/503/512 289/271/289 288/270/288 f 479/470/479 414/403/414 514/504/514 f 479/470/479 514/504/514 513/505/513 f 414/403/414 413/405/413 475/465/475 f 414/403/414 475/465/475 514/504/514 f 513/505/513 512/503/512 288/270/288 f 513/505/513 288/270/288 479/470/479 f 191/171/191 103/81/103 353/338/353 f 191/171/191 353/338/353 192/172/192 f 332/315/332 104/82/104 103/81/103 f 332/315/332 103/81/103 191/171/191 f 82/59/82 483/474/483 353/338/353 f 82/59/82 353/338/353 354/337/354 f 83/64/83 86/63/86 96/74/96 f 83/64/83 96/74/96 95/73/95 f 83/64/83 95/73/95 400/386/400 f 83/64/83 400/386/400 355/340/355 f 355/340/355 400/386/400 112/90/112 f 355/340/355 112/90/112 114/91/114 f 144/124/144 135/114/135 136/113/136 f 144/124/144 136/113/136 157/141/157 f 298/280/298 365/350/365 300/282/300 f 298/280/298 300/282/300 299/285/299 f 298/280/298 297/279/297 388/374/388 f 298/280/298 388/374/388 365/350/365 f 367/351/367 143/125/143 164/144/164 f 367/351/367 164/144/164 180/160/180 f 515/506/515 516/507/516 219/201/219 f 515/506/515 219/201/219 215/199/215 f 254/235/254 217/197/217 216/196/216 f 254/235/254 216/196/216 517/508/517 f 398/383/398 364/348/364 399/385/399 f 398/383/398 399/385/399 395/384/395 f 398/383/398 397/382/397 517/508/517 f 398/383/398 517/508/517 216/196/216 f 518/509/518 519/510/519 246/227/246 f 518/509/518 246/227/246 245/226/245 f 319/301/319 150/130/150 149/132/149 f 319/301/319 149/132/149 341/325/341 f 429/420/429 419/409/419 417/406/417 f 429/420/429 417/406/417 430/419/430 f 33/395/33 46/511/46 404/389/404 f 33/395/33 404/389/404 403/388/403 f 403/388/403 402/391/402 309/294/309 f 403/388/403 309/294/309 311/293/311 f 393/379/393 520/512/520 521/513/521 f 393/379/393 521/513/521 301/283/301 f 522/514/522 520/512/520 393/379/393 f 522/514/522 393/379/393 392/378/392 f 302/284/302 301/283/301 521/513/521 f 302/284/302 521/513/521 523/515/523 f 302/284/302 523/515/523 524/516/524 f 302/284/302 524/516/524 335/322/335 f 321/304/321 456/446/456 318/302/318 f 321/304/321 318/302/318 147/127/147 f 456/446/456 321/304/321 525/517/525 f 456/446/456 525/517/525 457/447/457 f 410/400/410 409/399/409 526/518/526 f 410/400/410 526/518/526 464/457/464 f 410/400/410 466/456/466 350/333/350 f 410/400/410 350/333/350 349/332/349 f 456/446/456 212/192/212 211/195/211 f 456/446/456 211/195/211 527/519/527 f 211/195/211 224/208/224 463/454/463 f 211/195/211 463/454/463 527/519/527 f 407/397/407 377/364/377 267/251/267 f 407/397/407 267/251/267 276/258/276 f 378/363/378 377/364/377 406/396/406 f 378/363/378 406/396/406 255/236/255 f 175/155/175 214/194/214 213/193/213 f 175/155/175 213/193/213 198/178/198 f 386/372/386 90/67/90 84/61/84 f 386/372/386 84/61/84 356/339/356 f 409/399/409 362/346/362 351/335/351 f 409/399/409 351/335/351 457/447/457 f 85/62/85 89/70/89 412/402/412 f 85/62/85 412/402/412 287/269/287 f 361/345/361 233/213/233 357/342/357 f 361/345/361 357/342/357 352/336/352 f 116/93/116 431/421/431 359/343/359 f 116/93/116 359/343/359 107/84/107 f 116/93/116 107/84/107 106/83/106 f 116/93/116 106/83/106 113/94/113 f 352/336/352 351/335/351 362/346/362 f 352/336/352 362/346/362 361/345/361 f 513/505/513 514/504/514 464/457/464 f 513/505/513 464/457/464 526/518/526 f 526/518/526 409/399/409 457/447/457 f 526/518/526 457/447/457 525/517/525 f 514/504/514 475/465/475 465/455/465 f 514/504/514 465/455/465 464/457/464 f 358/341/358 431/421/431 247/228/247 f 358/341/358 247/228/247 197/179/197 f 176/156/176 482/473/482 172/153/172 f 176/156/176 172/153/172 171/152/171 f 396/381/396 395/384/395 250/234/250 f 396/381/396 250/234/250 119/96/119 f 395/384/395 399/385/399 251/231/251 f 395/384/395 251/231/251 250/234/250 f 291/274/291 81/58/81 80/57/80 f 291/274/291 80/57/80 285/268/285 f 284/267/284 292/275/292 291/274/291 f 284/267/284 291/274/291 285/268/285 f 528/520/528 327/309/327 326/310/326 f 528/520/528 326/310/326 511/502/511 f 126/103/126 125/106/125 152/133/152 f 126/103/126 152/133/152 53/34/53 f 152/133/152 125/106/125 133/112/133 f 152/133/152 133/112/133 340/324/340 f 127/104/127 126/103/126 339/323/339 f 127/104/127 339/323/339 179/162/179 f 56/33/56 135/114/135 367/351/367 f 56/33/56 367/351/367 339/323/339 f 124/101/124 123/100/123 133/112/133 f 124/101/124 133/112/133 134/111/134 f 143/125/143 367/351/367 135/114/135 f 143/125/143 135/114/135 144/124/144 f 164/144/164 143/125/143 132/109/132 f 164/144/164 132/109/132 161/145/161 f 401/387/401 131/108/131 130/107/130 f 401/387/401 130/107/130 142/123/142 f 292/275/292 528/520/528 122/99/122 f 292/275/292 122/99/122 290/273/290 f 61/42/61 507/498/507 75/56/75 f 61/42/61 75/56/75 78/55/78 f 320/303/320 512/503/512 525/517/525 f 320/303/320 525/517/525 321/304/321 f 512/503/512 513/505/513 526/518/526 f 512/503/512 526/518/526 525/517/525 f 123/100/123 122/99/122 528/520/528 f 123/100/123 528/520/528 511/502/511 f 262/245/262 529/521/529 229/209/229 f 262/245/262 229/209/229 221/204/221 f 316/299/316 315/298/315 368/352/368 f 316/299/316 368/352/368 481/472/481 f 516/507/516 315/298/315 230/211/230 f 516/507/516 230/211/230 219/201/219 f 515/506/515 530/522/530 369/353/369 f 515/506/515 369/353/369 516/507/516 f 530/522/530 515/506/515 223/203/223 f 530/522/530 223/203/223 480/471/480 f 215/199/215 218/198/218 223/203/223 f 215/199/215 223/203/223 515/506/515 f 459/448/459 458/449/458 374/360/374 f 459/448/459 374/360/374 248/230/248 f 458/449/458 460/450/460 334/317/334 f 458/449/458 334/317/334 374/360/374 f 334/317/334 460/450/460 47/451/47 f 334/317/334 47/451/47 48/318/48 f 459/448/459 248/230/248 249/229/249 f 459/448/459 249/229/249 480/471/480 f 253/233/253 120/97/120 119/96/119 f 253/233/253 119/96/119 250/234/250 f 394/380/394 170/150/170 169/149/169 f 394/380/394 169/149/169 173/154/173 f 519/510/519 482/473/482 176/156/176 f 519/510/519 176/156/176 197/179/197 f 518/509/518 273/256/273 482/473/482 f 518/509/518 482/473/482 519/510/519 f 531/523/531 274/257/274 273/256/273 f 531/523/531 273/256/273 518/509/518 f 532/524/532 390/376/390 274/257/274 f 532/524/532 274/257/274 531/523/531 f 343/326/343 243/224/243 241/221/241 f 343/326/343 241/221/241 240/220/240 f 188/168/188 238/219/238 244/225/244 f 188/168/188 244/225/244 189/169/189 f 187/167/187 332/315/332 236/217/236 f 187/167/187 236/217/236 188/168/188 f 447/440/447 451/441/451 508/499/508 f 447/440/447 508/499/508 448/437/448 f 162/142/162 388/374/388 297/279/297 f 162/142/162 297/279/297 163/143/163 f 392/378/392 402/391/402 405/390/405 f 392/378/392 405/390/405 522/514/522 f 533/525/533 413/405/413 415/404/415 f 533/525/533 415/404/415 470/461/470 f 534/526/534 65/46/65 68/45/68 f 534/526/534 68/45/68 489/479/489 f 502/493/502 535/527/535 484/478/484 f 502/493/502 484/478/484 487/477/487 f 503/494/503 536/528/536 537/529/537 f 503/494/503 537/529/537 504/495/504 f 492/483/492 538/530/538 535/527/535 f 492/483/492 535/527/535 502/493/502 f 492/483/492 325/307/325 66/43/66 f 492/483/492 66/43/66 65/46/65 f 504/495/504 537/529/537 539/531/539 f 504/495/504 539/531/539 505/496/505 f 239/223/239 424/414/424 345/330/345 f 239/223/239 345/330/345 240/220/240 f 59/36/59 58/35/58 382/367/382 f 59/36/59 382/367/382 381/366/381 f 432/423/432 433/422/433 434/424/434 f 432/423/432 434/424/434 331/313/331 f 437/426/437 436/425/436 440/429/440 f 437/426/437 440/429/440 177/158/177 f 381/366/381 437/426/437 177/158/177 f 381/366/381 177/158/177 59/36/59 f 449/438/449 441/431/441 494/485/494 f 449/438/449 494/485/494 506/497/506 f 450/439/450 501/492/501 434/424/434 f 450/439/450 434/424/434 420/413/420 f 382/367/382 503/494/503 504/495/504 f 382/367/382 504/495/504 383/368/383 f 501/492/501 506/497/506 445/434/445 f 501/492/501 445/434/445 328/314/328 f 536/528/536 503/494/503 486/476/486 f 536/528/536 486/476/486 485/475/485 f 313/297/313 150/130/150 319/301/319 f 313/297/313 319/301/319 318/302/318 f 327/309/327 284/267/284 281/263/281 f 327/309/327 281/263/281 145/129/145 f 483/474/483 93/71/93 192/172/192 f 483/474/483 192/172/192 353/338/353 f 483/474/483 282/265/282 94/72/94 f 483/474/483 94/72/94 93/71/93 f 422/411/422 425/415/425 428/418/428 f 422/411/422 428/418/428 427/416/427 f 421/410/421 433/422/433 345/330/345 f 421/410/421 345/330/345 424/414/424 f 463/454/463 314/296/314 313/297/313 f 463/454/463 313/297/313 527/519/527 f 315/298/315 516/507/516 369/353/369 f 315/298/315 369/353/369 368/352/368 f 314/296/314 481/472/481 312/295/312 f 314/296/314 312/295/312 151/131/151 f 368/352/368 317/300/317 312/295/312 f 368/352/368 312/295/312 481/472/481 f 369/353/369 530/522/530 159/139/159 f 369/353/369 159/139/159 158/138/158 f 480/471/480 249/229/249 159/139/159 f 480/471/480 159/139/159 530/522/530 f 262/245/262 406/396/406 408/398/408 f 262/245/262 408/398/408 529/521/529 f 398/383/398 216/196/216 220/200/220 f 398/383/398 220/200/220 364/348/364 f 541/532/541 542/533/542 543/534/543 f 541/532/541 543/534/543 540/535/540 f 545/536/545 543/534/543 542/533/542 f 545/536/545 542/533/542 544/537/544 f 547/538/547 545/536/545 544/537/544 f 547/538/547 544/537/544 546/539/546 f 549/540/549 547/538/547 546/539/546 f 549/540/549 546/539/546 548/541/548 f 551/542/551 549/540/549 548/541/548 f 551/542/551 548/541/548 550/543/550 f 553/544/553 551/542/551 550/543/550 f 553/544/553 550/543/550 552/545/552 f 555/546/555 553/544/553 552/545/552 f 555/546/555 552/545/552 554/547/554 f 557/548/557 558/549/558 559/550/559 f 557/548/557 559/550/559 556/551/556 f 561/552/561 557/548/557 556/551/556 f 561/552/561 556/551/556 560/553/560 f 563/554/563 546/539/546 544/537/544 f 563/554/563 544/537/544 562/555/562 f 564/556/564 548/541/548 546/539/546 f 564/556/564 546/539/546 563/554/563 f 565/557/565 550/543/550 548/541/548 f 565/557/565 548/541/548 564/556/564 f 566/558/566 552/545/552 550/543/550 f 566/558/566 550/543/550 565/557/565 f 552/545/552 566/558/566 567/559/567 f 552/545/552 567/559/567 554/547/554 f 559/550/559 568/560/568 569/561/569 f 559/550/559 569/561/569 556/551/556 f 570/562/570 560/553/560 556/551/556 f 570/562/570 556/551/556 569/561/569 f 571/563/571 572/564/572 560/553/560 f 571/563/571 560/553/560 570/562/570 f 574/565/574 540/535/540 575/566/575 f 574/565/574 575/566/575 573/567/573 f 577/568/577 543/534/543 545/536/545 f 577/568/577 545/536/545 576/569/576 f 545/536/545 547/538/547 578/570/578 f 545/536/545 578/570/578 576/569/576 f 579/571/579 578/570/578 547/538/547 f 579/571/579 547/538/547 549/540/549 f 580/572/580 579/571/579 551/542/551 f 580/572/580 551/542/551 553/544/553 f 580/572/580 553/544/553 555/546/555 f 580/572/580 555/546/555 581/573/581 f 558/549/558 557/548/557 583/574/583 f 558/549/558 583/574/583 582/575/582 f 561/552/561 584/576/584 583/574/583 f 561/552/561 583/574/583 557/548/557 f 561/552/561 572/564/572 585/577/585 f 561/552/561 585/577/585 584/576/584 f 571/563/571 586/578/586 585/577/585 f 571/563/571 585/577/585 572/564/572 f 544/537/544 542/533/542 541/532/541 f 544/537/544 541/532/541 562/555/562 f 574/565/574 588/579/588 589/580/589 f 574/565/574 589/580/589 587/581/587 f 574/565/574 573/567/573 590/582/590 f 574/565/574 590/582/590 588/579/588 f 590/582/590 573/567/573 575/566/575 f 590/582/590 575/566/575 591/583/591 f 575/566/575 540/535/540 543/534/543 f 575/566/575 543/534/543 591/583/591 f 564/556/564 592/584/592 566/558/566 f 564/556/564 566/558/566 565/557/565 f 592/584/592 593/585/593 567/559/567 f 592/584/592 567/559/567 566/558/566 f 568/560/568 559/550/559 554/547/554 f 568/560/568 554/547/554 567/559/567 f 554/547/554 559/550/559 558/549/558 f 554/547/554 558/549/558 555/546/555 f 582/575/582 581/573/581 555/546/555 f 582/575/582 555/546/555 558/549/558 f 592/584/592 564/556/564 563/554/563 f 592/584/592 563/554/563 562/555/562 f 589/580/589 568/560/568 567/559/567 f 589/580/589 567/559/567 593/585/593 f 540/535/540 574/565/574 587/581/587 f 540/535/540 587/581/587 541/532/541 f 571/563/571 570/562/570 590/582/590 f 571/563/571 590/582/590 591/583/591 f 589/580/589 588/579/588 569/561/569 f 589/580/589 569/561/569 568/560/568 f 543/534/543 577/568/577 594/586/594 f 543/534/543 594/586/594 591/583/591 f 594/586/594 586/578/586 571/563/571 f 594/586/594 571/563/571 591/583/591 f 596/587/596 581/573/581 582/575/582 f 596/587/596 582/575/582 595/588/595 f 596/587/596 597/589/597 580/572/580 f 596/587/596 580/572/580 581/573/581 f 583/574/583 490/482/490 455/444/455 f 583/574/583 455/444/455 595/588/595 f 583/574/583 584/576/584 493/484/493 f 583/574/583 493/484/493 490/482/490 f 597/589/597 508/499/508 579/571/579 f 597/589/597 579/571/579 580/572/580 f 442/432/442 448/437/448 508/499/508 f 442/432/442 508/499/508 597/589/597 f 60/37/60 178/159/178 595/588/595 f 60/37/60 595/588/595 455/444/455 f 178/159/178 439/430/439 596/587/596 f 178/159/178 596/587/596 595/588/595 f 577/568/577 64/41/64 185/166/185 f 577/568/577 185/166/185 594/586/594 f 586/578/586 184/165/184 376/362/376 f 586/578/586 376/362/376 585/577/585 f 590/582/590 570/562/570 569/561/569 f 590/582/590 569/561/569 588/579/588 f 61/42/61 576/569/576 578/570/578 f 61/42/61 578/570/578 507/498/507 f 585/577/585 376/362/376 493/484/493 f 585/577/585 493/484/493 584/576/584 f 453/443/453 598/590/598 73/52/73 f 453/443/453 73/52/73 430/419/430 f 519/510/519 197/179/197 247/228/247 f 519/510/519 247/228/247 246/227/246 f 281/263/281 280/262/280 146/126/146 f 281/263/281 146/126/146 145/129/145 f 64/41/64 63/40/63 121/102/121 f 64/41/64 121/102/121 185/166/185 f 284/267/284 327/309/327 528/520/528 f 284/267/284 528/520/528 292/275/292 f 290/273/290 122/99/122 121/102/121 f 290/273/290 121/102/121 63/40/63 f 280/262/280 289/271/289 320/303/320 f 280/262/280 320/303/320 146/126/146 f 184/165/184 586/578/586 594/586/594 f 184/165/184 594/586/594 185/166/185 f 253/233/253 378/363/378 117/98/117 f 253/233/253 117/98/117 120/97/120 f 249/229/249 140/121/140 160/140/160 f 249/229/249 160/140/160 159/139/159 f 129/110/129 160/140/160 140/121/140 f 129/110/129 140/121/140 130/107/130 f 161/145/161 132/109/132 131/108/131 f 161/145/161 131/108/131 371/354/371 f 313/297/313 318/302/318 456/446/456 f 313/297/313 456/446/456 527/519/527 f 492/483/492 65/46/65 534/526/534 f 492/483/492 534/526/534 538/530/538 f 441/431/441 449/438/449 448/437/448 f 441/431/441 448/437/448 442/432/442 f 443/436/443 446/435/446 435/428/435 f 443/436/443 435/428/435 497/488/497 f 446/435/446 445/434/445 506/497/506 f 446/435/446 506/497/506 494/485/494 f 441/431/441 440/429/440 436/425/436 f 441/431/441 436/425/436 494/485/494 f 596/587/596 439/430/439 442/432/442 f 596/587/596 442/432/442 597/589/597 f 577/568/577 576/569/576 61/42/61 f 577/568/577 61/42/61 64/41/64 f 238/219/238 237/218/237 242/222/242 f 238/219/238 242/222/242 241/221/241 f 194/175/194 76/53/76 426/417/426 f 194/175/194 426/417/426 427/416/427 f 452/442/452 194/175/194 427/416/427 f 452/442/452 427/416/427 428/418/428 f 461/452/461 244/225/244 243/224/243 f 461/452/461 243/224/243 342/328/342 f 508/499/508 507/498/507 578/570/578 f 508/499/508 578/570/578 579/571/579 f 245/226/245 207/187/207 531/523/531 f 245/226/245 531/523/531 518/509/518 f 206/186/206 532/524/532 531/523/531 f 206/186/206 531/523/531 207/187/207 f 32/9/32 31/12/31 600/591/600 f 32/9/32 600/591/600 599/592/599 f 601/593/601 600/591/600 36/13/36 f 601/593/601 36/13/36 24/1/24 f 602/594/602 601/593/601 24/1/24 f 602/594/602 24/1/24 23/4/23 f 40/17/40 602/594/602 23/4/23 f 40/17/40 23/4/23 42/19/42 f 44/22/44 604/595/604 605/596/605 f 44/22/44 605/596/605 603/597/603 f 39/16/39 603/597/603 602/594/602 f 39/16/39 602/594/602 40/17/40 f 601/593/601 606/598/606 607/599/607 f 601/593/601 607/599/607 600/591/600 f 468/459/468 608/600/608 609/601/609 f 468/459/468 609/601/609 469/460/469 f 477/469/477 609/601/609 608/600/608 f 477/469/477 608/600/608 384/370/384 f 610/602/610 611/603/611 612/604/612 f 610/602/610 612/604/612 472/605/472 f 610/602/610 472/605/472 471/606/471 f 610/602/610 471/606/471 613/607/613 f 476/608/476 614/609/614 615/610/615 f 476/608/476 615/610/615 474/611/474 f 478/468/478 110/88/110 109/87/109 f 478/468/478 109/87/109 616/612/616 f 466/456/466 465/455/465 474/467/474 f 466/456/466 474/467/474 617/613/617 f 466/456/466 617/613/617 473/464/473 f 466/456/466 473/464/473 350/333/350 f 614/609/614 533/614/533 470/615/470 f 614/609/614 470/615/470 618/616/618 f 475/465/475 413/405/413 533/525/533 f 475/465/475 533/525/533 476/466/476 f 618/616/618 469/617/469 609/618/609 f 618/616/618 609/618/609 619/619/619 f 619/619/619 609/618/609 477/620/477 f 619/619/619 477/620/477 620/621/620 f 387/373/387 621/622/621 616/612/616 f 387/373/387 616/612/616 109/87/109 f 616/623/616 622/624/622 620/621/620 f 616/623/616 620/621/620 478/625/478 f 473/626/473 617/627/617 615/610/615 f 473/626/473 615/610/615 613/607/613 f 621/628/621 623/629/623 622/624/622 f 621/628/621 622/624/622 616/623/616 f 624/630/624 612/604/612 611/603/611 f 624/630/624 611/603/611 623/629/623 f 49/30/49 71/48/71 70/47/70 f 49/30/49 70/47/70 50/27/50 f 336/319/336 335/322/335 524/516/524 f 336/319/336 524/516/524 418/407/418 f 598/590/598 293/276/293 67/44/67 f 598/590/598 67/44/67 73/52/73 f 50/27/50 70/47/70 429/420/429 f 50/27/50 429/420/429 74/51/74 f 322/308/322 493/484/493 376/362/376 f 322/308/322 376/362/376 323/305/323 f 589/580/589 593/585/593 592/584/592 f 589/580/589 592/584/592 587/581/587 f 396/381/396 119/96/119 118/95/118 f 396/381/396 118/95/118 254/235/254 f 517/508/517 397/382/397 396/381/396 f 517/508/517 396/381/396 254/235/254 f 28/5/28 27/8/27 625/631/625 f 28/5/28 625/631/625 604/595/604 f 600/591/600 607/599/607 626/632/626 f 600/591/600 626/632/626 599/592/599 f 607/599/607 627/633/627 628/634/628 f 607/599/607 628/634/628 626/632/626 f 604/595/604 625/631/625 628/634/628 f 604/595/604 628/634/628 627/633/627 f 630/635/630 631/636/631 632/637/632 f 630/635/630 632/637/632 629/638/629 f 634/639/634 635/640/635 636/641/636 f 634/639/634 636/641/636 633/642/633 f 638/643/638 639/644/639 640/645/640 f 638/643/638 640/645/640 637/646/637 f 641/647/641 642/648/642 637/646/637 f 641/647/641 637/646/637 640/645/640 f 644/649/644 645/650/645 646/651/646 f 644/649/644 646/651/646 643/652/643 f 631/636/631 642/648/642 648/653/648 f 631/636/631 648/653/648 647/654/647 f 650/655/650 651/656/651 652/657/652 f 650/655/650 652/657/652 649/658/649 f 643/652/643 646/651/646 654/659/654 f 643/652/643 654/659/654 653/660/653 f 654/659/654 651/656/651 650/655/650 f 654/659/654 650/655/650 653/660/653 f 655/661/655 656/662/656 657/663/657 f 655/661/655 657/663/657 632/637/632 f 657/663/657 659/664/659 660/665/660 f 657/663/657 660/665/660 658/666/658 f 661/667/661 659/664/659 657/663/657 f 661/667/661 657/663/657 656/662/656 f 631/636/631 647/654/647 655/661/655 f 631/636/631 655/661/655 632/637/632 f 637/646/637 642/648/642 631/636/631 f 637/646/637 631/636/631 630/635/630 f 640/645/640 650/655/650 649/658/649 f 640/645/640 649/658/649 641/647/641 f 652/657/652 662/668/662 641/647/641 f 652/657/652 641/647/641 649/658/649 f 648/653/648 642/648/642 641/647/641 f 648/653/648 641/647/641 662/668/662 f 663/669/663 664/670/664 537/529/537 f 663/669/663 537/529/537 536/528/536 f 666/671/666 640/645/640 639/644/639 f 666/671/666 639/644/639 665/672/665 f 666/671/666 665/672/665 636/641/636 f 666/671/666 636/641/636 635/640/635 f 667/673/667 539/531/539 537/529/537 f 667/673/667 537/529/537 664/670/664 f 634/639/634 644/649/644 643/652/643 f 634/639/634 643/652/643 635/640/635 f 653/660/653 650/655/650 640/645/640 f 653/660/653 640/645/640 666/671/666 f 666/671/666 635/640/635 643/652/643 f 666/671/666 643/652/643 653/660/653 f 669/674/669 644/649/644 634/639/634 f 669/674/669 634/639/634 668/675/668 f 638/643/638 637/646/637 630/635/630 f 638/643/638 630/635/630 670/676/670 f 645/650/645 644/649/644 669/674/669 f 645/650/645 669/674/669 671/677/671 f 638/643/638 670/676/670 485/475/485 f 638/643/638 485/475/485 484/478/484 f 672/678/672 633/642/633 489/479/489 f 672/678/672 489/479/489 488/480/488 f 632/637/632 657/663/657 658/666/658 f 632/637/632 658/666/658 629/638/629 f 670/676/670 663/669/663 536/528/536 f 670/676/670 536/528/536 485/475/485 f 633/642/633 636/641/636 534/526/534 f 633/642/633 534/526/534 489/479/489 f 484/478/484 535/527/535 639/644/639 f 484/478/484 639/644/639 638/643/638 f 629/638/629 658/666/658 664/670/664 f 629/638/629 664/670/664 663/669/663 f 665/672/665 639/644/639 535/527/535 f 665/672/665 535/527/535 538/530/538 f 636/641/636 665/672/665 538/530/538 f 636/641/636 538/530/538 534/526/534 f 660/665/660 667/673/667 664/670/664 f 660/665/660 664/670/664 658/666/658 f 668/675/668 634/639/634 633/642/633 f 668/675/668 633/642/633 672/678/672 f 630/635/630 629/638/629 663/669/663 f 630/635/630 663/669/663 670/676/670 f 1/679/1 661/667/661 656/662/656 f 1/679/1 656/662/656 22/680/22 f 20/681/20 647/654/647 648/653/648 f 20/681/20 648/653/648 18/682/18 f 647/654/647 20/681/20 21/683/21 f 647/654/647 21/683/21 655/661/655 f 15/684/15 646/651/646 645/650/645 f 15/684/15 645/650/645 13/685/13 f 19/686/19 651/656/651 654/659/654 f 19/686/19 654/659/654 14/687/14 f 648/653/648 662/668/662 16/688/16 f 648/653/648 16/688/16 18/682/18 f 17/689/17 652/657/652 651/656/651 f 17/689/17 651/656/651 19/686/19 f 21/683/21 22/680/22 656/662/656 f 21/683/21 656/662/656 655/661/655 f 13/685/13 645/650/645 671/677/671 f 13/685/13 671/677/671 2/690/2 f 646/651/646 15/684/15 14/687/14 f 646/651/646 14/687/14 654/659/654 f 17/689/17 16/688/16 662/668/662 f 17/689/17 662/668/662 652/657/652 f 608/600/608 91/68/91 385/371/385 f 608/600/608 385/371/385 384/370/384 f 304/286/304 372/355/372 401/387/401 f 304/286/304 401/387/401 308/290/308 f 468/459/468 415/404/415 411/401/411 f 468/459/468 411/401/411 92/69/92 f 602/594/602 603/597/603 606/598/606 f 602/594/602 606/598/606 601/593/601 f 608/600/608 468/459/468 92/69/92 f 608/600/608 92/69/92 91/68/91 f 305/287/305 304/286/304 308/290/308 f 305/287/305 308/290/308 137/116/137 f 139/119/139 138/117/138 307/291/307 f 139/119/139 307/291/307 375/361/375 f 674/691/674 675/692/675 676/693/676 f 674/691/674 676/693/676 673/694/673 f 678/695/678 27/8/27 679/696/679 f 678/695/678 679/696/679 677/697/677 f 681/698/681 682/699/682 683/700/683 f 681/698/681 683/700/683 680/701/680 f 684/702/684 685/703/685 683/700/683 f 684/702/684 683/700/683 682/699/682 f 684/702/684 674/691/674 673/694/673 f 684/702/684 673/694/673 685/703/685 f 687/704/687 688/705/688 689/706/689 f 687/704/687 689/706/689 686/707/686 f 690/708/690 691/709/691 676/693/676 f 690/708/690 676/693/676 675/692/675 f 689/706/689 688/705/688 691/709/691 f 689/706/689 691/709/691 690/708/690 f 687/704/687 686/707/686 693/710/693 f 687/704/687 693/710/693 692/711/692 f 681/698/681 680/701/680 46/24/46 f 681/698/681 46/24/46 45/23/45 f 678/695/678 694/712/694 695/713/695 f 678/695/678 695/713/695 693/710/693 f 697/714/697 698/715/698 699/716/699 f 697/714/697 699/716/699 696/717/696 f 701/718/701 702/719/702 703/720/703 f 701/718/701 703/720/703 700/721/700 f 705/722/705 706/723/706 707/724/707 f 705/722/705 707/724/707 704/725/704 f 709/726/709 710/727/710 711/728/711 f 709/726/709 711/728/711 708/729/708 f 713/730/713 714/731/714 715/732/715 f 713/730/713 715/732/715 712/733/712 f 717/734/717 718/735/718 719/736/719 f 717/734/717 719/736/719 716/737/716 f 712/733/712 720/738/720 721/739/721 f 712/733/712 721/739/721 713/730/713 f 713/730/713 721/739/721 697/714/697 f 713/730/713 697/714/697 696/717/696 f 723/740/723 724/741/724 725/742/725 f 723/740/723 725/742/725 722/743/722 f 727/744/727 728/745/728 729/746/729 f 727/744/727 729/746/729 726/747/726 f 731/748/731 732/749/732 733/750/733 f 731/748/731 733/750/733 730/751/730 f 735/752/735 728/745/728 727/744/727 f 735/752/735 727/744/727 734/753/734 f 737/754/737 738/755/738 739/756/739 f 737/754/737 739/756/739 736/757/736 f 741/758/741 722/743/722 725/742/725 f 741/758/741 725/742/725 740/759/740 f 735/752/735 734/753/734 743/760/743 f 735/752/735 743/760/743 742/761/742 f 745/762/745 746/763/746 747/764/747 f 745/762/745 747/764/747 744/765/744 f 747/764/747 746/763/746 749/766/749 f 747/764/747 749/766/749 748/767/748 f 745/762/745 744/765/744 751/768/751 f 745/762/745 751/768/751 750/769/750 f 753/770/753 754/771/754 755/772/755 f 753/770/753 755/772/755 752/773/752 f 757/774/757 755/772/755 754/771/754 f 757/774/757 754/771/754 756/775/756 f 748/767/748 749/766/749 759/776/759 f 748/767/748 759/776/759 758/777/758 f 761/778/761 762/779/762 763/780/763 f 761/778/761 763/780/763 760/781/760 f 765/782/765 766/783/766 767/784/767 f 765/782/765 767/784/767 764/785/764 f 769/786/769 770/787/770 771/788/771 f 769/786/769 771/788/771 768/789/768 f 773/790/773 774/791/774 775/792/775 f 773/790/773 775/792/775 772/793/772 f 777/794/777 778/795/778 779/796/779 f 777/794/777 779/796/779 776/797/776 f 774/791/774 780/798/780 781/799/781 f 774/791/774 781/799/781 775/792/775 f 703/720/703 782/800/782 783/801/783 f 703/720/703 783/801/783 700/721/700 f 688/802/688 687/803/687 785/804/785 f 688/802/688 785/804/785 784/805/784 f 786/806/786 785/804/785 687/803/687 f 786/806/786 687/803/687 692/807/692 f 788/808/788 777/794/777 789/809/789 f 788/808/788 789/809/789 787/810/787 f 790/811/790 791/812/791 779/796/779 f 790/811/790 779/796/779 778/795/778 f 793/813/793 794/814/794 795/815/795 f 793/813/793 795/815/795 792/816/792 f 797/817/797 798/818/798 701/718/701 f 797/817/797 701/718/701 796/819/796 f 701/718/701 798/818/798 799/820/799 f 701/718/701 799/820/799 702/719/702 f 801/821/801 802/822/802 803/823/803 f 801/821/801 803/823/803 800/824/800 f 805/825/805 806/826/806 807/827/807 f 805/825/805 807/827/807 804/828/804 f 809/829/809 810/830/810 811/831/811 f 809/829/809 811/831/811 808/832/808 f 778/795/778 807/827/807 806/826/806 f 778/795/778 806/826/806 790/811/790 f 803/823/803 812/833/812 813/834/813 f 803/823/803 813/834/813 800/824/800 f 815/835/815 816/836/816 817/837/817 f 815/835/815 817/837/817 814/838/814 f 819/839/819 814/838/814 820/840/820 f 819/839/819 820/840/820 818/841/818 f 822/842/822 823/843/823 819/839/819 f 822/842/822 819/839/819 821/844/821 f 704/725/704 707/724/707 825/845/825 f 704/725/704 825/845/825 824/846/824 f 827/847/827 828/848/828 698/715/698 f 827/847/827 698/715/698 826/849/826 f 772/793/772 775/792/775 829/850/829 f 772/793/772 829/850/829 699/716/699 f 781/799/781 771/788/771 831/851/831 f 781/799/781 831/851/831 830/852/830 f 832/853/832 831/851/831 771/788/771 f 832/853/832 771/788/771 770/787/770 f 834/854/834 835/855/835 836/856/836 f 834/854/834 836/856/836 833/857/833 f 838/858/838 839/859/839 840/860/840 f 838/858/838 840/860/840 837/861/837 f 723/740/723 722/743/722 840/860/840 f 723/740/723 840/860/840 841/862/841 f 747/764/747 842/863/842 843/864/843 f 747/764/747 843/864/843 744/765/744 f 821/844/821 844/865/844 845/866/845 f 821/844/821 845/866/845 822/842/822 f 847/867/847 818/841/818 820/840/820 f 847/867/847 820/840/820 846/868/846 f 843/864/843 849/869/849 850/870/850 f 843/864/843 850/870/850 848/871/848 f 205/185/205 851/872/851 852/873/852 f 205/185/205 852/873/852 206/186/206 f 208/189/208 849/869/849 851/872/851 f 208/189/208 851/872/851 205/185/205 f 853/874/853 854/875/854 749/766/749 f 853/874/853 749/766/749 746/763/746 f 728/745/728 735/752/735 854/875/854 f 728/745/728 854/875/854 853/874/853 f 856/876/856 857/877/857 858/878/858 f 856/876/856 858/878/858 855/879/855 f 860/880/860 861/881/861 862/882/862 f 860/880/860 862/882/862 859/883/859 f 863/884/863 864/885/864 861/881/861 f 863/884/863 861/881/861 860/880/860 f 866/886/866 867/887/867 862/882/862 f 866/886/866 862/882/862 865/888/865 f 869/889/869 870/890/870 871/891/871 f 869/889/869 871/891/871 868/892/868 f 866/886/866 228/210/228 229/209/229 f 866/886/866 229/209/229 867/887/867 f 873/893/873 864/885/864 863/884/863 f 873/893/873 863/884/863 872/894/872 f 871/891/871 873/893/873 872/894/872 f 871/891/871 872/894/872 868/892/868 f 875/895/875 876/896/876 877/897/877 f 875/895/875 877/897/877 874/898/874 f 835/855/835 834/854/834 848/871/848 f 835/855/835 848/871/848 850/870/850 f 879/899/879 833/857/833 880/900/880 f 879/899/879 880/900/880 878/901/878 f 882/902/882 883/903/883 884/904/884 f 882/902/882 884/904/884 881/905/881 f 881/905/881 880/900/880 886/906/886 f 881/905/881 886/906/886 885/907/885 f 887/908/887 842/863/842 747/764/747 f 887/908/887 747/764/747 748/767/748 f 842/863/842 887/908/887 852/873/852 f 842/863/842 852/873/852 851/872/851 f 758/777/758 760/781/760 889/909/889 f 758/777/758 889/909/889 888/910/888 f 787/810/787 890/911/890 891/912/891 f 787/810/787 891/912/891 788/808/788 f 893/913/893 894/914/894 895/915/895 f 893/913/893 895/915/895 892/916/892 f 896/917/896 859/883/859 897/918/897 f 896/917/896 897/918/897 765/782/765 f 899/919/899 900/920/900 901/921/901 f 899/919/899 901/921/901 898/922/898 f 900/920/900 902/923/902 903/924/903 f 900/920/900 903/924/903 901/921/901 f 902/923/902 677/925/677 679/926/679 f 902/923/902 679/926/679 903/924/903 f 862/882/862 867/887/867 904/927/904 f 862/882/862 904/927/904 859/883/859 f 901/921/901 263/247/263 264/246/264 f 901/921/901 264/246/264 898/922/898 f 266/248/266 265/249/265 903/924/903 f 266/248/266 903/924/903 679/926/679 f 895/915/895 905/928/905 906/929/906 f 895/915/895 906/929/906 892/916/892 f 907/930/907 908/931/908 909/932/909 f 907/930/907 909/932/909 846/868/846 f 847/867/847 846/868/846 909/932/909 f 847/867/847 909/932/909 910/933/910 f 847/867/847 910/933/910 912/934/912 f 847/867/847 912/934/912 911/935/911 f 276/258/276 275/259/275 906/929/906 f 276/258/276 906/929/906 905/928/905 f 275/259/275 277/260/277 908/931/908 f 275/259/275 908/931/908 906/929/906 f 741/758/741 837/861/837 840/860/840 f 741/758/741 840/860/840 722/743/722 f 914/936/914 915/937/915 916/938/916 f 914/936/914 916/938/916 913/939/913 f 915/937/915 914/936/914 743/760/743 f 915/937/915 743/760/743 734/753/734 f 918/940/918 740/759/740 709/726/709 f 918/940/918 709/726/709 917/941/917 f 916/938/916 915/937/915 920/942/920 f 916/938/916 920/942/920 919/943/919 f 922/944/922 923/945/923 924/946/924 f 922/944/922 924/946/924 921/947/921 f 708/729/708 925/948/925 917/941/917 f 708/729/708 917/941/917 709/726/709 f 917/941/917 925/948/925 927/949/927 f 917/941/917 927/949/927 926/950/926 f 293/276/293 712/733/712 715/732/715 f 293/276/293 715/732/715 294/277/294 f 929/951/929 930/952/930 931/953/931 f 929/951/929 931/953/931 928/954/928 f 933/955/933 934/956/934 935/957/935 f 933/955/933 935/957/935 932/958/932 f 937/959/937 938/960/938 939/961/939 f 937/959/937 939/961/939 936/962/936 f 785/804/785 940/963/940 941/964/941 f 785/804/785 941/964/941 784/805/784 f 812/833/812 943/965/943 944/966/944 f 812/833/812 944/966/944 942/967/942 f 945/968/945 796/819/796 701/718/701 f 945/968/945 701/718/701 700/721/700 f 946/969/946 947/970/947 797/817/797 f 946/969/946 797/817/797 796/819/796 f 949/971/949 873/893/873 871/891/871 f 949/971/949 871/891/871 948/972/948 f 783/801/783 806/826/806 805/825/805 f 783/801/783 805/825/805 950/973/950 f 951/974/951 952/975/952 792/816/792 f 951/974/951 792/816/792 795/815/795 f 954/976/954 793/813/793 792/816/792 f 954/976/954 792/816/792 953/977/953 f 956/978/956 957/979/957 958/980/958 f 956/978/956 958/980/958 955/981/955 f 727/744/727 920/942/920 915/937/915 f 727/744/727 915/937/915 734/753/734 f 959/982/959 960/983/960 795/815/795 f 959/982/959 795/815/795 794/814/794 f 914/936/914 913/939/913 924/946/924 f 914/936/914 924/946/924 923/945/923 f 329/984/329 961/985/961 962/986/962 f 329/984/329 962/986/962 330/987/330 f 834/854/834 963/988/963 751/768/751 f 834/854/834 751/768/751 848/871/848 f 879/899/879 839/859/839 838/858/838 f 879/899/879 838/858/838 963/988/963 f 812/833/812 942/967/942 964/989/964 f 812/833/812 964/989/964 813/834/813 f 786/806/786 692/807/692 695/990/695 f 786/806/786 695/990/695 965/991/965 f 967/992/967 968/993/968 969/994/969 f 967/992/967 969/994/969 966/995/966 f 696/717/696 699/716/699 829/850/829 f 696/717/696 829/850/829 955/981/955 f 970/996/970 703/720/703 702/719/702 f 970/996/970 702/719/702 773/790/773 f 972/997/972 799/820/799 798/818/798 f 972/997/972 798/818/798 971/998/971 f 885/907/885 342/999/342 344/1000/344 f 885/907/885 344/1000/344 973/1001/973 f 974/1002/974 975/1003/975 882/902/882 f 974/1002/974 882/902/882 973/1001/973 f 977/1004/977 978/1005/978 979/1006/979 f 977/1004/977 979/1006/979 976/1007/976 f 981/1008/981 856/876/856 855/879/855 f 981/1008/981 855/879/855 980/1009/980 f 775/792/775 781/799/781 830/852/830 f 775/792/775 830/852/830 829/850/829 f 750/769/750 982/1010/982 983/1011/983 f 750/769/750 983/1011/983 745/762/745 f 761/778/761 984/1012/984 985/1013/985 f 761/778/761 985/1013/985 762/779/762 f 986/1014/986 987/1015/987 845/866/845 f 986/1014/986 845/866/845 844/865/844 f 752/773/752 755/772/755 989/1016/989 f 752/773/752 989/1016/989 988/1017/988 f 977/1004/977 976/1007/976 991/1018/991 f 977/1004/977 991/1018/991 990/1019/990 f 978/1005/978 977/1004/977 874/898/874 f 978/1005/978 874/898/874 992/1020/992 f 863/884/863 993/1021/993 816/836/816 f 863/884/863 816/836/816 872/894/872 f 802/822/802 995/1022/995 933/955/933 f 802/822/802 933/955/933 994/1023/994 f 930/952/930 929/951/929 716/737/716 f 930/952/930 716/737/716 719/736/719 f 828/848/828 827/847/827 996/1024/996 f 828/848/828 996/1024/996 970/996/970 f 998/1025/998 950/973/950 805/825/805 f 998/1025/998 805/825/805 997/1026/997 f 950/973/950 945/968/945 700/721/700 f 950/973/950 700/721/700 783/801/783 f 1000/1027/1000 1001/1028/1001 1002/1029/1002 f 1000/1027/1000 1002/1029/1002 999/1030/999 f 691/1031/691 936/962/936 939/961/939 f 691/1031/691 939/961/939 676/1032/676 f 936/962/936 691/1031/691 688/802/688 f 936/962/936 688/802/688 784/805/784 f 890/911/890 787/810/787 1004/1033/1004 f 890/911/890 1004/1033/1004 1003/1034/1003 f 713/730/713 696/717/696 955/981/955 f 713/730/713 955/981/955 958/980/958 f 830/852/830 831/851/831 1005/1035/1005 f 830/852/830 1005/1035/1005 956/978/956 f 1006/1036/1006 1007/1037/1007 905/928/905 f 1006/1036/1006 905/928/905 895/915/895 f 908/931/908 277/260/277 379/365/379 f 908/931/908 379/365/379 909/932/909 f 1009/1038/1009 1010/1039/1010 1011/1040/1011 f 1009/1038/1009 1011/1040/1011 1008/1041/1008 f 1013/1042/1013 756/775/756 754/771/754 f 1013/1042/1013 754/771/754 1012/1043/1012 f 754/771/754 753/770/753 1014/1044/1014 f 754/771/754 1014/1044/1014 1012/1043/1012 f 989/1016/989 755/772/755 757/774/757 f 989/1016/989 757/774/757 1015/1045/1015 f 826/849/826 808/832/808 811/831/811 f 826/849/826 811/831/811 827/847/827 f 995/1022/995 802/822/802 801/821/801 f 995/1022/995 801/821/801 1016/1046/1016 f 815/835/815 868/892/868 872/894/872 f 815/835/815 872/894/872 816/836/816 f 726/747/726 918/940/918 917/941/917 f 726/747/726 917/941/917 926/950/926 f 910/933/910 909/932/909 379/365/379 f 910/933/910 379/365/379 389/375/389 f 912/934/912 910/933/910 389/375/389 f 912/934/912 389/375/389 390/376/390 f 786/806/786 965/991/965 1003/1034/1003 f 786/806/786 1003/1034/1003 1004/1033/1004 f 1017/1047/1017 803/823/803 802/822/802 f 1017/1047/1017 802/822/802 994/1023/994 f 1019/1048/1019 1017/1047/1017 994/1023/994 f 1019/1048/1019 994/1023/994 1018/1049/1018 f 820/840/820 1020/1050/1020 907/930/907 f 820/840/820 907/930/907 846/868/846 f 932/958/932 1018/1049/1018 994/1023/994 f 932/958/932 994/1023/994 933/955/933 f 1022/1051/1022 1023/1052/1023 1024/1053/1024 f 1022/1051/1022 1024/1053/1024 1021/1054/1021 f 1025/1055/1025 817/837/817 816/836/816 f 1025/1055/1025 816/836/816 993/1021/993 f 1020/1050/1020 817/837/817 1025/1055/1025 f 1020/1050/1020 1025/1055/1025 893/913/893 f 907/930/907 1020/1050/1020 893/913/893 f 907/930/907 893/913/893 892/916/892 f 749/766/749 854/875/854 1026/1056/1026 f 749/766/749 1026/1056/1026 759/776/759 f 776/797/776 1000/1027/1000 999/1030/999 f 776/797/776 999/1030/999 1027/1057/1027 f 1017/1047/1017 943/965/943 812/833/812 f 1017/1047/1017 812/833/812 803/823/803 f 1028/1058/1028 1029/1059/1029 405/390/405 f 1028/1058/1028 405/390/405 404/389/404 f 1029/1059/1029 943/965/943 1017/1047/1017 f 1029/1059/1029 1017/1047/1017 1019/1048/1019 f 685/1060/685 673/1061/673 964/989/964 f 685/1060/685 964/989/964 942/967/942 f 685/1060/685 942/967/942 944/966/944 f 685/1060/685 944/966/944 683/1062/683 f 683/1062/683 944/966/944 1028/1058/1028 f 683/1062/683 1028/1058/1028 680/1063/680 f 1030/1064/1030 897/918/897 859/883/859 f 1030/1064/1030 859/883/859 904/927/904 f 1007/1037/1007 1030/1064/1030 408/398/408 f 1007/1037/1007 408/398/408 407/397/407 f 766/783/766 765/782/765 897/918/897 f 766/783/766 897/918/897 1006/1036/1006 f 907/930/907 892/916/892 906/929/906 f 907/930/907 906/929/906 908/931/908 f 937/959/937 999/1030/999 1002/1029/1002 f 937/959/937 1002/1029/1002 938/960/938 f 991/1018/991 976/1007/976 1032/1065/1032 f 991/1018/991 1032/1065/1032 1031/1066/1031 f 1034/1067/1034 739/756/739 738/755/738 f 1034/1067/1034 738/755/738 1033/1068/1033 f 1035/1069/1035 1036/1070/1036 1037/1071/1037 f 1035/1069/1035 1037/1071/1037 1034/1067/1034 f 1038/1072/1038 416/408/416 418/407/418 f 1038/1072/1038 418/407/418 967/992/967 f 966/995/966 719/736/719 718/735/718 f 966/995/966 718/735/718 1039/1073/1039 f 1041/1074/1041 1042/1075/1042 1043/1076/1043 f 1041/1074/1041 1043/1076/1043 1040/1077/1040 f 1041/1074/1041 1040/1077/1040 1045/1078/1045 f 1041/1074/1041 1045/1078/1045 1044/1079/1044 f 1043/1076/1043 1046/1080/1046 1047/1081/1047 f 1043/1076/1043 1047/1081/1047 1040/1077/1040 f 883/903/883 1045/1078/1045 1048/1082/1048 f 883/903/883 1048/1082/1048 884/904/884 f 1049/1083/1049 1050/1084/1050 721/739/721 f 1049/1083/1049 721/739/721 720/738/720 f 717/734/717 1050/1084/1050 1039/1073/1039 f 717/734/717 1039/1073/1039 718/735/718 f 889/909/889 760/781/760 763/780/763 f 889/909/889 763/780/763 1051/1085/1051 f 974/1002/974 1052/1086/1052 1053/1087/1053 f 974/1002/974 1053/1087/1053 975/1003/975 f 1053/1087/1053 1054/1088/1054 1042/1075/1042 f 1053/1087/1053 1042/1075/1042 1041/1074/1041 f 1056/1089/1056 1057/1090/1057 1058/1091/1058 f 1056/1089/1056 1058/1091/1058 1055/1092/1055 f 1055/1092/1055 1058/1091/1058 1010/1039/1010 f 1055/1092/1055 1010/1039/1010 1009/1038/1009 f 825/845/825 1059/1093/1059 1060/1094/1060 f 825/845/825 1060/1094/1060 824/846/824 f 1060/1094/1060 1059/1093/1059 1062/1095/1062 f 1060/1094/1060 1062/1095/1062 1061/1096/1061 f 444/1097/444 443/1098/443 1064/1099/1064 f 444/1097/444 1064/1099/1064 1063/1100/1063 f 955/981/955 829/850/829 830/852/830 f 955/981/955 830/852/830 956/978/956 f 855/879/855 845/866/845 987/1015/987 f 855/879/855 987/1015/987 980/1009/980 f 858/878/858 869/889/869 823/843/823 f 858/878/858 823/843/823 822/842/822 f 1066/1101/1066 1067/1102/1067 1068/1103/1068 f 1066/1101/1066 1068/1103/1068 1065/1104/1065 f 1043/1076/1043 1067/1102/1067 1069/1105/1069 f 1043/1076/1043 1069/1105/1069 1046/1080/1046 f 724/741/724 723/740/723 1046/1080/1046 f 724/741/724 1046/1080/1046 1069/1105/1069 f 725/742/725 710/727/710 709/726/709 f 725/742/725 709/726/709 740/759/740 f 923/945/923 922/944/922 730/751/730 f 923/945/923 730/751/730 733/750/733 f 742/761/742 1026/1056/1026 854/875/854 f 742/761/742 854/875/854 735/752/735 f 878/901/878 884/904/884 1048/1082/1048 f 878/901/878 1048/1082/1048 1070/1106/1070 f 839/859/839 1070/1106/1070 841/862/841 f 839/859/839 841/862/841 840/860/840 f 878/901/878 1070/1106/1070 839/859/839 f 878/901/878 839/859/839 879/899/879 f 728/745/728 853/874/853 983/1011/983 f 728/745/728 983/1011/983 729/746/729 f 923/945/923 733/750/733 743/760/743 f 923/945/923 743/760/743 914/936/914 f 1049/1083/1049 453/443/453 416/408/416 f 1049/1083/1049 416/408/416 1038/1072/1038 f 969/994/969 934/956/934 931/953/931 f 969/994/969 931/953/931 930/952/930 f 706/723/706 1071/1107/1071 1072/1108/1072 f 706/723/706 1072/1108/1072 707/724/707 f 856/876/856 981/1008/981 1074/1109/1074 f 856/876/856 1074/1109/1074 1073/1110/1073 f 732/749/732 731/748/731 985/1013/985 f 732/749/732 985/1013/985 984/1012/984 f 789/809/789 940/963/940 1004/1033/1004 f 789/809/789 1004/1033/1004 787/810/787 f 1027/1057/1027 941/964/941 940/963/940 f 1027/1057/1027 940/963/940 789/809/789 f 1075/1111/1075 1076/1112/1076 900/920/900 f 1075/1111/1075 900/920/900 899/919/899 f 228/210/228 866/886/866 898/922/898 f 228/210/228 898/922/898 264/246/264 f 900/920/900 1076/1112/1076 1077/1113/1077 f 900/920/900 1077/1113/1077 902/923/902 f 1077/1113/1077 694/1114/694 677/925/677 f 1077/1113/1077 677/925/677 902/923/902 f 263/247/263 901/921/901 903/924/903 f 263/247/263 903/924/903 265/249/265 f 461/1115/461 886/906/886 836/856/836 f 461/1115/461 836/856/836 462/1116/462 f 871/891/871 870/890/870 1078/1117/1078 f 871/891/871 1078/1117/1078 948/972/948 f 1080/1118/1080 1081/1119/1081 1032/1065/1032 f 1080/1118/1080 1032/1065/1032 1079/1120/1079 f 737/754/737 736/757/736 1012/1043/1012 f 737/754/737 1012/1043/1012 1014/1044/1014 f 875/895/875 874/898/874 977/1004/977 f 875/895/875 977/1004/977 990/1019/990 f 877/897/877 1082/1121/1082 992/1020/992 f 877/897/877 992/1020/992 874/898/874 f 969/994/969 930/952/930 719/736/719 f 969/994/969 719/736/719 966/995/966 f 969/994/969 968/993/968 935/957/935 f 969/994/969 935/957/935 934/956/934 f 1084/1122/1084 1037/1071/1037 1085/1123/1085 f 1084/1122/1084 1085/1123/1085 1083/1124/1083 f 978/1005/978 992/1020/992 1087/1125/1087 f 978/1005/978 1087/1125/1087 1086/1126/1086 f 1086/1126/1086 1088/1127/1088 979/1006/979 f 1086/1126/1086 979/1006/979 978/1005/978 f 1080/1118/1080 1090/1128/1090 1091/1129/1091 f 1080/1118/1080 1091/1129/1091 1089/1130/1089 f 1013/1042/1013 1092/1131/1092 1093/1132/1093 f 1013/1042/1013 1093/1132/1093 756/775/756 f 1035/1069/1035 1034/1067/1034 1033/1068/1033 f 1035/1069/1035 1033/1068/1033 1094/1133/1094 f 921/947/921 1094/1133/1094 1033/1068/1033 f 921/947/921 1033/1068/1033 922/944/922 f 730/751/730 738/755/738 737/754/737 f 730/751/730 737/754/737 731/748/731 f 1014/1044/1014 753/770/753 762/779/762 f 1014/1044/1014 762/779/762 985/1013/985 f 876/896/876 875/895/875 987/1015/987 f 876/896/876 987/1015/987 986/1014/986 f 928/954/928 808/832/808 826/849/826 f 928/954/928 826/849/826 929/951/929 f 1039/1073/1039 1038/1072/1038 967/992/967 f 1039/1073/1039 967/992/967 966/995/966 f 698/715/698 828/848/828 772/793/772 f 698/715/698 772/793/772 699/716/699 f 676/1032/676 939/961/939 964/989/964 f 676/1032/676 964/989/964 673/1061/673 f 1000/1027/1000 810/830/810 809/829/809 f 1000/1027/1000 809/829/809 1001/1028/1001 f 898/922/898 866/886/866 865/888/865 f 898/922/898 865/888/865 899/919/899 f 899/919/899 865/888/865 1095/1134/1095 f 899/919/899 1095/1134/1095 1075/1111/1075 f 857/877/857 870/890/870 869/889/869 f 857/877/857 869/889/869 858/878/858 f 948/972/948 1078/1117/1078 946/969/946 f 948/972/948 946/969/946 1096/1135/1096 f 819/839/819 823/843/823 815/835/815 f 819/839/819 815/835/815 814/838/814 f 911/935/911 1097/1136/1097 818/841/818 f 911/935/911 818/841/818 847/867/847 f 815/835/815 823/843/823 869/889/869 f 815/835/815 869/889/869 868/892/868 f 887/908/887 748/767/748 758/777/758 f 887/908/887 758/777/758 888/910/888 f 761/778/761 760/781/760 758/777/758 f 761/778/761 758/777/758 759/776/759 f 853/874/853 746/763/746 745/762/745 f 853/874/853 745/762/745 983/1011/983 f 1051/1085/1051 988/1017/988 876/896/876 f 1051/1085/1051 876/896/876 986/1014/986 f 877/897/877 876/896/876 988/1017/988 f 877/897/877 988/1017/988 989/1016/989 f 989/1016/989 1015/1045/1015 1082/1121/1082 f 989/1016/989 1082/1121/1082 877/897/877 f 726/747/726 729/746/729 1098/1137/1098 f 726/747/726 1098/1137/1098 918/940/918 f 1100/1138/1100 1101/1139/1101 1102/1140/1102 f 1100/1138/1100 1102/1140/1102 1099/1141/1099 f 1103/1142/1103 488/480/488 294/277/294 f 1103/1142/1103 294/277/294 715/732/715 f 1104/1143/1104 1105/1144/1105 1072/1108/1072 f 1104/1143/1104 1072/1108/1072 1071/1107/1071 f 801/821/801 800/824/800 1002/1029/1002 f 801/821/801 1002/1029/1002 1001/1028/1001 f 1104/1143/1104 1106/1145/1106 958/980/958 f 1104/1143/1104 958/980/958 957/979/957 f 1104/1143/1104 957/979/957 1107/1146/1107 f 1104/1143/1104 1107/1146/1107 1105/1144/1105 f 1056/1089/1056 1108/1147/1108 1064/1099/1064 f 1056/1089/1056 1064/1099/1064 1057/1090/1057 f 495/1148/495 1010/1039/1010 1058/1091/1058 f 495/1148/495 1058/1091/1058 496/1149/496 f 496/1149/496 1058/1091/1058 1057/1090/1057 f 496/1149/496 1057/1090/1057 497/1150/497 f 962/986/962 1052/1086/1052 498/1151/498 f 962/986/962 498/1151/498 330/987/330 f 499/1152/499 498/1151/498 1052/1086/1052 f 499/1152/499 1052/1086/1052 974/1002/974 f 1010/1039/1010 495/1148/495 500/1153/500 f 1010/1039/1010 500/1153/500 1011/1040/1011 f 1109/1154/1109 1054/1088/1054 962/986/962 f 1109/1154/1109 962/986/962 961/985/961 f 499/1152/499 974/1002/974 973/1001/973 f 499/1152/499 973/1001/973 344/1000/344 f 1106/1145/1106 1104/1143/1104 1071/1107/1071 f 1106/1145/1106 1071/1107/1071 1110/1155/1110 f 1071/1107/1071 706/723/706 1102/1140/1102 f 1071/1107/1071 1102/1140/1102 1110/1155/1110 f 1099/1141/1099 1102/1140/1102 706/723/706 f 1099/1141/1099 706/723/706 705/722/705 f 705/722/705 1008/1041/1008 1111/1156/1111 f 705/722/705 1111/1156/1111 1099/1141/1099 f 1011/1040/1011 500/1153/500 505/1157/505 f 1011/1040/1011 505/1157/505 1112/1158/1112 f 1067/1102/1067 1043/1076/1043 1042/1075/1042 f 1067/1102/1067 1042/1075/1042 1068/1103/1068 f 329/984/329 444/1097/444 1063/1100/1063 f 329/984/329 1063/1100/1063 961/985/961 f 1068/1103/1068 1109/1154/1109 1113/1159/1113 f 1068/1103/1068 1113/1159/1113 1065/1104/1065 f 1115/1160/1115 724/741/724 1069/1105/1069 f 1115/1160/1115 1069/1105/1069 1114/1161/1114 f 744/765/744 843/864/843 848/871/848 f 744/765/744 848/871/848 751/768/751 f 509/500/509 850/870/850 849/869/849 f 509/500/509 849/869/849 208/189/208 f 849/869/849 843/864/843 842/863/842 f 849/869/849 842/863/842 851/872/851 f 462/1116/462 836/856/836 835/855/835 f 462/1116/462 835/855/835 510/501/510 f 850/870/850 509/500/509 510/501/510 f 850/870/850 510/501/510 835/855/835 f 795/815/795 960/983/960 971/998/971 f 795/815/795 971/998/971 951/974/951 f 960/983/960 1116/1162/1116 972/997/972 f 960/983/960 972/997/972 971/998/971 f 768/789/768 780/798/780 972/997/972 f 768/789/768 972/997/972 1116/1162/1116 f 716/737/716 929/951/929 826/849/826 f 716/737/716 826/849/826 698/715/698 f 801/821/801 1001/1028/1001 809/829/809 f 801/821/801 809/829/809 1016/1046/1016 f 800/824/800 813/834/813 938/960/938 f 800/824/800 938/960/938 1002/1029/1002 f 813/834/813 964/989/964 939/961/939 f 813/834/813 939/961/939 938/960/938 f 1117/1163/1117 921/947/921 924/946/924 f 1117/1163/1117 924/946/924 954/976/954 f 1094/1133/1094 1118/1164/1118 1119/1165/1119 f 1094/1133/1094 1119/1165/1119 1035/1069/1035 f 1035/1069/1035 1119/1165/1119 1089/1130/1089 f 1035/1069/1035 1089/1130/1089 1036/1070/1036 f 1118/1164/1118 1094/1133/1094 921/947/921 f 1118/1164/1118 921/947/921 1117/1163/1117 f 838/858/838 837/861/837 982/1010/982 f 838/858/838 982/1010/982 750/769/750 f 963/988/963 838/858/838 750/769/750 f 963/988/963 750/769/750 751/768/751 f 729/746/729 983/1011/983 982/1010/982 f 729/746/729 982/1010/982 1098/1137/1098 f 732/749/732 742/761/742 743/760/743 f 732/749/732 743/760/743 733/750/733 f 732/749/732 984/1012/984 1026/1056/1026 f 732/749/732 1026/1056/1026 742/761/742 f 984/1012/984 761/778/761 759/776/759 f 984/1012/984 759/776/759 1026/1056/1026 f 790/811/790 806/826/806 783/801/783 f 790/811/790 783/801/783 782/800/782 f 931/953/931 934/956/934 933/955/933 f 931/953/931 933/955/933 995/1022/995 f 931/953/931 995/1022/995 1016/1046/1016 f 931/953/931 1016/1046/1016 928/954/928 f 996/1024/996 827/847/827 811/831/811 f 996/1024/996 811/831/811 791/812/791 f 1121/1166/1121 861/881/861 864/885/864 f 1121/1166/1121 864/885/864 1120/1167/1120 f 896/917/896 1122/1168/1122 860/880/860 f 896/917/896 860/880/860 859/883/859 f 1024/1053/1024 1023/1052/1023 1025/1055/1025 f 1024/1053/1024 1025/1055/1025 993/1021/993 f 1024/1053/1024 860/880/860 1122/1168/1122 f 1024/1053/1024 1122/1168/1122 1021/1054/1021 f 1124/1169/1124 887/908/887 888/910/888 f 1124/1169/1124 888/910/888 1123/1170/1123 f 951/974/951 971/998/971 798/818/798 f 951/974/951 798/818/798 797/817/797 f 1050/1084/1050 1049/1083/1049 1038/1072/1038 f 1050/1084/1050 1038/1072/1038 1039/1073/1039 f 680/1063/680 1028/1058/1028 404/389/404 f 680/1063/680 404/389/404 46/511/46 f 1028/1058/1028 944/966/944 943/965/943 f 1028/1058/1028 943/965/943 1029/1059/1029 f 1018/1049/1018 932/958/932 521/513/521 f 1018/1049/1018 521/513/521 520/512/520 f 522/514/522 1019/1048/1019 1018/1049/1018 f 522/514/522 1018/1049/1018 520/512/520 f 935/957/935 523/515/523 521/513/521 f 935/957/935 521/513/521 932/958/932 f 935/957/935 968/993/968 524/516/524 f 935/957/935 524/516/524 523/515/523 f 953/977/953 792/816/792 952/975/952 f 953/977/953 952/975/952 1073/1110/1073 f 1073/1110/1073 1074/1109/1074 1125/1171/1125 f 1073/1110/1073 1125/1171/1125 953/977/953 f 1032/1065/1032 1081/1119/1081 1126/1172/1126 f 1032/1065/1032 1126/1172/1126 1031/1066/1031 f 1032/1065/1032 976/1007/976 979/1006/979 f 1032/1065/1032 979/1006/979 1079/1120/1079 f 1073/1110/1073 1127/1173/1127 857/877/857 f 1073/1110/1073 857/877/857 856/876/856 f 857/877/857 1127/1173/1127 1078/1117/1078 f 857/877/857 1078/1117/1078 870/890/870 f 407/397/407 276/258/276 905/928/905 f 407/397/407 905/928/905 1007/1037/1007 f 1006/1036/1006 897/918/897 1030/1064/1030 f 1006/1036/1006 1030/1064/1030 1007/1037/1007 f 822/842/822 845/866/845 855/879/855 f 822/842/822 855/879/855 858/878/858 f 1014/1044/1014 985/1013/985 731/748/731 f 1014/1044/1014 731/748/731 737/754/737 f 1031/1066/1031 1074/1109/1074 981/1008/981 f 1031/1066/1031 981/1008/981 991/1018/991 f 730/751/730 922/944/922 1033/1068/1033 f 730/751/730 1033/1068/1033 738/755/738 f 990/1019/990 980/1009/980 987/1015/987 f 990/1019/990 987/1015/987 875/895/875 f 763/780/763 752/773/752 988/1017/988 f 763/780/763 988/1017/988 1051/1085/1051 f 763/780/763 762/779/762 753/770/753 f 763/780/763 753/770/753 752/773/752 f 980/1009/980 990/1019/990 991/1018/991 f 980/1009/980 991/1018/991 981/1008/981 f 1118/1164/1118 1126/1172/1126 1081/1119/1081 f 1118/1164/1118 1081/1119/1081 1119/1165/1119 f 1126/1172/1126 1125/1171/1125 1074/1109/1074 f 1126/1172/1126 1074/1109/1074 1031/1066/1031 f 1119/1165/1119 1081/1119/1081 1080/1118/1080 f 1119/1165/1119 1080/1118/1080 1089/1130/1089 f 986/1014/986 844/865/844 889/909/889 f 986/1014/986 889/909/889 1051/1085/1051 f 821/844/821 819/839/819 818/841/818 f 821/844/821 818/841/818 1097/1136/1097 f 1022/1051/1022 764/785/764 894/914/894 f 1022/1051/1022 894/914/894 1023/1052/1023 f 1023/1052/1023 894/914/894 893/913/893 f 1023/1052/1023 893/913/893 1025/1055/1025 f 926/950/926 920/942/920 727/744/727 f 926/950/926 727/744/727 726/747/726 f 919/943/919 920/942/920 926/950/926 f 919/943/919 926/950/926 927/949/927 f 1128/1174/1128 1116/1162/1116 960/983/960 f 1128/1174/1128 960/983/960 959/982/959 f 773/790/773 702/719/702 799/820/799 f 773/790/773 799/820/799 774/791/774 f 799/820/799 972/997/972 780/798/780 f 799/820/799 780/798/780 774/791/774 f 772/793/772 828/848/828 970/996/970 f 772/793/772 970/996/970 773/790/773 f 703/720/703 970/996/970 996/1024/996 f 703/720/703 996/1024/996 782/800/782 f 771/788/771 781/799/781 780/798/780 f 771/788/771 780/798/780 768/789/768 f 791/812/791 790/811/790 782/800/782 f 791/812/791 782/800/782 996/1024/996 f 811/831/811 810/830/810 779/796/779 f 811/831/811 779/796/779 791/812/791 f 1027/1057/1027 789/809/789 777/794/777 f 1027/1057/1027 777/794/777 776/797/776 f 927/949/927 925/948/925 769/786/769 f 927/949/927 769/786/769 1128/1174/1128 f 710/727/710 725/742/725 724/741/724 f 710/727/710 724/741/724 1115/1160/1115 f 954/976/954 953/977/953 1125/1171/1125 f 954/976/954 1125/1171/1125 1117/1163/1117 f 1117/1163/1117 1125/1171/1125 1126/1172/1126 f 1117/1163/1117 1126/1172/1126 1118/1164/1118 f 768/789/768 1116/1162/1116 1128/1174/1128 f 768/789/768 1128/1174/1128 769/786/769 f 904/927/904 867/887/867 229/209/229 f 904/927/904 229/209/229 529/521/529 f 948/972/948 1096/1135/1096 998/1025/998 f 948/972/948 998/1025/998 949/971/949 f 1120/1167/1120 864/885/864 873/893/873 f 1120/1167/1120 873/893/873 949/971/949 f 1121/1166/1121 1120/1167/1120 997/1026/997 f 1121/1166/1121 997/1026/997 1129/1175/1129 f 1129/1175/1129 1095/1134/1095 865/888/865 f 1129/1175/1129 865/888/865 1121/1166/1121 f 861/881/861 1121/1166/1121 865/888/865 f 861/881/861 865/888/865 862/882/862 f 1075/1111/1075 890/911/890 1003/1034/1003 f 1075/1111/1075 1003/1034/1003 1076/1112/1076 f 1076/1112/1076 1003/1034/1003 965/991/965 f 1076/1112/1076 965/991/965 1077/1113/1077 f 965/991/965 695/990/695 694/1114/694 f 965/991/965 694/1114/694 1077/1113/1077 f 1075/1111/1075 1095/1134/1095 891/912/891 f 1075/1111/1075 891/912/891 890/911/890 f 895/915/895 894/914/894 764/785/764 f 895/915/895 764/785/764 767/784/767 f 1020/1050/1020 820/840/820 814/838/814 f 1020/1050/1020 814/838/814 817/837/817 f 1123/1170/1123 844/865/844 821/844/821 f 1123/1170/1123 821/844/821 1097/1136/1097 f 1124/1169/1124 1123/1170/1123 1097/1136/1097 f 1124/1169/1124 1097/1136/1097 911/935/911 f 1130/1176/1130 1124/1169/1124 911/935/911 f 1130/1176/1130 911/935/911 912/934/912 f 532/524/532 1130/1176/1130 912/934/912 f 532/524/532 912/934/912 390/376/390 f 973/1001/973 882/902/882 881/905/881 f 973/1001/973 881/905/881 885/907/885 f 833/857/833 836/856/836 886/906/886 f 833/857/833 886/906/886 880/900/880 f 834/854/834 833/857/833 879/899/879 f 834/854/834 879/899/879 963/988/963 f 1067/1102/1067 1066/1101/1066 1114/1161/1114 f 1067/1102/1067 1114/1161/1114 1069/1105/1069 f 809/829/809 808/832/808 928/954/928 f 809/829/809 928/954/928 1016/1046/1016 f 1019/1048/1019 522/514/522 405/390/405 f 1019/1048/1019 405/390/405 1029/1059/1029 f 1131/1177/1131 1085/1123/1085 1037/1071/1037 f 1131/1177/1131 1037/1071/1037 1036/1070/1036 f 1132/1178/1132 1103/1142/1103 715/732/715 f 1132/1178/1132 715/732/715 714/731/714 f 1110/1155/1110 1102/1140/1102 1101/1139/1101 f 1110/1155/1110 1101/1139/1101 1133/1179/1133 f 1111/1156/1111 1112/1158/1112 1135/1180/1135 f 1111/1156/1111 1135/1180/1135 1134/1181/1134 f 1106/1145/1106 1110/1155/1110 1133/1179/1133 f 1106/1145/1106 1133/1179/1133 1136/1182/1136 f 1106/1145/1106 714/731/714 713/730/713 f 1106/1145/1106 713/730/713 958/980/958 f 1112/1158/1112 505/1157/505 539/1183/539 f 1112/1158/1112 539/1183/539 1135/1180/1135 f 883/903/883 882/902/882 975/1003/975 f 883/903/883 975/1003/975 1044/1079/1044 f 704/725/704 1009/1038/1009 1008/1041/1008 f 704/725/704 1008/1041/1008 705/722/705 f 1052/1086/1052 962/986/962 1054/1088/1054 f 1052/1086/1052 1054/1088/1054 1053/1087/1053 f 1055/1092/1055 824/846/824 1060/1094/1060 f 1055/1092/1055 1060/1094/1060 1056/1089/1056 f 1009/1038/1009 704/725/704 824/846/824 f 1009/1038/1009 824/846/824 1055/1092/1055 f 1065/1104/1065 1113/1159/1113 1108/1147/1108 f 1065/1104/1065 1108/1147/1108 1061/1096/1061 f 1068/1103/1068 1042/1075/1042 1054/1088/1054 f 1068/1103/1068 1054/1088/1054 1109/1154/1109 f 1008/1041/1008 1011/1040/1011 1112/1158/1112 f 1008/1041/1008 1112/1158/1112 1111/1156/1111 f 1109/1154/1109 961/985/961 1063/1100/1063 f 1109/1154/1109 1063/1100/1063 1113/1159/1113 f 1134/1181/1134 1100/1138/1100 1099/1141/1099 f 1134/1181/1134 1099/1141/1099 1111/1156/1111 f 947/970/947 952/975/952 951/974/951 f 947/970/947 951/974/951 797/817/797 f 959/982/959 794/814/794 916/938/916 f 959/982/959 916/938/916 919/943/919 f 1098/1137/1098 982/1010/982 837/861/837 f 1098/1137/1098 837/861/837 741/758/741 f 1098/1137/1098 741/758/741 740/759/740 f 1098/1137/1098 740/759/740 918/940/918 f 1040/1077/1040 1047/1081/1047 1048/1082/1048 f 1040/1077/1040 1048/1082/1048 1045/1078/1045 f 1041/1074/1041 1044/1079/1044 975/1003/975 f 1041/1074/1041 975/1003/975 1053/1087/1053 f 1078/1117/1078 1127/1173/1127 947/970/947 f 1078/1117/1078 947/970/947 946/969/946 f 949/971/949 998/1025/998 997/1026/997 f 949/971/949 997/1026/997 1120/1167/1120 f 946/969/946 796/819/796 945/968/945 f 946/969/946 945/968/945 1096/1135/1096 f 998/1025/998 1096/1135/1096 945/968/945 f 998/1025/998 945/968/945 950/973/950 f 997/1026/997 805/825/805 804/828/804 f 997/1026/997 804/828/804 1129/1175/1129 f 1095/1134/1095 1129/1175/1129 804/828/804 f 1095/1134/1095 804/828/804 891/912/891 f 904/927/904 529/521/529 408/398/408 f 904/927/904 408/398/408 1030/1064/1030 f 1024/1053/1024 993/1021/993 863/884/863 f 1024/1053/1024 863/884/863 860/880/860 f 1138/1184/1138 1139/1185/1139 1140/1186/1140 f 1138/1184/1138 1140/1186/1140 1137/1187/1137 f 1141/1188/1141 1142/1189/1142 1137/1187/1137 f 1141/1188/1141 1137/1187/1137 1140/1186/1140 f 1143/1190/1143 1144/1191/1144 1142/1189/1142 f 1143/1190/1143 1142/1189/1142 1141/1188/1141 f 1145/1192/1145 1146/1193/1146 1144/1191/1144 f 1145/1192/1145 1144/1191/1144 1143/1190/1143 f 1147/1194/1147 1148/1195/1148 1146/1193/1146 f 1147/1194/1147 1146/1193/1146 1145/1192/1145 f 1149/1196/1149 1150/1197/1150 1148/1195/1148 f 1149/1196/1149 1148/1195/1148 1147/1194/1147 f 1151/1198/1151 1152/1199/1152 1150/1197/1150 f 1151/1198/1151 1150/1197/1150 1149/1196/1149 f 1154/1200/1154 1155/1201/1155 1156/1202/1156 f 1154/1200/1154 1156/1202/1156 1153/1203/1153 f 1157/1204/1157 1158/1205/1158 1155/1201/1155 f 1157/1204/1157 1155/1201/1155 1154/1200/1154 f 1159/1206/1159 1160/1207/1160 1142/1189/1142 f 1159/1206/1159 1142/1189/1142 1144/1191/1144 f 1161/1208/1161 1159/1206/1159 1144/1191/1144 f 1161/1208/1161 1144/1191/1144 1146/1193/1146 f 1162/1209/1162 1161/1208/1161 1146/1193/1146 f 1162/1209/1162 1146/1193/1146 1148/1195/1148 f 1163/1210/1163 1162/1209/1162 1148/1195/1148 f 1163/1210/1163 1148/1195/1148 1150/1197/1150 f 1150/1197/1150 1152/1199/1152 1164/1211/1164 f 1150/1197/1150 1164/1211/1164 1163/1210/1163 f 1156/1202/1156 1155/1201/1155 1166/1212/1166 f 1156/1202/1156 1166/1212/1166 1165/1213/1165 f 1167/1214/1167 1166/1212/1166 1155/1201/1155 f 1167/1214/1167 1155/1201/1155 1158/1205/1158 f 1169/1215/1169 1167/1214/1167 1158/1205/1158 f 1169/1215/1169 1158/1205/1158 1168/1216/1168 f 1170/1217/1170 1171/1218/1171 1172/1219/1172 f 1170/1217/1170 1172/1219/1172 1139/1185/1139 f 1173/1220/1173 1174/1221/1174 1141/1188/1141 f 1173/1220/1173 1141/1188/1141 1140/1186/1140 f 1141/1188/1141 1174/1221/1174 1175/1222/1175 f 1141/1188/1141 1175/1222/1175 1143/1190/1143 f 1176/1223/1176 1145/1192/1145 1143/1190/1143 f 1176/1223/1176 1143/1190/1143 1175/1222/1175 f 1177/1224/1177 1149/1196/1149 1147/1194/1147 f 1177/1224/1177 1147/1194/1147 1176/1223/1176 f 1177/1224/1177 1178/1225/1178 1151/1198/1151 f 1177/1224/1177 1151/1198/1151 1149/1196/1149 f 1153/1203/1153 1179/1226/1179 1180/1227/1180 f 1153/1203/1153 1180/1227/1180 1154/1200/1154 f 1157/1204/1157 1154/1200/1154 1180/1227/1180 f 1157/1204/1157 1180/1227/1180 1181/1228/1181 f 1157/1204/1157 1181/1228/1181 1182/1229/1182 f 1157/1204/1157 1182/1229/1182 1168/1216/1168 f 1169/1215/1169 1168/1216/1168 1182/1229/1182 f 1169/1215/1169 1182/1229/1182 1183/1230/1183 f 1142/1189/1142 1160/1207/1160 1138/1184/1138 f 1142/1189/1142 1138/1184/1138 1137/1187/1137 f 1170/1217/1170 1185/1231/1185 1186/1232/1186 f 1170/1217/1170 1186/1232/1186 1184/1233/1184 f 1170/1217/1170 1184/1233/1184 1187/1234/1187 f 1170/1217/1170 1187/1234/1187 1171/1218/1171 f 1187/1234/1187 1188/1235/1188 1172/1219/1172 f 1187/1234/1187 1172/1219/1172 1171/1218/1171 f 1172/1219/1172 1188/1235/1188 1140/1186/1140 f 1172/1219/1172 1140/1186/1140 1139/1185/1139 f 1161/1208/1161 1162/1209/1162 1163/1210/1163 f 1161/1208/1161 1163/1210/1163 1189/1236/1189 f 1189/1236/1189 1163/1210/1163 1164/1211/1164 f 1189/1236/1189 1164/1211/1164 1190/1237/1190 f 1165/1213/1165 1164/1211/1164 1152/1199/1152 f 1165/1213/1165 1152/1199/1152 1156/1202/1156 f 1152/1199/1152 1151/1198/1151 1153/1203/1153 f 1152/1199/1152 1153/1203/1153 1156/1202/1156 f 1179/1226/1179 1153/1203/1153 1151/1198/1151 f 1179/1226/1179 1151/1198/1151 1178/1225/1178 f 1189/1236/1189 1160/1207/1160 1159/1206/1159 f 1189/1236/1189 1159/1206/1159 1161/1208/1161 f 1186/1232/1186 1190/1237/1190 1164/1211/1164 f 1186/1232/1186 1164/1211/1164 1165/1213/1165 f 1139/1185/1139 1138/1184/1138 1185/1231/1185 f 1139/1185/1139 1185/1231/1185 1170/1217/1170 f 1169/1215/1169 1188/1235/1188 1187/1234/1187 f 1169/1215/1169 1187/1234/1187 1167/1214/1167 f 1186/1232/1186 1165/1213/1165 1166/1212/1166 f 1186/1232/1186 1166/1212/1166 1184/1233/1184 f 1140/1186/1140 1188/1235/1188 1191/1238/1191 f 1140/1186/1140 1191/1238/1191 1173/1220/1173 f 1191/1238/1191 1188/1235/1188 1169/1215/1169 f 1191/1238/1191 1169/1215/1169 1183/1230/1183 f 1192/1239/1192 1193/1240/1193 1179/1226/1179 f 1192/1239/1192 1179/1226/1179 1178/1225/1178 f 1192/1239/1192 1178/1225/1178 1177/1224/1177 f 1192/1239/1192 1177/1224/1177 1194/1241/1194 f 1180/1227/1180 1193/1240/1193 1072/1108/1072 f 1180/1227/1180 1072/1108/1072 1105/1144/1105 f 1180/1227/1180 1105/1144/1105 1107/1146/1107 f 1180/1227/1180 1107/1146/1107 1181/1228/1181 f 1194/1241/1194 1177/1224/1177 1176/1223/1176 f 1194/1241/1194 1176/1223/1176 1114/1161/1114 f 1062/1095/1062 1194/1241/1194 1114/1161/1114 f 1062/1095/1062 1114/1161/1114 1066/1101/1066 f 707/724/707 1072/1108/1072 1193/1240/1193 f 707/724/707 1193/1240/1193 825/845/825 f 825/845/825 1193/1240/1193 1192/1239/1192 f 825/845/825 1192/1239/1192 1059/1093/1059 f 1173/1220/1173 1191/1238/1191 832/853/832 f 1173/1220/1173 832/853/832 711/728/711 f 1183/1230/1183 1182/1229/1182 1005/1035/1005 f 1183/1230/1183 1005/1035/1005 831/851/831 f 1187/1234/1187 1184/1233/1184 1166/1212/1166 f 1187/1234/1187 1166/1212/1166 1167/1214/1167 f 710/727/710 1115/1160/1115 1175/1222/1175 f 710/727/710 1175/1222/1175 1174/1221/1174 f 1182/1229/1182 1181/1228/1181 1107/1146/1107 f 1182/1229/1182 1107/1146/1107 1005/1035/1005 f 453/443/453 1049/1083/1049 720/738/720 f 453/443/453 720/738/720 598/590/598 f 1123/1170/1123 888/910/888 889/909/889 f 1123/1170/1123 889/909/889 844/865/844 f 916/938/916 794/814/794 793/813/793 f 916/938/916 793/813/793 913/939/913 f 711/728/711 832/853/832 770/787/770 f 711/728/711 770/787/770 708/729/708 f 919/943/919 927/949/927 1128/1174/1128 f 919/943/919 1128/1174/1128 959/982/959 f 925/948/925 708/729/708 770/787/770 f 925/948/925 770/787/770 769/786/769 f 913/939/913 793/813/793 954/976/954 f 913/939/913 954/976/954 924/946/924 f 831/851/831 832/853/832 1191/1238/1191 f 831/851/831 1191/1238/1191 1183/1230/1183 f 895/915/895 767/784/767 766/783/766 f 895/915/895 766/783/766 1006/1036/1006 f 891/912/891 804/828/804 807/827/807 f 891/912/891 807/827/807 788/808/788 f 778/795/778 777/794/777 788/808/788 f 778/795/778 788/808/788 807/827/807 f 810/830/810 1000/1027/1000 776/797/776 f 810/830/810 776/797/776 779/796/779 f 947/970/947 1127/1173/1127 1073/1110/1073 f 947/970/947 1073/1110/1073 952/975/952 f 1106/1145/1106 1136/1182/1136 1132/1178/1132 f 1106/1145/1106 1132/1178/1132 714/731/714 f 1061/1096/1061 1062/1095/1062 1066/1101/1066 f 1061/1096/1061 1066/1101/1066 1065/1104/1065 f 443/1098/443 497/1150/497 1057/1090/1057 f 443/1098/443 1057/1090/1057 1064/1099/1064 f 1064/1099/1064 1108/1147/1108 1113/1159/1113 f 1064/1099/1064 1113/1159/1113 1063/1100/1063 f 1061/1096/1061 1108/1147/1108 1056/1089/1056 f 1061/1096/1061 1056/1089/1056 1060/1094/1060 f 1192/1239/1192 1194/1241/1194 1062/1095/1062 f 1192/1239/1192 1062/1095/1062 1059/1093/1059 f 1173/1220/1173 711/728/711 710/727/710 f 1173/1220/1173 710/727/710 1174/1221/1174 f 880/900/880 881/905/881 884/904/884 f 880/900/880 884/904/884 878/901/878 f 841/862/841 1047/1081/1047 1046/1080/1046 f 841/862/841 1046/1080/1046 723/740/723 f 1070/1106/1070 1048/1082/1048 1047/1081/1047 f 1070/1106/1070 1047/1081/1047 841/862/841 f 461/1115/461 342/999/342 885/907/885 f 461/1115/461 885/907/885 886/906/886 f 1114/1161/1114 1176/1223/1176 1175/1222/1175 f 1114/1161/1114 1175/1222/1175 1115/1160/1115 f 887/908/887 1124/1169/1124 1130/1176/1130 f 887/908/887 1130/1176/1130 852/873/852 f 206/186/206 852/873/852 1130/1176/1130 f 206/186/206 1130/1176/1130 532/524/532 f 681/698/681 599/592/599 1195/1242/1195 f 681/698/681 1195/1242/1195 682/699/682 f 1196/1243/1196 674/691/674 684/702/684 f 1196/1243/1196 684/702/684 1195/1242/1195 f 1197/1244/1197 675/692/675 674/691/674 f 1197/1244/1197 674/691/674 1196/1243/1196 f 689/706/689 690/708/690 675/692/675 f 689/706/689 675/692/675 1197/1244/1197 f 693/710/693 1199/1245/1199 1200/1246/1200 f 693/710/693 1200/1246/1200 1198/1247/1198 f 686/707/686 689/706/689 1197/1244/1197 f 686/707/686 1197/1244/1197 1199/1245/1199 f 1196/1243/1196 1195/1242/1195 1202/1248/1202 f 1196/1243/1196 1202/1248/1202 1201/1249/1201 f 1084/1122/1084 1083/1124/1083 1204/1250/1204 f 1084/1122/1084 1204/1250/1204 1203/1251/1203 f 1092/1131/1092 1013/1042/1013 1203/1251/1203 f 1092/1131/1092 1203/1251/1203 1204/1250/1204 f 1206/1252/1206 1087/1253/1087 1207/1254/1207 f 1206/1252/1206 1207/1254/1207 1205/1255/1205 f 1206/1252/1206 1208/1256/1208 1086/1257/1086 f 1206/1252/1206 1086/1257/1086 1087/1253/1087 f 1091/1258/1091 1090/1259/1090 1210/1260/1210 f 1091/1258/1091 1210/1260/1210 1209/1261/1209 f 1093/1132/1093 1211/1262/1211 757/774/757 f 1093/1132/1093 757/774/757 756/775/756 f 1079/1120/1079 1212/1263/1212 1090/1128/1090 f 1079/1120/1079 1090/1128/1090 1080/1118/1080 f 1079/1120/1079 979/1006/979 1088/1127/1088 f 1079/1120/1079 1088/1127/1088 1212/1263/1212 f 1209/1261/1209 1213/1264/1213 1085/1265/1085 f 1209/1261/1209 1085/1265/1085 1131/1266/1131 f 1089/1130/1089 1091/1129/1091 1131/1177/1131 f 1089/1130/1089 1131/1177/1131 1036/1070/1036 f 1213/1264/1213 1214/1267/1214 1204/1268/1204 f 1213/1264/1213 1204/1268/1204 1083/1269/1083 f 1214/1267/1214 1215/1270/1215 1092/1271/1092 f 1214/1267/1214 1092/1271/1092 1204/1268/1204 f 1015/1045/1015 757/774/757 1211/1262/1211 f 1015/1045/1015 1211/1262/1211 1216/1272/1216 f 1211/1273/1211 1093/1274/1093 1215/1270/1215 f 1211/1273/1211 1215/1270/1215 1217/1275/1217 f 1088/1276/1088 1208/1256/1208 1210/1260/1210 f 1088/1276/1088 1210/1260/1210 1212/1277/1212 f 1216/1278/1216 1211/1273/1211 1217/1275/1217 f 1216/1278/1216 1217/1275/1217 1218/1279/1218 f 1219/1280/1219 1218/1279/1218 1205/1255/1205 f 1219/1280/1219 1205/1255/1205 1207/1254/1207 f 698/715/698 697/714/697 717/734/717 f 698/715/698 717/734/717 716/737/716 f 967/992/967 418/407/418 524/516/524 f 967/992/967 524/516/524 968/993/968 f 598/590/598 720/738/720 712/733/712 f 598/590/598 712/733/712 293/276/293 f 697/714/697 721/739/721 1050/1084/1050 f 697/714/697 1050/1084/1050 717/734/717 f 957/979/957 956/978/956 1005/1035/1005 f 957/979/957 1005/1035/1005 1107/1146/1107 f 1186/1232/1186 1185/1231/1185 1189/1236/1189 f 1186/1232/1186 1189/1236/1189 1190/1237/1190 f 1022/1051/1022 896/917/896 765/782/765 f 1022/1051/1022 765/782/765 764/785/764 f 1122/1168/1122 896/917/896 1022/1051/1022 f 1122/1168/1122 1022/1051/1022 1021/1054/1021 f 678/695/678 1198/1247/1198 625/631/625 f 678/695/678 625/631/625 27/8/27 f 1195/1242/1195 599/592/599 626/632/626 f 1195/1242/1195 626/632/626 1202/1248/1202 f 1202/1248/1202 626/632/626 628/634/628 f 1202/1248/1202 628/634/628 1220/1281/1220 f 1198/1247/1198 1220/1281/1220 628/634/628 f 1198/1247/1198 628/634/628 625/631/625 f 1222/1282/1222 1223/1283/1223 1224/1284/1224 f 1222/1282/1222 1224/1284/1224 1221/1285/1221 f 1226/1286/1226 1227/1287/1227 1228/1288/1228 f 1226/1286/1226 1228/1288/1228 1225/1289/1225 f 1230/1290/1230 1231/1291/1231 1232/1292/1232 f 1230/1290/1230 1232/1292/1232 1229/1293/1229 f 1234/1294/1234 1232/1292/1232 1231/1291/1231 f 1234/1294/1234 1231/1291/1231 1233/1295/1233 f 1236/1296/1236 1237/1297/1237 1238/1298/1238 f 1236/1296/1236 1238/1298/1238 1235/1299/1235 f 1221/1285/1221 1239/1300/1239 1240/1301/1240 f 1221/1285/1221 1240/1301/1240 1233/1295/1233 f 1242/1302/1242 1243/1303/1243 1244/1304/1244 f 1242/1302/1242 1244/1304/1244 1241/1305/1241 f 1237/1297/1237 1245/1306/1245 1246/1307/1246 f 1237/1297/1237 1246/1307/1246 1238/1298/1238 f 1246/1307/1246 1245/1306/1245 1242/1302/1242 f 1246/1307/1246 1242/1302/1242 1241/1305/1241 f 1248/1308/1248 1224/1284/1224 1249/1309/1249 f 1248/1308/1248 1249/1309/1249 1247/1310/1247 f 1249/1309/1249 1250/1311/1250 660/1312/660 f 1249/1309/1249 660/1312/660 659/1313/659 f 661/1314/661 1247/1310/1247 1249/1309/1249 f 661/1314/661 1249/1309/1249 659/1313/659 f 1221/1285/1221 1224/1284/1224 1248/1308/1248 f 1221/1285/1221 1248/1308/1248 1239/1300/1239 f 1231/1291/1231 1222/1282/1222 1221/1285/1221 f 1231/1291/1231 1221/1285/1221 1233/1295/1233 f 1232/1292/1232 1234/1294/1234 1243/1303/1243 f 1232/1292/1232 1243/1303/1243 1242/1302/1242 f 1244/1304/1244 1243/1303/1243 1234/1294/1234 f 1244/1304/1244 1234/1294/1234 1251/1315/1251 f 1240/1301/1240 1251/1315/1251 1234/1294/1234 f 1240/1301/1240 1234/1294/1234 1233/1295/1233 f 1253/1316/1253 1134/1181/1134 1135/1180/1135 f 1253/1316/1253 1135/1180/1135 1252/1317/1252 f 1254/1318/1254 1255/1319/1255 1229/1293/1229 f 1254/1318/1254 1229/1293/1229 1232/1292/1232 f 1254/1318/1254 1225/1289/1225 1228/1288/1228 f 1254/1318/1254 1228/1288/1228 1255/1319/1255 f 667/1320/667 1252/1317/1252 1135/1180/1135 f 667/1320/667 1135/1180/1135 539/1183/539 f 1226/1286/1226 1225/1289/1225 1237/1297/1237 f 1226/1286/1226 1237/1297/1237 1236/1296/1236 f 1245/1306/1245 1254/1318/1254 1232/1292/1232 f 1245/1306/1245 1232/1292/1232 1242/1302/1242 f 1254/1318/1254 1245/1306/1245 1237/1297/1237 f 1254/1318/1254 1237/1297/1237 1225/1289/1225 f 669/674/669 668/675/668 1226/1286/1226 f 669/674/669 1226/1286/1226 1236/1296/1236 f 1230/1290/1230 1256/1321/1256 1222/1282/1222 f 1230/1290/1230 1222/1282/1222 1231/1291/1231 f 1235/1299/1235 671/677/671 669/674/669 f 1235/1299/1235 669/674/669 1236/1296/1236 f 1230/1290/1230 1101/1139/1101 1100/1138/1100 f 1230/1290/1230 1100/1138/1100 1256/1321/1256 f 672/678/672 488/480/488 1103/1142/1103 f 672/678/672 1103/1142/1103 1227/1287/1227 f 1224/1284/1224 1223/1283/1223 1250/1311/1250 f 1224/1284/1224 1250/1311/1250 1249/1309/1249 f 1256/1321/1256 1100/1138/1100 1134/1181/1134 f 1256/1321/1256 1134/1181/1134 1253/1316/1253 f 1227/1287/1227 1103/1142/1103 1132/1178/1132 f 1227/1287/1227 1132/1178/1132 1228/1288/1228 f 1101/1139/1101 1230/1290/1230 1229/1293/1229 f 1101/1139/1101 1229/1293/1229 1133/1179/1133 f 1223/1283/1223 1253/1316/1253 1252/1317/1252 f 1223/1283/1223 1252/1317/1252 1250/1311/1250 f 1255/1319/1255 1136/1182/1136 1133/1179/1133 f 1255/1319/1255 1133/1179/1133 1229/1293/1229 f 1228/1288/1228 1132/1178/1132 1136/1182/1136 f 1228/1288/1228 1136/1182/1136 1255/1319/1255 f 660/1312/660 1250/1311/1250 1252/1317/1252 f 660/1312/660 1252/1317/1252 667/1320/667 f 668/675/668 672/678/672 1227/1287/1227 f 668/675/668 1227/1287/1227 1226/1286/1226 f 1222/1282/1222 1256/1321/1256 1253/1316/1253 f 1222/1282/1222 1253/1316/1253 1223/1283/1223 f 1/1322/1 12/1323/12 1247/1310/1247 f 1/1322/1 1247/1310/1247 661/1314/661 f 10/1324/10 8/1325/8 1240/1301/1240 f 10/1324/10 1240/1301/1240 1239/1300/1239 f 1239/1300/1239 1248/1308/1248 11/1326/11 f 1239/1300/1239 11/1326/11 10/1324/10 f 5/1327/5 3/1328/3 1235/1299/1235 f 5/1327/5 1235/1299/1235 1238/1298/1238 f 9/1329/9 4/1330/4 1246/1307/1246 f 9/1329/9 1246/1307/1246 1241/1305/1241 f 1240/1301/1240 8/1325/8 6/1331/6 f 1240/1301/1240 6/1331/6 1251/1315/1251 f 7/1332/7 9/1329/9 1241/1305/1241 f 7/1332/7 1241/1305/1241 1244/1304/1244 f 11/1326/11 1248/1308/1248 1247/1310/1247 f 11/1326/11 1247/1310/1247 12/1323/12 f 3/1328/3 2/690/2 671/677/671 f 3/1328/3 671/677/671 1235/1299/1235 f 1238/1298/1238 1246/1307/1246 4/1330/4 f 1238/1298/1238 4/1330/4 5/1327/5 f 7/1332/7 1244/1304/1244 1251/1315/1251 f 7/1332/7 1251/1315/1251 6/1331/6 f 1203/1251/1203 1013/1042/1013 1012/1043/1012 f 1203/1251/1203 1012/1043/1012 736/757/736 f 937/959/937 941/964/941 1027/1057/1027 f 937/959/937 1027/1057/1027 999/1030/999 f 1084/1122/1084 739/756/739 1034/1067/1034 f 1084/1122/1084 1034/1067/1034 1037/1071/1037 f 1197/1244/1197 1196/1243/1196 1201/1249/1201 f 1197/1244/1197 1201/1249/1201 1199/1245/1199 f 1203/1251/1203 736/757/736 739/756/739 f 1203/1251/1203 739/756/739 1084/1122/1084 f 936/962/936 784/805/784 941/964/941 f 936/962/936 941/964/941 937/959/937 f 786/806/786 1004/1033/1004 940/963/940 f 786/806/786 940/963/940 785/804/785 f 467/1333/467 612/604/612 387/1334/387 f 612/604/612 624/630/624 387/1334/387 f 621/628/621 387/1334/387 624/630/624 f 604/595/604 44/22/44 28/5/28 f 472/605/472 612/604/612 467/1333/467 f 29/6/29 28/5/28 47/26/47 f 43/21/43 48/25/48 44/22/44 f 30/7/30 266/1335/266 27/8/27 f 424/414/424 239/223/239 425/415/425 f 467/458/467 363/347/363 472/463/472 f 561/552/561 560/553/560 572/564/572 f 549/540/549 551/542/551 579/571/579 f 583/574/583 595/588/595 582/575/582 f 31/12/31 36/13/36 600/591/600 f 39/16/39 44/22/44 603/597/603 f 32/9/32 599/592/599 45/23/45 f 473/626/473 613/607/613 471/606/471 f 477/620/477 478/625/478 620/621/620 f 474/611/474 615/610/615 617/627/617 f 1257/1336/1257 614/609/614 618/616/618 f 1257/1336/1257 620/621/620 622/624/622 f 1257/1336/1257 618/616/618 619/619/619 f 1257/1336/1257 613/607/613 615/610/615 f 614/609/614 1257/1336/1257 615/610/615 f 622/624/622 623/629/623 1257/1336/1257 f 1257/1336/1257 623/629/623 611/603/611 f 624/630/624 623/629/623 621/628/621 f 469/617/469 618/616/618 470/615/470 f 614/609/614 476/608/476 533/614/533 f 610/602/610 1257/1336/1257 611/603/611 f 613/607/613 1257/1336/1257 610/602/610 f 620/621/620 1257/1336/1257 619/619/619 f 541/532/541 592/584/592 562/555/562 f 541/532/541 587/581/587 592/584/592 f 627/633/627 607/599/607 605/596/605 f 627/633/627 605/596/605 604/595/604 f 605/596/605 606/598/606 603/597/603 f 607/599/607 606/598/606 605/596/605 f 1207/1254/1207 1082/1337/1082 1015/1338/1015 f 1219/1280/1219 1207/1254/1207 1015/1338/1015 f 1015/1338/1015 1216/1278/1216 1219/1280/1219 f 693/710/693 1198/1247/1198 678/695/678 f 1207/1254/1207 1087/1253/1087 1082/1337/1082 f 678/695/678 677/697/677 694/712/694 f 695/713/695 692/711/692 693/710/693 f 266/1335/266 679/696/679 27/8/27 f 883/903/883 1044/1079/1044 1045/1078/1045 f 992/1020/992 1082/1121/1082 1087/1125/1087 f 1158/1205/1158 1157/1204/1157 1168/1216/1168 f 1147/1194/1147 1145/1192/1145 1176/1223/1176 f 1193/1240/1193 1180/1227/1180 1179/1226/1179 f 684/702/684 682/699/682 1195/1242/1195 f 693/710/693 686/707/686 1199/1245/1199 f 599/592/599 681/698/681 45/23/45 f 1208/1256/1208 1088/1276/1088 1086/1257/1086 f 1093/1274/1093 1092/1271/1092 1215/1270/1215 f 1210/1260/1210 1090/1259/1090 1212/1277/1212 f 1209/1261/1209 1258/1339/1258 1213/1264/1213 f 1215/1270/1215 1258/1339/1258 1217/1275/1217 f 1213/1264/1213 1258/1339/1258 1214/1267/1214 f 1208/1256/1208 1258/1339/1258 1210/1260/1210 f 1258/1339/1258 1209/1261/1209 1210/1260/1210 f 1218/1279/1218 1217/1275/1217 1258/1339/1258 f 1218/1279/1218 1258/1339/1258 1205/1255/1205 f 1218/1279/1218 1219/1280/1219 1216/1278/1216 f 1213/1264/1213 1083/1269/1083 1085/1265/1085 f 1091/1258/1091 1209/1261/1209 1131/1266/1131 f 1258/1339/1258 1206/1252/1206 1205/1255/1205 f 1258/1339/1258 1208/1256/1208 1206/1252/1206 f 1258/1339/1258 1215/1270/1215 1214/1267/1214 f 1189/1236/1189 1138/1184/1138 1160/1207/1160 f 1185/1231/1185 1138/1184/1138 1189/1236/1189 f 1202/1248/1202 1220/1281/1220 1200/1246/1200 f 1200/1246/1200 1220/1281/1220 1198/1247/1198 f 1201/1249/1201 1200/1246/1200 1199/1245/1199 f 1201/1249/1201 1202/1248/1202 1200/1246/1200 # 2492 faces ================================================ FILE: graphics/tiny-renderer/lesson6.workbook/Geometry.csx ================================================ struct Vec2f { public float x; public float y; public float this [int i] { get { if (i == 0) return x; if (i == 1) return y; throw new InvalidOperationException (); } set { if (i == 0) x = value; else if (i == 1) y = value; else throw new InvalidOperationException (); } } public Vec2f Normalize () { return this / Norm (); } public float Norm () { return (float)Math.Sqrt (x * x + y * y); } public static Vec2f operator / (Vec2f v, float num) { v.x /= num; v.y /= num; return v; } public static Vec2f operator * (Vec2f v, float num) { v.x *= num; v.y *= num; return v; } public static Vec2f operator - (Vec2f a, Vec2f b) { return new Vec2f { x = a.x - b.x, y = a.y - b.y }; } public static Vec2f operator + (Vec2f a, Vec2f b) { return new Vec2f { x = a.x + b.x, y = a.y + b.y }; } } public struct Vec3f { public float x; public float y; public float z; public float this [int i] { get { switch (i) { case 0: return x; case 1: return y; case 2: return z; default: throw new InvalidOperationException (); } } set { switch (i) { case 0: x = value; break; case 1: y = value; break; case 2: z = value; break; default: throw new InvalidOperationException (); } } } public Vec3f Normalize () { return this / Norm (); } public float Norm () { return (float)Math.Sqrt (x * x + y * y + z * z); } public static Vec3f operator - (Vec3f a, Vec3f b) { return new Vec3f { x = a.x - b.x, y = a.y - b.y, z = a.z - b.z }; } public static Vec3f operator / (Vec3f v, float num) { v.x /= num; v.y /= num; v.z /= num; return v; } public static Vec3f operator * (Vec3f v, float num) { v.x *= num; v.y *= num; v.z *= num; return v; } } struct Vec4f { public float x; public float y; public float z; public float h; public float this [int i] { get { switch (i) { case 0: return x; case 1: return y; case 2: return z; case 3: return h; default: throw new InvalidOperationException (); } } set { switch (i) { case 0: x = value; break; case 1: y = value; break; case 2: z = value; break; case 3: h = value; break; default: throw new InvalidOperationException (); } } } public Vec4f Normalize () { var len = Norm (); return this / len; } public float Norm () { return (float)Math.Sqrt (x * x + y * y + z * z + h * h); } public static Vec4f operator - (Vec4f a, Vec4f b) { return new Vec4f { x = a.x - b.x, y = a.y - b.y, z = a.z - b.z, h = a.h - b.h }; } public static Vec4f operator / (Vec4f v, float num) { v.x /= num; v.y /= num; v.z /= num; v.h /= num; return v; } } struct Vec2i { public int x; public int y; public static Vec2i operator - (Vec2i a, Vec2i b) { return new Vec2i { x = a.x - b.x, y = a.y - b.y }; } } struct Vec3i { public int x; public int y; public int z; public static Vec3i operator - (Vec3i a, Vec3i b) { return new Vec3i { x = a.x - b.x, y = a.y - b.y, z = a.z - b.z }; } } static class Geometry { public static Vec3f Cross (Vec3f l, Vec3f r) { return new Vec3f { x = l.y * r.z - l.z * r.y, y = l.z * r.x - l.x * r.z, z = l.x * r.y - l.y * r.x }; } public static float Dot (Vec3f l, Vec3f r) { return l.x * r.x + l.y * r.y + l.z * r.z; } public static Vec4f Embed4D (Vec3f v, float fill = 1) { return new Vec4f { x = v.x, y = v.y, z = v.z, h = fill }; } public static Vec2f Project2D (Vec3f v) { return new Vec2f { x = v.x, y = v.y }; } public static Vec2f Project2D (Vec4f v) { return new Vec2f { x = v.x, y = v.y }; } public static Vec3f Project3D (Vec4f v) { return new Vec3f { x = v.x, y = v.y, z = v.z }; } } ================================================ FILE: graphics/tiny-renderer/lesson6.workbook/Image.csx ================================================ using System.IO; enum Format { GRAYSCALE = 1, BGR = 3, BGRA = 4 } struct Color { // the value stored as little endian: // ARGB -> BGRA // xRGB -> BGRx public readonly int value; public readonly Format format; public byte this [int offset] { get { if (offset > 3) // int has only 4 bytes (0, 1, 2, 3) throw new ArgumentOutOfRangeException (); return (byte)(value >> 8 * (3 - offset)); } } public static Color Red = new Color (red: 255, green: 0, blue: 0, alpha: 255); public static Color Green = new Color (red: 0, green: 255, blue: 0, alpha: 255); public static Color Blue = new Color (red: 0, green: 0, blue: 255, alpha: 255); public static Color Black = new Color (red: 0, green: 0, blue: 0, alpha: 255); public static Color White = new Color (red: 255, green: 255, blue: 255, alpha: 255); public static Color Yellow = new Color (red: 225, green: 225, blue: 0, alpha: 255); public Color (byte red, byte green, byte blue, byte alpha) : this ((blue << 24) | (green << 16) | (red << 8) | alpha, Format.BGRA) { } public Color (byte red, byte green, byte blue) : this ((blue << 24) | (green << 16) | (red << 8) | 0xFF, Format.BGR) { } public Color (byte value) : this (value, Format.GRAYSCALE) { } public Color (int value, Format format) { this.value = value; this.format = format; } public static Color operator * (Color color, float intensivity) { intensivity = Math.Max (0f, Math.Min (1f, intensivity)); var ch0 = (byte)(color [0] * intensivity); var ch1 = (byte)(color [1] * intensivity); var ch2 = (byte)(color [2] * intensivity); var ch3 = color [3]; return new Color (ch0 << 24 | ch1 << 16 | ch2 << 8 | ch3, color.format); } } class Image { internal byte [] buffer; public int Width { get; } public int Height { get; } public Format Format { get; } public int BytesPerRow { get { return Width * (int)Format; } } public Image (int width, int height, Format format) { Width = width; Height = height; Format = format; buffer = new byte [height * BytesPerRow]; } public void VerticalFlip () { var bpp = (int)Format; int bytesPerLine = Width * bpp; var half = Height >> 1; for (int l = 0; l < half; l++) { var l1 = l * bytesPerLine; var l2 = (Height - 1 - l) * bytesPerLine; for (int i = 0; i < bytesPerLine; i++) { byte pixel = buffer [l1 + i]; buffer [l1 + i] = buffer [l2 + i]; buffer [l2 + i] = pixel; } } } public void Clear () { for (int i = 0; i < buffer.Length; i++) buffer [i] = 0; } public Color this [int x, int y] { get { if (x < 0 || x >= Width) throw new ArgumentException ("x"); if (y < 0 || y >= Height) throw new ArgumentException ("y"); var offset = GetOffset (x, y); var len = (int)Format; int value = 0; for (var ch = 0; ch < 4; ch++) value = (value << 8) | (ch < len ? buffer [offset++] : 0xFF); return new Color (value, Format); } set { if (x < 0 || x >= Width) return; //throw new ArgumentException ($"{nameof(x)}={x} {nameof(Width)}={Width}"); if (y < 0 || y >= Height) return; // throw new ArgumentException ($"{nameof(y)}={y} {nameof(Height)}={Height}"); var offset = GetOffset (x, y); var v = value.value; var len = (int)Format; for (int ch = 0; ch < len; ch++) // 0123 buffer [offset++] = (byte)(v >> (3 - ch) * 8); // BGRA } } int GetOffset (int x, int y) { return y * BytesPerRow + x * (int)Format; } public bool WriteToFile (string path, bool rle = true) { var bpp = (int)Format; using (var writer = new BinaryWriter (File.Create (path))) { var header = new TGAHeader { IdLength = 0, // The IDLength set to 0 indicates that there is no image identification field in the TGA file ColorMapType = 0, // a value of 0 indicates that no palette is included BitsPerPixel = (byte)(bpp * 8), Width = (short)Width, Height = (short)Height, DataTypeCode = DataTypeFor (bpp, rle), ImageDescriptor = (byte)(0x20 | (Format == Format.BGRA ? 8 : 0)) // top-left origin }; WriteTo (writer, header); if (!rle) writer.Write (buffer); else UnloadRleData (writer); } return true; } public static Image Load (string path) { using (var reader = new BinaryReader (File.OpenRead (path))) { var header = ReadHeader (reader); var height = header.Height; var width = header.Width; var bytespp = header.BitsPerPixel >> 3; var format = (Format)bytespp; if (width <= 0 || height <= 0) throw new InvalidProgramException ($"bad image size: width={width} height={height}"); if (format != Format.BGR && format != Format.BGRA && format != Format.GRAYSCALE) throw new InvalidProgramException ($"unknown format {format}"); var img = new Image (width, height, format); switch (header.DataTypeCode) { case DataType.UncompressedTrueColorImage: case DataType.UncompressedBlackAndWhiteImage: reader.Read (img.buffer, 0, img.buffer.Length); break; case DataType.RleTrueColorImage: case DataType.RleBlackAndWhiteImage: img.LoadRleData (reader); break; default: throw new InvalidProgramException ($"unsupported image format {header.DataTypeCode}"); } if ((header.ImageDescriptor & 0x20) == 0) img.VerticalFlip (); return img; } } static void WriteTo (BinaryWriter writer, TGAHeader header) { writer.Write (header.IdLength); writer.Write (header.ColorMapType); writer.Write ((byte)header.DataTypeCode); writer.Write (header.ColorMapOrigin); writer.Write (header.ColorMapLength); writer.Write (header.ColorMapDepth); writer.Write (header.OriginX); writer.Write (header.OriginY); writer.Write (header.Width); writer.Write (header.Height); writer.Write (header.BitsPerPixel); writer.Write (header.ImageDescriptor); } static TGAHeader ReadHeader (BinaryReader reader) { var header = new TGAHeader { IdLength = reader.ReadByte (), ColorMapType = reader.ReadByte (), DataTypeCode = (DataType)reader.ReadByte (), ColorMapOrigin = reader.ReadInt16 (), ColorMapLength = reader.ReadInt16 (), ColorMapDepth = reader.ReadByte (), OriginX = reader.ReadInt16 (), OriginY = reader.ReadInt16 (), Width = reader.ReadInt16 (), Height = reader.ReadInt16 (), BitsPerPixel = reader.ReadByte (), ImageDescriptor = reader.ReadByte () }; return header; } bool UnloadRleData (BinaryWriter writer) { const int max_chunk_length = 128; int npixels = Width * Height; int curpix = 0; var bpp = (int)Format; while (curpix < npixels) { int chunkstart = curpix * bpp; int curbyte = curpix * bpp; int run_length = 1; bool literal = true; while (curpix + run_length < npixels && run_length < max_chunk_length && curpix + run_length < curpix + Width) { bool succ_eq = true; for (int t = 0; succ_eq && t < bpp; t++) succ_eq = (buffer [curbyte + t] == buffer [curbyte + t + bpp]); curbyte += bpp; if (1 == run_length) literal = !succ_eq; if (literal && succ_eq) { run_length--; break; } if (!literal && !succ_eq) break; run_length++; } curpix += run_length; writer.Write ((byte)(literal ? run_length - 1 : 128 + (run_length - 1))); writer.Write (buffer, chunkstart, literal ? run_length * bpp : bpp); } return true; } void LoadRleData (BinaryReader reader) { var pixelcount = Width * Height; var currentpixel = 0; var currentbyte = 0; var bytespp = (int)Format; var color = new byte [4]; do { var chunkheader = reader.ReadByte (); if (chunkheader < 128) { chunkheader++; for (int i = 0; i < chunkheader; i++) { for (int t = 0; t < bytespp; t++) buffer [currentbyte++] = reader.ReadByte (); currentpixel++; if (currentpixel > pixelcount) throw new InvalidProgramException ("Too many pixels read"); } } else { chunkheader -= 127; reader.Read (color, 0, bytespp); for (int i = 0; i < chunkheader; i++) { for (int t = 0; t < bytespp; t++) buffer [currentbyte++] = color [t]; currentpixel++; if (currentpixel > pixelcount) throw new InvalidProgramException ("Too many pixels read"); } } } while (currentpixel < pixelcount); } static DataType DataTypeFor (int bpp, bool rle) { var format = (Format)bpp; if (format == Format.GRAYSCALE) return rle ? DataType.RleBlackAndWhiteImage : DataType.UncompressedBlackAndWhiteImage; return rle ? DataType.RleTrueColorImage : DataType.UncompressedTrueColorImage; } } struct TGAHeader { public byte IdLength; public byte ColorMapType; public DataType DataTypeCode; // field #4. Color map specification public short ColorMapOrigin; // index of first color map entry that is included in the file public short ColorMapLength; // number of entries of the color map that are included in the file public byte ColorMapDepth; // number of bits per pixel // field #5. Image specification public short OriginX; // absolute coordinate of lower-left corner for displays where origin is at the lower left public short OriginY; // as for X-origin public short Width; // width in pixels public short Height; // height in pixels public byte BitsPerPixel; // pixel depth public byte ImageDescriptor; // bits 3-0 give the alpha channel depth, bits 5-4 give direction } public enum DataType : byte { NoImageData = 0, // no image data is present UncompressedColorMappedImage = 1, UncompressedTrueColorImage = 2, UncompressedBlackAndWhiteImage = 3, RleColorMappedImage = 9, // run-length encoded color-mapped image RleTrueColorImage = 10, // run-length encoded true-color image RleBlackAndWhiteImage = 11 // run-length encoded black-and-white (grayscale) image } ================================================ FILE: graphics/tiny-renderer/lesson6.workbook/ImageResultHandler.csx ================================================ using XIR = Xamarin.Interactive.Representations; InteractiveAgent.RepresentationManager.AddProvider (img => { XIR.ImageFormat format; switch (img.Format) { case Format.BGRA: format = XIR.ImageFormat.Bgra32; break; case Format.BGR: format = XIR.ImageFormat.Bgr24; break; default: return null; } return new XIR.Image (format, img.buffer, img.Width, img.Height); }); ================================================ FILE: graphics/tiny-renderer/lesson6.workbook/LICENSE.txt ================================================ Tiny Renderer, https://github.com/ssloy/tinyrenderer Copyright Dmitry V. Sokolov This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. ================================================ FILE: graphics/tiny-renderer/lesson6.workbook/Matrix.csx ================================================ using System; public struct Matrix4 { public const int Len = 4; public float R0C0, R0C1, R0C2, R0C3; public float R1C0, R1C1, R1C2, R1C3; public float R2C0, R2C1, R2C2, R2C3; public float R3C0, R3C1, R3C2, R3C3; public float this [int row, int column] { get { switch (row) { case 0: switch (column) { case 0: return R0C0; case 1: return R0C1; case 2: return R0C2; case 3: return R0C3; } break; case 1: switch (column) { case 0: return R1C0; case 1: return R1C1; case 2: return R1C2; case 3: return R1C3; } break; case 2: switch (column) { case 0: return R2C0; case 1: return R2C1; case 2: return R2C2; case 3: return R2C3; } break; case 3: switch (column) { case 0: return R3C0; case 1: return R3C1; case 2: return R3C2; case 3: return R3C3; } break; } throw new IndexOutOfRangeException (); } set { switch (row) { case 0: switch (column) { case 0: R0C0 = value; return; case 1: R0C1 = value; return; case 2: R0C2 = value; return; case 3: R0C3 = value; return; } break; case 1: switch (column) { case 0: R1C0 = value; return; case 1: R1C1 = value; return; case 2: R1C2 = value; return; case 3: R1C3 = value; return; } break; case 2: switch (column) { case 0: R2C0 = value; return; case 1: R2C1 = value; return; case 2: R2C2 = value; return; case 3: R2C3 = value; return; } break; case 3: switch (column) { case 0: R3C0 = value; return; case 1: R3C1 = value; return; case 2: R3C2 = value; return; case 3: R3C3 = value; return; } break; } throw new IndexOutOfRangeException (); } } public Matrix4 Transpose () { return new Matrix4 { R0C0 = R0C0, R0C1 = R1C0, R0C2 = R2C0, R0C3 = R3C0, R1C0 = R0C1, R1C1 = R1C1, R1C2 = R2C1, R1C3 = R3C1, R2C0 = R0C2, R2C1 = R1C2, R2C2 = R2C2, R2C3 = R3C2, R3C0 = R0C3, R3C1 = R1C3, R3C2 = R2C3, R3C3 = R3C3 }; } public static Matrix4 Identity () { return new Matrix4 { R0C0 = 1, R1C1 = 1, R2C2 = 1, R3C3 = 1 }; } public static Matrix4 Zoom (float scale) { return new Matrix4 { R0C0 = scale, R1C1 = scale, R2C2 = scale, R3C3 = scale }; } public static Matrix4 RotationZ (float angle) { var cosangle = (float)Math.Cos (angle); var sinangle = (float)Math.Sin (angle); var R = Identity (); R [0, 0] = R [1, 1] = cosangle; R [0, 1] = -sinangle; R [1, 0] = sinangle; return R; } public static Matrix4 operator * (Matrix4 l, Matrix4 r) { var result = new Matrix4 (); for (int i = 0; i < Len; i++) { for (int j = 0; j < Len; j++) { result [i, j] = 0; for (int k = 0; k < Len; k++) { result [i, j] += l [i, k] * r [k, j]; } } } return result; } public override string ToString () { var sb = new System.Text.StringBuilder (); for (int r = 0; r < Len; r++) { for (int c = 0; c < Len; c++) sb.Append (this[r, c]).Append (" "); sb.AppendLine (); } return sb.ToString (); } } public struct Matrix3 { public const int Len = 3; public float R0C0, R0C1, R0C2; public float R1C0, R1C1, R1C2; public float R2C0, R2C1, R2C2; public float this [int row, int column] { get { switch (row) { case 0: switch (column) { case 0: return R0C0; case 1: return R0C1; case 2: return R0C2; } break; case 1: switch (column) { case 0: return R1C0; case 1: return R1C1; case 2: return R1C2; } break; case 2: switch (column) { case 0: return R2C0; case 1: return R2C1; case 2: return R2C2; } break; } throw new IndexOutOfRangeException (); } set { switch (row) { case 0: switch (column) { case 0: R0C0 = value; return; case 1: R0C1 = value; return; case 2: R0C2 = value; return; } break; case 1: switch (column) { case 0: R1C0 = value; return; case 1: R1C1 = value; return; case 2: R1C2 = value; return; } break; case 2: switch (column) { case 0: R2C0 = value; return; case 1: R2C1 = value; return; case 2: R2C2 = value; return; } break; } throw new IndexOutOfRangeException (); } } public Matrix3 Transpose () { return new Matrix3 { R0C0 = R0C0, R0C1 = R1C0, R0C2 = R2C0, R1C0 = R0C1, R1C1 = R1C1, R1C2 = R2C1, R2C0 = R0C2, R2C1 = R1C2, R2C2 = R2C2 }; } public void SetColumn (int col, Vec3f v) { this [0, col] = v.x; this [1, col] = v.y; this [2, col] = v.z; } public void SetRow (int row, Vec3f v) { this [row, 0] = v.x; this [row, 1] = v.y; this [row, 2] = v.z; } public override string ToString () { var sb = new System.Text.StringBuilder (); for (int r = 0; r < Len; r++) { for (int c = 0; c < Len; c++) sb.Append (this [r, c]).Append (" "); sb.AppendLine (); } return sb.ToString (); } } public struct Matrix2 { public const int Len = 2; public float R0C0, R0C1; public float R1C0, R1C1; public float this [int row, int column] { get { switch (row) { case 0: switch (column) { case 0: return R0C0; case 1: return R0C1; } break; case 1: switch (column) { case 0: return R1C0; case 1: return R1C1; } break; } throw new IndexOutOfRangeException (); } set { switch (row) { case 0: switch (column) { case 0: R0C0 = value; return; case 1: R0C1 = value; return; } break; case 1: switch (column) { case 0: R1C0 = value; return; case 1: R1C1 = value; return; } break; } throw new IndexOutOfRangeException (); } } } // we don't want to declare them in Matrix because we don't need them in lesson which introduces Matrix class static class MatrixHelpers { // For Matrix4 // how to calc inverse Matrix https://en.wikipedia.org/w/index.php?title=Invertible_matrix§ion=4#In_relation_to_its_adjugate public static Matrix4 TransposeInverse (Matrix4 m) { // returns Transpose(Inverse(m)) // where Inverse(m) = Transpose(cofactor) / det(m) // Transpose(Inverse(m)) = Transpose(Transpose(cofactor) / det(m)) = cofactor / det(m) var cofactor = Cofactor (m); float det = 0; for (int i = 0; i < Matrix4.Len; i++) det += m [0, i] * cofactor [0, i]; for (int r = 0; r < Matrix4.Len; r++) { for (int c = 0; c < Matrix4.Len; c++) cofactor [r, c] /= det; } return cofactor; } public static Matrix4 Inverse (Matrix4 m) { // where Inverse(m) = Transpose(Cofactor(m)) / det(m) var cofactor = Cofactor (m); int len = Matrix4.Len; float det = 0; for (int i = 0; i < len; i++) det += m [0, i] * cofactor [0, i]; cofactor = cofactor.Transpose (); for (int r = 0; r < len; r++) { for (int c = 0; c < len; c++) cofactor [r, c] /= det; } return cofactor; } public static Matrix3 Inverse (Matrix3 m) { // where Inverse(m) = Transpose(Cofactor(m)) / det(m) var cofactor = Cofactor (m); int len = Matrix3.Len; float det = 0; for (int i = 0; i < len; i++) det += m [0, i] * cofactor [0, i]; cofactor = cofactor.Transpose (); for (int r = 0; r < len; r++) { for (int c = 0; c < len; c++) cofactor [r, c] /= det; } return cofactor; } static Matrix4 Cofactor (Matrix4 m) { var r = new Matrix4 (); for (int row = 0; row < Matrix4.Len; row++) { for (int col = 0; col < Matrix4.Len; col++) r [row, col] = Cofactor (m, row, col); } return r; } static Matrix3 Cofactor (Matrix3 m) { var r = new Matrix3 (); for (int row = 0; row < Matrix3.Len; row++) { for (int col = 0; col < Matrix3.Len; col++) r [row, col] = Cofactor (m, row, col); } return r; } static float Cofactor (Matrix4 m, int row, int col) { int sign = ((row + col) % 2 == 0) ? 1 : -1; return Det (Minor (m, row, col)) * sign; } static float Cofactor (Matrix3 m, int row, int col) { int sign = ((row + col) % 2 == 0) ? 1 : -1; return Det (Minor (m, row, col)) * sign; } static Matrix3 Minor (Matrix4 m, int row, int col) { var minor = new Matrix3 (); for (int r = 0; r < Matrix3.Len; r++) { for (int c = 0; c < Matrix3.Len; c++) { int y = (r < row) ? r : r + 1; int x = (c < col) ? c : c + 1; minor [r, c] = m [y, x]; } } return minor; } static Matrix2 Minor (Matrix3 m, int row, int col) { var minor = new Matrix2 (); for (int r = 0; r < Matrix2.Len; r++) { for (int c = 0; c < Matrix2.Len; c++) { int y = (r < row) ? r : r + 1; int x = (c < col) ? c : c + 1; minor [r, c] = m [y, x]; } } return minor; } static float Det (Matrix3 m) { float det = 0; det += m [0, 0] * (m [1, 1] * m [2, 2] - m [1, 2] * m [2, 1]); det -= m [0, 1] * (m [1, 0] * m [2, 2] - m [1, 2] * m [2, 0]); det += m [0, 2] * (m [1, 0] * m [2, 1] - m [1, 1] * m [2, 0]); return det; } static float Det (Matrix2 m) { return m [0, 0] * m [1, 1] - m [0, 1] * m [1, 0]; } public static Vec3f Mult (Matrix3 m, Vec3f v) { return new Vec3f { x = m.R0C0 * v.x + m.R0C1 * v.y + m.R0C2 * v.z, y = m.R1C0 * v.x + m.R1C1 * v.y + m.R1C2 * v.z, z = m.R2C0 * v.x + m.R2C1 * v.y + m.R2C2 * v.z }; } public static Vec4f Mult (Matrix4 m, Vec4f v) { return new Vec4f { x = m.R0C0*v.x + m.R0C1*v.y + m.R0C2*v.z + m.R0C3*v.h, y = m.R1C0*v.x + m.R1C1*v.y + m.R1C2*v.z + m.R1C3*v.h, z = m.R2C0*v.x + m.R2C1*v.y + m.R2C2*v.z + m.R2C3*v.h, h = m.R3C0*v.x + m.R3C1*v.y + m.R3C2*v.z + m.R3C3*v.h }; } } ================================================ FILE: graphics/tiny-renderer/lesson6.workbook/Model.csx ================================================ using System.Collections.Generic; using System.Linq; struct Face { public int [] Vertices; public int [] Textures; public int [] Normals; } class Model { public List Vertices { get; } = new List (); public List Faces { get; } = new List (); public List Textures { get; } = new List (); public List Normals { get; } = new List (); public static Model FromFile (string path) { var model = new Model (); string line; using (var reader = new System.IO.StreamReader (path)) { while ((line = reader.ReadLine ()) != null) model.ParseLine (line); } Console.WriteLine ($"v#{model.Vertices.Count} f#{model.Faces.Count}"); return model; } public static Model FromText (string text) { var model = new Model (); var lines = text.Split (new char [] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); foreach (var line in lines) model.ParseLine (line); Console.WriteLine ($"v#{model.Vertices.Count} f#{model.Faces.Count}"); return model; } void ParseLine (string line) { Func parseV3f = strItems => new Vec3f { x = float.Parse (strItems [1]), y = float.Parse (strItems [2]), z = float.Parse (strItems [3]) }; var items = line.Split (new char [] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (line.StartsWith ("v ", StringComparison.InvariantCulture)) { Vertices.Add (parseV3f (items)); } else if (line.StartsWith ("vt ", StringComparison.InvariantCulture)) { Textures.Add (parseV3f (items)); } else if (line.StartsWith ("vn ", StringComparison.InvariantCulture)) { Normals.Add (parseV3f (items)); } else if (line.StartsWith ("f ", StringComparison.InvariantCulture)) { var indexes = items.Skip (1) .SelectMany (s => s.Split (new char [] { '/', ' ' }, StringSplitOptions.RemoveEmptyEntries)) .Select (s => int.Parse (s) - 1) // in wavefront obj all indices start at 1, not zero .ToArray (); Faces.Add (new Face { Vertices = indexes.Where ((v, index) => index % 3 == 0).ToArray (), Textures = indexes.Where ((v, index) => index % 3 == 1).ToArray (), Normals = indexes.Where ((v, index) => index % 3 == 2).ToArray () }); } } public Vec3f Normal (Face face, int nthvert) { int idx = face.Normals [nthvert]; return Normals [idx]; } public Vec3f Vertex (Face face, int nthvert) { int idx = face.Vertices [nthvert]; return Vertices [idx]; } public Vec3f GetUV (Face face, int nthvert) { int idx = face.Textures [nthvert]; return Textures [idx]; } } ================================================ FILE: graphics/tiny-renderer/lesson6.workbook/WpfImageResultHandler.csx ================================================ using System; using System.IO; using System.Windows.Media; using System.Windows.Media.Imaging; using XIR = Xamarin.Interactive.Representations; static PixelFormat ConvertFormat (Format format) { switch (format) { case Format.BGRA: return PixelFormats.Bgra32; case Format.GRAYSCALE: return PixelFormats.Gray8; case Format.BGR: default: return PixelFormats.Bgr24; } } InteractiveAgent.RepresentationManager.AddProvider (img => { var source = BitmapSource.Create (img.Width, img.Height, 96, 96, ConvertFormat (img.Format), null, img.buffer, img.BytesPerRow); var encoder = new PngBitmapEncoder (); var outputFrame = BitmapFrame.Create (source); encoder.Frames.Add (outputFrame); using (var memory = new MemoryStream ()) { encoder.Save (memory); return XIR.Image.FromPng (memory.GetBuffer (), img.Width, img.Height); } }); ================================================ FILE: graphics/tiny-renderer/lesson6.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Matrix.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" #load "lesson1.csx" #load "lesson2.csx" #load "lesson3.csx" #load "lesson4.csx" #load "lesson5.csx" using static Geometry; using static MatrixHelpers; ``` # **Lesson 6: Shaders for the software renderer** > ℹ️ This workbook is a port of an [excellent C++ series](https://github.com/ssloy/tinyrenderer/wiki) written by Dmitry Sokolov. We appreciate that original work is available under a license that allowed us to turn it into a Workbook. Refactoring the source code. IShader. ```csharp interface IShader { Vec4f Vertex (Face face, int nthvert); bool Fragment (Vec3f fragment, Vec3f bar, out Color color); }; class RenderResult { public Image Image { get; set; } public float [] ZBuffer { get; set; } } RenderResult Render (Model model, IShader shader) { var image = new Image (width, height, Format.BGR); var zbuffer = InitZBuffer (image); var screen_coords = new Vec4f [3]; foreach (var face in model.Faces) { for (int i = 0; i < 3; i++) screen_coords [i] = shader.Vertex (face, i); Triangle (image, screen_coords, shader, zbuffer); } return new RenderResult { Image = image, ZBuffer = zbuffer }; } void Box (Vec4f [] pts, out Vec2i pMin, out Vec2i pMax) { pMax = new Vec2i { x = int.MinValue, y = int.MinValue }; pMin = new Vec2i { x = int.MaxValue, y = int.MaxValue }; for (int i = 0; i < 3; i++) { pMax.x = (int)Math.Max (pMax.x, pts [i].x / pts [i].h); pMax.y = (int)Math.Max (pMax.y, pts [i].y / pts [i].h); pMin.x = (int)Math.Min (pMin.x, pts [i].x / pts [i].h); pMin.y = (int)Math.Min (pMin.y, pts [i].y / pts [i].h); } } void Triangle (Image image, Vec4f [] pts, IShader shader, float [] zbuffer) { Vec2i pMin, pMax; Box (pts, out pMin, out pMax); Color color; for (int x = pMin.x; x <= pMax.x; x++) { for (int y = pMin.y; y <= pMax.y; y++) { var pixelCenter = new Vec2f { x = x + 0.5f, y = y + 0.5f }; var bc = Barycentric (Project2D (pts [0] / pts [0].h), Project2D (pts [1] / pts [1].h), Project2D (pts [2] / pts [2].h), pixelCenter); var z = pts [0].z * bc.x + pts [1].z * bc.y + pts [2].z * bc.z; // z [0..255] var w = pts [0].h * bc.x + pts [1].h * bc.y + pts [2].h * bc.z; var frag_depth = z / w; var idx = x + y * image.Width; if (bc.x < 0 || bc.y < 0 || bc.z < 0 || zbuffer[idx] > frag_depth) continue; var fragment = new Vec3f { x = x, y = y, z = frag_depth }; var discard = shader.Fragment (fragment, bc, out color); if (!discard) { zbuffer [idx] = frag_depth; image [x, y] = color; } } } } ``` Let us see how it works. The actual render code: * Parsing the .obj file * Iteration through all triangles of the model and rasterization of each triangle. The last step is the most interesting. Outer loop iterates through all the triangles. Inner loop iterates through all the vertices of the current triangle and calls a vertex shader for each vertex. **The main goal of the vertex shader is to transform the coordinates of the vertices. The secondary goal is to prepare data for the fragment shader.** What happens after that? We call the rasterization routine. What happens inside the rasterizer we do not know (well, okay, we do know since we programmed it!) with one exception. We know that the rasterizer calls **our** routine for each pixel, namely, the fragment shader. Again, for each pixel inside the triangle the rasterizer calls our own callback, the fragment shader. **The main goal of the fragment shader - is to determine the color of the current pixel. Secondary goal - we can discard current pixel by returning true.** The rendering pipeline for the OpenGL 2 can be represented as follows (in fact, it is more or less the same for newer versions too): ![ ](./img/lesson6_opengl2_pipeline.png) Because of the time limits I have for my course, I restrict myself to the OpenGL 2 pipeline and therefore to fragment and vertex shaders only. In newer versions of OpenGL there are other shaders, allowing, for example, to generate geometry on the fly. Okay, in the above image all the stages we can not touch are shown in blue, whereas our callbacks are shown in orange. In fact, our render code - is the \*\*primitive processing \*\*routine. It calls the vertex shader. We do not have primitive assembly here, since we are drawing dumb triangles only (in our code it is merged with the primitive processing). `Triangle` function - is the **rasterizer**, for each point inside the triangle it calls the **fragment shader**, then performs depth checks (z-buffer) and such. That is all. You know what the shaders are and now you can create your own shaders. # **My implementation of shaders shown on Gouraud shading** According to its name, it is a Gouraud shader. Here is the code: ```csharp using static ShaderUtils; class GouraudShader : IShader { readonly Model model; readonly Vec3f lightDir; // written by vertex shader, read by fragment shader protected Vec3f varyingIntensity = new Vec3f (); readonly Matrix4 transformation; public GouraudShader (Model model, Matrix4 viewPort, Matrix4 projection, Matrix4 modelView, Vec3f lightDir) { this.model = model; transformation = viewPort * projection * modelView; this.lightDir = lightDir.Normalize (); } public virtual Vec4f Vertex (Face face, int nthvert) { var n = model.Normal (face, nthvert).Normalize (); // get diffuse lighting intensity varyingIntensity [nthvert] = Math.Max (0, Dot (n, lightDir)); var d = Dot(n, lightDir); return TransformFace (model, face, nthvert, transformation); } public virtual bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { // interpolate intensity for the current pixel var intensity = Dot (varyingIntensity, bar); color = Color.White * intensity; // well duh return false; } } // set of utils which will be used in our shaders static class ShaderUtils { public static Vec4f TransformFace (Model model, Face face, int nthvert, Matrix4 t) { var v = model.Vertex (face, nthvert); // read the vertex from model var glVertex = Embed4D (v); return Mult (t, glVertex); // transform it to screen coordinates } public static void UpdateVarayingUV (Model model, Face face, int nthvert, ref Vec3f varyingU, ref Vec3f varyingV) { var vt = model.GetUV (face, nthvert); varyingU [nthvert] = vt.x; varyingV [nthvert] = vt.y; } public static Vec2f CalcUV (Vec3f varU, Vec3f varV, Vec3f bar) { return new Vec2f { x = Dot (varU, bar), y = Dot (varV, bar) }; } public static Color GetColor (Image texture, Vec2f uvf) { var uvi = CalcXY(texture, uvf); return texture [uvi.x, uvi.y]; } public static Vec3f Transform (Matrix4 t, Vec3f v) { var v4d = Mult (t, Embed4D (v)); return Project3D (v4d); } public static Vec3f Normal (Image normalMap, Vec2f uvf) { // RGB values as xyz. But Color stores data as BGR (zyx) var c = GetColor (normalMap, uvf); return new Vec3f { x = (c [2] / 255f) * 2 - 1, y = (c [1] / 255f) * 2 - 1, z = (c [0] / 255f) * 2 - 1 }; } public static float Specular (Image specularMap, Vec2f uvf) { var uvi = CalcXY (specularMap, uvf); var color = specularMap [uvi.x, uvi.y]; return color[0]; } public static Vec2i CalcXY (Image texture, Vec2f uvf) { return new Vec2i { x = (int)(uvf.x * texture.Width), y = (int)(uvf.y * texture.Height) }; } } var light_dir = new Vec3f { x = 1, y = 1, z = 1 }; var eye = new Vec3f { x = 1, y = 1, z = 3 }; var center = new Vec3f { x = 0, y = 0, z = 0 }; var up = new Vec3f { x = 0, y = 1, z = 0 }; var modelView = LookAt(eye, center, up); var viewPort = Viewport(width/8, height/8, width*3/4, height*3/4); var projection = Projection(-1f/(eye-center).Norm()); var shader = new GouraudShader (headModel, viewPort, projection, modelView, light_dir); var image = Render (headModel, shader).Image; image.VerticalFlip(); image ``` **vayring** is a reserved keyword in GLSL language, I have used VaryingIntensity as a name in order to show the correspondence. In varying variables we store data to be interpolated inside the triangle, and the fragment shaders get the interpolated value (for the current pixel). Fragment routine is called for each pixel inside the triangle we draw; as an input it receives [barycentric coordinates](https://en.wikipedia.org/wiki/Barycentric_coordinate_system) for interpolation of VaryingXXX data. Thus, interpolated intensity can be computed as: VaryingIntensity\[0\]\*bar\[0\] \+ VaryingIntensity\[1\]\*bar\[1\] \+ VaryingIntensity\[2\]\*bar\[2\] or simply as a dot product between two vectors: `Dot(VaryingIntensity,bar)`. In true GLSL, of course, fragment shaders receive ready interpolated values. Notice that the shader returns a bool value. It is easy to understand what it does if we look inside the updated rasterizer: ```csharp /* ... var discard = shader.Fragment (fragment, bc, out color); if (!discard) { zbuffer [idx] = frag_depth; image [x, y] = color; } */ ``` Fragment shader can discard drawing of the current pixel, then the rasterizer simply skips it. It is handy if we want to create binary masks or whatever you want. Of course, the rasterizer can not imagine all the weird stuff you could program, therefore it can not be pre-compiled with your shader. Here we use IShader interface as an intermediate between the two. # **First modification of the shaders** Simple modification of the Gourad shading, where the intensities are allowed to have 6 values only: ```csharp class GouraudShader6 : GouraudShader { public GouraudShader6 (Model model, Matrix4 viewPort, Matrix4 projection, Matrix4 modelView, Vec3f lightDir) : base (model, viewPort, projection, modelView, lightDir) { } public override bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { var intensity = Dot (varyingIntensity, bar); if (intensity > 0.85f) intensity = 1; else if (intensity > 0.60f) intensity = 0.80f; else if (intensity > 0.45f) intensity = 0.60f; else if (intensity > 0.30f) intensity = 0.45f; else if (intensity > 0.15f) intensity = 0.30f; else intensity = 0; color = new Color (255, 155, 0) * intensity; return false; } } var shader = new GouraudShader6 (headModel, viewPort, projection, modelView, light_dir); var image = Render (headModel, shader).Image; image.VerticalFlip(); image ``` # **Textures** I'll skip the [Phong shading](https://en.wikipedia.org/wiki/Phong_shading), but take a look at the article. Remember the homework assignment I gave you for texturing? We had to interpolate uv-coordinates. ```csharp using static ShaderUtils; class TextureShader : IShader { readonly Model model; readonly Vec3f lightDir; readonly Matrix4 transformation; readonly Image texture; // written by vertex shader, read by fragment shader Vec3f varyingIntensity = new Vec3f (); Vec3f varyingU = new Vec3f (); Vec3f varyingV = new Vec3f (); public TextureShader (Model model, Matrix4 viewPort, Matrix4 projection, Matrix4 modelView, Vec3f lightDir, Image texture) { this.model = model; transformation = viewPort * projection * modelView; this.lightDir = lightDir.Normalize (); this.texture = texture; } public Vec4f Vertex (Face face, int nthvert) { UpdateVarayingUV (model, face, nthvert, ref varyingU, ref varyingV); var n = model.Normal (face, nthvert).Normalize (); varyingIntensity [nthvert] = Math.Max (0, Dot (n, lightDir)); // get diffuse lighting intensity return TransformFace (model, face, nthvert, transformation); } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { // interpolate intensity for the current pixel var intensity = Dot (varyingIntensity, bar); // interpolate uv for the current pixel var uvf = CalcUV (varyingU, varyingV, bar); color = GetColor (texture, uvf) * intensity; return false; } } var shader = new TextureShader (headModel, viewPort, projection, modelView, light_dir, headTexture); var image = Render (headModel, shader).Image; image.VerticalFlip(); image ``` # **Normalmapping** Okay, now we have texture coordinates. What can we store in texture images? In fact, almost anything. It can be color, directions, temperature and so on. Let us load this texture: ![ ](./img/lesson6_african_head_nm.png) If we interpret RGB values as xyz directions, this image gives us normal vectors **for each pixel** of our render and not only per vertex as before. By the way, compare this image to another one, it gives exactly the same information, but in another frame: ![ ](./img/lesson6_african_head_nm_tangent.png) One of the images gives normal vectors in global (Cartesian) coordinate system, another one in [Darboux frame](https://en.wikipedia.org/wiki/Darboux_frame) (so-called tangent space). In Darboux frame the z-vector is normal to the object, x - principal curvature direction and y - their cross product. **Exercise 1:** Can you tell which image is represented in Darboux frame and which one is in the global coordinate frame? **Exercise 2:** Can you tell which representation is better and if yes, why is that? **Uniform** is a reserved keyword in GLSL, it allows to pass constants to the shaders. Here I pass the matrix Projection\*ModelView and its inverse transpose to transform the normal vectors (refer to the end of the lesson5). So, computation of the lighting intensity is the same as before with one exception: instead of interpolating normal vectors we retrieve the information from the normal mapping texture (do not forget to transform light vector and normal vectors). ```csharp class NormalMapShader : IShader { Vec3f varyingU = new Vec3f (); Vec3f varyingV = new Vec3f (); readonly Model model; readonly Vec3f lightDir; readonly Matrix4 uniformM; readonly Matrix4 uniformMIT; readonly Matrix4 transformation; readonly Image texture; readonly Image normalMap; public NormalMapShader (Model model, Matrix4 viewport, Matrix4 projection, Matrix4 modelView, Vec3f lightDir, Image texture, Image normalMap) { this.model = model; this.lightDir = lightDir.Normalize (); this.texture = texture; this.normalMap = normalMap; uniformM = projection * modelView; uniformMIT = TransposeInverse (uniformM); transformation = viewport * uniformM; } public Vec4f Vertex (Face face, int nthvert) { UpdateVarayingUV (model, face, nthvert, ref varyingU, ref varyingV); return TransformFace (model, face, nthvert, transformation); } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { var uv = CalcUV (varyingU, varyingV, bar); var n = Transform (uniformMIT, Normal (normalMap, uv)).Normalize (); var l = Transform (uniformM, lightDir).Normalize (); var intensity = Math.Max (0f, Dot (n, l)); color = GetColor (texture, uv) * intensity; return false; } } var headNormalMap = Image.Load ("obj/african_head_nm.tga"); headNormalMap.VerticalFlip (); var shader = new NormalMapShader (headModel, viewPort, projection, modelView, light_dir, headTexture, headNormalMap); var image = Render (headModel, shader).Image; image.VerticalFlip(); image ``` # **Specular mapping** Okay, let us continue the fun. All the computer graphics science is the art to cheat. To (cheaply) trick the eye we use the [Phong's approximation](https://en.wikipedia.org/wiki/Phong_reflection_model) of the lighting model. Phong proposed to consider the final lighting as a (weighted) sum of three light intensities: ambient lighting (constant per scene), diffuse lighting (the one we computed up to this moment) and specular lighting. Take a look at the following image, it speaks for itself: ![ ](./img/lesson6_phong.png) We compute diffuse lighting as a cosine of the angle between the normal vector and the light direction vector. I mean, this supposes that the light is reflected in all directions uniformly. What happens to glossy surfaces? In the limit case (mirror) the pixel is illuminated if and only if we can see the light source reflected by this pixel: ![ ](./img/lesson6_reflection.png) For diffuse lighting we computed the (cosine of) angle between vectors **n** and **l**, and now we are interested in the (cosine of) angle between vectors **r** (reflected light direction) and **v**(view direction). **Exercise 3:** Given vectors **n** and **l**, find vector **r**. *Answer:* If **n** and **l** are normalized, then **r** = 2**n**<**n**,**l**> - **l** For diffused lighting we computed the light intensity as the cosine. But a glossy surface reflects in one direction much more than in others! Okay then, what happens if we take tenth power of the cosine? Recall that all numbers inferior to 1 will decrease when we apply the power. It means that tenth power of the cosine will give smaller radius of the reflected beam. And hundredth power **much** smaller beam radius. This power is stored in a special texture (specular mapping texture) that tells for each point if it is glossy or not.\ \ I think that i do not need to comment anything in the below code at the exception of coefficients: `5 + color [i] * (diff + 1.3f * specular)` I took 5 for the ambient component, 1 for the diffuse component and 1.3 for the specular component. What coefficients to choose - is your choice. Different choices give different appearances for the object. Normally it is for the artist to decide. *Please note that normally the sum of the coefficents must be equal to 1, but you know. I like to create light.* ```csharp class SpecularShader : IShader { Vec3f varyingU = new Vec3f (); Vec3f varyingV = new Vec3f (); readonly Model model; readonly Vec3f lightDir; readonly Matrix4 uniformM; readonly Matrix4 uniformMIT; readonly Matrix4 transformation; readonly Image texture; readonly Image normalMap; readonly Image specularMap; public SpecularShader (Model model, Matrix4 viewport, Matrix4 projection, Matrix4 modelView, Vec3f lightDir, Image texture, Image normalMap, Image specularMap) { this.model = model; this.lightDir = lightDir.Normalize (); this.texture = texture; this.normalMap = normalMap; this.specularMap = specularMap; uniformM = projection * modelView; uniformMIT = TransposeInverse (uniformM); transformation = viewport * uniformM; } public Vec4f Vertex (Face face, int nthvert) { UpdateVarayingUV (model, face, nthvert, ref varyingU, ref varyingV); return TransformFace (model, face, nthvert, transformation); } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { var uv = CalcUV (varyingU, varyingV, bar); var n = Transform (uniformMIT, Normal (normalMap, uv)).Normalize (); var l = Transform (uniformM, lightDir).Normalize (); var r = (n * (2 * Dot (n, l)) - l).Normalize (); var diff = Math.Max (0f, Dot (n, l)); var specular = Math.Pow (Math.Max (0f, r.z), Specular (specularMap, uv) + 15); color = GetColor (texture, uv); int v = 0; for (int i = 0; i < 4; i++) v = (v << 8) | (byte)Math.Min (255, (int)(5 + color [i] * (diff + 1.3f * specular))); color = new Color (v, color.format); return false; } } var headSpecularMap = Image.Load ("obj/african_head_spec.tga"); var shader = new SpecularShader (headModel, viewPort, projection, modelView, light_dir, headTexture, headNormalMap, headSpecularMap); var image = Render (headModel, shader).Image; image.VerticalFlip(); image ``` ```csharp var diabloModel = Model.FromFile ("obj/diablo3_pose.obj"); var diabloTexture = Image.Load ("obj/diablo3_pose_diffuse.tga"); var diabloNormalMap = Image.Load ("obj/diablo3_pose_nm.tga"); var diabloTangentMap = Image.Load ("obj/diablo3_pose_nm_tangent.tga"); var diabloSpecularMap = Image.Load ("obj/diablo3_pose_spec.tga"); diabloTexture.VerticalFlip (); diabloNormalMap.VerticalFlip (); diabloTangentMap.VerticalFlip (); diabloSpecularMap.VerticalFlip (); var shader = new SpecularShader (diabloModel, viewPort, projection, modelView, light_dir, diabloTexture, diabloNormalMap, diabloSpecularMap); var image = Render (diabloModel, shader).Image; image.VerticalFlip(); image ``` # **Conclusion** We know how to render quite nice scenes, but our lighting is far from being real. In the next articles I will talk about shadows. Enjoy! ================================================ FILE: graphics/tiny-renderer/lesson6.workbook/lesson1.csx ================================================ int width = 800; int height = 800; var headModel = Model.FromFile ("obj/african_head.obj"); static void Swap(ref T x, ref T y) { T t = y; y = x; x = t; } static void Swap(T[] arr, int x, int y) { T t = arr[y]; arr[y] = arr[x]; arr[x] = t; } Image Line (Image image, int x0, int y0, int x1, int y1, Color color) { bool steep = false; // if the line is steep, we transpose the image if (Math.Abs (x0-x1) < Math.Abs (y0-y1)) { Swap (ref x0, ref y0); Swap (ref x1, ref y1); steep = true; } if (x0 > x1) { // make it left to right Swap (ref x0, ref x1); Swap (ref y0, ref y1); } // (x0, y0) == (x1, y1) if(x0 == x1) { image [x0, y0] = color; } else { for (int x = x0; x <= x1; x++) { double t = (x-x0) / (double)(x1-x0); int y = (int)Math.Round(y0*(1-t) + y1*t); if (steep) image [y, x] = color; else image [x, y] = color; } } return image; } ================================================ FILE: graphics/tiny-renderer/lesson6.workbook/lesson1.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" ``` # **Lesson 1: Bresenham’s Line Drawing Algorithm** # First attempt The goal of the first lesson is to render the wire mesh. To do this, we should learn how to draw line segments. We can simply read what Bresenham’s line algorithm is, but let’s write code ourselves. How does the simplest code that draws a line segment between `(x0, y0)` and `(x1, y1)` points look like? Apparently, something like this: ```csharp Image Line (Image image, int x0, int y0, int x1, int y1, Color color) { for (double t = 0; t < 1; t += 0.01) { int x = (int) (x0 * (1-t) + x1 * t); int y = (int) (y0 * (1-t) + y1 * t); image [x, y] = color; } return image; } Line (new Image (100, 100, Format.BGR), x0: 13, y0: 20, x1: 80, y1: 40, color: Color.White); ``` # Second attempt The problem with this code (in addition to efficiency) is the choice of the constant, which I took equal to .01. If we take it equal to .1, our line segment will look like this: ```csharp Image Line (Image image, int x0, int y0, int x1, int y1, Color color) { for (int x = x0; x <= x1; x++) { double t = (x-x0)/(double)(x1-x0); int y = (int)(y0*(1-t) + y1*t); image [x, y] = color; } return image; } Line (new Image (100, 100, Format.BGR), x0: 13, y0: 20, x1: 80, y1: 40, color: Color.White); ``` Caution! The first source of errors in such code of my students is the integer division, like: `(x-x0)/(x1-x0)`. Then, if we try to draw the following lines with this code: ```csharp var image = new Image (100, 100, Format.BGR); Line(image, x0: 13, y0: 20, x1: 80, y1: 40, color: Color.White); Line(image, x0: 20, y0: 13, x1: 40, y1: 80, color: Color.Red); Line(image, x0: 80, y0: 40, x1: 13, y1: 20, color: Color.Red); ``` It turns out that one line is good, the second one is with holes, and there’s no third line at all. Note that the first and the third lines (in the code) draw the same line in different colors, and in different directions (with the source and target points flipped). We have already seen the white one, it is drawn well. I was hoping to change the color of the white line to red, but could not do it. It’s a test for symmetry: the result of drawing a line segment should not depend on the order of points: the `(a,b)` line segment should be exactly the same as the `(b,a)` line segment. # Third attempt We fix the missing red line by swapping the points so `x0` is always lower than `x1`. There are holes in one of the line segments due to the fact that its height is greater than the width. My students often suggest the following fix: `if (dx > dy) { for (int x) } else { for (int y) }` Holy cow! ```csharp static void Swap(ref T x, ref T y) { T t = y; y = x; x = t; } static void Swap(T[] arr, int x, int y) { T t = arr[y]; arr[y] = arr[x]; arr[x] = t; } Image Line (Image image, int x0, int y0, int x1, int y1, Color color) { bool steep = false; // if the line is steep, we transpose the image if (Math.Abs (x0-x1) < Math.Abs (y0-y1)) { Swap (ref x0, ref y0); Swap (ref x1, ref y1); steep = true; } if (x0 > x1) { // make it left to right Swap (ref x0, ref x1); Swap (ref y0, ref y1); } // (x0, y0) == (x1, y1) if(x0 == x1) { image [x0, y0] = color; } else { for (int x = x0; x <= x1; x++) { double t = (x-x0) / (double)(x1-x0); int y = (int)Math.Round(y0*(1-t) + y1*t); if (steep) image [y, x] = color; else image [x, y] = color; } } return image; } Line(image, x0: 13, y0: 20, x1: 80, y1: 40, color: Color.White); Line(image, x0: 20, y0: 13, x1: 40, y1: 80, color: Color.Red); Line(image, x0: 80, y0: 40, x1: 13, y1: 20, color: Color.Red); ``` # Wireframe rendering So now we are ready to create a wire render. You can find the snapshot of the code and the test model here. I used the [wavefront obj](http://en.wikipedia.org/wiki/Wavefront_.obj_file) format of the file to store model. All we need for the render is read from the file the array of vertices of the following type: `v 0.608654 -0.568839 -0.416318` are `x,y,z` coordinates, one vertex per file line and faces `f 1193/1240/1193 1180/1227/1180 1179/1226/1179` ```csharp int width = 800, height = 800; var headModel = Model.FromFile ("obj/african_head.obj"); var image = new Image(width, height, Format.BGR); foreach(var face in headModel.Faces) { for(int j=0; j<3; j++) { var v0 = headModel.Vertices[face.Vertices [j]]; var v1 = headModel.Vertices[face.Vertices [(j+1) % 3]]; // scale x from [-1..1] to [0..w] // scale y from [-1..1] to [0..h] int x0 = (int)((v0.x + 1) * width / 2); int y0 = (int)((v0.y + 1) * height / 2); int x1 = (int)((v1.x + 1) * width / 2); int y1 = (int)((v1.y + 1) * height / 2); Line(image, x0, y0, x1, y1, Color.White); } } image.VerticalFlip (); image ``` ================================================ FILE: graphics/tiny-renderer/lesson6.workbook/lesson2.csx ================================================ using static Geometry; var light_dir = new Vec3f { x = 0, y = 0, z = -1 }; var world = new Vec3f [3]; var screen = new Vec3f [3]; void Line (Image image, Vec2i p1, Vec2i p2, Color color) { Line(image, p1.x, p1.y, p2.x, p2.y, color); } void Line (Image image, Vec3f p1, Vec3f p2, Color color) { Line(image, (int)p1.x, (int)p1.y, (int)p2.x, (int)p2.y, color); } void Triangle (Image image, Vec2i[] t, Color color) { Line(image, t[0], t[1], color); Line(image, t[1], t[2], color); Line(image, t[2], t[0], color); } Vec3f Barycentric (Vec3f a, Vec3f b, Vec3f c, Vec2i p) { var pixel = new Vec3f { x = p.x + 0.5f, y = p.y + 0.5f }; var ab = b - a; var ac = c - a; var pa = a - pixel; var r = Cross (new Vec3f { x = ab.x, y = ac.x, z = pa.x }, new Vec3f { x = ab.y, y = ac.y, z = pa.y }); // triangle is degenerate, in this case return smth with negative coordinates if (Math.Abs (r.z) < 1) return new Vec3f { x = -1, y = 1, z = 1 }; return new Vec3f { x = 1 - r.x / r.z - r.y / r.z, y = r.x / r.z, z = r.y / r.z }; } void Triangle (Image image, Vec3f [] coordinates, Color color) { var t0 = coordinates [0]; var t1 = coordinates [1]; var t2 = coordinates [2]; var pMax = new Vec2i { x = (int)Math.Max (0, Math.Max (t0.x, Math.Max (t1.x, t2.x))), y = (int)Math.Max (0, Math.Max (t0.y, Math.Max (t1.y, t2.y))) }; var pMin = new Vec2i { x = (int)Math.Min (image.Width, Math.Min (t0.x, Math.Min (t1.x, t2.x))), y = (int)Math.Min (image.Height, Math.Min (t0.y, Math.Min (t1.y, t2.y))) }; Vec2i p; for (p.x = pMin.x; p.x <= pMax.x; p.x++) { for (p.y = pMin.y; p.y <= pMax.y; p.y++) { var bc = Barycentric (t0, t1, t2, p); if (bc.x < 0 || bc.y < 0 || bc.z < 0) continue; image [p.x, p.y] = color; } } } ================================================ FILE: graphics/tiny-renderer/lesson6.workbook/lesson2.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" #load "lesson1.csx" using static Geometry; ``` # Lesson 2: Triangle rasterization and back face culling # Old-school method: Line sweeping Thus, the task is to draw two-dimensional triangles. For motivated students it normally takes a couple of hours, even if they are bad programmers. Last time we saw Bresenham’s line drawing algorithm. Today’s task is to draw a filled triangle. Funny enough, but this task is not trivial. I don’t know why, but I know that it’s true. Most of my students struggle with this simple task. So, the initial stub will look like this: ```csharp void Line (Image image, Vec2i p1, Vec2i p2, Color color) { Line(image, p1.x, p1.y, p2.x, p2.y, color); } void Line (Image image, Vec3f p1, Vec3f p2, Color color) { Line(image, (int)p1.x, (int)p1.y, (int)p2.x, (int)p2.y, color); } void Triangle (Image image, Vec2i[] t, Color color) { Line(image, t[0], t[1], color); Line(image, t[1], t[2], color); Line(image, t[2], t[0], color); } Vec2i[] t0 = { new Vec2i { x = 10, y = 70 }, new Vec2i { x = 50, y = 160 }, new Vec2i { x = 70, y = 80 } }; Vec2i[] t1 = { new Vec2i { x = 180, y = 50 }, new Vec2i { x = 150, y = 1 }, new Vec2i { x = 70, y = 180 } }; Vec2i[] t2 = { new Vec2i { x = 180, y = 150 }, new Vec2i { x = 120, y = 160 }, new Vec2i { x = 130, y = 180 } }; var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); image.VerticalFlip (); image ``` The code is simple: I provide three triangles for the initial debugging of your code. If we invoke `Line` inside the triangle function, we’ll get the contour of the triangle. How to draw a filled triangle? A good method of drawing a triangle must have the following features: * It should be (surprise!) simple and fast. * It should be symmetrical: the picture should not depend on the order of vertices passed to the drawing function. * If two triangles have two common vertices, there should be no holes between them because of rasterization rounding. We could add more requirements, but let’s do with these ones. Traditionally a line sweeping is used: 1. Sort vertices of the triangle by their y-coordinates 2. Rasterize simultaneously the left and the right sides of the triangle 3. Draw a horizontal line segment between the left and the right boundary points At this point my students start to lose the firm ground: which segment is the left one, which one is right? Besides, there are three segments in a triangle... Usually, after this introduction I leave my students for about an hour: once again, reading my code is much less valuable than comparing your own code with mine. `[One hour passes]` How do I draw a triangle? Once again, if you have a better method, I’d be glad to adopt it. Let us assume that we have three points of the triangle: `t0`, `t1`, `t2`, they are sorted in ascending order by the y-coordinate. Then, the boundary A is between `t0` and `t2`, boundary B is between `t0` and `t1`, and then between `t1` and `t2`. ```csharp void OrderByY (Vec2i[] t) { if(t[0].y > t[1].y) Swap(t, 0, 1); if(t[1].y > t[2].y) Swap(t, 1, 2); if(t[0].y > t[1].y) Swap(t, 0, 1); } void Triangle (Image image, Vec2i[] t, Color color) { OrderByY(t); Line(image, t[0], t[1], Color.Green); Line(image, t[1], t[2], Color.Green); Line(image, t[2], t[0], Color.Red); } var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); // Here boundary A is red, and boundary B is green. image.VerticalFlip (); image ``` Unfortunately, boundary B is made of two parts. Let us draw the bottom half of the triangle by cutting it horizontally: ```csharp void Triangle (Image image, Vec2i[] t, Color color) { OrderByY(t); float height_10 = t[1].y - t[0].y; float height_20 = t[2].y - t[0].y; for(int y=t[0].y; y<=t[1].y; y++) { var alpha = (y-t[0].y) / height_20; var beta = (y-t[0].y) / height_10; // be careful with divisions by zero Vec2i A = new Vec2i { x = t[0].x + (int)((t[2].x-t[0].x)*alpha), y = y}; Vec2i B = new Vec2i { x = t[0].x + (int)((t[1].x-t[0].x)*beta), y = y}; image[A.x, y] = Color.Red; image[B.x, y] = Color.Green; } } var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); image.VerticalFlip (); image ``` Note that the segments are not continuous. Last time when we drew straight lines we struggled to get continuous segments and here I did not bother with rotating the image (remember the xy swapping?). Why? We fill the triangles aftewards, that’s why. If we connect the corresponding pairs of points by horizontal lines, the gaps disappear: ```csharp void Triangle (Image image, Vec2i[] t, Color color) { OrderByY(t); float height_10 = t[1].y - t[0].y; float height_20 = t[2].y - t[0].y; for(int y=t[0].y; y<=t[1].y; y++) { var alpha = (y-t[0].y) / height_20; var beta = (y-t[0].y) / height_10; // be careful with divisions by zero Vec2i A = new Vec2i { x = t[0].x + (int)((t[2].x-t[0].x)*alpha), y = y}; Vec2i B = new Vec2i { x = t[0].x + (int)((t[1].x-t[0].x)*beta), y = y}; Line(image, A, B, Color.White); image[B.x, y] = Color.Green; image[A.x, y] = Color.Red; } } var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); image.VerticalFlip (); image ``` Now, let us draw the second (upper) half of the triangle. We can do this by adding a second loop: ```csharp void Triangle (Image image, Vec2i[] t, Color color) { OrderByY(t); float height_10 = t[1].y - t[0].y; float height_20 = t[2].y - t[0].y; for(int y=t[0].y; y<=t[1].y; y++) { var alpha = (y-t[0].y) / height_20; var beta = (y-t[0].y) / height_10; // be careful with divisions by zero Vec2i A = new Vec2i { x = t[0].x + (int)((t[2].x-t[0].x)*alpha), y = y}; Vec2i B = new Vec2i { x = t[0].x + (int)((t[1].x-t[0].x)*beta), y = y}; if(A.x > B.x) Swap(ref A, ref B); for (int j=A.x; j<=B.x; j++) image[j, y] = color; } float height_21 = t[2].y - t[1].y; for(int y=t[1].y; y<=t[2].y; y++) { var alpha = (y-t[0].y) / height_20; var beta = (y-t[1].y) / height_21; // be careful with divisions by zero Vec2i A = new Vec2i { x = t[0].x + (int)((t[2].x-t[0].x)*alpha), y = y}; Vec2i B = new Vec2i { x = t[1].x + (int)((t[2].x-t[1].x)*beta), y = y}; if(A.x > B.x) Swap(ref A, ref B); for (int j=A.x; j<=B.x; j++) image[j, y] = color; } } var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); image.VerticalFlip (); image ``` This could be enough, but I dislike to see the same code twice. That is why we will make it a bit less readable, but more handy for modifications/maintaining: ```csharp void Triangle (Image image, Vec2i[] t, Color color) { // I dont care about degenerate triangles if(t[0].y == t[1].y && t[1].y == t[2].y) return; OrderByY(t); float height_10 = t[1].y - t[0].y; float total_height = t[2].y - t[0].y; for(int i=0; i t[1].y - t[0].y || t[1].y == t[0].y; float segment_height = second_half ? t[2].y-t[1].y : t[1].y-t[0].y; var alpha = i / total_height; // be careful with divisions by zero var beta = (i - (second_half ? t[1].y-t[0].y : 0)) / segment_height; Vec2i A = new Vec2i { x = t[0].x + (int)((t[2].x-t[0].x)*alpha), y = t[0].y + i }; Vec2i B = new Vec2i { x = second_half ? t[1].x + (int)((t[2].x-t[1].x)*beta) : t[0].x + (int)((t[1].x-t[0].x)*beta), y = t[0].y + i }; if(A.x > B.x) Swap(ref A, ref B); for (int j=A.x; j<=B.x; j++) image[j, t[0].y + i] = color; } } var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); image.VerticalFlip (); image ``` # The method I adopt for my code While not being really complicated, the source code for the line sweeping is a bit messy. Moreover, it is really an old-school approach designed for mono-thread CPU programming. Let us take a look at the following pseudo-code: ```csharp // triangle(Vec2i[] points) { // Vec2i bbox[2] = find_bounding_box(points); // for (each pixel in the bounding box) { // if (inside(points, pixel)) { // put_pixel(pixel); // } // } // } ``` Do you like it? I do. It is really easy to find a bounding box. It is certainly no problem to check whether a point belongs a 2D triangle (or any convex polygon). *Off Topic: if I have to implement some code to check whether a point belongs to a polygon, and this program will run on a plane, I will never get on this plane. Turns out, it is a surprisingly difficult task to solve this problem reliably. But here we just painting pixels. I am okay with that.* There is another thing I like about this pseudocode: a neophyte in programming accepts it with enthusiasm, more experienced programmers often chuckle: “*What an idiot wrote it?*”. And an expert in computer graphics programming will shrug his shoulders and say: “*Well, that’s how it works in real life*”. Massively parallel computations in thousands of threads (i’m talking about regular consumer computers here) change the way of thinking. Okay, let us start: first of all we need to know what the [barycentric coordinates](https://en.wikipedia.org/wiki/Barycentric_coordinate_system) are. Given a 2D triangle ABC and a point P, all in old good Cartesian coordinates `(xy)`. Our goal is to find barycentric coordinates of the point P with respect to the triangle ABC. It means that we look for three numbers `(1 − u − v,u,v)` such that we can find the point P as follows: ![ ](./img/lesson2_f1.png) While being a bit frightening at the first glance, it is really simple: imagine that we put three weights `(1−u−v,u,v)` at the vertices A, B and C, respectively. Then the barycenter of the system is exactly in the point P. We can say the same thing with other words: the point P has coordinates `(u,v)` in the (oblique) basis (A,![](./img/lesson2_ab.png),![](./img/lesson2_ac.png)): ![ ](./img/lesson2_f2.png) So, we have vectors ![](./img/lesson2_ab.png), ![](./img/lesson2_ac.png) and ![](./img/lesson2_ap.png), we need to find two real numbers u and v respecting the following constraint: ![ ](./img/lesson2_f3.png) It is a simple vector equation, or a linear system of two equations with two variables: ![ ](./img/lesson2_f4.png) I am lazy and do not want to solve linear systems in a scholar way. Let us write it in matrix form: ![ ](./img/lesson2_f5.png) It means that we are looking for a vector `(u,v,1)` that is orthogonal to `(ABx,ACx,PAx)` and `(ABy,ACy,PAy)` *at the same time*! I hope you see [where I am heading](https://en.wikipedia.org/wiki/Cross_product). That is a small hint: to find an intersection of two straight lines in a plane (that is exactly what we did here), it is sufficient to compute one cross product. By the way, test yourself: how do we find an equation of a line passing through two given points? So, let us program our new rasterization routine: we iterate through all pixels of a bounding box for a given triangle. For each pixel we compute its barycentric coordinates. If it has at least one negative component, then the pixel is outside of the triangle. Probably it is more clear to see the program directly: ```csharp Vec3f Barycentric (Vec3f a, Vec3f b, Vec3f c, Vec2i p) { var pixel = new Vec3f { x = p.x + 0.5f, y = p.y + 0.5f }; var ab = b - a; var ac = c - a; var pa = a - pixel; var r = Cross (new Vec3f { x = ab.x, y = ac.x, z = pa.x }, new Vec3f { x = ab.y, y = ac.y, z = pa.y }); // triangle is degenerate, in this case return smth with negative coordinates if (Math.Abs (r.z) < 1) return new Vec3f { x = -1, y = 1, z = 1 }; return new Vec3f { x = 1 - r.x / r.z - r.y / r.z, y = r.x / r.z, z = r.y / r.z }; } void Triangle (Image image, Vec3f [] coordinates, Color color) { var t0 = coordinates [0]; var t1 = coordinates [1]; var t2 = coordinates [2]; var pMax = new Vec2i { x = (int)Math.Max (0, Math.Max (t0.x, Math.Max (t1.x, t2.x))), y = (int)Math.Max (0, Math.Max (t0.y, Math.Max (t1.y, t2.y))) }; var pMin = new Vec2i { x = (int)Math.Min (image.Width, Math.Min (t0.x, Math.Min (t1.x, t2.x))), y = (int)Math.Min (image.Height, Math.Min (t0.y, Math.Min (t1.y, t2.y))) }; Vec2i p; for (p.x = pMin.x; p.x <= pMax.x; p.x++) { for (p.y = pMin.y; p.y <= pMax.y; p.y++) { var bc = Barycentric (t0, t1, t2, p); if (bc.x < 0 || bc.y < 0 || bc.z < 0) continue; image [p.x, p.y] = color; } } } ``` # Flat shading render We already know how to draw a model with empty triangles. Let us fill them with a random color. This will help us to see how well we have encoded filling of triangles. Here is the code: ```csharp var image = new Image(width, height, Format.BGR); // Map world coordinates [-1..-1] to screen coordinates [0..width] Func map = v => new Vec3f { x = (int)((v.x+1)*image.Width/2), y = (int)((v.y+1)*image.Height/2) }; var rnd = new Random(); Func rndByte = () => (byte)rnd.Next(255); Func rndColor = () => new Color(rndByte(), rndByte(), rndByte()); var coordinates = new Vec3f[3]; foreach(var face in headModel.Faces) { for(int i=0; i<3; i++) { var vIndex = face.Vertices[i]; var v = headModel.Vertices[vIndex]; coordinates[i] = map(v); } Triangle(image, coordinates, rndColor()); } image.VerticalFlip (); image ``` Let us get rid of these clown-colors and put some lighting. Captain Obvious: ”*At the same light intensity, the polygon is illuminated most brightly when it is orthogonal to the light direction.*” Let us compare: ![ ](./img/lesson2_light1.jpeg) ![](./img/lesson2_light2.jpeg) We get zero illumination if the polygon is parallel to the vector of light. To paraphrase: the intensity of illumination is equal to the scalar product of the light vector and the normal to the given triangle. The normal to the triangle can be calculated simply as the [cross product](https://en.wikipedia.org/wiki/Cross_product) of its two sides. As a side note, at this course we will perform linear computations on the colors. However `(128,128,128)` color is not half as bright as `(255, 255, 255)`. We are going to ignore gamma correction and tolerate the incorrectness of the brightness of our colors. ```csharp var image = new Image (width, height, Format.BGR); var light_dir = new Vec3f { x = 0, y = 0, z = -1 }; var world = new Vec3f [3]; var screen = new Vec3f [3]; foreach (var face in headModel.Faces) { for (int i = 0; i < 3; i++) { var vIndex = face.Vertices [i]; world [i] = headModel.Vertices [vIndex]; screen [i] = map (world [i]); } var n = Cross (world [2] - world [0], world [1] - world [0]).Normalize (); var intensivity = Dot (n, light_dir); if (intensivity > 0) Triangle (image, screen, Color.White * intensivity); } image.VerticalFlip (); image ``` ================================================ FILE: graphics/tiny-renderer/lesson6.workbook/lesson3.csx ================================================ using static Geometry; var headTexture = Image.Load ("obj/african_head_diffuse.tga"); headTexture.VerticalFlip (); float [] InitZBuffer (Image image) { var zbuffer = new float [image.Width * image.Height]; for (int idx = 0; idx < zbuffer.Length; idx++) zbuffer [idx] = float.NegativeInfinity; return zbuffer; } Vec3f Barycentric (Vec2f a, Vec2f b, Vec2f c, Vec2f p) { var ab = b - a; var ac = c - a; var pa = a - p; var r = Cross (new Vec3f { x = ab.x, y = ac.x, z = pa.x }, new Vec3f { x = ab.y, y = ac.y, z = pa.y }); // triangle is degenerate, in this case return smth with negative coordinates // dont forget that r.z is integer. If it is zero then triangle ABC is degenerate if ((int)r.z == 0) return new Vec3f { x = -1, y = 1, z = 1 }; return new Vec3f { x = 1 - (r.x + r.y) / r.z, y = r.x / r.z, z = r.y / r.z }; } void Triangle (Image image, Vec3f [] coordinates, Image texture, Vec2f [] uv, float intensivity, float [] zbuffer) { Vec3f t0 = coordinates [0]; Vec3f t1 = coordinates [1]; Vec3f t2 = coordinates [2]; var pMax = new Vec2i { x = (int)Math.Max (0, Math.Max (t0.x, Math.Max (t1.x, t2.x))), y = (int)Math.Max (0, Math.Max (t0.y, Math.Max (t1.y, t2.y))) }; var pMin = new Vec2i { x = (int)Math.Min (image.Width, Math.Min (t0.x, Math.Min (t1.x, t2.x))), y = (int)Math.Min (image.Height, Math.Min (t0.y, Math.Min (t1.y, t2.y))) }; for (int x = pMin.x; x <= pMax.x; x++) { for (int y = pMin.y; y <= pMax.y; y++) { var pixelCenter = new Vec2f { x = x + 0.5f, y = y + 0.5f }; var bc = Barycentric (Project2D(t0), Project2D(t1), Project2D(t2), pixelCenter); if (bc.x < 0 || bc.y < 0 || bc.z < 0) continue; var z = t0.z * bc.x + t1.z * bc.y + t2.z * bc.z; var u = (int)(uv [0].x * bc.x + uv [1].x * bc.y + uv [2].x * bc.z); var v = (int)(uv [0].y * bc.x + uv [1].y * bc.y + uv [2].y * bc.z); var idx = x + y * image.Width; if (zbuffer [idx] < z) { zbuffer [idx] = z; var color = texture [u, v]; image [x, y] = color * intensivity; } } } } ================================================ FILE: graphics/tiny-renderer/lesson6.workbook/lesson3.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" #load "lesson1.csx" #load "lesson2.csx" using static Geometry; ``` # **Lesson 3: Hidden faces removal (z buffer)** # Introduction Hello, let me introduce you my friend z-buffer of a black guy. He will help us get rid of the visual artifacts of the hidden faces removal we had during the last lesson. ![](./img/lesson3_face1.png) By the way, i'd like to mention that this model i use heavily in the course is created by [Vidar Rapp](https://se.linkedin.com/in/vidarrapp). He kindely granted me a permission to use it for teaching rendering basics and i vandalized it, but i promise you to give back the eyes to the guy. Well, back to the topic, in theory we could just draw all the triangles without discarding any. If we do it properly starting rear-to-front, the front facets will erase the back ones. It is called the [painter's algorithm](http://en.wikipedia.org/wiki/Painter%27s_algorithm). Unfortunately, it comes along with a high computational cost: for each camera movement we need to re-sort all the scene. And then there are dynamic scenes... And this is not even the main problem. The main problem is it is not always possible to determine the correct order. # **Let us try to render a simple scene** Imagine a simple scene made of three triangles: the camera looks up-to-down, we project the colored triangles onto the white screen: ![ ](./img/lesson3_scene1.png) The render should look like this: ![ ](./img/lesson3_scene2.png) Blue facet - is it behind or in front of the red one? The painter's algorithm does not work here. It is possible to split blue facet in two (one in front of the red facet and one behind). And then the one in front of the red one is to be split in two - one in front of the green triangle and one behind... I think you get the problem: in scenes with millions of triangles it is really expensive to compute. It is possible to use [BSP trees](https://en.wikipedia.org/wiki/Binary_space_partitioning) to get it done. By the way, this data structure is constant for moving camera, but it is really messy. And the life is too short to get it messy. # **Even simpler: let us lose a dimension. Y-buffer!** Let us lose a dimension for a while and to cut the above scene along the yellow plane: ![ ](./img/lesson3_scene3.png) I mean, now our scene is made of three line segments (intersection of the yellow plane and each of the triangles), and the final render has a normal width but 1 pixel height: ![ ](./img/lesson3_scene4.png) Our scene is two-dimensional, so it is easy to draw it using the line() function we programmed in the very first lesson. ```csharp var scene = new Image (800, 500, Format.BGR); // scene "2d mesh" Line(scene, new Vec2i {x=20, y=34}, new Vec2i {x=744, y=400}, Color.Red); Line(scene, new Vec2i {x=120, y=434}, new Vec2i {x=444, y=400}, Color.Green); Line(scene, new Vec2i {x=330, y=463}, new Vec2i {x=594, y=200}, Color.Blue); // screen line Line(scene, new Vec2i {x=10, y=10}, new Vec2i{x=790, y=10}, Color.White); scene.VerticalFlip(); // I want to have the origin at the left bottom corner of the image scene // This is how our 2D scene looks like if we look at it sideways: ``` Let us render it. Recall that the render is 1 pixel height. In my source code I create images 16 pixels height for the ease of reading on high resolution screens. `Rasterize()` function writes only in the first line of the image `render` ```csharp void Rasterize(Image image, Vec2i p0, Vec2i p1, int[] ybuffer, Color color) { if (p0.x>p1.x) Swap(ref p0, ref p1); for (int x=p0.x; x<=p1.x; x++) { float t = (x-p0.x)/(float)(p1.x-p0.x); var y = (int)(p0.y*(1-t) + p1.y*t); if (ybuffer[x] < y) { ybuffer[x] = y; image[x, 0] = color; } } } var ybuffer = new int [width]; for (int i = 0; i < width; i++) ybuffer[i] = int.MinValue; var render = new Image (width, 16, Format.BGR); Rasterize(render, new Vec2i{x=20,y=34}, new Vec2i{x=744, y=400}, ybuffer, Color.Red); Rasterize(render, new Vec2i{x=120, y=434}, new Vec2i{x=444,y=400}, ybuffer, Color.Green); Rasterize(render, new Vec2i{x=330, y=463}, new Vec2i{x=594,y=200}, ybuffer, Color.Blue); render ``` It is really-really simple: I iterate through all x-coordinates between `p0.x` and `p1.x` and compute the corresponding y-coordinate of the segment. Then I check what we got in our array `ybuffer` with current `x` index. If the current `y`-value is closer to the camera than the value in the `ybuffer`, then I draw it on the screen and update the `ybuffer`. Let us see it step-by-step. After calling `Rasterize()` on the first (red) segment this is our memory: screen:![](./img/lesson3_rasterize1.png) ybuffer: ![ ](./img/lesson3_rasterize2.png) Here the magenta color indicates the minus infinity, those are places corresponding to the screen we did not touch. All the rest is shown in the shades of gray: clear colors are close to the camera, dark colors far from the camera. Then we draw the green segment. screen:![ ](./img/lesson3_rasterize3.png) ybuffer:![ ](./img/lesson3_rasterize4.png) And finally the blue one. screen:![ ](./img/lesson3_rasterize5.png) ybuffer:![ ](./img/lesson3_rasterize6.png) Congratulations, we just drew a 2D scene on a 1D screen! Let us admire once again the render: ![ ](./img/lesson3_rasterize7.png) # Back to 3D So, for drawing on a 2D screen the z-buffer must be two-dimensional: `var zbuffer = new int[width * height];` Personally I pack a two-dimensional buffer into a one-dimensional, the conversion is trivial: `var idx = x + y* width;` and the back one: `var x = idx % width;`\ `var y = idx % width;` Then in the code I simply iterate through all the triangles and call the rasterizer function with current triangle and a reference to the z-buffer. The only difficulty is how to compute the z-value of a pixel we want to draw. Let us recall how we computed the y-value in the y-buffer example: `int y = p0.y*(1-t) + p1.y*t;` What is the nature of the `t` variable? It turns out that `(1-t, t)` are barycentric coordinates of the point `(x,y)` with respect to the segment `p0, p1: (x,y) = p0*(1-t) + p1*t`. So the idea is to take the barycentric coordinates version of triangle rasterization, and for every pixel we want to draw simply to multiply its barycentric coordinates by the z-values of the vertices of the triangle we rasterize: ```csharp Vec3f Barycentric (Vec2f a, Vec2f b, Vec2f c, Vec2f p) { var ab = b - a; var ac = c - a; var pa = a - p; var r = Cross (new Vec3f { x = ab.x, y = ac.x, z = pa.x }, new Vec3f { x = ab.y, y = ac.y, z = pa.y }); // triangle is degenerate, in this case return smth with negative coordinates // dont forget that r.z is integer. If it is zero then triangle ABC is degenerate if ((int)r.z == 0) return new Vec3f { x = -1, y = 1, z = 1 }; return new Vec3f { x = 1 - (r.x + r.y) / r.z, y = r.x / r.z, z = r.y / r.z }; } void Triangle (Image image, Vec3f [] coordinates, Color color, float [] zbuffer) { Vec3f t0 = coordinates [0]; Vec3f t1 = coordinates [1]; Vec3f t2 = coordinates [2]; var pMax = new Vec2i { x = (int)Math.Max (0, Math.Max (t0.x, Math.Max (t1.x, t2.x))), y = (int)Math.Max (0, Math.Max (t0.y, Math.Max (t1.y, t2.y))) }; var pMin = new Vec2i { x = (int)Math.Min (image.Width, Math.Min (t0.x, Math.Min (t1.x, t2.x))), y = (int)Math.Min (image.Height, Math.Min (t0.y, Math.Min (t1.y, t2.y))) }; for (int x = pMin.x; x <= pMax.x; x++) { for (int y = pMin.y; y <= pMax.y; y++) { var pixelCenter = new Vec2f { x = x + 0.5f, y = y + 0.5f }; var bc = Barycentric (Project2D (t0), Project2D (t1), Project2D (t2), pixelCenter); if (bc.x < 0 || bc.y < 0 || bc.z < 0) continue; var z = t0.z * bc.x + t1.z * bc.y + t2.z * bc.z; var idx = x + y * image.Width; if (zbuffer [idx] < z) { zbuffer [idx] = z; image [x, y] = color; } } } } float [] InitZBuffer (Image image) { var zbuffer = new float [image.Width * image.Height]; for (int idx = 0; idx < zbuffer.Length; idx++) zbuffer [idx] = float.NegativeInfinity; return zbuffer; } var image = new Image(width, height, Format.BGR); Func map = v => new Vec3f { x = (int)((v.x+1)*(image.Width-1)/2 + 0.5f), y = (int)((v.y+1)*(image.Height-1)/2 + 0.5f), z = v.z }; var zbuffer = InitZBuffer(image); foreach(var face in headModel.Faces) { for(int i=0; i<3; i++) { var vIndex = face.Vertices[i]; world[i] = headModel.Vertices[vIndex]; screen[i] = map(world[i]); } Vec3f n = Cross(world[2] - world[0], world[1] - world[0]).Normalize (); var intensivity = Dot(n, light_dir); if(intensivity > 0) Triangle(image, screen, Color.White * intensivity, zbuffer); } image.VerticalFlip (); image ``` # Okay, we just interpolated the z-values. What else can we do? Texture! In the `.obj` file we have lines starting with `vt u v`, they give an array of texture coordinates. The number in the middle (between the slashes) in the facet lines\ `f x/x/x x/x/x x/x/x` are the texture coordinates of this vertex of this triangle. Interpolate it inside the triangle, multiply by the width-height of the texture image and you will get the color to put in your render. ```csharp void Triangle (Image image, Vec3f [] coordinates, Image texture, Vec2f [] uv, float intensivity, float [] zbuffer) { Vec3f t0 = coordinates [0]; Vec3f t1 = coordinates [1]; Vec3f t2 = coordinates [2]; var pMax = new Vec2i { x = (int)Math.Max (0, Math.Max (t0.x, Math.Max (t1.x, t2.x))), y = (int)Math.Max (0, Math.Max (t0.y, Math.Max (t1.y, t2.y))) }; var pMin = new Vec2i { x = (int)Math.Min (image.Width, Math.Min (t0.x, Math.Min (t1.x, t2.x))), y = (int)Math.Min (image.Height, Math.Min (t0.y, Math.Min (t1.y, t2.y))) }; for (int x = pMin.x; x <= pMax.x; x++) { for (int y = pMin.y; y <= pMax.y; y++) { var pixelCenter = new Vec2f { x = x + 0.5f, y = y + 0.5f }; var bc = Barycentric (Project2D(t0), Project2D(t1), Project2D(t2), pixelCenter); if (bc.x < 0 || bc.y < 0 || bc.z < 0) continue; var z = t0.z * bc.x + t1.z * bc.y + t2.z * bc.z; var u = (int)(uv [0].x * bc.x + uv [1].x * bc.y + uv [2].x * bc.z); var v = (int)(uv [0].y * bc.x + uv [1].y * bc.y + uv [2].y * bc.z); var idx = x + y * image.Width; if (zbuffer [idx] < z) { zbuffer [idx] = z; var color = texture [u, v]; image [x, y] = color * intensivity; } } } } var image = new Image(width, height, Format.BGR); var headTexture = Image.Load ("obj/african_head_diffuse.tga"); headTexture.VerticalFlip (); Func uvMap = v => new Vec2f { x = v.x * (headTexture.Width - 1), y = v.y * (headTexture.Height - 1) }; var zbuffer = InitZBuffer(image); var uv = new Vec2f[3]; var model = headModel; foreach(var face in model.Faces) { for(int i=0; i<3; i++) { var vIndex = face.Vertices[i]; world[i] = model.Vertices[vIndex]; screen[i] = map(world[i]); var tIndex = face.Textures[i]; uv[i] = uvMap(model.Textures[tIndex]); } Vec3f n = Cross(world[2] - world[0], world[1] - world[0]).Normalize (); var intensivity = Dot(n, light_dir); if(intensivity > 0) Triangle(image, screen, headTexture, uv, intensivity, zbuffer); } image.VerticalFlip (); image ``` ================================================ FILE: graphics/tiny-renderer/lesson6.workbook/lesson4.csx ================================================ Vec2f[] uv = new Vec2f [3]; Func uvMap = (texture, v) => new Vec2f { x = v.x * (texture.Width - 1), y = v.y * (texture.Height - 1) }; Matrix4 Viewport (int x, int y, int w, int h) { var depth = 255f; var m = Matrix4.Identity (); m [0, 3] = x + w / 2f; m [1, 3] = y + h / 2f; m [2, 3] = depth / 2f; m [0, 0] = w / 2f; m [1, 1] = h / 2f; m [2, 2] = depth / 2f; return m; } Matrix4 Projection (float coeff) { var projection = Matrix4.Identity (); projection [3, 2] = coeff; return projection; } ================================================ FILE: graphics/tiny-renderer/lesson6.workbook/lesson4.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Matrix.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" #load "lesson1.csx" #load "lesson2.csx" #load "lesson3.csx" using static Geometry; using static MatrixHelpers; ``` # **Lesson 4: Perspective projection** # The goal In previous lessons we rendered our model in orthographic projection by simply forgetting the z-coordinate. The goal for today is to learn how to draw in perspective: ![ ](./img/lesson4_the_goal.png) # 2D geometry: Linear transformations A linear transformation on a plane can be represented by a corresponding matrix. If we take a point `(x,y)` then its transformation can be written as follows: ![ ](./img/lesson4_formula1.svg) The simplest (not degenerate) transformation is the identity, it does not move any point: ![ ](./img/lesson4_formula_2d_identity.svg) Diagonal coefficients of the matrix give scaling along coordinate axes. Let us illustrate it, if we take the following transformation: ![ ](./img/lesson4_formula_2d_scale.svg) Then the white object (the white square with one corner chopped) will be transformed into the yellow one. Red and green line segments give unit length vectors aligned with `x` and `y`, respectively. All the images for this article were generated using this code: ```csharp Matrix4 Viewport (int x, int y, int w, int h) { var depth = 255f; var m = Matrix4.Identity (); m [0, 3] = x + w / 2f; m [1, 3] = y + h / 2f; m [2, 3] = depth / 2f; m [0, 0] = w / 2f; m [1, 1] = h / 2f; m [2, 2] = depth / 2f; return m; } Matrix4 Projection (float coeff) { var projection = Matrix4.Identity (); projection [3, 2] = coeff; return projection; } Vec4f Embed4D (Vec3f v, float fill = 1) { return new Vec4f { x = v.x, y = v.y, z = v.z, h = fill }; } Vec3f Project3D (Vec4f v) { return new Vec3f { x = v.x, y = v.y, z = v.z }; } Func map = v => Project3D(v/v.h); void RenderAxes (Image image) { var w = image.Width; var h = image.Height; var vp = Viewport(w/4, w/4, w/2, h/2); // draw the axes var x = new Vec3f { x = 1 }; var y = new Vec3f { y = 1 }; var o = new Vec3f (); o = map(Mult(vp, Embed4D(o))); x = map(Mult(vp, Embed4D(x))); y = map(Mult(vp, Embed4D(y))); Line(image, o, x, Color.Red); Line(image, o, y, Color.Green); } var cube = Model.FromFile("obj/cube.obj"); void RenderCube(Image image, Matrix4 deformation, Color color) { var w = image.Width; var h = image.Height; var vp = Viewport(w/4, w/4, w/2, h/2); var face = cube.Faces[0]; var faceLen = face.Vertices.Length; for(int j=0; j x/(c-z) = x'/c. In other words: ![ ](./img/lesson4_formula_x.svg) By doing the same reasoning for triangles CPB and CP'D, it is easy to find the following expression: ![](./img/lesson4_formula_y.svg) It is really similar to the result we put aside few moments ago, but there we got the result by a single matrix multiplication. We got the law for the coefficient: `r = -1/c` # Let us sum up: the main formula for today *If you simply copy-paste this formula without understanding the above material, I hate you.* So, if we want to compute a central projection with a camera **(important!) camera located on the z-axis with distance c from the origin**, then we embed the point into 4D by augmenting it with 1, then we multiply it with the following matrix, and retro-project it into 3D. ![ ](./img/lesson4_formula_last.svg) We deformed our object in a way, that simply forgetting its z-coordinate we will get a drawing in a perspective. If we want to use the z-buffer, then, naturally, do not forget the z: ```csharp var image = new Image(width, height, Format.BGR); var camera = new Vec3f { z = 3 }; var projection = Projection(-1/camera.z); var viewPort = Viewport(width/8, height/8, width*3/4, height*3/4); Func map = v => { var r4 = Mult (viewPort * projection, Embed4D (v)); var r = Project3D (r4 / r4.h); r.x = (int)(r.x + 0.5f); r.y = (int)(r.y + 0.5f); return r; }; Func uvMap = (texture, v) => new Vec2f { x = v.x * (texture.Width - 1), y = v.y * (texture.Height - 1) }; var model = headModel; var zbuffer = InitZBuffer(image); Vec2f[] uv = new Vec2f [3]; foreach(var face in model.Faces) { for(int i=0; i<3; i++) { var vIndex = face.Vertices[i]; world[i] = model.Vertices[vIndex]; screen[i] = map(world[i]); var tIndex = face.Textures[i]; uv[i] = uvMap(headTexture, model.Textures[tIndex]); } Vec3f n = Cross(world[2] - world[0], world[1] - world[0]).Normalize (); var intensivity = Dot(n, light_dir); if(intensivity > 0) Triangle(image, screen, headTexture, uv, intensivity, zbuffer); } image.VerticalFlip (); image ``` ================================================ FILE: graphics/tiny-renderer/lesson6.workbook/lesson5.csx ================================================ using static Geometry; var eye = new Vec3f { x = 1, y = 1, z = 3 }; var center = new Vec3f { x = 0, y = 0, z = 0 }; var up = new Vec3f { x = 0, y = 1, z = 0 }; Matrix4 LookAt (Vec3f eye, Vec3f center, Vec3f up) { var z = (eye - center).Normalize (); var x = Cross (up, z).Normalize (); var y = Cross (z, x).Normalize (); var Minv = Matrix4.Identity (); Minv [0, 0] = x.x; Minv [0, 1] = x.y; Minv [0, 2] = x.z; Minv [1, 0] = y.x; Minv [1, 1] = y.y; Minv [1, 2] = y.z; Minv [2, 0] = z.x; Minv [2, 1] = z.y; Minv [2, 2] = z.z; var Tr = Matrix4.Identity (); Tr [0, 3] = -center.x; Tr [1, 3] = -center.y; Tr [2, 3] = -center.y; return Minv * Tr; } ================================================ FILE: graphics/tiny-renderer/lesson6.workbook/lesson5.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Matrix.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" #load "lesson1.csx" #load "lesson2.csx" #load "lesson3.csx" #load "lesson4.csx" using static Geometry; using static MatrixHelpers; ``` # Lesson 5: Moving the camera # Change of basis in 3D space In Euclidean space coordinates can be given by a point (the origin) and a basis. What does it mean that point P has coordinates `(x,y,z)` in the frame `(O, i,j,k)`? It means that the vector OP can be expressed as follows: ![ ](./img/lesson5_basis.svg) Now image that we have another frame `(O', i',j',k')`. How do we transform coordinates given in one frame to another? First of all let us note that since `(i,j,k)` and `(i',j',k')` are bases of 3D, there exists a (non degenerate) matrix M such that: ![ ](./img/lesson5_new_basis.svg) Let us draw an illustration: ![](./img/lesson5_sketch1.png) Then let us re-express the vector OP: ![ ](./img/lesson5_change_basis1.svg) Now let us substitute `(i',j',k')` in the right part with the change of basis matrix: ![ ](./img/lesson5_change_basis2.svg) And it gives us the formula to transform coordinates from one frame to another: ![ ](./img/lesson5_change_basis3.svg) # Let us create our own gluLookAt OpenGL and, as a consequence, our tiny renderer are able to draw scenes **only with the camera located on the z-axis.** If we want to move the camera, no problem, we can move all the scene, leaving the camera immobile. Let us put the problem this way: we want to draw a scene with a camera situated in point **e**(eye), the camera should be pointed to the point **c** (center) in such way that a given vector **u**(up) is to be vertical in the final render. Here is an illustration: ![ ](./img/lesson5_change_basis4.png) ```csharp Matrix4 LookAt (Vec3f eye, Vec3f center, Vec3f up) { var z = (eye - center).Normalize (); var x = Cross (up, z).Normalize (); var y = Cross (z, x).Normalize (); var Minv = Matrix4.Identity (); Minv [0, 0] = x.x; Minv [0, 1] = x.y; Minv [0, 2] = x.z; Minv [1, 0] = y.x; Minv [1, 1] = y.y; Minv [1, 2] = y.z; Minv [2, 0] = z.x; Minv [2, 1] = z.y; Minv [2, 2] = z.z; var Tr = Matrix4.Identity (); Tr [0, 3] = -center.x; Tr [1, 3] = -center.y; Tr [2, 3] = -center.y; return Minv * Tr; } ``` Note that `z'` is given by the vector **`ce`** (do not forget to normalize it, it helps later). How do we compute `x'`? Simply by a cross product between **`u`** and **`z'`**. Then we compute `y'`, such that it is orthogonal to already calculated `x'` and `z'` (let me remind you that in our problem settings \*\*`ce` \*\*and **`u`** are not necessarily orthogonal). The very last step is a translation of the origin to the center **c** and our transformation matrix is ready. Now it suffices to get any point with coordinates `(x,y,z,1)` in the model frame, multiply it by the matrix ModelView and we get the coordinates in the camera frame! By the way, the name ModelView comes from OpenGL terminology. # Viewport If you followed this course from the beginning, you should remember strange lines like this one: ```csharp // x = (v.x+1)*(width-1)/2 // y = (v.y+1)*(height-1)/2 ``` What does it mean? It means that i have a point Vec2f v, it belongs to the square \[-1,1\]\*\[-1,1\]. I want to draw it in the image of (width, height) dimensions. Value (v.x\+1) is varying between 0 and 2, (v.x\+1)/2 between 0 and 1, and (v.x\+1)\*width/2 sweeps all the image. Thus we effectively mapped the bi-unit square onto the image. But now we are getting rid of these ugly constructs, and i want to rewrite all the computiations in the matrix form. Let us consider the following C# code: ```csharp /* Matrix4 Viewport (int x, int y, int w, int h) { var depth = 255f; var m = Matrix4.Identity (); m [0, 3] = x + w / 2f; m [1, 3] = y + h / 2f; m [2, 3] = depth / 2f; m [0, 0] = w / 2f; m [1, 1] = h / 2f; m [2, 2] = depth / 2f; return m; } */ ``` This code creates this matrix: ![ ](./img/lesson5_viewport.svg) It means that the bi-unit cube \[-1,1\]*\[-1,1\]*\[-1,1\] is mapped onto the screen cube \[0,w\]*\[0,h\]*\[0,d\]. Right, cube, and not a rectangle, this is because of the depth computations with the z-buffer. Here d is the resolution of the z-buffer. I like to have it equal to 255 because of simplicity of dumping black-and-white images of the z-buffer for debugging. In the OpenGL terminology this matrix is called viewport matrix. # Chain of coordinate transformations So, let us sum up. Our models (characters, for example) are created in their own local frame (**object coordinates**). They are inserted into a scene expressed in **world coordinates**. The transformation from one to another is made with matrix **Model**. Then, we want to express it in the camera frame (**eye coordinates**), the transformation is called **View**. Then, we deform the scene to create a perspective deformation with **Projection** matrix (lesson 4), this matrix transforms the scene to so-called **clip coordinates**. Finally, we draw the scene, and the matrix transforming clip coordinates to the **screen coordinates** is called **Viewport**. Again, if we read a point **v** from the .obj file, then to draw it on the screen it undergoes the following chain of transformations: Viewport \* Projection \* View \* Model \* v As i draw a single object only, the matrix Model is equal to identity, and i merged it with the matrix View: ```csharp var eye = new Vec3f { x = 1, y = 1, z = 3 }; var center = new Vec3f { x = 0, y = 0, z = 0 }; var up = new Vec3f { x = 0, y = 1, z = 0 }; // draw the model var modelView = LookAt(eye, center, up); var viewPort = Viewport(width/8, height/8, width*3/4, height*3/4); var projection = Projection(-1/(eye-center).Norm()); Func map = v => { var r4 = Mult (viewPort * projection * modelView, Embed4D (v)); var r = Project3D (r4 / r4.h); r.x = (int)(r.x + 0.5f); r.y = (int)(r.y + 0.5f); return r; }; var image = new Image(width, height, Format.BGR); var model = headModel; var zbuffer = InitZBuffer(image); foreach(var face in model.Faces) { for(int i=0; i<3; i++) { var vIndex = face.Vertices[i]; world[i] = model.Vertices[vIndex]; screen[i] = map(world[i]); var tIndex = face.Textures[i]; uv[i] = uvMap(headTexture, model.Textures[tIndex]); } Vec3f n = Cross(world[2] - world[0], world[1] - world[0]).Normalize (); var intensivity = Dot(n, light_dir); if(intensivity > 0) Triangle(image, screen, headTexture, uv, intensivity, zbuffer); } image.VerticalFlip (); image ``` # Transformation of normal vectors There is a widely-known fact: * If we have a model and its normal vectors are given by the artist AND this model is transformed with an affine mapping, then normal vectors are to be transformed with a mapping, equal to the transposition of the inverse matrix of the original mapping matrix What-what-what?! I met quite a few programmers who know this fact, but it remains a black magic for them. In fact, it is not so complicated. Take a pencil and draw a 2D triangle `(0,0)`, `(0,1)`, `(1,0)` and a vector **n**, normal to the hypothenuse. Naturally, **n** is equal to `(1,1)`. Then let us stretch all the y-coordinates by a factor of 2, leaving x-coordinates intact. Thus, our triangle becomes `(0,0)`, `(0,2)`, `(1,0)`. If we transform the vector **n** in the same way, it becomes `(1, 2)` and it is no longer orthogonal to the transformed edge of the triangle. Thus, to remove all the black magic fog, we need to understand one simple thing: **we do not need to simply transform normal vectors (as they can become not normal anymore), we need to compute (new) normal vectors to the transformed model.** Back to 3D, we have a vector **n** = (A,B,C). We know that the plane passing through the origin and having **n** for its normal, has an equation `Ax+By+Cz=0`. Let us write it in the matrix form (i do it in homogeneous coordinates from the beginning): ![ ](./img/lesson5_transform_normal1.png) Recall that `(A,B,C)` - is a vector, so we augment it with 0 when embedding into the 4D, and `(x,y,z)` is augmented with 1 since it is a point. Let us insert an identity matrix in between (inverse to M multiplied by M is equal to identity): ![ ](./img/lesson5_transform_normal2.png) The expression in right parentheses - are for the transformed points of the object. In the left - are for normal vectors to the transformed object! In standard convention we usually write coordinates as columns (please let us not raise all the stuff about contra- and co-variant vectors), so we can rewrite the previous expression as follows: ![ ](./img/lesson5_transform_normal2.png) And the left parentheses tell us that a normal to the transformed object can be computed from the old normal by applying the inverse transpose matrix of the affine mapping. Please note that if our transformation matrix M is a composition of uniform scalings, rotations and translations, then M is equal to its inverse transpose, since inverse and transpose are cancelling each other in this case. But since our matrices include perspective deformations, usually this trick does not help. In the current code we do not use the transformation of normal vectors, but in the next lesson it will be very, very handy. Happy coding! ================================================ FILE: graphics/tiny-renderer/lesson6.workbook/lesson6.csx ================================================ using static Geometry; using static MatrixHelpers; using static ShaderUtils; var diabloModel = Model.FromFile ("obj/diablo3_pose.obj"); var diabloTexture = Image.Load ("obj/diablo3_pose_diffuse.tga"); var diabloNormalMap = Image.Load ("obj/diablo3_pose_nm.tga"); var diabloTangentMap = Image.Load ("obj/diablo3_pose_nm_tangent.tga"); var diabloSpecularMap = Image.Load ("obj/diablo3_pose_spec.tga"); diabloTexture.VerticalFlip (); diabloNormalMap.VerticalFlip (); diabloTangentMap.VerticalFlip (); diabloSpecularMap.VerticalFlip (); light_dir = new Vec3f { x = 1, y = 1, z = 1 }; eye = new Vec3f { x = 1, y = 1, z = 3 }; center = new Vec3f { x = 0, y = 0, z = 0 }; up = new Vec3f { x = 0, y = 1, z = 0 }; var modelView = LookAt(eye, center, up); var viewPort = Viewport(width/8, height/8, width*3/4, height*3/4); var projection = Projection(-1f/(eye-center).Norm()); interface IShader { Vec4f Vertex (Face face, int nthvert); bool Fragment (Vec3f fragment, Vec3f bar, out Color color); }; class RenderResult { public Image Image { get; set; } public float [] ZBuffer { get; set; } } RenderResult Render (Model model, IShader shader) { var image = new Image (width, height, Format.BGR); var zbuffer = InitZBuffer (image); var screen_coords = new Vec4f [3]; foreach (var face in model.Faces) { for (int i = 0; i < 3; i++) screen_coords [i] = shader.Vertex (face, i); Triangle (image, screen_coords, shader, zbuffer); } return new RenderResult { Image = image, ZBuffer = zbuffer }; } void Box (Vec4f [] pts, out Vec2i pMin, out Vec2i pMax) { pMax = new Vec2i { x = int.MinValue, y = int.MinValue }; pMin = new Vec2i { x = int.MaxValue, y = int.MaxValue }; for (int i = 0; i < 3; i++) { pMax.x = (int)Math.Max (pMax.x, pts [i].x / pts [i].h); pMax.y = (int)Math.Max (pMax.y, pts [i].y / pts [i].h); pMin.x = (int)Math.Min (pMin.x, pts [i].x / pts [i].h); pMin.y = (int)Math.Min (pMin.y, pts [i].y / pts [i].h); } } void Triangle (Image image, Vec4f [] pts, IShader shader, float [] zbuffer) { Vec2i pMin, pMax; Box (pts, out pMin, out pMax); Color color; for (int x = pMin.x; x <= pMax.x; x++) { for (int y = pMin.y; y <= pMax.y; y++) { var pixelCenter = new Vec2f { x = x + 0.5f, y = y + 0.5f }; var bc = Barycentric (Project2D (pts [0] / pts [0].h), Project2D (pts [1] / pts [1].h), Project2D (pts [2] / pts [2].h), pixelCenter); var z = pts [0].z * bc.x + pts [1].z * bc.y + pts [2].z * bc.z; // z [0..255] var w = pts [0].h * bc.x + pts [1].h * bc.y + pts [2].h * bc.z; var frag_depth = z / w; var idx = x + y * image.Width; if (bc.x < 0 || bc.y < 0 || bc.z < 0 || zbuffer[idx] > frag_depth) continue; var fragment = new Vec3f { x = x, y = y, z = frag_depth }; var discard = shader.Fragment (fragment, bc, out color); if (!discard) { zbuffer [idx] = frag_depth; image [x, y] = color; } } } } static class ShaderUtils { public static Vec4f TransformFace (Model model, Face face, int nthvert, Matrix4 t) { var v = model.Vertex (face, nthvert); // read the vertex from model var glVertex = Embed4D (v); return Mult (t, glVertex); // transform it to screen coordinates } public static void UpdateVarayingUV (Model model, Face face, int nthvert, ref Vec3f varyingU, ref Vec3f varyingV) { var vt = model.GetUV (face, nthvert); varyingU [nthvert] = vt.x; varyingV [nthvert] = vt.y; } public static Vec2f CalcUV (Vec3f varU, Vec3f varV, Vec3f bar) { return new Vec2f { x = Dot (varU, bar), y = Dot (varV, bar) }; } public static Color GetColor (Image texture, Vec2f uvf) { var uvi = CalcXY(texture, uvf); return texture [uvi.x, uvi.y]; } public static Vec3f Transform (Matrix4 t, Vec3f v) { var v4d = Mult (t, Embed4D (v)); return Project3D (v4d); } public static Vec3f Normal (Image normalMap, Vec2f uvf) { // RGB values as xyz. But Color stores data as BGR (zyx) var c = GetColor (normalMap, uvf); return new Vec3f { x = (c [2] / 255f) * 2 - 1, y = (c [1] / 255f) * 2 - 1, z = (c [0] / 255f) * 2 - 1 }; } public static float Specular (Image specularMap, Vec2f uvf) { var uvi = CalcXY (specularMap, uvf); var color = specularMap [uvi.x, uvi.y]; return color[0]; } public static Vec2i CalcXY (Image texture, Vec2f uvf) { return new Vec2i { x = (int)(uvf.x * texture.Width), y = (int)(uvf.y * texture.Height) }; } } class TextureShader : IShader { readonly Model model; readonly Vec3f lightDir; readonly Matrix4 transformation; readonly Image texture; // written by vertex shader, read by fragment shader Vec3f varyingIntensity = new Vec3f (); Vec3f varyingU = new Vec3f (); Vec3f varyingV = new Vec3f (); public TextureShader (Model model, Matrix4 viewPort, Matrix4 projection, Matrix4 modelView, Vec3f lightDir, Image texture) { this.model = model; transformation = viewPort * projection * modelView; this.lightDir = lightDir.Normalize (); this.texture = texture; } public Vec4f Vertex (Face face, int nthvert) { UpdateVarayingUV (model, face, nthvert, ref varyingU, ref varyingV); var n = model.Normal (face, nthvert).Normalize (); varyingIntensity [nthvert] = Math.Max (0, Dot (n, lightDir)); // get diffuse lighting intensity return TransformFace (model, face, nthvert, transformation); } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { // interpolate intensity for the current pixel var intensity = Dot (varyingIntensity, bar); // interpolate uv for the current pixel var uvf = CalcUV (varyingU, varyingV, bar); color = GetColor (texture, uvf) * intensity; return false; } } ================================================ FILE: graphics/tiny-renderer/lesson6.workbook/obj/african_head.obj ================================================ v -0.000581696 -0.734665 -0.623267 v 0.000283538 -1 0.286843 v -0.117277 -0.973564 0.306907 v -0.382144 -0.890788 0.221243 v -0.247144 -0.942602 0.276051 v -0.656078 -0.718512 -0.109025 v -0.609847 -0.786562 0.0198068 v -0.66248 -0.632053 -0.244271 v -0.511812 -0.845392 0.127809 v -0.609326 -0.569868 -0.41571 v -0.426949 -0.649767 -0.567143 v -0.201076 -0.720822 -0.633205 v 0.117382 -0.973645 0.306766 v 0.382454 -0.890869 0.221097 v 0.247512 -0.942667 0.275986 v 0.656371 -0.718624 -0.109224 v 0.610273 -0.786562 0.0197893 v 0.66248 -0.631463 -0.244119 v 0.511631 -0.845357 0.127832 v 0.608654 -0.568839 -0.416318 v 0.424663 -0.649937 -0.567418 v 0.198972 -0.720968 -0.633141 v 0.153371 -0.140519 0.477416 v 0.134781 -0.14723 0.48805 v 0.131261 -0.132153 0.49872 v 0.14749 -0.135105 0.489565 v 0.000686924 -0.0534984 0.505694 v 0.075062 -0.0473306 0.49955 v 0.0695841 -0.0997942 0.550277 v 0.0302569 -0.0971868 0.55389 v 0.0745124 -0.135953 0.523215 v 0.0354892 -0.12785 0.535159 v 0.0389268 -0.109557 0.550558 v 0.0734835 -0.11538 0.538029 v 0.106386 -0.125623 0.51513 v 0.107415 -0.144295 0.5047 v 0.15968 -0.130861 0.484794 v 0.156224 -0.123705 0.486735 v 0.15792 -0.107798 0.4677 v 0.163784 -0.126996 0.470144 v 0.154687 -0.134655 0.486373 v 0.160668 -0.135649 0.476189 v 0.143433 -0.119034 0.499854 v 0.131606 -0.0726738 0.476148 v -0.000260156 -0.124553 0.539058 v -0.000646004 -0.110651 0.55444 v 0.100423 -0.10574 0.537643 v 0.126128 -0.115784 0.515598 v 0.250944 -0.275583 0.380381 v 0.221602 -0.335752 0.330174 v 0.275434 -0.301318 0.24751 v 0.307699 -0.239869 0.292356 v 0.332124 -0.0415605 0.412962 v 0.319444 0.00732526 0.451091 v 0.28667 -0.025805 0.481549 v 0.297006 -0.0758717 0.454242 v 0.357953 -0.159928 -0.223225 v 0.303981 -0.144611 -0.343644 v 0.296386 -0.0547553 -0.357792 v 0.357339 -0.0633433 -0.24278 v 0.45086 0.331215 0.047962 v 0.438899 0.336167 0.131147 v 0.447405 0.226107 0.139349 v 0.455613 0.205353 0.0827643 v 0.197493 -0.411308 0.138256 v 0.204911 -0.353378 0.2082 v 0.102001 -0.419375 0.24969 v 0.0995867 -0.475697 0.20834 v 0.150133 -0.372261 0.431226 v 0.176423 -0.362054 0.392056 v 0.196019 -0.326474 0.426929 v 0.154611 -0.348549 0.463444 v 0.0892273 -0.391968 0.303592 v 0.159013 -0.363737 0.305077 v 0.455712 0.508986 -0.0641442 v 0.432146 0.648411 -0.0417475 v 0.417051 0.611568 0.0817295 v 0.44205 0.483438 0.0478626 v 0.3446 0.43288 0.398633 v 0.372358 0.383369 0.353998 v 0.388341 0.404485 0.306953 v 0.355059 0.467372 0.356967 v 0.305162 0.338815 0.458112 v 0.298579 0.319803 0.456627 v 0.313422 0.304568 0.427776 v 0.323711 0.315968 0.429291 v 0.33161 0.397557 0.430226 v 0.354427 0.359727 0.390478 v 0.304162 0.291952 0.432377 v 0.292662 0.309771 0.452991 v 0.282934 0.292496 0.4562 v 0.292025 0.281663 0.435178 v 0.397344 0.565249 0.192585 v 0.42257 0.455996 0.145494 v 0.317848 0.364866 0.448834 v 0.340595 0.337517 0.417978 v 0.243227 0.479439 0.494236 v 0.250155 0.546138 0.465934 v 0.179019 0.560251 0.511681 v 0.170173 0.4781 0.536229 v 0.162386 0.410407 0.547009 v 0.235031 0.427051 0.517018 v 0.271745 0.634415 0.42162 v 0.196896 0.657291 0.472505 v 0.186589 0.312952 0.511073 v 0.189518 0.32493 0.514165 v 0.146286 0.31277 0.509009 v 0.144959 0.300178 0.501713 v 0.143965 0.300412 0.49409 v 0.187203 0.310596 0.506407 v 0.157744 0.364614 0.528804 v 0.216697 0.382527 0.516083 v 0.194441 0.332425 0.515989 v 0.204286 0.349818 0.516732 v 0.156254 0.334062 0.519579 v 0.151565 0.320341 0.513961 v 0.0431068 0.071791 0.618005 v 0.0477954 0.0867105 0.593486 v 0.0780844 0.0816652 0.602518 v 0.0574124 0.0746147 0.621185 v 0.448253 0.130656 0.149533 v 0.431801 0.159355 0.215905 v 0.422792 0.0771637 0.237185 v 0.428691 0.0348783 0.166914 v 0.365073 -0.0526507 0.316126 v 0.326974 -0.104793 0.373068 v 0.312773 -0.172965 0.33446 v 0.368107 -0.126698 0.269222 v 0.203695 -0.131796 0.523934 v 0.180463 -0.136479 0.525396 v 0.182848 -0.14892 0.516989 v 0.204163 -0.152533 0.514914 v 0.39379 0.00616771 0.269368 v 0.40177 -0.0591341 0.209048 v 0.26083 -0.0996422 0.484274 v 0.250406 -0.0552171 0.50321 v 0.15851 -0.136292 0.498474 v 0.155032 -0.134684 0.502964 v 0.145006 -0.133819 0.514504 v 0.171033 -0.12032 0.538263 v 0.158849 -0.127938 0.534943 v 0.167969 -0.138075 0.523788 v 0.232061 -0.151474 0.497024 v 0.23074 -0.117128 0.507191 v 0.365798 0.221617 0.362743 v 0.342501 0.235507 0.392185 v 0.325951 0.202558 0.415114 v 0.359268 0.178677 0.383229 v 0.352369 0.0489033 0.417452 v 0.322262 0.0907619 0.44953 v 0.295322 0.04895 0.483251 v 0.367108 0.00328555 0.369771 v 0.138972 -0.18796 0.555521 v 0.161562 -0.177794 0.535913 v 0.154015 -0.155093 0.536392 v 0.136131 -0.156414 0.558491 v 0.220263 -0.08194 0.518603 v 0.202088 -0.0486753 0.52791 v 0.17564 -0.0814314 0.545822 v 0.193131 -0.106435 0.533575 v 0.199492 -0.169714 0.509722 v 0.190033 -0.188183 0.514668 v 0.207302 -0.213011 0.492721 v 0.222415 -0.183044 0.489617 v 0.125088 -0.132884 0.551294 v 0.144497 -0.139192 0.530254 v 0.135014 0.119128 0.544717 v 0.119534 0.149685 0.554253 v 0.096915 0.171211 0.569382 v 0.112553 0.137432 0.569616 v 0.0878476 0.217858 0.555667 v 0.0649773 0.232128 0.568628 v 0.073466 0.185119 0.584571 v 0.116359 0.191199 0.548932 v 0.111419 0.228591 0.524951 v 0.0858774 0.255408 0.530312 v 0.301408 0.0368718 -0.387812 v 0.366839 0.037626 -0.269538 v 0.272125 -0.199781 0.399533 v 0.246349 -0.195514 0.453266 v 0.223339 -0.243049 0.450553 v 0.364021 -0.197455 0.21335 v 0.411416 -0.124798 0.140589 v 0.431568 -0.0028997 0.0907502 v 0.449346 0.11075 0.0889086 v 0.0649948 0.777167 0.432594 v 0.133465 0.770619 0.418569 v 0.14341 0.869244 0.301253 v 0.0689586 0.877043 0.315395 v 0.305372 0.809321 0.22043 v 0.289307 0.723856 0.335524 v 0.355187 0.660735 0.264773 v 0.372264 0.728258 0.148528 v 0.382308 0.7766 0.0116631 v 0.0971488 0.470588 0.557912 v 0.110788 0.565185 0.534317 v 0.100113 0.277828 0.510938 v 0.10966 0.248679 0.503771 v 0.0443988 0.240822 0.58581 v 0.0522151 0.193614 0.604337 v 0.052601 0.564735 0.541859 v 0.123726 0.667896 0.498907 v 0.0597976 0.671147 0.508711 v 0.0466729 0.466215 0.561034 v 0.000423846 0.462807 0.558988 v -0.00017831 0.388326 0.563478 v 0.0352086 0.389069 0.560584 v 0.000833078 0.56384 0.544139 v 0.295773 0.426823 0.470722 v 0.301706 0.464689 0.451056 v 0.189957 0.181465 0.501181 v 0.186163 0.208931 0.491956 v 0.141574 0.222722 0.500509 v 0.146526 0.195338 0.518293 v 0.111986 0.0116865 0.562811 v 0.111343 0.0404672 0.565769 v 0.0577164 0.0420398 0.577988 v 0.0656438 -0.00796249 0.596918 v 0.147695 0.0440509 0.537258 v 0.144778 0.0631738 0.538491 v 0.0268719 -0.0140834 0.602378 v 0.0270356 -0.0372401 0.622027 v 0.0876429 -0.0456996 0.601127 v 0.183093 0.146552 0.519439 v 0.148589 0.164593 0.536819 v 0.147344 0.131095 0.542934 v 0.176733 0.112264 0.532435 v -0.000394618 -0.0441035 0.617625 v -0.000260156 -0.0187662 0.600677 v 0.165058 0.0770935 0.530856 v 0.148554 0.0982976 0.535562 v 0.116476 0.272829 0.494797 v 0.119084 0.26261 0.493569 v 0.120873 0.268971 0.480883 v 0.11761 0.27287 0.484221 v 0.224695 0.848444 0.271198 v 0.231324 0.918189 0.121063 v 0.14614 0.9439 0.150241 v 0.241894 0.945736 -0.185803 v 0.156043 0.976475 -0.183418 v 0.146906 0.980702 -0.0177607 v 0.23195 0.948285 -0.0402158 v 0.0684324 0.995189 -0.00981573 v 0.0682103 0.955014 0.162933 v 0.0891571 0.383649 0.555118 v 0.110613 0.336412 0.528863 v 0.122749 0.310759 0.512914 v 0.147081 -0.111919 0.55631 v 0.158656 -0.0994551 0.55786 v 0.0939743 0.0869969 0.616333 v 0.101206 0.119326 0.615532 v 0.0670469 0.122121 0.645885 v 0.0560853 0.0831385 0.640601 v 0.0795284 0.0820978 0.567845 v 0.0337354 0.0564741 0.595059 v 0.0854448 -0.103577 0.606979 v 0.0826211 -0.0671141 0.612931 v 0.0280704 -0.0555854 0.637736 v 0.0319698 -0.0970874 0.628212 v 0.0789964 -0.121811 0.579602 v 0.0327415 -0.116959 0.594106 v 0.0216981 0.0173339 0.585915 v -0.00123062 -0.095585 0.625704 v -0.000511542 -0.0598999 0.637227 v -0.00157555 -0.115643 0.593966 v -0.000219233 -0.0988881 0.554498 v 0.0291929 0.0853015 0.665324 v 0.0352671 0.124524 0.666125 v 0.0371846 0.159004 0.648446 v 0.0654158 0.154462 0.629171 v 0.0280178 0.19967 0.620548 v 0.0221015 0.245843 0.59797 v 0.0432997 0.281499 0.556866 v 0.0222008 0.28717 0.567459 v -0.000400465 0.125745 0.673871 v -0.00057585 0.0822265 0.675105 v -0.000347849 0.160916 0.656029 v 0.367195 0.315074 0.363767 v 0.346658 0.302744 0.393991 v 0.344389 0.266656 0.384439 v 0.371726 0.266504 0.352507 v 0.40246 0.429197 0.234116 v 0.422126 0.335763 0.207276 v 0.393316 0.264083 0.313887 v 0.387102 0.325737 0.325369 v 0.3274 0.295928 0.408636 v 0.316392 0.29076 0.418709 v 0.3085 0.274624 0.423199 v 0.323636 0.272379 0.406602 v 0.429381 0.244458 0.204002 v 0.407084 0.332408 0.277313 v 0.410597 0.257869 0.266264 v -0.0012657 -0.456867 0.290093 v -0.00137093 -0.520579 0.266159 v 0.154137 -0.304206 0.500479 v 0.193482 -0.282873 0.473493 v 0.186367 -0.242201 0.509588 v 0.148993 -0.26399 0.525367 v 0.110332 -0.274916 0.545857 v 0.099347 -0.233134 0.560204 v 0.0558865 -0.227615 0.569605 v 0.0659185 -0.270006 0.563817 v 0.154687 -0.142577 0.51838 v 0.159498 -0.143009 0.513072 v 0.154646 -0.138239 0.502496 v 0.149045 -0.137596 0.50639 v 0.15958 -0.138174 0.517463 v 0.161574 -0.141559 0.511657 v 0.0940387 -0.129288 0.582226 v 0.109215 -0.12609 0.531844 v 0.0782715 -0.117578 0.557129 v 0.264817 0.0151299 0.501573 v 0.280122 0.127096 0.47057 v 0.262508 0.0886748 0.494464 v 0.187613 0.050926 0.529248 v 0.207829 0.0868157 0.523449 v 0.231821 -0.0170182 0.518246 v 0.304138 0.164985 0.443485 v 0.343004 0.132813 0.418235 v 0.313621 0.250742 0.418382 v 0.290815 0.22492 0.444303 v 0.355269 -0.194146 0.0276407 v 0.388534 -0.179618 0.0746089 v 0.336544 -0.25083 0.156379 v 0.29365 -0.279868 0.104617 v 0.389288 0.153006 0.345258 v 0.39155 0.205715 0.320166 v 0.127262 0.566927 -0.64996 v 0.000868155 0.562946 -0.661419 v 0.000850617 0.724441 -0.605705 v 0.118774 0.725955 -0.596105 v 0.21095 0.754513 0.387525 v 0.133734 -0.133188 0.514651 v 0.131302 -0.13393 0.53047 v 0.0671053 -0.326445 0.551902 v 0.0661056 -0.374553 0.504765 v 0.117289 -0.365439 0.489939 v 0.116552 -0.318792 0.528974 v 0.288249 -0.135286 0.424736 v 0.39393 0.0544045 0.33225 v 0.374655 0.0965379 0.38044 v 0.000792155 1 -0.0074948 v 0.0731795 0.993937 -0.182792 v 0.000868155 0.999152 -0.181886 v 0.179405 0.936399 -0.330549 v 0.0842755 0.953459 -0.338026 v 0.141767 0.271455 0.486238 v 0.139978 0.267433 0.490862 v 0.175908 0.259465 0.501362 v 0.175312 0.263359 0.495861 v 0.181597 0.230187 0.495539 v 0.140253 0.240576 0.495341 v 0.336982 0.587763 0.356927 v 0.312043 0.518258 0.416183 v 0.259971 0.350203 0.495411 v 0.250763 0.331028 0.496036 v 0.114179 0.255893 0.495902 v 0.111069 0.276518 0.499456 v 0.125433 0.293116 0.500415 v 0.124965 0.282353 0.489968 v 0.13906 0.254928 0.497457 v 0.17737 0.2462 0.50062 v 0.121796 0.272327 0.47658 v 0.149548 0.0847578 0.549377 v 0.142825 -0.226381 0.544992 v 0.106181 -0.197232 0.576871 v 0.258193 -0.146669 0.465227 v 0.2105 0.0188071 0.525711 v 0.181041 -0.0155508 0.531721 v 0.173453 -0.168949 0.5218 v 0.180322 -0.15877 0.514949 v 0.168554 -0.150118 0.516667 v 0.163082 -0.153579 0.523344 v 0.139124 -0.128733 0.545343 v 0.152348 -0.134468 0.527471 v 0.416192 -0.0714636 0.0335278 v 0.0220956 0.0520719 0.640232 v 0.0361615 0.0619695 0.628476 v -0.000283541 0.202056 0.62768 v 0.0869063 -0.0493125 -0.489641 v 0.192289 -0.0534399 -0.447186 v 0.192003 -0.134672 -0.429197 v 0.0851642 -0.130335 -0.46373 v 0.236434 0.310245 0.495686 v 0.237714 0.31211 0.497539 v 0.244636 0.32534 0.496212 v 0.121253 0.281932 0.477293 v 0.173149 -0.207241 0.528208 v -0.000242618 0.247989 0.603612 v -0.00037708 0.28838 0.571697 v 0.108496 -0.160507 0.588207 v 0.0613995 -0.166388 0.620127 v 0.0634222 -0.199565 0.59462 v 0.0893734 0.151176 0.600127 v 0.122124 0.0729427 0.596088 v 0.0993528 0.072475 0.584781 v 0.108315 0.0599584 0.583916 v 0.133524 0.0551528 0.575778 v 0.13315 0.107517 0.580426 v 0.274937 0.384257 0.485735 v 0.170606 -0.145383 0.517205 v 0.0464391 -0.130399 0.611931 v 0.0392892 -0.113439 0.575094 v -0.00161647 -0.112428 0.579865 v -0.00351648 -0.131685 0.617859 v 0.0194356 0.03489 0.601858 v -0.000564158 0.0478802 0.644208 v -2.04632e-05 0.0350303 0.598835 v 0.222163 0.246884 0.4972 v 0.217802 0.257547 0.498129 v 0.293159 0.278716 0.430419 v 0.302852 0.281932 0.427367 v 0.285209 0.277366 0.434932 v 0.289307 0.275834 0.436551 v 0.290061 0.280494 0.427963 v -0.000225079 -0.384287 0.444245 v 0.0651001 -0.383883 0.440585 v -0.000891543 -0.364076 0.502426 v 0.116576 -0.381784 0.436341 v 0.363734 0.712842 -0.467571 v 0.32166 0.832542 -0.392653 v 0.376508 0.821429 -0.265451 v 0.427095 0.698004 -0.319575 v 0.27178 0.90956 -0.29643 v 0.310423 0.901357 -0.210644 v 0.441869 0.677005 -0.175175 v 0.389019 0.807076 -0.128411 v 0.313311 0.894506 -0.0788532 v 0.12783 -0.376125 0.378248 v 0.0722266 -0.391483 0.37664 v 0.125579 0.302411 0.505741 v 0.101656 0.861358 -0.486525 v 0.214084 0.849981 -0.463327 v 0.2467 0.723207 -0.559263 v 0.104913 0.117397 -0.600268 v 0.221579 0.117865 -0.555159 v 0.200848 0.0268164 -0.488992 v 0.0944011 0.0271204 -0.539134 v 0.391141 0.144178 -0.303545 v 0.331241 0.130393 -0.444613 v 0.360829 0.250357 -0.491155 v 0.424003 0.258021 -0.333419 v 0.000868155 0.23912 -0.655479 v 0.00089154 0.393909 -0.675105 v 0.125626 0.397949 -0.664716 v 0.115418 0.240453 -0.645617 v 0.452175 0.547687 -0.348309 v 0.450217 0.395605 -0.350776 v 0.383015 0.40193 -0.511868 v 0.3854 0.562496 -0.506472 v 0.464078 0.52881 -0.195929 v 0.311698 0.866351 0.071908 v -9.64635e-05 -0.406882 0.376985 v 0.373883 -0.18312 -0.115123 v 0.389189 -0.0789467 -0.141776 v 0.247109 0.197607 0.47589 v 0.22891 0.231497 0.489717 v 0.121077 -0.116725 0.574393 v 0.125626 -0.0895459 0.583057 v 0.110548 -0.128452 0.555428 v 0.000710309 0.959638 0.167019 v 0.000710309 0.881206 0.320973 v 0.224163 0.124079 0.505215 v 0.255305 0.260798 0.480649 v 0.25188 0.263516 0.478322 v 0.214891 0.26119 0.49413 v 0.116476 0.273741 0.475423 v 0.290704 0.283902 0.433377 v 0.29641 0.299523 0.422813 v 0.29406 0.288222 0.418078 v 0.142655 0.263364 0.482467 v 0.121638 0.267831 0.470296 v 0.171711 0.256898 0.489693 v 0.246864 0.257401 0.473821 v 0.274311 0.271648 0.453301 v 0.274539 0.26862 0.446654 v 0.233686 0.331104 0.49074 v 0.187548 0.326632 0.49682 v 0.296971 0.273928 0.433476 v 0.134067 -0.0744861 0.577333 v 0.237434 0.052867 0.514604 v 0.0637905 0.27076 0.54346 v 0.375421 0.514218 0.287328 v 0.353808 -0.333437 -0.190615 v 0.349365 -0.276331 -0.333858 v 0.323337 -0.214946 -0.338453 v 0.356725 -0.247925 -0.205557 v -0.000330311 -0.581268 0.237302 v 0.092922 -0.548418 0.185458 v 0.394783 -0.0876049 -0.0664009 v 0.358315 -0.197624 -0.02995 v 0.292785 -0.321493 0.0377429 v 0.395175 -0.0904345 -0.0143524 v 0.243385 0.243183 -0.602957 v 0.000587539 -0.0451091 -0.498205 v 0.000751232 0.030862 -0.55154 v 0.000809694 0.11928 -0.61144 v 0.000850617 0.862837 -0.491295 v 0.000868155 0.958527 -0.339277 v 0.000423846 -0.128189 -0.469085 v 0.264186 0.56961 -0.608026 v 0.35127 -0.283317 -0.0863656 v 0.196201 -0.209591 -0.418785 v 0.0873097 -0.206341 -0.44839 v 0.000488154 -0.206259 -0.449945 v 0.263397 0.402579 -0.621226 v 0.456683 0.384813 -0.0591516 v 0.457776 0.372302 -0.191281 v 0.000850617 0.671351 0.512487 v 0.000809694 0.77919 0.437668 v 0.408656 0.116286 0.298547 v 0.295913 0.259781 0.439334 v 0.285355 0.265481 0.449775 v 0.278766 0.270035 0.454663 v 0.128946 -0.0227065 0.564741 v 0.16203 0.016989 0.534633 v 0.0985987 0.0583799 0.58087 v 0.0538462 0.323165 0.543729 v 0.0794758 0.301522 0.528465 v -0.00330601 -0.197759 0.600525 v -0.000511542 -0.225551 0.572931 v -0.00456879 -0.164231 0.628277 v -0.000336157 -0.26392 0.574381 v -0.000768774 -0.325515 0.55686 v 0.269921 0.242499 0.464742 v 0.260573 0.253022 0.476072 v 0.235066 0.15963 0.493271 v 0.411369 0.186119 0.273583 v 0.000178307 0.0131539 0.584682 v 0.153436 -0.0554568 0.55786 v 0.0264569 0.331747 0.554112 v -0.000342003 0.332998 0.557743 v 0.285589 0.277974 0.428156 v 0.184795 -0.499655 0.1217 v 0.332808 -0.386298 -0.0699261 v 0.20739 -0.274419 -0.415909 v 0.0927467 -0.274308 -0.43723 v 0.278029 -0.438791 0.0475586 v 0.000505693 -0.27722 -0.43768 v 0.438191 0.12488 -0.0367783 v 0.460214 0.163208 -0.055258 v 0.485388 0.177437 -0.0277343 v 0.472304 0.161641 -0.00367724 v 0.496244 0.232684 -0.0170708 v 0.477425 0.247036 0.00446648 v 0.517015 0.298681 -0.0523876 v 0.492233 0.31788 -0.0441737 v 0.53425 0.316407 -0.124009 v 0.511491 0.332595 -0.129276 v 0.535904 0.290111 -0.170685 v 0.511128 0.30365 -0.186838 v 0.538611 0.228878 -0.193017 v 0.511286 0.231199 -0.218992 v 0.520242 0.128838 -0.191421 v 0.490433 0.122168 -0.208603 v 0.487562 0.00951757 -0.0819458 v 0.472286 -0.00658864 -0.0930419 v 0.47079 0.0399937 -0.154257 v 0.496437 0.0472722 -0.136917 v 0.485142 -0.0247586 -0.0238758 v 0.46129 -0.0429694 -0.0334343 v 0.474888 0.238927 -0.0419989 v 0.495232 0.289088 -0.0628581 v 0.508398 0.299996 -0.11766 v 0.51311 0.283323 -0.158478 v 0.514642 0.235303 -0.176531 v 0.501751 0.136134 -0.181559 v 0.486025 0.0533522 -0.11859 v 0.486451 0.0268164 -0.067155 v 0.482529 0.0136625 -0.0120607 v 0.464265 0.0280383 0.0249515 v 0.457519 -0.0185791 0.0196256 v 0.442769 0.0582571 -0.0293244 v 0.45632 0.0847169 -0.0600578 v 0.442465 0.0842785 -0.0209644 v 0.459612 0.268106 0.0209995 v 0.458559 0.182857 0.0414318 v 0.463026 0.318488 -0.0446005 v 0.470222 0.311835 -0.142898 v 0.455063 0.232836 -0.195221 v 0.43839 0.13186 -0.191088 v 0.424564 0.0473131 -0.148417 v 0.423447 -0.00471202 -0.0897563 v 0.425377 -0.0292075 -0.0262143 v 0.430714 -0.0102191 0.0297161 v 0.446335 0.0345567 0.0460036 v 0.475607 0.129364 -0.0864649 v 0.482611 0.0600636 -0.0525396 v 0.481517 0.0827175 -0.101349 v 0.470503 0.0444835 -0.0133527 v 0.479278 0.0776957 0.00471786 v 0.504692 0.223938 -0.101723 v 0.50375 0.131866 -0.1473 v 0.45452 0.100016 0.0450097 v 0.403623 0.0251386 -0.16934 v 0.414719 0.138607 -0.218957 v 0.435461 0.249632 -0.229924 v -0.000201695 -0.407876 0.310666 v 0.000347846 -0.171521 0.505794 v 0.0884205 -0.186598 0.484028 v 0.141147 -0.173807 0.465513 v 0.159878 -0.142255 0.458644 v 0.152483 -0.116468 0.431278 v 0.0708352 0.0121893 0.376371 v 0.128069 -0.116368 0.360528 v 0.143994 -0.166791 0.41184 v 0.0748398 -0.218144 0.372349 v 0.280941 0.292858 0.454897 v 0.281356 0.319879 0.451494 v 0.127268 0.269088 0.455435 v 0.116921 0.284697 0.447653 v 0.119996 0.274998 0.469126 v 0.15699 0.254759 0.466326 v 0.265916 0.273601 0.421176 v 0.214885 0.253946 0.455259 v 0.141223 0.313133 0.482117 v 0.211436 0.255823 0.486852 v 0.277135 0.302686 0.410799 v 0.252505 0.333881 0.433599 v 0.202023 0.342182 0.464578 v 0.11989 0.295816 0.471196 v 0.146526 0.322539 0.455943 v 0.126292 0.301838 0.454973 v 0.119744 0.284878 0.469419 v 0.00103185 0.0191579 0.374711 v 0.000909079 -0.205715 0.379849 v 0.0536357 -0.100847 0.27211 v 0.00103185 -0.098929 0.27128 v 0.255463 -0.398733 -0.446098 v 0.412907 -0.372688 -0.332858 v 0.452596 -0.41557 -0.353559 v 0.293329 -0.465367 -0.476007 v 0.0815337 -0.637104 0.176286 v 0.0726358 -0.738524 0.179519 v 0.174763 -0.714911 0.155526 v 0.172032 -0.601823 0.129884 v 0.380782 -0.504069 -0.184377 v 0.357368 -0.419095 -0.180384 v 0.337538 -0.494803 -0.0548371 v 0.372989 -0.619402 -0.0373571 v 0.453578 -0.652661 -0.0939539 v 0.452351 -0.545892 -0.196981 v 0.173576 -0.814197 0.195654 v 0.0739044 -0.845866 0.20734 v 0.0964414 -0.904976 0.254455 v 0.197703 -0.864562 0.243353 v 0.519564 -0.487407 -0.384801 v 0.555004 -0.584226 -0.219366 v 0.451357 -0.731555 -0.0215899 v 0.382594 -0.74824 0.0443666 v 0.439805 -0.799196 0.0975376 v 0.519108 -0.768071 -0.00769357 v 0.274837 -0.806199 0.115503 v 0.320508 -0.838061 0.183769 v 0.354533 -0.544232 -0.525256 v 0.162503 -0.604343 -0.559076 v 0.131098 -0.496837 -0.498761 v 0.115161 -0.410103 -0.457756 v -0.00017831 -0.492774 -0.504192 v 2.046e-05 -0.40666 -0.465186 v -0.000482311 -0.600531 -0.555322 v 0.546217 -0.696736 -0.117257 v 0.22746 -0.332063 -0.424345 v 0.101627 -0.33885 -0.437002 v 0.280193 -0.554165 0.0658922 v 0.274843 -0.684891 0.0781517 v 0.000347846 -0.34199 -0.438165 v 0.000733693 -0.746364 0.176765 v 0.000312769 -0.874904 0.179121 v 0.378648 -0.322586 -0.326994 v -0.000114002 -0.940246 0.234262 v 0.000979233 -0.650317 0.207112 v -0.130513 -0.13217 0.498924 v -0.133687 -0.14723 0.488109 v -0.15222 -0.140519 0.477457 v -0.14666 -0.13514 0.489746 v -0.0697653 -0.0999404 0.550318 v -0.0736414 -0.0473131 0.499649 v -0.0305784 -0.0972511 0.55389 v -0.0396517 -0.109762 0.550014 v -0.0358517 -0.127727 0.53534 v -0.0742493 -0.135994 0.523315 v -0.0733373 -0.115561 0.537643 v -0.106766 -0.144336 0.504823 v -0.106281 -0.125786 0.515779 v -0.156505 -0.107798 0.467782 v -0.155611 -0.123682 0.486899 v -0.159311 -0.130796 0.484958 v -0.162872 -0.126996 0.470243 v -0.159919 -0.135625 0.47627 v -0.154055 -0.134696 0.486513 v -0.142597 -0.118993 0.499994 v -0.130051 -0.0726738 0.476189 v -0.10054 -0.105798 0.538111 v -0.125684 -0.115824 0.51596 v -0.274604 -0.301394 0.247527 v -0.220831 -0.335775 0.330215 v -0.250102 -0.275554 0.380393 v -0.3066 -0.239804 0.292309 v -0.284302 -0.0258401 0.479772 v -0.319479 0.00809111 0.449577 v -0.331873 -0.0412272 0.412243 v -0.293674 -0.0747667 0.452418 v -0.294668 -0.0547787 -0.357622 v -0.302063 -0.144319 -0.34334 v -0.356012 -0.159916 -0.223184 v -0.355474 -0.0633082 -0.24271 v -0.447241 0.22613 0.139332 v -0.437922 0.336149 0.131124 v -0.449486 0.331215 0.047962 v -0.454982 0.205353 0.0827818 v -0.103311 -0.419241 0.249936 v -0.203701 -0.353384 0.208147 v -0.196966 -0.411506 0.138841 v -0.101797 -0.475733 0.208638 v -0.196499 -0.327216 0.427455 v -0.176283 -0.362363 0.392138 v -0.150331 -0.372548 0.431378 v -0.155575 -0.349484 0.46435 v -0.0890109 -0.391945 0.303855 v -0.158306 -0.363848 0.305182 v -0.415613 0.611627 0.0817705 v -0.430808 0.648493 -0.0417066 v -0.45411 0.508986 -0.0641209 v -0.440308 0.483438 0.0478393 v -0.389808 0.40462 0.306977 v -0.375935 0.38348 0.354021 v -0.34643 0.433026 0.398499 v -0.354807 0.467378 0.356891 v -0.317409 0.30382 0.429121 v -0.30173 0.320499 0.456861 v -0.309295 0.339493 0.457756 v -0.328406 0.316144 0.429519 v -0.358297 0.360101 0.389344 v -0.335684 0.397733 0.427864 v -0.285156 0.29304 0.457387 v -0.294212 0.310695 0.451757 v -0.307675 0.294425 0.430781 v -0.29475 0.281949 0.435698 v -0.421091 0.455996 0.145494 v -0.395403 0.565208 0.19252 v -0.321999 0.364421 0.449238 v -0.345494 0.336792 0.417218 v -0.178165 0.560672 0.512335 v -0.249354 0.546354 0.466589 v -0.243286 0.479638 0.494943 v -0.170168 0.4781 0.536796 v -0.164123 0.410647 0.547114 v -0.236966 0.427297 0.516007 v -0.270669 0.634748 0.422187 v -0.195815 0.657882 0.47347 v -0.14597 0.313039 0.508126 v -0.18946 0.324971 0.513312 v -0.186823 0.312829 0.511757 v -0.144895 0.300213 0.501871 v -0.186911 0.310514 0.506612 v -0.143462 0.300341 0.494353 v -0.160048 0.365076 0.528073 v -0.219468 0.382854 0.516404 v -0.15782 0.334506 0.520076 v -0.205952 0.349935 0.517012 v -0.195236 0.332495 0.516264 v -0.151653 0.320785 0.513142 v -0.0805691 0.0827468 0.603261 v -0.0493739 0.08878 0.593591 v -0.0448723 0.0732117 0.617958 v -0.0594819 0.0761932 0.621314 v -0.422927 0.0771812 0.237185 v -0.432205 0.159355 0.215905 v -0.448112 0.130656 0.149516 v -0.4282 0.0348607 0.166897 v -0.311779 -0.172912 0.334378 v -0.324787 -0.103758 0.371735 v -0.364851 -0.052639 0.316097 v -0.367254 -0.126698 0.269146 v -0.183918 -0.149136 0.51793 v -0.182024 -0.137865 0.527822 v -0.205163 -0.131463 0.524127 v -0.205514 -0.152071 0.514943 v -0.39379 0.00614433 0.269368 v -0.400951 -0.0591282 0.208995 v -0.261011 -0.0993382 0.483865 v -0.25102 -0.0551177 0.50328 v -0.158849 -0.136444 0.499199 v -0.155155 -0.134784 0.503397 v -0.145304 -0.133848 0.514902 v -0.160802 -0.128394 0.536919 v -0.173424 -0.121349 0.541327 v -0.169156 -0.138478 0.524928 v -0.232096 -0.116964 0.50767 v -0.232727 -0.151188 0.49696 v -0.326085 0.202611 0.415651 v -0.34094 0.235683 0.392156 v -0.367727 0.221336 0.359031 v -0.358829 0.177595 0.3841 v -0.295603 0.0501836 0.478632 v -0.32232 0.0902006 0.449922 v -0.351843 0.04895 0.416686 v -0.367248 0.00336155 0.369624 v -0.156137 -0.154941 0.536878 v -0.165134 -0.177028 0.538193 v -0.144573 -0.187364 0.558725 v -0.140533 -0.155882 0.559046 v -0.17761 -0.0804258 0.547933 v -0.201667 -0.0484356 0.526945 v -0.22024 -0.0817529 0.517585 v -0.195826 -0.106131 0.536439 v -0.207794 -0.213087 0.493049 v -0.191711 -0.188305 0.515551 v -0.201111 -0.170071 0.510745 v -0.223385 -0.183243 0.490178 v -0.128595 -0.132761 0.551212 v -0.145777 -0.139513 0.530605 v -0.0971664 0.171538 0.569909 v -0.120048 0.150182 0.555387 v -0.13557 0.119437 0.545004 v -0.113103 0.137432 0.569453 v -0.0653573 0.232432 0.569575 v -0.08745 0.217992 0.556468 v -0.0739395 0.185388 0.584933 v -0.0855266 0.255554 0.53095 v -0.110583 0.228714 0.525501 v -0.115915 0.191404 0.5495 v -0.300099 0.0366964 -0.387999 v -0.364734 0.0377897 -0.269357 v -0.223181 -0.243207 0.45081 v -0.246139 -0.195666 0.45347 v -0.271201 -0.199869 0.399446 v -0.362846 -0.197443 0.213286 v -0.410176 -0.124757 0.140565 v -0.430404 -0.00290555 0.0907385 v -0.448779 0.11075 0.0889086 v -0.142135 0.869847 0.301633 v -0.132167 0.771303 0.419317 v -0.0633989 0.777407 0.43288 v -0.0675789 0.877324 0.315577 v -0.353469 0.660735 0.264732 v -0.2875 0.723792 0.335465 v -0.30353 0.809117 0.220313 v -0.37099 0.728422 0.148627 v -0.381016 0.776764 0.0117274 v -0.0996744 0.472587 0.557146 v -0.109525 0.565325 0.53475 v -0.100294 0.277787 0.511248 v -0.108689 0.248457 0.503268 v -0.0528874 0.193947 0.604898 v -0.0453926 0.241125 0.586705 v -0.12255 0.668732 0.500514 v -0.0511336 0.564922 0.542589 v -0.0582191 0.671655 0.50974 v -0.0440363 0.465776 0.561151 v -0.0361966 0.388923 0.562367 v -0.301894 0.466338 0.448542 v -0.295831 0.424807 0.472166 v -0.140867 0.22264 0.499754 v -0.185742 0.209381 0.492394 v -0.186338 0.179495 0.502724 v -0.145859 0.19535 0.519018 v -0.0600022 0.0437294 0.578309 v -0.113337 0.0407946 0.564875 v -0.114196 0.0121659 0.564255 v -0.0686019 -0.00676987 0.598064 v -0.143661 0.0637116 0.537807 v -0.147607 0.0440217 0.535469 v -0.0907706 -0.0459919 0.600525 v -0.0300113 -0.0346152 0.623594 v -0.028047 -0.0138554 0.603173 v -0.148028 0.131527 0.5437 v -0.148519 0.164868 0.537322 v -0.183164 0.146873 0.520193 v -0.176978 0.112363 0.532908 v -0.147823 0.0979234 0.535574 v -0.165064 0.0766492 0.532955 v -0.120107 0.268649 0.480825 v -0.118558 0.262394 0.493353 v -0.115979 0.27287 0.494434 v -0.116476 0.272952 0.483859 v -0.229115 0.916634 0.120496 v -0.223379 0.848952 0.271461 v -0.145146 0.945128 0.150709 v -0.145409 0.980883 -0.0176788 v -0.154278 0.976311 -0.1834 v -0.240088 0.945514 -0.185786 v -0.230512 0.948548 -0.0401515 v -0.0669533 0.995411 -0.00979819 v -0.0669124 0.955581 0.163097 v -0.0891746 0.383199 0.554861 v -0.112226 0.336757 0.527307 v -0.123381 0.311174 0.513382 v -0.149484 -0.111966 0.558549 v -0.160264 -0.0991219 0.559216 v -0.0695139 0.122828 0.646821 v -0.103574 0.1197 0.616608 v -0.0967747 0.0873945 0.617683 v -0.0583127 0.0845006 0.640951 v -0.0810075 0.0824603 0.567973 v -0.0347818 0.058339 0.594989 v -0.031812 -0.0520134 0.636181 v -0.0876079 -0.0656701 0.61341 v -0.0905251 -0.101683 0.607529 v -0.0378686 -0.0937434 0.629054 v -0.0836617 -0.122507 0.579642 v -0.0385351 -0.11728 0.594673 v -0.0223295 0.0177081 0.586652 v -0.0307538 0.0864766 0.665646 v -0.0369098 0.125196 0.667078 v -0.0659946 0.154643 0.629212 v -0.0379446 0.159028 0.648136 v -0.0287544 0.19984 0.620642 v -0.0228205 0.245931 0.598298 v -0.0444456 0.281523 0.558544 v -0.0233467 0.287164 0.569581 v -0.348774 0.267521 0.384632 v -0.352083 0.30296 0.39367 v -0.371253 0.315308 0.363077 v -0.374871 0.266369 0.352501 v -0.422202 0.335746 0.207253 v -0.401928 0.429197 0.234116 v -0.395345 0.264083 0.313998 v -0.391071 0.32586 0.325679 v -0.312703 0.275793 0.421661 v -0.320315 0.291642 0.417107 v -0.332077 0.295173 0.409057 v -0.327599 0.271742 0.406824 v -0.429802 0.244434 0.203979 v -0.409282 0.332454 0.277442 v -0.411848 0.257886 0.266369 v -0.187414 -0.242265 0.510307 v -0.193763 -0.283183 0.474066 v -0.155254 -0.304954 0.501777 v -0.149998 -0.264183 0.526518 v -0.0567108 -0.227311 0.569523 v -0.101124 -0.233508 0.561461 v -0.11039 -0.27508 0.546021 v -0.066205 -0.270351 0.564711 v -0.154225 -0.138052 0.502391 v -0.159867 -0.142787 0.513271 v -0.15533 -0.142366 0.518626 v -0.148566 -0.137426 0.506285 v -0.160416 -0.138344 0.518258 v -0.161965 -0.141513 0.511996 v -0.110811 -0.126394 0.533276 v -0.10089 -0.129879 0.583501 v -0.0809374 -0.117865 0.558397 v -0.263876 0.014785 0.500935 v -0.26083 0.088932 0.49537 v -0.279702 0.127055 0.470506 v -0.207764 0.0867397 0.523776 v -0.187729 0.0509786 0.529558 v -0.232096 -0.0167025 0.518065 v -0.344056 0.133304 0.417078 v -0.302046 0.166376 0.445239 v -0.292551 0.225429 0.44414 v -0.316041 0.250468 0.418475 v -0.335386 -0.250836 0.156385 v -0.387207 -0.179618 0.074568 v -0.353755 -0.194151 0.0276524 v -0.292388 -0.279891 0.104617 v -0.392211 0.205733 0.320201 v -0.386651 0.150025 0.344942 v -0.126064 0.567371 -0.651942 v -0.117096 0.725914 -0.596082 v -0.209068 0.754227 0.387245 v -0.134091 -0.133281 0.515294 v -0.132384 -0.133778 0.530774 v -0.118289 -0.366228 0.490722 v -0.0673742 -0.375085 0.505343 v -0.0685259 -0.327012 0.553422 v -0.117722 -0.319453 0.530388 v -0.287793 -0.13528 0.424643 v -0.375234 0.0965671 0.380457 v -0.394351 0.054463 0.33218 v -0.0714373 0.993797 -0.182751 v -0.0825568 0.953558 -0.338084 v -0.177458 0.935674 -0.330221 v -0.176961 0.259482 0.501637 v -0.139651 0.267463 0.490903 v -0.141176 0.271537 0.486156 v -0.175792 0.263446 0.495797 v -0.139621 0.240295 0.49489 v -0.181918 0.230053 0.49499 v -0.335299 0.587722 0.356851 v -0.311189 0.51838 0.416464 v -0.263028 0.350391 0.495528 v -0.252435 0.331198 0.496568 v -0.111168 0.276448 0.500608 v -0.113553 0.255671 0.49582 v -0.124754 0.293525 0.500263 v -0.124275 0.282616 0.489933 v -0.138587 0.254671 0.496603 v -0.17851 0.246346 0.500783 v -0.120744 0.272286 0.476557 v -0.150635 0.0843194 0.549231 v -0.110981 -0.197039 0.578654 v -0.145877 -0.226522 0.547184 v -0.257825 -0.146365 0.464946 v -0.181813 -0.015013 0.533586 v -0.21057 0.0188715 0.525811 v -0.169226 -0.14996 0.516989 v -0.181743 -0.1588 0.515902 v -0.175376 -0.168545 0.522911 v -0.163813 -0.153415 0.52335 v -0.140253 -0.128364 0.545887 v -0.153091 -0.134363 0.527834 v -0.414608 -0.0714286 0.0335337 v -0.0376523 0.063203 0.628721 v -0.0232707 0.0530365 0.640016 v -0.190483 -0.134521 -0.42891 v -0.190425 -0.0530365 -0.446291 v -0.0856669 -0.0492716 -0.489617 v -0.0841703 -0.13027 -0.463549 v -0.238743 0.312729 0.498784 v -0.236568 0.310718 0.495914 v -0.245034 0.325784 0.495083 v -0.120311 0.281967 0.47734 v -0.176107 -0.207054 0.530523 v -0.114635 -0.15994 0.588938 v -0.0702155 -0.19877 0.595006 v -0.0735478 -0.165324 0.619338 v -0.0899814 0.151661 0.600396 v -0.111016 0.0572925 0.58557 v -0.101867 0.0715163 0.586237 v -0.127064 0.0733753 0.597824 v -0.136833 0.0543987 0.574241 v -0.135833 0.107312 0.581379 v -0.278287 0.38386 0.485911 v -0.171226 -0.145371 0.517737 v -0.0426215 -0.114106 0.575498 v -0.0575293 -0.131258 0.610721 v -0.0203535 0.0339429 0.602828 v -0.224215 0.246978 0.496697 v -0.219644 0.257664 0.498129 v -0.308126 0.284604 0.426215 v -0.296275 0.279026 0.430641 v -0.291721 0.275554 0.437358 v -0.286612 0.276705 0.435172 v -0.291949 0.280143 0.428238 v -0.065825 -0.384532 0.440825 v -0.11702 -0.382428 0.436651 v -0.374667 0.821265 -0.265393 v -0.3198 0.831958 -0.392208 v -0.362179 0.712818 -0.467507 v -0.425879 0.698185 -0.319692 v -0.269938 0.909215 -0.296313 v -0.308015 0.900609 -0.210562 v -0.440407 0.677046 -0.175192 v -0.387417 0.807117 -0.128411 v -0.312037 0.894728 -0.0788123 v -0.0720161 -0.391612 0.376675 v -0.127765 -0.376523 0.378341 v -0.124801 0.303066 0.504835 v -0.0997913 0.860855 -0.486022 v -0.212687 0.850449 -0.463771 v -0.245244 0.723306 -0.559461 v -0.199083 0.0271847 -0.488407 v -0.21986 0.118005 -0.554936 v -0.10327 0.117479 -0.600127 v -0.0928636 0.0273016 -0.53883 v -0.389259 0.144254 -0.303446 v -0.329178 0.130557 -0.444432 v -0.359227 0.250316 -0.491237 v -0.422325 0.258021 -0.333419 v -0.123907 0.397932 -0.664658 v -0.113699 0.240517 -0.645459 v -0.381641 0.401913 -0.512072 v -0.448592 0.395605 -0.3508 v -0.450574 0.547705 -0.348333 v -0.384366 0.562601 -0.506817 v -0.462722 0.528827 -0.195952 v -0.310604 0.866976 0.0721301 v -0.372013 -0.183143 -0.115123 v -0.387686 -0.0789994 -0.141781 v -0.2476 0.197566 0.475487 v -0.230342 0.231532 0.488372 v -0.129238 -0.0890256 0.584927 v -0.123544 -0.115971 0.574872 v -0.114588 -0.128867 0.557082 v -0.221702 0.122764 0.506442 v -0.216107 0.26119 0.49413 v -0.253242 0.263207 0.478422 v -0.256568 0.260547 0.479737 v -0.115342 0.273619 0.475323 v -0.298743 0.299903 0.422953 v -0.291698 0.283732 0.432722 v -0.295854 0.288181 0.418253 v -0.142059 0.263388 0.482491 v -0.120428 0.267802 0.470325 v -0.172108 0.256934 0.489641 v -0.275083 0.271584 0.453242 v -0.248582 0.25684 0.473757 v -0.275001 0.268573 0.446274 v -0.234253 0.331396 0.490634 v -0.187624 0.326819 0.49717 v -0.300292 0.274694 0.432944 v -0.135658 -0.0739483 0.577444 v -0.237428 0.052791 0.514919 v -0.0645564 0.270789 0.544612 v -0.373819 0.514195 0.287264 v -0.321852 -0.214718 -0.338184 v -0.348166 -0.27584 -0.333396 v -0.352171 -0.333378 -0.190533 v -0.354936 -0.247872 -0.205511 v -0.0936937 -0.549137 0.186785 v -0.35669 -0.197653 -0.0299733 v -0.393228 -0.0876225 -0.0664009 v -0.29161 -0.321499 0.0380294 v -0.393638 -0.0904403 -0.014329 v -0.241608 0.243201 -0.602916 v -0.263209 0.569914 -0.609242 v -0.349441 -0.283282 -0.0863831 v -0.194821 -0.209504 -0.418674 v -0.0862925 -0.206323 -0.448413 v -0.261795 0.402579 -0.621448 v -0.456233 0.372302 -0.191263 v -0.455245 0.384813 -0.0591282 v -0.408072 0.116608 0.297155 v -0.298661 0.260278 0.439147 v -0.287606 0.265861 0.450068 v -0.279696 0.270216 0.454289 v -0.162731 0.0172638 0.536515 v -0.13087 -0.0222973 0.565699 v -0.101475 0.0572691 0.580946 v -0.0809198 0.301049 0.528407 v -0.0556351 0.322972 0.54498 v -0.272306 0.242932 0.464508 v -0.262964 0.253017 0.476001 v -0.233067 0.158607 0.487893 v -0.412053 0.186142 0.273695 v -0.154815 -0.0532762 0.55793 v -0.0277489 0.331782 0.556427 v -0.286179 0.277611 0.427928 v -0.183941 -0.499632 0.122144 v -0.331493 -0.386257 -0.0698735 v -0.206238 -0.274279 -0.416026 v -0.0915482 -0.274332 -0.437317 v -0.277193 -0.438779 0.0481257 v -0.484037 0.177414 -0.0276816 v -0.458618 0.163319 -0.0553633 v -0.437233 0.124752 -0.0367315 v -0.471526 0.1616 -0.00366555 v -0.476232 0.247018 0.00445479 v -0.494987 0.232631 -0.0169773 v -0.491035 0.317921 -0.0441971 v -0.515688 0.298728 -0.0523583 v -0.510175 0.332513 -0.1293 v -0.532917 0.316524 -0.12405 v -0.50993 0.303592 -0.186815 v -0.534671 0.290233 -0.170849 v -0.510152 0.231181 -0.21891 v -0.537459 0.228895 -0.193058 v -0.48934 0.122068 -0.20872 v -0.519208 0.128879 -0.191363 v -0.469632 0.0399528 -0.15424 v -0.470766 -0.00661202 -0.0930419 v -0.486142 0.00947665 -0.0819458 v -0.495221 0.0472722 -0.1369 v -0.459705 -0.0431682 -0.033446 v -0.483546 -0.0248521 -0.0238816 v -0.494011 0.289082 -0.0628932 v -0.473502 0.238904 -0.0420457 v -0.507246 0.300137 -0.117724 v -0.512134 0.2833 -0.158502 v -0.513712 0.235303 -0.176549 v -0.50102 0.136093 -0.181582 v -0.485095 0.0532704 -0.118549 v -0.485253 0.0267755 -0.0671726 v -0.481172 0.0136801 -0.012201 v -0.456127 -0.0187428 0.0196958 v -0.462909 0.027933 0.024969 v -0.454923 0.0845591 -0.060163 v -0.441284 0.0577602 -0.0294063 v -0.440921 0.0840388 -0.0210813 v -0.457712 0.18288 0.0414318 v -0.458378 0.268123 0.0210228 v -0.461588 0.318505 -0.044618 v -0.468843 0.311858 -0.142898 v -0.453707 0.232836 -0.195204 v -0.436969 0.13182 -0.191047 v -0.423167 0.0473306 -0.148288 v -0.421945 -0.00467109 -0.089692 v -0.423991 -0.0291198 -0.0260915 v -0.429434 -0.0102776 0.0297746 v -0.445242 0.0345158 0.0460211 v -0.481617 0.0602039 -0.0524227 v -0.474104 0.129276 -0.0866754 v -0.480325 0.0824545 -0.101285 v -0.469474 0.0446648 -0.013376 v -0.478167 0.0776431 0.00467109 v -0.503592 0.223961 -0.101887 v -0.502575 0.131983 -0.147242 v -0.453707 0.0999988 0.0450097 v -0.413357 0.138549 -0.218945 v -0.402232 0.0251035 -0.169299 v -0.434023 0.249632 -0.229901 v -0.0871226 -0.186639 0.484069 v -0.139686 -0.173807 0.465537 v -0.158481 -0.142278 0.458685 v -0.0688299 0.0121893 0.376371 v -0.150805 -0.116468 0.431278 v -0.126228 -0.116368 0.360528 v -0.142316 -0.166791 0.41184 v -0.0730392 -0.218144 0.372349 v -0.282087 0.293548 0.454716 v -0.283513 0.320341 0.45129 v -0.124398 0.285323 0.452968 v -0.126795 0.269175 0.455978 v -0.119353 0.275057 0.469524 v -0.156265 0.2548 0.466332 v -0.265074 0.27356 0.421036 v -0.214762 0.253899 0.455218 v -0.141855 0.312577 0.484315 v -0.212745 0.255776 0.486875 v -0.277117 0.302621 0.410811 v -0.252014 0.333887 0.433371 v -0.20141 0.342405 0.464461 v -0.120767 0.295565 0.473184 v -0.145333 0.322832 0.456154 v -0.126041 0.301873 0.455785 v -0.119879 0.284837 0.470541 v -0.0516539 -0.100847 0.27211 v -0.454245 -0.41571 -0.353027 v -0.413392 -0.372097 -0.332203 v -0.255785 -0.398019 -0.4467 v -0.294685 -0.464338 -0.476902 v -0.174388 -0.714777 0.156607 v -0.0715543 -0.738454 0.180284 v -0.0798266 -0.636725 0.177765 v -0.171536 -0.601788 0.131147 v -0.337345 -0.494639 -0.0546091 v -0.355094 -0.419334 -0.180442 v -0.379665 -0.504905 -0.184915 v -0.373053 -0.619338 -0.0373044 v -0.45328 -0.545816 -0.197379 v -0.454128 -0.653065 -0.0942754 v -0.0965876 -0.904778 0.254759 v -0.0736004 -0.845567 0.20775 v -0.172974 -0.81408 0.195975 v -0.1973 -0.864375 0.243622 v -0.520961 -0.488138 -0.3841 v -0.556272 -0.584635 -0.21946 v -0.439238 -0.799155 0.0975785 v -0.381694 -0.748264 0.0442672 v -0.45103 -0.731883 -0.0219173 v -0.519067 -0.768135 -0.0077988 v -0.273785 -0.806328 0.115322 v -0.319391 -0.83802 0.183769 v -0.163088 -0.604103 -0.559421 v -0.356672 -0.543712 -0.525361 v -0.131226 -0.496761 -0.498854 v -0.114629 -0.410074 -0.45775 v -0.546533 -0.697291 -0.117619 v -0.100633 -0.33885 -0.437013 v -0.22677 -0.331835 -0.424707 v -0.274931 -0.684651 0.0790578 v -0.28021 -0.553908 0.0669913 v -0.378028 -0.321668 -0.326088 v 0.172833 0.300014 0.41564 v -0.171097 0.299996 0.415616 # 1258 vertices vt 0.532 0.923 0.000 vt 0.535 0.917 0.000 vt 0.542 0.923 0.000 vt 0.541 0.929 0.000 vt 0.521 0.984 0.000 vt 0.521 0.996 0.000 vt 0.505 0.998 0.000 vt 0.500 0.985 0.000 vt 0.504 0.917 0.000 vt 0.507 0.910 0.000 vt 0.516 0.910 0.000 vt 0.515 0.918 0.000 vt 0.523 0.921 0.000 vt 0.525 0.913 0.000 vt 0.549 0.958 0.000 vt 0.538 0.954 0.000 vt 0.544 0.942 0.000 vt 0.550 0.946 0.000 vt 0.545 0.935 0.000 vt 0.550 0.932 0.000 vt 0.547 0.974 0.000 vt 0.533 0.967 0.000 vt 0.500 0.917 0.000 vt 0.500 0.910 0.000 vt 0.542 0.987 0.000 vt 0.533 0.994 0.000 vt 0.616 0.254 0.000 vt 0.653 0.261 0.000 vt 0.658 0.307 0.000 vt 0.619 0.292 0.000 vt 0.636 0.438 0.000 vt 0.620 0.419 0.000 vt 0.627 0.396 0.000 vt 0.647 0.414 0.000 vt 0.886 0.312 0.000 vt 0.897 0.370 0.000 vt 0.860 0.369 0.000 vt 0.844 0.308 0.000 vt 0.740 0.593 0.000 vt 0.741 0.542 0.000 vt 0.759 0.541 0.000 vt 0.768 0.598 0.000 vt 0.644 0.213 0.000 vt 0.561 0.175 0.000 vt 0.566 0.146 0.000 vt 0.644 0.174 0.000 vt 0.580 0.254 0.000 vt 0.585 0.277 0.000 vt 0.565 0.268 0.000 vt 0.565 0.256 0.000 vt 0.590 0.217 0.000 vt 0.544 0.195 0.000 vt 0.771 0.721 0.000 vt 0.736 0.712 0.000 vt 0.758 0.653 0.000 vt 0.794 0.663 0.000 vt 0.669 0.622 0.000 vt 0.685 0.632 0.000 vt 0.665 0.669 0.000 vt 0.652 0.651 0.000 vt 0.623 0.588 0.000 vt 0.632 0.582 0.000 vt 0.639 0.590 0.000 vt 0.627 0.599 0.000 vt 0.641 0.632 0.000 vt 0.657 0.612 0.000 vt 0.619 0.580 0.000 vt 0.617 0.575 0.000 vt 0.623 0.573 0.000 vt 0.627 0.576 0.000 vt 0.708 0.702 0.000 vt 0.729 0.646 0.000 vt 0.633 0.614 0.000 vt 0.647 0.601 0.000 vt 0.604 0.718 0.000 vt 0.574 0.725 0.000 vt 0.567 0.686 0.000 vt 0.596 0.682 0.000 vt 0.562 0.648 0.000 vt 0.590 0.649 0.000 vt 0.618 0.756 0.000 vt 0.584 0.769 0.000 vt 0.586 0.587 0.000 vt 0.566 0.586 0.000 vt 0.568 0.579 0.000 vt 0.586 0.580 0.000 vt 0.569 0.574 0.000 vt 0.586 0.573 0.000 vt 0.562 0.627 0.000 vt 0.587 0.627 0.000 vt 0.587 0.610 0.000 vt 0.563 0.608 0.000 vt 0.565 0.595 0.000 vt 0.587 0.596 0.000 vt 0.521 0.441 0.000 vt 0.526 0.450 0.000 vt 0.520 0.450 0.000 vt 0.517 0.445 0.000 vt 0.720 0.504 0.000 vt 0.709 0.467 0.000 vt 0.727 0.446 0.000 vt 0.738 0.494 0.000 vt 0.656 0.383 0.000 vt 0.660 0.348 0.000 vt 0.684 0.368 0.000 vt 0.673 0.403 0.000 vt 0.572 0.371 0.000 vt 0.573 0.365 0.000 vt 0.581 0.364 0.000 vt 0.581 0.374 0.000 vt 0.708 0.400 0.000 vt 0.693 0.431 0.000 vt 0.604 0.401 0.000 vt 0.609 0.383 0.000 vt 0.557 0.364 0.000 vt 0.559 0.365 0.000 vt 0.557 0.366 0.000 vt 0.556 0.364 0.000 vt 0.552 0.367 0.000 vt 0.552 0.364 0.000 vt 0.568 0.377 0.000 vt 0.561 0.374 0.000 vt 0.566 0.370 0.000 vt 0.594 0.377 0.000 vt 0.594 0.363 0.000 vt 0.653 0.551 0.000 vt 0.644 0.534 0.000 vt 0.658 0.523 0.000 vt 0.666 0.545 0.000 vt 0.637 0.480 0.000 vt 0.625 0.458 0.000 vt 0.649 0.459 0.000 vt 0.662 0.434 0.000 vt 0.557 0.345 0.000 vt 0.553 0.353 0.000 vt 0.543 0.349 0.000 vt 0.546 0.337 0.000 vt 0.586 0.403 0.000 vt 0.573 0.392 0.000 vt 0.579 0.382 0.000 vt 0.591 0.389 0.000 vt 0.572 0.343 0.000 vt 0.584 0.331 0.000 vt 0.590 0.347 0.000 vt 0.578 0.353 0.000 vt 0.553 0.358 0.000 vt 0.543 0.355 0.000 vt 0.553 0.499 0.000 vt 0.541 0.507 0.000 vt 0.542 0.484 0.000 vt 0.553 0.477 0.000 vt 0.539 0.532 0.000 vt 0.529 0.541 0.000 vt 0.531 0.513 0.000 vt 0.551 0.538 0.000 vt 0.538 0.552 0.000 vt 0.552 0.521 0.000 vt 0.908 0.437 0.000 vt 0.876 0.429 0.000 vt 0.608 0.340 0.000 vt 0.599 0.314 0.000 vt 0.629 0.336 0.000 vt 0.691 0.326 0.000 vt 0.723 0.365 0.000 vt 0.748 0.426 0.000 vt 0.755 0.489 0.000 vt 0.564 0.825 0.000 vt 0.590 0.868 0.000 vt 0.558 0.886 0.000 vt 0.533 0.834 0.000 vt 0.637 0.789 0.000 vt 0.673 0.755 0.000 vt 0.702 0.774 0.000 vt 0.665 0.817 0.000 vt 0.740 0.787 0.000 vt 0.545 0.727 0.000 vt 0.540 0.686 0.000 vt 0.551 0.550 0.000 vt 0.538 0.572 0.000 vt 0.520 0.546 0.000 vt 0.522 0.517 0.000 vt 0.552 0.775 0.000 vt 0.524 0.777 0.000 vt 0.521 0.728 0.000 vt 0.500 0.687 0.000 vt 0.500 0.651 0.000 vt 0.515 0.650 0.000 vt 0.518 0.687 0.000 vt 0.500 0.727 0.000 vt 0.625 0.671 0.000 vt 0.618 0.644 0.000 vt 0.591 0.533 0.000 vt 0.571 0.539 0.000 vt 0.569 0.527 0.000 vt 0.589 0.518 0.000 vt 0.545 0.436 0.000 vt 0.525 0.427 0.000 vt 0.528 0.413 0.000 vt 0.549 0.425 0.000 vt 0.556 0.449 0.000 vt 0.563 0.439 0.000 vt 0.514 0.395 0.000 vt 0.532 0.396 0.000 vt 0.513 0.409 0.000 vt 0.566 0.511 0.000 vt 0.564 0.490 0.000 vt 0.577 0.478 0.000 vt 0.584 0.500 0.000 vt 0.500 0.408 0.000 vt 0.500 0.394 0.000 vt 0.571 0.457 0.000 vt 0.561 0.468 0.000 vt 0.554 0.561 0.000 vt 0.557 0.563 0.000 vt 0.552 0.569 0.000 vt 0.548 0.569 0.000 vt 0.627 0.847 0.000 vt 0.674 0.871 0.000 vt 0.645 0.898 0.000 vt 0.776 0.920 0.000 vt 0.709 0.921 0.000 vt 0.729 0.888 0.000 vt 0.783 0.887 0.000 vt 0.693 0.947 0.000 vt 0.621 0.920 0.000 vt 0.535 0.642 0.000 vt 0.542 0.618 0.000 vt 0.545 0.599 0.000 vt 0.559 0.383 0.000 vt 0.552 0.377 0.000 vt 0.531 0.470 0.000 vt 0.520 0.472 0.000 vt 0.517 0.456 0.000 vt 0.528 0.457 0.000 vt 0.530 0.438 0.000 vt 0.517 0.436 0.000 vt 0.528 0.383 0.000 vt 0.513 0.384 0.000 vt 0.512 0.374 0.000 vt 0.526 0.374 0.000 vt 0.512 0.367 0.000 vt 0.526 0.366 0.000 vt 0.512 0.362 0.000 vt 0.526 0.362 0.000 vt 0.511 0.422 0.000 vt 0.500 0.384 0.000 vt 0.500 0.375 0.000 vt 0.500 0.362 0.000 vt 0.500 0.367 0.000 vt 0.511 0.472 0.000 vt 0.508 0.457 0.000 vt 0.521 0.491 0.000 vt 0.512 0.519 0.000 vt 0.512 0.491 0.000 vt 0.511 0.550 0.000 vt 0.520 0.576 0.000 vt 0.510 0.583 0.000 vt 0.500 0.457 0.000 vt 0.500 0.472 0.000 vt 0.500 0.491 0.000 vt 0.654 0.584 0.000 vt 0.656 0.568 0.000 vt 0.669 0.567 0.000 vt 0.666 0.589 0.000 vt 0.705 0.639 0.000 vt 0.718 0.591 0.000 vt 0.684 0.563 0.000 vt 0.680 0.592 0.000 vt 0.637 0.575 0.000 vt 0.636 0.566 0.000 vt 0.645 0.567 0.000 vt 0.645 0.579 0.000 vt 0.723 0.546 0.000 vt 0.697 0.592 0.000 vt 0.702 0.554 0.000 vt 0.500 0.163 0.000 vt 0.500 0.137 0.000 vt 0.579 0.298 0.000 vt 0.570 0.317 0.000 vt 0.554 0.307 0.000 vt 0.560 0.287 0.000 vt 0.534 0.318 0.000 vt 0.517 0.314 0.000 vt 0.519 0.296 0.000 vt 0.538 0.300 0.000 vt 0.562 0.362 0.000 vt 0.559 0.363 0.000 vt 0.557 0.362 0.000 vt 0.559 0.360 0.000 vt 0.563 0.365 0.000 vt 0.561 0.368 0.000 vt 0.543 0.360 0.000 vt 0.531 0.358 0.000 vt 0.531 0.351 0.000 vt 0.611 0.437 0.000 vt 0.613 0.475 0.000 vt 0.624 0.497 0.000 vt 0.580 0.445 0.000 vt 0.590 0.466 0.000 vt 0.598 0.418 0.000 vt 0.648 0.501 0.000 vt 0.633 0.516 0.000 vt 0.641 0.554 0.000 vt 0.630 0.541 0.000 vt 0.733 0.331 0.000 vt 0.696 0.288 0.000 vt 0.706 0.252 0.000 vt 0.751 0.313 0.000 vt 0.683 0.535 0.000 vt 0.674 0.508 0.000 vt 0.999 0.696 0.000 vt 0.986 0.778 0.000 vt 0.950 0.772 0.000 vt 0.967 0.695 0.000 vt 0.600 0.811 0.000 vt 0.552 0.361 0.000 vt 0.547 0.367 0.000 vt 0.546 0.364 0.000 vt 0.525 0.254 0.000 vt 0.546 0.261 0.000 vt 0.542 0.280 0.000 vt 0.522 0.274 0.000 vt 0.631 0.369 0.000 vt 0.678 0.460 0.000 vt 0.662 0.482 0.000 vt 0.770 0.948 0.000 vt 0.762 0.981 0.000 vt 0.676 0.977 0.000 vt 0.845 0.915 0.000 vt 0.835 0.891 0.000 vt 0.569 0.560 0.000 vt 0.582 0.558 0.000 vt 0.580 0.563 0.000 vt 0.569 0.564 0.000 vt 0.590 0.544 0.000 vt 0.571 0.548 0.000 vt 0.635 0.701 0.000 vt 0.651 0.731 0.000 vt 0.607 0.593 0.000 vt 0.609 0.606 0.000 vt 0.543 0.570 0.000 vt 0.553 0.556 0.000 vt 0.552 0.580 0.000 vt 0.556 0.574 0.000 vt 0.569 0.554 0.000 vt 0.585 0.551 0.000 vt 0.559 0.566 0.000 vt 0.550 0.458 0.000 vt 0.532 0.330 0.000 vt 0.549 0.325 0.000 vt 0.610 0.364 0.000 vt 0.589 0.432 0.000 vt 0.578 0.417 0.000 vt 0.570 0.357 0.000 vt 0.565 0.360 0.000 vt 0.562 0.356 0.000 vt 0.565 0.351 0.000 vt 0.557 0.364 0.000 vt 0.556 0.364 0.000 vt 0.548 0.371 0.000 vt 0.557 0.371 0.000 vt 0.762 0.385 0.000 vt 0.513 0.445 0.000 vt 0.508 0.444 0.000 vt 0.500 0.520 0.000 vt 0.939 0.378 0.000 vt 0.932 0.316 0.000 vt 0.972 0.321 0.000 vt 0.974 0.384 0.000 vt 0.605 0.572 0.000 vt 0.605 0.578 0.000 vt 0.605 0.584 0.000 vt 0.559 0.571 0.000 vt 0.562 0.333 0.000 vt 0.500 0.552 0.000 vt 0.500 0.585 0.000 vt 0.531 0.343 0.000 vt 0.514 0.338 0.000 vt 0.516 0.324 0.000 vt 0.532 0.488 0.000 vt 0.534 0.448 0.000 vt 0.540 0.446 0.000 vt 0.545 0.448 0.000 vt 0.538 0.455 0.000 vt 0.541 0.466 0.000 vt 0.612 0.623 0.000 vt 0.567 0.366 0.000 vt 0.513 0.356 0.000 vt 0.500 0.355 0.000 vt 0.500 0.346 0.000 vt 0.514 0.348 0.000 vt 0.543 0.363 0.000 vt 0.552 0.364 0.000 vt 0.531 0.362 0.000 vt 0.512 0.361 0.000 vt 0.509 0.433 0.000 vt 0.500 0.444 0.000 vt 0.500 0.432 0.000 vt 0.603 0.551 0.000 vt 0.599 0.557 0.000 vt 0.627 0.570 0.000 vt 0.631 0.571 0.000 vt 0.625 0.566 0.000 vt 0.622 0.569 0.000 vt 0.621 0.567 0.000 vt 0.529 0.234 0.000 vt 0.500 0.249 0.000 vt 0.500 0.227 0.000 vt 0.550 0.245 0.000 vt 0.857 0.816 0.000 vt 0.825 0.804 0.000 vt 0.851 0.737 0.000 vt 0.886 0.748 0.000 vt 0.821 0.866 0.000 vt 0.798 0.856 0.000 vt 0.783 0.797 0.000 vt 0.810 0.729 0.000 vt 0.755 0.848 0.000 vt 0.534 0.215 0.000 vt 0.563 0.233 0.000 vt 0.548 0.588 0.000 vt 0.884 0.835 0.000 vt 0.908 0.854 0.000 vt 0.919 0.761 0.000 vt 0.947 0.512 0.000 vt 0.944 0.446 0.000 vt 0.974 0.452 0.000 vt 0.974 0.519 0.000 vt 0.915 0.504 0.000 vt 0.887 0.498 0.000 vt 0.917 0.564 0.000 vt 0.890 0.556 0.000 vt 0.999 0.634 0.000 vt 0.973 0.633 0.000 vt 0.975 0.577 0.000 vt 0.999 0.579 0.000 vt 0.882 0.614 0.000 vt 0.911 0.622 0.000 vt 0.901 0.679 0.000 vt 0.868 0.671 0.000 vt 0.833 0.667 0.000 vt 0.708 0.836 0.000 vt 0.500 0.205 0.000 vt 0.826 0.364 0.000 vt 0.801 0.303 0.000 vt 0.613 0.529 0.000 vt 0.607 0.544 0.000 vt 0.541 0.380 0.000 vt 0.538 0.372 0.000 vt 0.537 0.366 0.000 vt 0.537 0.363 0.000 vt 0.598 0.945 0.000 vt 0.524 0.902 0.000 vt 0.599 0.489 0.000 vt 0.609 0.563 0.000 vt 0.596 0.563 0.000 vt 0.612 0.559 0.000 vt 0.557 0.569 0.000 vt 0.620 0.571 0.000 vt 0.616 0.569 0.000 vt 0.618 0.569 0.000 vt 0.569 0.568 0.000 vt 0.561 0.568 0.000 vt 0.579 0.567 0.000 vt 0.616 0.564 0.000 vt 0.613 0.567 0.000 vt 0.607 0.567 0.000 vt 0.587 0.568 0.000 vt 0.606 0.568 0.000 vt 0.630 0.565 0.000 vt 0.548 0.389 0.000 vt 0.601 0.452 0.000 vt 0.529 0.566 0.000 vt 0.684 0.686 0.000 vt 0.872 0.222 0.000 vt 0.876 0.265 0.000 vt 0.825 0.258 0.000 vt 0.821 0.214 0.000 vt 0.561 0.119 0.000 vt 0.500 0.114 0.000 vt 0.771 0.304 0.000 vt 0.797 0.363 0.000 vt 0.726 0.227 0.000 vt 0.777 0.371 0.000 vt 0.947 0.571 0.000 vt 0.999 0.388 0.000 vt 0.999 0.456 0.000 vt 0.999 0.524 0.000 vt 0.936 0.877 0.000 vt 0.856 0.945 0.000 vt 0.999 0.323 0.000 vt 0.935 0.689 0.000 vt 0.776 0.240 0.000 vt 0.928 0.265 0.000 vt 0.969 0.264 0.000 vt 0.999 0.267 0.000 vt 0.943 0.628 0.000 vt 0.806 0.622 0.000 vt 0.851 0.611 0.000 vt 0.500 0.777 0.000 vt 0.500 0.839 0.000 vt 0.692 0.489 0.000 vt 0.631 0.558 0.000 vt 0.622 0.562 0.000 vt 0.626 0.560 0.000 vt 0.555 0.413 0.000 vt 0.570 0.429 0.000 vt 0.539 0.440 0.000 vt 0.524 0.607 0.000 vt 0.531 0.591 0.000 vt 0.500 0.361 0.000 vt 0.500 0.321 0.000 vt 0.500 0.312 0.000 vt 0.500 0.336 0.000 vt 0.500 0.294 0.000 vt 0.500 0.273 0.000 vt 0.622 0.549 0.000 vt 0.616 0.554 0.000 vt 0.607 0.509 0.000 vt 0.701 0.520 0.000 vt 0.500 0.421 0.000 vt 0.564 0.403 0.000 vt 0.511 0.615 0.000 vt 0.500 0.618 0.000 vt 0.617 0.568 0.000 vt 0.636 0.139 0.000 vt 0.764 0.192 0.000 vt 0.921 0.220 0.000 vt 0.967 0.219 0.000 vt 0.708 0.168 0.000 vt 0.999 0.218 0.000 vt 0.803 0.523 0.000 vt 0.794 0.535 0.000 vt 0.783 0.527 0.000 vt 0.791 0.508 0.000 vt 0.789 0.571 0.000 vt 0.797 0.562 0.000 vt 0.813 0.591 0.000 vt 0.815 0.578 0.000 vt 0.839 0.583 0.000 vt 0.835 0.574 0.000 vt 0.850 0.569 0.000 vt 0.845 0.560 0.000 vt 0.855 0.539 0.000 vt 0.847 0.535 0.000 vt 0.850 0.501 0.000 vt 0.841 0.502 0.000 vt 0.814 0.438 0.000 vt 0.836 0.464 0.000 vt 0.828 0.472 0.000 vt 0.809 0.452 0.000 vt 0.792 0.427 0.000 vt 0.790 0.441 0.000 vt 0.818 0.567 0.000 vt 0.807 0.550 0.000 vt 0.831 0.561 0.000 vt 0.839 0.553 0.000 vt 0.837 0.534 0.000 vt 0.831 0.505 0.000 vt 0.820 0.479 0.000 vt 0.804 0.465 0.000 vt 0.786 0.460 0.000 vt 0.773 0.456 0.000 vt 0.779 0.433 0.000 vt 0.797 0.489 0.000 vt 0.785 0.495 0.000 vt 0.789 0.486 0.000 vt 0.772 0.537 0.000 vt 0.781 0.583 0.000 vt 0.812 0.602 0.000 vt 0.848 0.587 0.000 vt 0.862 0.546 0.000 vt 0.859 0.500 0.000 vt 0.820 0.412 0.000 vt 0.843 0.450 0.000 vt 0.791 0.404 0.000 vt 0.773 0.417 0.000 vt 0.764 0.447 0.000 vt 0.801 0.477 0.000 vt 0.813 0.487 0.000 vt 0.806 0.496 0.000 vt 0.787 0.478 0.000 vt 0.778 0.489 0.000 vt 0.822 0.538 0.000 vt 0.822 0.510 0.000 vt 0.767 0.492 0.000 vt 0.870 0.496 0.000 vt 0.851 0.425 0.000 vt 0.872 0.552 0.000 vt 0.500 0.183 0.000 vt 0.516 0.930 0.000 vt 0.500 0.928 0.000 vt 0.528 0.934 0.000 vt 0.537 0.938 0.000 vt 0.516 0.970 0.000 vt 0.520 0.955 0.000 vt 0.530 0.952 0.000 vt 0.522 0.944 0.000 vt 0.512 0.942 0.000 vt 0.615 0.572 0.000 vt 0.612 0.569 0.000 vt 0.576 0.968 0.000 vt 0.573 0.973 0.000 vt 0.562 0.969 0.000 vt 0.563 0.961 0.000 vt 0.571 0.956 0.000 vt 0.582 0.961 0.000 vt 0.611 0.961 0.000 vt 0.606 0.967 0.000 vt 0.595 0.960 0.000 vt 0.601 0.955 0.000 vt 0.570 0.569 0.000 vt 0.595 0.566 0.000 vt 0.616 0.967 0.000 vt 0.617 0.975 0.000 vt 0.607 0.978 0.000 vt 0.614 0.982 0.000 vt 0.605 0.991 0.000 vt 0.599 0.986 0.000 vt 0.593 0.996 0.000 vt 0.589 0.989 0.000 vt 0.562 0.570 0.000 vt 0.573 0.994 0.000 vt 0.579 0.987 0.000 vt 0.584 0.996 0.000 vt 0.581 0.953 0.000 vt 0.592 0.953 0.000 vt 0.561 0.988 0.000 vt 0.572 0.981 0.000 vt 0.563 0.978 0.000 vt 0.500 0.970 0.000 vt 0.500 0.943 0.000 vt 0.511 0.956 0.000 vt 0.500 0.956 0.000 vt 0.868 0.132 0.000 vt 0.867 0.090 0.000 vt 0.916 0.092 0.000 vt 0.918 0.133 0.000 vt 0.554 0.066 0.000 vt 0.612 0.070 0.000 vt 0.619 0.103 0.000 vt 0.558 0.095 0.000 vt 0.815 0.169 0.000 vt 0.758 0.148 0.000 vt 0.747 0.102 0.000 vt 0.814 0.126 0.000 vt 0.770 0.072 0.000 vt 0.817 0.087 0.000 vt 0.552 0.038 0.000 vt 0.551 0.020 0.000 vt 0.602 0.021 0.000 vt 0.605 0.039 0.000 vt 0.821 0.050 0.000 vt 0.867 0.055 0.000 vt 0.712 0.053 0.000 vt 0.700 0.022 0.000 vt 0.739 0.023 0.000 vt 0.740 0.052 0.000 vt 0.652 0.022 0.000 vt 0.659 0.043 0.000 vt 0.913 0.055 0.000 vt 0.959 0.055 0.000 vt 0.960 0.091 0.000 vt 0.999 0.089 0.000 vt 0.999 0.131 0.000 vt 0.962 0.133 0.000 vt 0.999 0.053 0.000 vt 0.778 0.038 0.000 vt 0.917 0.177 0.000 vt 0.965 0.178 0.000 vt 0.674 0.083 0.000 vt 0.685 0.124 0.000 vt 0.999 0.175 0.000 vt 0.500 0.037 0.000 vt 0.500 0.066 0.000 vt 0.871 0.175 0.000 vt 0.500 0.019 0.000 vt 0.500 0.092 0.000 vt 0.999 0.002 0.000 vt 0.958 0.002 0.000 vt 0.867 0.002 0.000 vt 0.823 0.002 0.000 vt 0.908 0.002 0.000 vt 0.601 0.002 0.000 vt 0.550 0.002 0.000 vt 0.697 0.002 0.000 vt 0.650 0.002 0.000 vt 0.782 0.002 0.000 vt 0.740 0.002 0.000 vt 0.500 0.002 0.000 vt 0.468 0.923 0.000 vt 0.459 0.929 0.000 vt 0.458 0.923 0.000 vt 0.465 0.917 0.000 vt 0.479 0.984 0.000 vt 0.495 0.998 0.000 vt 0.479 0.996 0.000 vt 0.496 0.917 0.000 vt 0.485 0.918 0.000 vt 0.484 0.910 0.000 vt 0.493 0.910 0.000 vt 0.477 0.921 0.000 vt 0.475 0.913 0.000 vt 0.451 0.958 0.000 vt 0.450 0.946 0.000 vt 0.456 0.942 0.000 vt 0.462 0.954 0.000 vt 0.455 0.935 0.000 vt 0.450 0.932 0.000 vt 0.467 0.967 0.000 vt 0.453 0.974 0.000 vt 0.467 0.994 0.000 vt 0.458 0.987 0.000 vt 0.384 0.254 0.000 vt 0.381 0.292 0.000 vt 0.342 0.307 0.000 vt 0.347 0.261 0.000 vt 0.364 0.438 0.000 vt 0.353 0.414 0.000 vt 0.373 0.396 0.000 vt 0.380 0.419 0.000 vt 0.114 0.312 0.000 vt 0.156 0.308 0.000 vt 0.140 0.369 0.000 vt 0.103 0.370 0.000 vt 0.260 0.593 0.000 vt 0.232 0.598 0.000 vt 0.241 0.541 0.000 vt 0.259 0.542 0.000 vt 0.356 0.213 0.000 vt 0.356 0.174 0.000 vt 0.434 0.146 0.000 vt 0.439 0.175 0.000 vt 0.420 0.254 0.000 vt 0.435 0.256 0.000 vt 0.435 0.268 0.000 vt 0.415 0.277 0.000 vt 0.456 0.195 0.000 vt 0.410 0.217 0.000 vt 0.229 0.721 0.000 vt 0.206 0.663 0.000 vt 0.242 0.653 0.000 vt 0.264 0.712 0.000 vt 0.331 0.622 0.000 vt 0.348 0.651 0.000 vt 0.335 0.669 0.000 vt 0.315 0.632 0.000 vt 0.377 0.588 0.000 vt 0.373 0.599 0.000 vt 0.361 0.590 0.000 vt 0.368 0.582 0.000 vt 0.359 0.632 0.000 vt 0.343 0.612 0.000 vt 0.381 0.580 0.000 vt 0.373 0.576 0.000 vt 0.377 0.573 0.000 vt 0.383 0.575 0.000 vt 0.292 0.702 0.000 vt 0.271 0.646 0.000 vt 0.353 0.601 0.000 vt 0.367 0.614 0.000 vt 0.396 0.718 0.000 vt 0.404 0.682 0.000 vt 0.433 0.686 0.000 vt 0.426 0.725 0.000 vt 0.410 0.649 0.000 vt 0.438 0.648 0.000 vt 0.416 0.769 0.000 vt 0.382 0.756 0.000 vt 0.414 0.587 0.000 vt 0.414 0.580 0.000 vt 0.432 0.579 0.000 vt 0.434 0.586 0.000 vt 0.431 0.574 0.000 vt 0.414 0.573 0.000 vt 0.413 0.627 0.000 vt 0.438 0.627 0.000 vt 0.413 0.610 0.000 vt 0.413 0.596 0.000 vt 0.435 0.595 0.000 vt 0.437 0.608 0.000 vt 0.479 0.441 0.000 vt 0.483 0.445 0.000 vt 0.480 0.450 0.000 vt 0.474 0.450 0.000 vt 0.280 0.504 0.000 vt 0.262 0.494 0.000 vt 0.273 0.446 0.000 vt 0.291 0.467 0.000 vt 0.344 0.383 0.000 vt 0.327 0.403 0.000 vt 0.316 0.368 0.000 vt 0.340 0.348 0.000 vt 0.428 0.371 0.000 vt 0.419 0.374 0.000 vt 0.419 0.364 0.000 vt 0.427 0.365 0.000 vt 0.307 0.431 0.000 vt 0.292 0.400 0.000 vt 0.391 0.383 0.000 vt 0.396 0.401 0.000 vt 0.443 0.364 0.000 vt 0.444 0.364 0.000 vt 0.443 0.366 0.000 vt 0.441 0.365 0.000 vt 0.448 0.367 0.000 vt 0.448 0.364 0.000 vt 0.432 0.377 0.000 vt 0.434 0.370 0.000 vt 0.439 0.374 0.000 vt 0.406 0.377 0.000 vt 0.406 0.363 0.000 vt 0.347 0.551 0.000 vt 0.334 0.545 0.000 vt 0.342 0.523 0.000 vt 0.356 0.534 0.000 vt 0.363 0.480 0.000 vt 0.351 0.459 0.000 vt 0.375 0.458 0.000 vt 0.338 0.434 0.000 vt 0.443 0.345 0.000 vt 0.454 0.337 0.000 vt 0.457 0.349 0.000 vt 0.447 0.353 0.000 vt 0.414 0.403 0.000 vt 0.409 0.389 0.000 vt 0.421 0.382 0.000 vt 0.427 0.392 0.000 vt 0.428 0.343 0.000 vt 0.422 0.353 0.000 vt 0.410 0.347 0.000 vt 0.416 0.331 0.000 vt 0.457 0.355 0.000 vt 0.447 0.358 0.000 vt 0.447 0.499 0.000 vt 0.447 0.477 0.000 vt 0.458 0.484 0.000 vt 0.459 0.507 0.000 vt 0.461 0.532 0.000 vt 0.469 0.513 0.000 vt 0.471 0.541 0.000 vt 0.449 0.538 0.000 vt 0.448 0.521 0.000 vt 0.462 0.552 0.000 vt 0.124 0.429 0.000 vt 0.092 0.437 0.000 vt 0.392 0.340 0.000 vt 0.371 0.336 0.000 vt 0.401 0.314 0.000 vt 0.309 0.326 0.000 vt 0.252 0.426 0.000 vt 0.277 0.365 0.000 vt 0.245 0.489 0.000 vt 0.436 0.825 0.000 vt 0.467 0.834 0.000 vt 0.442 0.886 0.000 vt 0.410 0.868 0.000 vt 0.363 0.789 0.000 vt 0.335 0.817 0.000 vt 0.298 0.774 0.000 vt 0.327 0.755 0.000 vt 0.260 0.787 0.000 vt 0.460 0.686 0.000 vt 0.455 0.727 0.000 vt 0.462 0.572 0.000 vt 0.449 0.550 0.000 vt 0.480 0.546 0.000 vt 0.478 0.517 0.000 vt 0.479 0.728 0.000 vt 0.476 0.777 0.000 vt 0.448 0.775 0.000 vt 0.482 0.687 0.000 vt 0.485 0.650 0.000 vt 0.375 0.671 0.000 vt 0.382 0.644 0.000 vt 0.409 0.533 0.000 vt 0.411 0.518 0.000 vt 0.431 0.527 0.000 vt 0.429 0.539 0.000 vt 0.455 0.436 0.000 vt 0.451 0.425 0.000 vt 0.472 0.413 0.000 vt 0.475 0.427 0.000 vt 0.444 0.449 0.000 vt 0.437 0.439 0.000 vt 0.486 0.395 0.000 vt 0.487 0.409 0.000 vt 0.468 0.396 0.000 vt 0.434 0.511 0.000 vt 0.416 0.500 0.000 vt 0.423 0.478 0.000 vt 0.436 0.490 0.000 vt 0.429 0.457 0.000 vt 0.439 0.468 0.000 vt 0.446 0.561 0.000 vt 0.452 0.569 0.000 vt 0.448 0.569 0.000 vt 0.443 0.563 0.000 vt 0.373 0.847 0.000 vt 0.355 0.898 0.000 vt 0.326 0.871 0.000 vt 0.224 0.920 0.000 vt 0.217 0.887 0.000 vt 0.271 0.888 0.000 vt 0.291 0.921 0.000 vt 0.379 0.920 0.000 vt 0.307 0.947 0.000 vt 0.465 0.642 0.000 vt 0.455 0.599 0.000 vt 0.458 0.618 0.000 vt 0.448 0.377 0.000 vt 0.441 0.383 0.000 vt 0.469 0.470 0.000 vt 0.472 0.457 0.000 vt 0.483 0.456 0.000 vt 0.480 0.472 0.000 vt 0.470 0.438 0.000 vt 0.483 0.436 0.000 vt 0.472 0.383 0.000 vt 0.474 0.374 0.000 vt 0.488 0.374 0.000 vt 0.487 0.384 0.000 vt 0.474 0.366 0.000 vt 0.488 0.367 0.000 vt 0.474 0.362 0.000 vt 0.488 0.362 0.000 vt 0.489 0.422 0.000 vt 0.492 0.457 0.000 vt 0.489 0.472 0.000 vt 0.479 0.491 0.000 vt 0.488 0.491 0.000 vt 0.488 0.519 0.000 vt 0.489 0.550 0.000 vt 0.490 0.583 0.000 vt 0.480 0.576 0.000 vt 0.346 0.584 0.000 vt 0.334 0.589 0.000 vt 0.331 0.567 0.000 vt 0.344 0.568 0.000 vt 0.295 0.639 0.000 vt 0.282 0.591 0.000 vt 0.320 0.592 0.000 vt 0.316 0.563 0.000 vt 0.363 0.575 0.000 vt 0.355 0.579 0.000 vt 0.355 0.567 0.000 vt 0.364 0.566 0.000 vt 0.277 0.546 0.000 vt 0.298 0.554 0.000 vt 0.303 0.592 0.000 vt 0.421 0.298 0.000 vt 0.440 0.287 0.000 vt 0.446 0.307 0.000 vt 0.430 0.317 0.000 vt 0.466 0.318 0.000 vt 0.462 0.300 0.000 vt 0.481 0.296 0.000 vt 0.483 0.314 0.000 vt 0.438 0.362 0.000 vt 0.441 0.360 0.000 vt 0.443 0.362 0.000 vt 0.441 0.363 0.000 vt 0.439 0.368 0.000 vt 0.437 0.365 0.000 vt 0.469 0.351 0.000 vt 0.469 0.358 0.000 vt 0.457 0.360 0.000 vt 0.389 0.437 0.000 vt 0.387 0.475 0.000 vt 0.376 0.497 0.000 vt 0.420 0.445 0.000 vt 0.410 0.466 0.000 vt 0.402 0.418 0.000 vt 0.352 0.501 0.000 vt 0.367 0.516 0.000 vt 0.359 0.554 0.000 vt 0.370 0.541 0.000 vt 0.267 0.331 0.000 vt 0.249 0.313 0.000 vt 0.294 0.252 0.000 vt 0.304 0.288 0.000 vt 0.317 0.535 0.000 vt 0.326 0.508 0.000 vt 0.001 0.696 0.000 vt 0.033 0.695 0.000 vt 0.050 0.772 0.000 vt 0.014 0.778 0.000 vt 0.400 0.811 0.000 vt 0.448 0.361 0.000 vt 0.454 0.364 0.000 vt 0.453 0.367 0.000 vt 0.475 0.254 0.000 vt 0.478 0.274 0.000 vt 0.458 0.280 0.000 vt 0.454 0.261 0.000 vt 0.369 0.369 0.000 vt 0.322 0.460 0.000 vt 0.338 0.482 0.000 vt 0.324 0.977 0.000 vt 0.238 0.981 0.000 vt 0.230 0.948 0.000 vt 0.155 0.915 0.000 vt 0.165 0.891 0.000 vt 0.431 0.560 0.000 vt 0.431 0.564 0.000 vt 0.420 0.563 0.000 vt 0.418 0.558 0.000 vt 0.410 0.544 0.000 vt 0.429 0.548 0.000 vt 0.349 0.731 0.000 vt 0.365 0.701 0.000 vt 0.391 0.606 0.000 vt 0.393 0.593 0.000 vt 0.457 0.570 0.000 vt 0.447 0.556 0.000 vt 0.444 0.574 0.000 vt 0.448 0.580 0.000 vt 0.415 0.551 0.000 vt 0.431 0.554 0.000 vt 0.441 0.566 0.000 vt 0.450 0.458 0.000 vt 0.451 0.325 0.000 vt 0.468 0.330 0.000 vt 0.390 0.364 0.000 vt 0.411 0.432 0.000 vt 0.422 0.417 0.000 vt 0.430 0.357 0.000 vt 0.435 0.351 0.000 vt 0.438 0.356 0.000 vt 0.435 0.360 0.000 vt 0.443 0.364 0.000 vt 0.444 0.364 0.000 vt 0.443 0.371 0.000 vt 0.452 0.371 0.000 vt 0.238 0.385 0.000 vt 0.487 0.445 0.000 vt 0.492 0.444 0.000 vt 0.061 0.378 0.000 vt 0.026 0.384 0.000 vt 0.028 0.321 0.000 vt 0.068 0.316 0.000 vt 0.395 0.572 0.000 vt 0.395 0.578 0.000 vt 0.395 0.584 0.000 vt 0.441 0.571 0.000 vt 0.438 0.333 0.000 vt 0.469 0.343 0.000 vt 0.486 0.338 0.000 vt 0.484 0.324 0.000 vt 0.468 0.488 0.000 vt 0.466 0.448 0.000 vt 0.462 0.455 0.000 vt 0.455 0.448 0.000 vt 0.460 0.446 0.000 vt 0.459 0.466 0.000 vt 0.388 0.623 0.000 vt 0.433 0.366 0.000 vt 0.487 0.356 0.000 vt 0.486 0.348 0.000 vt 0.457 0.363 0.000 vt 0.448 0.364 0.000 vt 0.469 0.362 0.000 vt 0.488 0.361 0.000 vt 0.491 0.433 0.000 vt 0.401 0.557 0.000 vt 0.397 0.551 0.000 vt 0.373 0.570 0.000 vt 0.369 0.571 0.000 vt 0.375 0.566 0.000 vt 0.379 0.567 0.000 vt 0.378 0.569 0.000 vt 0.471 0.234 0.000 vt 0.450 0.245 0.000 vt 0.143 0.816 0.000 vt 0.114 0.748 0.000 vt 0.149 0.737 0.000 vt 0.175 0.804 0.000 vt 0.202 0.856 0.000 vt 0.179 0.866 0.000 vt 0.190 0.729 0.000 vt 0.217 0.797 0.000 vt 0.245 0.848 0.000 vt 0.466 0.215 0.000 vt 0.437 0.233 0.000 vt 0.452 0.588 0.000 vt 0.092 0.854 0.000 vt 0.116 0.835 0.000 vt 0.081 0.761 0.000 vt 0.053 0.512 0.000 vt 0.026 0.519 0.000 vt 0.026 0.452 0.000 vt 0.056 0.446 0.000 vt 0.113 0.498 0.000 vt 0.085 0.504 0.000 vt 0.110 0.556 0.000 vt 0.083 0.564 0.000 vt 0.001 0.634 0.000 vt 0.001 0.579 0.000 vt 0.025 0.577 0.000 vt 0.027 0.633 0.000 vt 0.118 0.614 0.000 vt 0.132 0.671 0.000 vt 0.099 0.679 0.000 vt 0.089 0.622 0.000 vt 0.167 0.667 0.000 vt 0.292 0.836 0.000 vt 0.199 0.303 0.000 vt 0.174 0.364 0.000 vt 0.393 0.544 0.000 vt 0.387 0.529 0.000 vt 0.459 0.380 0.000 vt 0.462 0.372 0.000 vt 0.463 0.366 0.000 vt 0.463 0.363 0.000 vt 0.402 0.945 0.000 vt 0.476 0.902 0.000 vt 0.401 0.489 0.000 vt 0.391 0.563 0.000 vt 0.388 0.559 0.000 vt 0.404 0.563 0.000 vt 0.443 0.569 0.000 vt 0.380 0.571 0.000 vt 0.382 0.569 0.000 vt 0.384 0.569 0.000 vt 0.439 0.568 0.000 vt 0.431 0.568 0.000 vt 0.421 0.567 0.000 vt 0.393 0.567 0.000 vt 0.387 0.567 0.000 vt 0.384 0.564 0.000 vt 0.394 0.568 0.000 vt 0.413 0.568 0.000 vt 0.370 0.565 0.000 vt 0.452 0.389 0.000 vt 0.399 0.452 0.000 vt 0.471 0.566 0.000 vt 0.316 0.686 0.000 vt 0.128 0.222 0.000 vt 0.179 0.214 0.000 vt 0.175 0.258 0.000 vt 0.124 0.265 0.000 vt 0.439 0.119 0.000 vt 0.229 0.304 0.000 vt 0.203 0.363 0.000 vt 0.274 0.227 0.000 vt 0.223 0.371 0.000 vt 0.053 0.571 0.000 vt 0.001 0.388 0.000 vt 0.001 0.456 0.000 vt 0.001 0.524 0.000 vt 0.064 0.877 0.000 vt 0.144 0.945 0.000 vt 0.001 0.323 0.000 vt 0.065 0.689 0.000 vt 0.224 0.240 0.000 vt 0.072 0.265 0.000 vt 0.001 0.267 0.000 vt 0.031 0.264 0.000 vt 0.057 0.628 0.000 vt 0.194 0.622 0.000 vt 0.149 0.611 0.000 vt 0.308 0.489 0.000 vt 0.369 0.558 0.000 vt 0.374 0.560 0.000 vt 0.378 0.562 0.000 vt 0.445 0.413 0.000 vt 0.430 0.429 0.000 vt 0.461 0.440 0.000 vt 0.476 0.607 0.000 vt 0.469 0.591 0.000 vt 0.378 0.549 0.000 vt 0.384 0.554 0.000 vt 0.393 0.509 0.000 vt 0.299 0.520 0.000 vt 0.436 0.403 0.000 vt 0.489 0.615 0.000 vt 0.383 0.568 0.000 vt 0.364 0.139 0.000 vt 0.236 0.192 0.000 vt 0.033 0.219 0.000 vt 0.079 0.220 0.000 vt 0.292 0.168 0.000 vt 0.001 0.218 0.000 vt 0.197 0.523 0.000 vt 0.209 0.508 0.000 vt 0.217 0.527 0.000 vt 0.206 0.535 0.000 vt 0.211 0.571 0.000 vt 0.203 0.562 0.000 vt 0.187 0.591 0.000 vt 0.185 0.578 0.000 vt 0.161 0.583 0.000 vt 0.165 0.574 0.000 vt 0.150 0.569 0.000 vt 0.155 0.560 0.000 vt 0.145 0.539 0.000 vt 0.153 0.535 0.000 vt 0.150 0.501 0.000 vt 0.159 0.502 0.000 vt 0.186 0.438 0.000 vt 0.191 0.452 0.000 vt 0.172 0.472 0.000 vt 0.164 0.464 0.000 vt 0.208 0.427 0.000 vt 0.210 0.441 0.000 vt 0.182 0.567 0.000 vt 0.193 0.550 0.000 vt 0.169 0.561 0.000 vt 0.161 0.553 0.000 vt 0.163 0.534 0.000 vt 0.169 0.505 0.000 vt 0.196 0.465 0.000 vt 0.180 0.479 0.000 vt 0.214 0.460 0.000 vt 0.227 0.456 0.000 vt 0.221 0.433 0.000 vt 0.203 0.489 0.000 vt 0.211 0.486 0.000 vt 0.215 0.495 0.000 vt 0.228 0.537 0.000 vt 0.219 0.583 0.000 vt 0.188 0.602 0.000 vt 0.152 0.587 0.000 vt 0.138 0.546 0.000 vt 0.141 0.500 0.000 vt 0.157 0.450 0.000 vt 0.180 0.412 0.000 vt 0.209 0.404 0.000 vt 0.227 0.417 0.000 vt 0.236 0.447 0.000 vt 0.194 0.496 0.000 vt 0.187 0.487 0.000 vt 0.199 0.477 0.000 vt 0.213 0.478 0.000 vt 0.222 0.489 0.000 vt 0.178 0.538 0.000 vt 0.178 0.510 0.000 vt 0.233 0.492 0.000 vt 0.130 0.496 0.000 vt 0.149 0.425 0.000 vt 0.128 0.552 0.000 vt 0.484 0.930 0.000 vt 0.472 0.934 0.000 vt 0.463 0.938 0.000 vt 0.470 0.952 0.000 vt 0.480 0.955 0.000 vt 0.484 0.970 0.000 vt 0.488 0.942 0.000 vt 0.478 0.944 0.000 vt 0.388 0.569 0.000 vt 0.385 0.572 0.000 vt 0.424 0.968 0.000 vt 0.437 0.961 0.000 vt 0.438 0.969 0.000 vt 0.427 0.973 0.000 vt 0.418 0.961 0.000 vt 0.429 0.956 0.000 vt 0.389 0.961 0.000 vt 0.399 0.955 0.000 vt 0.405 0.960 0.000 vt 0.394 0.967 0.000 vt 0.429 0.569 0.000 vt 0.405 0.566 0.000 vt 0.393 0.978 0.000 vt 0.383 0.975 0.000 vt 0.384 0.967 0.000 vt 0.401 0.986 0.000 vt 0.395 0.991 0.000 vt 0.386 0.982 0.000 vt 0.411 0.989 0.000 vt 0.407 0.996 0.000 vt 0.438 0.570 0.000 vt 0.427 0.994 0.000 vt 0.416 0.996 0.000 vt 0.421 0.987 0.000 vt 0.419 0.953 0.000 vt 0.408 0.953 0.000 vt 0.439 0.988 0.000 vt 0.428 0.981 0.000 vt 0.437 0.978 0.000 vt 0.489 0.956 0.000 vt 0.132 0.132 0.000 vt 0.082 0.133 0.000 vt 0.084 0.092 0.000 vt 0.133 0.090 0.000 vt 0.446 0.066 0.000 vt 0.442 0.095 0.000 vt 0.381 0.103 0.000 vt 0.388 0.070 0.000 vt 0.185 0.169 0.000 vt 0.186 0.126 0.000 vt 0.253 0.102 0.000 vt 0.242 0.148 0.000 vt 0.230 0.072 0.000 vt 0.183 0.087 0.000 vt 0.448 0.038 0.000 vt 0.395 0.039 0.000 vt 0.398 0.021 0.000 vt 0.449 0.020 0.000 vt 0.133 0.055 0.000 vt 0.179 0.050 0.000 vt 0.288 0.053 0.000 vt 0.260 0.052 0.000 vt 0.261 0.023 0.000 vt 0.300 0.022 0.000 vt 0.341 0.043 0.000 vt 0.348 0.022 0.000 vt 0.087 0.055 0.000 vt 0.040 0.091 0.000 vt 0.041 0.055 0.000 vt 0.038 0.133 0.000 vt 0.001 0.131 0.000 vt 0.001 0.089 0.000 vt 0.001 0.053 0.000 vt 0.222 0.038 0.000 vt 0.083 0.177 0.000 vt 0.035 0.178 0.000 vt 0.326 0.083 0.000 vt 0.315 0.124 0.000 vt 0.001 0.175 0.000 vt 0.129 0.175 0.000 vt 0.001 0.002 0.000 vt 0.042 0.002 0.000 vt 0.133 0.002 0.000 vt 0.177 0.002 0.000 vt 0.092 0.002 0.000 vt 0.399 0.002 0.000 vt 0.450 0.002 0.000 vt 0.303 0.002 0.000 vt 0.350 0.002 0.000 vt 0.218 0.002 0.000 vt 0.260 0.002 0.000 vt 0.558 0.967 0.000 vt 0.557 0.976 0.000 vt 0.500 0.997 0.000 vt 0.588 0.975 0.000 vt 0.442 0.967 0.000 vt 0.443 0.976 0.000 vt 0.412 0.975 0.000 # 1339 texture vertices vn 0.001 0.482 -0.876 vn -0.001 0.661 0.751 vn 0.136 0.595 0.792 vn -0.203 0.679 0.706 vn -0.092 0.474 0.876 vn -0.184 0.792 0.581 vn -0.098 0.863 0.495 vn -0.449 0.820 0.356 vn -0.220 0.748 0.626 vn -0.560 0.798 -0.222 vn -0.233 0.531 -0.815 vn 0.001 0.534 -0.845 vn -0.135 0.596 0.791 vn 0.203 0.676 0.708 vn 0.091 0.476 0.875 vn 0.189 0.792 0.581 vn 0.099 0.862 0.496 vn 0.444 0.821 0.360 vn 0.221 0.747 0.627 vn 0.556 0.801 -0.221 vn 0.228 0.532 -0.815 vn -0.002 0.536 -0.844 vn -0.574 0.744 -0.343 vn -0.485 0.523 -0.701 vn -0.121 0.869 -0.480 vn -0.215 0.930 -0.298 vn -0.000 -0.806 -0.591 vn -0.277 -0.779 -0.562 vn -0.258 -0.731 -0.632 vn -0.046 -0.809 -0.586 vn -0.210 0.565 -0.798 vn -0.094 0.624 -0.775 vn 0.015 0.952 -0.307 vn 0.045 0.919 -0.392 vn -0.099 0.857 -0.505 vn -0.379 0.493 -0.783 vn -0.947 0.285 -0.149 vn -0.809 -0.421 -0.411 vn -0.895 -0.443 -0.043 vn -0.999 -0.020 0.035 vn -0.359 0.933 -0.019 vn -0.809 0.586 0.047 vn -0.667 -0.516 -0.538 vn -0.726 -0.626 -0.285 vn -0.001 0.671 -0.741 vn -0.001 0.945 -0.327 vn -0.531 -0.632 -0.565 vn -0.618 -0.566 -0.546 vn 0.800 -0.473 0.369 vn 0.618 -0.771 0.151 vn 0.693 -0.711 0.116 vn 0.818 -0.467 0.335 vn 0.849 -0.259 0.460 vn 0.775 -0.130 0.619 vn 0.667 -0.132 0.733 vn 0.775 -0.270 0.571 vn 0.958 -0.057 -0.280 vn 0.763 0.033 -0.646 vn 0.763 -0.153 -0.628 vn 0.911 -0.129 -0.391 vn 0.990 0.067 0.126 vn 0.979 0.090 0.185 vn 0.981 0.057 0.184 vn 0.996 0.020 0.090 vn 0.770 -0.392 0.504 vn 0.657 -0.721 0.219 vn 0.478 -0.656 0.584 vn 0.599 -0.389 0.700 vn 0.498 -0.846 0.192 vn 0.537 -0.840 0.082 vn 0.740 -0.557 0.378 vn 0.668 -0.570 0.479 vn 0.280 -0.914 0.294 vn 0.421 -0.898 0.126 vn 0.991 0.084 0.103 vn 0.964 0.223 0.143 vn 0.960 0.189 0.207 vn 0.979 0.103 0.175 vn 0.868 0.172 0.465 vn 0.907 0.085 0.413 vn 0.938 0.144 0.316 vn 0.897 0.178 0.405 vn 0.662 -0.174 0.729 vn 0.583 -0.417 0.697 vn 0.627 -0.449 0.637 vn 0.685 -0.405 0.605 vn 0.827 0.091 0.555 vn 0.890 0.018 0.455 vn 0.663 -0.395 0.636 vn 0.606 -0.428 0.671 vn 0.313 -0.735 0.602 vn -0.136 -0.864 0.485 vn 0.951 0.158 0.267 vn 0.964 0.113 0.241 vn 0.731 -0.036 0.681 vn 0.819 -0.134 0.558 vn 0.546 0.270 0.793 vn 0.602 0.237 0.763 vn 0.444 0.233 0.865 vn 0.353 0.173 0.920 vn 0.240 -0.093 0.966 vn 0.498 0.051 0.866 vn 0.675 0.338 0.656 vn 0.480 0.400 0.780 vn 0.064 -0.572 0.818 vn 0.126 -0.313 0.941 vn 0.207 -0.613 0.763 vn 0.221 -0.810 0.544 vn 0.598 -0.694 -0.401 vn 0.124 -0.977 -0.175 vn 0.218 -0.333 0.917 vn 0.377 -0.161 0.912 vn 0.142 -0.210 0.967 vn 0.256 -0.155 0.954 vn 0.111 -0.351 0.930 vn 0.107 -0.480 0.871 vn 0.675 -0.732 -0.096 vn 0.496 -0.844 0.206 vn -0.016 -0.986 0.167 vn 0.304 -0.948 0.097 vn 0.982 -0.082 0.171 vn 0.963 -0.002 0.269 vn 0.967 -0.134 0.216 vn 0.969 -0.177 0.175 vn 0.916 -0.244 0.319 vn 0.853 -0.341 0.394 vn 0.837 -0.365 0.407 vn 0.886 -0.281 0.368 vn 0.422 -0.292 0.858 vn 0.039 -0.571 0.820 vn -0.011 -0.399 0.917 vn 0.333 -0.349 0.876 vn 0.935 -0.237 0.263 vn 0.949 -0.159 0.273 vn 0.697 -0.213 0.685 vn 0.568 -0.123 0.814 vn -0.938 0.322 0.130 vn -0.609 -0.738 -0.291 vn -0.447 -0.857 -0.258 vn 0.259 -0.528 0.809 vn 0.137 -0.704 0.697 vn -0.107 -0.741 0.663 vn 0.647 -0.296 0.703 vn 0.603 -0.168 0.780 vn 0.836 0.072 0.545 vn 0.744 0.114 0.659 vn 0.701 0.149 0.698 vn 0.802 0.157 0.577 vn 0.823 -0.080 0.562 vn 0.690 0.142 0.710 vn 0.628 0.036 0.778 vn 0.894 -0.247 0.373 vn 0.624 -0.153 0.766 vn 0.661 0.110 0.742 vn 0.712 0.424 0.559 vn 0.701 0.284 0.654 vn 0.504 -0.050 0.862 vn 0.413 0.027 0.910 vn 0.569 0.046 0.821 vn 0.488 -0.134 0.862 vn 0.411 -0.180 0.894 vn 0.610 -0.024 0.792 vn 0.747 -0.250 0.616 vn 0.672 -0.313 0.671 vn 0.536 0.762 0.363 vn 0.559 0.768 0.312 vn 0.802 0.272 0.531 vn 0.618 0.206 0.759 vn 0.717 0.383 0.583 vn 0.780 0.464 0.420 vn 0.617 0.401 0.678 vn 0.658 0.397 0.640 vn 0.672 0.440 0.596 vn 0.501 0.314 0.807 vn 0.612 0.527 0.589 vn 0.679 0.320 0.661 vn 0.732 -0.406 -0.547 vn 0.885 -0.261 -0.386 vn 0.842 -0.347 0.414 vn 0.782 -0.349 0.517 vn 0.784 -0.368 0.500 vn 0.858 -0.453 0.244 vn 0.953 -0.279 0.118 vn 0.977 -0.189 0.104 vn 0.989 -0.110 0.102 vn 0.142 0.669 0.730 vn 0.300 0.652 0.696 vn 0.291 0.792 0.536 vn 0.143 0.821 0.553 vn 0.737 0.561 0.378 vn 0.716 0.470 0.515 vn 0.884 0.306 0.353 vn 0.898 0.354 0.263 vn 0.890 0.423 0.171 vn 0.174 0.078 0.982 vn 0.219 0.254 0.942 vn 0.665 -0.104 0.739 vn 0.671 0.390 0.631 vn 0.596 0.435 0.675 vn 0.636 0.467 0.614 vn 0.076 0.244 0.967 vn 0.261 0.437 0.861 vn 0.107 0.440 0.892 vn 0.011 0.082 0.997 vn 0.005 0.082 0.997 vn 0.028 -0.027 0.999 vn 0.073 -0.057 0.996 vn 0.006 0.228 0.974 vn 0.683 0.140 0.717 vn 0.724 0.233 0.650 vn 0.400 0.338 0.852 vn 0.270 0.126 0.955 vn 0.357 0.433 0.828 vn 0.503 0.485 0.716 vn 0.536 0.133 0.834 vn 0.416 -0.306 0.856 vn 0.337 0.097 0.937 vn 0.262 0.372 0.891 vn 0.425 0.075 0.902 vn 0.701 -0.147 0.698 vn -0.056 0.558 0.828 vn 0.005 0.605 0.796 vn 0.483 0.327 0.812 vn 0.497 0.276 0.823 vn 0.505 0.283 0.815 vn 0.340 -0.030 0.940 vn 0.332 0.066 0.941 vn 0.026 0.644 0.765 vn 0.021 0.538 0.843 vn 0.170 -0.012 0.985 vn 0.365 -0.067 0.929 vn 0.826 -0.173 0.537 vn 0.320 0.415 0.852 vn 0.384 0.739 0.554 vn 0.987 -0.013 0.160 vn 0.495 0.720 0.487 vn 0.490 0.830 0.268 vn 0.279 0.906 0.317 vn 0.431 0.899 -0.074 vn 0.267 0.957 -0.112 vn 0.283 0.953 0.107 vn 0.471 0.877 0.092 vn 0.132 0.985 0.113 vn 0.135 0.931 0.339 vn 0.190 -0.184 0.964 vn 0.292 -0.372 0.881 vn 0.307 -0.447 0.840 vn 0.393 -0.580 0.713 vn 0.524 -0.286 0.802 vn 0.380 -0.582 0.719 vn 0.697 0.212 0.685 vn 0.603 0.070 0.795 vn 0.558 -0.571 0.602 vn -0.089 -0.701 0.707 vn 0.794 -0.345 0.500 vn 0.345 -0.517 0.783 vn 0.481 0.101 0.871 vn 0.134 0.283 0.950 vn 0.113 -0.558 0.822 vn -0.073 -0.993 0.089 vn -0.041 -0.994 0.103 vn 0.084 -0.038 0.996 vn -0.012 -0.622 0.783 vn -0.002 0.254 0.967 vn 0.004 -0.997 0.079 vn 0.001 -0.832 -0.555 vn 0.477 -0.363 0.801 vn 0.414 0.160 0.896 vn 0.395 0.485 0.780 vn 0.611 0.484 0.627 vn 0.406 0.510 0.758 vn 0.375 0.498 0.782 vn 0.555 0.314 0.770 vn 0.349 0.411 0.842 vn 0.012 0.247 0.969 vn 0.002 -0.369 0.930 vn -0.003 0.509 0.861 vn 0.876 -0.041 0.481 vn 0.757 -0.214 0.618 vn 0.737 -0.048 0.674 vn 0.840 -0.012 0.542 vn 0.960 0.137 0.243 vn 0.969 0.103 0.226 vn 0.909 0.015 0.417 vn 0.906 0.015 0.423 vn 0.676 -0.276 0.683 vn 0.688 -0.223 0.691 vn 0.691 0.035 0.722 vn 0.719 -0.082 0.691 vn 0.964 0.062 0.260 vn 0.956 0.070 0.286 vn 0.953 0.037 0.300 vn -0.003 -0.415 0.910 vn -0.001 -0.380 0.925 vn 0.658 -0.419 0.625 vn 0.735 -0.421 0.532 vn 0.663 -0.303 0.685 vn 0.550 -0.321 0.771 vn 0.423 -0.236 0.875 vn 0.326 -0.294 0.899 vn 0.124 -0.396 0.910 vn 0.218 -0.177 0.960 vn 0.530 0.781 0.331 vn 0.167 0.827 0.537 vn 0.094 0.948 0.303 vn 0.313 0.934 0.171 vn -0.406 -0.892 0.201 vn -0.743 0.107 0.661 vn 0.455 0.704 0.546 vn 0.288 0.957 0.025 vn 0.245 0.958 0.150 vn 0.532 -0.027 0.846 vn 0.566 0.213 0.796 vn 0.508 0.208 0.836 vn 0.173 0.028 0.984 vn 0.371 0.122 0.921 vn 0.429 -0.045 0.902 vn 0.614 0.165 0.772 vn 0.737 0.157 0.657 vn 0.726 0.057 0.685 vn 0.662 0.061 0.747 vn 0.845 -0.523 -0.112 vn 0.845 -0.501 -0.185 vn 0.744 -0.668 0.009 vn 0.773 -0.630 0.079 vn 0.889 0.108 0.445 vn 0.899 0.077 0.430 vn 0.184 0.204 -0.961 vn 0.005 0.202 -0.979 vn -0.000 0.485 -0.875 vn 0.159 0.484 -0.861 vn 0.499 0.592 0.633 vn 0.305 0.950 0.065 vn -0.274 -0.953 -0.127 vn 0.245 -0.456 0.856 vn 0.083 -0.881 0.465 vn 0.435 -0.739 0.515 vn 0.504 -0.429 0.750 vn 0.818 -0.367 0.443 vn 0.933 -0.162 0.322 vn 0.872 0.029 0.489 vn 0.002 0.994 0.113 vn 0.133 0.983 -0.126 vn -0.001 0.992 -0.127 vn 0.280 0.892 -0.356 vn 0.126 0.916 -0.381 vn 0.210 0.974 -0.083 vn -0.082 0.663 0.745 vn -0.059 0.391 0.919 vn 0.111 0.992 -0.055 vn 0.081 -0.190 0.978 vn 0.035 0.076 0.996 vn 0.852 0.236 0.467 vn 0.775 0.219 0.593 vn 0.505 -0.109 0.856 vn 0.446 -0.314 0.838 vn 0.511 0.200 0.836 vn 0.623 -0.242 0.744 vn 0.436 -0.554 0.709 vn 0.599 -0.742 0.300 vn -0.036 0.177 0.984 vn -0.039 -0.159 0.987 vn 0.308 0.942 -0.135 vn 0.989 0.093 -0.111 vn 0.477 -0.259 0.840 vn 0.473 -0.423 0.773 vn 0.774 -0.329 0.541 vn 0.285 0.019 0.958 vn 0.350 0.101 0.931 vn 0.579 0.261 0.773 vn 0.298 0.015 0.954 vn 0.165 0.336 0.927 vn 0.577 0.511 0.636 vn 0.254 -0.834 0.490 vn -0.114 -0.925 0.363 vn 0.941 -0.280 -0.188 vn 0.460 -0.738 0.493 vn 0.740 -0.635 0.221 vn 0.003 0.529 0.849 vn 0.206 -0.427 -0.881 vn 0.497 -0.316 -0.808 vn 0.457 -0.144 -0.878 vn 0.179 -0.244 -0.953 vn -0.182 -0.980 -0.078 vn 0.342 -0.427 0.837 vn 0.424 -0.296 0.856 vn 0.896 -0.357 -0.264 vn 0.594 -0.104 0.798 vn 0.012 0.528 0.849 vn 0.042 0.469 0.882 vn 0.624 0.102 0.775 vn 0.324 -0.123 0.938 vn 0.202 -0.638 0.743 vn 0.714 0.512 0.477 vn 0.433 -0.511 0.742 vn -0.350 -0.708 0.613 vn 0.095 -0.410 0.907 vn 0.622 -0.593 0.512 vn 0.846 0.304 0.437 vn 0.582 -0.043 0.812 vn -0.226 -0.380 0.897 vn 0.215 0.644 0.734 vn 0.123 0.952 0.280 vn -0.004 0.956 0.293 vn -0.005 0.635 0.772 vn 0.325 -0.730 0.601 vn -0.017 -0.840 0.543 vn 0.017 -0.788 0.616 vn 0.294 -0.138 0.946 vn 0.214 0.401 0.891 vn -0.150 0.490 0.859 vn 0.573 -0.125 0.810 vn -0.134 0.957 0.258 vn 0.252 0.828 0.501 vn -0.673 0.643 0.364 vn 0.004 -0.960 0.279 vn 0.032 -0.991 0.133 vn 0.006 -0.908 0.419 vn 0.180 -0.980 0.086 vn 0.740 0.403 -0.538 vn 0.627 0.652 -0.426 vn 0.814 0.561 -0.149 vn 0.925 0.321 -0.206 vn 0.492 0.825 -0.280 vn 0.649 0.757 -0.076 vn 0.966 0.258 0.022 vn 0.864 0.501 0.053 vn 0.680 0.729 0.077 vn 0.272 -0.962 -0.032 vn 0.225 -0.968 0.111 vn 0.288 -0.510 0.810 vn 0.126 0.748 -0.651 vn 0.340 0.725 -0.598 vn 0.421 0.466 -0.778 vn 0.205 -0.458 -0.865 vn 0.489 -0.479 -0.729 vn 0.500 -0.523 -0.690 vn 0.210 -0.566 -0.798 vn 0.895 -0.322 -0.309 vn 0.759 -0.434 -0.485 vn 0.797 -0.287 -0.532 vn 0.937 -0.248 -0.245 vn -0.001 -0.238 -0.971 vn -0.000 -0.025 -1.000 vn 0.194 -0.025 -0.981 vn 0.201 -0.248 -0.948 vn 0.969 0.094 -0.229 vn 0.968 -0.101 -0.228 vn 0.814 -0.088 -0.575 vn 0.800 0.142 -0.583 vn 0.998 0.061 -0.010 vn 0.726 0.657 0.205 vn 0.000 -0.985 0.174 vn 0.985 -0.166 0.038 vn 0.955 -0.220 -0.200 vn 0.472 0.076 0.879 vn 0.343 -0.235 0.909 vn 0.464 -0.641 0.612 vn 0.578 -0.186 0.795 vn -0.189 -0.982 0.010 vn 0.004 0.938 0.345 vn 0.002 0.829 0.559 vn 0.445 0.232 0.865 vn 0.463 0.340 0.818 vn -0.116 0.983 0.143 vn 0.004 0.995 0.102 vn 0.978 0.204 0.044 vn -0.967 -0.216 -0.137 vn -0.911 -0.347 0.224 vn -0.728 0.350 0.590 vn 0.426 0.738 -0.523 vn 0.618 0.786 0.011 vn 0.151 0.857 -0.493 vn -0.333 0.912 -0.241 vn -0.277 0.956 0.095 vn -0.569 0.822 -0.032 vn -0.341 -0.671 -0.658 vn 0.161 -0.736 -0.657 vn 0.528 0.432 0.731 vn 0.586 0.105 0.803 vn 0.436 0.074 0.897 vn 0.621 0.267 0.737 vn 0.936 0.153 0.316 vn 0.999 -0.010 0.042 vn 0.826 0.281 -0.489 vn 0.775 0.178 -0.606 vn 0.995 -0.039 -0.095 vn 0.005 -0.414 0.910 vn 0.580 -0.243 0.778 vn 0.938 -0.339 -0.068 vn 0.925 -0.371 0.080 vn 0.888 -0.269 0.373 vn 0.923 -0.371 -0.106 vn 0.494 -0.274 -0.825 vn -0.001 -0.456 -0.890 vn -0.002 -0.569 -0.822 vn -0.001 -0.452 -0.892 vn -0.003 0.749 -0.663 vn -0.000 0.920 -0.391 vn -0.001 -0.280 -0.960 vn 0.470 0.194 -0.861 vn 0.965 -0.123 0.234 vn 0.400 -0.039 -0.916 vn 0.142 -0.166 -0.976 vn -0.000 -0.194 -0.981 vn 0.497 -0.049 -0.867 vn 0.998 0.042 0.045 vn 0.996 -0.037 -0.082 vn 0.009 0.433 0.901 vn 0.004 0.669 0.743 vn 0.955 0.004 0.296 vn 0.737 -0.001 0.675 vn 0.707 0.177 0.684 vn 0.484 0.627 0.610 vn 0.515 0.250 0.820 vn 0.360 0.121 0.925 vn -0.544 -0.573 0.613 vn 0.382 -0.114 0.917 vn 0.489 -0.108 0.866 vn -0.002 -0.670 0.742 vn 0.002 -0.394 0.919 vn -0.004 -0.168 0.986 vn 0.007 -0.109 0.994 vn 0.009 -0.519 0.855 vn 0.660 -0.118 0.742 vn 0.621 -0.127 0.774 vn 0.416 0.220 0.882 vn 0.946 0.046 0.322 vn 0.014 0.006 1.000 vn 0.569 0.184 0.802 vn 0.218 0.013 0.976 vn 0.044 0.087 0.995 vn -0.419 0.862 0.284 vn 0.647 -0.120 0.753 vn 0.954 -0.017 0.301 vn 0.352 0.140 -0.926 vn 0.095 -0.050 -0.994 vn 0.770 0.025 0.638 vn 0.000 -0.078 -0.997 vn 0.985 -0.172 0.009 vn 0.920 -0.340 0.195 vn 0.929 -0.331 -0.163 vn 0.969 -0.237 0.074 vn 0.969 -0.183 0.165 vn 0.801 0.160 0.577 vn 0.954 -0.021 0.301 vn 0.293 0.803 0.520 vn 0.977 0.170 0.129 vn 0.134 0.985 -0.104 vn 0.994 0.106 -0.036 vn 0.099 0.675 -0.731 vn 0.997 -0.079 -0.000 vn 0.197 0.126 -0.972 vn 0.978 -0.175 -0.110 vn 0.110 -0.321 -0.941 vn 0.939 -0.332 -0.089 vn 0.400 -0.789 -0.467 vn 0.171 -0.673 -0.720 vn 0.931 -0.336 -0.144 vn 0.854 -0.500 0.146 vn 0.161 -0.985 -0.069 vn 0.931 -0.304 -0.200 vn 0.813 -0.565 -0.143 vn 0.823 -0.546 0.154 vn 0.795 -0.387 0.467 vn 0.809 -0.168 0.563 vn 0.826 0.053 0.562 vn 0.925 0.261 0.275 vn 0.990 0.071 0.119 vn 0.951 0.129 0.281 vn 0.810 -0.147 0.568 vn 0.383 -0.603 0.699 vn 0.769 0.635 0.079 vn 0.786 0.352 0.508 vn 0.919 0.082 -0.386 vn 0.937 0.163 0.310 vn 0.974 -0.026 0.224 vn 0.787 0.550 0.279 vn 0.517 0.758 -0.397 vn 0.337 0.112 -0.935 vn 0.221 -0.300 -0.928 vn 0.395 -0.578 -0.714 vn 0.521 -0.711 -0.472 vn 0.432 -0.901 -0.043 vn 0.826 -0.520 0.218 vn 0.885 -0.217 0.412 vn 0.786 -0.107 0.609 vn 0.864 0.400 0.304 vn 0.954 0.061 0.293 vn 0.949 0.313 0.046 vn 0.991 0.028 -0.131 vn 0.945 -0.116 0.305 vn 0.970 -0.241 0.032 vn 0.946 -0.038 0.322 vn 0.886 -0.270 -0.376 vn 0.855 -0.272 -0.441 vn 0.952 -0.122 -0.281 vn 0.002 -0.883 0.469 vn -0.001 0.792 -0.611 vn -0.180 0.823 -0.539 vn -0.642 0.677 -0.360 vn -0.957 0.288 -0.031 vn -0.912 -0.300 0.281 vn -0.454 -0.866 0.207 vn -0.855 -0.043 0.517 vn -0.834 0.460 0.305 vn -0.242 0.911 0.334 vn -0.720 -0.667 -0.192 vn -0.762 -0.580 -0.288 vn 0.452 0.774 0.444 vn 0.857 0.048 0.513 vn 0.966 0.131 0.225 vn 0.211 0.953 0.219 vn -0.108 0.726 0.679 vn 0.021 0.946 0.324 vn 0.566 -0.691 -0.450 vn -0.068 0.939 -0.338 vn -0.261 -0.298 0.918 vn -0.200 -0.891 0.407 vn 0.124 -0.991 0.059 vn 0.913 -0.350 -0.211 vn 0.488 -0.838 0.244 vn 0.738 -0.593 0.322 vn 0.994 -0.060 -0.087 vn -0.000 -0.981 0.193 vn 0.000 0.974 0.227 vn -0.350 -0.016 0.936 vn 0.000 -0.017 1.000 vn 0.252 0.455 -0.854 vn 0.774 0.620 -0.127 vn 0.634 0.759 -0.148 vn 0.192 0.569 -0.800 vn 0.405 -0.094 0.909 vn 0.031 0.149 0.988 vn 0.360 0.283 0.889 vn 0.469 0.080 0.880 vn 0.769 0.452 0.452 vn 0.946 0.185 0.266 vn 0.893 0.181 0.413 vn 0.654 0.429 0.623 vn 0.506 0.610 0.610 vn 0.436 0.659 0.613 vn 0.160 0.558 0.814 vn -0.285 0.396 0.873 vn -0.223 0.539 0.812 vn 0.037 0.570 0.821 vn 0.623 0.727 -0.289 vn 0.456 0.738 0.497 vn 0.382 0.656 0.651 vn 0.278 0.687 0.671 vn 0.213 0.798 0.563 vn 0.171 0.844 0.508 vn 0.300 0.690 0.659 vn 0.144 0.793 0.591 vn 0.204 0.541 -0.816 vn -0.001 0.494 -0.870 vn 0.029 0.458 -0.888 vn 0.060 0.366 -0.929 vn 0.000 0.421 -0.907 vn 0.000 0.386 -0.922 vn 0.001 0.455 -0.891 vn 0.264 0.718 0.644 vn 0.307 0.317 -0.897 vn 0.056 0.164 -0.985 vn 0.717 0.079 0.693 vn 0.638 0.188 0.746 vn 0.000 0.202 -0.979 vn 0.006 -0.044 0.999 vn 0.001 0.405 0.914 vn 0.805 0.560 -0.194 vn 0.002 0.627 0.779 vn 0.010 -0.298 0.954 vn 0.124 0.870 -0.477 vn 0.488 0.530 -0.693 vn 0.566 0.756 -0.329 vn 0.213 0.932 -0.294 vn 0.245 -0.741 -0.626 vn 0.275 -0.782 -0.559 vn 0.044 -0.811 -0.584 vn -0.012 0.949 -0.315 vn 0.097 0.621 -0.778 vn 0.215 0.561 -0.799 vn -0.030 0.913 -0.407 vn 0.378 0.505 -0.776 vn 0.084 0.865 -0.495 vn 0.892 -0.451 -0.026 vn 0.803 -0.447 -0.394 vn 0.954 0.274 -0.123 vn 0.998 -0.024 0.066 vn 0.806 0.588 0.057 vn 0.351 0.936 -0.012 vn 0.662 -0.536 -0.524 vn 0.725 -0.630 -0.278 vn 0.524 -0.662 -0.536 vn 0.620 -0.585 -0.522 vn -0.694 -0.711 0.115 vn -0.621 -0.770 0.148 vn -0.805 -0.470 0.362 vn -0.819 -0.465 0.335 vn -0.680 -0.145 0.719 vn -0.763 -0.140 0.631 vn -0.840 -0.272 0.470 vn -0.773 -0.256 0.580 vn -0.763 -0.155 -0.627 vn -0.763 0.034 -0.645 vn -0.958 -0.057 -0.281 vn -0.910 -0.129 -0.393 vn -0.983 0.060 0.175 vn -0.980 0.096 0.177 vn -0.990 0.069 0.123 vn -0.996 0.023 0.083 vn -0.484 -0.649 0.587 vn -0.662 -0.717 0.220 vn -0.775 -0.388 0.499 vn -0.606 -0.384 0.697 vn -0.748 -0.556 0.363 vn -0.539 -0.840 0.071 vn -0.496 -0.849 0.183 vn -0.668 -0.580 0.467 vn -0.280 -0.913 0.296 vn -0.424 -0.897 0.125 vn -0.960 0.187 0.209 vn -0.965 0.222 0.143 vn -0.991 0.084 0.104 vn -0.979 0.104 0.175 vn -0.940 0.170 0.295 vn -0.909 0.107 0.404 vn -0.862 0.204 0.464 vn -0.896 0.204 0.395 vn -0.570 -0.493 0.658 vn -0.531 -0.465 0.709 vn -0.651 -0.181 0.737 vn -0.688 -0.376 0.620 vn -0.892 0.030 0.452 vn -0.827 0.122 0.549 vn -0.345 -0.706 0.619 vn -0.566 -0.461 0.684 vn -0.543 -0.393 0.742 vn -0.097 -0.841 0.533 vn -0.964 0.119 0.237 vn -0.950 0.158 0.268 vn -0.733 -0.024 0.679 vn -0.825 -0.117 0.552 vn -0.442 0.232 0.866 vn -0.605 0.237 0.760 vn -0.556 0.267 0.787 vn -0.350 0.172 0.921 vn -0.239 -0.096 0.966 vn -0.501 0.068 0.863 vn -0.679 0.342 0.650 vn -0.486 0.403 0.776 vn -0.211 -0.600 0.772 vn -0.123 -0.334 0.934 vn -0.052 -0.530 0.847 vn -0.176 -0.798 0.577 vn -0.131 -0.968 -0.212 vn -0.598 -0.684 -0.418 vn -0.205 -0.329 0.922 vn -0.374 -0.151 0.915 vn -0.117 -0.376 0.919 vn -0.246 -0.160 0.956 vn -0.126 -0.268 0.955 vn -0.137 -0.531 0.837 vn 0.062 -0.980 0.190 vn -0.478 -0.855 0.203 vn -0.669 -0.734 -0.114 vn -0.286 -0.955 0.083 vn -0.967 -0.136 0.215 vn -0.965 -0.005 0.263 vn -0.983 -0.085 0.164 vn -0.969 -0.182 0.170 vn -0.840 -0.358 0.408 vn -0.857 -0.341 0.386 vn -0.910 -0.256 0.326 vn -0.884 -0.284 0.371 vn 0.022 -0.449 0.893 vn -0.046 -0.611 0.791 vn -0.478 -0.294 0.827 vn -0.375 -0.338 0.863 vn -0.935 -0.243 0.259 vn -0.949 -0.164 0.269 vn -0.736 -0.207 0.645 vn -0.587 -0.108 0.802 vn 0.945 0.284 0.163 vn 0.592 -0.756 -0.279 vn 0.442 -0.866 -0.236 vn -0.053 -0.740 0.670 vn -0.228 -0.529 0.817 vn 0.170 -0.772 0.613 vn -0.609 -0.162 0.777 vn -0.663 -0.292 0.690 vn -0.713 0.145 0.686 vn -0.759 0.059 0.648 vn -0.825 0.047 0.564 vn -0.809 0.158 0.566 vn -0.637 0.025 0.770 vn -0.687 0.129 0.715 vn -0.821 -0.086 0.564 vn -0.891 -0.252 0.378 vn -0.721 0.489 0.490 vn -0.698 0.164 0.697 vn -0.646 -0.143 0.750 vn -0.712 0.352 0.608 vn -0.567 0.074 0.821 vn -0.464 0.032 0.885 vn -0.518 -0.023 0.855 vn -0.550 -0.128 0.825 vn -0.756 -0.260 0.601 vn -0.645 -0.025 0.764 vn -0.437 -0.158 0.885 vn -0.687 -0.310 0.657 vn -0.541 0.781 0.313 vn -0.565 0.780 0.270 vn -0.712 0.385 0.587 vn -0.611 0.201 0.765 vn -0.859 0.335 0.388 vn -0.775 0.474 0.417 vn -0.673 0.387 0.630 vn -0.628 0.400 0.668 vn -0.676 0.438 0.592 vn -0.698 0.309 0.646 vn -0.622 0.535 0.573 vn -0.511 0.327 0.795 vn -0.733 -0.405 -0.547 vn -0.884 -0.261 -0.388 vn -0.791 -0.366 0.490 vn -0.793 -0.344 0.502 vn -0.844 -0.347 0.408 vn -0.858 -0.453 0.243 vn -0.953 -0.280 0.116 vn -0.976 -0.193 0.100 vn -0.989 -0.113 0.096 vn -0.289 0.792 0.537 vn -0.301 0.654 0.693 vn -0.134 0.672 0.728 vn -0.137 0.821 0.554 vn -0.884 0.305 0.354 vn -0.716 0.471 0.515 vn -0.736 0.562 0.377 vn -0.897 0.355 0.265 vn -0.890 0.422 0.171 vn -0.179 0.082 0.981 vn -0.216 0.250 0.944 vn -0.661 -0.125 0.740 vn -0.679 0.371 0.633 vn -0.636 0.460 0.620 vn -0.594 0.426 0.682 vn -0.258 0.436 0.862 vn -0.070 0.240 0.968 vn -0.095 0.440 0.893 vn -0.011 0.089 0.996 vn -0.069 -0.049 0.996 vn -0.719 0.247 0.649 vn -0.673 0.172 0.719 vn -0.353 0.447 0.822 vn -0.270 0.134 0.954 vn -0.440 0.328 0.836 vn -0.511 0.490 0.706 vn -0.342 0.114 0.933 vn -0.435 -0.298 0.849 vn -0.552 0.158 0.818 vn -0.273 0.369 0.888 vn -0.705 -0.192 0.683 vn -0.357 0.088 0.930 vn -0.499 0.346 0.795 vn 0.009 0.585 0.811 vn 0.086 0.584 0.807 vn -0.348 -0.035 0.937 vn -0.516 0.299 0.803 vn -0.512 0.295 0.806 vn -0.339 0.070 0.938 vn -0.348 -0.070 0.935 vn -0.148 -0.003 0.989 vn -0.349 0.750 0.561 vn -0.322 0.418 0.849 vn -0.890 -0.163 0.425 vn -0.990 -0.001 0.144 vn -0.500 0.824 0.267 vn -0.501 0.717 0.484 vn -0.285 0.905 0.315 vn -0.282 0.954 0.103 vn -0.268 0.957 -0.114 vn -0.433 0.898 -0.078 vn -0.473 0.876 0.093 vn -0.131 0.985 0.111 vn -0.127 0.932 0.339 vn -0.211 -0.186 0.960 vn -0.293 -0.359 0.886 vn -0.344 -0.465 0.816 vn -0.382 -0.591 0.710 vn -0.525 -0.255 0.812 vn -0.598 0.089 0.796 vn -0.688 0.244 0.683 vn -0.344 -0.576 0.742 vn -0.544 -0.583 0.603 vn 0.098 -0.695 0.712 vn -0.805 -0.326 0.496 vn -0.132 0.306 0.943 vn -0.485 0.160 0.860 vn -0.351 -0.498 0.793 vn -0.141 -0.499 0.855 vn 0.065 -0.990 0.123 vn 0.037 -0.989 0.143 vn -0.065 -0.055 0.996 vn -0.473 -0.369 0.800 vn -0.396 0.179 0.900 vn -0.600 0.505 0.620 vn -0.387 0.499 0.776 vn -0.398 0.505 0.766 vn -0.358 0.488 0.796 vn -0.570 0.304 0.763 vn -0.317 0.412 0.854 vn -0.742 -0.129 0.658 vn -0.771 -0.207 0.602 vn -0.881 -0.036 0.472 vn -0.841 -0.052 0.538 vn -0.972 0.111 0.208 vn -0.961 0.151 0.230 vn -0.916 -0.004 0.402 vn -0.913 0.013 0.408 vn -0.689 0.026 0.724 vn -0.641 -0.316 0.699 vn -0.647 -0.304 0.699 vn -0.697 -0.094 0.711 vn -0.966 0.063 0.249 vn -0.963 0.075 0.259 vn -0.958 0.031 0.287 vn -0.681 -0.315 0.661 vn -0.745 -0.412 0.525 vn -0.666 -0.413 0.621 vn -0.548 -0.335 0.767 vn -0.107 -0.395 0.913 vn -0.299 -0.320 0.899 vn -0.418 -0.236 0.877 vn -0.210 -0.169 0.963 vn -0.090 0.952 0.291 vn -0.166 0.838 0.520 vn -0.523 0.797 0.302 vn -0.302 0.941 0.154 vn 0.408 -0.888 0.211 vn 0.735 0.117 0.668 vn -0.279 0.960 0.001 vn -0.468 0.706 0.531 vn -0.232 0.964 0.131 vn -0.555 -0.033 0.831 vn -0.517 0.199 0.833 vn -0.549 0.222 0.806 vn -0.376 0.125 0.918 vn -0.210 0.031 0.977 vn -0.435 -0.045 0.899 vn -0.739 0.154 0.656 vn -0.610 0.153 0.777 vn -0.663 0.041 0.748 vn -0.733 0.013 0.681 vn -0.744 -0.668 0.007 vn -0.845 -0.501 -0.187 vn -0.845 -0.522 -0.114 vn -0.774 -0.629 0.079 vn -0.897 0.040 0.440 vn -0.896 0.094 0.434 vn -0.179 0.204 -0.962 vn -0.157 0.488 -0.858 vn -0.506 0.590 0.630 vn -0.305 0.951 0.047 vn 0.267 -0.958 -0.102 vn -0.432 -0.745 0.509 vn -0.075 -0.883 0.463 vn -0.236 -0.454 0.859 vn -0.504 -0.423 0.753 vn -0.821 -0.351 0.449 vn -0.876 0.033 0.481 vn -0.934 -0.155 0.322 vn -0.134 0.983 -0.126 vn -0.128 0.916 -0.381 vn -0.284 0.891 -0.353 vn 0.055 0.396 0.917 vn 0.092 0.644 0.760 vn -0.199 0.976 -0.093 vn -0.109 0.991 -0.072 vn -0.039 0.079 0.996 vn -0.081 -0.191 0.978 vn -0.854 0.239 0.462 vn -0.774 0.223 0.593 vn -0.502 -0.119 0.856 vn -0.403 -0.420 0.813 vn -0.680 -0.255 0.687 vn -0.525 0.172 0.834 vn -0.376 -0.531 0.759 vn -0.576 -0.754 0.316 vn 0.040 0.159 0.986 vn 0.036 -0.180 0.983 vn -0.308 0.943 -0.129 vn -0.983 0.074 -0.170 vn -0.456 -0.445 0.771 vn -0.476 -0.297 0.828 vn -0.788 -0.316 0.528 vn -0.393 0.095 0.915 vn -0.308 0.018 0.951 vn -0.125 0.331 0.935 vn -0.283 0.033 0.959 vn -0.598 0.322 0.734 vn -0.575 0.559 0.598 vn -0.216 -0.852 0.476 vn 0.156 -0.927 0.342 vn -0.941 -0.282 -0.189 vn -0.739 -0.637 0.221 vn -0.469 -0.731 0.495 vn -0.458 -0.139 -0.878 vn -0.498 -0.315 -0.808 vn -0.210 -0.426 -0.880 vn -0.182 -0.243 -0.953 vn -0.334 -0.402 0.853 vn 0.221 -0.960 -0.173 vn -0.414 -0.366 0.834 vn -0.902 -0.373 -0.218 vn -0.632 -0.114 0.767 vn -0.642 0.122 0.757 vn -0.194 -0.651 0.734 vn -0.351 -0.095 0.931 vn -0.707 0.530 0.467 vn -0.087 -0.550 0.831 vn 0.352 -0.710 0.610 vn -0.500 -0.482 0.720 vn -0.653 -0.626 0.427 vn -0.856 0.328 0.399 vn -0.578 -0.029 0.816 vn 0.275 -0.432 0.859 vn -0.123 0.953 0.277 vn -0.228 0.657 0.719 vn -0.298 -0.735 0.609 vn -0.300 -0.179 0.937 vn -0.219 0.400 0.890 vn -0.587 -0.175 0.791 vn 0.175 0.460 0.870 vn -0.179 0.856 0.485 vn 0.114 0.959 0.259 vn 0.664 0.620 0.418 vn -0.026 -0.991 0.129 vn -0.184 -0.979 0.082 vn -0.810 0.566 -0.151 vn -0.628 0.654 -0.422 vn -0.741 0.405 -0.536 vn -0.924 0.322 -0.207 vn -0.493 0.823 -0.280 vn -0.648 0.758 -0.080 vn -0.966 0.258 0.022 vn -0.864 0.501 0.051 vn -0.679 0.730 0.075 vn -0.221 -0.970 0.105 vn -0.271 -0.962 -0.038 vn -0.376 -0.516 0.769 vn -0.124 0.748 -0.652 vn -0.339 0.727 -0.598 vn -0.420 0.469 -0.777 vn -0.500 -0.524 -0.690 vn -0.489 -0.481 -0.728 vn -0.206 -0.458 -0.865 vn -0.212 -0.565 -0.797 vn -0.893 -0.325 -0.312 vn -0.759 -0.435 -0.485 vn -0.796 -0.289 -0.532 vn -0.937 -0.249 -0.246 vn -0.193 -0.029 -0.981 vn -0.202 -0.249 -0.947 vn -0.814 -0.090 -0.574 vn -0.969 -0.102 -0.227 vn -0.969 0.093 -0.229 vn -0.801 0.142 -0.581 vn -0.998 0.061 -0.010 vn -0.718 0.664 0.209 vn -0.985 -0.168 0.036 vn -0.954 -0.222 -0.201 vn -0.451 0.039 0.891 vn -0.341 -0.253 0.905 vn -0.604 -0.144 0.784 vn -0.472 -0.641 0.606 vn 0.107 -0.991 0.080 vn -0.463 0.274 0.843 vn -0.002 0.997 0.081 vn 0.083 0.977 0.195 vn -0.466 0.366 0.805 vn -0.977 0.200 0.072 vn 0.916 -0.331 0.226 vn 0.929 -0.364 -0.067 vn 0.728 0.359 0.584 vn -0.419 0.737 -0.531 vn -0.638 0.769 0.043 vn -0.146 0.857 -0.494 vn 0.280 0.954 0.105 vn 0.343 0.909 -0.237 vn 0.546 0.838 -0.008 vn 0.342 -0.678 -0.651 vn -0.159 -0.734 -0.660 vn -0.545 0.363 0.756 vn -0.599 0.165 0.783 vn -0.447 0.066 0.892 vn -0.645 0.255 0.721 vn -0.936 0.164 0.311 vn -0.776 0.182 -0.604 vn -0.827 0.285 -0.485 vn -0.999 -0.012 0.041 vn -0.995 -0.037 -0.093 vn -0.586 -0.252 0.770 vn -0.926 -0.370 0.079 vn -0.938 -0.339 -0.067 vn -0.889 -0.266 0.372 vn -0.922 -0.372 -0.106 vn -0.493 -0.275 -0.825 vn -0.473 0.194 -0.860 vn -0.965 -0.122 0.231 vn -0.401 -0.036 -0.915 vn -0.143 -0.164 -0.976 vn -0.496 -0.052 -0.867 vn -0.996 -0.037 -0.083 vn -0.998 0.042 0.045 vn -0.950 0.012 0.313 vn -0.733 -0.008 0.681 vn -0.670 0.247 0.700 vn -0.408 0.697 0.589 vn -0.330 0.155 0.931 vn -0.517 0.244 0.821 vn 0.568 -0.625 0.535 vn -0.512 -0.108 0.852 vn -0.414 -0.112 0.903 vn -0.654 -0.140 0.743 vn -0.608 -0.086 0.789 vn -0.422 0.215 0.881 vn -0.943 0.031 0.332 vn -0.549 0.190 0.814 vn -0.193 0.018 0.981 vn 0.358 0.872 0.335 vn -0.651 -0.118 0.750 vn -0.954 -0.010 0.300 vn -0.352 0.145 -0.925 vn -0.095 -0.049 -0.994 vn -0.769 0.031 0.639 vn -0.929 -0.329 -0.171 vn -0.923 -0.336 0.190 vn -0.985 -0.174 0.005 vn -0.970 -0.234 0.068 vn -0.801 0.162 0.576 vn -0.969 -0.184 0.166 vn -0.293 0.803 0.519 vn -0.954 -0.019 0.300 vn -0.133 0.986 -0.105 vn -0.976 0.175 0.130 vn -0.098 0.675 -0.732 vn -0.993 0.112 -0.041 vn -0.197 0.127 -0.972 vn -0.997 -0.077 -0.003 vn -0.112 -0.322 -0.940 vn -0.978 -0.176 -0.109 vn -0.171 -0.674 -0.719 vn -0.397 -0.789 -0.468 vn -0.937 -0.337 -0.091 vn -0.929 -0.341 -0.146 vn -0.158 -0.985 -0.070 vn -0.854 -0.500 0.145 vn -0.814 -0.564 -0.141 vn -0.931 -0.306 -0.199 vn -0.824 -0.545 0.156 vn -0.797 -0.383 0.466 vn -0.811 -0.165 0.562 vn -0.824 0.053 0.564 vn -0.926 0.257 0.275 vn -0.991 0.062 0.118 vn -0.952 0.122 0.281 vn -0.383 -0.604 0.699 vn -0.810 -0.150 0.567 vn -0.784 0.355 0.509 vn -0.761 0.645 0.076 vn -0.920 0.079 -0.385 vn -0.975 -0.023 0.222 vn -0.937 0.166 0.308 vn -0.787 0.551 0.279 vn -0.517 0.758 -0.396 vn -0.337 0.112 -0.935 vn -0.221 -0.301 -0.928 vn -0.395 -0.579 -0.714 vn -0.520 -0.711 -0.473 vn -0.426 -0.904 -0.044 vn -0.824 -0.523 0.219 vn -0.886 -0.220 0.409 vn -0.863 0.404 0.303 vn -0.782 -0.104 0.615 vn -0.953 0.066 0.297 vn -0.949 0.312 0.046 vn -0.991 0.025 -0.134 vn -0.944 -0.116 0.308 vn -0.971 -0.237 0.041 vn -0.947 -0.041 0.318 vn -0.854 -0.274 -0.443 vn -0.885 -0.271 -0.378 vn -0.952 -0.121 -0.282 vn 0.180 0.824 -0.537 vn 0.642 0.679 -0.355 vn 0.956 0.291 -0.021 vn 0.453 -0.867 0.208 vn 0.910 -0.301 0.285 vn 0.854 -0.043 0.518 vn 0.833 0.459 0.308 vn 0.241 0.911 0.334 vn 0.731 -0.650 -0.206 vn 0.760 -0.585 -0.282 vn -0.814 0.019 0.580 vn -0.563 0.638 0.526 vn -0.925 -0.012 0.381 vn -0.214 0.952 0.217 vn 0.096 0.721 0.686 vn -0.027 0.945 0.325 vn -0.555 -0.678 -0.481 vn 0.062 0.937 -0.343 vn 0.240 -0.291 0.926 vn 0.184 -0.889 0.419 vn -0.126 -0.990 0.061 vn -0.889 -0.369 -0.271 vn -0.506 -0.832 0.229 vn -0.808 -0.443 0.388 vn -0.993 -0.084 0.087 vn 0.350 -0.016 0.937 vn -0.636 0.759 -0.140 vn -0.771 0.626 -0.115 vn -0.250 0.462 -0.851 vn -0.192 0.568 -0.801 vn -0.359 0.279 0.891 vn -0.026 0.144 0.989 vn -0.398 -0.100 0.912 vn -0.465 0.084 0.881 vn -0.895 0.186 0.405 vn -0.947 0.184 0.264 vn -0.761 0.459 0.458 vn -0.657 0.429 0.620 vn -0.426 0.660 0.618 vn -0.505 0.610 0.611 vn 0.223 0.536 0.814 vn 0.285 0.393 0.874 vn -0.163 0.555 0.815 vn -0.038 0.570 0.821 vn -0.628 0.723 -0.288 vn -0.458 0.737 0.497 vn -0.212 0.799 0.563 vn -0.278 0.687 0.672 vn -0.380 0.657 0.651 vn -0.170 0.846 0.506 vn -0.305 0.687 0.660 vn -0.144 0.795 0.589 vn 0.001 0.494 -0.870 vn -0.208 0.539 -0.816 vn -0.027 0.458 -0.888 vn -0.057 0.367 -0.929 vn -0.262 0.718 0.645 vn -0.054 0.163 -0.985 vn -0.306 0.325 -0.895 vn -0.643 0.181 0.744 vn -0.717 0.083 0.692 vn -0.800 0.573 -0.178 vn 0.296 -0.070 0.953 vn -0.319 -0.065 0.946 # 1258 vertex normals g head s 1 f 24/1/24 25/2/25 26/3/26 f 24/1/24 26/3/26 23/4/23 f 28/5/28 29/6/29 30/7/30 f 28/5/28 30/7/30 27/8/27 f 32/9/32 33/10/33 34/11/34 f 32/9/32 34/11/34 31/12/31 f 36/13/36 31/12/31 34/11/34 f 36/13/36 34/11/34 35/14/35 f 36/13/36 35/14/35 25/2/25 f 36/13/36 25/2/25 24/1/24 f 38/15/38 39/16/39 40/17/40 f 38/15/38 40/17/40 37/18/37 f 42/19/42 23/4/23 26/3/26 f 42/19/42 26/3/26 41/20/41 f 40/17/40 42/19/42 41/20/41 f 40/17/40 41/20/41 37/18/37 f 38/15/38 43/21/43 44/22/44 f 38/15/38 44/22/44 39/16/39 f 32/9/32 45/23/45 46/24/46 f 32/9/32 46/24/46 33/10/33 f 28/5/28 44/22/44 48/25/48 f 28/5/28 48/25/48 47/26/47 f 50/27/50 51/28/51 52/29/52 f 50/27/50 52/29/52 49/30/49 f 54/31/54 55/32/55 56/33/56 f 54/31/54 56/33/56 53/34/53 f 58/35/58 59/36/59 60/37/60 f 58/35/58 60/37/60 57/38/57 f 62/39/62 63/40/63 64/41/64 f 62/39/62 64/41/64 61/42/61 f 66/43/66 67/44/67 68/45/68 f 66/43/66 68/45/68 65/46/65 f 70/47/70 71/48/71 72/49/72 f 70/47/70 72/49/72 69/50/69 f 67/44/67 66/43/66 74/51/74 f 67/44/67 74/51/74 73/52/73 f 66/43/66 51/28/51 50/27/50 f 66/43/66 50/27/50 74/51/74 f 76/53/76 77/54/77 78/55/78 f 76/53/76 78/55/78 75/56/75 f 80/57/80 81/58/81 82/59/82 f 80/57/80 82/59/82 79/60/79 f 84/61/84 85/62/85 86/63/86 f 84/61/84 86/63/86 83/64/83 f 87/65/87 88/66/88 80/57/80 f 87/65/87 80/57/80 79/60/79 f 90/67/90 91/68/91 92/69/92 f 90/67/90 92/69/92 89/70/89 f 93/71/93 94/72/94 78/55/78 f 93/71/93 78/55/78 77/54/77 f 87/65/87 95/73/95 96/74/96 f 87/65/87 96/74/96 88/66/88 f 98/75/98 99/76/99 100/77/100 f 98/75/98 100/77/100 97/78/97 f 100/77/100 101/79/101 102/80/102 f 100/77/100 102/80/102 97/78/97 f 98/75/98 103/81/103 104/82/104 f 98/75/98 104/82/104 99/76/99 f 106/83/106 107/84/107 108/85/108 f 106/83/106 108/85/108 105/86/105 f 109/87/109 110/88/110 105/86/105 f 109/87/109 105/86/105 108/85/108 f 101/79/101 111/89/111 112/90/112 f 101/79/101 112/90/112 102/80/102 f 114/91/114 115/92/115 116/93/116 f 114/91/114 116/93/116 113/94/113 f 118/95/118 119/96/119 120/97/120 f 118/95/118 120/97/120 117/98/117 f 122/99/122 123/100/123 124/101/124 f 122/99/122 124/101/124 121/102/121 f 126/103/126 127/104/127 128/105/128 f 126/103/126 128/105/128 125/106/125 f 130/107/130 131/108/131 132/109/132 f 130/107/130 132/109/132 129/110/129 f 125/106/125 128/105/128 134/111/134 f 125/106/125 134/111/134 133/112/133 f 56/33/56 55/32/55 136/113/136 f 56/33/56 136/113/136 135/114/135 f 37/115/37 137/116/137 138/117/138 f 37/115/37 138/117/138 38/118/38 f 139/119/139 43/120/43 38/118/38 f 139/119/139 38/118/38 138/117/138 f 140/121/140 141/122/141 142/123/142 f 140/121/140 142/123/142 130/107/130 f 144/124/144 129/110/129 132/109/132 f 144/124/144 132/109/132 143/125/143 f 146/126/146 147/127/147 148/128/148 f 146/126/146 148/128/148 145/129/145 f 150/130/150 151/131/151 54/31/54 f 150/130/150 54/31/54 149/132/149 f 54/31/54 53/34/53 152/133/152 f 54/31/54 152/133/152 149/132/149 f 154/134/154 155/135/155 156/136/156 f 154/134/154 156/136/156 153/137/153 f 158/138/158 159/139/159 160/140/160 f 158/138/158 160/140/160 157/141/157 f 162/142/162 163/143/163 164/144/164 f 162/142/162 164/144/164 161/145/161 f 129/110/129 144/124/144 157/141/157 f 129/110/129 157/141/157 160/140/160 f 156/136/156 155/135/155 166/146/166 f 156/136/156 166/146/166 165/147/165 f 168/148/168 169/149/169 170/150/170 f 168/148/168 170/150/170 167/151/167 f 171/152/171 172/153/172 173/154/173 f 171/152/171 173/154/173 169/149/169 f 175/155/175 176/156/176 171/152/171 f 175/155/175 171/152/171 174/157/174 f 59/36/59 177/158/177 178/159/178 f 59/36/59 178/159/178 60/37/60 f 180/160/180 181/161/181 49/30/49 f 180/160/180 49/30/49 179/162/179 f 127/104/127 52/29/52 182/163/182 f 127/104/127 182/163/182 128/105/128 f 134/111/134 183/164/183 184/165/184 f 134/111/134 184/165/184 124/101/124 f 185/166/185 121/102/121 124/101/124 f 185/166/185 124/101/124 184/165/184 f 187/167/187 188/168/188 189/169/189 f 187/167/187 189/169/189 186/170/186 f 191/171/191 192/172/192 193/173/193 f 191/171/191 193/173/193 190/174/190 f 76/53/76 194/175/194 193/173/193 f 76/53/76 193/173/193 77/54/77 f 100/77/100 99/76/99 196/176/196 f 100/77/100 196/176/196 195/177/195 f 176/156/176 175/155/175 198/178/198 f 176/156/176 198/178/198 197/179/197 f 199/180/199 200/181/200 173/154/173 f 199/180/199 173/154/173 172/153/172 f 196/176/196 202/182/202 203/183/203 f 196/176/196 203/183/203 201/184/201 f 205/185/205 206/186/206 207/187/207 f 205/185/205 207/187/207 204/188/204 f 208/189/208 205/185/205 204/188/204 f 208/189/208 204/188/204 201/184/201 f 210/190/210 97/78/97 102/80/102 f 210/190/210 102/80/102 209/191/209 f 79/60/79 210/190/210 209/191/209 f 79/60/79 209/191/209 87/65/87 f 212/192/212 213/193/213 214/194/214 f 212/192/212 214/194/214 211/195/211 f 216/196/216 217/197/217 218/198/218 f 216/196/216 218/198/218 215/199/215 f 220/200/220 216/196/216 215/199/215 f 220/200/220 215/199/215 219/201/219 f 222/202/222 223/203/223 218/198/218 f 222/202/222 218/198/218 221/204/221 f 225/205/225 226/206/226 227/207/227 f 225/205/225 227/207/227 224/208/224 f 222/202/222 221/204/221 229/209/229 f 222/202/222 229/209/229 228/210/228 f 230/211/230 231/212/231 220/200/220 f 230/211/230 220/200/220 219/201/219 f 227/207/227 226/206/226 231/212/231 f 227/207/227 231/212/231 230/211/230 f 233/213/233 234/214/234 235/215/235 f 233/213/233 235/215/235 232/216/232 f 186/170/186 203/183/203 202/182/202 f 186/170/186 202/182/202 187/167/187 f 236/217/236 237/218/237 238/219/238 f 236/217/236 238/219/238 188/168/188 f 240/220/240 241/221/241 242/222/242 f 240/220/240 242/222/242 239/223/239 f 241/221/241 243/224/243 244/225/244 f 241/221/241 244/225/244 238/219/238 f 245/226/245 101/79/101 100/77/100 f 245/226/245 100/77/100 195/177/195 f 195/177/195 204/188/204 207/187/207 f 195/177/195 207/187/207 245/226/245 f 111/89/111 246/227/246 247/228/247 f 111/89/111 247/228/247 115/92/115 f 141/122/141 140/121/140 249/229/249 f 141/122/141 249/229/249 248/230/248 f 251/231/251 252/232/252 253/233/253 f 251/231/251 253/233/253 250/234/250 f 254/235/254 118/95/118 255/236/255 f 254/235/254 255/236/255 217/197/217 f 257/237/257 258/238/258 259/239/259 f 257/237/257 259/239/259 256/240/256 f 256/240/256 259/239/259 261/241/261 f 256/240/256 261/241/261 260/242/260 f 260/242/260 261/241/261 30/243/30 f 260/242/260 30/243/30 29/244/29 f 218/198/218 217/197/217 262/245/262 f 218/198/218 262/245/262 221/204/221 f 259/239/259 258/238/258 264/246/264 f 259/239/259 264/246/264 263/247/263 f 266/248/266 30/243/30 261/241/261 f 266/248/266 261/241/261 265/249/265 f 253/233/253 252/232/252 268/250/268 f 253/233/253 268/250/268 267/251/267 f 270/252/270 200/181/200 271/253/271 f 270/252/270 271/253/271 269/254/269 f 199/180/199 272/255/272 271/253/271 f 199/180/199 271/253/271 200/181/200 f 199/180/199 273/256/273 274/257/274 f 199/180/199 274/257/274 272/255/272 f 276/258/276 267/251/267 268/250/268 f 276/258/276 268/250/268 275/259/275 f 275/259/275 268/250/268 269/254/269 f 275/259/275 269/254/269 277/260/277 f 93/71/93 77/54/77 193/173/193 f 93/71/93 193/173/193 192/172/192 f 279/261/279 280/262/280 281/263/281 f 279/261/279 281/263/281 278/264/278 f 278/264/278 88/66/88 96/74/96 f 278/264/278 96/74/96 279/261/279 f 282/265/282 283/266/283 62/39/62 f 282/265/282 62/39/62 94/72/94 f 281/263/281 284/267/284 285/268/285 f 281/263/281 285/268/285 278/264/278 f 287/269/287 288/270/288 289/271/289 f 287/269/287 289/271/289 286/272/286 f 63/40/63 62/39/62 283/266/283 f 63/40/63 283/266/283 290/273/290 f 283/266/283 291/274/291 292/275/292 f 283/266/283 292/275/292 290/273/290 f 293/276/293 294/277/294 68/45/68 f 293/276/293 68/45/68 67/44/67 f 296/278/296 297/279/297 298/280/298 f 296/278/296 298/280/298 295/281/295 f 300/282/300 301/283/301 302/284/302 f 300/282/300 302/284/302 299/285/299 f 304/286/304 305/287/305 306/288/306 f 304/286/304 306/288/306 303/289/303 f 138/117/138 137/116/137 308/290/308 f 138/117/138 308/290/308 307/291/307 f 165/147/165 310/292/310 311/293/311 f 165/147/165 311/293/311 309/294/309 f 312/295/312 55/32/55 54/31/54 f 312/295/312 54/31/54 151/131/151 f 314/296/314 151/131/151 150/130/150 f 314/296/314 150/130/150 313/297/313 f 315/298/315 316/299/316 227/207/227 f 315/298/315 227/207/227 230/211/230 f 136/113/136 317/300/317 158/138/158 f 136/113/136 158/138/158 157/141/157 f 319/301/319 148/128/148 147/127/147 f 319/301/319 147/127/147 318/302/318 f 320/303/320 321/304/321 147/127/147 f 320/303/320 147/127/147 146/126/146 f 323/305/323 324/306/324 325/307/325 f 323/305/323 325/307/325 322/308/322 f 80/57/80 88/66/88 278/264/278 f 80/57/80 278/264/278 285/268/285 f 327/309/327 145/129/145 148/128/148 f 327/309/327 148/128/148 326/310/326 f 279/261/279 286/272/286 289/271/289 f 279/261/279 289/271/289 280/262/280 f 329/311/329 330/312/330 331/313/331 f 329/311/329 331/313/331 328/314/328 f 187/167/187 202/182/202 104/82/104 f 187/167/187 104/82/104 332/315/332 f 236/217/236 332/315/332 191/171/191 f 236/217/236 191/171/191 190/174/190 f 165/147/165 166/146/166 333/316/333 f 165/147/165 333/316/333 310/292/310 f 139/119/139 334/317/334 48/318/48 f 139/119/139 48/318/48 43/120/43 f 336/319/336 337/320/337 338/321/338 f 336/319/336 338/321/338 335/322/335 f 51/28/51 324/306/324 182/163/182 f 51/28/51 182/163/182 52/29/52 f 339/323/339 126/103/126 53/34/53 f 339/323/339 53/34/53 56/33/56 f 340/324/340 341/325/341 149/132/149 f 340/324/340 149/132/149 152/133/152 f 243/224/243 343/326/343 344/327/344 f 243/224/243 344/327/344 342/328/342 f 346/329/346 343/326/343 240/220/240 f 346/329/346 240/220/240 345/330/345 f 348/331/348 349/332/349 350/333/350 f 348/331/348 350/333/350 347/334/347 f 351/335/351 352/336/352 213/193/213 f 351/335/351 213/193/213 212/192/212 f 128/105/128 182/163/182 183/164/183 f 128/105/128 183/164/183 134/111/134 f 103/81/103 98/75/98 354/337/354 f 103/81/103 354/337/354 353/338/353 f 114/91/114 113/94/113 356/339/356 f 114/91/114 356/339/356 355/340/355 f 358/341/358 197/179/197 198/178/198 f 358/341/358 198/178/198 357/342/357 f 107/84/107 359/343/359 360/344/360 f 107/84/107 360/344/360 108/85/108 f 348/331/348 361/345/361 362/346/362 f 348/331/348 362/346/362 349/332/349 f 347/334/347 363/347/363 234/214/234 f 347/334/347 234/214/234 348/331/348 f 220/200/220 231/212/231 167/151/167 f 220/200/220 167/151/167 364/348/364 f 153/137/153 366/349/366 300/282/300 f 153/137/153 300/282/300 365/350/365 f 295/281/295 72/49/72 71/48/71 f 295/281/295 71/48/71 296/278/296 f 179/162/179 339/323/339 367/351/367 f 179/162/179 367/351/367 180/160/180 f 368/352/368 369/353/369 158/138/158 f 368/352/368 158/138/158 317/300/317 f 317/300/317 136/113/136 55/32/55 f 317/300/317 55/32/55 312/295/312 f 371/354/371 372/355/372 373/356/373 f 371/354/371 373/356/373 370/357/370 f 41/358/41 26/359/26 306/288/306 f 41/358/41 306/288/306 305/287/305 f 305/287/305 137/116/137 37/115/37 f 305/287/305 37/115/37 41/358/41 f 248/230/248 374/360/374 375/361/375 f 248/230/248 375/361/375 141/122/141 f 66/43/66 325/307/325 324/306/324 f 66/43/66 324/306/324 51/28/51 f 183/164/183 323/305/323 376/362/376 f 183/164/183 376/362/376 184/165/184 f 378/363/378 253/233/253 267/251/267 f 378/363/378 267/251/267 377/364/377 f 269/254/269 271/253/271 379/365/379 f 269/254/269 379/365/379 277/260/277 f 381/366/381 382/367/382 383/368/383 f 381/366/381 383/368/383 380/369/380 f 384/370/384 385/371/385 105/86/105 f 384/370/384 105/86/105 110/88/110 f 105/86/105 385/371/385 386/372/386 f 105/86/105 386/372/386 106/83/106 f 360/344/360 387/373/387 109/87/109 f 360/344/360 109/87/109 108/85/108 f 181/161/181 180/160/180 164/144/164 f 181/161/181 164/144/164 163/143/163 f 365/350/365 388/374/388 154/134/154 f 365/350/365 154/134/154 153/137/153 f 168/148/168 167/151/167 231/212/231 f 168/148/168 231/212/231 226/206/226 f 81/58/81 291/274/291 283/266/283 f 81/58/81 283/266/283 282/265/282 f 272/255/272 389/375/389 379/365/379 f 272/255/272 379/365/379 271/253/271 f 274/257/274 390/376/390 389/375/389 f 274/257/274 389/375/389 272/255/272 f 139/119/139 375/361/375 374/360/374 f 139/119/139 374/360/374 334/317/334 f 391/377/391 366/349/366 153/137/153 f 391/377/391 153/137/153 156/136/156 f 392/378/392 393/379/393 366/349/366 f 392/378/392 366/349/366 391/377/391 f 173/154/173 200/181/200 270/252/270 f 173/154/173 270/252/270 394/380/394 f 301/283/301 300/282/300 366/349/366 f 301/283/301 366/349/366 393/379/393 f 396/381/396 397/382/397 398/383/398 f 396/381/396 398/383/398 395/384/395 f 399/385/399 364/348/364 167/151/167 f 399/385/399 167/151/167 170/150/170 f 394/380/394 251/231/251 399/385/399 f 394/380/394 399/385/399 170/150/170 f 270/252/270 252/232/252 251/231/251 f 270/252/270 251/231/251 394/380/394 f 102/80/102 112/90/112 400/386/400 f 102/80/102 400/386/400 209/191/209 f 131/108/131 401/387/401 372/355/372 f 131/108/131 372/355/372 371/354/371 f 391/377/391 156/136/156 165/147/165 f 391/377/391 165/147/165 309/294/309 f 403/388/403 404/389/404 405/390/405 f 403/388/403 405/390/405 402/391/402 f 402/391/402 392/378/392 391/377/391 f 402/391/402 391/377/391 309/294/309 f 35/392/35 310/292/310 333/316/333 f 35/392/35 333/316/333 25/393/25 f 35/392/35 34/394/34 311/293/311 f 35/392/35 311/293/311 310/292/310 f 34/394/34 33/395/33 403/388/403 f 34/394/34 403/388/403 311/293/311 f 406/396/406 262/245/262 217/197/217 f 406/396/406 217/197/217 255/236/255 f 377/364/377 407/397/407 408/398/408 f 377/364/377 408/398/408 406/396/406 f 117/98/117 378/363/378 255/236/255 f 117/98/117 255/236/255 118/95/118 f 270/252/270 269/254/269 268/250/268 f 270/252/270 268/250/268 252/232/252 f 304/286/304 303/289/303 373/356/373 f 304/286/304 373/356/373 372/355/372 f 362/346/362 409/399/409 410/400/410 f 362/346/362 410/400/410 349/332/349 f 411/401/411 412/402/412 89/70/89 f 411/401/411 89/70/89 92/69/92 f 414/403/414 411/401/411 415/404/415 f 414/403/414 415/404/415 413/405/413 f 417/406/417 336/319/336 418/407/418 f 417/406/417 418/407/418 416/408/416 f 337/320/337 419/409/419 69/50/69 f 337/320/337 69/50/69 72/49/72 f 421/410/421 422/411/422 423/412/423 f 421/410/421 423/412/423 420/413/420 f 421/410/421 424/414/424 425/415/425 f 421/410/421 425/415/425 422/411/422 f 423/412/423 422/411/422 427/416/427 f 423/412/423 427/416/427 426/417/426 f 239/223/239 242/222/242 428/418/428 f 239/223/239 428/418/428 425/415/425 f 430/419/430 73/52/73 74/51/74 f 430/419/430 74/51/74 429/420/429 f 70/47/70 69/50/69 419/409/419 f 70/47/70 419/409/419 429/420/429 f 247/228/247 431/421/431 116/93/116 f 247/228/247 116/93/116 115/92/115 f 346/329/346 345/330/345 433/422/433 f 346/329/346 433/422/433 432/423/432 f 433/422/433 421/410/421 420/413/420 f 433/422/433 420/413/420 434/424/434 f 436/425/436 437/426/437 438/427/438 f 436/425/436 438/427/438 435/428/435 f 437/426/437 381/366/381 380/369/380 f 437/426/437 380/369/380 438/427/438 f 178/159/178 177/158/177 440/429/440 f 178/159/178 440/429/440 439/430/439 f 440/429/440 441/431/441 442/432/442 f 440/429/440 442/432/442 439/430/439 f 444/433/444 445/434/445 446/435/446 f 444/433/444 446/435/446 443/436/443 f 324/306/324 323/305/323 183/164/183 f 324/306/324 183/164/183 182/163/182 f 213/193/213 352/336/352 357/342/357 f 213/193/213 357/342/357 198/178/198 f 214/194/214 175/155/175 174/157/174 f 214/194/214 174/157/174 225/205/225 f 448/437/448 449/438/449 450/439/450 f 448/437/448 450/439/450 447/440/447 f 423/412/423 426/417/426 451/441/451 f 423/412/423 451/441/451 447/440/447 f 75/56/75 451/441/451 426/417/426 f 75/56/75 426/417/426 76/53/76 f 78/55/78 94/72/94 62/39/62 f 78/55/78 62/39/62 61/42/61 f 286/272/286 86/63/86 85/62/85 f 286/272/286 85/62/85 287/269/287 f 95/73/95 87/65/87 209/191/209 f 95/73/95 209/191/209 400/386/400 f 237/218/237 452/442/452 428/418/428 f 237/218/237 428/418/428 242/222/242 f 190/174/190 193/173/193 194/175/194 f 190/174/190 194/175/194 452/442/452 f 237/218/237 236/217/236 190/174/190 f 237/218/237 190/174/190 452/442/452 f 79/60/79 82/59/82 354/337/354 f 79/60/79 354/337/354 210/190/210 f 286/272/286 279/261/279 96/74/96 f 286/272/286 96/74/96 86/63/86 f 430/419/430 417/406/417 416/408/416 f 430/419/430 416/408/416 453/443/453 f 338/321/338 295/281/295 298/280/298 f 338/321/338 298/280/298 299/285/299 f 57/38/57 60/37/60 455/444/455 f 57/38/57 455/444/455 454/445/454 f 212/192/212 456/446/456 457/447/457 f 212/192/212 457/447/457 351/335/351 f 83/64/83 355/340/355 356/339/356 f 83/64/83 356/339/356 84/61/84 f 142/123/142 141/122/141 375/361/375 f 142/123/142 375/361/375 307/291/307 f 401/387/401 142/123/142 307/291/307 f 401/387/401 307/291/307 308/290/308 f 459/448/459 257/237/257 256/240/256 f 459/448/459 256/240/256 458/449/458 f 228/210/228 264/246/264 258/238/258 f 228/210/228 258/238/258 222/202/222 f 256/240/256 260/242/260 460/450/460 f 256/240/256 460/450/460 458/449/458 f 460/450/460 260/242/260 29/244/29 f 460/450/460 29/244/29 47/451/47 f 263/247/263 265/249/265 261/241/261 f 263/247/263 261/241/261 259/239/259 f 461/452/461 462/453/462 189/169/189 f 461/452/461 189/169/189 244/225/244 f 227/207/227 316/299/316 463/454/463 f 227/207/227 463/454/463 224/208/224 f 465/455/465 466/456/466 410/400/410 f 465/455/465 410/400/410 464/457/464 f 90/67/90 386/372/386 385/371/385 f 90/67/90 385/371/385 91/68/91 f 233/213/233 361/345/361 348/331/348 f 233/213/233 348/331/348 234/214/234 f 235/215/235 234/214/234 363/347/363 f 235/215/235 363/347/363 467/458/467 f 338/321/338 337/320/337 72/49/72 f 338/321/338 72/49/72 295/281/295 f 338/321/338 299/285/299 302/284/302 f 338/321/338 302/284/302 335/322/335 f 468/459/468 469/460/469 470/461/470 f 468/459/468 470/461/470 415/404/415 f 347/334/347 471/462/471 472/463/472 f 347/334/347 472/463/472 363/347/363 f 471/462/471 347/334/347 350/333/350 f 471/462/471 350/333/350 473/464/473 f 465/455/465 475/465/475 476/466/476 f 465/455/465 476/466/476 474/467/474 f 384/370/384 110/88/110 478/468/478 f 384/370/384 478/468/478 477/469/477 f 414/403/414 479/470/479 412/402/412 f 414/403/414 412/402/412 411/401/411 f 288/270/288 287/269/287 412/402/412 f 288/270/288 412/402/412 479/470/479 f 85/62/85 84/61/84 90/67/90 f 85/62/85 90/67/90 89/70/89 f 386/372/386 356/339/356 113/94/113 f 386/372/386 113/94/113 106/83/106 f 232/216/232 358/341/358 357/342/357 f 232/216/232 357/342/357 233/213/233 f 297/279/297 296/278/296 181/161/181 f 297/279/297 181/161/181 163/143/163 f 419/409/419 337/320/337 336/319/336 f 419/409/419 336/319/336 417/406/417 f 49/30/49 52/29/52 127/104/127 f 49/30/49 127/104/127 179/162/179 f 26/359/26 25/393/25 333/316/333 f 26/359/26 333/316/333 306/288/306 f 371/354/371 370/357/370 162/142/162 f 371/354/371 162/142/162 161/145/161 f 258/238/258 257/237/257 223/203/223 f 258/238/258 223/203/223 222/202/222 f 257/237/257 459/448/459 480/471/480 f 257/237/257 480/471/480 223/203/223 f 211/195/211 214/194/214 225/205/225 f 211/195/211 225/205/225 224/208/224 f 316/299/316 481/472/481 314/296/314 f 316/299/316 314/296/314 463/454/463 f 171/152/171 169/149/169 168/148/168 f 171/152/171 168/148/168 174/157/174 f 273/256/273 199/180/199 172/153/172 f 273/256/273 172/153/172 482/473/482 f 168/148/168 226/206/226 225/205/225 f 168/148/168 225/205/225 174/157/174 f 245/226/245 246/227/246 111/89/111 f 245/226/245 111/89/111 101/79/101 f 114/91/114 112/90/112 111/89/111 f 114/91/114 111/89/111 115/92/115 f 210/190/210 354/337/354 98/75/98 f 210/190/210 98/75/98 97/78/97 f 431/421/431 358/341/358 232/216/232 f 431/421/431 232/216/232 359/343/359 f 235/215/235 360/344/360 359/343/359 f 235/215/235 359/343/359 232/216/232 f 360/344/360 235/215/235 467/458/467 f 360/344/360 467/458/467 387/373/387 f 81/58/81 282/265/282 483/474/483 f 81/58/81 483/474/483 82/59/82 f 485/475/485 486/476/486 487/477/487 f 485/475/485 487/477/487 484/478/484 f 489/479/489 68/45/68 294/277/294 f 489/479/489 294/277/294 488/480/488 f 491/481/491 454/445/454 455/444/455 f 491/481/491 455/444/455 490/482/490 f 154/134/154 370/357/370 373/356/373 f 154/134/154 373/356/373 155/135/155 f 491/481/491 322/308/322 325/307/325 f 491/481/491 325/307/325 492/483/492 f 491/481/491 490/482/490 493/484/493 f 491/481/491 493/484/493 322/308/322 f 436/425/436 435/428/435 446/435/446 f 436/425/436 446/435/446 494/485/494 f 495/486/495 496/487/496 438/427/438 f 495/486/495 438/427/438 380/369/380 f 496/487/496 497/488/497 435/428/435 f 496/487/496 435/428/435 438/427/438 f 331/313/331 330/312/330 498/489/498 f 331/313/331 498/489/498 432/423/432 f 499/490/499 346/329/346 432/423/432 f 499/490/499 432/423/432 498/489/498 f 380/369/380 383/368/383 500/491/500 f 380/369/380 500/491/500 495/486/495 f 501/492/501 328/314/328 331/313/331 f 501/492/501 331/313/331 434/424/434 f 499/490/499 344/327/344 343/326/343 f 499/490/499 343/326/343 346/329/346 f 492/483/492 502/493/502 454/445/454 f 492/483/492 454/445/454 491/481/491 f 454/445/454 502/493/502 487/477/487 f 454/445/454 487/477/487 57/38/57 f 486/476/486 58/35/58 57/38/57 f 486/476/486 57/38/57 487/477/487 f 58/35/58 486/476/486 503/494/503 f 58/35/58 503/494/503 382/367/382 f 383/368/383 504/495/504 505/496/505 f 383/368/383 505/496/505 500/491/500 f 447/440/447 450/439/450 420/413/420 f 447/440/447 420/413/420 423/412/423 f 329/311/329 328/314/328 445/434/445 f 329/311/329 445/434/445 444/433/444 f 450/439/450 449/438/449 506/497/506 f 450/439/450 506/497/506 501/492/501 f 507/498/507 508/499/508 451/441/451 f 507/498/507 451/441/451 75/56/75 f 99/76/99 104/82/104 202/182/202 f 99/76/99 202/182/202 196/176/196 f 509/500/509 208/189/208 201/184/201 f 509/500/509 201/184/201 203/183/203 f 201/184/201 204/188/204 195/177/195 f 201/184/201 195/177/195 196/176/196 f 462/453/462 510/501/510 186/170/186 f 462/453/462 186/170/186 189/169/189 f 203/183/203 186/170/186 510/501/510 f 203/183/203 510/501/510 509/500/509 f 148/128/148 319/301/319 341/325/341 f 148/128/148 341/325/341 326/310/326 f 326/310/326 341/325/341 340/324/340 f 326/310/326 340/324/340 511/502/511 f 123/100/123 511/502/511 340/324/340 f 123/100/123 340/324/340 133/112/133 f 71/48/71 49/30/49 181/161/181 f 71/48/71 181/161/181 296/278/296 f 154/134/154 388/374/388 162/142/162 f 154/134/154 162/142/162 370/357/370 f 155/135/155 373/356/373 303/289/303 f 155/135/155 303/289/303 166/146/166 f 166/146/166 303/289/303 306/288/306 f 166/146/166 306/288/306 333/316/333 f 512/503/512 320/303/320 289/271/289 f 512/503/512 289/271/289 288/270/288 f 479/470/479 414/403/414 514/504/514 f 479/470/479 514/504/514 513/505/513 f 414/403/414 413/405/413 475/465/475 f 414/403/414 475/465/475 514/504/514 f 513/505/513 512/503/512 288/270/288 f 513/505/513 288/270/288 479/470/479 f 191/171/191 103/81/103 353/338/353 f 191/171/191 353/338/353 192/172/192 f 332/315/332 104/82/104 103/81/103 f 332/315/332 103/81/103 191/171/191 f 82/59/82 483/474/483 353/338/353 f 82/59/82 353/338/353 354/337/354 f 83/64/83 86/63/86 96/74/96 f 83/64/83 96/74/96 95/73/95 f 83/64/83 95/73/95 400/386/400 f 83/64/83 400/386/400 355/340/355 f 355/340/355 400/386/400 112/90/112 f 355/340/355 112/90/112 114/91/114 f 144/124/144 135/114/135 136/113/136 f 144/124/144 136/113/136 157/141/157 f 298/280/298 365/350/365 300/282/300 f 298/280/298 300/282/300 299/285/299 f 298/280/298 297/279/297 388/374/388 f 298/280/298 388/374/388 365/350/365 f 367/351/367 143/125/143 164/144/164 f 367/351/367 164/144/164 180/160/180 f 515/506/515 516/507/516 219/201/219 f 515/506/515 219/201/219 215/199/215 f 254/235/254 217/197/217 216/196/216 f 254/235/254 216/196/216 517/508/517 f 398/383/398 364/348/364 399/385/399 f 398/383/398 399/385/399 395/384/395 f 398/383/398 397/382/397 517/508/517 f 398/383/398 517/508/517 216/196/216 f 518/509/518 519/510/519 246/227/246 f 518/509/518 246/227/246 245/226/245 f 319/301/319 150/130/150 149/132/149 f 319/301/319 149/132/149 341/325/341 f 429/420/429 419/409/419 417/406/417 f 429/420/429 417/406/417 430/419/430 f 33/395/33 46/511/46 404/389/404 f 33/395/33 404/389/404 403/388/403 f 403/388/403 402/391/402 309/294/309 f 403/388/403 309/294/309 311/293/311 f 393/379/393 520/512/520 521/513/521 f 393/379/393 521/513/521 301/283/301 f 522/514/522 520/512/520 393/379/393 f 522/514/522 393/379/393 392/378/392 f 302/284/302 301/283/301 521/513/521 f 302/284/302 521/513/521 523/515/523 f 302/284/302 523/515/523 524/516/524 f 302/284/302 524/516/524 335/322/335 f 321/304/321 456/446/456 318/302/318 f 321/304/321 318/302/318 147/127/147 f 456/446/456 321/304/321 525/517/525 f 456/446/456 525/517/525 457/447/457 f 410/400/410 409/399/409 526/518/526 f 410/400/410 526/518/526 464/457/464 f 410/400/410 466/456/466 350/333/350 f 410/400/410 350/333/350 349/332/349 f 456/446/456 212/192/212 211/195/211 f 456/446/456 211/195/211 527/519/527 f 211/195/211 224/208/224 463/454/463 f 211/195/211 463/454/463 527/519/527 f 407/397/407 377/364/377 267/251/267 f 407/397/407 267/251/267 276/258/276 f 378/363/378 377/364/377 406/396/406 f 378/363/378 406/396/406 255/236/255 f 175/155/175 214/194/214 213/193/213 f 175/155/175 213/193/213 198/178/198 f 386/372/386 90/67/90 84/61/84 f 386/372/386 84/61/84 356/339/356 f 409/399/409 362/346/362 351/335/351 f 409/399/409 351/335/351 457/447/457 f 85/62/85 89/70/89 412/402/412 f 85/62/85 412/402/412 287/269/287 f 361/345/361 233/213/233 357/342/357 f 361/345/361 357/342/357 352/336/352 f 116/93/116 431/421/431 359/343/359 f 116/93/116 359/343/359 107/84/107 f 116/93/116 107/84/107 106/83/106 f 116/93/116 106/83/106 113/94/113 f 352/336/352 351/335/351 362/346/362 f 352/336/352 362/346/362 361/345/361 f 513/505/513 514/504/514 464/457/464 f 513/505/513 464/457/464 526/518/526 f 526/518/526 409/399/409 457/447/457 f 526/518/526 457/447/457 525/517/525 f 514/504/514 475/465/475 465/455/465 f 514/504/514 465/455/465 464/457/464 f 358/341/358 431/421/431 247/228/247 f 358/341/358 247/228/247 197/179/197 f 176/156/176 482/473/482 172/153/172 f 176/156/176 172/153/172 171/152/171 f 396/381/396 395/384/395 250/234/250 f 396/381/396 250/234/250 119/96/119 f 395/384/395 399/385/399 251/231/251 f 395/384/395 251/231/251 250/234/250 f 291/274/291 81/58/81 80/57/80 f 291/274/291 80/57/80 285/268/285 f 284/267/284 292/275/292 291/274/291 f 284/267/284 291/274/291 285/268/285 f 528/520/528 327/309/327 326/310/326 f 528/520/528 326/310/326 511/502/511 f 126/103/126 125/106/125 152/133/152 f 126/103/126 152/133/152 53/34/53 f 152/133/152 125/106/125 133/112/133 f 152/133/152 133/112/133 340/324/340 f 127/104/127 126/103/126 339/323/339 f 127/104/127 339/323/339 179/162/179 f 56/33/56 135/114/135 367/351/367 f 56/33/56 367/351/367 339/323/339 f 124/101/124 123/100/123 133/112/133 f 124/101/124 133/112/133 134/111/134 f 143/125/143 367/351/367 135/114/135 f 143/125/143 135/114/135 144/124/144 f 164/144/164 143/125/143 132/109/132 f 164/144/164 132/109/132 161/145/161 f 401/387/401 131/108/131 130/107/130 f 401/387/401 130/107/130 142/123/142 f 292/275/292 528/520/528 122/99/122 f 292/275/292 122/99/122 290/273/290 f 61/42/61 507/498/507 75/56/75 f 61/42/61 75/56/75 78/55/78 f 320/303/320 512/503/512 525/517/525 f 320/303/320 525/517/525 321/304/321 f 512/503/512 513/505/513 526/518/526 f 512/503/512 526/518/526 525/517/525 f 123/100/123 122/99/122 528/520/528 f 123/100/123 528/520/528 511/502/511 f 262/245/262 529/521/529 229/209/229 f 262/245/262 229/209/229 221/204/221 f 316/299/316 315/298/315 368/352/368 f 316/299/316 368/352/368 481/472/481 f 516/507/516 315/298/315 230/211/230 f 516/507/516 230/211/230 219/201/219 f 515/506/515 530/522/530 369/353/369 f 515/506/515 369/353/369 516/507/516 f 530/522/530 515/506/515 223/203/223 f 530/522/530 223/203/223 480/471/480 f 215/199/215 218/198/218 223/203/223 f 215/199/215 223/203/223 515/506/515 f 459/448/459 458/449/458 374/360/374 f 459/448/459 374/360/374 248/230/248 f 458/449/458 460/450/460 334/317/334 f 458/449/458 334/317/334 374/360/374 f 334/317/334 460/450/460 47/451/47 f 334/317/334 47/451/47 48/318/48 f 459/448/459 248/230/248 249/229/249 f 459/448/459 249/229/249 480/471/480 f 253/233/253 120/97/120 119/96/119 f 253/233/253 119/96/119 250/234/250 f 394/380/394 170/150/170 169/149/169 f 394/380/394 169/149/169 173/154/173 f 519/510/519 482/473/482 176/156/176 f 519/510/519 176/156/176 197/179/197 f 518/509/518 273/256/273 482/473/482 f 518/509/518 482/473/482 519/510/519 f 531/523/531 274/257/274 273/256/273 f 531/523/531 273/256/273 518/509/518 f 532/524/532 390/376/390 274/257/274 f 532/524/532 274/257/274 531/523/531 f 343/326/343 243/224/243 241/221/241 f 343/326/343 241/221/241 240/220/240 f 188/168/188 238/219/238 244/225/244 f 188/168/188 244/225/244 189/169/189 f 187/167/187 332/315/332 236/217/236 f 187/167/187 236/217/236 188/168/188 f 447/440/447 451/441/451 508/499/508 f 447/440/447 508/499/508 448/437/448 f 162/142/162 388/374/388 297/279/297 f 162/142/162 297/279/297 163/143/163 f 392/378/392 402/391/402 405/390/405 f 392/378/392 405/390/405 522/514/522 f 533/525/533 413/405/413 415/404/415 f 533/525/533 415/404/415 470/461/470 f 534/526/534 65/46/65 68/45/68 f 534/526/534 68/45/68 489/479/489 f 502/493/502 535/527/535 484/478/484 f 502/493/502 484/478/484 487/477/487 f 503/494/503 536/528/536 537/529/537 f 503/494/503 537/529/537 504/495/504 f 492/483/492 538/530/538 535/527/535 f 492/483/492 535/527/535 502/493/502 f 492/483/492 325/307/325 66/43/66 f 492/483/492 66/43/66 65/46/65 f 504/495/504 537/529/537 539/531/539 f 504/495/504 539/531/539 505/496/505 f 239/223/239 424/414/424 345/330/345 f 239/223/239 345/330/345 240/220/240 f 59/36/59 58/35/58 382/367/382 f 59/36/59 382/367/382 381/366/381 f 432/423/432 433/422/433 434/424/434 f 432/423/432 434/424/434 331/313/331 f 437/426/437 436/425/436 440/429/440 f 437/426/437 440/429/440 177/158/177 f 381/366/381 437/426/437 177/158/177 f 381/366/381 177/158/177 59/36/59 f 449/438/449 441/431/441 494/485/494 f 449/438/449 494/485/494 506/497/506 f 450/439/450 501/492/501 434/424/434 f 450/439/450 434/424/434 420/413/420 f 382/367/382 503/494/503 504/495/504 f 382/367/382 504/495/504 383/368/383 f 501/492/501 506/497/506 445/434/445 f 501/492/501 445/434/445 328/314/328 f 536/528/536 503/494/503 486/476/486 f 536/528/536 486/476/486 485/475/485 f 313/297/313 150/130/150 319/301/319 f 313/297/313 319/301/319 318/302/318 f 327/309/327 284/267/284 281/263/281 f 327/309/327 281/263/281 145/129/145 f 483/474/483 93/71/93 192/172/192 f 483/474/483 192/172/192 353/338/353 f 483/474/483 282/265/282 94/72/94 f 483/474/483 94/72/94 93/71/93 f 422/411/422 425/415/425 428/418/428 f 422/411/422 428/418/428 427/416/427 f 421/410/421 433/422/433 345/330/345 f 421/410/421 345/330/345 424/414/424 f 463/454/463 314/296/314 313/297/313 f 463/454/463 313/297/313 527/519/527 f 315/298/315 516/507/516 369/353/369 f 315/298/315 369/353/369 368/352/368 f 314/296/314 481/472/481 312/295/312 f 314/296/314 312/295/312 151/131/151 f 368/352/368 317/300/317 312/295/312 f 368/352/368 312/295/312 481/472/481 f 369/353/369 530/522/530 159/139/159 f 369/353/369 159/139/159 158/138/158 f 480/471/480 249/229/249 159/139/159 f 480/471/480 159/139/159 530/522/530 f 262/245/262 406/396/406 408/398/408 f 262/245/262 408/398/408 529/521/529 f 398/383/398 216/196/216 220/200/220 f 398/383/398 220/200/220 364/348/364 f 541/532/541 542/533/542 543/534/543 f 541/532/541 543/534/543 540/535/540 f 545/536/545 543/534/543 542/533/542 f 545/536/545 542/533/542 544/537/544 f 547/538/547 545/536/545 544/537/544 f 547/538/547 544/537/544 546/539/546 f 549/540/549 547/538/547 546/539/546 f 549/540/549 546/539/546 548/541/548 f 551/542/551 549/540/549 548/541/548 f 551/542/551 548/541/548 550/543/550 f 553/544/553 551/542/551 550/543/550 f 553/544/553 550/543/550 552/545/552 f 555/546/555 553/544/553 552/545/552 f 555/546/555 552/545/552 554/547/554 f 557/548/557 558/549/558 559/550/559 f 557/548/557 559/550/559 556/551/556 f 561/552/561 557/548/557 556/551/556 f 561/552/561 556/551/556 560/553/560 f 563/554/563 546/539/546 544/537/544 f 563/554/563 544/537/544 562/555/562 f 564/556/564 548/541/548 546/539/546 f 564/556/564 546/539/546 563/554/563 f 565/557/565 550/543/550 548/541/548 f 565/557/565 548/541/548 564/556/564 f 566/558/566 552/545/552 550/543/550 f 566/558/566 550/543/550 565/557/565 f 552/545/552 566/558/566 567/559/567 f 552/545/552 567/559/567 554/547/554 f 559/550/559 568/560/568 569/561/569 f 559/550/559 569/561/569 556/551/556 f 570/562/570 560/553/560 556/551/556 f 570/562/570 556/551/556 569/561/569 f 571/563/571 572/564/572 560/553/560 f 571/563/571 560/553/560 570/562/570 f 574/565/574 540/535/540 575/566/575 f 574/565/574 575/566/575 573/567/573 f 577/568/577 543/534/543 545/536/545 f 577/568/577 545/536/545 576/569/576 f 545/536/545 547/538/547 578/570/578 f 545/536/545 578/570/578 576/569/576 f 579/571/579 578/570/578 547/538/547 f 579/571/579 547/538/547 549/540/549 f 580/572/580 579/571/579 551/542/551 f 580/572/580 551/542/551 553/544/553 f 580/572/580 553/544/553 555/546/555 f 580/572/580 555/546/555 581/573/581 f 558/549/558 557/548/557 583/574/583 f 558/549/558 583/574/583 582/575/582 f 561/552/561 584/576/584 583/574/583 f 561/552/561 583/574/583 557/548/557 f 561/552/561 572/564/572 585/577/585 f 561/552/561 585/577/585 584/576/584 f 571/563/571 586/578/586 585/577/585 f 571/563/571 585/577/585 572/564/572 f 544/537/544 542/533/542 541/532/541 f 544/537/544 541/532/541 562/555/562 f 574/565/574 588/579/588 589/580/589 f 574/565/574 589/580/589 587/581/587 f 574/565/574 573/567/573 590/582/590 f 574/565/574 590/582/590 588/579/588 f 590/582/590 573/567/573 575/566/575 f 590/582/590 575/566/575 591/583/591 f 575/566/575 540/535/540 543/534/543 f 575/566/575 543/534/543 591/583/591 f 564/556/564 592/584/592 566/558/566 f 564/556/564 566/558/566 565/557/565 f 592/584/592 593/585/593 567/559/567 f 592/584/592 567/559/567 566/558/566 f 568/560/568 559/550/559 554/547/554 f 568/560/568 554/547/554 567/559/567 f 554/547/554 559/550/559 558/549/558 f 554/547/554 558/549/558 555/546/555 f 582/575/582 581/573/581 555/546/555 f 582/575/582 555/546/555 558/549/558 f 592/584/592 564/556/564 563/554/563 f 592/584/592 563/554/563 562/555/562 f 589/580/589 568/560/568 567/559/567 f 589/580/589 567/559/567 593/585/593 f 540/535/540 574/565/574 587/581/587 f 540/535/540 587/581/587 541/532/541 f 571/563/571 570/562/570 590/582/590 f 571/563/571 590/582/590 591/583/591 f 589/580/589 588/579/588 569/561/569 f 589/580/589 569/561/569 568/560/568 f 543/534/543 577/568/577 594/586/594 f 543/534/543 594/586/594 591/583/591 f 594/586/594 586/578/586 571/563/571 f 594/586/594 571/563/571 591/583/591 f 596/587/596 581/573/581 582/575/582 f 596/587/596 582/575/582 595/588/595 f 596/587/596 597/589/597 580/572/580 f 596/587/596 580/572/580 581/573/581 f 583/574/583 490/482/490 455/444/455 f 583/574/583 455/444/455 595/588/595 f 583/574/583 584/576/584 493/484/493 f 583/574/583 493/484/493 490/482/490 f 597/589/597 508/499/508 579/571/579 f 597/589/597 579/571/579 580/572/580 f 442/432/442 448/437/448 508/499/508 f 442/432/442 508/499/508 597/589/597 f 60/37/60 178/159/178 595/588/595 f 60/37/60 595/588/595 455/444/455 f 178/159/178 439/430/439 596/587/596 f 178/159/178 596/587/596 595/588/595 f 577/568/577 64/41/64 185/166/185 f 577/568/577 185/166/185 594/586/594 f 586/578/586 184/165/184 376/362/376 f 586/578/586 376/362/376 585/577/585 f 590/582/590 570/562/570 569/561/569 f 590/582/590 569/561/569 588/579/588 f 61/42/61 576/569/576 578/570/578 f 61/42/61 578/570/578 507/498/507 f 585/577/585 376/362/376 493/484/493 f 585/577/585 493/484/493 584/576/584 f 453/443/453 598/590/598 73/52/73 f 453/443/453 73/52/73 430/419/430 f 519/510/519 197/179/197 247/228/247 f 519/510/519 247/228/247 246/227/246 f 281/263/281 280/262/280 146/126/146 f 281/263/281 146/126/146 145/129/145 f 64/41/64 63/40/63 121/102/121 f 64/41/64 121/102/121 185/166/185 f 284/267/284 327/309/327 528/520/528 f 284/267/284 528/520/528 292/275/292 f 290/273/290 122/99/122 121/102/121 f 290/273/290 121/102/121 63/40/63 f 280/262/280 289/271/289 320/303/320 f 280/262/280 320/303/320 146/126/146 f 184/165/184 586/578/586 594/586/594 f 184/165/184 594/586/594 185/166/185 f 253/233/253 378/363/378 117/98/117 f 253/233/253 117/98/117 120/97/120 f 249/229/249 140/121/140 160/140/160 f 249/229/249 160/140/160 159/139/159 f 129/110/129 160/140/160 140/121/140 f 129/110/129 140/121/140 130/107/130 f 161/145/161 132/109/132 131/108/131 f 161/145/161 131/108/131 371/354/371 f 313/297/313 318/302/318 456/446/456 f 313/297/313 456/446/456 527/519/527 f 492/483/492 65/46/65 534/526/534 f 492/483/492 534/526/534 538/530/538 f 441/431/441 449/438/449 448/437/448 f 441/431/441 448/437/448 442/432/442 f 443/436/443 446/435/446 435/428/435 f 443/436/443 435/428/435 497/488/497 f 446/435/446 445/434/445 506/497/506 f 446/435/446 506/497/506 494/485/494 f 441/431/441 440/429/440 436/425/436 f 441/431/441 436/425/436 494/485/494 f 596/587/596 439/430/439 442/432/442 f 596/587/596 442/432/442 597/589/597 f 577/568/577 576/569/576 61/42/61 f 577/568/577 61/42/61 64/41/64 f 238/219/238 237/218/237 242/222/242 f 238/219/238 242/222/242 241/221/241 f 194/175/194 76/53/76 426/417/426 f 194/175/194 426/417/426 427/416/427 f 452/442/452 194/175/194 427/416/427 f 452/442/452 427/416/427 428/418/428 f 461/452/461 244/225/244 243/224/243 f 461/452/461 243/224/243 342/328/342 f 508/499/508 507/498/507 578/570/578 f 508/499/508 578/570/578 579/571/579 f 245/226/245 207/187/207 531/523/531 f 245/226/245 531/523/531 518/509/518 f 206/186/206 532/524/532 531/523/531 f 206/186/206 531/523/531 207/187/207 f 32/9/32 31/12/31 600/591/600 f 32/9/32 600/591/600 599/592/599 f 601/593/601 600/591/600 36/13/36 f 601/593/601 36/13/36 24/1/24 f 602/594/602 601/593/601 24/1/24 f 602/594/602 24/1/24 23/4/23 f 40/17/40 602/594/602 23/4/23 f 40/17/40 23/4/23 42/19/42 f 44/22/44 604/595/604 605/596/605 f 44/22/44 605/596/605 603/597/603 f 39/16/39 603/597/603 602/594/602 f 39/16/39 602/594/602 40/17/40 f 601/593/601 606/598/606 607/599/607 f 601/593/601 607/599/607 600/591/600 f 468/459/468 608/600/608 609/601/609 f 468/459/468 609/601/609 469/460/469 f 477/469/477 609/601/609 608/600/608 f 477/469/477 608/600/608 384/370/384 f 610/602/610 611/603/611 612/604/612 f 610/602/610 612/604/612 472/605/472 f 610/602/610 472/605/472 471/606/471 f 610/602/610 471/606/471 613/607/613 f 476/608/476 614/609/614 615/610/615 f 476/608/476 615/610/615 474/611/474 f 478/468/478 110/88/110 109/87/109 f 478/468/478 109/87/109 616/612/616 f 466/456/466 465/455/465 474/467/474 f 466/456/466 474/467/474 617/613/617 f 466/456/466 617/613/617 473/464/473 f 466/456/466 473/464/473 350/333/350 f 614/609/614 533/614/533 470/615/470 f 614/609/614 470/615/470 618/616/618 f 475/465/475 413/405/413 533/525/533 f 475/465/475 533/525/533 476/466/476 f 618/616/618 469/617/469 609/618/609 f 618/616/618 609/618/609 619/619/619 f 619/619/619 609/618/609 477/620/477 f 619/619/619 477/620/477 620/621/620 f 387/373/387 621/622/621 616/612/616 f 387/373/387 616/612/616 109/87/109 f 616/623/616 622/624/622 620/621/620 f 616/623/616 620/621/620 478/625/478 f 473/626/473 617/627/617 615/610/615 f 473/626/473 615/610/615 613/607/613 f 621/628/621 623/629/623 622/624/622 f 621/628/621 622/624/622 616/623/616 f 624/630/624 612/604/612 611/603/611 f 624/630/624 611/603/611 623/629/623 f 49/30/49 71/48/71 70/47/70 f 49/30/49 70/47/70 50/27/50 f 336/319/336 335/322/335 524/516/524 f 336/319/336 524/516/524 418/407/418 f 598/590/598 293/276/293 67/44/67 f 598/590/598 67/44/67 73/52/73 f 50/27/50 70/47/70 429/420/429 f 50/27/50 429/420/429 74/51/74 f 322/308/322 493/484/493 376/362/376 f 322/308/322 376/362/376 323/305/323 f 589/580/589 593/585/593 592/584/592 f 589/580/589 592/584/592 587/581/587 f 396/381/396 119/96/119 118/95/118 f 396/381/396 118/95/118 254/235/254 f 517/508/517 397/382/397 396/381/396 f 517/508/517 396/381/396 254/235/254 f 28/5/28 27/8/27 625/631/625 f 28/5/28 625/631/625 604/595/604 f 600/591/600 607/599/607 626/632/626 f 600/591/600 626/632/626 599/592/599 f 607/599/607 627/633/627 628/634/628 f 607/599/607 628/634/628 626/632/626 f 604/595/604 625/631/625 628/634/628 f 604/595/604 628/634/628 627/633/627 f 630/635/630 631/636/631 632/637/632 f 630/635/630 632/637/632 629/638/629 f 634/639/634 635/640/635 636/641/636 f 634/639/634 636/641/636 633/642/633 f 638/643/638 639/644/639 640/645/640 f 638/643/638 640/645/640 637/646/637 f 641/647/641 642/648/642 637/646/637 f 641/647/641 637/646/637 640/645/640 f 644/649/644 645/650/645 646/651/646 f 644/649/644 646/651/646 643/652/643 f 631/636/631 642/648/642 648/653/648 f 631/636/631 648/653/648 647/654/647 f 650/655/650 651/656/651 652/657/652 f 650/655/650 652/657/652 649/658/649 f 643/652/643 646/651/646 654/659/654 f 643/652/643 654/659/654 653/660/653 f 654/659/654 651/656/651 650/655/650 f 654/659/654 650/655/650 653/660/653 f 655/661/655 656/662/656 657/663/657 f 655/661/655 657/663/657 632/637/632 f 657/663/657 659/664/659 660/665/660 f 657/663/657 660/665/660 658/666/658 f 661/667/661 659/664/659 657/663/657 f 661/667/661 657/663/657 656/662/656 f 631/636/631 647/654/647 655/661/655 f 631/636/631 655/661/655 632/637/632 f 637/646/637 642/648/642 631/636/631 f 637/646/637 631/636/631 630/635/630 f 640/645/640 650/655/650 649/658/649 f 640/645/640 649/658/649 641/647/641 f 652/657/652 662/668/662 641/647/641 f 652/657/652 641/647/641 649/658/649 f 648/653/648 642/648/642 641/647/641 f 648/653/648 641/647/641 662/668/662 f 663/669/663 664/670/664 537/529/537 f 663/669/663 537/529/537 536/528/536 f 666/671/666 640/645/640 639/644/639 f 666/671/666 639/644/639 665/672/665 f 666/671/666 665/672/665 636/641/636 f 666/671/666 636/641/636 635/640/635 f 667/673/667 539/531/539 537/529/537 f 667/673/667 537/529/537 664/670/664 f 634/639/634 644/649/644 643/652/643 f 634/639/634 643/652/643 635/640/635 f 653/660/653 650/655/650 640/645/640 f 653/660/653 640/645/640 666/671/666 f 666/671/666 635/640/635 643/652/643 f 666/671/666 643/652/643 653/660/653 f 669/674/669 644/649/644 634/639/634 f 669/674/669 634/639/634 668/675/668 f 638/643/638 637/646/637 630/635/630 f 638/643/638 630/635/630 670/676/670 f 645/650/645 644/649/644 669/674/669 f 645/650/645 669/674/669 671/677/671 f 638/643/638 670/676/670 485/475/485 f 638/643/638 485/475/485 484/478/484 f 672/678/672 633/642/633 489/479/489 f 672/678/672 489/479/489 488/480/488 f 632/637/632 657/663/657 658/666/658 f 632/637/632 658/666/658 629/638/629 f 670/676/670 663/669/663 536/528/536 f 670/676/670 536/528/536 485/475/485 f 633/642/633 636/641/636 534/526/534 f 633/642/633 534/526/534 489/479/489 f 484/478/484 535/527/535 639/644/639 f 484/478/484 639/644/639 638/643/638 f 629/638/629 658/666/658 664/670/664 f 629/638/629 664/670/664 663/669/663 f 665/672/665 639/644/639 535/527/535 f 665/672/665 535/527/535 538/530/538 f 636/641/636 665/672/665 538/530/538 f 636/641/636 538/530/538 534/526/534 f 660/665/660 667/673/667 664/670/664 f 660/665/660 664/670/664 658/666/658 f 668/675/668 634/639/634 633/642/633 f 668/675/668 633/642/633 672/678/672 f 630/635/630 629/638/629 663/669/663 f 630/635/630 663/669/663 670/676/670 f 1/679/1 661/667/661 656/662/656 f 1/679/1 656/662/656 22/680/22 f 20/681/20 647/654/647 648/653/648 f 20/681/20 648/653/648 18/682/18 f 647/654/647 20/681/20 21/683/21 f 647/654/647 21/683/21 655/661/655 f 15/684/15 646/651/646 645/650/645 f 15/684/15 645/650/645 13/685/13 f 19/686/19 651/656/651 654/659/654 f 19/686/19 654/659/654 14/687/14 f 648/653/648 662/668/662 16/688/16 f 648/653/648 16/688/16 18/682/18 f 17/689/17 652/657/652 651/656/651 f 17/689/17 651/656/651 19/686/19 f 21/683/21 22/680/22 656/662/656 f 21/683/21 656/662/656 655/661/655 f 13/685/13 645/650/645 671/677/671 f 13/685/13 671/677/671 2/690/2 f 646/651/646 15/684/15 14/687/14 f 646/651/646 14/687/14 654/659/654 f 17/689/17 16/688/16 662/668/662 f 17/689/17 662/668/662 652/657/652 f 608/600/608 91/68/91 385/371/385 f 608/600/608 385/371/385 384/370/384 f 304/286/304 372/355/372 401/387/401 f 304/286/304 401/387/401 308/290/308 f 468/459/468 415/404/415 411/401/411 f 468/459/468 411/401/411 92/69/92 f 602/594/602 603/597/603 606/598/606 f 602/594/602 606/598/606 601/593/601 f 608/600/608 468/459/468 92/69/92 f 608/600/608 92/69/92 91/68/91 f 305/287/305 304/286/304 308/290/308 f 305/287/305 308/290/308 137/116/137 f 139/119/139 138/117/138 307/291/307 f 139/119/139 307/291/307 375/361/375 f 674/691/674 675/692/675 676/693/676 f 674/691/674 676/693/676 673/694/673 f 678/695/678 27/8/27 679/696/679 f 678/695/678 679/696/679 677/697/677 f 681/698/681 682/699/682 683/700/683 f 681/698/681 683/700/683 680/701/680 f 684/702/684 685/703/685 683/700/683 f 684/702/684 683/700/683 682/699/682 f 684/702/684 674/691/674 673/694/673 f 684/702/684 673/694/673 685/703/685 f 687/704/687 688/705/688 689/706/689 f 687/704/687 689/706/689 686/707/686 f 690/708/690 691/709/691 676/693/676 f 690/708/690 676/693/676 675/692/675 f 689/706/689 688/705/688 691/709/691 f 689/706/689 691/709/691 690/708/690 f 687/704/687 686/707/686 693/710/693 f 687/704/687 693/710/693 692/711/692 f 681/698/681 680/701/680 46/24/46 f 681/698/681 46/24/46 45/23/45 f 678/695/678 694/712/694 695/713/695 f 678/695/678 695/713/695 693/710/693 f 697/714/697 698/715/698 699/716/699 f 697/714/697 699/716/699 696/717/696 f 701/718/701 702/719/702 703/720/703 f 701/718/701 703/720/703 700/721/700 f 705/722/705 706/723/706 707/724/707 f 705/722/705 707/724/707 704/725/704 f 709/726/709 710/727/710 711/728/711 f 709/726/709 711/728/711 708/729/708 f 713/730/713 714/731/714 715/732/715 f 713/730/713 715/732/715 712/733/712 f 717/734/717 718/735/718 719/736/719 f 717/734/717 719/736/719 716/737/716 f 712/733/712 720/738/720 721/739/721 f 712/733/712 721/739/721 713/730/713 f 713/730/713 721/739/721 697/714/697 f 713/730/713 697/714/697 696/717/696 f 723/740/723 724/741/724 725/742/725 f 723/740/723 725/742/725 722/743/722 f 727/744/727 728/745/728 729/746/729 f 727/744/727 729/746/729 726/747/726 f 731/748/731 732/749/732 733/750/733 f 731/748/731 733/750/733 730/751/730 f 735/752/735 728/745/728 727/744/727 f 735/752/735 727/744/727 734/753/734 f 737/754/737 738/755/738 739/756/739 f 737/754/737 739/756/739 736/757/736 f 741/758/741 722/743/722 725/742/725 f 741/758/741 725/742/725 740/759/740 f 735/752/735 734/753/734 743/760/743 f 735/752/735 743/760/743 742/761/742 f 745/762/745 746/763/746 747/764/747 f 745/762/745 747/764/747 744/765/744 f 747/764/747 746/763/746 749/766/749 f 747/764/747 749/766/749 748/767/748 f 745/762/745 744/765/744 751/768/751 f 745/762/745 751/768/751 750/769/750 f 753/770/753 754/771/754 755/772/755 f 753/770/753 755/772/755 752/773/752 f 757/774/757 755/772/755 754/771/754 f 757/774/757 754/771/754 756/775/756 f 748/767/748 749/766/749 759/776/759 f 748/767/748 759/776/759 758/777/758 f 761/778/761 762/779/762 763/780/763 f 761/778/761 763/780/763 760/781/760 f 765/782/765 766/783/766 767/784/767 f 765/782/765 767/784/767 764/785/764 f 769/786/769 770/787/770 771/788/771 f 769/786/769 771/788/771 768/789/768 f 773/790/773 774/791/774 775/792/775 f 773/790/773 775/792/775 772/793/772 f 777/794/777 778/795/778 779/796/779 f 777/794/777 779/796/779 776/797/776 f 774/791/774 780/798/780 781/799/781 f 774/791/774 781/799/781 775/792/775 f 703/720/703 782/800/782 783/801/783 f 703/720/703 783/801/783 700/721/700 f 688/802/688 687/803/687 785/804/785 f 688/802/688 785/804/785 784/805/784 f 786/806/786 785/804/785 687/803/687 f 786/806/786 687/803/687 692/807/692 f 788/808/788 777/794/777 789/809/789 f 788/808/788 789/809/789 787/810/787 f 790/811/790 791/812/791 779/796/779 f 790/811/790 779/796/779 778/795/778 f 793/813/793 794/814/794 795/815/795 f 793/813/793 795/815/795 792/816/792 f 797/817/797 798/818/798 701/718/701 f 797/817/797 701/718/701 796/819/796 f 701/718/701 798/818/798 799/820/799 f 701/718/701 799/820/799 702/719/702 f 801/821/801 802/822/802 803/823/803 f 801/821/801 803/823/803 800/824/800 f 805/825/805 806/826/806 807/827/807 f 805/825/805 807/827/807 804/828/804 f 809/829/809 810/830/810 811/831/811 f 809/829/809 811/831/811 808/832/808 f 778/795/778 807/827/807 806/826/806 f 778/795/778 806/826/806 790/811/790 f 803/823/803 812/833/812 813/834/813 f 803/823/803 813/834/813 800/824/800 f 815/835/815 816/836/816 817/837/817 f 815/835/815 817/837/817 814/838/814 f 819/839/819 814/838/814 820/840/820 f 819/839/819 820/840/820 818/841/818 f 822/842/822 823/843/823 819/839/819 f 822/842/822 819/839/819 821/844/821 f 704/725/704 707/724/707 825/845/825 f 704/725/704 825/845/825 824/846/824 f 827/847/827 828/848/828 698/715/698 f 827/847/827 698/715/698 826/849/826 f 772/793/772 775/792/775 829/850/829 f 772/793/772 829/850/829 699/716/699 f 781/799/781 771/788/771 831/851/831 f 781/799/781 831/851/831 830/852/830 f 832/853/832 831/851/831 771/788/771 f 832/853/832 771/788/771 770/787/770 f 834/854/834 835/855/835 836/856/836 f 834/854/834 836/856/836 833/857/833 f 838/858/838 839/859/839 840/860/840 f 838/858/838 840/860/840 837/861/837 f 723/740/723 722/743/722 840/860/840 f 723/740/723 840/860/840 841/862/841 f 747/764/747 842/863/842 843/864/843 f 747/764/747 843/864/843 744/765/744 f 821/844/821 844/865/844 845/866/845 f 821/844/821 845/866/845 822/842/822 f 847/867/847 818/841/818 820/840/820 f 847/867/847 820/840/820 846/868/846 f 843/864/843 849/869/849 850/870/850 f 843/864/843 850/870/850 848/871/848 f 205/185/205 851/872/851 852/873/852 f 205/185/205 852/873/852 206/186/206 f 208/189/208 849/869/849 851/872/851 f 208/189/208 851/872/851 205/185/205 f 853/874/853 854/875/854 749/766/749 f 853/874/853 749/766/749 746/763/746 f 728/745/728 735/752/735 854/875/854 f 728/745/728 854/875/854 853/874/853 f 856/876/856 857/877/857 858/878/858 f 856/876/856 858/878/858 855/879/855 f 860/880/860 861/881/861 862/882/862 f 860/880/860 862/882/862 859/883/859 f 863/884/863 864/885/864 861/881/861 f 863/884/863 861/881/861 860/880/860 f 866/886/866 867/887/867 862/882/862 f 866/886/866 862/882/862 865/888/865 f 869/889/869 870/890/870 871/891/871 f 869/889/869 871/891/871 868/892/868 f 866/886/866 228/210/228 229/209/229 f 866/886/866 229/209/229 867/887/867 f 873/893/873 864/885/864 863/884/863 f 873/893/873 863/884/863 872/894/872 f 871/891/871 873/893/873 872/894/872 f 871/891/871 872/894/872 868/892/868 f 875/895/875 876/896/876 877/897/877 f 875/895/875 877/897/877 874/898/874 f 835/855/835 834/854/834 848/871/848 f 835/855/835 848/871/848 850/870/850 f 879/899/879 833/857/833 880/900/880 f 879/899/879 880/900/880 878/901/878 f 882/902/882 883/903/883 884/904/884 f 882/902/882 884/904/884 881/905/881 f 881/905/881 880/900/880 886/906/886 f 881/905/881 886/906/886 885/907/885 f 887/908/887 842/863/842 747/764/747 f 887/908/887 747/764/747 748/767/748 f 842/863/842 887/908/887 852/873/852 f 842/863/842 852/873/852 851/872/851 f 758/777/758 760/781/760 889/909/889 f 758/777/758 889/909/889 888/910/888 f 787/810/787 890/911/890 891/912/891 f 787/810/787 891/912/891 788/808/788 f 893/913/893 894/914/894 895/915/895 f 893/913/893 895/915/895 892/916/892 f 896/917/896 859/883/859 897/918/897 f 896/917/896 897/918/897 765/782/765 f 899/919/899 900/920/900 901/921/901 f 899/919/899 901/921/901 898/922/898 f 900/920/900 902/923/902 903/924/903 f 900/920/900 903/924/903 901/921/901 f 902/923/902 677/925/677 679/926/679 f 902/923/902 679/926/679 903/924/903 f 862/882/862 867/887/867 904/927/904 f 862/882/862 904/927/904 859/883/859 f 901/921/901 263/247/263 264/246/264 f 901/921/901 264/246/264 898/922/898 f 266/248/266 265/249/265 903/924/903 f 266/248/266 903/924/903 679/926/679 f 895/915/895 905/928/905 906/929/906 f 895/915/895 906/929/906 892/916/892 f 907/930/907 908/931/908 909/932/909 f 907/930/907 909/932/909 846/868/846 f 847/867/847 846/868/846 909/932/909 f 847/867/847 909/932/909 910/933/910 f 847/867/847 910/933/910 912/934/912 f 847/867/847 912/934/912 911/935/911 f 276/258/276 275/259/275 906/929/906 f 276/258/276 906/929/906 905/928/905 f 275/259/275 277/260/277 908/931/908 f 275/259/275 908/931/908 906/929/906 f 741/758/741 837/861/837 840/860/840 f 741/758/741 840/860/840 722/743/722 f 914/936/914 915/937/915 916/938/916 f 914/936/914 916/938/916 913/939/913 f 915/937/915 914/936/914 743/760/743 f 915/937/915 743/760/743 734/753/734 f 918/940/918 740/759/740 709/726/709 f 918/940/918 709/726/709 917/941/917 f 916/938/916 915/937/915 920/942/920 f 916/938/916 920/942/920 919/943/919 f 922/944/922 923/945/923 924/946/924 f 922/944/922 924/946/924 921/947/921 f 708/729/708 925/948/925 917/941/917 f 708/729/708 917/941/917 709/726/709 f 917/941/917 925/948/925 927/949/927 f 917/941/917 927/949/927 926/950/926 f 293/276/293 712/733/712 715/732/715 f 293/276/293 715/732/715 294/277/294 f 929/951/929 930/952/930 931/953/931 f 929/951/929 931/953/931 928/954/928 f 933/955/933 934/956/934 935/957/935 f 933/955/933 935/957/935 932/958/932 f 937/959/937 938/960/938 939/961/939 f 937/959/937 939/961/939 936/962/936 f 785/804/785 940/963/940 941/964/941 f 785/804/785 941/964/941 784/805/784 f 812/833/812 943/965/943 944/966/944 f 812/833/812 944/966/944 942/967/942 f 945/968/945 796/819/796 701/718/701 f 945/968/945 701/718/701 700/721/700 f 946/969/946 947/970/947 797/817/797 f 946/969/946 797/817/797 796/819/796 f 949/971/949 873/893/873 871/891/871 f 949/971/949 871/891/871 948/972/948 f 783/801/783 806/826/806 805/825/805 f 783/801/783 805/825/805 950/973/950 f 951/974/951 952/975/952 792/816/792 f 951/974/951 792/816/792 795/815/795 f 954/976/954 793/813/793 792/816/792 f 954/976/954 792/816/792 953/977/953 f 956/978/956 957/979/957 958/980/958 f 956/978/956 958/980/958 955/981/955 f 727/744/727 920/942/920 915/937/915 f 727/744/727 915/937/915 734/753/734 f 959/982/959 960/983/960 795/815/795 f 959/982/959 795/815/795 794/814/794 f 914/936/914 913/939/913 924/946/924 f 914/936/914 924/946/924 923/945/923 f 329/984/329 961/985/961 962/986/962 f 329/984/329 962/986/962 330/987/330 f 834/854/834 963/988/963 751/768/751 f 834/854/834 751/768/751 848/871/848 f 879/899/879 839/859/839 838/858/838 f 879/899/879 838/858/838 963/988/963 f 812/833/812 942/967/942 964/989/964 f 812/833/812 964/989/964 813/834/813 f 786/806/786 692/807/692 695/990/695 f 786/806/786 695/990/695 965/991/965 f 967/992/967 968/993/968 969/994/969 f 967/992/967 969/994/969 966/995/966 f 696/717/696 699/716/699 829/850/829 f 696/717/696 829/850/829 955/981/955 f 970/996/970 703/720/703 702/719/702 f 970/996/970 702/719/702 773/790/773 f 972/997/972 799/820/799 798/818/798 f 972/997/972 798/818/798 971/998/971 f 885/907/885 342/999/342 344/1000/344 f 885/907/885 344/1000/344 973/1001/973 f 974/1002/974 975/1003/975 882/902/882 f 974/1002/974 882/902/882 973/1001/973 f 977/1004/977 978/1005/978 979/1006/979 f 977/1004/977 979/1006/979 976/1007/976 f 981/1008/981 856/876/856 855/879/855 f 981/1008/981 855/879/855 980/1009/980 f 775/792/775 781/799/781 830/852/830 f 775/792/775 830/852/830 829/850/829 f 750/769/750 982/1010/982 983/1011/983 f 750/769/750 983/1011/983 745/762/745 f 761/778/761 984/1012/984 985/1013/985 f 761/778/761 985/1013/985 762/779/762 f 986/1014/986 987/1015/987 845/866/845 f 986/1014/986 845/866/845 844/865/844 f 752/773/752 755/772/755 989/1016/989 f 752/773/752 989/1016/989 988/1017/988 f 977/1004/977 976/1007/976 991/1018/991 f 977/1004/977 991/1018/991 990/1019/990 f 978/1005/978 977/1004/977 874/898/874 f 978/1005/978 874/898/874 992/1020/992 f 863/884/863 993/1021/993 816/836/816 f 863/884/863 816/836/816 872/894/872 f 802/822/802 995/1022/995 933/955/933 f 802/822/802 933/955/933 994/1023/994 f 930/952/930 929/951/929 716/737/716 f 930/952/930 716/737/716 719/736/719 f 828/848/828 827/847/827 996/1024/996 f 828/848/828 996/1024/996 970/996/970 f 998/1025/998 950/973/950 805/825/805 f 998/1025/998 805/825/805 997/1026/997 f 950/973/950 945/968/945 700/721/700 f 950/973/950 700/721/700 783/801/783 f 1000/1027/1000 1001/1028/1001 1002/1029/1002 f 1000/1027/1000 1002/1029/1002 999/1030/999 f 691/1031/691 936/962/936 939/961/939 f 691/1031/691 939/961/939 676/1032/676 f 936/962/936 691/1031/691 688/802/688 f 936/962/936 688/802/688 784/805/784 f 890/911/890 787/810/787 1004/1033/1004 f 890/911/890 1004/1033/1004 1003/1034/1003 f 713/730/713 696/717/696 955/981/955 f 713/730/713 955/981/955 958/980/958 f 830/852/830 831/851/831 1005/1035/1005 f 830/852/830 1005/1035/1005 956/978/956 f 1006/1036/1006 1007/1037/1007 905/928/905 f 1006/1036/1006 905/928/905 895/915/895 f 908/931/908 277/260/277 379/365/379 f 908/931/908 379/365/379 909/932/909 f 1009/1038/1009 1010/1039/1010 1011/1040/1011 f 1009/1038/1009 1011/1040/1011 1008/1041/1008 f 1013/1042/1013 756/775/756 754/771/754 f 1013/1042/1013 754/771/754 1012/1043/1012 f 754/771/754 753/770/753 1014/1044/1014 f 754/771/754 1014/1044/1014 1012/1043/1012 f 989/1016/989 755/772/755 757/774/757 f 989/1016/989 757/774/757 1015/1045/1015 f 826/849/826 808/832/808 811/831/811 f 826/849/826 811/831/811 827/847/827 f 995/1022/995 802/822/802 801/821/801 f 995/1022/995 801/821/801 1016/1046/1016 f 815/835/815 868/892/868 872/894/872 f 815/835/815 872/894/872 816/836/816 f 726/747/726 918/940/918 917/941/917 f 726/747/726 917/941/917 926/950/926 f 910/933/910 909/932/909 379/365/379 f 910/933/910 379/365/379 389/375/389 f 912/934/912 910/933/910 389/375/389 f 912/934/912 389/375/389 390/376/390 f 786/806/786 965/991/965 1003/1034/1003 f 786/806/786 1003/1034/1003 1004/1033/1004 f 1017/1047/1017 803/823/803 802/822/802 f 1017/1047/1017 802/822/802 994/1023/994 f 1019/1048/1019 1017/1047/1017 994/1023/994 f 1019/1048/1019 994/1023/994 1018/1049/1018 f 820/840/820 1020/1050/1020 907/930/907 f 820/840/820 907/930/907 846/868/846 f 932/958/932 1018/1049/1018 994/1023/994 f 932/958/932 994/1023/994 933/955/933 f 1022/1051/1022 1023/1052/1023 1024/1053/1024 f 1022/1051/1022 1024/1053/1024 1021/1054/1021 f 1025/1055/1025 817/837/817 816/836/816 f 1025/1055/1025 816/836/816 993/1021/993 f 1020/1050/1020 817/837/817 1025/1055/1025 f 1020/1050/1020 1025/1055/1025 893/913/893 f 907/930/907 1020/1050/1020 893/913/893 f 907/930/907 893/913/893 892/916/892 f 749/766/749 854/875/854 1026/1056/1026 f 749/766/749 1026/1056/1026 759/776/759 f 776/797/776 1000/1027/1000 999/1030/999 f 776/797/776 999/1030/999 1027/1057/1027 f 1017/1047/1017 943/965/943 812/833/812 f 1017/1047/1017 812/833/812 803/823/803 f 1028/1058/1028 1029/1059/1029 405/390/405 f 1028/1058/1028 405/390/405 404/389/404 f 1029/1059/1029 943/965/943 1017/1047/1017 f 1029/1059/1029 1017/1047/1017 1019/1048/1019 f 685/1060/685 673/1061/673 964/989/964 f 685/1060/685 964/989/964 942/967/942 f 685/1060/685 942/967/942 944/966/944 f 685/1060/685 944/966/944 683/1062/683 f 683/1062/683 944/966/944 1028/1058/1028 f 683/1062/683 1028/1058/1028 680/1063/680 f 1030/1064/1030 897/918/897 859/883/859 f 1030/1064/1030 859/883/859 904/927/904 f 1007/1037/1007 1030/1064/1030 408/398/408 f 1007/1037/1007 408/398/408 407/397/407 f 766/783/766 765/782/765 897/918/897 f 766/783/766 897/918/897 1006/1036/1006 f 907/930/907 892/916/892 906/929/906 f 907/930/907 906/929/906 908/931/908 f 937/959/937 999/1030/999 1002/1029/1002 f 937/959/937 1002/1029/1002 938/960/938 f 991/1018/991 976/1007/976 1032/1065/1032 f 991/1018/991 1032/1065/1032 1031/1066/1031 f 1034/1067/1034 739/756/739 738/755/738 f 1034/1067/1034 738/755/738 1033/1068/1033 f 1035/1069/1035 1036/1070/1036 1037/1071/1037 f 1035/1069/1035 1037/1071/1037 1034/1067/1034 f 1038/1072/1038 416/408/416 418/407/418 f 1038/1072/1038 418/407/418 967/992/967 f 966/995/966 719/736/719 718/735/718 f 966/995/966 718/735/718 1039/1073/1039 f 1041/1074/1041 1042/1075/1042 1043/1076/1043 f 1041/1074/1041 1043/1076/1043 1040/1077/1040 f 1041/1074/1041 1040/1077/1040 1045/1078/1045 f 1041/1074/1041 1045/1078/1045 1044/1079/1044 f 1043/1076/1043 1046/1080/1046 1047/1081/1047 f 1043/1076/1043 1047/1081/1047 1040/1077/1040 f 883/903/883 1045/1078/1045 1048/1082/1048 f 883/903/883 1048/1082/1048 884/904/884 f 1049/1083/1049 1050/1084/1050 721/739/721 f 1049/1083/1049 721/739/721 720/738/720 f 717/734/717 1050/1084/1050 1039/1073/1039 f 717/734/717 1039/1073/1039 718/735/718 f 889/909/889 760/781/760 763/780/763 f 889/909/889 763/780/763 1051/1085/1051 f 974/1002/974 1052/1086/1052 1053/1087/1053 f 974/1002/974 1053/1087/1053 975/1003/975 f 1053/1087/1053 1054/1088/1054 1042/1075/1042 f 1053/1087/1053 1042/1075/1042 1041/1074/1041 f 1056/1089/1056 1057/1090/1057 1058/1091/1058 f 1056/1089/1056 1058/1091/1058 1055/1092/1055 f 1055/1092/1055 1058/1091/1058 1010/1039/1010 f 1055/1092/1055 1010/1039/1010 1009/1038/1009 f 825/845/825 1059/1093/1059 1060/1094/1060 f 825/845/825 1060/1094/1060 824/846/824 f 1060/1094/1060 1059/1093/1059 1062/1095/1062 f 1060/1094/1060 1062/1095/1062 1061/1096/1061 f 444/1097/444 443/1098/443 1064/1099/1064 f 444/1097/444 1064/1099/1064 1063/1100/1063 f 955/981/955 829/850/829 830/852/830 f 955/981/955 830/852/830 956/978/956 f 855/879/855 845/866/845 987/1015/987 f 855/879/855 987/1015/987 980/1009/980 f 858/878/858 869/889/869 823/843/823 f 858/878/858 823/843/823 822/842/822 f 1066/1101/1066 1067/1102/1067 1068/1103/1068 f 1066/1101/1066 1068/1103/1068 1065/1104/1065 f 1043/1076/1043 1067/1102/1067 1069/1105/1069 f 1043/1076/1043 1069/1105/1069 1046/1080/1046 f 724/741/724 723/740/723 1046/1080/1046 f 724/741/724 1046/1080/1046 1069/1105/1069 f 725/742/725 710/727/710 709/726/709 f 725/742/725 709/726/709 740/759/740 f 923/945/923 922/944/922 730/751/730 f 923/945/923 730/751/730 733/750/733 f 742/761/742 1026/1056/1026 854/875/854 f 742/761/742 854/875/854 735/752/735 f 878/901/878 884/904/884 1048/1082/1048 f 878/901/878 1048/1082/1048 1070/1106/1070 f 839/859/839 1070/1106/1070 841/862/841 f 839/859/839 841/862/841 840/860/840 f 878/901/878 1070/1106/1070 839/859/839 f 878/901/878 839/859/839 879/899/879 f 728/745/728 853/874/853 983/1011/983 f 728/745/728 983/1011/983 729/746/729 f 923/945/923 733/750/733 743/760/743 f 923/945/923 743/760/743 914/936/914 f 1049/1083/1049 453/443/453 416/408/416 f 1049/1083/1049 416/408/416 1038/1072/1038 f 969/994/969 934/956/934 931/953/931 f 969/994/969 931/953/931 930/952/930 f 706/723/706 1071/1107/1071 1072/1108/1072 f 706/723/706 1072/1108/1072 707/724/707 f 856/876/856 981/1008/981 1074/1109/1074 f 856/876/856 1074/1109/1074 1073/1110/1073 f 732/749/732 731/748/731 985/1013/985 f 732/749/732 985/1013/985 984/1012/984 f 789/809/789 940/963/940 1004/1033/1004 f 789/809/789 1004/1033/1004 787/810/787 f 1027/1057/1027 941/964/941 940/963/940 f 1027/1057/1027 940/963/940 789/809/789 f 1075/1111/1075 1076/1112/1076 900/920/900 f 1075/1111/1075 900/920/900 899/919/899 f 228/210/228 866/886/866 898/922/898 f 228/210/228 898/922/898 264/246/264 f 900/920/900 1076/1112/1076 1077/1113/1077 f 900/920/900 1077/1113/1077 902/923/902 f 1077/1113/1077 694/1114/694 677/925/677 f 1077/1113/1077 677/925/677 902/923/902 f 263/247/263 901/921/901 903/924/903 f 263/247/263 903/924/903 265/249/265 f 461/1115/461 886/906/886 836/856/836 f 461/1115/461 836/856/836 462/1116/462 f 871/891/871 870/890/870 1078/1117/1078 f 871/891/871 1078/1117/1078 948/972/948 f 1080/1118/1080 1081/1119/1081 1032/1065/1032 f 1080/1118/1080 1032/1065/1032 1079/1120/1079 f 737/754/737 736/757/736 1012/1043/1012 f 737/754/737 1012/1043/1012 1014/1044/1014 f 875/895/875 874/898/874 977/1004/977 f 875/895/875 977/1004/977 990/1019/990 f 877/897/877 1082/1121/1082 992/1020/992 f 877/897/877 992/1020/992 874/898/874 f 969/994/969 930/952/930 719/736/719 f 969/994/969 719/736/719 966/995/966 f 969/994/969 968/993/968 935/957/935 f 969/994/969 935/957/935 934/956/934 f 1084/1122/1084 1037/1071/1037 1085/1123/1085 f 1084/1122/1084 1085/1123/1085 1083/1124/1083 f 978/1005/978 992/1020/992 1087/1125/1087 f 978/1005/978 1087/1125/1087 1086/1126/1086 f 1086/1126/1086 1088/1127/1088 979/1006/979 f 1086/1126/1086 979/1006/979 978/1005/978 f 1080/1118/1080 1090/1128/1090 1091/1129/1091 f 1080/1118/1080 1091/1129/1091 1089/1130/1089 f 1013/1042/1013 1092/1131/1092 1093/1132/1093 f 1013/1042/1013 1093/1132/1093 756/775/756 f 1035/1069/1035 1034/1067/1034 1033/1068/1033 f 1035/1069/1035 1033/1068/1033 1094/1133/1094 f 921/947/921 1094/1133/1094 1033/1068/1033 f 921/947/921 1033/1068/1033 922/944/922 f 730/751/730 738/755/738 737/754/737 f 730/751/730 737/754/737 731/748/731 f 1014/1044/1014 753/770/753 762/779/762 f 1014/1044/1014 762/779/762 985/1013/985 f 876/896/876 875/895/875 987/1015/987 f 876/896/876 987/1015/987 986/1014/986 f 928/954/928 808/832/808 826/849/826 f 928/954/928 826/849/826 929/951/929 f 1039/1073/1039 1038/1072/1038 967/992/967 f 1039/1073/1039 967/992/967 966/995/966 f 698/715/698 828/848/828 772/793/772 f 698/715/698 772/793/772 699/716/699 f 676/1032/676 939/961/939 964/989/964 f 676/1032/676 964/989/964 673/1061/673 f 1000/1027/1000 810/830/810 809/829/809 f 1000/1027/1000 809/829/809 1001/1028/1001 f 898/922/898 866/886/866 865/888/865 f 898/922/898 865/888/865 899/919/899 f 899/919/899 865/888/865 1095/1134/1095 f 899/919/899 1095/1134/1095 1075/1111/1075 f 857/877/857 870/890/870 869/889/869 f 857/877/857 869/889/869 858/878/858 f 948/972/948 1078/1117/1078 946/969/946 f 948/972/948 946/969/946 1096/1135/1096 f 819/839/819 823/843/823 815/835/815 f 819/839/819 815/835/815 814/838/814 f 911/935/911 1097/1136/1097 818/841/818 f 911/935/911 818/841/818 847/867/847 f 815/835/815 823/843/823 869/889/869 f 815/835/815 869/889/869 868/892/868 f 887/908/887 748/767/748 758/777/758 f 887/908/887 758/777/758 888/910/888 f 761/778/761 760/781/760 758/777/758 f 761/778/761 758/777/758 759/776/759 f 853/874/853 746/763/746 745/762/745 f 853/874/853 745/762/745 983/1011/983 f 1051/1085/1051 988/1017/988 876/896/876 f 1051/1085/1051 876/896/876 986/1014/986 f 877/897/877 876/896/876 988/1017/988 f 877/897/877 988/1017/988 989/1016/989 f 989/1016/989 1015/1045/1015 1082/1121/1082 f 989/1016/989 1082/1121/1082 877/897/877 f 726/747/726 729/746/729 1098/1137/1098 f 726/747/726 1098/1137/1098 918/940/918 f 1100/1138/1100 1101/1139/1101 1102/1140/1102 f 1100/1138/1100 1102/1140/1102 1099/1141/1099 f 1103/1142/1103 488/480/488 294/277/294 f 1103/1142/1103 294/277/294 715/732/715 f 1104/1143/1104 1105/1144/1105 1072/1108/1072 f 1104/1143/1104 1072/1108/1072 1071/1107/1071 f 801/821/801 800/824/800 1002/1029/1002 f 801/821/801 1002/1029/1002 1001/1028/1001 f 1104/1143/1104 1106/1145/1106 958/980/958 f 1104/1143/1104 958/980/958 957/979/957 f 1104/1143/1104 957/979/957 1107/1146/1107 f 1104/1143/1104 1107/1146/1107 1105/1144/1105 f 1056/1089/1056 1108/1147/1108 1064/1099/1064 f 1056/1089/1056 1064/1099/1064 1057/1090/1057 f 495/1148/495 1010/1039/1010 1058/1091/1058 f 495/1148/495 1058/1091/1058 496/1149/496 f 496/1149/496 1058/1091/1058 1057/1090/1057 f 496/1149/496 1057/1090/1057 497/1150/497 f 962/986/962 1052/1086/1052 498/1151/498 f 962/986/962 498/1151/498 330/987/330 f 499/1152/499 498/1151/498 1052/1086/1052 f 499/1152/499 1052/1086/1052 974/1002/974 f 1010/1039/1010 495/1148/495 500/1153/500 f 1010/1039/1010 500/1153/500 1011/1040/1011 f 1109/1154/1109 1054/1088/1054 962/986/962 f 1109/1154/1109 962/986/962 961/985/961 f 499/1152/499 974/1002/974 973/1001/973 f 499/1152/499 973/1001/973 344/1000/344 f 1106/1145/1106 1104/1143/1104 1071/1107/1071 f 1106/1145/1106 1071/1107/1071 1110/1155/1110 f 1071/1107/1071 706/723/706 1102/1140/1102 f 1071/1107/1071 1102/1140/1102 1110/1155/1110 f 1099/1141/1099 1102/1140/1102 706/723/706 f 1099/1141/1099 706/723/706 705/722/705 f 705/722/705 1008/1041/1008 1111/1156/1111 f 705/722/705 1111/1156/1111 1099/1141/1099 f 1011/1040/1011 500/1153/500 505/1157/505 f 1011/1040/1011 505/1157/505 1112/1158/1112 f 1067/1102/1067 1043/1076/1043 1042/1075/1042 f 1067/1102/1067 1042/1075/1042 1068/1103/1068 f 329/984/329 444/1097/444 1063/1100/1063 f 329/984/329 1063/1100/1063 961/985/961 f 1068/1103/1068 1109/1154/1109 1113/1159/1113 f 1068/1103/1068 1113/1159/1113 1065/1104/1065 f 1115/1160/1115 724/741/724 1069/1105/1069 f 1115/1160/1115 1069/1105/1069 1114/1161/1114 f 744/765/744 843/864/843 848/871/848 f 744/765/744 848/871/848 751/768/751 f 509/500/509 850/870/850 849/869/849 f 509/500/509 849/869/849 208/189/208 f 849/869/849 843/864/843 842/863/842 f 849/869/849 842/863/842 851/872/851 f 462/1116/462 836/856/836 835/855/835 f 462/1116/462 835/855/835 510/501/510 f 850/870/850 509/500/509 510/501/510 f 850/870/850 510/501/510 835/855/835 f 795/815/795 960/983/960 971/998/971 f 795/815/795 971/998/971 951/974/951 f 960/983/960 1116/1162/1116 972/997/972 f 960/983/960 972/997/972 971/998/971 f 768/789/768 780/798/780 972/997/972 f 768/789/768 972/997/972 1116/1162/1116 f 716/737/716 929/951/929 826/849/826 f 716/737/716 826/849/826 698/715/698 f 801/821/801 1001/1028/1001 809/829/809 f 801/821/801 809/829/809 1016/1046/1016 f 800/824/800 813/834/813 938/960/938 f 800/824/800 938/960/938 1002/1029/1002 f 813/834/813 964/989/964 939/961/939 f 813/834/813 939/961/939 938/960/938 f 1117/1163/1117 921/947/921 924/946/924 f 1117/1163/1117 924/946/924 954/976/954 f 1094/1133/1094 1118/1164/1118 1119/1165/1119 f 1094/1133/1094 1119/1165/1119 1035/1069/1035 f 1035/1069/1035 1119/1165/1119 1089/1130/1089 f 1035/1069/1035 1089/1130/1089 1036/1070/1036 f 1118/1164/1118 1094/1133/1094 921/947/921 f 1118/1164/1118 921/947/921 1117/1163/1117 f 838/858/838 837/861/837 982/1010/982 f 838/858/838 982/1010/982 750/769/750 f 963/988/963 838/858/838 750/769/750 f 963/988/963 750/769/750 751/768/751 f 729/746/729 983/1011/983 982/1010/982 f 729/746/729 982/1010/982 1098/1137/1098 f 732/749/732 742/761/742 743/760/743 f 732/749/732 743/760/743 733/750/733 f 732/749/732 984/1012/984 1026/1056/1026 f 732/749/732 1026/1056/1026 742/761/742 f 984/1012/984 761/778/761 759/776/759 f 984/1012/984 759/776/759 1026/1056/1026 f 790/811/790 806/826/806 783/801/783 f 790/811/790 783/801/783 782/800/782 f 931/953/931 934/956/934 933/955/933 f 931/953/931 933/955/933 995/1022/995 f 931/953/931 995/1022/995 1016/1046/1016 f 931/953/931 1016/1046/1016 928/954/928 f 996/1024/996 827/847/827 811/831/811 f 996/1024/996 811/831/811 791/812/791 f 1121/1166/1121 861/881/861 864/885/864 f 1121/1166/1121 864/885/864 1120/1167/1120 f 896/917/896 1122/1168/1122 860/880/860 f 896/917/896 860/880/860 859/883/859 f 1024/1053/1024 1023/1052/1023 1025/1055/1025 f 1024/1053/1024 1025/1055/1025 993/1021/993 f 1024/1053/1024 860/880/860 1122/1168/1122 f 1024/1053/1024 1122/1168/1122 1021/1054/1021 f 1124/1169/1124 887/908/887 888/910/888 f 1124/1169/1124 888/910/888 1123/1170/1123 f 951/974/951 971/998/971 798/818/798 f 951/974/951 798/818/798 797/817/797 f 1050/1084/1050 1049/1083/1049 1038/1072/1038 f 1050/1084/1050 1038/1072/1038 1039/1073/1039 f 680/1063/680 1028/1058/1028 404/389/404 f 680/1063/680 404/389/404 46/511/46 f 1028/1058/1028 944/966/944 943/965/943 f 1028/1058/1028 943/965/943 1029/1059/1029 f 1018/1049/1018 932/958/932 521/513/521 f 1018/1049/1018 521/513/521 520/512/520 f 522/514/522 1019/1048/1019 1018/1049/1018 f 522/514/522 1018/1049/1018 520/512/520 f 935/957/935 523/515/523 521/513/521 f 935/957/935 521/513/521 932/958/932 f 935/957/935 968/993/968 524/516/524 f 935/957/935 524/516/524 523/515/523 f 953/977/953 792/816/792 952/975/952 f 953/977/953 952/975/952 1073/1110/1073 f 1073/1110/1073 1074/1109/1074 1125/1171/1125 f 1073/1110/1073 1125/1171/1125 953/977/953 f 1032/1065/1032 1081/1119/1081 1126/1172/1126 f 1032/1065/1032 1126/1172/1126 1031/1066/1031 f 1032/1065/1032 976/1007/976 979/1006/979 f 1032/1065/1032 979/1006/979 1079/1120/1079 f 1073/1110/1073 1127/1173/1127 857/877/857 f 1073/1110/1073 857/877/857 856/876/856 f 857/877/857 1127/1173/1127 1078/1117/1078 f 857/877/857 1078/1117/1078 870/890/870 f 407/397/407 276/258/276 905/928/905 f 407/397/407 905/928/905 1007/1037/1007 f 1006/1036/1006 897/918/897 1030/1064/1030 f 1006/1036/1006 1030/1064/1030 1007/1037/1007 f 822/842/822 845/866/845 855/879/855 f 822/842/822 855/879/855 858/878/858 f 1014/1044/1014 985/1013/985 731/748/731 f 1014/1044/1014 731/748/731 737/754/737 f 1031/1066/1031 1074/1109/1074 981/1008/981 f 1031/1066/1031 981/1008/981 991/1018/991 f 730/751/730 922/944/922 1033/1068/1033 f 730/751/730 1033/1068/1033 738/755/738 f 990/1019/990 980/1009/980 987/1015/987 f 990/1019/990 987/1015/987 875/895/875 f 763/780/763 752/773/752 988/1017/988 f 763/780/763 988/1017/988 1051/1085/1051 f 763/780/763 762/779/762 753/770/753 f 763/780/763 753/770/753 752/773/752 f 980/1009/980 990/1019/990 991/1018/991 f 980/1009/980 991/1018/991 981/1008/981 f 1118/1164/1118 1126/1172/1126 1081/1119/1081 f 1118/1164/1118 1081/1119/1081 1119/1165/1119 f 1126/1172/1126 1125/1171/1125 1074/1109/1074 f 1126/1172/1126 1074/1109/1074 1031/1066/1031 f 1119/1165/1119 1081/1119/1081 1080/1118/1080 f 1119/1165/1119 1080/1118/1080 1089/1130/1089 f 986/1014/986 844/865/844 889/909/889 f 986/1014/986 889/909/889 1051/1085/1051 f 821/844/821 819/839/819 818/841/818 f 821/844/821 818/841/818 1097/1136/1097 f 1022/1051/1022 764/785/764 894/914/894 f 1022/1051/1022 894/914/894 1023/1052/1023 f 1023/1052/1023 894/914/894 893/913/893 f 1023/1052/1023 893/913/893 1025/1055/1025 f 926/950/926 920/942/920 727/744/727 f 926/950/926 727/744/727 726/747/726 f 919/943/919 920/942/920 926/950/926 f 919/943/919 926/950/926 927/949/927 f 1128/1174/1128 1116/1162/1116 960/983/960 f 1128/1174/1128 960/983/960 959/982/959 f 773/790/773 702/719/702 799/820/799 f 773/790/773 799/820/799 774/791/774 f 799/820/799 972/997/972 780/798/780 f 799/820/799 780/798/780 774/791/774 f 772/793/772 828/848/828 970/996/970 f 772/793/772 970/996/970 773/790/773 f 703/720/703 970/996/970 996/1024/996 f 703/720/703 996/1024/996 782/800/782 f 771/788/771 781/799/781 780/798/780 f 771/788/771 780/798/780 768/789/768 f 791/812/791 790/811/790 782/800/782 f 791/812/791 782/800/782 996/1024/996 f 811/831/811 810/830/810 779/796/779 f 811/831/811 779/796/779 791/812/791 f 1027/1057/1027 789/809/789 777/794/777 f 1027/1057/1027 777/794/777 776/797/776 f 927/949/927 925/948/925 769/786/769 f 927/949/927 769/786/769 1128/1174/1128 f 710/727/710 725/742/725 724/741/724 f 710/727/710 724/741/724 1115/1160/1115 f 954/976/954 953/977/953 1125/1171/1125 f 954/976/954 1125/1171/1125 1117/1163/1117 f 1117/1163/1117 1125/1171/1125 1126/1172/1126 f 1117/1163/1117 1126/1172/1126 1118/1164/1118 f 768/789/768 1116/1162/1116 1128/1174/1128 f 768/789/768 1128/1174/1128 769/786/769 f 904/927/904 867/887/867 229/209/229 f 904/927/904 229/209/229 529/521/529 f 948/972/948 1096/1135/1096 998/1025/998 f 948/972/948 998/1025/998 949/971/949 f 1120/1167/1120 864/885/864 873/893/873 f 1120/1167/1120 873/893/873 949/971/949 f 1121/1166/1121 1120/1167/1120 997/1026/997 f 1121/1166/1121 997/1026/997 1129/1175/1129 f 1129/1175/1129 1095/1134/1095 865/888/865 f 1129/1175/1129 865/888/865 1121/1166/1121 f 861/881/861 1121/1166/1121 865/888/865 f 861/881/861 865/888/865 862/882/862 f 1075/1111/1075 890/911/890 1003/1034/1003 f 1075/1111/1075 1003/1034/1003 1076/1112/1076 f 1076/1112/1076 1003/1034/1003 965/991/965 f 1076/1112/1076 965/991/965 1077/1113/1077 f 965/991/965 695/990/695 694/1114/694 f 965/991/965 694/1114/694 1077/1113/1077 f 1075/1111/1075 1095/1134/1095 891/912/891 f 1075/1111/1075 891/912/891 890/911/890 f 895/915/895 894/914/894 764/785/764 f 895/915/895 764/785/764 767/784/767 f 1020/1050/1020 820/840/820 814/838/814 f 1020/1050/1020 814/838/814 817/837/817 f 1123/1170/1123 844/865/844 821/844/821 f 1123/1170/1123 821/844/821 1097/1136/1097 f 1124/1169/1124 1123/1170/1123 1097/1136/1097 f 1124/1169/1124 1097/1136/1097 911/935/911 f 1130/1176/1130 1124/1169/1124 911/935/911 f 1130/1176/1130 911/935/911 912/934/912 f 532/524/532 1130/1176/1130 912/934/912 f 532/524/532 912/934/912 390/376/390 f 973/1001/973 882/902/882 881/905/881 f 973/1001/973 881/905/881 885/907/885 f 833/857/833 836/856/836 886/906/886 f 833/857/833 886/906/886 880/900/880 f 834/854/834 833/857/833 879/899/879 f 834/854/834 879/899/879 963/988/963 f 1067/1102/1067 1066/1101/1066 1114/1161/1114 f 1067/1102/1067 1114/1161/1114 1069/1105/1069 f 809/829/809 808/832/808 928/954/928 f 809/829/809 928/954/928 1016/1046/1016 f 1019/1048/1019 522/514/522 405/390/405 f 1019/1048/1019 405/390/405 1029/1059/1029 f 1131/1177/1131 1085/1123/1085 1037/1071/1037 f 1131/1177/1131 1037/1071/1037 1036/1070/1036 f 1132/1178/1132 1103/1142/1103 715/732/715 f 1132/1178/1132 715/732/715 714/731/714 f 1110/1155/1110 1102/1140/1102 1101/1139/1101 f 1110/1155/1110 1101/1139/1101 1133/1179/1133 f 1111/1156/1111 1112/1158/1112 1135/1180/1135 f 1111/1156/1111 1135/1180/1135 1134/1181/1134 f 1106/1145/1106 1110/1155/1110 1133/1179/1133 f 1106/1145/1106 1133/1179/1133 1136/1182/1136 f 1106/1145/1106 714/731/714 713/730/713 f 1106/1145/1106 713/730/713 958/980/958 f 1112/1158/1112 505/1157/505 539/1183/539 f 1112/1158/1112 539/1183/539 1135/1180/1135 f 883/903/883 882/902/882 975/1003/975 f 883/903/883 975/1003/975 1044/1079/1044 f 704/725/704 1009/1038/1009 1008/1041/1008 f 704/725/704 1008/1041/1008 705/722/705 f 1052/1086/1052 962/986/962 1054/1088/1054 f 1052/1086/1052 1054/1088/1054 1053/1087/1053 f 1055/1092/1055 824/846/824 1060/1094/1060 f 1055/1092/1055 1060/1094/1060 1056/1089/1056 f 1009/1038/1009 704/725/704 824/846/824 f 1009/1038/1009 824/846/824 1055/1092/1055 f 1065/1104/1065 1113/1159/1113 1108/1147/1108 f 1065/1104/1065 1108/1147/1108 1061/1096/1061 f 1068/1103/1068 1042/1075/1042 1054/1088/1054 f 1068/1103/1068 1054/1088/1054 1109/1154/1109 f 1008/1041/1008 1011/1040/1011 1112/1158/1112 f 1008/1041/1008 1112/1158/1112 1111/1156/1111 f 1109/1154/1109 961/985/961 1063/1100/1063 f 1109/1154/1109 1063/1100/1063 1113/1159/1113 f 1134/1181/1134 1100/1138/1100 1099/1141/1099 f 1134/1181/1134 1099/1141/1099 1111/1156/1111 f 947/970/947 952/975/952 951/974/951 f 947/970/947 951/974/951 797/817/797 f 959/982/959 794/814/794 916/938/916 f 959/982/959 916/938/916 919/943/919 f 1098/1137/1098 982/1010/982 837/861/837 f 1098/1137/1098 837/861/837 741/758/741 f 1098/1137/1098 741/758/741 740/759/740 f 1098/1137/1098 740/759/740 918/940/918 f 1040/1077/1040 1047/1081/1047 1048/1082/1048 f 1040/1077/1040 1048/1082/1048 1045/1078/1045 f 1041/1074/1041 1044/1079/1044 975/1003/975 f 1041/1074/1041 975/1003/975 1053/1087/1053 f 1078/1117/1078 1127/1173/1127 947/970/947 f 1078/1117/1078 947/970/947 946/969/946 f 949/971/949 998/1025/998 997/1026/997 f 949/971/949 997/1026/997 1120/1167/1120 f 946/969/946 796/819/796 945/968/945 f 946/969/946 945/968/945 1096/1135/1096 f 998/1025/998 1096/1135/1096 945/968/945 f 998/1025/998 945/968/945 950/973/950 f 997/1026/997 805/825/805 804/828/804 f 997/1026/997 804/828/804 1129/1175/1129 f 1095/1134/1095 1129/1175/1129 804/828/804 f 1095/1134/1095 804/828/804 891/912/891 f 904/927/904 529/521/529 408/398/408 f 904/927/904 408/398/408 1030/1064/1030 f 1024/1053/1024 993/1021/993 863/884/863 f 1024/1053/1024 863/884/863 860/880/860 f 1138/1184/1138 1139/1185/1139 1140/1186/1140 f 1138/1184/1138 1140/1186/1140 1137/1187/1137 f 1141/1188/1141 1142/1189/1142 1137/1187/1137 f 1141/1188/1141 1137/1187/1137 1140/1186/1140 f 1143/1190/1143 1144/1191/1144 1142/1189/1142 f 1143/1190/1143 1142/1189/1142 1141/1188/1141 f 1145/1192/1145 1146/1193/1146 1144/1191/1144 f 1145/1192/1145 1144/1191/1144 1143/1190/1143 f 1147/1194/1147 1148/1195/1148 1146/1193/1146 f 1147/1194/1147 1146/1193/1146 1145/1192/1145 f 1149/1196/1149 1150/1197/1150 1148/1195/1148 f 1149/1196/1149 1148/1195/1148 1147/1194/1147 f 1151/1198/1151 1152/1199/1152 1150/1197/1150 f 1151/1198/1151 1150/1197/1150 1149/1196/1149 f 1154/1200/1154 1155/1201/1155 1156/1202/1156 f 1154/1200/1154 1156/1202/1156 1153/1203/1153 f 1157/1204/1157 1158/1205/1158 1155/1201/1155 f 1157/1204/1157 1155/1201/1155 1154/1200/1154 f 1159/1206/1159 1160/1207/1160 1142/1189/1142 f 1159/1206/1159 1142/1189/1142 1144/1191/1144 f 1161/1208/1161 1159/1206/1159 1144/1191/1144 f 1161/1208/1161 1144/1191/1144 1146/1193/1146 f 1162/1209/1162 1161/1208/1161 1146/1193/1146 f 1162/1209/1162 1146/1193/1146 1148/1195/1148 f 1163/1210/1163 1162/1209/1162 1148/1195/1148 f 1163/1210/1163 1148/1195/1148 1150/1197/1150 f 1150/1197/1150 1152/1199/1152 1164/1211/1164 f 1150/1197/1150 1164/1211/1164 1163/1210/1163 f 1156/1202/1156 1155/1201/1155 1166/1212/1166 f 1156/1202/1156 1166/1212/1166 1165/1213/1165 f 1167/1214/1167 1166/1212/1166 1155/1201/1155 f 1167/1214/1167 1155/1201/1155 1158/1205/1158 f 1169/1215/1169 1167/1214/1167 1158/1205/1158 f 1169/1215/1169 1158/1205/1158 1168/1216/1168 f 1170/1217/1170 1171/1218/1171 1172/1219/1172 f 1170/1217/1170 1172/1219/1172 1139/1185/1139 f 1173/1220/1173 1174/1221/1174 1141/1188/1141 f 1173/1220/1173 1141/1188/1141 1140/1186/1140 f 1141/1188/1141 1174/1221/1174 1175/1222/1175 f 1141/1188/1141 1175/1222/1175 1143/1190/1143 f 1176/1223/1176 1145/1192/1145 1143/1190/1143 f 1176/1223/1176 1143/1190/1143 1175/1222/1175 f 1177/1224/1177 1149/1196/1149 1147/1194/1147 f 1177/1224/1177 1147/1194/1147 1176/1223/1176 f 1177/1224/1177 1178/1225/1178 1151/1198/1151 f 1177/1224/1177 1151/1198/1151 1149/1196/1149 f 1153/1203/1153 1179/1226/1179 1180/1227/1180 f 1153/1203/1153 1180/1227/1180 1154/1200/1154 f 1157/1204/1157 1154/1200/1154 1180/1227/1180 f 1157/1204/1157 1180/1227/1180 1181/1228/1181 f 1157/1204/1157 1181/1228/1181 1182/1229/1182 f 1157/1204/1157 1182/1229/1182 1168/1216/1168 f 1169/1215/1169 1168/1216/1168 1182/1229/1182 f 1169/1215/1169 1182/1229/1182 1183/1230/1183 f 1142/1189/1142 1160/1207/1160 1138/1184/1138 f 1142/1189/1142 1138/1184/1138 1137/1187/1137 f 1170/1217/1170 1185/1231/1185 1186/1232/1186 f 1170/1217/1170 1186/1232/1186 1184/1233/1184 f 1170/1217/1170 1184/1233/1184 1187/1234/1187 f 1170/1217/1170 1187/1234/1187 1171/1218/1171 f 1187/1234/1187 1188/1235/1188 1172/1219/1172 f 1187/1234/1187 1172/1219/1172 1171/1218/1171 f 1172/1219/1172 1188/1235/1188 1140/1186/1140 f 1172/1219/1172 1140/1186/1140 1139/1185/1139 f 1161/1208/1161 1162/1209/1162 1163/1210/1163 f 1161/1208/1161 1163/1210/1163 1189/1236/1189 f 1189/1236/1189 1163/1210/1163 1164/1211/1164 f 1189/1236/1189 1164/1211/1164 1190/1237/1190 f 1165/1213/1165 1164/1211/1164 1152/1199/1152 f 1165/1213/1165 1152/1199/1152 1156/1202/1156 f 1152/1199/1152 1151/1198/1151 1153/1203/1153 f 1152/1199/1152 1153/1203/1153 1156/1202/1156 f 1179/1226/1179 1153/1203/1153 1151/1198/1151 f 1179/1226/1179 1151/1198/1151 1178/1225/1178 f 1189/1236/1189 1160/1207/1160 1159/1206/1159 f 1189/1236/1189 1159/1206/1159 1161/1208/1161 f 1186/1232/1186 1190/1237/1190 1164/1211/1164 f 1186/1232/1186 1164/1211/1164 1165/1213/1165 f 1139/1185/1139 1138/1184/1138 1185/1231/1185 f 1139/1185/1139 1185/1231/1185 1170/1217/1170 f 1169/1215/1169 1188/1235/1188 1187/1234/1187 f 1169/1215/1169 1187/1234/1187 1167/1214/1167 f 1186/1232/1186 1165/1213/1165 1166/1212/1166 f 1186/1232/1186 1166/1212/1166 1184/1233/1184 f 1140/1186/1140 1188/1235/1188 1191/1238/1191 f 1140/1186/1140 1191/1238/1191 1173/1220/1173 f 1191/1238/1191 1188/1235/1188 1169/1215/1169 f 1191/1238/1191 1169/1215/1169 1183/1230/1183 f 1192/1239/1192 1193/1240/1193 1179/1226/1179 f 1192/1239/1192 1179/1226/1179 1178/1225/1178 f 1192/1239/1192 1178/1225/1178 1177/1224/1177 f 1192/1239/1192 1177/1224/1177 1194/1241/1194 f 1180/1227/1180 1193/1240/1193 1072/1108/1072 f 1180/1227/1180 1072/1108/1072 1105/1144/1105 f 1180/1227/1180 1105/1144/1105 1107/1146/1107 f 1180/1227/1180 1107/1146/1107 1181/1228/1181 f 1194/1241/1194 1177/1224/1177 1176/1223/1176 f 1194/1241/1194 1176/1223/1176 1114/1161/1114 f 1062/1095/1062 1194/1241/1194 1114/1161/1114 f 1062/1095/1062 1114/1161/1114 1066/1101/1066 f 707/724/707 1072/1108/1072 1193/1240/1193 f 707/724/707 1193/1240/1193 825/845/825 f 825/845/825 1193/1240/1193 1192/1239/1192 f 825/845/825 1192/1239/1192 1059/1093/1059 f 1173/1220/1173 1191/1238/1191 832/853/832 f 1173/1220/1173 832/853/832 711/728/711 f 1183/1230/1183 1182/1229/1182 1005/1035/1005 f 1183/1230/1183 1005/1035/1005 831/851/831 f 1187/1234/1187 1184/1233/1184 1166/1212/1166 f 1187/1234/1187 1166/1212/1166 1167/1214/1167 f 710/727/710 1115/1160/1115 1175/1222/1175 f 710/727/710 1175/1222/1175 1174/1221/1174 f 1182/1229/1182 1181/1228/1181 1107/1146/1107 f 1182/1229/1182 1107/1146/1107 1005/1035/1005 f 453/443/453 1049/1083/1049 720/738/720 f 453/443/453 720/738/720 598/590/598 f 1123/1170/1123 888/910/888 889/909/889 f 1123/1170/1123 889/909/889 844/865/844 f 916/938/916 794/814/794 793/813/793 f 916/938/916 793/813/793 913/939/913 f 711/728/711 832/853/832 770/787/770 f 711/728/711 770/787/770 708/729/708 f 919/943/919 927/949/927 1128/1174/1128 f 919/943/919 1128/1174/1128 959/982/959 f 925/948/925 708/729/708 770/787/770 f 925/948/925 770/787/770 769/786/769 f 913/939/913 793/813/793 954/976/954 f 913/939/913 954/976/954 924/946/924 f 831/851/831 832/853/832 1191/1238/1191 f 831/851/831 1191/1238/1191 1183/1230/1183 f 895/915/895 767/784/767 766/783/766 f 895/915/895 766/783/766 1006/1036/1006 f 891/912/891 804/828/804 807/827/807 f 891/912/891 807/827/807 788/808/788 f 778/795/778 777/794/777 788/808/788 f 778/795/778 788/808/788 807/827/807 f 810/830/810 1000/1027/1000 776/797/776 f 810/830/810 776/797/776 779/796/779 f 947/970/947 1127/1173/1127 1073/1110/1073 f 947/970/947 1073/1110/1073 952/975/952 f 1106/1145/1106 1136/1182/1136 1132/1178/1132 f 1106/1145/1106 1132/1178/1132 714/731/714 f 1061/1096/1061 1062/1095/1062 1066/1101/1066 f 1061/1096/1061 1066/1101/1066 1065/1104/1065 f 443/1098/443 497/1150/497 1057/1090/1057 f 443/1098/443 1057/1090/1057 1064/1099/1064 f 1064/1099/1064 1108/1147/1108 1113/1159/1113 f 1064/1099/1064 1113/1159/1113 1063/1100/1063 f 1061/1096/1061 1108/1147/1108 1056/1089/1056 f 1061/1096/1061 1056/1089/1056 1060/1094/1060 f 1192/1239/1192 1194/1241/1194 1062/1095/1062 f 1192/1239/1192 1062/1095/1062 1059/1093/1059 f 1173/1220/1173 711/728/711 710/727/710 f 1173/1220/1173 710/727/710 1174/1221/1174 f 880/900/880 881/905/881 884/904/884 f 880/900/880 884/904/884 878/901/878 f 841/862/841 1047/1081/1047 1046/1080/1046 f 841/862/841 1046/1080/1046 723/740/723 f 1070/1106/1070 1048/1082/1048 1047/1081/1047 f 1070/1106/1070 1047/1081/1047 841/862/841 f 461/1115/461 342/999/342 885/907/885 f 461/1115/461 885/907/885 886/906/886 f 1114/1161/1114 1176/1223/1176 1175/1222/1175 f 1114/1161/1114 1175/1222/1175 1115/1160/1115 f 887/908/887 1124/1169/1124 1130/1176/1130 f 887/908/887 1130/1176/1130 852/873/852 f 206/186/206 852/873/852 1130/1176/1130 f 206/186/206 1130/1176/1130 532/524/532 f 681/698/681 599/592/599 1195/1242/1195 f 681/698/681 1195/1242/1195 682/699/682 f 1196/1243/1196 674/691/674 684/702/684 f 1196/1243/1196 684/702/684 1195/1242/1195 f 1197/1244/1197 675/692/675 674/691/674 f 1197/1244/1197 674/691/674 1196/1243/1196 f 689/706/689 690/708/690 675/692/675 f 689/706/689 675/692/675 1197/1244/1197 f 693/710/693 1199/1245/1199 1200/1246/1200 f 693/710/693 1200/1246/1200 1198/1247/1198 f 686/707/686 689/706/689 1197/1244/1197 f 686/707/686 1197/1244/1197 1199/1245/1199 f 1196/1243/1196 1195/1242/1195 1202/1248/1202 f 1196/1243/1196 1202/1248/1202 1201/1249/1201 f 1084/1122/1084 1083/1124/1083 1204/1250/1204 f 1084/1122/1084 1204/1250/1204 1203/1251/1203 f 1092/1131/1092 1013/1042/1013 1203/1251/1203 f 1092/1131/1092 1203/1251/1203 1204/1250/1204 f 1206/1252/1206 1087/1253/1087 1207/1254/1207 f 1206/1252/1206 1207/1254/1207 1205/1255/1205 f 1206/1252/1206 1208/1256/1208 1086/1257/1086 f 1206/1252/1206 1086/1257/1086 1087/1253/1087 f 1091/1258/1091 1090/1259/1090 1210/1260/1210 f 1091/1258/1091 1210/1260/1210 1209/1261/1209 f 1093/1132/1093 1211/1262/1211 757/774/757 f 1093/1132/1093 757/774/757 756/775/756 f 1079/1120/1079 1212/1263/1212 1090/1128/1090 f 1079/1120/1079 1090/1128/1090 1080/1118/1080 f 1079/1120/1079 979/1006/979 1088/1127/1088 f 1079/1120/1079 1088/1127/1088 1212/1263/1212 f 1209/1261/1209 1213/1264/1213 1085/1265/1085 f 1209/1261/1209 1085/1265/1085 1131/1266/1131 f 1089/1130/1089 1091/1129/1091 1131/1177/1131 f 1089/1130/1089 1131/1177/1131 1036/1070/1036 f 1213/1264/1213 1214/1267/1214 1204/1268/1204 f 1213/1264/1213 1204/1268/1204 1083/1269/1083 f 1214/1267/1214 1215/1270/1215 1092/1271/1092 f 1214/1267/1214 1092/1271/1092 1204/1268/1204 f 1015/1045/1015 757/774/757 1211/1262/1211 f 1015/1045/1015 1211/1262/1211 1216/1272/1216 f 1211/1273/1211 1093/1274/1093 1215/1270/1215 f 1211/1273/1211 1215/1270/1215 1217/1275/1217 f 1088/1276/1088 1208/1256/1208 1210/1260/1210 f 1088/1276/1088 1210/1260/1210 1212/1277/1212 f 1216/1278/1216 1211/1273/1211 1217/1275/1217 f 1216/1278/1216 1217/1275/1217 1218/1279/1218 f 1219/1280/1219 1218/1279/1218 1205/1255/1205 f 1219/1280/1219 1205/1255/1205 1207/1254/1207 f 698/715/698 697/714/697 717/734/717 f 698/715/698 717/734/717 716/737/716 f 967/992/967 418/407/418 524/516/524 f 967/992/967 524/516/524 968/993/968 f 598/590/598 720/738/720 712/733/712 f 598/590/598 712/733/712 293/276/293 f 697/714/697 721/739/721 1050/1084/1050 f 697/714/697 1050/1084/1050 717/734/717 f 957/979/957 956/978/956 1005/1035/1005 f 957/979/957 1005/1035/1005 1107/1146/1107 f 1186/1232/1186 1185/1231/1185 1189/1236/1189 f 1186/1232/1186 1189/1236/1189 1190/1237/1190 f 1022/1051/1022 896/917/896 765/782/765 f 1022/1051/1022 765/782/765 764/785/764 f 1122/1168/1122 896/917/896 1022/1051/1022 f 1122/1168/1122 1022/1051/1022 1021/1054/1021 f 678/695/678 1198/1247/1198 625/631/625 f 678/695/678 625/631/625 27/8/27 f 1195/1242/1195 599/592/599 626/632/626 f 1195/1242/1195 626/632/626 1202/1248/1202 f 1202/1248/1202 626/632/626 628/634/628 f 1202/1248/1202 628/634/628 1220/1281/1220 f 1198/1247/1198 1220/1281/1220 628/634/628 f 1198/1247/1198 628/634/628 625/631/625 f 1222/1282/1222 1223/1283/1223 1224/1284/1224 f 1222/1282/1222 1224/1284/1224 1221/1285/1221 f 1226/1286/1226 1227/1287/1227 1228/1288/1228 f 1226/1286/1226 1228/1288/1228 1225/1289/1225 f 1230/1290/1230 1231/1291/1231 1232/1292/1232 f 1230/1290/1230 1232/1292/1232 1229/1293/1229 f 1234/1294/1234 1232/1292/1232 1231/1291/1231 f 1234/1294/1234 1231/1291/1231 1233/1295/1233 f 1236/1296/1236 1237/1297/1237 1238/1298/1238 f 1236/1296/1236 1238/1298/1238 1235/1299/1235 f 1221/1285/1221 1239/1300/1239 1240/1301/1240 f 1221/1285/1221 1240/1301/1240 1233/1295/1233 f 1242/1302/1242 1243/1303/1243 1244/1304/1244 f 1242/1302/1242 1244/1304/1244 1241/1305/1241 f 1237/1297/1237 1245/1306/1245 1246/1307/1246 f 1237/1297/1237 1246/1307/1246 1238/1298/1238 f 1246/1307/1246 1245/1306/1245 1242/1302/1242 f 1246/1307/1246 1242/1302/1242 1241/1305/1241 f 1248/1308/1248 1224/1284/1224 1249/1309/1249 f 1248/1308/1248 1249/1309/1249 1247/1310/1247 f 1249/1309/1249 1250/1311/1250 660/1312/660 f 1249/1309/1249 660/1312/660 659/1313/659 f 661/1314/661 1247/1310/1247 1249/1309/1249 f 661/1314/661 1249/1309/1249 659/1313/659 f 1221/1285/1221 1224/1284/1224 1248/1308/1248 f 1221/1285/1221 1248/1308/1248 1239/1300/1239 f 1231/1291/1231 1222/1282/1222 1221/1285/1221 f 1231/1291/1231 1221/1285/1221 1233/1295/1233 f 1232/1292/1232 1234/1294/1234 1243/1303/1243 f 1232/1292/1232 1243/1303/1243 1242/1302/1242 f 1244/1304/1244 1243/1303/1243 1234/1294/1234 f 1244/1304/1244 1234/1294/1234 1251/1315/1251 f 1240/1301/1240 1251/1315/1251 1234/1294/1234 f 1240/1301/1240 1234/1294/1234 1233/1295/1233 f 1253/1316/1253 1134/1181/1134 1135/1180/1135 f 1253/1316/1253 1135/1180/1135 1252/1317/1252 f 1254/1318/1254 1255/1319/1255 1229/1293/1229 f 1254/1318/1254 1229/1293/1229 1232/1292/1232 f 1254/1318/1254 1225/1289/1225 1228/1288/1228 f 1254/1318/1254 1228/1288/1228 1255/1319/1255 f 667/1320/667 1252/1317/1252 1135/1180/1135 f 667/1320/667 1135/1180/1135 539/1183/539 f 1226/1286/1226 1225/1289/1225 1237/1297/1237 f 1226/1286/1226 1237/1297/1237 1236/1296/1236 f 1245/1306/1245 1254/1318/1254 1232/1292/1232 f 1245/1306/1245 1232/1292/1232 1242/1302/1242 f 1254/1318/1254 1245/1306/1245 1237/1297/1237 f 1254/1318/1254 1237/1297/1237 1225/1289/1225 f 669/674/669 668/675/668 1226/1286/1226 f 669/674/669 1226/1286/1226 1236/1296/1236 f 1230/1290/1230 1256/1321/1256 1222/1282/1222 f 1230/1290/1230 1222/1282/1222 1231/1291/1231 f 1235/1299/1235 671/677/671 669/674/669 f 1235/1299/1235 669/674/669 1236/1296/1236 f 1230/1290/1230 1101/1139/1101 1100/1138/1100 f 1230/1290/1230 1100/1138/1100 1256/1321/1256 f 672/678/672 488/480/488 1103/1142/1103 f 672/678/672 1103/1142/1103 1227/1287/1227 f 1224/1284/1224 1223/1283/1223 1250/1311/1250 f 1224/1284/1224 1250/1311/1250 1249/1309/1249 f 1256/1321/1256 1100/1138/1100 1134/1181/1134 f 1256/1321/1256 1134/1181/1134 1253/1316/1253 f 1227/1287/1227 1103/1142/1103 1132/1178/1132 f 1227/1287/1227 1132/1178/1132 1228/1288/1228 f 1101/1139/1101 1230/1290/1230 1229/1293/1229 f 1101/1139/1101 1229/1293/1229 1133/1179/1133 f 1223/1283/1223 1253/1316/1253 1252/1317/1252 f 1223/1283/1223 1252/1317/1252 1250/1311/1250 f 1255/1319/1255 1136/1182/1136 1133/1179/1133 f 1255/1319/1255 1133/1179/1133 1229/1293/1229 f 1228/1288/1228 1132/1178/1132 1136/1182/1136 f 1228/1288/1228 1136/1182/1136 1255/1319/1255 f 660/1312/660 1250/1311/1250 1252/1317/1252 f 660/1312/660 1252/1317/1252 667/1320/667 f 668/675/668 672/678/672 1227/1287/1227 f 668/675/668 1227/1287/1227 1226/1286/1226 f 1222/1282/1222 1256/1321/1256 1253/1316/1253 f 1222/1282/1222 1253/1316/1253 1223/1283/1223 f 1/1322/1 12/1323/12 1247/1310/1247 f 1/1322/1 1247/1310/1247 661/1314/661 f 10/1324/10 8/1325/8 1240/1301/1240 f 10/1324/10 1240/1301/1240 1239/1300/1239 f 1239/1300/1239 1248/1308/1248 11/1326/11 f 1239/1300/1239 11/1326/11 10/1324/10 f 5/1327/5 3/1328/3 1235/1299/1235 f 5/1327/5 1235/1299/1235 1238/1298/1238 f 9/1329/9 4/1330/4 1246/1307/1246 f 9/1329/9 1246/1307/1246 1241/1305/1241 f 1240/1301/1240 8/1325/8 6/1331/6 f 1240/1301/1240 6/1331/6 1251/1315/1251 f 7/1332/7 9/1329/9 1241/1305/1241 f 7/1332/7 1241/1305/1241 1244/1304/1244 f 11/1326/11 1248/1308/1248 1247/1310/1247 f 11/1326/11 1247/1310/1247 12/1323/12 f 3/1328/3 2/690/2 671/677/671 f 3/1328/3 671/677/671 1235/1299/1235 f 1238/1298/1238 1246/1307/1246 4/1330/4 f 1238/1298/1238 4/1330/4 5/1327/5 f 7/1332/7 1244/1304/1244 1251/1315/1251 f 7/1332/7 1251/1315/1251 6/1331/6 f 1203/1251/1203 1013/1042/1013 1012/1043/1012 f 1203/1251/1203 1012/1043/1012 736/757/736 f 937/959/937 941/964/941 1027/1057/1027 f 937/959/937 1027/1057/1027 999/1030/999 f 1084/1122/1084 739/756/739 1034/1067/1034 f 1084/1122/1084 1034/1067/1034 1037/1071/1037 f 1197/1244/1197 1196/1243/1196 1201/1249/1201 f 1197/1244/1197 1201/1249/1201 1199/1245/1199 f 1203/1251/1203 736/757/736 739/756/739 f 1203/1251/1203 739/756/739 1084/1122/1084 f 936/962/936 784/805/784 941/964/941 f 936/962/936 941/964/941 937/959/937 f 786/806/786 1004/1033/1004 940/963/940 f 786/806/786 940/963/940 785/804/785 f 467/1333/467 612/604/612 387/1334/387 f 612/604/612 624/630/624 387/1334/387 f 621/628/621 387/1334/387 624/630/624 f 604/595/604 44/22/44 28/5/28 f 472/605/472 612/604/612 467/1333/467 f 29/6/29 28/5/28 47/26/47 f 43/21/43 48/25/48 44/22/44 f 30/7/30 266/1335/266 27/8/27 f 424/414/424 239/223/239 425/415/425 f 467/458/467 363/347/363 472/463/472 f 561/552/561 560/553/560 572/564/572 f 549/540/549 551/542/551 579/571/579 f 583/574/583 595/588/595 582/575/582 f 31/12/31 36/13/36 600/591/600 f 39/16/39 44/22/44 603/597/603 f 32/9/32 599/592/599 45/23/45 f 473/626/473 613/607/613 471/606/471 f 477/620/477 478/625/478 620/621/620 f 474/611/474 615/610/615 617/627/617 f 1257/1336/1257 614/609/614 618/616/618 f 1257/1336/1257 620/621/620 622/624/622 f 1257/1336/1257 618/616/618 619/619/619 f 1257/1336/1257 613/607/613 615/610/615 f 614/609/614 1257/1336/1257 615/610/615 f 622/624/622 623/629/623 1257/1336/1257 f 1257/1336/1257 623/629/623 611/603/611 f 624/630/624 623/629/623 621/628/621 f 469/617/469 618/616/618 470/615/470 f 614/609/614 476/608/476 533/614/533 f 610/602/610 1257/1336/1257 611/603/611 f 613/607/613 1257/1336/1257 610/602/610 f 620/621/620 1257/1336/1257 619/619/619 f 541/532/541 592/584/592 562/555/562 f 541/532/541 587/581/587 592/584/592 f 627/633/627 607/599/607 605/596/605 f 627/633/627 605/596/605 604/595/604 f 605/596/605 606/598/606 603/597/603 f 607/599/607 606/598/606 605/596/605 f 1207/1254/1207 1082/1337/1082 1015/1338/1015 f 1219/1280/1219 1207/1254/1207 1015/1338/1015 f 1015/1338/1015 1216/1278/1216 1219/1280/1219 f 693/710/693 1198/1247/1198 678/695/678 f 1207/1254/1207 1087/1253/1087 1082/1337/1082 f 678/695/678 677/697/677 694/712/694 f 695/713/695 692/711/692 693/710/693 f 266/1335/266 679/696/679 27/8/27 f 883/903/883 1044/1079/1044 1045/1078/1045 f 992/1020/992 1082/1121/1082 1087/1125/1087 f 1158/1205/1158 1157/1204/1157 1168/1216/1168 f 1147/1194/1147 1145/1192/1145 1176/1223/1176 f 1193/1240/1193 1180/1227/1180 1179/1226/1179 f 684/702/684 682/699/682 1195/1242/1195 f 693/710/693 686/707/686 1199/1245/1199 f 599/592/599 681/698/681 45/23/45 f 1208/1256/1208 1088/1276/1088 1086/1257/1086 f 1093/1274/1093 1092/1271/1092 1215/1270/1215 f 1210/1260/1210 1090/1259/1090 1212/1277/1212 f 1209/1261/1209 1258/1339/1258 1213/1264/1213 f 1215/1270/1215 1258/1339/1258 1217/1275/1217 f 1213/1264/1213 1258/1339/1258 1214/1267/1214 f 1208/1256/1208 1258/1339/1258 1210/1260/1210 f 1258/1339/1258 1209/1261/1209 1210/1260/1210 f 1218/1279/1218 1217/1275/1217 1258/1339/1258 f 1218/1279/1218 1258/1339/1258 1205/1255/1205 f 1218/1279/1218 1219/1280/1219 1216/1278/1216 f 1213/1264/1213 1083/1269/1083 1085/1265/1085 f 1091/1258/1091 1209/1261/1209 1131/1266/1131 f 1258/1339/1258 1206/1252/1206 1205/1255/1205 f 1258/1339/1258 1208/1256/1208 1206/1252/1206 f 1258/1339/1258 1215/1270/1215 1214/1267/1214 f 1189/1236/1189 1138/1184/1138 1160/1207/1160 f 1185/1231/1185 1138/1184/1138 1189/1236/1189 f 1202/1248/1202 1220/1281/1220 1200/1246/1200 f 1200/1246/1200 1220/1281/1220 1198/1247/1198 f 1201/1249/1201 1200/1246/1200 1199/1245/1199 f 1201/1249/1201 1202/1248/1202 1200/1246/1200 # 2492 faces ================================================ FILE: graphics/tiny-renderer/lesson6.workbook/obj/diablo3_pose.obj ================================================ v 0.11526 0.700717 0.0677257 v 0.114223 0.654606 0.0821706 v 0.119952 0.67202 0.101202 v 0.12069 0.712368 0.0932415 v 0.120409 0.670105 0.118388 v 0.103434 0.63749 0.102854 v 0.0998313 0.642305 0.121165 v 0.113204 0.661161 0.119513 v 0.110674 0.71474 0.118248 v 0.114329 0.673286 0.128141 v 0.0938038 0.672987 0.125628 v 0.0910976 0.702896 0.120497 v 0.107546 0.664288 0.12793 v 0.116526 0.652831 0.0186975 v 0.122606 0.631867 0.0339156 v 0.123238 0.584561 0.0390644 v 0.113679 0.582153 0.0698344 v 0.107247 0.593611 0.124012 v 0.099392 0.618107 0.132025 v 0.0519629 0.664482 0.148508 v 0.056813 0.67065 0.139722 v 0.0671458 0.660001 0.134186 v 0.0799037 0.658226 0.13039 v 0.0872667 0.645679 0.131726 v 0.0690261 0.645978 0.151671 v 0.0731557 0.627719 0.151074 v 0.0524549 0.654325 0.16232 v 0.0402945 0.655625 0.166186 v 0.0399431 0.667873 0.157259 v 0.0514006 0.648069 0.163058 v 0.0395565 0.644343 0.164429 v 0.0403297 0.634327 0.163322 v 0.048132 0.610076 0.154571 v 0.021597 0.677468 0.15559 v 0.0424033 0.672267 0.161494 v 0.0551611 0.669385 0.152479 v 0.0324219 0.694391 0.157312 v 0.0500123 0.692264 0.158015 v 0.0621024 0.681106 0.149088 v 0.042087 0.725178 0.149141 v 0.0617158 0.711489 0.15088 v 0.0706604 0.695445 0.133782 v 0.0129512 0.710365 0.135873 v 0.0267634 0.736074 0.134696 v 0.0996029 0.759463 0.122043 v 0.127526 0.758813 0.113749 v 0.0634907 0.787228 0.117404 v 0.0781113 0.602994 0.15624 v 0.0661442 0.626208 0.15269 v 0.0892525 0.572418 0.146698 v 0.0501705 0.601641 0.155028 v 0.0637543 0.593944 0.162443 v 0.0649668 0.641321 0.158156 v 0.0678663 0.629969 0.156521 v 0.0497663 0.643588 0.152233 v 0.0475697 0.626384 0.148209 v 0.0605209 0.610199 0.15566 v 0.0599761 0.626419 0.15429 v 0.0643869 0.628457 0.153182 v 0.0578146 0.640741 0.152849 v 0.0813095 0.813025 0.103117 v 0.135047 0.790409 0.0950163 v 0.116789 0.817945 0.0520332 v 0.0892876 0.821565 0.0596598 v 0.0257091 0.775507 0.125488 v 0.0636313 0.679507 0.139194 v 0.0781289 0.671792 0.13872 v 0.0878993 0.595034 0.00293464 v 0.116772 0.566636 0.0537026 v 0.114417 0.562155 0.0744385 v 0.128176 0.558166 0.0246547 v 0.107194 0.567445 0.09651 v 0.0944716 0.545496 0.110902 v 0.0712403 0.535304 0.117264 v 0.112431 0.54474 0.087214 v 0.0971602 0.533775 0.0882684 v 0.0731382 0.524128 0.0962816 v 0.106368 0.520964 0.0665483 v 0.099392 0.514164 0.0756159 v 0.0780586 0.512283 0.0791129 v 0.1141 0.533037 0.0671107 v 0.115436 0.533582 0.0411731 v 0.115752 0.527449 0.0417179 v 0.114469 0.546304 0.0516993 v 0.102151 0.525076 0.0562506 v 0.0970021 0.503198 0.0402242 v 0.100605 0.498208 0.054177 v 0.0863529 0.491407 0.0541595 v 0.0949988 0.486943 0.0309282 v 0.0732963 0.583559 0.000140556 v 0.0795522 0.555653 0.0176783 v 0.0874073 0.557569 0.0307173 v 0.0843848 0.502601 0.03439 v 0.0989175 0.529927 0.0420342 v 0.0913612 0.482164 0.025094 v 0.0906759 0.48197 0.0349172 v 0.00242505 0.842706 0.085773 v -0.0105613 0.872456 0.0789021 v -0.0279935 0.869416 0.0666186 v -0.0107546 0.825273 0.0714863 v -0.00999895 0.80039 0.118951 v -0.0275542 0.855217 0.105806 v 0.00233719 0.823744 0.11222 v -0.0122131 0.863705 0.0988999 v -0.039451 0.902576 0.0606087 v -0.00137068 0.808351 0.0664078 v 0.0207008 0.806207 0.0844902 v 0.0138474 0.77795 0.120374 v -0.00152884 0.759691 0.126718 v -0.0331072 0.875532 0.0913612 v 0.0211577 0.79605 0.104594 v -0.226707 -0.278811 0.0844199 v -0.164271 -0.310688 0.0763188 v -0.190121 -0.154536 0.0547394 v -0.115682 -0.174358 0.0460584 v -0.102748 -0.13025 0.0384494 v -0.268074 -0.269339 0.0650371 v -0.243946 -0.149703 0.0212455 v -0.189084 -0.00231963 -0.0608723 v -0.259147 -0.376006 0.0909394 v -0.140495 -0.0527185 0.0225987 v -0.164921 -0.01086 -0.00980567 v -0.129125 -0.0841915 0.0319474 v -0.116754 -0.0240045 0.0389238 v -0.120655 -0.0525252 0.0430183 v -0.0982849 -0.162391 0.0430007 v -0.203775 -0.406776 0.0984782 v -0.145872 -0.436597 0.059484 v -0.112062 -0.35411 0.0492742 v -0.237813 -0.446297 0.116033 v -0.20511 -0.499332 0.0841563 v -0.272291 -0.426932 0.106158 v -0.270692 -0.459635 0.163568 v -0.233912 -0.504639 0.102661 v -0.283362 -0.512406 0.0865638 v -0.252293 -0.489931 0.130584 v -0.29858 -0.454451 0.1128 v -0.291674 -0.453854 0.139897 v -0.284153 -0.488068 0.128897 v -0.294415 -0.476822 0.0981619 v -0.302639 -0.443292 0.0965276 v -0.311004 -0.454768 0.12489 v -0.320423 -0.453836 0.0878993 v -0.311865 -0.403683 0.0613995 v -0.328718 -0.434137 0.0385899 v -0.328278 -0.278442 -0.00706431 v -0.321495 -0.34311 0.0478333 v -0.297754 -0.253506 -0.137736 v -0.214301 -0.520314 0.0970899 v -0.231346 -0.516958 0.105876 v -0.24356 -0.52411 0.101887 v -0.222419 -0.53743 0.100727 v -0.238007 -0.537219 0.100323 v -0.233315 -0.527818 0.121288 v -0.226268 -0.536639 0.0605033 v -0.180209 -0.502091 0.0646329 v -0.2563 -0.52404 0.0890767 v -0.278617 -0.532422 0.106368 v -0.24739 -0.547007 0.0609426 v -0.272256 -0.556567 0.0515938 v -0.237128 -0.554546 -0.0027238 v -0.329438 -0.473131 0.0214564 v -0.328981 -0.486733 0.0608371 v -0.307384 -0.510948 0.0583242 v -0.214266 -0.520806 0.0641936 v -0.209187 -0.532686 0.0775489 v -0.210118 -0.541472 0.0516817 v -0.18448 -0.526307 0.0144449 v -0.202369 -0.52469 0.046691 v -0.13995 -0.494078 -0.0121604 v -0.076477 -0.16464 -0.246828 v -0.215215 -0.18578 -0.218676 v -0.177468 -0.0685341 -0.2912 v -0.300513 -0.164886 -0.0611535 v -0.328489 -0.511264 -0.0174498 v -0.32754 -0.511071 0.0356377 v -0.294732 -0.547429 -0.00166944 v -0.313974 -0.486012 0.0562506 v -0.113872 -0.083102 0.0324922 v -0.0877061 -0.1322 0.0504868 v -0.0748427 -0.168576 0.02896 v -0.0878115 -0.13336 0.0293466 v -0.106439 -0.0435104 0.0336695 v -0.100411 -0.0729097 0.019664 v -0.0763716 -0.204442 0.0280814 v -0.155678 -0.252803 -0.213914 v -0.270464 -0.298615 -0.174779 v -0.227252 -0.0342143 -0.120321 v -0.229097 -0.0836292 -0.207834 v -0.0959301 -0.172671 -0.22314 v -0.18571 -0.119987 -0.24421 v -0.0694303 -0.201104 0.043317 v -0.0647911 -0.227656 0.0175025 v -0.0861948 -0.217271 0.0386778 v -0.0703792 -0.219379 0.0386251 v -0.099515 -0.241258 0.0468492 v -0.0809229 -0.241837 0.0346185 v -0.361825 -0.347046 -0.0517169 v -0.356465 -0.383352 0.0123713 v -0.365041 -0.413717 -0.0374302 v -0.198011 -0.343672 -0.195164 v -0.222542 -0.382104 -0.170984 v -0.0891119 -0.308386 -0.115946 v -0.0247777 -0.200436 -0.16942 v -0.122096 -0.400907 -0.110357 v -0.0774611 -0.32262 -0.0285383 v -0.0899027 -0.36237 -0.0259375 v -0.0697642 -0.274013 0.00676553 v -0.126085 -0.453625 -0.0196289 v -0.150986 -0.459249 -0.0810108 v -0.343496 -0.37142 -0.228429 v -0.232489 -0.383334 -0.251801 v -0.17195 -0.413577 -0.222964 v -0.319439 -0.410818 -0.323955 v -0.242874 -0.411029 -0.323674 v -0.300373 -0.419147 -0.372492 v -0.241398 -0.423136 -0.377693 v -0.280023 -0.359242 -0.238586 v -0.336608 -0.363635 -0.116596 v -0.341528 -0.467894 -0.310635 v -0.376516 -0.419341 -0.17 v -0.34021 -0.470987 -0.359734 v -0.356922 -0.494693 -0.23154 v -0.3678 -0.432415 -0.235687 v -0.3691 -0.469423 -0.118248 v -0.337117 -0.518838 -0.136945 v -0.268197 -0.578551 -0.134977 v -0.192633 -0.538994 -0.0549854 v -0.157927 -0.511422 -0.0755105 v -0.170052 -0.525604 -0.152884 v -0.146153 -0.481074 -0.182283 v -0.185956 -0.440973 -0.312691 v -0.281376 -0.36418 -0.154307 v -0.159315 -0.374846 -0.160071 v -0.177029 -0.419499 -0.142814 v -0.207623 -0.455523 -0.380628 v -0.20019 -0.524444 -0.379503 v -0.332267 -0.533529 -0.224792 v -0.27563 -0.574175 -0.229923 v -0.175816 -0.507697 -0.257214 v -0.293695 -0.535023 0.0562506 v -0.0170808 -0.191808 -0.0932415 v -0.0249886 -0.115858 -0.00550031 v -0.0118968 -0.173286 -0.0372369 v -0.216093 -0.549345 -0.141426 v -0.23291 -0.571153 -0.356694 v -0.211893 -0.551805 -0.242365 v -0.213334 -0.49464 -0.477524 v -0.24196 -0.540681 -0.524602 v -0.222824 -0.433786 -0.46568 v -0.322303 -0.541771 -0.514656 v -0.347767 -0.520121 -0.487664 v -0.280392 -0.547306 -0.527994 v -0.286262 -0.580027 -0.331002 v -0.335676 -0.543387 -0.345904 v -0.371261 -0.533406 -0.419358 v -0.324289 -0.469845 -0.50427 v -0.359347 -0.47343 -0.451956 v -0.242259 -0.468843 -0.513584 v -0.328155 -0.438284 -0.464064 v -0.274066 -0.472727 -0.520121 v -0.268636 -0.418778 -0.47336 v -0.26405 -0.676959 -0.365744 v -0.223509 -0.587302 -0.461551 v -0.229431 -0.689242 -0.390381 v -0.217798 -0.629336 -0.456683 v -0.244421 -0.666872 -0.48132 v -0.27078 -0.728043 -0.425509 v -0.283204 -0.679841 -0.483376 v -0.276843 -0.784821 -0.410097 v -0.244755 -0.72734 -0.414403 v -0.238868 -0.781991 -0.378519 v -0.24739 -0.767353 -0.363354 v -0.241451 -0.720768 -0.382596 v -0.268583 -0.7146 -0.363898 v -0.251221 -0.79851 -0.377096 v -0.273469 -0.798422 -0.39191 v -0.263188 -0.827716 -0.377482 v -0.25326 -0.811514 -0.363354 v -0.282466 -0.829192 -0.392033 v -0.274997 -0.828366 -0.372615 v -0.275489 -0.81487 -0.357748 v -0.239852 -0.749868 -0.402822 v -0.257881 -0.783801 -0.405107 v -0.234703 -0.689839 -0.458511 v -0.328454 -0.660264 -0.488051 v -0.367167 -0.637666 -0.455101 v -0.388641 -0.741943 -0.435631 v -0.376199 -0.631515 -0.395108 v -0.400098 -0.749288 -0.367958 v -0.383721 -0.823042 -0.261308 v -0.341229 -0.632657 -0.35462 v -0.362352 -0.751995 -0.321882 v -0.42405 -0.853284 -0.300847 v -0.350174 -0.740432 -0.472639 v -0.374196 -0.81292 -0.477929 v -0.319228 -0.757776 -0.318754 v -0.282642 -0.767582 -0.344621 v -0.337117 -0.824061 -0.251221 v -0.378642 -0.839771 -0.211243 v -0.346519 -0.841335 -0.204056 v -0.384265 -0.849313 -0.179577 v -0.353566 -0.852177 -0.173321 v -0.398341 -0.84731 -0.154711 v -0.351914 -0.850033 -0.14466 v -0.403841 -0.868169 -0.125505 v -0.359206 -0.872685 -0.119829 v -0.407268 -0.896601 -0.109988 v -0.428268 -0.941078 -0.0731733 v -0.385618 -0.936808 -0.0554072 v -0.427512 -0.988226 -0.0347064 v -0.40834 -0.985977 -0.0265877 v -0.418638 -1 -0.0334763 v -0.409447 -0.922574 -0.0527537 v -0.368555 -0.903806 -0.104699 v -0.420114 -0.954082 -0.0233543 v -0.420711 -0.984887 -0.0225108 v -0.380716 -0.952641 -0.0529294 v -0.34615 -0.890767 -0.143553 v -0.322708 -0.865621 -0.209732 v -0.305029 -0.838523 -0.25282 v -0.394229 -0.880435 -0.21279 v -0.40298 -0.884916 -0.172548 v -0.339911 -0.878431 -0.173321 v -0.340333 -0.942467 -0.116332 v -0.372263 -0.974871 -0.0709767 v -0.418111 -0.930781 -0.135627 v -0.368063 -0.961059 -0.140565 v -0.395266 -0.987225 -0.105613 v -0.412768 -0.970864 -0.0551963 v -0.405546 -0.98306 -0.078041 v -0.434401 -0.949988 -0.0829438 v -0.430183 -0.963326 -0.099269 v -0.400661 -0.968861 -0.0308228 v -0.415563 -0.977208 -0.0443539 v -0.43173 -0.974168 -0.0451095 v -0.224142 -0.382578 -0.183021 v -0.280744 -0.362475 -0.179102 v -0.344762 -0.376305 -0.133308 v -0.175869 -0.418251 -0.162514 v -0.151408 -0.46742 -0.0904298 v -0.409061 -0.832689 -0.359452 v -0.436527 -0.875479 -0.277827 v -0.409078 -0.870471 -0.240203 v -0.391171 -0.957931 -0.0474467 v -0.428619 -0.95236 -0.0712403 v -0.392612 -0.924736 -0.175588 v -0.355446 -0.943785 -0.177661 v -0.330826 -0.922803 -0.173795 v -0.319826 -0.938302 -0.223263 v -0.383246 -0.93419 -0.226075 v -0.347784 -0.955277 -0.227568 v -0.480494 -0.870594 -0.26296 v -0.466014 -0.867518 -0.233859 v -0.496784 -0.864953 -0.258479 v -0.484782 -0.858591 -0.230099 v -0.519383 -0.873036 -0.246775 v -0.51021 -0.867501 -0.220557 v -0.533916 -0.892402 -0.2382 v -0.52476 -0.883633 -0.21532 v -0.587987 -0.92753 -0.202176 v -0.573015 -0.93013 -0.187977 v -0.603399 -0.965013 -0.185112 v -0.587759 -0.96807 -0.171968 v -0.586863 -0.943134 -0.216779 v -0.594753 -0.980635 -0.201314 v -0.598478 -0.987506 -0.180719 v -0.494025 -0.905792 -0.259076 v -0.524075 -0.915598 -0.247777 v -0.576249 -0.955312 -0.233332 v -0.549134 -0.94679 -0.181686 v -0.488437 -0.883668 -0.221137 v -0.471251 -0.883334 -0.227797 v -0.500105 -0.92268 -0.200366 v -0.542315 -0.9693 -0.213774 v -0.510175 -0.93665 -0.225196 v -0.579254 -0.973834 -0.194496 v -0.562577 -0.97654 -0.205005 v -0.574913 -0.952009 -0.179278 v -0.587583 -0.966858 -0.20931 v -0.586318 -0.976945 -0.189242 v -0.474519 -0.931536 -0.233244 v -0.471128 -0.917724 -0.215742 v -0.419358 -0.91319 -0.226532 v -0.434822 -0.917548 -0.305978 v -0.403086 -0.886515 -0.359224 v -0.386269 -0.851984 -0.4263 v -0.313341 -0.810829 -0.460127 v -0.316188 -0.843602 -0.441131 v -0.336397 -0.967947 -0.279725 v -0.260763 -0.938847 -0.308069 v -0.331336 -0.942554 -0.324307 v -0.331266 -0.886444 -0.370506 v -0.42948 -0.944575 -0.319878 v -0.402225 -0.95707 -0.275103 v -0.289021 -0.878203 -0.359347 v -0.281288 -0.843813 -0.282975 v -0.270323 -0.859347 -0.334481 v -0.24479 -0.877289 -0.243893 v -0.248199 -0.887095 -0.304731 v -0.253963 -0.845781 -0.223509 v -0.303676 -0.75029 -0.466717 v -0.289108 -0.850455 -0.208502 v -0.260588 -0.844603 -0.187889 v -0.228816 -0.848575 -0.203423 v -0.206727 -0.855376 -0.172688 v -0.241908 -0.847099 -0.155889 v -0.203898 -0.870436 -0.156785 v -0.234949 -0.862159 -0.140811 v -0.19541 -0.921221 -0.103943 v -0.216146 -0.921098 -0.103697 v -0.198591 -0.962798 -0.0907462 v -0.213334 -0.965487 -0.0940499 v -0.205005 -0.982515 -0.0964222 v -0.188469 -0.935121 -0.118687 v -0.196746 -0.973518 -0.107019 v -0.22669 -0.884125 -0.210769 v -0.20989 -0.902594 -0.18202 v -0.244526 -0.94744 -0.12315 v -0.259902 -0.893702 -0.160827 v -0.264629 -0.859558 -0.181721 v -0.263751 -0.886901 -0.173022 v -0.23342 -0.952659 -0.161125 v -0.195779 -0.953432 -0.152198 v -0.238007 -0.917232 -0.176185 v -0.212333 -0.960742 -0.113608 v -0.223579 -0.965434 -0.138123 v -0.22379 -0.944452 -0.106509 v -0.197817 -0.949302 -0.126999 v -0.21047 -0.968914 -0.104084 v -0.240818 -0.908744 -0.186219 v -0.307929 -0.903314 -0.210066 v -0.240484 -0.924402 -0.250308 v -0.278231 -0.957896 -0.25159 v -0.268987 -0.933399 -0.223456 v -0.0218079 -0.117158 0.00576388 v -0.00451622 -0.172354 -0.017485 v 0.0111588 -0.124943 0.00857553 v 0.0238112 -0.188258 -0.0190665 v -0.0554599 -0.00961236 0.0186623 v -0.0614171 -0.0116157 0.0119144 v -0.110744 -0.0432116 0.0195761 v -0.0848944 0.0545812 0.00748601 v 0.00130039 -0.0290304 0.0240924 v 0.0115981 0.0488525 -0.00326856 v -0.12735 -0.033775 0.0174498 v -0.137437 0.00885669 0.00472708 v -0.171651 0.0863529 -0.0459706 v -0.154799 0.0739816 -0.0121253 v -0.236794 0.11208 -0.127719 v -0.00829438 -0.198556 -0.0915369 v 0.00970021 -0.244807 -0.25275 v -0.00630865 -0.252961 -0.285629 v -0.126911 -0.230521 -0.328032 v -0.0404702 -0.290022 -0.341757 v -0.15805 -0.313658 -0.37764 v -0.083225 -0.350771 -0.392753 v -0.256054 -0.452518 -0.493463 v -0.20815 -0.500773 -0.534478 v -0.38785 -0.571943 -0.536727 v -0.35831 -0.604172 -0.591642 v -0.540699 -0.660106 -0.534829 v -0.543475 -0.680473 -0.592679 v -0.683214 -0.726338 -0.418321 v -0.724001 -0.750641 -0.408744 v -0.724388 -0.787808 -0.271782 v -0.748234 -0.790022 -0.2689 v -0.211313 -0.245001 -0.433381 v -0.302499 -0.393263 -0.526043 v -0.427301 -0.509964 -0.533318 v -0.554036 -0.612449 -0.514199 v -0.680245 -0.695516 -0.410888 v -0.737585 -0.772502 -0.255017 v -0.178171 -0.180192 -0.381313 v -0.188715 -0.170773 -0.417759 v -0.202053 -0.145064 -0.39212 v -0.206551 -0.151056 -0.425157 v -0.221031 -0.117808 -0.435455 v -0.164482 -0.136752 -0.357045 v -0.188293 -0.11888 -0.377025 v -0.176484 -0.109971 -0.401733 v -0.181826 -0.108793 -0.358328 v -0.109865 -0.184638 -0.285313 v -0.154623 -0.103557 -0.339982 v -0.202105 -0.071293 -0.404562 v -0.154992 -0.0832074 -0.364443 v -0.237673 -0.218747 -0.499807 v -0.233719 -0.194953 -0.539715 v -0.245194 -0.22676 -0.551506 v -0.263188 -0.209345 -0.57783 v -0.23089 -0.256071 -0.488666 v -0.233016 -0.250308 -0.535919 v -0.207043 -0.223298 -0.566162 v -0.206217 -0.240853 -0.557498 v -0.18462 -0.187748 -0.548993 v -0.212754 -0.192264 -0.556426 v -0.241556 -0.20678 -0.578357 v -0.20685 -0.173057 -0.491934 v -0.20866 -0.138597 -0.47705 v -0.218413 -0.113661 -0.525147 v -0.215232 -0.118546 -0.496538 v -0.224581 -0.051998 -0.457843 v -0.201227 -0.0994096 -0.483007 v -0.237444 -0.0798334 -0.476435 v -0.190437 -0.1364 -0.440147 v -0.238042 -0.0523847 -0.479932 v -0.225038 -0.0361825 -0.473184 v -0.204144 -0.026781 -0.448248 v -0.221506 -0.00962994 -0.477858 v -0.204899 -0.0453907 -0.494746 v -0.219309 -0.0796226 -0.49884 v -0.252188 -0.0474643 -0.521035 v -0.151654 -0.104471 -0.517538 v -0.186817 -0.100341 -0.495466 v -0.169595 -0.0330721 -0.360524 v -0.213686 0.0203142 -0.414912 v -0.201771 -0.0223878 -0.43129 v -0.22727 0.0430359 -0.42572 v -0.168734 -0.0770218 -0.383475 v -0.183689 -0.0212104 -0.453045 v -0.137332 -0.0663023 -0.501599 v -0.112677 -0.028714 -0.463185 v -0.295294 -0.356096 -0.576424 v -0.431079 -0.483569 -0.569009 v -0.567901 -0.587179 -0.534109 v -0.692089 -0.676326 -0.409816 v -0.255263 -0.307103 -0.551752 v -0.257512 -0.329192 -0.491811 v -0.271079 -0.273082 -0.567005 v -0.224423 -0.265631 -0.564756 v -0.246758 -0.275191 -0.500949 v -0.250712 -0.3106 -0.564299 v -0.247461 -0.264401 -0.533986 v -0.239676 -0.282202 -0.568868 v -0.745598 -0.785278 -0.25282 v -0.17058 -0.14835 -0.537219 v -0.179348 -0.114329 -0.518979 v -0.191597 -0.00715217 -0.30814 v -0.223983 0.0790953 -0.344287 v -0.260517 0.131884 -0.356869 v -0.214125 0.0328788 -0.389818 v -0.18383 0.0240396 -0.427231 v -0.253137 0.104137 -0.375637 v -0.27867 0.149861 -0.385531 v -0.218202 0.115418 -0.406548 v -0.113731 0.0165009 -0.454627 v -0.106632 0.064545 -0.41971 v -0.0471831 0.182318 0.00604504 v -0.0370084 0.130549 -0.00416479 v 0.0283977 0.118494 -0.0347767 v -0.0450743 0.109514 0.0105788 v -0.0674973 0.0732787 0.00590445 v -0.0687977 0.109936 0.020279 v -0.0988824 0.0630865 0.00678309 v -0.05669 0.128475 -0.0250062 v -0.0825396 0.0679893 -0.0156926 v -0.0641233 0.105279 -0.0112818 v -0.0997083 0.0442132 -0.00295226 v -0.0515236 0.26368 -0.0284329 v -0.0974063 0.409869 0.0412259 v 0.0925034 0.404755 -0.0309634 v 0.0899027 0.504077 -0.0140231 v -0.210681 0.101466 -0.0606263 v -0.165009 0.0900959 -0.0308931 v -0.230907 0.108987 -0.0835589 v -0.250554 0.145661 -0.116578 v -0.200893 0.125663 -0.036534 v -0.23762 0.0883387 -0.157453 v -0.243384 0.101887 -0.219081 v -0.228078 0.108495 -0.156838 v -0.242119 0.0460057 -0.217148 v -0.268724 0.124398 -0.177169 v -0.267652 0.106948 -0.200401 v -0.25869 0.0981092 -0.257196 v -0.259709 0.086968 -0.311461 v -0.245299 0.0941025 -0.28468 v -0.25695 0.14162 -0.257354 v -0.196306 0.118845 -0.202369 v -0.273732 0.14603 -0.312094 v -0.215056 0.115348 -0.267634 v -0.170527 0.115172 -0.243489 v -0.228342 0.113608 -0.289723 v -0.273556 0.141321 -0.210171 v -0.227094 0.121639 -0.194883 v -0.245387 0.132816 -0.1839 v -0.22669 0.12192 -0.242997 v -0.203037 0.127825 -0.0755457 v -0.162478 0.071293 -0.0233016 v -0.199311 0.0553193 -0.0644221 v -0.152181 0.114505 -0.0470777 v -0.147137 0.0883738 -0.0385548 v -0.02353 0.169859 -0.00704673 v -0.0356201 0.185991 -0.0167645 v -0.0239518 0.218184 -0.0281517 v 0.0821706 0.347187 -0.041015 v -0.0566197 0.318332 0.0103152 v -0.0683056 0.370277 0.0193301 v -0.0364461 0.218097 -0.0120901 v -0.043317 0.219098 -0.0370436 v -0.05307 0.172354 -0.0321056 v -0.0248304 0.275858 -0.0146382 v 0.0609602 0.245018 -0.0526834 v -0.0702914 0.389133 0.0130566 v -0.14104 0.178927 -0.0426493 v -0.111201 0.22256 -0.0572172 v -0.142305 0.331863 -0.0111939 v -0.191509 0.13213 -0.126981 v -0.171599 0.222419 -0.119566 v -0.176273 0.291973 -0.0724353 v -0.199294 0.174323 -0.243278 v -0.218009 0.268003 -0.221312 v -0.197079 0.350789 -0.0400134 v -0.255931 0.328243 -0.16898 v -0.265297 0.32204 -0.262398 v -0.295716 0.36794 -0.250501 v -0.238815 0.310301 -0.361508 v -0.164552 0.174815 -0.262345 v -0.192721 0.227779 -0.324852 v -0.225512 0.270411 -0.334271 v -0.206534 0.262538 -0.357906 v -0.28642 0.334306 -0.245914 v -0.287175 0.361561 -0.288827 v -0.101905 0.20634 -0.336221 v -0.211928 0.115524 -0.296419 v -0.0737884 0.120304 -0.331195 v -0.224686 0.145942 -0.351773 v -0.153921 0.104348 -0.353601 v -0.154729 0.134432 -0.300109 v -0.0861421 0.470161 0.0632095 v -0.0696236 0.420026 0.0354971 v -0.116174 0.456788 0.065986 v -0.099269 0.427459 0.0370084 v -0.129213 0.440973 0.0426493 v -0.0952799 0.419798 0.0239693 v -0.104365 0.403015 0.0261659 v -0.0480969 0.358345 0.0105964 v -0.0635434 0.366148 0.00333882 v -0.0767054 0.349594 -0.00279411 v -0.216937 0.325537 -0.317963 v -0.262064 0.35339 -0.277862 v -0.251415 0.353232 -0.298896 v -0.214248 0.287474 -0.268988 v -0.135996 0.272449 -0.331441 v -0.185991 0.352002 -0.366183 v -0.177802 0.298334 -0.299353 v -0.113152 0.272098 -0.350912 v -0.134292 0.34789 -0.371683 v -0.158419 0.209749 -0.320775 v -0.144818 0.381788 -0.391628 v -0.21887 0.291006 -0.323709 v -0.271307 0.36982 -0.273662 v -0.261308 0.383703 -0.295646 v -0.297684 0.401206 -0.397586 v -0.303553 0.405441 -0.369926 v -0.300302 0.425087 -0.348329 v -0.40841 0.456244 -0.431378 v -0.39697 0.473869 -0.44389 v -0.407022 0.47292 -0.407338 v -0.474027 0.488859 -0.474607 v -0.452114 0.485819 -0.465645 v -0.470091 0.486293 -0.452764 v -0.444593 0.465276 -0.442396 v -0.434576 0.480617 -0.454891 v -0.44758 0.479703 -0.426159 v -0.460567 0.471971 -0.460742 v -0.294855 0.443574 -0.346009 v -0.3969 0.493867 -0.432872 v -0.403051 0.493762 -0.411802 v -0.461586 0.496538 -0.458528 v -0.439356 0.495923 -0.443749 v -0.444435 0.494289 -0.432222 v -0.270253 0.463361 -0.397058 v -0.258426 0.427653 -0.419183 v -0.285242 0.464714 -0.364232 v -0.250185 0.415 -0.287913 v -0.163884 0.398587 -0.370242 v -0.219731 0.462746 -0.353495 v -0.188961 0.445067 -0.35411 v -0.361104 0.568288 -0.308245 v -0.354374 0.574403 -0.367589 v -0.300671 0.599989 -0.392384 v -0.312603 0.471637 -0.212051 v -0.386058 0.625136 -0.27078 v -0.440551 0.614206 -0.365181 v -0.428162 0.646558 -0.388518 v -0.435631 0.65566 -0.290444 v -0.412997 0.68636 -0.368063 v -0.319984 0.679524 -0.371999 v -0.342003 0.658823 -0.283327 v -0.419024 0.697079 -0.32218 v -0.347538 0.705813 -0.334007 v -0.150898 0.625716 -0.381893 v -0.217552 0.679577 -0.296735 v -0.172671 0.673479 -0.332232 v -0.117756 0.687766 -0.318455 v -0.274593 0.646874 -0.386726 v -0.281798 0.677837 -0.329421 v -0.351615 0.679278 -0.32863 v -0.320616 0.659386 -0.380259 v -0.148614 0.556022 -0.396496 v -0.315696 0.684708 -0.327171 v -0.223491 0.65812 -0.237216 v -0.345218 0.671054 -0.308368 v -0.278635 0.65436 -0.281763 v -0.268724 0.631164 -0.229431 v -0.307103 0.626401 -0.26108 v -0.190244 0.68701 -0.250308 v -0.138263 0.694531 -0.272678 v -0.22191 0.704495 -0.291621 v -0.450023 0.628686 -0.313236 v -0.43013 0.694039 -0.294784 v -0.524321 0.683882 -0.367483 v -0.508716 0.697167 -0.386058 v -0.526465 0.725723 -0.31835 v -0.496134 0.739325 -0.369979 v -0.524426 0.689189 -0.338225 v -0.511616 0.739975 -0.314009 v -0.56878 0.72973 -0.383703 v -0.572558 0.782993 -0.358873 v -0.575177 0.73994 -0.349489 v -0.573753 0.771307 -0.338277 v -0.503356 0.754279 -0.335097 v -0.573753 0.768566 -0.379872 v -0.6435 0.751379 -0.372492 v -0.642481 0.760517 -0.362932 v -0.631621 0.77621 -0.375321 v -0.63633 0.76296 -0.380997 v -0.659632 0.761062 -0.377588 v -0.185622 0.524198 -0.384898 v -0.195972 0.482902 -0.368678 v -0.180772 0.441324 -0.45837 v -0.208748 0.450216 -0.438776 v -0.174727 0.536727 -0.443257 v -0.207518 0.508523 -0.428971 v -0.219696 0.522564 -0.519102 v -0.21358 0.496345 -0.511967 v -0.22379 0.498998 -0.504956 v -0.212262 0.529558 -0.506203 v -0.224054 0.519822 -0.500984 v 0.0923629 0.459284 -0.0198397 v -0.0165888 0.480195 0.0423329 v -0.0253752 0.461832 0.0294521 v 0.0173268 0.396935 0.00817136 v 0.022792 0.347169 -0.0113345 v 0.0708713 0.278617 -0.0503638 v -0.0942256 0.492742 0.0723122 v -0.144501 0.538379 0.0842617 v -0.121007 0.498225 0.0578322 v -0.17738 0.700137 -0.291727 v -0.197835 0.689418 -0.27085 v -0.094454 0.718676 -0.274576 v -0.18643 0.712456 -0.219748 v -0.132482 0.742681 -0.20374 v -0.0662145 0.766668 -0.220293 v -0.122079 0.76593 -0.171388 v -0.022792 0.82566 -0.153393 v -0.202527 0.718676 -0.194039 v -0.172425 0.7327 -0.191245 v -0.190349 0.696253 -0.212913 v -0.191298 0.731575 -0.162039 v -0.199786 0.700418 -0.184655 v -0.187889 0.720293 -0.151794 v -0.168893 0.765912 -0.128194 v -0.118582 0.757196 -0.141215 v -0.256001 0.688855 -0.215285 v -0.252697 0.664183 -0.237655 v -0.299336 0.51694 -0.317787 v -0.33109 0.484132 -0.307191 v -0.353232 0.496169 -0.348223 v -0.305767 0.472376 -0.350227 v -0.291217 0.558395 -0.371753 v -0.192616 0.558518 -0.389836 v -0.173813 0.725266 -0.155959 v -0.1519 0.741662 -0.109338 v -0.171072 0.73827 -0.132587 v -0.101958 0.792395 -0.147788 v -0.0465856 0.798352 -0.190982 v -0.114364 0.756071 -0.102959 v -0.118177 0.801937 -0.175553 v -0.07479 0.79909 -0.172794 v -0.109004 0.810284 -0.162285 v -0.0652304 0.809756 -0.153991 v -0.0105789 0.847556 -0.114452 v -0.0680596 0.827646 -0.11881 v -0.0867747 0.811689 -0.137051 v -0.0922398 0.784522 -0.0962289 v -0.119864 0.774751 -0.162531 v -0.111921 0.777985 -0.16826 v -0.214582 0.714283 -0.13814 v -0.219661 0.734 -0.107862 v -0.202914 0.686272 -0.107229 v -0.233279 0.688785 -0.156662 v -0.194514 0.694391 -0.0893579 v -0.230028 0.679384 -0.12967 v -0.233016 0.704812 -0.150951 v -0.241205 0.703089 -0.115735 v -0.219327 0.697378 -0.120075 v -0.191702 0.721646 -0.109075 v -0.160897 0.730977 -0.12113 v -0.196763 0.675412 -0.0858961 v -0.233033 0.661213 -0.112413 v -0.0795698 0.802552 -0.103223 v -0.0903596 0.821706 -0.135961 v -0.0982849 0.783924 -0.165132 v -0.103012 0.778863 -0.108723 v -0.0882508 0.757337 -0.119337 v -0.0494324 0.624433 -0.0333006 v -0.158525 0.619741 -0.0540541 v -0.0821179 0.708836 -0.110832 v -0.153165 0.686202 -0.0551963 v -0.0980037 0.604699 -0.0436334 v -0.0140407 0.523776 0.0235476 v -0.112923 0.520789 0.0663375 v -0.188521 0.609057 -0.033652 v -0.150652 0.559062 0.0299968 v -0.222982 0.630021 0.0142516 v -0.202703 0.545865 0.0467613 v -0.174129 0.52165 0.0595192 v -0.186993 0.649211 -0.0749482 v -0.211805 0.605964 -0.0708713 v -0.226531 0.680051 -0.0760728 v -0.236443 0.616016 -0.0921168 v -0.332777 0.47401 -0.181334 v -0.361596 0.500176 -0.114786 v -0.383158 0.42108 -0.117474 v -0.276632 0.657435 -0.172073 v -0.331793 0.511493 -0.219977 v -0.39683 0.498295 -0.216146 v -0.256599 0.664658 -0.123766 v -0.271869 0.626226 -0.129916 v -0.317717 0.629442 -0.1574 v -0.315134 0.531192 -0.134397 v -0.332689 0.496116 -0.155783 v -0.355938 0.566777 -0.148174 v -0.329842 0.531139 -0.115998 v -0.348276 0.502003 -0.126577 v -0.32081 0.521228 -0.148912 v -0.39495 0.413225 0.045953 v -0.403332 0.363143 -0.0164833 v -0.399817 0.398991 -0.0650371 v -0.392489 0.450181 -0.00407692 v -0.346308 0.43491 0.123959 v -0.367518 0.474801 0.0462341 v -0.332373 0.535427 -0.0382912 v -0.28171 0.441078 0.132236 v -0.227849 0.465768 0.117439 v -0.427459 0.387095 0.09108 v -0.435789 0.338453 0.0306997 v -0.381436 0.404456 0.137543 v -0.445981 0.345218 0.129793 v -0.40103 0.37815 0.163304 v -0.343022 0.395828 0.198415 v -0.247057 0.387112 0.149193 v -0.301111 0.351193 0.208554 v -0.502935 0.347099 0.210927 v -0.414561 0.369135 0.26528 v -0.472393 0.369047 0.222507 v -0.525076 0.289671 0.226672 v -0.448547 0.317436 0.0624011 v -0.445647 0.289442 0.112765 v -0.417601 0.287597 0.0317717 v -0.29619 0.500808 0.109813 v -0.37685 0.487435 -0.0773381 v -0.271483 0.550118 0.0389062 v -0.258215 0.567093 0.00386601 v -0.136998 0.472797 0.0573753 v -0.180543 0.516308 0.092644 v -0.501213 0.341177 0.366253 v -0.390398 0.318877 0.236513 v -0.372615 0.303729 0.239026 v -0.359189 0.311127 0.233859 v -0.39017 0.326925 0.273469 v -0.403455 0.34926 0.222015 v -0.507029 0.287281 0.188065 v -0.476048 0.350719 0.460285 v -0.506801 0.306312 0.424876 v -0.502144 0.329262 0.430622 v -0.513303 0.304643 0.4609 v -0.509595 0.322251 0.46554 v -0.506063 0.31719 0.482867 v -0.510579 0.288757 0.368063 v -0.525006 0.295276 0.294152 v -0.514884 0.339683 0.306224 v -0.464573 0.372861 0.314378 v -0.525375 0.258321 0.270218 v -0.509138 0.244122 0.192212 v -0.5223 0.242857 0.214107 v -0.42043 0.246863 0.106316 v -0.508576 0.232155 0.282606 v -0.497733 0.22024 0.196499 v -0.510807 0.219362 0.221734 v -0.505869 0.288423 0.468931 v -0.497188 0.29141 0.425948 v -0.495291 0.25876 0.376164 v -0.477788 0.219239 0.165835 v -0.49327 0.246723 0.15921 v -0.267037 0.352072 -0.149562 v -0.309581 0.383808 -0.237778 v -0.241785 0.297719 0.0423857 v -0.302042 0.39683 -0.224282 v -0.285277 0.271711 -0.000948948 v -0.30698 0.390785 -0.281306 v -0.316698 0.406249 -0.27512 v -0.2731 0.385249 -0.293677 v -0.263452 0.412821 -0.286367 v -0.286156 0.401961 -0.303887 v -0.314079 0.416002 -0.307226 v -0.318156 0.421854 -0.302042 v -0.280621 0.424296 -0.28403 v -0.311935 0.428074 -0.302042 v -0.304098 0.422187 -0.306839 v -0.307331 0.457052 -0.262398 v -0.370822 0.327382 -0.0895688 v -0.343953 0.366218 -0.148139 v -0.300671 0.491583 -0.277616 v -0.335659 0.290637 -0.0737357 v -0.320476 0.46496 -0.312111 v -0.338066 0.474344 -0.340579 v -0.297455 0.435719 -0.267617 v -0.256634 0.516343 -0.333726 v -0.263557 0.467613 -0.353636 v -0.267793 0.493428 -0.353425 v -0.301357 0.455242 -0.326503 v -0.334429 0.500176 -0.33768 v -0.309809 0.493182 -0.353495 v -0.421098 0.275489 0.0633149 v -0.386567 0.326714 -0.0402945 v -0.335378 0.285875 -0.0232489 v -0.203247 0.386761 0.0166415 v -0.149896 0.414297 0.0263241 v -0.167258 0.475011 0.0974941 v -0.148438 0.479405 0.0743682 v -0.35274 0.258619 0.207799 v -0.291727 0.300443 0.118898 v -0.249025 0.347099 0.0987418 v -0.178312 0.408604 -0.0285207 v -0.208185 0.421116 0.0755808 v -0.363195 0.231136 0.119407 v -0.381454 0.243911 0.0394686 v -0.444241 0.202755 0.242646 v -0.429023 0.199294 0.184251 v -0.465821 0.260869 0.409061 v -0.465557 0.22973 0.327733 v -0.415211 0.276596 0.412751 v -0.393597 0.231311 0.322954 v -0.456859 0.366745 0.377236 v -0.379275 0.297403 0.336239 v -0.404 0.318508 0.418778 v -0.410941 0.343268 0.465909 v -0.372035 0.293062 0.278196 v -0.364689 0.249991 0.295505 v -0.381225 0.262714 0.347626 v -0.322198 0.264489 0.169402 v -0.3203 0.246318 0.0940498 v -0.378115 0.221892 0.213018 v -0.356131 0.254033 0.246986 v -0.470144 0.325098 0.522862 v -0.395406 0.31784 0.498172 v -0.395582 0.311356 0.464889 v -0.529013 0.265543 0.56031 v -0.496521 0.275208 0.59101 v -0.453555 0.274734 0.607458 v -0.422012 0.276386 0.605578 v -0.545127 0.249148 0.535286 v -0.449671 0.259937 0.639388 v -0.425755 0.262978 0.637648 v -0.453432 0.243595 0.685306 v -0.43918 0.246811 0.686764 v -0.458844 0.243296 0.700418 v -0.441359 0.248445 0.704003 v -0.461111 0.233473 0.724071 v -0.446245 0.234597 0.726356 v -0.46684 0.212385 0.754261 v -0.467807 0.186237 0.773363 v -0.442291 0.188012 0.777001 v -0.454803 0.197378 0.773047 v -0.446543 0.214723 0.759059 v -0.37337 0.244649 0.570081 v -0.382438 0.288862 0.488543 v -0.416617 0.235072 0.660212 v -0.429603 0.229765 0.707535 v -0.437212 0.17499 0.772731 v -0.433434 0.201701 0.754701 v -0.465382 0.163761 0.788089 v -0.444066 0.169226 0.791094 v -0.457614 0.177345 0.796067 v -0.455699 0.149299 0.809458 v -0.385355 0.257214 0.483657 v -0.438987 0.241152 0.490282 v -0.41428 0.220363 0.525305 v -0.393983 0.231838 0.499772 v -0.421625 0.273398 0.459706 v -0.195111 0.17195 -0.13148 v -0.221857 0.217675 -0.229484 v -0.224985 0.237954 -0.304274 v -0.218975 0.267494 -0.169472 v -0.216445 0.599743 -0.0423681 v -0.249605 0.611078 -0.0264823 v -0.246072 0.579904 -0.0156047 v -0.222595 0.611429 -0.0137947 v -0.304256 0.549028 -0.0794644 v -0.334798 0.551559 -0.0657927 v -0.307472 0.551383 -0.0465153 v -0.289021 0.567603 -0.102098 v -0.29243 0.56096 -0.0901838 v -0.269251 0.558887 -0.0647735 v -0.25876 0.58015 -0.0920817 v -0.279391 0.611588 -0.0779356 v -0.273152 0.576776 -0.102801 v -0.297561 0.552402 -0.12496 v -0.320775 0.592855 -0.0986539 v -0.326837 0.535023 -0.101132 v -0.276948 0.558553 -0.0438091 v -0.299564 0.5724 -0.066109 v -0.230362 0.584156 -0.0659333 v -0.242593 0.581556 -0.0777423 v -0.228728 0.610463 -0.0642639 v -0.233438 0.59825 -0.0768109 v -0.257635 0.570063 -0.044758 v -0.272713 0.570133 -0.0577444 v -0.255369 0.562401 -0.0579904 v -0.247812 0.568552 -0.0716796 v -0.261466 0.562594 -0.0362001 v -0.32877 0.535163 -0.0792535 v -0.470899 0.192792 0.742171 v -0.471145 0.174586 0.765895 v -0.463132 0.2243 0.646997 v -0.468 0.226215 0.696974 v -0.4415 0.16334 0.76419 v -0.438056 0.191192 0.738885 v -0.46264 0.184726 0.733262 v -0.46257 0.162039 0.760974 v -0.444698 0.163533 0.787703 v -0.463554 0.161196 0.785207 v -0.450884 0.150898 0.803694 v -0.459003 0.147823 0.801163 v -0.432099 0.208607 0.696271 v -0.425474 0.212561 0.647243 v -0.459284 0.201719 0.689804 v -0.454363 0.142041 0.808228 v -0.3413 0.250958 0.508997 v -0.347608 0.255158 0.535497 v -0.344744 0.220873 0.540681 v -0.340702 0.215179 0.51557 v -0.339788 0.207184 0.543915 v -0.334727 0.203265 0.518118 v -0.333937 0.192387 0.547271 v -0.329825 0.18694 0.519928 v -0.314202 0.176537 0.534865 v -0.309756 0.176343 0.553826 v -0.30872 0.165888 0.522405 v -0.367571 0.23762 0.495044 v -0.347204 0.191737 0.506976 v -0.314027 0.149158 0.516975 v -0.281728 0.160493 0.547042 v -0.29004 0.156785 0.559484 v -0.287685 0.154465 0.530981 v -0.266106 0.136717 0.553966 v -0.272467 0.130513 0.559941 v -0.271588 0.128633 0.545162 v -0.352986 0.197027 0.551928 v -0.321671 0.166995 0.561698 v -0.328946 0.144378 0.533599 v -0.329913 0.151601 0.555882 v -0.311479 0.14002 0.537167 v -0.312902 0.145872 0.557287 v -0.291252 0.150125 0.53193 v -0.297596 0.152585 0.560995 v -0.364988 0.1839 0.546357 v -0.364443 0.178645 0.521316 v -0.389098 0.217007 0.557797 v -0.265596 0.126419 0.553035 v -0.401311 0.24305 0.616209 v -0.456472 0.223034 0.53186 v -0.407005 0.219362 0.605578 v -0.428812 0.21105 0.570239 v -0.484782 0.249886 0.629547 v -0.501388 0.247215 0.62185 v -0.512002 0.199048 0.670843 v -0.497101 0.202404 0.678136 v -0.518223 0.179682 0.684655 v -0.498524 0.184954 0.695305 v -0.513742 0.153727 0.686747 v -0.492655 0.152339 0.696675 v -0.505114 0.106562 0.691034 v -0.489702 0.109022 0.701262 v -0.49146 0.0842793 0.696974 v -0.498594 0.0740871 0.680754 v -0.472745 0.0792535 0.694707 v -0.468896 0.221295 0.643184 v -0.478913 0.169789 0.684462 v -0.476857 0.112396 0.694057 v -0.461305 0.0847362 0.683074 v -0.481742 0.0503462 0.689716 v -0.483482 0.0493621 0.669525 v -0.465733 0.0555653 0.684198 v -0.466594 0.0331951 0.668629 v -0.469564 0.0414192 0.660458 v -0.462535 0.0429129 0.668032 v -0.517169 0.166186 0.667979 v -0.507152 0.109848 0.668524 v -0.495783 0.0758795 0.664991 v -0.50854 0.214195 0.619091 v -0.461516 0.0807823 0.667944 v -0.469177 0.118986 0.676133 v -0.491846 0.114803 0.656978 v -0.481812 0.0766703 0.653534 v -0.465136 0.0619618 0.679278 v -0.480354 0.0565318 0.664781 v -0.501898 0.157101 0.654061 v -0.47575 0.165062 0.668734 v -0.457544 0.197536 0.633764 v -0.461832 0.0351808 0.660669 v -0.521843 0.23878 0.604822 v -0.535708 0.235441 0.591115 v -0.545373 0.173848 0.626894 v -0.531561 0.178681 0.634169 v -0.547605 0.158981 0.631129 v -0.533265 0.164534 0.643078 v -0.535866 0.131515 0.627245 v -0.523723 0.136154 0.637472 v -0.51267 0.0994974 0.608776 v -0.499649 0.103276 0.616789 v -0.497206 0.0910976 0.602836 v -0.498454 0.0871964 0.588919 v -0.479756 0.0949636 0.598496 v -0.511633 0.210452 0.617193 v -0.512863 0.154641 0.633044 v -0.48791 0.115102 0.608583 v -0.471268 0.10194 0.590026 v -0.479176 0.076108 0.584842 v -0.482445 0.0781815 0.570573 v -0.466278 0.0845956 0.584209 v -0.455014 0.072857 0.550979 v -0.543493 0.145732 0.618125 v -0.514884 0.105911 0.59036 v -0.499016 0.0927846 0.576758 v -0.536183 0.195322 0.585281 v -0.472586 0.109725 0.578217 v -0.493428 0.127139 0.601413 v -0.509208 0.125716 0.590184 v -0.4903 0.102081 0.568288 v -0.465997 0.090342 0.577391 v -0.482199 0.0845605 0.567866 v -0.529663 0.153305 0.603926 v -0.509366 0.155397 0.621253 v -0.523407 0.185727 0.575036 v -0.493358 0.190015 0.606825 v -0.512319 0.245721 0.489158 v -0.525762 0.224757 0.51926 v -0.482339 0.268232 0.453801 v -0.519998 0.277704 0.493621 v -0.542175 0.230907 0.578305 v -0.553667 0.225161 0.564053 v -0.567128 0.187326 0.577795 v -0.558342 0.186676 0.585703 v -0.573103 0.16232 0.583172 v -0.562788 0.163849 0.592574 v -0.56516 0.146803 0.574122 v -0.557551 0.144501 0.584209 v -0.550856 0.125857 0.56205 v -0.542702 0.126068 0.573121 v -0.535761 0.121639 0.561558 v -0.530788 0.128457 0.544055 v -0.52295 0.125171 0.562963 v -0.537184 0.193618 0.581854 v -0.549432 0.168805 0.587073 v -0.536885 0.134713 0.576126 v -0.51998 0.132113 0.564457 v -0.505641 0.12055 0.539398 v -0.508962 0.127491 0.535163 v -0.503567 0.128826 0.54887 v -0.484958 0.135153 0.529733 v -0.566425 0.169841 0.563157 v -0.548782 0.139054 0.549397 v -0.530471 0.137121 0.540224 v -0.549889 0.211208 0.548132 v -0.520754 0.139212 0.561575 v -0.537096 0.140688 0.572137 v -0.543686 0.146188 0.552701 v -0.523723 0.147612 0.543159 v -0.503005 0.133975 0.548729 v -0.509085 0.131181 0.534882 v -0.553316 0.166555 0.558412 v -0.54228 0.167276 0.58073 v -0.53685 0.196183 0.541577 v -0.388834 0.216286 0.528855 v -0.0103153 0.638052 -0.0238288 v -0.0345658 0.629775 -0.019049 v 0.00405933 0.557569 -0.00878644 v 0.0426317 0.577356 -0.0394862 v 0.0241099 0.566988 -0.0196816 v 0.0076969 0.631867 0.00458649 v 0.0390469 0.596791 -0.0216498 v 0.00486768 0.58514 -0.0238639 v -0.0266404 0.585053 -0.0152181 v -0.0916424 0.719766 -0.0684989 v -0.0402945 0.674287 -0.0183461 v -0.103855 0.744473 -0.0815204 v -0.0429129 0.848452 -0.0981092 v -0.092398 0.884441 -0.0697291 v -0.125101 0.830369 -0.0901663 v -0.108389 0.790391 -0.0504165 v -0.0952272 0.788318 -0.00485012 v -0.115524 0.871068 -0.115471 v -0.0911679 0.938144 -0.114979 v -0.0952272 0.926387 -0.137261 v -0.107458 0.964485 -0.149984 v -0.109584 0.95359 -0.159368 v -0.0954029 0.825888 -0.120778 v -0.0910625 0.856799 -0.136928 v -0.078779 0.917917 -0.151337 v -0.0947528 0.955014 -0.166274 v -0.052947 0.868327 -0.112958 v -0.0526658 0.925157 -0.137191 v -0.0896039 0.964643 -0.158894 v -0.0641057 0.949953 -0.146927 v -0.097582 0.969968 -0.151285 v -0.0716796 0.957878 -0.132165 v -0.0365691 0.84977 -0.047148 v -0.0555302 0.884968 -0.0781816 v -0.0588339 0.934506 -0.1141 v -0.0658454 0.862739 -0.127298 v -0.0327733 0.832935 0.00599231 v -0.0683056 0.893034 -0.0646856 v -0.0804485 0.947018 -0.113644 v -0.104031 0.965065 -0.165343 v -0.0224757 0.610234 0.00912029 v -0.0561277 0.648034 0.0549327 v -0.0191193 0.588321 0.0233367 v -0.0485186 0.620251 0.0886198 v -0.0482726 0.623309 0.115998 v -0.0187678 0.599937 0.0937335 v -0.0111939 0.615418 0.124381 v -0.0447756 0.661125 0.110357 v -0.0671107 0.660106 0.104963 v -0.0315257 0.609813 0.071293 v 0.00829438 0.549204 0.0310863 v 0.00829438 0.640758 0.159017 v -0.00133554 0.652778 0.135381 v -0.00307525 0.638421 0.128949 v 0.000843496 0.625013 0.146575 v -0.00405933 0.586089 0.126507 v 0.0165712 0.584402 0.148438 v 0.012301 0.563139 0.116912 v 0.0242681 0.552736 0.138878 v -0.0181703 0.606052 0.112361 v -0.0501529 0.617685 0.105665 v -0.0705549 0.653587 0.0789723 v -0.0394159 0.614259 0.108108 v -0.0376762 0.619654 0.117105 v -0.0309809 0.634626 0.116315 v -0.0120198 0.629986 0.123519 v 0.00490282 0.650019 0.144993 v 0.0281341 0.654096 0.164095 v 0.0247953 0.667065 0.155414 v 0.00774962 0.607616 0.146188 v 0.0350051 0.632148 0.162514 v 0.0241275 0.639616 0.163269 v 0.0169754 0.648455 0.164447 v 0.0116332 0.659175 0.155151 v 0.0440727 0.604523 0.154764 v 0.0376059 0.606843 0.15378 v 0.0292588 0.630918 0.162496 v 0.0313675 0.643763 0.16334 v -0.000984079 0.652128 0.148297 v 0.00660739 0.661266 0.158823 v -0.0127755 0.658103 0.1435 v 0.00296981 0.685341 0.155115 v -0.0103328 0.673725 0.153516 v -0.0257091 0.665835 0.126595 v -0.0210171 0.705778 0.144431 v -0.029663 0.683408 0.144045 v -0.0126173 0.723966 0.131761 v -0.106333 0.734756 -0.0590096 v -0.1128 0.754437 -0.00653711 v -0.0787966 0.707061 0.114751 v 0.0330545 0.585211 0.153288 v 0.0272555 0.599972 0.153182 v 0.059115 0.557112 0.14835 v 0.050434 0.58384 0.154606 v 0.012547 0.636137 0.160159 v 0.00590447 0.623168 0.153745 v 0.0100868 0.612203 0.152216 v 0.014111 0.610234 0.148807 v 0.0298211 0.620919 0.146874 v 0.014234 0.613046 0.149439 v 0.0127755 0.626911 0.149492 v 0.0188205 0.613767 0.151214 v 0.0178716 0.633782 0.149844 v 0.0405933 0.598707 0.154307 v -0.120761 0.744948 0.0342846 v -0.181984 0.660475 0.0333181 v -0.162689 0.638931 -0.042825 v -0.215812 0.575581 0.0540716 v -0.178856 0.511844 0.0236355 v -0.200981 0.54156 0.0800619 v -0.135715 0.517749 0.0859312 v -0.165958 0.54047 0.115787 v -0.0240396 0.530735 0.175166 v -0.0771272 0.523372 0.148016 v -0.0928022 0.541525 0.164482 v -0.12062 0.656592 0.0797455 v -0.104875 0.687379 0.0964046 v -0.143974 0.593382 0.0891119 v -0.126155 0.710136 0.0755105 v -0.0166591 0.53671 0.170421 v -0.0740695 0.562841 0.150582 v -0.142252 0.814308 -0.0267283 v -0.170562 0.813236 0.0110709 v -0.130865 0.792307 0.0589217 v -0.174639 0.808491 -0.0442309 v -0.196113 0.814607 -0.0249886 v -0.21293 0.783485 -0.0637719 v -0.103416 0.844709 0.0578498 v -0.158683 0.850912 0.00551786 v -0.188328 0.840544 -0.0316136 v -0.206832 0.803852 -0.0627878 v -0.129688 0.845078 -0.0156047 v -0.0665483 0.818912 0.00741572 v -0.121762 0.832021 -0.0222297 v -0.162215 0.841142 -0.0418234 v -0.194162 0.795276 -0.0576214 v -0.208045 0.800706 -0.0498366 v -0.0959126 0.758567 0.0898851 v -0.0675851 0.843075 0.0246195 v -0.0274488 0.815063 0.0534566 v -0.077918 0.82942 0.0770042 v -0.0649316 0.749359 0.111447 v -0.101325 0.762995 0.0454258 v -0.0159561 0.854989 -0.072119 v -0.0170808 0.841458 -0.00147615 v -0.0364461 0.783292 0.0993393 v -0.0281693 0.75825 0.120725 v -0.0181527 0.767669 0.117545 v -0.0282747 0.799986 0.0745264 v -0.026904 0.792166 0.0829438 v -0.0282923 0.781218 0.102256 v -0.0383615 0.830422 0.0836116 v -0.0465856 0.861508 0.0766527 v -0.0328788 0.813078 0.110129 v -0.0438091 0.854075 0.0968263 v -0.0117914 0.656328 0.133571 v -0.0192598 0.641848 0.131462 v -0.0913612 0.64473 -0.0213159 v -0.0823288 0.621657 0.0387657 v -0.176607 0.536112 0.00196813 v -0.116262 0.556813 0.037026 v -0.139581 0.586511 -0.015306 v -0.103961 0.538326 0.0664078 v -0.0602221 0.534583 0.120022 v -0.0206305 0.520033 0.164868 v -0.0187854 0.525902 0.156082 v -0.131814 0.576618 0.104576 v -0.0118617 0.526236 0.169139 v 0.0568481 0.578094 -0.0518223 v 0.0632095 0.595544 -0.0297157 v 0.0492391 0.583787 0.00488523 v 0.019418 0.53671 0.0464274 v 0.0210347 0.533459 0.0674621 v 0.0300496 0.528503 0.0214916 v 0.0110885 0.550627 0.0621727 v 0.020982 0.540945 0.0900784 v 0.0417179 0.529276 0.106948 v 0.0491337 0.519014 0.0846835 v 0.0306646 0.519611 0.0811162 v 0.0514884 0.507029 0.0627877 v 0.0406811 0.510614 0.035585 v 0.0437739 0.505325 0.0363406 v 0.0385548 0.509823 0.0614698 v 0.0329315 0.521246 0.0456015 v 0.0592908 0.505729 0.0730679 v 0.0708186 0.489052 0.0519629 v 0.0542649 0.51035 0.0526658 v 0.0745088 0.496292 0.0385372 v 0.0665308 0.547886 0.0225459 v 0.0700453 0.518135 0.0338804 v 0.0848592 0.483815 0.0301726 v -0.419446 0.356096 0.403086 v -0.413717 0.363371 0.323393 v 0.0299793 -0.116772 -0.00943663 v 0.0278881 -0.117035 0.0023196 v 0.0328261 -0.174323 -0.0231435 v 0.0351457 -0.176607 -0.0447756 v 0.0457597 -0.00630867 0.0128809 v 0.0517872 -0.00905004 0.00576388 v 0.107651 0.0463044 -0.031596 v 0.102169 0.0571117 -0.0239869 v 0.0152181 -0.208045 -0.0943662 v 0.0278354 -0.19954 -0.0988824 v 0.0328788 -0.19309 -0.102608 v 0.00843496 -0.221101 -0.18752 v 0.0369733 -0.196236 -0.178874 v 0.114382 0.167241 -0.0716093 v 0.106527 0.129301 -0.0596071 v 0.144027 0.178364 -0.0871964 v 0.10925 0.109321 -0.0409272 v 0.0984782 0.0749657 -0.0309282 v 0.13438 0.109619 -0.0477981 v 0.12055 0.0655643 -0.0350227 v 0.108161 0.105015 -0.0648438 v 0.105648 0.127157 -0.085527 v 0.0997259 0.0685692 -0.0509964 v 0.113644 0.169332 -0.10918 v 0.119443 0.18267 -0.0928022 v 0.172214 0.545127 -0.0801146 v 0.192862 0.504358 -0.0835765 v 0.225249 0.599919 -0.183267 v 0.113907 0.214002 -0.10324 v 0.140038 0.264436 -0.121182 v 0.131867 0.338962 -0.0827681 v 0.159649 0.400169 -0.0818543 v 0.179911 0.300531 -0.144572 v 0.201139 0.358539 -0.155203 v 0.181123 0.34137 -0.139441 v 0.134274 0.213106 -0.104857 v 0.116666 0.214406 -0.123273 v 0.13742 0.254982 -0.142656 v 0.180139 0.331547 -0.170703 v 0.182424 0.350648 -0.157066 v 0.218149 0.459003 -0.139441 v 0.231645 0.475029 -0.169349 v 0.250431 0.527572 -0.192897 v 0.231645 0.542122 -0.17608 v 0.237427 0.455224 -0.162303 v 0.229062 0.448178 -0.176519 v 0.219942 0.462746 -0.168155 v 0.240748 0.503075 -0.204109 v 0.203827 0.402963 -0.158753 v 0.1852 0.490353 -0.0985485 v 0.234931 0.568183 -0.174129 v 0.229677 0.574263 -0.196394 v 0.240625 0.539574 -0.218307 v 0.0274663 0.802411 0.102309 v 0.0202263 0.814185 0.0757741 v -0.183496 0.644396 -0.0129336 v -0.209134 0.549766 0.0197167 v -0.198714 0.522599 0.0515587 v -0.0914491 0.62844 0.0662671 v -0.115383 0.576547 0.0599058 v -0.108161 0.563139 0.0778653 v -0.109637 0.603838 0.0616631 v -0.105718 0.58797 0.0298562 v 0.0795522 0.555671 0.0176783 v 0.0844024 0.502601 0.03439 v 0.0913788 0.482164 0.025094 v 0.319615 -0.279391 -0.0492391 v 0.26542 -0.323744 -0.0486416 v 0.245229 -0.168875 -0.011809 v 0.175711 -0.204601 -0.00776722 v 0.131093 -0.152427 0.0120725 v 0.349541 -0.256388 -0.0736126 v 0.28417 -0.142199 -0.0529821 v 0.173532 0.00755631 -0.0877412 v 0.368221 -0.35534 -0.0836819 v 0.133079 -0.0532984 0.0125997 v 0.156627 -0.00543002 -0.0297684 v 0.132323 -0.0923804 0.0181527 v 0.101993 -0.0188733 0.0320001 v 0.106439 -0.0508207 0.037887 v 0.149053 -0.193354 0.00110707 v 0.32682 -0.398939 -0.0634907 v 0.267968 -0.440604 -0.0848241 v 0.217007 -0.373809 -0.0685517 v 0.372439 -0.428092 -0.0628405 v 0.343936 -0.485028 -0.0888659 v 0.396496 -0.40038 -0.0800267 v 0.420834 -0.434436 -0.0314378 v 0.377394 -0.483394 -0.0817137 v 0.41906 -0.476822 -0.112906 v 0.400011 -0.46619 -0.0599234 v 0.428777 -0.419745 -0.08565 v 0.431097 -0.422328 -0.0587284 v 0.428197 -0.456015 -0.0710997 v 0.425157 -0.441149 -0.100745 v 0.424771 -0.407391 -0.100271 v 0.444118 -0.417408 -0.0785155 v 0.440586 -0.412171 -0.115014 v 0.413085 -0.36613 -0.130144 v 0.427881 -0.38908 -0.159966 v 0.382473 -0.23393 -0.155871 v 0.404685 -0.306558 -0.135838 v 0.307718 -0.187889 -0.250958 v 0.361104 -0.502987 -0.0829087 v 0.3788 -0.495835 -0.0797456 v 0.390205 -0.499139 -0.0882157 v 0.373405 -0.517169 -0.0846835 v 0.387481 -0.512863 -0.0898851 v 0.387956 -0.506414 -0.0679366 v 0.363705 -0.513162 -0.122377 v 0.315468 -0.493182 -0.0992866 v 0.397673 -0.495009 -0.103873 v 0.425491 -0.498014 -0.0964046 v 0.385355 -0.517292 -0.130162 v 0.40704 -0.519067 -0.148034 v 0.35824 -0.524989 -0.182213 v 0.431589 -0.424507 -0.180807 v 0.446825 -0.439321 -0.146874 v 0.431536 -0.467525 -0.145907 v 0.350508 -0.501722 -0.112941 v 0.352775 -0.514902 -0.100921 v 0.347134 -0.521456 -0.126103 v 0.308755 -0.512424 -0.148631 v 0.334815 -0.507556 -0.125751 v 0.253084 -0.494429 -0.153446 v 0.0683584 -0.169156 -0.319492 v 0.199188 -0.144045 -0.250554 v 0.104963 -0.0734018 -0.409623 v 0.31473 -0.122852 -0.14357 v 0.427881 -0.461305 -0.218132 v 0.442607 -0.461006 -0.172794 v 0.4095 -0.503005 -0.198696 v 0.431466 -0.442361 -0.146294 v 0.112923 -0.0907462 0.0221242 v 0.110428 -0.153253 0.0297859 v 0.118845 -0.198538 -0.00574633 v 0.111658 -0.154536 0.00688854 v 0.0916072 -0.0419112 0.0288546 v 0.093716 -0.0783397 0.0125821 v 0.140495 -0.2395 -0.0249359 v 0.151355 -0.217938 -0.267283 v 0.279162 -0.253611 -0.309071 v 0.201789 -0.0121956 -0.147208 v 0.1991 -0.0523144 -0.231715 v 0.108495 -0.165255 -0.268197 v 0.166714 -0.0962113 -0.275876 v 0.136945 -0.241152 -0.00766177 v 0.133431 -0.26289 -0.0405757 v 0.159298 -0.253418 -0.024233 v 0.144185 -0.25927 -0.0205427 v 0.181545 -0.274769 -0.0289425 v 0.159895 -0.277458 -0.0354972 v 0.409851 -0.294099 -0.240801 v 0.433592 -0.333058 -0.185938 v 0.432766 -0.361807 -0.239694 v 0.216374 -0.339244 -0.32863 v 0.255597 -0.383088 -0.322216 v 0.131937 -0.302657 -0.197273 v 0.184989 -0.41254 -0.23096 v 0.152884 -0.338664 -0.117387 v 0.173057 -0.376498 -0.130847 v 0.147524 -0.303659 -0.0683232 v 0.228675 -0.459829 -0.152444 v 0.235546 -0.466489 -0.216058 v 0.347556 -0.362703 -0.420694 v 0.242066 -0.403894 -0.407233 v 0.203019 -0.443662 -0.359294 v 0.307999 -0.418532 -0.501898 v 0.237796 -0.437089 -0.47763 v 0.277756 -0.436791 -0.542772 v 0.223052 -0.455576 -0.529329 v 0.283046 -0.366323 -0.410273 v 0.370928 -0.32761 -0.303061 v 0.34752 -0.466032 -0.493006 v 0.40776 -0.393122 -0.373265 v 0.33239 -0.475029 -0.5391 v 0.393544 -0.478456 -0.420922 v 0.38423 -0.416459 -0.432099 v 0.429445 -0.435947 -0.319299 v 0.410168 -0.494271 -0.323903 v 0.373388 -0.568727 -0.293045 v 0.301515 -0.529944 -0.2062 v 0.257723 -0.516975 -0.212473 v 0.251907 -0.542807 -0.286613 v 0.209398 -0.50963 -0.309247 v 0.197009 -0.478368 -0.447563 v 0.309721 -0.345271 -0.321917 v 0.198573 -0.380628 -0.287878 v 0.231698 -0.430605 -0.282483 v 0.200067 -0.495185 -0.519418 v 0.212684 -0.562805 -0.510667 v 0.387218 -0.520841 -0.402506 v 0.349928 -0.57291 -0.382297 v 0.22205 -0.53794 -0.388219 v 0.423541 -0.493551 -0.14712 v 0.305469 -0.553035 -0.288177 v 0.26238 -0.594788 -0.493481 v 0.273785 -0.569026 -0.380786 v 0.189541 -0.547218 -0.610674 v 0.216093 -0.59217 -0.660229 v 0.181141 -0.483692 -0.607599 v 0.293185 -0.57226 -0.675201 v 0.31791 -0.54091 -0.659122 v 0.252434 -0.589815 -0.674656 v 0.322163 -0.585228 -0.48248 v 0.352441 -0.541894 -0.517186 v 0.362018 -0.536358 -0.599427 v 0.277493 -0.500914 -0.672126 v 0.325098 -0.487295 -0.63271 v 0.197607 -0.521105 -0.656117 v 0.283116 -0.463062 -0.637701 v 0.227516 -0.518416 -0.671652 v 0.21822 -0.460039 -0.630514 v 0.322479 -0.683461 -0.487488 v 0.229958 -0.631181 -0.589534 v 0.287316 -0.705884 -0.494658 v 0.238551 -0.671054 -0.575757 v 0.266808 -0.701807 -0.595913 v 0.322426 -0.739377 -0.53866 v 0.304309 -0.703687 -0.60607 v 0.345341 -0.788089 -0.520262 v 0.302745 -0.741433 -0.516888 v 0.324272 -0.788089 -0.473817 v 0.334815 -0.771202 -0.465171 v 0.309932 -0.73089 -0.485854 v 0.338769 -0.717253 -0.480934 v 0.338927 -0.801708 -0.477718 v 0.35223 -0.799441 -0.501494 v 0.354058 -0.82761 -0.483218 v 0.34926 -0.812621 -0.465997 v 0.364795 -0.827013 -0.505114 v 0.366974 -0.826047 -0.484466 v 0.371701 -0.811672 -0.471427 v 0.308034 -0.760746 -0.499807 v 0.330123 -0.789583 -0.507047 v 0.269989 -0.718237 -0.563069 v 0.339033 -0.676185 -0.628633 v 0.377535 -0.639757 -0.613204 v 0.423505 -0.727762 -0.592029 v 0.401856 -0.620515 -0.559607 v 0.461797 -0.72553 -0.536569 v 0.513303 -0.800513 -0.446912 v 0.383035 -0.622852 -0.510069 v 0.448107 -0.729765 -0.477735 v 0.530296 -0.825572 -0.503884 v 0.376041 -0.738815 -0.609795 v 0.396707 -0.799494 -0.624504 v 0.412663 -0.743243 -0.456507 v 0.372597 -0.76289 -0.464257 v 0.478649 -0.807454 -0.416828 v 0.534478 -0.816434 -0.403859 v 0.507152 -0.819439 -0.384634 v 0.549678 -0.820353 -0.371841 v 0.522915 -0.823674 -0.355709 v 0.570379 -0.816487 -0.34991 v 0.528187 -0.818807 -0.326205 v 0.583489 -0.839648 -0.320616 v 0.54221 -0.842618 -0.302868 v 0.588374 -0.870646 -0.307191 v 0.613521 -0.919376 -0.279619 v 0.577531 -0.914543 -0.250712 v 0.619443 -0.969705 -0.245914 v 0.603328 -0.967209 -0.23277 v 0.610375 -0.981074 -0.243191 v 0.602151 -0.901856 -0.253559 v 0.552525 -0.876568 -0.291902 v 0.617861 -0.936386 -0.230503 v 0.616403 -0.967121 -0.23212 v 0.572277 -0.930271 -0.248164 v 0.525147 -0.860349 -0.323006 v 0.486487 -0.846765 -0.378853 v 0.45417 -0.827013 -0.401873 v 0.552402 -0.855745 -0.409781 v 0.572365 -0.854919 -0.370594 v 0.511827 -0.850947 -0.350244 v 0.53504 -0.916933 -0.301093 v 0.557938 -0.950339 -0.264893 v 0.596405 -0.902963 -0.342337 v 0.567585 -0.936632 -0.340228 v 0.576038 -0.961024 -0.307525 v 0.601132 -0.949812 -0.260324 v 0.587302 -0.959512 -0.281218 v 0.616244 -0.927635 -0.291358 v 0.607669 -0.93918 -0.307331 v 0.596088 -0.949425 -0.233508 v 0.606228 -0.957245 -0.251134 v 0.621797 -0.954996 -0.256001 v 0.253805 -0.386954 -0.335255 v 0.301655 -0.350701 -0.347767 v 0.37706 -0.347028 -0.326345 v 0.224862 -0.434313 -0.30148 v 0.235705 -0.476927 -0.224897 v 0.486803 -0.80705 -0.539311 v 0.564088 -0.845289 -0.496591 v 0.552771 -0.845025 -0.446104 v 0.583383 -0.936545 -0.24609 v 0.613503 -0.930781 -0.27867 v 0.572962 -0.897884 -0.379767 v 0.549714 -0.924085 -0.370365 v 0.524426 -0.904984 -0.351246 v 0.495115 -0.924683 -0.389959 v 0.546199 -0.911451 -0.424367 v 0.519049 -0.937581 -0.409834 v 0.620497 -0.845658 -0.491126 v 0.612501 -0.842372 -0.459723 v 0.638 -0.842741 -0.488314 v 0.631744 -0.836028 -0.458423 v 0.660686 -0.852388 -0.479422 v 0.656187 -0.84629 -0.452378 v 0.676379 -0.870646 -0.472622 v 0.671036 -0.861456 -0.449021 v 0.736899 -0.902436 -0.443082 v 0.724528 -0.905142 -0.426616 v 0.756634 -0.938548 -0.42753 v 0.743419 -0.941781 -0.411978 v 0.734264 -0.918603 -0.456824 v 0.746301 -0.955137 -0.441658 v 0.753576 -0.961041 -0.421731 v 0.632253 -0.881348 -0.491794 v 0.666151 -0.893474 -0.481724 v 0.721787 -0.931853 -0.471128 v 0.702861 -0.922504 -0.41623 v 0.635328 -0.862053 -0.449619 v 0.617861 -0.859558 -0.4541 v 0.653464 -0.898763 -0.432889 v 0.692229 -0.94642 -0.446315 v 0.658419 -0.913665 -0.457614 v 0.731768 -0.948758 -0.432679 v 0.713791 -0.952571 -0.440305 v 0.728816 -0.926581 -0.417636 v 0.737304 -0.941992 -0.448828 v 0.739711 -0.951341 -0.428514 v 0.619952 -0.902717 -0.468773 v 0.622184 -0.891013 -0.448389 v 0.570924 -0.885864 -0.441992 v 0.553175 -0.886849 -0.523407 v 0.486733 -0.862704 -0.544407 v 0.436175 -0.832935 -0.588163 v 0.356834 -0.808614 -0.579535 v 0.370066 -0.837258 -0.56502 v 0.483482 -0.952536 -0.448898 v 0.401293 -0.935525 -0.430816 v 0.452167 -0.928848 -0.482146 v 0.422223 -0.873687 -0.514832 v 0.537448 -0.915563 -0.531227 v 0.538256 -0.931167 -0.479844 v 0.391171 -0.871859 -0.483183 v 0.420536 -0.835378 -0.412048 v 0.38532 -0.855323 -0.451112 v 0.418304 -0.875303 -0.361104 v 0.385689 -0.885583 -0.417513 v 0.43737 -0.84608 -0.344305 v 0.340087 -0.757196 -0.585158 v 0.469634 -0.844937 -0.353952 v 0.463501 -0.850525 -0.319984 v 0.42948 -0.855042 -0.316698 v 0.426792 -0.862317 -0.284293 v 0.46554 -0.856043 -0.287562 v 0.431185 -0.874688 -0.270481 v 0.46633 -0.868836 -0.272713 v 0.445647 -0.914016 -0.213949 v 0.463782 -0.91725 -0.223544 v 0.451376 -0.953414 -0.196095 v 0.462306 -0.958897 -0.205374 v 0.452501 -0.974467 -0.200243 v 0.431255 -0.928303 -0.22075 v 0.440885 -0.965645 -0.207219 v 0.421801 -0.889766 -0.325695 v 0.42159 -0.909043 -0.292342 v 0.476786 -0.950111 -0.248902 v 0.476031 -0.902383 -0.300724 v 0.470407 -0.867255 -0.319176 v 0.473237 -0.895284 -0.313763 v 0.449812 -0.958036 -0.277932 v 0.420008 -0.952061 -0.250079 v 0.448441 -0.924841 -0.300267 v 0.452255 -0.956595 -0.222701 v 0.449724 -0.96619 -0.248445 v 0.467051 -0.941676 -0.225091 v 0.434084 -0.944734 -0.229624 v 0.454609 -0.963044 -0.212034 v 0.446174 -0.916406 -0.31306 v 0.484923 -0.891418 -0.370365 v 0.412944 -0.9234 -0.3704 v 0.448547 -0.950989 -0.393632 v 0.452237 -0.928373 -0.363494 v 0.0993217 -0.0437212 0.013039 v 0.117 -0.0326855 0.00843494 v 0.132956 0.0132675 -0.0162198 v 0.174393 0.0882332 -0.136154 v 0.172284 0.0767757 -0.0868099 v 0.171159 0.108829 -0.285049 v 0.00316311 -0.239694 -0.424384 v -0.0470776 -0.322356 -0.4651 v -0.206288 -0.446754 -0.598162 v -0.387411 -0.551928 -0.631445 v -0.577268 -0.63445 -0.594559 v -0.729255 -0.698028 -0.432784 v -0.756634 -0.767687 -0.272432 v -0.0792359 -0.255087 -0.536024 v -0.261572 -0.388817 -0.610832 v -0.427213 -0.493516 -0.610639 v -0.583787 -0.592222 -0.559713 v -0.7104 -0.676994 -0.421221 v -0.0270973 -0.190806 -0.492918 v -0.0579904 -0.180034 -0.514849 v -0.023407 -0.156609 -0.518012 v -0.0553017 -0.161248 -0.534214 v -0.0514006 -0.128001 -0.550258 v -0.00166942 -0.146557 -0.467385 v -0.00917302 -0.129371 -0.496679 v -0.035708 -0.118283 -0.496187 v 0.007117 -0.119214 -0.480547 v 0.0405405 -0.19309 -0.383492 v 0.0145679 -0.112326 -0.445964 v -0.0222824 -0.0805364 -0.516835 v -0.00671283 -0.090834 -0.457034 v -0.131445 -0.226655 -0.581046 v -0.161038 -0.199944 -0.592732 v -0.186729 -0.231417 -0.598092 v -0.191685 -0.214336 -0.630531 v -0.136365 -0.263962 -0.566109 v -0.184778 -0.254472 -0.576389 v -0.182881 -0.19432 -0.578199 v -0.199258 -0.209767 -0.609725 v -0.121833 -0.178909 -0.554037 v -0.100534 -0.145644 -0.553632 v -0.130584 -0.118546 -0.582259 v -0.109795 -0.124855 -0.567726 v -0.0574456 -0.0602397 -0.560046 v -0.0993393 -0.105314 -0.550575 v -0.0711524 -0.0882332 -0.579341 v -0.0723474 -0.144238 -0.524584 v -0.0709416 -0.0606088 -0.58203 v -0.069729 -0.0438443 -0.568077 v -0.0576565 -0.0340386 -0.537799 v -0.0776895 -0.0167997 -0.565898 v -0.0986539 -0.0506449 -0.559677 v -0.099761 -0.0857555 -0.573349 v -0.100692 -0.0549151 -0.613608 v -0.116982 -0.104435 -0.542157 v 0.00662496 -0.0410502 -0.463958 v -0.0404878 0.0115278 -0.520332 v -0.0445472 -0.0301902 -0.527414 v -0.0606439 0.0340737 -0.528099 v -0.0182758 -0.0848768 -0.478104 v -0.0715566 -0.026781 -0.521632 v -0.237427 -0.307929 -0.574316 v -0.176308 -0.333954 -0.587425 v -0.239694 -0.275841 -0.599304 v -0.156925 -0.283221 -0.579623 v -0.18947 -0.269655 -0.585211 v -0.144132 -0.116473 -0.542983 v 0.0806769 -0.0121428 -0.424314 v -0.00416476 0.0702035 -0.465505 v -0.0435982 0.121868 -0.484852 v -0.0251292 0.0236179 -0.502829 v -0.0629459 0.0179594 -0.50065 v -0.0487998 0.0939092 -0.497382 v -0.0861245 0.139528 -0.506537 v -0.0925386 0.109092 -0.482779 v 0.199487 0.100938 -0.197782 v 0.17738 0.0913612 -0.124627 v 0.19831 0.106421 -0.242382 v 0.175887 0.137174 -0.313728 v 0.206639 0.121463 -0.19787 v 0.162514 0.0891997 -0.289969 v 0.111763 0.0971251 -0.364724 v 0.147348 0.106263 -0.297948 v 0.154588 0.0526482 -0.320616 v 0.144045 0.11635 -0.363319 v 0.133835 0.100376 -0.371753 v 0.0854743 0.0908691 -0.411521 v 0.0331424 0.0769514 -0.462359 v 0.0567427 0.0864408 -0.42709 v 0.0578674 0.132394 -0.418814 v 0.0914666 0.115664 -0.319017 v 0.0016167 0.135241 -0.468404 v 0.0493445 0.109145 -0.391611 v 0.0489404 0.111588 -0.338225 v 0.0333533 0.106052 -0.420044 v 0.108635 0.131322 -0.399483 v 0.111939 0.116701 -0.338611 v 0.12431 0.125769 -0.350754 v 0.0719081 0.115612 -0.379767 v 0.181773 0.124222 -0.225758 v 0.173251 0.074421 -0.0969318 v 0.187168 0.0622078 -0.136506 v 0.161776 0.113239 -0.152321 v 0.156644 0.0894457 -0.11577 v 0.163533 0.173005 -0.186237 v 0.138052 0.21655 -0.187854 v 0.189839 0.314607 -0.241785 v 0.139194 0.129389 -0.254472 v 0.103065 0.216954 -0.298123 v 0.140635 0.300373 -0.309159 v 0.0359189 0.167785 -0.365445 v 0.0516114 0.260623 -0.381559 v 0.184603 0.382684 -0.320423 v 0.12243 0.350279 -0.409394 v 0.048132 0.337785 -0.456929 v 0.0643166 0.384441 -0.477665 v -0.0773381 0.303975 -0.46568 v 0.00256563 0.170052 -0.349875 v -0.0538783 0.223702 -0.407795 v -0.0493797 0.267019 -0.444101 v -0.0796753 0.25999 -0.437142 v 0.0692721 0.35274 -0.468861 v 0.0275191 0.374653 -0.486399 v 0.0205427 0.1086 -0.41363 v -0.0501353 0.13879 -0.453133 v -0.0464977 0.100271 -0.41247 v -0.0154465 0.130267 -0.371507 v -0.0440024 0.319562 -0.428795 v 0.0268162 0.364338 -0.458932 v -0.00581661 0.351791 -0.455365 v 0.0063438 0.282782 -0.404316 v -0.0853337 0.271272 -0.362405 v -0.10846 0.346167 -0.416951 v -0.0374653 0.295681 -0.386321 v -0.0625417 0.206727 -0.376322 v -0.0438442 0.287351 -0.433715 v 0.0339859 0.382596 -0.465118 v 0.00667768 0.391382 -0.464749 v -0.070801 0.407426 -0.540962 v -0.0435104 0.41254 -0.534267 v -0.0234422 0.43969 -0.521738 v -0.0482902 0.500281 -0.651337 v -0.0672513 0.516044 -0.644853 v -0.0307876 0.517503 -0.637455 v -0.0628756 0.544547 -0.724528 v -0.0640882 0.538362 -0.701508 v -0.0449865 0.543862 -0.711173 v -0.0430886 0.519154 -0.686553 v -0.0613995 0.531069 -0.681756 v -0.0303483 0.535427 -0.679946 v -0.0533863 0.527115 -0.708256 v -0.0242681 0.461129 -0.514744 v -0.0612941 0.537131 -0.637367 v -0.0400309 0.539012 -0.633325 v -0.0557762 0.551488 -0.705216 v -0.0525076 0.548237 -0.678892 v -0.0398552 0.548835 -0.678206 v -0.081907 0.478157 -0.513935 v -0.106122 0.434717 -0.514796 v -0.0461814 0.483745 -0.512512 v 0.00878642 0.425755 -0.450708 v -0.115998 0.394985 -0.40161 v -0.0658279 0.470935 -0.449812 v -0.0820652 0.444083 -0.422504 v 0.0177661 0.620304 -0.538432 v -0.03859 0.617158 -0.559537 v -0.0890064 0.628668 -0.521052 v 0.0423505 0.613222 -0.466664 v 0.0536323 0.686571 -0.536639 v -0.00625593 0.673022 -0.629178 v -0.0384669 0.699329 -0.6254 v 0.0489579 0.721295 -0.585 v -0.0350051 0.73755 -0.597828 v -0.0781464 0.71228 -0.518996 v 0.0140231 0.706112 -0.49993 v 0.00576389 0.754613 -0.580378 v -0.0378695 0.747759 -0.522247 v -0.053193 0.699698 -0.395407 v -0.10556 0.682195 -0.37279 v -0.104717 0.669894 -0.489984 v -0.0573753 0.708238 -0.465838 v -0.0261484 0.723351 -0.526465 v -0.0811865 0.691825 -0.525797 v -0.0417882 0.721804 -0.493656 v 0.00660739 0.685288 -0.375514 v -0.00962992 0.716515 -0.512354 v -0.00961234 0.688381 -0.444909 v 0.0383615 0.66833 -0.415703 v 0.026658 0.667786 -0.464433 v -0.0246723 0.706305 -0.348962 v -0.0683584 0.702334 -0.313992 v -0.0517344 0.7256 -0.393684 v 0.0405933 0.695129 -0.611465 v 0.0352335 0.757073 -0.577654 v 0.0150951 0.756932 -0.695357 v -0.0106491 0.764612 -0.688803 v 0.0508909 0.803922 -0.669314 v -0.0103504 0.805117 -0.665255 v 0.0397146 0.765596 -0.681141 v 0.0453731 0.815397 -0.652567 v 0.0115454 0.808333 -0.736443 v 0.0245493 0.863863 -0.72184 v 0.042333 0.823586 -0.724862 v 0.0454082 0.855165 -0.714635 v 0.0204724 0.825221 -0.653516 v 0.00950691 0.847573 -0.734404 v 0.0500826 0.845324 -0.794099 v 0.0562331 0.855147 -0.78765 v 0.037518 0.866833 -0.782062 v 0.0372193 0.854198 -0.790409 v 0.0508558 0.857291 -0.809458 v -0.115981 0.531051 -0.427653 v -0.0912382 0.489737 -0.433873 v -0.149598 0.450497 -0.476435 v -0.14299 0.513847 -0.468949 v -0.202931 0.499982 -0.518047 v -0.201086 0.521492 -0.515271 v 0.24551 0.627122 -0.204091 v -0.0693424 0.71286 -0.356043 v -0.0400134 0.70808 -0.365023 v -0.00474467 0.733877 -0.327874 v -0.0193301 0.755263 -0.270218 v 0.0036903 0.780181 -0.243208 v 0.0229326 0.74602 -0.328753 v 0.0102098 0.754086 -0.299599 v 0.00609778 0.719309 -0.329983 v 0.0434576 0.75992 -0.30206 v 0.0336344 0.728377 -0.324201 v 0.0531227 0.749165 -0.295522 v 0.0597301 0.793361 -0.261589 v 0.0312621 0.774259 -0.225389 v 0.0324395 0.725214 -0.389414 v 0.0169051 0.697308 -0.400467 v -0.00803079 0.556391 -0.494851 v 0.0222648 0.52302 -0.523969 v -0.00615049 0.534162 -0.561224 v -0.0252697 0.499192 -0.523231 v -0.0669877 0.58876 -0.508066 v -0.125417 0.567093 -0.430728 v 0.042825 0.750641 -0.284592 v 0.061628 0.772854 -0.233508 v 0.0597828 0.765438 -0.269286 v 0.0325976 0.812586 -0.209451 v 0.065986 0.777791 -0.199803 v 0.0765473 0.852494 -0.202088 v 0.0429129 0.830651 -0.188346 v 0.073349 0.858293 -0.18158 v 0.0397498 0.837978 -0.164499 v 0.0480969 0.863108 -0.110902 v 0.0721189 0.858996 -0.130742 v 0.0882508 0.835413 -0.0971251 v 0.0114399 0.790057 -0.23588 v 0.0655643 0.817155 -0.217868 v 0.076969 0.750589 -0.313306 v 0.0968439 0.77686 -0.299687 v 0.105226 0.724177 -0.29243 v 0.0745088 0.727182 -0.342143 v 0.103662 0.737919 -0.272274 v 0.0993393 0.720768 -0.328208 v 0.0754929 0.7437 -0.336907 v 0.109865 0.748111 -0.327944 v 0.0984255 0.737075 -0.311426 v 0.0810811 0.760693 -0.274699 v 0.0665483 0.757688 -0.255263 v 0.121094 0.716146 -0.278178 v 0.117931 0.712403 -0.323235 v 0.0691316 0.846431 -0.0978456 v 0.0713985 0.870945 -0.125593 v 0.068868 0.826275 -0.191509 v 0.0580782 0.800214 -0.187871 v 0.086845 0.798914 -0.148578 v 0.114751 0.643904 -0.123924 v 0.148297 0.657769 -0.237269 v 0.101149 0.750343 -0.149756 v 0.10867 0.729361 -0.215478 v 0.125769 0.632622 -0.179788 v 0.183127 0.658788 -0.255931 v 0.213598 0.618933 -0.212913 v 0.2353 0.68701 -0.26043 v 0.246108 0.624381 -0.262942 v 0.246231 0.594612 -0.24428 v 0.134907 0.692247 -0.26716 v 0.15682 0.673374 -0.290022 v 0.14176 0.728904 -0.299564 v 0.14241 0.691157 -0.318385 v 0.0764946 0.682582 -0.44642 v 0.16898 0.688715 -0.44447 v 0.144554 0.645696 -0.50297 v 0.0820827 0.709943 -0.390381 v 0.0476224 0.665009 -0.471971 v 0.0828384 0.701191 -0.526412 v 0.115787 0.719748 -0.348944 v 0.120567 0.709556 -0.362791 v 0.105349 0.729378 -0.41196 v 0.143834 0.710558 -0.388746 v 0.114346 0.702105 -0.422346 v 0.136154 0.738569 -0.429164 v 0.16464 0.704442 -0.400221 v 0.15081 0.694602 -0.431659 v 0.127842 0.713352 -0.399431 v 0.20207 0.501476 -0.500211 v 0.160106 0.53193 -0.529821 v 0.158015 0.590377 -0.519488 v 0.223896 0.560995 -0.485028 v 0.256563 0.454416 -0.452413 v 0.265016 0.527994 -0.443749 v 0.244895 0.63814 -0.399466 v 0.256599 0.444646 -0.385179 v 0.261027 0.474555 -0.31429 v 0.207096 0.454434 -0.539117 v 0.134731 0.469335 -0.554212 v 0.246319 0.427196 -0.491178 v 0.203335 0.399448 -0.562718 v 0.258989 0.384687 -0.510315 v 0.276473 0.37272 -0.454065 v 0.228974 0.39625 -0.360278 v 0.253207 0.32812 -0.415615 v 0.237128 0.345201 -0.636998 v 0.313095 0.320775 -0.570081 v 0.278846 0.350262 -0.607915 v 0.193477 0.292799 -0.652023 v 0.138333 0.431976 -0.568886 v 0.150529 0.375584 -0.569465 v 0.0929076 0.432819 -0.542017 v 0.278477 0.478895 -0.362194 v 0.20316 0.651619 -0.462851 v 0.274787 0.562858 -0.330475 v 0.265578 0.603855 -0.31603 v 0.261045 0.516518 -0.253102 v 0.328911 0.233965 -0.682055 v 0.267494 0.304783 -0.533037 v 0.266896 0.292605 -0.516255 v 0.264665 0.29851 -0.495835 v 0.298281 0.285225 -0.544828 v 0.274013 0.333814 -0.537799 v 0.173778 0.317612 -0.624205 v 0.408217 0.176133 -0.686571 v 0.341563 0.162848 -0.698169 v 0.36258 0.179032 -0.699821 v 0.365058 0.133571 -0.711577 v 0.380136 0.147313 -0.71358 v 0.390925 0.132851 -0.712298 v 0.293062 0.194742 -0.677925 v 0.242277 0.250431 -0.672249 v 0.282694 0.274294 -0.677486 v 0.329842 0.292008 -0.639335 v 0.202474 0.24008 -0.656521 v 0.147296 0.283292 -0.616033 v 0.15617 0.267423 -0.634046 v 0.112185 0.350402 -0.549872 v 0.200401 0.21242 -0.637771 v 0.139212 0.26289 -0.600622 v 0.150617 0.245036 -0.619566 v 0.364531 0.115418 -0.701121 v 0.336063 0.14849 -0.686905 v 0.285084 0.167258 -0.658419 v 0.125576 0.283098 -0.573331 v 0.134274 0.307261 -0.593628 v 0.138597 0.37706 -0.411363 v 0.0770921 0.39987 -0.484308 v 0.0934172 0.420325 -0.4011 v 0.0719608 0.423136 -0.473324 v 0.0955084 0.416072 -0.450866 v 0.0423681 0.409148 -0.500088 v 0.0506801 0.425087 -0.505377 v 0.015675 0.397744 -0.475047 v 0.0168524 0.426598 -0.462113 v 0.0130742 0.419675 -0.490862 v 0.0217727 0.438354 -0.516536 v 0.0273433 0.444013 -0.517538 v 0.0263241 0.441992 -0.475925 v 0.0241451 0.450005 -0.511581 v 0.0173795 0.444259 -0.507029 v 0.0509437 0.486276 -0.487154 v 0.0784276 0.575598 -0.52353 v 0.064176 0.613837 -0.497276 v 0.0314027 0.540769 -0.479809 v 0.0544231 0.526728 -0.505465 v 0.0159737 0.495642 -0.519945 v -0.00274136 0.50717 -0.547218 v 0.0469195 0.453713 -0.483359 v -0.0390293 0.540347 -0.467104 v -0.0466559 0.483991 -0.488384 v -0.0477103 0.51506 -0.489017 v -0.00442836 0.478684 -0.510755 v -0.00618564 0.540382 -0.538151 v -0.0295927 0.52585 -0.525006 v 0.105103 0.401504 -0.546972 v 0.104207 0.515816 -0.532932 v 0.0946122 0.458774 -0.492145 v 0.190279 0.441061 -0.330967 v 0.24117 0.472446 -0.223931 v 0.241345 0.485274 -0.25927 v 0.250237 0.511282 -0.227305 v 0.219573 0.280656 -0.478192 v 0.180069 0.338207 -0.41066 v 0.175535 0.389432 -0.375514 v 0.206165 0.45772 -0.26665 v 0.197782 0.47111 -0.320529 v 0.107388 0.326697 -0.496327 v 0.0789372 0.389432 -0.516852 v 0.179155 0.218009 -0.559572 v 0.14589 0.253084 -0.530506 v 0.317014 0.141936 -0.644554 v 0.245334 0.179243 -0.609971 v 0.346747 0.156943 -0.603592 v 0.270323 0.183056 -0.542403 v 0.369364 0.244579 -0.650564 v 0.32689 0.221769 -0.549643 v 0.38604 0.180666 -0.601237 v 0.425649 0.174639 -0.626156 v 0.287474 0.258268 -0.525024 v 0.274804 0.215232 -0.512705 v 0.311602 0.188767 -0.545812 v 0.184181 0.305539 -0.441377 v 0.130197 0.35998 -0.470566 v 0.195814 0.251643 -0.495115 v 0.247812 0.251415 -0.492145 v 0.434506 0.136682 -0.691509 v 0.435929 0.145978 -0.608934 v 0.408498 0.156117 -0.605332 v 0.438319 0.0318771 -0.703652 v 0.476294 0.0384669 -0.672354 v 0.495976 0.0486416 -0.630812 v 0.498823 0.0632798 -0.604172 v 0.402611 0.0256212 -0.716831 v 0.518399 0.0263768 -0.614206 v 0.52049 0.039943 -0.594243 v 0.552209 -0.00880402 -0.600868 v 0.555829 -0.000369045 -0.588655 v 0.56523 -0.0182758 -0.601606 v 0.571574 -0.0077145 -0.587196 v 0.581064 -0.0372896 -0.593593 v 0.584068 -0.030401 -0.58022 v 0.596633 -0.0694479 -0.582803 v 0.600341 -0.0983025 -0.568517 v 0.605156 -0.0864935 -0.546041 v 0.605964 -0.0835413 -0.561874 v 0.602573 -0.0602046 -0.564914 v 0.461217 0.0783397 -0.548659 v 0.41261 0.136242 -0.587513 v 0.528029 0.0128106 -0.569202 v 0.565881 -0.017854 -0.567462 v 0.595175 -0.0921344 -0.536921 v 0.592767 -0.0619619 -0.548747 v 0.602169 -0.120813 -0.553703 v 0.608108 -0.107915 -0.536639 v 0.616016 -0.11034 -0.550996 v 0.614013 -0.136734 -0.534583 v 0.394229 0.109215 -0.580695 v 0.376797 0.0783046 -0.624732 v 0.402014 0.0526834 -0.590641 v 0.391523 0.0777422 -0.580132 v 0.374794 0.125646 -0.617668 v 0.128036 0.164921 -0.286455 v 0.0497311 0.209609 -0.381893 v -0.020982 0.232278 -0.427002 v 0.102063 0.264014 -0.357713 v 0.18882 0.668875 -0.281447 v 0.216779 0.690577 -0.297807 v 0.236794 0.652673 -0.299213 v 0.217271 0.672934 -0.273504 v 0.197413 0.685763 -0.367044 v 0.218466 0.689558 -0.39089 v 0.226883 0.66594 -0.366218 v 0.165167 0.703265 -0.356817 v 0.182951 0.697255 -0.355094 v 0.202404 0.672249 -0.331389 v 0.159069 0.690542 -0.332654 v 0.173409 0.718518 -0.338752 v 0.155484 0.696394 -0.348065 v 0.147647 0.708326 -0.370348 v 0.176554 0.726742 -0.379538 v 0.179366 0.696781 -0.394897 v 0.22437 0.658402 -0.336625 v 0.212631 0.695357 -0.351105 v 0.172003 0.674217 -0.301568 v 0.165237 0.682476 -0.314554 v 0.166397 0.689154 -0.297596 v 0.158226 0.68513 -0.30749 v 0.21648 0.666011 -0.314905 v 0.213405 0.678259 -0.327575 v 0.200313 0.667206 -0.318982 v 0.17789 0.675869 -0.31712 v 0.228377 0.650371 -0.320915 v 0.200225 0.682301 -0.395336 v 0.576389 -0.080923 -0.580572 v 0.588022 -0.105455 -0.568042 v 0.507715 -0.0106667 -0.609479 v 0.553615 -0.0340386 -0.602766 v 0.581889 -0.0992339 -0.537518 v 0.573736 -0.0651425 -0.551664 v 0.564932 -0.0792008 -0.57175 v 0.57783 -0.108758 -0.55618 v 0.602344 -0.111025 -0.53548 v 0.598461 -0.12062 -0.551611 v 0.609918 -0.130689 -0.532211 v 0.605964 -0.135733 -0.538572 v 0.545689 -0.0302077 -0.563122 v 0.505377 -0.0027238 -0.569747 v 0.535761 -0.0454961 -0.586107 v 0.609426 -0.141075 -0.530559 v 0.413067 0.126893 -0.532193 v 0.438056 0.116877 -0.536059 v 0.432784 0.101799 -0.505571 v 0.408252 0.109461 -0.50188 v 0.43187 0.0954732 -0.489439 v 0.407268 0.104857 -0.486328 v 0.429498 0.0848065 -0.475011 v 0.402594 0.092644 -0.472235 v 0.409693 0.0749657 -0.45243 v 0.425421 0.0643869 -0.447686 v 0.392542 0.0690437 -0.44816 v 0.392981 0.10129 -0.551137 v 0.391171 0.092644 -0.493305 v 0.379644 0.0546867 -0.453168 v 0.410537 0.0548624 -0.420413 v 0.420096 0.044881 -0.427284 v 0.393684 0.0560749 -0.427038 v 0.405335 0.0327558 -0.401979 v 0.407954 0.0237409 -0.407145 v 0.393948 0.0289249 -0.407303 v 0.433575 0.0765121 -0.495009 v 0.428057 0.0499947 -0.45786 v 0.392577 0.0409798 -0.465469 v 0.415598 0.037026 -0.465522 v 0.393122 0.0375004 -0.448652 v 0.413717 0.0333357 -0.449021 v 0.392612 0.0513654 -0.430043 v 0.419692 0.0395389 -0.434225 v 0.421678 0.0610305 -0.500685 v 0.397058 0.0669876 -0.500879 v 0.436931 0.0567075 -0.547324 v 0.399765 0.0241451 -0.400485 v 0.494289 0.0443187 -0.56755 v 0.401188 0.0382385 -0.628335 v 0.473412 0.0279935 -0.564106 v 0.435824 0.025709 -0.587372 v 0.501283 0.00789019 -0.642639 v 0.491723 0.00207358 -0.657488 v 0.510737 -0.0610481 -0.639722 v 0.520174 -0.0554072 -0.626876 v 0.514164 -0.0838225 -0.6364 v 0.527765 -0.0760728 -0.61953 v 0.507785 -0.104348 -0.623168 v 0.518996 -0.101378 -0.603047 v 0.501529 -0.143728 -0.601536 v 0.513478 -0.139493 -0.587847 v 0.505342 -0.16218 -0.583243 v 0.487717 -0.170878 -0.587038 v 0.504903 -0.162109 -0.564264 v 0.50188 -0.0136717 -0.614311 v 0.513355 -0.0773381 -0.596071 v 0.508224 -0.131339 -0.576143 v 0.495361 -0.152532 -0.553703 v 0.495484 -0.191245 -0.56581 v 0.475257 -0.189646 -0.56581 v 0.492373 -0.181809 -0.551155 v 0.474115 -0.201262 -0.545549 v 0.466787 -0.192827 -0.549784 v 0.47517 -0.190911 -0.543879 v 0.493481 -0.0884968 -0.631146 v 0.479809 -0.136348 -0.603434 v 0.47278 -0.166169 -0.583664 v 0.473483 -0.0254279 -0.650072 v 0.479949 -0.154184 -0.551875 v 0.492549 -0.119197 -0.569835 v 0.470759 -0.125066 -0.589569 v 0.463097 -0.160616 -0.569518 v 0.488384 -0.174779 -0.551735 v 0.471796 -0.181334 -0.564141 v 0.478262 -0.0850526 -0.614311 v 0.497171 -0.0737357 -0.592451 v 0.483763 -0.0229677 -0.595385 v 0.467016 -0.197132 -0.540822 v 0.470776 -0.00569362 -0.674639 v 0.455576 -0.00808352 -0.687573 v 0.457562 -0.0733666 -0.665027 v 0.467402 -0.0675676 -0.653464 v 0.455769 -0.0879169 -0.661635 v 0.470038 -0.0832074 -0.649334 v 0.445876 -0.107827 -0.643447 v 0.457509 -0.103662 -0.63257 v 0.426387 -0.129846 -0.616297 v 0.435771 -0.1254 -0.604471 v 0.420694 -0.134749 -0.599445 v 0.406196 -0.136594 -0.599111 v 0.418181 -0.127561 -0.582469 v 0.469757 -0.0288019 -0.651443 v 0.457685 -0.0812744 -0.626296 v 0.429955 -0.110849 -0.594085 v 0.411292 -0.118142 -0.574614 v 0.402084 -0.143799 -0.577971 v 0.387991 -0.140214 -0.580677 v 0.403631 -0.133483 -0.566566 v 0.370189 -0.138509 -0.551611 v 0.438882 -0.0935754 -0.653481 v 0.408832 -0.121182 -0.618406 v 0.394791 -0.129406 -0.599779 v 0.432222 -0.0367624 -0.671107 v 0.400467 -0.108987 -0.576389 v 0.4234 -0.0987067 -0.600446 v 0.411257 -0.100921 -0.615489 v 0.38829 -0.117703 -0.592099 v 0.397691 -0.126823 -0.566812 v 0.386198 -0.133536 -0.581274 v 0.428074 -0.0769866 -0.642656 v 0.446772 -0.0745264 -0.62366 v 0.420026 -0.0341792 -0.657347 v 0.453063 -0.0321583 -0.62793 v 0.358662 0.0625769 -0.692915 v 0.377957 0.0218782 -0.692651 v 0.349471 0.110709 -0.671283 v 0.375655 0.085404 -0.71235 v 0.441219 -0.00864585 -0.693635 v 0.424613 -0.0115629 -0.703652 v 0.418954 -0.0527713 -0.696113 v 0.426528 -0.0531227 -0.687028 v 0.410853 -0.0766528 -0.68933 v 0.42101 -0.0754051 -0.679753 v 0.395758 -0.0803079 -0.675939 v 0.404439 -0.0834359 -0.666995 v 0.376322 -0.0832777 -0.655028 v 0.387007 -0.0848417 -0.646505 v 0.375022 -0.0797983 -0.639458 v 0.362422 -0.064053 -0.639335 v 0.378642 -0.0719959 -0.628844 v 0.428391 -0.0369909 -0.67181 v 0.419815 -0.0633677 -0.67072 v 0.394247 -0.0771096 -0.644677 v 0.383088 -0.0658806 -0.628563 v 0.35636 -0.0587812 -0.613714 v 0.355235 -0.0525955 -0.619847 v 0.36852 -0.0550733 -0.613819 v 0.354901 -0.0347767 -0.601184 v 0.397287 -0.0588515 -0.689084 v 0.371015 -0.0659685 -0.659878 v 0.362633 -0.0551084 -0.642709 v 0.404 -0.0135311 -0.696763 v 0.383439 -0.0591853 -0.632306 v 0.393509 -0.0707659 -0.647946 v 0.377711 -0.0597828 -0.657962 v 0.370049 -0.0449338 -0.640056 v 0.370576 -0.0505219 -0.615225 v 0.356518 -0.0494676 -0.621358 v 0.393069 -0.0537729 -0.676853 v 0.414438 -0.0587636 -0.664763 v 0.391488 -0.0168172 -0.680877 v 0.410484 0.0641409 -0.552121 v 0.102871 0.658261 -0.0631041 v 0.121024 0.65146 -0.094208 v 0.127596 0.573472 -0.0729976 v 0.0750185 0.581661 -0.0556708 v 0.104998 0.578059 -0.0594314 v 0.102871 0.655291 -0.00917304 v 0.0840509 0.604927 -0.0374478 v 0.106509 0.598566 -0.0755281 v 0.129529 0.604207 -0.100341 v 0.123695 0.779303 -0.0699751 v 0.101606 0.7146 -0.016044 v 0.118125 0.805346 -0.0877764 v 0.0132675 0.865726 -0.0939093 v 0.0375356 0.9221 -0.06755 v 0.0895336 0.896338 -0.0741398 v 0.0928022 0.85223 -0.0353917 v 0.0770218 0.841265 0.0080132 v 0.0623836 0.925737 -0.102204 v 0.00576389 0.967736 -0.108618 v 0.0187502 0.960936 -0.130514 v 0.00847011 1 -0.14176 v 0.0176431 0.992479 -0.15067 v 0.0718026 0.877131 -0.108793 v 0.0532633 0.90117 -0.126155 v 0.0110357 0.945524 -0.144625 v 0.00553544 0.985608 -0.159561 v 0.0123889 0.888413 -0.108073 v -0.0163076 0.936334 -0.134467 v -0.00506098 0.990493 -0.153077 v -0.0194707 0.963659 -0.143588 v -0.00254806 0.999104 -0.144537 v -0.0197167 0.973852 -0.128282 v 0.000421748 0.861139 -0.044389 v 0.000474467 0.90219 -0.0739993 v -0.0196113 0.946561 -0.111166 v 0.0279935 0.891593 -0.120286 v 0.0138123 0.848592 0.00926086 v 0.00954205 0.91674 -0.0609251 v -0.00832953 0.969054 -0.108829 v 0.00736302 0.999157 -0.157558 v 0.123379 0.805363 -0.0418761 v 0.110551 0.823077 0.0101395 v 0.214248 0.782255 0.0628932 v 0.220838 0.756809 -0.0141989 v 0.28656 0.729993 0.091572 v 0.298563 0.657189 0.0578498 v 0.289899 0.69244 0.116719 v 0.259674 0.63155 0.114821 v 0.257003 0.670474 0.147348 v 0.138281 0.580607 0.187291 v 0.189506 0.605332 0.167926 v 0.189962 0.628422 0.185587 v 0.159913 0.742822 0.100675 v 0.213088 0.703125 0.11577 v 0.129547 0.581643 0.181334 v 0.164605 0.63619 0.1684 v 0.103943 0.889977 -0.00834712 v 0.122571 0.903332 0.0329491 v 0.0952799 0.861807 0.0758092 v 0.136067 0.903982 -0.0210347 v 0.147594 0.920255 0.000667753 v 0.184005 0.905493 -0.034144 v 0.0506976 0.891224 0.0661969 v 0.0925562 0.928127 0.0242681 v 0.127632 0.937652 -0.00801324 v 0.167504 0.918901 -0.034847 v 0.0749482 0.907971 -0.000333902 v 0.0480969 0.851843 0.00903242 v 0.0766527 0.893017 -0.00741575 v 0.107317 0.92398 -0.0217025 v 0.161231 0.904509 -0.031104 v 0.168506 0.916441 -0.02172 v 0.0276421 0.872825 0.0308052 v 0.00883914 0.827734 0.0575335 v 0.0361825 0.863828 0.0831547 v 0.156451 0.720609 -0.00374304 v 0.153674 0.694197 0.0563736 v 0.290532 0.680332 0.0269743 v 0.220188 0.660299 0.0603451 v 0.231505 0.700858 0.00569359 v 0.217956 0.637384 0.0884441 v 0.173215 0.606333 0.137455 v 0.142867 0.570274 0.177082 v 0.139282 0.574474 0.167873 v 0.2104 0.681809 0.130127 v 0.131656 0.570344 0.179858 v 0.0881278 0.595016 0.00268863 v 0.128264 0.558201 0.0246547 v 0.115524 0.533617 0.0411731 v 0.11584 0.527484 0.0417179 v 0.0849823 0.499508 0.039328 v 0.0874952 0.557604 0.0307173 v 0.0989878 0.529944 0.0420518 v 0.0950866 0.486961 0.0309282 v 0.388992 0.221172 -0.621499 v 0.347503 0.278723 -0.594384 v 0.230767 0.771711 0.0179946 v 0.300162 0.706305 0.0577268 v 0.302516 0.67666 0.0889713 v 0.153604 0.703757 0.0845605 v 0.203054 0.674428 0.0836819 v 0.202193 0.658525 0.101026 v 0.182863 0.693741 0.0835061 v 0.192844 0.679717 0.0521562 # 2519 vertices vt 0.644 0.154 0.599 vt 0.632 0.188 0.600 vt 0.640 0.183 0.600 vt 0.656 0.168 0.599 vt 0.643 0.221 0.601 vt 0.656 0.202 0.601 vt 0.639 0.194 0.600 vt 0.621 0.228 0.601 vt 0.586 0.119 0.597 vt 0.562 0.130 0.598 vt 0.578 0.188 0.600 vt 0.615 0.158 0.599 vt 0.614 0.081 0.598 vt 0.644 0.095 0.597 vt 0.695 0.188 0.602 vt 0.671 0.180 0.600 vt 0.673 0.195 0.601 vt 0.684 0.201 0.602 vt 0.647 0.189 0.600 vt 0.595 0.214 0.600 vt 0.703 0.208 0.602 vt 0.713 0.199 0.602 vt 0.719 0.214 0.603 vt 0.724 0.204 0.603 vt 0.715 0.196 0.602 vt 0.728 0.196 0.602 vt 0.735 0.206 0.602 vt 0.734 0.198 0.602 vt 0.734 0.218 0.603 vt 0.730 0.165 0.600 vt 0.731 0.189 0.602 vt 0.734 0.188 0.602 vt 0.733 0.162 0.600 vt 0.734 0.227 0.602 vt 0.716 0.218 0.603 vt 0.703 0.212 0.603 vt 0.717 0.236 0.602 vt 0.702 0.230 0.602 vt 0.694 0.221 0.602 vt 0.697 0.257 0.602 vt 0.682 0.239 0.602 vt 0.673 0.225 0.602 vt 0.734 0.260 0.602 vt 0.710 0.276 0.602 vt 0.637 0.273 0.601 vt 0.598 0.264 0.601 vt 0.659 0.309 0.601 vt 0.704 0.152 0.599 vt 0.706 0.125 0.597 vt 0.682 0.130 0.598 vt 0.677 0.154 0.599 vt 0.719 0.150 0.599 vt 0.733 0.122 0.597 vt 0.703 0.187 0.602 vt 0.703 0.177 0.601 vt 0.699 0.172 0.601 vt 0.707 0.175 0.602 vt 0.711 0.186 0.606 vt 0.717 0.188 0.606 vt 0.706 0.173 0.601 vt 0.717 0.161 0.601 vt 0.730 0.159 0.599 vt 0.624 0.324 0.601 vt 0.578 0.291 0.600 vt 0.734 0.303 0.601 vt 0.700 0.310 0.601 vt 0.715 0.317 0.601 vt 0.673 0.210 0.602 vt 0.692 0.216 0.602 vt 0.691 0.211 0.602 vt 0.641 0.070 0.597 vt 0.662 0.081 0.596 vt 0.676 0.098 0.596 vt 0.705 0.093 0.595 vt 0.733 0.096 0.595 vt 0.686 0.077 0.596 vt 0.704 0.073 0.595 vt 0.733 0.077 0.595 vt 0.711 0.057 0.595 vt 0.697 0.054 0.595 vt 0.661 0.057 0.597 vt 0.682 0.060 0.596 vt 0.674 0.039 0.597 vt 0.670 0.043 0.597 vt 0.694 0.044 0.596 vt 0.719 0.033 0.595 vt 0.711 0.023 0.596 vt 0.733 0.053 0.594 vt 0.734 0.032 0.594 vt 0.275 0.976 0.506 vt 0.271 0.991 0.510 vt 0.241 0.990 0.536 vt 0.236 0.970 0.540 vt 0.325 0.976 0.455 vt 0.322 0.987 0.457 vt 0.299 0.955 0.477 vt 0.305 0.955 0.472 vt 0.302 0.969 0.479 vt 0.339 0.984 0.440 vt 0.336 0.990 0.443 vt 0.733 0.014 0.595 vt 0.727 0.011 0.596 vt 0.298 0.668 0.427 vt 0.321 0.707 0.450 vt 0.332 0.693 0.450 vt 0.323 0.665 0.434 vt 0.339 0.678 0.447 vt 0.337 0.640 0.426 vt 0.307 0.634 0.413 vt 0.288 0.655 0.417 vt 0.352 0.621 0.416 vt 0.352 0.584 0.395 vt 0.333 0.597 0.401 vt 0.320 0.616 0.409 vt 0.597 0.747 -0.465 vt 0.621 0.733 -0.465 vt 0.638 0.776 -0.437 vt 0.611 0.783 -0.437 vt 0.648 0.761 -0.440 vt 0.645 0.778 -0.437 vt 0.644 0.754 -0.446 vt 0.579 0.752 -0.465 vt 0.590 0.787 -0.440 vt 0.542 0.754 -0.462 vt 0.556 0.791 -0.451 vt 0.606 0.693 -0.456 vt 0.634 0.678 -0.468 vt 0.643 0.715 -0.465 vt 0.572 0.710 -0.457 vt 0.571 0.695 -0.460 vt 0.593 0.685 -0.461 vt 0.563 0.668 -0.455 vt 0.566 0.684 -0.426 vt 0.561 0.686 -0.437 vt 0.553 0.670 -0.459 vt 0.547 0.707 -0.450 vt 0.554 0.695 -0.446 vt 0.541 0.682 -0.446 vt 0.525 0.688 -0.442 vt 0.556 0.654 -0.501 vt 0.569 0.652 -0.505 vt 0.576 0.668 -0.453 vt 0.603 0.655 -0.496 vt 0.586 0.664 -0.492 vt 0.585 0.658 -0.494 vt 0.595 0.649 -0.493 vt 0.577 0.651 -0.498 vt 0.586 0.642 -0.488 vt 0.577 0.645 -0.494 vt 0.570 0.634 -0.513 vt 0.582 0.634 -0.511 vt 0.563 0.651 -0.516 vt 0.557 0.631 -0.502 vt 0.521 0.674 -0.487 vt 0.533 0.670 -0.497 vt 0.588 0.624 -0.500 vt 0.564 0.611 -0.444 vt 0.609 0.620 -0.451 vt 0.597 0.626 -0.482 vt 0.454 0.857 -0.466 vt 0.462 0.834 -0.465 vt 0.497 0.846 -0.461 vt 0.485 0.886 -0.467 vt 0.525 0.846 -0.458 vt 0.518 0.777 -0.462 vt 0.563 0.844 -0.459 vt 0.645 0.790 -0.437 vt 0.643 0.805 -0.440 vt 0.636 0.805 -0.444 vt 0.640 0.813 -0.425 vt 0.650 0.809 -0.442 vt 0.644 0.817 -0.430 vt 0.653 0.790 -0.438 vt 0.657 0.776 -0.440 vt 0.654 0.769 -0.436 vt 0.467 0.802 -0.465 vt 0.470 0.774 -0.467 vt 0.499 0.775 -0.465 vt 0.498 0.818 -0.462 vt 0.661 0.741 -0.451 vt 0.651 0.753 -0.447 vt 0.517 0.713 -0.454 vt 0.544 0.728 -0.465 vt 0.512 0.735 -0.456 vt 0.499 0.707 -0.479 vt 0.386 0.562 -0.685 vt 0.424 0.552 -0.685 vt 0.411 0.596 -0.685 vt 0.388 0.597 -0.685 vt 0.423 0.813 -0.467 vt 0.431 0.768 -0.467 vt 0.441 0.742 -0.469 vt 0.449 0.721 -0.469 vt 0.460 0.745 -0.469 vt 0.456 0.760 -0.468 vt 0.408 0.746 -0.469 vt 0.413 0.734 -0.469 vt 0.667 0.706 -0.465 vt 0.670 0.722 -0.461 vt 0.430 0.709 -0.454 vt 0.397 0.522 -0.685 vt 0.389 0.523 -0.685 vt 0.387 0.496 -0.685 vt 0.395 0.491 -0.685 vt 0.389 0.442 -0.685 vt 0.409 0.461 -0.685 vt 0.384 0.469 -0.685 vt 0.367 0.448 -0.685 vt 0.457 0.478 -0.685 vt 0.437 0.450 -0.685 vt 0.453 0.440 -0.697 vt 0.468 0.464 -0.696 vt 0.445 0.513 -0.685 vt 0.425 0.499 -0.685 vt 0.477 0.499 -0.685 vt 0.495 0.484 -0.696 vt 0.497 0.445 -0.646 vt 0.510 0.452 -0.642 vt 0.423 0.527 -0.685 vt 0.462 0.528 -0.685 vt 0.474 0.542 -0.685 vt 0.445 0.562 -0.685 vt 0.367 0.420 -0.685 vt 0.334 0.432 -0.685 vt 0.351 0.404 -0.685 vt 0.323 0.418 -0.685 vt 0.422 0.427 -0.685 vt 0.395 0.403 -0.685 vt 0.474 0.760 -0.468 vt 0.493 0.756 -0.468 vt 0.379 0.470 -0.685 vt 0.447 0.388 -0.709 vt 0.448 0.419 -0.705 vt 0.485 0.401 -0.627 vt 0.480 0.420 -0.637 vt 0.478 0.587 -0.685 vt 0.496 0.568 -0.685 vt 0.486 0.600 -0.685 vt 0.515 0.584 -0.685 vt 0.395 0.801 -0.468 vt 0.678 0.800 -0.452 vt 0.660 0.758 -0.446 vt 0.688 0.779 -0.457 vt 0.706 0.767 -0.457 vt 0.467 0.627 -0.685 vt 0.501 0.611 -0.685 vt 0.487 0.631 -0.685 vt 0.538 0.562 -0.685 vt 0.550 0.583 -0.685 vt 0.528 0.603 -0.685 vt 0.513 0.398 -0.667 vt 0.523 0.406 -0.679 vt 0.502 0.418 -0.600 vt 0.496 0.414 -0.604 vt 0.521 0.549 -0.685 vt 0.508 0.511 -0.685 vt 0.486 0.431 -0.620 vt 0.506 0.432 -0.616 vt 0.527 0.421 -0.676 vt 0.545 0.559 -0.712 vt 0.584 0.532 -0.709 vt 0.583 0.550 -0.708 vt 0.551 0.566 -0.701 vt 0.612 0.550 -0.709 vt 0.598 0.562 -0.709 vt 0.589 0.564 -0.710 vt 0.594 0.551 -0.709 vt 0.598 0.537 -0.709 vt 0.611 0.577 -0.710 vt 0.610 0.570 -0.709 vt 0.619 0.561 -0.709 vt 0.617 0.570 -0.710 vt 0.589 0.577 -0.701 vt 0.629 0.566 -0.710 vt 0.625 0.558 -0.709 vt 0.632 0.555 -0.709 vt 0.632 0.565 -0.709 vt 0.620 0.536 -0.709 vt 0.576 0.387 -0.709 vt 0.605 0.396 -0.709 vt 0.603 0.416 -0.709 vt 0.574 0.413 -0.709 vt 0.609 0.439 -0.709 vt 0.570 0.439 -0.708 vt 0.620 0.466 -0.709 vt 0.572 0.467 -0.708 vt 0.572 0.490 -0.708 vt 0.623 0.493 -0.709 vt 0.538 0.492 -0.708 vt 0.531 0.463 -0.706 vt 0.555 0.509 -0.709 vt 0.623 0.515 -0.709 vt 0.627 0.419 -0.709 vt 0.647 0.429 -0.709 vt 0.524 0.437 -0.666 vt 0.521 0.356 -0.709 vt 0.554 0.364 -0.708 vt 0.662 0.494 -0.709 vt 0.661 0.511 -0.709 vt 0.681 0.501 -0.709 vt 0.680 0.507 -0.709 vt 0.752 0.685 -0.953 vt 0.738 0.692 -0.953 vt 0.731 0.679 -0.953 vt 0.746 0.673 -0.953 vt 0.726 0.671 -0.953 vt 0.742 0.665 -0.954 vt 0.721 0.659 -0.954 vt 0.737 0.654 -0.954 vt 0.716 0.649 -0.955 vt 0.733 0.642 -0.955 vt 0.720 0.620 -0.957 vt 0.711 0.625 -0.957 vt 0.705 0.612 -0.959 vt 0.710 0.605 -0.958 vt 0.700 0.603 -0.961 vt 0.703 0.601 -0.958 vt 0.699 0.629 -0.957 vt 0.694 0.612 -0.958 vt 0.695 0.604 -0.958 vt 0.713 0.676 -0.954 vt 0.698 0.655 -0.954 vt 0.749 0.652 -0.954 vt 0.756 0.664 -0.953 vt 0.681 0.514 -0.709 vt 0.665 0.524 -0.709 vt 0.766 0.677 -0.953 vt 0.684 0.487 -0.709 vt 0.694 0.494 -0.709 vt 0.717 0.692 -0.953 vt 0.748 0.630 -0.954 vt 0.766 0.647 -0.954 vt 0.722 0.614 -0.956 vt 0.733 0.611 -0.955 vt 0.778 0.662 -0.953 vt 0.695 0.631 -0.956 vt 0.690 0.637 -0.955 vt 0.678 0.661 -0.954 vt 0.674 0.640 -0.954 vt 0.747 0.602 -0.954 vt 0.762 0.619 -0.954 vt 0.720 0.599 -0.956 vt 0.733 0.598 -0.955 vt 0.677 0.627 -0.955 vt 0.686 0.617 -0.956 vt 0.718 0.610 -0.957 vt 0.711 0.598 -0.957 vt 0.695 0.626 -0.957 vt 0.688 0.610 -0.957 vt 0.696 0.597 -0.957 vt 0.414 0.480 -0.685 vt 0.360 0.450 -0.685 vt 0.331 0.436 -0.685 vt 0.652 0.454 -0.709 vt 0.698 0.676 -0.954 vt 0.682 0.679 -0.954 vt 0.773 0.634 -0.954 vt 0.695 0.697 -0.953 vt 0.679 0.699 -0.953 vt 0.793 0.639 -0.953 vt 0.788 0.651 -0.953 vt 0.861 0.723 -0.888 vt 0.883 0.735 -0.890 vt 0.863 0.747 -0.890 vt 0.848 0.731 -0.892 vt 0.845 0.726 -0.890 vt 0.855 0.720 -0.882 vt 0.840 0.719 -0.901 vt 0.848 0.713 -0.894 vt 0.833 0.714 -0.922 vt 0.844 0.708 -0.911 vt 0.826 0.685 -0.961 vt 0.820 0.689 -0.959 vt 0.810 0.676 -0.999 vt 0.816 0.672 -1.002 vt 0.813 0.691 -0.977 vt 0.801 0.679 -1.017 vt 0.831 0.733 -0.932 vt 0.823 0.719 -0.947 vt 0.835 0.680 -0.979 vt 0.855 0.694 -0.951 vt 0.859 0.711 -0.910 vt 0.864 0.716 -0.907 vt 0.869 0.703 -0.942 vt 0.808 0.696 -0.991 vt 0.809 0.722 -0.968 vt 0.794 0.706 -1.006 vt 0.848 0.669 -1.006 vt 0.862 0.685 -0.968 vt 0.825 0.666 -1.010 vt 0.824 0.676 -0.985 vt 0.816 0.666 -1.013 vt 0.803 0.685 -1.003 vt 0.795 0.684 -1.010 vt 0.796 0.678 -1.013 vt 0.817 0.738 -0.955 vt 0.876 0.697 -0.955 vt 0.668 0.471 -0.709 vt 0.672 0.442 -0.708 vt 0.691 0.461 -0.709 vt 0.848 0.762 -0.935 vt 0.629 0.397 -0.709 vt 0.644 0.401 -0.709 vt 0.741 0.427 -0.750 vt 0.741 0.443 -0.728 vt 0.718 0.446 -0.708 vt 0.721 0.422 -0.704 vt 0.746 0.415 -0.734 vt 0.733 0.401 -0.694 vt 0.699 0.454 -0.709 vt 0.702 0.418 -0.714 vt 0.711 0.392 -0.725 vt 0.675 0.413 -0.707 vt 0.679 0.396 -0.703 vt 0.840 0.774 -0.966 vt 0.817 0.772 -0.983 vt 0.659 0.538 -0.709 vt 0.651 0.559 -0.709 vt 0.648 0.573 -0.709 vt 0.693 0.558 -0.709 vt 0.679 0.577 -0.709 vt 0.668 0.560 -0.709 vt 0.684 0.544 -0.709 vt 0.685 0.525 -0.709 vt 0.686 0.533 -0.709 vt 0.913 0.704 -0.983 vt 0.887 0.717 -0.934 vt 0.628 0.574 -0.709 vt 0.623 0.597 -0.709 vt 0.610 0.598 -0.709 vt 0.591 0.597 -0.711 vt 0.711 0.753 -0.884 vt 0.725 0.749 -0.889 vt 0.736 0.760 -0.893 vt 0.723 0.763 -0.883 vt 0.737 0.743 -0.895 vt 0.747 0.754 -0.900 vt 0.742 0.740 -0.909 vt 0.752 0.751 -0.914 vt 0.788 0.725 -1.001 vt 0.774 0.734 -0.957 vt 0.769 0.729 -0.962 vt 0.786 0.720 -1.007 vt 0.780 0.738 -0.972 vt 0.794 0.729 -1.014 vt 0.747 0.772 -0.931 vt 0.762 0.763 -0.952 vt 0.734 0.726 -0.947 vt 0.762 0.715 -0.999 vt 0.724 0.741 -0.908 vt 0.726 0.729 -0.939 vt 0.785 0.751 -0.999 vt 0.790 0.765 -1.007 vt 0.771 0.773 -0.970 vt 0.734 0.713 -0.970 vt 0.751 0.704 -1.007 vt 0.779 0.713 -1.005 vt 0.787 0.716 -1.012 vt 0.773 0.720 -0.989 vt 0.799 0.731 -1.012 vt 0.798 0.739 -1.005 vt 0.787 0.741 -0.991 vt 0.762 0.775 -0.961 vt 0.726 0.715 -0.961 vt 0.757 0.794 -0.975 vt 0.740 0.793 -0.968 vt 0.703 0.714 -0.975 vt 0.700 0.733 -0.937 vt 0.022 0.649 0.173 vt 0.019 0.619 0.173 vt 0.014 0.626 0.173 vt 0.017 0.652 0.173 vt 0.006 0.626 0.173 vt 0.006 0.652 0.173 vt 0.006 0.694 0.173 vt 0.029 0.699 0.173 vt 0.033 0.697 0.173 vt 0.659 0.833 -0.454 vt 0.646 0.821 -0.443 vt 0.049 0.730 0.173 vt 0.057 0.726 0.173 vt 0.006 0.734 0.173 vt 0.638 0.852 -0.457 vt 0.628 0.839 -0.451 vt 0.636 0.824 -0.446 vt 0.615 0.835 -0.450 vt 0.630 0.817 -0.442 vt 0.013 0.588 0.173 vt 0.006 0.588 0.173 vt 0.017 0.588 0.172 vt 0.022 0.546 0.111 vt 0.006 0.532 0.117 vt 0.203 0.940 -0.291 vt 0.213 0.950 -0.291 vt 0.264 0.917 -0.291 vt 0.225 0.894 -0.291 vt 0.281 0.893 -0.291 vt 0.238 0.881 -0.291 vt 0.291 0.865 -0.291 vt 0.255 0.859 -0.291 vt 0.289 0.825 -0.291 vt 0.261 0.832 -0.291 vt 0.268 0.756 -0.291 vt 0.236 0.767 -0.291 vt 0.226 0.700 -0.291 vt 0.203 0.715 -0.291 vt 0.183 0.647 -0.292 vt 0.165 0.659 -0.292 vt 0.146 0.581 -0.292 vt 0.126 0.574 -0.292 vt 0.121 0.528 -0.292 vt 0.116 0.525 -0.292 vt 0.328 0.815 -0.291 vt 0.314 0.767 -0.291 vt 0.295 0.734 -0.291 vt 0.249 0.684 -0.291 vt 0.201 0.637 -0.292 vt 0.158 0.579 -0.292 vt 0.123 0.522 -0.292 vt 0.322 0.855 -0.291 vt 0.338 0.844 -0.290 vt 0.363 0.821 -0.291 vt 0.330 0.862 -0.290 vt 0.340 0.851 -0.290 vt 0.319 0.881 -0.290 vt 0.330 0.878 -0.290 vt 0.325 0.888 -0.290 vt 0.320 0.900 -0.291 vt 0.333 0.900 -0.290 vt 0.342 0.894 -0.290 vt 0.353 0.802 -0.291 vt 0.368 0.799 -0.290 vt 0.368 0.783 -0.285 vt 0.364 0.783 -0.291 vt 0.355 0.777 -0.291 vt 0.340 0.792 -0.291 vt 0.377 0.783 -0.291 vt 0.369 0.773 -0.291 vt 0.381 0.805 -0.291 vt 0.374 0.796 -0.291 vt 0.368 0.782 -0.284 vt 0.314 0.932 -0.291 vt 0.364 0.837 -0.290 vt 0.349 0.852 -0.290 vt 0.374 0.850 -0.290 vt 0.376 0.877 -0.290 vt 0.370 0.877 -0.290 vt 0.374 0.890 -0.290 vt 0.380 0.880 -0.290 vt 0.343 0.876 -0.290 vt 0.385 0.850 -0.290 vt 0.389 0.841 -0.290 vt 0.373 0.840 -0.290 vt 0.379 0.858 -0.290 vt 0.385 0.871 -0.290 vt 0.345 0.913 -0.290 vt 0.398 0.846 -0.291 vt 0.404 0.867 -0.291 vt 0.385 0.891 -0.290 vt 0.386 0.908 -0.290 vt 0.411 0.901 -0.291 vt 0.409 0.889 -0.291 vt 0.315 0.721 -0.291 vt 0.262 0.675 -0.291 vt 0.211 0.632 -0.292 vt 0.163 0.577 -0.292 vt 0.335 0.781 -0.291 vt 0.347 0.772 -0.291 vt 0.372 0.918 -0.290 vt 0.335 0.938 -0.291 vt 0.372 0.939 -0.290 vt 0.385 0.932 -0.287 vt 0.381 0.927 -0.292 vt 0.392 0.922 -0.290 vt 0.419 0.914 -0.291 vt 0.006 0.768 0.173 vt 0.043 0.760 0.173 vt 0.046 0.742 0.173 vt 0.042 0.774 0.173 vt 0.056 0.776 0.173 vt 0.056 0.763 0.173 vt 0.049 0.797 0.173 vt 0.060 0.798 0.173 vt 0.564 0.899 -0.417 vt 0.556 0.895 -0.436 vt 0.545 0.910 -0.381 vt 0.540 0.908 -0.399 vt 0.534 0.892 -0.435 vt 0.535 0.915 -0.422 vt 0.553 0.926 -0.441 vt 0.533 0.931 -0.422 vt 0.524 0.931 -0.385 vt 0.601 0.873 -0.460 vt 0.605 0.872 -0.459 vt 0.612 0.875 -0.459 vt 0.606 0.880 -0.452 vt 0.006 0.921 0.173 vt 0.042 0.914 0.173 vt 0.035 0.886 0.173 vt 0.006 0.890 0.173 vt 0.048 0.804 0.173 vt 0.046 0.816 0.173 vt 0.055 0.821 0.173 vt 0.064 0.840 0.173 vt 0.044 0.821 0.173 vt 0.052 0.847 0.173 vt 0.040 0.795 0.173 vt 0.379 0.374 0.257 vt 0.397 0.365 0.257 vt 0.417 0.331 0.257 vt 0.395 0.331 0.257 vt 0.369 0.339 0.257 vt 0.357 0.348 0.257 vt 0.416 0.362 0.257 vt 0.432 0.356 0.257 vt 0.118 0.199 0.365 vt 0.138 0.210 0.372 vt 0.133 0.232 0.365 vt 0.098 0.201 0.360 vt 0.390 0.287 0.257 vt 0.399 0.237 0.257 vt 0.379 0.242 0.257 vt 0.374 0.298 0.257 vt 0.392 0.203 0.257 vt 0.375 0.199 0.257 vt 0.364 0.236 0.257 vt 0.393 0.185 0.257 vt 0.379 0.181 0.257 vt 0.519 0.123 0.194 vt 0.504 0.133 0.211 vt 0.498 0.157 0.248 vt 0.531 0.162 0.263 vt 0.413 0.942 -0.291 vt 0.438 0.941 -0.291 vt 0.384 0.962 -0.291 vt 0.412 0.962 -0.291 vt 0.395 0.939 -0.294 vt 0.395 0.986 -0.291 vt 0.376 0.973 -0.291 vt 0.498 0.055 0.095 vt 0.491 0.083 0.156 vt 0.506 0.088 0.158 vt 0.521 0.069 0.118 vt 0.355 0.382 0.257 vt 0.370 0.379 0.257 vt 0.083 0.929 0.173 vt 0.109 0.962 0.173 vt 0.117 0.953 0.173 vt 0.098 0.934 0.173 vt 0.092 0.923 0.173 vt 0.094 0.928 0.173 vt 0.097 0.920 0.173 vt 0.118 0.942 0.173 vt 0.078 0.901 0.173 vt 0.085 0.881 0.173 vt 0.078 0.890 0.168 vt 0.069 0.885 0.173 vt 0.470 0.350 0.257 vt 0.466 0.318 0.257 vt 0.548 0.208 0.346 vt 0.562 0.190 0.346 vt 0.544 0.158 0.263 vt 0.569 0.217 0.399 vt 0.573 0.203 0.382 vt 0.803 0.618 0.349 vt 0.802 0.627 0.353 vt 0.809 0.631 0.373 vt 0.817 0.623 0.386 vt 0.786 0.610 0.318 vt 0.838 0.598 0.408 vt 0.835 0.588 0.402 vt 0.846 0.608 0.435 vt 0.890 0.638 0.432 vt 0.911 0.637 0.402 vt 0.920 0.588 0.479 vt 0.911 0.586 0.497 vt 0.887 0.576 0.499 vt 0.882 0.567 0.479 vt 0.925 0.574 0.493 vt 0.916 0.572 0.508 vt 0.900 0.564 0.511 vt 0.896 0.558 0.493 vt 0.925 0.564 0.500 vt 0.918 0.564 0.514 vt 0.911 0.558 0.517 vt 0.907 0.552 0.500 vt 0.902 0.583 0.521 vt 0.877 0.626 0.476 vt 0.853 0.614 0.458 vt 0.895 0.580 0.522 vt 0.914 0.561 0.527 vt 0.909 0.569 0.526 vt 0.905 0.567 0.526 vt 0.865 0.619 0.481 vt 0.828 0.632 0.426 vt 0.858 0.642 0.476 vt 0.858 0.656 0.452 vt 0.870 0.675 0.399 vt 0.936 0.481 0.530 vt 0.900 0.508 0.615 vt 0.913 0.530 0.614 vt 0.936 0.499 0.553 vt 0.902 0.477 0.613 vt 0.867 0.503 0.683 vt 0.797 0.433 0.635 vt 0.770 0.443 0.614 vt 0.760 0.479 0.665 vt 0.778 0.485 0.697 vt 0.799 0.492 0.741 vt 0.813 0.454 0.703 vt 0.847 0.519 0.718 vt 0.855 0.482 0.715 vt 0.830 0.513 0.759 vt 0.819 0.504 0.759 vt 0.829 0.478 0.733 vt 0.872 0.434 0.726 vt 0.868 0.411 0.712 vt 0.821 0.436 0.685 vt 0.846 0.450 0.726 vt 0.821 0.456 0.726 vt 0.840 0.463 0.736 vt 0.831 0.472 0.761 vt 0.843 0.479 0.726 vt 0.867 0.459 0.704 vt 0.878 0.473 0.678 vt 0.319 0.117 0.426 vt 0.330 0.095 0.408 vt 0.337 0.110 0.409 vt 0.328 0.119 0.417 vt 0.858 0.530 0.687 vt 0.753 0.522 0.747 vt 0.765 0.522 0.759 vt 0.808 0.551 0.799 vt 0.824 0.558 0.757 vt 0.783 0.530 0.806 vt 0.796 0.539 0.826 vt 0.805 0.543 0.814 vt 0.875 0.545 0.665 vt 0.831 0.568 0.747 vt 0.795 0.572 0.815 vt 0.805 0.583 0.799 vt 0.755 0.549 0.799 vt 0.766 0.559 0.843 vt 0.784 0.565 0.850 vt 0.775 0.562 0.861 vt 0.750 0.584 0.830 vt 0.756 0.582 0.841 vt 0.767 0.589 0.841 vt 0.769 0.593 0.830 vt 0.762 0.582 0.856 vt 0.810 0.388 0.581 vt 0.798 0.378 0.543 vt 0.782 0.420 0.591 vt 0.961 0.985 0.382 vt 0.947 0.980 0.399 vt 0.959 0.938 0.454 vt 0.972 0.944 0.444 vt 0.918 0.921 0.543 vt 0.908 0.902 0.575 vt 0.933 0.899 0.550 vt 0.941 0.918 0.522 vt 0.928 0.961 0.452 vt 0.923 0.942 0.497 vt 0.973 0.905 0.505 vt 0.977 0.906 0.501 vt 0.965 0.892 0.538 vt 0.967 0.898 0.528 vt 0.006 0.949 0.173 vt 0.063 0.948 0.173 vt 0.070 0.868 0.173 vt 0.006 0.853 0.173 vt 0.293 0.111 0.446 vt 0.304 0.108 0.435 vt 0.303 0.115 0.440 vt 0.290 0.118 0.449 vt 0.282 0.106 0.451 vt 0.277 0.108 0.452 vt 0.947 0.645 0.476 vt 0.960 0.631 0.484 vt 0.953 0.621 0.516 vt 0.932 0.645 0.497 vt 0.845 0.391 0.653 vt 0.267 0.092 0.439 vt 0.292 0.099 0.441 vt 0.278 0.102 0.449 vt 0.267 0.100 0.447 vt 0.299 0.045 0.396 vt 0.307 0.058 0.404 vt 0.279 0.070 0.423 vt 0.269 0.058 0.420 vt 0.288 0.029 0.389 vt 0.266 0.039 0.406 vt 0.257 0.025 0.395 vt 0.277 0.011 0.381 vt 0.251 0.125 0.456 vt 0.263 0.135 0.458 vt 0.256 0.138 0.459 vt 0.243 0.124 0.453 vt 0.230 0.042 0.396 vt 0.255 0.047 0.442 vt 0.256 0.045 0.457 vt 0.234 0.058 0.410 vt 0.257 0.085 0.433 vt 0.257 0.098 0.443 vt 0.231 0.101 0.436 vt 0.223 0.076 0.415 vt 0.190 0.114 0.418 vt 0.181 0.094 0.409 vt 0.209 0.129 0.436 vt 0.229 0.128 0.449 vt 0.210 0.144 0.444 vt 0.228 0.141 0.458 vt 0.266 0.150 0.460 vt 0.244 0.144 0.463 vt 0.265 0.144 0.457 vt 0.284 0.252 0.376 vt 0.251 0.260 0.377 vt 0.258 0.236 0.390 vt 0.289 0.230 0.388 vt 0.280 0.276 0.366 vt 0.250 0.284 0.365 vt 0.212 0.270 0.374 vt 0.223 0.288 0.364 vt 0.279 0.290 0.360 vt 0.255 0.308 0.356 vt 0.223 0.310 0.356 vt 0.199 0.303 0.359 vt 0.185 0.262 0.371 vt 0.177 0.311 0.356 vt 0.165 0.278 0.364 vt 0.209 0.343 0.348 vt 0.186 0.346 0.348 vt 0.267 0.205 0.416 vt 0.295 0.211 0.405 vt 0.234 0.239 0.387 vt 0.240 0.197 0.422 vt 0.199 0.238 0.383 vt 0.205 0.202 0.409 vt 0.235 0.351 0.345 vt 0.248 0.349 0.345 vt 0.251 0.386 0.336 vt 0.229 0.388 0.336 vt 0.216 0.364 0.343 vt 0.209 0.388 0.336 vt 0.197 0.355 0.345 vt 0.188 0.357 0.345 vt 0.269 0.410 0.332 vt 0.266 0.431 0.327 vt 0.255 0.433 0.326 vt 0.248 0.409 0.331 vt 0.268 0.445 0.325 vt 0.260 0.447 0.324 vt 0.275 0.448 0.325 vt 0.261 0.453 0.323 vt 0.267 0.381 0.336 vt 0.228 0.413 0.331 vt 0.286 0.352 0.343 vt 0.285 0.344 0.345 vt 0.295 0.345 0.345 vt 0.293 0.354 0.342 vt 0.280 0.372 0.338 vt 0.290 0.376 0.338 vt 0.286 0.331 0.348 vt 0.282 0.312 0.354 vt 0.304 0.315 0.354 vt 0.298 0.334 0.348 vt 0.274 0.431 0.329 vt 0.282 0.412 0.332 vt 0.241 0.445 0.325 vt 0.298 0.284 0.364 vt 0.310 0.258 0.374 vt 0.329 0.212 0.396 vt 0.320 0.234 0.385 vt 0.475 0.201 0.257 vt 0.465 0.241 0.257 vt 0.481 0.242 0.257 vt 0.481 0.203 0.257 vt 0.493 0.218 0.257 vt 0.488 0.201 0.257 vt 0.367 0.022 0.372 vt 0.384 0.023 0.393 vt 0.387 0.049 0.417 vt 0.375 0.047 0.398 vt 0.410 0.055 0.452 vt 0.392 0.072 0.442 vt 0.389 0.068 0.435 vt 0.384 0.069 0.427 vt 0.816 0.627 0.389 vt 0.824 0.635 0.423 vt 0.425 0.079 0.423 vt 0.424 0.101 0.389 vt 0.410 0.092 0.409 vt 0.415 0.072 0.437 vt 0.383 0.075 0.434 vt 0.396 0.078 0.434 vt 0.351 0.217 0.382 vt 0.337 0.243 0.377 vt 0.353 0.236 0.372 vt 0.360 0.258 0.369 vt 0.306 0.191 0.446 vt 0.315 0.180 0.422 vt 0.333 0.190 0.402 vt 0.968 0.585 0.515 vt 0.983 0.599 0.526 vt 0.985 0.588 0.499 vt 0.975 0.577 0.490 vt 0.958 0.563 0.479 vt 0.965 0.554 0.452 vt 0.984 0.660 0.426 vt 0.982 0.628 0.475 vt 0.974 0.542 0.423 vt 0.971 0.550 0.437 vt 0.983 0.570 0.475 vt 0.979 0.539 0.426 vt 0.948 0.581 0.530 vt 0.952 0.599 0.553 vt 0.972 0.599 0.532 vt 0.143 0.197 0.377 vt 0.153 0.202 0.383 vt 0.152 0.219 0.378 vt 0.146 0.310 0.354 vt 0.147 0.283 0.360 vt 0.164 0.349 0.347 vt 0.151 0.329 0.350 vt 0.151 0.247 0.367 vt 0.172 0.239 0.376 vt 0.117 0.341 0.348 vt 0.114 0.323 0.351 vt 0.320 0.341 0.346 vt 0.327 0.317 0.352 vt 0.318 0.294 0.360 vt 0.342 0.306 0.356 vt 0.334 0.262 0.369 vt 0.355 0.272 0.363 vt 0.318 0.362 0.342 vt 0.291 0.425 0.332 vt 0.286 0.439 0.329 vt 0.160 0.455 0.334 vt 0.162 0.440 0.336 vt 0.181 0.432 0.334 vt 0.184 0.450 0.331 vt 0.142 0.416 0.339 vt 0.163 0.399 0.339 vt 0.200 0.432 0.331 vt 0.203 0.450 0.328 vt 0.176 0.404 0.337 vt 0.185 0.398 0.336 vt 0.189 0.377 0.341 vt 0.201 0.371 0.342 vt 0.171 0.383 0.340 vt 0.149 0.359 0.345 vt 0.168 0.365 0.344 vt 0.129 0.383 0.342 vt 0.125 0.364 0.345 vt 0.090 0.293 0.352 vt 0.112 0.282 0.355 vt 0.216 0.448 0.327 vt 0.247 0.465 0.321 vt 0.216 0.464 0.323 vt 0.203 0.465 0.325 vt 0.268 0.497 0.314 vt 0.283 0.485 0.316 vt 0.236 0.501 0.318 vt 0.249 0.504 0.315 vt 0.280 0.457 0.323 vt 0.292 0.474 0.319 vt 0.261 0.517 0.312 vt 0.272 0.513 0.311 vt 0.292 0.498 0.312 vt 0.284 0.506 0.311 vt 0.245 0.518 0.313 vt 0.236 0.514 0.315 vt 0.301 0.485 0.315 vt 0.297 0.491 0.313 vt 0.233 0.538 0.310 vt 0.228 0.535 0.311 vt 0.231 0.544 0.309 vt 0.225 0.541 0.310 vt 0.225 0.553 0.308 vt 0.220 0.550 0.308 vt 0.219 0.565 0.306 vt 0.212 0.562 0.307 vt 0.205 0.493 0.322 vt 0.198 0.487 0.324 vt 0.216 0.542 0.313 vt 0.222 0.525 0.318 vt 0.205 0.560 0.312 vt 0.203 0.571 0.306 vt 0.198 0.570 0.309 vt 0.204 0.580 0.303 vt 0.210 0.570 0.304 vt 0.213 0.576 0.305 vt 0.208 0.585 0.309 vt 0.199 0.579 0.307 vt 0.198 0.590 0.309 vt 0.202 0.591 0.311 vt 0.196 0.588 0.310 vt 0.189 0.479 0.327 vt 0.192 0.466 0.328 vt 0.413 0.279 0.257 vt 0.421 0.232 0.257 vt 0.420 0.203 0.257 vt 0.211 0.163 0.451 vt 0.209 0.165 0.460 vt 0.218 0.150 0.456 vt 0.260 0.159 0.467 vt 0.251 0.154 0.471 vt 0.273 0.164 0.459 vt 0.265 0.164 0.464 vt 0.234 0.187 0.439 vt 0.208 0.187 0.428 vt 0.225 0.178 0.447 vt 0.236 0.150 0.466 vt 0.243 0.152 0.467 vt 0.232 0.155 0.465 vt 0.229 0.149 0.464 vt 0.211 0.175 0.448 vt 0.222 0.170 0.456 vt 0.219 0.176 0.447 vt 0.270 0.189 0.433 vt 0.255 0.180 0.445 vt 0.261 0.177 0.452 vt 0.274 0.184 0.440 vt 0.235 0.549 0.311 vt 0.225 0.570 0.310 vt 0.217 0.580 0.310 vt 0.250 0.533 0.312 vt 0.192 0.569 0.313 vt 0.200 0.555 0.317 vt 0.230 0.573 0.316 vt 0.220 0.585 0.315 vt 0.990 0.300 -0.059 vt 0.991 0.318 -0.059 vt 0.982 0.319 -0.059 vt 0.979 0.302 -0.059 vt 0.992 0.329 -0.059 vt 0.984 0.330 -0.059 vt 0.991 0.339 -0.060 vt 0.988 0.340 -0.060 vt 0.976 0.280 -0.059 vt 0.988 0.278 -0.059 vt 0.971 0.257 -0.059 vt 0.986 0.256 -0.059 vt 0.242 0.556 0.316 vt 0.253 0.541 0.315 vt 0.213 0.520 0.322 vt 0.208 0.538 0.318 vt 0.196 0.503 0.322 vt 0.189 0.497 0.323 vt 0.191 0.508 0.322 vt 0.185 0.501 0.323 vt 0.186 0.513 0.322 vt 0.179 0.505 0.323 vt 0.179 0.497 0.325 vt 0.166 0.512 0.324 vt 0.160 0.508 0.327 vt 0.163 0.525 0.324 vt 0.173 0.514 0.322 vt 0.175 0.521 0.323 vt 0.167 0.529 0.325 vt 0.159 0.519 0.325 vt 0.155 0.532 0.325 vt 0.156 0.535 0.327 vt 0.151 0.529 0.327 vt 0.195 0.515 0.323 vt 0.179 0.526 0.325 vt 0.211 0.505 0.322 vt 0.155 0.501 0.329 vt 0.170 0.493 0.328 vt 0.197 0.522 0.326 vt 0.183 0.533 0.328 vt 0.940 0.076 -0.059 vt 0.959 0.078 -0.059 vt 0.958 0.089 -0.059 vt 0.939 0.088 -0.059 vt 0.966 0.079 -0.060 vt 0.965 0.089 -0.060 vt 0.976 0.079 -0.060 vt 0.972 0.092 -0.060 vt 0.987 0.086 -0.063 vt 0.986 0.093 -0.064 vt 0.925 0.090 -0.059 vt 0.922 0.076 -0.059 vt 0.210 0.519 0.325 vt 0.172 0.480 0.330 vt 0.225 0.507 0.320 vt 0.977 0.223 -0.059 vt 0.960 0.205 -0.059 vt 0.977 0.199 -0.059 vt 0.989 0.207 -0.059 vt 0.221 0.509 0.324 vt 0.990 0.237 -0.059 vt 0.277 0.540 0.307 vt 0.270 0.543 0.307 vt 0.280 0.549 0.305 vt 0.273 0.551 0.305 vt 0.283 0.557 0.304 vt 0.275 0.562 0.304 vt 0.287 0.574 0.301 vt 0.280 0.576 0.302 vt 0.266 0.557 0.308 vt 0.256 0.532 0.312 vt 0.275 0.578 0.305 vt 0.281 0.589 0.297 vt 0.276 0.591 0.304 vt 0.289 0.595 0.286 vt 0.285 0.583 0.295 vt 0.292 0.585 0.297 vt 0.296 0.596 0.297 vt 0.284 0.599 0.297 vt 0.293 0.605 0.292 vt 0.297 0.604 0.300 vt 0.288 0.606 0.299 vt 0.287 0.549 0.307 vt 0.295 0.570 0.306 vt 0.298 0.585 0.303 vt 0.285 0.520 0.310 vt 0.272 0.596 0.309 vt 0.268 0.579 0.312 vt 0.302 0.568 0.312 vt 0.304 0.586 0.309 vt 0.955 0.307 -0.059 vt 0.948 0.325 -0.059 vt 0.938 0.322 -0.059 vt 0.943 0.302 -0.059 vt 0.945 0.335 -0.059 vt 0.937 0.332 -0.059 vt 0.939 0.343 -0.059 vt 0.935 0.341 -0.059 vt 0.949 0.279 -0.059 vt 0.962 0.282 -0.059 vt 0.953 0.248 -0.059 vt 0.296 0.548 0.313 vt 0.294 0.526 0.313 vt 0.259 0.559 0.313 vt 0.311 0.515 0.307 vt 0.306 0.520 0.307 vt 0.315 0.517 0.306 vt 0.311 0.523 0.306 vt 0.323 0.524 0.304 vt 0.319 0.529 0.304 vt 0.333 0.531 0.303 vt 0.330 0.535 0.302 vt 0.310 0.532 0.308 vt 0.290 0.518 0.310 vt 0.327 0.542 0.306 vt 0.337 0.543 0.300 vt 0.337 0.548 0.306 vt 0.346 0.541 0.297 vt 0.337 0.536 0.299 vt 0.342 0.534 0.301 vt 0.351 0.539 0.299 vt 0.344 0.547 0.302 vt 0.322 0.517 0.308 vt 0.339 0.526 0.307 vt 0.346 0.531 0.305 vt 0.308 0.498 0.313 vt 0.335 0.553 0.312 vt 0.322 0.546 0.312 vt 0.340 0.517 0.313 vt 0.351 0.529 0.309 vt 0.932 0.243 -0.059 vt 0.927 0.260 -0.059 vt 0.917 0.257 -0.059 vt 0.923 0.240 -0.059 vt 0.924 0.270 -0.059 vt 0.914 0.267 -0.059 vt 0.927 0.219 -0.059 vt 0.939 0.224 -0.059 vt 0.930 0.194 -0.059 vt 0.950 0.203 -0.059 vt 0.326 0.509 0.314 vt 0.313 0.498 0.315 vt 0.306 0.537 0.313 vt 0.917 0.159 -0.059 vt 0.918 0.137 -0.059 vt 0.954 0.131 -0.059 vt 0.953 0.158 -0.059 vt 0.293 0.453 0.326 vt 0.301 0.463 0.324 vt 0.490 0.357 0.257 vt 0.515 0.310 0.257 vt 0.316 0.486 0.313 vt 0.316 0.491 0.312 vt 0.325 0.486 0.311 vt 0.325 0.491 0.311 vt 0.331 0.484 0.310 vt 0.332 0.489 0.310 vt 0.339 0.484 0.310 vt 0.340 0.489 0.310 vt 0.323 0.496 0.313 vt 0.310 0.496 0.313 vt 0.340 0.494 0.313 vt 0.348 0.489 0.310 vt 0.350 0.493 0.314 vt 0.356 0.484 0.310 vt 0.344 0.486 0.309 vt 0.348 0.480 0.311 vt 0.356 0.481 0.310 vt 0.355 0.489 0.313 vt 0.323 0.478 0.316 vt 0.339 0.476 0.315 vt 0.348 0.477 0.314 vt 0.306 0.478 0.318 vt 0.351 0.497 0.318 vt 0.339 0.498 0.317 vt 0.339 0.471 0.319 vt 0.350 0.472 0.319 vt 0.907 0.217 -0.059 vt 0.897 0.228 -0.059 vt 0.891 0.223 -0.059 vt 0.898 0.211 -0.059 vt 0.892 0.236 -0.059 vt 0.885 0.233 -0.059 vt 0.909 0.197 -0.059 vt 0.920 0.203 -0.059 vt 0.918 0.178 -0.059 vt 0.324 0.472 0.320 vt 0.310 0.470 0.322 vt 0.323 0.500 0.316 vt 0.176 0.085 0.401 vt 0.215 0.062 0.397 vt 0.153 0.089 0.396 vt 0.162 0.098 0.403 vt 0.145 0.098 0.397 vt 0.142 0.089 0.391 vt 0.137 0.117 0.393 vt 0.108 0.087 0.373 vt 0.147 0.068 0.378 vt 0.166 0.059 0.379 vt 0.171 0.074 0.392 vt 0.141 0.078 0.384 vt 0.953 0.836 0.434 vt 0.972 0.813 0.434 vt 0.986 0.844 0.428 vt 0.934 0.863 0.427 vt 0.075 0.646 0.962 vt 0.074 0.608 0.962 vt 0.090 0.585 0.962 vt 0.101 0.665 0.963 vt 0.100 0.713 0.964 vt 0.089 0.720 0.963 vt 0.079 0.677 0.963 vt 0.101 0.745 0.969 vt 0.096 0.746 0.962 vt 0.063 0.684 0.962 vt 0.058 0.658 0.962 vt 0.079 0.725 0.963 vt 0.091 0.752 0.963 vt 0.053 0.625 0.962 vt 0.164 0.685 0.962 vt 0.150 0.699 0.962 vt 0.142 0.688 0.962 vt 0.147 0.671 0.962 vt 0.104 0.747 0.962 vt 0.110 0.728 0.964 vt 0.117 0.733 0.963 vt 0.108 0.750 0.963 vt 0.116 0.710 0.963 vt 0.125 0.721 0.963 vt 0.125 0.672 0.963 vt 0.133 0.639 0.962 vt 0.160 0.712 0.962 vt 0.134 0.738 0.962 vt 0.114 0.667 0.963 vt 0.105 0.715 0.963 vt 0.161 0.043 0.599 vt 0.176 0.031 0.599 vt 0.186 0.055 0.382 vt 0.821 0.154 0.598 vt 0.830 0.180 0.599 vt 0.837 0.187 0.599 vt 0.846 0.183 0.599 vt 0.824 0.224 0.601 vt 0.847 0.227 0.600 vt 0.830 0.192 0.600 vt 0.813 0.199 0.600 vt 0.879 0.119 0.598 vt 0.850 0.158 0.598 vt 0.888 0.188 0.599 vt 0.903 0.130 0.599 vt 0.851 0.081 0.598 vt 0.822 0.095 0.597 vt 0.771 0.186 0.601 vt 0.785 0.197 0.601 vt 0.795 0.191 0.600 vt 0.797 0.177 0.600 vt 0.822 0.187 0.600 vt 0.873 0.214 0.600 vt 0.812 0.166 0.599 vt 0.766 0.207 0.602 vt 0.755 0.198 0.602 vt 0.750 0.214 0.602 vt 0.745 0.203 0.602 vt 0.753 0.195 0.602 vt 0.740 0.196 0.602 vt 0.737 0.165 0.600 vt 0.737 0.188 0.602 vt 0.753 0.218 0.602 vt 0.766 0.212 0.602 vt 0.751 0.237 0.602 vt 0.767 0.231 0.602 vt 0.777 0.219 0.602 vt 0.769 0.259 0.602 vt 0.784 0.243 0.602 vt 0.798 0.225 0.601 vt 0.758 0.276 0.602 vt 0.884 0.834 0.418 vt 0.846 0.815 0.389 vt 0.881 0.797 0.403 vt 0.905 0.808 0.417 vt 0.832 0.274 0.601 vt 0.870 0.264 0.600 vt 0.807 0.309 0.601 vt 0.763 0.151 0.599 vt 0.790 0.152 0.598 vt 0.785 0.129 0.597 vt 0.760 0.125 0.597 vt 0.748 0.150 0.599 vt 0.765 0.185 0.601 vt 0.764 0.175 0.601 vt 0.769 0.171 0.600 vt 0.760 0.174 0.601 vt 0.757 0.185 0.606 vt 0.751 0.187 0.606 vt 0.750 0.160 0.600 vt 0.761 0.172 0.600 vt 0.737 0.158 0.599 vt 0.844 0.324 0.601 vt 0.891 0.292 0.600 vt 0.888 0.768 0.401 vt 0.910 0.771 0.408 vt 0.752 0.937 0.721 vt 0.801 0.920 0.721 vt 0.816 0.938 0.722 vt 0.759 0.960 0.721 vt 0.736 0.957 0.721 vt 0.731 0.939 0.720 vt 0.700 0.960 0.721 vt 0.644 0.938 0.720 vt 0.655 0.926 0.719 vt 0.709 0.931 0.720 vt 0.612 0.920 0.701 vt 0.606 0.925 0.711 vt 0.730 0.896 0.720 vt 0.777 0.879 0.721 vt 0.704 0.902 0.720 vt 0.611 0.917 0.708 vt 0.653 0.913 0.717 vt 0.188 0.806 0.906 vt 0.220 0.794 0.906 vt 0.241 0.834 0.906 vt 0.191 0.856 0.906 vt 0.185 0.773 0.907 vt 0.205 0.767 0.906 vt 0.151 0.854 0.906 vt 0.160 0.807 0.906 vt 0.167 0.777 0.909 vt 0.119 0.850 0.906 vt 0.135 0.806 0.906 vt 0.148 0.779 0.908 vt 0.099 0.841 0.906 vt 0.124 0.803 0.906 vt 0.195 0.746 0.906 vt 0.183 0.749 0.906 vt 0.174 0.743 0.905 vt 0.195 0.900 0.906 vt 0.148 0.876 0.906 vt 0.971 0.755 0.431 vt 0.954 0.793 0.436 vt 0.943 0.747 0.431 vt 0.976 0.691 0.417 vt 0.952 0.704 0.423 vt 0.778 0.337 0.601 vt 0.769 0.309 0.601 vt 0.756 0.316 0.601 vt 0.770 0.334 0.601 vt 0.111 0.890 0.906 vt 0.771 0.353 0.601 vt 0.774 0.363 0.601 vt 0.405 0.669 0.427 vt 0.381 0.665 0.434 vt 0.371 0.694 0.450 vt 0.381 0.708 0.450 vt 0.367 0.640 0.426 vt 0.364 0.678 0.447 vt 0.416 0.655 0.417 vt 0.397 0.634 0.413 vt 0.372 0.598 0.401 vt 0.385 0.617 0.409 vt 0.796 0.204 0.601 vt 0.777 0.208 0.602 vt 0.785 0.214 0.602 vt 0.755 0.850 0.721 vt 0.756 0.817 0.721 vt 0.790 0.811 0.722 vt 0.779 0.847 0.721 vt 0.894 0.935 0.722 vt 0.864 0.975 0.722 vt 0.828 0.951 0.722 vt 0.893 0.927 0.722 vt 0.685 0.872 0.720 vt 0.669 0.827 0.721 vt 0.685 0.818 0.721 vt 0.706 0.858 0.720 vt 0.785 0.851 0.722 vt 0.764 0.862 0.721 vt 0.743 0.867 0.721 vt 0.716 0.874 0.720 vt 0.733 0.854 0.721 vt 0.625 0.885 0.720 vt 0.662 0.857 0.721 vt 0.643 0.895 0.718 vt 0.610 0.909 0.717 vt 0.604 0.909 0.717 vt 0.692 0.883 0.720 vt 0.136 0.074 0.377 vt 0.138 0.067 0.371 vt 0.134 0.056 0.365 vt 0.143 0.055 0.370 vt 0.825 0.070 0.597 vt 0.804 0.081 0.597 vt 0.789 0.097 0.596 vt 0.761 0.093 0.595 vt 0.780 0.077 0.596 vt 0.762 0.073 0.595 vt 0.770 0.054 0.595 vt 0.754 0.051 0.595 vt 0.805 0.057 0.597 vt 0.796 0.043 0.597 vt 0.792 0.039 0.597 vt 0.784 0.060 0.596 vt 0.746 0.033 0.595 vt 0.772 0.044 0.596 vt 0.755 0.024 0.596 vt 0.944 0.389 0.506 vt 0.988 0.393 0.540 vt 0.982 0.369 0.536 vt 0.948 0.371 0.510 vt 0.887 0.372 0.457 vt 0.893 0.379 0.455 vt 0.909 0.408 0.477 vt 0.912 0.391 0.479 vt 0.904 0.406 0.472 vt 0.877 0.372 0.443 vt 0.879 0.381 0.440 vt 0.741 0.011 0.596 vt 0.214 0.421 0.330 vt 0.029 0.141 0.173 vt 0.024 0.143 0.173 vt 0.022 0.118 0.173 vt 0.027 0.110 0.173 vt 0.014 0.144 0.173 vt 0.014 0.118 0.173 vt 0.036 0.190 0.173 vt 0.014 0.186 0.173 vt 0.040 0.189 0.173 vt 0.064 0.218 0.173 vt 0.056 0.222 0.173 vt 0.014 0.225 0.173 vt 0.014 0.080 0.173 vt 0.021 0.080 0.173 vt 0.025 0.080 0.172 vt 0.014 0.024 0.117 vt 0.029 0.038 0.111 vt 0.014 0.260 0.173 vt 0.053 0.233 0.173 vt 0.050 0.252 0.173 vt 0.063 0.255 0.173 vt 0.064 0.268 0.173 vt 0.050 0.266 0.173 vt 0.057 0.289 0.173 vt 0.067 0.290 0.173 vt 0.014 0.412 0.173 vt 0.014 0.382 0.173 vt 0.042 0.377 0.173 vt 0.050 0.406 0.173 vt 0.062 0.313 0.173 vt 0.054 0.307 0.173 vt 0.056 0.296 0.173 vt 0.072 0.332 0.173 vt 0.059 0.339 0.173 vt 0.051 0.313 0.173 vt 0.047 0.286 0.173 vt 0.090 0.421 0.173 vt 0.105 0.426 0.173 vt 0.124 0.445 0.173 vt 0.116 0.454 0.173 vt 0.100 0.415 0.173 vt 0.105 0.412 0.173 vt 0.102 0.419 0.173 vt 0.126 0.433 0.173 vt 0.085 0.393 0.173 vt 0.077 0.377 0.173 vt 0.086 0.382 0.168 vt 0.093 0.372 0.173 vt 0.071 0.440 0.173 vt 0.014 0.441 0.173 vt 0.014 0.345 0.173 vt 0.077 0.359 0.173 vt 0.691 0.337 0.601 vt 0.700 0.334 0.601 vt 0.696 0.362 0.601 vt 0.698 0.353 0.601 vt 0.765 0.978 0.721 vt 0.740 0.975 0.721 vt 0.799 0.868 0.721 vt 0.597 0.747 -0.465 vt 0.611 0.783 -0.437 vt 0.638 0.776 -0.437 vt 0.621 0.733 -0.465 vt 0.648 0.761 -0.440 vt 0.644 0.754 -0.446 vt 0.645 0.778 -0.437 vt 0.579 0.752 -0.465 vt 0.590 0.787 -0.440 vt 0.542 0.754 -0.462 vt 0.556 0.791 -0.451 vt 0.643 0.715 -0.465 vt 0.634 0.678 -0.468 vt 0.606 0.693 -0.456 vt 0.593 0.685 -0.461 vt 0.571 0.695 -0.460 vt 0.572 0.710 -0.457 vt 0.563 0.668 -0.455 vt 0.553 0.670 -0.459 vt 0.561 0.686 -0.437 vt 0.566 0.684 -0.426 vt 0.554 0.695 -0.446 vt 0.547 0.707 -0.450 vt 0.541 0.682 -0.446 vt 0.525 0.688 -0.442 vt 0.576 0.668 -0.453 vt 0.569 0.652 -0.505 vt 0.556 0.654 -0.501 vt 0.603 0.655 -0.496 vt 0.595 0.649 -0.493 vt 0.585 0.658 -0.494 vt 0.586 0.664 -0.492 vt 0.577 0.651 -0.498 vt 0.586 0.642 -0.488 vt 0.582 0.634 -0.511 vt 0.570 0.634 -0.513 vt 0.577 0.645 -0.494 vt 0.557 0.631 -0.502 vt 0.563 0.651 -0.516 vt 0.533 0.670 -0.497 vt 0.521 0.674 -0.487 vt 0.588 0.624 -0.500 vt 0.597 0.626 -0.482 vt 0.609 0.620 -0.451 vt 0.564 0.611 -0.444 vt 0.454 0.857 -0.466 vt 0.485 0.886 -0.467 vt 0.497 0.846 -0.461 vt 0.462 0.834 -0.465 vt 0.525 0.846 -0.458 vt 0.563 0.844 -0.459 vt 0.518 0.777 -0.462 vt 0.645 0.790 -0.437 vt 0.636 0.805 -0.444 vt 0.643 0.805 -0.440 vt 0.640 0.813 -0.425 vt 0.644 0.817 -0.430 vt 0.650 0.809 -0.442 vt 0.653 0.790 -0.438 vt 0.657 0.776 -0.440 vt 0.654 0.769 -0.436 vt 0.467 0.802 -0.465 vt 0.498 0.818 -0.462 vt 0.499 0.775 -0.465 vt 0.470 0.774 -0.467 vt 0.651 0.753 -0.447 vt 0.661 0.741 -0.451 vt 0.517 0.713 -0.454 vt 0.512 0.735 -0.456 vt 0.544 0.728 -0.465 vt 0.499 0.707 -0.479 vt 0.386 0.562 -0.685 vt 0.388 0.597 -0.685 vt 0.411 0.596 -0.685 vt 0.424 0.552 -0.685 vt 0.431 0.768 -0.467 vt 0.423 0.813 -0.467 vt 0.441 0.742 -0.469 vt 0.456 0.760 -0.468 vt 0.460 0.745 -0.469 vt 0.449 0.721 -0.469 vt 0.408 0.746 -0.469 vt 0.413 0.734 -0.469 vt 0.667 0.706 -0.465 vt 0.670 0.722 -0.461 vt 0.430 0.709 -0.454 vt 0.397 0.522 -0.685 vt 0.395 0.491 -0.685 vt 0.387 0.496 -0.685 vt 0.389 0.523 -0.685 vt 0.389 0.442 -0.685 vt 0.367 0.448 -0.685 vt 0.384 0.469 -0.685 vt 0.409 0.461 -0.685 vt 0.457 0.478 -0.685 vt 0.468 0.464 -0.696 vt 0.453 0.440 -0.697 vt 0.437 0.450 -0.685 vt 0.445 0.513 -0.685 vt 0.477 0.499 -0.685 vt 0.425 0.499 -0.685 vt 0.495 0.484 -0.696 vt 0.510 0.452 -0.642 vt 0.497 0.445 -0.646 vt 0.462 0.528 -0.685 vt 0.423 0.527 -0.685 vt 0.474 0.542 -0.685 vt 0.445 0.562 -0.685 vt 0.367 0.420 -0.685 vt 0.334 0.432 -0.685 vt 0.351 0.404 -0.685 vt 0.323 0.418 -0.685 vt 0.422 0.427 -0.685 vt 0.395 0.403 -0.685 vt 0.474 0.760 -0.468 vt 0.493 0.756 -0.468 vt 0.379 0.470 -0.685 vt 0.448 0.419 -0.705 vt 0.447 0.388 -0.709 vt 0.480 0.420 -0.637 vt 0.485 0.401 -0.627 vt 0.478 0.587 -0.685 vt 0.496 0.568 -0.685 vt 0.486 0.600 -0.685 vt 0.515 0.584 -0.685 vt 0.395 0.801 -0.468 vt 0.678 0.800 -0.452 vt 0.688 0.779 -0.457 vt 0.660 0.758 -0.446 vt 0.706 0.767 -0.457 vt 0.467 0.627 -0.685 vt 0.487 0.631 -0.685 vt 0.501 0.611 -0.685 vt 0.538 0.562 -0.685 vt 0.528 0.603 -0.685 vt 0.550 0.583 -0.685 vt 0.513 0.398 -0.667 vt 0.496 0.414 -0.604 vt 0.502 0.418 -0.600 vt 0.523 0.406 -0.679 vt 0.521 0.549 -0.685 vt 0.508 0.511 -0.685 vt 0.486 0.431 -0.620 vt 0.506 0.432 -0.616 vt 0.527 0.421 -0.676 vt 0.545 0.559 -0.712 vt 0.551 0.566 -0.701 vt 0.583 0.550 -0.708 vt 0.584 0.532 -0.709 vt 0.612 0.550 -0.709 vt 0.594 0.551 -0.709 vt 0.589 0.564 -0.710 vt 0.598 0.562 -0.709 vt 0.598 0.537 -0.709 vt 0.611 0.577 -0.710 vt 0.617 0.570 -0.710 vt 0.619 0.561 -0.709 vt 0.610 0.570 -0.709 vt 0.589 0.577 -0.701 vt 0.629 0.566 -0.710 vt 0.632 0.565 -0.709 vt 0.632 0.555 -0.709 vt 0.625 0.558 -0.709 vt 0.620 0.536 -0.709 vt 0.576 0.387 -0.709 vt 0.574 0.413 -0.709 vt 0.603 0.416 -0.709 vt 0.605 0.396 -0.709 vt 0.570 0.439 -0.708 vt 0.609 0.439 -0.709 vt 0.572 0.467 -0.708 vt 0.620 0.466 -0.709 vt 0.572 0.490 -0.708 vt 0.623 0.493 -0.709 vt 0.538 0.492 -0.708 vt 0.531 0.463 -0.706 vt 0.623 0.515 -0.709 vt 0.555 0.509 -0.709 vt 0.627 0.419 -0.709 vt 0.647 0.429 -0.709 vt 0.524 0.437 -0.666 vt 0.521 0.356 -0.709 vt 0.554 0.364 -0.708 vt 0.661 0.511 -0.709 vt 0.662 0.494 -0.709 vt 0.680 0.507 -0.709 vt 0.681 0.501 -0.709 vt 0.752 0.685 -0.953 vt 0.746 0.673 -0.953 vt 0.731 0.679 -0.953 vt 0.738 0.692 -0.953 vt 0.742 0.665 -0.954 vt 0.726 0.671 -0.953 vt 0.737 0.654 -0.954 vt 0.721 0.659 -0.954 vt 0.733 0.642 -0.955 vt 0.716 0.649 -0.955 vt 0.720 0.620 -0.957 vt 0.710 0.605 -0.958 vt 0.705 0.612 -0.959 vt 0.711 0.625 -0.957 vt 0.703 0.601 -0.958 vt 0.700 0.603 -0.961 vt 0.699 0.629 -0.957 vt 0.694 0.612 -0.958 vt 0.695 0.604 -0.958 vt 0.713 0.676 -0.954 vt 0.698 0.655 -0.954 vt 0.756 0.664 -0.953 vt 0.749 0.652 -0.954 vt 0.665 0.524 -0.709 vt 0.681 0.514 -0.709 vt 0.766 0.677 -0.953 vt 0.694 0.494 -0.709 vt 0.684 0.487 -0.709 vt 0.717 0.692 -0.953 vt 0.766 0.647 -0.954 vt 0.748 0.630 -0.954 vt 0.733 0.611 -0.955 vt 0.722 0.614 -0.956 vt 0.778 0.662 -0.953 vt 0.695 0.631 -0.956 vt 0.690 0.637 -0.955 vt 0.674 0.640 -0.954 vt 0.678 0.661 -0.954 vt 0.762 0.619 -0.954 vt 0.747 0.602 -0.954 vt 0.733 0.598 -0.955 vt 0.720 0.599 -0.956 vt 0.677 0.627 -0.955 vt 0.686 0.617 -0.956 vt 0.711 0.598 -0.957 vt 0.718 0.610 -0.957 vt 0.688 0.610 -0.957 vt 0.695 0.626 -0.957 vt 0.696 0.597 -0.957 vt 0.414 0.480 -0.685 vt 0.360 0.450 -0.685 vt 0.331 0.436 -0.685 vt 0.652 0.454 -0.709 vt 0.682 0.679 -0.954 vt 0.698 0.676 -0.954 vt 0.773 0.634 -0.954 vt 0.679 0.699 -0.953 vt 0.695 0.697 -0.953 vt 0.788 0.651 -0.953 vt 0.793 0.639 -0.953 vt 0.861 0.723 -0.888 vt 0.848 0.731 -0.892 vt 0.863 0.747 -0.890 vt 0.883 0.735 -0.890 vt 0.855 0.720 -0.882 vt 0.845 0.726 -0.890 vt 0.848 0.713 -0.894 vt 0.840 0.719 -0.901 vt 0.844 0.708 -0.911 vt 0.833 0.714 -0.922 vt 0.826 0.685 -0.961 vt 0.816 0.672 -1.002 vt 0.810 0.676 -0.999 vt 0.820 0.689 -0.959 vt 0.813 0.691 -0.977 vt 0.801 0.679 -1.017 vt 0.831 0.733 -0.932 vt 0.823 0.719 -0.947 vt 0.855 0.694 -0.951 vt 0.835 0.680 -0.979 vt 0.864 0.716 -0.907 vt 0.859 0.711 -0.910 vt 0.869 0.703 -0.942 vt 0.808 0.696 -0.991 vt 0.794 0.706 -1.006 vt 0.809 0.722 -0.968 vt 0.862 0.685 -0.968 vt 0.848 0.669 -1.006 vt 0.825 0.666 -1.010 vt 0.816 0.666 -1.013 vt 0.824 0.676 -0.985 vt 0.796 0.678 -1.013 vt 0.795 0.684 -1.010 vt 0.803 0.685 -1.003 vt 0.817 0.738 -0.955 vt 0.876 0.697 -0.955 vt 0.668 0.471 -0.709 vt 0.691 0.461 -0.709 vt 0.672 0.442 -0.708 vt 0.848 0.762 -0.935 vt 0.629 0.397 -0.709 vt 0.644 0.401 -0.709 vt 0.741 0.427 -0.750 vt 0.721 0.422 -0.704 vt 0.718 0.446 -0.708 vt 0.741 0.443 -0.728 vt 0.746 0.415 -0.734 vt 0.733 0.401 -0.694 vt 0.702 0.418 -0.714 vt 0.699 0.454 -0.709 vt 0.711 0.392 -0.725 vt 0.675 0.413 -0.707 vt 0.679 0.396 -0.703 vt 0.840 0.774 -0.966 vt 0.817 0.772 -0.983 vt 0.659 0.538 -0.709 vt 0.648 0.573 -0.709 vt 0.651 0.559 -0.709 vt 0.693 0.558 -0.709 vt 0.684 0.544 -0.709 vt 0.668 0.560 -0.709 vt 0.679 0.577 -0.709 vt 0.686 0.533 -0.709 vt 0.685 0.525 -0.709 vt 0.913 0.704 -0.983 vt 0.887 0.717 -0.934 vt 0.628 0.574 -0.709 vt 0.623 0.597 -0.709 vt 0.610 0.598 -0.709 vt 0.591 0.597 -0.711 vt 0.711 0.753 -0.884 vt 0.723 0.763 -0.883 vt 0.736 0.760 -0.893 vt 0.725 0.749 -0.889 vt 0.747 0.754 -0.900 vt 0.737 0.743 -0.895 vt 0.752 0.751 -0.914 vt 0.742 0.740 -0.909 vt 0.788 0.725 -1.001 vt 0.786 0.720 -1.007 vt 0.769 0.729 -0.962 vt 0.774 0.734 -0.957 vt 0.780 0.738 -0.972 vt 0.794 0.729 -1.014 vt 0.747 0.772 -0.931 vt 0.762 0.763 -0.952 vt 0.762 0.715 -0.999 vt 0.734 0.726 -0.947 vt 0.724 0.741 -0.908 vt 0.726 0.729 -0.939 vt 0.785 0.751 -0.999 vt 0.771 0.773 -0.970 vt 0.790 0.765 -1.007 vt 0.751 0.704 -1.007 vt 0.734 0.713 -0.970 vt 0.779 0.713 -1.005 vt 0.773 0.720 -0.989 vt 0.787 0.716 -1.012 vt 0.787 0.741 -0.991 vt 0.798 0.739 -1.005 vt 0.799 0.731 -1.012 vt 0.762 0.775 -0.961 vt 0.726 0.715 -0.961 vt 0.740 0.793 -0.968 vt 0.757 0.794 -0.975 vt 0.703 0.714 -0.975 vt 0.700 0.733 -0.937 vt 0.646 0.821 -0.443 vt 0.659 0.833 -0.454 vt 0.636 0.824 -0.446 vt 0.628 0.839 -0.451 vt 0.638 0.852 -0.457 vt 0.630 0.817 -0.442 vt 0.615 0.835 -0.450 vt 0.203 0.940 -0.291 vt 0.225 0.894 -0.291 vt 0.264 0.917 -0.291 vt 0.213 0.950 -0.291 vt 0.238 0.881 -0.291 vt 0.281 0.893 -0.291 vt 0.255 0.859 -0.291 vt 0.291 0.865 -0.291 vt 0.261 0.832 -0.291 vt 0.289 0.825 -0.291 vt 0.236 0.767 -0.291 vt 0.268 0.756 -0.291 vt 0.203 0.715 -0.291 vt 0.226 0.700 -0.291 vt 0.165 0.659 -0.292 vt 0.183 0.647 -0.292 vt 0.126 0.574 -0.292 vt 0.146 0.581 -0.292 vt 0.116 0.525 -0.292 vt 0.121 0.528 -0.292 vt 0.314 0.767 -0.291 vt 0.328 0.815 -0.291 vt 0.249 0.684 -0.291 vt 0.295 0.734 -0.291 vt 0.201 0.637 -0.292 vt 0.158 0.579 -0.292 vt 0.123 0.522 -0.292 vt 0.322 0.855 -0.291 vt 0.363 0.821 -0.291 vt 0.338 0.844 -0.290 vt 0.340 0.851 -0.290 vt 0.330 0.862 -0.290 vt 0.330 0.878 -0.290 vt 0.319 0.881 -0.290 vt 0.325 0.888 -0.290 vt 0.320 0.900 -0.291 vt 0.342 0.894 -0.290 vt 0.333 0.900 -0.290 vt 0.353 0.802 -0.291 vt 0.364 0.783 -0.291 vt 0.368 0.783 -0.285 vt 0.368 0.799 -0.290 vt 0.340 0.792 -0.291 vt 0.355 0.777 -0.291 vt 0.369 0.773 -0.291 vt 0.377 0.783 -0.291 vt 0.374 0.796 -0.291 vt 0.381 0.805 -0.291 vt 0.368 0.782 -0.284 vt 0.314 0.932 -0.291 vt 0.364 0.837 -0.290 vt 0.374 0.850 -0.290 vt 0.349 0.852 -0.290 vt 0.376 0.877 -0.290 vt 0.380 0.880 -0.290 vt 0.374 0.890 -0.290 vt 0.370 0.877 -0.290 vt 0.343 0.876 -0.290 vt 0.373 0.840 -0.290 vt 0.389 0.841 -0.290 vt 0.385 0.850 -0.290 vt 0.379 0.858 -0.290 vt 0.385 0.871 -0.290 vt 0.345 0.913 -0.290 vt 0.398 0.846 -0.291 vt 0.404 0.867 -0.291 vt 0.385 0.891 -0.290 vt 0.409 0.889 -0.291 vt 0.411 0.901 -0.291 vt 0.386 0.908 -0.290 vt 0.262 0.675 -0.291 vt 0.315 0.721 -0.291 vt 0.211 0.632 -0.292 vt 0.163 0.577 -0.292 vt 0.335 0.781 -0.291 vt 0.347 0.772 -0.291 vt 0.372 0.918 -0.290 vt 0.372 0.939 -0.290 vt 0.335 0.938 -0.291 vt 0.381 0.927 -0.292 vt 0.385 0.932 -0.287 vt 0.419 0.914 -0.291 vt 0.392 0.922 -0.290 vt 0.564 0.899 -0.417 vt 0.556 0.895 -0.436 vt 0.534 0.892 -0.435 vt 0.540 0.908 -0.399 vt 0.545 0.910 -0.381 vt 0.535 0.915 -0.422 vt 0.524 0.931 -0.385 vt 0.533 0.931 -0.422 vt 0.553 0.926 -0.441 vt 0.601 0.873 -0.460 vt 0.606 0.880 -0.452 vt 0.612 0.875 -0.459 vt 0.605 0.872 -0.459 vt 0.379 0.374 0.257 vt 0.395 0.331 0.257 vt 0.417 0.331 0.257 vt 0.397 0.365 0.257 vt 0.357 0.348 0.257 vt 0.369 0.339 0.257 vt 0.432 0.356 0.257 vt 0.416 0.362 0.257 vt 0.118 0.199 0.365 vt 0.098 0.201 0.360 vt 0.133 0.232 0.365 vt 0.138 0.210 0.372 vt 0.390 0.287 0.257 vt 0.374 0.298 0.257 vt 0.379 0.242 0.257 vt 0.399 0.237 0.257 vt 0.364 0.236 0.257 vt 0.375 0.199 0.257 vt 0.392 0.203 0.257 vt 0.393 0.185 0.257 vt 0.379 0.181 0.257 vt 0.519 0.123 0.194 vt 0.531 0.162 0.263 vt 0.498 0.157 0.248 vt 0.504 0.133 0.211 vt 0.438 0.941 -0.291 vt 0.413 0.942 -0.291 vt 0.384 0.962 -0.291 vt 0.395 0.939 -0.294 vt 0.412 0.962 -0.291 vt 0.395 0.986 -0.291 vt 0.376 0.973 -0.291 vt 0.498 0.055 0.095 vt 0.521 0.069 0.118 vt 0.506 0.088 0.158 vt 0.491 0.083 0.156 vt 0.370 0.379 0.257 vt 0.355 0.382 0.257 vt 0.466 0.318 0.257 vt 0.470 0.350 0.257 vt 0.544 0.158 0.263 vt 0.562 0.190 0.346 vt 0.548 0.208 0.346 vt 0.573 0.203 0.382 vt 0.569 0.217 0.399 vt 0.803 0.618 0.349 vt 0.817 0.623 0.386 vt 0.809 0.631 0.373 vt 0.802 0.627 0.353 vt 0.786 0.610 0.318 vt 0.835 0.588 0.402 vt 0.838 0.598 0.408 vt 0.846 0.608 0.435 vt 0.890 0.638 0.432 vt 0.911 0.586 0.497 vt 0.920 0.588 0.479 vt 0.911 0.637 0.402 vt 0.882 0.567 0.479 vt 0.887 0.576 0.499 vt 0.916 0.572 0.508 vt 0.925 0.574 0.493 vt 0.896 0.558 0.493 vt 0.900 0.564 0.511 vt 0.918 0.564 0.514 vt 0.925 0.564 0.500 vt 0.911 0.558 0.517 vt 0.907 0.552 0.500 vt 0.877 0.626 0.476 vt 0.902 0.583 0.521 vt 0.895 0.580 0.522 vt 0.853 0.614 0.458 vt 0.909 0.569 0.526 vt 0.914 0.561 0.527 vt 0.905 0.567 0.526 vt 0.865 0.619 0.481 vt 0.858 0.642 0.476 vt 0.828 0.632 0.426 vt 0.870 0.675 0.399 vt 0.858 0.656 0.452 vt 0.936 0.481 0.530 vt 0.936 0.499 0.553 vt 0.913 0.530 0.614 vt 0.900 0.508 0.615 vt 0.867 0.503 0.683 vt 0.902 0.477 0.613 vt 0.797 0.433 0.635 vt 0.778 0.485 0.697 vt 0.760 0.479 0.665 vt 0.770 0.443 0.614 vt 0.813 0.454 0.703 vt 0.799 0.492 0.741 vt 0.847 0.519 0.718 vt 0.830 0.513 0.759 vt 0.855 0.482 0.715 vt 0.829 0.478 0.733 vt 0.819 0.504 0.759 vt 0.872 0.434 0.726 vt 0.846 0.450 0.726 vt 0.821 0.436 0.685 vt 0.868 0.411 0.712 vt 0.821 0.456 0.726 vt 0.840 0.463 0.736 vt 0.831 0.472 0.761 vt 0.867 0.459 0.704 vt 0.843 0.479 0.726 vt 0.878 0.473 0.678 vt 0.319 0.117 0.426 vt 0.328 0.119 0.417 vt 0.337 0.110 0.409 vt 0.330 0.095 0.408 vt 0.858 0.530 0.687 vt 0.765 0.522 0.759 vt 0.753 0.522 0.747 vt 0.824 0.558 0.757 vt 0.808 0.551 0.799 vt 0.783 0.530 0.806 vt 0.805 0.543 0.814 vt 0.796 0.539 0.826 vt 0.875 0.545 0.665 vt 0.831 0.568 0.747 vt 0.805 0.583 0.799 vt 0.795 0.572 0.815 vt 0.766 0.559 0.843 vt 0.755 0.549 0.799 vt 0.784 0.565 0.850 vt 0.775 0.562 0.861 vt 0.756 0.582 0.841 vt 0.750 0.584 0.830 vt 0.769 0.593 0.830 vt 0.767 0.589 0.841 vt 0.762 0.582 0.856 vt 0.810 0.388 0.581 vt 0.782 0.420 0.591 vt 0.798 0.378 0.543 vt 0.961 0.985 0.382 vt 0.972 0.944 0.444 vt 0.959 0.938 0.454 vt 0.947 0.980 0.399 vt 0.918 0.921 0.543 vt 0.941 0.918 0.522 vt 0.933 0.899 0.550 vt 0.908 0.902 0.575 vt 0.928 0.961 0.452 vt 0.923 0.942 0.497 vt 0.977 0.906 0.501 vt 0.973 0.905 0.505 vt 0.967 0.898 0.528 vt 0.965 0.892 0.538 vt 0.293 0.111 0.446 vt 0.290 0.118 0.449 vt 0.303 0.115 0.440 vt 0.304 0.108 0.435 vt 0.282 0.106 0.451 vt 0.277 0.108 0.452 vt 0.947 0.645 0.476 vt 0.932 0.645 0.497 vt 0.953 0.621 0.516 vt 0.960 0.631 0.484 vt 0.845 0.391 0.653 vt 0.267 0.092 0.439 vt 0.267 0.100 0.447 vt 0.278 0.102 0.449 vt 0.292 0.099 0.441 vt 0.299 0.045 0.396 vt 0.269 0.058 0.420 vt 0.279 0.070 0.423 vt 0.307 0.058 0.404 vt 0.288 0.029 0.389 vt 0.277 0.011 0.381 vt 0.257 0.025 0.395 vt 0.266 0.039 0.406 vt 0.251 0.125 0.456 vt 0.243 0.124 0.453 vt 0.256 0.138 0.459 vt 0.263 0.135 0.458 vt 0.230 0.042 0.396 vt 0.234 0.058 0.410 vt 0.256 0.045 0.457 vt 0.255 0.047 0.442 vt 0.257 0.085 0.433 vt 0.223 0.076 0.415 vt 0.231 0.101 0.436 vt 0.257 0.098 0.443 vt 0.190 0.114 0.418 vt 0.181 0.094 0.409 vt 0.209 0.129 0.436 vt 0.229 0.128 0.449 vt 0.210 0.144 0.444 vt 0.228 0.141 0.458 vt 0.266 0.150 0.460 vt 0.265 0.144 0.457 vt 0.244 0.144 0.463 vt 0.284 0.252 0.376 vt 0.289 0.230 0.388 vt 0.258 0.236 0.390 vt 0.251 0.260 0.377 vt 0.250 0.284 0.365 vt 0.280 0.276 0.366 vt 0.212 0.270 0.374 vt 0.223 0.288 0.364 vt 0.255 0.308 0.356 vt 0.279 0.290 0.360 vt 0.223 0.310 0.356 vt 0.199 0.303 0.359 vt 0.185 0.262 0.371 vt 0.165 0.278 0.364 vt 0.177 0.311 0.356 vt 0.186 0.346 0.348 vt 0.209 0.343 0.348 vt 0.267 0.205 0.416 vt 0.295 0.211 0.405 vt 0.240 0.197 0.422 vt 0.234 0.239 0.387 vt 0.205 0.202 0.409 vt 0.199 0.238 0.383 vt 0.235 0.351 0.345 vt 0.229 0.388 0.336 vt 0.251 0.386 0.336 vt 0.248 0.349 0.345 vt 0.216 0.364 0.343 vt 0.209 0.388 0.336 vt 0.197 0.355 0.345 vt 0.188 0.357 0.345 vt 0.269 0.410 0.332 vt 0.248 0.409 0.331 vt 0.255 0.433 0.326 vt 0.266 0.431 0.327 vt 0.260 0.447 0.324 vt 0.268 0.445 0.325 vt 0.261 0.453 0.323 vt 0.275 0.448 0.325 vt 0.267 0.381 0.336 vt 0.228 0.413 0.331 vt 0.286 0.352 0.343 vt 0.293 0.354 0.342 vt 0.295 0.345 0.345 vt 0.285 0.344 0.345 vt 0.280 0.372 0.338 vt 0.290 0.376 0.338 vt 0.286 0.331 0.348 vt 0.298 0.334 0.348 vt 0.304 0.315 0.354 vt 0.282 0.312 0.354 vt 0.274 0.431 0.329 vt 0.282 0.412 0.332 vt 0.241 0.445 0.325 vt 0.298 0.284 0.364 vt 0.310 0.258 0.374 vt 0.320 0.234 0.385 vt 0.329 0.212 0.396 vt 0.475 0.201 0.257 vt 0.481 0.203 0.257 vt 0.481 0.242 0.257 vt 0.465 0.241 0.257 vt 0.493 0.218 0.257 vt 0.488 0.201 0.257 vt 0.367 0.022 0.372 vt 0.375 0.047 0.398 vt 0.387 0.049 0.417 vt 0.384 0.023 0.393 vt 0.389 0.068 0.435 vt 0.392 0.072 0.442 vt 0.410 0.055 0.452 vt 0.384 0.069 0.427 vt 0.824 0.635 0.423 vt 0.816 0.627 0.389 vt 0.425 0.079 0.423 vt 0.415 0.072 0.437 vt 0.410 0.092 0.409 vt 0.424 0.101 0.389 vt 0.383 0.075 0.434 vt 0.396 0.078 0.434 vt 0.337 0.243 0.377 vt 0.351 0.217 0.382 vt 0.353 0.236 0.372 vt 0.360 0.258 0.369 vt 0.333 0.190 0.402 vt 0.315 0.180 0.422 vt 0.306 0.191 0.446 vt 0.968 0.585 0.515 vt 0.975 0.577 0.490 vt 0.985 0.588 0.499 vt 0.983 0.599 0.526 vt 0.958 0.563 0.479 vt 0.965 0.554 0.452 vt 0.982 0.628 0.475 vt 0.984 0.660 0.426 vt 0.971 0.550 0.437 vt 0.983 0.570 0.475 vt 0.974 0.542 0.423 vt 0.979 0.539 0.426 vt 0.972 0.599 0.532 vt 0.952 0.599 0.553 vt 0.948 0.581 0.530 vt 0.152 0.219 0.378 vt 0.153 0.202 0.383 vt 0.143 0.197 0.377 vt 0.147 0.283 0.360 vt 0.146 0.310 0.354 vt 0.151 0.329 0.350 vt 0.164 0.349 0.347 vt 0.151 0.247 0.367 vt 0.172 0.239 0.376 vt 0.114 0.323 0.351 vt 0.117 0.341 0.348 vt 0.320 0.341 0.346 vt 0.327 0.317 0.352 vt 0.318 0.294 0.360 vt 0.342 0.306 0.356 vt 0.334 0.262 0.369 vt 0.355 0.272 0.363 vt 0.318 0.362 0.342 vt 0.286 0.439 0.329 vt 0.291 0.425 0.332 vt 0.160 0.455 0.334 vt 0.184 0.450 0.331 vt 0.181 0.432 0.334 vt 0.162 0.440 0.336 vt 0.163 0.399 0.339 vt 0.142 0.416 0.339 vt 0.203 0.450 0.328 vt 0.200 0.432 0.331 vt 0.185 0.398 0.336 vt 0.176 0.404 0.337 vt 0.201 0.371 0.342 vt 0.189 0.377 0.341 vt 0.171 0.383 0.340 vt 0.168 0.365 0.344 vt 0.149 0.359 0.345 vt 0.129 0.383 0.342 vt 0.125 0.364 0.345 vt 0.112 0.282 0.355 vt 0.090 0.293 0.352 vt 0.216 0.448 0.327 vt 0.216 0.464 0.323 vt 0.247 0.465 0.321 vt 0.203 0.465 0.325 vt 0.268 0.497 0.314 vt 0.283 0.485 0.316 vt 0.236 0.501 0.318 vt 0.249 0.504 0.315 vt 0.280 0.457 0.323 vt 0.292 0.474 0.319 vt 0.261 0.517 0.312 vt 0.272 0.513 0.311 vt 0.284 0.506 0.311 vt 0.292 0.498 0.312 vt 0.236 0.514 0.315 vt 0.245 0.518 0.313 vt 0.297 0.491 0.313 vt 0.301 0.485 0.315 vt 0.228 0.535 0.311 vt 0.233 0.538 0.310 vt 0.225 0.541 0.310 vt 0.231 0.544 0.309 vt 0.220 0.550 0.308 vt 0.225 0.553 0.308 vt 0.212 0.562 0.307 vt 0.219 0.565 0.306 vt 0.198 0.487 0.324 vt 0.205 0.493 0.322 vt 0.222 0.525 0.318 vt 0.216 0.542 0.313 vt 0.205 0.560 0.312 vt 0.198 0.570 0.309 vt 0.203 0.571 0.306 vt 0.204 0.580 0.303 vt 0.208 0.585 0.309 vt 0.213 0.576 0.305 vt 0.210 0.570 0.304 vt 0.199 0.579 0.307 vt 0.198 0.590 0.309 vt 0.202 0.591 0.311 vt 0.196 0.588 0.310 vt 0.192 0.466 0.328 vt 0.189 0.479 0.327 vt 0.413 0.279 0.257 vt 0.421 0.232 0.257 vt 0.420 0.203 0.257 vt 0.211 0.163 0.451 vt 0.218 0.150 0.456 vt 0.209 0.165 0.460 vt 0.251 0.154 0.471 vt 0.260 0.159 0.467 vt 0.273 0.164 0.459 vt 0.265 0.164 0.464 vt 0.234 0.187 0.439 vt 0.225 0.178 0.447 vt 0.208 0.187 0.428 vt 0.236 0.150 0.466 vt 0.229 0.149 0.464 vt 0.232 0.155 0.465 vt 0.243 0.152 0.467 vt 0.219 0.176 0.447 vt 0.222 0.170 0.456 vt 0.211 0.175 0.448 vt 0.270 0.189 0.433 vt 0.274 0.184 0.440 vt 0.261 0.177 0.452 vt 0.255 0.180 0.445 vt 0.235 0.549 0.311 vt 0.225 0.570 0.310 vt 0.217 0.580 0.310 vt 0.250 0.533 0.312 vt 0.192 0.569 0.313 vt 0.200 0.555 0.317 vt 0.230 0.573 0.316 vt 0.220 0.585 0.315 vt 0.990 0.300 -0.059 vt 0.979 0.302 -0.059 vt 0.982 0.319 -0.059 vt 0.991 0.318 -0.059 vt 0.992 0.329 -0.059 vt 0.984 0.330 -0.059 vt 0.991 0.339 -0.060 vt 0.988 0.340 -0.060 vt 0.976 0.280 -0.059 vt 0.988 0.278 -0.059 vt 0.971 0.257 -0.059 vt 0.986 0.256 -0.059 vt 0.242 0.556 0.316 vt 0.253 0.541 0.315 vt 0.213 0.520 0.322 vt 0.208 0.538 0.318 vt 0.189 0.497 0.323 vt 0.196 0.503 0.322 vt 0.185 0.501 0.323 vt 0.191 0.508 0.322 vt 0.179 0.505 0.323 vt 0.186 0.513 0.322 vt 0.179 0.497 0.325 vt 0.160 0.508 0.327 vt 0.166 0.512 0.324 vt 0.163 0.525 0.324 vt 0.167 0.529 0.325 vt 0.175 0.521 0.323 vt 0.173 0.514 0.322 vt 0.159 0.519 0.325 vt 0.155 0.532 0.325 vt 0.156 0.535 0.327 vt 0.151 0.529 0.327 vt 0.195 0.515 0.323 vt 0.179 0.526 0.325 vt 0.211 0.505 0.322 vt 0.155 0.501 0.329 vt 0.170 0.493 0.328 vt 0.197 0.522 0.326 vt 0.183 0.533 0.328 vt 0.940 0.076 -0.059 vt 0.939 0.088 -0.059 vt 0.958 0.089 -0.059 vt 0.959 0.078 -0.059 vt 0.966 0.079 -0.060 vt 0.965 0.089 -0.060 vt 0.976 0.079 -0.060 vt 0.972 0.092 -0.060 vt 0.987 0.086 -0.063 vt 0.986 0.093 -0.064 vt 0.925 0.090 -0.059 vt 0.922 0.076 -0.059 vt 0.210 0.519 0.325 vt 0.172 0.480 0.330 vt 0.225 0.507 0.320 vt 0.977 0.223 -0.059 vt 0.989 0.207 -0.059 vt 0.977 0.199 -0.059 vt 0.960 0.205 -0.059 vt 0.221 0.509 0.324 vt 0.990 0.237 -0.059 vt 0.270 0.543 0.307 vt 0.277 0.540 0.307 vt 0.273 0.551 0.305 vt 0.280 0.549 0.305 vt 0.275 0.562 0.304 vt 0.283 0.557 0.304 vt 0.280 0.576 0.302 vt 0.287 0.574 0.301 vt 0.256 0.532 0.312 vt 0.266 0.557 0.308 vt 0.275 0.578 0.305 vt 0.276 0.591 0.304 vt 0.281 0.589 0.297 vt 0.289 0.595 0.286 vt 0.296 0.596 0.297 vt 0.292 0.585 0.297 vt 0.285 0.583 0.295 vt 0.284 0.599 0.297 vt 0.293 0.605 0.292 vt 0.297 0.604 0.300 vt 0.288 0.606 0.299 vt 0.287 0.549 0.307 vt 0.295 0.570 0.306 vt 0.298 0.585 0.303 vt 0.285 0.520 0.310 vt 0.268 0.579 0.312 vt 0.272 0.596 0.309 vt 0.302 0.568 0.312 vt 0.304 0.586 0.309 vt 0.955 0.307 -0.059 vt 0.943 0.302 -0.059 vt 0.938 0.322 -0.059 vt 0.948 0.325 -0.059 vt 0.945 0.335 -0.059 vt 0.937 0.332 -0.059 vt 0.939 0.343 -0.059 vt 0.935 0.341 -0.059 vt 0.949 0.279 -0.059 vt 0.962 0.282 -0.059 vt 0.953 0.248 -0.059 vt 0.296 0.548 0.313 vt 0.294 0.526 0.313 vt 0.259 0.559 0.313 vt 0.306 0.520 0.307 vt 0.311 0.515 0.307 vt 0.311 0.523 0.306 vt 0.315 0.517 0.306 vt 0.319 0.529 0.304 vt 0.323 0.524 0.304 vt 0.330 0.535 0.302 vt 0.333 0.531 0.303 vt 0.290 0.518 0.310 vt 0.310 0.532 0.308 vt 0.327 0.542 0.306 vt 0.337 0.548 0.306 vt 0.337 0.543 0.300 vt 0.346 0.541 0.297 vt 0.351 0.539 0.299 vt 0.342 0.534 0.301 vt 0.337 0.536 0.299 vt 0.344 0.547 0.302 vt 0.322 0.517 0.308 vt 0.339 0.526 0.307 vt 0.346 0.531 0.305 vt 0.308 0.498 0.313 vt 0.335 0.553 0.312 vt 0.322 0.546 0.312 vt 0.340 0.517 0.313 vt 0.351 0.529 0.309 vt 0.932 0.243 -0.059 vt 0.923 0.240 -0.059 vt 0.917 0.257 -0.059 vt 0.927 0.260 -0.059 vt 0.924 0.270 -0.059 vt 0.914 0.267 -0.059 vt 0.927 0.219 -0.059 vt 0.939 0.224 -0.059 vt 0.930 0.194 -0.059 vt 0.950 0.203 -0.059 vt 0.326 0.509 0.314 vt 0.313 0.498 0.315 vt 0.306 0.537 0.313 vt 0.917 0.159 -0.059 vt 0.953 0.158 -0.059 vt 0.954 0.131 -0.059 vt 0.918 0.137 -0.059 vt 0.293 0.453 0.326 vt 0.301 0.463 0.324 vt 0.515 0.310 0.257 vt 0.490 0.357 0.257 vt 0.316 0.491 0.312 vt 0.316 0.486 0.313 vt 0.325 0.491 0.311 vt 0.325 0.486 0.311 vt 0.332 0.489 0.310 vt 0.331 0.484 0.310 vt 0.340 0.489 0.310 vt 0.339 0.484 0.310 vt 0.310 0.496 0.313 vt 0.323 0.496 0.313 vt 0.340 0.494 0.313 vt 0.350 0.493 0.314 vt 0.348 0.489 0.310 vt 0.356 0.484 0.310 vt 0.356 0.481 0.310 vt 0.348 0.480 0.311 vt 0.344 0.486 0.309 vt 0.355 0.489 0.313 vt 0.323 0.478 0.316 vt 0.339 0.476 0.315 vt 0.348 0.477 0.314 vt 0.306 0.478 0.318 vt 0.351 0.497 0.318 vt 0.339 0.498 0.317 vt 0.339 0.471 0.319 vt 0.350 0.472 0.319 vt 0.907 0.217 -0.059 vt 0.898 0.211 -0.059 vt 0.891 0.223 -0.059 vt 0.897 0.228 -0.059 vt 0.892 0.236 -0.059 vt 0.885 0.233 -0.059 vt 0.909 0.197 -0.059 vt 0.920 0.203 -0.059 vt 0.918 0.178 -0.059 vt 0.324 0.472 0.320 vt 0.310 0.470 0.322 vt 0.323 0.500 0.316 vt 0.215 0.062 0.397 vt 0.176 0.085 0.401 vt 0.153 0.089 0.396 vt 0.142 0.089 0.391 vt 0.145 0.098 0.397 vt 0.162 0.098 0.403 vt 0.137 0.117 0.393 vt 0.108 0.087 0.373 vt 0.147 0.068 0.378 vt 0.141 0.078 0.384 vt 0.171 0.074 0.392 vt 0.166 0.059 0.379 vt 0.953 0.836 0.434 vt 0.934 0.863 0.427 vt 0.986 0.844 0.428 vt 0.972 0.813 0.434 vt 0.075 0.646 0.962 vt 0.101 0.665 0.963 vt 0.090 0.585 0.962 vt 0.074 0.608 0.962 vt 0.100 0.713 0.964 vt 0.079 0.677 0.963 vt 0.089 0.720 0.963 vt 0.096 0.746 0.962 vt 0.101 0.745 0.969 vt 0.063 0.684 0.962 vt 0.058 0.658 0.962 vt 0.079 0.725 0.963 vt 0.091 0.752 0.963 vt 0.053 0.625 0.962 vt 0.164 0.685 0.962 vt 0.147 0.671 0.962 vt 0.142 0.688 0.962 vt 0.150 0.699 0.962 vt 0.104 0.747 0.962 vt 0.108 0.750 0.963 vt 0.117 0.733 0.963 vt 0.110 0.728 0.964 vt 0.125 0.721 0.963 vt 0.116 0.710 0.963 vt 0.125 0.672 0.963 vt 0.133 0.639 0.962 vt 0.134 0.738 0.962 vt 0.160 0.712 0.962 vt 0.105 0.715 0.963 vt 0.114 0.667 0.963 vt 0.161 0.043 0.599 vt 0.186 0.055 0.382 vt 0.176 0.031 0.599 vt 0.884 0.834 0.418 vt 0.905 0.808 0.417 vt 0.881 0.797 0.403 vt 0.846 0.815 0.389 vt 0.888 0.768 0.401 vt 0.910 0.771 0.408 vt 0.752 0.937 0.721 vt 0.759 0.960 0.721 vt 0.816 0.938 0.722 vt 0.801 0.920 0.721 vt 0.736 0.957 0.721 vt 0.731 0.939 0.720 vt 0.700 0.960 0.721 vt 0.709 0.931 0.720 vt 0.655 0.926 0.719 vt 0.644 0.938 0.720 vt 0.612 0.920 0.701 vt 0.606 0.925 0.711 vt 0.777 0.879 0.721 vt 0.730 0.896 0.720 vt 0.704 0.902 0.720 vt 0.653 0.913 0.717 vt 0.611 0.917 0.708 vt 0.188 0.806 0.906 vt 0.191 0.856 0.906 vt 0.241 0.834 0.906 vt 0.220 0.794 0.906 vt 0.185 0.773 0.907 vt 0.205 0.767 0.906 vt 0.151 0.854 0.906 vt 0.160 0.807 0.906 vt 0.167 0.777 0.909 vt 0.119 0.850 0.906 vt 0.135 0.806 0.906 vt 0.148 0.779 0.908 vt 0.124 0.803 0.906 vt 0.099 0.841 0.906 vt 0.195 0.746 0.906 vt 0.183 0.749 0.906 vt 0.174 0.743 0.905 vt 0.195 0.900 0.906 vt 0.148 0.876 0.906 vt 0.971 0.755 0.431 vt 0.943 0.747 0.431 vt 0.954 0.793 0.436 vt 0.976 0.691 0.417 vt 0.952 0.704 0.423 vt 0.111 0.890 0.906 vt 0.755 0.850 0.721 vt 0.779 0.847 0.721 vt 0.790 0.811 0.722 vt 0.756 0.817 0.721 vt 0.894 0.935 0.722 vt 0.828 0.951 0.722 vt 0.864 0.975 0.722 vt 0.904 0.978 0.721 vt 0.685 0.872 0.720 vt 0.685 0.818 0.721 vt 0.669 0.827 0.721 vt 0.662 0.857 0.721 vt 0.764 0.862 0.721 vt 0.785 0.851 0.722 vt 0.743 0.867 0.721 vt 0.733 0.854 0.721 vt 0.706 0.858 0.720 vt 0.716 0.874 0.720 vt 0.625 0.885 0.720 vt 0.643 0.895 0.718 vt 0.610 0.909 0.717 vt 0.604 0.909 0.717 vt 0.692 0.883 0.720 vt 0.136 0.074 0.377 vt 0.138 0.067 0.371 vt 0.134 0.056 0.365 vt 0.143 0.055 0.370 vt 0.944 0.389 0.506 vt 0.948 0.371 0.510 vt 0.982 0.369 0.536 vt 0.988 0.393 0.540 vt 0.893 0.379 0.455 vt 0.887 0.372 0.457 vt 0.909 0.408 0.477 vt 0.904 0.406 0.472 vt 0.912 0.391 0.479 vt 0.877 0.372 0.443 vt 0.879 0.381 0.440 vt 0.214 0.421 0.330 vt 0.765 0.978 0.721 vt 0.740 0.975 0.721 vt 0.799 0.868 0.721 vt 0.619 0.182 0.599 vt 0.733 0.144 0.598 vt 0.723 0.176 0.596 vt 0.712 0.174 0.600 vt 0.563 0.337 0.616 vt 0.589 0.348 0.604 vt 0.562 0.075 0.607 vt 0.613 0.056 0.591 vt 0.637 0.035 0.604 vt 0.687 0.032 0.597 vt 0.734 0.006 0.596 vt 0.281 0.943 0.494 vt 0.351 0.673 0.445 vt 0.350 0.730 0.468 vt 0.351 0.694 0.455 vt 0.593 0.846 -0.455 vt 0.640 0.820 -0.420 vt 0.573 0.682 -0.408 vt 0.553 0.683 -0.421 vt 0.583 0.651 -0.475 vt 0.601 0.639 -0.491 vt 0.531 0.626 -0.447 vt 0.538 0.653 -0.511 vt 0.529 0.660 -0.506 vt 0.545 0.641 -0.514 vt 0.616 0.646 -0.504 vt 0.592 0.630 -0.504 vt 0.648 0.640 -0.468 vt 0.437 0.628 -0.685 vt 0.420 0.613 -0.685 vt 0.527 0.653 -0.492 vt 0.510 0.640 -0.443 vt 0.649 0.787 -0.420 vt 0.654 0.764 -0.418 vt 0.653 0.759 -0.433 vt 0.501 0.744 -0.468 vt 0.658 0.665 -0.468 vt 0.438 0.697 -0.491 vt 0.450 0.649 -0.685 vt 0.474 0.655 -0.685 vt 0.547 0.524 -0.709 vt 0.528 0.525 -0.708 vt 0.499 0.369 -0.697 vt 0.568 0.575 -0.720 vt 0.554 0.586 -0.723 vt 0.564 0.596 -0.696 vt 0.613 0.558 -0.709 vt 0.698 0.510 -0.709 vt 0.300 0.430 -0.685 vt 0.683 0.473 -0.709 vt 0.701 0.483 -0.709 vt 0.714 0.492 -0.709 vt 0.805 0.670 -1.024 vt 0.836 0.665 -1.013 vt 0.792 0.694 -1.013 vt 0.741 0.458 -0.752 vt 0.703 0.574 -0.710 vt 0.795 0.722 -1.024 vt 0.767 0.704 -1.015 vt 0.798 0.753 -1.015 vt 0.730 0.778 -0.915 vt 0.729 0.554 -0.937 vt 0.726 0.573 -0.831 vt 0.710 0.560 -0.852 vt 0.609 0.865 -0.458 vt 0.617 0.861 -0.457 vt 0.343 0.860 -0.290 vt 0.342 0.888 -0.290 vt 0.378 0.838 -0.290 vt 0.371 0.864 -0.290 vt 0.374 0.872 -0.291 vt 0.379 0.866 -0.246 vt 0.375 0.908 -0.290 vt 0.371 0.896 -0.290 vt 0.379 0.905 -0.290 vt 0.492 0.904 -0.459 vt 0.336 0.740 -0.291 vt 0.333 0.746 -0.291 vt 0.346 0.750 -0.291 vt 0.342 0.756 -0.291 vt 0.356 0.761 -0.291 vt 0.118 0.520 -0.292 vt 0.389 0.825 -0.291 vt 0.387 0.925 -0.262 vt 0.048 0.758 0.173 vt 0.054 0.734 0.173 vt 0.061 0.742 0.173 vt 0.640 0.862 -0.460 vt 0.059 0.979 0.173 vt 0.117 0.988 0.173 vt 0.061 0.959 0.173 vt 0.576 0.888 -0.406 vt 0.589 0.865 -0.461 vt 0.584 0.882 -0.410 vt 0.589 0.886 -0.402 vt 0.585 0.893 -0.415 vt 0.573 0.899 -0.388 vt 0.560 0.906 -0.441 vt 0.547 0.916 -0.399 vt 0.540 0.913 -0.377 vt 0.360 0.961 -0.290 vt 0.373 0.951 -0.256 vt 0.362 0.949 -0.295 vt 0.519 0.920 -0.431 vt 0.511 0.928 -0.430 vt 0.374 0.966 -0.291 vt 0.547 0.942 -0.405 vt 0.526 0.940 -0.403 vt 0.550 0.921 -0.418 vt 0.580 0.910 -0.445 vt 0.006 0.834 0.173 vt 0.077 0.888 0.183 vt 0.449 0.282 0.257 vt 0.479 0.051 0.100 vt 0.444 0.043 0.119 vt 0.432 0.255 0.257 vt 0.461 0.209 0.257 vt 0.449 0.205 0.257 vt 0.402 0.182 0.257 vt 0.390 0.164 0.257 vt 0.466 0.191 0.257 vt 0.483 0.175 0.298 vt 0.515 0.190 0.292 vt 0.420 0.181 0.257 vt 0.481 0.285 0.257 vt 0.457 0.189 0.257 vt 0.469 0.185 0.257 vt 0.434 0.178 0.257 vt 0.451 0.183 0.257 vt 0.520 0.211 0.318 vt 0.542 0.123 0.193 vt 0.551 0.080 0.107 vt 0.889 0.682 0.346 vt 0.916 0.688 0.318 vt 0.919 0.555 0.518 vt 0.993 0.520 0.543 vt 0.992 0.501 0.497 vt 0.942 0.525 0.591 vt 0.316 0.159 0.424 vt 0.318 0.136 0.427 vt 0.338 0.152 0.409 vt 0.335 0.167 0.406 vt 0.383 0.100 0.375 vt 0.356 0.108 0.394 vt 0.348 0.088 0.393 vt 0.339 0.128 0.404 vt 0.338 0.125 0.414 vt 0.757 0.592 0.841 vt 0.943 0.660 0.452 vt 0.973 0.893 0.530 vt 0.111 0.974 0.173 vt 0.006 0.974 0.173 vt 0.168 0.154 0.405 vt 0.178 0.161 0.411 vt 0.159 0.169 0.397 vt 0.121 0.975 0.173 vt 0.329 0.077 0.404 vt 0.298 0.083 0.425 vt 0.283 0.074 0.424 vt 0.260 0.064 0.448 vt 0.268 0.076 0.426 vt 0.300 0.140 0.439 vt 0.311 0.144 0.433 vt 0.956 0.501 0.544 vt 0.819 0.374 0.575 vt 0.266 0.050 0.414 vt 0.250 0.073 0.424 vt 0.253 0.060 0.417 vt 0.254 0.051 0.427 vt 0.255 0.035 0.419 vt 0.254 0.037 0.416 vt 0.241 0.028 0.395 vt 0.275 0.127 0.461 vt 0.270 0.119 0.459 vt 0.263 0.114 0.480 vt 0.261 0.106 0.451 vt 0.277 0.133 0.454 vt 0.249 0.114 0.452 vt 0.264 0.127 0.479 vt 0.260 0.125 0.465 vt 0.287 0.152 0.447 vt 0.184 0.152 0.421 vt 0.193 0.173 0.429 vt 0.182 0.174 0.411 vt 0.245 0.132 0.459 vt 0.300 0.171 0.432 vt 0.284 0.171 0.452 vt 0.281 0.163 0.460 vt 0.274 0.175 0.482 vt 0.250 0.185 0.436 vt 0.164 0.208 0.388 vt 0.270 0.356 0.342 vt 0.270 0.341 0.347 vt 0.297 0.296 0.359 vt 0.157 0.188 0.388 vt 0.144 0.175 0.386 vt 0.129 0.958 0.173 vt 0.494 0.243 0.257 vt 0.400 0.029 0.419 vt 0.350 0.036 0.373 vt 0.364 0.064 0.409 vt 0.352 0.052 0.389 vt 0.427 0.055 0.479 vt 0.973 0.619 0.494 vt 0.985 0.611 0.499 vt 0.940 0.614 0.544 vt 0.968 0.611 0.520 vt 0.507 0.282 0.257 vt 0.121 0.192 0.368 vt 0.134 0.253 0.361 vt 0.301 0.395 0.336 vt 0.186 0.473 0.330 vt 0.983 0.184 -0.059 vt 0.964 0.180 -0.059 vt 0.176 0.469 0.332 vt 0.217 0.164 0.460 vt 0.245 0.188 0.433 vt 0.251 0.161 0.472 vt 0.255 0.171 0.463 vt 0.244 0.168 0.464 vt 0.243 0.177 0.453 vt 0.244 0.162 0.481 vt 0.230 0.169 0.459 vt 0.227 0.172 0.460 vt 0.237 0.178 0.464 vt 0.228 0.165 0.461 vt 0.232 0.146 0.470 vt 0.236 0.146 0.465 vt 0.210 0.587 0.312 vt 0.196 0.578 0.310 vt 0.197 0.592 0.312 vt 0.990 0.344 -0.060 vt 0.176 0.535 0.328 vt 0.170 0.531 0.327 vt 0.157 0.518 0.327 vt 0.152 0.509 0.329 vt 0.152 0.534 0.327 vt 0.989 0.090 -0.058 vt 0.299 0.595 0.303 vt 0.281 0.600 0.302 vt 0.294 0.608 0.301 vt 0.935 0.346 -0.059 vt 0.358 0.551 0.309 vt 0.914 0.284 -0.059 vt 0.353 0.537 0.303 vt 0.344 0.550 0.307 vt 0.927 0.112 -0.059 vt 0.365 0.486 0.317 vt 0.883 0.245 -0.060 vt 0.357 0.480 0.312 vt 0.356 0.491 0.316 vt 0.991 0.220 -0.059 vt 0.220 0.056 0.399 vt 0.841 0.831 0.393 vt 0.829 0.813 0.379 vt 0.858 0.858 0.410 vt 0.468 0.690 0.962 vt 0.483 0.681 0.962 vt 0.478 0.704 0.962 vt 0.174 0.698 0.962 vt 0.112 0.757 0.963 vt 0.109 0.595 0.962 vt 0.123 0.601 0.962 vt 0.101 0.755 0.963 vt 0.745 0.176 0.596 vt 0.756 0.173 0.600 vt 0.905 0.338 0.601 vt 0.878 0.898 0.722 vt 0.855 0.884 0.722 vt 0.820 0.876 0.722 vt 0.218 0.872 0.906 vt 0.183 0.732 0.906 vt 0.086 0.812 0.906 vt 0.122 0.781 0.906 vt 0.146 0.755 0.906 vt 0.164 0.738 0.906 vt 0.146 0.923 0.906 vt 0.125 0.908 0.906 vt 0.917 0.743 0.428 vt 0.180 0.930 0.906 vt 0.879 0.349 0.601 vt 0.953 0.683 0.417 vt 0.955 0.673 0.413 vt 0.716 0.822 0.721 vt 0.811 0.978 0.722 vt 0.904 0.978 0.721 vt 0.604 0.916 0.715 vt 0.904 0.074 0.599 vt 0.853 0.056 0.598 vt 0.829 0.035 0.598 vt 0.779 0.031 0.597 vt 0.493 0.680 0.946 vt 0.940 0.431 0.494 vt 0.055 0.249 0.173 vt 0.062 0.225 0.173 vt 0.068 0.234 0.173 vt 0.067 0.471 0.173 vt 0.068 0.450 0.173 vt 0.124 0.480 0.173 vt 0.014 0.325 0.173 vt 0.085 0.380 0.183 vt 0.119 0.465 0.173 vt 0.014 0.465 0.173 vt 0.129 0.467 0.173 vt 0.136 0.449 0.173 vt 0.593 0.846 -0.455 vt 0.640 0.820 -0.420 vt 0.573 0.682 -0.408 vt 0.553 0.683 -0.421 vt 0.583 0.651 -0.475 vt 0.601 0.639 -0.491 vt 0.531 0.626 -0.447 vt 0.538 0.653 -0.511 vt 0.529 0.660 -0.506 vt 0.545 0.641 -0.514 vt 0.616 0.646 -0.504 vt 0.592 0.630 -0.504 vt 0.648 0.640 -0.468 vt 0.437 0.628 -0.685 vt 0.420 0.613 -0.685 vt 0.527 0.653 -0.492 vt 0.510 0.640 -0.443 vt 0.649 0.787 -0.420 vt 0.654 0.764 -0.418 vt 0.653 0.759 -0.433 vt 0.501 0.744 -0.468 vt 0.658 0.665 -0.468 vt 0.438 0.697 -0.491 vt 0.450 0.649 -0.685 vt 0.474 0.655 -0.685 vt 0.547 0.524 -0.709 vt 0.528 0.525 -0.708 vt 0.499 0.369 -0.697 vt 0.568 0.575 -0.720 vt 0.554 0.586 -0.723 vt 0.564 0.596 -0.696 vt 0.613 0.558 -0.709 vt 0.698 0.510 -0.709 vt 0.300 0.430 -0.685 vt 0.683 0.473 -0.709 vt 0.714 0.492 -0.709 vt 0.701 0.483 -0.709 vt 0.805 0.670 -1.024 vt 0.836 0.665 -1.013 vt 0.792 0.694 -1.013 vt 0.741 0.458 -0.752 vt 0.703 0.574 -0.710 vt 0.795 0.722 -1.024 vt 0.767 0.704 -1.015 vt 0.798 0.753 -1.015 vt 0.730 0.778 -0.915 vt 0.729 0.554 -0.937 vt 0.710 0.560 -0.852 vt 0.726 0.573 -0.831 vt 0.609 0.865 -0.458 vt 0.617 0.861 -0.457 vt 0.343 0.860 -0.290 vt 0.342 0.888 -0.290 vt 0.378 0.838 -0.290 vt 0.371 0.864 -0.290 vt 0.379 0.866 -0.246 vt 0.374 0.872 -0.291 vt 0.375 0.908 -0.290 vt 0.371 0.896 -0.290 vt 0.379 0.905 -0.290 vt 0.492 0.904 -0.459 vt 0.336 0.740 -0.291 vt 0.333 0.746 -0.291 vt 0.346 0.750 -0.291 vt 0.342 0.756 -0.291 vt 0.356 0.761 -0.291 vt 0.118 0.520 -0.292 vt 0.389 0.825 -0.291 vt 0.387 0.925 -0.262 vt 0.640 0.862 -0.460 vt 0.576 0.888 -0.406 vt 0.589 0.865 -0.461 vt 0.584 0.882 -0.410 vt 0.585 0.893 -0.415 vt 0.589 0.886 -0.402 vt 0.573 0.899 -0.388 vt 0.560 0.906 -0.441 vt 0.547 0.916 -0.399 vt 0.540 0.913 -0.377 vt 0.360 0.961 -0.290 vt 0.362 0.949 -0.295 vt 0.373 0.951 -0.256 vt 0.519 0.920 -0.431 vt 0.511 0.928 -0.430 vt 0.374 0.966 -0.291 vt 0.526 0.940 -0.403 vt 0.547 0.942 -0.405 vt 0.550 0.921 -0.418 vt 0.580 0.910 -0.445 vt 0.449 0.282 0.257 vt 0.479 0.051 0.100 vt 0.444 0.043 0.119 vt 0.432 0.255 0.257 vt 0.461 0.209 0.257 vt 0.449 0.205 0.257 vt 0.402 0.182 0.257 vt 0.390 0.164 0.257 vt 0.466 0.191 0.257 vt 0.483 0.175 0.298 vt 0.515 0.190 0.292 vt 0.420 0.181 0.257 vt 0.481 0.285 0.257 vt 0.457 0.189 0.257 vt 0.469 0.185 0.257 vt 0.434 0.178 0.257 vt 0.451 0.183 0.257 vt 0.520 0.211 0.318 vt 0.542 0.123 0.193 vt 0.551 0.080 0.107 vt 0.889 0.682 0.346 vt 0.916 0.688 0.318 vt 0.919 0.555 0.518 vt 0.993 0.520 0.543 vt 0.942 0.525 0.591 vt 0.992 0.501 0.497 vt 0.316 0.159 0.424 vt 0.338 0.152 0.409 vt 0.318 0.136 0.427 vt 0.335 0.167 0.406 vt 0.383 0.100 0.375 vt 0.348 0.088 0.393 vt 0.356 0.108 0.394 vt 0.338 0.125 0.414 vt 0.339 0.128 0.404 vt 0.757 0.592 0.841 vt 0.943 0.660 0.452 vt 0.973 0.893 0.530 vt 0.168 0.154 0.405 vt 0.159 0.169 0.397 vt 0.178 0.161 0.411 vt 0.329 0.077 0.404 vt 0.298 0.083 0.425 vt 0.283 0.074 0.424 vt 0.260 0.064 0.448 vt 0.268 0.076 0.426 vt 0.300 0.140 0.439 vt 0.311 0.144 0.433 vt 0.956 0.501 0.544 vt 0.819 0.374 0.575 vt 0.266 0.050 0.414 vt 0.250 0.073 0.424 vt 0.253 0.060 0.417 vt 0.254 0.051 0.427 vt 0.255 0.035 0.419 vt 0.254 0.037 0.416 vt 0.241 0.028 0.395 vt 0.270 0.119 0.459 vt 0.275 0.127 0.461 vt 0.263 0.114 0.480 vt 0.261 0.106 0.451 vt 0.277 0.133 0.454 vt 0.249 0.114 0.452 vt 0.264 0.127 0.479 vt 0.260 0.125 0.465 vt 0.287 0.152 0.447 vt 0.184 0.152 0.421 vt 0.193 0.173 0.429 vt 0.182 0.174 0.411 vt 0.245 0.132 0.459 vt 0.300 0.171 0.432 vt 0.284 0.171 0.452 vt 0.281 0.163 0.460 vt 0.274 0.175 0.482 vt 0.250 0.185 0.436 vt 0.164 0.208 0.388 vt 0.270 0.356 0.342 vt 0.270 0.341 0.347 vt 0.297 0.296 0.359 vt 0.157 0.188 0.388 vt 0.144 0.175 0.386 vt 0.494 0.243 0.257 vt 0.400 0.029 0.419 vt 0.350 0.036 0.373 vt 0.364 0.064 0.409 vt 0.352 0.052 0.389 vt 0.427 0.055 0.479 vt 0.985 0.611 0.499 vt 0.973 0.619 0.494 vt 0.940 0.614 0.544 vt 0.968 0.611 0.520 vt 0.507 0.282 0.257 vt 0.121 0.192 0.368 vt 0.134 0.253 0.361 vt 0.301 0.395 0.336 vt 0.186 0.473 0.330 vt 0.983 0.184 -0.059 vt 0.964 0.180 -0.059 vt 0.176 0.469 0.332 vt 0.217 0.164 0.460 vt 0.245 0.188 0.433 vt 0.251 0.161 0.472 vt 0.244 0.168 0.464 vt 0.255 0.171 0.463 vt 0.243 0.177 0.453 vt 0.244 0.162 0.481 vt 0.230 0.169 0.459 vt 0.227 0.172 0.460 vt 0.237 0.178 0.464 vt 0.228 0.165 0.461 vt 0.236 0.146 0.465 vt 0.232 0.146 0.470 vt 0.210 0.587 0.312 vt 0.196 0.578 0.310 vt 0.197 0.592 0.312 vt 0.990 0.344 -0.060 vt 0.176 0.535 0.328 vt 0.170 0.531 0.327 vt 0.157 0.518 0.327 vt 0.152 0.509 0.329 vt 0.152 0.534 0.327 vt 0.989 0.090 -0.058 vt 0.299 0.595 0.303 vt 0.281 0.600 0.302 vt 0.294 0.608 0.301 vt 0.935 0.346 -0.059 vt 0.358 0.551 0.309 vt 0.914 0.284 -0.059 vt 0.353 0.537 0.303 vt 0.344 0.550 0.307 vt 0.927 0.112 -0.059 vt 0.365 0.486 0.317 vt 0.883 0.245 -0.060 vt 0.357 0.480 0.312 vt 0.356 0.491 0.316 vt 0.991 0.220 -0.059 vt 0.220 0.056 0.399 vt 0.841 0.831 0.393 vt 0.829 0.813 0.379 vt 0.858 0.858 0.410 vt 0.468 0.690 0.962 vt 0.478 0.704 0.962 vt 0.483 0.681 0.962 vt 0.174 0.698 0.962 vt 0.112 0.757 0.963 vt 0.109 0.595 0.962 vt 0.123 0.601 0.962 vt 0.101 0.755 0.963 vt 0.878 0.898 0.722 vt 0.893 0.927 0.722 vt 0.855 0.884 0.722 vt 0.820 0.876 0.722 vt 0.218 0.872 0.906 vt 0.183 0.732 0.906 vt 0.086 0.812 0.906 vt 0.122 0.781 0.906 vt 0.146 0.755 0.906 vt 0.164 0.738 0.906 vt 0.125 0.908 0.906 vt 0.146 0.923 0.906 vt 0.917 0.743 0.428 vt 0.180 0.930 0.906 vt 0.955 0.673 0.413 vt 0.953 0.683 0.417 vt 0.716 0.822 0.721 vt 0.811 0.978 0.722 vt 0.604 0.916 0.715 vt 0.493 0.680 0.946 vt 0.940 0.431 0.494 # 3263 texture vertices vn 0.760 -0.649 0.033 vn 0.982 -0.127 0.139 vn 0.978 -0.195 -0.079 vn 0.740 -0.425 0.521 vn 0.924 -0.223 0.310 vn 0.963 -0.145 0.228 vn 0.830 -0.154 0.537 vn 0.718 -0.501 0.483 vn 0.563 0.011 0.826 vn 0.487 -0.038 0.872 vn 0.220 0.118 0.968 vn 0.355 0.055 0.933 vn 0.347 -0.199 0.916 vn 0.941 -0.019 -0.339 vn 0.968 -0.027 -0.251 vn 0.990 0.074 -0.116 vn 0.973 -0.011 0.231 vn 0.926 -0.053 0.374 vn 0.783 0.176 0.596 vn 0.798 0.109 0.592 vn 0.718 -0.257 0.646 vn 0.410 0.238 0.881 vn 0.418 0.124 0.900 vn 0.561 0.192 0.805 vn 0.677 0.407 0.614 vn 0.572 0.121 0.811 vn 0.479 0.413 0.775 vn 0.056 0.253 0.966 vn 0.070 -0.036 0.997 vn 0.233 -0.432 0.871 vn 0.207 -0.259 0.943 vn 0.476 -0.109 0.873 vn 0.118 0.100 0.988 vn -0.115 0.133 0.984 vn 0.094 -0.325 0.941 vn 0.667 -0.504 0.549 vn -0.310 0.255 0.916 vn 0.287 0.104 0.952 vn 0.810 -0.225 0.542 vn -0.172 0.397 0.901 vn 0.458 0.123 0.881 vn 0.654 -0.051 0.754 vn -0.188 0.392 0.901 vn -0.268 0.311 0.912 vn 0.293 0.239 0.926 vn 0.401 0.117 0.909 vn 0.055 0.424 0.904 vn 0.475 0.141 0.868 vn 0.114 -0.170 0.979 vn 0.619 -0.352 0.702 vn -0.300 -0.035 0.953 vn -0.006 -0.019 1.000 vn 0.321 -0.104 0.941 vn 0.152 -0.317 0.936 vn 0.191 -0.631 0.752 vn 0.365 0.080 0.928 vn -0.037 0.280 0.959 vn -0.101 0.072 0.992 vn -0.160 -0.184 0.970 vn -0.349 -0.486 0.801 vn 0.338 0.508 0.792 vn 0.374 0.621 0.689 vn 0.317 0.920 0.232 vn 0.761 0.631 0.151 vn -0.054 0.443 0.895 vn 0.639 -0.190 0.746 vn 0.371 -0.106 0.922 vn 0.557 -0.288 -0.779 vn 0.964 -0.251 0.091 vn 0.984 0.034 0.176 vn 0.737 -0.570 -0.364 vn 0.936 -0.122 0.329 vn 0.653 -0.556 0.514 vn 0.242 -0.799 0.551 vn 0.866 -0.263 0.426 vn 0.465 -0.602 0.650 vn 0.179 -0.803 0.569 vn 0.685 -0.704 -0.187 vn 0.599 -0.614 0.513 vn 0.123 -0.776 0.619 vn 0.918 -0.375 0.126 vn 0.731 0.062 -0.680 vn 0.606 -0.592 -0.532 vn 0.946 0.121 -0.301 vn 0.772 -0.611 -0.177 vn 0.816 0.071 -0.574 vn 0.848 -0.483 0.218 vn 0.195 -0.811 0.552 vn 0.920 -0.189 -0.343 vn 0.349 -0.682 -0.643 vn 0.503 -0.320 -0.803 vn 0.565 -0.384 -0.730 vn 0.046 0.040 -0.998 vn 0.510 -0.351 -0.785 vn 0.217 -0.525 -0.823 vn 0.282 -0.947 0.151 vn 0.888 0.390 -0.245 vn 0.814 0.524 -0.250 vn 0.108 -0.109 -0.988 vn 0.010 0.148 -0.989 vn -0.110 0.152 0.982 vn -0.177 0.366 0.913 vn 0.533 0.387 0.753 vn 0.510 0.578 0.637 vn -0.246 0.841 -0.482 vn -0.275 0.958 -0.084 vn -0.116 0.904 0.411 vn 0.000 0.451 0.893 vn -0.165 0.231 0.959 vn -0.256 0.654 0.712 vn 0.118 0.737 0.665 vn -0.106 0.203 0.973 vn 0.327 0.060 0.943 vn -0.164 0.318 0.934 vn 0.185 0.107 0.977 vn 0.090 0.361 0.928 vn -0.552 0.308 0.775 vn -0.638 0.446 0.627 vn -0.838 0.216 0.501 vn -0.297 0.215 0.930 vn -0.491 0.350 0.797 vn -0.663 0.301 0.686 vn -0.077 0.082 0.994 vn 0.116 0.881 0.459 vn -0.078 -0.036 0.996 vn 0.206 -0.039 0.978 vn 0.321 0.056 0.946 vn 0.741 -0.240 0.627 vn 0.726 -0.196 0.659 vn 0.508 0.244 0.826 vn 0.647 -0.292 0.704 vn -0.246 0.582 0.775 vn 0.011 0.107 0.994 vn 0.395 -0.145 0.907 vn -0.752 -0.300 0.588 vn 0.451 -0.532 0.717 vn -0.320 0.482 0.816 vn -0.806 0.309 0.505 vn -0.602 -0.614 0.511 vn -0.551 -0.627 0.550 vn -0.519 0.642 0.565 vn -0.268 0.165 0.949 vn -0.936 0.107 0.336 vn -0.718 0.204 0.666 vn -0.927 -0.040 0.372 vn -0.885 0.378 0.273 vn -0.697 0.219 0.683 vn -0.861 0.186 -0.473 vn 0.873 -0.079 0.481 vn 0.033 0.557 0.830 vn -0.744 0.039 0.667 vn 0.566 -0.760 0.320 vn -0.417 -0.808 0.417 vn -0.107 -0.049 0.993 vn 0.257 -0.940 0.223 vn 0.621 -0.556 0.553 vn -0.148 -0.639 0.755 vn -0.188 -0.217 0.958 vn 0.190 -0.931 0.311 vn -0.191 -0.951 0.245 vn 0.205 -0.974 0.092 vn -0.971 -0.112 0.213 vn -0.572 0.320 0.755 vn -0.677 -0.534 0.505 vn 0.810 -0.250 0.530 vn 0.266 -0.124 0.956 vn 0.449 -0.856 0.258 vn 0.592 -0.786 0.179 vn 0.892 0.192 0.410 vn 0.855 -0.512 0.083 vn -0.566 -0.817 0.110 vn -0.412 -0.131 -0.901 vn -0.850 -0.420 -0.319 vn -0.923 0.376 0.080 vn -0.865 -0.486 0.124 vn -0.829 -0.508 0.234 vn -0.503 -0.859 0.096 vn -0.771 0.070 0.633 vn 0.343 0.015 0.939 vn 0.313 0.538 0.783 vn 0.597 -0.000 0.802 vn 0.652 0.430 0.624 vn 0.910 0.206 0.360 vn 0.522 0.064 0.850 vn 0.735 0.360 0.574 vn 0.175 -0.315 -0.933 vn -0.543 -0.057 -0.838 vn -0.966 0.219 0.138 vn -0.865 0.038 -0.500 vn 0.003 -0.667 -0.745 vn -0.486 -0.352 -0.800 vn 0.341 0.722 0.602 vn 0.832 -0.177 0.525 vn 0.224 0.046 0.974 vn 0.587 -0.278 0.760 vn 0.445 0.026 0.895 vn 0.665 -0.173 0.727 vn -0.970 0.221 -0.106 vn -0.909 0.022 0.415 vn -0.987 -0.069 0.143 vn 0.002 -0.351 -0.936 vn 0.357 0.418 -0.835 vn 0.793 -0.448 -0.412 vn -0.004 -0.977 -0.215 vn 0.771 -0.436 -0.464 vn 0.940 -0.341 0.024 vn 0.941 -0.335 0.042 vn 0.884 -0.266 0.386 vn 0.929 -0.369 0.002 vn 0.934 -0.201 -0.296 vn -0.588 0.783 -0.204 vn 0.444 0.862 -0.246 vn 0.779 0.616 -0.119 vn -0.552 0.731 -0.402 vn 0.294 0.889 -0.350 vn -0.363 0.925 -0.115 vn 0.399 0.914 -0.075 vn 0.077 0.975 -0.206 vn -0.815 0.405 -0.414 vn -0.975 0.106 -0.196 vn -0.980 0.197 -0.038 vn -0.950 0.303 0.070 vn -0.941 -0.332 -0.065 vn -0.964 0.105 -0.243 vn -0.943 -0.322 0.084 vn -0.756 -0.651 0.069 vn -0.089 -0.996 0.024 vn 0.520 -0.852 0.051 vn 0.846 -0.530 -0.065 vn 0.735 -0.677 -0.013 vn 0.994 -0.085 -0.072 vn 0.833 0.445 -0.329 vn -0.370 0.633 -0.680 vn 0.492 -0.420 -0.762 vn 0.884 0.116 -0.452 vn 0.883 0.434 -0.178 vn 0.966 -0.241 -0.096 vn -0.732 -0.679 0.061 vn -0.121 -0.992 0.037 vn 0.899 -0.393 -0.193 vn -0.787 -0.558 0.263 vn 0.208 -0.962 0.177 vn -0.367 -0.312 0.876 vn 0.047 -0.811 0.583 vn 0.459 -0.888 -0.012 vn 0.758 -0.604 0.245 vn 0.550 -0.835 -0.017 vn 0.937 0.051 -0.345 vn 0.518 -0.182 -0.836 vn 0.689 0.645 -0.332 vn -0.514 -0.024 -0.857 vn -0.835 0.062 -0.546 vn -0.038 -0.139 -0.990 vn -0.077 -0.689 0.721 vn -0.897 -0.200 0.394 vn -0.991 0.118 0.062 vn -0.522 0.406 -0.750 vn -0.906 0.385 -0.173 vn 0.439 0.453 -0.776 vn -0.576 0.766 -0.285 vn -0.044 0.405 -0.913 vn 0.031 0.903 -0.428 vn 0.716 -0.013 0.698 vn 0.996 -0.061 -0.065 vn 0.896 -0.016 0.443 vn 0.980 -0.031 -0.199 vn 0.504 -0.347 -0.791 vn 0.556 -0.472 -0.684 vn 0.193 -0.411 -0.891 vn 0.397 -0.602 -0.693 vn 0.783 -0.440 -0.439 vn 0.936 -0.327 0.128 vn 0.753 0.055 0.655 vn 0.897 -0.093 0.432 vn 0.745 0.018 0.667 vn 0.852 -0.431 -0.298 vn 0.630 -0.425 -0.651 vn 0.611 -0.778 -0.143 vn 0.756 -0.431 0.493 vn 0.785 -0.384 -0.486 vn 0.763 -0.644 0.060 vn 0.860 -0.182 0.477 vn 0.945 0.022 -0.327 vn 0.449 -0.556 -0.699 vn 0.688 -0.538 -0.487 vn -0.366 -0.169 -0.915 vn -0.877 0.016 -0.480 vn -0.905 0.113 -0.410 vn -0.958 0.144 0.247 vn -0.943 0.275 0.185 vn -0.512 0.707 0.488 vn -0.606 0.130 0.785 vn -0.376 0.533 0.758 vn -0.936 0.352 -0.018 vn -0.334 0.028 -0.942 vn -0.421 -0.347 -0.838 vn 0.324 0.427 0.844 vn 0.640 0.169 0.750 vn 0.183 0.776 0.603 vn -0.497 0.815 0.298 vn 0.380 0.844 0.378 vn -0.504 0.861 -0.065 vn 0.504 0.844 0.185 vn -0.598 0.801 0.032 vn 0.561 0.758 0.334 vn -0.669 0.539 0.511 vn 0.498 0.419 0.759 vn -0.662 0.643 0.385 vn -0.891 0.399 0.214 vn 0.614 0.444 0.652 vn -0.890 -0.435 -0.134 vn 0.791 -0.441 0.423 vn 0.009 -0.994 -0.113 vn -0.217 0.780 0.587 vn 0.509 0.521 0.685 vn -0.324 0.399 0.858 vn -0.346 -0.233 0.909 vn 0.619 -0.066 0.783 vn 0.915 0.183 0.360 vn 0.460 0.516 0.723 vn 0.286 0.849 0.444 vn -0.939 0.172 0.298 vn -0.965 0.107 -0.241 vn 0.900 0.264 0.347 vn 0.935 -0.249 0.253 vn 0.605 -0.668 0.433 vn -0.889 -0.174 -0.424 vn 0.152 -0.899 -0.411 vn -0.058 -0.939 -0.340 vn -0.028 -0.995 -0.094 vn -0.298 -0.926 0.234 vn -0.991 -0.046 0.125 vn -0.832 -0.493 -0.254 vn 0.835 -0.269 0.480 vn 0.328 -0.722 -0.610 vn -0.893 -0.390 -0.226 vn 0.460 0.887 -0.039 vn 0.078 0.995 0.056 vn -0.651 0.755 -0.075 vn 0.764 0.642 0.067 vn 0.991 0.038 -0.130 vn -0.966 -0.017 -0.259 vn -0.572 0.759 -0.312 vn -0.572 0.609 0.550 vn 0.776 -0.536 0.332 vn -0.963 -0.241 0.117 vn -0.763 -0.553 -0.335 vn 0.147 -0.987 -0.065 vn 0.905 -0.313 0.290 vn 0.344 -0.760 0.551 vn -0.572 -0.715 0.403 vn 0.051 -0.946 0.320 vn -0.149 0.697 -0.701 vn 0.250 0.824 0.508 vn -0.252 0.683 -0.685 vn 0.191 0.900 0.391 vn -0.665 0.554 -0.501 vn -0.264 0.738 0.621 vn -0.669 0.495 -0.554 vn -0.350 0.701 0.621 vn -0.778 0.625 0.069 vn -0.238 0.563 0.791 vn -0.954 0.169 0.248 vn 0.126 -0.137 0.983 vn -0.815 0.214 -0.538 vn -0.298 -0.733 -0.611 vn -0.310 -0.870 0.383 vn -0.490 -0.312 -0.814 vn -0.192 -0.244 -0.951 vn -0.431 -0.335 -0.838 vn 0.316 -0.157 0.936 vn 0.275 0.315 0.908 vn 0.247 0.297 0.922 vn 0.433 -0.193 0.880 vn 0.467 -0.867 -0.174 vn 0.375 -0.864 -0.335 vn 0.395 -0.909 0.134 vn 0.109 -0.993 0.037 vn 0.247 -0.024 0.969 vn -0.249 -0.611 -0.752 vn 0.603 -0.779 0.172 vn -0.084 -0.987 0.138 vn 0.342 -0.262 0.902 vn -0.101 -0.283 0.954 vn -0.729 0.234 -0.644 vn -0.650 -0.419 -0.634 vn -0.590 -0.581 -0.561 vn 0.529 -0.373 -0.762 vn 0.366 -0.623 -0.691 vn 0.097 -0.989 -0.115 vn 0.601 -0.647 -0.469 vn 0.096 -0.766 -0.636 vn 0.094 -0.764 -0.638 vn -0.512 -0.618 -0.596 vn -0.241 -0.958 0.153 vn 0.634 -0.472 -0.613 vn 0.771 0.624 0.127 vn 0.964 0.097 -0.247 vn 0.877 0.335 -0.344 vn 0.928 0.183 -0.324 vn 0.347 0.926 -0.151 vn 0.530 -0.233 -0.816 vn -0.355 0.751 0.558 vn -0.319 0.921 0.225 vn 0.559 0.762 -0.329 vn 0.825 0.563 -0.042 vn -0.242 0.821 0.518 vn 0.882 0.441 0.163 vn -0.203 0.593 0.779 vn 0.596 0.400 0.696 vn -0.344 0.341 0.875 vn 0.495 -0.080 0.865 vn -0.734 -0.251 0.631 vn -0.072 -0.969 0.238 vn 0.999 -0.017 0.039 vn 0.583 -0.718 -0.381 vn 0.907 -0.117 -0.405 vn 0.720 -0.256 -0.645 vn -0.833 -0.373 0.409 vn -0.953 -0.155 0.258 vn -0.724 0.305 0.619 vn -0.828 -0.272 0.490 vn -0.393 -0.655 -0.645 vn 0.692 -0.566 -0.447 vn -0.372 -0.583 -0.722 vn -0.417 -0.893 -0.167 vn -0.177 -0.981 -0.080 vn -0.697 -0.162 0.699 vn 0.764 -0.636 -0.106 vn -0.728 -0.566 -0.386 vn -0.055 -0.990 -0.126 vn 0.259 -0.224 0.940 vn 0.889 -0.457 -0.016 vn 0.317 -0.925 0.211 vn 0.213 -0.782 0.586 vn -0.597 -0.363 0.715 vn -0.548 -0.587 0.596 vn 0.131 -0.281 0.951 vn 0.280 -0.763 0.582 vn -0.390 -0.091 0.916 vn -0.376 -0.088 0.922 vn 0.644 0.508 0.572 vn -0.161 -0.046 0.986 vn 0.088 0.021 0.996 vn 0.175 0.322 0.931 vn -0.345 0.638 0.689 vn -0.281 0.186 0.942 vn -0.470 0.090 0.878 vn -0.356 0.779 0.515 vn -0.926 0.227 -0.302 vn -0.486 -0.847 0.215 vn 0.252 -0.921 0.298 vn 0.191 -0.935 0.299 vn -0.584 -0.352 0.732 vn 0.352 -0.788 0.505 vn -0.468 -0.350 0.812 vn 0.374 -0.779 0.503 vn -0.268 -0.322 0.908 vn 0.592 -0.795 0.132 vn 0.177 -0.424 0.888 vn 0.487 -0.836 -0.253 vn 0.533 -0.606 0.591 vn 0.091 -0.779 -0.620 vn 0.755 -0.595 0.275 vn -0.395 -0.809 -0.435 vn 0.720 -0.637 0.276 vn -0.528 -0.849 0.025 vn -0.860 0.099 0.501 vn -0.663 0.370 0.651 vn -0.277 0.351 0.894 vn 0.298 0.229 0.927 vn 0.785 0.116 0.609 vn 0.258 0.429 0.866 vn -0.823 -0.146 0.549 vn -0.973 -0.163 0.163 vn -0.855 -0.225 0.467 vn -0.728 -0.586 -0.356 vn -0.732 0.455 -0.508 vn -0.791 -0.318 0.523 vn -0.901 -0.020 0.434 vn -0.927 0.369 -0.065 vn -0.773 0.127 0.622 vn -0.668 -0.301 0.680 vn -0.896 -0.042 0.443 vn -0.591 0.643 -0.487 vn -0.928 0.155 0.340 vn -0.938 0.179 0.297 vn -0.523 0.852 0.037 vn -0.632 -0.728 -0.267 vn -0.772 0.032 -0.634 vn -0.938 0.287 0.194 vn -0.932 0.181 -0.314 vn -0.575 -0.150 -0.804 vn -0.625 -0.005 -0.781 vn -0.360 0.754 -0.549 vn 0.041 0.839 -0.543 vn 0.009 0.137 -0.991 vn -0.970 0.242 0.009 vn -0.945 0.028 0.326 vn -0.679 0.521 -0.518 vn -0.898 0.423 0.117 vn -0.770 0.206 0.604 vn -0.823 -0.359 -0.441 vn -0.876 -0.468 0.115 vn -0.987 -0.040 -0.158 vn -0.830 0.491 0.265 vn -0.905 0.423 -0.033 vn -0.658 0.583 0.476 vn -0.476 0.831 -0.287 vn 0.061 0.536 -0.842 vn -0.164 -0.537 -0.828 vn -0.606 0.332 -0.722 vn -0.463 0.467 -0.753 vn -0.487 0.250 -0.837 vn -0.926 -0.366 0.093 vn -0.891 0.157 0.426 vn -0.978 -0.204 -0.049 vn -0.646 0.764 -0.003 vn -0.809 0.260 0.527 vn -0.110 0.709 -0.696 vn -0.362 0.687 -0.630 vn -0.465 0.466 -0.753 vn -0.667 0.669 -0.327 vn -0.624 0.763 0.169 vn -0.335 0.803 0.493 vn 0.158 0.771 0.617 vn -0.937 0.091 -0.339 vn -0.870 0.151 0.470 vn -0.752 0.322 -0.576 vn -0.398 0.785 -0.475 vn -0.862 0.422 0.280 vn -0.677 0.511 -0.529 vn -0.587 0.808 0.054 vn -0.714 0.182 -0.676 vn -0.279 -0.419 0.864 vn -0.535 0.193 -0.823 vn -0.124 0.702 -0.702 vn -0.898 -0.392 -0.200 vn -0.902 -0.422 -0.092 vn -0.783 0.125 0.609 vn -0.932 -0.332 -0.143 vn -0.157 0.491 -0.857 vn -0.862 -0.475 -0.175 vn -0.783 0.535 -0.318 vn -0.092 0.492 -0.866 vn -0.457 0.435 -0.776 vn -0.435 0.721 -0.539 vn -0.324 0.559 0.763 vn -0.084 0.215 0.973 vn 0.322 0.189 0.927 vn 0.207 0.288 0.935 vn -0.156 0.026 0.987 vn -0.386 0.535 0.751 vn -0.778 0.382 0.499 vn -0.577 0.233 0.783 vn -0.547 0.619 0.564 vn -0.804 0.576 0.147 vn -0.305 0.193 0.933 vn -0.278 -0.353 0.893 vn -0.440 -0.005 0.898 vn 0.529 -0.209 0.823 vn 0.470 0.195 0.861 vn -0.833 0.016 0.554 vn -0.333 0.767 0.549 vn -0.828 0.096 0.552 vn -0.740 0.646 -0.186 vn -0.388 0.558 0.734 vn -0.956 -0.071 0.283 vn -0.800 0.516 -0.307 vn -0.486 0.849 0.209 vn -0.966 -0.248 -0.066 vn -0.738 0.279 0.614 vn -0.912 -0.361 -0.194 vn -0.990 -0.124 -0.070 vn -0.914 -0.394 -0.096 vn -0.993 -0.044 0.111 vn -0.479 0.873 -0.090 vn -0.716 0.692 -0.088 vn -0.607 0.789 -0.090 vn 0.043 0.981 -0.190 vn -0.674 0.640 -0.369 vn -0.207 0.792 0.575 vn -0.556 0.688 -0.465 vn 0.315 0.928 -0.199 vn 0.250 0.916 0.314 vn 0.139 0.958 0.251 vn -0.208 0.919 0.336 vn -0.654 0.425 0.626 vn -0.613 -0.170 0.772 vn -0.527 0.307 0.792 vn -0.137 0.481 0.866 vn 0.409 0.165 0.897 vn -0.257 0.531 0.808 vn 0.160 0.262 0.952 vn 0.524 -0.219 0.823 vn -0.308 -0.357 0.881 vn -0.318 0.700 0.639 vn -0.085 0.547 0.833 vn -0.526 0.126 0.841 vn -0.676 0.248 0.694 vn 0.106 -0.341 0.934 vn 0.500 -0.047 0.865 vn -0.055 -0.486 0.872 vn -0.507 0.290 0.812 vn -0.418 -0.012 0.908 vn -0.364 -0.279 0.888 vn -0.737 0.671 0.083 vn -0.859 -0.033 0.511 vn -0.683 -0.477 0.553 vn -0.798 -0.478 -0.369 vn -0.914 -0.404 0.038 vn 0.076 -0.801 0.593 vn -0.801 -0.517 0.301 vn -0.603 -0.654 -0.456 vn -0.873 -0.475 -0.109 vn -0.646 0.577 -0.500 vn -0.612 -0.425 -0.667 vn -0.436 -0.705 -0.559 vn -0.950 -0.284 -0.128 vn -0.207 -0.385 -0.899 vn -0.868 -0.496 -0.014 vn -0.449 0.200 -0.871 vn -0.486 -0.172 -0.857 vn -0.027 0.994 0.102 vn -0.382 0.470 -0.796 vn 0.142 0.980 0.136 vn 0.166 0.919 -0.357 vn -0.382 0.790 -0.479 vn 0.168 -0.286 0.943 vn 0.195 -0.414 0.889 vn -0.199 -0.251 0.947 vn -0.225 -0.814 0.536 vn -0.046 -0.638 0.769 vn -0.408 -0.156 0.900 vn -0.374 -0.630 0.681 vn 0.225 -0.034 0.974 vn -0.476 0.250 0.843 vn -0.419 -0.308 0.854 vn -0.414 -0.753 -0.512 vn -0.506 -0.280 -0.816 vn -0.823 -0.488 -0.291 vn -0.919 -0.259 -0.296 vn -0.284 -0.218 -0.934 vn -0.118 -0.531 -0.839 vn -0.566 0.180 -0.805 vn -0.498 -0.314 -0.809 vn -0.505 -0.382 -0.774 vn -0.313 -0.522 -0.794 vn -0.430 -0.692 -0.579 vn -0.758 0.519 0.396 vn -0.480 -0.086 -0.873 vn -0.931 -0.259 -0.256 vn -0.315 -0.812 -0.491 vn -0.686 -0.683 0.253 vn -0.727 -0.169 0.666 vn -0.309 -0.926 -0.215 vn 0.194 -0.040 -0.980 vn -0.519 -0.222 0.825 vn -0.627 0.167 -0.761 vn 0.526 0.137 -0.839 vn -0.913 0.044 0.405 vn -0.300 -0.952 -0.063 vn 0.357 -0.040 -0.933 vn -0.609 -0.173 0.774 vn -0.235 -0.897 -0.375 vn -0.465 0.438 0.770 vn 0.227 0.864 -0.450 vn -0.152 0.816 0.557 vn -0.155 0.978 -0.137 vn 0.185 0.939 -0.292 vn -0.347 0.788 0.509 vn 0.320 0.845 -0.429 vn 0.281 -0.005 -0.960 vn -0.026 0.918 0.395 vn -0.861 -0.151 -0.486 vn -0.409 -0.471 -0.782 vn 0.009 0.269 -0.963 vn -0.526 0.135 -0.840 vn -0.712 -0.692 0.122 vn -0.370 -0.688 -0.625 vn -0.095 -0.158 -0.983 vn -0.853 -0.148 -0.501 vn -0.463 -0.051 0.885 vn -0.500 -0.756 -0.422 vn -0.083 -0.093 -0.992 vn -0.332 -0.158 0.930 vn 0.303 0.720 -0.624 vn -0.099 0.722 -0.684 vn 0.024 0.703 0.711 vn 0.415 0.907 0.075 vn -0.439 0.898 0.024 vn -0.497 0.486 -0.719 vn -0.576 0.788 -0.217 vn -0.001 0.829 -0.559 vn -0.315 0.885 -0.342 vn 0.105 0.507 -0.856 vn 0.150 0.989 0.004 vn -0.458 0.889 -0.004 vn -0.134 0.368 -0.920 vn -0.521 0.391 -0.759 vn 0.312 0.859 0.406 vn -0.518 0.750 -0.411 vn 0.096 0.854 0.511 vn -0.225 0.843 0.488 vn -0.851 0.522 0.064 vn -0.293 0.503 0.813 vn -0.449 0.878 -0.169 vn -0.261 0.866 -0.426 vn -0.767 0.641 0.036 vn -0.572 -0.652 0.497 vn 0.161 0.583 0.796 vn -0.600 -0.735 -0.314 vn -0.122 -0.149 -0.981 vn -0.462 -0.186 0.867 vn 0.381 0.659 -0.649 vn -0.665 -0.612 0.427 vn -0.039 0.457 0.889 vn -0.327 -0.517 -0.791 vn 0.146 0.988 -0.040 vn -0.522 -0.606 0.600 vn -0.221 0.474 0.853 vn 0.393 0.902 0.176 vn 0.189 0.527 -0.829 vn -0.448 -0.891 -0.080 vn -0.529 0.046 0.848 vn -0.296 0.921 -0.252 vn -0.151 0.008 -0.989 vn -0.967 0.003 -0.256 vn -0.714 0.242 -0.657 vn -0.826 -0.233 -0.514 vn -0.341 -0.771 -0.538 vn -0.876 -0.476 -0.081 vn -0.195 0.967 -0.166 vn -0.894 0.393 0.216 vn -0.502 0.426 -0.753 vn -0.415 -0.584 -0.698 vn -0.880 -0.367 -0.302 vn -0.182 0.969 -0.168 vn -0.906 0.417 0.080 vn 0.529 -0.135 0.838 vn 0.388 -0.162 0.907 vn 0.333 -0.409 0.850 vn 0.333 -0.215 0.918 vn 0.365 -0.255 0.896 vn 0.525 -0.231 0.819 vn -0.032 -0.064 0.997 vn -0.052 0.368 0.928 vn -0.177 -0.213 0.961 vn 0.128 0.981 -0.149 vn -0.365 0.847 0.386 vn -0.374 0.794 -0.478 vn -0.659 0.593 -0.463 vn -0.369 0.814 -0.449 vn -0.382 0.769 -0.512 vn -0.500 0.797 -0.339 vn -0.273 0.868 -0.414 vn -0.892 0.397 -0.215 vn -0.404 0.856 -0.324 vn -0.722 0.610 -0.325 vn -0.523 0.764 0.378 vn -0.747 0.652 -0.130 vn -0.530 0.848 0.002 vn -0.558 0.739 0.378 vn -0.464 0.840 0.281 vn -0.583 0.744 -0.325 vn -0.336 0.315 -0.888 vn -0.648 -0.101 -0.755 vn -0.876 0.135 0.462 vn -0.855 0.322 -0.406 vn -0.166 -0.540 -0.825 vn -0.244 -0.596 -0.765 vn -0.102 -0.059 -0.993 vn -0.633 0.771 0.067 vn -0.381 0.542 0.749 vn -0.842 0.445 0.305 vn -0.488 0.871 0.060 vn -0.341 0.788 -0.513 vn -0.186 0.396 0.899 vn -0.748 0.154 -0.646 vn -0.239 0.149 -0.959 vn -0.470 0.880 -0.066 vn -0.182 0.890 -0.417 vn -0.242 0.894 -0.378 vn -0.013 0.483 -0.876 vn -0.795 0.592 -0.133 vn -0.967 -0.099 -0.233 vn -0.545 0.819 0.178 vn -0.235 -0.111 0.966 vn -0.541 0.822 -0.180 vn -0.616 0.704 0.353 vn -0.803 0.227 0.551 vn -0.777 0.623 -0.093 vn -0.600 0.354 0.718 vn -0.703 0.355 0.616 vn -0.710 0.597 -0.375 vn -0.649 0.269 0.712 vn -0.105 0.350 0.931 vn 0.158 0.806 0.570 vn -0.578 0.471 0.666 vn -0.438 0.545 0.715 vn -0.667 0.534 0.520 vn -0.761 0.119 -0.637 vn -0.801 0.531 -0.275 vn 0.052 -0.869 -0.491 vn 0.023 0.716 0.698 vn -0.598 0.132 0.791 vn -0.574 0.153 0.804 vn -0.042 0.524 0.851 vn -0.597 0.098 0.796 vn -0.117 0.442 0.889 vn -0.013 0.584 0.812 vn 0.298 0.498 0.815 vn 0.265 0.334 0.904 vn 0.009 0.950 0.313 vn 0.175 0.757 0.630 vn -0.452 0.816 0.360 vn -0.413 0.084 0.907 vn 0.100 0.680 0.727 vn -0.305 0.267 0.914 vn -0.540 0.575 0.615 vn -0.436 0.765 0.474 vn -0.688 0.274 0.671 vn -0.405 0.913 0.045 vn -0.749 0.643 -0.162 vn -0.967 -0.096 -0.234 vn -0.820 0.572 0.016 vn -0.672 0.325 -0.666 vn -0.604 0.460 -0.650 vn -0.609 0.502 0.614 vn -0.649 0.358 0.672 vn -0.891 0.451 -0.057 vn -0.239 0.864 -0.443 vn -0.820 0.316 -0.477 vn -0.457 0.855 -0.247 vn -0.768 0.630 0.119 vn -0.786 0.460 -0.413 vn -0.605 0.791 -0.085 vn -0.870 0.490 0.059 vn -0.961 0.022 -0.276 vn -0.979 -0.013 -0.205 vn -0.932 0.354 0.080 vn -0.485 0.716 0.502 vn -0.753 0.576 0.318 vn -0.670 0.713 0.205 vn 0.079 0.489 0.869 vn 0.344 0.130 0.930 vn -0.783 0.620 0.047 vn -0.889 0.100 -0.446 vn -0.561 0.753 0.345 vn -0.838 0.506 -0.202 vn -0.464 0.857 0.224 vn -0.053 0.693 0.719 vn 0.760 -0.051 0.648 vn 0.620 0.033 0.784 vn -0.756 0.584 -0.296 vn 0.506 0.860 -0.069 vn -0.282 0.950 -0.133 vn -0.968 0.140 -0.206 vn -0.963 -0.112 -0.244 vn -0.871 -0.156 -0.467 vn -0.704 -0.499 -0.504 vn -0.279 0.642 0.715 vn -0.876 0.474 -0.089 vn -0.240 0.880 0.409 vn -0.293 0.897 0.331 vn 0.349 0.032 0.937 vn 0.416 0.656 0.629 vn -0.807 0.578 0.121 vn 0.669 0.635 0.386 vn 0.763 0.337 0.551 vn 0.370 0.022 0.929 vn 0.866 0.500 0.025 vn 0.342 0.846 0.409 vn -0.846 0.150 -0.511 vn -0.309 0.919 0.244 vn -0.992 -0.128 -0.022 vn -0.867 0.499 0.006 vn -0.980 -0.118 0.159 vn -0.878 0.450 0.161 vn -0.831 0.520 0.198 vn -0.975 -0.136 0.178 vn -0.992 0.073 0.100 vn -0.840 0.536 0.082 vn -0.223 0.973 0.066 vn -0.962 -0.249 0.109 vn -0.840 -0.244 -0.484 vn -0.929 -0.255 -0.267 vn -0.489 -0.722 -0.490 vn -0.635 -0.735 0.237 vn -0.562 -0.763 -0.320 vn -0.628 -0.775 -0.074 vn -0.912 -0.238 -0.335 vn -0.787 -0.615 0.050 vn -0.643 -0.695 0.323 vn -0.466 -0.743 -0.480 vn -0.761 -0.219 -0.611 vn -0.282 -0.956 -0.087 vn -0.954 -0.280 0.106 vn 0.768 -0.622 0.152 vn -0.996 -0.037 -0.081 vn 0.369 -0.873 -0.318 vn -0.635 -0.671 -0.382 vn -0.997 -0.017 0.078 vn -0.201 -0.493 -0.846 vn 0.028 -0.113 -0.993 vn 0.192 -0.222 -0.956 vn -0.539 -0.213 -0.815 vn -0.916 0.312 -0.251 vn -0.275 -0.079 -0.958 vn -0.359 0.854 -0.376 vn 0.222 0.460 -0.859 vn -0.995 -0.069 0.075 vn -0.694 -0.536 -0.481 vn 0.166 -0.786 0.595 vn -0.992 -0.046 0.121 vn 0.219 -0.922 -0.318 vn -0.711 -0.700 0.058 vn -0.636 -0.711 -0.300 vn -0.991 -0.047 -0.124 vn -0.495 -0.156 -0.855 vn -0.075 -0.446 -0.892 vn -0.077 0.401 -0.913 vn -0.348 -0.842 -0.413 vn -0.299 0.954 0.008 vn -0.086 0.405 -0.910 vn -0.766 -0.560 -0.315 vn -0.792 -0.486 -0.370 vn -0.180 -0.857 -0.482 vn 0.885 -0.350 0.308 vn 0.047 -0.871 0.489 vn 0.572 -0.143 0.808 vn 0.826 0.106 0.553 vn 0.830 -0.349 0.435 vn 0.789 -0.498 0.360 vn 0.820 -0.428 0.379 vn 0.193 -0.639 0.745 vn 0.707 -0.504 0.495 vn 0.226 -0.968 -0.113 vn -0.279 -0.862 -0.424 vn -0.013 -0.991 0.137 vn 0.036 -0.985 -0.167 vn -0.130 -0.932 0.338 vn -0.162 -0.935 0.314 vn 0.631 -0.713 0.306 vn 0.430 -0.839 0.333 vn -0.146 0.982 0.120 vn 0.947 0.268 0.179 vn 0.988 0.145 0.053 vn 0.558 0.807 0.194 vn 0.943 0.323 0.076 vn 0.913 -0.374 0.161 vn 0.860 -0.317 0.400 vn 0.764 -0.576 0.292 vn 0.499 -0.864 0.063 vn 0.565 -0.818 0.111 vn 0.970 -0.190 0.149 vn -0.188 0.884 0.428 vn 0.641 0.739 0.211 vn 0.968 0.095 -0.233 vn -0.716 0.639 0.280 vn -0.429 0.755 0.495 vn -0.134 0.856 0.498 vn 0.371 0.804 0.465 vn -0.925 0.283 -0.254 vn -0.342 0.820 0.459 vn 0.389 0.835 0.389 vn -0.577 0.817 -0.010 vn 0.207 0.953 0.222 vn -0.626 0.779 0.016 vn 0.302 0.927 0.224 vn -0.586 0.729 0.354 vn 0.269 0.804 0.530 vn -0.710 0.557 0.431 vn -0.838 0.361 0.410 vn 0.643 0.454 0.616 vn -0.140 0.654 0.743 vn 0.263 0.741 0.618 vn 0.731 0.035 0.681 vn 0.739 0.225 -0.635 vn 0.957 0.021 0.288 vn 0.926 0.264 0.270 vn 0.978 -0.115 0.176 vn 0.950 0.191 0.249 vn -0.961 -0.146 0.234 vn 0.826 0.142 0.545 vn -0.226 0.528 0.818 vn -0.168 0.044 0.985 vn 0.427 -0.230 -0.874 vn -0.005 -0.815 -0.579 vn -0.104 -0.928 -0.358 vn 0.028 -0.783 -0.621 vn 0.438 -0.758 -0.484 vn -0.942 0.064 0.329 vn -0.975 -0.181 0.127 vn -0.900 -0.342 -0.272 vn -0.765 -0.610 0.207 vn -0.290 0.917 -0.275 vn -0.611 0.783 0.111 vn -0.694 0.530 0.487 vn -0.581 0.813 -0.031 vn -0.502 0.852 0.150 vn -0.755 0.633 -0.170 vn -0.418 0.875 0.245 vn -0.222 0.905 -0.363 vn -0.323 0.642 0.696 vn -0.262 0.955 0.141 vn -0.075 0.930 0.359 vn -0.209 0.958 0.195 vn -0.654 0.751 -0.090 vn -0.672 0.701 -0.240 vn -0.354 0.929 0.110 vn -0.844 0.516 0.145 vn -0.279 0.942 0.187 vn -0.332 0.915 -0.228 vn -0.738 0.552 0.388 vn -0.678 0.423 0.601 vn -0.234 0.841 0.487 vn -0.755 0.605 0.250 vn -0.743 0.669 -0.016 vn -0.524 0.765 -0.374 vn -0.424 0.840 -0.339 vn -0.417 0.834 0.361 vn -0.575 0.809 0.123 vn -0.700 0.671 -0.245 vn -0.978 -0.153 -0.142 vn -0.979 -0.205 -0.017 vn -0.876 0.031 0.482 vn -0.982 0.170 -0.085 vn 0.575 -0.772 -0.271 vn 0.754 -0.582 -0.305 vn -0.368 -0.779 -0.508 vn -0.364 -0.856 -0.366 vn 0.735 -0.678 0.008 vn -0.495 -0.842 -0.214 vn 0.925 -0.375 0.059 vn -0.570 -0.759 -0.314 vn 0.784 -0.620 -0.018 vn 0.681 -0.723 0.113 vn -0.517 -0.842 -0.158 vn 0.123 -0.920 0.372 vn 0.887 0.255 -0.385 vn 0.829 0.419 0.370 vn 0.871 0.190 0.454 vn 0.960 0.118 -0.255 vn 0.702 0.411 0.582 vn 0.877 0.298 -0.377 vn 0.598 0.682 0.421 vn 0.757 0.516 -0.400 vn 0.590 0.781 -0.206 vn 0.429 0.773 0.467 vn 0.559 0.449 -0.697 vn 0.186 -0.322 -0.928 vn 0.045 -0.207 -0.977 vn 0.094 -0.516 -0.851 vn 0.724 0.690 0.017 vn 0.372 0.420 0.828 vn 0.618 0.186 -0.764 vn 0.939 0.293 0.181 vn -0.026 -0.547 0.837 vn 0.144 -0.743 -0.654 vn 0.116 0.013 0.993 vn -0.061 0.116 0.991 vn -0.485 -0.857 -0.175 vn -0.469 -0.604 0.645 vn 0.113 -0.993 -0.019 vn -0.023 -0.773 0.634 vn 0.209 -0.793 -0.572 vn -0.015 -0.442 0.897 vn -0.612 -0.551 0.567 vn -0.665 -0.589 -0.459 vn 0.059 -0.891 0.450 vn 0.654 -0.755 0.051 vn 0.893 0.120 0.435 vn 0.046 -0.922 -0.385 vn 0.645 -0.727 0.235 vn 0.144 -0.981 -0.127 vn -0.280 0.675 0.683 vn -0.612 0.565 0.554 vn -0.804 0.488 0.341 vn 0.091 0.685 0.723 vn -0.867 0.216 0.450 vn 0.044 0.425 0.904 vn -0.824 -0.108 0.557 vn 0.070 0.083 0.994 vn -0.843 -0.146 0.518 vn -0.061 0.020 0.998 vn -0.406 -0.266 0.875 vn -0.909 -0.384 0.164 vn 0.443 -0.096 0.891 vn 0.048 0.166 0.985 vn 0.788 0.200 0.583 vn 0.675 0.151 0.722 vn 0.937 0.058 0.344 vn -0.303 -0.630 0.715 vn -0.762 -0.553 -0.337 vn 0.766 -0.259 0.589 vn 0.100 -0.980 0.172 vn -0.122 -0.060 -0.991 vn 0.979 0.155 -0.132 vn -0.956 -0.145 -0.255 vn -0.889 -0.179 -0.421 vn -0.786 -0.317 -0.531 vn -0.899 -0.051 0.434 vn 0.859 -0.066 -0.508 vn 0.956 0.205 -0.211 vn 0.008 0.026 -1.000 vn 0.048 -0.202 -0.978 vn 0.952 -0.091 -0.291 vn -0.015 -0.196 -0.981 vn -0.253 -0.479 -0.841 vn 0.932 -0.288 -0.221 vn 0.458 -0.888 0.035 vn 0.592 -0.482 -0.647 vn -0.622 0.463 0.632 vn -0.822 0.392 0.414 vn -0.904 0.246 0.350 vn -0.054 0.455 0.889 vn -0.932 -0.041 0.360 vn -0.139 0.207 0.968 vn -0.717 -0.568 0.404 vn 0.015 -0.354 0.935 vn -0.575 -0.750 0.326 vn 0.247 -0.488 0.837 vn -0.070 -0.832 0.551 vn -0.609 -0.793 -0.006 vn 0.561 -0.321 0.763 vn -0.193 0.040 0.980 vn 0.677 0.078 0.732 vn 0.788 0.202 0.581 vn 0.863 0.257 0.434 vn 0.007 -0.915 0.403 vn -0.535 -0.731 -0.424 vn 0.795 -0.291 0.532 vn 0.585 -0.308 -0.750 vn -0.907 -0.295 -0.300 vn -0.798 -0.283 -0.532 vn -0.729 -0.360 -0.582 vn -0.964 -0.264 -0.027 vn 0.643 0.634 -0.430 vn 0.681 0.698 -0.224 vn -0.142 0.495 -0.857 vn -0.188 0.288 -0.939 vn 0.858 0.450 -0.247 vn -0.282 0.048 -0.958 vn -0.200 -0.266 -0.943 vn 0.992 0.005 -0.123 vn 0.339 -0.881 -0.329 vn 0.412 -0.886 -0.213 vn -0.504 -0.544 -0.670 vn -0.418 -0.546 -0.726 vn -0.359 -0.847 -0.393 vn -0.925 0.134 -0.356 vn -0.810 0.330 0.485 vn -0.932 0.351 0.094 vn -0.917 0.325 0.233 vn -0.286 0.268 0.920 vn -0.934 -0.169 0.315 vn -0.223 -0.093 0.970 vn -0.876 -0.482 -0.007 vn -0.302 -0.508 0.807 vn -0.634 -0.757 -0.157 vn -0.085 -0.770 0.633 vn -0.078 -0.996 0.048 vn -0.399 -0.617 -0.678 vn 0.402 -0.690 0.602 vn -0.091 -0.267 0.959 vn 0.420 -0.047 0.906 vn 0.494 -0.143 0.858 vn 0.611 -0.030 0.791 vn 0.231 -0.943 -0.239 vn -0.221 -0.377 -0.899 vn 0.665 -0.409 0.625 vn 0.840 0.271 -0.470 vn -0.791 -0.011 -0.612 vn -0.581 -0.062 -0.811 vn -0.372 0.073 -0.925 vn -0.819 -0.039 -0.573 vn 0.504 0.662 0.554 vn 0.767 0.543 0.343 vn 0.149 0.782 -0.605 vn 0.112 0.904 -0.413 vn 0.693 0.564 0.450 vn -0.068 0.424 -0.903 vn 0.224 -0.097 -0.970 vn 0.883 -0.317 0.345 vn -0.141 -0.617 -0.774 vn -0.415 -0.828 -0.377 vn -0.420 -0.354 0.835 vn -0.266 0.155 0.951 vn 0.210 0.575 0.790 vn 0.502 0.103 0.859 vn 0.362 0.532 0.765 vn -0.468 -0.654 -0.594 vn -0.438 -0.861 0.257 vn 0.317 0.301 0.899 vn -0.011 0.362 0.932 vn -0.734 -0.461 -0.500 vn -0.363 -0.866 -0.345 vn -0.950 -0.156 -0.272 vn 0.437 0.768 -0.468 vn -0.660 0.501 0.560 vn -0.992 -0.074 -0.103 vn -0.996 -0.083 0.024 vn -0.983 -0.010 -0.184 vn -0.956 0.119 -0.270 vn -0.762 0.404 0.506 vn -0.953 -0.185 -0.239 vn -0.794 0.524 0.307 vn -0.895 -0.233 -0.381 vn -0.348 -0.450 -0.823 vn -0.212 -0.264 -0.941 vn 0.018 -0.306 -0.952 vn 0.117 -0.065 -0.991 vn 0.924 -0.014 -0.383 vn 0.916 0.065 -0.397 vn 0.491 0.704 -0.513 vn 0.794 0.405 -0.453 vn -0.045 0.991 0.126 vn 0.493 0.828 0.268 vn 0.420 0.896 0.142 vn 0.893 0.414 0.179 vn 0.781 0.497 0.378 vn 0.587 -0.233 -0.775 vn -0.203 0.860 0.468 vn 0.190 0.722 0.665 vn -0.086 0.719 0.690 vn -0.390 0.532 -0.752 vn -0.519 -0.418 -0.745 vn -0.257 -0.964 -0.073 vn -0.689 -0.568 -0.451 vn -0.695 -0.688 -0.210 vn -0.497 -0.339 0.799 vn -0.696 -0.701 0.155 vn -0.676 -0.188 0.712 vn -0.439 -0.195 0.877 vn -0.581 -0.375 0.723 vn -0.760 -0.649 -0.025 vn -0.719 -0.544 -0.433 vn -0.729 0.042 0.684 vn -0.531 -0.641 0.554 vn -0.588 -0.069 0.806 vn -0.864 -0.067 0.499 vn -0.798 -0.460 0.389 vn -0.524 -0.290 0.801 vn -0.811 -0.535 0.236 vn -0.521 -0.606 0.601 vn -0.627 -0.631 0.458 vn -0.683 -0.703 0.200 vn -0.439 -0.787 0.433 vn -0.375 -0.817 0.438 vn -0.298 -0.397 0.868 vn -0.377 -0.065 0.924 vn -0.533 -0.169 0.829 vn -0.794 -0.381 0.473 vn -0.148 0.250 0.957 vn -0.138 0.216 0.967 vn -0.619 -0.288 0.730 vn -0.007 -0.217 0.976 vn -0.153 -0.371 0.916 vn -0.319 0.137 0.938 vn -0.173 -0.112 0.979 vn -0.051 -0.075 0.996 vn -0.300 -0.084 0.950 vn -0.447 -0.392 0.804 vn -0.048 -0.087 0.995 vn -0.338 -0.813 0.475 vn -0.023 -0.362 0.932 vn -0.610 -0.662 0.436 vn -0.014 0.346 0.938 vn -0.422 -0.114 0.899 vn -0.609 -0.439 0.660 vn -0.179 0.377 0.908 vn -0.554 -0.205 0.807 vn -0.054 0.377 0.925 vn -0.904 0.033 -0.426 vn -0.899 0.432 -0.071 vn -0.524 -0.007 0.852 vn -0.176 -0.181 0.968 vn -0.188 0.036 0.982 vn 0.075 -0.594 0.801 vn -0.218 -0.188 0.958 vn -0.068 -0.524 0.849 vn -0.331 -0.304 0.893 vn -0.073 -0.388 0.919 vn -0.131 -0.286 0.949 vn -0.468 -0.176 0.866 vn 0.102 -0.104 0.989 vn 0.449 -0.241 0.860 vn -0.092 0.074 0.993 vn 0.093 -0.660 0.745 vn -0.114 -0.011 0.993 vn -0.805 0.575 0.148 vn -0.842 0.455 0.289 vn -0.381 -0.103 -0.919 vn -0.934 0.167 0.317 vn -0.107 -0.902 -0.417 vn -0.778 -0.212 0.592 vn 0.063 -0.994 0.088 vn -0.590 -0.212 0.779 vn 0.025 -0.104 0.994 vn -0.114 -0.969 0.217 vn -0.407 -0.064 0.911 vn -0.272 -0.114 0.955 vn -0.540 -0.178 0.823 vn 0.012 0.452 0.892 vn -0.746 0.276 0.606 vn 0.654 0.683 0.324 vn 0.212 0.928 0.305 vn 0.165 -0.687 -0.707 vn -0.767 -0.463 0.444 vn -0.823 -0.291 0.488 vn 0.486 -0.781 -0.392 vn -0.734 -0.389 0.557 vn -0.482 -0.809 -0.337 vn -0.199 0.798 0.569 vn -0.419 0.850 0.319 vn -0.631 0.773 -0.067 vn -0.453 0.379 -0.807 vn 0.278 0.862 -0.423 vn 0.055 0.995 -0.078 vn 0.457 0.238 -0.857 vn 0.206 0.606 -0.768 vn 0.602 -0.712 -0.363 vn -0.811 -0.274 0.517 vn -0.692 0.203 0.692 vn 0.486 0.844 -0.226 vn 0.191 0.904 0.383 vn 0.007 0.698 0.716 vn -0.374 0.316 0.872 vn -0.996 0.091 0.019 vn -0.292 0.956 -0.021 vn -0.313 0.883 0.351 vn 0.003 0.659 0.752 vn -0.279 0.382 0.881 vn -0.398 0.325 0.858 vn 0.214 0.751 0.625 vn -0.564 0.750 0.344 vn -0.660 0.456 0.596 vn -0.843 -0.281 -0.459 vn -0.909 -0.092 -0.407 vn -0.789 -0.068 0.611 vn -0.852 0.114 0.512 vn -0.518 -0.545 0.660 vn -0.369 -0.335 0.867 vn 0.462 -0.585 -0.667 vn 0.734 -0.677 0.056 vn -0.049 -0.573 -0.818 vn 0.816 -0.403 -0.414 vn 0.390 -0.494 -0.777 vn 0.777 -0.413 -0.476 vn 0.725 -0.245 -0.643 vn 0.208 -0.969 0.130 vn 0.672 -0.229 -0.704 vn 0.058 0.853 0.519 vn 0.916 -0.274 0.293 vn 0.445 -0.063 0.893 vn 0.223 -0.971 0.082 vn -0.263 -0.619 -0.740 vn -0.693 -0.714 -0.104 vn -0.847 -0.529 0.039 vn -0.100 -0.897 -0.431 vn -0.829 -0.550 0.104 vn -0.805 -0.549 0.226 vn -0.271 -0.851 0.449 vn -0.114 -0.814 0.569 vn -0.604 -0.735 0.308 vn -0.111 -0.989 -0.101 vn -0.639 -0.293 -0.711 vn -0.215 -0.838 -0.502 vn -0.498 -0.864 0.072 vn -0.783 -0.405 -0.471 vn -0.231 -0.861 0.453 vn -0.472 -0.871 0.134 vn -0.221 -0.961 -0.166 vn -0.655 -0.288 -0.698 vn -0.047 -0.428 -0.902 vn -0.541 -0.441 -0.716 vn -0.621 -0.609 -0.494 vn 0.577 0.806 0.132 vn 0.588 0.804 0.092 vn 0.588 -0.246 0.771 vn 0.743 -0.174 0.646 vn 0.903 -0.254 0.347 vn 0.256 -0.796 0.549 vn 0.346 0.168 0.923 vn 0.468 -0.041 0.883 vn 0.570 0.233 0.788 vn 0.431 0.129 0.893 vn 0.121 -0.979 0.164 vn 0.699 -0.710 0.092 vn 0.085 -0.982 0.169 vn 0.083 -0.987 0.138 vn 0.055 -0.984 -0.169 vn 0.438 0.296 0.849 vn 0.779 0.186 0.599 vn 0.912 0.409 0.023 vn 0.329 0.590 0.738 vn 0.433 0.340 0.835 vn 0.914 0.405 0.031 vn 0.977 0.213 0.009 vn 0.870 -0.105 -0.482 vn 0.965 -0.031 0.260 vn 0.915 0.343 0.212 vn 0.978 -0.142 -0.154 vn 0.840 0.488 0.236 vn 0.593 0.442 0.673 vn 0.795 -0.235 0.559 vn 0.602 0.525 0.601 vn 0.676 0.328 0.659 vn 0.779 -0.407 0.478 vn 0.653 -0.265 0.709 vn 0.707 -0.205 0.677 vn 0.870 -0.491 0.050 vn 0.690 0.722 -0.052 vn 0.770 -0.098 0.630 vn 0.866 0.469 0.171 vn 0.994 -0.098 0.043 vn 0.876 -0.451 0.168 vn 0.919 -0.380 -0.110 vn 0.944 0.310 -0.112 vn 0.827 -0.092 0.554 vn 0.872 -0.489 -0.013 vn 0.973 0.201 0.111 vn 0.934 0.103 0.342 vn 0.962 0.269 0.049 vn 0.960 -0.212 -0.185 vn 0.996 0.089 -0.019 vn 0.970 -0.212 0.117 vn 0.917 -0.333 0.219 vn 0.789 -0.347 0.507 vn 0.968 0.147 0.202 vn 0.987 0.035 0.154 vn 0.949 0.179 0.260 vn -0.466 0.559 0.685 vn -0.708 0.420 0.569 vn -0.876 0.301 -0.377 vn -0.864 -0.276 -0.421 vn -0.669 -0.732 0.126 vn 0.416 -0.566 0.712 vn 0.969 0.124 0.212 vn 0.775 0.607 -0.177 vn 0.705 -0.345 0.619 vn 0.916 -0.400 0.036 vn 0.856 -0.107 -0.506 vn 0.993 0.066 -0.102 vn 0.479 0.656 -0.583 vn 0.413 -0.041 0.910 vn 0.048 -0.245 0.968 vn 0.405 0.076 0.911 vn 0.148 -0.245 0.958 vn 0.292 0.082 0.953 vn 0.736 0.218 0.641 vn 0.697 0.428 0.575 vn 0.888 0.333 0.317 vn 0.582 0.159 0.798 vn 0.593 0.315 0.741 vn 0.689 0.375 0.620 vn 0.305 -0.046 0.951 vn -0.172 0.914 0.367 vn 0.026 -0.071 0.997 vn 0.122 -0.325 0.938 vn 0.051 -0.132 0.990 vn -0.393 -0.478 0.785 vn -0.386 -0.514 0.766 vn -0.234 0.062 0.970 vn -0.274 -0.489 0.828 vn 0.342 0.588 0.733 vn 0.298 0.049 0.953 vn -0.010 -0.292 0.956 vn 0.948 -0.137 0.287 vn -0.044 -0.666 0.744 vn 0.459 0.498 0.736 vn 0.833 0.478 0.277 vn 0.858 -0.467 0.215 vn 0.831 -0.492 0.260 vn 0.504 0.726 0.468 vn 0.528 0.180 0.830 vn 0.944 0.327 0.050 vn 0.827 0.340 0.447 vn 0.981 0.179 0.071 vn 0.855 0.508 0.101 vn 0.844 0.247 0.476 vn 0.538 0.571 -0.619 vn -0.609 -0.338 0.718 vn 0.125 0.473 0.872 vn 0.892 0.182 0.414 vn -0.232 -0.900 0.369 vn 0.700 -0.698 0.152 vn 0.445 -0.079 0.892 vn 0.061 -0.984 0.168 vn -0.233 -0.726 0.647 vn 0.533 -0.626 0.569 vn 0.546 -0.221 0.808 vn 0.162 -0.960 0.228 vn 0.477 -0.878 0.045 vn 0.111 -0.974 0.197 vn 0.987 0.127 -0.098 vn 0.706 0.411 0.576 vn 0.903 -0.377 0.204 vn -0.488 -0.488 0.724 vn 0.101 -0.247 0.964 vn -0.125 -0.953 0.275 vn -0.255 -0.912 0.321 vn -0.698 -0.105 0.708 vn -0.626 -0.702 0.339 vn 0.700 -0.662 -0.269 vn 0.182 0.169 -0.969 vn 0.696 -0.284 -0.660 vn 0.796 0.605 -0.005 vn 0.966 -0.233 -0.114 vn 0.955 -0.278 -0.100 vn 0.747 -0.664 -0.030 vn 0.904 0.215 0.370 vn -0.211 -0.271 0.939 vn -0.445 0.386 0.808 vn -0.351 -0.500 0.792 vn -0.633 -0.011 0.774 vn -0.949 0.132 0.285 vn -0.474 -0.177 0.862 vn -0.537 -0.128 0.834 vn -0.443 -0.053 -0.895 vn 0.137 0.388 -0.911 vn 0.899 0.438 0.017 vn 0.826 0.267 -0.497 vn 0.189 -0.679 -0.709 vn 0.729 -0.212 -0.651 vn -0.337 0.429 0.838 vn -0.564 -0.582 0.587 vn 0.107 -0.317 0.942 vn -0.180 -0.649 0.739 vn -0.079 -0.358 0.930 vn -0.317 -0.550 0.773 vn 0.800 0.460 -0.385 vn 0.971 0.211 0.114 vn 0.963 0.192 -0.189 vn -0.369 -0.086 -0.925 vn -0.687 0.327 -0.650 vn -0.842 -0.453 -0.292 vn -0.818 -0.538 -0.203 vn -0.817 -0.551 0.169 vn -0.777 -0.567 0.273 vn -0.623 -0.600 0.501 vn -0.760 -0.590 0.273 vn -0.907 -0.422 0.006 vn 0.287 0.840 -0.460 vn -0.722 0.671 -0.167 vn -0.930 0.360 0.077 vn 0.198 0.786 -0.585 vn -0.612 0.743 -0.271 vn 0.050 0.963 -0.266 vn -0.630 0.777 0.014 vn -0.403 0.869 -0.287 vn 0.486 0.560 -0.671 vn 0.808 0.308 -0.503 vn 0.840 0.398 -0.368 vn 0.806 0.537 -0.250 vn 0.931 -0.070 -0.359 vn 0.785 0.305 -0.539 vn 0.983 -0.064 -0.174 vn 0.920 -0.379 -0.098 vn 0.421 -0.901 0.106 vn -0.194 -0.929 0.315 vn -0.633 -0.727 0.267 vn -0.486 -0.828 0.279 vn -0.906 -0.342 0.248 vn -0.981 0.184 -0.063 vn -0.084 0.671 -0.737 vn -0.726 -0.375 -0.577 vn -0.984 -0.082 -0.158 vn -0.979 0.178 0.098 vn -0.850 -0.476 0.226 vn 0.884 -0.431 -0.182 vn 0.400 -0.916 -0.009 vn -0.768 -0.630 0.119 vn 0.931 -0.361 -0.061 vn -0.174 -0.960 0.218 vn -0.491 -0.715 0.498 vn -0.269 -0.945 0.186 vn -0.966 -0.257 -0.034 vn -0.646 -0.453 -0.614 vn -0.910 0.386 -0.148 vn 0.273 -0.085 -0.958 vn 0.615 0.150 -0.774 vn -0.169 -0.327 -0.930 vn 0.454 -0.524 0.721 vn 0.988 0.132 0.081 vn 0.895 0.354 -0.270 vn 0.167 0.390 -0.906 vn 0.680 0.559 -0.474 vn -0.738 0.184 -0.649 vn 0.244 0.826 -0.509 vn -0.310 0.242 -0.919 vn -0.390 0.788 -0.477 vn -0.408 0.037 0.912 vn -0.923 -0.304 0.236 vn -0.694 -0.047 0.718 vn -0.939 -0.335 0.074 vn -0.508 -0.692 -0.513 vn -0.617 -0.709 -0.340 vn -0.287 -0.659 -0.696 vn -0.487 -0.761 -0.428 vn -0.733 -0.679 -0.034 vn -0.699 -0.454 0.552 vn -0.400 0.038 0.916 vn -0.630 -0.156 0.761 vn -0.381 0.058 0.923 vn -0.794 -0.595 0.126 vn -0.757 -0.587 -0.288 vn -0.459 -0.877 0.144 vn -0.346 -0.499 0.795 vn -0.854 -0.516 -0.063 vn -0.537 -0.739 0.406 vn -0.513 -0.287 0.809 vn -0.980 -0.136 0.147 vn -0.565 -0.728 -0.388 vn -0.608 -0.787 -0.107 vn 0.148 -0.309 -0.939 vn 0.682 0.098 -0.724 vn 0.638 0.177 -0.749 vn 0.908 0.411 -0.080 vn 0.853 0.477 -0.214 vn 0.591 0.779 0.209 vn 0.715 0.442 0.541 vn 0.543 0.647 0.535 vn 0.652 0.553 -0.519 vn -0.038 -0.069 -0.997 vn -0.001 -0.321 -0.947 vn -0.013 0.428 0.904 vn -0.272 0.154 0.950 vn 0.064 0.745 0.665 vn 0.521 0.853 0.028 vn -0.299 0.859 0.415 vn 0.380 0.889 -0.257 vn -0.502 0.842 0.197 vn 0.564 0.817 -0.119 vn -0.478 0.762 0.436 vn 0.792 0.494 0.359 vn -0.271 0.412 0.870 vn 0.756 0.580 0.302 vn 0.946 0.324 0.005 vn -0.399 0.421 0.815 vn 0.787 -0.467 -0.402 vn -0.681 -0.437 0.588 vn -0.112 -0.977 -0.179 vn 0.416 0.712 0.565 vn -0.385 0.428 0.818 vn 0.568 0.303 0.765 vn 0.556 -0.332 0.762 vn -0.456 -0.095 0.885 vn -0.870 -0.010 0.494 vn -0.095 0.609 0.788 vn -0.117 0.770 0.627 vn 0.951 0.285 -0.119 vn 0.873 0.269 -0.407 vn -0.848 0.073 0.525 vn -0.912 -0.301 0.280 vn -0.624 -0.610 0.488 vn 0.896 -0.054 -0.440 vn -0.002 -0.866 -0.500 vn -0.092 -0.940 -0.330 vn -0.072 -0.983 -0.169 vn 0.268 -0.957 0.108 vn 0.989 -0.123 -0.086 vn 0.765 -0.536 -0.358 vn -0.696 -0.268 0.666 vn -0.530 -0.646 -0.550 vn 0.770 -0.413 -0.486 vn -0.726 0.687 -0.030 vn -0.323 0.940 -0.109 vn 0.412 0.830 -0.377 vn -0.891 0.391 0.232 vn -0.959 -0.215 0.183 vn 0.684 0.139 -0.716 vn 0.317 0.788 -0.527 vn 0.685 0.676 0.273 vn -0.698 -0.522 0.491 vn 0.940 -0.300 -0.162 vn 0.829 -0.265 -0.492 vn 0.140 -0.983 -0.117 vn -0.715 -0.558 0.420 vn 0.109 -0.795 0.596 vn 0.817 -0.577 0.015 vn 0.262 -0.937 0.231 vn 0.106 0.711 -0.695 vn -0.052 0.858 0.510 vn 0.239 0.689 -0.684 vn -0.046 0.905 0.422 vn 0.611 0.538 -0.581 vn 0.367 0.735 0.570 vn 0.586 0.503 -0.635 vn 0.412 0.725 0.552 vn 0.750 0.657 -0.070 vn 0.319 0.607 0.728 vn 0.972 0.219 0.087 vn 0.037 -0.106 0.994 vn 0.714 0.224 -0.663 vn 0.233 -0.743 -0.628 vn 0.409 -0.841 0.355 vn 0.321 -0.303 -0.897 vn 0.109 -0.270 -0.957 vn 0.321 -0.356 -0.878 vn -0.207 -0.114 0.972 vn -0.169 0.266 0.949 vn -0.026 0.243 0.970 vn -0.397 -0.183 0.899 vn -0.471 -0.880 -0.055 vn -0.463 -0.858 -0.222 vn -0.325 -0.919 0.223 vn -0.058 -0.994 0.088 vn -0.092 0.002 0.996 vn 0.157 -0.627 -0.763 vn -0.529 -0.797 0.290 vn 0.140 -0.988 -0.070 vn -0.192 -0.377 0.906 vn 0.518 -0.277 0.809 vn 0.346 0.214 -0.913 vn 0.231 -0.299 -0.926 vn 0.310 -0.509 -0.803 vn -0.766 -0.495 -0.411 vn -0.585 -0.689 -0.428 vn -0.005 -0.993 -0.114 vn -0.670 -0.731 -0.133 vn -0.328 -0.769 -0.548 vn -0.319 -0.771 -0.551 vn 0.180 -0.571 -0.801 vn 0.378 -0.923 -0.065 vn -0.796 -0.558 -0.236 vn -0.636 0.485 0.600 vn -0.956 -0.051 0.288 vn -0.925 0.273 0.264 vn -0.972 0.039 0.230 vn -0.413 0.876 0.250 vn -0.754 -0.442 -0.487 vn 0.563 0.751 0.345 vn 0.458 0.870 0.183 vn -0.648 0.750 0.133 vn -0.705 0.589 0.396 vn 0.533 0.774 0.341 vn -0.662 0.547 0.513 vn 0.617 0.605 0.503 vn -0.142 0.575 0.805 vn 0.757 0.384 0.529 vn -0.011 0.114 0.993 vn 0.925 -0.288 0.248 vn 0.099 -0.929 0.357 vn -0.852 0.152 0.502 vn -0.753 -0.653 0.083 vn -0.982 -0.118 0.148 vn -0.944 -0.255 -0.211 vn 0.895 -0.444 0.048 vn 0.938 -0.241 -0.250 vn 0.959 0.257 0.118 vn 0.941 -0.330 -0.080 vn 0.006 -0.787 -0.617 vn -0.862 -0.505 0.044 vn -0.059 -0.697 -0.715 vn 0.205 -0.964 -0.168 vn 0.029 -0.999 0.046 vn 0.933 -0.187 0.307 vn -0.771 -0.510 0.381 vn 0.395 -0.725 -0.565 vn -0.070 -0.986 -0.150 vn 0.393 -0.253 0.884 vn -0.721 -0.559 0.410 vn -0.026 -0.960 0.280 vn 0.257 -0.844 0.470 vn -0.742 0.471 0.477 vn 0.402 0.685 0.608 vn 0.407 0.415 0.814 vn 0.736 0.551 0.393 vn 0.620 0.767 0.164 vn 0.467 -0.213 -0.858 vn 0.860 -0.422 -0.286 vn 0.807 -0.531 -0.259 vn 0.552 -0.343 -0.760 vn 0.087 -0.188 -0.978 vn -0.504 0.019 -0.864 vn -0.899 0.184 -0.398 vn -0.902 0.335 0.274 vn 0.677 -0.120 -0.726 vn -0.042 0.264 -0.964 vn -0.458 0.526 -0.717 vn -0.653 0.682 -0.330 vn -0.561 0.813 0.157 vn 0.750 -0.276 -0.601 vn 0.439 -0.264 -0.859 vn 0.717 -0.321 -0.619 vn -0.157 -0.570 -0.806 vn -0.102 0.462 -0.881 vn 0.786 -0.358 -0.504 vn 0.751 -0.081 -0.655 vn 0.383 0.336 -0.861 vn 0.890 0.065 -0.451 vn 0.890 -0.353 -0.290 vn 0.807 -0.022 -0.590 vn -0.116 0.674 -0.729 vn 0.721 0.127 -0.681 vn 0.541 -0.092 -0.836 vn 0.319 0.748 -0.582 vn -0.324 -0.780 -0.536 vn -0.286 0.012 -0.958 vn 0.374 -0.068 -0.925 vn -0.200 0.006 -0.980 vn -0.339 0.919 -0.201 vn -0.891 0.321 -0.320 vn 0.314 0.090 -0.945 vn 0.630 -0.161 -0.760 vn -0.079 0.497 -0.864 vn 0.536 0.300 -0.789 vn 0.905 0.134 -0.405 vn -0.101 -0.380 -0.920 vn 0.461 -0.518 -0.720 vn 0.191 -0.114 -0.975 vn 0.651 0.412 -0.638 vn 0.415 0.422 -0.806 vn 0.746 0.547 -0.380 vn -0.077 0.837 -0.541 vn -0.732 0.580 -0.359 vn -0.696 -0.462 -0.549 vn -0.333 0.327 -0.884 vn -0.535 0.309 -0.787 vn 0.573 -0.178 -0.800 vn 0.608 0.411 -0.679 vn 0.590 0.030 -0.807 vn -0.176 0.887 -0.427 vn 0.825 0.255 -0.505 vn -0.533 0.689 -0.492 vn -0.561 0.084 -0.823 vn 0.292 0.016 -0.956 vn -0.605 0.346 -0.717 vn 0.367 0.130 -0.921 vn 0.094 0.467 -0.879 vn -0.531 0.731 -0.429 vn 0.642 0.040 -0.765 vn 0.442 0.194 -0.875 vn 0.602 0.536 -0.593 vn 0.474 0.218 -0.853 vn -0.633 0.479 -0.608 vn 0.241 0.126 -0.962 vn -0.486 0.596 -0.639 vn -0.950 0.195 -0.245 vn 0.992 -0.072 -0.104 vn 0.677 0.736 -0.020 vn 0.961 0.143 -0.237 vn 0.119 0.376 -0.919 vn 0.829 0.548 -0.110 vn 0.816 0.064 -0.575 vn 0.246 0.228 -0.942 vn 0.462 0.846 -0.268 vn 0.887 0.019 -0.462 vn 0.866 0.383 -0.322 vn 0.458 -0.515 -0.725 vn 0.684 0.213 -0.698 vn 0.484 0.021 -0.875 vn 0.556 0.369 -0.745 vn -0.236 0.834 -0.499 vn 0.450 0.753 -0.479 vn -0.349 0.819 -0.455 vn -0.293 0.956 -0.014 vn 0.241 0.647 -0.723 vn 0.447 0.893 -0.051 vn -0.345 0.442 -0.828 vn -0.447 0.894 0.020 vn 0.044 0.980 0.196 vn 0.043 0.987 0.154 vn 0.400 0.915 0.056 vn 0.794 0.531 0.296 vn 0.856 0.238 0.458 vn 0.835 0.451 0.317 vn 0.467 0.705 0.534 vn 0.958 0.271 0.088 vn 0.995 -0.004 0.099 vn 0.905 -0.401 -0.140 vn 0.635 0.641 -0.431 vn 0.887 -0.074 -0.457 vn 0.800 -0.469 -0.374 vn 0.166 -0.549 -0.819 vn 0.483 -0.407 -0.775 vn 0.878 -0.219 -0.426 vn 0.706 -0.453 -0.544 vn -0.067 -0.633 -0.772 vn 0.305 -0.406 -0.862 vn -0.309 0.541 -0.782 vn -0.151 -0.420 -0.895 vn -0.298 -0.737 -0.607 vn 0.297 -0.259 -0.919 vn -0.699 -0.466 -0.543 vn 0.431 -0.420 -0.799 vn -0.614 0.162 -0.772 vn 0.113 0.993 -0.025 vn -0.090 0.966 0.241 vn -0.412 0.906 0.096 vn -0.091 0.802 -0.590 vn -0.259 -0.776 -0.576 vn -0.438 -0.339 -0.833 vn 0.096 -0.522 -0.847 vn 0.217 -0.274 -0.937 vn -0.712 -0.242 -0.659 vn -0.726 -0.485 -0.487 vn -0.497 0.132 -0.857 vn -0.543 -0.538 -0.645 vn 0.601 0.583 -0.546 vn -0.558 -0.059 -0.828 vn 0.215 -0.267 -0.939 vn -0.283 -0.716 -0.638 vn 0.543 -0.603 -0.585 vn 0.914 -0.143 -0.379 vn 0.091 -0.820 -0.565 vn -0.940 -0.142 -0.311 vn 0.992 -0.075 -0.097 vn -0.422 0.195 -0.885 vn -0.994 -0.065 0.083 vn 0.749 0.271 -0.604 vn 0.258 -0.852 -0.456 vn -0.973 -0.185 -0.137 vn 0.980 0.047 -0.192 vn -0.054 -0.867 -0.496 vn 0.902 0.430 -0.026 vn -0.634 0.761 0.139 vn 0.457 0.840 0.294 vn -0.241 0.967 -0.081 vn -0.511 0.845 0.161 vn 0.460 0.886 0.059 vn -0.614 0.759 0.217 vn -0.977 0.002 -0.214 vn 0.311 0.900 0.307 vn -0.026 -0.067 -0.997 vn -0.572 -0.451 -0.685 vn -0.876 0.262 -0.404 vn -0.548 0.212 -0.809 vn 0.550 -0.536 -0.640 vn -0.244 -0.674 -0.697 vn -0.788 -0.252 -0.562 vn 0.246 0.298 -0.922 vn 0.991 0.134 0.028 vn -0.000 -0.690 -0.724 vn -0.815 -0.192 -0.547 vn 0.993 0.026 0.117 vn -0.821 0.568 0.059 vn -0.697 0.641 -0.321 vn 0.463 0.762 0.452 vn -0.293 0.810 0.509 vn 0.040 0.963 -0.267 vn -0.060 0.861 -0.504 vn -0.627 0.764 -0.152 vn -0.895 0.375 -0.242 vn -0.259 0.926 0.274 vn 0.025 0.955 -0.297 vn -0.819 0.276 -0.503 vn 0.050 0.823 0.565 vn -0.282 0.783 -0.554 vn 0.256 0.866 0.431 vn 0.384 0.913 0.137 vn -0.077 0.865 -0.496 vn 0.810 0.556 0.184 vn -0.105 0.921 -0.376 vn -0.404 0.849 -0.341 vn 0.241 0.782 -0.574 vn 0.815 -0.465 -0.346 vn 0.511 0.630 0.585 vn 0.134 -0.636 -0.760 vn -0.776 -0.238 -0.583 vn 1.000 0.012 -0.021 vn -0.865 0.490 0.109 vn 0.787 -0.416 -0.456 vn 0.707 0.558 0.435 vn -0.448 -0.533 -0.718 vn -0.292 0.929 0.227 vn 0.874 -0.417 -0.248 vn 0.752 0.605 0.261 vn -0.195 0.823 0.534 vn -0.912 0.377 -0.160 vn 0.300 -0.789 -0.535 vn 0.967 0.248 -0.061 vn -0.270 0.925 -0.268 vn -0.801 -0.080 -0.593 vn 0.202 0.161 -0.966 vn -0.307 0.273 -0.912 vn -0.114 -0.164 -0.980 vn 0.313 -0.473 -0.824 vn 0.546 0.482 -0.686 vn 0.143 -0.305 -0.942 vn 0.421 0.511 -0.750 vn 0.590 0.776 0.224 vn -0.333 0.926 0.176 vn 0.352 0.935 -0.048 vn -0.211 0.654 -0.727 vn -0.354 0.822 -0.445 vn -0.213 0.835 -0.508 vn 0.132 0.546 -0.827 vn -0.259 0.880 -0.399 vn -0.074 0.707 -0.703 vn 0.417 0.892 -0.176 vn 0.087 0.772 -0.629 vn 0.027 0.933 -0.359 vn 0.495 0.839 -0.228 vn 0.430 0.770 -0.472 vn -0.205 0.802 -0.561 vn -0.704 0.262 -0.660 vn -0.260 -0.116 -0.959 vn 0.785 0.297 -0.544 vn -0.026 0.384 -0.923 vn -0.624 -0.481 -0.616 vn -0.451 -0.607 -0.654 vn -0.817 -0.160 -0.555 vn 0.208 0.878 -0.431 vn 0.584 0.810 0.048 vn 0.559 0.622 -0.548 vn -0.086 0.886 -0.456 vn 0.818 0.449 -0.359 vn 0.329 0.471 -0.818 vn -0.217 0.651 -0.727 vn 0.164 0.975 -0.152 vn -0.370 0.879 -0.302 vn -0.158 0.480 -0.863 vn 0.939 0.206 -0.275 vn 0.821 0.475 -0.317 vn 0.064 0.560 -0.826 vn 0.644 0.675 -0.358 vn -0.071 0.884 -0.461 vn 0.407 0.872 -0.271 vn 0.761 0.607 -0.229 vn 0.088 0.789 -0.608 vn 0.784 0.614 0.096 vn 0.694 0.691 -0.202 vn -0.151 0.685 -0.713 vn 0.837 0.508 -0.204 vn 0.785 0.491 0.378 vn 0.232 0.893 0.385 vn 0.758 0.651 0.038 vn 0.586 0.794 0.163 vn 0.478 0.862 -0.169 vn 0.575 0.406 -0.710 vn 0.502 0.858 -0.107 vn 0.347 -0.372 -0.861 vn 0.846 0.333 -0.417 vn 0.897 0.192 -0.397 vn 0.976 0.213 -0.044 vn 0.557 0.657 0.509 vn 0.936 0.254 -0.244 vn 0.839 0.542 0.038 vn 0.741 0.562 0.368 vn 0.066 0.864 0.499 vn 0.236 0.860 0.453 vn 0.477 0.879 -0.018 vn 0.906 0.298 0.300 vn 0.933 0.205 0.295 vn 0.767 0.559 0.313 vn 0.507 0.798 0.326 vn 0.432 0.900 -0.054 vn 0.614 0.785 -0.084 vn -0.355 0.926 -0.127 vn 0.380 0.840 -0.387 vn 0.352 0.333 -0.875 vn -0.144 0.908 -0.393 vn -0.870 0.417 -0.263 vn -0.224 0.639 -0.736 vn 0.570 0.816 -0.097 vn 0.338 0.941 0.032 vn -0.152 0.863 -0.481 vn -0.004 0.988 0.155 vn -0.242 0.672 -0.700 vn -0.053 0.897 -0.439 vn 0.463 0.781 -0.419 vn 0.155 0.767 -0.622 vn 0.034 0.975 0.221 vn 0.644 0.206 -0.737 vn 0.313 0.140 -0.939 vn 0.287 0.261 -0.922 vn 0.676 0.170 -0.717 vn 0.931 0.127 -0.343 vn 0.893 0.096 -0.440 vn 0.858 0.449 -0.249 vn 0.928 -0.340 0.151 vn 0.618 -0.670 0.412 vn 0.568 0.425 -0.705 vn -0.187 0.460 -0.868 vn 0.833 0.328 -0.445 vn 0.335 0.553 -0.763 vn 0.822 0.487 -0.294 vn 0.996 0.029 0.078 vn 0.343 -0.516 0.785 vn 0.553 -0.572 0.606 vn -0.002 0.705 -0.709 vn 0.733 0.578 0.359 vn 0.466 0.829 -0.308 vn -0.397 0.288 -0.871 vn -0.157 0.183 -0.971 vn -0.345 0.275 -0.897 vn -0.799 0.140 -0.585 vn 0.955 -0.291 0.051 vn 0.625 0.537 -0.566 vn 0.990 0.136 0.046 vn 0.941 0.328 0.083 vn 0.932 -0.169 0.319 vn 0.145 0.355 -0.923 vn 0.830 0.153 0.536 vn 0.847 0.094 0.523 vn 0.791 -0.564 0.237 vn 0.663 0.255 0.704 vn 0.931 0.227 0.286 vn -0.507 0.477 -0.718 vn 0.598 0.540 -0.592 vn -0.450 -0.025 -0.893 vn 0.010 0.355 -0.935 vn -0.233 -0.283 -0.930 vn 0.082 0.177 -0.981 vn 0.155 0.080 -0.985 vn -0.359 -0.187 -0.914 vn -0.261 -0.007 -0.965 vn 0.083 0.363 -0.928 vn 0.584 0.671 -0.457 vn -0.450 -0.248 -0.858 vn -0.798 0.171 -0.578 vn -0.693 0.008 -0.721 vn -0.830 -0.113 -0.547 vn -0.551 -0.691 -0.467 vn -0.914 -0.329 -0.235 vn -0.782 -0.506 -0.363 vn -0.661 -0.153 -0.735 vn -0.674 -0.447 -0.588 vn -0.534 -0.666 -0.521 vn -0.956 -0.272 -0.113 vn -0.791 0.168 -0.588 vn 0.848 0.071 -0.526 vn 0.609 -0.175 -0.773 vn 0.526 0.057 0.849 vn 0.624 0.051 -0.780 vn -0.240 -0.238 -0.941 vn -0.053 -0.603 -0.796 vn 0.556 0.042 -0.830 vn -0.561 -0.403 -0.723 vn -0.880 -0.141 -0.454 vn -0.926 -0.222 -0.305 vn -0.489 -0.166 -0.856 vn 0.200 0.391 -0.898 vn -0.734 -0.069 -0.676 vn -0.185 0.884 -0.429 vn -0.883 0.450 -0.132 vn 0.098 -0.235 -0.967 vn -0.388 0.206 -0.898 vn -0.607 0.148 -0.781 vn 0.100 0.181 -0.978 vn -0.637 -0.154 -0.755 vn 0.510 -0.467 -0.722 vn 0.114 -0.555 -0.824 vn 0.396 0.112 -0.911 vn -0.515 -0.112 -0.850 vn -0.710 -0.440 -0.550 vn -0.853 0.293 -0.431 vn -0.138 -0.733 -0.666 vn -0.005 0.955 -0.297 vn -0.841 0.325 -0.433 vn -0.604 -0.088 -0.792 vn -0.310 -0.012 -0.951 vn -0.803 -0.169 -0.572 vn 0.940 -0.281 -0.195 vn 0.876 -0.482 -0.015 vn 0.715 -0.697 0.047 vn 0.948 -0.075 0.310 vn 0.295 -0.623 0.724 vn -0.372 -0.656 0.657 vn -0.294 -0.549 0.783 vn 0.853 -0.472 -0.225 vn 0.592 -0.721 0.360 vn -0.845 -0.400 0.355 vn -0.979 -0.182 -0.096 vn -0.547 -0.813 0.200 vn -0.696 -0.637 0.330 vn -0.461 -0.885 0.058 vn -0.465 -0.885 -0.000 vn 0.004 -0.759 0.652 vn -0.145 -0.842 0.520 vn 0.660 0.632 -0.406 vn 0.657 0.056 0.752 vn 0.481 0.032 0.876 vn 0.807 0.528 0.265 vn 0.603 0.155 0.782 vn 0.216 -0.391 0.895 vn 0.391 -0.546 0.741 vn -0.328 -0.682 0.653 vn -0.724 -0.434 0.536 vn -0.260 -0.677 0.688 vn 0.341 -0.236 0.910 vn 0.700 0.350 -0.622 vn 0.692 0.666 0.280 vn 0.063 0.406 0.912 vn 0.486 0.042 -0.873 vn 0.742 0.141 -0.656 vn 0.829 0.357 -0.430 vn 0.817 0.576 0.008 vn -0.143 -0.155 -0.978 vn 0.761 0.266 -0.591 vn 0.739 0.673 0.040 vn 0.389 0.340 -0.856 vn 0.659 0.731 -0.175 vn 0.399 0.272 -0.876 vn 0.659 0.748 -0.083 vn 0.660 0.110 -0.743 vn 0.866 0.500 0.011 vn 0.632 -0.110 -0.767 vn 0.509 -0.306 -0.805 vn 0.779 0.374 0.503 vn 0.964 0.099 -0.245 vn 0.910 0.411 0.048 vn 0.780 0.054 0.624 vn -0.448 0.780 0.437 vn 0.295 0.362 0.884 vn 0.389 0.530 0.754 vn 0.126 0.297 0.946 vn 0.338 0.484 0.807 vn 0.103 -0.670 -0.735 vn 0.569 0.257 0.781 vn 0.965 -0.070 -0.252 vn 0.874 -0.484 0.037 vn -0.880 0.356 0.314 vn -0.888 -0.308 0.341 vn -0.736 -0.608 0.298 vn -0.912 -0.276 0.302 vn -0.692 -0.229 0.684 vn 0.824 -0.055 -0.563 vn 0.624 -0.216 -0.751 vn 0.176 -0.408 -0.896 vn 0.612 -0.596 -0.520 vn -0.165 0.922 0.351 vn 0.328 0.943 -0.057 vn 0.835 0.538 -0.117 vn 0.232 0.972 -0.047 vn 0.492 0.870 0.024 vn 0.401 0.850 -0.341 vn 0.822 0.562 0.097 vn -0.196 0.950 0.244 vn 0.711 0.692 0.123 vn 0.220 0.904 0.366 vn -0.087 0.836 0.541 vn 0.045 0.980 0.193 vn -0.233 0.918 0.320 vn -0.113 0.926 0.361 vn 0.325 0.944 -0.052 vn 0.647 0.661 -0.380 vn 0.801 0.578 0.157 vn 0.206 0.970 0.127 vn 0.456 0.847 0.272 vn 0.475 0.876 0.081 vn 0.292 0.852 0.434 vn -0.060 0.985 0.164 vn 0.671 0.711 -0.211 vn 0.223 0.969 -0.104 vn 0.134 0.982 -0.130 vn 0.251 0.889 0.383 vn 0.800 0.599 0.043 vn 0.397 0.836 -0.378 vn -0.225 -0.521 -0.823 vn -0.144 -0.611 -0.778 vn 0.377 -0.591 -0.713 vn -0.006 -0.321 -0.947 vn -0.599 -0.193 0.777 vn -0.533 0.055 0.845 vn -0.837 -0.538 -0.095 vn -0.750 -0.660 -0.033 vn -0.303 -0.172 0.937 vn -0.613 -0.780 -0.122 vn -0.103 0.127 0.987 vn -0.664 -0.707 -0.243 vn -0.307 -0.088 0.948 vn -0.227 -0.282 0.932 vn -0.556 -0.821 -0.132 vn -0.123 -0.806 0.578 vn -0.245 0.912 0.329 vn 0.641 0.671 0.372 vn 0.688 0.591 0.421 vn -0.157 0.905 0.396 vn 0.773 0.525 0.357 vn -0.143 0.884 0.445 vn 0.758 0.456 0.467 vn -0.245 0.782 0.572 vn 0.127 0.788 0.602 vn 0.792 0.429 0.435 vn -0.506 0.717 0.479 vn -0.986 0.146 0.085 vn -0.936 0.345 0.065 vn -0.995 -0.067 0.074 vn 0.303 0.657 0.690 vn 0.913 0.015 0.408 vn -0.621 0.554 0.554 vn 0.271 0.297 0.915 vn 0.492 -0.865 0.099 vn -0.926 -0.340 0.165 vn 0.956 -0.229 0.184 vn 0.938 -0.346 0.017 vn -0.539 -0.739 -0.403 vn 0.317 -0.883 -0.345 vn -0.481 -0.854 0.197 vn 0.212 -0.972 0.096 vn -0.878 -0.414 0.242 vn 0.587 -0.803 0.102 vn 0.348 -0.925 -0.153 vn -0.769 -0.552 -0.324 vn 0.063 -0.821 0.567 vn -0.319 -0.605 0.729 vn 0.523 0.308 0.795 vn -0.758 -0.512 0.403 vn -0.076 -0.407 0.910 vn -0.534 -0.658 0.531 vn 0.886 0.085 -0.457 vn 0.702 -0.091 -0.707 vn 0.449 -0.108 -0.887 vn 0.958 0.261 -0.117 vn 0.408 -0.328 -0.852 vn 0.998 0.029 -0.048 vn 0.421 -0.536 -0.732 vn 0.980 -0.193 0.056 vn 0.390 -0.477 -0.787 vn 0.973 -0.208 -0.097 vn 0.782 -0.488 -0.388 vn 0.022 -0.601 -0.799 vn 0.914 -0.128 0.384 vn 0.946 -0.316 0.070 vn 0.663 0.255 0.704 vn 0.790 0.177 0.586 vn 0.443 0.219 0.870 vn 0.597 -0.778 -0.198 vn -0.481 -0.655 -0.583 vn 0.629 -0.163 0.760 vn 0.058 -0.947 0.317 vn -0.998 0.060 -0.032 vn -0.008 0.388 0.921 vn -0.393 -0.383 -0.836 vn -0.553 -0.310 -0.774 vn -0.647 -0.403 -0.647 vn 0.276 -0.627 -0.729 vn -0.420 0.207 0.884 vn -0.095 0.495 0.864 vn -0.969 0.244 0.050 vn -0.986 -0.037 0.165 vn -0.199 0.169 0.965 vn -0.993 -0.049 0.104 vn -0.984 -0.168 -0.054 vn -0.263 0.199 0.944 vn -0.340 -0.507 0.792 vn -0.636 -0.237 0.734 vn 0.711 -0.217 -0.669 vn 0.480 -0.268 -0.835 vn 0.340 -0.309 -0.888 vn 0.992 -0.035 -0.125 vn 0.228 -0.448 -0.864 vn 0.970 -0.195 -0.143 vn 0.198 -0.781 -0.592 vn 0.834 -0.542 0.104 vn 0.161 -0.877 -0.452 vn 0.772 -0.566 0.289 vn 0.419 -0.907 0.037 vn -0.168 -0.868 -0.467 vn 0.753 -0.339 0.563 vn 0.864 -0.499 -0.064 vn 0.740 0.070 0.669 vn 0.665 0.227 0.711 vn 0.534 0.321 0.782 vn 0.273 -0.953 0.134 vn -0.562 -0.733 -0.384 vn 0.551 -0.241 0.799 vn -0.734 -0.106 0.671 vn -0.486 -0.404 -0.775 vn -0.629 -0.324 -0.707 vn -0.683 -0.377 -0.625 vn -0.224 -0.624 -0.749 vn -0.289 0.777 0.559 vn -0.060 0.817 0.574 vn -0.798 0.574 -0.185 vn -0.905 0.387 -0.177 vn -0.115 0.604 0.789 vn -0.963 0.145 -0.228 vn -0.993 0.102 -0.060 vn -0.100 0.400 0.911 vn -0.669 -0.372 0.643 vn -0.565 -0.396 0.724 vn -0.917 -0.290 -0.274 vn -0.884 -0.401 -0.238 vn -0.915 -0.401 -0.039 vn -0.367 -0.027 -0.930 vn 0.511 -0.346 -0.787 vn 0.199 -0.245 -0.949 vn 0.265 -0.295 -0.918 vn 0.909 -0.343 -0.236 vn 0.079 -0.705 -0.705 vn 0.768 -0.640 -0.027 vn -0.348 -0.761 -0.548 vn 0.407 -0.910 0.081 vn -0.563 -0.785 -0.259 vn 0.176 -0.922 0.346 vn -0.414 -0.843 0.342 vn -0.906 -0.366 -0.212 vn 0.269 -0.645 0.716 vn 0.711 -0.694 0.117 vn 0.810 -0.274 0.518 vn 0.731 -0.273 0.626 vn 0.740 -0.110 0.663 vn -0.602 -0.587 0.541 vn -0.986 -0.031 -0.165 vn 0.433 -0.333 0.838 vn -0.264 0.740 0.619 vn -0.631 -0.103 -0.769 vn -0.796 0.087 -0.599 vn -0.821 0.297 -0.488 vn -0.521 -0.286 -0.804 vn 0.827 0.498 0.263 vn 0.635 0.609 0.475 vn -0.089 0.947 -0.308 vn 0.028 0.955 -0.295 vn 0.690 0.547 0.473 vn -0.643 0.694 -0.325 vn -0.830 0.546 0.112 vn 0.276 0.006 0.961 vn -0.952 -0.304 0.013 vn -0.672 -0.707 0.219 vn 0.934 -0.149 0.326 vn 0.985 0.017 0.174 vn 0.500 0.578 0.645 vn 0.398 0.039 0.917 vn 0.334 0.517 0.788 vn 0.955 -0.164 -0.249 vn 0.835 -0.550 -0.015 vn 0.605 0.237 0.760 vn 0.803 0.445 0.397 vn 0.924 0.019 -0.383 vn 0.850 -0.455 -0.265 vn 0.890 0.361 -0.278 vn -0.728 0.410 -0.549 vn 0.274 0.757 0.593 vn 0.860 0.509 0.047 vn 0.862 0.482 0.159 vn 0.850 0.525 -0.047 vn 0.755 0.639 -0.147 vn 0.343 0.737 0.583 vn 0.923 0.356 -0.144 vn 0.318 0.865 0.388 vn 0.910 0.323 -0.259 vn 0.621 -0.057 -0.782 vn 0.448 -0.053 -0.893 vn 0.269 -0.243 -0.932 vn 0.066 -0.081 -0.995 vn -0.700 -0.507 -0.503 vn -0.732 -0.441 -0.520 vn -0.728 0.332 -0.599 vn -0.818 -0.092 -0.568 vn -0.531 0.842 0.093 vn -0.897 0.406 0.176 vn -0.795 0.585 0.163 vn -0.987 -0.082 0.140 vn -0.959 -0.031 0.283 vn -0.250 -0.479 -0.841 vn -0.296 0.827 0.478 vn -0.487 0.543 0.684 vn -0.401 0.614 0.680 vn 0.116 0.696 -0.709 vn 0.718 0.651 -0.246 vn 0.504 0.863 0.034 vn 0.395 0.836 0.382 vn 0.511 0.205 -0.835 vn 0.628 0.647 0.433 vn 0.680 -0.658 -0.324 vn 0.674 0.234 0.701 vn 0.519 -0.843 0.144 vn 0.473 0.201 0.858 vn -0.097 -0.142 0.985 vn 0.570 -0.772 0.280 vn 0.213 0.139 0.967 vn 0.157 0.019 0.987 vn -0.383 0.331 0.862 vn -0.961 0.187 0.203 vn -0.734 0.638 0.235 vn 0.345 -0.632 -0.694 vn 0.827 0.027 0.561 vn 0.766 0.196 0.612 vn 0.093 -0.902 -0.421 vn 0.742 0.065 0.667 vn 0.892 -0.386 -0.235 vn -0.356 0.741 0.569 vn -0.187 0.922 0.339 vn 0.093 0.996 -0.012 vn 0.268 0.600 -0.753 vn -0.671 0.566 -0.478 vn -0.450 0.881 -0.144 vn -0.411 -0.020 -0.911 vn -0.403 0.419 -0.814 vn -0.046 -0.910 -0.412 vn 0.747 0.204 0.633 vn -0.864 0.404 -0.301 vn -0.809 0.495 0.318 vn -0.495 0.535 0.685 vn 0.097 -0.760 -0.642 vn -0.223 -0.975 -0.004 vn 0.591 -0.333 -0.735 vn -0.383 -0.783 -0.491 vn 0.043 -0.563 -0.825 vn -0.343 -0.752 -0.563 vn -0.372 -0.581 -0.724 vn 0.354 -0.925 0.141 vn -0.325 -0.537 -0.779 vn -0.594 0.652 0.470 vn -0.636 -0.751 0.178 vn 0.656 -0.582 -0.480 vn -0.110 -0.595 -0.796 vn -0.006 -0.206 -0.979 vn -0.033 -0.090 -0.995 vn 0.951 0.194 -0.239 vn 0.525 -0.349 -0.776 vn 0.273 -0.239 -0.932 vn 0.244 0.667 -0.704 vn 0.804 0.501 0.320 vn 0.816 0.492 0.303 vn 0.600 0.754 -0.267 vn 0.922 0.331 -0.202 vn 0.951 -0.170 0.258 vn -0.121 -0.731 0.672 vn -0.882 -0.470 0.025 vn -0.937 0.051 -0.344 vn -0.464 -0.711 0.529 vn -0.495 -0.865 -0.077 # 2519 vertex normals g objDiablo3 s 1 f 6/1/6 5/2/5 8/3/8 f 6/1/6 8/3/8 7/4/7 f 12/5/12 11/6/11 10/7/10 f 12/5/12 10/7/10 9/8/9 f 15/9/15 14/10/14 1/11/1 f 15/9/15 1/11/1 2/12/2 f 16/13/16 15/9/15 2/12/2 f 16/13/16 2/12/2 17/14/17 f 25/15/25 24/16/24 23/17/23 f 25/15/25 23/17/23 22/18/22 f 5/2/5 10/7/10 13/19/13 f 5/2/5 13/19/13 8/3/8 f 9/8/9 10/7/10 5/2/5 f 9/8/9 5/2/5 4/20/4 f 13/19/13 24/16/24 7/4/7 f 13/19/13 7/4/7 8/3/8 f 11/6/11 23/17/23 24/16/24 f 11/6/11 24/16/24 13/19/13 f 20/21/20 27/22/27 25/15/25 f 20/21/20 25/15/25 22/18/22 f 29/23/29 28/24/28 27/22/27 f 29/23/29 27/22/27 20/21/20 f 30/25/30 27/22/27 28/24/28 f 30/25/30 28/24/28 31/26/31 f 31/26/31 28/24/28 1255/27/1255 f 31/26/31 1255/27/1255 1265/28/1265 f 1256/29/1256 1255/27/1255 28/24/28 f 1256/29/1256 28/24/28 29/23/29 f 33/30/33 32/31/32 1258/32/1258 f 33/30/33 1258/32/1258 1262/33/1262 f 1258/32/1258 32/31/32 31/26/31 f 1258/32/1258 31/26/31 1265/28/1265 f 34/34/34 1256/29/1256 29/23/29 f 34/34/34 29/23/29 35/35/35 f 35/35/35 29/23/29 20/21/20 f 35/35/35 20/21/20 36/36/36 f 37/37/37 34/34/34 35/35/35 f 37/37/37 35/35/35 38/38/38 f 35/35/35 36/36/36 39/39/39 f 35/35/35 39/39/39 38/38/38 f 40/40/40 37/37/37 38/38/38 f 40/40/40 38/38/38 41/41/41 f 41/41/41 38/38/38 39/39/39 f 41/41/41 39/39/39 42/42/42 f 43/43/43 37/37/37 40/40/40 f 43/43/43 40/40/40 44/44/44 f 45/45/45 12/5/12 9/8/9 f 45/45/45 9/8/9 46/46/46 f 41/41/41 42/42/42 12/5/12 f 41/41/41 12/5/12 45/45/45 f 47/47/47 44/44/44 40/40/40 f 47/47/47 40/40/40 45/45/45 f 48/48/48 50/49/50 18/50/18 f 48/48/48 18/50/18 19/51/19 f 52/52/52 1280/53/1280 50/49/50 f 52/52/52 50/49/50 48/48/48 f 53/54/53 25/15/25 27/22/27 f 53/54/53 27/22/27 30/25/30 f 54/55/54 26/56/26 25/15/25 f 54/55/54 25/15/25 53/54/53 f 59/57/59 54/55/54 53/54/53 f 59/57/59 53/54/53 60/58/60 f 30/25/30 55/59/55 60/58/60 f 30/25/30 60/58/60 53/54/53 f 48/48/48 49/60/49 57/61/57 f 48/48/48 57/61/57 52/52/52 f 52/52/52 57/61/57 33/30/33 f 52/52/52 33/30/33 51/62/51 f 61/63/61 45/45/45 46/46/46 f 61/63/61 46/46/46 62/64/62 f 109/65/109 44/44/44 65/66/65 f 109/65/109 65/66/65 108/67/108 f 67/68/67 42/42/42 66/69/66 f 67/68/67 66/69/66 21/70/21 f 69/71/69 16/13/16 17/14/17 f 69/71/69 17/14/17 70/72/70 f 17/14/17 6/1/6 18/50/18 f 17/14/17 18/50/18 72/73/72 f 72/73/72 18/50/18 50/49/50 f 72/73/72 50/49/50 73/74/73 f 73/74/73 50/49/50 1280/53/1280 f 73/74/73 1280/53/1280 74/75/74 f 75/76/75 72/73/72 73/74/73 f 75/76/75 73/74/73 76/77/76 f 76/77/76 73/74/73 74/75/74 f 76/77/76 74/75/74 77/78/77 f 75/76/75 76/77/76 79/79/79 f 75/76/75 79/79/79 78/80/78 f 84/81/84 81/82/81 83/83/83 f 84/81/84 83/83/83 82/84/82 f 85/85/85 79/79/79 87/86/87 f 85/85/85 87/86/87 86/87/86 f 79/79/79 80/88/80 88/89/88 f 79/79/79 88/89/88 87/86/87 f 85/85/85 83/83/83 81/82/81 f 85/85/85 81/82/81 78/80/78 f 92/90/92 91/91/91 90/92/90 f 92/90/92 90/92/90 68/93/68 f 92/90/92 86/94/86 93/95/93 f 92/90/92 93/95/93 91/91/91 f 82/96/82 83/97/83 94/98/94 f 82/96/82 94/98/94 92/90/92 f 86/94/86 89/99/89 95/100/95 f 86/94/86 95/100/95 93/95/93 f 96/101/96 89/102/89 87/86/87 f 96/101/96 87/86/87 88/89/88 f 100/103/100 99/104/99 98/105/98 f 100/103/100 98/105/98 97/106/97 f 97/106/97 98/105/98 104/107/104 f 97/106/97 104/107/104 103/108/103 f 97/106/97 107/109/107 106/110/106 f 97/106/97 106/110/106 100/103/100 f 101/111/101 109/112/109 108/113/108 f 101/111/101 108/113/108 103/108/103 f 103/108/103 111/114/111 107/109/107 f 103/108/103 107/109/107 97/106/97 f 112/115/112 113/116/113 115/117/115 f 112/115/112 115/117/115 114/118/114 f 194/119/194 126/120/126 115/117/115 f 194/119/194 115/117/115 196/121/196 f 117/122/117 112/115/112 114/118/114 f 117/122/117 114/118/114 118/123/118 f 146/124/146 117/122/117 118/123/118 f 146/124/146 118/123/118 174/125/174 f 113/116/113 127/126/127 128/127/128 f 113/116/113 128/127/128 129/128/129 f 127/126/127 120/129/120 132/130/132 f 127/126/127 132/130/132 130/131/130 f 139/132/139 138/133/138 137/134/137 f 139/132/139 137/134/137 140/135/140 f 120/129/120 144/136/144 141/137/141 f 120/129/120 141/137/141 132/130/132 f 143/138/143 141/137/141 144/136/144 f 143/138/143 144/136/144 145/139/145 f 139/132/139 135/140/135 157/141/157 f 139/132/139 157/141/157 136/142/136 f 131/143/131 134/144/134 150/145/150 f 131/143/131 150/145/150 149/146/149 f 134/144/134 157/141/157 151/147/151 f 134/144/134 151/147/151 150/145/150 f 152/148/152 153/149/153 159/150/159 f 152/148/152 159/150/159 155/151/155 f 157/141/157 158/152/158 160/153/160 f 157/141/157 160/153/160 159/150/159 f 143/138/143 145/139/145 162/154/162 f 143/138/143 162/154/162 178/155/178 f 153/149/153 151/147/151 157/141/157 f 153/149/153 157/141/157 159/150/159 f 167/156/167 161/157/161 168/158/168 f 167/156/167 168/158/168 169/159/169 f 171/160/171 190/161/190 191/162/191 f 171/160/171 191/162/191 173/163/173 f 189/164/189 148/165/148 174/125/174 f 189/164/189 174/125/174 188/166/188 f 116/167/116 179/168/179 123/169/123 f 116/167/116 123/169/123 115/117/115 f 125/170/125 179/168/179 184/171/184 f 125/170/125 184/171/184 183/172/183 f 179/168/179 116/167/116 182/173/182 f 179/168/179 182/173/182 184/171/184 f 181/174/181 126/120/126 194/119/194 f 181/174/181 194/119/194 185/175/185 f 186/176/186 201/177/201 187/178/187 f 186/176/186 187/178/187 172/179/172 f 172/179/172 191/162/191 190/161/190 f 172/179/172 190/161/190 186/176/186 f 129/128/129 208/180/208 197/181/197 f 129/128/129 197/181/197 196/121/196 f 199/182/199 147/183/147 146/124/146 f 199/182/199 146/124/146 198/184/198 f 200/185/200 162/154/162 145/139/145 f 200/185/200 145/139/145 199/182/199 f 200/186/200 225/187/225 175/188/175 f 200/186/200 175/188/175 162/189/162 f 186/176/186 190/161/190 204/190/204 f 186/176/186 204/190/204 203/191/203 f 205/192/205 210/193/210 235/194/235 f 205/192/205 235/194/235 234/195/234 f 206/196/206 207/197/207 205/192/205 f 206/196/206 205/192/205 203/191/203 f 207/198/207 206/199/206 208/180/208 f 207/198/207 208/180/208 129/128/129 f 205/192/205 207/197/207 209/200/209 f 205/192/205 209/200/209 210/193/210 f 339/201/339 219/202/219 233/203/233 f 339/201/339 233/203/233 338/204/338 f 213/205/213 212/206/212 337/207/337 f 213/205/213 337/207/337 340/208/340 f 214/209/214 215/210/215 217/211/217 f 214/209/214 217/211/217 216/212/216 f 224/213/224 211/214/211 214/209/214 f 224/213/224 214/209/214 220/215/220 f 214/209/214 216/212/216 222/216/222 f 214/209/214 222/216/222 220/215/220 f 216/212/216 260/217/260 258/218/258 f 216/212/216 258/218/258 222/216/222 f 225/187/225 221/219/221 224/213/224 f 225/187/225 224/213/224 223/220/223 f 238/221/238 226/222/226 225/187/225 f 238/221/238 225/187/225 223/220/223 f 231/223/231 213/205/213 340/208/340 f 231/223/231 340/208/340 341/224/341 f 230/225/230 231/223/231 341/224/341 f 230/225/230 341/224/341 229/226/229 f 232/227/232 213/205/213 231/223/231 f 232/227/232 231/223/231 240/228/240 f 212/206/212 213/205/213 232/227/232 f 212/206/212 232/227/232 215/210/215 f 202/229/202 233/230/233 187/178/187 f 202/229/202 187/178/187 201/177/201 f 202/231/202 337/207/337 338/204/338 f 202/231/202 338/204/338 233/203/233 f 202/229/202 201/177/201 234/195/234 f 202/229/202 234/195/234 235/194/235 f 232/227/232 240/228/240 237/232/237 f 232/227/232 237/232/237 236/233/236 f 236/233/236 237/232/237 248/234/248 f 236/233/236 248/234/248 250/235/250 f 215/210/215 232/227/232 236/233/236 f 215/210/215 236/233/236 217/211/217 f 227/236/227 226/222/226 238/221/238 f 227/236/227 238/221/238 239/237/239 f 245/238/245 227/236/227 239/237/239 f 245/238/245 239/237/239 247/239/247 f 242/240/242 206/196/206 203/191/203 f 242/240/242 203/191/203 204/190/204 f 243/241/243 181/174/181 193/242/193 f 243/241/243 193/242/193 244/243/244 f 208/180/208 242/244/242 244/243/244 f 208/180/208 244/243/244 193/242/193 f 228/245/228 245/238/245 230/246/230 f 228/245/228 230/246/230 229/247/229 f 246/248/246 237/249/237 240/250/240 f 246/248/246 240/250/240 247/239/247 f 249/251/249 253/252/253 261/253/261 f 249/251/249 261/253/261 259/254/259 f 254/255/254 246/248/246 247/239/247 f 254/255/254 247/239/247 239/237/239 f 238/221/238 255/256/255 254/255/254 f 238/221/238 254/255/254 239/237/239 f 255/256/255 238/221/238 223/220/223 f 255/256/255 223/220/223 220/215/220 f 261/253/261 262/257/262 250/235/250 f 261/253/261 250/235/250 259/254/259 f 257/258/257 260/217/260 262/257/262 f 257/258/257 262/257/262 261/253/261 f 251/259/251 257/258/257 261/253/261 f 251/259/251 261/253/261 253/252/253 f 264/260/264 263/261/263 265/262/265 f 264/260/264 265/262/265 266/263/266 f 273/264/273 283/265/283 271/266/271 f 273/264/273 271/266/271 274/267/274 f 274/267/274 265/262/265 263/261/263 f 274/267/274 263/261/263 275/268/275 f 270/269/270 284/270/284 276/271/276 f 270/269/270 276/271/276 277/272/277 f 268/273/268 271/266/271 283/265/283 f 268/273/268 283/265/283 284/270/284 f 278/274/278 279/275/279 282/276/282 f 278/274/278 282/276/282 281/277/281 f 279/275/279 273/264/273 298/278/298 f 279/275/279 298/278/298 282/276/282 f 273/264/273 274/267/274 275/268/275 f 273/264/273 275/268/275 298/278/298 f 269/279/269 402/280/402 295/281/295 f 269/279/269 295/281/295 286/282/286 f 286/282/286 295/281/295 288/283/288 f 286/282/286 288/283/288 287/284/287 f 287/284/287 288/283/288 290/285/290 f 287/284/287 290/285/290 289/286/289 f 292/287/292 289/286/289 290/285/290 f 292/287/292 290/285/290 293/288/293 f 255/289/255 256/290/256 289/286/289 f 255/289/255 289/286/289 292/287/292 f 263/261/263 254/291/254 297/292/297 f 263/261/263 297/292/297 298/278/298 f 292/287/292 293/288/293 297/292/297 f 292/287/292 297/292/297 254/291/254 f 296/293/296 387/294/387 288/283/288 f 296/293/296 288/283/288 295/281/295 f 286/282/286 251/259/251 253/252/253 f 286/282/286 253/252/253 269/279/269 f 287/284/287 289/286/289 256/290/256 f 287/284/287 256/290/256 252/295/252 f 251/259/251 286/282/286 287/284/287 f 251/259/251 287/284/287 252/295/252 f 266/296/266 267/297/267 253/252/253 f 266/296/266 253/252/253 249/251/249 f 293/288/293 291/298/291 299/299/299 f 293/288/293 299/299/299 297/292/297 f 299/299/299 291/298/291 300/300/300 f 299/299/299 300/300/300 301/301/301 f 301/302/301 300/303/300 302/304/302 f 301/302/301 302/304/302 303/305/303 f 303/305/303 302/304/302 304/306/304 f 303/305/303 304/306/304 305/307/305 f 305/307/305 304/306/304 306/308/306 f 305/307/305 306/308/306 307/309/307 f 306/308/306 308/310/308 315/311/315 f 306/308/306 315/311/315 307/309/307 f 310/312/310 314/313/314 316/314/316 f 310/312/310 316/314/316 334/315/334 f 316/314/316 317/316/317 312/317/312 f 316/314/316 312/317/312 334/315/334 f 309/318/309 336/319/336 316/314/316 f 309/318/309 316/314/316 314/313/314 f 336/319/336 311/320/311 317/316/317 f 336/319/336 317/316/317 316/314/316 f 323/321/323 327/322/327 308/310/308 f 323/321/323 308/310/308 306/308/306 f 305/307/305 319/323/319 324/324/324 f 305/307/305 324/324/324 303/305/303 f 299/299/299 301/301/301 320/325/320 f 299/299/299 320/325/320 321/326/321 f 303/305/303 324/324/324 320/327/320 f 303/305/303 320/327/320 301/302/301 f 300/300/300 291/298/291 344/328/344 f 300/300/300 344/328/344 322/329/322 f 302/304/302 300/303/300 322/330/322 f 302/304/302 322/330/322 323/321/323 f 319/323/319 315/311/315 325/331/325 f 319/323/319 325/331/325 349/332/349 f 325/331/325 315/311/315 318/333/318 f 325/331/325 318/333/318 326/334/326 f 320/327/320 324/324/324 349/332/349 f 320/327/320 349/332/349 432/335/432 f 332/336/332 308/310/308 327/322/327 f 332/336/332 327/322/327 333/337/333 f 333/337/333 327/322/327 328/338/328 f 333/337/333 328/338/328 329/339/329 f 325/331/325 326/334/326 329/340/329 f 325/331/325 329/340/329 328/341/328 f 326/334/326 318/333/318 330/342/330 f 326/334/326 330/342/330 331/343/331 f 331/344/331 330/345/330 332/336/332 f 331/344/331 332/336/332 333/337/333 f 330/342/330 345/346/345 334/315/334 f 330/342/330 334/315/334 335/347/335 f 336/319/336 346/348/346 330/345/330 f 336/319/336 330/345/330 335/349/335 f 312/317/312 313/350/313 335/347/335 f 312/317/312 335/347/335 334/315/334 f 335/349/335 313/350/313 311/320/311 f 335/349/335 311/320/311 336/319/336 f 337/207/337 212/206/212 218/351/218 f 337/207/337 218/351/218 338/204/338 f 338/204/338 218/351/218 211/214/211 f 338/204/338 211/214/211 339/201/339 f 202/231/202 235/352/235 340/208/340 f 202/231/202 340/208/340 337/207/337 f 235/352/235 210/353/210 341/224/341 f 235/352/235 341/224/341 340/208/340 f 342/354/342 290/285/290 288/283/288 f 342/354/342 288/283/288 387/294/387 f 328/338/328 327/322/327 347/355/347 f 328/338/328 347/355/347 348/356/348 f 325/331/325 328/341/328 348/357/348 f 325/331/325 348/357/348 349/332/349 f 348/356/348 347/355/347 351/358/351 f 348/356/348 351/358/351 352/359/352 f 349/332/349 348/357/348 352/360/352 f 349/332/349 352/360/352 350/361/350 f 347/355/347 323/321/323 322/330/322 f 347/355/347 322/330/322 351/358/351 f 354/362/354 344/363/344 343/364/343 f 354/362/354 343/364/343 353/365/353 f 354/362/354 353/365/353 355/366/355 f 354/362/354 355/366/355 356/367/356 f 356/367/356 355/366/355 357/368/357 f 356/367/356 357/368/357 358/369/358 f 357/368/357 359/370/359 360/371/360 f 357/368/357 360/371/360 358/369/358 f 362/372/362 361/373/361 363/374/363 f 362/372/362 363/374/363 364/375/364 f 365/376/365 366/377/366 363/374/363 f 365/376/365 363/374/363 361/373/361 f 368/378/368 369/379/369 359/370/359 f 368/378/368 359/370/359 357/368/357 f 362/372/362 371/380/371 374/381/374 f 362/372/362 374/381/374 360/371/360 f 356/367/356 372/382/372 373/383/373 f 356/367/356 373/383/373 354/362/354 f 372/382/372 360/371/360 374/381/374 f 372/382/372 374/381/374 383/384/383 f 370/385/370 369/379/369 376/386/376 f 370/385/370 376/386/376 375/387/375 f 374/381/374 371/380/371 375/388/375 f 374/381/374 375/388/375 376/389/376 f 377/390/377 379/391/379 364/375/364 f 377/390/377 364/375/364 381/392/381 f 366/377/366 380/393/380 377/394/377 f 366/377/366 377/394/377 381/395/381 f 376/386/376 369/379/369 368/378/368 f 376/386/376 368/378/368 382/396/382 f 374/381/374 376/389/376 382/397/382 f 374/381/374 382/397/382 383/384/383 f 294/398/294 342/354/342 386/399/386 f 294/398/294 386/399/386 385/400/385 f 353/365/353 343/364/343 385/401/385 f 353/365/353 385/401/385 368/378/368 f 296/293/296 295/281/295 402/280/402 f 296/293/296 402/280/402 388/402/388 f 387/294/387 296/293/296 388/402/388 f 387/294/387 388/402/388 389/403/389 f 352/404/352 351/405/351 395/406/395 f 352/404/352 395/406/395 390/407/390 f 350/408/350 352/404/352 390/407/390 f 350/408/350 390/407/390 434/409/434 f 390/407/390 395/406/395 394/410/394 f 390/407/390 394/410/394 392/411/392 f 434/409/434 390/407/390 392/411/392 f 434/409/434 392/411/392 391/412/391 f 392/411/392 394/410/394 386/399/386 f 392/411/392 386/399/386 393/413/393 f 391/412/391 392/411/392 393/413/393 f 391/412/391 393/413/393 396/414/396 f 359/370/359 369/379/369 370/385/370 f 359/370/359 370/385/370 365/376/365 f 394/415/394 395/416/395 382/396/382 f 394/415/394 382/396/382 368/378/368 f 297/292/297 321/326/321 397/417/397 f 297/292/297 397/417/397 298/278/298 f 281/277/281 282/276/282 398/418/398 f 281/277/281 398/418/398 396/419/396 f 433/420/433 391/421/391 400/422/400 f 433/420/433 400/422/400 399/423/399 f 396/419/396 398/418/398 400/422/400 f 396/419/396 400/422/400 391/421/391 f 298/278/298 397/417/397 398/418/398 f 298/278/298 398/418/398 282/276/282 f 321/326/321 403/424/403 401/425/401 f 321/326/321 401/425/401 397/417/397 f 395/426/395 384/427/384 383/384/383 f 395/426/395 383/384/383 382/397/382 f 280/428/280 281/277/281 396/419/396 f 280/428/280 396/419/396 389/429/389 f 280/428/280 389/429/389 388/430/388 f 280/428/280 388/430/388 277/272/277 f 402/431/402 270/269/270 277/272/277 f 402/431/402 277/272/277 388/430/388 f 403/432/403 404/433/404 405/434/405 f 403/432/403 405/434/405 401/435/401 f 404/433/404 407/436/407 406/437/406 f 404/433/404 406/437/406 405/434/405 f 406/437/406 407/436/407 409/438/409 f 406/437/406 409/438/409 408/439/408 f 412/440/412 410/441/410 411/442/411 f 412/440/412 411/442/411 413/443/413 f 415/444/415 410/441/410 412/440/412 f 415/444/415 412/440/412 416/445/416 f 417/446/417 406/437/406 408/439/408 f 417/446/417 408/439/408 418/447/418 f 411/442/411 409/438/409 420/448/420 f 411/442/411 420/448/420 419/449/419 f 421/450/421 422/451/422 420/448/420 f 421/450/421 420/448/420 409/438/409 f 424/452/424 423/453/423 425/454/425 f 424/452/424 425/454/425 418/447/418 f 420/448/420 425/455/425 423/456/423 f 420/448/420 423/456/423 419/449/419 f 426/457/426 430/458/430 413/443/413 f 426/457/426 413/443/413 428/459/428 f 416/445/416 430/460/430 426/461/426 f 416/445/416 426/461/426 429/462/429 f 425/454/425 431/463/431 417/446/417 f 425/454/425 417/446/417 418/447/418 f 420/448/420 422/451/422 431/464/431 f 420/448/420 431/464/431 425/455/425 f 408/439/408 415/444/415 424/452/424 f 408/439/408 424/452/424 418/447/418 f 431/463/431 435/465/435 433/466/433 f 431/463/431 433/466/433 417/446/417 f 435/467/435 431/464/431 422/451/422 f 435/467/435 422/451/422 432/468/432 f 243/469/243 244/470/244 437/471/437 f 243/469/243 437/471/437 436/472/436 f 436/472/436 437/471/437 439/473/439 f 436/472/436 439/473/439 438/474/438 f 436/472/436 438/474/438 444/475/444 f 436/472/436 444/475/444 440/476/440 f 436/472/436 440/476/440 441/477/441 f 436/472/436 441/477/441 243/469/243 f 184/171/184 243/241/243 441/478/441 f 184/171/184 441/478/441 442/479/442 f 441/477/441 440/476/440 443/480/443 f 441/477/441 443/480/443 558/481/558 f 443/480/443 440/476/440 444/475/444 f 443/480/443 444/475/444 445/482/445 f 441/478/441 558/483/558 447/484/447 f 441/478/441 447/484/447 446/485/446 f 446/485/446 447/484/447 122/486/122 f 446/485/446 122/486/122 121/487/121 f 439/473/439 437/471/437 451/488/451 f 439/473/439 451/488/451 1389/489/1389 f 451/488/451 437/471/437 244/470/244 f 451/488/451 244/470/244 242/490/242 f 1389/489/1389 451/488/451 204/491/204 f 1389/489/1389 204/491/204 1392/492/1392 f 1392/493/1392 204/494/204 171/495/171 f 1392/493/1392 171/495/171 452/496/452 f 452/496/452 171/495/171 483/497/483 f 452/496/452 483/497/483 453/498/453 f 453/498/453 483/497/483 454/499/454 f 453/498/453 454/499/454 455/500/455 f 455/500/455 454/499/454 456/501/456 f 455/500/455 456/501/456 457/502/457 f 457/502/457 456/501/456 458/503/458 f 457/502/457 458/503/458 459/504/459 f 459/504/459 458/503/458 460/505/460 f 459/504/459 460/505/460 461/506/461 f 461/506/461 460/505/460 462/507/462 f 461/506/461 462/507/462 463/508/463 f 463/508/463 462/507/462 464/509/464 f 463/508/463 464/509/464 465/510/465 f 465/510/465 464/509/464 466/511/466 f 465/510/465 466/511/466 467/512/467 f 458/503/458 456/501/456 468/513/468 f 458/503/458 468/513/468 528/514/528 f 460/505/460 458/503/458 469/515/469 f 460/505/460 469/515/469 470/516/470 f 462/507/462 460/505/460 470/516/470 f 462/507/462 470/516/470 471/517/471 f 464/509/464 462/507/462 471/517/471 f 464/509/464 471/517/471 472/518/472 f 466/511/466 464/509/464 472/518/472 f 466/511/466 472/518/472 473/519/473 f 468/513/468 456/501/456 454/499/454 f 468/513/468 454/499/454 474/520/474 f 468/513/468 474/520/474 475/521/475 f 468/513/468 475/521/475 498/522/498 f 475/521/475 474/520/474 476/523/476 f 475/521/475 476/523/476 477/524/477 f 476/523/476 474/520/474 479/525/479 f 476/523/476 479/525/479 480/526/480 f 482/527/482 479/525/479 483/497/483 f 482/527/482 483/497/483 484/528/484 f 482/527/482 484/528/484 486/529/486 f 482/527/482 486/529/486 519/530/519 f 487/531/487 488/532/488 490/533/490 f 487/531/487 490/533/490 489/534/489 f 487/531/487 489/534/489 492/535/492 f 487/531/487 492/535/492 491/536/491 f 492/535/492 489/534/489 493/537/493 f 492/535/492 493/537/493 494/538/494 f 488/532/488 498/522/498 495/539/495 f 488/532/488 495/539/495 496/540/496 f 490/533/490 488/532/488 496/540/496 f 490/533/490 496/540/496 497/541/497 f 171/495/171 173/542/173 484/528/484 f 171/495/171 484/528/484 483/497/483 f 479/525/479 474/520/474 454/499/454 f 479/525/479 454/499/454 483/497/483 f 489/534/489 490/533/490 497/541/497 f 489/534/489 497/541/497 493/537/493 f 499/543/499 475/521/475 505/544/505 f 499/543/499 505/544/505 503/545/503 f 507/546/507 502/547/502 508/548/508 f 507/546/507 508/548/508 509/549/509 f 481/550/481 519/530/519 508/548/508 f 481/550/481 508/548/508 502/547/502 f 503/545/503 514/551/514 537/552/537 f 503/545/503 537/552/537 501/553/501 f 511/554/511 510/555/510 514/551/514 f 511/554/511 514/551/514 503/545/503 f 515/556/515 486/529/486 484/528/484 f 515/556/515 484/528/484 173/542/173 f 513/557/513 514/551/514 510/555/510 f 513/557/513 510/555/510 521/558/521 f 520/559/520 542/560/542 546/561/546 f 520/559/520 546/561/546 522/562/522 f 470/516/470 469/515/469 523/563/523 f 470/516/470 523/563/523 524/564/524 f 471/517/471 470/516/470 524/564/524 f 471/517/471 524/564/524 525/565/525 f 472/518/472 471/517/471 525/565/525 f 472/518/472 525/565/525 526/566/526 f 531/567/531 491/536/491 492/535/492 f 531/567/531 492/535/492 533/568/533 f 541/569/541 515/556/515 538/570/538 f 541/569/541 538/570/538 539/571/539 f 539/571/539 540/572/540 543/573/543 f 539/571/539 543/573/543 541/569/541 f 542/560/542 545/574/545 547/575/547 f 542/560/542 547/575/547 546/561/546 f 550/576/550 551/577/551 552/578/552 f 550/576/550 552/578/552 445/482/445 f 551/577/551 549/579/549 555/580/555 f 551/577/551 555/580/555 557/581/557 f 548/582/548 600/583/600 555/580/555 f 548/582/548 555/580/555 549/579/549 f 450/584/450 568/585/568 189/164/189 f 450/584/450 189/164/189 188/166/188 f 568/585/568 572/586/572 573/587/573 f 568/585/568 573/587/573 571/588/571 f 569/589/569 578/590/578 586/591/586 f 569/589/569 586/591/586 577/592/577 f 448/593/448 564/594/564 591/595/591 f 448/593/448 591/595/591 590/596/590 f 561/597/561 743/598/743 744/599/744 f 561/597/561 744/599/744 595/600/595 f 600/583/600 593/601/593 598/602/598 f 600/583/600 598/602/598 599/603/599 f 559/604/559 599/603/599 594/605/594 f 559/604/559 594/605/594 601/606/601 f 594/605/594 598/602/598 593/601/593 f 594/605/594 593/601/593 592/607/592 f 555/608/555 600/609/600 605/610/605 f 555/608/555 605/610/605 604/611/604 f 604/611/604 590/612/590 591/613/591 f 604/611/604 591/613/591 555/608/555 f 605/610/605 600/609/600 599/614/599 f 605/610/605 599/614/599 559/615/559 f 635/616/635 930/617/930 936/618/936 f 635/616/635 936/618/936 603/619/603 f 993/620/993 994/621/994 610/622/610 f 993/620/993 610/622/610 607/623/607 f 610/622/610 995/624/995 618/625/618 f 610/622/610 618/625/618 617/626/617 f 619/627/619 620/628/620 618/625/618 f 619/627/619 618/625/618 995/624/995 f 648/629/648 618/630/618 620/631/620 f 648/629/648 620/631/620 643/632/643 f 547/575/547 545/574/545 627/633/627 f 547/575/547 627/633/627 625/634/625 f 624/635/624 628/636/628 627/633/627 f 624/635/624 627/633/627 626/637/626 f 581/638/581 628/636/628 624/635/624 f 581/638/581 624/635/624 580/639/580 f 581/640/581 610/641/610 617/642/617 f 581/640/581 617/642/617 628/643/628 f 555/608/555 591/613/591 556/644/556 f 555/608/555 556/644/556 557/645/557 f 630/646/630 629/647/629 631/648/631 f 630/646/630 631/648/631 632/649/632 f 560/650/560 630/646/630 634/651/634 f 560/650/560 634/651/634 635/652/635 f 632/649/632 631/648/631 633/653/633 f 632/649/632 633/653/633 634/651/634 f 603/654/603 638/655/638 637/656/637 f 603/654/603 637/656/637 636/657/636 f 559/615/559 638/658/638 606/659/606 f 559/615/559 606/659/606 605/610/605 f 643/632/643 644/660/644 647/661/647 f 643/632/643 647/661/647 646/662/646 f 647/661/647 644/660/644 676/663/676 f 647/661/647 676/663/676 649/664/649 f 641/665/641 640/666/640 651/667/651 f 641/665/641 651/667/651 652/668/652 f 639/669/639 641/665/641 654/670/654 f 639/669/639 654/670/654 653/671/653 f 641/665/641 652/668/652 655/672/655 f 641/665/641 655/672/655 654/670/654 f 673/673/673 653/674/653 656/675/656 f 673/673/673 656/675/656 657/676/657 f 654/670/654 655/672/655 658/677/658 f 654/670/654 658/677/658 656/678/656 f 656/675/656 662/679/662 663/680/663 f 656/675/656 663/680/663 657/676/657 f 656/678/656 658/677/658 664/681/664 f 656/678/656 664/681/664 662/682/662 f 662/679/662 665/683/665 660/684/660 f 662/679/662 660/684/660 663/680/663 f 661/685/661 665/686/665 662/682/662 f 661/685/661 662/682/662 664/681/664 f 673/673/673 657/676/657 667/687/667 f 673/673/673 667/687/667 672/688/672 f 658/677/658 655/672/655 666/689/666 f 658/677/658 666/689/666 668/690/668 f 663/680/663 660/684/660 669/691/669 f 663/680/663 669/691/669 670/692/670 f 664/681/664 658/677/658 668/690/668 f 664/681/664 668/690/668 671/693/671 f 657/676/657 663/680/663 670/692/670 f 657/676/657 670/692/670 667/687/667 f 661/685/661 664/681/664 671/693/671 f 661/685/661 671/693/671 669/691/669 f 671/693/671 668/690/668 667/687/667 f 671/693/671 667/687/667 670/692/670 f 668/690/668 674/694/674 672/688/672 f 668/690/668 672/688/672 667/687/667 f 674/694/674 666/689/666 675/695/675 f 674/694/674 675/695/675 677/696/677 f 675/695/675 666/689/666 655/672/655 f 675/695/675 655/672/655 652/668/652 f 673/673/673 672/688/672 678/697/678 f 673/673/673 678/697/678 676/698/676 f 915/699/915 679/700/679 680/701/680 f 915/699/915 680/701/680 767/702/767 f 915/699/915 682/703/682 683/704/683 f 915/699/915 683/704/683 679/700/679 f 681/705/681 680/706/680 684/707/684 f 681/705/681 684/707/684 685/708/685 f 681/705/681 685/708/685 687/709/687 f 681/705/681 687/709/687 699/710/699 f 686/711/686 683/704/683 689/712/689 f 686/711/686 689/712/689 711/713/711 f 687/709/687 690/714/690 698/715/698 f 687/709/687 698/715/698 699/710/699 f 693/716/693 694/717/694 696/718/696 f 693/716/693 696/718/696 697/719/697 f 688/720/688 701/721/701 697/719/697 f 688/720/688 697/719/697 696/718/696 f 691/722/691 688/720/688 699/710/699 f 691/722/691 699/710/699 698/715/698 f 697/719/697 701/721/701 703/723/703 f 697/719/697 703/723/703 704/724/704 f 706/725/706 689/712/689 683/704/683 f 706/725/706 683/704/683 682/703/682 f 707/726/707 708/727/708 749/728/749 f 707/726/707 749/728/749 750/729/750 f 679/700/679 683/704/683 686/711/686 f 679/700/679 686/711/686 710/730/710 f 685/708/685 684/707/684 712/731/712 f 685/708/685 712/731/712 713/732/713 f 710/730/710 686/711/686 714/733/714 f 710/730/710 714/733/714 716/734/716 f 715/735/715 687/709/687 685/708/685 f 715/735/715 685/708/685 713/732/713 f 711/713/711 690/714/690 722/736/722 f 711/713/711 722/736/722 717/737/717 f 690/714/690 687/709/687 715/735/715 f 690/714/690 715/735/715 722/736/722 f 684/738/684 710/730/710 716/734/716 f 684/738/684 716/734/716 712/739/712 f 686/711/686 711/713/711 717/737/717 f 686/711/686 717/737/717 714/733/714 f 712/739/712 716/734/716 720/740/720 f 712/739/712 720/740/720 718/741/718 f 715/735/715 713/732/713 718/742/718 f 715/735/715 718/742/718 723/743/723 f 714/733/714 717/737/717 721/744/721 f 714/733/714 721/744/721 720/740/720 f 721/744/721 717/737/717 722/736/722 f 721/744/721 722/736/722 719/745/719 f 723/743/723 719/745/719 722/736/722 f 723/743/723 722/736/722 715/735/715 f 718/742/718 724/746/724 727/747/727 f 718/742/718 727/747/727 723/743/723 f 720/740/720 721/744/721 725/748/725 f 720/740/720 725/748/725 724/749/724 f 721/744/721 719/745/719 726/750/726 f 721/744/721 726/750/726 725/748/725 f 723/743/723 727/747/727 726/750/726 f 723/743/723 726/750/726 719/745/719 f 772/751/772 729/752/729 771/753/771 f 772/751/772 771/753/771 681/705/681 f 649/754/649 676/755/676 732/756/732 f 649/754/649 732/756/732 731/757/731 f 729/758/729 700/759/700 733/760/733 f 729/758/729 733/760/733 734/761/734 f 678/762/678 730/763/730 734/761/734 f 678/762/678 734/761/734 732/756/732 f 732/756/732 737/764/737 736/765/736 f 732/756/732 736/765/736 731/757/731 f 734/761/734 733/760/733 738/766/738 f 734/761/734 738/766/738 739/767/739 f 734/761/734 739/767/739 737/764/737 f 734/761/734 737/764/737 732/756/732 f 743/598/743 561/597/561 740/768/740 f 743/598/743 740/768/740 742/769/742 f 743/598/743 603/654/603 636/657/636 f 743/598/743 636/657/636 744/599/744 f 744/599/744 596/770/596 601/606/601 f 744/599/744 601/606/601 745/771/745 f 757/772/757 752/773/752 759/774/759 f 757/772/757 759/774/759 761/775/761 f 760/776/760 757/772/757 761/775/761 f 760/776/760 761/775/761 762/777/762 f 677/778/677 921/779/921 922/780/922 f 677/778/677 922/780/922 730/781/730 f 681/705/681 696/718/696 692/782/692 f 681/705/681 692/782/692 772/751/772 f 763/783/763 758/784/758 773/785/773 f 763/783/763 773/785/773 775/786/775 f 760/776/760 762/777/762 773/785/773 f 760/776/760 773/785/773 758/784/758 f 777/787/777 754/788/754 787/789/787 f 777/787/777 787/789/787 776/790/776 f 756/791/756 782/792/782 784/793/784 f 756/791/756 784/793/784 783/794/783 f 791/795/791 794/796/794 801/797/801 f 791/795/791 801/797/801 800/798/800 f 786/799/786 781/800/781 779/801/779 f 786/799/786 779/801/779 806/802/806 f 774/803/774 799/804/799 810/805/810 f 774/803/774 810/805/810 809/806/809 f 811/807/811 807/808/807 809/806/809 f 811/807/811 809/806/809 810/805/810 f 808/809/808 811/807/811 810/805/810 f 808/809/808 810/805/810 819/810/819 f 814/811/814 808/809/808 819/810/819 f 814/811/814 819/810/819 820/812/820 f 830/813/830 822/814/822 801/797/801 f 830/813/830 801/797/801 829/815/829 f 839/816/839 838/817/838 841/818/841 f 839/816/839 841/818/841 840/819/840 f 838/817/838 839/816/839 848/820/848 f 838/817/838 848/820/848 847/821/847 f 842/822/842 838/817/838 847/821/847 f 842/822/842 847/821/847 849/823/849 f 847/821/847 848/820/848 859/824/859 f 847/821/847 859/824/859 850/825/850 f 849/823/849 847/821/847 850/825/850 f 849/823/849 850/825/850 851/826/851 f 852/827/852 845/828/845 842/822/842 f 852/827/852 842/822/842 849/823/849 f 845/828/845 852/827/852 854/829/854 f 845/828/845 854/829/854 853/830/853 f 852/827/852 873/831/873 871/832/871 f 852/827/852 871/832/871 854/829/854 f 863/833/863 825/834/825 840/819/840 f 863/833/863 840/819/840 841/818/841 f 863/833/863 841/818/841 843/835/843 f 863/833/863 843/835/843 844/836/844 f 843/835/843 862/837/862 864/838/864 f 843/835/843 864/838/864 844/836/844 f 857/839/857 855/840/855 883/841/883 f 857/839/857 883/841/883 884/842/884 f 856/843/856 857/839/857 884/842/884 f 856/843/856 884/842/884 1380/844/1380 f 869/845/869 870/846/870 871/832/871 f 869/845/869 871/832/871 873/831/873 f 851/826/851 850/825/850 855/840/855 f 851/826/851 855/840/855 857/839/857 f 881/847/881 876/848/876 877/849/877 f 881/847/881 877/849/877 868/850/868 f 877/849/877 876/848/876 878/851/878 f 877/849/877 878/851/878 879/852/879 f 879/852/879 878/851/878 892/853/892 f 879/852/879 892/853/892 880/854/880 f 881/847/881 868/850/868 883/841/883 f 881/847/881 883/841/883 882/855/882 f 868/850/868 946/856/946 884/842/884 f 868/850/868 884/842/884 883/841/883 f 887/857/887 886/858/886 890/859/890 f 887/857/887 890/859/890 891/860/891 f 885/861/885 887/857/887 891/860/891 f 885/861/885 891/860/891 889/862/889 f 896/863/896 860/864/860 888/865/888 f 896/863/896 888/865/888 895/866/895 f 878/851/878 876/848/876 893/867/893 f 878/851/878 893/867/893 892/853/892 f 876/848/876 881/847/881 894/868/894 f 876/848/876 894/868/894 893/867/893 f 881/847/881 885/861/885 889/862/889 f 881/847/881 889/862/889 894/868/894 f 875/869/875 877/849/877 879/852/879 f 875/869/875 879/852/879 880/854/880 f 895/866/895 890/859/890 886/858/886 f 895/866/895 886/858/886 896/863/896 f 861/870/861 848/820/848 839/816/839 f 861/870/861 839/816/839 927/871/927 f 825/834/825 914/872/914 913/873/913 f 825/834/825 913/873/913 840/819/840 f 520/559/520 522/562/522 521/558/521 f 520/559/520 521/558/521 510/555/510 f 615/874/615 613/875/613 897/876/897 f 615/874/615 897/876/897 898/877/898 f 901/878/901 900/879/900 898/877/898 f 901/878/901 898/877/898 897/876/897 f 615/880/615 898/881/898 903/882/903 f 615/880/615 903/882/903 902/883/902 f 903/882/903 919/884/919 910/885/910 f 903/882/903 910/885/910 908/886/908 f 902/883/902 903/882/903 908/886/908 f 902/883/902 908/886/908 907/887/907 f 675/695/675 652/668/652 904/888/904 f 675/695/675 904/888/904 905/889/905 f 905/890/905 904/891/904 906/892/906 f 905/890/905 906/892/906 909/893/909 f 910/885/910 911/894/911 907/887/907 f 910/885/910 907/887/907 908/886/908 f 910/885/910 919/884/919 909/893/909 f 910/885/910 909/893/909 911/895/911 f 913/873/913 914/872/914 915/896/915 f 913/873/913 915/896/915 916/897/916 f 912/898/912 900/899/900 916/897/916 f 912/898/912 916/897/916 915/896/915 f 914/872/914 828/900/828 827/901/827 f 914/872/914 827/901/827 682/902/682 f 768/903/768 769/904/769 918/905/918 f 768/903/768 918/905/918 917/906/917 f 912/907/912 768/903/768 917/906/917 f 912/907/912 917/906/917 919/908/919 f 921/779/921 677/778/677 675/909/675 f 921/779/921 675/909/675 923/910/923 f 905/911/905 909/912/909 923/913/923 f 905/911/905 923/913/923 675/914/675 f 919/908/919 917/906/917 923/913/923 f 919/908/919 923/913/923 909/912/909 f 768/903/768 915/915/915 767/916/767 f 768/903/768 767/916/767 924/917/924 f 930/617/930 633/918/633 932/919/932 f 930/617/930 932/919/932 931/920/931 f 853/830/853 854/829/854 934/921/934 f 853/830/853 934/921/934 935/922/935 f 854/829/854 871/832/871 933/923/933 f 854/829/854 933/923/933 953/924/953 f 930/617/930 931/920/931 937/925/937 f 930/617/930 937/925/937 936/618/936 f 853/830/853 937/925/937 846/926/846 f 853/830/853 846/926/846 845/828/845 f 953/924/953 938/927/938 954/928/954 f 953/924/953 954/928/954 934/921/934 f 941/929/941 895/866/895 888/865/888 f 941/929/941 888/865/888 938/930/938 f 939/931/939 954/932/954 938/930/938 f 939/931/939 938/930/938 888/865/888 f 861/870/861 927/871/927 928/933/928 f 861/870/861 928/933/928 939/931/939 f 939/931/939 928/933/928 901/934/901 f 939/931/939 901/934/901 954/932/954 f 890/859/890 895/866/895 941/929/941 f 890/859/890 941/929/941 940/935/940 f 892/853/892 893/867/893 942/936/942 f 892/853/892 942/936/942 1151/937/1151 f 1151/938/1151 942/939/942 944/940/944 f 1151/938/1151 944/940/944 992/941/992 f 942/939/942 943/942/943 945/943/945 f 942/939/942 945/943/945 944/940/944 f 944/940/944 948/944/948 959/945/959 f 944/940/944 959/945/959 992/941/992 f 948/944/948 944/940/944 952/946/952 f 948/944/948 952/946/952 947/947/947 f 947/947/947 950/948/950 872/949/872 f 947/947/947 872/949/872 1380/844/1380 f 951/950/951 950/948/950 947/947/947 f 951/950/951 947/947/947 952/946/952 f 945/943/945 955/951/955 956/952/956 f 945/943/945 956/952/956 951/950/951 f 870/846/870 869/845/869 872/949/872 f 870/846/870 872/949/872 950/948/950 f 951/950/951 956/952/956 870/846/870 f 951/950/951 870/846/870 950/948/950 f 940/953/940 941/954/941 955/951/955 f 940/953/940 955/951/955 945/943/945 f 955/951/955 941/954/941 938/927/938 f 955/951/955 938/927/938 953/924/953 f 954/928/954 901/955/901 899/956/899 f 954/928/954 899/956/899 934/921/934 f 949/957/949 875/869/875 957/958/957 f 949/957/949 957/958/957 958/959/958 f 949/957/949 958/959/958 979/960/979 f 949/957/949 979/960/979 959/945/959 f 961/961/961 957/958/957 880/854/880 f 961/961/961 880/854/880 960/962/960 f 963/963/963 958/959/958 957/958/957 f 963/963/963 957/958/957 962/964/962 f 1152/965/1152 964/966/964 960/962/960 f 1152/965/1152 960/962/960 880/854/880 f 1077/967/1077 962/964/962 961/961/961 f 1077/967/1077 961/961/961 1078/968/1078 f 961/961/961 960/962/960 1115/969/1115 f 961/961/961 1115/969/1115 1114/970/1114 f 963/963/963 962/964/962 965/971/965 f 963/963/963 965/971/965 966/972/966 f 960/962/960 964/966/964 1154/973/1154 f 960/962/960 1154/973/1154 1153/974/1153 f 966/972/966 965/971/965 967/975/967 f 966/972/966 967/975/967 968/976/968 f 968/976/968 967/975/967 969/977/969 f 968/976/968 969/977/969 970/978/970 f 970/978/970 969/977/969 971/979/971 f 970/978/970 971/979/971 972/980/972 f 972/980/972 971/979/971 973/981/973 f 972/980/972 973/981/973 977/982/977 f 958/959/958 1042/983/1042 1041/984/1041 f 958/959/958 1041/984/1041 979/960/979 f 966/972/966 968/976/968 981/985/981 f 966/972/966 981/985/981 980/986/980 f 972/980/972 977/982/977 983/987/983 f 972/980/972 983/987/983 981/985/981 f 983/987/983 977/982/977 975/988/975 f 983/987/983 975/988/975 982/989/982 f 986/990/986 976/991/976 974/992/974 f 986/990/986 974/992/974 984/993/984 f 975/988/975 976/991/976 986/990/986 f 975/988/975 986/990/986 985/994/985 f 987/995/987 986/990/986 984/993/984 f 987/995/987 984/993/984 1036/996/1036 f 985/994/985 986/990/986 987/995/987 f 985/994/985 987/995/987 1035/997/1035 f 979/960/979 1041/984/1041 1052/998/1052 f 979/960/979 1052/998/1052 988/999/988 f 992/941/992 959/945/959 979/960/979 f 992/941/992 979/960/979 988/999/988 f 608/1000/608 611/1001/611 994/621/994 f 608/1000/608 994/621/994 993/620/993 f 995/624/995 994/621/994 611/1001/611 f 995/624/995 611/1001/611 642/1002/642 f 1000/1003/1000 816/1004/816 814/811/814 f 1000/1003/1000 814/811/814 997/1005/997 f 830/813/830 1010/1006/1010 1009/1007/1009 f 830/813/830 1009/1007/1009 822/814/822 f 837/1008/837 832/1009/832 1010/1006/1010 f 837/1008/837 1010/1006/1010 830/813/830 f 1003/1010/1003 844/836/844 865/1011/865 f 1003/1010/1003 865/1011/865 1013/1012/1013 f 1016/1013/1016 1007/1014/1007 1022/1015/1022 f 1016/1013/1016 1022/1015/1022 1015/1016/1015 f 865/1011/865 999/1017/999 1019/1018/1019 f 865/1011/865 1019/1018/1019 1023/1019/1023 f 824/1020/824 1012/1021/1012 835/1022/835 f 824/1020/824 835/1022/835 836/1023/836 f 1028/1024/1028 1025/1025/1025 973/981/973 f 1028/1024/1028 973/981/973 971/979/971 f 1025/1025/1025 1026/1026/1026 974/992/974 f 1025/1025/1025 974/992/974 973/981/973 f 1027/1027/1027 1028/1024/1028 967/975/967 f 1027/1027/1027 967/975/967 965/971/965 f 1029/1028/1029 1030/1029/1030 983/987/983 f 1029/1028/1029 983/987/983 982/989/982 f 1031/1030/1031 1032/1031/1032 1026/1026/1026 f 1031/1030/1031 1026/1026/1026 1025/1025/1025 f 1030/1032/1030 1029/1033/1029 1032/1034/1032 f 1030/1032/1030 1032/1034/1032 1031/1035/1031 f 1033/1036/1033 1034/1037/1034 1032/1034/1032 f 1033/1036/1033 1032/1034/1032 1029/1033/1029 f 1035/1038/1035 1036/1039/1036 1034/1037/1034 f 1035/1038/1035 1034/1037/1034 1033/1036/1033 f 1039/1040/1039 1037/1041/1037 1030/1032/1030 f 1039/1040/1039 1030/1032/1030 1031/1035/1031 f 1112/1042/1112 1038/1043/1038 1037/1041/1037 f 1112/1042/1112 1037/1041/1037 1039/1040/1039 f 1028/1024/1028 1039/1044/1039 1031/1030/1031 f 1028/1024/1028 1031/1030/1031 1025/1025/1025 f 1027/1027/1027 1112/1045/1112 1039/1044/1039 f 1027/1027/1027 1039/1044/1039 1028/1024/1028 f 1038/1046/1038 980/986/980 981/985/981 f 1038/1046/1038 981/985/981 1037/1047/1037 f 1041/984/1041 1042/983/1042 1043/1048/1043 f 1041/984/1041 1043/1048/1043 1044/1049/1044 f 1044/1049/1044 1043/1048/1043 1045/1050/1045 f 1044/1049/1044 1045/1050/1045 1046/1051/1046 f 1046/1051/1046 1045/1050/1045 1047/1052/1047 f 1046/1051/1046 1047/1052/1047 1048/1053/1048 f 1041/984/1041 1044/1049/1044 1053/1054/1053 f 1041/984/1041 1053/1054/1053 1052/998/1052 f 1053/1054/1053 1048/1053/1048 1051/1055/1051 f 1053/1054/1053 1051/1055/1051 1054/1056/1054 f 1055/1057/1055 1049/1058/1049 1050/1059/1050 f 1055/1057/1055 1050/1059/1050 1056/1060/1056 f 1051/1055/1051 1049/1058/1049 1055/1057/1055 f 1051/1055/1051 1055/1057/1055 1057/1061/1057 f 1058/1062/1058 1055/1057/1055 1056/1060/1056 f 1058/1062/1058 1056/1060/1056 1059/1063/1059 f 1057/1061/1057 1055/1057/1055 1058/1062/1058 f 1057/1061/1057 1058/1062/1058 1060/1064/1060 f 1061/1065/1061 1062/1066/1062 1050/1059/1050 f 1061/1065/1061 1050/1059/1050 1047/1052/1047 f 978/1067/978 1061/1065/1061 1043/1048/1043 f 978/1067/978 1043/1048/1043 1042/983/1042 f 1063/1068/1063 1070/1069/1070 1053/1054/1053 f 1063/1068/1063 1053/1054/1053 1054/1056/1054 f 1069/1070/1069 1064/1071/1064 1062/1066/1062 f 1069/1070/1069 1062/1066/1062 1061/1065/1061 f 1070/1072/1070 1063/1073/1063 1064/1074/1064 f 1070/1072/1070 1064/1074/1064 1069/1075/1069 f 1065/1076/1065 1066/1077/1066 1064/1074/1064 f 1065/1076/1065 1064/1074/1064 1063/1073/1063 f 1067/1078/1067 1068/1079/1068 1066/1077/1066 f 1067/1078/1067 1066/1077/1066 1065/1076/1065 f 1060/1080/1060 1059/1081/1059 1068/1079/1068 f 1060/1080/1060 1068/1079/1068 1067/1078/1067 f 1071/1082/1071 1187/1083/1187 1070/1072/1070 f 1071/1082/1071 1070/1072/1070 1069/1075/1069 f 1061/1065/1061 978/1067/978 1071/1084/1071 f 1061/1065/1061 1071/1084/1071 1069/1070/1069 f 1187/1085/1187 1052/998/1052 1053/1054/1053 f 1187/1085/1187 1053/1054/1053 1070/1069/1070 f 1073/1086/1073 963/963/963 966/972/966 f 1073/1086/1073 966/972/966 980/986/980 f 1076/1087/1076 1074/1088/1074 990/1089/990 f 1076/1087/1076 990/1089/990 1187/1090/1187 f 1073/1086/1073 980/986/980 1038/1046/1038 f 1073/1086/1073 1038/1046/1038 1075/1091/1075 f 1075/1092/1075 1038/1043/1038 1112/1042/1112 f 1075/1092/1075 1112/1042/1112 1076/1087/1076 f 981/985/981 983/987/983 1030/1029/1030 f 981/985/981 1030/1029/1030 1037/1047/1037 f 1077/967/1077 1078/968/1078 1079/1093/1079 f 1077/967/1077 1079/1093/1079 1080/1094/1080 f 1080/1094/1080 1079/1093/1079 1081/1095/1081 f 1080/1094/1080 1081/1095/1081 1082/1096/1082 f 1082/1096/1082 1081/1095/1081 1083/1097/1083 f 1082/1096/1082 1083/1097/1083 1084/1098/1084 f 1084/1098/1084 1083/1097/1083 1085/1099/1085 f 1084/1098/1084 1085/1099/1085 1086/1100/1086 f 1077/967/1077 1080/1094/1080 1091/1101/1091 f 1077/967/1077 1091/1101/1091 1090/1102/1090 f 1084/1098/1084 1086/1100/1086 1092/1103/1092 f 1084/1098/1084 1092/1103/1092 1091/1101/1091 f 1092/1103/1092 1086/1100/1086 1089/1104/1089 f 1092/1103/1092 1089/1104/1089 1093/1105/1093 f 1094/1106/1094 1087/1107/1087 1088/1108/1088 f 1094/1106/1094 1088/1108/1088 1095/1109/1095 f 1089/1104/1089 1087/1107/1087 1094/1106/1094 f 1089/1104/1089 1094/1106/1094 1096/1110/1096 f 1097/1111/1097 1094/1106/1094 1095/1109/1095 f 1097/1111/1097 1095/1109/1095 1098/1112/1098 f 1096/1110/1096 1094/1106/1094 1097/1111/1097 f 1096/1110/1096 1097/1111/1097 1099/1113/1099 f 1100/1114/1100 1101/1115/1101 1085/1099/1085 f 1100/1114/1100 1085/1099/1085 1083/1097/1083 f 1101/1115/1101 1102/1116/1102 1088/1108/1088 f 1101/1115/1101 1088/1108/1088 1085/1099/1085 f 1103/1117/1103 1100/1114/1100 1079/1093/1079 f 1103/1117/1103 1079/1093/1079 1078/968/1078 f 1093/1105/1093 1104/1118/1104 1105/1119/1105 f 1093/1105/1093 1105/1119/1105 1092/1103/1092 f 1106/1120/1106 1107/1121/1107 1102/1116/1102 f 1106/1120/1106 1102/1116/1102 1101/1115/1101 f 1105/1122/1105 1104/1123/1104 1107/1124/1107 f 1105/1122/1105 1107/1124/1107 1106/1125/1106 f 1108/1126/1108 1109/1127/1109 1107/1124/1107 f 1108/1126/1108 1107/1124/1107 1104/1123/1104 f 1099/1128/1099 1098/1129/1098 1109/1127/1109 f 1099/1128/1099 1109/1127/1109 1108/1126/1108 f 1110/1130/1110 1111/1131/1111 1105/1122/1105 f 1110/1130/1110 1105/1122/1105 1106/1125/1106 f 1148/1132/1148 1112/1042/1112 1111/1131/1111 f 1148/1132/1148 1111/1131/1111 1110/1130/1110 f 1100/1114/1100 1110/1133/1110 1106/1120/1106 f 1100/1114/1100 1106/1120/1106 1101/1115/1101 f 1103/1117/1103 1148/1134/1148 1110/1133/1110 f 1103/1117/1103 1110/1133/1110 1100/1114/1100 f 1112/1045/1112 1090/1102/1090 1091/1101/1091 f 1112/1045/1112 1091/1101/1091 1111/1135/1111 f 1091/1101/1091 1092/1103/1092 1105/1119/1105 f 1091/1101/1091 1105/1119/1105 1111/1135/1111 f 1077/967/1077 1090/1102/1090 1027/1027/1027 f 1077/967/1077 1027/1027/1027 965/971/965 f 1114/970/1114 1115/969/1115 1116/1136/1116 f 1114/970/1114 1116/1136/1116 1117/1137/1117 f 1117/1137/1117 1116/1136/1116 1118/1138/1118 f 1117/1137/1117 1118/1138/1118 1119/1139/1119 f 1119/1139/1119 1118/1138/1118 1120/1140/1120 f 1119/1139/1119 1120/1140/1120 1121/1141/1121 f 1121/1141/1121 1120/1140/1120 1122/1142/1122 f 1121/1141/1121 1122/1142/1122 1123/1143/1123 f 1114/970/1114 1117/1137/1117 1128/1144/1128 f 1114/970/1114 1128/1144/1128 1127/1145/1127 f 1121/1141/1121 1123/1143/1123 1129/1146/1129 f 1121/1141/1121 1129/1146/1129 1128/1144/1128 f 1129/1146/1129 1123/1143/1123 1126/1147/1126 f 1129/1146/1129 1126/1147/1126 1130/1148/1130 f 1131/1149/1131 1124/1150/1124 1125/1151/1125 f 1131/1149/1131 1125/1151/1125 1132/1152/1132 f 1126/1147/1126 1124/1150/1124 1131/1149/1131 f 1126/1147/1126 1131/1149/1131 1133/1153/1133 f 1135/1154/1135 1136/1155/1136 1122/1142/1122 f 1135/1154/1135 1122/1142/1122 1120/1140/1120 f 1136/1155/1136 1137/1156/1137 1125/1151/1125 f 1136/1155/1136 1125/1151/1125 1122/1142/1122 f 1138/1157/1138 1135/1154/1135 1116/1136/1116 f 1138/1157/1138 1116/1136/1116 1115/969/1115 f 1139/1158/1139 1140/1159/1140 1129/1146/1129 f 1139/1158/1139 1129/1146/1129 1130/1148/1130 f 1141/1160/1141 1142/1161/1142 1137/1156/1137 f 1141/1160/1141 1137/1156/1137 1136/1155/1136 f 1140/1162/1140 1139/1163/1139 1142/1164/1142 f 1140/1162/1140 1142/1164/1142 1141/1165/1141 f 1143/1166/1143 1144/1167/1144 1142/1164/1142 f 1143/1166/1143 1142/1164/1142 1139/1163/1139 f 1145/1168/1145 1146/1169/1146 1140/1162/1140 f 1145/1168/1145 1140/1162/1140 1141/1165/1141 f 1147/1170/1147 1148/1171/1148 1146/1169/1146 f 1147/1170/1147 1146/1169/1146 1145/1168/1145 f 1135/1154/1135 1145/1172/1145 1141/1160/1141 f 1135/1154/1135 1141/1160/1141 1136/1155/1136 f 1138/1157/1138 1147/1173/1147 1145/1172/1145 f 1138/1157/1138 1145/1172/1145 1135/1154/1135 f 1148/1134/1148 1127/1145/1127 1128/1144/1128 f 1148/1134/1148 1128/1144/1128 1146/1174/1146 f 1128/1144/1128 1129/1146/1129 1140/1159/1140 f 1128/1144/1128 1140/1159/1140 1146/1174/1146 f 1103/1117/1103 1078/968/1078 1114/970/1114 f 1103/1117/1103 1114/970/1114 1127/1145/1127 f 1148/1132/1148 1074/1088/1074 1076/1087/1076 f 1148/1132/1148 1076/1087/1076 1112/1042/1112 f 1150/1175/1150 1149/1176/1149 989/1177/989 f 1150/1175/1150 989/1177/989 1074/1178/1074 f 1149/1179/1149 1152/965/1152 892/853/892 f 1149/1179/1149 892/853/892 1151/937/1151 f 964/966/964 1152/965/1152 1149/1179/1149 f 964/966/964 1149/1179/1149 1150/1180/1150 f 606/659/606 638/658/638 603/1181/603 f 606/659/606 603/1181/603 936/1182/936 f 1153/974/1153 1154/973/1154 1155/1183/1155 f 1153/974/1153 1155/1183/1155 1156/1184/1156 f 1156/1184/1156 1155/1183/1155 1157/1185/1157 f 1156/1184/1156 1157/1185/1157 1158/1186/1158 f 1158/1186/1158 1157/1185/1157 1159/1187/1159 f 1158/1186/1158 1159/1187/1159 1160/1188/1160 f 1160/1188/1160 1159/1187/1159 1161/1189/1161 f 1160/1188/1160 1161/1189/1161 1162/1190/1162 f 1153/974/1153 1156/1184/1156 1167/1191/1167 f 1153/974/1153 1167/1191/1167 1166/1192/1166 f 1160/1188/1160 1162/1190/1162 1168/1193/1168 f 1160/1188/1160 1168/1193/1168 1167/1191/1167 f 1168/1193/1168 1162/1190/1162 1165/1194/1165 f 1168/1193/1168 1165/1194/1165 1169/1195/1169 f 1170/1196/1170 1163/1197/1163 1164/1198/1164 f 1170/1196/1170 1164/1198/1164 1171/1199/1171 f 1165/1194/1165 1163/1197/1163 1170/1196/1170 f 1165/1194/1165 1170/1196/1170 1172/1200/1172 f 1174/1201/1174 1175/1202/1175 1161/1189/1161 f 1174/1201/1174 1161/1189/1161 1159/1187/1159 f 1175/1202/1175 1176/1203/1176 1164/1198/1164 f 1175/1202/1175 1164/1198/1164 1161/1189/1161 f 1177/1204/1177 1174/1201/1174 1155/1183/1155 f 1177/1204/1177 1155/1183/1155 1154/973/1154 f 1178/1205/1178 1179/1206/1179 1168/1193/1168 f 1178/1205/1178 1168/1193/1168 1169/1195/1169 f 1180/1207/1180 1181/1208/1181 1176/1203/1176 f 1180/1207/1180 1176/1203/1176 1175/1202/1175 f 1179/1209/1179 1178/1210/1178 1181/1211/1181 f 1179/1209/1179 1181/1211/1181 1180/1212/1180 f 1182/1213/1182 1183/1214/1183 1181/1211/1181 f 1182/1213/1182 1181/1211/1181 1178/1210/1178 f 1184/1215/1184 1185/1216/1185 1179/1209/1179 f 1184/1215/1184 1179/1209/1179 1180/1212/1180 f 1186/1217/1186 1147/1170/1147 1185/1216/1185 f 1186/1217/1186 1185/1216/1185 1184/1215/1184 f 1174/1201/1174 1184/1218/1184 1180/1207/1180 f 1174/1201/1174 1180/1207/1180 1175/1202/1175 f 1177/1204/1177 1186/1219/1186 1184/1218/1184 f 1177/1204/1177 1184/1218/1184 1174/1201/1174 f 1147/1173/1147 1166/1192/1166 1167/1191/1167 f 1147/1173/1147 1167/1191/1167 1185/1220/1185 f 1167/1191/1167 1168/1193/1168 1179/1206/1179 f 1167/1191/1167 1179/1206/1179 1185/1220/1185 f 1138/1157/1138 1115/969/1115 1153/974/1153 f 1138/1157/1138 1153/974/1153 1166/1192/1166 f 1074/1178/1074 1148/1171/1148 1147/1170/1147 f 1074/1178/1074 1147/1170/1147 1186/1217/1186 f 1177/1204/1177 964/966/964 1150/1180/1150 f 1177/1204/1177 1150/1180/1150 1186/1219/1186 f 963/963/963 1073/1086/1073 978/1067/978 f 963/963/963 978/1067/978 1042/983/1042 f 1075/1091/1075 1071/1084/1071 978/1067/978 f 1075/1091/1075 978/1067/978 1073/1086/1073 f 807/808/807 1189/1221/1189 1197/1222/1197 f 807/808/807 1197/1222/1197 809/806/809 f 1195/1223/1195 1196/1224/1196 1190/1225/1190 f 1195/1223/1195 1190/1225/1190 1192/1226/1192 f 812/1227/812 562/1228/562 1192/1226/1192 f 812/1227/812 1192/1226/1192 1190/1225/1190 f 1194/1229/1194 1193/1230/1193 1188/1231/1188 f 1194/1229/1194 1188/1231/1188 1191/1232/1191 f 1195/1223/1195 1191/1232/1191 1188/1231/1188 f 1195/1223/1195 1188/1231/1188 1189/1221/1189 f 1196/1224/1196 1195/1223/1195 1189/1221/1189 f 1196/1224/1196 1189/1221/1189 807/808/807 f 1200/1233/1200 1331/1234/1331 783/1235/783 f 1200/1233/1200 783/1235/783 784/1236/784 f 1202/1237/1202 1203/1238/1203 1204/1239/1204 f 1202/1237/1202 1204/1239/1204 1201/1240/1201 f 1206/1241/1206 1207/1242/1207 1205/1243/1205 f 1206/1241/1206 1205/1243/1205 1201/1240/1201 f 1206/1241/1206 1208/1244/1208 1209/1245/1209 f 1206/1241/1206 1209/1245/1209 1207/1242/1207 f 1211/1246/1211 1210/1247/1210 1202/1237/1202 f 1211/1246/1211 1202/1237/1202 1205/1243/1205 f 1212/1248/1212 1211/1246/1211 1205/1243/1205 f 1212/1248/1212 1205/1243/1205 1207/1242/1207 f 1209/1245/1209 1213/1249/1213 1212/1248/1212 f 1209/1245/1209 1212/1248/1212 1207/1242/1207 f 1202/1237/1202 1210/1247/1210 786/1250/786 f 1202/1237/1202 786/1250/786 1203/1238/1203 f 784/1251/784 1223/1252/1223 1214/1253/1214 f 784/1251/784 1214/1253/1214 1200/1254/1200 f 1218/1255/1218 1219/1256/1219 1217/1257/1217 f 1218/1255/1218 1217/1257/1217 1216/1258/1216 f 1219/1256/1219 1222/1259/1222 1215/1260/1215 f 1219/1256/1219 1215/1260/1215 1217/1257/1217 f 1222/1259/1222 1221/1261/1221 1214/1253/1214 f 1222/1259/1222 1214/1253/1214 1215/1260/1215 f 1221/1261/1221 1220/1262/1220 1200/1254/1200 f 1221/1261/1221 1200/1254/1200 1214/1253/1214 f 1215/1260/1215 1223/1252/1223 1211/1263/1211 f 1215/1260/1215 1211/1263/1211 1212/1264/1212 f 1206/1241/1206 1201/1240/1201 1225/1265/1225 f 1206/1241/1206 1225/1265/1225 1226/1266/1226 f 1206/1241/1206 1226/1266/1226 1218/1255/1218 f 1206/1241/1206 1218/1255/1218 1208/1244/1208 f 1228/1267/1228 1229/1268/1229 1198/1269/1198 f 1228/1267/1228 1198/1269/1198 1193/1230/1193 f 1233/1270/1233 1250/1271/1250 1248/1272/1248 f 1233/1270/1233 1248/1272/1248 1231/1273/1231 f 1235/1274/1235 1236/1275/1236 1232/1276/1232 f 1235/1274/1235 1232/1276/1232 1252/1277/1252 f 1230/1278/1230 1237/1279/1237 1229/1280/1229 f 1230/1278/1230 1229/1280/1229 1228/1281/1228 f 1238/1282/1238 1362/1283/1362 1237/1279/1237 f 1238/1282/1238 1237/1279/1237 1230/1278/1230 f 1242/1284/1242 1241/1285/1241 1253/1286/1253 f 1242/1284/1242 1253/1286/1253 1234/1287/1234 f 1248/1272/1248 1250/1271/1250 1251/1288/1251 f 1248/1272/1248 1251/1288/1251 1232/1276/1232 f 1236/1275/1236 1249/1289/1249 1248/1272/1248 f 1236/1275/1236 1248/1272/1248 1232/1276/1232 f 1251/1288/1251 1250/1271/1250 1247/1290/1247 f 1251/1288/1251 1247/1290/1247 1234/1287/1234 f 1252/1277/1252 1251/1288/1251 1234/1287/1234 f 1252/1277/1252 1234/1287/1234 1253/1286/1253 f 1254/1291/1254 1241/1285/1241 1242/1284/1242 f 1254/1291/1254 1242/1284/1242 1239/1292/1239 f 1261/1293/1261 1254/1291/1254 1239/1292/1239 f 1261/1293/1261 1239/1292/1239 1260/1294/1260 f 1282/1295/1282 1259/1296/1259 1260/1294/1260 f 1282/1295/1282 1260/1294/1260 1239/1292/1239 f 1259/1296/1259 1265/28/1265 1255/27/1255 f 1259/1296/1259 1255/27/1255 1260/1294/1260 f 1256/29/1256 1261/1293/1261 1260/1294/1260 f 1256/29/1256 1260/1294/1260 1255/27/1255 f 1263/1297/1263 1262/33/1262 1258/32/1258 f 1263/1297/1263 1258/32/1258 1264/1298/1264 f 1258/32/1258 1265/28/1265 1259/1296/1259 f 1258/32/1258 1259/1296/1259 1264/1298/1264 f 34/34/34 1267/1299/1267 1261/1293/1261 f 34/34/34 1261/1293/1261 1256/29/1256 f 1267/1299/1267 1266/1300/1266 1254/1291/1254 f 1267/1299/1267 1254/1291/1254 1261/1293/1261 f 1269/1301/1269 1270/1302/1270 1267/1299/1267 f 1269/1301/1269 1267/1299/1267 34/34/34 f 1267/1299/1267 1270/1302/1270 1268/1303/1268 f 1267/1299/1267 1268/1303/1268 1266/1300/1266 f 1272/1304/1272 1273/1305/1273 1270/1302/1270 f 1272/1304/1272 1270/1302/1270 1269/1301/1269 f 1273/1305/1273 1271/1306/1271 1268/1303/1268 f 1273/1305/1273 1268/1303/1268 1270/1302/1270 f 43/43/43 1274/1307/1274 1272/1304/1272 f 43/43/43 1272/1304/1272 1269/1301/1269 f 1203/1308/1203 1275/1309/1275 1276/1310/1276 f 1203/1308/1203 1276/1310/1276 1204/1311/1204 f 1277/1312/1277 1304/1313/1304 1236/1275/1236 f 1277/1312/1277 1236/1275/1236 1235/1274/1235 f 1273/1305/1273 1277/1312/1277 1235/1274/1235 f 1273/1305/1273 1235/1274/1235 1271/1306/1271 f 1329/1314/1329 1277/1312/1277 1272/1304/1272 f 1329/1314/1329 1272/1304/1272 1274/1307/1274 f 1244/1315/1244 1243/1316/1243 1245/1317/1245 f 1244/1315/1244 1245/1317/1245 1246/1318/1246 f 1278/1319/1278 1244/1315/1244 1246/1318/1246 f 1278/1319/1278 1246/1318/1246 1280/53/1280 f 1283/1320/1283 1282/1295/1282 1239/1292/1239 f 1283/1320/1283 1239/1292/1239 1242/1284/1242 f 1284/1321/1284 1283/1320/1283 1242/1284/1242 f 1284/1321/1284 1242/1284/1242 1257/1322/1257 f 1287/1323/1287 1288/1324/1288 1283/1320/1283 f 1287/1323/1287 1283/1320/1283 1284/1321/1284 f 1282/1295/1282 1283/1320/1283 1288/1324/1288 f 1282/1295/1282 1288/1324/1288 1290/1325/1290 f 1244/1315/1244 1278/1319/1278 1279/1326/1279 f 1244/1315/1244 1279/1326/1279 1285/1327/1285 f 1278/1319/1278 1291/1328/1291 1263/1297/1263 f 1278/1319/1278 1263/1297/1263 1279/1326/1279 f 1325/1329/1325 1306/1330/1306 1304/1313/1304 f 1325/1329/1325 1304/1313/1304 1277/1312/1277 f 1292/1331/1292 1330/1332/1330 1204/1311/1204 f 1292/1331/1292 1204/1311/1204 1276/1310/1276 f 1295/1333/1295 1293/1334/1293 1436/1335/1436 f 1295/1333/1295 1436/1335/1436 1437/1336/1437 f 1438/1337/1438 1297/1338/1297 1295/1333/1295 f 1438/1337/1438 1295/1333/1295 1437/1336/1437 f 1298/1339/1298 1301/1340/1301 1302/1341/1302 f 1298/1339/1298 1302/1341/1302 1299/1342/1299 f 1300/1343/1300 1302/1341/1302 1301/1340/1301 f 1300/1343/1300 1301/1340/1301 1352/1344/1352 f 1295/1333/1295 1305/1345/1305 1303/1346/1303 f 1295/1333/1295 1303/1346/1303 1293/1334/1293 f 1299/1342/1299 1354/1347/1354 1305/1345/1305 f 1299/1342/1299 1305/1345/1305 1297/1338/1297 f 1300/1343/1300 1307/1348/1307 1308/1349/1308 f 1300/1343/1300 1308/1349/1308 1302/1341/1302 f 1302/1341/1302 1308/1349/1308 1354/1347/1354 f 1302/1341/1302 1354/1347/1354 1299/1342/1299 f 1310/1350/1310 1309/1351/1309 1204/1352/1204 f 1310/1350/1310 1204/1352/1204 1311/1353/1311 f 1313/1354/1313 1312/1355/1312 1309/1351/1309 f 1313/1354/1313 1309/1351/1309 1310/1350/1310 f 1315/1356/1315 1316/1357/1316 1310/1350/1310 f 1315/1356/1315 1310/1350/1310 1311/1353/1311 f 1316/1357/1316 1317/1358/1317 1313/1354/1313 f 1316/1357/1316 1313/1354/1313 1310/1350/1310 f 1326/1359/1326 1319/1360/1319 1316/1357/1316 f 1326/1359/1326 1316/1357/1316 1315/1356/1315 f 1316/1357/1316 1319/1360/1319 1322/1361/1322 f 1316/1357/1316 1322/1361/1322 1317/1358/1317 f 1326/1359/1326 1320/1362/1320 1321/1363/1321 f 1326/1359/1326 1321/1363/1321 1319/1360/1319 f 1323/1364/1323 1312/1355/1312 1313/1354/1313 f 1323/1364/1323 1313/1354/1313 1324/1365/1324 f 1317/1358/1317 1318/1366/1318 1324/1365/1324 f 1317/1358/1317 1324/1365/1324 1313/1354/1313 f 1325/1367/1325 1328/1368/1328 1315/1356/1315 f 1325/1367/1325 1315/1356/1315 1311/1353/1311 f 1332/1369/1332 1331/1234/1331 1220/1370/1220 f 1332/1369/1332 1220/1370/1220 1224/1371/1224 f 106/1372/106 1332/1369/1332 1224/1371/1224 f 106/1372/106 1224/1371/1224 1327/1373/1327 f 1333/1374/1333 1334/1375/1334 1335/1376/1335 f 1333/1374/1333 1335/1376/1335 1338/1377/1338 f 109/65/109 1334/1375/1334 1274/1307/1274 f 109/65/109 1274/1307/1274 43/43/43 f 1315/1356/1315 1328/1368/1328 1327/1378/1327 f 1315/1356/1315 1327/1378/1327 1326/1359/1326 f 1333/1374/1333 1338/1377/1338 1337/1379/1337 f 1333/1374/1333 1337/1379/1337 1336/1380/1336 f 100/1381/100 1339/1382/1339 1340/1383/1340 f 100/1381/100 1340/1383/1340 99/1384/99 f 1339/1382/1339 1341/1385/1341 1342/1386/1342 f 1339/1382/1339 1342/1386/1342 1340/1383/1340 f 1339/1382/1339 100/1381/100 106/1387/106 f 1339/1382/1339 106/1387/106 1337/1388/1337 f 101/111/101 1341/1385/1341 1335/1389/1335 f 101/111/101 1335/1389/1335 109/112/109 f 1341/1385/1341 1339/1382/1339 1337/1388/1337 f 1341/1385/1341 1337/1388/1337 1338/1390/1338 f 1344/1391/1344 1240/1392/1240 1343/1393/1343 f 1344/1391/1344 1343/1393/1343 1271/1306/1271 f 1346/1394/1346 1345/1395/1345 1198/1396/1198 f 1346/1394/1346 1198/1396/1198 1229/1397/1229 f 1197/1398/1197 1345/1399/1345 1294/1400/1294 f 1197/1398/1197 1294/1400/1294 1275/1401/1275 f 1350/1402/1350 1296/1403/1296 1347/1404/1347 f 1350/1402/1350 1347/1404/1347 1348/1405/1348 f 1346/1394/1346 1229/1397/1229 1249/1406/1249 f 1346/1394/1346 1249/1406/1249 1439/1407/1439 f 1442/1408/1442 1440/1409/1440 1348/1405/1348 f 1442/1408/1442 1348/1405/1348 1443/1410/1443 f 1301/1411/1301 1298/1412/1298 1350/1402/1350 f 1301/1411/1301 1350/1402/1350 1351/1413/1351 f 1353/1414/1353 1352/1415/1352 1301/1411/1301 f 1353/1414/1353 1301/1411/1301 1351/1413/1351 f 1351/1413/1351 1308/1349/1308 1307/1348/1307 f 1351/1413/1351 1307/1348/1307 1353/1414/1353 f 1441/1416/1441 1308/1349/1308 1351/1413/1351 f 1441/1416/1441 1351/1413/1351 1350/1402/1350 f 1440/1409/1440 1441/1416/1441 1350/1402/1350 f 1440/1409/1440 1350/1402/1350 1348/1405/1348 f 1356/1417/1356 1357/1418/1357 1194/1229/1194 f 1356/1417/1356 1194/1229/1194 1191/1232/1191 f 90/1419/90 1358/1420/1358 1194/1229/1194 f 90/1419/90 1194/1229/1194 1357/1418/1357 f 1359/1421/1359 1360/1422/1360 1362/1283/1362 f 1359/1421/1359 1362/1283/1362 1238/1282/1238 f 1362/1283/1362 1363/1423/1363 1245/1317/1245 f 1362/1283/1362 1245/1317/1245 1233/1270/1233 f 1363/1423/1363 1364/1424/1364 1246/1318/1246 f 1363/1423/1363 1246/1318/1246 1245/1317/1245 f 1364/1424/1364 74/75/74 1280/53/1280 f 1364/1424/1364 1280/53/1280 1246/1318/1246 f 1366/1425/1366 1365/1426/1365 1364/1424/1364 f 1366/1425/1366 1364/1424/1364 1363/1423/1363 f 1365/1426/1365 77/78/77 74/75/74 f 1365/1426/1365 74/75/74 1364/1424/1364 f 1366/1425/1366 1367/1427/1367 1372/1428/1372 f 1366/1425/1366 1372/1428/1372 1365/1426/1365 f 1371/1429/1371 1368/1430/1368 1369/1431/1369 f 1371/1429/1371 1369/1431/1369 1370/1432/1370 f 1373/1433/1373 1372/1428/1372 1374/1434/1374 f 1373/1433/1373 1374/1434/1374 1375/1435/1375 f 1372/1428/1372 1373/1433/1373 88/89/88 f 1372/1428/1372 88/89/88 80/88/80 f 1374/1434/1374 1367/1427/1367 1370/1432/1370 f 1374/1434/1374 1370/1432/1370 1369/1431/1369 f 1376/1436/1376 1358/1437/1358 90/1438/90 f 1376/1436/1376 90/1438/90 91/1439/91 f 1376/1436/1376 91/1439/91 93/1440/93 f 1376/1436/1376 93/1440/93 1375/1441/1375 f 1368/1442/1368 1376/1436/1376 1377/1443/1377 f 1368/1442/1368 1377/1443/1377 1369/1444/1369 f 95/1445/95 1378/1446/1378 1375/1441/1375 f 95/1445/95 1375/1441/1375 93/1440/93 f 1373/1433/1373 1378/1447/1378 96/101/96 f 1373/1433/1373 96/101/96 88/89/88 f 948/944/948 1379/1448/1379 949/957/949 f 948/944/948 949/957/949 959/945/959 f 947/947/947 1380/844/1380 1379/1448/1379 f 947/947/947 1379/1448/1379 948/944/948 f 1381/1449/1381 1382/1450/1382 1383/1451/1383 f 1381/1449/1381 1383/1451/1383 1384/1452/1384 f 1382/1450/1382 438/1453/438 439/1454/439 f 1382/1450/1382 439/1454/439 1383/1451/1383 f 1382/1450/1382 1385/1455/1385 444/1456/444 f 1382/1450/1382 444/1456/444 438/1453/438 f 1382/1450/1382 1381/1449/1381 1386/1457/1386 f 1382/1450/1382 1386/1457/1386 1385/1455/1385 f 1386/1457/1386 1387/1458/1387 1388/1459/1388 f 1386/1457/1386 1388/1459/1388 1385/1455/1385 f 1388/1459/1388 445/1460/445 444/1456/444 f 1388/1459/1388 444/1456/444 1385/1455/1385 f 439/1454/439 1389/1461/1389 1390/1462/1390 f 439/1454/439 1390/1462/1390 1383/1451/1383 f 1390/1462/1390 1391/1463/1391 1384/1452/1384 f 1390/1462/1390 1384/1452/1384 1383/1451/1383 f 1389/1461/1389 1392/1464/1392 1393/1465/1393 f 1389/1461/1389 1393/1465/1393 1390/1462/1390 f 550/1466/550 445/1460/445 1398/1467/1398 f 550/1466/550 1398/1467/1398 1397/1468/1397 f 1397/1468/1397 1401/1469/1401 1402/1470/1402 f 1397/1468/1397 1402/1470/1402 1395/1471/1395 f 1396/1472/1396 1395/1471/1395 1402/1470/1402 f 1396/1472/1396 1402/1470/1402 1404/1473/1404 f 561/1474/561 595/1475/595 1411/1476/1411 f 561/1474/561 1411/1476/1411 1412/1477/1412 f 1404/1473/1404 1417/1478/1417 1416/1479/1416 f 1404/1473/1404 1416/1479/1416 1405/1480/1405 f 1418/1481/1418 1410/1482/1410 1409/1483/1409 f 1418/1481/1418 1409/1483/1409 1417/1478/1417 f 1409/1483/1409 1394/1484/1394 1405/1480/1405 f 1409/1483/1409 1405/1480/1405 1416/1479/1416 f 1421/1485/1421 1422/1486/1422 1423/1487/1423 f 1421/1485/1421 1423/1487/1423 1424/1488/1424 f 1425/1489/1425 1426/1490/1426 1427/1491/1427 f 1425/1489/1425 1427/1491/1427 1421/1485/1421 f 1422/1486/1422 1427/1491/1427 1428/1492/1428 f 1422/1486/1422 1428/1492/1428 1423/1487/1423 f 1429/1493/1429 1415/1494/1415 1420/1495/1420 f 1429/1493/1429 1420/1495/1420 1419/1496/1419 f 1412/1477/1412 1430/1497/1430 740/1498/740 f 1412/1477/1412 740/1498/740 561/1474/561 f 1412/1477/1412 1411/1476/1411 1415/1494/1415 f 1412/1477/1412 1415/1494/1415 1429/1493/1429 f 1411/1476/1411 745/1499/745 1410/1482/1410 f 1411/1476/1411 1410/1482/1410 1413/1500/1413 f 1434/1501/1434 111/1502/111 108/67/108 f 1434/1501/1434 108/67/108 65/66/65 f 1434/1501/1434 1435/1503/1435 107/1504/107 f 1434/1501/1434 107/1504/107 111/1502/111 f 1437/1336/1437 1436/1335/1436 1294/1400/1294 f 1437/1336/1437 1294/1400/1294 1347/1505/1347 f 1296/1506/1296 1438/1337/1438 1437/1336/1437 f 1296/1506/1296 1437/1336/1437 1347/1505/1347 f 1303/1346/1303 1439/1407/1439 1249/1406/1249 f 1303/1346/1303 1249/1406/1249 1304/1507/1304 f 1354/1347/1354 1441/1416/1441 1440/1409/1440 f 1354/1347/1354 1440/1409/1440 1305/1345/1305 f 1447/1508/1447 1449/1509/1449 1450/1510/1450 f 1447/1508/1447 1450/1510/1450 1448/1511/1448 f 1529/1512/1529 1531/1513/1531 1450/1510/1450 f 1529/1512/1529 1450/1510/1450 1461/1514/1461 f 1452/1515/1452 1453/1516/1453 1449/1509/1449 f 1452/1515/1452 1449/1509/1449 1447/1508/1447 f 1481/1517/1481 1509/1518/1509 1453/1516/1453 f 1481/1517/1481 1453/1516/1453 1452/1515/1452 f 1448/1511/1448 1464/1519/1464 1463/1520/1463 f 1448/1511/1448 1463/1520/1463 1462/1521/1462 f 1462/1521/1462 1465/1522/1465 1467/1523/1467 f 1462/1521/1462 1467/1523/1467 1455/1524/1455 f 1474/1525/1474 1475/1526/1475 1472/1527/1472 f 1474/1525/1474 1472/1527/1472 1473/1528/1473 f 1455/1524/1455 1467/1523/1467 1476/1529/1476 f 1455/1524/1455 1476/1529/1476 1479/1530/1479 f 1478/1531/1478 1480/1532/1480 1479/1530/1479 f 1478/1531/1478 1479/1530/1479 1476/1529/1476 f 1474/1525/1474 1471/1533/1471 1492/1534/1492 f 1474/1525/1474 1492/1534/1492 1470/1535/1470 f 1466/1536/1466 1484/1537/1484 1485/1538/1485 f 1466/1536/1466 1485/1538/1485 1469/1539/1469 f 1469/1539/1469 1485/1538/1485 1486/1540/1486 f 1469/1539/1469 1486/1540/1486 1492/1534/1492 f 1487/1541/1487 1490/1542/1490 1494/1543/1494 f 1487/1541/1487 1494/1543/1494 1488/1544/1488 f 1492/1534/1492 1494/1543/1494 1495/1545/1495 f 1492/1534/1492 1495/1545/1495 1493/1546/1493 f 1478/1531/1478 1513/1547/1513 1497/1548/1497 f 1478/1531/1478 1497/1548/1497 1480/1532/1480 f 1488/1544/1488 1494/1543/1494 1492/1534/1492 f 1488/1544/1488 1492/1534/1492 1486/1540/1486 f 1502/1549/1502 1504/1550/1504 1503/1551/1503 f 1502/1549/1502 1503/1551/1503 1496/1552/1496 f 1506/1553/1506 1508/1554/1508 1526/1555/1526 f 1506/1553/1506 1526/1555/1526 1525/1556/1525 f 1524/1557/1524 1523/1558/1523 1509/1518/1509 f 1524/1557/1524 1509/1518/1509 1483/1559/1483 f 1451/1560/1451 1450/1510/1450 1458/1561/1458 f 1451/1560/1451 1458/1561/1458 1514/1562/1514 f 1460/1563/1460 1518/1564/1518 1519/1565/1519 f 1460/1563/1460 1519/1565/1519 1514/1562/1514 f 1514/1562/1514 1519/1565/1519 1517/1566/1517 f 1514/1562/1514 1517/1566/1517 1451/1560/1451 f 1516/1567/1516 1520/1568/1520 1529/1512/1529 f 1516/1567/1516 1529/1512/1529 1461/1514/1461 f 1521/1569/1521 1507/1570/1507 1522/1571/1522 f 1521/1569/1521 1522/1571/1522 1536/1572/1536 f 1507/1570/1507 1521/1569/1521 1525/1556/1525 f 1507/1570/1507 1525/1556/1525 1526/1555/1526 f 1464/1519/1464 1531/1513/1531 1532/1573/1532 f 1464/1519/1464 1532/1573/1532 1542/1574/1542 f 1534/1575/1534 1533/1576/1533 1481/1517/1481 f 1534/1575/1534 1481/1517/1481 1482/1577/1482 f 1535/1578/1535 1534/1575/1534 1480/1532/1480 f 1535/1578/1535 1480/1532/1480 1497/1548/1497 f 1535/1579/1535 1497/1580/1497 1510/1581/1510 f 1535/1579/1535 1510/1581/1510 1559/1582/1559 f 1521/1569/1521 1538/1583/1538 1393/1584/1393 f 1521/1569/1521 1393/1584/1393 1525/1556/1525 f 1539/1585/1539 1568/1586/1568 1569/1587/1569 f 1539/1585/1539 1569/1587/1569 1544/1588/1544 f 1540/1589/1540 1538/1583/1538 1539/1585/1539 f 1540/1589/1540 1539/1585/1539 1541/1590/1541 f 1541/1591/1541 1464/1519/1464 1542/1574/1542 f 1541/1591/1541 1542/1574/1542 1540/1592/1540 f 1539/1585/1539 1544/1588/1544 1543/1593/1543 f 1539/1585/1539 1543/1593/1543 1541/1590/1541 f 1670/1594/1670 1669/1595/1669 1567/1596/1567 f 1670/1594/1670 1567/1596/1567 1553/1597/1553 f 1547/1598/1547 1671/1599/1671 1668/1600/1668 f 1547/1598/1547 1668/1600/1668 1546/1601/1546 f 1548/1602/1548 1550/1603/1550 1551/1604/1551 f 1548/1602/1548 1551/1604/1551 1549/1605/1549 f 1558/1606/1558 1554/1607/1554 1548/1602/1548 f 1558/1606/1558 1548/1602/1548 1545/1608/1545 f 1548/1602/1548 1554/1607/1554 1556/1609/1556 f 1548/1602/1548 1556/1609/1556 1550/1603/1550 f 1550/1603/1550 1556/1609/1556 1589/1610/1589 f 1550/1603/1550 1589/1610/1589 1591/1611/1591 f 1559/1582/1559 1557/1612/1557 1558/1606/1558 f 1559/1582/1559 1558/1606/1558 1555/1613/1555 f 1572/1614/1572 1557/1612/1557 1559/1582/1559 f 1572/1614/1572 1559/1582/1559 1560/1615/1560 f 1565/1616/1565 1672/1617/1672 1671/1599/1671 f 1565/1616/1565 1671/1599/1671 1547/1598/1547 f 1564/1618/1564 1563/1619/1563 1672/1617/1672 f 1564/1618/1564 1672/1617/1672 1565/1616/1565 f 1566/1620/1566 1574/1621/1574 1565/1616/1565 f 1566/1620/1566 1565/1616/1565 1547/1598/1547 f 1546/1601/1546 1549/1605/1549 1566/1620/1566 f 1546/1601/1546 1566/1620/1566 1547/1598/1547 f 1537/1622/1537 1536/1572/1536 1522/1571/1522 f 1537/1622/1537 1522/1571/1522 1567/1623/1567 f 1537/1624/1537 1567/1596/1567 1669/1595/1669 f 1537/1624/1537 1669/1595/1669 1668/1600/1668 f 1537/1622/1537 1569/1587/1569 1568/1586/1568 f 1537/1622/1537 1568/1586/1568 1536/1572/1536 f 1566/1620/1566 1570/1625/1570 1571/1626/1571 f 1566/1620/1566 1571/1626/1571 1574/1621/1574 f 1570/1625/1570 1581/1627/1581 1579/1628/1579 f 1570/1625/1570 1579/1628/1579 1571/1626/1571 f 1549/1605/1549 1551/1604/1551 1570/1625/1570 f 1549/1605/1549 1570/1625/1570 1566/1620/1566 f 1561/1629/1561 1573/1630/1573 1572/1614/1572 f 1561/1629/1561 1572/1614/1572 1560/1615/1560 f 1576/1631/1576 1578/1632/1578 1573/1630/1573 f 1576/1631/1576 1573/1630/1573 1561/1629/1561 f 1391/1633/1391 1393/1584/1393 1538/1583/1538 f 1391/1633/1391 1538/1583/1538 1540/1589/1540 f 1381/1634/1381 1384/1635/1384 1528/1636/1528 f 1381/1634/1381 1528/1636/1528 1516/1567/1516 f 1542/1574/1542 1528/1636/1528 1384/1635/1384 f 1542/1574/1542 1384/1635/1384 1391/1637/1391 f 1562/1638/1562 1563/1639/1563 1564/1640/1564 f 1562/1638/1562 1564/1640/1564 1576/1631/1576 f 1577/1641/1577 1578/1632/1578 1574/1642/1574 f 1577/1641/1577 1574/1642/1574 1571/1643/1571 f 1580/1644/1580 1590/1645/1590 1592/1646/1592 f 1580/1644/1580 1592/1646/1592 1584/1647/1584 f 1585/1648/1585 1573/1630/1573 1578/1632/1578 f 1585/1648/1585 1578/1632/1578 1577/1641/1577 f 1572/1614/1572 1573/1630/1573 1585/1648/1585 f 1572/1614/1572 1585/1648/1585 1586/1649/1586 f 1586/1649/1586 1554/1607/1554 1557/1612/1557 f 1586/1649/1586 1557/1612/1557 1572/1614/1572 f 1592/1646/1592 1590/1645/1590 1581/1627/1581 f 1592/1646/1592 1581/1627/1581 1593/1650/1593 f 1588/1651/1588 1592/1646/1592 1593/1650/1593 f 1588/1651/1588 1593/1650/1593 1591/1611/1591 f 1582/1652/1582 1584/1647/1584 1592/1646/1592 f 1582/1652/1582 1592/1646/1592 1588/1651/1588 f 1595/1653/1595 1597/1654/1597 1596/1655/1596 f 1595/1653/1595 1596/1655/1596 1594/1656/1594 f 1604/1657/1604 1605/1658/1605 1602/1659/1602 f 1604/1657/1604 1602/1659/1602 1614/1660/1614 f 1605/1658/1605 1606/1661/1606 1594/1656/1594 f 1605/1658/1605 1594/1656/1594 1596/1655/1596 f 1601/1662/1601 1608/1663/1608 1607/1664/1607 f 1601/1662/1601 1607/1664/1607 1615/1665/1615 f 1599/1666/1599 1615/1665/1615 1614/1660/1614 f 1599/1666/1599 1614/1660/1614 1602/1659/1602 f 1609/1667/1609 1612/1668/1612 1613/1669/1613 f 1609/1667/1609 1613/1669/1613 1610/1670/1610 f 1610/1670/1610 1613/1669/1613 1629/1671/1629 f 1610/1670/1610 1629/1671/1629 1604/1657/1604 f 1604/1657/1604 1629/1671/1629 1606/1661/1606 f 1604/1657/1604 1606/1661/1606 1605/1658/1605 f 1600/1672/1600 1617/1673/1617 1626/1674/1626 f 1600/1672/1600 1626/1674/1626 1733/1675/1733 f 1617/1673/1617 1618/1676/1618 1619/1677/1619 f 1617/1673/1617 1619/1677/1619 1626/1674/1626 f 1618/1676/1618 1620/1678/1620 1621/1679/1621 f 1618/1676/1618 1621/1679/1621 1619/1677/1619 f 1623/1680/1623 1624/1681/1624 1621/1679/1621 f 1623/1680/1623 1621/1679/1621 1620/1678/1620 f 1586/1682/1586 1623/1680/1623 1620/1678/1620 f 1586/1682/1586 1620/1678/1620 1587/1683/1587 f 1594/1656/1594 1629/1671/1629 1628/1684/1628 f 1594/1656/1594 1628/1684/1628 1585/1685/1585 f 1623/1680/1623 1585/1685/1585 1628/1684/1628 f 1623/1680/1623 1628/1684/1628 1624/1681/1624 f 1627/1686/1627 1626/1674/1626 1619/1677/1619 f 1627/1686/1627 1619/1677/1619 1718/1687/1718 f 1617/1673/1617 1600/1672/1600 1584/1647/1584 f 1617/1673/1617 1584/1647/1584 1582/1652/1582 f 1618/1676/1618 1583/1688/1583 1587/1683/1587 f 1618/1676/1618 1587/1683/1587 1620/1678/1620 f 1582/1652/1582 1583/1688/1583 1618/1676/1618 f 1582/1652/1582 1618/1676/1618 1617/1673/1617 f 1597/1689/1597 1580/1644/1580 1584/1647/1584 f 1597/1689/1597 1584/1647/1584 1598/1690/1598 f 1624/1681/1624 1628/1684/1628 1630/1691/1630 f 1624/1681/1624 1630/1691/1630 1622/1692/1622 f 1630/1691/1630 1632/1693/1632 1631/1694/1631 f 1630/1691/1630 1631/1694/1631 1622/1692/1622 f 1632/1695/1632 1634/1696/1634 1633/1697/1633 f 1632/1695/1632 1633/1697/1633 1631/1698/1631 f 1634/1696/1634 1636/1699/1636 1635/1700/1635 f 1634/1696/1634 1635/1700/1635 1633/1697/1633 f 1636/1699/1636 1638/1701/1638 1637/1702/1637 f 1636/1699/1636 1637/1702/1637 1635/1700/1635 f 1637/1702/1637 1638/1701/1638 1646/1703/1646 f 1637/1702/1637 1646/1703/1646 1639/1704/1639 f 1641/1705/1641 1665/1706/1665 1647/1707/1647 f 1641/1705/1641 1647/1707/1647 1645/1708/1645 f 1647/1707/1647 1665/1706/1665 1643/1709/1643 f 1647/1707/1647 1643/1709/1643 1648/1710/1648 f 1640/1711/1640 1645/1708/1645 1647/1707/1647 f 1640/1711/1640 1647/1707/1647 1667/1712/1667 f 1667/1712/1667 1647/1707/1647 1648/1710/1648 f 1667/1712/1667 1648/1710/1648 1642/1713/1642 f 1654/1714/1654 1637/1702/1637 1639/1704/1639 f 1654/1714/1654 1639/1704/1639 1658/1715/1658 f 1636/1699/1636 1634/1696/1634 1655/1716/1655 f 1636/1699/1636 1655/1716/1655 1650/1717/1650 f 1630/1691/1630 1652/1718/1652 1651/1719/1651 f 1630/1691/1630 1651/1719/1651 1632/1693/1632 f 1634/1696/1634 1632/1695/1632 1651/1720/1651 f 1634/1696/1634 1651/1720/1651 1655/1716/1655 f 1631/1694/1631 1653/1721/1653 1675/1722/1675 f 1631/1694/1631 1675/1722/1675 1622/1692/1622 f 1633/1697/1633 1654/1714/1654 1653/1723/1653 f 1633/1697/1633 1653/1723/1653 1631/1698/1631 f 1650/1717/1650 1680/1724/1680 1656/1725/1656 f 1650/1717/1650 1656/1725/1656 1646/1703/1646 f 1656/1725/1656 1657/1726/1657 1649/1727/1649 f 1656/1725/1656 1649/1727/1649 1646/1703/1646 f 1651/1720/1651 1763/1728/1763 1680/1724/1680 f 1651/1720/1651 1680/1724/1680 1655/1716/1655 f 1663/1729/1663 1664/1730/1664 1658/1715/1658 f 1663/1729/1663 1658/1715/1658 1639/1704/1639 f 1664/1730/1664 1660/1731/1660 1659/1732/1659 f 1664/1730/1664 1659/1732/1659 1658/1715/1658 f 1656/1725/1656 1659/1733/1659 1660/1734/1660 f 1656/1725/1656 1660/1734/1660 1657/1726/1657 f 1657/1726/1657 1662/1735/1662 1661/1736/1661 f 1657/1726/1657 1661/1736/1661 1649/1727/1649 f 1662/1737/1662 1664/1730/1664 1663/1729/1663 f 1662/1737/1662 1663/1729/1663 1661/1738/1661 f 1661/1736/1661 1666/1739/1666 1665/1706/1665 f 1661/1736/1661 1665/1706/1665 1676/1740/1676 f 1667/1712/1667 1666/1741/1666 1661/1738/1661 f 1667/1712/1667 1661/1738/1661 1677/1742/1677 f 1643/1709/1643 1665/1706/1665 1666/1739/1666 f 1643/1709/1643 1666/1739/1666 1644/1743/1644 f 1666/1741/1666 1667/1712/1667 1642/1713/1642 f 1666/1741/1666 1642/1713/1642 1644/1743/1644 f 1668/1600/1668 1669/1595/1669 1552/1744/1552 f 1668/1600/1668 1552/1744/1552 1546/1601/1546 f 1669/1595/1669 1670/1594/1670 1545/1608/1545 f 1669/1595/1669 1545/1608/1545 1552/1744/1552 f 1537/1624/1537 1668/1600/1668 1671/1599/1671 f 1537/1624/1537 1671/1599/1671 1569/1745/1569 f 1569/1745/1569 1671/1599/1671 1672/1617/1672 f 1569/1745/1569 1672/1617/1672 1544/1746/1544 f 1673/1747/1673 1718/1687/1718 1619/1677/1619 f 1673/1747/1673 1619/1677/1619 1621/1679/1621 f 1659/1732/1659 1679/1748/1679 1678/1749/1678 f 1659/1732/1659 1678/1749/1678 1658/1715/1658 f 1656/1725/1656 1680/1724/1680 1679/1750/1679 f 1656/1725/1656 1679/1750/1679 1659/1733/1659 f 1679/1748/1679 1683/1751/1683 1682/1752/1682 f 1679/1748/1679 1682/1752/1682 1678/1749/1678 f 1680/1724/1680 1681/1753/1681 1683/1754/1683 f 1680/1724/1680 1683/1754/1683 1679/1750/1679 f 1678/1749/1678 1682/1752/1682 1653/1723/1653 f 1678/1749/1678 1653/1723/1653 1654/1714/1654 f 1685/1755/1685 1684/1756/1684 1674/1757/1674 f 1685/1755/1685 1674/1757/1674 1675/1758/1675 f 1685/1755/1685 1687/1759/1687 1686/1760/1686 f 1685/1755/1685 1686/1760/1686 1684/1756/1684 f 1687/1759/1687 1689/1761/1689 1688/1762/1688 f 1687/1759/1687 1688/1762/1688 1686/1760/1686 f 1688/1762/1688 1689/1761/1689 1691/1763/1691 f 1688/1762/1688 1691/1763/1691 1690/1764/1690 f 1693/1765/1693 1695/1766/1695 1694/1767/1694 f 1693/1765/1693 1694/1767/1694 1692/1768/1692 f 1696/1769/1696 1692/1768/1692 1694/1767/1694 f 1696/1769/1696 1694/1767/1694 1697/1770/1697 f 1699/1771/1699 1688/1762/1688 1690/1764/1690 f 1699/1771/1699 1690/1764/1690 1700/1772/1700 f 1693/1765/1693 1691/1763/1691 1705/1773/1705 f 1693/1765/1693 1705/1773/1705 1702/1774/1702 f 1687/1759/1687 1685/1755/1685 1704/1775/1704 f 1687/1759/1687 1704/1775/1704 1703/1776/1703 f 1703/1776/1703 1714/1777/1714 1705/1773/1705 f 1703/1776/1703 1705/1773/1705 1691/1763/1691 f 1701/1778/1701 1706/1779/1706 1707/1780/1707 f 1701/1778/1701 1707/1780/1707 1700/1772/1700 f 1705/1773/1705 1707/1781/1707 1706/1782/1706 f 1705/1773/1705 1706/1782/1706 1702/1774/1702 f 1708/1783/1708 1712/1784/1712 1695/1766/1695 f 1708/1783/1708 1695/1766/1695 1710/1785/1710 f 1697/1770/1697 1712/1786/1712 1708/1787/1708 f 1697/1770/1697 1708/1787/1708 1711/1788/1711 f 1707/1780/1707 1713/1789/1713 1699/1771/1699 f 1707/1780/1707 1699/1771/1699 1700/1772/1700 f 1705/1773/1705 1714/1777/1714 1713/1790/1713 f 1705/1773/1705 1713/1790/1713 1707/1781/1707 f 1625/1791/1625 1716/1792/1716 1717/1793/1717 f 1625/1791/1625 1717/1793/1717 1673/1747/1673 f 1684/1756/1684 1699/1771/1699 1716/1794/1716 f 1684/1756/1684 1716/1794/1716 1674/1757/1674 f 1627/1686/1627 1719/1795/1719 1733/1675/1733 f 1627/1686/1627 1733/1675/1733 1626/1674/1626 f 1718/1687/1718 1720/1796/1720 1719/1795/1719 f 1718/1687/1718 1719/1795/1719 1627/1686/1627 f 1683/1797/1683 1721/1798/1721 1726/1799/1726 f 1683/1797/1683 1726/1799/1726 1682/1800/1682 f 1681/1801/1681 1765/1802/1765 1721/1798/1721 f 1681/1801/1681 1721/1798/1721 1683/1797/1683 f 1721/1798/1721 1723/1803/1723 1725/1804/1725 f 1721/1798/1721 1725/1804/1725 1726/1799/1726 f 1765/1802/1765 1722/1805/1722 1723/1803/1723 f 1765/1802/1765 1723/1803/1723 1721/1798/1721 f 1723/1803/1723 1724/1806/1724 1717/1793/1717 f 1723/1803/1723 1717/1793/1717 1725/1804/1725 f 1722/1805/1722 1727/1807/1727 1724/1806/1724 f 1722/1805/1722 1724/1806/1724 1723/1803/1723 f 1690/1764/1690 1696/1769/1696 1701/1778/1701 f 1690/1764/1690 1701/1778/1701 1700/1772/1700 f 1725/1808/1725 1699/1771/1699 1713/1789/1713 f 1725/1808/1725 1713/1789/1713 1726/1809/1726 f 1628/1684/1628 1629/1671/1629 1728/1810/1728 f 1628/1684/1628 1728/1810/1728 1652/1718/1652 f 1612/1668/1612 1727/1811/1727 1729/1812/1729 f 1612/1668/1612 1729/1812/1729 1613/1669/1613 f 1764/1813/1764 1730/1814/1730 1731/1815/1731 f 1764/1813/1764 1731/1815/1731 1722/1816/1722 f 1727/1811/1727 1722/1816/1722 1731/1815/1731 f 1727/1811/1727 1731/1815/1731 1729/1812/1729 f 1629/1671/1629 1613/1669/1613 1729/1812/1729 f 1629/1671/1629 1729/1812/1729 1728/1810/1728 f 1652/1718/1652 1728/1810/1728 1732/1817/1732 f 1652/1718/1652 1732/1817/1732 1734/1818/1734 f 1726/1819/1726 1713/1790/1713 1714/1777/1714 f 1726/1819/1726 1714/1777/1714 1715/1820/1715 f 1611/1821/1611 1720/1822/1720 1727/1811/1727 f 1611/1821/1611 1727/1811/1727 1612/1668/1612 f 1611/1821/1611 1608/1663/1608 1719/1823/1719 f 1611/1821/1611 1719/1823/1719 1720/1822/1720 f 1733/1824/1733 1719/1823/1719 1608/1663/1608 f 1733/1824/1733 1608/1663/1608 1601/1662/1601 f 1734/1825/1734 1732/1826/1732 1736/1827/1736 f 1734/1825/1734 1736/1827/1736 1735/1828/1735 f 1735/1828/1735 1736/1827/1736 1737/1829/1737 f 1735/1828/1735 1737/1829/1737 1738/1830/1738 f 1737/1829/1737 1739/1831/1739 1740/1832/1740 f 1737/1829/1737 1740/1832/1740 1738/1830/1738 f 1743/1833/1743 1744/1834/1744 1742/1835/1742 f 1743/1833/1743 1742/1835/1742 1741/1836/1741 f 1746/1837/1746 1747/1838/1747 1743/1833/1743 f 1746/1837/1746 1743/1833/1743 1741/1836/1741 f 1748/1839/1748 1749/1840/1749 1739/1831/1739 f 1748/1839/1748 1739/1831/1739 1737/1829/1737 f 1742/1835/1742 1750/1841/1750 1751/1842/1751 f 1742/1835/1742 1751/1842/1751 1740/1832/1740 f 1752/1843/1752 1740/1832/1740 1751/1842/1751 f 1752/1843/1752 1751/1842/1751 1753/1844/1753 f 1755/1845/1755 1749/1840/1749 1756/1846/1756 f 1755/1845/1755 1756/1846/1756 1754/1847/1754 f 1751/1842/1751 1750/1841/1750 1754/1848/1754 f 1751/1842/1751 1754/1848/1754 1756/1849/1756 f 1757/1850/1757 1759/1851/1759 1744/1834/1744 f 1757/1850/1757 1744/1834/1744 1761/1852/1761 f 1747/1838/1747 1760/1853/1760 1757/1854/1757 f 1747/1838/1747 1757/1854/1757 1761/1855/1761 f 1756/1846/1756 1749/1840/1749 1748/1839/1748 f 1756/1846/1756 1748/1839/1748 1762/1856/1762 f 1751/1842/1751 1756/1849/1756 1762/1857/1762 f 1751/1842/1751 1762/1857/1762 1753/1844/1753 f 1739/1831/1739 1749/1840/1749 1755/1845/1755 f 1739/1831/1739 1755/1845/1755 1746/1837/1746 f 1762/1856/1762 1748/1839/1748 1764/1858/1764 f 1762/1856/1762 1764/1858/1764 1766/1859/1766 f 1766/1860/1766 1763/1861/1763 1753/1844/1753 f 1766/1860/1766 1753/1844/1753 1762/1857/1762 f 1519/1565/1519 1767/1862/1767 1386/1863/1386 f 1519/1565/1519 1386/1863/1386 1381/1634/1381 f 1386/1863/1386 1768/1864/1768 1769/1865/1769 f 1386/1863/1386 1769/1865/1769 1387/1866/1387 f 1768/1864/1768 1456/1867/1456 1457/1868/1457 f 1768/1864/1768 1457/1868/1457 1769/1865/1769 f 1392/1869/1392 452/1870/452 1506/1871/1506 f 1392/1869/1392 1506/1871/1506 1393/1872/1393 f 452/1870/452 453/1873/453 1794/1874/1794 f 452/1870/452 1794/1874/1794 1506/1871/1506 f 453/1873/453 455/1875/455 1773/1876/1773 f 453/1873/453 1773/1876/1773 1794/1874/1794 f 455/1875/455 457/1877/457 1774/1878/1774 f 455/1875/455 1774/1878/1774 1773/1876/1773 f 457/1877/457 459/1879/459 1775/1880/1775 f 457/1877/457 1775/1880/1775 1774/1878/1774 f 459/1879/459 461/1881/461 1776/1882/1776 f 459/1879/459 1776/1882/1776 1775/1880/1775 f 461/1881/461 463/1883/463 1777/1884/1777 f 461/1881/461 1777/1884/1777 1776/1882/1776 f 463/1883/463 465/1885/465 1778/1886/1778 f 463/1883/463 1778/1886/1778 1777/1884/1777 f 465/1885/465 467/1887/467 1779/1888/1779 f 465/1885/465 1779/1888/1779 1778/1886/1778 f 1775/1880/1775 1829/1889/1829 1780/1890/1780 f 1775/1880/1775 1780/1890/1780 1774/1878/1774 f 1776/1882/1776 1782/1891/1782 1781/1892/1781 f 1776/1882/1776 1781/1892/1781 1775/1880/1775 f 1777/1884/1777 1783/1893/1783 1782/1891/1782 f 1777/1884/1777 1782/1891/1782 1776/1882/1776 f 1778/1886/1778 1784/1894/1784 1783/1893/1783 f 1778/1886/1778 1783/1893/1783 1777/1884/1777 f 1779/1888/1779 473/1895/473 1784/1894/1784 f 1779/1888/1779 1784/1894/1784 1778/1886/1778 f 1780/1890/1780 1785/1896/1785 1773/1876/1773 f 1780/1890/1780 1773/1876/1773 1774/1878/1774 f 1780/1890/1780 1806/1897/1806 1786/1898/1786 f 1780/1890/1780 1786/1898/1786 1785/1896/1785 f 1786/1898/1786 1788/1899/1788 1787/1900/1787 f 1786/1898/1786 1787/1900/1787 1785/1896/1785 f 1787/1900/1787 1791/1901/1791 1790/1902/1790 f 1787/1900/1787 1790/1902/1790 1785/1896/1785 f 1793/1903/1793 1795/1904/1795 1794/1874/1794 f 1793/1903/1793 1794/1874/1794 1790/1902/1790 f 1793/1903/1793 1826/1905/1826 1797/1906/1797 f 1793/1903/1793 1797/1906/1797 1795/1904/1795 f 1798/1907/1798 1800/1908/1800 1801/1909/1801 f 1798/1907/1798 1801/1909/1801 1799/1910/1799 f 1798/1907/1798 1802/1911/1802 1803/1912/1803 f 1798/1907/1798 1803/1912/1803 1800/1908/1800 f 1803/1912/1803 494/1913/494 493/1914/493 f 1803/1912/1803 493/1914/493 1800/1908/1800 f 1799/1910/1799 1804/1915/1804 495/1916/495 f 1799/1910/1799 495/1916/495 1806/1897/1806 f 1801/1909/1801 1805/1917/1805 1804/1915/1804 f 1801/1909/1801 1804/1915/1804 1799/1910/1799 f 1506/1871/1506 1794/1874/1794 1795/1904/1795 f 1506/1871/1506 1795/1904/1795 1508/1918/1508 f 1790/1902/1790 1794/1874/1794 1773/1876/1773 f 1790/1902/1790 1773/1876/1773 1785/1896/1785 f 1800/1908/1800 493/1914/493 1805/1917/1805 f 1800/1908/1800 1805/1917/1805 1801/1909/1801 f 1807/1919/1807 1811/1920/1811 1813/1921/1813 f 1807/1919/1807 1813/1921/1813 1786/1898/1786 f 1815/1922/1815 1817/1923/1817 1816/1924/1816 f 1815/1922/1815 1816/1924/1816 1810/1925/1810 f 1792/1926/1792 1810/1925/1810 1816/1924/1816 f 1792/1926/1792 1816/1924/1816 1826/1905/1826 f 1811/1920/1811 1809/1927/1809 1833/1928/1833 f 1811/1920/1811 1833/1928/1833 1821/1929/1821 f 1819/1930/1819 1811/1920/1811 1821/1929/1821 f 1819/1930/1819 1821/1929/1821 1818/1931/1818 f 1822/1932/1822 1508/1918/1508 1795/1904/1795 f 1822/1932/1822 1795/1904/1795 1797/1906/1797 f 513/1933/513 521/1934/521 1818/1931/1818 f 513/1933/513 1818/1931/1818 1821/1929/1821 f 1827/1935/1827 522/1936/522 546/1937/546 f 1827/1935/1827 546/1937/546 1838/1938/1838 f 1782/1891/1782 524/1939/524 523/1940/523 f 1782/1891/1782 523/1940/523 1781/1892/1781 f 1783/1893/1783 525/1941/525 524/1939/524 f 1783/1893/1783 524/1939/524 1782/1891/1782 f 1784/1894/1784 526/1942/526 525/1941/525 f 1784/1894/1784 525/1941/525 1783/1893/1783 f 1831/1943/1831 1832/1944/1832 1803/1912/1803 f 1831/1943/1831 1803/1912/1803 1802/1911/1802 f 1837/1945/1837 1835/1946/1835 1834/1947/1834 f 1837/1945/1837 1834/1947/1834 1822/1932/1822 f 1835/1946/1835 1837/1945/1837 1839/1948/1839 f 1835/1946/1835 1839/1948/1839 1836/1949/1836 f 1838/1938/1838 546/1937/546 547/1950/547 f 1838/1938/1838 547/1950/547 1841/1951/1841 f 1772/1952/1772 1523/1558/1523 1524/1557/1524 f 1772/1952/1772 1524/1557/1524 1847/1953/1847 f 1847/1953/1847 1850/1954/1850 1852/1955/1852 f 1847/1953/1847 1852/1955/1852 1851/1956/1851 f 1848/1957/1848 1856/1958/1856 1865/1959/1865 f 1848/1957/1848 1865/1959/1865 1857/1960/1857 f 1770/1961/1770 1869/1962/1869 1870/1963/1870 f 1770/1961/1770 1870/1963/1870 1843/1964/1843 f 1402/1965/1402 1871/1966/1871 1872/1967/1872 f 1402/1965/1402 1872/1967/1872 1404/1968/1404 f 1871/1966/1871 1402/1965/1402 1870/1969/1870 f 1871/1966/1871 1870/1969/1870 1869/1970/1869 f 1872/1967/1872 1418/1971/1418 1417/1972/1417 f 1872/1967/1872 1417/1972/1417 1404/1968/1404 f 1426/1973/1426 1429/1974/1429 2164/1975/2164 f 1426/1973/1426 2164/1975/2164 2158/1976/2158 f 2221/1977/2221 1874/1978/1874 1877/1979/1877 f 2221/1977/2221 1877/1979/1877 2222/1980/2222 f 1877/1979/1877 1884/1981/1884 1885/1982/1885 f 1877/1979/1877 1885/1982/1885 2223/1983/2223 f 1886/1984/1886 2223/1983/2223 1885/1982/1885 f 1886/1984/1886 1885/1982/1885 1887/1985/1887 f 1901/1986/1901 1898/1987/1898 1887/1988/1887 f 1901/1986/1901 1887/1988/1887 1885/1989/1885 f 547/1950/547 625/1990/625 1892/1991/1892 f 547/1950/547 1892/1991/1892 1841/1951/1841 f 1890/1992/1890 1891/1993/1891 1892/1991/1892 f 1890/1992/1890 1892/1991/1892 1893/1994/1893 f 1860/1995/1860 1859/1996/1859 1890/1992/1890 f 1860/1995/1860 1890/1992/1890 1893/1994/1893 f 1860/1997/1860 1893/1998/1893 1884/1999/1884 f 1860/1997/1860 1884/1999/1884 1877/2000/1877 f 1402/1965/1402 1401/2001/1401 1403/2002/1403 f 1402/1965/1402 1403/2002/1403 1870/1969/1870 f 1418/1971/1418 1872/1967/1872 1873/2003/1873 f 1418/1971/1418 1873/2003/1873 1419/2004/1419 f 1898/1987/1898 646/2005/646 647/2006/647 f 1898/1987/1898 647/2006/647 1899/2007/1899 f 647/2006/647 649/2008/649 1928/2009/1928 f 647/2006/647 1928/2009/1928 1899/2007/1899 f 1896/2010/1896 1904/2011/1904 1903/2012/1903 f 1896/2010/1896 1903/2012/1903 1895/2013/1895 f 1894/2014/1894 1905/2015/1905 1906/2016/1906 f 1894/2014/1894 1906/2016/1906 1896/2010/1896 f 1896/2010/1896 1906/2016/1906 1907/2017/1907 f 1896/2010/1896 1907/2017/1907 1904/2011/1904 f 1925/2018/1925 1909/2019/1909 1908/2020/1908 f 1925/2018/1925 1908/2020/1908 1905/2021/1905 f 1906/2016/1906 1908/2022/1908 1910/2023/1910 f 1906/2016/1906 1910/2023/1910 1907/2017/1907 f 1908/2020/1908 1909/2019/1909 1915/2024/1915 f 1908/2020/1908 1915/2024/1915 1914/2025/1914 f 1908/2022/1908 1914/2026/1914 1916/2027/1916 f 1908/2022/1908 1916/2027/1916 1910/2023/1910 f 1914/2025/1914 1915/2024/1915 1912/2028/1912 f 1914/2025/1914 1912/2028/1912 1917/2029/1917 f 1913/2030/1913 1916/2027/1916 1914/2026/1914 f 1913/2030/1913 1914/2026/1914 1917/2031/1917 f 1925/2018/1925 1924/2032/1924 1919/2033/1919 f 1925/2018/1925 1919/2033/1919 1909/2019/1909 f 1910/2023/1910 1920/2034/1920 1918/2035/1918 f 1910/2023/1910 1918/2035/1918 1907/2017/1907 f 1915/2024/1915 1922/2036/1922 1921/2037/1921 f 1915/2024/1915 1921/2037/1921 1912/2028/1912 f 1916/2027/1916 1923/2038/1923 1920/2034/1920 f 1916/2027/1916 1920/2034/1920 1910/2023/1910 f 1909/2019/1909 1919/2033/1919 1922/2036/1922 f 1909/2019/1909 1922/2036/1922 1915/2024/1915 f 1913/2030/1913 1921/2037/1921 1923/2038/1923 f 1913/2030/1913 1923/2038/1923 1916/2027/1916 f 1923/2038/1923 1922/2036/1922 1919/2033/1919 f 1923/2038/1923 1919/2033/1919 1920/2034/1920 f 1920/2034/1920 1919/2033/1919 1924/2032/1924 f 1920/2034/1920 1924/2032/1924 1926/2039/1926 f 1926/2039/1926 1929/2040/1929 1927/2041/1927 f 1926/2039/1926 1927/2041/1927 1918/2035/1918 f 1927/2041/1927 1904/2011/1904 1907/2017/1907 f 1927/2041/1927 1907/2017/1907 1918/2035/1918 f 1925/2018/1925 1928/2042/1928 1930/2043/1930 f 1925/2018/1925 1930/2043/1930 1924/2032/1924 f 2143/2044/2143 2000/2045/2000 1932/2046/1932 f 2143/2044/2143 1932/2046/1932 1931/2047/1931 f 2143/2044/2143 1931/2047/1931 1935/2048/1935 f 2143/2044/2143 1935/2048/1935 1934/2049/1934 f 1933/2050/1933 1937/2051/1937 1936/2052/1936 f 1933/2050/1933 1936/2052/1936 1932/2053/1932 f 1933/2050/1933 1949/2054/1949 1939/2055/1939 f 1933/2050/1933 1939/2055/1939 1937/2051/1937 f 1938/2056/1938 1960/2057/1960 1941/2058/1941 f 1938/2056/1938 1941/2058/1941 1935/2048/1935 f 1939/2055/1939 1949/2054/1949 1948/2059/1948 f 1939/2055/1939 1948/2059/1948 1942/2060/1942 f 1944/2061/1944 1947/2062/1947 1946/2063/1946 f 1944/2061/1944 1946/2063/1946 1945/2064/1945 f 1940/2065/1940 1946/2063/1946 1947/2062/1947 f 1940/2065/1940 1947/2062/1947 1950/2066/1950 f 1943/2067/1943 1948/2059/1948 1949/2054/1949 f 1943/2067/1943 1949/2054/1949 1940/2065/1940 f 1947/2062/1947 1953/2068/1953 1952/2069/1952 f 1947/2062/1947 1952/2069/1952 1950/2066/1950 f 1955/2070/1955 1934/2049/1934 1935/2048/1935 f 1955/2070/1955 1935/2048/1935 1941/2058/1941 f 1956/2071/1956 1986/2072/1986 1985/2073/1985 f 1956/2071/1956 1985/2073/1985 1957/2074/1957 f 1931/2047/1931 1959/2075/1959 1938/2056/1938 f 1931/2047/1931 1938/2056/1938 1935/2048/1935 f 1937/2051/1937 1962/2076/1962 1961/2077/1961 f 1937/2051/1937 1961/2077/1961 1936/2052/1936 f 1959/2075/1959 1965/2078/1965 1963/2079/1963 f 1959/2075/1959 1963/2079/1963 1938/2056/1938 f 1964/2080/1964 1962/2076/1962 1937/2051/1937 f 1964/2080/1964 1937/2051/1937 1939/2055/1939 f 1960/2057/1960 1966/2081/1966 1971/2082/1971 f 1960/2057/1960 1971/2082/1971 1942/2060/1942 f 1942/2060/1942 1971/2082/1971 1964/2080/1964 f 1942/2060/1942 1964/2080/1964 1939/2055/1939 f 1936/2083/1936 1961/2084/1961 1965/2078/1965 f 1936/2083/1936 1965/2078/1965 1959/2075/1959 f 1938/2056/1938 1963/2079/1963 1966/2081/1966 f 1938/2056/1938 1966/2081/1966 1960/2057/1960 f 1961/2084/1961 1967/2085/1967 1969/2086/1969 f 1961/2084/1961 1969/2086/1969 1965/2078/1965 f 1964/2080/1964 1972/2087/1972 1967/2088/1967 f 1964/2080/1964 1967/2088/1967 1962/2076/1962 f 1963/2079/1963 1969/2086/1969 1970/2089/1970 f 1963/2079/1963 1970/2089/1970 1966/2081/1966 f 1970/2089/1970 1968/2090/1968 1971/2082/1971 f 1970/2089/1970 1971/2082/1971 1966/2081/1966 f 1972/2087/1972 1964/2080/1964 1971/2082/1971 f 1972/2087/1972 1971/2082/1971 1968/2090/1968 f 1967/2088/1967 1972/2087/1972 1976/2091/1976 f 1967/2088/1967 1976/2091/1976 1973/2092/1973 f 1969/2086/1969 1973/2093/1973 1974/2094/1974 f 1969/2086/1969 1974/2094/1974 1970/2089/1970 f 1970/2089/1970 1974/2094/1974 1975/2095/1975 f 1970/2089/1970 1975/2095/1975 1968/2090/1968 f 1972/2087/1972 1968/2090/1968 1975/2095/1975 f 1972/2087/1972 1975/2095/1975 1976/2091/1976 f 2005/2096/2005 1933/2050/1933 2004/2097/2004 f 2005/2096/2005 2004/2097/2004 1978/2098/1978 f 649/2099/649 731/2100/731 1980/2101/1980 f 649/2099/649 1980/2101/1980 1928/2102/1928 f 1978/2103/1978 1981/2104/1981 733/2105/733 f 1978/2103/1978 733/2105/733 700/2106/700 f 1930/2107/1930 1980/2101/1980 1981/2104/1981 f 1930/2107/1930 1981/2104/1981 1979/2108/1979 f 1980/2101/1980 731/2100/731 736/2109/736 f 1980/2101/1980 736/2109/736 1982/2110/1982 f 1981/2104/1981 1983/2111/1983 738/2112/738 f 1981/2104/1981 738/2112/738 733/2105/733 f 1981/2104/1981 1980/2101/1980 1982/2110/1982 f 1981/2104/1981 1982/2110/1982 1983/2111/1983 f 1990/2113/1990 1994/2114/1994 1992/2115/1992 f 1990/2113/1990 1992/2115/1992 1987/2116/1987 f 1993/2117/1993 1995/2118/1995 1994/2114/1994 f 1993/2117/1993 1994/2114/1994 1990/2113/1990 f 1929/2119/1929 1979/2120/1979 2150/2121/2150 f 1929/2119/1929 2150/2121/2150 2149/2122/2149 f 1933/2050/1933 2005/2096/2005 692/2123/692 f 1933/2050/1933 692/2123/692 1946/2063/1946 f 1996/2124/1996 2008/2125/2008 2006/2126/2006 f 1996/2124/1996 2006/2126/2006 1991/2127/1991 f 1993/2117/1993 1991/2127/1991 2006/2126/2006 f 1993/2117/1993 2006/2126/2006 1995/2118/1995 f 777/2128/777 2009/2129/2009 2018/2130/2018 f 777/2128/777 2018/2130/2018 754/2131/754 f 756/2132/756 783/2133/783 2015/2134/2015 f 756/2132/756 2015/2134/2015 2014/2135/2014 f 2022/2136/2022 2031/2137/2031 2032/2138/2032 f 2022/2136/2022 2032/2138/2032 2025/2139/2025 f 2017/2140/2017 2037/2141/2037 2011/2142/2011 f 2017/2140/2017 2011/2142/2011 2013/2143/2013 f 2007/2144/2007 2040/2145/2040 2041/2146/2041 f 2007/2144/2007 2041/2146/2041 2030/2147/2030 f 2042/2148/2042 2041/2146/2041 2040/2145/2040 f 2042/2148/2042 2040/2145/2040 2038/2149/2038 f 2039/2150/2039 2048/2151/2048 2041/2146/2041 f 2039/2150/2039 2041/2146/2041 2042/2148/2042 f 2043/2152/2043 2049/2153/2049 2048/2151/2048 f 2043/2152/2043 2048/2151/2048 2039/2150/2039 f 2059/2154/2059 2058/2155/2058 2032/2138/2032 f 2059/2154/2059 2032/2138/2032 2051/2156/2051 f 2068/2157/2068 2069/2158/2069 2070/2159/2070 f 2068/2157/2068 2070/2159/2070 2067/2160/2067 f 2067/2160/2067 2076/2161/2076 2077/2162/2077 f 2067/2160/2067 2077/2162/2077 2068/2157/2068 f 2071/2163/2071 2078/2164/2078 2076/2161/2076 f 2071/2163/2071 2076/2161/2076 2067/2160/2067 f 2076/2161/2076 2079/2165/2079 2088/2166/2088 f 2076/2161/2076 2088/2166/2088 2077/2162/2077 f 2078/2164/2078 2080/2167/2080 2079/2165/2079 f 2078/2164/2078 2079/2165/2079 2076/2161/2076 f 2081/2168/2081 2078/2164/2078 2071/2163/2071 f 2081/2168/2081 2071/2163/2071 2074/2169/2074 f 2074/2169/2074 2082/2170/2082 2083/2171/2083 f 2074/2169/2074 2083/2171/2083 2081/2168/2081 f 2081/2168/2081 2083/2171/2083 2099/2172/2099 f 2081/2168/2081 2099/2172/2099 2101/2173/2101 f 2092/2174/2092 2070/2159/2070 2069/2158/2069 f 2092/2174/2092 2069/2158/2069 2054/2175/2054 f 2092/2174/2092 2073/2176/2073 2072/2177/2072 f 2092/2174/2092 2072/2177/2072 2070/2159/2070 f 2072/2177/2072 2073/2176/2073 2093/2178/2093 f 2072/2177/2072 2093/2178/2093 2091/2179/2091 f 2086/2180/2086 2112/2181/2112 2111/2182/2111 f 2086/2180/2086 2111/2182/2111 2084/2183/2084 f 2085/2184/2085 2511/2185/2511 2112/2181/2112 f 2085/2184/2085 2112/2181/2112 2086/2180/2086 f 2097/2186/2097 2101/2173/2101 2099/2172/2099 f 2097/2186/2097 2099/2172/2099 2098/2187/2098 f 2080/2167/2080 2086/2180/2086 2084/2183/2084 f 2080/2167/2080 2084/2183/2084 2079/2165/2079 f 2109/2188/2109 2096/2189/2096 2105/2190/2105 f 2109/2188/2109 2105/2190/2105 2104/2191/2104 f 2105/2190/2105 2107/2192/2107 2106/2193/2106 f 2105/2190/2105 2106/2193/2106 2104/2191/2104 f 2107/2192/2107 2108/2194/2108 2120/2195/2120 f 2107/2192/2107 2120/2195/2120 2106/2193/2106 f 2109/2188/2109 2110/2196/2110 2111/2182/2111 f 2109/2188/2109 2111/2182/2111 2096/2189/2096 f 2096/2189/2096 2111/2182/2111 2112/2181/2112 f 2096/2189/2096 2112/2181/2112 2174/2197/2174 f 2115/2198/2115 2119/2199/2119 2118/2200/2118 f 2115/2198/2115 2118/2200/2118 2114/2201/2114 f 2113/2202/2113 2117/2203/2117 2119/2199/2119 f 2113/2202/2113 2119/2199/2119 2115/2198/2115 f 2124/2204/2124 2123/2205/2123 2116/2206/2116 f 2124/2204/2124 2116/2206/2116 2089/2207/2089 f 2106/2193/2106 2120/2195/2120 2121/2208/2121 f 2106/2193/2106 2121/2208/2121 2104/2191/2104 f 2104/2191/2104 2121/2208/2121 2122/2209/2122 f 2104/2191/2104 2122/2209/2122 2109/2188/2109 f 2109/2188/2109 2122/2209/2122 2117/2203/2117 f 2109/2188/2109 2117/2203/2117 2113/2202/2113 f 2103/2210/2103 2108/2194/2108 2107/2192/2107 f 2103/2210/2103 2107/2192/2107 2105/2190/2105 f 2123/2205/2123 2124/2204/2124 2114/2201/2114 f 2123/2205/2123 2114/2201/2114 2118/2200/2118 f 2090/2211/2090 2155/2212/2155 2068/2157/2068 f 2090/2211/2090 2068/2157/2068 2077/2162/2077 f 2054/2175/2054 2069/2158/2069 2141/2213/2141 f 2054/2175/2054 2141/2213/2141 2142/2214/2142 f 1827/1935/1827 1818/1931/1818 521/1934/521 f 1827/1935/1827 521/1934/521 522/1936/522 f 1882/2215/1882 2126/2216/2126 2125/2217/2125 f 1882/2215/1882 2125/2217/2125 1880/2218/1880 f 2129/2219/2129 2125/2217/2125 2126/2216/2126 f 2129/2219/2129 2126/2216/2126 2128/2220/2128 f 1882/2221/1882 2130/2222/2130 2131/2223/2131 f 1882/2221/1882 2131/2223/2131 2126/2224/2126 f 2131/2223/2131 2136/2225/2136 2138/2226/2138 f 2131/2223/2131 2138/2226/2138 2147/2227/2147 f 2130/2222/2130 2135/2228/2135 2136/2225/2136 f 2130/2222/2130 2136/2225/2136 2131/2223/2131 f 1927/2041/1927 2133/2229/2133 2132/2230/2132 f 1927/2041/1927 2132/2230/2132 1904/2011/1904 f 2133/2231/2133 2137/2232/2137 2134/2233/2134 f 2133/2231/2133 2134/2233/2134 2132/2234/2132 f 2138/2226/2138 2136/2225/2136 2135/2228/2135 f 2138/2226/2138 2135/2228/2135 2139/2235/2139 f 2138/2226/2138 2139/2236/2139 2137/2232/2137 f 2138/2226/2138 2137/2232/2137 2147/2227/2147 f 2141/2213/2141 2144/2237/2144 2143/2238/2143 f 2141/2213/2141 2143/2238/2143 2142/2214/2142 f 2140/2239/2140 2143/2238/2143 2144/2237/2144 f 2140/2239/2140 2144/2237/2144 2128/2240/2128 f 2142/2214/2142 1934/2241/1934 2056/2242/2056 f 2142/2214/2142 2056/2242/2056 2057/2243/2057 f 2001/2244/2001 2145/2245/2145 2146/2246/2146 f 2001/2244/2001 2146/2246/2146 2002/2247/2002 f 2140/2248/2140 2147/2249/2147 2145/2245/2145 f 2140/2248/2140 2145/2245/2145 2001/2244/2001 f 2149/2122/2149 2151/2250/2151 1927/2251/1927 f 2149/2122/2149 1927/2251/1927 1929/2119/1929 f 2147/2249/2147 2137/2252/2137 2151/2253/2151 f 2147/2249/2147 2151/2253/2151 2145/2245/2145 f 2133/2254/2133 1927/2255/1927 2151/2253/2151 f 2133/2254/2133 2151/2253/2151 2137/2252/2137 f 2001/2244/2001 2152/2256/2152 2000/2257/2000 f 2001/2244/2001 2000/2257/2000 2143/2258/2143 f 2158/1976/2158 2159/2259/2159 2160/2260/2160 f 2158/1976/2158 2160/2260/2160 1428/2261/1428 f 2082/2170/2082 2163/2262/2163 2162/2263/2162 f 2082/2170/2082 2162/2263/2162 2083/2171/2083 f 2083/2171/2083 2181/2264/2181 2161/2265/2161 f 2083/2171/2083 2161/2265/2161 2099/2172/2099 f 2158/1976/2158 2164/1975/2164 2165/2266/2165 f 2158/1976/2158 2165/2266/2165 2159/2259/2159 f 2082/2170/2082 2074/2169/2074 2075/2267/2075 f 2082/2170/2082 2075/2267/2075 2165/2266/2165 f 2181/2264/2181 2162/2263/2162 2182/2268/2182 f 2181/2264/2181 2182/2268/2182 2166/2269/2166 f 2169/2270/2169 2166/2271/2166 2116/2206/2116 f 2169/2270/2169 2116/2206/2116 2123/2205/2123 f 2167/2272/2167 2116/2206/2116 2166/2271/2166 f 2167/2272/2167 2166/2271/2166 2182/2273/2182 f 2090/2211/2090 2167/2272/2167 2156/2274/2156 f 2090/2211/2090 2156/2274/2156 2155/2212/2155 f 2167/2272/2167 2182/2273/2182 2129/2275/2129 f 2167/2272/2167 2129/2275/2129 2156/2274/2156 f 2118/2200/2118 2168/2276/2168 2169/2270/2169 f 2118/2200/2118 2169/2270/2169 2123/2205/2123 f 2120/2195/2120 2379/2277/2379 2170/2278/2170 f 2120/2195/2120 2170/2278/2170 2121/2208/2121 f 2379/2279/2379 2220/2280/2220 2172/2281/2172 f 2379/2279/2379 2172/2281/2172 2170/2282/2170 f 2170/2282/2170 2172/2281/2172 2173/2283/2173 f 2170/2282/2170 2173/2283/2173 2171/2284/2171 f 2172/2281/2172 2220/2280/2220 2187/2285/2187 f 2172/2281/2172 2187/2285/2187 2176/2286/2176 f 2176/2286/2176 2175/2287/2175 2180/2288/2180 f 2176/2286/2176 2180/2288/2180 2172/2281/2172 f 2175/2287/2175 2511/2185/2511 2100/2289/2100 f 2175/2287/2175 2100/2289/2100 2178/2290/2178 f 2179/2291/2179 2180/2288/2180 2175/2287/2175 f 2179/2291/2179 2175/2287/2175 2178/2290/2178 f 2173/2283/2173 2179/2291/2179 2184/2292/2184 f 2173/2283/2173 2184/2292/2184 2183/2293/2183 f 2098/2187/2098 2178/2290/2178 2100/2289/2100 f 2098/2187/2098 2100/2289/2100 2097/2186/2097 f 2179/2291/2179 2178/2290/2178 2098/2187/2098 f 2179/2291/2179 2098/2187/2098 2184/2292/2184 f 2168/2294/2168 2173/2283/2173 2183/2293/2183 f 2168/2294/2168 2183/2293/2183 2169/2295/2169 f 2183/2293/2183 2181/2264/2181 2166/2269/2166 f 2183/2293/2183 2166/2269/2166 2169/2295/2169 f 2182/2268/2182 2162/2263/2162 2127/2296/2127 f 2182/2268/2182 2127/2296/2127 2129/2297/2129 f 2177/2298/2177 2186/2299/2186 2185/2300/2185 f 2177/2298/2177 2185/2300/2185 2103/2210/2103 f 2177/2298/2177 2187/2285/2187 2207/2301/2207 f 2177/2298/2177 2207/2301/2207 2186/2299/2186 f 2189/2302/2189 2188/2303/2188 2108/2194/2108 f 2189/2302/2189 2108/2194/2108 2185/2300/2185 f 2191/2304/2191 2190/2305/2190 2185/2300/2185 f 2191/2304/2191 2185/2300/2185 2186/2299/2186 f 2380/2306/2380 2108/2194/2108 2188/2303/2188 f 2380/2306/2380 2188/2303/2188 2192/2307/2192 f 2305/2308/2305 2306/2309/2306 2189/2302/2189 f 2305/2308/2305 2189/2302/2189 2190/2305/2190 f 2189/2302/2189 2342/2310/2342 2343/2311/2343 f 2189/2302/2189 2343/2311/2343 2188/2303/2188 f 2191/2304/2191 2194/2312/2194 2193/2313/2193 f 2191/2304/2191 2193/2313/2193 2190/2305/2190 f 2188/2303/2188 2381/2314/2381 2382/2315/2382 f 2188/2303/2188 2382/2315/2382 2192/2307/2192 f 2194/2312/2194 2196/2316/2196 2195/2317/2195 f 2194/2312/2194 2195/2317/2195 2193/2313/2193 f 2196/2316/2196 2198/2318/2198 2197/2319/2197 f 2196/2316/2196 2197/2319/2197 2195/2317/2195 f 2198/2318/2198 2200/2320/2200 2199/2321/2199 f 2198/2318/2198 2199/2321/2199 2197/2319/2197 f 2200/2320/2200 2205/2322/2205 2201/2323/2201 f 2200/2320/2200 2201/2323/2201 2199/2321/2199 f 2186/2299/2186 2207/2301/2207 2269/2324/2269 f 2186/2299/2186 2269/2324/2269 2270/2325/2270 f 2194/2312/2194 2208/2326/2208 2209/2327/2209 f 2194/2312/2194 2209/2327/2209 2196/2316/2196 f 2200/2320/2200 2209/2327/2209 2211/2328/2211 f 2200/2320/2200 2211/2328/2211 2205/2322/2205 f 2211/2328/2211 2210/2329/2210 2203/2330/2203 f 2211/2328/2211 2203/2330/2203 2205/2322/2205 f 2214/2331/2214 2212/2332/2212 2202/2333/2202 f 2214/2331/2214 2202/2333/2202 2204/2334/2204 f 2203/2330/2203 2213/2335/2213 2214/2331/2214 f 2203/2330/2203 2214/2331/2214 2204/2334/2204 f 2215/2336/2215 2264/2337/2264 2212/2332/2212 f 2215/2336/2215 2212/2332/2212 2214/2331/2214 f 2213/2335/2213 2263/2338/2263 2215/2336/2215 f 2213/2335/2213 2215/2336/2215 2214/2331/2214 f 2207/2301/2207 2216/2339/2216 2280/2340/2280 f 2207/2301/2207 2280/2340/2280 2269/2324/2269 f 2220/2280/2220 2216/2339/2216 2207/2301/2207 f 2220/2280/2220 2207/2301/2207 2187/2285/2187 f 1875/2341/1875 2221/1977/2221 2222/1980/2222 f 1875/2341/1875 2222/1980/2222 1878/2342/1878 f 2223/1983/2223 1897/2343/1897 1878/2342/1878 f 2223/1983/2223 1878/2342/1878 2222/1980/2222 f 2228/2344/2228 2225/2345/2225 2043/2152/2043 f 2228/2344/2228 2043/2152/2043 2045/2346/2045 f 2059/2154/2059 2051/2156/2051 2237/2347/2237 f 2059/2154/2059 2237/2347/2237 2238/2348/2238 f 2066/2349/2066 2059/2154/2059 2238/2348/2238 f 2066/2349/2066 2238/2348/2238 2061/2350/2061 f 2231/2351/2231 2241/2352/2241 2094/2353/2094 f 2231/2351/2231 2094/2353/2094 2073/2176/2073 f 2244/2354/2244 2243/2355/2243 2250/2356/2250 f 2244/2354/2244 2250/2356/2250 2235/2357/2235 f 2094/2353/2094 2251/2358/2251 2247/2359/2247 f 2094/2353/2094 2247/2359/2247 2227/2360/2227 f 2053/2361/2053 2065/2362/2065 2064/2363/2064 f 2053/2361/2053 2064/2363/2064 2240/2364/2240 f 2256/2365/2256 2199/2321/2199 2201/2323/2201 f 2256/2365/2256 2201/2323/2201 2253/2366/2253 f 2253/2366/2253 2201/2323/2201 2202/2333/2202 f 2253/2366/2253 2202/2333/2202 2254/2367/2254 f 2255/2368/2255 2193/2313/2193 2195/2317/2195 f 2255/2368/2255 2195/2317/2195 2256/2365/2256 f 2257/2369/2257 2210/2329/2210 2211/2328/2211 f 2257/2369/2257 2211/2328/2211 2258/2370/2258 f 2259/2371/2259 2253/2366/2253 2254/2367/2254 f 2259/2371/2259 2254/2367/2254 2260/2372/2260 f 2258/2373/2258 2259/2374/2259 2260/2375/2260 f 2258/2373/2258 2260/2375/2260 2257/2376/2257 f 2261/2377/2261 2257/2376/2257 2260/2375/2260 f 2261/2377/2261 2260/2375/2260 2262/2378/2262 f 2263/2379/2263 2261/2377/2261 2262/2378/2262 f 2263/2379/2263 2262/2378/2262 2264/2380/2264 f 2267/2381/2267 2259/2374/2259 2258/2373/2258 f 2267/2381/2267 2258/2373/2258 2265/2382/2265 f 2340/2383/2340 2267/2381/2267 2265/2382/2265 f 2340/2383/2340 2265/2382/2265 2266/2384/2266 f 2256/2365/2256 2253/2366/2253 2259/2371/2259 f 2256/2365/2256 2259/2371/2259 2267/2385/2267 f 2255/2368/2255 2256/2365/2256 2267/2385/2267 f 2255/2368/2255 2267/2385/2267 2340/2386/2340 f 2266/2387/2266 2265/2388/2265 2209/2327/2209 f 2266/2387/2266 2209/2327/2209 2208/2326/2208 f 2269/2324/2269 2272/2389/2272 2271/2390/2271 f 2269/2324/2269 2271/2390/2271 2270/2325/2270 f 2272/2389/2272 2274/2391/2274 2273/2392/2273 f 2272/2389/2272 2273/2392/2273 2271/2390/2271 f 2274/2391/2274 2276/2393/2276 2275/2394/2275 f 2274/2391/2274 2275/2394/2275 2273/2392/2273 f 2269/2324/2269 2280/2340/2280 2281/2395/2281 f 2269/2324/2269 2281/2395/2281 2272/2389/2272 f 2281/2395/2281 2282/2396/2282 2279/2397/2279 f 2281/2395/2281 2279/2397/2279 2276/2393/2276 f 2283/2398/2283 2284/2399/2284 2278/2400/2278 f 2283/2398/2283 2278/2400/2278 2277/2401/2277 f 2279/2397/2279 2285/2402/2285 2283/2398/2283 f 2279/2397/2279 2283/2398/2283 2277/2401/2277 f 2286/2403/2286 2287/2404/2287 2284/2399/2284 f 2286/2403/2286 2284/2399/2284 2283/2398/2283 f 2285/2402/2285 2288/2405/2288 2286/2403/2286 f 2285/2402/2285 2286/2403/2286 2283/2398/2283 f 2289/2406/2289 2275/2394/2275 2278/2400/2278 f 2289/2406/2289 2278/2400/2278 2290/2407/2290 f 2206/2408/2206 2270/2325/2270 2271/2390/2271 f 2206/2408/2206 2271/2390/2271 2289/2406/2289 f 2291/2409/2291 2282/2396/2282 2281/2395/2281 f 2291/2409/2291 2281/2395/2281 2298/2410/2298 f 2297/2411/2297 2289/2406/2289 2290/2407/2290 f 2297/2411/2297 2290/2407/2290 2292/2412/2292 f 2298/2413/2298 2297/2414/2297 2292/2415/2292 f 2298/2413/2298 2292/2415/2292 2291/2416/2291 f 2293/2417/2293 2291/2416/2291 2292/2415/2292 f 2293/2417/2293 2292/2415/2292 2294/2418/2294 f 2295/2419/2295 2293/2417/2293 2294/2418/2294 f 2295/2419/2295 2294/2418/2294 2296/2420/2296 f 2288/2421/2288 2295/2419/2295 2296/2420/2296 f 2288/2421/2288 2296/2420/2296 2287/2422/2287 f 2299/2423/2299 2297/2414/2297 2298/2413/2298 f 2299/2423/2299 2298/2413/2298 2415/2424/2415 f 2289/2406/2289 2297/2411/2297 2299/2425/2299 f 2289/2406/2289 2299/2425/2299 2206/2408/2206 f 2415/2426/2415 2298/2410/2298 2281/2395/2281 f 2415/2426/2415 2281/2395/2281 2280/2340/2280 f 2301/2427/2301 2208/2326/2208 2194/2312/2194 f 2301/2427/2301 2194/2312/2194 2191/2304/2191 f 2304/2428/2304 2415/2429/2415 2218/2430/2218 f 2304/2428/2304 2218/2430/2218 2302/2431/2302 f 2301/2427/2301 2303/2432/2303 2266/2387/2266 f 2301/2427/2301 2266/2387/2266 2208/2326/2208 f 2303/2433/2303 2304/2428/2304 2340/2383/2340 f 2303/2433/2303 2340/2383/2340 2266/2384/2266 f 2209/2327/2209 2265/2388/2265 2258/2370/2258 f 2209/2327/2209 2258/2370/2258 2211/2328/2211 f 2305/2308/2305 2308/2434/2308 2307/2435/2307 f 2305/2308/2305 2307/2435/2307 2306/2309/2306 f 2308/2434/2308 2310/2436/2310 2309/2437/2309 f 2308/2434/2308 2309/2437/2309 2307/2435/2307 f 2310/2436/2310 2312/2438/2312 2311/2439/2311 f 2310/2436/2310 2311/2439/2311 2309/2437/2309 f 2312/2438/2312 2314/2440/2314 2313/2441/2313 f 2312/2438/2312 2313/2441/2313 2311/2439/2311 f 2305/2308/2305 2318/2442/2318 2319/2443/2319 f 2305/2308/2305 2319/2443/2319 2308/2434/2308 f 2312/2438/2312 2319/2443/2319 2320/2444/2320 f 2312/2438/2312 2320/2444/2320 2314/2440/2314 f 2320/2444/2320 2321/2445/2321 2317/2446/2317 f 2320/2444/2320 2317/2446/2317 2314/2440/2314 f 2322/2447/2322 2323/2448/2323 2316/2449/2316 f 2322/2447/2322 2316/2449/2316 2315/2450/2315 f 2317/2446/2317 2324/2451/2324 2322/2447/2322 f 2317/2446/2317 2322/2447/2322 2315/2450/2315 f 2325/2452/2325 2326/2453/2326 2323/2448/2323 f 2325/2452/2325 2323/2448/2323 2322/2447/2322 f 2324/2451/2324 2327/2454/2327 2325/2452/2325 f 2324/2451/2324 2325/2452/2325 2322/2447/2322 f 2328/2455/2328 2311/2439/2311 2313/2441/2313 f 2328/2455/2328 2313/2441/2313 2329/2456/2329 f 2329/2456/2329 2313/2441/2313 2316/2449/2316 f 2329/2456/2329 2316/2449/2316 2330/2457/2330 f 2331/2458/2331 2306/2309/2306 2307/2435/2307 f 2331/2458/2331 2307/2435/2307 2328/2455/2328 f 2321/2445/2321 2320/2444/2320 2333/2459/2333 f 2321/2445/2321 2333/2459/2333 2332/2460/2332 f 2334/2461/2334 2329/2456/2329 2330/2457/2330 f 2334/2461/2334 2330/2457/2330 2335/2462/2335 f 2333/2463/2333 2334/2464/2334 2335/2465/2335 f 2333/2463/2333 2335/2465/2335 2332/2466/2332 f 2336/2467/2336 2332/2466/2332 2335/2465/2335 f 2336/2467/2336 2335/2465/2335 2337/2468/2337 f 2327/2469/2327 2336/2467/2336 2337/2468/2337 f 2327/2469/2327 2337/2468/2337 2326/2470/2326 f 2338/2471/2338 2334/2464/2334 2333/2463/2333 f 2338/2471/2338 2333/2463/2333 2339/2472/2339 f 2376/2473/2376 2338/2471/2338 2339/2472/2339 f 2376/2473/2376 2339/2472/2339 2340/2383/2340 f 2328/2455/2328 2329/2456/2329 2334/2461/2334 f 2328/2455/2328 2334/2461/2334 2338/2474/2338 f 2331/2458/2331 2328/2455/2328 2338/2474/2338 f 2331/2458/2331 2338/2474/2338 2376/2475/2376 f 2340/2386/2340 2339/2476/2339 2319/2443/2319 f 2340/2386/2340 2319/2443/2319 2318/2442/2318 f 2319/2443/2319 2339/2476/2339 2333/2459/2333 f 2319/2443/2319 2333/2459/2333 2320/2444/2320 f 2305/2308/2305 2193/2313/2193 2255/2368/2255 f 2305/2308/2305 2255/2368/2255 2318/2442/2318 f 2342/2310/2342 2345/2477/2345 2344/2478/2344 f 2342/2310/2342 2344/2478/2344 2343/2311/2343 f 2345/2477/2345 2347/2479/2347 2346/2480/2346 f 2345/2477/2345 2346/2480/2346 2344/2478/2344 f 2347/2479/2347 2349/2481/2349 2348/2482/2348 f 2347/2479/2347 2348/2482/2348 2346/2480/2346 f 2349/2481/2349 2351/2483/2351 2350/2484/2350 f 2349/2481/2349 2350/2484/2350 2348/2482/2348 f 2342/2310/2342 2355/2485/2355 2356/2486/2356 f 2342/2310/2342 2356/2486/2356 2345/2477/2345 f 2349/2481/2349 2356/2486/2356 2357/2487/2357 f 2349/2481/2349 2357/2487/2357 2351/2483/2351 f 2357/2487/2357 2358/2488/2358 2354/2489/2354 f 2357/2487/2357 2354/2489/2354 2351/2483/2351 f 2359/2490/2359 2360/2491/2360 2353/2492/2353 f 2359/2490/2359 2353/2492/2353 2352/2493/2352 f 2354/2489/2354 2361/2494/2361 2359/2490/2359 f 2354/2489/2354 2359/2490/2359 2352/2493/2352 f 2363/2495/2363 2348/2482/2348 2350/2484/2350 f 2363/2495/2363 2350/2484/2350 2364/2496/2364 f 2364/2496/2364 2350/2484/2350 2353/2492/2353 f 2364/2496/2364 2353/2492/2353 2365/2497/2365 f 2366/2498/2366 2343/2311/2343 2344/2478/2344 f 2366/2498/2366 2344/2478/2344 2363/2495/2363 f 2367/2499/2367 2358/2488/2358 2357/2487/2357 f 2367/2499/2367 2357/2487/2357 2368/2500/2368 f 2369/2501/2369 2364/2496/2364 2365/2497/2365 f 2369/2501/2369 2365/2497/2365 2370/2502/2370 f 2368/2503/2368 2369/2504/2369 2370/2505/2370 f 2368/2503/2368 2370/2505/2370 2367/2506/2367 f 2371/2507/2371 2367/2506/2367 2370/2505/2370 f 2371/2507/2371 2370/2505/2370 2372/2508/2372 f 2373/2509/2373 2369/2504/2369 2368/2503/2368 f 2373/2509/2373 2368/2503/2368 2374/2510/2374 f 2375/2511/2375 2373/2509/2373 2374/2510/2374 f 2375/2511/2375 2374/2510/2374 2376/2512/2376 f 2363/2495/2363 2364/2496/2364 2369/2501/2369 f 2363/2495/2363 2369/2501/2369 2373/2513/2373 f 2366/2498/2366 2363/2495/2363 2373/2513/2373 f 2366/2498/2366 2373/2513/2373 2375/2514/2375 f 2376/2475/2376 2374/2515/2374 2356/2486/2356 f 2376/2475/2376 2356/2486/2356 2355/2485/2355 f 2356/2486/2356 2374/2515/2374 2368/2500/2368 f 2356/2486/2356 2368/2500/2368 2357/2487/2357 f 2331/2458/2331 2355/2485/2355 2342/2310/2342 f 2331/2458/2331 2342/2310/2342 2306/2309/2306 f 2376/2473/2376 2340/2383/2340 2304/2428/2304 f 2376/2473/2376 2304/2428/2304 2302/2431/2302 f 2378/2516/2378 2302/2517/2302 2217/2518/2217 f 2378/2516/2378 2217/2518/2217 2377/2519/2377 f 2377/2520/2377 2379/2277/2379 2120/2195/2120 f 2377/2520/2377 2120/2195/2120 2380/2306/2380 f 2192/2307/2192 2378/2521/2378 2377/2520/2377 f 2192/2307/2192 2377/2520/2377 2380/2306/2380 f 1873/2003/1873 2164/2522/2164 1429/2523/1429 f 1873/2003/1873 1429/2523/1429 1419/2004/1419 f 2381/2314/2381 2384/2524/2384 2383/2525/2383 f 2381/2314/2381 2383/2525/2383 2382/2315/2382 f 2384/2524/2384 2386/2526/2386 2385/2527/2385 f 2384/2524/2384 2385/2527/2385 2383/2525/2383 f 2386/2526/2386 2388/2528/2388 2387/2529/2387 f 2386/2526/2386 2387/2529/2387 2385/2527/2385 f 2388/2528/2388 2390/2530/2390 2389/2531/2389 f 2388/2528/2388 2389/2531/2389 2387/2529/2387 f 2381/2314/2381 2394/2532/2394 2395/2533/2395 f 2381/2314/2381 2395/2533/2395 2384/2524/2384 f 2388/2528/2388 2395/2533/2395 2396/2534/2396 f 2388/2528/2388 2396/2534/2396 2390/2530/2390 f 2396/2534/2396 2397/2535/2397 2393/2536/2393 f 2396/2534/2396 2393/2536/2393 2390/2530/2390 f 2398/2537/2398 2399/2538/2399 2392/2539/2392 f 2398/2537/2398 2392/2539/2392 2391/2540/2391 f 2393/2536/2393 2400/2541/2400 2398/2537/2398 f 2393/2536/2393 2398/2537/2398 2391/2540/2391 f 2402/2542/2402 2387/2529/2387 2389/2531/2389 f 2402/2542/2402 2389/2531/2389 2403/2543/2403 f 2403/2543/2403 2389/2531/2389 2392/2539/2392 f 2403/2543/2403 2392/2539/2392 2404/2544/2404 f 2405/2545/2405 2382/2315/2382 2383/2525/2383 f 2405/2545/2405 2383/2525/2383 2402/2542/2402 f 2406/2546/2406 2397/2535/2397 2396/2534/2396 f 2406/2546/2406 2396/2534/2396 2407/2547/2407 f 2408/2548/2408 2403/2543/2403 2404/2544/2404 f 2408/2548/2408 2404/2544/2404 2409/2549/2409 f 2407/2550/2407 2408/2551/2408 2409/2552/2409 f 2407/2550/2407 2409/2552/2409 2406/2553/2406 f 2410/2554/2410 2406/2553/2406 2409/2552/2409 f 2410/2554/2410 2409/2552/2409 2411/2555/2411 f 2412/2556/2412 2408/2551/2408 2407/2550/2407 f 2412/2556/2412 2407/2550/2407 2413/2557/2413 f 2414/2558/2414 2412/2556/2412 2413/2557/2413 f 2414/2558/2414 2413/2557/2413 2375/2511/2375 f 2402/2542/2402 2403/2543/2403 2408/2548/2408 f 2402/2542/2402 2408/2548/2408 2412/2559/2412 f 2405/2545/2405 2402/2542/2402 2412/2559/2412 f 2405/2545/2405 2412/2559/2412 2414/2560/2414 f 2375/2514/2375 2413/2561/2413 2395/2533/2395 f 2375/2514/2375 2395/2533/2395 2394/2532/2394 f 2395/2533/2395 2413/2561/2413 2407/2547/2407 f 2395/2533/2395 2407/2547/2407 2396/2534/2396 f 2366/2498/2366 2394/2532/2394 2381/2314/2381 f 2366/2498/2366 2381/2314/2381 2343/2311/2343 f 2302/2517/2302 2414/2558/2414 2375/2511/2375 f 2302/2517/2302 2375/2511/2375 2376/2512/2376 f 2405/2545/2405 2414/2560/2414 2378/2521/2378 f 2405/2545/2405 2378/2521/2378 2192/2307/2192 f 2191/2304/2191 2270/2325/2270 2206/2408/2206 f 2191/2304/2191 2206/2408/2206 2301/2427/2301 f 2303/2432/2303 2301/2427/2301 2206/2408/2206 f 2303/2432/2303 2206/2408/2206 2299/2425/2299 f 2038/2149/2038 2040/2145/2040 2425/2562/2425 f 2038/2149/2038 2425/2562/2425 2417/2563/2417 f 2423/2564/2423 2420/2565/2420 2418/2566/2418 f 2423/2564/2423 2418/2566/2418 2424/2567/2424 f 1406/2568/1406 2418/2566/2418 2420/2565/2420 f 1406/2568/1406 2420/2565/2420 562/2569/562 f 2422/2570/2422 2419/2571/2419 2416/2572/2416 f 2422/2570/2422 2416/2572/2416 2421/2573/2421 f 2423/2564/2423 2417/2563/2417 2416/2572/2416 f 2423/2564/2423 2416/2572/2416 2419/2571/2419 f 2424/2567/2424 2038/2149/2038 2417/2563/2417 f 2424/2567/2424 2417/2563/2417 2423/2564/2423 f 2428/2574/2428 2015/2575/2015 783/2576/783 f 2428/2574/2428 783/2576/783 1331/2577/1331 f 2430/2578/2430 2429/2579/2429 2432/2580/2432 f 2430/2578/2430 2432/2580/2432 2431/2581/2431 f 2434/2582/2434 2429/2579/2429 2433/2583/2433 f 2434/2582/2434 2433/2583/2433 2435/2584/2435 f 2434/2582/2434 2435/2584/2435 2437/2585/2437 f 2434/2582/2434 2437/2585/2437 2436/2586/2436 f 2439/2587/2439 2433/2583/2433 2430/2578/2430 f 2439/2587/2439 2430/2578/2430 2438/2588/2438 f 2440/2589/2440 2435/2584/2435 2433/2583/2433 f 2440/2589/2440 2433/2583/2433 2439/2587/2439 f 2437/2585/2437 2435/2584/2435 2440/2589/2440 f 2437/2585/2437 2440/2589/2440 2441/2590/2441 f 2430/2578/2430 2431/2581/2431 2017/2591/2017 f 2430/2578/2430 2017/2591/2017 2438/2588/2438 f 2015/2592/2015 2428/2593/2428 2442/2594/2442 f 2015/2592/2015 2442/2594/2442 2451/2595/2451 f 2446/2596/2446 2444/2597/2444 2445/2598/2445 f 2446/2596/2446 2445/2598/2445 2447/2599/2447 f 2447/2599/2447 2445/2598/2445 2443/2600/2443 f 2447/2599/2447 2443/2600/2443 2450/2601/2450 f 2450/2601/2450 2443/2600/2443 2442/2594/2442 f 2450/2601/2450 2442/2594/2442 2449/2602/2449 f 2449/2602/2449 2442/2594/2442 2428/2593/2428 f 2449/2602/2449 2428/2593/2428 2448/2603/2448 f 2443/2600/2443 2440/2604/2440 2439/2605/2439 f 2443/2600/2443 2439/2605/2439 2451/2595/2451 f 2434/2582/2434 2454/2606/2454 2453/2607/2453 f 2434/2582/2434 2453/2607/2453 2429/2579/2429 f 2434/2582/2434 2436/2586/2436 2446/2596/2446 f 2434/2582/2434 2446/2596/2446 2454/2606/2454 f 14/2608/14 2421/2573/2421 2426/2609/2426 f 14/2608/14 2426/2609/2426 1/2610/1 f 2431/2611/2431 2432/2612/2432 2457/2613/2457 f 2431/2611/2431 2457/2613/2457 2456/2614/2456 f 63/2615/63 2457/2613/2457 2432/2612/2432 f 63/2615/63 2432/2612/2432 64/2616/64 f 2460/2617/2460 2513/2618/2513 2512/2619/2512 f 2460/2617/2460 2512/2619/2512 2458/2620/2458 f 2514/2621/2514 2513/2618/2513 2460/2617/2460 f 2514/2621/2514 2460/2617/2460 2462/2622/2462 f 2463/2623/2463 2464/2624/2464 2467/2625/2467 f 2463/2623/2463 2467/2625/2467 2466/2626/2466 f 2465/2627/2465 2498/2628/2498 2466/2626/2466 f 2465/2627/2465 2466/2626/2466 2467/2625/2467 f 2460/2617/2460 2458/2620/2458 2468/2629/2468 f 2460/2617/2460 2468/2629/2468 2469/2630/2469 f 2464/2624/2464 2462/2622/2462 2469/2630/2469 f 2464/2624/2464 2469/2630/2469 2500/2631/2500 f 2465/2627/2465 2467/2625/2467 2471/2632/2471 f 2465/2627/2465 2471/2632/2471 2470/2633/2470 f 2467/2625/2467 2464/2624/2464 2500/2631/2500 f 2467/2625/2467 2500/2631/2500 2471/2632/2471 f 2473/2634/2473 2474/2635/2474 2432/2636/2432 f 2473/2634/2473 2432/2636/2432 2472/2637/2472 f 2476/2638/2476 2473/2634/2473 2472/2637/2472 f 2476/2638/2476 2472/2637/2472 2475/2639/2475 f 2478/2640/2478 2474/2635/2474 2473/2634/2473 f 2478/2640/2478 2473/2634/2473 2479/2641/2479 f 2479/2641/2479 2473/2634/2473 2476/2638/2476 f 2479/2641/2479 2476/2638/2476 2480/2642/2480 f 2488/2643/2488 2478/2640/2478 2479/2641/2479 f 2488/2643/2488 2479/2641/2479 2482/2644/2482 f 2479/2641/2479 2480/2642/2480 2485/2645/2485 f 2479/2641/2479 2485/2645/2485 2482/2644/2482 f 2488/2643/2488 2482/2644/2482 2484/2646/2484 f 2488/2643/2488 2484/2646/2484 2483/2647/2483 f 2486/2648/2486 2487/2649/2487 2476/2638/2476 f 2486/2648/2486 2476/2638/2476 2475/2639/2475 f 2480/2642/2480 2476/2638/2476 2487/2649/2487 f 2480/2642/2480 2487/2649/2487 2481/2650/2481 f 61/2651/61 2474/2635/2474 2478/2640/2478 f 61/2651/61 2478/2640/2478 2490/2652/2490 f 1332/2653/1332 2452/2654/2452 2448/2655/2448 f 1332/2653/1332 2448/2655/2448 1331/2577/1331 f 106/2656/106 2489/2657/2489 2452/2654/2452 f 106/2656/106 2452/2654/2452 1332/2653/1332 f 2478/2640/2478 2488/2643/2488 2489/2658/2489 f 2478/2640/2478 2489/2658/2489 2490/2652/2490 f 2492/2659/2492 1/2660/1 2426/2661/2426 f 2492/2659/2492 2426/2661/2426 2491/2662/2491 f 2425/2663/2425 2459/2664/2459 2491/2665/2491 f 2425/2663/2425 2491/2665/2491 2426/2666/2426 f 2496/2667/2496 2493/2668/2493 2461/2669/2461 f 2496/2667/2496 2461/2669/2461 2463/2670/2463 f 2492/2659/2492 2515/2671/2515 4/2672/4 f 2492/2659/2492 4/2672/4 1/2660/1 f 2518/2673/2518 2519/2674/2519 2494/2675/2494 f 2518/2673/2518 2494/2675/2494 2516/2676/2516 f 2466/2677/2466 2497/2678/2497 2496/2667/2496 f 2466/2677/2466 2496/2667/2496 2463/2670/2463 f 2499/2679/2499 2497/2678/2497 2466/2677/2466 f 2499/2679/2499 2466/2677/2466 2498/2680/2498 f 2497/2678/2497 2499/2679/2499 2470/2633/2470 f 2497/2678/2497 2470/2633/2470 2471/2632/2471 f 2517/2681/2517 2496/2667/2496 2497/2678/2497 f 2517/2681/2517 2497/2678/2497 2471/2632/2471 f 2516/2676/2516 2494/2675/2494 2496/2667/2496 f 2516/2676/2516 2496/2667/2496 2517/2681/2517 f 1356/2682/1356 2419/2571/2419 2422/2570/2422 f 1356/2682/1356 2422/2570/2422 1357/2683/1357 f 90/2684/90 1357/2683/1357 2422/2570/2422 f 90/2684/90 2422/2570/2422 2502/2685/2502 f 2507/2686/2507 1444/2687/1444 90/2688/90 f 2507/2686/2507 90/2688/90 2502/2689/2502 f 2507/2686/2507 2506/2690/2506 1445/2691/1445 f 2507/2686/2507 1445/2691/1445 1444/2687/1444 f 2504/2692/2504 2505/2693/2505 2508/2694/2508 f 2504/2692/2504 2508/2694/2508 2507/2686/2507 f 1446/2695/1446 1445/2691/1445 2506/2690/2506 f 1446/2695/1446 2506/2690/2506 2509/2696/2509 f 2176/2286/2176 2187/2285/2187 2177/2298/2177 f 2176/2286/2176 2177/2298/2177 2510/2697/2510 f 2175/2287/2175 2176/2286/2176 2510/2697/2510 f 2175/2287/2175 2510/2697/2510 2511/2185/2511 f 2513/2618/2513 2493/2698/2493 2459/2664/2459 f 2513/2618/2513 2459/2664/2459 2512/2619/2512 f 2461/2699/2461 2493/2698/2493 2513/2618/2513 f 2461/2699/2461 2513/2618/2513 2514/2621/2514 f 2468/2629/2468 46/2700/46 4/2672/4 f 2468/2629/2468 4/2672/4 2515/2671/2515 f 2500/2631/2500 2469/2630/2469 2516/2676/2516 f 2500/2631/2500 2516/2676/2516 2517/2681/2517 f 1/11/1 3/2701/3 2/12/2 f 1/11/1 4/20/4 3/2701/3 f 3/2701/3 4/20/4 5/2/5 f 5/2/5 6/1/6 3/2701/3 f 10/7/10 11/6/11 13/19/13 f 7/4/7 19/51/19 18/50/18 f 2/12/2 3/2701/3 6/1/6 f 20/21/20 22/18/22 21/70/21 f 25/15/25 26/56/26 24/16/24 f 19/51/19 7/4/7 24/16/24 f 24/16/24 26/56/26 19/51/19 f 37/37/37 43/43/43 34/34/34 f 46/46/46 9/8/9 4/20/4 f 41/41/41 45/45/45 40/40/40 f 26/56/26 49/60/49 48/48/48 f 19/51/19 26/56/26 48/48/48 f 1262/33/1262 51/62/51 33/30/33 f 1262/33/1262 1281/2702/1281 51/62/51 f 52/52/52 1281/2702/1281 1280/53/1280 f 49/60/49 26/56/26 54/55/54 f 31/26/31 55/59/55 30/25/30 f 32/31/32 56/2703/56 31/26/31 f 33/30/33 56/2703/56 32/31/32 f 57/61/57 58/2704/58 56/2703/56 f 57/61/57 56/2703/56 33/30/33 f 54/55/54 59/57/59 49/60/49 f 58/2704/58 60/58/60 56/2703/56 f 60/58/60 58/2704/58 59/57/59 f 58/2704/58 49/60/49 59/57/59 f 58/2704/58 57/61/57 49/60/49 f 60/58/60 55/59/55 56/2703/56 f 55/59/55 31/26/31 56/2703/56 f 51/62/51 1281/2702/1281 52/52/52 f 63/2705/63 61/63/61 62/64/62 f 63/2705/63 64/2706/64 61/63/61 f 45/45/45 61/63/61 47/47/47 f 47/47/47 65/66/65 44/44/44 f 109/65/109 43/43/43 44/44/44 f 21/70/21 36/36/36 20/21/20 f 21/70/21 66/69/66 36/36/36 f 39/39/39 66/69/66 42/42/42 f 36/36/36 66/69/66 39/39/39 f 12/5/12 67/68/67 11/6/11 f 11/6/11 67/68/67 23/17/23 f 22/18/22 67/68/67 21/70/21 f 23/17/23 67/68/67 22/18/22 f 42/42/42 67/68/67 12/5/12 f 68/2707/68 14/10/14 15/9/15 f 68/2707/68 15/9/15 16/13/16 f 69/71/69 71/2708/71 16/13/16 f 2/12/2 6/1/6 17/14/17 f 77/78/77 80/88/80 79/79/79 f 77/78/77 79/79/79 76/77/76 f 72/73/72 70/72/70 17/14/17 f 70/72/70 72/73/72 75/76/75 f 75/76/75 81/82/81 70/72/70 f 84/81/84 70/72/70 81/82/81 f 84/81/84 69/71/69 70/72/70 f 81/82/81 75/76/75 78/80/78 f 86/87/86 87/86/87 89/102/89 f 79/79/79 85/85/85 78/80/78 f 7/4/7 18/50/18 6/1/6 f 92/2709/92 69/71/69 84/81/84 f 69/71/69 92/2709/92 71/2708/71 f 82/84/82 92/2709/92 84/81/84 f 86/87/86 94/2710/94 85/85/85 f 92/90/92 94/98/94 86/94/86 f 85/85/85 94/2710/94 83/83/83 f 89/102/89 96/101/96 95/2711/95 f 68/93/68 71/2712/71 92/90/92 f 71/2708/71 68/2707/68 16/13/16 f 101/111/101 103/108/103 102/2713/102 f 102/2713/102 103/108/103 104/107/104 f 98/105/98 99/104/99 105/2714/105 f 110/2715/110 104/107/104 105/2714/105 f 102/2713/102 104/107/104 110/2715/110 f 103/108/103 108/113/108 111/114/111 f 105/2714/105 104/107/104 98/105/98 f 114/118/114 121/487/121 122/486/122 f 126/120/126 116/167/116 115/117/115 f 113/116/113 112/115/112 127/126/127 f 112/115/112 117/122/117 120/129/120 f 122/486/122 119/2716/119 118/123/118 f 446/485/446 121/487/121 124/2717/124 f 114/118/114 115/117/115 123/169/123 f 121/487/121 125/170/125 124/2717/124 f 121/487/121 123/169/123 125/170/125 f 118/123/118 119/2716/119 174/125/174 f 174/125/174 148/165/148 146/124/146 f 127/126/127 130/131/130 131/143/131 f 130/131/130 132/130/132 133/2718/133 f 133/2718/133 136/142/136 130/131/130 f 134/144/134 131/143/131 130/131/130 f 136/142/136 133/2718/133 139/132/139 f 157/141/157 134/144/134 136/142/136 f 136/142/136 134/144/134 130/131/130 f 132/130/132 137/134/137 138/133/138 f 138/133/138 133/2718/133 132/130/132 f 140/135/140 135/140/135 139/132/139 f 133/2718/133 138/133/138 139/132/139 f 137/134/137 132/130/132 141/137/141 f 141/137/141 143/138/143 142/2719/142 f 142/2719/142 137/134/137 141/137/141 f 145/139/145 144/136/144 199/182/199 f 117/122/117 146/124/146 147/183/147 f 147/183/147 120/129/120 117/122/117 f 144/136/144 120/129/120 147/183/147 f 119/2716/119 188/166/188 174/125/174 f 149/146/149 150/145/150 154/2720/154 f 150/145/150 151/147/151 154/2720/154 f 153/149/153 152/148/152 154/2720/154 f 149/146/149 154/2720/154 152/148/152 f 153/149/153 154/2720/154 151/147/151 f 159/150/159 161/157/161 155/151/155 f 149/146/149 152/148/152 165/2721/165 f 157/141/157 135/140/135 158/152/158 f 160/153/160 177/2722/177 161/157/161 f 137/134/137 142/2719/142 140/135/140 f 142/2719/142 143/138/143 164/2723/164 f 140/135/140 142/2719/142 164/2723/164 f 140/135/140 164/2723/164 135/140/135 f 178/155/178 162/154/162 163/2724/163 f 158/152/158 135/140/135 241/2725/241 f 135/140/135 164/2723/164 241/2725/241 f 160/153/160 158/152/158 241/2725/241 f 152/148/152 155/151/155 165/2721/165 f 131/143/131 149/146/149 165/2721/165 f 165/2721/165 156/2726/156 131/143/131 f 165/2721/165 155/151/155 166/2727/166 f 166/2727/166 155/151/155 167/156/167 f 155/151/155 161/157/161 167/156/167 f 169/159/169 166/2727/166 167/156/167 f 169/159/169 165/2721/165 166/2727/166 f 156/2726/156 165/2721/165 168/158/168 f 165/2721/165 169/159/169 168/158/168 f 156/2726/156 170/2728/170 128/127/128 f 156/2726/156 168/158/168 170/2728/170 f 131/143/131 128/127/128 127/126/127 f 571/588/571 173/163/173 191/162/191 f 118/123/118 114/118/114 122/486/122 f 172/179/172 148/165/148 189/164/189 f 161/2729/161 177/2730/177 227/236/227 f 176/2731/176 177/2722/177 164/2723/164 f 163/2724/163 162/154/162 176/2731/176 f 162/154/162 175/2732/175 176/2731/176 f 176/2731/176 175/2732/175 177/2722/177 f 163/2724/163 164/2723/164 178/155/178 f 178/155/178 164/2723/164 143/138/143 f 164/2723/164 163/2724/163 176/2731/176 f 121/487/121 114/118/114 123/169/123 f 125/170/125 123/169/123 179/168/179 f 116/167/116 126/120/126 180/2733/180 f 116/167/116 180/2733/180 182/173/182 f 180/2733/180 181/174/181 182/173/182 f 180/2733/180 126/120/126 181/174/181 f 124/2717/124 125/170/125 183/172/183 f 185/175/185 194/119/194 192/2734/192 f 148/165/148 172/179/172 187/178/187 f 568/585/568 571/588/571 189/164/189 f 191/162/191 189/164/189 571/588/571 f 194/119/194 195/2735/195 192/2734/192 f 185/175/185 192/2734/192 193/242/193 f 192/2734/192 195/2735/195 193/242/193 f 113/116/113 129/128/129 196/121/196 f 197/181/197 208/180/208 193/242/193 f 181/174/181 185/175/185 193/242/193 f 115/117/115 113/116/113 196/121/196 f 193/242/193 195/2735/195 197/181/197 f 197/181/197 195/2735/195 194/119/194 f 197/181/197 194/119/194 196/121/196 f 198/184/198 219/2736/219 200/185/200 f 200/185/200 199/182/199 198/184/198 f 148/165/148 198/184/198 146/124/146 f 148/165/148 219/2736/219 198/184/198 f 148/165/148 187/178/187 219/2736/219 f 219/2736/219 187/178/187 233/230/233 f 186/176/186 203/191/203 234/195/234 f 129/128/129 128/127/128 207/198/207 f 207/198/207 128/127/128 209/2737/209 f 128/127/128 170/2728/170 209/2737/209 f 209/200/209 170/2738/170 210/193/210 f 218/351/218 212/206/212 215/210/215 f 216/212/216 217/211/217 262/257/262 f 214/209/214 211/214/211 218/351/218 f 211/214/211 224/213/224 221/219/221 f 220/215/220 223/220/223 224/213/224 f 219/202/219 339/201/339 200/186/200 f 225/187/225 226/222/226 175/188/175 f 226/222/226 177/2730/177 175/188/175 f 168/2739/168 228/245/228 170/2740/170 f 168/2739/168 161/2729/161 228/245/228 f 228/245/228 227/236/227 245/238/245 f 228/245/228 229/247/229 170/2740/170 f 231/223/231 230/225/230 240/228/240 f 203/191/203 205/192/205 234/195/234 f 234/195/234 201/177/201 186/176/186 f 217/211/217 236/233/236 250/235/250 f 230/246/230 247/239/247 240/250/240 f 164/2723/164 177/2722/177 241/2725/241 f 241/2725/241 177/2722/177 160/153/160 f 161/157/161 159/150/159 160/153/160 f 191/162/191 172/179/172 189/164/189 f 243/241/243 182/173/182 181/174/181 f 243/241/243 184/171/184 182/173/182 f 206/199/206 242/244/242 208/180/208 f 161/2729/161 227/236/227 228/245/228 f 247/239/247 230/246/230 245/238/245 f 226/222/226 227/236/227 177/2730/177 f 246/2741/246 264/260/264 237/2742/237 f 248/234/248 264/2743/264 249/251/249 f 250/235/250 262/257/262 217/211/217 f 216/212/216 262/257/262 260/217/260 f 248/234/248 249/251/249 259/254/259 f 257/258/257 251/259/251 252/295/252 f 260/217/260 257/258/257 258/218/258 f 220/215/220 222/216/222 255/256/255 f 222/216/222 256/290/256 255/289/255 f 258/218/258 252/295/252 256/290/256 f 257/258/257 252/295/252 258/218/258 f 250/235/250 248/234/248 259/254/259 f 218/351/218 215/210/215 214/209/214 f 246/2741/246 263/261/263 264/260/264 f 266/263/266 265/262/265 285/2744/285 f 267/2745/267 285/2744/285 269/2746/269 f 269/2746/269 268/273/268 402/431/402 f 271/266/271 265/262/265 274/267/274 f 270/269/270 268/273/268 284/270/284 f 246/2741/246 254/291/254 263/261/263 f 273/264/273 276/271/276 272/2747/272 f 276/271/276 273/264/273 279/275/279 f 284/270/284 272/2747/272 276/271/276 f 277/272/277 278/274/278 280/428/280 f 278/274/278 281/277/281 280/428/280 f 279/275/279 278/274/278 276/271/276 f 276/271/276 278/274/278 277/272/277 f 273/264/273 272/2747/272 283/265/283 f 283/265/283 272/2747/272 284/270/284 f 285/2744/285 265/262/265 271/266/271 f 285/2744/285 271/266/271 268/273/268 f 285/2744/285 267/2745/267 266/263/266 f 285/2744/285 268/273/268 269/2746/269 f 254/291/254 255/289/255 292/287/292 f 290/285/290 342/354/342 294/398/294 f 294/398/294 291/298/291 290/285/290 f 298/278/298 275/268/275 263/261/263 f 290/285/290 291/298/291 293/288/293 f 249/251/249 264/2743/264 266/296/266 f 267/297/267 269/279/269 253/252/253 f 308/310/308 314/313/314 315/311/315 f 312/317/312 317/316/317 313/350/313 f 308/310/308 309/318/309 314/313/314 f 314/313/314 310/312/310 315/311/315 f 317/316/317 311/320/311 313/350/313 f 306/308/306 304/306/304 323/321/323 f 309/318/309 308/310/308 332/336/332 f 315/311/315 310/312/310 318/333/318 f 305/307/305 307/309/307 319/323/319 f 307/309/307 315/311/315 319/323/319 f 320/325/320 403/424/403 321/326/321 f 323/321/323 304/306/304 302/304/302 f 324/324/324 319/323/319 349/332/349 f 403/424/403 320/325/320 432/2748/432 f 331/344/331 333/337/333 329/339/329 f 329/340/329 326/334/326 331/343/331 f 318/333/318 310/312/310 345/346/345 f 336/319/336 309/318/309 346/348/346 f 339/201/339 211/214/211 221/219/221 f 339/201/339 221/219/221 200/186/200 f 221/219/221 225/187/225 200/186/200 f 170/2749/170 341/224/341 210/353/210 f 291/298/291 343/2750/343 344/328/344 f 310/312/310 334/315/334 345/346/345 f 309/318/309 332/336/332 346/348/346 f 330/342/330 318/333/318 345/346/345 f 346/348/346 332/336/332 330/345/330 f 347/355/347 327/322/327 323/321/323 f 322/329/322 384/2751/384 351/2752/351 f 344/328/344 384/2751/384 322/329/322 f 359/370/359 361/373/361 360/371/360 f 363/374/363 367/2753/367 364/375/364 f 359/370/359 365/376/365 361/373/361 f 361/373/361 362/372/362 360/371/360 f 366/377/366 367/2753/367 363/374/363 f 357/368/357 355/366/355 368/378/368 f 356/367/356 358/369/358 372/382/372 f 358/369/358 360/371/360 372/382/372 f 368/378/368 355/366/355 353/365/353 f 373/383/373 372/382/372 383/384/383 f 371/380/371 377/390/377 378/2754/378 f 378/2755/378 377/394/377 370/385/370 f 378/2755/378 370/385/370 375/387/375 f 375/388/375 371/380/371 378/2754/378 f 371/380/371 362/372/362 379/391/379 f 366/377/366 365/376/365 380/393/380 f 367/2753/367 381/392/381 364/375/364 f 381/395/381 367/2753/367 366/377/366 f 362/372/362 364/375/364 379/391/379 f 365/376/365 370/385/370 380/393/380 f 377/390/377 371/380/371 379/391/379 f 380/393/380 370/385/370 377/394/377 f 373/383/373 383/384/383 384/427/384 f 344/363/344 354/362/354 373/383/373 f 373/383/373 384/427/384 344/363/344 f 343/2750/343 294/398/294 385/400/385 f 291/298/291 294/398/294 343/2750/343 f 386/399/386 342/354/342 387/294/387 f 351/405/351 384/2756/384 395/406/395 f 349/332/349 350/361/350 432/335/432 f 393/413/393 386/399/386 387/294/387 f 396/414/396 393/413/393 389/403/389 f 385/400/385 386/399/386 394/410/394 f 393/413/393 387/294/387 389/403/389 f 297/292/297 299/299/299 321/326/321 f 434/2757/434 391/421/391 433/420/433 f 400/422/400 398/418/398 397/417/397 f 397/417/397 399/423/399 400/422/400 f 368/378/368 385/401/385 394/415/394 f 401/425/401 399/423/399 397/417/397 f 268/273/268 270/269/270 402/431/402 f 408/439/408 409/438/409 410/441/410 f 412/440/412 413/443/413 414/2758/414 f 408/439/408 410/441/410 415/444/415 f 410/441/410 409/438/409 411/442/411 f 416/445/416 412/440/412 414/2758/414 f 406/437/406 417/446/417 405/434/405 f 404/433/404 421/450/421 407/436/407 f 407/436/407 421/450/421 409/438/409 f 419/449/419 427/2759/427 426/457/426 f 427/2760/427 424/452/424 426/461/426 f 427/2760/427 423/453/423 424/452/424 f 423/456/423 427/2759/427 419/449/419 f 419/449/419 428/459/428 411/442/411 f 416/445/416 429/462/429 415/444/415 f 413/443/413 430/458/430 414/2758/414 f 430/460/430 416/445/416 414/2758/414 f 411/442/411 428/459/428 413/443/413 f 415/444/415 429/462/429 424/452/424 f 426/457/426 428/459/428 419/449/419 f 429/462/429 426/461/426 424/452/424 f 421/450/421 432/468/432 422/451/422 f 403/432/403 421/450/421 404/433/404 f 421/450/421 403/432/403 432/468/432 f 405/434/405 417/446/417 399/2761/399 f 417/446/417 433/466/433 399/2761/399 f 405/434/405 399/2761/399 401/435/401 f 432/2762/432 350/2763/350 435/2764/435 f 435/2764/435 434/2757/434 433/420/433 f 350/2763/350 434/2757/434 435/2764/435 f 441/478/441 446/485/446 442/479/442 f 183/172/183 442/479/442 124/2717/124 f 183/172/183 184/171/184 442/479/442 f 442/479/442 446/485/446 124/2717/124 f 588/2765/588 564/594/564 119/2716/119 f 447/484/447 558/483/558 449/2766/449 f 449/2766/449 122/486/122 447/484/447 f 451/488/451 242/490/242 204/491/204 f 477/524/477 476/523/476 478/2767/478 f 478/2767/478 480/526/480 481/550/481 f 478/2767/478 476/523/476 480/526/480 f 481/550/481 480/526/480 485/2768/485 f 480/526/480 479/525/479 482/527/482 f 480/526/480 482/527/482 485/2768/485 f 482/527/482 519/530/519 485/2768/485 f 498/522/498 488/532/488 487/531/487 f 487/531/487 468/513/468 498/522/498 f 468/513/468 487/531/487 491/536/491 f 497/541/497 496/540/496 493/537/493 f 171/160/171 204/190/204 190/161/190 f 475/521/475 499/543/499 498/522/498 f 498/522/498 501/553/501 500/2769/500 f 499/543/499 503/545/503 501/553/501 f 475/521/475 477/524/477 505/544/505 f 477/524/477 478/2767/478 505/544/505 f 478/2767/478 481/550/481 505/544/505 f 481/550/481 504/2770/504 505/544/505 f 481/550/481 502/547/502 504/2770/504 f 504/2770/504 503/545/503 505/544/505 f 504/2770/504 506/2771/506 512/2772/512 f 504/2770/504 502/547/502 506/2771/506 f 506/2771/506 502/547/502 507/546/507 f 506/2771/506 507/546/507 510/555/510 f 510/555/510 512/2772/512 506/2771/506 f 507/546/507 509/549/509 510/555/510 f 481/550/481 485/2768/485 519/530/519 f 503/545/503 504/2770/504 511/554/511 f 504/2770/504 512/2772/512 511/554/511 f 510/555/510 511/554/511 512/2772/512 f 514/551/514 513/557/513 537/552/537 f 500/2769/500 501/553/501 537/552/537 f 498/522/498 499/543/499 501/553/501 f 516/2773/516 517/2774/517 519/530/519 f 517/2774/517 508/548/508 519/530/519 f 517/2774/517 516/2773/516 518/2775/518 f 519/530/519 515/556/515 516/2773/516 f 486/529/486 515/556/515 519/530/519 f 515/556/515 173/542/173 538/570/538 f 173/163/173 571/588/571 538/2776/538 f 508/548/508 517/2774/517 520/559/520 f 520/559/520 509/549/509 508/548/508 f 517/2774/517 518/2775/518 520/559/520 f 520/559/520 510/555/510 509/549/509 f 518/2775/518 516/2773/516 542/560/542 f 542/560/542 520/559/520 518/2775/518 f 526/566/526 473/519/473 472/518/472 f 532/2777/532 523/563/523 527/2778/527 f 523/563/523 469/515/469 527/2778/527 f 534/2779/534 527/2778/527 529/2780/529 f 529/2780/529 528/514/528 531/567/531 f 527/2778/527 469/515/469 528/514/528 f 529/2780/529 531/567/531 533/568/533 f 530/2781/530 492/535/492 494/538/494 f 534/2779/534 532/2777/532 527/2778/527 f 492/535/492 530/2781/530 533/568/533 f 533/568/533 530/2781/530 529/2780/529 f 528/514/528 469/515/469 458/503/458 f 529/2780/529 530/2781/530 534/2779/534 f 468/513/468 491/536/491 531/567/531 f 531/567/531 528/514/528 468/513/468 f 528/514/528 529/2780/529 527/2778/527 f 535/2782/535 467/512/467 466/511/466 f 466/511/466 473/519/473 535/2782/535 f 496/540/496 495/539/495 493/537/493 f 498/522/498 500/2769/500 536/2783/536 f 500/2769/500 537/552/537 536/2783/536 f 513/557/513 536/2783/536 537/552/537 f 495/539/495 498/522/498 536/2783/536 f 516/2773/516 515/556/515 541/569/541 f 541/569/541 542/560/542 516/2773/516 f 541/569/541 543/573/543 542/560/542 f 543/573/543 540/572/540 544/2784/544 f 543/573/543 544/2784/544 545/574/545 f 542/560/542 543/573/543 545/574/545 f 592/607/592 548/582/548 549/579/549 f 549/579/549 551/577/551 550/576/550 f 552/578/552 443/480/443 445/482/445 f 552/578/552 551/577/551 553/2785/553 f 554/2786/554 558/481/558 443/480/443 f 443/480/443 552/578/552 554/2786/554 f 557/581/557 553/2785/553 551/577/551 f 553/2785/553 557/581/557 556/2787/556 f 554/2786/554 552/578/552 556/2787/556 f 556/2787/556 552/578/552 553/2785/553 f 556/2787/556 558/481/558 554/2786/554 f 558/483/558 556/2788/556 449/2766/449 f 548/582/548 592/607/592 593/601/593 f 812/2789/812 813/2790/813 741/2791/741 f 565/2792/565 450/584/450 188/166/188 f 564/594/564 448/593/448 119/2716/119 f 119/2716/119 448/593/448 589/2793/589 f 119/2716/119 589/2793/589 188/166/188 f 563/2794/563 565/2792/565 188/166/188 f 563/2794/563 567/2795/567 587/2796/587 f 565/2792/565 587/2796/587 566/2797/566 f 566/2797/566 450/584/450 565/2792/565 f 587/2796/587 565/2792/565 563/2794/563 f 569/589/569 571/588/571 573/587/573 f 568/585/568 570/2798/570 572/586/572 f 570/2798/570 585/2799/585 572/586/572 f 572/586/572 583/2800/583 573/587/573 f 573/587/573 583/2800/583 569/589/569 f 576/2801/576 579/2802/579 575/2803/575 f 571/588/571 569/589/569 574/2804/574 f 579/2802/579 539/571/539 575/2803/575 f 539/571/539 538/570/538 575/2803/575 f 575/2803/575 538/570/538 576/2801/576 f 576/2805/576 574/2804/574 577/592/577 f 577/592/577 574/2804/574 569/589/569 f 538/2776/538 574/2804/574 576/2805/576 f 574/2804/574 538/2776/538 571/588/571 f 576/2801/576 582/2806/582 579/2802/579 f 586/591/586 581/2807/581 580/2808/580 f 578/590/578 581/2807/581 586/591/586 f 576/2801/576 580/639/580 582/2806/582 f 580/2808/580 576/2805/576 577/592/577 f 569/589/569 584/2809/584 578/590/578 f 578/590/578 584/2809/584 570/2798/570 f 569/589/569 583/2800/583 584/2809/584 f 583/2800/583 572/586/572 585/2799/585 f 570/2798/570 584/2809/584 585/2799/585 f 585/2799/585 584/2809/584 583/2800/583 f 580/2808/580 577/592/577 586/591/586 f 570/2798/570 568/585/568 450/584/450 f 450/584/450 566/2797/566 607/2810/607 f 566/2797/566 587/2796/587 607/2810/607 f 607/2810/607 570/2798/570 450/584/450 f 607/2810/607 578/590/578 570/2798/570 f 587/2796/587 567/2795/567 590/596/590 f 567/2795/567 448/593/448 590/596/590 f 119/2716/119 122/486/122 588/2765/588 f 448/593/448 567/2795/567 589/2793/589 f 589/2793/589 567/2795/567 563/2794/563 f 589/2793/589 563/2794/563 188/166/188 f 122/486/122 449/2766/449 588/2765/588 f 564/594/564 588/2765/588 591/595/591 f 449/2766/449 556/2788/556 588/2765/588 f 549/579/549 550/576/550 592/607/592 f 550/576/550 602/2811/602 592/607/592 f 602/2811/602 601/606/601 594/605/594 f 745/771/745 595/600/595 744/599/744 f 596/770/596 636/657/636 597/2812/597 f 598/602/598 594/605/594 599/603/599 f 548/582/548 593/601/593 600/583/600 f 596/770/596 559/604/559 601/606/601 f 559/604/559 596/770/596 638/655/638 f 602/2811/602 594/605/594 592/607/592 f 607/2810/607 587/2796/587 590/596/590 f 607/623/607 590/612/590 604/611/604 f 638/655/638 597/2812/597 637/656/637 f 637/656/637 597/2812/597 636/657/636 f 604/611/604 993/620/993 607/623/607 f 605/610/605 606/659/606 609/2813/609 f 604/611/604 605/610/605 608/1000/608 f 578/2814/578 607/2815/607 610/641/610 f 610/641/610 581/640/581 578/2814/578 f 610/622/610 994/621/994 995/624/995 f 609/2813/609 897/876/897 613/875/613 f 996/2816/996 621/2817/621 611/1001/611 f 611/1001/611 621/2817/621 614/2818/614 f 609/2813/609 613/875/613 996/2816/996 f 609/2813/609 608/1000/608 605/610/605 f 642/1002/642 650/2819/650 619/627/619 f 619/627/619 616/2820/616 620/628/620 f 613/875/613 615/874/615 621/2817/621 f 621/2817/621 615/874/615 622/2821/622 f 614/2818/614 621/2817/621 622/2821/622 f 614/2818/614 642/1002/642 611/1001/611 f 619/627/619 995/624/995 642/1002/642 f 616/2822/616 645/2823/645 643/632/643 f 650/2819/650 642/1002/642 645/2824/645 f 617/642/617 618/630/618 648/629/648 f 620/631/620 616/2822/616 643/632/643 f 628/636/628 625/634/625 627/633/627 f 624/635/624 626/637/626 540/572/540 f 626/637/626 545/574/545 544/2784/544 f 626/637/626 544/2784/544 540/572/540 f 624/635/624 540/572/540 539/571/539 f 539/571/539 579/2802/579 624/635/624 f 579/2802/579 582/2806/582 624/635/624 f 545/574/545 626/637/626 627/633/627 f 624/635/624 582/2806/582 580/639/580 f 591/595/591 588/2765/588 556/2788/556 f 630/646/630 632/649/632 634/651/634 f 603/654/603 560/650/560 635/652/635 f 936/1182/936 612/2825/612 606/659/606 f 596/770/596 597/2812/597 638/655/638 f 630/646/630 560/650/560 603/654/603 f 614/2818/614 622/2821/622 640/2826/640 f 622/2821/622 651/2827/651 640/2826/640 f 622/2821/622 615/874/615 651/2827/651 f 614/2818/614 639/2828/639 642/1002/642 f 639/2828/639 645/2824/645 642/1002/642 f 614/2818/614 640/2826/640 641/2829/641 f 639/2830/639 644/660/644 645/2823/645 f 644/660/644 643/632/643 645/2823/645 f 623/2831/623 643/632/643 646/662/646 f 643/632/643 623/2831/623 648/629/648 f 625/2832/625 628/643/628 617/642/617 f 648/629/648 623/2831/623 625/2832/625 f 617/642/617 648/629/648 625/2832/625 f 645/2824/645 616/2820/616 650/2819/650 f 650/2819/650 616/2820/616 619/627/619 f 614/2818/614 641/2829/641 639/2828/639 f 644/2833/644 639/2834/639 653/674/653 f 644/2833/644 653/674/653 673/673/673 f 653/671/653 654/670/654 656/678/656 f 665/683/665 659/2835/659 660/684/660 f 661/685/661 659/2835/659 665/686/665 f 661/685/661 669/691/669 659/2835/659 f 669/691/669 660/684/660 659/2835/659 f 671/693/671 670/692/670 669/691/669 f 668/690/668 666/689/666 674/694/674 f 673/673/673 676/698/676 644/2833/644 f 672/688/672 674/694/674 677/696/677 f 672/688/672 677/696/677 678/697/678 f 729/2836/729 730/2837/730 771/2838/771 f 680/701/680 679/700/679 684/738/684 f 679/700/679 710/730/710 684/738/684 f 690/714/690 703/723/703 698/715/698 f 705/2839/705 702/2840/702 704/2841/704 f 705/2839/705 706/2842/706 682/902/682 f 692/2843/692 694/2844/694 695/2845/695 f 681/705/681 699/710/699 696/718/696 f 699/710/699 688/720/688 696/718/696 f 696/718/696 694/717/694 692/782/692 f 688/720/688 691/722/691 701/721/701 f 701/721/701 691/722/691 703/723/703 f 703/723/703 691/722/691 698/715/698 f 704/724/704 703/723/703 689/712/689 f 706/2842/706 705/2839/705 704/2841/704 f 694/2844/694 693/2846/693 709/2847/709 f 704/724/704 689/712/689 706/725/706 f 708/727/708 695/2845/695 694/2844/694 f 693/2846/693 750/729/750 709/2847/709 f 694/2844/694 749/728/749 708/727/708 f 689/712/689 690/714/690 711/713/711 f 720/740/720 716/734/716 714/733/714 f 718/742/718 713/732/713 712/731/712 f 690/714/690 689/712/689 703/723/703 f 718/741/718 720/740/720 724/749/724 f 724/749/724 725/748/725 728/2848/728 f 725/748/725 726/750/726 728/2848/728 f 726/750/726 727/747/727 728/2848/728 f 727/747/727 724/746/724 728/2848/728 f 730/781/730 678/2849/678 677/778/677 f 676/755/676 678/762/678 732/756/732 f 730/763/730 729/758/729 734/761/734 f 737/764/737 735/2850/735 736/765/736 f 738/766/738 735/2850/735 739/767/739 f 739/767/739 735/2850/735 737/764/737 f 609/2813/609 606/659/606 612/2825/612 f 629/647/629 742/769/742 741/2791/741 f 813/2790/813 746/2851/746 741/2791/741 f 741/2791/741 740/768/740 562/2852/562 f 629/647/629 630/646/630 742/769/742 f 742/769/742 740/768/740 741/2791/741 f 742/769/742 630/646/630 743/598/743 f 743/598/743 630/646/630 603/654/603 f 744/599/744 636/657/636 596/770/596 f 601/606/601 602/2811/602 745/771/745 f 741/2791/741 562/2852/562 812/2789/812 f 746/2851/746 629/647/629 741/2791/741 f 813/2853/813 747/2854/747 748/2855/748 f 748/2856/748 746/2851/746 813/2790/813 f 629/647/629 746/2851/746 748/2856/748 f 694/2844/694 709/2847/709 749/728/749 f 749/728/749 709/2847/709 750/729/750 f 693/2846/693 704/2841/704 750/729/750 f 693/716/693 697/719/697 704/724/704 f 704/2841/704 702/2840/702 750/729/750 f 702/2840/702 707/726/707 750/729/750 f 695/2845/695 708/727/708 751/2857/751 f 751/2857/751 753/2858/753 754/788/754 f 753/2858/753 755/2859/755 754/788/754 f 788/2860/788 776/790/776 787/789/787 f 751/2857/751 752/773/752 753/2858/753 f 753/2858/753 752/773/752 758/784/758 f 752/773/752 757/772/757 758/784/758 f 752/773/752 707/726/707 759/774/759 f 758/784/758 757/772/757 760/776/760 f 755/2859/755 753/2858/753 763/783/763 f 753/2858/753 758/784/758 763/783/763 f 763/783/763 774/803/774 764/2861/764 f 759/774/759 707/726/707 765/2862/765 f 765/2862/765 707/726/707 702/2840/702 f 702/2840/702 705/2839/705 766/2863/766 f 765/2862/765 702/2840/702 766/2863/766 f 705/2839/705 765/2862/765 766/2863/766 f 765/2862/765 761/775/761 759/774/759 f 771/2838/771 730/2837/730 920/2864/920 f 924/917/924 769/904/769 768/903/768 f 767/702/767 680/701/680 771/2838/771 f 771/753/771 680/706/680 681/705/681 f 692/782/692 700/2865/700 772/751/772 f 772/751/772 700/2865/700 729/752/729 f 708/727/708 707/726/707 751/2857/751 f 707/726/707 752/773/752 751/2857/751 f 763/783/763 799/804/799 774/803/774 f 775/786/775 773/785/773 762/777/762 f 763/783/763 775/786/775 799/804/799 f 776/790/776 780/2866/780 777/787/777 f 764/2861/764 788/2860/788 787/789/787 f 788/2860/788 764/2861/764 778/2867/778 f 764/2861/764 774/803/774 778/2867/778 f 764/2861/764 755/2859/755 763/783/763 f 788/2860/788 778/2867/778 805/2868/805 f 805/2868/805 776/790/776 788/2860/788 f 804/2869/804 780/2866/780 805/2868/805 f 780/2866/780 776/790/776 805/2868/805 f 782/792/782 756/791/756 780/2866/780 f 780/2866/780 756/791/756 777/787/777 f 782/792/782 803/2870/803 784/793/784 f 785/2871/785 782/792/782 781/800/781 f 785/2871/785 781/800/781 802/2872/802 f 754/788/754 755/2859/755 787/789/787 f 787/789/787 755/2859/755 764/2861/764 f 761/775/761 795/2873/795 789/2874/789 f 762/777/762 789/2874/789 790/2875/790 f 775/786/775 762/777/762 798/2876/798 f 790/2875/790 789/2874/789 791/795/791 f 761/775/761 765/2862/765 792/2877/792 f 789/2874/789 762/777/762 761/775/761 f 761/775/761 792/2877/792 795/2873/795 f 762/777/762 790/2875/790 798/2876/798 f 798/2876/798 799/804/799 775/786/775 f 790/2875/790 793/2878/793 798/2876/798 f 790/2875/790 791/795/791 793/2878/793 f 795/2873/795 796/2879/796 789/2874/789 f 795/2873/795 792/2877/792 796/2879/796 f 796/2879/796 792/2877/792 794/796/794 f 796/2879/796 794/796/794 797/2880/797 f 797/2880/797 789/2874/789 796/2879/796 f 794/796/794 791/795/791 797/2880/797 f 797/2880/797 791/795/791 789/2874/789 f 792/2877/792 765/2862/765 826/2881/826 f 798/2876/798 793/2878/793 799/804/799 f 802/2872/802 803/2870/803 785/2871/785 f 803/2870/803 802/2872/802 784/793/784 f 804/2869/804 805/2868/805 806/802/806 f 780/2866/780 779/801/779 781/800/781 f 804/2869/804 779/801/779 780/2866/780 f 780/2866/780 781/800/781 782/792/782 f 779/801/779 804/2869/804 806/802/806 f 806/802/806 805/2868/805 778/2867/778 f 800/798/800 793/2878/793 791/795/791 f 799/804/799 793/2878/793 810/805/810 f 793/2878/793 800/798/800 810/805/810 f 809/806/809 806/802/806 778/2867/778 f 811/807/811 812/1227/812 1196/1224/1196 f 813/2853/813 811/807/811 815/2882/815 f 808/809/808 814/811/814 815/2882/815 f 815/2882/815 814/811/814 816/1004/816 f 815/2882/815 816/1004/816 817/2883/817 f 747/2854/747 813/2853/813 815/2882/815 f 747/2854/747 815/2882/815 818/2884/818 f 815/2882/815 817/2883/817 818/2884/818 f 818/2884/818 748/2855/748 747/2854/747 f 820/812/820 819/810/819 821/2885/821 f 821/2885/821 819/810/819 800/798/800 f 800/798/800 801/797/801 821/2885/821 f 822/814/822 820/812/820 821/2885/821 f 821/2885/821 801/797/801 822/814/822 f 765/2862/765 705/2839/705 826/2881/826 f 705/2839/705 823/2886/823 826/2881/826 f 824/1020/824 823/2886/823 828/900/828 f 828/900/828 825/834/825 824/1020/824 f 833/2887/833 823/2886/823 836/1023/836 f 825/834/825 828/900/828 914/872/914 f 823/2886/823 827/901/827 828/900/828 f 827/901/827 823/2886/823 705/2839/705 f 826/2881/826 830/813/830 829/815/829 f 829/815/829 801/797/801 794/796/794 f 792/2877/792 826/2881/826 829/815/829 f 829/815/829 794/796/794 792/2877/792 f 830/813/830 826/2881/826 831/2888/831 f 830/813/830 831/2888/831 837/1008/837 f 831/2888/831 833/2887/833 837/1008/837 f 837/1008/837 833/2887/833 834/2889/834 f 832/1009/832 834/2889/834 835/1022/835 f 835/1022/835 834/2889/834 836/1023/836 f 823/2886/823 824/1020/824 836/1023/836 f 836/1023/836 834/2889/834 833/2887/833 f 834/2889/834 832/1009/832 837/1008/837 f 831/2888/831 826/2881/826 833/2887/833 f 833/2887/833 826/2881/826 823/2886/823 f 824/1020/824 825/834/825 863/833/863 f 841/818/841 838/817/838 843/835/843 f 824/1020/824 863/833/863 1024/2890/1024 f 865/1011/865 844/836/844 864/838/864 f 862/837/862 842/822/842 845/828/845 f 846/926/846 867/2891/867 862/837/862 f 862/837/862 845/828/845 846/926/846 f 851/826/851 873/831/873 852/827/852 f 849/823/849 851/826/851 852/827/852 f 858/2892/858 855/840/855 874/2893/874 f 857/839/857 856/843/856 873/831/873 f 859/824/859 861/870/861 926/2894/926 f 859/824/859 848/820/848 861/870/861 f 838/817/838 842/822/842 843/835/843 f 843/835/843 842/822/842 862/837/862 f 867/2891/867 864/838/864 862/837/862 f 927/871/927 839/816/839 840/819/840 f 840/819/840 913/873/913 927/871/927 f 864/838/864 818/2884/818 865/1011/865 f 865/1011/865 818/2884/818 817/2883/817 f 748/2855/748 818/2884/818 866/2895/866 f 629/2896/629 748/2855/748 866/2895/866 f 866/2897/866 633/653/633 631/648/631 f 631/648/631 629/647/629 866/2897/866 f 866/2895/866 867/2891/867 932/919/932 f 855/840/855 858/2892/858 883/841/883 f 858/2892/858 882/855/882 883/841/883 f 873/831/873 872/949/872 869/845/869 f 872/949/872 856/843/856 1380/844/1380 f 856/843/856 872/949/872 873/831/873 f 873/831/873 851/826/851 857/839/857 f 855/840/855 850/825/850 874/2893/874 f 874/2893/874 850/825/850 860/864/860 f 946/856/946 868/850/868 875/869/875 f 946/856/946 875/869/875 949/957/949 f 877/849/877 875/869/875 868/850/868 f 882/855/882 858/2892/858 885/861/885 f 885/861/885 881/847/881 882/855/882 f 946/856/946 1380/844/1380 884/842/884 f 858/2892/858 887/857/887 885/861/885 f 874/2893/874 886/858/886 887/857/887 f 887/857/887 858/2892/858 874/2893/874 f 860/864/860 926/2894/926 888/865/888 f 896/863/896 874/2893/874 860/864/860 f 896/863/896 886/858/886 874/2893/874 f 897/876/897 899/2898/899 901/878/901 f 898/881/898 900/2899/900 903/882/903 f 900/2899/900 919/884/919 903/882/903 f 902/883/902 651/2900/651 615/880/615 f 651/2900/651 902/883/902 906/2901/906 f 902/883/902 907/887/907 906/2901/906 f 906/2901/906 904/2902/904 651/2900/651 f 904/888/904 652/668/652 651/667/651 f 906/2901/906 907/887/907 911/894/911 f 911/895/911 909/893/909 906/892/906 f 919/884/919 900/2899/900 912/2903/912 f 927/871/927 913/873/913 916/897/916 f 915/915/915 768/903/768 912/907/912 f 827/901/827 705/2839/705 682/902/682 f 915/896/915 914/872/914 682/902/682 f 769/904/769 770/2904/770 918/2905/918 f 770/2904/770 921/779/921 923/910/923 f 918/2905/918 770/2904/770 923/910/923 f 767/916/767 920/2906/920 922/780/922 f 920/2864/920 767/702/767 771/2838/771 f 921/779/921 925/2907/925 922/780/922 f 922/780/922 925/2907/925 767/916/767 f 923/913/923 917/906/917 918/905/918 f 922/780/922 920/2906/920 730/781/730 f 770/2904/770 769/904/769 925/2907/925 f 925/2907/925 769/904/769 924/917/924 f 925/2907/925 924/917/924 767/916/767 f 921/779/921 770/2904/770 925/2907/925 f 900/899/900 901/934/901 928/933/928 f 928/933/928 927/871/927 916/897/916 f 928/933/928 916/897/916 900/899/900 f 899/2898/899 897/876/897 612/2825/612 f 899/2898/899 612/2825/612 929/2908/929 f 612/2825/612 936/1182/936 929/2908/929 f 609/2813/609 612/2825/612 897/876/897 f 634/2909/634 633/918/633 930/617/930 f 635/616/635 634/2909/634 930/617/930 f 932/919/932 867/2891/867 931/920/931 f 867/2891/867 846/926/846 931/920/931 f 932/919/932 633/918/633 866/2895/866 f 811/807/811 813/2853/813 812/1227/812 f 854/829/854 953/924/953 934/921/934 f 937/925/937 931/920/931 846/926/846 f 853/830/853 935/922/935 937/925/937 f 936/618/936 937/925/937 929/2910/929 f 933/923/933 955/951/955 953/924/953 f 888/865/888 926/2894/926 939/931/939 f 926/2894/926 861/870/861 939/931/939 f 933/923/933 871/832/871 870/846/870 f 889/862/889 940/935/940 943/2911/943 f 891/860/891 890/859/890 940/935/940 f 889/862/889 891/860/891 940/935/940 f 894/868/894 889/862/889 943/2911/943 f 893/867/893 894/868/894 942/936/942 f 894/868/894 943/2911/943 942/936/942 f 946/856/946 1379/1448/1379 1380/844/1380 f 1379/1448/1379 946/856/946 949/957/949 f 945/943/945 943/942/943 940/953/940 f 952/946/952 945/943/945 951/950/951 f 944/940/944 945/943/945 952/946/952 f 955/951/955 933/923/933 956/952/956 f 956/952/956 933/923/933 870/846/870 f 935/922/935 899/956/899 929/2910/929 f 929/2910/929 937/925/937 935/922/935 f 935/922/935 934/921/934 899/956/899 f 875/869/875 880/854/880 957/958/957 f 957/958/957 961/961/961 962/964/962 f 1115/969/1115 960/962/960 1153/974/1153 f 1078/968/1078 961/961/961 1114/970/1114 f 965/971/965 962/964/962 1077/967/1077 f 973/981/973 976/991/976 977/982/977 f 973/981/973 974/992/974 976/991/976 f 976/991/976 975/988/975 977/982/977 f 968/976/968 970/978/970 981/985/981 f 970/978/970 972/980/972 981/985/981 f 969/977/969 967/975/967 1028/1024/1028 f 971/979/971 969/977/969 1028/1024/1028 f 988/999/988 1052/998/1052 991/2912/991 f 988/999/988 991/2912/991 992/941/992 f 1187/1090/1187 990/1089/990 991/2913/991 f 1052/998/1052 1187/1085/1187 991/2912/991 f 991/2913/991 990/1089/990 989/2914/989 f 991/2912/991 989/2915/989 992/941/992 f 604/611/604 608/1000/608 993/620/993 f 611/1001/611 608/1000/608 996/2816/996 f 996/2816/996 608/1000/608 609/2813/609 f 996/2816/996 613/875/613 621/2817/621 f 997/1005/997 998/2916/998 1000/1003/1000 f 1000/1003/1000 817/2883/817 816/1004/816 f 814/811/814 820/812/820 997/1005/997 f 998/2916/998 999/1017/999 1000/1003/1000 f 1000/1003/1000 999/1017/999 817/2883/817 f 999/1017/999 865/1011/865 817/2883/817 f 1002/2917/1002 844/836/844 1003/1010/1003 f 1004/2918/1004 1011/2919/1011 1005/2920/1005 f 1011/2919/1011 1001/2921/1001 1005/2920/1005 f 1004/2918/1004 1005/2920/1005 1008/2922/1008 f 1005/2920/1005 1006/2923/1006 1008/2922/1008 f 1006/2923/1006 1022/1015/1022 1008/2922/1008 f 1022/1015/1022 1007/1014/1007 1008/2922/1008 f 1008/2922/1008 1009/1007/1009 1004/2918/1004 f 1008/2922/1008 1007/1014/1007 1009/1007/1009 f 1004/2918/1004 1010/1006/1010 1011/2919/1011 f 1004/2918/1004 1009/1007/1009 1010/1006/1010 f 1009/1007/1009 1007/1014/1007 822/814/822 f 1010/1006/1010 832/1009/832 1011/2919/1011 f 1001/2921/1001 1011/2919/1011 1012/1021/1012 f 1012/1021/1012 1011/2919/1011 835/1022/835 f 832/1009/832 835/1022/835 1011/2919/1011 f 1023/1019/1023 1019/1018/1019 1020/2924/1020 f 1003/1010/1003 1013/1012/1013 1014/2925/1014 f 1001/2921/1001 1003/1010/1003 1014/2925/1014 f 1003/1010/1003 1001/2921/1001 1002/2917/1002 f 1014/2925/1014 1006/2923/1006 1001/2921/1001 f 1006/2923/1006 1005/2920/1005 1001/2921/1001 f 1014/2925/1014 1013/1012/1013 1006/2923/1006 f 1006/2923/1006 1021/2926/1021 1022/1015/1022 f 1022/1015/1022 998/2916/998 997/1005/997 f 1022/1015/1022 997/1005/997 1015/1016/1015 f 997/1005/997 820/812/820 1015/1016/1015 f 822/814/822 1007/1014/1007 1016/1013/1016 f 1016/1013/1016 1017/2927/1017 1018/2928/1018 f 1016/1013/1016 1015/1016/1015 1017/2927/1017 f 1015/1016/1015 820/812/820 1017/2927/1017 f 1017/2927/1017 820/812/820 1018/2928/1018 f 820/812/820 822/814/822 1018/2928/1018 f 1018/2928/1018 822/814/822 1016/1013/1016 f 1019/1018/1019 999/1017/999 998/2916/998 f 1019/1018/1019 998/2916/998 1021/2926/1021 f 1021/2926/1021 998/2916/998 1022/1015/1022 f 1023/1019/1023 1013/1012/1013 865/1011/865 f 1020/2924/1020 1019/1018/1019 1021/2926/1021 f 1023/1019/1023 1020/2924/1020 1013/1012/1013 f 1013/1012/1013 1020/2924/1020 1006/2923/1006 f 1006/2923/1006 1020/2924/1020 1021/2926/1021 f 844/836/844 1002/2917/1002 1024/2890/1024 f 1001/2921/1001 1012/1021/1012 1024/2890/1024 f 1024/2890/1024 1012/1021/1012 824/1020/824 f 1024/2890/1024 1002/2917/1002 1001/2921/1001 f 844/836/844 1024/2890/1024 863/833/863 f 811/807/811 808/809/808 815/2882/815 f 926/2894/926 860/864/860 859/824/859 f 860/864/860 850/825/850 859/824/859 f 1026/1026/1026 984/993/984 974/992/974 f 985/994/985 982/989/982 975/988/975 f 1026/1026/1026 1032/1031/1032 1034/2929/1034 f 984/993/984 1026/1026/1026 1034/2929/1034 f 984/993/984 1034/2929/1034 1036/996/1036 f 1035/997/1035 1033/2930/1033 985/994/985 f 1033/2930/1033 1029/1028/1029 982/989/982 f 982/989/982 985/994/985 1033/2930/1033 f 987/995/987 1036/996/1036 1040/2931/1040 f 1035/997/1035 987/995/987 1040/2931/1040 f 1036/1039/1036 1035/1038/1035 1040/2932/1040 f 1047/1052/1047 1049/1058/1049 1048/1053/1048 f 1047/1052/1047 1050/1059/1050 1049/1058/1049 f 1049/1058/1049 1051/1055/1051 1048/1053/1048 f 1044/1049/1044 1046/1051/1046 1053/1054/1053 f 1046/1051/1046 1048/1053/1048 1053/1054/1053 f 1045/1050/1045 1043/1048/1043 1061/1065/1061 f 1047/1052/1047 1045/1050/1045 1061/1065/1061 f 1062/1066/1062 1056/1060/1056 1050/1059/1050 f 1057/1061/1057 1054/1056/1054 1051/1055/1051 f 1062/1066/1062 1064/1071/1064 1066/2933/1066 f 1056/1060/1056 1062/1066/1062 1068/2934/1068 f 1056/1060/1056 1068/2934/1068 1059/1063/1059 f 1060/1064/1060 1067/2935/1067 1057/1061/1057 f 1054/1056/1054 1067/2935/1067 1065/2936/1065 f 1065/2936/1065 1063/1068/1063 1054/1056/1054 f 1054/1056/1054 1057/1061/1057 1067/2935/1067 f 1062/1066/1062 1066/2933/1066 1068/2934/1068 f 1058/1062/1058 1059/1063/1059 1072/2937/1072 f 1060/1064/1060 1058/1062/1058 1072/2937/1072 f 1059/1081/1059 1060/1080/1060 1072/2938/1072 f 989/2914/989 990/1089/990 1074/1088/1074 f 1085/1099/1085 1087/1107/1087 1086/1100/1086 f 1085/1099/1085 1088/1108/1088 1087/1107/1087 f 1087/1107/1087 1089/1104/1089 1086/1100/1086 f 1080/1094/1080 1082/1096/1082 1091/1101/1091 f 1082/1096/1082 1084/1098/1084 1091/1101/1091 f 1081/1095/1081 1079/1093/1079 1100/1114/1100 f 1083/1097/1083 1081/1095/1081 1100/1114/1100 f 1102/1116/1102 1095/1109/1095 1088/1108/1088 f 1096/1110/1096 1093/1105/1093 1089/1104/1089 f 1102/1116/1102 1107/1121/1107 1109/2939/1109 f 1095/1109/1095 1102/1116/1102 1109/2939/1109 f 1095/1109/1095 1109/2939/1109 1098/1112/1098 f 1099/1113/1099 1108/2940/1108 1096/1110/1096 f 1108/2940/1108 1104/1118/1104 1093/1105/1093 f 1093/1105/1093 1096/1110/1096 1108/2940/1108 f 1097/1111/1097 1098/1112/1098 1113/2941/1113 f 1099/1113/1099 1097/1111/1097 1113/2941/1113 f 1098/1129/1098 1099/1128/1099 1113/2942/1113 f 1090/1102/1090 1112/1045/1112 1027/1027/1027 f 1122/1142/1122 1124/1150/1124 1123/1143/1123 f 1122/1142/1122 1125/1151/1125 1124/1150/1124 f 1124/1150/1124 1126/1147/1126 1123/1143/1123 f 1117/1137/1117 1119/1139/1119 1128/1144/1128 f 1119/1139/1119 1121/1141/1121 1128/1144/1128 f 1134/2943/1134 1131/1149/1131 1132/1152/1132 f 1133/1153/1133 1131/1149/1131 1134/2943/1134 f 1118/1138/1118 1116/1136/1116 1135/1154/1135 f 1120/1140/1120 1118/1138/1118 1135/1154/1135 f 1137/1156/1137 1132/1152/1132 1125/1151/1125 f 1133/1153/1133 1130/1148/1130 1126/1147/1126 f 1144/1167/1144 1143/1166/1143 1134/2944/1134 f 1137/1156/1137 1142/1161/1142 1144/2945/1144 f 1132/1152/1132 1137/1156/1137 1144/2945/1144 f 1132/1152/1132 1144/2945/1144 1134/2943/1134 f 1134/2943/1134 1143/2946/1143 1133/1153/1133 f 1143/2946/1143 1139/1158/1139 1130/1148/1130 f 1130/1148/1130 1133/1153/1133 1143/2946/1143 f 1127/1145/1127 1148/1134/1148 1103/1117/1103 f 1186/1217/1186 1150/1175/1150 1074/1178/1074 f 992/941/992 989/2915/989 1151/938/1151 f 989/1177/989 1149/1176/1149 1151/2947/1151 f 880/854/880 892/853/892 1152/965/1152 f 144/136/144 147/183/147 199/182/199 f 222/216/222 258/218/258 256/290/256 f 264/2743/264 248/234/248 237/232/237 f 229/226/229 341/224/341 170/2749/170 f 128/127/128 131/143/131 156/2726/156 f 112/115/112 120/129/120 127/126/127 f 864/838/864 867/2891/867 818/2884/818 f 867/2891/867 866/2895/866 818/2884/818 f 1161/1189/1161 1163/1197/1163 1162/1190/1162 f 1161/1189/1161 1164/1198/1164 1163/1197/1163 f 1163/1197/1163 1165/1194/1165 1162/1190/1162 f 1156/1184/1156 1158/1186/1158 1167/1191/1167 f 1158/1186/1158 1160/1188/1160 1167/1191/1167 f 1173/2948/1173 1170/1196/1170 1171/1199/1171 f 1172/1200/1172 1170/1196/1170 1173/2948/1173 f 1157/1185/1157 1155/1183/1155 1174/1201/1174 f 1159/1187/1159 1157/1185/1157 1174/1201/1174 f 1176/1203/1176 1171/1199/1171 1164/1198/1164 f 1172/1200/1172 1169/1195/1169 1165/1194/1165 f 1183/1214/1183 1182/1213/1182 1173/2949/1173 f 1176/1203/1176 1181/1208/1181 1183/2950/1183 f 1171/1199/1171 1176/1203/1176 1183/2950/1183 f 1171/1199/1171 1183/2950/1183 1173/2948/1173 f 1173/2948/1173 1182/2951/1182 1172/1200/1172 f 1182/2951/1182 1178/1205/1178 1169/1195/1169 f 1169/1195/1169 1172/1200/1172 1182/2951/1182 f 1166/1192/1166 1147/1173/1147 1138/1157/1138 f 1177/1204/1177 1154/973/1154 964/966/964 f 1071/2952/1071 1075/1092/1075 1076/1087/1076 f 1071/2952/1071 1076/1087/1076 1187/1090/1187 f 1042/983/1042 958/959/958 963/963/963 f 1189/1221/1189 1188/1231/1188 1197/1222/1197 f 1195/1223/1195 1192/1226/1192 1191/1232/1191 f 812/1227/812 1190/1225/1190 1196/1224/1196 f 562/1228/562 1191/1232/1191 1192/1226/1192 f 1196/1224/1196 807/808/807 811/807/811 f 1188/1231/1188 1198/1269/1198 1197/1222/1197 f 1188/1231/1188 1193/1230/1193 1198/1269/1198 f 786/799/786 806/802/806 1199/2953/1199 f 1199/2954/1199 1197/2955/1197 1275/1309/1275 f 1203/1308/1203 786/2956/786 1199/2954/1199 f 1199/2954/1199 1275/1309/1275 1203/1308/1203 f 809/806/809 1197/1222/1197 1199/2953/1199 f 1199/2953/1199 806/802/806 809/806/809 f 1202/1237/1202 1201/1240/1201 1205/1243/1205 f 784/2957/784 802/2958/802 1210/2959/1210 f 1215/1260/1215 1214/1253/1214 1223/1252/1223 f 1210/2960/1210 1211/1263/1211 784/1251/784 f 782/792/782 785/2871/785 803/2870/803 f 1212/1264/1212 1217/1257/1217 1215/1260/1215 f 1213/2961/1213 1216/1258/1216 1217/1257/1217 f 1217/1257/1217 1212/1264/1212 1213/2961/1213 f 784/1251/784 1211/1263/1211 1223/1252/1223 f 1201/1240/1201 1320/2962/1320 1225/1265/1225 f 1224/2963/1224 1220/1262/1220 1225/1265/1225 f 1225/1265/1225 1220/1262/1220 1221/1261/1221 f 1225/1265/1225 1221/1261/1221 1222/1259/1222 f 1225/1265/1225 1222/1259/1222 1226/1266/1226 f 1226/1266/1226 1222/1259/1222 1219/1256/1219 f 1226/1266/1226 1219/1256/1219 1218/1255/1218 f 1209/1245/1209 1208/1244/1208 1227/2964/1227 f 1213/1249/1213 1209/1245/1209 1227/2964/1227 f 1216/1258/1216 1213/2961/1213 1227/2964/1227 f 1218/1255/1218 1216/1258/1216 1227/2964/1227 f 1208/1244/1208 1218/1255/1218 1227/2964/1227 f 1331/1234/1331 1200/1233/1200 1220/1370/1220 f 1229/1280/1229 1237/1279/1237 1231/1273/1231 f 1229/1280/1229 1231/1273/1231 1249/1289/1249 f 1231/1273/1231 1248/1272/1248 1249/1289/1249 f 1233/1270/1233 1247/1290/1247 1250/1271/1250 f 1232/1276/1232 1251/1288/1251 1252/1277/1252 f 1247/1290/1247 1245/1317/1245 1243/1316/1243 f 1237/1279/1237 1233/1270/1233 1231/1273/1231 f 1254/1291/1254 1240/1392/1240 1241/1285/1241 f 1242/1284/1242 1234/1287/1234 1257/1322/1257 f 1243/1316/1243 1234/1287/1234 1247/1290/1247 f 1234/1287/1234 1243/1316/1243 1257/1322/1257 f 1269/1301/1269 34/34/34 43/43/43 f 1201/1240/1201 1204/1239/1204 1320/2962/1320 f 1320/2962/1320 1224/2963/1224 1225/1265/1225 f 1304/1313/1304 1249/1289/1249 1236/1275/1236 f 1273/1305/1273 1272/1304/1272 1277/1312/1277 f 1257/1322/1257 1244/1315/1244 1285/1327/1285 f 1243/1316/1243 1244/1315/1244 1257/1322/1257 f 1262/33/1262 1263/1297/1263 1291/1328/1291 f 1262/33/1262 1291/1328/1291 1281/2702/1281 f 1278/1319/1278 1280/53/1280 1281/2702/1281 f 1285/1327/1285 1284/1321/1284 1257/1322/1257 f 1259/1296/1259 1282/1295/1282 1290/1325/1290 f 1264/1298/1264 1259/1296/1259 1286/2965/1286 f 1263/1297/1263 1264/1298/1264 1286/2965/1286 f 1279/1326/1279 1286/2965/1286 1289/2966/1289 f 1279/1326/1279 1263/1297/1263 1286/2965/1286 f 1284/1321/1284 1285/1327/1285 1287/1323/1287 f 1289/2966/1289 1286/2965/1286 1288/1324/1288 f 1288/1324/1288 1287/1323/1287 1289/2966/1289 f 1289/2966/1289 1287/1323/1287 1285/1327/1285 f 1289/2966/1289 1285/1327/1285 1279/1326/1279 f 1288/1324/1288 1286/2965/1286 1290/1325/1290 f 1290/1325/1290 1286/2965/1286 1259/1296/1259 f 1291/1328/1291 1278/1319/1278 1281/2702/1281 f 1292/2967/1292 1306/1330/1306 1325/1329/1325 f 1276/2968/1276 1275/1401/1275 1436/1335/1436 f 1292/2969/1292 1276/2968/1276 1293/1334/1293 f 1438/1337/1438 1298/1339/1298 1299/1342/1299 f 1293/1334/1293 1303/1346/1303 1306/2970/1306 f 1295/1333/1295 1297/1338/1297 1305/1345/1305 f 1292/2969/1292 1293/1334/1293 1306/2970/1306 f 1204/1352/1204 1330/2971/1330 1311/1353/1311 f 1324/1365/1324 1314/2972/1314 1323/1364/1323 f 1314/2972/1314 1324/1365/1324 1318/1366/1318 f 1319/1360/1319 1321/1363/1321 1322/1361/1322 f 1321/1363/1321 1320/1362/1320 1204/2973/1204 f 1204/2973/1204 1309/2974/1309 1321/1363/1321 f 1322/1361/1322 1321/1363/1321 1309/2974/1309 f 1309/2974/1309 1312/2975/1312 1322/1361/1322 f 1322/1361/1322 1318/1366/1318 1317/1358/1317 f 1312/2975/1312 1318/1366/1318 1322/1361/1322 f 1323/2976/1323 1314/2972/1314 1318/1366/1318 f 1318/1366/1318 1312/2975/1312 1323/2976/1323 f 1328/1368/1328 1333/2977/1333 1336/2978/1336 f 1320/1362/1320 1326/1359/1326 1327/1378/1327 f 1224/1371/1224 1320/2979/1320 1327/1373/1327 f 1329/2980/1329 1333/2977/1333 1328/1368/1328 f 1328/1368/1328 1325/1367/1325 1329/2980/1329 f 1292/2967/1292 1325/1329/1325 1330/2981/1330 f 1330/2971/1330 1325/1367/1325 1311/1353/1311 f 106/1372/106 1336/2982/1336 1337/2983/1337 f 1333/1374/1333 1329/1314/1329 1334/1375/1334 f 1277/1312/1277 1329/1314/1329 1325/1329/1325 f 1329/1314/1329 1274/1307/1274 1334/1375/1334 f 1334/1375/1334 109/65/109 1335/1376/1335 f 106/1372/106 1327/1373/1327 1336/2982/1336 f 1336/2978/1336 1327/1378/1327 1328/1368/1328 f 101/111/101 102/2713/102 1341/1385/1341 f 102/2713/102 1342/1386/1342 1341/1385/1341 f 1340/1383/1340 105/2714/105 99/1384/99 f 110/2715/110 105/2714/105 1342/1386/1342 f 102/2713/102 110/2715/110 1342/1386/1342 f 1341/1385/1341 1338/1390/1338 1335/1389/1335 f 105/2714/105 1340/1383/1340 1342/1386/1342 f 1240/1392/1240 1254/1291/1254 1266/1300/1266 f 1240/1392/1240 1266/1300/1266 1343/1393/1343 f 1268/1303/1268 1271/1306/1271 1343/1393/1343 f 1266/1300/1266 1268/1303/1268 1343/1393/1343 f 1235/1274/1235 1252/1277/1252 1344/1391/1344 f 1252/1277/1252 1253/1286/1253 1344/1391/1344 f 1241/1285/1241 1240/1392/1240 1344/1391/1344 f 1253/1286/1253 1241/1285/1241 1344/1391/1344 f 1271/1306/1271 1235/1274/1235 1344/1391/1344 f 1443/1410/1443 1348/1405/1348 1345/1395/1345 f 1348/1405/1348 1347/1404/1347 1349/2984/1349 f 1349/2985/1349 1347/1505/1347 1294/1400/1294 f 1294/1400/1294 1345/1399/1345 1349/2985/1349 f 1345/1399/1345 1197/1398/1197 1198/2986/1198 f 1350/1402/1350 1298/1412/1298 1296/1403/1296 f 1300/1343/1300 1352/1344/1352 1355/2987/1355 f 1307/1348/1307 1300/1343/1300 1355/2987/1355 f 1352/1415/1352 1353/1414/1353 1355/2987/1355 f 1353/1414/1353 1307/1348/1307 1355/2987/1355 f 1191/1232/1191 562/1228/562 1356/1417/1356 f 1193/1230/1193 1194/1229/1194 1358/1420/1358 f 1358/1420/1358 1228/1267/1228 1193/1230/1193 f 1358/2988/1358 1230/1278/1230 1228/1281/1228 f 1358/2988/1358 1238/1282/1238 1230/1278/1230 f 1359/1421/1359 1238/1282/1238 1361/2989/1361 f 1237/1279/1237 1362/1283/1362 1233/1270/1233 f 77/78/77 1372/1428/1372 80/88/80 f 77/78/77 1365/1426/1365 1372/1428/1372 f 1363/1423/1363 1362/1283/1362 1360/1422/1360 f 1360/1422/1360 1366/1425/1366 1363/1423/1363 f 1366/1425/1366 1360/1422/1360 1370/1432/1370 f 1371/1429/1371 1370/1432/1370 1360/1422/1360 f 1371/1429/1371 1360/1422/1360 1359/1421/1359 f 1370/1432/1370 1367/1427/1367 1366/1425/1366 f 1375/1435/1375 1378/1447/1378 1373/1433/1373 f 1372/1428/1372 1367/1427/1367 1374/1434/1374 f 1247/1290/1247 1233/1270/1233 1245/1317/1245 f 1376/2990/1376 1371/1429/1371 1359/1421/1359 f 1359/1421/1359 1361/2989/1361 1376/2990/1376 f 1368/1430/1368 1371/1429/1371 1376/2990/1376 f 1375/1435/1375 1374/1434/1374 1377/2991/1377 f 1376/1436/1376 1375/1441/1375 1377/1443/1377 f 1374/1434/1374 1369/1431/1369 1377/2991/1377 f 1378/1447/1378 95/2711/95 96/101/96 f 810/805/810 800/798/800 819/810/819 f 781/800/781 786/799/786 802/2872/802 f 802/2958/802 786/2992/786 1210/2959/1210 f 809/806/809 778/2867/778 774/803/774 f 1358/1437/1358 1376/1436/1376 1361/2993/1361 f 1361/2989/1361 1238/1282/1238 1358/2988/1358 f 1390/1462/1390 1393/1465/1393 1391/1463/1391 f 1394/1484/1394 1395/1471/1395 1396/1472/1396 f 1395/1471/1395 550/1466/550 1397/1468/1397 f 1398/1467/1398 445/1460/445 1388/1459/1388 f 1398/1467/1398 1399/2994/1399 1397/1468/1397 f 1400/2995/1400 1388/1459/1388 1387/1458/1387 f 1388/1459/1388 1400/2995/1400 1398/1467/1398 f 1401/1469/1401 1397/1468/1397 1399/2994/1399 f 1399/2994/1399 1403/2996/1403 1401/1469/1401 f 1400/2995/1400 1403/2996/1403 1398/1467/1398 f 1403/2996/1403 1399/2994/1399 1398/1467/1398 f 1403/2996/1403 1400/2995/1400 1387/1458/1387 f 1396/1472/1396 1405/1480/1405 1394/1484/1394 f 1406/2997/1406 1407/2998/1407 1408/2999/1408 f 1395/1471/1395 1394/1484/1394 550/1466/550 f 550/1466/550 1394/1484/1394 602/3000/602 f 602/3000/602 1409/1483/1409 1410/1482/1410 f 745/1499/745 1411/1476/1411 595/1475/595 f 1413/1500/1413 1414/3001/1414 1415/1494/1415 f 1416/1479/1416 1417/1478/1417 1409/1483/1409 f 1396/1472/1396 1404/1473/1404 1405/1480/1405 f 1413/1500/1413 1410/1482/1410 1418/1481/1418 f 1418/1481/1418 1419/1496/1419 1413/1500/1413 f 602/3000/602 1394/1484/1394 1409/1483/1409 f 1419/1496/1419 1420/1495/1420 1414/3001/1414 f 1420/1495/1420 1415/1494/1415 1414/3001/1414 f 1421/1485/1421 1427/1491/1427 1422/1486/1422 f 1429/1493/1429 1426/1490/1426 1425/1489/1425 f 1413/1500/1413 1419/1496/1419 1414/3001/1414 f 1421/1485/1421 1429/1493/1429 1425/1489/1425 f 1424/1488/1424 1407/2998/1407 1430/1497/1430 f 1408/2999/1408 1407/2998/1407 1431/3002/1431 f 1407/2998/1407 562/3003/562 740/1498/740 f 1424/1488/1424 1430/1497/1430 1421/1485/1421 f 1430/1497/1430 1407/2998/1407 740/1498/740 f 1430/1497/1430 1412/1477/1412 1421/1485/1421 f 1412/1477/1412 1429/1493/1429 1421/1485/1421 f 1411/1476/1411 1413/1500/1413 1415/1494/1415 f 1410/1482/1410 745/1499/745 602/3000/602 f 1407/2998/1407 1406/2997/1406 562/3003/562 f 1431/3002/1431 1407/2998/1407 1424/1488/1424 f 1432/3004/1432 1408/2999/1408 1431/3002/1431 f 1424/1488/1424 1432/3004/1432 1431/3002/1431 f 1433/3005/1433 1423/1487/1423 1428/1492/1428 f 1423/1487/1423 1433/3005/1433 1424/1488/1424 f 1434/1501/1434 65/66/65 47/47/47 f 1436/1335/1436 1293/1334/1293 1276/2968/1276 f 1275/1401/1275 1294/1400/1294 1436/1335/1436 f 1438/1337/1438 1296/1506/1296 1298/1339/1298 f 1299/1342/1299 1297/1338/1297 1438/1337/1438 f 1303/1346/1303 1304/1507/1304 1306/2970/1306 f 1439/1407/1439 1303/1346/1303 1442/1408/1442 f 1441/1416/1441 1354/1347/1354 1308/1349/1308 f 1305/1345/1305 1440/1409/1440 1442/1408/1442 f 1442/1408/1442 1303/1346/1303 1305/1345/1305 f 1346/1394/1346 1439/1407/1439 1442/1408/1442 f 1345/1395/1345 1346/1394/1346 1443/1410/1443 f 1443/1410/1443 1346/1394/1346 1442/1408/1442 f 1348/1405/1348 1349/2984/1349 1345/1395/1345 f 1449/1509/1449 1457/1868/1457 1456/1867/1456 f 1461/1514/1461 1450/1510/1450 1451/1560/1451 f 1448/1511/1448 1462/1521/1462 1447/1508/1447 f 1447/1508/1447 1455/1524/1455 1452/1515/1452 f 1457/1868/1457 1453/1516/1453 1454/3006/1454 f 1768/1864/1768 1459/3007/1459 1456/1867/1456 f 1449/1509/1449 1458/1561/1458 1450/1510/1450 f 1456/1867/1456 1459/3007/1459 1460/1563/1460 f 1456/1867/1456 1460/1563/1460 1458/1561/1458 f 1453/1516/1453 1509/1518/1509 1454/3006/1454 f 1509/1518/1509 1481/1517/1481 1483/1559/1483 f 1462/1521/1462 1466/1536/1466 1465/1522/1465 f 1465/1522/1465 1468/3008/1468 1467/1523/1467 f 1468/3008/1468 1465/1522/1465 1471/1533/1471 f 1469/1539/1469 1465/1522/1465 1466/1536/1466 f 1471/1533/1471 1474/1525/1474 1468/3008/1468 f 1492/1534/1492 1471/1533/1471 1469/1539/1469 f 1471/1533/1471 1465/1522/1465 1469/1539/1469 f 1467/1523/1467 1473/1528/1473 1472/1527/1472 f 1473/1528/1473 1467/1523/1467 1468/3008/1468 f 1475/1526/1475 1474/1525/1474 1470/1535/1470 f 1468/3008/1468 1474/1525/1474 1473/1528/1473 f 1472/1527/1472 1476/1529/1476 1467/1523/1467 f 1476/1529/1476 1477/3009/1477 1478/1531/1478 f 1477/3009/1477 1476/1529/1476 1472/1527/1472 f 1480/1532/1480 1534/1575/1534 1479/1530/1479 f 1452/1515/1452 1482/1577/1482 1481/1517/1481 f 1482/1577/1482 1452/1515/1452 1455/1524/1455 f 1479/1530/1479 1482/1577/1482 1455/1524/1455 f 1454/3006/1454 1509/1518/1509 1523/1558/1523 f 1484/1537/1484 1489/3010/1489 1485/1538/1485 f 1485/1538/1485 1489/3010/1489 1486/1540/1486 f 1488/1544/1488 1489/3010/1489 1487/1541/1487 f 1484/1537/1484 1487/1541/1487 1489/3010/1489 f 1488/1544/1488 1486/1540/1486 1489/3010/1489 f 1494/1543/1494 1490/1542/1490 1496/1552/1496 f 1484/1537/1484 1500/3011/1500 1487/1541/1487 f 1492/1534/1492 1493/1546/1493 1470/1535/1470 f 1495/1545/1495 1496/1552/1496 1512/3012/1512 f 1472/1527/1472 1475/1526/1475 1477/3009/1477 f 1477/3009/1477 1499/3013/1499 1478/1531/1478 f 1475/1526/1475 1499/3013/1499 1477/3009/1477 f 1475/1526/1475 1470/1535/1470 1499/3013/1499 f 1513/1547/1513 1498/3014/1498 1497/1548/1497 f 1493/1546/1493 1575/3015/1575 1470/1535/1470 f 1470/1535/1470 1575/3015/1575 1499/3013/1499 f 1495/1545/1495 1575/3015/1575 1493/1546/1493 f 1487/1541/1487 1500/3011/1500 1490/1542/1490 f 1466/1536/1466 1500/3011/1500 1484/1537/1484 f 1500/3011/1500 1466/1536/1466 1491/3016/1491 f 1500/3011/1500 1501/3017/1501 1490/1542/1490 f 1501/3017/1501 1502/1549/1502 1490/1542/1490 f 1490/1542/1490 1502/1549/1502 1496/1552/1496 f 1504/1550/1504 1502/1549/1502 1501/3017/1501 f 1504/1550/1504 1501/3017/1501 1500/3011/1500 f 1491/3016/1491 1503/1551/1503 1500/3011/1500 f 1500/3011/1500 1503/1551/1503 1504/1550/1504 f 1491/3016/1491 1463/1520/1463 1505/3018/1505 f 1491/3016/1491 1505/3018/1505 1503/1551/1503 f 1466/1536/1466 1462/1521/1462 1463/1520/1463 f 1850/1954/1850 1526/1555/1526 1508/1554/1508 f 1453/1516/1453 1457/1868/1457 1449/1509/1449 f 1507/1570/1507 1524/1557/1524 1483/1559/1483 f 1496/3019/1496 1561/1629/1561 1512/3020/1512 f 1511/3021/1511 1499/3013/1499 1512/3012/1512 f 1498/3014/1498 1511/3021/1511 1497/1548/1497 f 1497/1548/1497 1511/3021/1511 1510/3022/1510 f 1511/3021/1511 1512/3012/1512 1510/3022/1510 f 1498/3014/1498 1513/1547/1513 1499/3013/1499 f 1513/1547/1513 1478/1531/1478 1499/3013/1499 f 1499/3013/1499 1511/3021/1511 1498/3014/1498 f 1456/1867/1456 1458/1561/1458 1449/1509/1449 f 1460/1563/1460 1514/1562/1514 1458/1561/1458 f 1451/1560/1451 1515/3023/1515 1461/1514/1461 f 1451/1560/1451 1517/1566/1517 1515/3023/1515 f 1515/3023/1515 1517/1566/1517 1516/1567/1516 f 1515/3023/1515 1516/1567/1516 1461/1514/1461 f 1459/3007/1459 1518/1564/1518 1460/1563/1460 f 1520/1568/1520 1527/3024/1527 1529/1512/1529 f 1483/1559/1483 1522/1571/1522 1507/1570/1507 f 1847/1953/1847 1524/1557/1524 1850/1954/1850 f 1526/1555/1526 1850/1954/1850 1524/1557/1524 f 1529/1512/1529 1527/3024/1527 1530/3025/1530 f 1520/1568/1520 1528/1636/1528 1527/3024/1527 f 1527/3024/1527 1528/1636/1528 1530/3025/1530 f 1448/1511/1448 1531/1513/1531 1464/1519/1464 f 1532/1573/1532 1528/1636/1528 1542/1574/1542 f 1516/1567/1516 1528/1636/1528 1520/1568/1520 f 1450/1510/1450 1531/1513/1531 1448/1511/1448 f 1528/1636/1528 1532/1573/1532 1530/3025/1530 f 1532/1573/1532 1529/1512/1529 1530/3025/1530 f 1532/1573/1532 1531/1513/1531 1529/1512/1529 f 1533/1576/1533 1535/1578/1535 1553/3026/1553 f 1535/1578/1535 1533/1576/1533 1534/1575/1534 f 1483/1559/1483 1481/1517/1481 1533/1576/1533 f 1483/1559/1483 1533/1576/1533 1553/3026/1553 f 1483/1559/1483 1553/3026/1553 1522/1571/1522 f 1553/3026/1553 1567/1623/1567 1522/1571/1522 f 1521/1569/1521 1568/1586/1568 1538/1583/1538 f 1464/1519/1464 1541/1591/1541 1463/1520/1463 f 1541/1591/1541 1543/3027/1543 1463/1520/1463 f 1463/1520/1463 1543/3027/1543 1505/3018/1505 f 1543/1593/1543 1544/1588/1544 1505/3028/1505 f 1552/1744/1552 1549/1605/1549 1546/1601/1546 f 1550/1603/1550 1593/1650/1593 1551/1604/1551 f 1548/1602/1548 1552/1744/1552 1545/1608/1545 f 1545/1608/1545 1555/1613/1555 1558/1606/1558 f 1554/1607/1554 1558/1606/1558 1557/1612/1557 f 1553/1597/1553 1535/1579/1535 1670/1594/1670 f 1559/1582/1559 1510/1581/1510 1560/1615/1560 f 1560/1615/1560 1510/1581/1510 1512/3020/1512 f 1503/3029/1503 1505/3030/1505 1562/1638/1562 f 1503/3029/1503 1562/1638/1562 1496/3019/1496 f 1562/1638/1562 1576/1631/1576 1561/1629/1561 f 1562/1638/1562 1505/3030/1505 1563/1639/1563 f 1565/1616/1565 1574/1621/1574 1564/1618/1564 f 1538/1583/1538 1568/1586/1568 1539/1585/1539 f 1568/1586/1568 1521/1569/1521 1536/1572/1536 f 1551/1604/1551 1581/1627/1581 1570/1625/1570 f 1564/1640/1564 1574/1642/1574 1578/1632/1578 f 1499/3013/1499 1575/3015/1575 1512/3012/1512 f 1575/3015/1575 1495/1545/1495 1512/3012/1512 f 1496/1552/1496 1495/1545/1495 1494/1543/1494 f 1526/1555/1526 1524/1557/1524 1507/1570/1507 f 1381/1634/1381 1516/1567/1516 1517/1566/1517 f 1381/1634/1381 1517/1566/1517 1519/1565/1519 f 1540/1592/1540 1542/1574/1542 1391/1637/1391 f 1496/3019/1496 1562/1638/1562 1561/1629/1561 f 1578/1632/1578 1576/1631/1576 1564/1640/1564 f 1560/1615/1560 1512/3020/1512 1561/1629/1561 f 1577/3031/1577 1571/3032/1571 1595/1653/1595 f 1579/1628/1579 1580/1644/1580 1595/3033/1595 f 1581/1627/1581 1551/1604/1551 1593/1650/1593 f 1550/1603/1550 1591/1611/1591 1593/1650/1593 f 1579/1628/1579 1590/1645/1590 1580/1644/1580 f 1588/1651/1588 1583/1688/1583 1582/1652/1582 f 1591/1611/1591 1589/1610/1589 1588/1651/1588 f 1554/1607/1554 1586/1649/1586 1556/1609/1556 f 1556/1609/1556 1586/1682/1586 1587/1683/1587 f 1589/1610/1589 1587/1683/1587 1583/1688/1583 f 1588/1651/1588 1589/1610/1589 1583/1688/1583 f 1581/1627/1581 1590/1645/1590 1579/1628/1579 f 1552/1744/1552 1548/1602/1548 1549/1605/1549 f 1577/3031/1577 1595/1653/1595 1594/1656/1594 f 1597/1654/1597 1616/3034/1616 1596/1655/1596 f 1598/3035/1598 1600/3036/1600 1616/3034/1616 f 1600/3036/1600 1733/1824/1733 1599/1666/1599 f 1602/1659/1602 1605/1658/1605 1596/1655/1596 f 1601/1662/1601 1615/1665/1615 1599/1666/1599 f 1577/3031/1577 1594/1656/1594 1585/1685/1585 f 1604/1657/1604 1603/3037/1603 1607/1664/1607 f 1607/1664/1607 1610/1670/1610 1604/1657/1604 f 1615/1665/1615 1607/1664/1607 1603/3037/1603 f 1608/1663/1608 1611/1821/1611 1609/1667/1609 f 1609/1667/1609 1611/1821/1611 1612/1668/1612 f 1610/1670/1610 1607/1664/1607 1609/1667/1609 f 1607/1664/1607 1608/1663/1608 1609/1667/1609 f 1604/1657/1604 1614/1660/1614 1603/3037/1603 f 1614/1660/1614 1615/1665/1615 1603/3037/1603 f 1616/3034/1616 1602/1659/1602 1596/1655/1596 f 1616/3034/1616 1599/1666/1599 1602/1659/1602 f 1616/3034/1616 1597/1654/1597 1598/3035/1598 f 1616/3034/1616 1600/3036/1600 1599/1666/1599 f 1585/1685/1585 1623/1680/1623 1586/1682/1586 f 1621/1679/1621 1625/1791/1625 1673/1747/1673 f 1625/1791/1625 1621/1679/1621 1622/1692/1622 f 1629/1671/1629 1594/1656/1594 1606/1661/1606 f 1621/1679/1621 1624/1681/1624 1622/1692/1622 f 1580/1644/1580 1597/1689/1597 1595/3033/1595 f 1598/1690/1598 1584/1647/1584 1600/1672/1600 f 1639/1704/1639 1646/1703/1646 1645/1708/1645 f 1643/1709/1643 1644/1743/1644 1648/1710/1648 f 1639/1704/1639 1645/1708/1645 1640/1711/1640 f 1645/1708/1645 1646/1703/1646 1641/1705/1641 f 1648/1710/1648 1644/1743/1644 1642/1713/1642 f 1637/1702/1637 1654/1714/1654 1635/1700/1635 f 1640/1711/1640 1663/1729/1663 1639/1704/1639 f 1646/1703/1646 1649/1727/1649 1641/1705/1641 f 1636/1699/1636 1650/1717/1650 1638/1701/1638 f 1638/1701/1638 1650/1717/1650 1646/1703/1646 f 1651/1719/1651 1652/1718/1652 1734/1818/1734 f 1654/1714/1654 1633/1697/1633 1635/1700/1635 f 1655/1716/1655 1680/1724/1680 1650/1717/1650 f 1734/1818/1734 1763/3038/1763 1651/1719/1651 f 1662/1737/1662 1660/1731/1660 1664/1730/1664 f 1660/1734/1660 1662/1735/1662 1657/1726/1657 f 1649/1727/1649 1676/1740/1676 1641/1705/1641 f 1667/1712/1667 1677/1742/1677 1640/1711/1640 f 1670/1594/1670 1555/1613/1555 1545/1608/1545 f 1670/1594/1670 1535/1579/1535 1555/1613/1555 f 1555/1613/1555 1535/1579/1535 1559/1582/1559 f 1505/3039/1505 1544/1746/1544 1672/1617/1672 f 1622/1692/1622 1675/1722/1675 1674/3040/1674 f 1641/1705/1641 1676/1740/1676 1665/1706/1665 f 1640/1711/1640 1677/1742/1677 1663/1729/1663 f 1661/1736/1661 1676/1740/1676 1649/1727/1649 f 1677/1742/1677 1661/1738/1661 1663/1729/1663 f 1678/1749/1678 1654/1714/1654 1658/1715/1658 f 1653/1721/1653 1682/3041/1682 1715/3042/1715 f 1675/1722/1675 1653/1721/1653 1715/3042/1715 f 1690/1764/1690 1691/1763/1691 1692/1768/1692 f 1694/1767/1694 1695/1766/1695 1698/3043/1698 f 1690/1764/1690 1692/1768/1692 1696/1769/1696 f 1692/1768/1692 1691/1763/1691 1693/1765/1693 f 1697/1770/1697 1694/1767/1694 1698/3043/1698 f 1688/1762/1688 1699/1771/1699 1686/1760/1686 f 1687/1759/1687 1703/1776/1703 1689/1761/1689 f 1689/1761/1689 1703/1776/1703 1691/1763/1691 f 1699/1771/1699 1684/1756/1684 1686/1760/1686 f 1704/1775/1704 1714/1777/1714 1703/1776/1703 f 1702/1774/1702 1709/3044/1709 1708/1783/1708 f 1709/3045/1709 1701/1778/1701 1708/1787/1708 f 1709/3045/1709 1706/1779/1706 1701/1778/1701 f 1706/1782/1706 1709/3044/1709 1702/1774/1702 f 1702/1774/1702 1710/1785/1710 1693/1765/1693 f 1697/1770/1697 1711/1788/1711 1696/1769/1696 f 1698/3043/1698 1695/1766/1695 1712/1784/1712 f 1712/1786/1712 1697/1770/1697 1698/3043/1698 f 1693/1765/1693 1710/1785/1710 1695/1766/1695 f 1696/1769/1696 1711/1788/1711 1701/1778/1701 f 1708/1783/1708 1710/1785/1710 1702/1774/1702 f 1711/1788/1711 1708/1787/1708 1701/1778/1701 f 1704/1775/1704 1715/1820/1715 1714/1777/1714 f 1675/1758/1675 1704/1775/1704 1685/1755/1685 f 1704/1775/1704 1675/1758/1675 1715/1820/1715 f 1674/3040/1674 1716/1792/1716 1625/1791/1625 f 1622/1692/1622 1674/3040/1674 1625/1791/1625 f 1717/1793/1717 1718/1687/1718 1673/1747/1673 f 1682/1800/1682 1726/1799/1726 1715/3046/1715 f 1680/1724/1680 1763/1728/1763 1681/1753/1681 f 1724/1806/1724 1718/1687/1718 1717/1793/1717 f 1727/1807/1727 1720/1796/1720 1724/1806/1724 f 1716/1792/1716 1725/1804/1725 1717/1793/1717 f 1724/1806/1724 1720/1796/1720 1718/1687/1718 f 1628/1684/1628 1652/1718/1652 1630/1691/1630 f 1765/3047/1765 1764/1813/1764 1722/1816/1722 f 1731/1815/1731 1728/1810/1728 1729/1812/1729 f 1728/1810/1728 1731/1815/1731 1730/1814/1730 f 1699/1771/1699 1725/1808/1725 1716/1794/1716 f 1732/1817/1732 1728/1810/1728 1730/1814/1730 f 1599/1666/1599 1733/1824/1733 1601/1662/1601 f 1739/1831/1739 1741/1836/1741 1740/1832/1740 f 1743/1833/1743 1745/3048/1745 1744/1834/1744 f 1739/1831/1739 1746/1837/1746 1741/1836/1741 f 1741/1836/1741 1742/1835/1742 1740/1832/1740 f 1747/1838/1747 1745/3048/1745 1743/1833/1743 f 1737/1829/1737 1736/1827/1736 1748/1839/1748 f 1735/1828/1735 1738/1830/1738 1752/1843/1752 f 1738/1830/1738 1740/1832/1740 1752/1843/1752 f 1750/1841/1750 1757/1850/1757 1758/3049/1758 f 1758/3050/1758 1757/1854/1757 1755/1845/1755 f 1758/3050/1758 1755/1845/1755 1754/1847/1754 f 1754/1848/1754 1750/1841/1750 1758/3049/1758 f 1750/1841/1750 1742/1835/1742 1759/1851/1759 f 1747/1838/1747 1746/1837/1746 1760/1853/1760 f 1744/1834/1744 1745/3048/1745 1761/1852/1761 f 1761/1855/1761 1745/3048/1745 1747/1838/1747 f 1742/1835/1742 1744/1834/1744 1759/1851/1759 f 1746/1837/1746 1755/1845/1755 1760/1853/1760 f 1757/1850/1757 1750/1841/1750 1759/1851/1759 f 1760/1853/1760 1755/1845/1755 1757/1854/1757 f 1752/1843/1752 1753/1844/1753 1763/1861/1763 f 1734/1825/1734 1735/1828/1735 1752/1843/1752 f 1752/1843/1752 1763/1861/1763 1734/1825/1734 f 1736/1827/1736 1730/3051/1730 1748/1839/1748 f 1748/1839/1748 1730/3051/1730 1764/1858/1764 f 1736/1827/1736 1732/1826/1732 1730/3051/1730 f 1763/3052/1763 1766/3053/1766 1681/3054/1681 f 1766/3053/1766 1764/1813/1764 1765/3047/1765 f 1681/3054/1681 1766/3053/1766 1765/3047/1765 f 1386/1863/1386 1767/1862/1767 1768/1864/1768 f 1518/1564/1518 1459/3007/1459 1767/1862/1767 f 1518/1564/1518 1767/1862/1767 1519/1565/1519 f 1767/1862/1767 1459/3007/1459 1768/1864/1768 f 1867/3055/1867 1454/3006/1454 1843/1964/1843 f 1769/1865/1769 1771/3056/1771 1387/1866/1387 f 1771/3056/1771 1769/1865/1769 1457/1868/1457 f 1788/1899/1788 1789/3057/1789 1787/1900/1787 f 1789/3057/1789 1792/1926/1792 1791/1901/1791 f 1789/3057/1789 1791/1901/1791 1787/1900/1787 f 1792/1926/1792 1796/3058/1796 1791/1901/1791 f 1791/1901/1791 1793/1903/1793 1790/1902/1790 f 1791/1901/1791 1796/3058/1796 1793/1903/1793 f 1793/1903/1793 1796/3058/1796 1826/1905/1826 f 1806/1897/1806 1798/1907/1798 1799/1910/1799 f 1798/1907/1798 1806/1897/1806 1780/1890/1780 f 1780/1890/1780 1802/1911/1802 1798/1907/1798 f 1805/1917/1805 493/1914/493 1804/1915/1804 f 1506/1553/1506 1525/1556/1525 1393/1584/1393 f 1786/1898/1786 1806/1897/1806 1807/1919/1807 f 1806/1897/1806 1808/3059/1808 1809/1927/1809 f 1807/1919/1807 1809/1927/1809 1811/1920/1811 f 1786/1898/1786 1813/1921/1813 1788/1899/1788 f 1788/1899/1788 1813/1921/1813 1789/3057/1789 f 1789/3057/1789 1813/1921/1813 1792/1926/1792 f 1792/1926/1792 1813/1921/1813 1812/3060/1812 f 1792/1926/1792 1812/3060/1812 1810/1925/1810 f 1812/3060/1812 1813/1921/1813 1811/1920/1811 f 1812/3060/1812 1820/3061/1820 1814/3062/1814 f 1812/3060/1812 1814/3062/1814 1810/1925/1810 f 1814/3062/1814 1815/1922/1815 1810/1925/1810 f 1814/3062/1814 1818/1931/1818 1815/1922/1815 f 1818/1931/1818 1814/3062/1814 1820/3061/1820 f 1815/1922/1815 1818/1931/1818 1817/1923/1817 f 1792/1926/1792 1826/1905/1826 1796/3058/1796 f 1811/1920/1811 1819/1930/1819 1812/3060/1812 f 1812/3060/1812 1819/1930/1819 1820/3061/1820 f 1818/1931/1818 1820/3061/1820 1819/1930/1819 f 1821/1929/1821 1833/1928/1833 513/1933/513 f 1808/3059/1808 1833/1928/1833 1809/1927/1809 f 1806/1897/1806 1809/1927/1809 1807/1919/1807 f 1823/3063/1823 1826/1905/1826 1824/3064/1824 f 1824/3064/1824 1826/1905/1826 1816/1924/1816 f 1824/3064/1824 1825/3065/1825 1823/3063/1823 f 1826/1905/1826 1823/3063/1823 1822/1932/1822 f 1797/1906/1797 1826/1905/1826 1822/1932/1822 f 1822/1932/1822 1834/1947/1834 1508/1918/1508 f 1508/1554/1508 1834/3066/1834 1850/1954/1850 f 1816/1924/1816 1827/1935/1827 1824/3064/1824 f 1827/1935/1827 1816/1924/1816 1817/1923/1817 f 1824/3064/1824 1827/1935/1827 1825/3065/1825 f 1827/1935/1827 1817/1923/1817 1818/1931/1818 f 1825/3065/1825 1838/1938/1838 1823/3063/1823 f 1838/1938/1838 1825/3065/1825 1827/1935/1827 f 526/1942/526 1784/1894/1784 473/1895/473 f 532/3067/532 1828/3068/1828 523/1940/523 f 523/1940/523 1828/3068/1828 1781/1892/1781 f 534/3069/534 1830/3070/1830 1828/3068/1828 f 1830/3070/1830 1831/1943/1831 1829/1889/1829 f 1828/3068/1828 1829/1889/1829 1781/1892/1781 f 1830/3070/1830 1832/1944/1832 1831/1943/1831 f 530/3071/530 494/1913/494 1803/1912/1803 f 534/3069/534 1828/3068/1828 532/3067/532 f 1803/1912/1803 1832/1944/1832 530/3071/530 f 1832/1944/1832 1830/3070/1830 530/3071/530 f 1829/1889/1829 1775/1880/1775 1781/1892/1781 f 1830/3070/1830 534/3069/534 530/3071/530 f 1780/1890/1780 1831/1943/1831 1802/1911/1802 f 1831/1943/1831 1780/1890/1780 1829/1889/1829 f 1829/1889/1829 1828/3068/1828 1830/3070/1830 f 535/3072/535 1779/1888/1779 467/1887/467 f 1779/1888/1779 535/3072/535 473/1895/473 f 1804/1915/1804 493/1914/493 495/1916/495 f 1806/1897/1806 536/3073/536 1808/3059/1808 f 1808/3059/1808 536/3073/536 1833/1928/1833 f 513/1933/513 1833/1928/1833 536/3073/536 f 495/1916/495 536/3073/536 1806/1897/1806 f 1823/3063/1823 1837/1945/1837 1822/1932/1822 f 1837/1945/1837 1823/3063/1823 1838/1938/1838 f 1837/1945/1837 1838/1938/1838 1839/1948/1839 f 1839/1948/1839 1840/3074/1840 1836/1949/1836 f 1839/1948/1839 1841/1951/1841 1840/3074/1840 f 1838/1938/1838 1841/1951/1841 1839/1948/1839 f 1387/1866/1387 1771/3056/1771 1403/3075/1403 f 1844/3076/1844 1523/1558/1523 1772/1952/1772 f 1843/1964/1843 1454/3006/1454 1770/1961/1770 f 1454/3006/1454 1868/3077/1868 1770/1961/1770 f 1454/3006/1454 1523/1558/1523 1868/3077/1868 f 1842/3078/1842 1523/1558/1523 1844/3076/1844 f 1842/3078/1842 1866/3079/1866 1846/3080/1846 f 1844/3076/1844 1845/3081/1845 1866/3079/1866 f 1845/3081/1845 1844/3076/1844 1772/1952/1772 f 1866/3079/1866 1842/3078/1842 1844/3076/1844 f 1848/1957/1848 1852/1955/1852 1850/1954/1850 f 1847/1953/1847 1851/1956/1851 1849/3082/1849 f 1849/3082/1849 1851/1956/1851 1864/3083/1864 f 1851/1956/1851 1852/1955/1852 1862/3084/1862 f 1852/1955/1852 1848/1957/1848 1862/3084/1862 f 1855/3085/1855 1854/3086/1854 1858/3087/1858 f 1850/1954/1850 1853/3088/1853 1848/1957/1848 f 1858/3087/1858 1854/3086/1854 1835/1946/1835 f 1835/1946/1835 1854/3086/1854 1834/1947/1834 f 1854/3086/1854 1855/3085/1855 1834/1947/1834 f 1855/3089/1855 1856/1958/1856 1853/3088/1853 f 1856/1958/1856 1848/1957/1848 1853/3088/1853 f 1834/3066/1834 1855/3089/1855 1853/3088/1853 f 1853/3088/1853 1850/1954/1850 1834/3066/1834 f 1855/3085/1855 1858/3087/1858 1861/3090/1861 f 1865/1959/1865 1859/3091/1859 1860/3092/1860 f 1857/1960/1857 1865/1959/1865 1860/3092/1860 f 1855/3085/1855 1861/3090/1861 1859/1996/1859 f 1859/3091/1859 1856/1958/1856 1855/3089/1855 f 1848/1957/1848 1857/1960/1857 1863/3093/1863 f 1857/1960/1857 1849/3082/1849 1863/3093/1863 f 1848/1957/1848 1863/3093/1863 1862/3084/1862 f 1862/3084/1862 1864/3083/1864 1851/1956/1851 f 1849/3082/1849 1864/3083/1864 1863/3093/1863 f 1864/3083/1864 1862/3084/1862 1863/3093/1863 f 1859/3091/1859 1865/1959/1865 1856/1958/1856 f 1849/3082/1849 1772/1952/1772 1847/1953/1847 f 1772/1952/1772 1874/3094/1874 1845/3081/1845 f 1845/3081/1845 1874/3094/1874 1866/3079/1866 f 1874/3094/1874 1772/1952/1772 1849/3082/1849 f 1874/3094/1874 1849/3082/1849 1857/1960/1857 f 1866/3079/1866 1869/1962/1869 1846/3080/1846 f 1846/3080/1846 1869/1962/1869 1770/1961/1770 f 1454/3006/1454 1867/3055/1867 1457/1868/1457 f 1770/1961/1770 1868/3077/1868 1846/3080/1846 f 1868/3077/1868 1842/3078/1842 1846/3080/1846 f 1868/3077/1868 1523/1558/1523 1842/3078/1842 f 1457/1868/1457 1867/3055/1867 1771/3056/1771 f 1843/1964/1843 1870/1963/1870 1867/3055/1867 f 1771/3056/1771 1867/3055/1867 1403/3075/1403 f 1874/3094/1874 1869/1962/1869 1866/3079/1866 f 1874/1978/1874 1871/1966/1871 1869/1970/1869 f 1871/1966/1871 1874/1978/1874 2221/1977/2221 f 1872/1967/1872 1876/3095/1876 1873/2003/1873 f 1871/1966/1871 1875/2341/1875 1872/1967/1872 f 1857/3096/1857 1877/2000/1877 1874/3097/1874 f 1877/2000/1877 1857/3096/1857 1860/1997/1860 f 1877/1979/1877 2223/1983/2223 2222/1980/2222 f 1876/3095/1876 1880/2218/1880 2125/2217/2125 f 2224/3098/2224 1878/2342/1878 1888/3099/1888 f 1878/2342/1878 1881/3100/1881 1888/3099/1888 f 1876/3095/1876 2224/3098/2224 1880/2218/1880 f 1876/3095/1876 1872/1967/1872 1875/2341/1875 f 1897/2343/1897 1886/1984/1886 1902/3101/1902 f 1886/1984/1886 1887/1985/1887 1883/3102/1883 f 1880/2218/1880 1888/3099/1888 1882/2215/1882 f 1888/3099/1888 1889/3103/1889 1882/2215/1882 f 1881/3100/1881 1889/3103/1889 1888/3099/1888 f 1881/3100/1881 1878/2342/1878 1897/2343/1897 f 1886/1984/1886 1897/2343/1897 2223/1983/2223 f 1883/3104/1883 1898/1987/1898 1900/3105/1900 f 1902/3101/1902 1900/3106/1900 1897/2343/1897 f 1884/1999/1884 1901/1986/1901 1885/1989/1885 f 1887/1988/1887 1898/1987/1898 1883/3104/1883 f 1893/1994/1893 1892/1991/1892 625/1990/625 f 1890/1992/1890 1836/1949/1836 1891/1993/1891 f 1891/1993/1891 1840/3074/1840 1841/1951/1841 f 1891/1993/1891 1836/1949/1836 1840/3074/1840 f 1890/1992/1890 1835/1946/1835 1836/1949/1836 f 1835/1946/1835 1890/1992/1890 1858/3087/1858 f 1858/3087/1858 1890/1992/1890 1861/3090/1861 f 1841/1951/1841 1892/1991/1892 1891/1993/1891 f 1890/1992/1890 1859/1996/1859 1861/3090/1861 f 1870/1963/1870 1403/3075/1403 1867/3055/1867 f 2164/2522/2164 1873/2003/1873 1879/3107/1879 f 1881/3100/1881 1895/3108/1895 1889/3103/1889 f 1889/3103/1889 1895/3108/1895 1903/3109/1903 f 1889/3103/1889 1903/3109/1903 1882/2215/1882 f 1881/3100/1881 1897/2343/1897 1894/3110/1894 f 1894/3110/1894 1897/2343/1897 1900/3106/1900 f 1881/3100/1881 1896/3111/1896 1895/3108/1895 f 1894/3112/1894 1900/3105/1900 1899/2007/1899 f 1899/2007/1899 1900/3105/1900 1898/1987/1898 f 623/3113/623 646/2005/646 1898/1987/1898 f 1898/1987/1898 1901/1986/1901 623/3113/623 f 625/3114/625 1884/1999/1884 1893/1998/1893 f 1901/1986/1901 625/3114/625 623/3113/623 f 1884/1999/1884 625/3114/625 1901/1986/1901 f 1900/3106/1900 1902/3101/1902 1883/3102/1883 f 1902/3101/1902 1886/1984/1886 1883/3102/1883 f 1881/3100/1881 1894/3110/1894 1896/3111/1896 f 1899/3115/1899 1905/2021/1905 1894/3116/1894 f 1899/3115/1899 1925/2018/1925 1905/2021/1905 f 1905/2015/1905 1908/2022/1908 1906/2016/1906 f 1917/2029/1917 1912/2028/1912 1911/3117/1911 f 1913/2030/1913 1917/2031/1917 1911/3117/1911 f 1913/2030/1913 1911/3117/1911 1921/2037/1921 f 1921/2037/1921 1911/3117/1911 1912/2028/1912 f 1923/2038/1923 1921/2037/1921 1922/2036/1922 f 1920/2034/1920 1926/2039/1926 1918/2035/1918 f 1925/2018/1925 1899/3115/1899 1928/2042/1928 f 1924/2032/1924 1929/2040/1929 1926/2039/1926 f 1924/2032/1924 1930/2043/1930 1929/2040/1929 f 1978/3118/1978 2004/3119/2004 1979/3120/1979 f 1932/2046/1932 1936/2083/1936 1931/2047/1931 f 1931/2047/1931 1936/2083/1936 1959/2075/1959 f 1942/2060/1942 1948/2059/1948 1952/2069/1952 f 1954/3121/1954 1953/3122/1953 1951/3123/1951 f 1954/3121/1954 1934/2241/1934 1955/3124/1955 f 692/3125/692 695/3126/695 1945/3127/1945 f 1933/2050/1933 1946/2063/1946 1949/2054/1949 f 1949/2054/1949 1946/2063/1946 1940/2065/1940 f 1946/2063/1946 692/2123/692 1945/2064/1945 f 1940/2065/1940 1950/2066/1950 1943/2067/1943 f 1950/2066/1950 1952/2069/1952 1943/2067/1943 f 1952/2069/1952 1948/2059/1948 1943/2067/1943 f 1953/2068/1953 1941/2058/1941 1952/2069/1952 f 1955/3124/1955 1953/3122/1953 1954/3121/1954 f 1945/3127/1945 1958/3128/1958 1944/3129/1944 f 1953/2068/1953 1955/2070/1955 1941/2058/1941 f 1957/2074/1957 1945/3127/1945 695/3126/695 f 1944/3129/1944 1958/3128/1958 1986/2072/1986 f 1945/3127/1945 1957/2074/1957 1985/2073/1985 f 1941/2058/1941 1960/2057/1960 1942/2060/1942 f 1969/2086/1969 1963/2079/1963 1965/2078/1965 f 1967/2088/1967 1961/2077/1961 1962/2076/1962 f 1942/2060/1942 1952/2069/1952 1941/2058/1941 f 1967/2085/1967 1973/2093/1973 1969/2086/1969 f 1973/2093/1973 1977/3130/1977 1974/2094/1974 f 1974/2094/1974 1977/3130/1977 1975/2095/1975 f 1975/2095/1975 1977/3130/1977 1976/2091/1976 f 1976/2091/1976 1977/3130/1977 1973/2092/1973 f 1979/2120/1979 1929/2119/1929 1930/3131/1930 f 1928/2102/1928 1980/2101/1980 1930/2107/1930 f 1979/2108/1979 1981/2104/1981 1978/2103/1978 f 1982/2110/1982 736/2109/736 735/3132/735 f 738/2112/738 1983/2111/1983 735/3132/735 f 1983/2111/1983 1982/2110/1982 735/3132/735 f 1876/3095/1876 1879/3107/1879 1873/2003/1873 f 1408/3133/1408 1432/3134/1432 1984/3135/1984 f 1945/3127/1945 1985/2073/1985 1958/3128/1958 f 1985/2073/1985 1986/2072/1986 1958/3128/1958 f 1944/3129/1944 1986/2072/1986 1953/3122/1953 f 1944/2061/1944 1953/2068/1953 1947/2062/1947 f 1953/3122/1953 1986/2072/1986 1951/3123/1951 f 1951/3123/1951 1986/2072/1986 1956/2071/1956 f 695/3126/695 751/3136/751 1957/2074/1957 f 751/3136/751 754/2131/754 1988/3137/1988 f 1988/3137/1988 754/2131/754 1989/3138/1989 f 2019/3139/2019 2018/2130/2018 2009/2129/2009 f 751/3136/751 1988/3137/1988 1987/2116/1987 f 1988/3137/1988 1991/2127/1991 1987/2116/1987 f 1987/2116/1987 1991/2127/1991 1990/2113/1990 f 1987/2116/1987 1992/2115/1992 1956/2071/1956 f 1991/2127/1991 1993/2117/1993 1990/2113/1990 f 1989/3138/1989 1996/2124/1996 1988/3137/1988 f 1988/3137/1988 1996/2124/1996 1991/2127/1991 f 1996/2124/1996 1997/3140/1997 2007/2144/2007 f 1992/2115/1992 1998/3141/1998 1956/2071/1956 f 1998/3141/1998 1951/3123/1951 1956/2071/1956 f 1951/3123/1951 1999/3142/1999 1954/3121/1954 f 1998/3141/1998 1999/3142/1999 1951/3123/1951 f 1954/3121/1954 1999/3142/1999 1998/3141/1998 f 1998/3141/1998 1992/2115/1992 1994/2114/1994 f 2004/3119/2004 2148/3143/2148 1979/3120/1979 f 2152/2256/2152 2001/2244/2001 2002/2247/2002 f 2000/2045/2000 2004/3119/2004 1932/2046/1932 f 2004/2097/2004 1933/2050/1933 1932/2053/1932 f 692/2123/692 2005/2096/2005 700/3144/700 f 2005/2096/2005 1978/2098/1978 700/3144/700 f 1957/2074/1957 751/3136/751 1956/2071/1956 f 1956/2071/1956 751/3136/751 1987/2116/1987 f 1996/2124/1996 2007/2144/2007 2030/2147/2030 f 2008/2125/2008 1995/2118/1995 2006/2126/2006 f 1996/2124/1996 2030/2147/2030 2008/2125/2008 f 2009/2129/2009 777/2128/777 2012/3145/2012 f 1997/3140/1997 2018/2130/2018 2019/3139/2019 f 2019/3139/2019 2010/3146/2010 1997/3140/1997 f 1997/3140/1997 2010/3146/2010 2007/2144/2007 f 1997/3140/1997 1996/2124/1996 1989/3138/1989 f 2019/3139/2019 2036/3147/2036 2010/3146/2010 f 2036/3147/2036 2019/3139/2019 2009/2129/2009 f 2035/3148/2035 2036/3147/2036 2012/3145/2012 f 2012/3145/2012 2036/3147/2036 2009/2129/2009 f 2014/2135/2014 2012/3145/2012 756/2132/756 f 2012/3145/2012 777/2128/777 756/2132/756 f 2014/2135/2014 2015/2134/2015 2034/3149/2034 f 2016/3150/2016 2013/2143/2013 2014/2135/2014 f 2016/3150/2016 2033/3151/2033 2013/2143/2013 f 754/2131/754 2018/2130/2018 1989/3138/1989 f 2018/2130/2018 1997/3140/1997 1989/3138/1989 f 1994/2114/1994 2020/3152/2020 2026/3153/2026 f 1995/2118/1995 2021/3154/2021 2020/3152/2020 f 2008/2125/2008 2029/3155/2029 1995/2118/1995 f 2021/3154/2021 2022/2136/2022 2020/3152/2020 f 1994/2114/1994 2023/3156/2023 1998/3141/1998 f 2020/3152/2020 1994/2114/1994 1995/2118/1995 f 1994/2114/1994 2026/3153/2026 2023/3156/2023 f 1995/2118/1995 2029/3155/2029 2021/3154/2021 f 2029/3155/2029 2008/2125/2008 2030/2147/2030 f 2021/3154/2021 2029/3155/2029 2024/3157/2024 f 2021/3154/2021 2024/3157/2024 2022/2136/2022 f 2026/3153/2026 2020/3152/2020 2027/3158/2027 f 2026/3153/2026 2027/3158/2027 2023/3156/2023 f 2027/3158/2027 2025/2139/2025 2023/3156/2023 f 2027/3158/2027 2028/3159/2028 2025/2139/2025 f 2028/3159/2028 2027/3158/2027 2020/3152/2020 f 2025/2139/2025 2028/3159/2028 2022/2136/2022 f 2028/3159/2028 2020/3152/2020 2022/2136/2022 f 2023/3156/2023 2055/3160/2055 1998/3141/1998 f 2029/3155/2029 2030/2147/2030 2024/3157/2024 f 2033/3151/2033 2016/3150/2016 2034/3149/2034 f 2034/3149/2034 2015/2134/2015 2033/3151/2033 f 2035/3148/2035 2037/2141/2037 2036/3147/2036 f 2012/3145/2012 2013/2143/2013 2011/2142/2011 f 2035/3148/2035 2012/3145/2012 2011/2142/2011 f 2012/3145/2012 2014/2135/2014 2013/2143/2013 f 2011/2142/2011 2037/2141/2037 2035/3148/2035 f 2037/2141/2037 2010/3146/2010 2036/3147/2036 f 2031/2137/2031 2022/2136/2022 2024/3157/2024 f 2030/2147/2030 2041/2146/2041 2024/3157/2024 f 2024/3157/2024 2041/2146/2041 2031/2137/2031 f 2040/2145/2040 2010/3146/2010 2037/2141/2037 f 2042/2148/2042 2424/2567/2424 1406/2568/1406 f 1408/3133/1408 2044/3161/2044 2042/2148/2042 f 2039/2150/2039 2044/3161/2044 2043/2152/2043 f 2044/3161/2044 2045/2346/2045 2043/2152/2043 f 2044/3161/2044 2046/3162/2046 2045/2346/2045 f 1984/3135/1984 2044/3161/2044 1408/3133/1408 f 1984/3135/1984 2047/3163/2047 2044/3161/2044 f 2044/3161/2044 2047/3163/2047 2046/3162/2046 f 2047/3163/2047 1984/3135/1984 1432/3134/1432 f 2049/2153/2049 2050/3164/2050 2048/2151/2048 f 2050/3164/2050 2031/2137/2031 2048/2151/2048 f 2031/2137/2031 2050/3164/2050 2032/2138/2032 f 2051/2156/2051 2050/3164/2050 2049/2153/2049 f 2050/3164/2050 2051/2156/2051 2032/2138/2032 f 1998/3141/1998 2055/3160/2055 1954/3121/1954 f 1954/3121/1954 2055/3160/2055 2052/3165/2052 f 2053/2361/2053 2057/2243/2057 2052/3165/2052 f 2057/2243/2057 2053/2361/2053 2054/2175/2054 f 2062/3166/2062 2065/2362/2065 2052/3165/2052 f 2054/2175/2054 2142/2214/2142 2057/2243/2057 f 2052/3165/2052 2057/2243/2057 2056/2242/2056 f 2056/2242/2056 1954/3121/1954 2052/3165/2052 f 2055/3160/2055 2058/2155/2058 2059/2154/2059 f 2058/2155/2058 2025/2139/2025 2032/2138/2032 f 2023/3156/2023 2058/2155/2058 2055/3160/2055 f 2058/2155/2058 2023/3156/2023 2025/2139/2025 f 2059/2154/2059 2060/3167/2060 2055/3160/2055 f 2059/2154/2059 2066/2349/2066 2060/3167/2060 f 2060/3167/2060 2066/2349/2066 2062/3166/2062 f 2066/2349/2066 2063/3168/2063 2062/3166/2062 f 2061/2350/2061 2064/2363/2064 2063/3168/2063 f 2064/2363/2064 2065/2362/2065 2063/3168/2063 f 2052/3165/2052 2065/2362/2065 2053/2361/2053 f 2065/2362/2065 2062/3166/2062 2063/3168/2063 f 2063/3168/2063 2066/2349/2066 2061/2350/2061 f 2060/3167/2060 2062/3166/2062 2055/3160/2055 f 2062/3166/2062 2052/3165/2052 2055/3160/2055 f 2053/2361/2053 2092/2174/2092 2054/2175/2054 f 2070/2159/2070 2072/2177/2072 2067/2160/2067 f 2053/2361/2053 2252/3169/2252 2092/2174/2092 f 2094/2353/2094 2093/2178/2093 2073/2176/2073 f 2091/2179/2091 2074/2169/2074 2071/2163/2071 f 2075/2267/2075 2091/2179/2091 2095/3170/2095 f 2091/2179/2091 2075/2267/2075 2074/2169/2074 f 2080/2167/2080 2081/2168/2081 2101/2173/2101 f 2078/2164/2078 2081/2168/2081 2080/2167/2080 f 2087/3171/2087 2102/3172/2102 2084/2183/2084 f 2086/2180/2086 2101/2173/2101 2085/2184/2085 f 2088/2166/2088 2154/3173/2154 2090/2211/2090 f 2088/2166/2088 2090/2211/2090 2077/2162/2077 f 2067/2160/2067 2072/2177/2072 2071/2163/2071 f 2072/2177/2072 2091/2179/2091 2071/2163/2071 f 2095/3170/2095 2091/2179/2091 2093/2178/2093 f 2155/2212/2155 2069/2158/2069 2068/2157/2068 f 2069/2158/2069 2155/2212/2155 2141/2213/2141 f 2093/2178/2093 2094/2353/2094 2047/3163/2047 f 2094/2353/2094 2046/3162/2046 2047/3163/2047 f 1432/3134/1432 1433/3174/1433 2047/3163/2047 f 1424/3175/1424 1433/3174/1433 1432/3134/1432 f 1433/3174/1433 2160/2260/2160 2095/3170/2095 f 2084/2183/2084 2111/2182/2111 2087/3171/2087 f 2087/3171/2087 2111/2182/2111 2110/2196/2110 f 2101/2173/2101 2097/2186/2097 2100/2289/2100 f 2100/2289/2100 2511/2185/2511 2085/2184/2085 f 2085/2184/2085 2101/2173/2101 2100/2289/2100 f 2101/2173/2101 2086/2180/2086 2080/2167/2080 f 2084/2183/2084 2102/3172/2102 2079/2165/2079 f 2102/3172/2102 2089/2207/2089 2079/2165/2079 f 2174/2197/2174 2103/2210/2103 2096/2189/2096 f 2174/2197/2174 2177/2298/2177 2103/2210/2103 f 2105/2190/2105 2096/2189/2096 2103/2210/2103 f 2110/2196/2110 2113/2202/2113 2087/3171/2087 f 2113/2202/2113 2110/2196/2110 2109/2188/2109 f 2174/2197/2174 2112/2181/2112 2511/2185/2511 f 2087/3171/2087 2113/2202/2113 2115/2198/2115 f 2102/3172/2102 2115/2198/2115 2114/2201/2114 f 2115/2198/2115 2102/3172/2102 2087/3171/2087 f 2089/2207/2089 2116/2206/2116 2154/3173/2154 f 2124/2204/2124 2089/2207/2089 2102/3172/2102 f 2124/2204/2124 2102/3172/2102 2114/2201/2114 f 2125/2217/2125 2129/2219/2129 2127/3176/2127 f 2126/2224/2126 2131/2223/2131 2128/3177/2128 f 2128/3177/2128 2131/2223/2131 2147/2227/2147 f 2130/2222/2130 1882/2221/1882 1903/3178/1903 f 1903/3178/1903 2134/3179/2134 2130/2222/2130 f 2130/2222/2130 2134/3179/2134 2135/2228/2135 f 2134/3179/2134 1903/3178/1903 2132/3180/2132 f 2132/2230/2132 1903/2012/1903 1904/2011/1904 f 2134/3179/2134 2139/2235/2139 2135/2228/2135 f 2139/2236/2139 2134/2233/2134 2137/2232/2137 f 2147/2227/2147 2140/3181/2140 2128/3177/2128 f 2155/2212/2155 2144/2237/2144 2141/2213/2141 f 2143/2258/2143 2140/2248/2140 2001/2244/2001 f 2056/2242/2056 1934/2241/1934 1954/3121/1954 f 2143/2238/2143 1934/2241/1934 2142/2214/2142 f 2002/2247/2002 2146/3182/2146 2003/3183/2003 f 2003/3183/2003 2151/2250/2151 2149/2122/2149 f 2146/3182/2146 2151/2250/2151 2003/3183/2003 f 2000/2257/2000 2150/2121/2150 2148/3184/2148 f 2148/3143/2148 2004/3119/2004 2000/2045/2000 f 2149/2122/2149 2150/2121/2150 2153/3185/2153 f 2150/2121/2150 2000/2257/2000 2153/3185/2153 f 2151/2253/2151 2146/2246/2146 2145/2245/2145 f 2150/2121/2150 1979/2120/1979 2148/3184/2148 f 2003/3183/2003 2153/3185/2153 2002/2247/2002 f 2153/3185/2153 2152/2256/2152 2002/2247/2002 f 2153/3185/2153 2000/2257/2000 2152/2256/2152 f 2149/2122/2149 2153/3185/2153 2003/3183/2003 f 2128/2240/2128 2156/2274/2156 2129/2275/2129 f 2156/2274/2156 2144/2237/2144 2155/2212/2155 f 2156/2274/2156 2128/2240/2128 2144/2237/2144 f 2127/3176/2127 1879/3107/1879 2125/2217/2125 f 2127/3176/2127 2157/3186/2157 1879/3107/1879 f 1879/3107/1879 2157/3186/2157 2164/2522/2164 f 1876/3095/1876 2125/2217/2125 1879/3107/1879 f 1427/3187/1427 2158/1976/2158 1428/2261/1428 f 1426/1973/1426 2158/1976/2158 1427/3187/1427 f 2160/2260/2160 2159/2259/2159 2095/3170/2095 f 2095/3170/2095 2159/2259/2159 2075/2267/2075 f 2160/2260/2160 1433/3174/1433 1428/2261/1428 f 2042/2148/2042 1406/2568/1406 1408/3133/1408 f 2083/2171/2083 2162/2263/2162 2181/2264/2181 f 2165/2266/2165 2075/2267/2075 2159/2259/2159 f 2082/2170/2082 2165/2266/2165 2163/2262/2163 f 2164/1975/2164 2157/3188/2157 2165/2266/2165 f 2161/2265/2161 2181/2264/2181 2183/2293/2183 f 2116/2206/2116 2167/2272/2167 2154/3173/2154 f 2154/3173/2154 2167/2272/2167 2090/2211/2090 f 2161/2265/2161 2098/2187/2098 2099/2172/2099 f 2117/2203/2117 2171/3189/2171 2168/2276/2168 f 2119/2199/2119 2168/2276/2168 2118/2200/2118 f 2117/2203/2117 2168/2276/2168 2119/2199/2119 f 2122/2209/2122 2171/3189/2171 2117/2203/2117 f 2121/2208/2121 2170/2278/2170 2122/2209/2122 f 2122/2209/2122 2170/2278/2170 2171/3189/2171 f 2174/2197/2174 2511/2185/2511 2510/2697/2510 f 2510/2697/2510 2177/2298/2177 2174/2197/2174 f 2173/2283/2173 2168/2294/2168 2171/2284/2171 f 2180/2288/2180 2179/2291/2179 2173/2283/2173 f 2172/2281/2172 2180/2288/2180 2173/2283/2173 f 2183/2293/2183 2184/2292/2184 2161/2265/2161 f 2184/2292/2184 2098/2187/2098 2161/2265/2161 f 2163/2262/2163 2157/3188/2157 2127/2296/2127 f 2157/3188/2157 2163/2262/2163 2165/2266/2165 f 2163/2262/2163 2127/2296/2127 2162/2263/2162 f 2103/2210/2103 2185/2300/2185 2108/2194/2108 f 2185/2300/2185 2190/2305/2190 2189/2302/2189 f 2343/2311/2343 2381/2314/2381 2188/2303/2188 f 2306/2309/2306 2342/2310/2342 2189/2302/2189 f 2193/2313/2193 2305/2308/2305 2190/2305/2190 f 2201/2323/2201 2205/2322/2205 2204/2334/2204 f 2201/2323/2201 2204/2334/2204 2202/2333/2202 f 2204/2334/2204 2205/2322/2205 2203/2330/2203 f 2196/2316/2196 2209/2327/2209 2198/2318/2198 f 2198/2318/2198 2209/2327/2209 2200/2320/2200 f 2197/2319/2197 2256/2365/2256 2195/2317/2195 f 2199/2321/2199 2256/2365/2256 2197/2319/2197 f 2216/2339/2216 2219/3190/2219 2280/2340/2280 f 2216/2339/2216 2220/2280/2220 2219/3190/2219 f 2415/2429/2415 2219/3191/2219 2218/2430/2218 f 2280/2340/2280 2219/3190/2219 2415/2426/2415 f 2219/3191/2219 2217/3192/2217 2218/2430/2218 f 2219/3190/2219 2220/2280/2220 2217/3193/2217 f 1871/1966/1871 2221/1977/2221 1875/2341/1875 f 1878/2342/1878 2224/3098/2224 1875/2341/1875 f 2224/3098/2224 1876/3095/1876 1875/2341/1875 f 2224/3098/2224 1888/3099/1888 1880/2218/1880 f 2225/2345/2225 2228/2344/2228 2226/3194/2226 f 2228/2344/2228 2045/2346/2045 2046/3162/2046 f 2043/2152/2043 2225/2345/2225 2049/2153/2049 f 2226/3194/2226 2228/2344/2228 2227/2360/2227 f 2228/2344/2228 2046/3162/2046 2227/2360/2227 f 2227/2360/2227 2046/3162/2046 2094/2353/2094 f 2230/3195/2230 2231/2351/2231 2073/2176/2073 f 2232/3196/2232 2233/3197/2233 2239/3198/2239 f 2239/3198/2239 2233/3197/2233 2229/3199/2229 f 2232/3196/2232 2236/3200/2236 2233/3197/2233 f 2233/3197/2233 2236/3200/2236 2234/3201/2234 f 2234/3201/2234 2236/3200/2236 2250/2356/2250 f 2250/2356/2250 2236/3200/2236 2235/2357/2235 f 2236/3200/2236 2232/3196/2232 2237/2347/2237 f 2236/3200/2236 2237/2347/2237 2235/2357/2235 f 2232/3196/2232 2239/3198/2239 2238/2348/2238 f 2232/3196/2232 2238/2348/2238 2237/2347/2237 f 2237/2347/2237 2051/2156/2051 2235/2357/2235 f 2238/2348/2238 2239/3198/2239 2061/2350/2061 f 2229/3199/2229 2240/2364/2240 2239/3198/2239 f 2240/2364/2240 2064/2363/2064 2239/3198/2239 f 2061/2350/2061 2239/3198/2239 2064/2363/2064 f 2251/2358/2251 2248/3202/2248 2247/2359/2247 f 2231/2351/2231 2242/3203/2242 2241/2352/2241 f 2229/3199/2229 2242/3203/2242 2231/2351/2231 f 2231/2351/2231 2230/3195/2230 2229/3199/2229 f 2242/3203/2242 2229/3199/2229 2234/3201/2234 f 2234/3201/2234 2229/3199/2229 2233/3197/2233 f 2242/3203/2242 2234/3201/2234 2241/2352/2241 f 2234/3201/2234 2250/2356/2250 2249/3204/2249 f 2250/2356/2250 2225/2345/2225 2226/3194/2226 f 2250/2356/2250 2243/2355/2243 2225/2345/2225 f 2225/2345/2225 2243/2355/2243 2049/2153/2049 f 2051/2156/2051 2244/2354/2244 2235/2357/2235 f 2244/2354/2244 2246/3205/2246 2245/3206/2245 f 2244/2354/2244 2245/3206/2245 2243/2355/2243 f 2243/2355/2243 2245/3206/2245 2049/2153/2049 f 2245/3206/2245 2246/3205/2246 2049/2153/2049 f 2049/2153/2049 2246/3205/2246 2051/2156/2051 f 2246/3205/2246 2244/2354/2244 2051/2156/2051 f 2247/2359/2247 2226/3194/2226 2227/2360/2227 f 2247/2359/2247 2249/3204/2249 2226/3194/2226 f 2249/3204/2249 2250/2356/2250 2226/3194/2226 f 2251/2358/2251 2094/2353/2094 2241/2352/2241 f 2248/3202/2248 2249/3204/2249 2247/2359/2247 f 2251/2358/2251 2241/2352/2241 2248/3202/2248 f 2241/2352/2241 2234/3201/2234 2248/3202/2248 f 2234/3201/2234 2249/3204/2249 2248/3202/2248 f 2073/2176/2073 2252/3169/2252 2230/3195/2230 f 2229/3199/2229 2252/3169/2252 2240/2364/2240 f 2252/3169/2252 2053/2361/2053 2240/2364/2240 f 2252/3169/2252 2229/3199/2229 2230/3195/2230 f 2073/2176/2073 2092/2174/2092 2252/3169/2252 f 2042/2148/2042 2044/3161/2044 2039/2150/2039 f 2154/3173/2154 2088/2166/2088 2089/2207/2089 f 2089/2207/2089 2088/2166/2088 2079/2165/2079 f 2254/2367/2254 2202/2333/2202 2212/2332/2212 f 2213/2335/2213 2203/2330/2203 2210/2329/2210 f 2254/2367/2254 2262/3207/2262 2260/2372/2260 f 2212/2332/2212 2262/3207/2262 2254/2367/2254 f 2212/2332/2212 2264/2337/2264 2262/3207/2262 f 2263/2338/2263 2213/2335/2213 2261/3208/2261 f 2261/3208/2261 2210/2329/2210 2257/2369/2257 f 2210/2329/2210 2261/3208/2261 2213/2335/2213 f 2215/2336/2215 2268/3209/2268 2264/2337/2264 f 2263/2338/2263 2268/3209/2268 2215/2336/2215 f 2264/2380/2264 2268/3210/2268 2263/2379/2263 f 2275/2394/2275 2276/2393/2276 2277/2401/2277 f 2275/2394/2275 2277/2401/2277 2278/2400/2278 f 2277/2401/2277 2276/2393/2276 2279/2397/2279 f 2272/2389/2272 2281/2395/2281 2274/2391/2274 f 2274/2391/2274 2281/2395/2281 2276/2393/2276 f 2273/2392/2273 2289/2406/2289 2271/2390/2271 f 2275/2394/2275 2289/2406/2289 2273/2392/2273 f 2290/2407/2290 2278/2400/2278 2284/2399/2284 f 2285/2402/2285 2279/2397/2279 2282/2396/2282 f 2290/2407/2290 2294/3211/2294 2292/2412/2292 f 2284/2399/2284 2296/3212/2296 2290/2407/2290 f 2284/2399/2284 2287/2404/2287 2296/3212/2296 f 2288/2405/2288 2285/2402/2285 2295/3213/2295 f 2282/2396/2282 2293/3214/2293 2295/3213/2295 f 2293/3214/2293 2282/2396/2282 2291/2409/2291 f 2282/2396/2282 2295/3213/2295 2285/2402/2285 f 2290/2407/2290 2296/3212/2296 2294/3211/2294 f 2286/2403/2286 2300/3215/2300 2287/2404/2287 f 2288/2405/2288 2300/3215/2300 2286/2403/2286 f 2287/2422/2287 2300/3216/2300 2288/2421/2288 f 2217/3192/2217 2302/2431/2302 2218/2430/2218 f 2313/2441/2313 2314/2440/2314 2315/2450/2315 f 2313/2441/2313 2315/2450/2315 2316/2449/2316 f 2315/2450/2315 2314/2440/2314 2317/2446/2317 f 2308/2434/2308 2319/2443/2319 2310/2436/2310 f 2310/2436/2310 2319/2443/2319 2312/2438/2312 f 2309/2437/2309 2328/2455/2328 2307/2435/2307 f 2311/2439/2311 2328/2455/2328 2309/2437/2309 f 2330/2457/2330 2316/2449/2316 2323/2448/2323 f 2324/2451/2324 2317/2446/2317 2321/2445/2321 f 2330/2457/2330 2337/3217/2337 2335/2462/2335 f 2323/2448/2323 2337/3217/2337 2330/2457/2330 f 2323/2448/2323 2326/2453/2326 2337/3217/2337 f 2327/2454/2327 2324/2451/2324 2336/3218/2336 f 2336/3218/2336 2321/2445/2321 2332/2460/2332 f 2321/2445/2321 2336/3218/2336 2324/2451/2324 f 2325/2452/2325 2341/3219/2341 2326/2453/2326 f 2327/2454/2327 2341/3219/2341 2325/2452/2325 f 2326/2470/2326 2341/3220/2341 2327/2469/2327 f 2318/2442/2318 2255/2368/2255 2340/2386/2340 f 2350/2484/2350 2351/2483/2351 2352/2493/2352 f 2350/2484/2350 2352/2493/2352 2353/2492/2353 f 2352/2493/2352 2351/2483/2351 2354/2489/2354 f 2345/2477/2345 2356/2486/2356 2347/2479/2347 f 2347/2479/2347 2356/2486/2356 2349/2481/2349 f 2362/3221/2362 2360/2491/2360 2359/2490/2359 f 2361/2494/2361 2362/3221/2362 2359/2490/2359 f 2346/2480/2346 2363/2495/2363 2344/2478/2344 f 2348/2482/2348 2363/2495/2363 2346/2480/2346 f 2365/2497/2365 2353/2492/2353 2360/2491/2360 f 2361/2494/2361 2354/2489/2354 2358/2488/2358 f 2372/2508/2372 2362/3222/2362 2371/2507/2371 f 2365/2497/2365 2372/3223/2372 2370/2502/2370 f 2360/2491/2360 2372/3223/2372 2365/2497/2365 f 2360/2491/2360 2362/3221/2362 2372/3223/2372 f 2362/3221/2362 2361/2494/2361 2371/3224/2371 f 2371/3224/2371 2358/2488/2358 2367/2499/2367 f 2358/2488/2358 2371/3224/2371 2361/2494/2361 f 2355/2485/2355 2331/2458/2331 2376/2475/2376 f 2414/2558/2414 2302/2517/2302 2378/2516/2378 f 2220/2280/2220 2379/2279/2379 2217/3193/2217 f 2217/2518/2217 2379/3225/2379 2377/2519/2377 f 2108/2194/2108 2380/2306/2380 2120/2195/2120 f 1479/1530/1479 1534/1575/1534 1482/1577/1482 f 1556/1609/1556 1587/1683/1587 1589/1610/1589 f 1595/3033/1595 1571/1626/1571 1579/1628/1579 f 1563/1619/1563 1505/3039/1505 1672/1617/1672 f 1463/1520/1463 1491/3016/1491 1466/1536/1466 f 1447/1508/1447 1462/1521/1462 1455/1524/1455 f 2093/2178/2093 2047/3163/2047 2095/3170/2095 f 2095/3170/2095 2047/3163/2047 1433/3174/1433 f 2389/2531/2389 2390/2530/2390 2391/2540/2391 f 2389/2531/2389 2391/2540/2391 2392/2539/2392 f 2391/2540/2391 2390/2530/2390 2393/2536/2393 f 2384/2524/2384 2395/2533/2395 2386/2526/2386 f 2386/2526/2386 2395/2533/2395 2388/2528/2388 f 2401/3226/2401 2399/2538/2399 2398/2537/2398 f 2400/2541/2400 2401/3226/2401 2398/2537/2398 f 2385/2527/2385 2402/2542/2402 2383/2525/2383 f 2387/2529/2387 2402/2542/2402 2385/2527/2385 f 2404/2544/2404 2392/2539/2392 2399/2538/2399 f 2400/2541/2400 2393/2536/2393 2397/2535/2397 f 2411/2555/2411 2401/3227/2401 2410/2554/2410 f 2404/2544/2404 2411/3228/2411 2409/2549/2409 f 2399/2538/2399 2411/3228/2411 2404/2544/2404 f 2399/2538/2399 2401/3226/2401 2411/3228/2411 f 2401/3226/2401 2400/2541/2400 2410/3229/2410 f 2410/3229/2410 2397/2535/2397 2406/2546/2406 f 2397/2535/2397 2410/3229/2410 2400/2541/2400 f 2394/2532/2394 2366/2498/2366 2375/2514/2375 f 2405/2545/2405 2192/2307/2192 2382/2315/2382 f 2299/3230/2299 2304/2428/2304 2303/2433/2303 f 2299/3230/2299 2415/2429/2415 2304/2428/2304 f 2270/2325/2270 2191/2304/2191 2186/2299/2186 f 2417/2563/2417 2425/2562/2425 2416/2572/2416 f 2423/2564/2423 2419/2571/2419 2420/2565/2420 f 1406/2568/1406 2424/2567/2424 2418/2566/2418 f 562/2569/562 2420/2565/2420 2419/2571/2419 f 2424/2567/2424 2042/2148/2042 2038/2149/2038 f 2416/2572/2416 2425/2562/2425 2426/2609/2426 f 2416/2572/2416 2426/2609/2426 2421/2573/2421 f 2017/2140/2017 2427/3231/2427 2037/2141/2037 f 2427/3232/2427 2456/2614/2456 2425/3233/2425 f 2431/2611/2431 2427/3232/2427 2017/3234/2017 f 2427/3232/2427 2431/2611/2431 2456/2614/2456 f 2040/2145/2040 2427/3231/2427 2425/2562/2425 f 2427/3231/2427 2040/2145/2040 2037/2141/2037 f 2430/2578/2430 2433/2583/2433 2429/2579/2429 f 2015/3235/2015 2438/3236/2438 2033/3237/2033 f 2443/2600/2443 2451/2595/2451 2442/2594/2442 f 2438/3238/2438 2015/2592/2015 2439/2605/2439 f 2014/2135/2014 2034/3149/2034 2016/3150/2016 f 2440/2604/2440 2443/2600/2443 2445/2598/2445 f 2441/3239/2441 2445/2598/2445 2444/2597/2444 f 2445/2598/2445 2441/3239/2441 2440/2604/2440 f 2015/2592/2015 2451/2595/2451 2439/2605/2439 f 2429/2579/2429 2453/2607/2453 2483/3240/2483 f 2452/3241/2452 2453/2607/2453 2448/2603/2448 f 2453/2607/2453 2449/2602/2449 2448/2603/2448 f 2453/2607/2453 2450/2601/2450 2449/2602/2449 f 2453/2607/2453 2454/2606/2454 2450/2601/2450 f 2454/2606/2454 2447/2599/2447 2450/2601/2450 f 2454/2606/2454 2446/2596/2446 2447/2599/2447 f 2437/2585/2437 2455/3242/2455 2436/2586/2436 f 2441/2590/2441 2455/3242/2455 2437/2585/2437 f 2444/2597/2444 2455/3242/2455 2441/3239/2441 f 2446/2596/2446 2455/3242/2455 2444/2597/2444 f 2436/2586/2436 2455/3242/2455 2446/2596/2446 f 1331/2577/1331 2448/2655/2448 2428/2574/2428 f 2429/2579/2429 2483/3240/2483 2432/2580/2432 f 2483/3240/2483 2453/2607/2453 2452/3241/2452 f 2457/3243/2457 2512/2619/2512 2456/3244/2456 f 63/3245/63 2458/2620/2458 2457/3243/2457 f 2514/2621/2514 2464/2624/2464 2463/2623/2463 f 2458/2620/2458 62/3246/62 2468/2629/2468 f 2460/2617/2460 2469/2630/2469 2462/2622/2462 f 63/3245/63 62/3246/62 2458/2620/2458 f 2432/2636/2432 2474/2635/2474 64/3247/64 f 2487/2649/2487 2486/2648/2486 2477/3248/2477 f 2477/3248/2477 2481/2650/2481 2487/2649/2487 f 2482/2644/2482 2485/2645/2485 2484/2646/2484 f 2484/2646/2484 2432/3249/2432 2483/2647/2483 f 2432/3249/2432 2484/2646/2484 2472/3250/2472 f 2485/2645/2485 2472/3250/2472 2484/2646/2484 f 2472/3250/2472 2485/2645/2485 2475/3251/2475 f 2485/2645/2485 2480/2642/2480 2481/2650/2481 f 2475/3251/2475 2485/2645/2485 2481/2650/2481 f 2486/3252/2486 2481/2650/2481 2477/3248/2477 f 2481/2650/2481 2486/3252/2486 2475/3251/2475 f 2490/2652/2490 1435/3253/1435 1434/3254/1434 f 2483/2647/2483 2489/2658/2489 2488/2643/2488 f 2452/2654/2452 2489/2657/2489 2483/3255/2483 f 47/3256/47 2490/2652/2490 1434/3254/1434 f 2490/2652/2490 47/3256/47 61/2651/61 f 64/3247/64 2474/2635/2474 61/2651/61 f 106/2656/106 107/3257/107 1435/3258/1435 f 106/2656/106 1435/3258/1435 2489/2657/2489 f 1435/3253/1435 2490/2652/2490 2489/2658/2489 f 2519/2674/2519 2491/2662/2491 2494/2675/2494 f 2494/2675/2494 2495/3259/2495 2493/2668/2493 f 2495/3260/2495 2459/2664/2459 2493/2698/2493 f 2459/2664/2459 2495/3260/2495 2491/2665/2491 f 2425/2663/2425 2456/3244/2456 2459/2664/2459 f 2493/2668/2493 2496/2667/2496 2494/2675/2494 f 2465/2627/2465 2501/3261/2501 2498/2628/2498 f 2470/2633/2470 2501/3261/2501 2465/2627/2465 f 2498/2680/2498 2501/3261/2501 2499/2679/2499 f 2499/2679/2499 2501/3261/2501 2470/2633/2470 f 2419/2571/2419 1356/2682/1356 562/2569/562 f 2421/2573/2421 2502/2685/2502 2422/2570/2422 f 2502/2685/2502 2421/2573/2421 14/2608/14 f 2507/2686/2507 2508/2694/2508 2506/2690/2506 f 2041/2146/2041 2048/2151/2048 2031/2137/2031 f 2013/2143/2013 2033/3151/2033 2017/2140/2017 f 2033/3237/2033 2438/3236/2438 2017/3262/2017 f 2040/2145/2040 2007/2144/2007 2010/3146/2010 f 2502/2689/2502 2503/3263/2503 2507/2686/2507 f 2512/2619/2512 2457/3243/2457 2458/2620/2458 f 2456/3244/2456 2512/2619/2512 2459/2664/2459 f 2514/2621/2514 2463/2623/2463 2461/2699/2461 f 2464/2624/2464 2514/2621/2514 2462/2622/2462 f 2468/2629/2468 62/3246/62 46/2700/46 f 2515/2671/2515 2518/2673/2518 2468/2629/2468 f 2517/2681/2517 2471/2632/2471 2500/2631/2500 f 2469/2630/2469 2518/2673/2518 2516/2676/2516 f 2518/2673/2518 2469/2630/2469 2468/2629/2468 f 2492/2659/2492 2518/2673/2518 2515/2671/2515 f 2491/2662/2491 2519/2674/2519 2492/2659/2492 f 2519/2674/2519 2518/2673/2518 2492/2659/2492 f 2494/2675/2494 2491/2662/2491 2495/3259/2495 # 5022 faces g ================================================ FILE: graphics/tiny-renderer/lesson6bis.workbook/Geometry.csx ================================================ struct Vec2f { public float x; public float y; public float this [int i] { get { if (i == 0) return x; if (i == 1) return y; throw new InvalidOperationException (); } set { if (i == 0) x = value; else if (i == 1) y = value; else throw new InvalidOperationException (); } } public Vec2f Normalize () { return this / Norm (); } public float Norm () { return (float)Math.Sqrt (x * x + y * y); } public static Vec2f operator / (Vec2f v, float num) { v.x /= num; v.y /= num; return v; } public static Vec2f operator * (Vec2f v, float num) { v.x *= num; v.y *= num; return v; } public static Vec2f operator - (Vec2f a, Vec2f b) { return new Vec2f { x = a.x - b.x, y = a.y - b.y }; } public static Vec2f operator + (Vec2f a, Vec2f b) { return new Vec2f { x = a.x + b.x, y = a.y + b.y }; } } public struct Vec3f { public float x; public float y; public float z; public float this [int i] { get { switch (i) { case 0: return x; case 1: return y; case 2: return z; default: throw new InvalidOperationException (); } } set { switch (i) { case 0: x = value; break; case 1: y = value; break; case 2: z = value; break; default: throw new InvalidOperationException (); } } } public Vec3f Normalize () { return this / Norm (); } public float Norm () { return (float)Math.Sqrt (x * x + y * y + z * z); } public static Vec3f operator - (Vec3f a, Vec3f b) { return new Vec3f { x = a.x - b.x, y = a.y - b.y, z = a.z - b.z }; } public static Vec3f operator / (Vec3f v, float num) { v.x /= num; v.y /= num; v.z /= num; return v; } public static Vec3f operator * (Vec3f v, float num) { v.x *= num; v.y *= num; v.z *= num; return v; } } struct Vec4f { public float x; public float y; public float z; public float h; public float this [int i] { get { switch (i) { case 0: return x; case 1: return y; case 2: return z; case 3: return h; default: throw new InvalidOperationException (); } } set { switch (i) { case 0: x = value; break; case 1: y = value; break; case 2: z = value; break; case 3: h = value; break; default: throw new InvalidOperationException (); } } } public Vec4f Normalize () { var len = Norm (); return this / len; } public float Norm () { return (float)Math.Sqrt (x * x + y * y + z * z + h * h); } public static Vec4f operator - (Vec4f a, Vec4f b) { return new Vec4f { x = a.x - b.x, y = a.y - b.y, z = a.z - b.z, h = a.h - b.h }; } public static Vec4f operator / (Vec4f v, float num) { v.x /= num; v.y /= num; v.z /= num; v.h /= num; return v; } } struct Vec2i { public int x; public int y; public static Vec2i operator - (Vec2i a, Vec2i b) { return new Vec2i { x = a.x - b.x, y = a.y - b.y }; } } struct Vec3i { public int x; public int y; public int z; public static Vec3i operator - (Vec3i a, Vec3i b) { return new Vec3i { x = a.x - b.x, y = a.y - b.y, z = a.z - b.z }; } } static class Geometry { public static Vec3f Cross (Vec3f l, Vec3f r) { return new Vec3f { x = l.y * r.z - l.z * r.y, y = l.z * r.x - l.x * r.z, z = l.x * r.y - l.y * r.x }; } public static float Dot (Vec3f l, Vec3f r) { return l.x * r.x + l.y * r.y + l.z * r.z; } public static Vec4f Embed4D (Vec3f v, float fill = 1) { return new Vec4f { x = v.x, y = v.y, z = v.z, h = fill }; } public static Vec2f Project2D (Vec3f v) { return new Vec2f { x = v.x, y = v.y }; } public static Vec2f Project2D (Vec4f v) { return new Vec2f { x = v.x, y = v.y }; } public static Vec3f Project3D (Vec4f v) { return new Vec3f { x = v.x, y = v.y, z = v.z }; } } ================================================ FILE: graphics/tiny-renderer/lesson6bis.workbook/Image.csx ================================================ using System.IO; enum Format { GRAYSCALE = 1, BGR = 3, BGRA = 4 } struct Color { // the value stored as little endian: // ARGB -> BGRA // xRGB -> BGRx public readonly int value; public readonly Format format; public byte this [int offset] { get { if (offset > 3) // int has only 4 bytes (0, 1, 2, 3) throw new ArgumentOutOfRangeException (); return (byte)(value >> 8 * (3 - offset)); } } public static Color Red = new Color (red: 255, green: 0, blue: 0, alpha: 255); public static Color Green = new Color (red: 0, green: 255, blue: 0, alpha: 255); public static Color Blue = new Color (red: 0, green: 0, blue: 255, alpha: 255); public static Color Black = new Color (red: 0, green: 0, blue: 0, alpha: 255); public static Color White = new Color (red: 255, green: 255, blue: 255, alpha: 255); public static Color Yellow = new Color (red: 225, green: 225, blue: 0, alpha: 255); public Color (byte red, byte green, byte blue, byte alpha) : this ((blue << 24) | (green << 16) | (red << 8) | alpha, Format.BGRA) { } public Color (byte red, byte green, byte blue) : this ((blue << 24) | (green << 16) | (red << 8) | 0xFF, Format.BGR) { } public Color (byte value) : this (value, Format.GRAYSCALE) { } public Color (int value, Format format) { this.value = value; this.format = format; } public static Color operator * (Color color, float intensivity) { intensivity = Math.Max (0f, Math.Min (1f, intensivity)); var ch0 = (byte)(color [0] * intensivity); var ch1 = (byte)(color [1] * intensivity); var ch2 = (byte)(color [2] * intensivity); var ch3 = color [3]; return new Color (ch0 << 24 | ch1 << 16 | ch2 << 8 | ch3, color.format); } } class Image { internal byte [] buffer; public int Width { get; } public int Height { get; } public Format Format { get; } public int BytesPerRow { get { return Width * (int)Format; } } public Image (int width, int height, Format format) { Width = width; Height = height; Format = format; buffer = new byte [height * BytesPerRow]; } public void VerticalFlip () { var bpp = (int)Format; int bytesPerLine = Width * bpp; var half = Height >> 1; for (int l = 0; l < half; l++) { var l1 = l * bytesPerLine; var l2 = (Height - 1 - l) * bytesPerLine; for (int i = 0; i < bytesPerLine; i++) { byte pixel = buffer [l1 + i]; buffer [l1 + i] = buffer [l2 + i]; buffer [l2 + i] = pixel; } } } public void Clear () { for (int i = 0; i < buffer.Length; i++) buffer [i] = 0; } public Color this [int x, int y] { get { if (x < 0 || x >= Width) throw new ArgumentException ("x"); if (y < 0 || y >= Height) throw new ArgumentException ("y"); var offset = GetOffset (x, y); var len = (int)Format; int value = 0; for (var ch = 0; ch < 4; ch++) value = (value << 8) | (ch < len ? buffer [offset++] : 0xFF); return new Color (value, Format); } set { if (x < 0 || x >= Width) return; //throw new ArgumentException ($"{nameof(x)}={x} {nameof(Width)}={Width}"); if (y < 0 || y >= Height) return; // throw new ArgumentException ($"{nameof(y)}={y} {nameof(Height)}={Height}"); var offset = GetOffset (x, y); var v = value.value; var len = (int)Format; for (int ch = 0; ch < len; ch++) // 0123 buffer [offset++] = (byte)(v >> (3 - ch) * 8); // BGRA } } int GetOffset (int x, int y) { return y * BytesPerRow + x * (int)Format; } public bool WriteToFile (string path, bool rle = true) { var bpp = (int)Format; using (var writer = new BinaryWriter (File.Create (path))) { var header = new TGAHeader { IdLength = 0, // The IDLength set to 0 indicates that there is no image identification field in the TGA file ColorMapType = 0, // a value of 0 indicates that no palette is included BitsPerPixel = (byte)(bpp * 8), Width = (short)Width, Height = (short)Height, DataTypeCode = DataTypeFor (bpp, rle), ImageDescriptor = (byte)(0x20 | (Format == Format.BGRA ? 8 : 0)) // top-left origin }; WriteTo (writer, header); if (!rle) writer.Write (buffer); else UnloadRleData (writer); } return true; } public static Image Load (string path) { using (var reader = new BinaryReader (File.OpenRead (path))) { var header = ReadHeader (reader); var height = header.Height; var width = header.Width; var bytespp = header.BitsPerPixel >> 3; var format = (Format)bytespp; if (width <= 0 || height <= 0) throw new InvalidProgramException ($"bad image size: width={width} height={height}"); if (format != Format.BGR && format != Format.BGRA && format != Format.GRAYSCALE) throw new InvalidProgramException ($"unknown format {format}"); var img = new Image (width, height, format); switch (header.DataTypeCode) { case DataType.UncompressedTrueColorImage: case DataType.UncompressedBlackAndWhiteImage: reader.Read (img.buffer, 0, img.buffer.Length); break; case DataType.RleTrueColorImage: case DataType.RleBlackAndWhiteImage: img.LoadRleData (reader); break; default: throw new InvalidProgramException ($"unsupported image format {header.DataTypeCode}"); } if ((header.ImageDescriptor & 0x20) == 0) img.VerticalFlip (); return img; } } static void WriteTo (BinaryWriter writer, TGAHeader header) { writer.Write (header.IdLength); writer.Write (header.ColorMapType); writer.Write ((byte)header.DataTypeCode); writer.Write (header.ColorMapOrigin); writer.Write (header.ColorMapLength); writer.Write (header.ColorMapDepth); writer.Write (header.OriginX); writer.Write (header.OriginY); writer.Write (header.Width); writer.Write (header.Height); writer.Write (header.BitsPerPixel); writer.Write (header.ImageDescriptor); } static TGAHeader ReadHeader (BinaryReader reader) { var header = new TGAHeader { IdLength = reader.ReadByte (), ColorMapType = reader.ReadByte (), DataTypeCode = (DataType)reader.ReadByte (), ColorMapOrigin = reader.ReadInt16 (), ColorMapLength = reader.ReadInt16 (), ColorMapDepth = reader.ReadByte (), OriginX = reader.ReadInt16 (), OriginY = reader.ReadInt16 (), Width = reader.ReadInt16 (), Height = reader.ReadInt16 (), BitsPerPixel = reader.ReadByte (), ImageDescriptor = reader.ReadByte () }; return header; } bool UnloadRleData (BinaryWriter writer) { const int max_chunk_length = 128; int npixels = Width * Height; int curpix = 0; var bpp = (int)Format; while (curpix < npixels) { int chunkstart = curpix * bpp; int curbyte = curpix * bpp; int run_length = 1; bool literal = true; while (curpix + run_length < npixels && run_length < max_chunk_length && curpix + run_length < curpix + Width) { bool succ_eq = true; for (int t = 0; succ_eq && t < bpp; t++) succ_eq = (buffer [curbyte + t] == buffer [curbyte + t + bpp]); curbyte += bpp; if (1 == run_length) literal = !succ_eq; if (literal && succ_eq) { run_length--; break; } if (!literal && !succ_eq) break; run_length++; } curpix += run_length; writer.Write ((byte)(literal ? run_length - 1 : 128 + (run_length - 1))); writer.Write (buffer, chunkstart, literal ? run_length * bpp : bpp); } return true; } void LoadRleData (BinaryReader reader) { var pixelcount = Width * Height; var currentpixel = 0; var currentbyte = 0; var bytespp = (int)Format; var color = new byte [4]; do { var chunkheader = reader.ReadByte (); if (chunkheader < 128) { chunkheader++; for (int i = 0; i < chunkheader; i++) { for (int t = 0; t < bytespp; t++) buffer [currentbyte++] = reader.ReadByte (); currentpixel++; if (currentpixel > pixelcount) throw new InvalidProgramException ("Too many pixels read"); } } else { chunkheader -= 127; reader.Read (color, 0, bytespp); for (int i = 0; i < chunkheader; i++) { for (int t = 0; t < bytespp; t++) buffer [currentbyte++] = color [t]; currentpixel++; if (currentpixel > pixelcount) throw new InvalidProgramException ("Too many pixels read"); } } } while (currentpixel < pixelcount); } static DataType DataTypeFor (int bpp, bool rle) { var format = (Format)bpp; if (format == Format.GRAYSCALE) return rle ? DataType.RleBlackAndWhiteImage : DataType.UncompressedBlackAndWhiteImage; return rle ? DataType.RleTrueColorImage : DataType.UncompressedTrueColorImage; } } struct TGAHeader { public byte IdLength; public byte ColorMapType; public DataType DataTypeCode; // field #4. Color map specification public short ColorMapOrigin; // index of first color map entry that is included in the file public short ColorMapLength; // number of entries of the color map that are included in the file public byte ColorMapDepth; // number of bits per pixel // field #5. Image specification public short OriginX; // absolute coordinate of lower-left corner for displays where origin is at the lower left public short OriginY; // as for X-origin public short Width; // width in pixels public short Height; // height in pixels public byte BitsPerPixel; // pixel depth public byte ImageDescriptor; // bits 3-0 give the alpha channel depth, bits 5-4 give direction } public enum DataType : byte { NoImageData = 0, // no image data is present UncompressedColorMappedImage = 1, UncompressedTrueColorImage = 2, UncompressedBlackAndWhiteImage = 3, RleColorMappedImage = 9, // run-length encoded color-mapped image RleTrueColorImage = 10, // run-length encoded true-color image RleBlackAndWhiteImage = 11 // run-length encoded black-and-white (grayscale) image } ================================================ FILE: graphics/tiny-renderer/lesson6bis.workbook/ImageResultHandler.csx ================================================ using XIR = Xamarin.Interactive.Representations; InteractiveAgent.RepresentationManager.AddProvider (img => { XIR.ImageFormat format; switch (img.Format) { case Format.BGRA: format = XIR.ImageFormat.Bgra32; break; case Format.BGR: format = XIR.ImageFormat.Bgr24; break; default: return null; } return new XIR.Image (format, img.buffer, img.Width, img.Height); }); ================================================ FILE: graphics/tiny-renderer/lesson6bis.workbook/LICENSE.txt ================================================ Tiny Renderer, https://github.com/ssloy/tinyrenderer Copyright Dmitry V. Sokolov This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. ================================================ FILE: graphics/tiny-renderer/lesson6bis.workbook/Matrix.csx ================================================ using System; public struct Matrix4 { public const int Len = 4; public float R0C0, R0C1, R0C2, R0C3; public float R1C0, R1C1, R1C2, R1C3; public float R2C0, R2C1, R2C2, R2C3; public float R3C0, R3C1, R3C2, R3C3; public float this [int row, int column] { get { switch (row) { case 0: switch (column) { case 0: return R0C0; case 1: return R0C1; case 2: return R0C2; case 3: return R0C3; } break; case 1: switch (column) { case 0: return R1C0; case 1: return R1C1; case 2: return R1C2; case 3: return R1C3; } break; case 2: switch (column) { case 0: return R2C0; case 1: return R2C1; case 2: return R2C2; case 3: return R2C3; } break; case 3: switch (column) { case 0: return R3C0; case 1: return R3C1; case 2: return R3C2; case 3: return R3C3; } break; } throw new IndexOutOfRangeException (); } set { switch (row) { case 0: switch (column) { case 0: R0C0 = value; return; case 1: R0C1 = value; return; case 2: R0C2 = value; return; case 3: R0C3 = value; return; } break; case 1: switch (column) { case 0: R1C0 = value; return; case 1: R1C1 = value; return; case 2: R1C2 = value; return; case 3: R1C3 = value; return; } break; case 2: switch (column) { case 0: R2C0 = value; return; case 1: R2C1 = value; return; case 2: R2C2 = value; return; case 3: R2C3 = value; return; } break; case 3: switch (column) { case 0: R3C0 = value; return; case 1: R3C1 = value; return; case 2: R3C2 = value; return; case 3: R3C3 = value; return; } break; } throw new IndexOutOfRangeException (); } } public Matrix4 Transpose () { return new Matrix4 { R0C0 = R0C0, R0C1 = R1C0, R0C2 = R2C0, R0C3 = R3C0, R1C0 = R0C1, R1C1 = R1C1, R1C2 = R2C1, R1C3 = R3C1, R2C0 = R0C2, R2C1 = R1C2, R2C2 = R2C2, R2C3 = R3C2, R3C0 = R0C3, R3C1 = R1C3, R3C2 = R2C3, R3C3 = R3C3 }; } public static Matrix4 Identity () { return new Matrix4 { R0C0 = 1, R1C1 = 1, R2C2 = 1, R3C3 = 1 }; } public static Matrix4 Zoom (float scale) { return new Matrix4 { R0C0 = scale, R1C1 = scale, R2C2 = scale, R3C3 = scale }; } public static Matrix4 RotationZ (float angle) { var cosangle = (float)Math.Cos (angle); var sinangle = (float)Math.Sin (angle); var R = Identity (); R [0, 0] = R [1, 1] = cosangle; R [0, 1] = -sinangle; R [1, 0] = sinangle; return R; } public static Matrix4 operator * (Matrix4 l, Matrix4 r) { var result = new Matrix4 (); for (int i = 0; i < Len; i++) { for (int j = 0; j < Len; j++) { result [i, j] = 0; for (int k = 0; k < Len; k++) { result [i, j] += l [i, k] * r [k, j]; } } } return result; } public override string ToString () { var sb = new System.Text.StringBuilder (); for (int r = 0; r < Len; r++) { for (int c = 0; c < Len; c++) sb.Append (this[r, c]).Append (" "); sb.AppendLine (); } return sb.ToString (); } } public struct Matrix3 { public const int Len = 3; public float R0C0, R0C1, R0C2; public float R1C0, R1C1, R1C2; public float R2C0, R2C1, R2C2; public float this [int row, int column] { get { switch (row) { case 0: switch (column) { case 0: return R0C0; case 1: return R0C1; case 2: return R0C2; } break; case 1: switch (column) { case 0: return R1C0; case 1: return R1C1; case 2: return R1C2; } break; case 2: switch (column) { case 0: return R2C0; case 1: return R2C1; case 2: return R2C2; } break; } throw new IndexOutOfRangeException (); } set { switch (row) { case 0: switch (column) { case 0: R0C0 = value; return; case 1: R0C1 = value; return; case 2: R0C2 = value; return; } break; case 1: switch (column) { case 0: R1C0 = value; return; case 1: R1C1 = value; return; case 2: R1C2 = value; return; } break; case 2: switch (column) { case 0: R2C0 = value; return; case 1: R2C1 = value; return; case 2: R2C2 = value; return; } break; } throw new IndexOutOfRangeException (); } } public Matrix3 Transpose () { return new Matrix3 { R0C0 = R0C0, R0C1 = R1C0, R0C2 = R2C0, R1C0 = R0C1, R1C1 = R1C1, R1C2 = R2C1, R2C0 = R0C2, R2C1 = R1C2, R2C2 = R2C2 }; } public void SetColumn (int col, Vec3f v) { this [0, col] = v.x; this [1, col] = v.y; this [2, col] = v.z; } public void SetRow (int row, Vec3f v) { this [row, 0] = v.x; this [row, 1] = v.y; this [row, 2] = v.z; } public override string ToString () { var sb = new System.Text.StringBuilder (); for (int r = 0; r < Len; r++) { for (int c = 0; c < Len; c++) sb.Append (this [r, c]).Append (" "); sb.AppendLine (); } return sb.ToString (); } } public struct Matrix2 { public const int Len = 2; public float R0C0, R0C1; public float R1C0, R1C1; public float this [int row, int column] { get { switch (row) { case 0: switch (column) { case 0: return R0C0; case 1: return R0C1; } break; case 1: switch (column) { case 0: return R1C0; case 1: return R1C1; } break; } throw new IndexOutOfRangeException (); } set { switch (row) { case 0: switch (column) { case 0: R0C0 = value; return; case 1: R0C1 = value; return; } break; case 1: switch (column) { case 0: R1C0 = value; return; case 1: R1C1 = value; return; } break; } throw new IndexOutOfRangeException (); } } } // we don't want to declare them in Matrix because we don't need them in lesson which introduces Matrix class static class MatrixHelpers { // For Matrix4 // how to calc inverse Matrix https://en.wikipedia.org/w/index.php?title=Invertible_matrix§ion=4#In_relation_to_its_adjugate public static Matrix4 TransposeInverse (Matrix4 m) { // returns Transpose(Inverse(m)) // where Inverse(m) = Transpose(cofactor) / det(m) // Transpose(Inverse(m)) = Transpose(Transpose(cofactor) / det(m)) = cofactor / det(m) var cofactor = Cofactor (m); float det = 0; for (int i = 0; i < Matrix4.Len; i++) det += m [0, i] * cofactor [0, i]; for (int r = 0; r < Matrix4.Len; r++) { for (int c = 0; c < Matrix4.Len; c++) cofactor [r, c] /= det; } return cofactor; } public static Matrix4 Inverse (Matrix4 m) { // where Inverse(m) = Transpose(Cofactor(m)) / det(m) var cofactor = Cofactor (m); int len = Matrix4.Len; float det = 0; for (int i = 0; i < len; i++) det += m [0, i] * cofactor [0, i]; cofactor = cofactor.Transpose (); for (int r = 0; r < len; r++) { for (int c = 0; c < len; c++) cofactor [r, c] /= det; } return cofactor; } public static Matrix3 Inverse (Matrix3 m) { // where Inverse(m) = Transpose(Cofactor(m)) / det(m) var cofactor = Cofactor (m); int len = Matrix3.Len; float det = 0; for (int i = 0; i < len; i++) det += m [0, i] * cofactor [0, i]; cofactor = cofactor.Transpose (); for (int r = 0; r < len; r++) { for (int c = 0; c < len; c++) cofactor [r, c] /= det; } return cofactor; } static Matrix4 Cofactor (Matrix4 m) { var r = new Matrix4 (); for (int row = 0; row < Matrix4.Len; row++) { for (int col = 0; col < Matrix4.Len; col++) r [row, col] = Cofactor (m, row, col); } return r; } static Matrix3 Cofactor (Matrix3 m) { var r = new Matrix3 (); for (int row = 0; row < Matrix3.Len; row++) { for (int col = 0; col < Matrix3.Len; col++) r [row, col] = Cofactor (m, row, col); } return r; } static float Cofactor (Matrix4 m, int row, int col) { int sign = ((row + col) % 2 == 0) ? 1 : -1; return Det (Minor (m, row, col)) * sign; } static float Cofactor (Matrix3 m, int row, int col) { int sign = ((row + col) % 2 == 0) ? 1 : -1; return Det (Minor (m, row, col)) * sign; } static Matrix3 Minor (Matrix4 m, int row, int col) { var minor = new Matrix3 (); for (int r = 0; r < Matrix3.Len; r++) { for (int c = 0; c < Matrix3.Len; c++) { int y = (r < row) ? r : r + 1; int x = (c < col) ? c : c + 1; minor [r, c] = m [y, x]; } } return minor; } static Matrix2 Minor (Matrix3 m, int row, int col) { var minor = new Matrix2 (); for (int r = 0; r < Matrix2.Len; r++) { for (int c = 0; c < Matrix2.Len; c++) { int y = (r < row) ? r : r + 1; int x = (c < col) ? c : c + 1; minor [r, c] = m [y, x]; } } return minor; } static float Det (Matrix3 m) { float det = 0; det += m [0, 0] * (m [1, 1] * m [2, 2] - m [1, 2] * m [2, 1]); det -= m [0, 1] * (m [1, 0] * m [2, 2] - m [1, 2] * m [2, 0]); det += m [0, 2] * (m [1, 0] * m [2, 1] - m [1, 1] * m [2, 0]); return det; } static float Det (Matrix2 m) { return m [0, 0] * m [1, 1] - m [0, 1] * m [1, 0]; } public static Vec3f Mult (Matrix3 m, Vec3f v) { return new Vec3f { x = m.R0C0 * v.x + m.R0C1 * v.y + m.R0C2 * v.z, y = m.R1C0 * v.x + m.R1C1 * v.y + m.R1C2 * v.z, z = m.R2C0 * v.x + m.R2C1 * v.y + m.R2C2 * v.z }; } public static Vec4f Mult (Matrix4 m, Vec4f v) { return new Vec4f { x = m.R0C0*v.x + m.R0C1*v.y + m.R0C2*v.z + m.R0C3*v.h, y = m.R1C0*v.x + m.R1C1*v.y + m.R1C2*v.z + m.R1C3*v.h, z = m.R2C0*v.x + m.R2C1*v.y + m.R2C2*v.z + m.R2C3*v.h, h = m.R3C0*v.x + m.R3C1*v.y + m.R3C2*v.z + m.R3C3*v.h }; } } ================================================ FILE: graphics/tiny-renderer/lesson6bis.workbook/Model.csx ================================================ using System.Collections.Generic; using System.Linq; struct Face { public int [] Vertices; public int [] Textures; public int [] Normals; } class Model { public List Vertices { get; } = new List (); public List Faces { get; } = new List (); public List Textures { get; } = new List (); public List Normals { get; } = new List (); public static Model FromFile (string path) { var model = new Model (); string line; using (var reader = new System.IO.StreamReader (path)) { while ((line = reader.ReadLine ()) != null) model.ParseLine (line); } Console.WriteLine ($"v#{model.Vertices.Count} f#{model.Faces.Count}"); return model; } public static Model FromText (string text) { var model = new Model (); var lines = text.Split (new char [] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); foreach (var line in lines) model.ParseLine (line); Console.WriteLine ($"v#{model.Vertices.Count} f#{model.Faces.Count}"); return model; } void ParseLine (string line) { Func parseV3f = strItems => new Vec3f { x = float.Parse (strItems [1]), y = float.Parse (strItems [2]), z = float.Parse (strItems [3]) }; var items = line.Split (new char [] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (line.StartsWith ("v ", StringComparison.InvariantCulture)) { Vertices.Add (parseV3f (items)); } else if (line.StartsWith ("vt ", StringComparison.InvariantCulture)) { Textures.Add (parseV3f (items)); } else if (line.StartsWith ("vn ", StringComparison.InvariantCulture)) { Normals.Add (parseV3f (items)); } else if (line.StartsWith ("f ", StringComparison.InvariantCulture)) { var indexes = items.Skip (1) .SelectMany (s => s.Split (new char [] { '/', ' ' }, StringSplitOptions.RemoveEmptyEntries)) .Select (s => int.Parse (s) - 1) // in wavefront obj all indices start at 1, not zero .ToArray (); Faces.Add (new Face { Vertices = indexes.Where ((v, index) => index % 3 == 0).ToArray (), Textures = indexes.Where ((v, index) => index % 3 == 1).ToArray (), Normals = indexes.Where ((v, index) => index % 3 == 2).ToArray () }); } } public Vec3f Normal (Face face, int nthvert) { int idx = face.Normals [nthvert]; return Normals [idx]; } public Vec3f Vertex (Face face, int nthvert) { int idx = face.Vertices [nthvert]; return Vertices [idx]; } public Vec3f GetUV (Face face, int nthvert) { int idx = face.Textures [nthvert]; return Textures [idx]; } } ================================================ FILE: graphics/tiny-renderer/lesson6bis.workbook/WpfImageResultHandler.csx ================================================ using System; using System.IO; using System.Windows.Media; using System.Windows.Media.Imaging; using XIR = Xamarin.Interactive.Representations; static PixelFormat ConvertFormat (Format format) { switch (format) { case Format.BGRA: return PixelFormats.Bgra32; case Format.GRAYSCALE: return PixelFormats.Gray8; case Format.BGR: default: return PixelFormats.Bgr24; } } InteractiveAgent.RepresentationManager.AddProvider (img => { var source = BitmapSource.Create (img.Width, img.Height, 96, 96, ConvertFormat (img.Format), null, img.buffer, img.BytesPerRow); var encoder = new PngBitmapEncoder (); var outputFrame = BitmapFrame.Create (source); encoder.Frames.Add (outputFrame); using (var memory = new MemoryStream ()) { encoder.Save (memory); return XIR.Image.FromPng (memory.GetBuffer (), img.Width, img.Height); } }); ================================================ FILE: graphics/tiny-renderer/lesson6bis.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Matrix.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" #load "lesson1.csx" #load "lesson2.csx" #load "lesson3.csx" #load "lesson4.csx" #load "lesson5.csx" #load "lesson6.csx" using static Geometry; using static MatrixHelpers; using static ShaderUtils; ``` # Lesson 6bis: tangent space normal mapping > ℹ️ This workbook is a port of an [excellent C++ series](https://github.com/ssloy/tinyrenderer/wiki) written by Dmitry Sokolov. We appreciate that original work is available under a license that allowed us to turn it into a Workbook. The subject for today is [normal mapping](https://en.wikipedia.org/wiki/Normal_mapping). What is the main difference between normal mapping and Phong shading? The key is the density of information we have. For Phong shading we use normal vectors given per vertex of triangle mesh (and interpolate it inside triangles), whereas normal mapping textures provide dense information, dramatically improving rendering details. Well, we have already applied normal mapping in previous lesson, however we used the global system of coordinates to store the texture. Today we are talking about [tangent space](https://en.wikipedia.org/wiki/Darboux_frame) normal mapping. So, we have two textures, the left one is given in the global frame (direct transformation from RGB to XYZ normal), whereas the right one in the Darboux frame: ![](./img/lesson6bis_nm.jpg) To use right texture, for each pixel we draw we compute tangent space (Darboux) frame. In this basis one vector (usually z) is orthogonal to our surface, and two others give a plane tangent to the current point. Then we read a (perturbed) normal vector from our texture, transform its coordinates from Darboux frame to the global system coordinates and we are done. Usually normal maps provide small perturbations of normal vectors, thus textures are in dominant blue color. Well, why such a mess? Why not to use global system as we did before? Imagine we want to animate our model. For example, I took the black guy model and opened his mouth. It is obvious that normal vectors are to be modified. ![ ](./img/lesson6bis_mouth.jpg) Left image gives the head with open mouth, but unchanged (global frame) normal texture. Inspect closely the interior of the lower lip. The light coming directly to his face; when the mouth was closed the backside of the lower lip naturally was not lit. Now the mouth is open, but the lip is not lit... The right image was computed with tangent space normal mapping. Therefore, if we have an animated model, then for correct normal mapping in global frame we need to have one texture per frame of the animation, whereas tangent space deforms accordingly to the model and we need one texture only! Here is another example: ![ ](./img/global_vs_tangent_diablo.jpg) These are textures for the Diablo model. Notice that only one hand is drawn in the texture, and only one side of the tail. The artist used the same texture for both arms and for both sides of the tail. It means that in the global coordinate system I can provide normal vectors either for the left side of the tail, either for the right one, but not for both! Same goes for the arms. And I need different information for the left and the right sides, for example, inspect left and right cheekbones in the left image, naturally normal vectors are pointing in the opposite directions! Let us finish with the motivation section and go straight ahead to the computations. # **Starting point, Phong shading** Okay, here is the starting point. The shader is really simple, it is Phong shading. ```csharp class TangentShader : IShader { // triangle uv coordinates, written by the vertex shader, read by the fragment shader Vec3f varyingU = new Vec3f (); Vec3f varyingV = new Vec3f (); // normal per vertex to be interpolated by FS Matrix3 varyingNrm = new Matrix3 (); readonly Model model; readonly Vec3f lightDir; readonly Matrix4 uniformM; readonly Matrix4 uniformMIT; readonly Matrix4 transformation; readonly Image texture; public TangentShader (Model model, Matrix4 viewport, Matrix4 projection, Matrix4 modelView, Vec3f lightDir, Image texture) { this.model = model; this.lightDir = lightDir.Normalize (); this.texture = texture; uniformM = projection * modelView; uniformMIT = TransposeInverse (uniformM); transformation = viewport * uniformM; } public Vec4f Vertex (Face face, int nthvert) { UpdateVarayingUV (model, face, nthvert, ref varyingU, ref varyingV); var normal = Project3D (Mult (uniformMIT, Embed4D (model.Normal (face, nthvert)))); varyingNrm.SetColumn (nthvert, normal); var glVertex = TransformFace (model, face, nthvert, transformation); return glVertex; } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { Vec3f bn = Mult(varyingNrm, bar).Normalize (); var uv = CalcUV (varyingU, varyingV, bar); Vec3f l = Transform (uniformM, lightDir).Normalize (); var diff = Math.Max (0f, Dot (bn, l)); color = GetColor (texture, uv); color *= diff; return false; } } var shader = new TangentShader (headModel, viewPort, projection, modelView, light_dir, headTexture); var image = Render (headModel, shader).Image; image.VerticalFlip(); image ``` For the educational and debugging purposes I am removing the skin texture and apply a regular grid with horizontal red and vertical blue lines: ```csharp var gridTexture = Image.Load ("obj/grid.tga"); var shader = new TangentShader (headModel, viewPort, projection, modelView, light_dir, gridTexture); var image = Render (headModel, shader).Image; image.VerticalFlip(); image ``` Let us remember how Phong shading works: ![ ](./img/lesson6bis_triangle.png) For each vertex of a triangle we have its coordinates p, texture coordinates uv and normal vectors. For shading current fragment our software rasterizer gives us barycentric coordinates of the fragment (alpha, beta, gamma). It means that the coordinates of the fragment can be obtained as p = alpha p0 \+ beta p1 \+ gamma p2. Then in the same way we interpolate texture coordinates and the normal vector: ![ ](./img/lesson6bis_f00.png) Notice that blue and red lines are isolines of u and v, correspondingly. So, for each point of our surface we define a so-called Darboux frame, with x and y axes parallel to blue and red lines, and z axis orthogonal to the surface. This is the frame where tangent space normal map lives. # **How to reconstruct a (3D) linear function from three samples** Okay, so our goal is to compute three vectors (tangent basis) for each pixel we draw. Let us put that aside for a while and imagine a linear function f that for each point (x,y,z) gives a real number f(x,y,z) = Ax \+ By \+ Cz \+ D. The only problem that we do not know A, B, C and D, however we do know three values of the function at three different points of the space (p0, p1, p2): ![ ](./img/lesson6bis_f01.png) ![ ](./img/lesson6bis_gradient_a.png) It is convenient to imagine f as a height map of an inclined plane. We fix three different (non collinear) points on the plane and we know values of f in those points. Red lines inside the triangle show the iso-heights f0, f0 \+ 1 meter, f0 \+ 2 meters and so on. For a linear function we have the isolines are parallel (straight) lines. In fact, I am more interested in the direction, orthogonal to the isolines. If we move along an iso, the height does not change (well duh, it is an iso!). If we deviate a little bit from an iso, the height starts to change a little bit. The steepest ascent we obtain when we move orthogonally to the isolines. Let us recall that the steepest ascent direction for a function is nothing else than its [gradient](https://en.wikipedia.org/wiki/Gradient). For a linear function f(x,y,z) = Ax \+ By \+ Cz \+ D its gradient is a constant vector (A, B, C). Recall that we do not know the values of (A,B,C). We know only three samples of the function. Can we reconstruct A,B and C? Sure thing. So, we have three points p0, p1, p2 and thre values f0, f1, f2. We need to find the vector of the steepest ascent (A,B,C). Let us consider another function defined as g(p) = f(p) - f(p0): ![ ](./img/lesson6bis_gradient_b.png) Obviously that we simply translated our inclined plane, without changing its inclination, therefore the steepest ascent direction for f and g is the same. Let us rewrite the definition of g: ![ ](./img/lesson6bis_f02.png) Please note that superscript x in p^x means x coordinate of the point p and not a power. So, the function g is simply a dot product between vector (p-p0) and (ABC). And we still do not know (A,B,C)! Okay, let us recall what we know. We know that if we go from point p0 to point p2, then the function g will go from zero to f2-f0. In other words, the dot product between vectors (p2-p0) and (ABC) is equal to f2-f0. Same thing for (p1-p0). Therefore, we are looking for the vector ABC, orthogonal to the normal n and respecting two constraints on dot products: ![ ](./img/lesson6bis_f03.png) Let us rewrite this in a matrix form: ![ ](./img/lesson6bis_f04.png) So, we got an easy to solve linear matrix equation Ax = b: ![ ](./img/lesson6bis_f05.png) Please note that I used the letter A for two different things, the meaning should be clear from the context. So, our 3x3 matrix A, multiplied with the unknown vector x=(A,B,C), gives the vector b = (f1-f0, f2-f0, 0). Unknown vector x becomes known when we multiply inverse to A by b. Also note that in the matrix A we have nothing related to the function f. It contains only some information about our triangle. # **Let us compute Darboux basis and apply the perturbation of normals** So, Darboux basis is a triplet of vectors (i,j,n), where n - is the original normal vector, and i, j can be computed as follows: ![ ](./img/lesson6bis_f06.png) Using the normal maps in the tangent space. ```csharp class TangentShader : IShader { // triangle uv coordinates, written by the vertex shader, read by the fragment shader Vec3f varyingU = new Vec3f (); Vec3f varyingV = new Vec3f (); // normal per vertex to be interpolated by FS Matrix3 varyingNrm = new Matrix3 (); readonly Model model; readonly Vec3f lightDir; readonly Matrix4 uniformM; readonly Matrix4 uniformMIT; readonly Matrix4 transformation; readonly Vec3f[] ndcTri = new Vec3f[3]; // triangle in normalized device coordinates readonly Image texture; readonly Image normalMap; public TangentShader (Model model, Matrix4 viewport, Matrix4 projection, Matrix4 modelView, Vec3f lightDir, Image texture, Image normalMap) { this.model = model; this.lightDir = lightDir.Normalize (); this.texture = texture; this.normalMap = normalMap; uniformM = projection * modelView; uniformMIT = TransposeInverse (uniformM); transformation = viewport * uniformM; } public Vec4f Vertex (Face face, int nthvert) { UpdateVarayingUV (model, face, nthvert, ref varyingU, ref varyingV); var normal = Project3D (Mult (uniformMIT, Embed4D (model.Normal (face, nthvert)))); varyingNrm.SetColumn (nthvert, normal); var glVertex = TransformFace (model, face, nthvert, transformation); ndcTri[nthvert] = Project3D (glVertex / glVertex.h); return glVertex; } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { var bn = Mult(varyingNrm, bar).Normalize (); var uv = CalcUV (varyingU, varyingV, bar); var A = new Matrix3 (); A.SetRow (0, ndcTri [1] - ndcTri [0]); A.SetRow (1, ndcTri [2] - ndcTri [0]); A.SetRow (2, bn); var AI = Inverse (A); var i = Mult (AI, new Vec3f { x = varyingU.y - varyingU.x, y = varyingU.z - varyingU.x }); var j = Mult (AI, new Vec3f { x = varyingV.y - varyingV.x, y = varyingV.z - varyingV.x }); var B = new Matrix3 (); B.SetColumn (0, i.Normalize ()); B.SetColumn (1, j.Normalize ()); B.SetColumn (2, bn); var n = Mult (B, Normal (normalMap, uv)).Normalize (); var l = Transform (uniformM, lightDir).Normalize (); var diff = Math.Max (0f, Dot (n, l)); color = GetColor (texture, uv) * diff; return false; } } ``` All is quite straightforward, I compute the matrix A: ```csharp // var A = new Matrix3 (); // A.SetRow (0, ndcTri [1] - ndcTri [0]); // A.SetRow (1, ndcTri [2] - ndcTri [0]); // A.SetRow (2, bn); ``` Then compute two unknown vectors (i,j) of Darboux basis: ```csharp // var AI = Inverse (A); // var i = Mult (AI, new Vec3f { x = varyingU.y - varyingU.x, y = varyingU.z - varyingU.x }); // var j = Mult (AI, new Vec3f { x = varyingV.y - varyingV.x, y = varyingV.z - varyingV.x }); ``` Once we have all the tangent basis, I read the perturbed normal from the texture and apply the basis change from the tangent basis to the global coordinates. Recall that I have already described how to perform change of basis. Here is the final rendered image, compare the details with Phong shading: ```csharp var headTangentMap = Image.Load ("obj/african_head_nm_tangent.tga"); headTangentMap.VerticalFlip (); var shader = new TangentShader (headModel, viewPort, projection, modelView, light_dir, headTexture, headTangentMap); var image = Render (headModel, shader).Image; image.VerticalFlip(); image ``` # **Were you paying attention?** Have you noticed that generally a (flat) triangle has a constant normal vector, whereas I used the interpolated normal in the last row of the matrix A? Why did I do it? Happy coding! ================================================ FILE: graphics/tiny-renderer/lesson6bis.workbook/lesson1.csx ================================================ int width = 800; int height = 800; var headModel = Model.FromFile ("obj/african_head.obj"); static void Swap(ref T x, ref T y) { T t = y; y = x; x = t; } static void Swap(T[] arr, int x, int y) { T t = arr[y]; arr[y] = arr[x]; arr[x] = t; } Image Line (Image image, int x0, int y0, int x1, int y1, Color color) { bool steep = false; // if the line is steep, we transpose the image if (Math.Abs (x0-x1) < Math.Abs (y0-y1)) { Swap (ref x0, ref y0); Swap (ref x1, ref y1); steep = true; } if (x0 > x1) { // make it left to right Swap (ref x0, ref x1); Swap (ref y0, ref y1); } // (x0, y0) == (x1, y1) if(x0 == x1) { image [x0, y0] = color; } else { for (int x = x0; x <= x1; x++) { double t = (x-x0) / (double)(x1-x0); int y = (int)Math.Round(y0*(1-t) + y1*t); if (steep) image [y, x] = color; else image [x, y] = color; } } return image; } ================================================ FILE: graphics/tiny-renderer/lesson6bis.workbook/lesson1.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" ``` # **Lesson 1: Bresenham’s Line Drawing Algorithm** # First attempt The goal of the first lesson is to render the wire mesh. To do this, we should learn how to draw line segments. We can simply read what Bresenham’s line algorithm is, but let’s write code ourselves. How does the simplest code that draws a line segment between `(x0, y0)` and `(x1, y1)` points look like? Apparently, something like this: ```csharp Image Line (Image image, int x0, int y0, int x1, int y1, Color color) { for (double t = 0; t < 1; t += 0.01) { int x = (int) (x0 * (1-t) + x1 * t); int y = (int) (y0 * (1-t) + y1 * t); image [x, y] = color; } return image; } Line (new Image (100, 100, Format.BGR), x0: 13, y0: 20, x1: 80, y1: 40, color: Color.White); ``` # Second attempt The problem with this code (in addition to efficiency) is the choice of the constant, which I took equal to .01. If we take it equal to .1, our line segment will look like this: ```csharp Image Line (Image image, int x0, int y0, int x1, int y1, Color color) { for (int x = x0; x <= x1; x++) { double t = (x-x0)/(double)(x1-x0); int y = (int)(y0*(1-t) + y1*t); image [x, y] = color; } return image; } Line (new Image (100, 100, Format.BGR), x0: 13, y0: 20, x1: 80, y1: 40, color: Color.White); ``` Caution! The first source of errors in such code of my students is the integer division, like: `(x-x0)/(x1-x0)`. Then, if we try to draw the following lines with this code: ```csharp var image = new Image (100, 100, Format.BGR); Line(image, x0: 13, y0: 20, x1: 80, y1: 40, color: Color.White); Line(image, x0: 20, y0: 13, x1: 40, y1: 80, color: Color.Red); Line(image, x0: 80, y0: 40, x1: 13, y1: 20, color: Color.Red); ``` It turns out that one line is good, the second one is with holes, and there’s no third line at all. Note that the first and the third lines (in the code) draw the same line in different colors, and in different directions (with the source and target points flipped). We have already seen the white one, it is drawn well. I was hoping to change the color of the white line to red, but could not do it. It’s a test for symmetry: the result of drawing a line segment should not depend on the order of points: the `(a,b)` line segment should be exactly the same as the `(b,a)` line segment. # Third attempt We fix the missing red line by swapping the points so `x0` is always lower than `x1`. There are holes in one of the line segments due to the fact that its height is greater than the width. My students often suggest the following fix: `if (dx > dy) { for (int x) } else { for (int y) }` Holy cow! ```csharp static void Swap(ref T x, ref T y) { T t = y; y = x; x = t; } static void Swap(T[] arr, int x, int y) { T t = arr[y]; arr[y] = arr[x]; arr[x] = t; } Image Line (Image image, int x0, int y0, int x1, int y1, Color color) { bool steep = false; // if the line is steep, we transpose the image if (Math.Abs (x0-x1) < Math.Abs (y0-y1)) { Swap (ref x0, ref y0); Swap (ref x1, ref y1); steep = true; } if (x0 > x1) { // make it left to right Swap (ref x0, ref x1); Swap (ref y0, ref y1); } // (x0, y0) == (x1, y1) if(x0 == x1) { image [x0, y0] = color; } else { for (int x = x0; x <= x1; x++) { double t = (x-x0) / (double)(x1-x0); int y = (int)Math.Round(y0*(1-t) + y1*t); if (steep) image [y, x] = color; else image [x, y] = color; } } return image; } Line(image, x0: 13, y0: 20, x1: 80, y1: 40, color: Color.White); Line(image, x0: 20, y0: 13, x1: 40, y1: 80, color: Color.Red); Line(image, x0: 80, y0: 40, x1: 13, y1: 20, color: Color.Red); ``` # Wireframe rendering So now we are ready to create a wire render. You can find the snapshot of the code and the test model here. I used the [wavefront obj](http://en.wikipedia.org/wiki/Wavefront_.obj_file) format of the file to store model. All we need for the render is read from the file the array of vertices of the following type: `v 0.608654 -0.568839 -0.416318` are `x,y,z` coordinates, one vertex per file line and faces `f 1193/1240/1193 1180/1227/1180 1179/1226/1179` ```csharp int width = 800, height = 800; var headModel = Model.FromFile ("obj/african_head.obj"); var image = new Image(width, height, Format.BGR); foreach(var face in headModel.Faces) { for(int j=0; j<3; j++) { var v0 = headModel.Vertices[face.Vertices [j]]; var v1 = headModel.Vertices[face.Vertices [(j+1) % 3]]; // scale x from [-1..1] to [0..w] // scale y from [-1..1] to [0..h] int x0 = (int)((v0.x + 1) * width / 2); int y0 = (int)((v0.y + 1) * height / 2); int x1 = (int)((v1.x + 1) * width / 2); int y1 = (int)((v1.y + 1) * height / 2); Line(image, x0, y0, x1, y1, Color.White); } } image.VerticalFlip (); image ``` ================================================ FILE: graphics/tiny-renderer/lesson6bis.workbook/lesson2.csx ================================================ using static Geometry; var light_dir = new Vec3f { x = 0, y = 0, z = -1 }; var world = new Vec3f [3]; var screen = new Vec3f [3]; void Line (Image image, Vec2i p1, Vec2i p2, Color color) { Line(image, p1.x, p1.y, p2.x, p2.y, color); } void Line (Image image, Vec3f p1, Vec3f p2, Color color) { Line(image, (int)p1.x, (int)p1.y, (int)p2.x, (int)p2.y, color); } void Triangle (Image image, Vec2i[] t, Color color) { Line(image, t[0], t[1], color); Line(image, t[1], t[2], color); Line(image, t[2], t[0], color); } Vec3f Barycentric (Vec3f a, Vec3f b, Vec3f c, Vec2i p) { var pixel = new Vec3f { x = p.x + 0.5f, y = p.y + 0.5f }; var ab = b - a; var ac = c - a; var pa = a - pixel; var r = Cross (new Vec3f { x = ab.x, y = ac.x, z = pa.x }, new Vec3f { x = ab.y, y = ac.y, z = pa.y }); // triangle is degenerate, in this case return smth with negative coordinates if (Math.Abs (r.z) < 1) return new Vec3f { x = -1, y = 1, z = 1 }; return new Vec3f { x = 1 - r.x / r.z - r.y / r.z, y = r.x / r.z, z = r.y / r.z }; } void Triangle (Image image, Vec3f [] coordinates, Color color) { var t0 = coordinates [0]; var t1 = coordinates [1]; var t2 = coordinates [2]; var pMax = new Vec2i { x = (int)Math.Max (0, Math.Max (t0.x, Math.Max (t1.x, t2.x))), y = (int)Math.Max (0, Math.Max (t0.y, Math.Max (t1.y, t2.y))) }; var pMin = new Vec2i { x = (int)Math.Min (image.Width, Math.Min (t0.x, Math.Min (t1.x, t2.x))), y = (int)Math.Min (image.Height, Math.Min (t0.y, Math.Min (t1.y, t2.y))) }; Vec2i p; for (p.x = pMin.x; p.x <= pMax.x; p.x++) { for (p.y = pMin.y; p.y <= pMax.y; p.y++) { var bc = Barycentric (t0, t1, t2, p); if (bc.x < 0 || bc.y < 0 || bc.z < 0) continue; image [p.x, p.y] = color; } } } ================================================ FILE: graphics/tiny-renderer/lesson6bis.workbook/lesson2.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" #load "lesson1.csx" using static Geometry; ``` # Lesson 2: Triangle rasterization and back face culling # Old-school method: Line sweeping Thus, the task is to draw two-dimensional triangles. For motivated students it normally takes a couple of hours, even if they are bad programmers. Last time we saw Bresenham’s line drawing algorithm. Today’s task is to draw a filled triangle. Funny enough, but this task is not trivial. I don’t know why, but I know that it’s true. Most of my students struggle with this simple task. So, the initial stub will look like this: ```csharp void Line (Image image, Vec2i p1, Vec2i p2, Color color) { Line(image, p1.x, p1.y, p2.x, p2.y, color); } void Line (Image image, Vec3f p1, Vec3f p2, Color color) { Line(image, (int)p1.x, (int)p1.y, (int)p2.x, (int)p2.y, color); } void Triangle (Image image, Vec2i[] t, Color color) { Line(image, t[0], t[1], color); Line(image, t[1], t[2], color); Line(image, t[2], t[0], color); } Vec2i[] t0 = { new Vec2i { x = 10, y = 70 }, new Vec2i { x = 50, y = 160 }, new Vec2i { x = 70, y = 80 } }; Vec2i[] t1 = { new Vec2i { x = 180, y = 50 }, new Vec2i { x = 150, y = 1 }, new Vec2i { x = 70, y = 180 } }; Vec2i[] t2 = { new Vec2i { x = 180, y = 150 }, new Vec2i { x = 120, y = 160 }, new Vec2i { x = 130, y = 180 } }; var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); image.VerticalFlip (); image ``` The code is simple: I provide three triangles for the initial debugging of your code. If we invoke `Line` inside the triangle function, we’ll get the contour of the triangle. How to draw a filled triangle? A good method of drawing a triangle must have the following features: * It should be (surprise!) simple and fast. * It should be symmetrical: the picture should not depend on the order of vertices passed to the drawing function. * If two triangles have two common vertices, there should be no holes between them because of rasterization rounding. We could add more requirements, but let’s do with these ones. Traditionally a line sweeping is used: 1. Sort vertices of the triangle by their y-coordinates 2. Rasterize simultaneously the left and the right sides of the triangle 3. Draw a horizontal line segment between the left and the right boundary points At this point my students start to lose the firm ground: which segment is the left one, which one is right? Besides, there are three segments in a triangle... Usually, after this introduction I leave my students for about an hour: once again, reading my code is much less valuable than comparing your own code with mine. `[One hour passes]` How do I draw a triangle? Once again, if you have a better method, I’d be glad to adopt it. Let us assume that we have three points of the triangle: `t0`, `t1`, `t2`, they are sorted in ascending order by the y-coordinate. Then, the boundary A is between `t0` and `t2`, boundary B is between `t0` and `t1`, and then between `t1` and `t2`. ```csharp void OrderByY (Vec2i[] t) { if(t[0].y > t[1].y) Swap(t, 0, 1); if(t[1].y > t[2].y) Swap(t, 1, 2); if(t[0].y > t[1].y) Swap(t, 0, 1); } void Triangle (Image image, Vec2i[] t, Color color) { OrderByY(t); Line(image, t[0], t[1], Color.Green); Line(image, t[1], t[2], Color.Green); Line(image, t[2], t[0], Color.Red); } var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); // Here boundary A is red, and boundary B is green. image.VerticalFlip (); image ``` Unfortunately, boundary B is made of two parts. Let us draw the bottom half of the triangle by cutting it horizontally: ```csharp void Triangle (Image image, Vec2i[] t, Color color) { OrderByY(t); float height_10 = t[1].y - t[0].y; float height_20 = t[2].y - t[0].y; for(int y=t[0].y; y<=t[1].y; y++) { var alpha = (y-t[0].y) / height_20; var beta = (y-t[0].y) / height_10; // be careful with divisions by zero Vec2i A = new Vec2i { x = t[0].x + (int)((t[2].x-t[0].x)*alpha), y = y}; Vec2i B = new Vec2i { x = t[0].x + (int)((t[1].x-t[0].x)*beta), y = y}; image[A.x, y] = Color.Red; image[B.x, y] = Color.Green; } } var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); image.VerticalFlip (); image ``` Note that the segments are not continuous. Last time when we drew straight lines we struggled to get continuous segments and here I did not bother with rotating the image (remember the xy swapping?). Why? We fill the triangles aftewards, that’s why. If we connect the corresponding pairs of points by horizontal lines, the gaps disappear: ```csharp void Triangle (Image image, Vec2i[] t, Color color) { OrderByY(t); float height_10 = t[1].y - t[0].y; float height_20 = t[2].y - t[0].y; for(int y=t[0].y; y<=t[1].y; y++) { var alpha = (y-t[0].y) / height_20; var beta = (y-t[0].y) / height_10; // be careful with divisions by zero Vec2i A = new Vec2i { x = t[0].x + (int)((t[2].x-t[0].x)*alpha), y = y}; Vec2i B = new Vec2i { x = t[0].x + (int)((t[1].x-t[0].x)*beta), y = y}; Line(image, A, B, Color.White); image[B.x, y] = Color.Green; image[A.x, y] = Color.Red; } } var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); image.VerticalFlip (); image ``` Now, let us draw the second (upper) half of the triangle. We can do this by adding a second loop: ```csharp void Triangle (Image image, Vec2i[] t, Color color) { OrderByY(t); float height_10 = t[1].y - t[0].y; float height_20 = t[2].y - t[0].y; for(int y=t[0].y; y<=t[1].y; y++) { var alpha = (y-t[0].y) / height_20; var beta = (y-t[0].y) / height_10; // be careful with divisions by zero Vec2i A = new Vec2i { x = t[0].x + (int)((t[2].x-t[0].x)*alpha), y = y}; Vec2i B = new Vec2i { x = t[0].x + (int)((t[1].x-t[0].x)*beta), y = y}; if(A.x > B.x) Swap(ref A, ref B); for (int j=A.x; j<=B.x; j++) image[j, y] = color; } float height_21 = t[2].y - t[1].y; for(int y=t[1].y; y<=t[2].y; y++) { var alpha = (y-t[0].y) / height_20; var beta = (y-t[1].y) / height_21; // be careful with divisions by zero Vec2i A = new Vec2i { x = t[0].x + (int)((t[2].x-t[0].x)*alpha), y = y}; Vec2i B = new Vec2i { x = t[1].x + (int)((t[2].x-t[1].x)*beta), y = y}; if(A.x > B.x) Swap(ref A, ref B); for (int j=A.x; j<=B.x; j++) image[j, y] = color; } } var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); image.VerticalFlip (); image ``` This could be enough, but I dislike to see the same code twice. That is why we will make it a bit less readable, but more handy for modifications/maintaining: ```csharp void Triangle (Image image, Vec2i[] t, Color color) { // I dont care about degenerate triangles if(t[0].y == t[1].y && t[1].y == t[2].y) return; OrderByY(t); float height_10 = t[1].y - t[0].y; float total_height = t[2].y - t[0].y; for(int i=0; i t[1].y - t[0].y || t[1].y == t[0].y; float segment_height = second_half ? t[2].y-t[1].y : t[1].y-t[0].y; var alpha = i / total_height; // be careful with divisions by zero var beta = (i - (second_half ? t[1].y-t[0].y : 0)) / segment_height; Vec2i A = new Vec2i { x = t[0].x + (int)((t[2].x-t[0].x)*alpha), y = t[0].y + i }; Vec2i B = new Vec2i { x = second_half ? t[1].x + (int)((t[2].x-t[1].x)*beta) : t[0].x + (int)((t[1].x-t[0].x)*beta), y = t[0].y + i }; if(A.x > B.x) Swap(ref A, ref B); for (int j=A.x; j<=B.x; j++) image[j, t[0].y + i] = color; } } var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); image.VerticalFlip (); image ``` # The method I adopt for my code While not being really complicated, the source code for the line sweeping is a bit messy. Moreover, it is really an old-school approach designed for mono-thread CPU programming. Let us take a look at the following pseudo-code: ```csharp // triangle(Vec2i[] points) { // Vec2i bbox[2] = find_bounding_box(points); // for (each pixel in the bounding box) { // if (inside(points, pixel)) { // put_pixel(pixel); // } // } // } ``` Do you like it? I do. It is really easy to find a bounding box. It is certainly no problem to check whether a point belongs a 2D triangle (or any convex polygon). *Off Topic: if I have to implement some code to check whether a point belongs to a polygon, and this program will run on a plane, I will never get on this plane. Turns out, it is a surprisingly difficult task to solve this problem reliably. But here we just painting pixels. I am okay with that.* There is another thing I like about this pseudocode: a neophyte in programming accepts it with enthusiasm, more experienced programmers often chuckle: “*What an idiot wrote it?*”. And an expert in computer graphics programming will shrug his shoulders and say: “*Well, that’s how it works in real life*”. Massively parallel computations in thousands of threads (i’m talking about regular consumer computers here) change the way of thinking. Okay, let us start: first of all we need to know what the [barycentric coordinates](https://en.wikipedia.org/wiki/Barycentric_coordinate_system) are. Given a 2D triangle ABC and a point P, all in old good Cartesian coordinates `(xy)`. Our goal is to find barycentric coordinates of the point P with respect to the triangle ABC. It means that we look for three numbers `(1 − u − v,u,v)` such that we can find the point P as follows: ![ ](./img/lesson2_f1.png) While being a bit frightening at the first glance, it is really simple: imagine that we put three weights `(1−u−v,u,v)` at the vertices A, B and C, respectively. Then the barycenter of the system is exactly in the point P. We can say the same thing with other words: the point P has coordinates `(u,v)` in the (oblique) basis (A,![](./img/lesson2_ab.png),![](./img/lesson2_ac.png)): ![ ](./img/lesson2_f2.png) So, we have vectors ![](./img/lesson2_ab.png), ![](./img/lesson2_ac.png) and ![](./img/lesson2_ap.png), we need to find two real numbers u and v respecting the following constraint: ![ ](./img/lesson2_f3.png) It is a simple vector equation, or a linear system of two equations with two variables: ![ ](./img/lesson2_f4.png) I am lazy and do not want to solve linear systems in a scholar way. Let us write it in matrix form: ![ ](./img/lesson2_f5.png) It means that we are looking for a vector `(u,v,1)` that is orthogonal to `(ABx,ACx,PAx)` and `(ABy,ACy,PAy)` *at the same time*! I hope you see [where I am heading](https://en.wikipedia.org/wiki/Cross_product). That is a small hint: to find an intersection of two straight lines in a plane (that is exactly what we did here), it is sufficient to compute one cross product. By the way, test yourself: how do we find an equation of a line passing through two given points? So, let us program our new rasterization routine: we iterate through all pixels of a bounding box for a given triangle. For each pixel we compute its barycentric coordinates. If it has at least one negative component, then the pixel is outside of the triangle. Probably it is more clear to see the program directly: ```csharp Vec3f Barycentric (Vec3f a, Vec3f b, Vec3f c, Vec2i p) { var pixel = new Vec3f { x = p.x + 0.5f, y = p.y + 0.5f }; var ab = b - a; var ac = c - a; var pa = a - pixel; var r = Cross (new Vec3f { x = ab.x, y = ac.x, z = pa.x }, new Vec3f { x = ab.y, y = ac.y, z = pa.y }); // triangle is degenerate, in this case return smth with negative coordinates if (Math.Abs (r.z) < 1) return new Vec3f { x = -1, y = 1, z = 1 }; return new Vec3f { x = 1 - r.x / r.z - r.y / r.z, y = r.x / r.z, z = r.y / r.z }; } void Triangle (Image image, Vec3f [] coordinates, Color color) { var t0 = coordinates [0]; var t1 = coordinates [1]; var t2 = coordinates [2]; var pMax = new Vec2i { x = (int)Math.Max (0, Math.Max (t0.x, Math.Max (t1.x, t2.x))), y = (int)Math.Max (0, Math.Max (t0.y, Math.Max (t1.y, t2.y))) }; var pMin = new Vec2i { x = (int)Math.Min (image.Width, Math.Min (t0.x, Math.Min (t1.x, t2.x))), y = (int)Math.Min (image.Height, Math.Min (t0.y, Math.Min (t1.y, t2.y))) }; Vec2i p; for (p.x = pMin.x; p.x <= pMax.x; p.x++) { for (p.y = pMin.y; p.y <= pMax.y; p.y++) { var bc = Barycentric (t0, t1, t2, p); if (bc.x < 0 || bc.y < 0 || bc.z < 0) continue; image [p.x, p.y] = color; } } } ``` # Flat shading render We already know how to draw a model with empty triangles. Let us fill them with a random color. This will help us to see how well we have encoded filling of triangles. Here is the code: ```csharp var image = new Image(width, height, Format.BGR); // Map world coordinates [-1..-1] to screen coordinates [0..width] Func map = v => new Vec3f { x = (int)((v.x+1)*image.Width/2), y = (int)((v.y+1)*image.Height/2) }; var rnd = new Random(); Func rndByte = () => (byte)rnd.Next(255); Func rndColor = () => new Color(rndByte(), rndByte(), rndByte()); var coordinates = new Vec3f[3]; foreach(var face in headModel.Faces) { for(int i=0; i<3; i++) { var vIndex = face.Vertices[i]; var v = headModel.Vertices[vIndex]; coordinates[i] = map(v); } Triangle(image, coordinates, rndColor()); } image.VerticalFlip (); image ``` Let us get rid of these clown-colors and put some lighting. Captain Obvious: ”*At the same light intensity, the polygon is illuminated most brightly when it is orthogonal to the light direction.*” Let us compare: ![ ](./img/lesson2_light1.jpeg) ![](./img/lesson2_light2.jpeg) We get zero illumination if the polygon is parallel to the vector of light. To paraphrase: the intensity of illumination is equal to the scalar product of the light vector and the normal to the given triangle. The normal to the triangle can be calculated simply as the [cross product](https://en.wikipedia.org/wiki/Cross_product) of its two sides. As a side note, at this course we will perform linear computations on the colors. However `(128,128,128)` color is not half as bright as `(255, 255, 255)`. We are going to ignore gamma correction and tolerate the incorrectness of the brightness of our colors. ```csharp var image = new Image (width, height, Format.BGR); var light_dir = new Vec3f { x = 0, y = 0, z = -1 }; var world = new Vec3f [3]; var screen = new Vec3f [3]; foreach (var face in headModel.Faces) { for (int i = 0; i < 3; i++) { var vIndex = face.Vertices [i]; world [i] = headModel.Vertices [vIndex]; screen [i] = map (world [i]); } var n = Cross (world [2] - world [0], world [1] - world [0]).Normalize (); var intensivity = Dot (n, light_dir); if (intensivity > 0) Triangle (image, screen, Color.White * intensivity); } image.VerticalFlip (); image ``` ================================================ FILE: graphics/tiny-renderer/lesson6bis.workbook/lesson3.csx ================================================ using static Geometry; var headTexture = Image.Load ("obj/african_head_diffuse.tga"); headTexture.VerticalFlip (); float [] InitZBuffer (Image image) { var zbuffer = new float [image.Width * image.Height]; for (int idx = 0; idx < zbuffer.Length; idx++) zbuffer [idx] = float.NegativeInfinity; return zbuffer; } Vec3f Barycentric (Vec2f a, Vec2f b, Vec2f c, Vec2f p) { var ab = b - a; var ac = c - a; var pa = a - p; var r = Cross (new Vec3f { x = ab.x, y = ac.x, z = pa.x }, new Vec3f { x = ab.y, y = ac.y, z = pa.y }); // triangle is degenerate, in this case return smth with negative coordinates // dont forget that r.z is integer. If it is zero then triangle ABC is degenerate if ((int)r.z == 0) return new Vec3f { x = -1, y = 1, z = 1 }; return new Vec3f { x = 1 - (r.x + r.y) / r.z, y = r.x / r.z, z = r.y / r.z }; } void Triangle (Image image, Vec3f [] coordinates, Image texture, Vec2f [] uv, float intensivity, float [] zbuffer) { Vec3f t0 = coordinates [0]; Vec3f t1 = coordinates [1]; Vec3f t2 = coordinates [2]; var pMax = new Vec2i { x = (int)Math.Max (0, Math.Max (t0.x, Math.Max (t1.x, t2.x))), y = (int)Math.Max (0, Math.Max (t0.y, Math.Max (t1.y, t2.y))) }; var pMin = new Vec2i { x = (int)Math.Min (image.Width, Math.Min (t0.x, Math.Min (t1.x, t2.x))), y = (int)Math.Min (image.Height, Math.Min (t0.y, Math.Min (t1.y, t2.y))) }; for (int x = pMin.x; x <= pMax.x; x++) { for (int y = pMin.y; y <= pMax.y; y++) { var pixelCenter = new Vec2f { x = x + 0.5f, y = y + 0.5f }; var bc = Barycentric (Project2D(t0), Project2D(t1), Project2D(t2), pixelCenter); if (bc.x < 0 || bc.y < 0 || bc.z < 0) continue; var z = t0.z * bc.x + t1.z * bc.y + t2.z * bc.z; var u = (int)(uv [0].x * bc.x + uv [1].x * bc.y + uv [2].x * bc.z); var v = (int)(uv [0].y * bc.x + uv [1].y * bc.y + uv [2].y * bc.z); var idx = x + y * image.Width; if (zbuffer [idx] < z) { zbuffer [idx] = z; var color = texture [u, v]; image [x, y] = color * intensivity; } } } } ================================================ FILE: graphics/tiny-renderer/lesson6bis.workbook/lesson3.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" #load "lesson1.csx" #load "lesson2.csx" using static Geometry; ``` # **Lesson 3: Hidden faces removal (z buffer)** # Introduction Hello, let me introduce you my friend z-buffer of a black guy. He will help us get rid of the visual artifacts of the hidden faces removal we had during the last lesson. ![](./img/lesson3_face1.png) By the way, i'd like to mention that this model i use heavily in the course is created by [Vidar Rapp](https://se.linkedin.com/in/vidarrapp). He kindely granted me a permission to use it for teaching rendering basics and i vandalized it, but i promise you to give back the eyes to the guy. Well, back to the topic, in theory we could just draw all the triangles without discarding any. If we do it properly starting rear-to-front, the front facets will erase the back ones. It is called the [painter's algorithm](http://en.wikipedia.org/wiki/Painter%27s_algorithm). Unfortunately, it comes along with a high computational cost: for each camera movement we need to re-sort all the scene. And then there are dynamic scenes... And this is not even the main problem. The main problem is it is not always possible to determine the correct order. # **Let us try to render a simple scene** Imagine a simple scene made of three triangles: the camera looks up-to-down, we project the colored triangles onto the white screen: ![ ](./img/lesson3_scene1.png) The render should look like this: ![ ](./img/lesson3_scene2.png) Blue facet - is it behind or in front of the red one? The painter's algorithm does not work here. It is possible to split blue facet in two (one in front of the red facet and one behind). And then the one in front of the red one is to be split in two - one in front of the green triangle and one behind... I think you get the problem: in scenes with millions of triangles it is really expensive to compute. It is possible to use [BSP trees](https://en.wikipedia.org/wiki/Binary_space_partitioning) to get it done. By the way, this data structure is constant for moving camera, but it is really messy. And the life is too short to get it messy. # **Even simpler: let us lose a dimension. Y-buffer!** Let us lose a dimension for a while and to cut the above scene along the yellow plane: ![ ](./img/lesson3_scene3.png) I mean, now our scene is made of three line segments (intersection of the yellow plane and each of the triangles), and the final render has a normal width but 1 pixel height: ![ ](./img/lesson3_scene4.png) Our scene is two-dimensional, so it is easy to draw it using the line() function we programmed in the very first lesson. ```csharp var scene = new Image (800, 500, Format.BGR); // scene "2d mesh" Line(scene, new Vec2i {x=20, y=34}, new Vec2i {x=744, y=400}, Color.Red); Line(scene, new Vec2i {x=120, y=434}, new Vec2i {x=444, y=400}, Color.Green); Line(scene, new Vec2i {x=330, y=463}, new Vec2i {x=594, y=200}, Color.Blue); // screen line Line(scene, new Vec2i {x=10, y=10}, new Vec2i{x=790, y=10}, Color.White); scene.VerticalFlip(); // I want to have the origin at the left bottom corner of the image scene // This is how our 2D scene looks like if we look at it sideways: ``` Let us render it. Recall that the render is 1 pixel height. In my source code I create images 16 pixels height for the ease of reading on high resolution screens. `Rasterize()` function writes only in the first line of the image `render` ```csharp void Rasterize(Image image, Vec2i p0, Vec2i p1, int[] ybuffer, Color color) { if (p0.x>p1.x) Swap(ref p0, ref p1); for (int x=p0.x; x<=p1.x; x++) { float t = (x-p0.x)/(float)(p1.x-p0.x); var y = (int)(p0.y*(1-t) + p1.y*t); if (ybuffer[x] < y) { ybuffer[x] = y; image[x, 0] = color; } } } var ybuffer = new int [width]; for (int i = 0; i < width; i++) ybuffer[i] = int.MinValue; var render = new Image (width, 16, Format.BGR); Rasterize(render, new Vec2i{x=20,y=34}, new Vec2i{x=744, y=400}, ybuffer, Color.Red); Rasterize(render, new Vec2i{x=120, y=434}, new Vec2i{x=444,y=400}, ybuffer, Color.Green); Rasterize(render, new Vec2i{x=330, y=463}, new Vec2i{x=594,y=200}, ybuffer, Color.Blue); render ``` It is really-really simple: I iterate through all x-coordinates between `p0.x` and `p1.x` and compute the corresponding y-coordinate of the segment. Then I check what we got in our array `ybuffer` with current `x` index. If the current `y`-value is closer to the camera than the value in the `ybuffer`, then I draw it on the screen and update the `ybuffer`. Let us see it step-by-step. After calling `Rasterize()` on the first (red) segment this is our memory: screen:![](./img/lesson3_rasterize1.png) ybuffer: ![ ](./img/lesson3_rasterize2.png) Here the magenta color indicates the minus infinity, those are places corresponding to the screen we did not touch. All the rest is shown in the shades of gray: clear colors are close to the camera, dark colors far from the camera. Then we draw the green segment. screen:![ ](./img/lesson3_rasterize3.png) ybuffer:![ ](./img/lesson3_rasterize4.png) And finally the blue one. screen:![ ](./img/lesson3_rasterize5.png) ybuffer:![ ](./img/lesson3_rasterize6.png) Congratulations, we just drew a 2D scene on a 1D screen! Let us admire once again the render: ![ ](./img/lesson3_rasterize7.png) # Back to 3D So, for drawing on a 2D screen the z-buffer must be two-dimensional: `var zbuffer = new int[width * height];` Personally I pack a two-dimensional buffer into a one-dimensional, the conversion is trivial: `var idx = x + y* width;` and the back one: `var x = idx % width;`\ `var y = idx % width;` Then in the code I simply iterate through all the triangles and call the rasterizer function with current triangle and a reference to the z-buffer. The only difficulty is how to compute the z-value of a pixel we want to draw. Let us recall how we computed the y-value in the y-buffer example: `int y = p0.y*(1-t) + p1.y*t;` What is the nature of the `t` variable? It turns out that `(1-t, t)` are barycentric coordinates of the point `(x,y)` with respect to the segment `p0, p1: (x,y) = p0*(1-t) + p1*t`. So the idea is to take the barycentric coordinates version of triangle rasterization, and for every pixel we want to draw simply to multiply its barycentric coordinates by the z-values of the vertices of the triangle we rasterize: ```csharp Vec3f Barycentric (Vec2f a, Vec2f b, Vec2f c, Vec2f p) { var ab = b - a; var ac = c - a; var pa = a - p; var r = Cross (new Vec3f { x = ab.x, y = ac.x, z = pa.x }, new Vec3f { x = ab.y, y = ac.y, z = pa.y }); // triangle is degenerate, in this case return smth with negative coordinates // dont forget that r.z is integer. If it is zero then triangle ABC is degenerate if ((int)r.z == 0) return new Vec3f { x = -1, y = 1, z = 1 }; return new Vec3f { x = 1 - (r.x + r.y) / r.z, y = r.x / r.z, z = r.y / r.z }; } void Triangle (Image image, Vec3f [] coordinates, Color color, float [] zbuffer) { Vec3f t0 = coordinates [0]; Vec3f t1 = coordinates [1]; Vec3f t2 = coordinates [2]; var pMax = new Vec2i { x = (int)Math.Max (0, Math.Max (t0.x, Math.Max (t1.x, t2.x))), y = (int)Math.Max (0, Math.Max (t0.y, Math.Max (t1.y, t2.y))) }; var pMin = new Vec2i { x = (int)Math.Min (image.Width, Math.Min (t0.x, Math.Min (t1.x, t2.x))), y = (int)Math.Min (image.Height, Math.Min (t0.y, Math.Min (t1.y, t2.y))) }; for (int x = pMin.x; x <= pMax.x; x++) { for (int y = pMin.y; y <= pMax.y; y++) { var pixelCenter = new Vec2f { x = x + 0.5f, y = y + 0.5f }; var bc = Barycentric (Project2D (t0), Project2D (t1), Project2D (t2), pixelCenter); if (bc.x < 0 || bc.y < 0 || bc.z < 0) continue; var z = t0.z * bc.x + t1.z * bc.y + t2.z * bc.z; var idx = x + y * image.Width; if (zbuffer [idx] < z) { zbuffer [idx] = z; image [x, y] = color; } } } } float [] InitZBuffer (Image image) { var zbuffer = new float [image.Width * image.Height]; for (int idx = 0; idx < zbuffer.Length; idx++) zbuffer [idx] = float.NegativeInfinity; return zbuffer; } var image = new Image(width, height, Format.BGR); Func map = v => new Vec3f { x = (int)((v.x+1)*(image.Width-1)/2 + 0.5f), y = (int)((v.y+1)*(image.Height-1)/2 + 0.5f), z = v.z }; var zbuffer = InitZBuffer(image); foreach(var face in headModel.Faces) { for(int i=0; i<3; i++) { var vIndex = face.Vertices[i]; world[i] = headModel.Vertices[vIndex]; screen[i] = map(world[i]); } Vec3f n = Cross(world[2] - world[0], world[1] - world[0]).Normalize (); var intensivity = Dot(n, light_dir); if(intensivity > 0) Triangle(image, screen, Color.White * intensivity, zbuffer); } image.VerticalFlip (); image ``` # Okay, we just interpolated the z-values. What else can we do? Texture! In the `.obj` file we have lines starting with `vt u v`, they give an array of texture coordinates. The number in the middle (between the slashes) in the facet lines\ `f x/x/x x/x/x x/x/x` are the texture coordinates of this vertex of this triangle. Interpolate it inside the triangle, multiply by the width-height of the texture image and you will get the color to put in your render. ```csharp void Triangle (Image image, Vec3f [] coordinates, Image texture, Vec2f [] uv, float intensivity, float [] zbuffer) { Vec3f t0 = coordinates [0]; Vec3f t1 = coordinates [1]; Vec3f t2 = coordinates [2]; var pMax = new Vec2i { x = (int)Math.Max (0, Math.Max (t0.x, Math.Max (t1.x, t2.x))), y = (int)Math.Max (0, Math.Max (t0.y, Math.Max (t1.y, t2.y))) }; var pMin = new Vec2i { x = (int)Math.Min (image.Width, Math.Min (t0.x, Math.Min (t1.x, t2.x))), y = (int)Math.Min (image.Height, Math.Min (t0.y, Math.Min (t1.y, t2.y))) }; for (int x = pMin.x; x <= pMax.x; x++) { for (int y = pMin.y; y <= pMax.y; y++) { var pixelCenter = new Vec2f { x = x + 0.5f, y = y + 0.5f }; var bc = Barycentric (Project2D(t0), Project2D(t1), Project2D(t2), pixelCenter); if (bc.x < 0 || bc.y < 0 || bc.z < 0) continue; var z = t0.z * bc.x + t1.z * bc.y + t2.z * bc.z; var u = (int)(uv [0].x * bc.x + uv [1].x * bc.y + uv [2].x * bc.z); var v = (int)(uv [0].y * bc.x + uv [1].y * bc.y + uv [2].y * bc.z); var idx = x + y * image.Width; if (zbuffer [idx] < z) { zbuffer [idx] = z; var color = texture [u, v]; image [x, y] = color * intensivity; } } } } var image = new Image(width, height, Format.BGR); var headTexture = Image.Load ("obj/african_head_diffuse.tga"); headTexture.VerticalFlip (); Func uvMap = v => new Vec2f { x = v.x * (headTexture.Width - 1), y = v.y * (headTexture.Height - 1) }; var zbuffer = InitZBuffer(image); var uv = new Vec2f[3]; var model = headModel; foreach(var face in model.Faces) { for(int i=0; i<3; i++) { var vIndex = face.Vertices[i]; world[i] = model.Vertices[vIndex]; screen[i] = map(world[i]); var tIndex = face.Textures[i]; uv[i] = uvMap(model.Textures[tIndex]); } Vec3f n = Cross(world[2] - world[0], world[1] - world[0]).Normalize (); var intensivity = Dot(n, light_dir); if(intensivity > 0) Triangle(image, screen, headTexture, uv, intensivity, zbuffer); } image.VerticalFlip (); image ``` ================================================ FILE: graphics/tiny-renderer/lesson6bis.workbook/lesson4.csx ================================================ Vec2f[] uv = new Vec2f [3]; Func uvMap = (texture, v) => new Vec2f { x = v.x * (texture.Width - 1), y = v.y * (texture.Height - 1) }; Matrix4 Viewport (int x, int y, int w, int h) { var depth = 255f; var m = Matrix4.Identity (); m [0, 3] = x + w / 2f; m [1, 3] = y + h / 2f; m [2, 3] = depth / 2f; m [0, 0] = w / 2f; m [1, 1] = h / 2f; m [2, 2] = depth / 2f; return m; } Matrix4 Projection (float coeff) { var projection = Matrix4.Identity (); projection [3, 2] = coeff; return projection; } ================================================ FILE: graphics/tiny-renderer/lesson6bis.workbook/lesson4.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Matrix.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" #load "lesson1.csx" #load "lesson2.csx" #load "lesson3.csx" using static Geometry; using static MatrixHelpers; ``` # **Lesson 4: Perspective projection** # The goal In previous lessons we rendered our model in orthographic projection by simply forgetting the z-coordinate. The goal for today is to learn how to draw in perspective: ![ ](./img/lesson4_the_goal.png) # 2D geometry: Linear transformations A linear transformation on a plane can be represented by a corresponding matrix. If we take a point `(x,y)` then its transformation can be written as follows: ![ ](./img/lesson4_formula1.svg) The simplest (not degenerate) transformation is the identity, it does not move any point: ![ ](./img/lesson4_formula_2d_identity.svg) Diagonal coefficients of the matrix give scaling along coordinate axes. Let us illustrate it, if we take the following transformation: ![ ](./img/lesson4_formula_2d_scale.svg) Then the white object (the white square with one corner chopped) will be transformed into the yellow one. Red and green line segments give unit length vectors aligned with `x` and `y`, respectively. All the images for this article were generated using this code: ```csharp Matrix4 Viewport (int x, int y, int w, int h) { var depth = 255f; var m = Matrix4.Identity (); m [0, 3] = x + w / 2f; m [1, 3] = y + h / 2f; m [2, 3] = depth / 2f; m [0, 0] = w / 2f; m [1, 1] = h / 2f; m [2, 2] = depth / 2f; return m; } Matrix4 Projection (float coeff) { var projection = Matrix4.Identity (); projection [3, 2] = coeff; return projection; } Vec4f Embed4D (Vec3f v, float fill = 1) { return new Vec4f { x = v.x, y = v.y, z = v.z, h = fill }; } Vec3f Project3D (Vec4f v) { return new Vec3f { x = v.x, y = v.y, z = v.z }; } Func map = v => Project3D(v/v.h); void RenderAxes (Image image) { var w = image.Width; var h = image.Height; var vp = Viewport(w/4, w/4, w/2, h/2); // draw the axes var x = new Vec3f { x = 1 }; var y = new Vec3f { y = 1 }; var o = new Vec3f (); o = map(Mult(vp, Embed4D(o))); x = map(Mult(vp, Embed4D(x))); y = map(Mult(vp, Embed4D(y))); Line(image, o, x, Color.Red); Line(image, o, y, Color.Green); } var cube = Model.FromFile("obj/cube.obj"); void RenderCube(Image image, Matrix4 deformation, Color color) { var w = image.Width; var h = image.Height; var vp = Viewport(w/4, w/4, w/2, h/2); var face = cube.Faces[0]; var faceLen = face.Vertices.Length; for(int j=0; j x/(c-z) = x'/c. In other words: ![ ](./img/lesson4_formula_x.svg) By doing the same reasoning for triangles CPB and CP'D, it is easy to find the following expression: ![](./img/lesson4_formula_y.svg) It is really similar to the result we put aside few moments ago, but there we got the result by a single matrix multiplication. We got the law for the coefficient: `r = -1/c` # Let us sum up: the main formula for today *If you simply copy-paste this formula without understanding the above material, I hate you.* So, if we want to compute a central projection with a camera **(important!) camera located on the z-axis with distance c from the origin**, then we embed the point into 4D by augmenting it with 1, then we multiply it with the following matrix, and retro-project it into 3D. ![ ](./img/lesson4_formula_last.svg) We deformed our object in a way, that simply forgetting its z-coordinate we will get a drawing in a perspective. If we want to use the z-buffer, then, naturally, do not forget the z: ```csharp var image = new Image(width, height, Format.BGR); var camera = new Vec3f { z = 3 }; var projection = Projection(-1/camera.z); var viewPort = Viewport(width/8, height/8, width*3/4, height*3/4); Func map = v => { var r4 = Mult (viewPort * projection, Embed4D (v)); var r = Project3D (r4 / r4.h); r.x = (int)(r.x + 0.5f); r.y = (int)(r.y + 0.5f); return r; }; Func uvMap = (texture, v) => new Vec2f { x = v.x * (texture.Width - 1), y = v.y * (texture.Height - 1) }; var model = headModel; var zbuffer = InitZBuffer(image); Vec2f[] uv = new Vec2f [3]; foreach(var face in model.Faces) { for(int i=0; i<3; i++) { var vIndex = face.Vertices[i]; world[i] = model.Vertices[vIndex]; screen[i] = map(world[i]); var tIndex = face.Textures[i]; uv[i] = uvMap(headTexture, model.Textures[tIndex]); } Vec3f n = Cross(world[2] - world[0], world[1] - world[0]).Normalize (); var intensivity = Dot(n, light_dir); if(intensivity > 0) Triangle(image, screen, headTexture, uv, intensivity, zbuffer); } image.VerticalFlip (); image ``` ================================================ FILE: graphics/tiny-renderer/lesson6bis.workbook/lesson5.csx ================================================ using static Geometry; var eye = new Vec3f { x = 1, y = 1, z = 3 }; var center = new Vec3f { x = 0, y = 0, z = 0 }; var up = new Vec3f { x = 0, y = 1, z = 0 }; Matrix4 LookAt (Vec3f eye, Vec3f center, Vec3f up) { var z = (eye - center).Normalize (); var x = Cross (up, z).Normalize (); var y = Cross (z, x).Normalize (); var Minv = Matrix4.Identity (); Minv [0, 0] = x.x; Minv [0, 1] = x.y; Minv [0, 2] = x.z; Minv [1, 0] = y.x; Minv [1, 1] = y.y; Minv [1, 2] = y.z; Minv [2, 0] = z.x; Minv [2, 1] = z.y; Minv [2, 2] = z.z; var Tr = Matrix4.Identity (); Tr [0, 3] = -center.x; Tr [1, 3] = -center.y; Tr [2, 3] = -center.y; return Minv * Tr; } ================================================ FILE: graphics/tiny-renderer/lesson6bis.workbook/lesson5.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Matrix.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" #load "lesson1.csx" #load "lesson2.csx" #load "lesson3.csx" #load "lesson4.csx" using static Geometry; using static MatrixHelpers; ``` # Lesson 5: Moving the camera # Change of basis in 3D space In Euclidean space coordinates can be given by a point (the origin) and a basis. What does it mean that point P has coordinates `(x,y,z)` in the frame `(O, i,j,k)`? It means that the vector OP can be expressed as follows: ![ ](./img/lesson5_basis.svg) Now image that we have another frame `(O', i',j',k')`. How do we transform coordinates given in one frame to another? First of all let us note that since `(i,j,k)` and `(i',j',k')` are bases of 3D, there exists a (non degenerate) matrix M such that: ![ ](./img/lesson5_new_basis.svg) Let us draw an illustration: ![](./img/lesson5_sketch1.png) Then let us re-express the vector OP: ![ ](./img/lesson5_change_basis1.svg) Now let us substitute `(i',j',k')` in the right part with the change of basis matrix: ![ ](./img/lesson5_change_basis2.svg) And it gives us the formula to transform coordinates from one frame to another: ![ ](./img/lesson5_change_basis3.svg) # Let us create our own gluLookAt OpenGL and, as a consequence, our tiny renderer are able to draw scenes **only with the camera located on the z-axis.** If we want to move the camera, no problem, we can move all the scene, leaving the camera immobile. Let us put the problem this way: we want to draw a scene with a camera situated in point **e**(eye), the camera should be pointed to the point **c** (center) in such way that a given vector **u**(up) is to be vertical in the final render. Here is an illustration: ![ ](./img/lesson5_change_basis4.png) ```csharp Matrix4 LookAt (Vec3f eye, Vec3f center, Vec3f up) { var z = (eye - center).Normalize (); var x = Cross (up, z).Normalize (); var y = Cross (z, x).Normalize (); var Minv = Matrix4.Identity (); Minv [0, 0] = x.x; Minv [0, 1] = x.y; Minv [0, 2] = x.z; Minv [1, 0] = y.x; Minv [1, 1] = y.y; Minv [1, 2] = y.z; Minv [2, 0] = z.x; Minv [2, 1] = z.y; Minv [2, 2] = z.z; var Tr = Matrix4.Identity (); Tr [0, 3] = -center.x; Tr [1, 3] = -center.y; Tr [2, 3] = -center.y; return Minv * Tr; } ``` Note that `z'` is given by the vector **`ce`** (do not forget to normalize it, it helps later). How do we compute `x'`? Simply by a cross product between **`u`** and **`z'`**. Then we compute `y'`, such that it is orthogonal to already calculated `x'` and `z'` (let me remind you that in our problem settings \*\*`ce` \*\*and **`u`** are not necessarily orthogonal). The very last step is a translation of the origin to the center **c** and our transformation matrix is ready. Now it suffices to get any point with coordinates `(x,y,z,1)` in the model frame, multiply it by the matrix ModelView and we get the coordinates in the camera frame! By the way, the name ModelView comes from OpenGL terminology. # Viewport If you followed this course from the beginning, you should remember strange lines like this one: ```csharp // x = (v.x+1)*(width-1)/2 // y = (v.y+1)*(height-1)/2 ``` What does it mean? It means that i have a point Vec2f v, it belongs to the square \[-1,1\]\*\[-1,1\]. I want to draw it in the image of (width, height) dimensions. Value (v.x\+1) is varying between 0 and 2, (v.x\+1)/2 between 0 and 1, and (v.x\+1)\*width/2 sweeps all the image. Thus we effectively mapped the bi-unit square onto the image. But now we are getting rid of these ugly constructs, and i want to rewrite all the computiations in the matrix form. Let us consider the following C# code: ```csharp /* Matrix4 Viewport (int x, int y, int w, int h) { var depth = 255f; var m = Matrix4.Identity (); m [0, 3] = x + w / 2f; m [1, 3] = y + h / 2f; m [2, 3] = depth / 2f; m [0, 0] = w / 2f; m [1, 1] = h / 2f; m [2, 2] = depth / 2f; return m; } */ ``` This code creates this matrix: ![ ](./img/lesson5_viewport.svg) It means that the bi-unit cube \[-1,1\]*\[-1,1\]*\[-1,1\] is mapped onto the screen cube \[0,w\]*\[0,h\]*\[0,d\]. Right, cube, and not a rectangle, this is because of the depth computations with the z-buffer. Here d is the resolution of the z-buffer. I like to have it equal to 255 because of simplicity of dumping black-and-white images of the z-buffer for debugging. In the OpenGL terminology this matrix is called viewport matrix. # Chain of coordinate transformations So, let us sum up. Our models (characters, for example) are created in their own local frame (**object coordinates**). They are inserted into a scene expressed in **world coordinates**. The transformation from one to another is made with matrix **Model**. Then, we want to express it in the camera frame (**eye coordinates**), the transformation is called **View**. Then, we deform the scene to create a perspective deformation with **Projection** matrix (lesson 4), this matrix transforms the scene to so-called **clip coordinates**. Finally, we draw the scene, and the matrix transforming clip coordinates to the **screen coordinates** is called **Viewport**. Again, if we read a point **v** from the .obj file, then to draw it on the screen it undergoes the following chain of transformations: Viewport \* Projection \* View \* Model \* v As i draw a single object only, the matrix Model is equal to identity, and i merged it with the matrix View: ```csharp var eye = new Vec3f { x = 1, y = 1, z = 3 }; var center = new Vec3f { x = 0, y = 0, z = 0 }; var up = new Vec3f { x = 0, y = 1, z = 0 }; // draw the model var modelView = LookAt(eye, center, up); var viewPort = Viewport(width/8, height/8, width*3/4, height*3/4); var projection = Projection(-1/(eye-center).Norm()); Func map = v => { var r4 = Mult (viewPort * projection * modelView, Embed4D (v)); var r = Project3D (r4 / r4.h); r.x = (int)(r.x + 0.5f); r.y = (int)(r.y + 0.5f); return r; }; var image = new Image(width, height, Format.BGR); var model = headModel; var zbuffer = InitZBuffer(image); foreach(var face in model.Faces) { for(int i=0; i<3; i++) { var vIndex = face.Vertices[i]; world[i] = model.Vertices[vIndex]; screen[i] = map(world[i]); var tIndex = face.Textures[i]; uv[i] = uvMap(headTexture, model.Textures[tIndex]); } Vec3f n = Cross(world[2] - world[0], world[1] - world[0]).Normalize (); var intensivity = Dot(n, light_dir); if(intensivity > 0) Triangle(image, screen, headTexture, uv, intensivity, zbuffer); } image.VerticalFlip (); image ``` # Transformation of normal vectors There is a widely-known fact: * If we have a model and its normal vectors are given by the artist AND this model is transformed with an affine mapping, then normal vectors are to be transformed with a mapping, equal to the transposition of the inverse matrix of the original mapping matrix What-what-what?! I met quite a few programmers who know this fact, but it remains a black magic for them. In fact, it is not so complicated. Take a pencil and draw a 2D triangle `(0,0)`, `(0,1)`, `(1,0)` and a vector **n**, normal to the hypothenuse. Naturally, **n** is equal to `(1,1)`. Then let us stretch all the y-coordinates by a factor of 2, leaving x-coordinates intact. Thus, our triangle becomes `(0,0)`, `(0,2)`, `(1,0)`. If we transform the vector **n** in the same way, it becomes `(1, 2)` and it is no longer orthogonal to the transformed edge of the triangle. Thus, to remove all the black magic fog, we need to understand one simple thing: **we do not need to simply transform normal vectors (as they can become not normal anymore), we need to compute (new) normal vectors to the transformed model.** Back to 3D, we have a vector **n** = (A,B,C). We know that the plane passing through the origin and having **n** for its normal, has an equation `Ax+By+Cz=0`. Let us write it in the matrix form (i do it in homogeneous coordinates from the beginning): ![ ](./img/lesson5_transform_normal1.png) Recall that `(A,B,C)` - is a vector, so we augment it with 0 when embedding into the 4D, and `(x,y,z)` is augmented with 1 since it is a point. Let us insert an identity matrix in between (inverse to M multiplied by M is equal to identity): ![ ](./img/lesson5_transform_normal2.png) The expression in right parentheses - are for the transformed points of the object. In the left - are for normal vectors to the transformed object! In standard convention we usually write coordinates as columns (please let us not raise all the stuff about contra- and co-variant vectors), so we can rewrite the previous expression as follows: ![ ](./img/lesson5_transform_normal2.png) And the left parentheses tell us that a normal to the transformed object can be computed from the old normal by applying the inverse transpose matrix of the affine mapping. Please note that if our transformation matrix M is a composition of uniform scalings, rotations and translations, then M is equal to its inverse transpose, since inverse and transpose are cancelling each other in this case. But since our matrices include perspective deformations, usually this trick does not help. In the current code we do not use the transformation of normal vectors, but in the next lesson it will be very, very handy. Happy coding! ================================================ FILE: graphics/tiny-renderer/lesson6bis.workbook/lesson6.csx ================================================ using static Geometry; using static MatrixHelpers; using static ShaderUtils; var diabloModel = Model.FromFile ("obj/diablo3_pose.obj"); var diabloTexture = Image.Load ("obj/diablo3_pose_diffuse.tga"); var diabloNormalMap = Image.Load ("obj/diablo3_pose_nm.tga"); var diabloTangentMap = Image.Load ("obj/diablo3_pose_nm_tangent.tga"); var diabloSpecularMap = Image.Load ("obj/diablo3_pose_spec.tga"); diabloTexture.VerticalFlip (); diabloNormalMap.VerticalFlip (); diabloTangentMap.VerticalFlip (); diabloSpecularMap.VerticalFlip (); light_dir = new Vec3f { x = 1, y = 1, z = 1 }; eye = new Vec3f { x = 1, y = 1, z = 3 }; center = new Vec3f { x = 0, y = 0, z = 0 }; up = new Vec3f { x = 0, y = 1, z = 0 }; var modelView = LookAt(eye, center, up); var viewPort = Viewport(width/8, height/8, width*3/4, height*3/4); var projection = Projection(-1f/(eye-center).Norm()); interface IShader { Vec4f Vertex (Face face, int nthvert); bool Fragment (Vec3f fragment, Vec3f bar, out Color color); }; class RenderResult { public Image Image { get; set; } public float [] ZBuffer { get; set; } } RenderResult Render (Model model, IShader shader) { var image = new Image (width, height, Format.BGR); var zbuffer = InitZBuffer (image); var screen_coords = new Vec4f [3]; foreach (var face in model.Faces) { for (int i = 0; i < 3; i++) screen_coords [i] = shader.Vertex (face, i); Triangle (image, screen_coords, shader, zbuffer); } return new RenderResult { Image = image, ZBuffer = zbuffer }; } void Box (Vec4f [] pts, out Vec2i pMin, out Vec2i pMax) { pMax = new Vec2i { x = int.MinValue, y = int.MinValue }; pMin = new Vec2i { x = int.MaxValue, y = int.MaxValue }; for (int i = 0; i < 3; i++) { pMax.x = (int)Math.Max (pMax.x, pts [i].x / pts [i].h); pMax.y = (int)Math.Max (pMax.y, pts [i].y / pts [i].h); pMin.x = (int)Math.Min (pMin.x, pts [i].x / pts [i].h); pMin.y = (int)Math.Min (pMin.y, pts [i].y / pts [i].h); } } void Triangle (Image image, Vec4f [] pts, IShader shader, float [] zbuffer) { Vec2i pMin, pMax; Box (pts, out pMin, out pMax); Color color; for (int x = pMin.x; x <= pMax.x; x++) { for (int y = pMin.y; y <= pMax.y; y++) { var pixelCenter = new Vec2f { x = x + 0.5f, y = y + 0.5f }; var bc = Barycentric (Project2D (pts [0] / pts [0].h), Project2D (pts [1] / pts [1].h), Project2D (pts [2] / pts [2].h), pixelCenter); var z = pts [0].z * bc.x + pts [1].z * bc.y + pts [2].z * bc.z; // z [0..255] var w = pts [0].h * bc.x + pts [1].h * bc.y + pts [2].h * bc.z; var frag_depth = z / w; var idx = x + y * image.Width; if (bc.x < 0 || bc.y < 0 || bc.z < 0 || zbuffer[idx] > frag_depth) continue; var fragment = new Vec3f { x = x, y = y, z = frag_depth }; var discard = shader.Fragment (fragment, bc, out color); if (!discard) { zbuffer [idx] = frag_depth; image [x, y] = color; } } } } static class ShaderUtils { public static Vec4f TransformFace (Model model, Face face, int nthvert, Matrix4 t) { var v = model.Vertex (face, nthvert); // read the vertex from model var glVertex = Embed4D (v); return Mult (t, glVertex); // transform it to screen coordinates } public static void UpdateVarayingUV (Model model, Face face, int nthvert, ref Vec3f varyingU, ref Vec3f varyingV) { var vt = model.GetUV (face, nthvert); varyingU [nthvert] = vt.x; varyingV [nthvert] = vt.y; } public static Vec2f CalcUV (Vec3f varU, Vec3f varV, Vec3f bar) { return new Vec2f { x = Dot (varU, bar), y = Dot (varV, bar) }; } public static Color GetColor (Image texture, Vec2f uvf) { var uvi = CalcXY(texture, uvf); return texture [uvi.x, uvi.y]; } public static Vec3f Transform (Matrix4 t, Vec3f v) { var v4d = Mult (t, Embed4D (v)); return Project3D (v4d); } public static Vec3f Normal (Image normalMap, Vec2f uvf) { // RGB values as xyz. But Color stores data as BGR (zyx) var c = GetColor (normalMap, uvf); return new Vec3f { x = (c [2] / 255f) * 2 - 1, y = (c [1] / 255f) * 2 - 1, z = (c [0] / 255f) * 2 - 1 }; } public static float Specular (Image specularMap, Vec2f uvf) { var uvi = CalcXY (specularMap, uvf); var color = specularMap [uvi.x, uvi.y]; return color[0]; } public static Vec2i CalcXY (Image texture, Vec2f uvf) { return new Vec2i { x = (int)(uvf.x * texture.Width), y = (int)(uvf.y * texture.Height) }; } } class TextureShader : IShader { readonly Model model; readonly Vec3f lightDir; readonly Matrix4 transformation; readonly Image texture; // written by vertex shader, read by fragment shader Vec3f varyingIntensity = new Vec3f (); Vec3f varyingU = new Vec3f (); Vec3f varyingV = new Vec3f (); public TextureShader (Model model, Matrix4 viewPort, Matrix4 projection, Matrix4 modelView, Vec3f lightDir, Image texture) { this.model = model; transformation = viewPort * projection * modelView; this.lightDir = lightDir.Normalize (); this.texture = texture; } public Vec4f Vertex (Face face, int nthvert) { UpdateVarayingUV (model, face, nthvert, ref varyingU, ref varyingV); var n = model.Normal (face, nthvert).Normalize (); varyingIntensity [nthvert] = Math.Max (0, Dot (n, lightDir)); // get diffuse lighting intensity return TransformFace (model, face, nthvert, transformation); } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { // interpolate intensity for the current pixel var intensity = Dot (varyingIntensity, bar); // interpolate uv for the current pixel var uvf = CalcUV (varyingU, varyingV, bar); color = GetColor (texture, uvf) * intensity; return false; } } ================================================ FILE: graphics/tiny-renderer/lesson6bis.workbook/lesson6.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Matrix.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" #load "lesson1.csx" #load "lesson2.csx" #load "lesson3.csx" #load "lesson4.csx" #load "lesson5.csx" using static Geometry; using static MatrixHelpers; ``` # **Lesson 6: Shaders for the software renderer** Refactoring the source code. IShader. ```csharp interface IShader { Vec4f Vertex (Face face, int nthvert); bool Fragment (Vec3f fragment, Vec3f bar, out Color color); }; class RenderResult { public Image Image { get; set; } public float [] ZBuffer { get; set; } } RenderResult Render (Model model, IShader shader) { var image = new Image (width, height, Format.BGR); var zbuffer = InitZBuffer (image); var screen_coords = new Vec4f [3]; foreach (var face in model.Faces) { for (int i = 0; i < 3; i++) screen_coords [i] = shader.Vertex (face, i); Triangle (image, screen_coords, shader, zbuffer); } return new RenderResult { Image = image, ZBuffer = zbuffer }; } void Box (Vec4f [] pts, out Vec2i pMin, out Vec2i pMax) { pMax = new Vec2i { x = int.MinValue, y = int.MinValue }; pMin = new Vec2i { x = int.MaxValue, y = int.MaxValue }; for (int i = 0; i < 3; i++) { pMax.x = (int)Math.Max (pMax.x, pts [i].x / pts [i].h); pMax.y = (int)Math.Max (pMax.y, pts [i].y / pts [i].h); pMin.x = (int)Math.Min (pMin.x, pts [i].x / pts [i].h); pMin.y = (int)Math.Min (pMin.y, pts [i].y / pts [i].h); } } void Triangle (Image image, Vec4f [] pts, IShader shader, float [] zbuffer) { Vec2i pMin, pMax; Box (pts, out pMin, out pMax); Color color; for (int x = pMin.x; x <= pMax.x; x++) { for (int y = pMin.y; y <= pMax.y; y++) { var pixelCenter = new Vec2f { x = x + 0.5f, y = y + 0.5f }; var bc = Barycentric (Project2D (pts [0] / pts [0].h), Project2D (pts [1] / pts [1].h), Project2D (pts [2] / pts [2].h), pixelCenter); var z = pts [0].z * bc.x + pts [1].z * bc.y + pts [2].z * bc.z; // z [0..255] var w = pts [0].h * bc.x + pts [1].h * bc.y + pts [2].h * bc.z; var frag_depth = z / w; var idx = x + y * image.Width; if (bc.x < 0 || bc.y < 0 || bc.z < 0 || zbuffer[idx] > frag_depth) continue; var fragment = new Vec3f { x = x, y = y, z = frag_depth }; var discard = shader.Fragment (fragment, bc, out color); if (!discard) { zbuffer [idx] = frag_depth; image [x, y] = color; } } } } ``` Let us see how it works. The actual render code: * Parsing the .obj file * Iteration through all triangles of the model and rasterization of each triangle. The last step is the most interesting. Outer loop iterates through all the triangles. Inner loop iterates through all the vertices of the current triangle and calls a vertex shader for each vertex. **The main goal of the vertex shader is to transform the coordinates of the vertices. The secondary goal is to prepare data for the fragment shader.** What happens after that? We call the rasterization routine. What happens inside the rasterizer we do not know (well, okay, we do know since we programmed it!) with one exception. We know that the rasterizer calls **our** routine for each pixel, namely, the fragment shader. Again, for each pixel inside the triangle the rasterizer calls our own callback, the fragment shader. **The main goal of the fragment shader - is to determine the color of the current pixel. Secondary goal - we can discard current pixel by returning true.** The rendering pipeline for the OpenGL 2 can be represented as follows (in fact, it is more or less the same for newer versions too): ![ ](./img/lesson6_opengl2_pipeline.png) Because of the time limits I have for my course, I restrict myself to the OpenGL 2 pipeline and therefore to fragment and vertex shaders only. In newer versions of OpenGL there are other shaders, allowing, for example, to generate geometry on the fly. Okay, in the above image all the stages we can not touch are shown in blue, whereas our callbacks are shown in orange. In fact, our render code - is the \*\*primitive processing \*\*routine. It calls the vertex shader. We do not have primitive assembly here, since we are drawing dumb triangles only (in our code it is merged with the primitive processing). `Triangle` function - is the **rasterizer**, for each point inside the triangle it calls the **fragment shader**, then performs depth checks (z-buffer) and such. That is all. You know what the shaders are and now you can create your own shaders. # **My implementation of shaders shown on Gouraud shading** According to its name, it is a Gouraud shader. Here is the code: ```csharp using static ShaderUtils; class GouraudShader : IShader { readonly Model model; readonly Vec3f lightDir; // written by vertex shader, read by fragment shader protected Vec3f varyingIntensity = new Vec3f (); readonly Matrix4 transformation; public GouraudShader (Model model, Matrix4 viewPort, Matrix4 projection, Matrix4 modelView, Vec3f lightDir) { this.model = model; transformation = viewPort * projection * modelView; this.lightDir = lightDir.Normalize (); } public virtual Vec4f Vertex (Face face, int nthvert) { var n = model.Normal (face, nthvert).Normalize (); // get diffuse lighting intensity varyingIntensity [nthvert] = Math.Max (0, Dot (n, lightDir)); var d = Dot(n, lightDir); return TransformFace (model, face, nthvert, transformation); } public virtual bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { // interpolate intensity for the current pixel var intensity = Dot (varyingIntensity, bar); color = Color.White * intensity; // well duh return false; } } // set of utils which will be used in our shaders static class ShaderUtils { public static Vec4f TransformFace (Model model, Face face, int nthvert, Matrix4 t) { var v = model.Vertex (face, nthvert); // read the vertex from model var glVertex = Embed4D (v); return Mult (t, glVertex); // transform it to screen coordinates } public static void UpdateVarayingUV (Model model, Face face, int nthvert, ref Vec3f varyingU, ref Vec3f varyingV) { var vt = model.GetUV (face, nthvert); varyingU [nthvert] = vt.x; varyingV [nthvert] = vt.y; } public static Vec2f CalcUV (Vec3f varU, Vec3f varV, Vec3f bar) { return new Vec2f { x = Dot (varU, bar), y = Dot (varV, bar) }; } public static Color GetColor (Image texture, Vec2f uvf) { var uvi = CalcXY(texture, uvf); return texture [uvi.x, uvi.y]; } public static Vec3f Transform (Matrix4 t, Vec3f v) { var v4d = Mult (t, Embed4D (v)); return Project3D (v4d); } public static Vec3f Normal (Image normalMap, Vec2f uvf) { // RGB values as xyz. But Color stores data as BGR (zyx) var c = GetColor (normalMap, uvf); return new Vec3f { x = (c [2] / 255f) * 2 - 1, y = (c [1] / 255f) * 2 - 1, z = (c [0] / 255f) * 2 - 1 }; } public static float Specular (Image specularMap, Vec2f uvf) { var uvi = CalcXY (specularMap, uvf); var color = specularMap [uvi.x, uvi.y]; return color[0]; } public static Vec2i CalcXY (Image texture, Vec2f uvf) { return new Vec2i { x = (int)(uvf.x * texture.Width), y = (int)(uvf.y * texture.Height) }; } } var light_dir = new Vec3f { x = 1, y = 1, z = 1 }; var eye = new Vec3f { x = 1, y = 1, z = 3 }; var center = new Vec3f { x = 0, y = 0, z = 0 }; var up = new Vec3f { x = 0, y = 1, z = 0 }; var modelView = LookAt(eye, center, up); var viewPort = Viewport(width/8, height/8, width*3/4, height*3/4); var projection = Projection(-1f/(eye-center).Norm()); var shader = new GouraudShader (headModel, viewPort, projection, modelView, light_dir); var image = Render (headModel, shader).Image; image.VerticalFlip(); image ``` **vayring** is a reserved keyword in GLSL language, I have used VaryingIntensity as a name in order to show the correspondence. In varying variables we store data to be interpolated inside the triangle, and the fragment shaders get the interpolated value (for the current pixel). Fragment routine is called for each pixel inside the triangle we draw; as an input it receives [barycentric coordinates](https://en.wikipedia.org/wiki/Barycentric_coordinate_system) for interpolation of VaryingXXX data. Thus, interpolated intensity can be computed as: VaryingIntensity\[0\]\*bar\[0\] \+ VaryingIntensity\[1\]\*bar\[1\] \+ VaryingIntensity\[2\]\*bar\[2\] or simply as a dot product between two vectors: `Dot(VaryingIntensity,bar)`. In true GLSL, of course, fragment shaders receive ready interpolated values. Notice that the shader returns a bool value. It is easy to understand what it does if we look inside the updated rasterizer: ```csharp /* ... var discard = shader.Fragment (fragment, bc, out color); if (!discard) { zbuffer [idx] = frag_depth; image [x, y] = color; } */ ``` Fragment shader can discard drawing of the current pixel, then the rasterizer simply skips it. It is handy if we want to create binary masks or whatever you want. Of course, the rasterizer can not imagine all the weird stuff you could program, therefore it can not be pre-compiled with your shader. Here we use IShader interface as an intermediate between the two. # **First modification of the shaders** Simple modification of the Gourad shading, where the intensities are allowed to have 6 values only: ```csharp class GouraudShader6 : GouraudShader { public GouraudShader6 (Model model, Matrix4 viewPort, Matrix4 projection, Matrix4 modelView, Vec3f lightDir) : base (model, viewPort, projection, modelView, lightDir) { } public override bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { var intensity = Dot (varyingIntensity, bar); if (intensity > 0.85f) intensity = 1; else if (intensity > 0.60f) intensity = 0.80f; else if (intensity > 0.45f) intensity = 0.60f; else if (intensity > 0.30f) intensity = 0.45f; else if (intensity > 0.15f) intensity = 0.30f; else intensity = 0; color = new Color (255, 155, 0) * intensity; return false; } } var shader = new GouraudShader6 (headModel, viewPort, projection, modelView, light_dir); var image = Render (headModel, shader).Image; image.VerticalFlip(); image ``` # **Textures** I'll skip the [Phong shading](https://en.wikipedia.org/wiki/Phong_shading), but take a look at the article. Remember the homework assignment I gave you for texturing? We had to interpolate uv-coordinates. ```csharp using static ShaderUtils; class TextureShader : IShader { readonly Model model; readonly Vec3f lightDir; readonly Matrix4 transformation; readonly Image texture; // written by vertex shader, read by fragment shader Vec3f varyingIntensity = new Vec3f (); Vec3f varyingU = new Vec3f (); Vec3f varyingV = new Vec3f (); public TextureShader (Model model, Matrix4 viewPort, Matrix4 projection, Matrix4 modelView, Vec3f lightDir, Image texture) { this.model = model; transformation = viewPort * projection * modelView; this.lightDir = lightDir.Normalize (); this.texture = texture; } public Vec4f Vertex (Face face, int nthvert) { UpdateVarayingUV (model, face, nthvert, ref varyingU, ref varyingV); var n = model.Normal (face, nthvert).Normalize (); varyingIntensity [nthvert] = Math.Max (0, Dot (n, lightDir)); // get diffuse lighting intensity return TransformFace (model, face, nthvert, transformation); } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { // interpolate intensity for the current pixel var intensity = Dot (varyingIntensity, bar); // interpolate uv for the current pixel var uvf = CalcUV (varyingU, varyingV, bar); color = GetColor (texture, uvf) * intensity; return false; } } var shader = new TextureShader (headModel, viewPort, projection, modelView, light_dir, headTexture); var image = Render (headModel, shader).Image; image.VerticalFlip(); image ``` # **Normalmapping** Okay, now we have texture coordinates. What can we store in texture images? In fact, almost anything. It can be color, directions, temperature and so on. Let us load this texture: ![ ](./img/lesson6_african_head_nm.png) If we interpret RGB values as xyz directions, this image gives us normal vectors **for each pixel** of our render and not only per vertex as before. By the way, compare this image to another one, it gives exactly the same information, but in another frame: ![ ](./img/lesson6_african_head_nm_tangent.png) One of the images gives normal vectors in global (Cartesian) coordinate system, another one in [Darboux frame](https://en.wikipedia.org/wiki/Darboux_frame) (so-called tangent space). In Darboux frame the z-vector is normal to the object, x - principal curvature direction and y - their cross product. **Exercise 1:** Can you tell which image is represented in Darboux frame and which one is in the global coordinate frame? **Exercise 2:** Can you tell which representation is better and if yes, why is that? **Uniform** is a reserved keyword in GLSL, it allows to pass constants to the shaders. Here I pass the matrix Projection\*ModelView and its inverse transpose to transform the normal vectors (refer to the end of the lesson5). So, computation of the lighting intensity is the same as before with one exception: instead of interpolating normal vectors we retrieve the information from the normal mapping texture (do not forget to transform light vector and normal vectors). ```csharp class NormalMapShader : IShader { Vec3f varyingU = new Vec3f (); Vec3f varyingV = new Vec3f (); readonly Model model; readonly Vec3f lightDir; readonly Matrix4 uniformM; readonly Matrix4 uniformMIT; readonly Matrix4 transformation; readonly Image texture; readonly Image normalMap; public NormalMapShader (Model model, Matrix4 viewport, Matrix4 projection, Matrix4 modelView, Vec3f lightDir, Image texture, Image normalMap) { this.model = model; this.lightDir = lightDir.Normalize (); this.texture = texture; this.normalMap = normalMap; uniformM = projection * modelView; uniformMIT = TransposeInverse (uniformM); transformation = viewport * uniformM; } public Vec4f Vertex (Face face, int nthvert) { UpdateVarayingUV (model, face, nthvert, ref varyingU, ref varyingV); return TransformFace (model, face, nthvert, transformation); } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { var uv = CalcUV (varyingU, varyingV, bar); var n = Transform (uniformMIT, Normal (normalMap, uv)).Normalize (); var l = Transform (uniformM, lightDir).Normalize (); var intensity = Math.Max (0f, Dot (n, l)); color = GetColor (texture, uv) * intensity; return false; } } var headNormalMap = Image.Load ("obj/african_head_nm.tga"); headNormalMap.VerticalFlip (); var shader = new NormalMapShader (headModel, viewPort, projection, modelView, light_dir, headTexture, headNormalMap); var image = Render (headModel, shader).Image; image.VerticalFlip(); image ``` # **Specular mapping** Okay, let us continue the fun. All the computer graphics science is the art to cheat. To (cheaply) trick the eye we use the [Phong's approximation](https://en.wikipedia.org/wiki/Phong_reflection_model) of the lighting model. Phong proposed to consider the final lighting as a (weighted) sum of three light intensities: ambient lighting (constant per scene), diffuse lighting (the one we computed up to this moment) and specular lighting. Take a look at the following image, it speaks for itself: ![ ](./img/lesson6_phong.png) We compute diffuse lighting as a cosine of the angle between the normal vector and the light direction vector. I mean, this supposes that the light is reflected in all directions uniformly. What happens to glossy surfaces? In the limit case (mirror) the pixel is illuminated if and only if we can see the light source reflected by this pixel: ![ ](./img/lesson6_reflection.png) For diffuse lighting we computed the (cosine of) angle between vectors **n** and **l**, and now we are interested in the (cosine of) angle between vectors **r** (reflected light direction) and **v**(view direction). **Exercise 3:** Given vectors **n** and **l**, find vector **r**. *Answer:* If **n** and **l** are normalized, then **r** = 2**n**<**n**,**l**> - **l** For diffused lighting we computed the light intensity as the cosine. But a glossy surface reflects in one direction much more than in others! Okay then, what happens if we take tenth power of the cosine? Recall that all numbers inferior to 1 will decrease when we apply the power. It means that tenth power of the cosine will give smaller radius of the reflected beam. And hundredth power **much** smaller beam radius. This power is stored in a special texture (specular mapping texture) that tells for each point if it is glossy or not.\ \ I think that i do not need to comment anything in the below code at the exception of coefficients: `5 + color [i] * (diff + 1.3f * specular)` I took 5 for the ambient component, 1 for the diffuse component and 1.3 for the specular component. What coefficients to choose - is your choice. Different choices give different appearances for the object. Normally it is for the artist to decide. *Please note that normally the sum of the coefficents must be equal to 1, but you know. I like to create light.* ```csharp class SpecularShader : IShader { Vec3f varyingU = new Vec3f (); Vec3f varyingV = new Vec3f (); readonly Model model; readonly Vec3f lightDir; readonly Matrix4 uniformM; readonly Matrix4 uniformMIT; readonly Matrix4 transformation; readonly Image texture; readonly Image normalMap; readonly Image specularMap; public SpecularShader (Model model, Matrix4 viewport, Matrix4 projection, Matrix4 modelView, Vec3f lightDir, Image texture, Image normalMap, Image specularMap) { this.model = model; this.lightDir = lightDir.Normalize (); this.texture = texture; this.normalMap = normalMap; this.specularMap = specularMap; uniformM = projection * modelView; uniformMIT = TransposeInverse (uniformM); transformation = viewport * uniformM; } public Vec4f Vertex (Face face, int nthvert) { UpdateVarayingUV (model, face, nthvert, ref varyingU, ref varyingV); return TransformFace (model, face, nthvert, transformation); } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { var uv = CalcUV (varyingU, varyingV, bar); var n = Transform (uniformMIT, Normal (normalMap, uv)).Normalize (); var l = Transform (uniformM, lightDir).Normalize (); var r = (n * (2 * Dot (n, l)) - l).Normalize (); var diff = Math.Max (0f, Dot (n, l)); var specular = Math.Pow (Math.Max (0f, r.z), Specular (specularMap, uv) + 15); color = GetColor (texture, uv); int v = 0; for (int i = 0; i < 4; i++) v = (v << 8) | (byte)Math.Min (255, (int)(5 + color [i] * (diff + 1.3f * specular))); color = new Color (v, color.format); return false; } } var headSpecularMap = Image.Load ("./obj/african_head_spec.tga"); var shader = new SpecularShader (headModel, viewPort, projection, modelView, light_dir, headTexture, headNormalMap, headSpecularMap); var image = Render (headModel, shader).Image; image.VerticalFlip(); image ``` ```csharp var diabloModel = Model.FromFile ("obj/diablo3_pose.obj"); var diabloTexture = Image.Load ("obj/diablo3_pose_diffuse.tga"); var diabloNormalMap = Image.Load ("obj/diablo3_pose_nm.tga"); var diabloTangentMap = Image.Load ("obj/diablo3_pose_nm_tangent.tga"); var diabloSpecularMap = Image.Load ("obj/diablo3_pose_spec.tga"); diabloTexture.VerticalFlip (); diabloNormalMap.VerticalFlip (); diabloTangentMap.VerticalFlip (); diabloSpecularMap.VerticalFlip (); var shader = new SpecularShader (diabloModel, viewPort, projection, modelView, light_dir, diabloTexture, diabloNormalMap, diabloSpecularMap); var image = Render (diabloModel, shader).Image; image.VerticalFlip(); image ``` # **Conclusion** We know how to render quite nice scenes, but our lighting is far from being real. In the next articles I will talk about shadows. Enjoy! ================================================ FILE: graphics/tiny-renderer/lesson6bis.workbook/lesson6bis.csx ================================================ using static Geometry; using static MatrixHelpers; using static ShaderUtils; class TangentShader : IShader { // triangle uv coordinates, written by the vertex shader, read by the fragment shader Vec3f varyingU = new Vec3f (); Vec3f varyingV = new Vec3f (); // normal per vertex to be interpolated by FS Matrix3 varyingNrm = new Matrix3 (); readonly Model model; readonly Vec3f lightDir; readonly Matrix4 uniformM; readonly Matrix4 uniformMIT; readonly Matrix4 transformation; readonly Vec3f[] ndcTri = new Vec3f[3]; // triangle in normalized device coordinates readonly Image texture; readonly Image normalMap; public TangentShader (Model model, Matrix4 viewport, Matrix4 projection, Matrix4 modelView, Vec3f lightDir, Image texture, Image normalMap) { this.model = model; this.lightDir = lightDir.Normalize (); this.texture = texture; this.normalMap = normalMap; uniformM = projection * modelView; uniformMIT = TransposeInverse (uniformM); transformation = viewport * uniformM; } public Vec4f Vertex (Face face, int nthvert) { UpdateVarayingUV (model, face, nthvert, ref varyingU, ref varyingV); var normal = Project3D (Mult (uniformMIT, Embed4D (model.Normal (face, nthvert)))); varyingNrm.SetColumn (nthvert, normal); var glVertex = TransformFace (model, face, nthvert, transformation); ndcTri[nthvert] = Project3D (glVertex / glVertex.h); return glVertex; } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { var bn = Mult(varyingNrm, bar).Normalize (); var uv = CalcUV (varyingU, varyingV, bar); var A = new Matrix3 (); A.SetRow (0, ndcTri [1] - ndcTri [0]); A.SetRow (1, ndcTri [2] - ndcTri [0]); A.SetRow (2, bn); var AI = Inverse (A); var i = Mult (AI, new Vec3f { x = varyingU.y - varyingU.x, y = varyingU.z - varyingU.x }); var j = Mult (AI, new Vec3f { x = varyingV.y - varyingV.x, y = varyingV.z - varyingV.x }); var B = new Matrix3 (); B.SetColumn (0, i.Normalize ()); B.SetColumn (1, j.Normalize ()); B.SetColumn (2, bn); var n = Mult (B, Normal (normalMap, uv)).Normalize (); var l = Transform (uniformM, lightDir).Normalize (); var diff = Math.Max (0f, Dot (n, l)); color = GetColor (texture, uv) * diff; return false; } } ================================================ FILE: graphics/tiny-renderer/lesson6bis.workbook/obj/african_head.obj ================================================ v -0.000581696 -0.734665 -0.623267 v 0.000283538 -1 0.286843 v -0.117277 -0.973564 0.306907 v -0.382144 -0.890788 0.221243 v -0.247144 -0.942602 0.276051 v -0.656078 -0.718512 -0.109025 v -0.609847 -0.786562 0.0198068 v -0.66248 -0.632053 -0.244271 v -0.511812 -0.845392 0.127809 v -0.609326 -0.569868 -0.41571 v -0.426949 -0.649767 -0.567143 v -0.201076 -0.720822 -0.633205 v 0.117382 -0.973645 0.306766 v 0.382454 -0.890869 0.221097 v 0.247512 -0.942667 0.275986 v 0.656371 -0.718624 -0.109224 v 0.610273 -0.786562 0.0197893 v 0.66248 -0.631463 -0.244119 v 0.511631 -0.845357 0.127832 v 0.608654 -0.568839 -0.416318 v 0.424663 -0.649937 -0.567418 v 0.198972 -0.720968 -0.633141 v 0.153371 -0.140519 0.477416 v 0.134781 -0.14723 0.48805 v 0.131261 -0.132153 0.49872 v 0.14749 -0.135105 0.489565 v 0.000686924 -0.0534984 0.505694 v 0.075062 -0.0473306 0.49955 v 0.0695841 -0.0997942 0.550277 v 0.0302569 -0.0971868 0.55389 v 0.0745124 -0.135953 0.523215 v 0.0354892 -0.12785 0.535159 v 0.0389268 -0.109557 0.550558 v 0.0734835 -0.11538 0.538029 v 0.106386 -0.125623 0.51513 v 0.107415 -0.144295 0.5047 v 0.15968 -0.130861 0.484794 v 0.156224 -0.123705 0.486735 v 0.15792 -0.107798 0.4677 v 0.163784 -0.126996 0.470144 v 0.154687 -0.134655 0.486373 v 0.160668 -0.135649 0.476189 v 0.143433 -0.119034 0.499854 v 0.131606 -0.0726738 0.476148 v -0.000260156 -0.124553 0.539058 v -0.000646004 -0.110651 0.55444 v 0.100423 -0.10574 0.537643 v 0.126128 -0.115784 0.515598 v 0.250944 -0.275583 0.380381 v 0.221602 -0.335752 0.330174 v 0.275434 -0.301318 0.24751 v 0.307699 -0.239869 0.292356 v 0.332124 -0.0415605 0.412962 v 0.319444 0.00732526 0.451091 v 0.28667 -0.025805 0.481549 v 0.297006 -0.0758717 0.454242 v 0.357953 -0.159928 -0.223225 v 0.303981 -0.144611 -0.343644 v 0.296386 -0.0547553 -0.357792 v 0.357339 -0.0633433 -0.24278 v 0.45086 0.331215 0.047962 v 0.438899 0.336167 0.131147 v 0.447405 0.226107 0.139349 v 0.455613 0.205353 0.0827643 v 0.197493 -0.411308 0.138256 v 0.204911 -0.353378 0.2082 v 0.102001 -0.419375 0.24969 v 0.0995867 -0.475697 0.20834 v 0.150133 -0.372261 0.431226 v 0.176423 -0.362054 0.392056 v 0.196019 -0.326474 0.426929 v 0.154611 -0.348549 0.463444 v 0.0892273 -0.391968 0.303592 v 0.159013 -0.363737 0.305077 v 0.455712 0.508986 -0.0641442 v 0.432146 0.648411 -0.0417475 v 0.417051 0.611568 0.0817295 v 0.44205 0.483438 0.0478626 v 0.3446 0.43288 0.398633 v 0.372358 0.383369 0.353998 v 0.388341 0.404485 0.306953 v 0.355059 0.467372 0.356967 v 0.305162 0.338815 0.458112 v 0.298579 0.319803 0.456627 v 0.313422 0.304568 0.427776 v 0.323711 0.315968 0.429291 v 0.33161 0.397557 0.430226 v 0.354427 0.359727 0.390478 v 0.304162 0.291952 0.432377 v 0.292662 0.309771 0.452991 v 0.282934 0.292496 0.4562 v 0.292025 0.281663 0.435178 v 0.397344 0.565249 0.192585 v 0.42257 0.455996 0.145494 v 0.317848 0.364866 0.448834 v 0.340595 0.337517 0.417978 v 0.243227 0.479439 0.494236 v 0.250155 0.546138 0.465934 v 0.179019 0.560251 0.511681 v 0.170173 0.4781 0.536229 v 0.162386 0.410407 0.547009 v 0.235031 0.427051 0.517018 v 0.271745 0.634415 0.42162 v 0.196896 0.657291 0.472505 v 0.186589 0.312952 0.511073 v 0.189518 0.32493 0.514165 v 0.146286 0.31277 0.509009 v 0.144959 0.300178 0.501713 v 0.143965 0.300412 0.49409 v 0.187203 0.310596 0.506407 v 0.157744 0.364614 0.528804 v 0.216697 0.382527 0.516083 v 0.194441 0.332425 0.515989 v 0.204286 0.349818 0.516732 v 0.156254 0.334062 0.519579 v 0.151565 0.320341 0.513961 v 0.0431068 0.071791 0.618005 v 0.0477954 0.0867105 0.593486 v 0.0780844 0.0816652 0.602518 v 0.0574124 0.0746147 0.621185 v 0.448253 0.130656 0.149533 v 0.431801 0.159355 0.215905 v 0.422792 0.0771637 0.237185 v 0.428691 0.0348783 0.166914 v 0.365073 -0.0526507 0.316126 v 0.326974 -0.104793 0.373068 v 0.312773 -0.172965 0.33446 v 0.368107 -0.126698 0.269222 v 0.203695 -0.131796 0.523934 v 0.180463 -0.136479 0.525396 v 0.182848 -0.14892 0.516989 v 0.204163 -0.152533 0.514914 v 0.39379 0.00616771 0.269368 v 0.40177 -0.0591341 0.209048 v 0.26083 -0.0996422 0.484274 v 0.250406 -0.0552171 0.50321 v 0.15851 -0.136292 0.498474 v 0.155032 -0.134684 0.502964 v 0.145006 -0.133819 0.514504 v 0.171033 -0.12032 0.538263 v 0.158849 -0.127938 0.534943 v 0.167969 -0.138075 0.523788 v 0.232061 -0.151474 0.497024 v 0.23074 -0.117128 0.507191 v 0.365798 0.221617 0.362743 v 0.342501 0.235507 0.392185 v 0.325951 0.202558 0.415114 v 0.359268 0.178677 0.383229 v 0.352369 0.0489033 0.417452 v 0.322262 0.0907619 0.44953 v 0.295322 0.04895 0.483251 v 0.367108 0.00328555 0.369771 v 0.138972 -0.18796 0.555521 v 0.161562 -0.177794 0.535913 v 0.154015 -0.155093 0.536392 v 0.136131 -0.156414 0.558491 v 0.220263 -0.08194 0.518603 v 0.202088 -0.0486753 0.52791 v 0.17564 -0.0814314 0.545822 v 0.193131 -0.106435 0.533575 v 0.199492 -0.169714 0.509722 v 0.190033 -0.188183 0.514668 v 0.207302 -0.213011 0.492721 v 0.222415 -0.183044 0.489617 v 0.125088 -0.132884 0.551294 v 0.144497 -0.139192 0.530254 v 0.135014 0.119128 0.544717 v 0.119534 0.149685 0.554253 v 0.096915 0.171211 0.569382 v 0.112553 0.137432 0.569616 v 0.0878476 0.217858 0.555667 v 0.0649773 0.232128 0.568628 v 0.073466 0.185119 0.584571 v 0.116359 0.191199 0.548932 v 0.111419 0.228591 0.524951 v 0.0858774 0.255408 0.530312 v 0.301408 0.0368718 -0.387812 v 0.366839 0.037626 -0.269538 v 0.272125 -0.199781 0.399533 v 0.246349 -0.195514 0.453266 v 0.223339 -0.243049 0.450553 v 0.364021 -0.197455 0.21335 v 0.411416 -0.124798 0.140589 v 0.431568 -0.0028997 0.0907502 v 0.449346 0.11075 0.0889086 v 0.0649948 0.777167 0.432594 v 0.133465 0.770619 0.418569 v 0.14341 0.869244 0.301253 v 0.0689586 0.877043 0.315395 v 0.305372 0.809321 0.22043 v 0.289307 0.723856 0.335524 v 0.355187 0.660735 0.264773 v 0.372264 0.728258 0.148528 v 0.382308 0.7766 0.0116631 v 0.0971488 0.470588 0.557912 v 0.110788 0.565185 0.534317 v 0.100113 0.277828 0.510938 v 0.10966 0.248679 0.503771 v 0.0443988 0.240822 0.58581 v 0.0522151 0.193614 0.604337 v 0.052601 0.564735 0.541859 v 0.123726 0.667896 0.498907 v 0.0597976 0.671147 0.508711 v 0.0466729 0.466215 0.561034 v 0.000423846 0.462807 0.558988 v -0.00017831 0.388326 0.563478 v 0.0352086 0.389069 0.560584 v 0.000833078 0.56384 0.544139 v 0.295773 0.426823 0.470722 v 0.301706 0.464689 0.451056 v 0.189957 0.181465 0.501181 v 0.186163 0.208931 0.491956 v 0.141574 0.222722 0.500509 v 0.146526 0.195338 0.518293 v 0.111986 0.0116865 0.562811 v 0.111343 0.0404672 0.565769 v 0.0577164 0.0420398 0.577988 v 0.0656438 -0.00796249 0.596918 v 0.147695 0.0440509 0.537258 v 0.144778 0.0631738 0.538491 v 0.0268719 -0.0140834 0.602378 v 0.0270356 -0.0372401 0.622027 v 0.0876429 -0.0456996 0.601127 v 0.183093 0.146552 0.519439 v 0.148589 0.164593 0.536819 v 0.147344 0.131095 0.542934 v 0.176733 0.112264 0.532435 v -0.000394618 -0.0441035 0.617625 v -0.000260156 -0.0187662 0.600677 v 0.165058 0.0770935 0.530856 v 0.148554 0.0982976 0.535562 v 0.116476 0.272829 0.494797 v 0.119084 0.26261 0.493569 v 0.120873 0.268971 0.480883 v 0.11761 0.27287 0.484221 v 0.224695 0.848444 0.271198 v 0.231324 0.918189 0.121063 v 0.14614 0.9439 0.150241 v 0.241894 0.945736 -0.185803 v 0.156043 0.976475 -0.183418 v 0.146906 0.980702 -0.0177607 v 0.23195 0.948285 -0.0402158 v 0.0684324 0.995189 -0.00981573 v 0.0682103 0.955014 0.162933 v 0.0891571 0.383649 0.555118 v 0.110613 0.336412 0.528863 v 0.122749 0.310759 0.512914 v 0.147081 -0.111919 0.55631 v 0.158656 -0.0994551 0.55786 v 0.0939743 0.0869969 0.616333 v 0.101206 0.119326 0.615532 v 0.0670469 0.122121 0.645885 v 0.0560853 0.0831385 0.640601 v 0.0795284 0.0820978 0.567845 v 0.0337354 0.0564741 0.595059 v 0.0854448 -0.103577 0.606979 v 0.0826211 -0.0671141 0.612931 v 0.0280704 -0.0555854 0.637736 v 0.0319698 -0.0970874 0.628212 v 0.0789964 -0.121811 0.579602 v 0.0327415 -0.116959 0.594106 v 0.0216981 0.0173339 0.585915 v -0.00123062 -0.095585 0.625704 v -0.000511542 -0.0598999 0.637227 v -0.00157555 -0.115643 0.593966 v -0.000219233 -0.0988881 0.554498 v 0.0291929 0.0853015 0.665324 v 0.0352671 0.124524 0.666125 v 0.0371846 0.159004 0.648446 v 0.0654158 0.154462 0.629171 v 0.0280178 0.19967 0.620548 v 0.0221015 0.245843 0.59797 v 0.0432997 0.281499 0.556866 v 0.0222008 0.28717 0.567459 v -0.000400465 0.125745 0.673871 v -0.00057585 0.0822265 0.675105 v -0.000347849 0.160916 0.656029 v 0.367195 0.315074 0.363767 v 0.346658 0.302744 0.393991 v 0.344389 0.266656 0.384439 v 0.371726 0.266504 0.352507 v 0.40246 0.429197 0.234116 v 0.422126 0.335763 0.207276 v 0.393316 0.264083 0.313887 v 0.387102 0.325737 0.325369 v 0.3274 0.295928 0.408636 v 0.316392 0.29076 0.418709 v 0.3085 0.274624 0.423199 v 0.323636 0.272379 0.406602 v 0.429381 0.244458 0.204002 v 0.407084 0.332408 0.277313 v 0.410597 0.257869 0.266264 v -0.0012657 -0.456867 0.290093 v -0.00137093 -0.520579 0.266159 v 0.154137 -0.304206 0.500479 v 0.193482 -0.282873 0.473493 v 0.186367 -0.242201 0.509588 v 0.148993 -0.26399 0.525367 v 0.110332 -0.274916 0.545857 v 0.099347 -0.233134 0.560204 v 0.0558865 -0.227615 0.569605 v 0.0659185 -0.270006 0.563817 v 0.154687 -0.142577 0.51838 v 0.159498 -0.143009 0.513072 v 0.154646 -0.138239 0.502496 v 0.149045 -0.137596 0.50639 v 0.15958 -0.138174 0.517463 v 0.161574 -0.141559 0.511657 v 0.0940387 -0.129288 0.582226 v 0.109215 -0.12609 0.531844 v 0.0782715 -0.117578 0.557129 v 0.264817 0.0151299 0.501573 v 0.280122 0.127096 0.47057 v 0.262508 0.0886748 0.494464 v 0.187613 0.050926 0.529248 v 0.207829 0.0868157 0.523449 v 0.231821 -0.0170182 0.518246 v 0.304138 0.164985 0.443485 v 0.343004 0.132813 0.418235 v 0.313621 0.250742 0.418382 v 0.290815 0.22492 0.444303 v 0.355269 -0.194146 0.0276407 v 0.388534 -0.179618 0.0746089 v 0.336544 -0.25083 0.156379 v 0.29365 -0.279868 0.104617 v 0.389288 0.153006 0.345258 v 0.39155 0.205715 0.320166 v 0.127262 0.566927 -0.64996 v 0.000868155 0.562946 -0.661419 v 0.000850617 0.724441 -0.605705 v 0.118774 0.725955 -0.596105 v 0.21095 0.754513 0.387525 v 0.133734 -0.133188 0.514651 v 0.131302 -0.13393 0.53047 v 0.0671053 -0.326445 0.551902 v 0.0661056 -0.374553 0.504765 v 0.117289 -0.365439 0.489939 v 0.116552 -0.318792 0.528974 v 0.288249 -0.135286 0.424736 v 0.39393 0.0544045 0.33225 v 0.374655 0.0965379 0.38044 v 0.000792155 1 -0.0074948 v 0.0731795 0.993937 -0.182792 v 0.000868155 0.999152 -0.181886 v 0.179405 0.936399 -0.330549 v 0.0842755 0.953459 -0.338026 v 0.141767 0.271455 0.486238 v 0.139978 0.267433 0.490862 v 0.175908 0.259465 0.501362 v 0.175312 0.263359 0.495861 v 0.181597 0.230187 0.495539 v 0.140253 0.240576 0.495341 v 0.336982 0.587763 0.356927 v 0.312043 0.518258 0.416183 v 0.259971 0.350203 0.495411 v 0.250763 0.331028 0.496036 v 0.114179 0.255893 0.495902 v 0.111069 0.276518 0.499456 v 0.125433 0.293116 0.500415 v 0.124965 0.282353 0.489968 v 0.13906 0.254928 0.497457 v 0.17737 0.2462 0.50062 v 0.121796 0.272327 0.47658 v 0.149548 0.0847578 0.549377 v 0.142825 -0.226381 0.544992 v 0.106181 -0.197232 0.576871 v 0.258193 -0.146669 0.465227 v 0.2105 0.0188071 0.525711 v 0.181041 -0.0155508 0.531721 v 0.173453 -0.168949 0.5218 v 0.180322 -0.15877 0.514949 v 0.168554 -0.150118 0.516667 v 0.163082 -0.153579 0.523344 v 0.139124 -0.128733 0.545343 v 0.152348 -0.134468 0.527471 v 0.416192 -0.0714636 0.0335278 v 0.0220956 0.0520719 0.640232 v 0.0361615 0.0619695 0.628476 v -0.000283541 0.202056 0.62768 v 0.0869063 -0.0493125 -0.489641 v 0.192289 -0.0534399 -0.447186 v 0.192003 -0.134672 -0.429197 v 0.0851642 -0.130335 -0.46373 v 0.236434 0.310245 0.495686 v 0.237714 0.31211 0.497539 v 0.244636 0.32534 0.496212 v 0.121253 0.281932 0.477293 v 0.173149 -0.207241 0.528208 v -0.000242618 0.247989 0.603612 v -0.00037708 0.28838 0.571697 v 0.108496 -0.160507 0.588207 v 0.0613995 -0.166388 0.620127 v 0.0634222 -0.199565 0.59462 v 0.0893734 0.151176 0.600127 v 0.122124 0.0729427 0.596088 v 0.0993528 0.072475 0.584781 v 0.108315 0.0599584 0.583916 v 0.133524 0.0551528 0.575778 v 0.13315 0.107517 0.580426 v 0.274937 0.384257 0.485735 v 0.170606 -0.145383 0.517205 v 0.0464391 -0.130399 0.611931 v 0.0392892 -0.113439 0.575094 v -0.00161647 -0.112428 0.579865 v -0.00351648 -0.131685 0.617859 v 0.0194356 0.03489 0.601858 v -0.000564158 0.0478802 0.644208 v -2.04632e-05 0.0350303 0.598835 v 0.222163 0.246884 0.4972 v 0.217802 0.257547 0.498129 v 0.293159 0.278716 0.430419 v 0.302852 0.281932 0.427367 v 0.285209 0.277366 0.434932 v 0.289307 0.275834 0.436551 v 0.290061 0.280494 0.427963 v -0.000225079 -0.384287 0.444245 v 0.0651001 -0.383883 0.440585 v -0.000891543 -0.364076 0.502426 v 0.116576 -0.381784 0.436341 v 0.363734 0.712842 -0.467571 v 0.32166 0.832542 -0.392653 v 0.376508 0.821429 -0.265451 v 0.427095 0.698004 -0.319575 v 0.27178 0.90956 -0.29643 v 0.310423 0.901357 -0.210644 v 0.441869 0.677005 -0.175175 v 0.389019 0.807076 -0.128411 v 0.313311 0.894506 -0.0788532 v 0.12783 -0.376125 0.378248 v 0.0722266 -0.391483 0.37664 v 0.125579 0.302411 0.505741 v 0.101656 0.861358 -0.486525 v 0.214084 0.849981 -0.463327 v 0.2467 0.723207 -0.559263 v 0.104913 0.117397 -0.600268 v 0.221579 0.117865 -0.555159 v 0.200848 0.0268164 -0.488992 v 0.0944011 0.0271204 -0.539134 v 0.391141 0.144178 -0.303545 v 0.331241 0.130393 -0.444613 v 0.360829 0.250357 -0.491155 v 0.424003 0.258021 -0.333419 v 0.000868155 0.23912 -0.655479 v 0.00089154 0.393909 -0.675105 v 0.125626 0.397949 -0.664716 v 0.115418 0.240453 -0.645617 v 0.452175 0.547687 -0.348309 v 0.450217 0.395605 -0.350776 v 0.383015 0.40193 -0.511868 v 0.3854 0.562496 -0.506472 v 0.464078 0.52881 -0.195929 v 0.311698 0.866351 0.071908 v -9.64635e-05 -0.406882 0.376985 v 0.373883 -0.18312 -0.115123 v 0.389189 -0.0789467 -0.141776 v 0.247109 0.197607 0.47589 v 0.22891 0.231497 0.489717 v 0.121077 -0.116725 0.574393 v 0.125626 -0.0895459 0.583057 v 0.110548 -0.128452 0.555428 v 0.000710309 0.959638 0.167019 v 0.000710309 0.881206 0.320973 v 0.224163 0.124079 0.505215 v 0.255305 0.260798 0.480649 v 0.25188 0.263516 0.478322 v 0.214891 0.26119 0.49413 v 0.116476 0.273741 0.475423 v 0.290704 0.283902 0.433377 v 0.29641 0.299523 0.422813 v 0.29406 0.288222 0.418078 v 0.142655 0.263364 0.482467 v 0.121638 0.267831 0.470296 v 0.171711 0.256898 0.489693 v 0.246864 0.257401 0.473821 v 0.274311 0.271648 0.453301 v 0.274539 0.26862 0.446654 v 0.233686 0.331104 0.49074 v 0.187548 0.326632 0.49682 v 0.296971 0.273928 0.433476 v 0.134067 -0.0744861 0.577333 v 0.237434 0.052867 0.514604 v 0.0637905 0.27076 0.54346 v 0.375421 0.514218 0.287328 v 0.353808 -0.333437 -0.190615 v 0.349365 -0.276331 -0.333858 v 0.323337 -0.214946 -0.338453 v 0.356725 -0.247925 -0.205557 v -0.000330311 -0.581268 0.237302 v 0.092922 -0.548418 0.185458 v 0.394783 -0.0876049 -0.0664009 v 0.358315 -0.197624 -0.02995 v 0.292785 -0.321493 0.0377429 v 0.395175 -0.0904345 -0.0143524 v 0.243385 0.243183 -0.602957 v 0.000587539 -0.0451091 -0.498205 v 0.000751232 0.030862 -0.55154 v 0.000809694 0.11928 -0.61144 v 0.000850617 0.862837 -0.491295 v 0.000868155 0.958527 -0.339277 v 0.000423846 -0.128189 -0.469085 v 0.264186 0.56961 -0.608026 v 0.35127 -0.283317 -0.0863656 v 0.196201 -0.209591 -0.418785 v 0.0873097 -0.206341 -0.44839 v 0.000488154 -0.206259 -0.449945 v 0.263397 0.402579 -0.621226 v 0.456683 0.384813 -0.0591516 v 0.457776 0.372302 -0.191281 v 0.000850617 0.671351 0.512487 v 0.000809694 0.77919 0.437668 v 0.408656 0.116286 0.298547 v 0.295913 0.259781 0.439334 v 0.285355 0.265481 0.449775 v 0.278766 0.270035 0.454663 v 0.128946 -0.0227065 0.564741 v 0.16203 0.016989 0.534633 v 0.0985987 0.0583799 0.58087 v 0.0538462 0.323165 0.543729 v 0.0794758 0.301522 0.528465 v -0.00330601 -0.197759 0.600525 v -0.000511542 -0.225551 0.572931 v -0.00456879 -0.164231 0.628277 v -0.000336157 -0.26392 0.574381 v -0.000768774 -0.325515 0.55686 v 0.269921 0.242499 0.464742 v 0.260573 0.253022 0.476072 v 0.235066 0.15963 0.493271 v 0.411369 0.186119 0.273583 v 0.000178307 0.0131539 0.584682 v 0.153436 -0.0554568 0.55786 v 0.0264569 0.331747 0.554112 v -0.000342003 0.332998 0.557743 v 0.285589 0.277974 0.428156 v 0.184795 -0.499655 0.1217 v 0.332808 -0.386298 -0.0699261 v 0.20739 -0.274419 -0.415909 v 0.0927467 -0.274308 -0.43723 v 0.278029 -0.438791 0.0475586 v 0.000505693 -0.27722 -0.43768 v 0.438191 0.12488 -0.0367783 v 0.460214 0.163208 -0.055258 v 0.485388 0.177437 -0.0277343 v 0.472304 0.161641 -0.00367724 v 0.496244 0.232684 -0.0170708 v 0.477425 0.247036 0.00446648 v 0.517015 0.298681 -0.0523876 v 0.492233 0.31788 -0.0441737 v 0.53425 0.316407 -0.124009 v 0.511491 0.332595 -0.129276 v 0.535904 0.290111 -0.170685 v 0.511128 0.30365 -0.186838 v 0.538611 0.228878 -0.193017 v 0.511286 0.231199 -0.218992 v 0.520242 0.128838 -0.191421 v 0.490433 0.122168 -0.208603 v 0.487562 0.00951757 -0.0819458 v 0.472286 -0.00658864 -0.0930419 v 0.47079 0.0399937 -0.154257 v 0.496437 0.0472722 -0.136917 v 0.485142 -0.0247586 -0.0238758 v 0.46129 -0.0429694 -0.0334343 v 0.474888 0.238927 -0.0419989 v 0.495232 0.289088 -0.0628581 v 0.508398 0.299996 -0.11766 v 0.51311 0.283323 -0.158478 v 0.514642 0.235303 -0.176531 v 0.501751 0.136134 -0.181559 v 0.486025 0.0533522 -0.11859 v 0.486451 0.0268164 -0.067155 v 0.482529 0.0136625 -0.0120607 v 0.464265 0.0280383 0.0249515 v 0.457519 -0.0185791 0.0196256 v 0.442769 0.0582571 -0.0293244 v 0.45632 0.0847169 -0.0600578 v 0.442465 0.0842785 -0.0209644 v 0.459612 0.268106 0.0209995 v 0.458559 0.182857 0.0414318 v 0.463026 0.318488 -0.0446005 v 0.470222 0.311835 -0.142898 v 0.455063 0.232836 -0.195221 v 0.43839 0.13186 -0.191088 v 0.424564 0.0473131 -0.148417 v 0.423447 -0.00471202 -0.0897563 v 0.425377 -0.0292075 -0.0262143 v 0.430714 -0.0102191 0.0297161 v 0.446335 0.0345567 0.0460036 v 0.475607 0.129364 -0.0864649 v 0.482611 0.0600636 -0.0525396 v 0.481517 0.0827175 -0.101349 v 0.470503 0.0444835 -0.0133527 v 0.479278 0.0776957 0.00471786 v 0.504692 0.223938 -0.101723 v 0.50375 0.131866 -0.1473 v 0.45452 0.100016 0.0450097 v 0.403623 0.0251386 -0.16934 v 0.414719 0.138607 -0.218957 v 0.435461 0.249632 -0.229924 v -0.000201695 -0.407876 0.310666 v 0.000347846 -0.171521 0.505794 v 0.0884205 -0.186598 0.484028 v 0.141147 -0.173807 0.465513 v 0.159878 -0.142255 0.458644 v 0.152483 -0.116468 0.431278 v 0.0708352 0.0121893 0.376371 v 0.128069 -0.116368 0.360528 v 0.143994 -0.166791 0.41184 v 0.0748398 -0.218144 0.372349 v 0.280941 0.292858 0.454897 v 0.281356 0.319879 0.451494 v 0.127268 0.269088 0.455435 v 0.116921 0.284697 0.447653 v 0.119996 0.274998 0.469126 v 0.15699 0.254759 0.466326 v 0.265916 0.273601 0.421176 v 0.214885 0.253946 0.455259 v 0.141223 0.313133 0.482117 v 0.211436 0.255823 0.486852 v 0.277135 0.302686 0.410799 v 0.252505 0.333881 0.433599 v 0.202023 0.342182 0.464578 v 0.11989 0.295816 0.471196 v 0.146526 0.322539 0.455943 v 0.126292 0.301838 0.454973 v 0.119744 0.284878 0.469419 v 0.00103185 0.0191579 0.374711 v 0.000909079 -0.205715 0.379849 v 0.0536357 -0.100847 0.27211 v 0.00103185 -0.098929 0.27128 v 0.255463 -0.398733 -0.446098 v 0.412907 -0.372688 -0.332858 v 0.452596 -0.41557 -0.353559 v 0.293329 -0.465367 -0.476007 v 0.0815337 -0.637104 0.176286 v 0.0726358 -0.738524 0.179519 v 0.174763 -0.714911 0.155526 v 0.172032 -0.601823 0.129884 v 0.380782 -0.504069 -0.184377 v 0.357368 -0.419095 -0.180384 v 0.337538 -0.494803 -0.0548371 v 0.372989 -0.619402 -0.0373571 v 0.453578 -0.652661 -0.0939539 v 0.452351 -0.545892 -0.196981 v 0.173576 -0.814197 0.195654 v 0.0739044 -0.845866 0.20734 v 0.0964414 -0.904976 0.254455 v 0.197703 -0.864562 0.243353 v 0.519564 -0.487407 -0.384801 v 0.555004 -0.584226 -0.219366 v 0.451357 -0.731555 -0.0215899 v 0.382594 -0.74824 0.0443666 v 0.439805 -0.799196 0.0975376 v 0.519108 -0.768071 -0.00769357 v 0.274837 -0.806199 0.115503 v 0.320508 -0.838061 0.183769 v 0.354533 -0.544232 -0.525256 v 0.162503 -0.604343 -0.559076 v 0.131098 -0.496837 -0.498761 v 0.115161 -0.410103 -0.457756 v -0.00017831 -0.492774 -0.504192 v 2.046e-05 -0.40666 -0.465186 v -0.000482311 -0.600531 -0.555322 v 0.546217 -0.696736 -0.117257 v 0.22746 -0.332063 -0.424345 v 0.101627 -0.33885 -0.437002 v 0.280193 -0.554165 0.0658922 v 0.274843 -0.684891 0.0781517 v 0.000347846 -0.34199 -0.438165 v 0.000733693 -0.746364 0.176765 v 0.000312769 -0.874904 0.179121 v 0.378648 -0.322586 -0.326994 v -0.000114002 -0.940246 0.234262 v 0.000979233 -0.650317 0.207112 v -0.130513 -0.13217 0.498924 v -0.133687 -0.14723 0.488109 v -0.15222 -0.140519 0.477457 v -0.14666 -0.13514 0.489746 v -0.0697653 -0.0999404 0.550318 v -0.0736414 -0.0473131 0.499649 v -0.0305784 -0.0972511 0.55389 v -0.0396517 -0.109762 0.550014 v -0.0358517 -0.127727 0.53534 v -0.0742493 -0.135994 0.523315 v -0.0733373 -0.115561 0.537643 v -0.106766 -0.144336 0.504823 v -0.106281 -0.125786 0.515779 v -0.156505 -0.107798 0.467782 v -0.155611 -0.123682 0.486899 v -0.159311 -0.130796 0.484958 v -0.162872 -0.126996 0.470243 v -0.159919 -0.135625 0.47627 v -0.154055 -0.134696 0.486513 v -0.142597 -0.118993 0.499994 v -0.130051 -0.0726738 0.476189 v -0.10054 -0.105798 0.538111 v -0.125684 -0.115824 0.51596 v -0.274604 -0.301394 0.247527 v -0.220831 -0.335775 0.330215 v -0.250102 -0.275554 0.380393 v -0.3066 -0.239804 0.292309 v -0.284302 -0.0258401 0.479772 v -0.319479 0.00809111 0.449577 v -0.331873 -0.0412272 0.412243 v -0.293674 -0.0747667 0.452418 v -0.294668 -0.0547787 -0.357622 v -0.302063 -0.144319 -0.34334 v -0.356012 -0.159916 -0.223184 v -0.355474 -0.0633082 -0.24271 v -0.447241 0.22613 0.139332 v -0.437922 0.336149 0.131124 v -0.449486 0.331215 0.047962 v -0.454982 0.205353 0.0827818 v -0.103311 -0.419241 0.249936 v -0.203701 -0.353384 0.208147 v -0.196966 -0.411506 0.138841 v -0.101797 -0.475733 0.208638 v -0.196499 -0.327216 0.427455 v -0.176283 -0.362363 0.392138 v -0.150331 -0.372548 0.431378 v -0.155575 -0.349484 0.46435 v -0.0890109 -0.391945 0.303855 v -0.158306 -0.363848 0.305182 v -0.415613 0.611627 0.0817705 v -0.430808 0.648493 -0.0417066 v -0.45411 0.508986 -0.0641209 v -0.440308 0.483438 0.0478393 v -0.389808 0.40462 0.306977 v -0.375935 0.38348 0.354021 v -0.34643 0.433026 0.398499 v -0.354807 0.467378 0.356891 v -0.317409 0.30382 0.429121 v -0.30173 0.320499 0.456861 v -0.309295 0.339493 0.457756 v -0.328406 0.316144 0.429519 v -0.358297 0.360101 0.389344 v -0.335684 0.397733 0.427864 v -0.285156 0.29304 0.457387 v -0.294212 0.310695 0.451757 v -0.307675 0.294425 0.430781 v -0.29475 0.281949 0.435698 v -0.421091 0.455996 0.145494 v -0.395403 0.565208 0.19252 v -0.321999 0.364421 0.449238 v -0.345494 0.336792 0.417218 v -0.178165 0.560672 0.512335 v -0.249354 0.546354 0.466589 v -0.243286 0.479638 0.494943 v -0.170168 0.4781 0.536796 v -0.164123 0.410647 0.547114 v -0.236966 0.427297 0.516007 v -0.270669 0.634748 0.422187 v -0.195815 0.657882 0.47347 v -0.14597 0.313039 0.508126 v -0.18946 0.324971 0.513312 v -0.186823 0.312829 0.511757 v -0.144895 0.300213 0.501871 v -0.186911 0.310514 0.506612 v -0.143462 0.300341 0.494353 v -0.160048 0.365076 0.528073 v -0.219468 0.382854 0.516404 v -0.15782 0.334506 0.520076 v -0.205952 0.349935 0.517012 v -0.195236 0.332495 0.516264 v -0.151653 0.320785 0.513142 v -0.0805691 0.0827468 0.603261 v -0.0493739 0.08878 0.593591 v -0.0448723 0.0732117 0.617958 v -0.0594819 0.0761932 0.621314 v -0.422927 0.0771812 0.237185 v -0.432205 0.159355 0.215905 v -0.448112 0.130656 0.149516 v -0.4282 0.0348607 0.166897 v -0.311779 -0.172912 0.334378 v -0.324787 -0.103758 0.371735 v -0.364851 -0.052639 0.316097 v -0.367254 -0.126698 0.269146 v -0.183918 -0.149136 0.51793 v -0.182024 -0.137865 0.527822 v -0.205163 -0.131463 0.524127 v -0.205514 -0.152071 0.514943 v -0.39379 0.00614433 0.269368 v -0.400951 -0.0591282 0.208995 v -0.261011 -0.0993382 0.483865 v -0.25102 -0.0551177 0.50328 v -0.158849 -0.136444 0.499199 v -0.155155 -0.134784 0.503397 v -0.145304 -0.133848 0.514902 v -0.160802 -0.128394 0.536919 v -0.173424 -0.121349 0.541327 v -0.169156 -0.138478 0.524928 v -0.232096 -0.116964 0.50767 v -0.232727 -0.151188 0.49696 v -0.326085 0.202611 0.415651 v -0.34094 0.235683 0.392156 v -0.367727 0.221336 0.359031 v -0.358829 0.177595 0.3841 v -0.295603 0.0501836 0.478632 v -0.32232 0.0902006 0.449922 v -0.351843 0.04895 0.416686 v -0.367248 0.00336155 0.369624 v -0.156137 -0.154941 0.536878 v -0.165134 -0.177028 0.538193 v -0.144573 -0.187364 0.558725 v -0.140533 -0.155882 0.559046 v -0.17761 -0.0804258 0.547933 v -0.201667 -0.0484356 0.526945 v -0.22024 -0.0817529 0.517585 v -0.195826 -0.106131 0.536439 v -0.207794 -0.213087 0.493049 v -0.191711 -0.188305 0.515551 v -0.201111 -0.170071 0.510745 v -0.223385 -0.183243 0.490178 v -0.128595 -0.132761 0.551212 v -0.145777 -0.139513 0.530605 v -0.0971664 0.171538 0.569909 v -0.120048 0.150182 0.555387 v -0.13557 0.119437 0.545004 v -0.113103 0.137432 0.569453 v -0.0653573 0.232432 0.569575 v -0.08745 0.217992 0.556468 v -0.0739395 0.185388 0.584933 v -0.0855266 0.255554 0.53095 v -0.110583 0.228714 0.525501 v -0.115915 0.191404 0.5495 v -0.300099 0.0366964 -0.387999 v -0.364734 0.0377897 -0.269357 v -0.223181 -0.243207 0.45081 v -0.246139 -0.195666 0.45347 v -0.271201 -0.199869 0.399446 v -0.362846 -0.197443 0.213286 v -0.410176 -0.124757 0.140565 v -0.430404 -0.00290555 0.0907385 v -0.448779 0.11075 0.0889086 v -0.142135 0.869847 0.301633 v -0.132167 0.771303 0.419317 v -0.0633989 0.777407 0.43288 v -0.0675789 0.877324 0.315577 v -0.353469 0.660735 0.264732 v -0.2875 0.723792 0.335465 v -0.30353 0.809117 0.220313 v -0.37099 0.728422 0.148627 v -0.381016 0.776764 0.0117274 v -0.0996744 0.472587 0.557146 v -0.109525 0.565325 0.53475 v -0.100294 0.277787 0.511248 v -0.108689 0.248457 0.503268 v -0.0528874 0.193947 0.604898 v -0.0453926 0.241125 0.586705 v -0.12255 0.668732 0.500514 v -0.0511336 0.564922 0.542589 v -0.0582191 0.671655 0.50974 v -0.0440363 0.465776 0.561151 v -0.0361966 0.388923 0.562367 v -0.301894 0.466338 0.448542 v -0.295831 0.424807 0.472166 v -0.140867 0.22264 0.499754 v -0.185742 0.209381 0.492394 v -0.186338 0.179495 0.502724 v -0.145859 0.19535 0.519018 v -0.0600022 0.0437294 0.578309 v -0.113337 0.0407946 0.564875 v -0.114196 0.0121659 0.564255 v -0.0686019 -0.00676987 0.598064 v -0.143661 0.0637116 0.537807 v -0.147607 0.0440217 0.535469 v -0.0907706 -0.0459919 0.600525 v -0.0300113 -0.0346152 0.623594 v -0.028047 -0.0138554 0.603173 v -0.148028 0.131527 0.5437 v -0.148519 0.164868 0.537322 v -0.183164 0.146873 0.520193 v -0.176978 0.112363 0.532908 v -0.147823 0.0979234 0.535574 v -0.165064 0.0766492 0.532955 v -0.120107 0.268649 0.480825 v -0.118558 0.262394 0.493353 v -0.115979 0.27287 0.494434 v -0.116476 0.272952 0.483859 v -0.229115 0.916634 0.120496 v -0.223379 0.848952 0.271461 v -0.145146 0.945128 0.150709 v -0.145409 0.980883 -0.0176788 v -0.154278 0.976311 -0.1834 v -0.240088 0.945514 -0.185786 v -0.230512 0.948548 -0.0401515 v -0.0669533 0.995411 -0.00979819 v -0.0669124 0.955581 0.163097 v -0.0891746 0.383199 0.554861 v -0.112226 0.336757 0.527307 v -0.123381 0.311174 0.513382 v -0.149484 -0.111966 0.558549 v -0.160264 -0.0991219 0.559216 v -0.0695139 0.122828 0.646821 v -0.103574 0.1197 0.616608 v -0.0967747 0.0873945 0.617683 v -0.0583127 0.0845006 0.640951 v -0.0810075 0.0824603 0.567973 v -0.0347818 0.058339 0.594989 v -0.031812 -0.0520134 0.636181 v -0.0876079 -0.0656701 0.61341 v -0.0905251 -0.101683 0.607529 v -0.0378686 -0.0937434 0.629054 v -0.0836617 -0.122507 0.579642 v -0.0385351 -0.11728 0.594673 v -0.0223295 0.0177081 0.586652 v -0.0307538 0.0864766 0.665646 v -0.0369098 0.125196 0.667078 v -0.0659946 0.154643 0.629212 v -0.0379446 0.159028 0.648136 v -0.0287544 0.19984 0.620642 v -0.0228205 0.245931 0.598298 v -0.0444456 0.281523 0.558544 v -0.0233467 0.287164 0.569581 v -0.348774 0.267521 0.384632 v -0.352083 0.30296 0.39367 v -0.371253 0.315308 0.363077 v -0.374871 0.266369 0.352501 v -0.422202 0.335746 0.207253 v -0.401928 0.429197 0.234116 v -0.395345 0.264083 0.313998 v -0.391071 0.32586 0.325679 v -0.312703 0.275793 0.421661 v -0.320315 0.291642 0.417107 v -0.332077 0.295173 0.409057 v -0.327599 0.271742 0.406824 v -0.429802 0.244434 0.203979 v -0.409282 0.332454 0.277442 v -0.411848 0.257886 0.266369 v -0.187414 -0.242265 0.510307 v -0.193763 -0.283183 0.474066 v -0.155254 -0.304954 0.501777 v -0.149998 -0.264183 0.526518 v -0.0567108 -0.227311 0.569523 v -0.101124 -0.233508 0.561461 v -0.11039 -0.27508 0.546021 v -0.066205 -0.270351 0.564711 v -0.154225 -0.138052 0.502391 v -0.159867 -0.142787 0.513271 v -0.15533 -0.142366 0.518626 v -0.148566 -0.137426 0.506285 v -0.160416 -0.138344 0.518258 v -0.161965 -0.141513 0.511996 v -0.110811 -0.126394 0.533276 v -0.10089 -0.129879 0.583501 v -0.0809374 -0.117865 0.558397 v -0.263876 0.014785 0.500935 v -0.26083 0.088932 0.49537 v -0.279702 0.127055 0.470506 v -0.207764 0.0867397 0.523776 v -0.187729 0.0509786 0.529558 v -0.232096 -0.0167025 0.518065 v -0.344056 0.133304 0.417078 v -0.302046 0.166376 0.445239 v -0.292551 0.225429 0.44414 v -0.316041 0.250468 0.418475 v -0.335386 -0.250836 0.156385 v -0.387207 -0.179618 0.074568 v -0.353755 -0.194151 0.0276524 v -0.292388 -0.279891 0.104617 v -0.392211 0.205733 0.320201 v -0.386651 0.150025 0.344942 v -0.126064 0.567371 -0.651942 v -0.117096 0.725914 -0.596082 v -0.209068 0.754227 0.387245 v -0.134091 -0.133281 0.515294 v -0.132384 -0.133778 0.530774 v -0.118289 -0.366228 0.490722 v -0.0673742 -0.375085 0.505343 v -0.0685259 -0.327012 0.553422 v -0.117722 -0.319453 0.530388 v -0.287793 -0.13528 0.424643 v -0.375234 0.0965671 0.380457 v -0.394351 0.054463 0.33218 v -0.0714373 0.993797 -0.182751 v -0.0825568 0.953558 -0.338084 v -0.177458 0.935674 -0.330221 v -0.176961 0.259482 0.501637 v -0.139651 0.267463 0.490903 v -0.141176 0.271537 0.486156 v -0.175792 0.263446 0.495797 v -0.139621 0.240295 0.49489 v -0.181918 0.230053 0.49499 v -0.335299 0.587722 0.356851 v -0.311189 0.51838 0.416464 v -0.263028 0.350391 0.495528 v -0.252435 0.331198 0.496568 v -0.111168 0.276448 0.500608 v -0.113553 0.255671 0.49582 v -0.124754 0.293525 0.500263 v -0.124275 0.282616 0.489933 v -0.138587 0.254671 0.496603 v -0.17851 0.246346 0.500783 v -0.120744 0.272286 0.476557 v -0.150635 0.0843194 0.549231 v -0.110981 -0.197039 0.578654 v -0.145877 -0.226522 0.547184 v -0.257825 -0.146365 0.464946 v -0.181813 -0.015013 0.533586 v -0.21057 0.0188715 0.525811 v -0.169226 -0.14996 0.516989 v -0.181743 -0.1588 0.515902 v -0.175376 -0.168545 0.522911 v -0.163813 -0.153415 0.52335 v -0.140253 -0.128364 0.545887 v -0.153091 -0.134363 0.527834 v -0.414608 -0.0714286 0.0335337 v -0.0376523 0.063203 0.628721 v -0.0232707 0.0530365 0.640016 v -0.190483 -0.134521 -0.42891 v -0.190425 -0.0530365 -0.446291 v -0.0856669 -0.0492716 -0.489617 v -0.0841703 -0.13027 -0.463549 v -0.238743 0.312729 0.498784 v -0.236568 0.310718 0.495914 v -0.245034 0.325784 0.495083 v -0.120311 0.281967 0.47734 v -0.176107 -0.207054 0.530523 v -0.114635 -0.15994 0.588938 v -0.0702155 -0.19877 0.595006 v -0.0735478 -0.165324 0.619338 v -0.0899814 0.151661 0.600396 v -0.111016 0.0572925 0.58557 v -0.101867 0.0715163 0.586237 v -0.127064 0.0733753 0.597824 v -0.136833 0.0543987 0.574241 v -0.135833 0.107312 0.581379 v -0.278287 0.38386 0.485911 v -0.171226 -0.145371 0.517737 v -0.0426215 -0.114106 0.575498 v -0.0575293 -0.131258 0.610721 v -0.0203535 0.0339429 0.602828 v -0.224215 0.246978 0.496697 v -0.219644 0.257664 0.498129 v -0.308126 0.284604 0.426215 v -0.296275 0.279026 0.430641 v -0.291721 0.275554 0.437358 v -0.286612 0.276705 0.435172 v -0.291949 0.280143 0.428238 v -0.065825 -0.384532 0.440825 v -0.11702 -0.382428 0.436651 v -0.374667 0.821265 -0.265393 v -0.3198 0.831958 -0.392208 v -0.362179 0.712818 -0.467507 v -0.425879 0.698185 -0.319692 v -0.269938 0.909215 -0.296313 v -0.308015 0.900609 -0.210562 v -0.440407 0.677046 -0.175192 v -0.387417 0.807117 -0.128411 v -0.312037 0.894728 -0.0788123 v -0.0720161 -0.391612 0.376675 v -0.127765 -0.376523 0.378341 v -0.124801 0.303066 0.504835 v -0.0997913 0.860855 -0.486022 v -0.212687 0.850449 -0.463771 v -0.245244 0.723306 -0.559461 v -0.199083 0.0271847 -0.488407 v -0.21986 0.118005 -0.554936 v -0.10327 0.117479 -0.600127 v -0.0928636 0.0273016 -0.53883 v -0.389259 0.144254 -0.303446 v -0.329178 0.130557 -0.444432 v -0.359227 0.250316 -0.491237 v -0.422325 0.258021 -0.333419 v -0.123907 0.397932 -0.664658 v -0.113699 0.240517 -0.645459 v -0.381641 0.401913 -0.512072 v -0.448592 0.395605 -0.3508 v -0.450574 0.547705 -0.348333 v -0.384366 0.562601 -0.506817 v -0.462722 0.528827 -0.195952 v -0.310604 0.866976 0.0721301 v -0.372013 -0.183143 -0.115123 v -0.387686 -0.0789994 -0.141781 v -0.2476 0.197566 0.475487 v -0.230342 0.231532 0.488372 v -0.129238 -0.0890256 0.584927 v -0.123544 -0.115971 0.574872 v -0.114588 -0.128867 0.557082 v -0.221702 0.122764 0.506442 v -0.216107 0.26119 0.49413 v -0.253242 0.263207 0.478422 v -0.256568 0.260547 0.479737 v -0.115342 0.273619 0.475323 v -0.298743 0.299903 0.422953 v -0.291698 0.283732 0.432722 v -0.295854 0.288181 0.418253 v -0.142059 0.263388 0.482491 v -0.120428 0.267802 0.470325 v -0.172108 0.256934 0.489641 v -0.275083 0.271584 0.453242 v -0.248582 0.25684 0.473757 v -0.275001 0.268573 0.446274 v -0.234253 0.331396 0.490634 v -0.187624 0.326819 0.49717 v -0.300292 0.274694 0.432944 v -0.135658 -0.0739483 0.577444 v -0.237428 0.052791 0.514919 v -0.0645564 0.270789 0.544612 v -0.373819 0.514195 0.287264 v -0.321852 -0.214718 -0.338184 v -0.348166 -0.27584 -0.333396 v -0.352171 -0.333378 -0.190533 v -0.354936 -0.247872 -0.205511 v -0.0936937 -0.549137 0.186785 v -0.35669 -0.197653 -0.0299733 v -0.393228 -0.0876225 -0.0664009 v -0.29161 -0.321499 0.0380294 v -0.393638 -0.0904403 -0.014329 v -0.241608 0.243201 -0.602916 v -0.263209 0.569914 -0.609242 v -0.349441 -0.283282 -0.0863831 v -0.194821 -0.209504 -0.418674 v -0.0862925 -0.206323 -0.448413 v -0.261795 0.402579 -0.621448 v -0.456233 0.372302 -0.191263 v -0.455245 0.384813 -0.0591282 v -0.408072 0.116608 0.297155 v -0.298661 0.260278 0.439147 v -0.287606 0.265861 0.450068 v -0.279696 0.270216 0.454289 v -0.162731 0.0172638 0.536515 v -0.13087 -0.0222973 0.565699 v -0.101475 0.0572691 0.580946 v -0.0809198 0.301049 0.528407 v -0.0556351 0.322972 0.54498 v -0.272306 0.242932 0.464508 v -0.262964 0.253017 0.476001 v -0.233067 0.158607 0.487893 v -0.412053 0.186142 0.273695 v -0.154815 -0.0532762 0.55793 v -0.0277489 0.331782 0.556427 v -0.286179 0.277611 0.427928 v -0.183941 -0.499632 0.122144 v -0.331493 -0.386257 -0.0698735 v -0.206238 -0.274279 -0.416026 v -0.0915482 -0.274332 -0.437317 v -0.277193 -0.438779 0.0481257 v -0.484037 0.177414 -0.0276816 v -0.458618 0.163319 -0.0553633 v -0.437233 0.124752 -0.0367315 v -0.471526 0.1616 -0.00366555 v -0.476232 0.247018 0.00445479 v -0.494987 0.232631 -0.0169773 v -0.491035 0.317921 -0.0441971 v -0.515688 0.298728 -0.0523583 v -0.510175 0.332513 -0.1293 v -0.532917 0.316524 -0.12405 v -0.50993 0.303592 -0.186815 v -0.534671 0.290233 -0.170849 v -0.510152 0.231181 -0.21891 v -0.537459 0.228895 -0.193058 v -0.48934 0.122068 -0.20872 v -0.519208 0.128879 -0.191363 v -0.469632 0.0399528 -0.15424 v -0.470766 -0.00661202 -0.0930419 v -0.486142 0.00947665 -0.0819458 v -0.495221 0.0472722 -0.1369 v -0.459705 -0.0431682 -0.033446 v -0.483546 -0.0248521 -0.0238816 v -0.494011 0.289082 -0.0628932 v -0.473502 0.238904 -0.0420457 v -0.507246 0.300137 -0.117724 v -0.512134 0.2833 -0.158502 v -0.513712 0.235303 -0.176549 v -0.50102 0.136093 -0.181582 v -0.485095 0.0532704 -0.118549 v -0.485253 0.0267755 -0.0671726 v -0.481172 0.0136801 -0.012201 v -0.456127 -0.0187428 0.0196958 v -0.462909 0.027933 0.024969 v -0.454923 0.0845591 -0.060163 v -0.441284 0.0577602 -0.0294063 v -0.440921 0.0840388 -0.0210813 v -0.457712 0.18288 0.0414318 v -0.458378 0.268123 0.0210228 v -0.461588 0.318505 -0.044618 v -0.468843 0.311858 -0.142898 v -0.453707 0.232836 -0.195204 v -0.436969 0.13182 -0.191047 v -0.423167 0.0473306 -0.148288 v -0.421945 -0.00467109 -0.089692 v -0.423991 -0.0291198 -0.0260915 v -0.429434 -0.0102776 0.0297746 v -0.445242 0.0345158 0.0460211 v -0.481617 0.0602039 -0.0524227 v -0.474104 0.129276 -0.0866754 v -0.480325 0.0824545 -0.101285 v -0.469474 0.0446648 -0.013376 v -0.478167 0.0776431 0.00467109 v -0.503592 0.223961 -0.101887 v -0.502575 0.131983 -0.147242 v -0.453707 0.0999988 0.0450097 v -0.413357 0.138549 -0.218945 v -0.402232 0.0251035 -0.169299 v -0.434023 0.249632 -0.229901 v -0.0871226 -0.186639 0.484069 v -0.139686 -0.173807 0.465537 v -0.158481 -0.142278 0.458685 v -0.0688299 0.0121893 0.376371 v -0.150805 -0.116468 0.431278 v -0.126228 -0.116368 0.360528 v -0.142316 -0.166791 0.41184 v -0.0730392 -0.218144 0.372349 v -0.282087 0.293548 0.454716 v -0.283513 0.320341 0.45129 v -0.124398 0.285323 0.452968 v -0.126795 0.269175 0.455978 v -0.119353 0.275057 0.469524 v -0.156265 0.2548 0.466332 v -0.265074 0.27356 0.421036 v -0.214762 0.253899 0.455218 v -0.141855 0.312577 0.484315 v -0.212745 0.255776 0.486875 v -0.277117 0.302621 0.410811 v -0.252014 0.333887 0.433371 v -0.20141 0.342405 0.464461 v -0.120767 0.295565 0.473184 v -0.145333 0.322832 0.456154 v -0.126041 0.301873 0.455785 v -0.119879 0.284837 0.470541 v -0.0516539 -0.100847 0.27211 v -0.454245 -0.41571 -0.353027 v -0.413392 -0.372097 -0.332203 v -0.255785 -0.398019 -0.4467 v -0.294685 -0.464338 -0.476902 v -0.174388 -0.714777 0.156607 v -0.0715543 -0.738454 0.180284 v -0.0798266 -0.636725 0.177765 v -0.171536 -0.601788 0.131147 v -0.337345 -0.494639 -0.0546091 v -0.355094 -0.419334 -0.180442 v -0.379665 -0.504905 -0.184915 v -0.373053 -0.619338 -0.0373044 v -0.45328 -0.545816 -0.197379 v -0.454128 -0.653065 -0.0942754 v -0.0965876 -0.904778 0.254759 v -0.0736004 -0.845567 0.20775 v -0.172974 -0.81408 0.195975 v -0.1973 -0.864375 0.243622 v -0.520961 -0.488138 -0.3841 v -0.556272 -0.584635 -0.21946 v -0.439238 -0.799155 0.0975785 v -0.381694 -0.748264 0.0442672 v -0.45103 -0.731883 -0.0219173 v -0.519067 -0.768135 -0.0077988 v -0.273785 -0.806328 0.115322 v -0.319391 -0.83802 0.183769 v -0.163088 -0.604103 -0.559421 v -0.356672 -0.543712 -0.525361 v -0.131226 -0.496761 -0.498854 v -0.114629 -0.410074 -0.45775 v -0.546533 -0.697291 -0.117619 v -0.100633 -0.33885 -0.437013 v -0.22677 -0.331835 -0.424707 v -0.274931 -0.684651 0.0790578 v -0.28021 -0.553908 0.0669913 v -0.378028 -0.321668 -0.326088 v 0.172833 0.300014 0.41564 v -0.171097 0.299996 0.415616 # 1258 vertices vt 0.532 0.923 0.000 vt 0.535 0.917 0.000 vt 0.542 0.923 0.000 vt 0.541 0.929 0.000 vt 0.521 0.984 0.000 vt 0.521 0.996 0.000 vt 0.505 0.998 0.000 vt 0.500 0.985 0.000 vt 0.504 0.917 0.000 vt 0.507 0.910 0.000 vt 0.516 0.910 0.000 vt 0.515 0.918 0.000 vt 0.523 0.921 0.000 vt 0.525 0.913 0.000 vt 0.549 0.958 0.000 vt 0.538 0.954 0.000 vt 0.544 0.942 0.000 vt 0.550 0.946 0.000 vt 0.545 0.935 0.000 vt 0.550 0.932 0.000 vt 0.547 0.974 0.000 vt 0.533 0.967 0.000 vt 0.500 0.917 0.000 vt 0.500 0.910 0.000 vt 0.542 0.987 0.000 vt 0.533 0.994 0.000 vt 0.616 0.254 0.000 vt 0.653 0.261 0.000 vt 0.658 0.307 0.000 vt 0.619 0.292 0.000 vt 0.636 0.438 0.000 vt 0.620 0.419 0.000 vt 0.627 0.396 0.000 vt 0.647 0.414 0.000 vt 0.886 0.312 0.000 vt 0.897 0.370 0.000 vt 0.860 0.369 0.000 vt 0.844 0.308 0.000 vt 0.740 0.593 0.000 vt 0.741 0.542 0.000 vt 0.759 0.541 0.000 vt 0.768 0.598 0.000 vt 0.644 0.213 0.000 vt 0.561 0.175 0.000 vt 0.566 0.146 0.000 vt 0.644 0.174 0.000 vt 0.580 0.254 0.000 vt 0.585 0.277 0.000 vt 0.565 0.268 0.000 vt 0.565 0.256 0.000 vt 0.590 0.217 0.000 vt 0.544 0.195 0.000 vt 0.771 0.721 0.000 vt 0.736 0.712 0.000 vt 0.758 0.653 0.000 vt 0.794 0.663 0.000 vt 0.669 0.622 0.000 vt 0.685 0.632 0.000 vt 0.665 0.669 0.000 vt 0.652 0.651 0.000 vt 0.623 0.588 0.000 vt 0.632 0.582 0.000 vt 0.639 0.590 0.000 vt 0.627 0.599 0.000 vt 0.641 0.632 0.000 vt 0.657 0.612 0.000 vt 0.619 0.580 0.000 vt 0.617 0.575 0.000 vt 0.623 0.573 0.000 vt 0.627 0.576 0.000 vt 0.708 0.702 0.000 vt 0.729 0.646 0.000 vt 0.633 0.614 0.000 vt 0.647 0.601 0.000 vt 0.604 0.718 0.000 vt 0.574 0.725 0.000 vt 0.567 0.686 0.000 vt 0.596 0.682 0.000 vt 0.562 0.648 0.000 vt 0.590 0.649 0.000 vt 0.618 0.756 0.000 vt 0.584 0.769 0.000 vt 0.586 0.587 0.000 vt 0.566 0.586 0.000 vt 0.568 0.579 0.000 vt 0.586 0.580 0.000 vt 0.569 0.574 0.000 vt 0.586 0.573 0.000 vt 0.562 0.627 0.000 vt 0.587 0.627 0.000 vt 0.587 0.610 0.000 vt 0.563 0.608 0.000 vt 0.565 0.595 0.000 vt 0.587 0.596 0.000 vt 0.521 0.441 0.000 vt 0.526 0.450 0.000 vt 0.520 0.450 0.000 vt 0.517 0.445 0.000 vt 0.720 0.504 0.000 vt 0.709 0.467 0.000 vt 0.727 0.446 0.000 vt 0.738 0.494 0.000 vt 0.656 0.383 0.000 vt 0.660 0.348 0.000 vt 0.684 0.368 0.000 vt 0.673 0.403 0.000 vt 0.572 0.371 0.000 vt 0.573 0.365 0.000 vt 0.581 0.364 0.000 vt 0.581 0.374 0.000 vt 0.708 0.400 0.000 vt 0.693 0.431 0.000 vt 0.604 0.401 0.000 vt 0.609 0.383 0.000 vt 0.557 0.364 0.000 vt 0.559 0.365 0.000 vt 0.557 0.366 0.000 vt 0.556 0.364 0.000 vt 0.552 0.367 0.000 vt 0.552 0.364 0.000 vt 0.568 0.377 0.000 vt 0.561 0.374 0.000 vt 0.566 0.370 0.000 vt 0.594 0.377 0.000 vt 0.594 0.363 0.000 vt 0.653 0.551 0.000 vt 0.644 0.534 0.000 vt 0.658 0.523 0.000 vt 0.666 0.545 0.000 vt 0.637 0.480 0.000 vt 0.625 0.458 0.000 vt 0.649 0.459 0.000 vt 0.662 0.434 0.000 vt 0.557 0.345 0.000 vt 0.553 0.353 0.000 vt 0.543 0.349 0.000 vt 0.546 0.337 0.000 vt 0.586 0.403 0.000 vt 0.573 0.392 0.000 vt 0.579 0.382 0.000 vt 0.591 0.389 0.000 vt 0.572 0.343 0.000 vt 0.584 0.331 0.000 vt 0.590 0.347 0.000 vt 0.578 0.353 0.000 vt 0.553 0.358 0.000 vt 0.543 0.355 0.000 vt 0.553 0.499 0.000 vt 0.541 0.507 0.000 vt 0.542 0.484 0.000 vt 0.553 0.477 0.000 vt 0.539 0.532 0.000 vt 0.529 0.541 0.000 vt 0.531 0.513 0.000 vt 0.551 0.538 0.000 vt 0.538 0.552 0.000 vt 0.552 0.521 0.000 vt 0.908 0.437 0.000 vt 0.876 0.429 0.000 vt 0.608 0.340 0.000 vt 0.599 0.314 0.000 vt 0.629 0.336 0.000 vt 0.691 0.326 0.000 vt 0.723 0.365 0.000 vt 0.748 0.426 0.000 vt 0.755 0.489 0.000 vt 0.564 0.825 0.000 vt 0.590 0.868 0.000 vt 0.558 0.886 0.000 vt 0.533 0.834 0.000 vt 0.637 0.789 0.000 vt 0.673 0.755 0.000 vt 0.702 0.774 0.000 vt 0.665 0.817 0.000 vt 0.740 0.787 0.000 vt 0.545 0.727 0.000 vt 0.540 0.686 0.000 vt 0.551 0.550 0.000 vt 0.538 0.572 0.000 vt 0.520 0.546 0.000 vt 0.522 0.517 0.000 vt 0.552 0.775 0.000 vt 0.524 0.777 0.000 vt 0.521 0.728 0.000 vt 0.500 0.687 0.000 vt 0.500 0.651 0.000 vt 0.515 0.650 0.000 vt 0.518 0.687 0.000 vt 0.500 0.727 0.000 vt 0.625 0.671 0.000 vt 0.618 0.644 0.000 vt 0.591 0.533 0.000 vt 0.571 0.539 0.000 vt 0.569 0.527 0.000 vt 0.589 0.518 0.000 vt 0.545 0.436 0.000 vt 0.525 0.427 0.000 vt 0.528 0.413 0.000 vt 0.549 0.425 0.000 vt 0.556 0.449 0.000 vt 0.563 0.439 0.000 vt 0.514 0.395 0.000 vt 0.532 0.396 0.000 vt 0.513 0.409 0.000 vt 0.566 0.511 0.000 vt 0.564 0.490 0.000 vt 0.577 0.478 0.000 vt 0.584 0.500 0.000 vt 0.500 0.408 0.000 vt 0.500 0.394 0.000 vt 0.571 0.457 0.000 vt 0.561 0.468 0.000 vt 0.554 0.561 0.000 vt 0.557 0.563 0.000 vt 0.552 0.569 0.000 vt 0.548 0.569 0.000 vt 0.627 0.847 0.000 vt 0.674 0.871 0.000 vt 0.645 0.898 0.000 vt 0.776 0.920 0.000 vt 0.709 0.921 0.000 vt 0.729 0.888 0.000 vt 0.783 0.887 0.000 vt 0.693 0.947 0.000 vt 0.621 0.920 0.000 vt 0.535 0.642 0.000 vt 0.542 0.618 0.000 vt 0.545 0.599 0.000 vt 0.559 0.383 0.000 vt 0.552 0.377 0.000 vt 0.531 0.470 0.000 vt 0.520 0.472 0.000 vt 0.517 0.456 0.000 vt 0.528 0.457 0.000 vt 0.530 0.438 0.000 vt 0.517 0.436 0.000 vt 0.528 0.383 0.000 vt 0.513 0.384 0.000 vt 0.512 0.374 0.000 vt 0.526 0.374 0.000 vt 0.512 0.367 0.000 vt 0.526 0.366 0.000 vt 0.512 0.362 0.000 vt 0.526 0.362 0.000 vt 0.511 0.422 0.000 vt 0.500 0.384 0.000 vt 0.500 0.375 0.000 vt 0.500 0.362 0.000 vt 0.500 0.367 0.000 vt 0.511 0.472 0.000 vt 0.508 0.457 0.000 vt 0.521 0.491 0.000 vt 0.512 0.519 0.000 vt 0.512 0.491 0.000 vt 0.511 0.550 0.000 vt 0.520 0.576 0.000 vt 0.510 0.583 0.000 vt 0.500 0.457 0.000 vt 0.500 0.472 0.000 vt 0.500 0.491 0.000 vt 0.654 0.584 0.000 vt 0.656 0.568 0.000 vt 0.669 0.567 0.000 vt 0.666 0.589 0.000 vt 0.705 0.639 0.000 vt 0.718 0.591 0.000 vt 0.684 0.563 0.000 vt 0.680 0.592 0.000 vt 0.637 0.575 0.000 vt 0.636 0.566 0.000 vt 0.645 0.567 0.000 vt 0.645 0.579 0.000 vt 0.723 0.546 0.000 vt 0.697 0.592 0.000 vt 0.702 0.554 0.000 vt 0.500 0.163 0.000 vt 0.500 0.137 0.000 vt 0.579 0.298 0.000 vt 0.570 0.317 0.000 vt 0.554 0.307 0.000 vt 0.560 0.287 0.000 vt 0.534 0.318 0.000 vt 0.517 0.314 0.000 vt 0.519 0.296 0.000 vt 0.538 0.300 0.000 vt 0.562 0.362 0.000 vt 0.559 0.363 0.000 vt 0.557 0.362 0.000 vt 0.559 0.360 0.000 vt 0.563 0.365 0.000 vt 0.561 0.368 0.000 vt 0.543 0.360 0.000 vt 0.531 0.358 0.000 vt 0.531 0.351 0.000 vt 0.611 0.437 0.000 vt 0.613 0.475 0.000 vt 0.624 0.497 0.000 vt 0.580 0.445 0.000 vt 0.590 0.466 0.000 vt 0.598 0.418 0.000 vt 0.648 0.501 0.000 vt 0.633 0.516 0.000 vt 0.641 0.554 0.000 vt 0.630 0.541 0.000 vt 0.733 0.331 0.000 vt 0.696 0.288 0.000 vt 0.706 0.252 0.000 vt 0.751 0.313 0.000 vt 0.683 0.535 0.000 vt 0.674 0.508 0.000 vt 0.999 0.696 0.000 vt 0.986 0.778 0.000 vt 0.950 0.772 0.000 vt 0.967 0.695 0.000 vt 0.600 0.811 0.000 vt 0.552 0.361 0.000 vt 0.547 0.367 0.000 vt 0.546 0.364 0.000 vt 0.525 0.254 0.000 vt 0.546 0.261 0.000 vt 0.542 0.280 0.000 vt 0.522 0.274 0.000 vt 0.631 0.369 0.000 vt 0.678 0.460 0.000 vt 0.662 0.482 0.000 vt 0.770 0.948 0.000 vt 0.762 0.981 0.000 vt 0.676 0.977 0.000 vt 0.845 0.915 0.000 vt 0.835 0.891 0.000 vt 0.569 0.560 0.000 vt 0.582 0.558 0.000 vt 0.580 0.563 0.000 vt 0.569 0.564 0.000 vt 0.590 0.544 0.000 vt 0.571 0.548 0.000 vt 0.635 0.701 0.000 vt 0.651 0.731 0.000 vt 0.607 0.593 0.000 vt 0.609 0.606 0.000 vt 0.543 0.570 0.000 vt 0.553 0.556 0.000 vt 0.552 0.580 0.000 vt 0.556 0.574 0.000 vt 0.569 0.554 0.000 vt 0.585 0.551 0.000 vt 0.559 0.566 0.000 vt 0.550 0.458 0.000 vt 0.532 0.330 0.000 vt 0.549 0.325 0.000 vt 0.610 0.364 0.000 vt 0.589 0.432 0.000 vt 0.578 0.417 0.000 vt 0.570 0.357 0.000 vt 0.565 0.360 0.000 vt 0.562 0.356 0.000 vt 0.565 0.351 0.000 vt 0.557 0.364 0.000 vt 0.556 0.364 0.000 vt 0.548 0.371 0.000 vt 0.557 0.371 0.000 vt 0.762 0.385 0.000 vt 0.513 0.445 0.000 vt 0.508 0.444 0.000 vt 0.500 0.520 0.000 vt 0.939 0.378 0.000 vt 0.932 0.316 0.000 vt 0.972 0.321 0.000 vt 0.974 0.384 0.000 vt 0.605 0.572 0.000 vt 0.605 0.578 0.000 vt 0.605 0.584 0.000 vt 0.559 0.571 0.000 vt 0.562 0.333 0.000 vt 0.500 0.552 0.000 vt 0.500 0.585 0.000 vt 0.531 0.343 0.000 vt 0.514 0.338 0.000 vt 0.516 0.324 0.000 vt 0.532 0.488 0.000 vt 0.534 0.448 0.000 vt 0.540 0.446 0.000 vt 0.545 0.448 0.000 vt 0.538 0.455 0.000 vt 0.541 0.466 0.000 vt 0.612 0.623 0.000 vt 0.567 0.366 0.000 vt 0.513 0.356 0.000 vt 0.500 0.355 0.000 vt 0.500 0.346 0.000 vt 0.514 0.348 0.000 vt 0.543 0.363 0.000 vt 0.552 0.364 0.000 vt 0.531 0.362 0.000 vt 0.512 0.361 0.000 vt 0.509 0.433 0.000 vt 0.500 0.444 0.000 vt 0.500 0.432 0.000 vt 0.603 0.551 0.000 vt 0.599 0.557 0.000 vt 0.627 0.570 0.000 vt 0.631 0.571 0.000 vt 0.625 0.566 0.000 vt 0.622 0.569 0.000 vt 0.621 0.567 0.000 vt 0.529 0.234 0.000 vt 0.500 0.249 0.000 vt 0.500 0.227 0.000 vt 0.550 0.245 0.000 vt 0.857 0.816 0.000 vt 0.825 0.804 0.000 vt 0.851 0.737 0.000 vt 0.886 0.748 0.000 vt 0.821 0.866 0.000 vt 0.798 0.856 0.000 vt 0.783 0.797 0.000 vt 0.810 0.729 0.000 vt 0.755 0.848 0.000 vt 0.534 0.215 0.000 vt 0.563 0.233 0.000 vt 0.548 0.588 0.000 vt 0.884 0.835 0.000 vt 0.908 0.854 0.000 vt 0.919 0.761 0.000 vt 0.947 0.512 0.000 vt 0.944 0.446 0.000 vt 0.974 0.452 0.000 vt 0.974 0.519 0.000 vt 0.915 0.504 0.000 vt 0.887 0.498 0.000 vt 0.917 0.564 0.000 vt 0.890 0.556 0.000 vt 0.999 0.634 0.000 vt 0.973 0.633 0.000 vt 0.975 0.577 0.000 vt 0.999 0.579 0.000 vt 0.882 0.614 0.000 vt 0.911 0.622 0.000 vt 0.901 0.679 0.000 vt 0.868 0.671 0.000 vt 0.833 0.667 0.000 vt 0.708 0.836 0.000 vt 0.500 0.205 0.000 vt 0.826 0.364 0.000 vt 0.801 0.303 0.000 vt 0.613 0.529 0.000 vt 0.607 0.544 0.000 vt 0.541 0.380 0.000 vt 0.538 0.372 0.000 vt 0.537 0.366 0.000 vt 0.537 0.363 0.000 vt 0.598 0.945 0.000 vt 0.524 0.902 0.000 vt 0.599 0.489 0.000 vt 0.609 0.563 0.000 vt 0.596 0.563 0.000 vt 0.612 0.559 0.000 vt 0.557 0.569 0.000 vt 0.620 0.571 0.000 vt 0.616 0.569 0.000 vt 0.618 0.569 0.000 vt 0.569 0.568 0.000 vt 0.561 0.568 0.000 vt 0.579 0.567 0.000 vt 0.616 0.564 0.000 vt 0.613 0.567 0.000 vt 0.607 0.567 0.000 vt 0.587 0.568 0.000 vt 0.606 0.568 0.000 vt 0.630 0.565 0.000 vt 0.548 0.389 0.000 vt 0.601 0.452 0.000 vt 0.529 0.566 0.000 vt 0.684 0.686 0.000 vt 0.872 0.222 0.000 vt 0.876 0.265 0.000 vt 0.825 0.258 0.000 vt 0.821 0.214 0.000 vt 0.561 0.119 0.000 vt 0.500 0.114 0.000 vt 0.771 0.304 0.000 vt 0.797 0.363 0.000 vt 0.726 0.227 0.000 vt 0.777 0.371 0.000 vt 0.947 0.571 0.000 vt 0.999 0.388 0.000 vt 0.999 0.456 0.000 vt 0.999 0.524 0.000 vt 0.936 0.877 0.000 vt 0.856 0.945 0.000 vt 0.999 0.323 0.000 vt 0.935 0.689 0.000 vt 0.776 0.240 0.000 vt 0.928 0.265 0.000 vt 0.969 0.264 0.000 vt 0.999 0.267 0.000 vt 0.943 0.628 0.000 vt 0.806 0.622 0.000 vt 0.851 0.611 0.000 vt 0.500 0.777 0.000 vt 0.500 0.839 0.000 vt 0.692 0.489 0.000 vt 0.631 0.558 0.000 vt 0.622 0.562 0.000 vt 0.626 0.560 0.000 vt 0.555 0.413 0.000 vt 0.570 0.429 0.000 vt 0.539 0.440 0.000 vt 0.524 0.607 0.000 vt 0.531 0.591 0.000 vt 0.500 0.361 0.000 vt 0.500 0.321 0.000 vt 0.500 0.312 0.000 vt 0.500 0.336 0.000 vt 0.500 0.294 0.000 vt 0.500 0.273 0.000 vt 0.622 0.549 0.000 vt 0.616 0.554 0.000 vt 0.607 0.509 0.000 vt 0.701 0.520 0.000 vt 0.500 0.421 0.000 vt 0.564 0.403 0.000 vt 0.511 0.615 0.000 vt 0.500 0.618 0.000 vt 0.617 0.568 0.000 vt 0.636 0.139 0.000 vt 0.764 0.192 0.000 vt 0.921 0.220 0.000 vt 0.967 0.219 0.000 vt 0.708 0.168 0.000 vt 0.999 0.218 0.000 vt 0.803 0.523 0.000 vt 0.794 0.535 0.000 vt 0.783 0.527 0.000 vt 0.791 0.508 0.000 vt 0.789 0.571 0.000 vt 0.797 0.562 0.000 vt 0.813 0.591 0.000 vt 0.815 0.578 0.000 vt 0.839 0.583 0.000 vt 0.835 0.574 0.000 vt 0.850 0.569 0.000 vt 0.845 0.560 0.000 vt 0.855 0.539 0.000 vt 0.847 0.535 0.000 vt 0.850 0.501 0.000 vt 0.841 0.502 0.000 vt 0.814 0.438 0.000 vt 0.836 0.464 0.000 vt 0.828 0.472 0.000 vt 0.809 0.452 0.000 vt 0.792 0.427 0.000 vt 0.790 0.441 0.000 vt 0.818 0.567 0.000 vt 0.807 0.550 0.000 vt 0.831 0.561 0.000 vt 0.839 0.553 0.000 vt 0.837 0.534 0.000 vt 0.831 0.505 0.000 vt 0.820 0.479 0.000 vt 0.804 0.465 0.000 vt 0.786 0.460 0.000 vt 0.773 0.456 0.000 vt 0.779 0.433 0.000 vt 0.797 0.489 0.000 vt 0.785 0.495 0.000 vt 0.789 0.486 0.000 vt 0.772 0.537 0.000 vt 0.781 0.583 0.000 vt 0.812 0.602 0.000 vt 0.848 0.587 0.000 vt 0.862 0.546 0.000 vt 0.859 0.500 0.000 vt 0.820 0.412 0.000 vt 0.843 0.450 0.000 vt 0.791 0.404 0.000 vt 0.773 0.417 0.000 vt 0.764 0.447 0.000 vt 0.801 0.477 0.000 vt 0.813 0.487 0.000 vt 0.806 0.496 0.000 vt 0.787 0.478 0.000 vt 0.778 0.489 0.000 vt 0.822 0.538 0.000 vt 0.822 0.510 0.000 vt 0.767 0.492 0.000 vt 0.870 0.496 0.000 vt 0.851 0.425 0.000 vt 0.872 0.552 0.000 vt 0.500 0.183 0.000 vt 0.516 0.930 0.000 vt 0.500 0.928 0.000 vt 0.528 0.934 0.000 vt 0.537 0.938 0.000 vt 0.516 0.970 0.000 vt 0.520 0.955 0.000 vt 0.530 0.952 0.000 vt 0.522 0.944 0.000 vt 0.512 0.942 0.000 vt 0.615 0.572 0.000 vt 0.612 0.569 0.000 vt 0.576 0.968 0.000 vt 0.573 0.973 0.000 vt 0.562 0.969 0.000 vt 0.563 0.961 0.000 vt 0.571 0.956 0.000 vt 0.582 0.961 0.000 vt 0.611 0.961 0.000 vt 0.606 0.967 0.000 vt 0.595 0.960 0.000 vt 0.601 0.955 0.000 vt 0.570 0.569 0.000 vt 0.595 0.566 0.000 vt 0.616 0.967 0.000 vt 0.617 0.975 0.000 vt 0.607 0.978 0.000 vt 0.614 0.982 0.000 vt 0.605 0.991 0.000 vt 0.599 0.986 0.000 vt 0.593 0.996 0.000 vt 0.589 0.989 0.000 vt 0.562 0.570 0.000 vt 0.573 0.994 0.000 vt 0.579 0.987 0.000 vt 0.584 0.996 0.000 vt 0.581 0.953 0.000 vt 0.592 0.953 0.000 vt 0.561 0.988 0.000 vt 0.572 0.981 0.000 vt 0.563 0.978 0.000 vt 0.500 0.970 0.000 vt 0.500 0.943 0.000 vt 0.511 0.956 0.000 vt 0.500 0.956 0.000 vt 0.868 0.132 0.000 vt 0.867 0.090 0.000 vt 0.916 0.092 0.000 vt 0.918 0.133 0.000 vt 0.554 0.066 0.000 vt 0.612 0.070 0.000 vt 0.619 0.103 0.000 vt 0.558 0.095 0.000 vt 0.815 0.169 0.000 vt 0.758 0.148 0.000 vt 0.747 0.102 0.000 vt 0.814 0.126 0.000 vt 0.770 0.072 0.000 vt 0.817 0.087 0.000 vt 0.552 0.038 0.000 vt 0.551 0.020 0.000 vt 0.602 0.021 0.000 vt 0.605 0.039 0.000 vt 0.821 0.050 0.000 vt 0.867 0.055 0.000 vt 0.712 0.053 0.000 vt 0.700 0.022 0.000 vt 0.739 0.023 0.000 vt 0.740 0.052 0.000 vt 0.652 0.022 0.000 vt 0.659 0.043 0.000 vt 0.913 0.055 0.000 vt 0.959 0.055 0.000 vt 0.960 0.091 0.000 vt 0.999 0.089 0.000 vt 0.999 0.131 0.000 vt 0.962 0.133 0.000 vt 0.999 0.053 0.000 vt 0.778 0.038 0.000 vt 0.917 0.177 0.000 vt 0.965 0.178 0.000 vt 0.674 0.083 0.000 vt 0.685 0.124 0.000 vt 0.999 0.175 0.000 vt 0.500 0.037 0.000 vt 0.500 0.066 0.000 vt 0.871 0.175 0.000 vt 0.500 0.019 0.000 vt 0.500 0.092 0.000 vt 0.999 0.002 0.000 vt 0.958 0.002 0.000 vt 0.867 0.002 0.000 vt 0.823 0.002 0.000 vt 0.908 0.002 0.000 vt 0.601 0.002 0.000 vt 0.550 0.002 0.000 vt 0.697 0.002 0.000 vt 0.650 0.002 0.000 vt 0.782 0.002 0.000 vt 0.740 0.002 0.000 vt 0.500 0.002 0.000 vt 0.468 0.923 0.000 vt 0.459 0.929 0.000 vt 0.458 0.923 0.000 vt 0.465 0.917 0.000 vt 0.479 0.984 0.000 vt 0.495 0.998 0.000 vt 0.479 0.996 0.000 vt 0.496 0.917 0.000 vt 0.485 0.918 0.000 vt 0.484 0.910 0.000 vt 0.493 0.910 0.000 vt 0.477 0.921 0.000 vt 0.475 0.913 0.000 vt 0.451 0.958 0.000 vt 0.450 0.946 0.000 vt 0.456 0.942 0.000 vt 0.462 0.954 0.000 vt 0.455 0.935 0.000 vt 0.450 0.932 0.000 vt 0.467 0.967 0.000 vt 0.453 0.974 0.000 vt 0.467 0.994 0.000 vt 0.458 0.987 0.000 vt 0.384 0.254 0.000 vt 0.381 0.292 0.000 vt 0.342 0.307 0.000 vt 0.347 0.261 0.000 vt 0.364 0.438 0.000 vt 0.353 0.414 0.000 vt 0.373 0.396 0.000 vt 0.380 0.419 0.000 vt 0.114 0.312 0.000 vt 0.156 0.308 0.000 vt 0.140 0.369 0.000 vt 0.103 0.370 0.000 vt 0.260 0.593 0.000 vt 0.232 0.598 0.000 vt 0.241 0.541 0.000 vt 0.259 0.542 0.000 vt 0.356 0.213 0.000 vt 0.356 0.174 0.000 vt 0.434 0.146 0.000 vt 0.439 0.175 0.000 vt 0.420 0.254 0.000 vt 0.435 0.256 0.000 vt 0.435 0.268 0.000 vt 0.415 0.277 0.000 vt 0.456 0.195 0.000 vt 0.410 0.217 0.000 vt 0.229 0.721 0.000 vt 0.206 0.663 0.000 vt 0.242 0.653 0.000 vt 0.264 0.712 0.000 vt 0.331 0.622 0.000 vt 0.348 0.651 0.000 vt 0.335 0.669 0.000 vt 0.315 0.632 0.000 vt 0.377 0.588 0.000 vt 0.373 0.599 0.000 vt 0.361 0.590 0.000 vt 0.368 0.582 0.000 vt 0.359 0.632 0.000 vt 0.343 0.612 0.000 vt 0.381 0.580 0.000 vt 0.373 0.576 0.000 vt 0.377 0.573 0.000 vt 0.383 0.575 0.000 vt 0.292 0.702 0.000 vt 0.271 0.646 0.000 vt 0.353 0.601 0.000 vt 0.367 0.614 0.000 vt 0.396 0.718 0.000 vt 0.404 0.682 0.000 vt 0.433 0.686 0.000 vt 0.426 0.725 0.000 vt 0.410 0.649 0.000 vt 0.438 0.648 0.000 vt 0.416 0.769 0.000 vt 0.382 0.756 0.000 vt 0.414 0.587 0.000 vt 0.414 0.580 0.000 vt 0.432 0.579 0.000 vt 0.434 0.586 0.000 vt 0.431 0.574 0.000 vt 0.414 0.573 0.000 vt 0.413 0.627 0.000 vt 0.438 0.627 0.000 vt 0.413 0.610 0.000 vt 0.413 0.596 0.000 vt 0.435 0.595 0.000 vt 0.437 0.608 0.000 vt 0.479 0.441 0.000 vt 0.483 0.445 0.000 vt 0.480 0.450 0.000 vt 0.474 0.450 0.000 vt 0.280 0.504 0.000 vt 0.262 0.494 0.000 vt 0.273 0.446 0.000 vt 0.291 0.467 0.000 vt 0.344 0.383 0.000 vt 0.327 0.403 0.000 vt 0.316 0.368 0.000 vt 0.340 0.348 0.000 vt 0.428 0.371 0.000 vt 0.419 0.374 0.000 vt 0.419 0.364 0.000 vt 0.427 0.365 0.000 vt 0.307 0.431 0.000 vt 0.292 0.400 0.000 vt 0.391 0.383 0.000 vt 0.396 0.401 0.000 vt 0.443 0.364 0.000 vt 0.444 0.364 0.000 vt 0.443 0.366 0.000 vt 0.441 0.365 0.000 vt 0.448 0.367 0.000 vt 0.448 0.364 0.000 vt 0.432 0.377 0.000 vt 0.434 0.370 0.000 vt 0.439 0.374 0.000 vt 0.406 0.377 0.000 vt 0.406 0.363 0.000 vt 0.347 0.551 0.000 vt 0.334 0.545 0.000 vt 0.342 0.523 0.000 vt 0.356 0.534 0.000 vt 0.363 0.480 0.000 vt 0.351 0.459 0.000 vt 0.375 0.458 0.000 vt 0.338 0.434 0.000 vt 0.443 0.345 0.000 vt 0.454 0.337 0.000 vt 0.457 0.349 0.000 vt 0.447 0.353 0.000 vt 0.414 0.403 0.000 vt 0.409 0.389 0.000 vt 0.421 0.382 0.000 vt 0.427 0.392 0.000 vt 0.428 0.343 0.000 vt 0.422 0.353 0.000 vt 0.410 0.347 0.000 vt 0.416 0.331 0.000 vt 0.457 0.355 0.000 vt 0.447 0.358 0.000 vt 0.447 0.499 0.000 vt 0.447 0.477 0.000 vt 0.458 0.484 0.000 vt 0.459 0.507 0.000 vt 0.461 0.532 0.000 vt 0.469 0.513 0.000 vt 0.471 0.541 0.000 vt 0.449 0.538 0.000 vt 0.448 0.521 0.000 vt 0.462 0.552 0.000 vt 0.124 0.429 0.000 vt 0.092 0.437 0.000 vt 0.392 0.340 0.000 vt 0.371 0.336 0.000 vt 0.401 0.314 0.000 vt 0.309 0.326 0.000 vt 0.252 0.426 0.000 vt 0.277 0.365 0.000 vt 0.245 0.489 0.000 vt 0.436 0.825 0.000 vt 0.467 0.834 0.000 vt 0.442 0.886 0.000 vt 0.410 0.868 0.000 vt 0.363 0.789 0.000 vt 0.335 0.817 0.000 vt 0.298 0.774 0.000 vt 0.327 0.755 0.000 vt 0.260 0.787 0.000 vt 0.460 0.686 0.000 vt 0.455 0.727 0.000 vt 0.462 0.572 0.000 vt 0.449 0.550 0.000 vt 0.480 0.546 0.000 vt 0.478 0.517 0.000 vt 0.479 0.728 0.000 vt 0.476 0.777 0.000 vt 0.448 0.775 0.000 vt 0.482 0.687 0.000 vt 0.485 0.650 0.000 vt 0.375 0.671 0.000 vt 0.382 0.644 0.000 vt 0.409 0.533 0.000 vt 0.411 0.518 0.000 vt 0.431 0.527 0.000 vt 0.429 0.539 0.000 vt 0.455 0.436 0.000 vt 0.451 0.425 0.000 vt 0.472 0.413 0.000 vt 0.475 0.427 0.000 vt 0.444 0.449 0.000 vt 0.437 0.439 0.000 vt 0.486 0.395 0.000 vt 0.487 0.409 0.000 vt 0.468 0.396 0.000 vt 0.434 0.511 0.000 vt 0.416 0.500 0.000 vt 0.423 0.478 0.000 vt 0.436 0.490 0.000 vt 0.429 0.457 0.000 vt 0.439 0.468 0.000 vt 0.446 0.561 0.000 vt 0.452 0.569 0.000 vt 0.448 0.569 0.000 vt 0.443 0.563 0.000 vt 0.373 0.847 0.000 vt 0.355 0.898 0.000 vt 0.326 0.871 0.000 vt 0.224 0.920 0.000 vt 0.217 0.887 0.000 vt 0.271 0.888 0.000 vt 0.291 0.921 0.000 vt 0.379 0.920 0.000 vt 0.307 0.947 0.000 vt 0.465 0.642 0.000 vt 0.455 0.599 0.000 vt 0.458 0.618 0.000 vt 0.448 0.377 0.000 vt 0.441 0.383 0.000 vt 0.469 0.470 0.000 vt 0.472 0.457 0.000 vt 0.483 0.456 0.000 vt 0.480 0.472 0.000 vt 0.470 0.438 0.000 vt 0.483 0.436 0.000 vt 0.472 0.383 0.000 vt 0.474 0.374 0.000 vt 0.488 0.374 0.000 vt 0.487 0.384 0.000 vt 0.474 0.366 0.000 vt 0.488 0.367 0.000 vt 0.474 0.362 0.000 vt 0.488 0.362 0.000 vt 0.489 0.422 0.000 vt 0.492 0.457 0.000 vt 0.489 0.472 0.000 vt 0.479 0.491 0.000 vt 0.488 0.491 0.000 vt 0.488 0.519 0.000 vt 0.489 0.550 0.000 vt 0.490 0.583 0.000 vt 0.480 0.576 0.000 vt 0.346 0.584 0.000 vt 0.334 0.589 0.000 vt 0.331 0.567 0.000 vt 0.344 0.568 0.000 vt 0.295 0.639 0.000 vt 0.282 0.591 0.000 vt 0.320 0.592 0.000 vt 0.316 0.563 0.000 vt 0.363 0.575 0.000 vt 0.355 0.579 0.000 vt 0.355 0.567 0.000 vt 0.364 0.566 0.000 vt 0.277 0.546 0.000 vt 0.298 0.554 0.000 vt 0.303 0.592 0.000 vt 0.421 0.298 0.000 vt 0.440 0.287 0.000 vt 0.446 0.307 0.000 vt 0.430 0.317 0.000 vt 0.466 0.318 0.000 vt 0.462 0.300 0.000 vt 0.481 0.296 0.000 vt 0.483 0.314 0.000 vt 0.438 0.362 0.000 vt 0.441 0.360 0.000 vt 0.443 0.362 0.000 vt 0.441 0.363 0.000 vt 0.439 0.368 0.000 vt 0.437 0.365 0.000 vt 0.469 0.351 0.000 vt 0.469 0.358 0.000 vt 0.457 0.360 0.000 vt 0.389 0.437 0.000 vt 0.387 0.475 0.000 vt 0.376 0.497 0.000 vt 0.420 0.445 0.000 vt 0.410 0.466 0.000 vt 0.402 0.418 0.000 vt 0.352 0.501 0.000 vt 0.367 0.516 0.000 vt 0.359 0.554 0.000 vt 0.370 0.541 0.000 vt 0.267 0.331 0.000 vt 0.249 0.313 0.000 vt 0.294 0.252 0.000 vt 0.304 0.288 0.000 vt 0.317 0.535 0.000 vt 0.326 0.508 0.000 vt 0.001 0.696 0.000 vt 0.033 0.695 0.000 vt 0.050 0.772 0.000 vt 0.014 0.778 0.000 vt 0.400 0.811 0.000 vt 0.448 0.361 0.000 vt 0.454 0.364 0.000 vt 0.453 0.367 0.000 vt 0.475 0.254 0.000 vt 0.478 0.274 0.000 vt 0.458 0.280 0.000 vt 0.454 0.261 0.000 vt 0.369 0.369 0.000 vt 0.322 0.460 0.000 vt 0.338 0.482 0.000 vt 0.324 0.977 0.000 vt 0.238 0.981 0.000 vt 0.230 0.948 0.000 vt 0.155 0.915 0.000 vt 0.165 0.891 0.000 vt 0.431 0.560 0.000 vt 0.431 0.564 0.000 vt 0.420 0.563 0.000 vt 0.418 0.558 0.000 vt 0.410 0.544 0.000 vt 0.429 0.548 0.000 vt 0.349 0.731 0.000 vt 0.365 0.701 0.000 vt 0.391 0.606 0.000 vt 0.393 0.593 0.000 vt 0.457 0.570 0.000 vt 0.447 0.556 0.000 vt 0.444 0.574 0.000 vt 0.448 0.580 0.000 vt 0.415 0.551 0.000 vt 0.431 0.554 0.000 vt 0.441 0.566 0.000 vt 0.450 0.458 0.000 vt 0.451 0.325 0.000 vt 0.468 0.330 0.000 vt 0.390 0.364 0.000 vt 0.411 0.432 0.000 vt 0.422 0.417 0.000 vt 0.430 0.357 0.000 vt 0.435 0.351 0.000 vt 0.438 0.356 0.000 vt 0.435 0.360 0.000 vt 0.443 0.364 0.000 vt 0.444 0.364 0.000 vt 0.443 0.371 0.000 vt 0.452 0.371 0.000 vt 0.238 0.385 0.000 vt 0.487 0.445 0.000 vt 0.492 0.444 0.000 vt 0.061 0.378 0.000 vt 0.026 0.384 0.000 vt 0.028 0.321 0.000 vt 0.068 0.316 0.000 vt 0.395 0.572 0.000 vt 0.395 0.578 0.000 vt 0.395 0.584 0.000 vt 0.441 0.571 0.000 vt 0.438 0.333 0.000 vt 0.469 0.343 0.000 vt 0.486 0.338 0.000 vt 0.484 0.324 0.000 vt 0.468 0.488 0.000 vt 0.466 0.448 0.000 vt 0.462 0.455 0.000 vt 0.455 0.448 0.000 vt 0.460 0.446 0.000 vt 0.459 0.466 0.000 vt 0.388 0.623 0.000 vt 0.433 0.366 0.000 vt 0.487 0.356 0.000 vt 0.486 0.348 0.000 vt 0.457 0.363 0.000 vt 0.448 0.364 0.000 vt 0.469 0.362 0.000 vt 0.488 0.361 0.000 vt 0.491 0.433 0.000 vt 0.401 0.557 0.000 vt 0.397 0.551 0.000 vt 0.373 0.570 0.000 vt 0.369 0.571 0.000 vt 0.375 0.566 0.000 vt 0.379 0.567 0.000 vt 0.378 0.569 0.000 vt 0.471 0.234 0.000 vt 0.450 0.245 0.000 vt 0.143 0.816 0.000 vt 0.114 0.748 0.000 vt 0.149 0.737 0.000 vt 0.175 0.804 0.000 vt 0.202 0.856 0.000 vt 0.179 0.866 0.000 vt 0.190 0.729 0.000 vt 0.217 0.797 0.000 vt 0.245 0.848 0.000 vt 0.466 0.215 0.000 vt 0.437 0.233 0.000 vt 0.452 0.588 0.000 vt 0.092 0.854 0.000 vt 0.116 0.835 0.000 vt 0.081 0.761 0.000 vt 0.053 0.512 0.000 vt 0.026 0.519 0.000 vt 0.026 0.452 0.000 vt 0.056 0.446 0.000 vt 0.113 0.498 0.000 vt 0.085 0.504 0.000 vt 0.110 0.556 0.000 vt 0.083 0.564 0.000 vt 0.001 0.634 0.000 vt 0.001 0.579 0.000 vt 0.025 0.577 0.000 vt 0.027 0.633 0.000 vt 0.118 0.614 0.000 vt 0.132 0.671 0.000 vt 0.099 0.679 0.000 vt 0.089 0.622 0.000 vt 0.167 0.667 0.000 vt 0.292 0.836 0.000 vt 0.199 0.303 0.000 vt 0.174 0.364 0.000 vt 0.393 0.544 0.000 vt 0.387 0.529 0.000 vt 0.459 0.380 0.000 vt 0.462 0.372 0.000 vt 0.463 0.366 0.000 vt 0.463 0.363 0.000 vt 0.402 0.945 0.000 vt 0.476 0.902 0.000 vt 0.401 0.489 0.000 vt 0.391 0.563 0.000 vt 0.388 0.559 0.000 vt 0.404 0.563 0.000 vt 0.443 0.569 0.000 vt 0.380 0.571 0.000 vt 0.382 0.569 0.000 vt 0.384 0.569 0.000 vt 0.439 0.568 0.000 vt 0.431 0.568 0.000 vt 0.421 0.567 0.000 vt 0.393 0.567 0.000 vt 0.387 0.567 0.000 vt 0.384 0.564 0.000 vt 0.394 0.568 0.000 vt 0.413 0.568 0.000 vt 0.370 0.565 0.000 vt 0.452 0.389 0.000 vt 0.399 0.452 0.000 vt 0.471 0.566 0.000 vt 0.316 0.686 0.000 vt 0.128 0.222 0.000 vt 0.179 0.214 0.000 vt 0.175 0.258 0.000 vt 0.124 0.265 0.000 vt 0.439 0.119 0.000 vt 0.229 0.304 0.000 vt 0.203 0.363 0.000 vt 0.274 0.227 0.000 vt 0.223 0.371 0.000 vt 0.053 0.571 0.000 vt 0.001 0.388 0.000 vt 0.001 0.456 0.000 vt 0.001 0.524 0.000 vt 0.064 0.877 0.000 vt 0.144 0.945 0.000 vt 0.001 0.323 0.000 vt 0.065 0.689 0.000 vt 0.224 0.240 0.000 vt 0.072 0.265 0.000 vt 0.001 0.267 0.000 vt 0.031 0.264 0.000 vt 0.057 0.628 0.000 vt 0.194 0.622 0.000 vt 0.149 0.611 0.000 vt 0.308 0.489 0.000 vt 0.369 0.558 0.000 vt 0.374 0.560 0.000 vt 0.378 0.562 0.000 vt 0.445 0.413 0.000 vt 0.430 0.429 0.000 vt 0.461 0.440 0.000 vt 0.476 0.607 0.000 vt 0.469 0.591 0.000 vt 0.378 0.549 0.000 vt 0.384 0.554 0.000 vt 0.393 0.509 0.000 vt 0.299 0.520 0.000 vt 0.436 0.403 0.000 vt 0.489 0.615 0.000 vt 0.383 0.568 0.000 vt 0.364 0.139 0.000 vt 0.236 0.192 0.000 vt 0.033 0.219 0.000 vt 0.079 0.220 0.000 vt 0.292 0.168 0.000 vt 0.001 0.218 0.000 vt 0.197 0.523 0.000 vt 0.209 0.508 0.000 vt 0.217 0.527 0.000 vt 0.206 0.535 0.000 vt 0.211 0.571 0.000 vt 0.203 0.562 0.000 vt 0.187 0.591 0.000 vt 0.185 0.578 0.000 vt 0.161 0.583 0.000 vt 0.165 0.574 0.000 vt 0.150 0.569 0.000 vt 0.155 0.560 0.000 vt 0.145 0.539 0.000 vt 0.153 0.535 0.000 vt 0.150 0.501 0.000 vt 0.159 0.502 0.000 vt 0.186 0.438 0.000 vt 0.191 0.452 0.000 vt 0.172 0.472 0.000 vt 0.164 0.464 0.000 vt 0.208 0.427 0.000 vt 0.210 0.441 0.000 vt 0.182 0.567 0.000 vt 0.193 0.550 0.000 vt 0.169 0.561 0.000 vt 0.161 0.553 0.000 vt 0.163 0.534 0.000 vt 0.169 0.505 0.000 vt 0.196 0.465 0.000 vt 0.180 0.479 0.000 vt 0.214 0.460 0.000 vt 0.227 0.456 0.000 vt 0.221 0.433 0.000 vt 0.203 0.489 0.000 vt 0.211 0.486 0.000 vt 0.215 0.495 0.000 vt 0.228 0.537 0.000 vt 0.219 0.583 0.000 vt 0.188 0.602 0.000 vt 0.152 0.587 0.000 vt 0.138 0.546 0.000 vt 0.141 0.500 0.000 vt 0.157 0.450 0.000 vt 0.180 0.412 0.000 vt 0.209 0.404 0.000 vt 0.227 0.417 0.000 vt 0.236 0.447 0.000 vt 0.194 0.496 0.000 vt 0.187 0.487 0.000 vt 0.199 0.477 0.000 vt 0.213 0.478 0.000 vt 0.222 0.489 0.000 vt 0.178 0.538 0.000 vt 0.178 0.510 0.000 vt 0.233 0.492 0.000 vt 0.130 0.496 0.000 vt 0.149 0.425 0.000 vt 0.128 0.552 0.000 vt 0.484 0.930 0.000 vt 0.472 0.934 0.000 vt 0.463 0.938 0.000 vt 0.470 0.952 0.000 vt 0.480 0.955 0.000 vt 0.484 0.970 0.000 vt 0.488 0.942 0.000 vt 0.478 0.944 0.000 vt 0.388 0.569 0.000 vt 0.385 0.572 0.000 vt 0.424 0.968 0.000 vt 0.437 0.961 0.000 vt 0.438 0.969 0.000 vt 0.427 0.973 0.000 vt 0.418 0.961 0.000 vt 0.429 0.956 0.000 vt 0.389 0.961 0.000 vt 0.399 0.955 0.000 vt 0.405 0.960 0.000 vt 0.394 0.967 0.000 vt 0.429 0.569 0.000 vt 0.405 0.566 0.000 vt 0.393 0.978 0.000 vt 0.383 0.975 0.000 vt 0.384 0.967 0.000 vt 0.401 0.986 0.000 vt 0.395 0.991 0.000 vt 0.386 0.982 0.000 vt 0.411 0.989 0.000 vt 0.407 0.996 0.000 vt 0.438 0.570 0.000 vt 0.427 0.994 0.000 vt 0.416 0.996 0.000 vt 0.421 0.987 0.000 vt 0.419 0.953 0.000 vt 0.408 0.953 0.000 vt 0.439 0.988 0.000 vt 0.428 0.981 0.000 vt 0.437 0.978 0.000 vt 0.489 0.956 0.000 vt 0.132 0.132 0.000 vt 0.082 0.133 0.000 vt 0.084 0.092 0.000 vt 0.133 0.090 0.000 vt 0.446 0.066 0.000 vt 0.442 0.095 0.000 vt 0.381 0.103 0.000 vt 0.388 0.070 0.000 vt 0.185 0.169 0.000 vt 0.186 0.126 0.000 vt 0.253 0.102 0.000 vt 0.242 0.148 0.000 vt 0.230 0.072 0.000 vt 0.183 0.087 0.000 vt 0.448 0.038 0.000 vt 0.395 0.039 0.000 vt 0.398 0.021 0.000 vt 0.449 0.020 0.000 vt 0.133 0.055 0.000 vt 0.179 0.050 0.000 vt 0.288 0.053 0.000 vt 0.260 0.052 0.000 vt 0.261 0.023 0.000 vt 0.300 0.022 0.000 vt 0.341 0.043 0.000 vt 0.348 0.022 0.000 vt 0.087 0.055 0.000 vt 0.040 0.091 0.000 vt 0.041 0.055 0.000 vt 0.038 0.133 0.000 vt 0.001 0.131 0.000 vt 0.001 0.089 0.000 vt 0.001 0.053 0.000 vt 0.222 0.038 0.000 vt 0.083 0.177 0.000 vt 0.035 0.178 0.000 vt 0.326 0.083 0.000 vt 0.315 0.124 0.000 vt 0.001 0.175 0.000 vt 0.129 0.175 0.000 vt 0.001 0.002 0.000 vt 0.042 0.002 0.000 vt 0.133 0.002 0.000 vt 0.177 0.002 0.000 vt 0.092 0.002 0.000 vt 0.399 0.002 0.000 vt 0.450 0.002 0.000 vt 0.303 0.002 0.000 vt 0.350 0.002 0.000 vt 0.218 0.002 0.000 vt 0.260 0.002 0.000 vt 0.558 0.967 0.000 vt 0.557 0.976 0.000 vt 0.500 0.997 0.000 vt 0.588 0.975 0.000 vt 0.442 0.967 0.000 vt 0.443 0.976 0.000 vt 0.412 0.975 0.000 # 1339 texture vertices vn 0.001 0.482 -0.876 vn -0.001 0.661 0.751 vn 0.136 0.595 0.792 vn -0.203 0.679 0.706 vn -0.092 0.474 0.876 vn -0.184 0.792 0.581 vn -0.098 0.863 0.495 vn -0.449 0.820 0.356 vn -0.220 0.748 0.626 vn -0.560 0.798 -0.222 vn -0.233 0.531 -0.815 vn 0.001 0.534 -0.845 vn -0.135 0.596 0.791 vn 0.203 0.676 0.708 vn 0.091 0.476 0.875 vn 0.189 0.792 0.581 vn 0.099 0.862 0.496 vn 0.444 0.821 0.360 vn 0.221 0.747 0.627 vn 0.556 0.801 -0.221 vn 0.228 0.532 -0.815 vn -0.002 0.536 -0.844 vn -0.574 0.744 -0.343 vn -0.485 0.523 -0.701 vn -0.121 0.869 -0.480 vn -0.215 0.930 -0.298 vn -0.000 -0.806 -0.591 vn -0.277 -0.779 -0.562 vn -0.258 -0.731 -0.632 vn -0.046 -0.809 -0.586 vn -0.210 0.565 -0.798 vn -0.094 0.624 -0.775 vn 0.015 0.952 -0.307 vn 0.045 0.919 -0.392 vn -0.099 0.857 -0.505 vn -0.379 0.493 -0.783 vn -0.947 0.285 -0.149 vn -0.809 -0.421 -0.411 vn -0.895 -0.443 -0.043 vn -0.999 -0.020 0.035 vn -0.359 0.933 -0.019 vn -0.809 0.586 0.047 vn -0.667 -0.516 -0.538 vn -0.726 -0.626 -0.285 vn -0.001 0.671 -0.741 vn -0.001 0.945 -0.327 vn -0.531 -0.632 -0.565 vn -0.618 -0.566 -0.546 vn 0.800 -0.473 0.369 vn 0.618 -0.771 0.151 vn 0.693 -0.711 0.116 vn 0.818 -0.467 0.335 vn 0.849 -0.259 0.460 vn 0.775 -0.130 0.619 vn 0.667 -0.132 0.733 vn 0.775 -0.270 0.571 vn 0.958 -0.057 -0.280 vn 0.763 0.033 -0.646 vn 0.763 -0.153 -0.628 vn 0.911 -0.129 -0.391 vn 0.990 0.067 0.126 vn 0.979 0.090 0.185 vn 0.981 0.057 0.184 vn 0.996 0.020 0.090 vn 0.770 -0.392 0.504 vn 0.657 -0.721 0.219 vn 0.478 -0.656 0.584 vn 0.599 -0.389 0.700 vn 0.498 -0.846 0.192 vn 0.537 -0.840 0.082 vn 0.740 -0.557 0.378 vn 0.668 -0.570 0.479 vn 0.280 -0.914 0.294 vn 0.421 -0.898 0.126 vn 0.991 0.084 0.103 vn 0.964 0.223 0.143 vn 0.960 0.189 0.207 vn 0.979 0.103 0.175 vn 0.868 0.172 0.465 vn 0.907 0.085 0.413 vn 0.938 0.144 0.316 vn 0.897 0.178 0.405 vn 0.662 -0.174 0.729 vn 0.583 -0.417 0.697 vn 0.627 -0.449 0.637 vn 0.685 -0.405 0.605 vn 0.827 0.091 0.555 vn 0.890 0.018 0.455 vn 0.663 -0.395 0.636 vn 0.606 -0.428 0.671 vn 0.313 -0.735 0.602 vn -0.136 -0.864 0.485 vn 0.951 0.158 0.267 vn 0.964 0.113 0.241 vn 0.731 -0.036 0.681 vn 0.819 -0.134 0.558 vn 0.546 0.270 0.793 vn 0.602 0.237 0.763 vn 0.444 0.233 0.865 vn 0.353 0.173 0.920 vn 0.240 -0.093 0.966 vn 0.498 0.051 0.866 vn 0.675 0.338 0.656 vn 0.480 0.400 0.780 vn 0.064 -0.572 0.818 vn 0.126 -0.313 0.941 vn 0.207 -0.613 0.763 vn 0.221 -0.810 0.544 vn 0.598 -0.694 -0.401 vn 0.124 -0.977 -0.175 vn 0.218 -0.333 0.917 vn 0.377 -0.161 0.912 vn 0.142 -0.210 0.967 vn 0.256 -0.155 0.954 vn 0.111 -0.351 0.930 vn 0.107 -0.480 0.871 vn 0.675 -0.732 -0.096 vn 0.496 -0.844 0.206 vn -0.016 -0.986 0.167 vn 0.304 -0.948 0.097 vn 0.982 -0.082 0.171 vn 0.963 -0.002 0.269 vn 0.967 -0.134 0.216 vn 0.969 -0.177 0.175 vn 0.916 -0.244 0.319 vn 0.853 -0.341 0.394 vn 0.837 -0.365 0.407 vn 0.886 -0.281 0.368 vn 0.422 -0.292 0.858 vn 0.039 -0.571 0.820 vn -0.011 -0.399 0.917 vn 0.333 -0.349 0.876 vn 0.935 -0.237 0.263 vn 0.949 -0.159 0.273 vn 0.697 -0.213 0.685 vn 0.568 -0.123 0.814 vn -0.938 0.322 0.130 vn -0.609 -0.738 -0.291 vn -0.447 -0.857 -0.258 vn 0.259 -0.528 0.809 vn 0.137 -0.704 0.697 vn -0.107 -0.741 0.663 vn 0.647 -0.296 0.703 vn 0.603 -0.168 0.780 vn 0.836 0.072 0.545 vn 0.744 0.114 0.659 vn 0.701 0.149 0.698 vn 0.802 0.157 0.577 vn 0.823 -0.080 0.562 vn 0.690 0.142 0.710 vn 0.628 0.036 0.778 vn 0.894 -0.247 0.373 vn 0.624 -0.153 0.766 vn 0.661 0.110 0.742 vn 0.712 0.424 0.559 vn 0.701 0.284 0.654 vn 0.504 -0.050 0.862 vn 0.413 0.027 0.910 vn 0.569 0.046 0.821 vn 0.488 -0.134 0.862 vn 0.411 -0.180 0.894 vn 0.610 -0.024 0.792 vn 0.747 -0.250 0.616 vn 0.672 -0.313 0.671 vn 0.536 0.762 0.363 vn 0.559 0.768 0.312 vn 0.802 0.272 0.531 vn 0.618 0.206 0.759 vn 0.717 0.383 0.583 vn 0.780 0.464 0.420 vn 0.617 0.401 0.678 vn 0.658 0.397 0.640 vn 0.672 0.440 0.596 vn 0.501 0.314 0.807 vn 0.612 0.527 0.589 vn 0.679 0.320 0.661 vn 0.732 -0.406 -0.547 vn 0.885 -0.261 -0.386 vn 0.842 -0.347 0.414 vn 0.782 -0.349 0.517 vn 0.784 -0.368 0.500 vn 0.858 -0.453 0.244 vn 0.953 -0.279 0.118 vn 0.977 -0.189 0.104 vn 0.989 -0.110 0.102 vn 0.142 0.669 0.730 vn 0.300 0.652 0.696 vn 0.291 0.792 0.536 vn 0.143 0.821 0.553 vn 0.737 0.561 0.378 vn 0.716 0.470 0.515 vn 0.884 0.306 0.353 vn 0.898 0.354 0.263 vn 0.890 0.423 0.171 vn 0.174 0.078 0.982 vn 0.219 0.254 0.942 vn 0.665 -0.104 0.739 vn 0.671 0.390 0.631 vn 0.596 0.435 0.675 vn 0.636 0.467 0.614 vn 0.076 0.244 0.967 vn 0.261 0.437 0.861 vn 0.107 0.440 0.892 vn 0.011 0.082 0.997 vn 0.005 0.082 0.997 vn 0.028 -0.027 0.999 vn 0.073 -0.057 0.996 vn 0.006 0.228 0.974 vn 0.683 0.140 0.717 vn 0.724 0.233 0.650 vn 0.400 0.338 0.852 vn 0.270 0.126 0.955 vn 0.357 0.433 0.828 vn 0.503 0.485 0.716 vn 0.536 0.133 0.834 vn 0.416 -0.306 0.856 vn 0.337 0.097 0.937 vn 0.262 0.372 0.891 vn 0.425 0.075 0.902 vn 0.701 -0.147 0.698 vn -0.056 0.558 0.828 vn 0.005 0.605 0.796 vn 0.483 0.327 0.812 vn 0.497 0.276 0.823 vn 0.505 0.283 0.815 vn 0.340 -0.030 0.940 vn 0.332 0.066 0.941 vn 0.026 0.644 0.765 vn 0.021 0.538 0.843 vn 0.170 -0.012 0.985 vn 0.365 -0.067 0.929 vn 0.826 -0.173 0.537 vn 0.320 0.415 0.852 vn 0.384 0.739 0.554 vn 0.987 -0.013 0.160 vn 0.495 0.720 0.487 vn 0.490 0.830 0.268 vn 0.279 0.906 0.317 vn 0.431 0.899 -0.074 vn 0.267 0.957 -0.112 vn 0.283 0.953 0.107 vn 0.471 0.877 0.092 vn 0.132 0.985 0.113 vn 0.135 0.931 0.339 vn 0.190 -0.184 0.964 vn 0.292 -0.372 0.881 vn 0.307 -0.447 0.840 vn 0.393 -0.580 0.713 vn 0.524 -0.286 0.802 vn 0.380 -0.582 0.719 vn 0.697 0.212 0.685 vn 0.603 0.070 0.795 vn 0.558 -0.571 0.602 vn -0.089 -0.701 0.707 vn 0.794 -0.345 0.500 vn 0.345 -0.517 0.783 vn 0.481 0.101 0.871 vn 0.134 0.283 0.950 vn 0.113 -0.558 0.822 vn -0.073 -0.993 0.089 vn -0.041 -0.994 0.103 vn 0.084 -0.038 0.996 vn -0.012 -0.622 0.783 vn -0.002 0.254 0.967 vn 0.004 -0.997 0.079 vn 0.001 -0.832 -0.555 vn 0.477 -0.363 0.801 vn 0.414 0.160 0.896 vn 0.395 0.485 0.780 vn 0.611 0.484 0.627 vn 0.406 0.510 0.758 vn 0.375 0.498 0.782 vn 0.555 0.314 0.770 vn 0.349 0.411 0.842 vn 0.012 0.247 0.969 vn 0.002 -0.369 0.930 vn -0.003 0.509 0.861 vn 0.876 -0.041 0.481 vn 0.757 -0.214 0.618 vn 0.737 -0.048 0.674 vn 0.840 -0.012 0.542 vn 0.960 0.137 0.243 vn 0.969 0.103 0.226 vn 0.909 0.015 0.417 vn 0.906 0.015 0.423 vn 0.676 -0.276 0.683 vn 0.688 -0.223 0.691 vn 0.691 0.035 0.722 vn 0.719 -0.082 0.691 vn 0.964 0.062 0.260 vn 0.956 0.070 0.286 vn 0.953 0.037 0.300 vn -0.003 -0.415 0.910 vn -0.001 -0.380 0.925 vn 0.658 -0.419 0.625 vn 0.735 -0.421 0.532 vn 0.663 -0.303 0.685 vn 0.550 -0.321 0.771 vn 0.423 -0.236 0.875 vn 0.326 -0.294 0.899 vn 0.124 -0.396 0.910 vn 0.218 -0.177 0.960 vn 0.530 0.781 0.331 vn 0.167 0.827 0.537 vn 0.094 0.948 0.303 vn 0.313 0.934 0.171 vn -0.406 -0.892 0.201 vn -0.743 0.107 0.661 vn 0.455 0.704 0.546 vn 0.288 0.957 0.025 vn 0.245 0.958 0.150 vn 0.532 -0.027 0.846 vn 0.566 0.213 0.796 vn 0.508 0.208 0.836 vn 0.173 0.028 0.984 vn 0.371 0.122 0.921 vn 0.429 -0.045 0.902 vn 0.614 0.165 0.772 vn 0.737 0.157 0.657 vn 0.726 0.057 0.685 vn 0.662 0.061 0.747 vn 0.845 -0.523 -0.112 vn 0.845 -0.501 -0.185 vn 0.744 -0.668 0.009 vn 0.773 -0.630 0.079 vn 0.889 0.108 0.445 vn 0.899 0.077 0.430 vn 0.184 0.204 -0.961 vn 0.005 0.202 -0.979 vn -0.000 0.485 -0.875 vn 0.159 0.484 -0.861 vn 0.499 0.592 0.633 vn 0.305 0.950 0.065 vn -0.274 -0.953 -0.127 vn 0.245 -0.456 0.856 vn 0.083 -0.881 0.465 vn 0.435 -0.739 0.515 vn 0.504 -0.429 0.750 vn 0.818 -0.367 0.443 vn 0.933 -0.162 0.322 vn 0.872 0.029 0.489 vn 0.002 0.994 0.113 vn 0.133 0.983 -0.126 vn -0.001 0.992 -0.127 vn 0.280 0.892 -0.356 vn 0.126 0.916 -0.381 vn 0.210 0.974 -0.083 vn -0.082 0.663 0.745 vn -0.059 0.391 0.919 vn 0.111 0.992 -0.055 vn 0.081 -0.190 0.978 vn 0.035 0.076 0.996 vn 0.852 0.236 0.467 vn 0.775 0.219 0.593 vn 0.505 -0.109 0.856 vn 0.446 -0.314 0.838 vn 0.511 0.200 0.836 vn 0.623 -0.242 0.744 vn 0.436 -0.554 0.709 vn 0.599 -0.742 0.300 vn -0.036 0.177 0.984 vn -0.039 -0.159 0.987 vn 0.308 0.942 -0.135 vn 0.989 0.093 -0.111 vn 0.477 -0.259 0.840 vn 0.473 -0.423 0.773 vn 0.774 -0.329 0.541 vn 0.285 0.019 0.958 vn 0.350 0.101 0.931 vn 0.579 0.261 0.773 vn 0.298 0.015 0.954 vn 0.165 0.336 0.927 vn 0.577 0.511 0.636 vn 0.254 -0.834 0.490 vn -0.114 -0.925 0.363 vn 0.941 -0.280 -0.188 vn 0.460 -0.738 0.493 vn 0.740 -0.635 0.221 vn 0.003 0.529 0.849 vn 0.206 -0.427 -0.881 vn 0.497 -0.316 -0.808 vn 0.457 -0.144 -0.878 vn 0.179 -0.244 -0.953 vn -0.182 -0.980 -0.078 vn 0.342 -0.427 0.837 vn 0.424 -0.296 0.856 vn 0.896 -0.357 -0.264 vn 0.594 -0.104 0.798 vn 0.012 0.528 0.849 vn 0.042 0.469 0.882 vn 0.624 0.102 0.775 vn 0.324 -0.123 0.938 vn 0.202 -0.638 0.743 vn 0.714 0.512 0.477 vn 0.433 -0.511 0.742 vn -0.350 -0.708 0.613 vn 0.095 -0.410 0.907 vn 0.622 -0.593 0.512 vn 0.846 0.304 0.437 vn 0.582 -0.043 0.812 vn -0.226 -0.380 0.897 vn 0.215 0.644 0.734 vn 0.123 0.952 0.280 vn -0.004 0.956 0.293 vn -0.005 0.635 0.772 vn 0.325 -0.730 0.601 vn -0.017 -0.840 0.543 vn 0.017 -0.788 0.616 vn 0.294 -0.138 0.946 vn 0.214 0.401 0.891 vn -0.150 0.490 0.859 vn 0.573 -0.125 0.810 vn -0.134 0.957 0.258 vn 0.252 0.828 0.501 vn -0.673 0.643 0.364 vn 0.004 -0.960 0.279 vn 0.032 -0.991 0.133 vn 0.006 -0.908 0.419 vn 0.180 -0.980 0.086 vn 0.740 0.403 -0.538 vn 0.627 0.652 -0.426 vn 0.814 0.561 -0.149 vn 0.925 0.321 -0.206 vn 0.492 0.825 -0.280 vn 0.649 0.757 -0.076 vn 0.966 0.258 0.022 vn 0.864 0.501 0.053 vn 0.680 0.729 0.077 vn 0.272 -0.962 -0.032 vn 0.225 -0.968 0.111 vn 0.288 -0.510 0.810 vn 0.126 0.748 -0.651 vn 0.340 0.725 -0.598 vn 0.421 0.466 -0.778 vn 0.205 -0.458 -0.865 vn 0.489 -0.479 -0.729 vn 0.500 -0.523 -0.690 vn 0.210 -0.566 -0.798 vn 0.895 -0.322 -0.309 vn 0.759 -0.434 -0.485 vn 0.797 -0.287 -0.532 vn 0.937 -0.248 -0.245 vn -0.001 -0.238 -0.971 vn -0.000 -0.025 -1.000 vn 0.194 -0.025 -0.981 vn 0.201 -0.248 -0.948 vn 0.969 0.094 -0.229 vn 0.968 -0.101 -0.228 vn 0.814 -0.088 -0.575 vn 0.800 0.142 -0.583 vn 0.998 0.061 -0.010 vn 0.726 0.657 0.205 vn 0.000 -0.985 0.174 vn 0.985 -0.166 0.038 vn 0.955 -0.220 -0.200 vn 0.472 0.076 0.879 vn 0.343 -0.235 0.909 vn 0.464 -0.641 0.612 vn 0.578 -0.186 0.795 vn -0.189 -0.982 0.010 vn 0.004 0.938 0.345 vn 0.002 0.829 0.559 vn 0.445 0.232 0.865 vn 0.463 0.340 0.818 vn -0.116 0.983 0.143 vn 0.004 0.995 0.102 vn 0.978 0.204 0.044 vn -0.967 -0.216 -0.137 vn -0.911 -0.347 0.224 vn -0.728 0.350 0.590 vn 0.426 0.738 -0.523 vn 0.618 0.786 0.011 vn 0.151 0.857 -0.493 vn -0.333 0.912 -0.241 vn -0.277 0.956 0.095 vn -0.569 0.822 -0.032 vn -0.341 -0.671 -0.658 vn 0.161 -0.736 -0.657 vn 0.528 0.432 0.731 vn 0.586 0.105 0.803 vn 0.436 0.074 0.897 vn 0.621 0.267 0.737 vn 0.936 0.153 0.316 vn 0.999 -0.010 0.042 vn 0.826 0.281 -0.489 vn 0.775 0.178 -0.606 vn 0.995 -0.039 -0.095 vn 0.005 -0.414 0.910 vn 0.580 -0.243 0.778 vn 0.938 -0.339 -0.068 vn 0.925 -0.371 0.080 vn 0.888 -0.269 0.373 vn 0.923 -0.371 -0.106 vn 0.494 -0.274 -0.825 vn -0.001 -0.456 -0.890 vn -0.002 -0.569 -0.822 vn -0.001 -0.452 -0.892 vn -0.003 0.749 -0.663 vn -0.000 0.920 -0.391 vn -0.001 -0.280 -0.960 vn 0.470 0.194 -0.861 vn 0.965 -0.123 0.234 vn 0.400 -0.039 -0.916 vn 0.142 -0.166 -0.976 vn -0.000 -0.194 -0.981 vn 0.497 -0.049 -0.867 vn 0.998 0.042 0.045 vn 0.996 -0.037 -0.082 vn 0.009 0.433 0.901 vn 0.004 0.669 0.743 vn 0.955 0.004 0.296 vn 0.737 -0.001 0.675 vn 0.707 0.177 0.684 vn 0.484 0.627 0.610 vn 0.515 0.250 0.820 vn 0.360 0.121 0.925 vn -0.544 -0.573 0.613 vn 0.382 -0.114 0.917 vn 0.489 -0.108 0.866 vn -0.002 -0.670 0.742 vn 0.002 -0.394 0.919 vn -0.004 -0.168 0.986 vn 0.007 -0.109 0.994 vn 0.009 -0.519 0.855 vn 0.660 -0.118 0.742 vn 0.621 -0.127 0.774 vn 0.416 0.220 0.882 vn 0.946 0.046 0.322 vn 0.014 0.006 1.000 vn 0.569 0.184 0.802 vn 0.218 0.013 0.976 vn 0.044 0.087 0.995 vn -0.419 0.862 0.284 vn 0.647 -0.120 0.753 vn 0.954 -0.017 0.301 vn 0.352 0.140 -0.926 vn 0.095 -0.050 -0.994 vn 0.770 0.025 0.638 vn 0.000 -0.078 -0.997 vn 0.985 -0.172 0.009 vn 0.920 -0.340 0.195 vn 0.929 -0.331 -0.163 vn 0.969 -0.237 0.074 vn 0.969 -0.183 0.165 vn 0.801 0.160 0.577 vn 0.954 -0.021 0.301 vn 0.293 0.803 0.520 vn 0.977 0.170 0.129 vn 0.134 0.985 -0.104 vn 0.994 0.106 -0.036 vn 0.099 0.675 -0.731 vn 0.997 -0.079 -0.000 vn 0.197 0.126 -0.972 vn 0.978 -0.175 -0.110 vn 0.110 -0.321 -0.941 vn 0.939 -0.332 -0.089 vn 0.400 -0.789 -0.467 vn 0.171 -0.673 -0.720 vn 0.931 -0.336 -0.144 vn 0.854 -0.500 0.146 vn 0.161 -0.985 -0.069 vn 0.931 -0.304 -0.200 vn 0.813 -0.565 -0.143 vn 0.823 -0.546 0.154 vn 0.795 -0.387 0.467 vn 0.809 -0.168 0.563 vn 0.826 0.053 0.562 vn 0.925 0.261 0.275 vn 0.990 0.071 0.119 vn 0.951 0.129 0.281 vn 0.810 -0.147 0.568 vn 0.383 -0.603 0.699 vn 0.769 0.635 0.079 vn 0.786 0.352 0.508 vn 0.919 0.082 -0.386 vn 0.937 0.163 0.310 vn 0.974 -0.026 0.224 vn 0.787 0.550 0.279 vn 0.517 0.758 -0.397 vn 0.337 0.112 -0.935 vn 0.221 -0.300 -0.928 vn 0.395 -0.578 -0.714 vn 0.521 -0.711 -0.472 vn 0.432 -0.901 -0.043 vn 0.826 -0.520 0.218 vn 0.885 -0.217 0.412 vn 0.786 -0.107 0.609 vn 0.864 0.400 0.304 vn 0.954 0.061 0.293 vn 0.949 0.313 0.046 vn 0.991 0.028 -0.131 vn 0.945 -0.116 0.305 vn 0.970 -0.241 0.032 vn 0.946 -0.038 0.322 vn 0.886 -0.270 -0.376 vn 0.855 -0.272 -0.441 vn 0.952 -0.122 -0.281 vn 0.002 -0.883 0.469 vn -0.001 0.792 -0.611 vn -0.180 0.823 -0.539 vn -0.642 0.677 -0.360 vn -0.957 0.288 -0.031 vn -0.912 -0.300 0.281 vn -0.454 -0.866 0.207 vn -0.855 -0.043 0.517 vn -0.834 0.460 0.305 vn -0.242 0.911 0.334 vn -0.720 -0.667 -0.192 vn -0.762 -0.580 -0.288 vn 0.452 0.774 0.444 vn 0.857 0.048 0.513 vn 0.966 0.131 0.225 vn 0.211 0.953 0.219 vn -0.108 0.726 0.679 vn 0.021 0.946 0.324 vn 0.566 -0.691 -0.450 vn -0.068 0.939 -0.338 vn -0.261 -0.298 0.918 vn -0.200 -0.891 0.407 vn 0.124 -0.991 0.059 vn 0.913 -0.350 -0.211 vn 0.488 -0.838 0.244 vn 0.738 -0.593 0.322 vn 0.994 -0.060 -0.087 vn -0.000 -0.981 0.193 vn 0.000 0.974 0.227 vn -0.350 -0.016 0.936 vn 0.000 -0.017 1.000 vn 0.252 0.455 -0.854 vn 0.774 0.620 -0.127 vn 0.634 0.759 -0.148 vn 0.192 0.569 -0.800 vn 0.405 -0.094 0.909 vn 0.031 0.149 0.988 vn 0.360 0.283 0.889 vn 0.469 0.080 0.880 vn 0.769 0.452 0.452 vn 0.946 0.185 0.266 vn 0.893 0.181 0.413 vn 0.654 0.429 0.623 vn 0.506 0.610 0.610 vn 0.436 0.659 0.613 vn 0.160 0.558 0.814 vn -0.285 0.396 0.873 vn -0.223 0.539 0.812 vn 0.037 0.570 0.821 vn 0.623 0.727 -0.289 vn 0.456 0.738 0.497 vn 0.382 0.656 0.651 vn 0.278 0.687 0.671 vn 0.213 0.798 0.563 vn 0.171 0.844 0.508 vn 0.300 0.690 0.659 vn 0.144 0.793 0.591 vn 0.204 0.541 -0.816 vn -0.001 0.494 -0.870 vn 0.029 0.458 -0.888 vn 0.060 0.366 -0.929 vn 0.000 0.421 -0.907 vn 0.000 0.386 -0.922 vn 0.001 0.455 -0.891 vn 0.264 0.718 0.644 vn 0.307 0.317 -0.897 vn 0.056 0.164 -0.985 vn 0.717 0.079 0.693 vn 0.638 0.188 0.746 vn 0.000 0.202 -0.979 vn 0.006 -0.044 0.999 vn 0.001 0.405 0.914 vn 0.805 0.560 -0.194 vn 0.002 0.627 0.779 vn 0.010 -0.298 0.954 vn 0.124 0.870 -0.477 vn 0.488 0.530 -0.693 vn 0.566 0.756 -0.329 vn 0.213 0.932 -0.294 vn 0.245 -0.741 -0.626 vn 0.275 -0.782 -0.559 vn 0.044 -0.811 -0.584 vn -0.012 0.949 -0.315 vn 0.097 0.621 -0.778 vn 0.215 0.561 -0.799 vn -0.030 0.913 -0.407 vn 0.378 0.505 -0.776 vn 0.084 0.865 -0.495 vn 0.892 -0.451 -0.026 vn 0.803 -0.447 -0.394 vn 0.954 0.274 -0.123 vn 0.998 -0.024 0.066 vn 0.806 0.588 0.057 vn 0.351 0.936 -0.012 vn 0.662 -0.536 -0.524 vn 0.725 -0.630 -0.278 vn 0.524 -0.662 -0.536 vn 0.620 -0.585 -0.522 vn -0.694 -0.711 0.115 vn -0.621 -0.770 0.148 vn -0.805 -0.470 0.362 vn -0.819 -0.465 0.335 vn -0.680 -0.145 0.719 vn -0.763 -0.140 0.631 vn -0.840 -0.272 0.470 vn -0.773 -0.256 0.580 vn -0.763 -0.155 -0.627 vn -0.763 0.034 -0.645 vn -0.958 -0.057 -0.281 vn -0.910 -0.129 -0.393 vn -0.983 0.060 0.175 vn -0.980 0.096 0.177 vn -0.990 0.069 0.123 vn -0.996 0.023 0.083 vn -0.484 -0.649 0.587 vn -0.662 -0.717 0.220 vn -0.775 -0.388 0.499 vn -0.606 -0.384 0.697 vn -0.748 -0.556 0.363 vn -0.539 -0.840 0.071 vn -0.496 -0.849 0.183 vn -0.668 -0.580 0.467 vn -0.280 -0.913 0.296 vn -0.424 -0.897 0.125 vn -0.960 0.187 0.209 vn -0.965 0.222 0.143 vn -0.991 0.084 0.104 vn -0.979 0.104 0.175 vn -0.940 0.170 0.295 vn -0.909 0.107 0.404 vn -0.862 0.204 0.464 vn -0.896 0.204 0.395 vn -0.570 -0.493 0.658 vn -0.531 -0.465 0.709 vn -0.651 -0.181 0.737 vn -0.688 -0.376 0.620 vn -0.892 0.030 0.452 vn -0.827 0.122 0.549 vn -0.345 -0.706 0.619 vn -0.566 -0.461 0.684 vn -0.543 -0.393 0.742 vn -0.097 -0.841 0.533 vn -0.964 0.119 0.237 vn -0.950 0.158 0.268 vn -0.733 -0.024 0.679 vn -0.825 -0.117 0.552 vn -0.442 0.232 0.866 vn -0.605 0.237 0.760 vn -0.556 0.267 0.787 vn -0.350 0.172 0.921 vn -0.239 -0.096 0.966 vn -0.501 0.068 0.863 vn -0.679 0.342 0.650 vn -0.486 0.403 0.776 vn -0.211 -0.600 0.772 vn -0.123 -0.334 0.934 vn -0.052 -0.530 0.847 vn -0.176 -0.798 0.577 vn -0.131 -0.968 -0.212 vn -0.598 -0.684 -0.418 vn -0.205 -0.329 0.922 vn -0.374 -0.151 0.915 vn -0.117 -0.376 0.919 vn -0.246 -0.160 0.956 vn -0.126 -0.268 0.955 vn -0.137 -0.531 0.837 vn 0.062 -0.980 0.190 vn -0.478 -0.855 0.203 vn -0.669 -0.734 -0.114 vn -0.286 -0.955 0.083 vn -0.967 -0.136 0.215 vn -0.965 -0.005 0.263 vn -0.983 -0.085 0.164 vn -0.969 -0.182 0.170 vn -0.840 -0.358 0.408 vn -0.857 -0.341 0.386 vn -0.910 -0.256 0.326 vn -0.884 -0.284 0.371 vn 0.022 -0.449 0.893 vn -0.046 -0.611 0.791 vn -0.478 -0.294 0.827 vn -0.375 -0.338 0.863 vn -0.935 -0.243 0.259 vn -0.949 -0.164 0.269 vn -0.736 -0.207 0.645 vn -0.587 -0.108 0.802 vn 0.945 0.284 0.163 vn 0.592 -0.756 -0.279 vn 0.442 -0.866 -0.236 vn -0.053 -0.740 0.670 vn -0.228 -0.529 0.817 vn 0.170 -0.772 0.613 vn -0.609 -0.162 0.777 vn -0.663 -0.292 0.690 vn -0.713 0.145 0.686 vn -0.759 0.059 0.648 vn -0.825 0.047 0.564 vn -0.809 0.158 0.566 vn -0.637 0.025 0.770 vn -0.687 0.129 0.715 vn -0.821 -0.086 0.564 vn -0.891 -0.252 0.378 vn -0.721 0.489 0.490 vn -0.698 0.164 0.697 vn -0.646 -0.143 0.750 vn -0.712 0.352 0.608 vn -0.567 0.074 0.821 vn -0.464 0.032 0.885 vn -0.518 -0.023 0.855 vn -0.550 -0.128 0.825 vn -0.756 -0.260 0.601 vn -0.645 -0.025 0.764 vn -0.437 -0.158 0.885 vn -0.687 -0.310 0.657 vn -0.541 0.781 0.313 vn -0.565 0.780 0.270 vn -0.712 0.385 0.587 vn -0.611 0.201 0.765 vn -0.859 0.335 0.388 vn -0.775 0.474 0.417 vn -0.673 0.387 0.630 vn -0.628 0.400 0.668 vn -0.676 0.438 0.592 vn -0.698 0.309 0.646 vn -0.622 0.535 0.573 vn -0.511 0.327 0.795 vn -0.733 -0.405 -0.547 vn -0.884 -0.261 -0.388 vn -0.791 -0.366 0.490 vn -0.793 -0.344 0.502 vn -0.844 -0.347 0.408 vn -0.858 -0.453 0.243 vn -0.953 -0.280 0.116 vn -0.976 -0.193 0.100 vn -0.989 -0.113 0.096 vn -0.289 0.792 0.537 vn -0.301 0.654 0.693 vn -0.134 0.672 0.728 vn -0.137 0.821 0.554 vn -0.884 0.305 0.354 vn -0.716 0.471 0.515 vn -0.736 0.562 0.377 vn -0.897 0.355 0.265 vn -0.890 0.422 0.171 vn -0.179 0.082 0.981 vn -0.216 0.250 0.944 vn -0.661 -0.125 0.740 vn -0.679 0.371 0.633 vn -0.636 0.460 0.620 vn -0.594 0.426 0.682 vn -0.258 0.436 0.862 vn -0.070 0.240 0.968 vn -0.095 0.440 0.893 vn -0.011 0.089 0.996 vn -0.069 -0.049 0.996 vn -0.719 0.247 0.649 vn -0.673 0.172 0.719 vn -0.353 0.447 0.822 vn -0.270 0.134 0.954 vn -0.440 0.328 0.836 vn -0.511 0.490 0.706 vn -0.342 0.114 0.933 vn -0.435 -0.298 0.849 vn -0.552 0.158 0.818 vn -0.273 0.369 0.888 vn -0.705 -0.192 0.683 vn -0.357 0.088 0.930 vn -0.499 0.346 0.795 vn 0.009 0.585 0.811 vn 0.086 0.584 0.807 vn -0.348 -0.035 0.937 vn -0.516 0.299 0.803 vn -0.512 0.295 0.806 vn -0.339 0.070 0.938 vn -0.348 -0.070 0.935 vn -0.148 -0.003 0.989 vn -0.349 0.750 0.561 vn -0.322 0.418 0.849 vn -0.890 -0.163 0.425 vn -0.990 -0.001 0.144 vn -0.500 0.824 0.267 vn -0.501 0.717 0.484 vn -0.285 0.905 0.315 vn -0.282 0.954 0.103 vn -0.268 0.957 -0.114 vn -0.433 0.898 -0.078 vn -0.473 0.876 0.093 vn -0.131 0.985 0.111 vn -0.127 0.932 0.339 vn -0.211 -0.186 0.960 vn -0.293 -0.359 0.886 vn -0.344 -0.465 0.816 vn -0.382 -0.591 0.710 vn -0.525 -0.255 0.812 vn -0.598 0.089 0.796 vn -0.688 0.244 0.683 vn -0.344 -0.576 0.742 vn -0.544 -0.583 0.603 vn 0.098 -0.695 0.712 vn -0.805 -0.326 0.496 vn -0.132 0.306 0.943 vn -0.485 0.160 0.860 vn -0.351 -0.498 0.793 vn -0.141 -0.499 0.855 vn 0.065 -0.990 0.123 vn 0.037 -0.989 0.143 vn -0.065 -0.055 0.996 vn -0.473 -0.369 0.800 vn -0.396 0.179 0.900 vn -0.600 0.505 0.620 vn -0.387 0.499 0.776 vn -0.398 0.505 0.766 vn -0.358 0.488 0.796 vn -0.570 0.304 0.763 vn -0.317 0.412 0.854 vn -0.742 -0.129 0.658 vn -0.771 -0.207 0.602 vn -0.881 -0.036 0.472 vn -0.841 -0.052 0.538 vn -0.972 0.111 0.208 vn -0.961 0.151 0.230 vn -0.916 -0.004 0.402 vn -0.913 0.013 0.408 vn -0.689 0.026 0.724 vn -0.641 -0.316 0.699 vn -0.647 -0.304 0.699 vn -0.697 -0.094 0.711 vn -0.966 0.063 0.249 vn -0.963 0.075 0.259 vn -0.958 0.031 0.287 vn -0.681 -0.315 0.661 vn -0.745 -0.412 0.525 vn -0.666 -0.413 0.621 vn -0.548 -0.335 0.767 vn -0.107 -0.395 0.913 vn -0.299 -0.320 0.899 vn -0.418 -0.236 0.877 vn -0.210 -0.169 0.963 vn -0.090 0.952 0.291 vn -0.166 0.838 0.520 vn -0.523 0.797 0.302 vn -0.302 0.941 0.154 vn 0.408 -0.888 0.211 vn 0.735 0.117 0.668 vn -0.279 0.960 0.001 vn -0.468 0.706 0.531 vn -0.232 0.964 0.131 vn -0.555 -0.033 0.831 vn -0.517 0.199 0.833 vn -0.549 0.222 0.806 vn -0.376 0.125 0.918 vn -0.210 0.031 0.977 vn -0.435 -0.045 0.899 vn -0.739 0.154 0.656 vn -0.610 0.153 0.777 vn -0.663 0.041 0.748 vn -0.733 0.013 0.681 vn -0.744 -0.668 0.007 vn -0.845 -0.501 -0.187 vn -0.845 -0.522 -0.114 vn -0.774 -0.629 0.079 vn -0.897 0.040 0.440 vn -0.896 0.094 0.434 vn -0.179 0.204 -0.962 vn -0.157 0.488 -0.858 vn -0.506 0.590 0.630 vn -0.305 0.951 0.047 vn 0.267 -0.958 -0.102 vn -0.432 -0.745 0.509 vn -0.075 -0.883 0.463 vn -0.236 -0.454 0.859 vn -0.504 -0.423 0.753 vn -0.821 -0.351 0.449 vn -0.876 0.033 0.481 vn -0.934 -0.155 0.322 vn -0.134 0.983 -0.126 vn -0.128 0.916 -0.381 vn -0.284 0.891 -0.353 vn 0.055 0.396 0.917 vn 0.092 0.644 0.760 vn -0.199 0.976 -0.093 vn -0.109 0.991 -0.072 vn -0.039 0.079 0.996 vn -0.081 -0.191 0.978 vn -0.854 0.239 0.462 vn -0.774 0.223 0.593 vn -0.502 -0.119 0.856 vn -0.403 -0.420 0.813 vn -0.680 -0.255 0.687 vn -0.525 0.172 0.834 vn -0.376 -0.531 0.759 vn -0.576 -0.754 0.316 vn 0.040 0.159 0.986 vn 0.036 -0.180 0.983 vn -0.308 0.943 -0.129 vn -0.983 0.074 -0.170 vn -0.456 -0.445 0.771 vn -0.476 -0.297 0.828 vn -0.788 -0.316 0.528 vn -0.393 0.095 0.915 vn -0.308 0.018 0.951 vn -0.125 0.331 0.935 vn -0.283 0.033 0.959 vn -0.598 0.322 0.734 vn -0.575 0.559 0.598 vn -0.216 -0.852 0.476 vn 0.156 -0.927 0.342 vn -0.941 -0.282 -0.189 vn -0.739 -0.637 0.221 vn -0.469 -0.731 0.495 vn -0.458 -0.139 -0.878 vn -0.498 -0.315 -0.808 vn -0.210 -0.426 -0.880 vn -0.182 -0.243 -0.953 vn -0.334 -0.402 0.853 vn 0.221 -0.960 -0.173 vn -0.414 -0.366 0.834 vn -0.902 -0.373 -0.218 vn -0.632 -0.114 0.767 vn -0.642 0.122 0.757 vn -0.194 -0.651 0.734 vn -0.351 -0.095 0.931 vn -0.707 0.530 0.467 vn -0.087 -0.550 0.831 vn 0.352 -0.710 0.610 vn -0.500 -0.482 0.720 vn -0.653 -0.626 0.427 vn -0.856 0.328 0.399 vn -0.578 -0.029 0.816 vn 0.275 -0.432 0.859 vn -0.123 0.953 0.277 vn -0.228 0.657 0.719 vn -0.298 -0.735 0.609 vn -0.300 -0.179 0.937 vn -0.219 0.400 0.890 vn -0.587 -0.175 0.791 vn 0.175 0.460 0.870 vn -0.179 0.856 0.485 vn 0.114 0.959 0.259 vn 0.664 0.620 0.418 vn -0.026 -0.991 0.129 vn -0.184 -0.979 0.082 vn -0.810 0.566 -0.151 vn -0.628 0.654 -0.422 vn -0.741 0.405 -0.536 vn -0.924 0.322 -0.207 vn -0.493 0.823 -0.280 vn -0.648 0.758 -0.080 vn -0.966 0.258 0.022 vn -0.864 0.501 0.051 vn -0.679 0.730 0.075 vn -0.221 -0.970 0.105 vn -0.271 -0.962 -0.038 vn -0.376 -0.516 0.769 vn -0.124 0.748 -0.652 vn -0.339 0.727 -0.598 vn -0.420 0.469 -0.777 vn -0.500 -0.524 -0.690 vn -0.489 -0.481 -0.728 vn -0.206 -0.458 -0.865 vn -0.212 -0.565 -0.797 vn -0.893 -0.325 -0.312 vn -0.759 -0.435 -0.485 vn -0.796 -0.289 -0.532 vn -0.937 -0.249 -0.246 vn -0.193 -0.029 -0.981 vn -0.202 -0.249 -0.947 vn -0.814 -0.090 -0.574 vn -0.969 -0.102 -0.227 vn -0.969 0.093 -0.229 vn -0.801 0.142 -0.581 vn -0.998 0.061 -0.010 vn -0.718 0.664 0.209 vn -0.985 -0.168 0.036 vn -0.954 -0.222 -0.201 vn -0.451 0.039 0.891 vn -0.341 -0.253 0.905 vn -0.604 -0.144 0.784 vn -0.472 -0.641 0.606 vn 0.107 -0.991 0.080 vn -0.463 0.274 0.843 vn -0.002 0.997 0.081 vn 0.083 0.977 0.195 vn -0.466 0.366 0.805 vn -0.977 0.200 0.072 vn 0.916 -0.331 0.226 vn 0.929 -0.364 -0.067 vn 0.728 0.359 0.584 vn -0.419 0.737 -0.531 vn -0.638 0.769 0.043 vn -0.146 0.857 -0.494 vn 0.280 0.954 0.105 vn 0.343 0.909 -0.237 vn 0.546 0.838 -0.008 vn 0.342 -0.678 -0.651 vn -0.159 -0.734 -0.660 vn -0.545 0.363 0.756 vn -0.599 0.165 0.783 vn -0.447 0.066 0.892 vn -0.645 0.255 0.721 vn -0.936 0.164 0.311 vn -0.776 0.182 -0.604 vn -0.827 0.285 -0.485 vn -0.999 -0.012 0.041 vn -0.995 -0.037 -0.093 vn -0.586 -0.252 0.770 vn -0.926 -0.370 0.079 vn -0.938 -0.339 -0.067 vn -0.889 -0.266 0.372 vn -0.922 -0.372 -0.106 vn -0.493 -0.275 -0.825 vn -0.473 0.194 -0.860 vn -0.965 -0.122 0.231 vn -0.401 -0.036 -0.915 vn -0.143 -0.164 -0.976 vn -0.496 -0.052 -0.867 vn -0.996 -0.037 -0.083 vn -0.998 0.042 0.045 vn -0.950 0.012 0.313 vn -0.733 -0.008 0.681 vn -0.670 0.247 0.700 vn -0.408 0.697 0.589 vn -0.330 0.155 0.931 vn -0.517 0.244 0.821 vn 0.568 -0.625 0.535 vn -0.512 -0.108 0.852 vn -0.414 -0.112 0.903 vn -0.654 -0.140 0.743 vn -0.608 -0.086 0.789 vn -0.422 0.215 0.881 vn -0.943 0.031 0.332 vn -0.549 0.190 0.814 vn -0.193 0.018 0.981 vn 0.358 0.872 0.335 vn -0.651 -0.118 0.750 vn -0.954 -0.010 0.300 vn -0.352 0.145 -0.925 vn -0.095 -0.049 -0.994 vn -0.769 0.031 0.639 vn -0.929 -0.329 -0.171 vn -0.923 -0.336 0.190 vn -0.985 -0.174 0.005 vn -0.970 -0.234 0.068 vn -0.801 0.162 0.576 vn -0.969 -0.184 0.166 vn -0.293 0.803 0.519 vn -0.954 -0.019 0.300 vn -0.133 0.986 -0.105 vn -0.976 0.175 0.130 vn -0.098 0.675 -0.732 vn -0.993 0.112 -0.041 vn -0.197 0.127 -0.972 vn -0.997 -0.077 -0.003 vn -0.112 -0.322 -0.940 vn -0.978 -0.176 -0.109 vn -0.171 -0.674 -0.719 vn -0.397 -0.789 -0.468 vn -0.937 -0.337 -0.091 vn -0.929 -0.341 -0.146 vn -0.158 -0.985 -0.070 vn -0.854 -0.500 0.145 vn -0.814 -0.564 -0.141 vn -0.931 -0.306 -0.199 vn -0.824 -0.545 0.156 vn -0.797 -0.383 0.466 vn -0.811 -0.165 0.562 vn -0.824 0.053 0.564 vn -0.926 0.257 0.275 vn -0.991 0.062 0.118 vn -0.952 0.122 0.281 vn -0.383 -0.604 0.699 vn -0.810 -0.150 0.567 vn -0.784 0.355 0.509 vn -0.761 0.645 0.076 vn -0.920 0.079 -0.385 vn -0.975 -0.023 0.222 vn -0.937 0.166 0.308 vn -0.787 0.551 0.279 vn -0.517 0.758 -0.396 vn -0.337 0.112 -0.935 vn -0.221 -0.301 -0.928 vn -0.395 -0.579 -0.714 vn -0.520 -0.711 -0.473 vn -0.426 -0.904 -0.044 vn -0.824 -0.523 0.219 vn -0.886 -0.220 0.409 vn -0.863 0.404 0.303 vn -0.782 -0.104 0.615 vn -0.953 0.066 0.297 vn -0.949 0.312 0.046 vn -0.991 0.025 -0.134 vn -0.944 -0.116 0.308 vn -0.971 -0.237 0.041 vn -0.947 -0.041 0.318 vn -0.854 -0.274 -0.443 vn -0.885 -0.271 -0.378 vn -0.952 -0.121 -0.282 vn 0.180 0.824 -0.537 vn 0.642 0.679 -0.355 vn 0.956 0.291 -0.021 vn 0.453 -0.867 0.208 vn 0.910 -0.301 0.285 vn 0.854 -0.043 0.518 vn 0.833 0.459 0.308 vn 0.241 0.911 0.334 vn 0.731 -0.650 -0.206 vn 0.760 -0.585 -0.282 vn -0.814 0.019 0.580 vn -0.563 0.638 0.526 vn -0.925 -0.012 0.381 vn -0.214 0.952 0.217 vn 0.096 0.721 0.686 vn -0.027 0.945 0.325 vn -0.555 -0.678 -0.481 vn 0.062 0.937 -0.343 vn 0.240 -0.291 0.926 vn 0.184 -0.889 0.419 vn -0.126 -0.990 0.061 vn -0.889 -0.369 -0.271 vn -0.506 -0.832 0.229 vn -0.808 -0.443 0.388 vn -0.993 -0.084 0.087 vn 0.350 -0.016 0.937 vn -0.636 0.759 -0.140 vn -0.771 0.626 -0.115 vn -0.250 0.462 -0.851 vn -0.192 0.568 -0.801 vn -0.359 0.279 0.891 vn -0.026 0.144 0.989 vn -0.398 -0.100 0.912 vn -0.465 0.084 0.881 vn -0.895 0.186 0.405 vn -0.947 0.184 0.264 vn -0.761 0.459 0.458 vn -0.657 0.429 0.620 vn -0.426 0.660 0.618 vn -0.505 0.610 0.611 vn 0.223 0.536 0.814 vn 0.285 0.393 0.874 vn -0.163 0.555 0.815 vn -0.038 0.570 0.821 vn -0.628 0.723 -0.288 vn -0.458 0.737 0.497 vn -0.212 0.799 0.563 vn -0.278 0.687 0.672 vn -0.380 0.657 0.651 vn -0.170 0.846 0.506 vn -0.305 0.687 0.660 vn -0.144 0.795 0.589 vn 0.001 0.494 -0.870 vn -0.208 0.539 -0.816 vn -0.027 0.458 -0.888 vn -0.057 0.367 -0.929 vn -0.262 0.718 0.645 vn -0.054 0.163 -0.985 vn -0.306 0.325 -0.895 vn -0.643 0.181 0.744 vn -0.717 0.083 0.692 vn -0.800 0.573 -0.178 vn 0.296 -0.070 0.953 vn -0.319 -0.065 0.946 # 1258 vertex normals g head s 1 f 24/1/24 25/2/25 26/3/26 f 24/1/24 26/3/26 23/4/23 f 28/5/28 29/6/29 30/7/30 f 28/5/28 30/7/30 27/8/27 f 32/9/32 33/10/33 34/11/34 f 32/9/32 34/11/34 31/12/31 f 36/13/36 31/12/31 34/11/34 f 36/13/36 34/11/34 35/14/35 f 36/13/36 35/14/35 25/2/25 f 36/13/36 25/2/25 24/1/24 f 38/15/38 39/16/39 40/17/40 f 38/15/38 40/17/40 37/18/37 f 42/19/42 23/4/23 26/3/26 f 42/19/42 26/3/26 41/20/41 f 40/17/40 42/19/42 41/20/41 f 40/17/40 41/20/41 37/18/37 f 38/15/38 43/21/43 44/22/44 f 38/15/38 44/22/44 39/16/39 f 32/9/32 45/23/45 46/24/46 f 32/9/32 46/24/46 33/10/33 f 28/5/28 44/22/44 48/25/48 f 28/5/28 48/25/48 47/26/47 f 50/27/50 51/28/51 52/29/52 f 50/27/50 52/29/52 49/30/49 f 54/31/54 55/32/55 56/33/56 f 54/31/54 56/33/56 53/34/53 f 58/35/58 59/36/59 60/37/60 f 58/35/58 60/37/60 57/38/57 f 62/39/62 63/40/63 64/41/64 f 62/39/62 64/41/64 61/42/61 f 66/43/66 67/44/67 68/45/68 f 66/43/66 68/45/68 65/46/65 f 70/47/70 71/48/71 72/49/72 f 70/47/70 72/49/72 69/50/69 f 67/44/67 66/43/66 74/51/74 f 67/44/67 74/51/74 73/52/73 f 66/43/66 51/28/51 50/27/50 f 66/43/66 50/27/50 74/51/74 f 76/53/76 77/54/77 78/55/78 f 76/53/76 78/55/78 75/56/75 f 80/57/80 81/58/81 82/59/82 f 80/57/80 82/59/82 79/60/79 f 84/61/84 85/62/85 86/63/86 f 84/61/84 86/63/86 83/64/83 f 87/65/87 88/66/88 80/57/80 f 87/65/87 80/57/80 79/60/79 f 90/67/90 91/68/91 92/69/92 f 90/67/90 92/69/92 89/70/89 f 93/71/93 94/72/94 78/55/78 f 93/71/93 78/55/78 77/54/77 f 87/65/87 95/73/95 96/74/96 f 87/65/87 96/74/96 88/66/88 f 98/75/98 99/76/99 100/77/100 f 98/75/98 100/77/100 97/78/97 f 100/77/100 101/79/101 102/80/102 f 100/77/100 102/80/102 97/78/97 f 98/75/98 103/81/103 104/82/104 f 98/75/98 104/82/104 99/76/99 f 106/83/106 107/84/107 108/85/108 f 106/83/106 108/85/108 105/86/105 f 109/87/109 110/88/110 105/86/105 f 109/87/109 105/86/105 108/85/108 f 101/79/101 111/89/111 112/90/112 f 101/79/101 112/90/112 102/80/102 f 114/91/114 115/92/115 116/93/116 f 114/91/114 116/93/116 113/94/113 f 118/95/118 119/96/119 120/97/120 f 118/95/118 120/97/120 117/98/117 f 122/99/122 123/100/123 124/101/124 f 122/99/122 124/101/124 121/102/121 f 126/103/126 127/104/127 128/105/128 f 126/103/126 128/105/128 125/106/125 f 130/107/130 131/108/131 132/109/132 f 130/107/130 132/109/132 129/110/129 f 125/106/125 128/105/128 134/111/134 f 125/106/125 134/111/134 133/112/133 f 56/33/56 55/32/55 136/113/136 f 56/33/56 136/113/136 135/114/135 f 37/115/37 137/116/137 138/117/138 f 37/115/37 138/117/138 38/118/38 f 139/119/139 43/120/43 38/118/38 f 139/119/139 38/118/38 138/117/138 f 140/121/140 141/122/141 142/123/142 f 140/121/140 142/123/142 130/107/130 f 144/124/144 129/110/129 132/109/132 f 144/124/144 132/109/132 143/125/143 f 146/126/146 147/127/147 148/128/148 f 146/126/146 148/128/148 145/129/145 f 150/130/150 151/131/151 54/31/54 f 150/130/150 54/31/54 149/132/149 f 54/31/54 53/34/53 152/133/152 f 54/31/54 152/133/152 149/132/149 f 154/134/154 155/135/155 156/136/156 f 154/134/154 156/136/156 153/137/153 f 158/138/158 159/139/159 160/140/160 f 158/138/158 160/140/160 157/141/157 f 162/142/162 163/143/163 164/144/164 f 162/142/162 164/144/164 161/145/161 f 129/110/129 144/124/144 157/141/157 f 129/110/129 157/141/157 160/140/160 f 156/136/156 155/135/155 166/146/166 f 156/136/156 166/146/166 165/147/165 f 168/148/168 169/149/169 170/150/170 f 168/148/168 170/150/170 167/151/167 f 171/152/171 172/153/172 173/154/173 f 171/152/171 173/154/173 169/149/169 f 175/155/175 176/156/176 171/152/171 f 175/155/175 171/152/171 174/157/174 f 59/36/59 177/158/177 178/159/178 f 59/36/59 178/159/178 60/37/60 f 180/160/180 181/161/181 49/30/49 f 180/160/180 49/30/49 179/162/179 f 127/104/127 52/29/52 182/163/182 f 127/104/127 182/163/182 128/105/128 f 134/111/134 183/164/183 184/165/184 f 134/111/134 184/165/184 124/101/124 f 185/166/185 121/102/121 124/101/124 f 185/166/185 124/101/124 184/165/184 f 187/167/187 188/168/188 189/169/189 f 187/167/187 189/169/189 186/170/186 f 191/171/191 192/172/192 193/173/193 f 191/171/191 193/173/193 190/174/190 f 76/53/76 194/175/194 193/173/193 f 76/53/76 193/173/193 77/54/77 f 100/77/100 99/76/99 196/176/196 f 100/77/100 196/176/196 195/177/195 f 176/156/176 175/155/175 198/178/198 f 176/156/176 198/178/198 197/179/197 f 199/180/199 200/181/200 173/154/173 f 199/180/199 173/154/173 172/153/172 f 196/176/196 202/182/202 203/183/203 f 196/176/196 203/183/203 201/184/201 f 205/185/205 206/186/206 207/187/207 f 205/185/205 207/187/207 204/188/204 f 208/189/208 205/185/205 204/188/204 f 208/189/208 204/188/204 201/184/201 f 210/190/210 97/78/97 102/80/102 f 210/190/210 102/80/102 209/191/209 f 79/60/79 210/190/210 209/191/209 f 79/60/79 209/191/209 87/65/87 f 212/192/212 213/193/213 214/194/214 f 212/192/212 214/194/214 211/195/211 f 216/196/216 217/197/217 218/198/218 f 216/196/216 218/198/218 215/199/215 f 220/200/220 216/196/216 215/199/215 f 220/200/220 215/199/215 219/201/219 f 222/202/222 223/203/223 218/198/218 f 222/202/222 218/198/218 221/204/221 f 225/205/225 226/206/226 227/207/227 f 225/205/225 227/207/227 224/208/224 f 222/202/222 221/204/221 229/209/229 f 222/202/222 229/209/229 228/210/228 f 230/211/230 231/212/231 220/200/220 f 230/211/230 220/200/220 219/201/219 f 227/207/227 226/206/226 231/212/231 f 227/207/227 231/212/231 230/211/230 f 233/213/233 234/214/234 235/215/235 f 233/213/233 235/215/235 232/216/232 f 186/170/186 203/183/203 202/182/202 f 186/170/186 202/182/202 187/167/187 f 236/217/236 237/218/237 238/219/238 f 236/217/236 238/219/238 188/168/188 f 240/220/240 241/221/241 242/222/242 f 240/220/240 242/222/242 239/223/239 f 241/221/241 243/224/243 244/225/244 f 241/221/241 244/225/244 238/219/238 f 245/226/245 101/79/101 100/77/100 f 245/226/245 100/77/100 195/177/195 f 195/177/195 204/188/204 207/187/207 f 195/177/195 207/187/207 245/226/245 f 111/89/111 246/227/246 247/228/247 f 111/89/111 247/228/247 115/92/115 f 141/122/141 140/121/140 249/229/249 f 141/122/141 249/229/249 248/230/248 f 251/231/251 252/232/252 253/233/253 f 251/231/251 253/233/253 250/234/250 f 254/235/254 118/95/118 255/236/255 f 254/235/254 255/236/255 217/197/217 f 257/237/257 258/238/258 259/239/259 f 257/237/257 259/239/259 256/240/256 f 256/240/256 259/239/259 261/241/261 f 256/240/256 261/241/261 260/242/260 f 260/242/260 261/241/261 30/243/30 f 260/242/260 30/243/30 29/244/29 f 218/198/218 217/197/217 262/245/262 f 218/198/218 262/245/262 221/204/221 f 259/239/259 258/238/258 264/246/264 f 259/239/259 264/246/264 263/247/263 f 266/248/266 30/243/30 261/241/261 f 266/248/266 261/241/261 265/249/265 f 253/233/253 252/232/252 268/250/268 f 253/233/253 268/250/268 267/251/267 f 270/252/270 200/181/200 271/253/271 f 270/252/270 271/253/271 269/254/269 f 199/180/199 272/255/272 271/253/271 f 199/180/199 271/253/271 200/181/200 f 199/180/199 273/256/273 274/257/274 f 199/180/199 274/257/274 272/255/272 f 276/258/276 267/251/267 268/250/268 f 276/258/276 268/250/268 275/259/275 f 275/259/275 268/250/268 269/254/269 f 275/259/275 269/254/269 277/260/277 f 93/71/93 77/54/77 193/173/193 f 93/71/93 193/173/193 192/172/192 f 279/261/279 280/262/280 281/263/281 f 279/261/279 281/263/281 278/264/278 f 278/264/278 88/66/88 96/74/96 f 278/264/278 96/74/96 279/261/279 f 282/265/282 283/266/283 62/39/62 f 282/265/282 62/39/62 94/72/94 f 281/263/281 284/267/284 285/268/285 f 281/263/281 285/268/285 278/264/278 f 287/269/287 288/270/288 289/271/289 f 287/269/287 289/271/289 286/272/286 f 63/40/63 62/39/62 283/266/283 f 63/40/63 283/266/283 290/273/290 f 283/266/283 291/274/291 292/275/292 f 283/266/283 292/275/292 290/273/290 f 293/276/293 294/277/294 68/45/68 f 293/276/293 68/45/68 67/44/67 f 296/278/296 297/279/297 298/280/298 f 296/278/296 298/280/298 295/281/295 f 300/282/300 301/283/301 302/284/302 f 300/282/300 302/284/302 299/285/299 f 304/286/304 305/287/305 306/288/306 f 304/286/304 306/288/306 303/289/303 f 138/117/138 137/116/137 308/290/308 f 138/117/138 308/290/308 307/291/307 f 165/147/165 310/292/310 311/293/311 f 165/147/165 311/293/311 309/294/309 f 312/295/312 55/32/55 54/31/54 f 312/295/312 54/31/54 151/131/151 f 314/296/314 151/131/151 150/130/150 f 314/296/314 150/130/150 313/297/313 f 315/298/315 316/299/316 227/207/227 f 315/298/315 227/207/227 230/211/230 f 136/113/136 317/300/317 158/138/158 f 136/113/136 158/138/158 157/141/157 f 319/301/319 148/128/148 147/127/147 f 319/301/319 147/127/147 318/302/318 f 320/303/320 321/304/321 147/127/147 f 320/303/320 147/127/147 146/126/146 f 323/305/323 324/306/324 325/307/325 f 323/305/323 325/307/325 322/308/322 f 80/57/80 88/66/88 278/264/278 f 80/57/80 278/264/278 285/268/285 f 327/309/327 145/129/145 148/128/148 f 327/309/327 148/128/148 326/310/326 f 279/261/279 286/272/286 289/271/289 f 279/261/279 289/271/289 280/262/280 f 329/311/329 330/312/330 331/313/331 f 329/311/329 331/313/331 328/314/328 f 187/167/187 202/182/202 104/82/104 f 187/167/187 104/82/104 332/315/332 f 236/217/236 332/315/332 191/171/191 f 236/217/236 191/171/191 190/174/190 f 165/147/165 166/146/166 333/316/333 f 165/147/165 333/316/333 310/292/310 f 139/119/139 334/317/334 48/318/48 f 139/119/139 48/318/48 43/120/43 f 336/319/336 337/320/337 338/321/338 f 336/319/336 338/321/338 335/322/335 f 51/28/51 324/306/324 182/163/182 f 51/28/51 182/163/182 52/29/52 f 339/323/339 126/103/126 53/34/53 f 339/323/339 53/34/53 56/33/56 f 340/324/340 341/325/341 149/132/149 f 340/324/340 149/132/149 152/133/152 f 243/224/243 343/326/343 344/327/344 f 243/224/243 344/327/344 342/328/342 f 346/329/346 343/326/343 240/220/240 f 346/329/346 240/220/240 345/330/345 f 348/331/348 349/332/349 350/333/350 f 348/331/348 350/333/350 347/334/347 f 351/335/351 352/336/352 213/193/213 f 351/335/351 213/193/213 212/192/212 f 128/105/128 182/163/182 183/164/183 f 128/105/128 183/164/183 134/111/134 f 103/81/103 98/75/98 354/337/354 f 103/81/103 354/337/354 353/338/353 f 114/91/114 113/94/113 356/339/356 f 114/91/114 356/339/356 355/340/355 f 358/341/358 197/179/197 198/178/198 f 358/341/358 198/178/198 357/342/357 f 107/84/107 359/343/359 360/344/360 f 107/84/107 360/344/360 108/85/108 f 348/331/348 361/345/361 362/346/362 f 348/331/348 362/346/362 349/332/349 f 347/334/347 363/347/363 234/214/234 f 347/334/347 234/214/234 348/331/348 f 220/200/220 231/212/231 167/151/167 f 220/200/220 167/151/167 364/348/364 f 153/137/153 366/349/366 300/282/300 f 153/137/153 300/282/300 365/350/365 f 295/281/295 72/49/72 71/48/71 f 295/281/295 71/48/71 296/278/296 f 179/162/179 339/323/339 367/351/367 f 179/162/179 367/351/367 180/160/180 f 368/352/368 369/353/369 158/138/158 f 368/352/368 158/138/158 317/300/317 f 317/300/317 136/113/136 55/32/55 f 317/300/317 55/32/55 312/295/312 f 371/354/371 372/355/372 373/356/373 f 371/354/371 373/356/373 370/357/370 f 41/358/41 26/359/26 306/288/306 f 41/358/41 306/288/306 305/287/305 f 305/287/305 137/116/137 37/115/37 f 305/287/305 37/115/37 41/358/41 f 248/230/248 374/360/374 375/361/375 f 248/230/248 375/361/375 141/122/141 f 66/43/66 325/307/325 324/306/324 f 66/43/66 324/306/324 51/28/51 f 183/164/183 323/305/323 376/362/376 f 183/164/183 376/362/376 184/165/184 f 378/363/378 253/233/253 267/251/267 f 378/363/378 267/251/267 377/364/377 f 269/254/269 271/253/271 379/365/379 f 269/254/269 379/365/379 277/260/277 f 381/366/381 382/367/382 383/368/383 f 381/366/381 383/368/383 380/369/380 f 384/370/384 385/371/385 105/86/105 f 384/370/384 105/86/105 110/88/110 f 105/86/105 385/371/385 386/372/386 f 105/86/105 386/372/386 106/83/106 f 360/344/360 387/373/387 109/87/109 f 360/344/360 109/87/109 108/85/108 f 181/161/181 180/160/180 164/144/164 f 181/161/181 164/144/164 163/143/163 f 365/350/365 388/374/388 154/134/154 f 365/350/365 154/134/154 153/137/153 f 168/148/168 167/151/167 231/212/231 f 168/148/168 231/212/231 226/206/226 f 81/58/81 291/274/291 283/266/283 f 81/58/81 283/266/283 282/265/282 f 272/255/272 389/375/389 379/365/379 f 272/255/272 379/365/379 271/253/271 f 274/257/274 390/376/390 389/375/389 f 274/257/274 389/375/389 272/255/272 f 139/119/139 375/361/375 374/360/374 f 139/119/139 374/360/374 334/317/334 f 391/377/391 366/349/366 153/137/153 f 391/377/391 153/137/153 156/136/156 f 392/378/392 393/379/393 366/349/366 f 392/378/392 366/349/366 391/377/391 f 173/154/173 200/181/200 270/252/270 f 173/154/173 270/252/270 394/380/394 f 301/283/301 300/282/300 366/349/366 f 301/283/301 366/349/366 393/379/393 f 396/381/396 397/382/397 398/383/398 f 396/381/396 398/383/398 395/384/395 f 399/385/399 364/348/364 167/151/167 f 399/385/399 167/151/167 170/150/170 f 394/380/394 251/231/251 399/385/399 f 394/380/394 399/385/399 170/150/170 f 270/252/270 252/232/252 251/231/251 f 270/252/270 251/231/251 394/380/394 f 102/80/102 112/90/112 400/386/400 f 102/80/102 400/386/400 209/191/209 f 131/108/131 401/387/401 372/355/372 f 131/108/131 372/355/372 371/354/371 f 391/377/391 156/136/156 165/147/165 f 391/377/391 165/147/165 309/294/309 f 403/388/403 404/389/404 405/390/405 f 403/388/403 405/390/405 402/391/402 f 402/391/402 392/378/392 391/377/391 f 402/391/402 391/377/391 309/294/309 f 35/392/35 310/292/310 333/316/333 f 35/392/35 333/316/333 25/393/25 f 35/392/35 34/394/34 311/293/311 f 35/392/35 311/293/311 310/292/310 f 34/394/34 33/395/33 403/388/403 f 34/394/34 403/388/403 311/293/311 f 406/396/406 262/245/262 217/197/217 f 406/396/406 217/197/217 255/236/255 f 377/364/377 407/397/407 408/398/408 f 377/364/377 408/398/408 406/396/406 f 117/98/117 378/363/378 255/236/255 f 117/98/117 255/236/255 118/95/118 f 270/252/270 269/254/269 268/250/268 f 270/252/270 268/250/268 252/232/252 f 304/286/304 303/289/303 373/356/373 f 304/286/304 373/356/373 372/355/372 f 362/346/362 409/399/409 410/400/410 f 362/346/362 410/400/410 349/332/349 f 411/401/411 412/402/412 89/70/89 f 411/401/411 89/70/89 92/69/92 f 414/403/414 411/401/411 415/404/415 f 414/403/414 415/404/415 413/405/413 f 417/406/417 336/319/336 418/407/418 f 417/406/417 418/407/418 416/408/416 f 337/320/337 419/409/419 69/50/69 f 337/320/337 69/50/69 72/49/72 f 421/410/421 422/411/422 423/412/423 f 421/410/421 423/412/423 420/413/420 f 421/410/421 424/414/424 425/415/425 f 421/410/421 425/415/425 422/411/422 f 423/412/423 422/411/422 427/416/427 f 423/412/423 427/416/427 426/417/426 f 239/223/239 242/222/242 428/418/428 f 239/223/239 428/418/428 425/415/425 f 430/419/430 73/52/73 74/51/74 f 430/419/430 74/51/74 429/420/429 f 70/47/70 69/50/69 419/409/419 f 70/47/70 419/409/419 429/420/429 f 247/228/247 431/421/431 116/93/116 f 247/228/247 116/93/116 115/92/115 f 346/329/346 345/330/345 433/422/433 f 346/329/346 433/422/433 432/423/432 f 433/422/433 421/410/421 420/413/420 f 433/422/433 420/413/420 434/424/434 f 436/425/436 437/426/437 438/427/438 f 436/425/436 438/427/438 435/428/435 f 437/426/437 381/366/381 380/369/380 f 437/426/437 380/369/380 438/427/438 f 178/159/178 177/158/177 440/429/440 f 178/159/178 440/429/440 439/430/439 f 440/429/440 441/431/441 442/432/442 f 440/429/440 442/432/442 439/430/439 f 444/433/444 445/434/445 446/435/446 f 444/433/444 446/435/446 443/436/443 f 324/306/324 323/305/323 183/164/183 f 324/306/324 183/164/183 182/163/182 f 213/193/213 352/336/352 357/342/357 f 213/193/213 357/342/357 198/178/198 f 214/194/214 175/155/175 174/157/174 f 214/194/214 174/157/174 225/205/225 f 448/437/448 449/438/449 450/439/450 f 448/437/448 450/439/450 447/440/447 f 423/412/423 426/417/426 451/441/451 f 423/412/423 451/441/451 447/440/447 f 75/56/75 451/441/451 426/417/426 f 75/56/75 426/417/426 76/53/76 f 78/55/78 94/72/94 62/39/62 f 78/55/78 62/39/62 61/42/61 f 286/272/286 86/63/86 85/62/85 f 286/272/286 85/62/85 287/269/287 f 95/73/95 87/65/87 209/191/209 f 95/73/95 209/191/209 400/386/400 f 237/218/237 452/442/452 428/418/428 f 237/218/237 428/418/428 242/222/242 f 190/174/190 193/173/193 194/175/194 f 190/174/190 194/175/194 452/442/452 f 237/218/237 236/217/236 190/174/190 f 237/218/237 190/174/190 452/442/452 f 79/60/79 82/59/82 354/337/354 f 79/60/79 354/337/354 210/190/210 f 286/272/286 279/261/279 96/74/96 f 286/272/286 96/74/96 86/63/86 f 430/419/430 417/406/417 416/408/416 f 430/419/430 416/408/416 453/443/453 f 338/321/338 295/281/295 298/280/298 f 338/321/338 298/280/298 299/285/299 f 57/38/57 60/37/60 455/444/455 f 57/38/57 455/444/455 454/445/454 f 212/192/212 456/446/456 457/447/457 f 212/192/212 457/447/457 351/335/351 f 83/64/83 355/340/355 356/339/356 f 83/64/83 356/339/356 84/61/84 f 142/123/142 141/122/141 375/361/375 f 142/123/142 375/361/375 307/291/307 f 401/387/401 142/123/142 307/291/307 f 401/387/401 307/291/307 308/290/308 f 459/448/459 257/237/257 256/240/256 f 459/448/459 256/240/256 458/449/458 f 228/210/228 264/246/264 258/238/258 f 228/210/228 258/238/258 222/202/222 f 256/240/256 260/242/260 460/450/460 f 256/240/256 460/450/460 458/449/458 f 460/450/460 260/242/260 29/244/29 f 460/450/460 29/244/29 47/451/47 f 263/247/263 265/249/265 261/241/261 f 263/247/263 261/241/261 259/239/259 f 461/452/461 462/453/462 189/169/189 f 461/452/461 189/169/189 244/225/244 f 227/207/227 316/299/316 463/454/463 f 227/207/227 463/454/463 224/208/224 f 465/455/465 466/456/466 410/400/410 f 465/455/465 410/400/410 464/457/464 f 90/67/90 386/372/386 385/371/385 f 90/67/90 385/371/385 91/68/91 f 233/213/233 361/345/361 348/331/348 f 233/213/233 348/331/348 234/214/234 f 235/215/235 234/214/234 363/347/363 f 235/215/235 363/347/363 467/458/467 f 338/321/338 337/320/337 72/49/72 f 338/321/338 72/49/72 295/281/295 f 338/321/338 299/285/299 302/284/302 f 338/321/338 302/284/302 335/322/335 f 468/459/468 469/460/469 470/461/470 f 468/459/468 470/461/470 415/404/415 f 347/334/347 471/462/471 472/463/472 f 347/334/347 472/463/472 363/347/363 f 471/462/471 347/334/347 350/333/350 f 471/462/471 350/333/350 473/464/473 f 465/455/465 475/465/475 476/466/476 f 465/455/465 476/466/476 474/467/474 f 384/370/384 110/88/110 478/468/478 f 384/370/384 478/468/478 477/469/477 f 414/403/414 479/470/479 412/402/412 f 414/403/414 412/402/412 411/401/411 f 288/270/288 287/269/287 412/402/412 f 288/270/288 412/402/412 479/470/479 f 85/62/85 84/61/84 90/67/90 f 85/62/85 90/67/90 89/70/89 f 386/372/386 356/339/356 113/94/113 f 386/372/386 113/94/113 106/83/106 f 232/216/232 358/341/358 357/342/357 f 232/216/232 357/342/357 233/213/233 f 297/279/297 296/278/296 181/161/181 f 297/279/297 181/161/181 163/143/163 f 419/409/419 337/320/337 336/319/336 f 419/409/419 336/319/336 417/406/417 f 49/30/49 52/29/52 127/104/127 f 49/30/49 127/104/127 179/162/179 f 26/359/26 25/393/25 333/316/333 f 26/359/26 333/316/333 306/288/306 f 371/354/371 370/357/370 162/142/162 f 371/354/371 162/142/162 161/145/161 f 258/238/258 257/237/257 223/203/223 f 258/238/258 223/203/223 222/202/222 f 257/237/257 459/448/459 480/471/480 f 257/237/257 480/471/480 223/203/223 f 211/195/211 214/194/214 225/205/225 f 211/195/211 225/205/225 224/208/224 f 316/299/316 481/472/481 314/296/314 f 316/299/316 314/296/314 463/454/463 f 171/152/171 169/149/169 168/148/168 f 171/152/171 168/148/168 174/157/174 f 273/256/273 199/180/199 172/153/172 f 273/256/273 172/153/172 482/473/482 f 168/148/168 226/206/226 225/205/225 f 168/148/168 225/205/225 174/157/174 f 245/226/245 246/227/246 111/89/111 f 245/226/245 111/89/111 101/79/101 f 114/91/114 112/90/112 111/89/111 f 114/91/114 111/89/111 115/92/115 f 210/190/210 354/337/354 98/75/98 f 210/190/210 98/75/98 97/78/97 f 431/421/431 358/341/358 232/216/232 f 431/421/431 232/216/232 359/343/359 f 235/215/235 360/344/360 359/343/359 f 235/215/235 359/343/359 232/216/232 f 360/344/360 235/215/235 467/458/467 f 360/344/360 467/458/467 387/373/387 f 81/58/81 282/265/282 483/474/483 f 81/58/81 483/474/483 82/59/82 f 485/475/485 486/476/486 487/477/487 f 485/475/485 487/477/487 484/478/484 f 489/479/489 68/45/68 294/277/294 f 489/479/489 294/277/294 488/480/488 f 491/481/491 454/445/454 455/444/455 f 491/481/491 455/444/455 490/482/490 f 154/134/154 370/357/370 373/356/373 f 154/134/154 373/356/373 155/135/155 f 491/481/491 322/308/322 325/307/325 f 491/481/491 325/307/325 492/483/492 f 491/481/491 490/482/490 493/484/493 f 491/481/491 493/484/493 322/308/322 f 436/425/436 435/428/435 446/435/446 f 436/425/436 446/435/446 494/485/494 f 495/486/495 496/487/496 438/427/438 f 495/486/495 438/427/438 380/369/380 f 496/487/496 497/488/497 435/428/435 f 496/487/496 435/428/435 438/427/438 f 331/313/331 330/312/330 498/489/498 f 331/313/331 498/489/498 432/423/432 f 499/490/499 346/329/346 432/423/432 f 499/490/499 432/423/432 498/489/498 f 380/369/380 383/368/383 500/491/500 f 380/369/380 500/491/500 495/486/495 f 501/492/501 328/314/328 331/313/331 f 501/492/501 331/313/331 434/424/434 f 499/490/499 344/327/344 343/326/343 f 499/490/499 343/326/343 346/329/346 f 492/483/492 502/493/502 454/445/454 f 492/483/492 454/445/454 491/481/491 f 454/445/454 502/493/502 487/477/487 f 454/445/454 487/477/487 57/38/57 f 486/476/486 58/35/58 57/38/57 f 486/476/486 57/38/57 487/477/487 f 58/35/58 486/476/486 503/494/503 f 58/35/58 503/494/503 382/367/382 f 383/368/383 504/495/504 505/496/505 f 383/368/383 505/496/505 500/491/500 f 447/440/447 450/439/450 420/413/420 f 447/440/447 420/413/420 423/412/423 f 329/311/329 328/314/328 445/434/445 f 329/311/329 445/434/445 444/433/444 f 450/439/450 449/438/449 506/497/506 f 450/439/450 506/497/506 501/492/501 f 507/498/507 508/499/508 451/441/451 f 507/498/507 451/441/451 75/56/75 f 99/76/99 104/82/104 202/182/202 f 99/76/99 202/182/202 196/176/196 f 509/500/509 208/189/208 201/184/201 f 509/500/509 201/184/201 203/183/203 f 201/184/201 204/188/204 195/177/195 f 201/184/201 195/177/195 196/176/196 f 462/453/462 510/501/510 186/170/186 f 462/453/462 186/170/186 189/169/189 f 203/183/203 186/170/186 510/501/510 f 203/183/203 510/501/510 509/500/509 f 148/128/148 319/301/319 341/325/341 f 148/128/148 341/325/341 326/310/326 f 326/310/326 341/325/341 340/324/340 f 326/310/326 340/324/340 511/502/511 f 123/100/123 511/502/511 340/324/340 f 123/100/123 340/324/340 133/112/133 f 71/48/71 49/30/49 181/161/181 f 71/48/71 181/161/181 296/278/296 f 154/134/154 388/374/388 162/142/162 f 154/134/154 162/142/162 370/357/370 f 155/135/155 373/356/373 303/289/303 f 155/135/155 303/289/303 166/146/166 f 166/146/166 303/289/303 306/288/306 f 166/146/166 306/288/306 333/316/333 f 512/503/512 320/303/320 289/271/289 f 512/503/512 289/271/289 288/270/288 f 479/470/479 414/403/414 514/504/514 f 479/470/479 514/504/514 513/505/513 f 414/403/414 413/405/413 475/465/475 f 414/403/414 475/465/475 514/504/514 f 513/505/513 512/503/512 288/270/288 f 513/505/513 288/270/288 479/470/479 f 191/171/191 103/81/103 353/338/353 f 191/171/191 353/338/353 192/172/192 f 332/315/332 104/82/104 103/81/103 f 332/315/332 103/81/103 191/171/191 f 82/59/82 483/474/483 353/338/353 f 82/59/82 353/338/353 354/337/354 f 83/64/83 86/63/86 96/74/96 f 83/64/83 96/74/96 95/73/95 f 83/64/83 95/73/95 400/386/400 f 83/64/83 400/386/400 355/340/355 f 355/340/355 400/386/400 112/90/112 f 355/340/355 112/90/112 114/91/114 f 144/124/144 135/114/135 136/113/136 f 144/124/144 136/113/136 157/141/157 f 298/280/298 365/350/365 300/282/300 f 298/280/298 300/282/300 299/285/299 f 298/280/298 297/279/297 388/374/388 f 298/280/298 388/374/388 365/350/365 f 367/351/367 143/125/143 164/144/164 f 367/351/367 164/144/164 180/160/180 f 515/506/515 516/507/516 219/201/219 f 515/506/515 219/201/219 215/199/215 f 254/235/254 217/197/217 216/196/216 f 254/235/254 216/196/216 517/508/517 f 398/383/398 364/348/364 399/385/399 f 398/383/398 399/385/399 395/384/395 f 398/383/398 397/382/397 517/508/517 f 398/383/398 517/508/517 216/196/216 f 518/509/518 519/510/519 246/227/246 f 518/509/518 246/227/246 245/226/245 f 319/301/319 150/130/150 149/132/149 f 319/301/319 149/132/149 341/325/341 f 429/420/429 419/409/419 417/406/417 f 429/420/429 417/406/417 430/419/430 f 33/395/33 46/511/46 404/389/404 f 33/395/33 404/389/404 403/388/403 f 403/388/403 402/391/402 309/294/309 f 403/388/403 309/294/309 311/293/311 f 393/379/393 520/512/520 521/513/521 f 393/379/393 521/513/521 301/283/301 f 522/514/522 520/512/520 393/379/393 f 522/514/522 393/379/393 392/378/392 f 302/284/302 301/283/301 521/513/521 f 302/284/302 521/513/521 523/515/523 f 302/284/302 523/515/523 524/516/524 f 302/284/302 524/516/524 335/322/335 f 321/304/321 456/446/456 318/302/318 f 321/304/321 318/302/318 147/127/147 f 456/446/456 321/304/321 525/517/525 f 456/446/456 525/517/525 457/447/457 f 410/400/410 409/399/409 526/518/526 f 410/400/410 526/518/526 464/457/464 f 410/400/410 466/456/466 350/333/350 f 410/400/410 350/333/350 349/332/349 f 456/446/456 212/192/212 211/195/211 f 456/446/456 211/195/211 527/519/527 f 211/195/211 224/208/224 463/454/463 f 211/195/211 463/454/463 527/519/527 f 407/397/407 377/364/377 267/251/267 f 407/397/407 267/251/267 276/258/276 f 378/363/378 377/364/377 406/396/406 f 378/363/378 406/396/406 255/236/255 f 175/155/175 214/194/214 213/193/213 f 175/155/175 213/193/213 198/178/198 f 386/372/386 90/67/90 84/61/84 f 386/372/386 84/61/84 356/339/356 f 409/399/409 362/346/362 351/335/351 f 409/399/409 351/335/351 457/447/457 f 85/62/85 89/70/89 412/402/412 f 85/62/85 412/402/412 287/269/287 f 361/345/361 233/213/233 357/342/357 f 361/345/361 357/342/357 352/336/352 f 116/93/116 431/421/431 359/343/359 f 116/93/116 359/343/359 107/84/107 f 116/93/116 107/84/107 106/83/106 f 116/93/116 106/83/106 113/94/113 f 352/336/352 351/335/351 362/346/362 f 352/336/352 362/346/362 361/345/361 f 513/505/513 514/504/514 464/457/464 f 513/505/513 464/457/464 526/518/526 f 526/518/526 409/399/409 457/447/457 f 526/518/526 457/447/457 525/517/525 f 514/504/514 475/465/475 465/455/465 f 514/504/514 465/455/465 464/457/464 f 358/341/358 431/421/431 247/228/247 f 358/341/358 247/228/247 197/179/197 f 176/156/176 482/473/482 172/153/172 f 176/156/176 172/153/172 171/152/171 f 396/381/396 395/384/395 250/234/250 f 396/381/396 250/234/250 119/96/119 f 395/384/395 399/385/399 251/231/251 f 395/384/395 251/231/251 250/234/250 f 291/274/291 81/58/81 80/57/80 f 291/274/291 80/57/80 285/268/285 f 284/267/284 292/275/292 291/274/291 f 284/267/284 291/274/291 285/268/285 f 528/520/528 327/309/327 326/310/326 f 528/520/528 326/310/326 511/502/511 f 126/103/126 125/106/125 152/133/152 f 126/103/126 152/133/152 53/34/53 f 152/133/152 125/106/125 133/112/133 f 152/133/152 133/112/133 340/324/340 f 127/104/127 126/103/126 339/323/339 f 127/104/127 339/323/339 179/162/179 f 56/33/56 135/114/135 367/351/367 f 56/33/56 367/351/367 339/323/339 f 124/101/124 123/100/123 133/112/133 f 124/101/124 133/112/133 134/111/134 f 143/125/143 367/351/367 135/114/135 f 143/125/143 135/114/135 144/124/144 f 164/144/164 143/125/143 132/109/132 f 164/144/164 132/109/132 161/145/161 f 401/387/401 131/108/131 130/107/130 f 401/387/401 130/107/130 142/123/142 f 292/275/292 528/520/528 122/99/122 f 292/275/292 122/99/122 290/273/290 f 61/42/61 507/498/507 75/56/75 f 61/42/61 75/56/75 78/55/78 f 320/303/320 512/503/512 525/517/525 f 320/303/320 525/517/525 321/304/321 f 512/503/512 513/505/513 526/518/526 f 512/503/512 526/518/526 525/517/525 f 123/100/123 122/99/122 528/520/528 f 123/100/123 528/520/528 511/502/511 f 262/245/262 529/521/529 229/209/229 f 262/245/262 229/209/229 221/204/221 f 316/299/316 315/298/315 368/352/368 f 316/299/316 368/352/368 481/472/481 f 516/507/516 315/298/315 230/211/230 f 516/507/516 230/211/230 219/201/219 f 515/506/515 530/522/530 369/353/369 f 515/506/515 369/353/369 516/507/516 f 530/522/530 515/506/515 223/203/223 f 530/522/530 223/203/223 480/471/480 f 215/199/215 218/198/218 223/203/223 f 215/199/215 223/203/223 515/506/515 f 459/448/459 458/449/458 374/360/374 f 459/448/459 374/360/374 248/230/248 f 458/449/458 460/450/460 334/317/334 f 458/449/458 334/317/334 374/360/374 f 334/317/334 460/450/460 47/451/47 f 334/317/334 47/451/47 48/318/48 f 459/448/459 248/230/248 249/229/249 f 459/448/459 249/229/249 480/471/480 f 253/233/253 120/97/120 119/96/119 f 253/233/253 119/96/119 250/234/250 f 394/380/394 170/150/170 169/149/169 f 394/380/394 169/149/169 173/154/173 f 519/510/519 482/473/482 176/156/176 f 519/510/519 176/156/176 197/179/197 f 518/509/518 273/256/273 482/473/482 f 518/509/518 482/473/482 519/510/519 f 531/523/531 274/257/274 273/256/273 f 531/523/531 273/256/273 518/509/518 f 532/524/532 390/376/390 274/257/274 f 532/524/532 274/257/274 531/523/531 f 343/326/343 243/224/243 241/221/241 f 343/326/343 241/221/241 240/220/240 f 188/168/188 238/219/238 244/225/244 f 188/168/188 244/225/244 189/169/189 f 187/167/187 332/315/332 236/217/236 f 187/167/187 236/217/236 188/168/188 f 447/440/447 451/441/451 508/499/508 f 447/440/447 508/499/508 448/437/448 f 162/142/162 388/374/388 297/279/297 f 162/142/162 297/279/297 163/143/163 f 392/378/392 402/391/402 405/390/405 f 392/378/392 405/390/405 522/514/522 f 533/525/533 413/405/413 415/404/415 f 533/525/533 415/404/415 470/461/470 f 534/526/534 65/46/65 68/45/68 f 534/526/534 68/45/68 489/479/489 f 502/493/502 535/527/535 484/478/484 f 502/493/502 484/478/484 487/477/487 f 503/494/503 536/528/536 537/529/537 f 503/494/503 537/529/537 504/495/504 f 492/483/492 538/530/538 535/527/535 f 492/483/492 535/527/535 502/493/502 f 492/483/492 325/307/325 66/43/66 f 492/483/492 66/43/66 65/46/65 f 504/495/504 537/529/537 539/531/539 f 504/495/504 539/531/539 505/496/505 f 239/223/239 424/414/424 345/330/345 f 239/223/239 345/330/345 240/220/240 f 59/36/59 58/35/58 382/367/382 f 59/36/59 382/367/382 381/366/381 f 432/423/432 433/422/433 434/424/434 f 432/423/432 434/424/434 331/313/331 f 437/426/437 436/425/436 440/429/440 f 437/426/437 440/429/440 177/158/177 f 381/366/381 437/426/437 177/158/177 f 381/366/381 177/158/177 59/36/59 f 449/438/449 441/431/441 494/485/494 f 449/438/449 494/485/494 506/497/506 f 450/439/450 501/492/501 434/424/434 f 450/439/450 434/424/434 420/413/420 f 382/367/382 503/494/503 504/495/504 f 382/367/382 504/495/504 383/368/383 f 501/492/501 506/497/506 445/434/445 f 501/492/501 445/434/445 328/314/328 f 536/528/536 503/494/503 486/476/486 f 536/528/536 486/476/486 485/475/485 f 313/297/313 150/130/150 319/301/319 f 313/297/313 319/301/319 318/302/318 f 327/309/327 284/267/284 281/263/281 f 327/309/327 281/263/281 145/129/145 f 483/474/483 93/71/93 192/172/192 f 483/474/483 192/172/192 353/338/353 f 483/474/483 282/265/282 94/72/94 f 483/474/483 94/72/94 93/71/93 f 422/411/422 425/415/425 428/418/428 f 422/411/422 428/418/428 427/416/427 f 421/410/421 433/422/433 345/330/345 f 421/410/421 345/330/345 424/414/424 f 463/454/463 314/296/314 313/297/313 f 463/454/463 313/297/313 527/519/527 f 315/298/315 516/507/516 369/353/369 f 315/298/315 369/353/369 368/352/368 f 314/296/314 481/472/481 312/295/312 f 314/296/314 312/295/312 151/131/151 f 368/352/368 317/300/317 312/295/312 f 368/352/368 312/295/312 481/472/481 f 369/353/369 530/522/530 159/139/159 f 369/353/369 159/139/159 158/138/158 f 480/471/480 249/229/249 159/139/159 f 480/471/480 159/139/159 530/522/530 f 262/245/262 406/396/406 408/398/408 f 262/245/262 408/398/408 529/521/529 f 398/383/398 216/196/216 220/200/220 f 398/383/398 220/200/220 364/348/364 f 541/532/541 542/533/542 543/534/543 f 541/532/541 543/534/543 540/535/540 f 545/536/545 543/534/543 542/533/542 f 545/536/545 542/533/542 544/537/544 f 547/538/547 545/536/545 544/537/544 f 547/538/547 544/537/544 546/539/546 f 549/540/549 547/538/547 546/539/546 f 549/540/549 546/539/546 548/541/548 f 551/542/551 549/540/549 548/541/548 f 551/542/551 548/541/548 550/543/550 f 553/544/553 551/542/551 550/543/550 f 553/544/553 550/543/550 552/545/552 f 555/546/555 553/544/553 552/545/552 f 555/546/555 552/545/552 554/547/554 f 557/548/557 558/549/558 559/550/559 f 557/548/557 559/550/559 556/551/556 f 561/552/561 557/548/557 556/551/556 f 561/552/561 556/551/556 560/553/560 f 563/554/563 546/539/546 544/537/544 f 563/554/563 544/537/544 562/555/562 f 564/556/564 548/541/548 546/539/546 f 564/556/564 546/539/546 563/554/563 f 565/557/565 550/543/550 548/541/548 f 565/557/565 548/541/548 564/556/564 f 566/558/566 552/545/552 550/543/550 f 566/558/566 550/543/550 565/557/565 f 552/545/552 566/558/566 567/559/567 f 552/545/552 567/559/567 554/547/554 f 559/550/559 568/560/568 569/561/569 f 559/550/559 569/561/569 556/551/556 f 570/562/570 560/553/560 556/551/556 f 570/562/570 556/551/556 569/561/569 f 571/563/571 572/564/572 560/553/560 f 571/563/571 560/553/560 570/562/570 f 574/565/574 540/535/540 575/566/575 f 574/565/574 575/566/575 573/567/573 f 577/568/577 543/534/543 545/536/545 f 577/568/577 545/536/545 576/569/576 f 545/536/545 547/538/547 578/570/578 f 545/536/545 578/570/578 576/569/576 f 579/571/579 578/570/578 547/538/547 f 579/571/579 547/538/547 549/540/549 f 580/572/580 579/571/579 551/542/551 f 580/572/580 551/542/551 553/544/553 f 580/572/580 553/544/553 555/546/555 f 580/572/580 555/546/555 581/573/581 f 558/549/558 557/548/557 583/574/583 f 558/549/558 583/574/583 582/575/582 f 561/552/561 584/576/584 583/574/583 f 561/552/561 583/574/583 557/548/557 f 561/552/561 572/564/572 585/577/585 f 561/552/561 585/577/585 584/576/584 f 571/563/571 586/578/586 585/577/585 f 571/563/571 585/577/585 572/564/572 f 544/537/544 542/533/542 541/532/541 f 544/537/544 541/532/541 562/555/562 f 574/565/574 588/579/588 589/580/589 f 574/565/574 589/580/589 587/581/587 f 574/565/574 573/567/573 590/582/590 f 574/565/574 590/582/590 588/579/588 f 590/582/590 573/567/573 575/566/575 f 590/582/590 575/566/575 591/583/591 f 575/566/575 540/535/540 543/534/543 f 575/566/575 543/534/543 591/583/591 f 564/556/564 592/584/592 566/558/566 f 564/556/564 566/558/566 565/557/565 f 592/584/592 593/585/593 567/559/567 f 592/584/592 567/559/567 566/558/566 f 568/560/568 559/550/559 554/547/554 f 568/560/568 554/547/554 567/559/567 f 554/547/554 559/550/559 558/549/558 f 554/547/554 558/549/558 555/546/555 f 582/575/582 581/573/581 555/546/555 f 582/575/582 555/546/555 558/549/558 f 592/584/592 564/556/564 563/554/563 f 592/584/592 563/554/563 562/555/562 f 589/580/589 568/560/568 567/559/567 f 589/580/589 567/559/567 593/585/593 f 540/535/540 574/565/574 587/581/587 f 540/535/540 587/581/587 541/532/541 f 571/563/571 570/562/570 590/582/590 f 571/563/571 590/582/590 591/583/591 f 589/580/589 588/579/588 569/561/569 f 589/580/589 569/561/569 568/560/568 f 543/534/543 577/568/577 594/586/594 f 543/534/543 594/586/594 591/583/591 f 594/586/594 586/578/586 571/563/571 f 594/586/594 571/563/571 591/583/591 f 596/587/596 581/573/581 582/575/582 f 596/587/596 582/575/582 595/588/595 f 596/587/596 597/589/597 580/572/580 f 596/587/596 580/572/580 581/573/581 f 583/574/583 490/482/490 455/444/455 f 583/574/583 455/444/455 595/588/595 f 583/574/583 584/576/584 493/484/493 f 583/574/583 493/484/493 490/482/490 f 597/589/597 508/499/508 579/571/579 f 597/589/597 579/571/579 580/572/580 f 442/432/442 448/437/448 508/499/508 f 442/432/442 508/499/508 597/589/597 f 60/37/60 178/159/178 595/588/595 f 60/37/60 595/588/595 455/444/455 f 178/159/178 439/430/439 596/587/596 f 178/159/178 596/587/596 595/588/595 f 577/568/577 64/41/64 185/166/185 f 577/568/577 185/166/185 594/586/594 f 586/578/586 184/165/184 376/362/376 f 586/578/586 376/362/376 585/577/585 f 590/582/590 570/562/570 569/561/569 f 590/582/590 569/561/569 588/579/588 f 61/42/61 576/569/576 578/570/578 f 61/42/61 578/570/578 507/498/507 f 585/577/585 376/362/376 493/484/493 f 585/577/585 493/484/493 584/576/584 f 453/443/453 598/590/598 73/52/73 f 453/443/453 73/52/73 430/419/430 f 519/510/519 197/179/197 247/228/247 f 519/510/519 247/228/247 246/227/246 f 281/263/281 280/262/280 146/126/146 f 281/263/281 146/126/146 145/129/145 f 64/41/64 63/40/63 121/102/121 f 64/41/64 121/102/121 185/166/185 f 284/267/284 327/309/327 528/520/528 f 284/267/284 528/520/528 292/275/292 f 290/273/290 122/99/122 121/102/121 f 290/273/290 121/102/121 63/40/63 f 280/262/280 289/271/289 320/303/320 f 280/262/280 320/303/320 146/126/146 f 184/165/184 586/578/586 594/586/594 f 184/165/184 594/586/594 185/166/185 f 253/233/253 378/363/378 117/98/117 f 253/233/253 117/98/117 120/97/120 f 249/229/249 140/121/140 160/140/160 f 249/229/249 160/140/160 159/139/159 f 129/110/129 160/140/160 140/121/140 f 129/110/129 140/121/140 130/107/130 f 161/145/161 132/109/132 131/108/131 f 161/145/161 131/108/131 371/354/371 f 313/297/313 318/302/318 456/446/456 f 313/297/313 456/446/456 527/519/527 f 492/483/492 65/46/65 534/526/534 f 492/483/492 534/526/534 538/530/538 f 441/431/441 449/438/449 448/437/448 f 441/431/441 448/437/448 442/432/442 f 443/436/443 446/435/446 435/428/435 f 443/436/443 435/428/435 497/488/497 f 446/435/446 445/434/445 506/497/506 f 446/435/446 506/497/506 494/485/494 f 441/431/441 440/429/440 436/425/436 f 441/431/441 436/425/436 494/485/494 f 596/587/596 439/430/439 442/432/442 f 596/587/596 442/432/442 597/589/597 f 577/568/577 576/569/576 61/42/61 f 577/568/577 61/42/61 64/41/64 f 238/219/238 237/218/237 242/222/242 f 238/219/238 242/222/242 241/221/241 f 194/175/194 76/53/76 426/417/426 f 194/175/194 426/417/426 427/416/427 f 452/442/452 194/175/194 427/416/427 f 452/442/452 427/416/427 428/418/428 f 461/452/461 244/225/244 243/224/243 f 461/452/461 243/224/243 342/328/342 f 508/499/508 507/498/507 578/570/578 f 508/499/508 578/570/578 579/571/579 f 245/226/245 207/187/207 531/523/531 f 245/226/245 531/523/531 518/509/518 f 206/186/206 532/524/532 531/523/531 f 206/186/206 531/523/531 207/187/207 f 32/9/32 31/12/31 600/591/600 f 32/9/32 600/591/600 599/592/599 f 601/593/601 600/591/600 36/13/36 f 601/593/601 36/13/36 24/1/24 f 602/594/602 601/593/601 24/1/24 f 602/594/602 24/1/24 23/4/23 f 40/17/40 602/594/602 23/4/23 f 40/17/40 23/4/23 42/19/42 f 44/22/44 604/595/604 605/596/605 f 44/22/44 605/596/605 603/597/603 f 39/16/39 603/597/603 602/594/602 f 39/16/39 602/594/602 40/17/40 f 601/593/601 606/598/606 607/599/607 f 601/593/601 607/599/607 600/591/600 f 468/459/468 608/600/608 609/601/609 f 468/459/468 609/601/609 469/460/469 f 477/469/477 609/601/609 608/600/608 f 477/469/477 608/600/608 384/370/384 f 610/602/610 611/603/611 612/604/612 f 610/602/610 612/604/612 472/605/472 f 610/602/610 472/605/472 471/606/471 f 610/602/610 471/606/471 613/607/613 f 476/608/476 614/609/614 615/610/615 f 476/608/476 615/610/615 474/611/474 f 478/468/478 110/88/110 109/87/109 f 478/468/478 109/87/109 616/612/616 f 466/456/466 465/455/465 474/467/474 f 466/456/466 474/467/474 617/613/617 f 466/456/466 617/613/617 473/464/473 f 466/456/466 473/464/473 350/333/350 f 614/609/614 533/614/533 470/615/470 f 614/609/614 470/615/470 618/616/618 f 475/465/475 413/405/413 533/525/533 f 475/465/475 533/525/533 476/466/476 f 618/616/618 469/617/469 609/618/609 f 618/616/618 609/618/609 619/619/619 f 619/619/619 609/618/609 477/620/477 f 619/619/619 477/620/477 620/621/620 f 387/373/387 621/622/621 616/612/616 f 387/373/387 616/612/616 109/87/109 f 616/623/616 622/624/622 620/621/620 f 616/623/616 620/621/620 478/625/478 f 473/626/473 617/627/617 615/610/615 f 473/626/473 615/610/615 613/607/613 f 621/628/621 623/629/623 622/624/622 f 621/628/621 622/624/622 616/623/616 f 624/630/624 612/604/612 611/603/611 f 624/630/624 611/603/611 623/629/623 f 49/30/49 71/48/71 70/47/70 f 49/30/49 70/47/70 50/27/50 f 336/319/336 335/322/335 524/516/524 f 336/319/336 524/516/524 418/407/418 f 598/590/598 293/276/293 67/44/67 f 598/590/598 67/44/67 73/52/73 f 50/27/50 70/47/70 429/420/429 f 50/27/50 429/420/429 74/51/74 f 322/308/322 493/484/493 376/362/376 f 322/308/322 376/362/376 323/305/323 f 589/580/589 593/585/593 592/584/592 f 589/580/589 592/584/592 587/581/587 f 396/381/396 119/96/119 118/95/118 f 396/381/396 118/95/118 254/235/254 f 517/508/517 397/382/397 396/381/396 f 517/508/517 396/381/396 254/235/254 f 28/5/28 27/8/27 625/631/625 f 28/5/28 625/631/625 604/595/604 f 600/591/600 607/599/607 626/632/626 f 600/591/600 626/632/626 599/592/599 f 607/599/607 627/633/627 628/634/628 f 607/599/607 628/634/628 626/632/626 f 604/595/604 625/631/625 628/634/628 f 604/595/604 628/634/628 627/633/627 f 630/635/630 631/636/631 632/637/632 f 630/635/630 632/637/632 629/638/629 f 634/639/634 635/640/635 636/641/636 f 634/639/634 636/641/636 633/642/633 f 638/643/638 639/644/639 640/645/640 f 638/643/638 640/645/640 637/646/637 f 641/647/641 642/648/642 637/646/637 f 641/647/641 637/646/637 640/645/640 f 644/649/644 645/650/645 646/651/646 f 644/649/644 646/651/646 643/652/643 f 631/636/631 642/648/642 648/653/648 f 631/636/631 648/653/648 647/654/647 f 650/655/650 651/656/651 652/657/652 f 650/655/650 652/657/652 649/658/649 f 643/652/643 646/651/646 654/659/654 f 643/652/643 654/659/654 653/660/653 f 654/659/654 651/656/651 650/655/650 f 654/659/654 650/655/650 653/660/653 f 655/661/655 656/662/656 657/663/657 f 655/661/655 657/663/657 632/637/632 f 657/663/657 659/664/659 660/665/660 f 657/663/657 660/665/660 658/666/658 f 661/667/661 659/664/659 657/663/657 f 661/667/661 657/663/657 656/662/656 f 631/636/631 647/654/647 655/661/655 f 631/636/631 655/661/655 632/637/632 f 637/646/637 642/648/642 631/636/631 f 637/646/637 631/636/631 630/635/630 f 640/645/640 650/655/650 649/658/649 f 640/645/640 649/658/649 641/647/641 f 652/657/652 662/668/662 641/647/641 f 652/657/652 641/647/641 649/658/649 f 648/653/648 642/648/642 641/647/641 f 648/653/648 641/647/641 662/668/662 f 663/669/663 664/670/664 537/529/537 f 663/669/663 537/529/537 536/528/536 f 666/671/666 640/645/640 639/644/639 f 666/671/666 639/644/639 665/672/665 f 666/671/666 665/672/665 636/641/636 f 666/671/666 636/641/636 635/640/635 f 667/673/667 539/531/539 537/529/537 f 667/673/667 537/529/537 664/670/664 f 634/639/634 644/649/644 643/652/643 f 634/639/634 643/652/643 635/640/635 f 653/660/653 650/655/650 640/645/640 f 653/660/653 640/645/640 666/671/666 f 666/671/666 635/640/635 643/652/643 f 666/671/666 643/652/643 653/660/653 f 669/674/669 644/649/644 634/639/634 f 669/674/669 634/639/634 668/675/668 f 638/643/638 637/646/637 630/635/630 f 638/643/638 630/635/630 670/676/670 f 645/650/645 644/649/644 669/674/669 f 645/650/645 669/674/669 671/677/671 f 638/643/638 670/676/670 485/475/485 f 638/643/638 485/475/485 484/478/484 f 672/678/672 633/642/633 489/479/489 f 672/678/672 489/479/489 488/480/488 f 632/637/632 657/663/657 658/666/658 f 632/637/632 658/666/658 629/638/629 f 670/676/670 663/669/663 536/528/536 f 670/676/670 536/528/536 485/475/485 f 633/642/633 636/641/636 534/526/534 f 633/642/633 534/526/534 489/479/489 f 484/478/484 535/527/535 639/644/639 f 484/478/484 639/644/639 638/643/638 f 629/638/629 658/666/658 664/670/664 f 629/638/629 664/670/664 663/669/663 f 665/672/665 639/644/639 535/527/535 f 665/672/665 535/527/535 538/530/538 f 636/641/636 665/672/665 538/530/538 f 636/641/636 538/530/538 534/526/534 f 660/665/660 667/673/667 664/670/664 f 660/665/660 664/670/664 658/666/658 f 668/675/668 634/639/634 633/642/633 f 668/675/668 633/642/633 672/678/672 f 630/635/630 629/638/629 663/669/663 f 630/635/630 663/669/663 670/676/670 f 1/679/1 661/667/661 656/662/656 f 1/679/1 656/662/656 22/680/22 f 20/681/20 647/654/647 648/653/648 f 20/681/20 648/653/648 18/682/18 f 647/654/647 20/681/20 21/683/21 f 647/654/647 21/683/21 655/661/655 f 15/684/15 646/651/646 645/650/645 f 15/684/15 645/650/645 13/685/13 f 19/686/19 651/656/651 654/659/654 f 19/686/19 654/659/654 14/687/14 f 648/653/648 662/668/662 16/688/16 f 648/653/648 16/688/16 18/682/18 f 17/689/17 652/657/652 651/656/651 f 17/689/17 651/656/651 19/686/19 f 21/683/21 22/680/22 656/662/656 f 21/683/21 656/662/656 655/661/655 f 13/685/13 645/650/645 671/677/671 f 13/685/13 671/677/671 2/690/2 f 646/651/646 15/684/15 14/687/14 f 646/651/646 14/687/14 654/659/654 f 17/689/17 16/688/16 662/668/662 f 17/689/17 662/668/662 652/657/652 f 608/600/608 91/68/91 385/371/385 f 608/600/608 385/371/385 384/370/384 f 304/286/304 372/355/372 401/387/401 f 304/286/304 401/387/401 308/290/308 f 468/459/468 415/404/415 411/401/411 f 468/459/468 411/401/411 92/69/92 f 602/594/602 603/597/603 606/598/606 f 602/594/602 606/598/606 601/593/601 f 608/600/608 468/459/468 92/69/92 f 608/600/608 92/69/92 91/68/91 f 305/287/305 304/286/304 308/290/308 f 305/287/305 308/290/308 137/116/137 f 139/119/139 138/117/138 307/291/307 f 139/119/139 307/291/307 375/361/375 f 674/691/674 675/692/675 676/693/676 f 674/691/674 676/693/676 673/694/673 f 678/695/678 27/8/27 679/696/679 f 678/695/678 679/696/679 677/697/677 f 681/698/681 682/699/682 683/700/683 f 681/698/681 683/700/683 680/701/680 f 684/702/684 685/703/685 683/700/683 f 684/702/684 683/700/683 682/699/682 f 684/702/684 674/691/674 673/694/673 f 684/702/684 673/694/673 685/703/685 f 687/704/687 688/705/688 689/706/689 f 687/704/687 689/706/689 686/707/686 f 690/708/690 691/709/691 676/693/676 f 690/708/690 676/693/676 675/692/675 f 689/706/689 688/705/688 691/709/691 f 689/706/689 691/709/691 690/708/690 f 687/704/687 686/707/686 693/710/693 f 687/704/687 693/710/693 692/711/692 f 681/698/681 680/701/680 46/24/46 f 681/698/681 46/24/46 45/23/45 f 678/695/678 694/712/694 695/713/695 f 678/695/678 695/713/695 693/710/693 f 697/714/697 698/715/698 699/716/699 f 697/714/697 699/716/699 696/717/696 f 701/718/701 702/719/702 703/720/703 f 701/718/701 703/720/703 700/721/700 f 705/722/705 706/723/706 707/724/707 f 705/722/705 707/724/707 704/725/704 f 709/726/709 710/727/710 711/728/711 f 709/726/709 711/728/711 708/729/708 f 713/730/713 714/731/714 715/732/715 f 713/730/713 715/732/715 712/733/712 f 717/734/717 718/735/718 719/736/719 f 717/734/717 719/736/719 716/737/716 f 712/733/712 720/738/720 721/739/721 f 712/733/712 721/739/721 713/730/713 f 713/730/713 721/739/721 697/714/697 f 713/730/713 697/714/697 696/717/696 f 723/740/723 724/741/724 725/742/725 f 723/740/723 725/742/725 722/743/722 f 727/744/727 728/745/728 729/746/729 f 727/744/727 729/746/729 726/747/726 f 731/748/731 732/749/732 733/750/733 f 731/748/731 733/750/733 730/751/730 f 735/752/735 728/745/728 727/744/727 f 735/752/735 727/744/727 734/753/734 f 737/754/737 738/755/738 739/756/739 f 737/754/737 739/756/739 736/757/736 f 741/758/741 722/743/722 725/742/725 f 741/758/741 725/742/725 740/759/740 f 735/752/735 734/753/734 743/760/743 f 735/752/735 743/760/743 742/761/742 f 745/762/745 746/763/746 747/764/747 f 745/762/745 747/764/747 744/765/744 f 747/764/747 746/763/746 749/766/749 f 747/764/747 749/766/749 748/767/748 f 745/762/745 744/765/744 751/768/751 f 745/762/745 751/768/751 750/769/750 f 753/770/753 754/771/754 755/772/755 f 753/770/753 755/772/755 752/773/752 f 757/774/757 755/772/755 754/771/754 f 757/774/757 754/771/754 756/775/756 f 748/767/748 749/766/749 759/776/759 f 748/767/748 759/776/759 758/777/758 f 761/778/761 762/779/762 763/780/763 f 761/778/761 763/780/763 760/781/760 f 765/782/765 766/783/766 767/784/767 f 765/782/765 767/784/767 764/785/764 f 769/786/769 770/787/770 771/788/771 f 769/786/769 771/788/771 768/789/768 f 773/790/773 774/791/774 775/792/775 f 773/790/773 775/792/775 772/793/772 f 777/794/777 778/795/778 779/796/779 f 777/794/777 779/796/779 776/797/776 f 774/791/774 780/798/780 781/799/781 f 774/791/774 781/799/781 775/792/775 f 703/720/703 782/800/782 783/801/783 f 703/720/703 783/801/783 700/721/700 f 688/802/688 687/803/687 785/804/785 f 688/802/688 785/804/785 784/805/784 f 786/806/786 785/804/785 687/803/687 f 786/806/786 687/803/687 692/807/692 f 788/808/788 777/794/777 789/809/789 f 788/808/788 789/809/789 787/810/787 f 790/811/790 791/812/791 779/796/779 f 790/811/790 779/796/779 778/795/778 f 793/813/793 794/814/794 795/815/795 f 793/813/793 795/815/795 792/816/792 f 797/817/797 798/818/798 701/718/701 f 797/817/797 701/718/701 796/819/796 f 701/718/701 798/818/798 799/820/799 f 701/718/701 799/820/799 702/719/702 f 801/821/801 802/822/802 803/823/803 f 801/821/801 803/823/803 800/824/800 f 805/825/805 806/826/806 807/827/807 f 805/825/805 807/827/807 804/828/804 f 809/829/809 810/830/810 811/831/811 f 809/829/809 811/831/811 808/832/808 f 778/795/778 807/827/807 806/826/806 f 778/795/778 806/826/806 790/811/790 f 803/823/803 812/833/812 813/834/813 f 803/823/803 813/834/813 800/824/800 f 815/835/815 816/836/816 817/837/817 f 815/835/815 817/837/817 814/838/814 f 819/839/819 814/838/814 820/840/820 f 819/839/819 820/840/820 818/841/818 f 822/842/822 823/843/823 819/839/819 f 822/842/822 819/839/819 821/844/821 f 704/725/704 707/724/707 825/845/825 f 704/725/704 825/845/825 824/846/824 f 827/847/827 828/848/828 698/715/698 f 827/847/827 698/715/698 826/849/826 f 772/793/772 775/792/775 829/850/829 f 772/793/772 829/850/829 699/716/699 f 781/799/781 771/788/771 831/851/831 f 781/799/781 831/851/831 830/852/830 f 832/853/832 831/851/831 771/788/771 f 832/853/832 771/788/771 770/787/770 f 834/854/834 835/855/835 836/856/836 f 834/854/834 836/856/836 833/857/833 f 838/858/838 839/859/839 840/860/840 f 838/858/838 840/860/840 837/861/837 f 723/740/723 722/743/722 840/860/840 f 723/740/723 840/860/840 841/862/841 f 747/764/747 842/863/842 843/864/843 f 747/764/747 843/864/843 744/765/744 f 821/844/821 844/865/844 845/866/845 f 821/844/821 845/866/845 822/842/822 f 847/867/847 818/841/818 820/840/820 f 847/867/847 820/840/820 846/868/846 f 843/864/843 849/869/849 850/870/850 f 843/864/843 850/870/850 848/871/848 f 205/185/205 851/872/851 852/873/852 f 205/185/205 852/873/852 206/186/206 f 208/189/208 849/869/849 851/872/851 f 208/189/208 851/872/851 205/185/205 f 853/874/853 854/875/854 749/766/749 f 853/874/853 749/766/749 746/763/746 f 728/745/728 735/752/735 854/875/854 f 728/745/728 854/875/854 853/874/853 f 856/876/856 857/877/857 858/878/858 f 856/876/856 858/878/858 855/879/855 f 860/880/860 861/881/861 862/882/862 f 860/880/860 862/882/862 859/883/859 f 863/884/863 864/885/864 861/881/861 f 863/884/863 861/881/861 860/880/860 f 866/886/866 867/887/867 862/882/862 f 866/886/866 862/882/862 865/888/865 f 869/889/869 870/890/870 871/891/871 f 869/889/869 871/891/871 868/892/868 f 866/886/866 228/210/228 229/209/229 f 866/886/866 229/209/229 867/887/867 f 873/893/873 864/885/864 863/884/863 f 873/893/873 863/884/863 872/894/872 f 871/891/871 873/893/873 872/894/872 f 871/891/871 872/894/872 868/892/868 f 875/895/875 876/896/876 877/897/877 f 875/895/875 877/897/877 874/898/874 f 835/855/835 834/854/834 848/871/848 f 835/855/835 848/871/848 850/870/850 f 879/899/879 833/857/833 880/900/880 f 879/899/879 880/900/880 878/901/878 f 882/902/882 883/903/883 884/904/884 f 882/902/882 884/904/884 881/905/881 f 881/905/881 880/900/880 886/906/886 f 881/905/881 886/906/886 885/907/885 f 887/908/887 842/863/842 747/764/747 f 887/908/887 747/764/747 748/767/748 f 842/863/842 887/908/887 852/873/852 f 842/863/842 852/873/852 851/872/851 f 758/777/758 760/781/760 889/909/889 f 758/777/758 889/909/889 888/910/888 f 787/810/787 890/911/890 891/912/891 f 787/810/787 891/912/891 788/808/788 f 893/913/893 894/914/894 895/915/895 f 893/913/893 895/915/895 892/916/892 f 896/917/896 859/883/859 897/918/897 f 896/917/896 897/918/897 765/782/765 f 899/919/899 900/920/900 901/921/901 f 899/919/899 901/921/901 898/922/898 f 900/920/900 902/923/902 903/924/903 f 900/920/900 903/924/903 901/921/901 f 902/923/902 677/925/677 679/926/679 f 902/923/902 679/926/679 903/924/903 f 862/882/862 867/887/867 904/927/904 f 862/882/862 904/927/904 859/883/859 f 901/921/901 263/247/263 264/246/264 f 901/921/901 264/246/264 898/922/898 f 266/248/266 265/249/265 903/924/903 f 266/248/266 903/924/903 679/926/679 f 895/915/895 905/928/905 906/929/906 f 895/915/895 906/929/906 892/916/892 f 907/930/907 908/931/908 909/932/909 f 907/930/907 909/932/909 846/868/846 f 847/867/847 846/868/846 909/932/909 f 847/867/847 909/932/909 910/933/910 f 847/867/847 910/933/910 912/934/912 f 847/867/847 912/934/912 911/935/911 f 276/258/276 275/259/275 906/929/906 f 276/258/276 906/929/906 905/928/905 f 275/259/275 277/260/277 908/931/908 f 275/259/275 908/931/908 906/929/906 f 741/758/741 837/861/837 840/860/840 f 741/758/741 840/860/840 722/743/722 f 914/936/914 915/937/915 916/938/916 f 914/936/914 916/938/916 913/939/913 f 915/937/915 914/936/914 743/760/743 f 915/937/915 743/760/743 734/753/734 f 918/940/918 740/759/740 709/726/709 f 918/940/918 709/726/709 917/941/917 f 916/938/916 915/937/915 920/942/920 f 916/938/916 920/942/920 919/943/919 f 922/944/922 923/945/923 924/946/924 f 922/944/922 924/946/924 921/947/921 f 708/729/708 925/948/925 917/941/917 f 708/729/708 917/941/917 709/726/709 f 917/941/917 925/948/925 927/949/927 f 917/941/917 927/949/927 926/950/926 f 293/276/293 712/733/712 715/732/715 f 293/276/293 715/732/715 294/277/294 f 929/951/929 930/952/930 931/953/931 f 929/951/929 931/953/931 928/954/928 f 933/955/933 934/956/934 935/957/935 f 933/955/933 935/957/935 932/958/932 f 937/959/937 938/960/938 939/961/939 f 937/959/937 939/961/939 936/962/936 f 785/804/785 940/963/940 941/964/941 f 785/804/785 941/964/941 784/805/784 f 812/833/812 943/965/943 944/966/944 f 812/833/812 944/966/944 942/967/942 f 945/968/945 796/819/796 701/718/701 f 945/968/945 701/718/701 700/721/700 f 946/969/946 947/970/947 797/817/797 f 946/969/946 797/817/797 796/819/796 f 949/971/949 873/893/873 871/891/871 f 949/971/949 871/891/871 948/972/948 f 783/801/783 806/826/806 805/825/805 f 783/801/783 805/825/805 950/973/950 f 951/974/951 952/975/952 792/816/792 f 951/974/951 792/816/792 795/815/795 f 954/976/954 793/813/793 792/816/792 f 954/976/954 792/816/792 953/977/953 f 956/978/956 957/979/957 958/980/958 f 956/978/956 958/980/958 955/981/955 f 727/744/727 920/942/920 915/937/915 f 727/744/727 915/937/915 734/753/734 f 959/982/959 960/983/960 795/815/795 f 959/982/959 795/815/795 794/814/794 f 914/936/914 913/939/913 924/946/924 f 914/936/914 924/946/924 923/945/923 f 329/984/329 961/985/961 962/986/962 f 329/984/329 962/986/962 330/987/330 f 834/854/834 963/988/963 751/768/751 f 834/854/834 751/768/751 848/871/848 f 879/899/879 839/859/839 838/858/838 f 879/899/879 838/858/838 963/988/963 f 812/833/812 942/967/942 964/989/964 f 812/833/812 964/989/964 813/834/813 f 786/806/786 692/807/692 695/990/695 f 786/806/786 695/990/695 965/991/965 f 967/992/967 968/993/968 969/994/969 f 967/992/967 969/994/969 966/995/966 f 696/717/696 699/716/699 829/850/829 f 696/717/696 829/850/829 955/981/955 f 970/996/970 703/720/703 702/719/702 f 970/996/970 702/719/702 773/790/773 f 972/997/972 799/820/799 798/818/798 f 972/997/972 798/818/798 971/998/971 f 885/907/885 342/999/342 344/1000/344 f 885/907/885 344/1000/344 973/1001/973 f 974/1002/974 975/1003/975 882/902/882 f 974/1002/974 882/902/882 973/1001/973 f 977/1004/977 978/1005/978 979/1006/979 f 977/1004/977 979/1006/979 976/1007/976 f 981/1008/981 856/876/856 855/879/855 f 981/1008/981 855/879/855 980/1009/980 f 775/792/775 781/799/781 830/852/830 f 775/792/775 830/852/830 829/850/829 f 750/769/750 982/1010/982 983/1011/983 f 750/769/750 983/1011/983 745/762/745 f 761/778/761 984/1012/984 985/1013/985 f 761/778/761 985/1013/985 762/779/762 f 986/1014/986 987/1015/987 845/866/845 f 986/1014/986 845/866/845 844/865/844 f 752/773/752 755/772/755 989/1016/989 f 752/773/752 989/1016/989 988/1017/988 f 977/1004/977 976/1007/976 991/1018/991 f 977/1004/977 991/1018/991 990/1019/990 f 978/1005/978 977/1004/977 874/898/874 f 978/1005/978 874/898/874 992/1020/992 f 863/884/863 993/1021/993 816/836/816 f 863/884/863 816/836/816 872/894/872 f 802/822/802 995/1022/995 933/955/933 f 802/822/802 933/955/933 994/1023/994 f 930/952/930 929/951/929 716/737/716 f 930/952/930 716/737/716 719/736/719 f 828/848/828 827/847/827 996/1024/996 f 828/848/828 996/1024/996 970/996/970 f 998/1025/998 950/973/950 805/825/805 f 998/1025/998 805/825/805 997/1026/997 f 950/973/950 945/968/945 700/721/700 f 950/973/950 700/721/700 783/801/783 f 1000/1027/1000 1001/1028/1001 1002/1029/1002 f 1000/1027/1000 1002/1029/1002 999/1030/999 f 691/1031/691 936/962/936 939/961/939 f 691/1031/691 939/961/939 676/1032/676 f 936/962/936 691/1031/691 688/802/688 f 936/962/936 688/802/688 784/805/784 f 890/911/890 787/810/787 1004/1033/1004 f 890/911/890 1004/1033/1004 1003/1034/1003 f 713/730/713 696/717/696 955/981/955 f 713/730/713 955/981/955 958/980/958 f 830/852/830 831/851/831 1005/1035/1005 f 830/852/830 1005/1035/1005 956/978/956 f 1006/1036/1006 1007/1037/1007 905/928/905 f 1006/1036/1006 905/928/905 895/915/895 f 908/931/908 277/260/277 379/365/379 f 908/931/908 379/365/379 909/932/909 f 1009/1038/1009 1010/1039/1010 1011/1040/1011 f 1009/1038/1009 1011/1040/1011 1008/1041/1008 f 1013/1042/1013 756/775/756 754/771/754 f 1013/1042/1013 754/771/754 1012/1043/1012 f 754/771/754 753/770/753 1014/1044/1014 f 754/771/754 1014/1044/1014 1012/1043/1012 f 989/1016/989 755/772/755 757/774/757 f 989/1016/989 757/774/757 1015/1045/1015 f 826/849/826 808/832/808 811/831/811 f 826/849/826 811/831/811 827/847/827 f 995/1022/995 802/822/802 801/821/801 f 995/1022/995 801/821/801 1016/1046/1016 f 815/835/815 868/892/868 872/894/872 f 815/835/815 872/894/872 816/836/816 f 726/747/726 918/940/918 917/941/917 f 726/747/726 917/941/917 926/950/926 f 910/933/910 909/932/909 379/365/379 f 910/933/910 379/365/379 389/375/389 f 912/934/912 910/933/910 389/375/389 f 912/934/912 389/375/389 390/376/390 f 786/806/786 965/991/965 1003/1034/1003 f 786/806/786 1003/1034/1003 1004/1033/1004 f 1017/1047/1017 803/823/803 802/822/802 f 1017/1047/1017 802/822/802 994/1023/994 f 1019/1048/1019 1017/1047/1017 994/1023/994 f 1019/1048/1019 994/1023/994 1018/1049/1018 f 820/840/820 1020/1050/1020 907/930/907 f 820/840/820 907/930/907 846/868/846 f 932/958/932 1018/1049/1018 994/1023/994 f 932/958/932 994/1023/994 933/955/933 f 1022/1051/1022 1023/1052/1023 1024/1053/1024 f 1022/1051/1022 1024/1053/1024 1021/1054/1021 f 1025/1055/1025 817/837/817 816/836/816 f 1025/1055/1025 816/836/816 993/1021/993 f 1020/1050/1020 817/837/817 1025/1055/1025 f 1020/1050/1020 1025/1055/1025 893/913/893 f 907/930/907 1020/1050/1020 893/913/893 f 907/930/907 893/913/893 892/916/892 f 749/766/749 854/875/854 1026/1056/1026 f 749/766/749 1026/1056/1026 759/776/759 f 776/797/776 1000/1027/1000 999/1030/999 f 776/797/776 999/1030/999 1027/1057/1027 f 1017/1047/1017 943/965/943 812/833/812 f 1017/1047/1017 812/833/812 803/823/803 f 1028/1058/1028 1029/1059/1029 405/390/405 f 1028/1058/1028 405/390/405 404/389/404 f 1029/1059/1029 943/965/943 1017/1047/1017 f 1029/1059/1029 1017/1047/1017 1019/1048/1019 f 685/1060/685 673/1061/673 964/989/964 f 685/1060/685 964/989/964 942/967/942 f 685/1060/685 942/967/942 944/966/944 f 685/1060/685 944/966/944 683/1062/683 f 683/1062/683 944/966/944 1028/1058/1028 f 683/1062/683 1028/1058/1028 680/1063/680 f 1030/1064/1030 897/918/897 859/883/859 f 1030/1064/1030 859/883/859 904/927/904 f 1007/1037/1007 1030/1064/1030 408/398/408 f 1007/1037/1007 408/398/408 407/397/407 f 766/783/766 765/782/765 897/918/897 f 766/783/766 897/918/897 1006/1036/1006 f 907/930/907 892/916/892 906/929/906 f 907/930/907 906/929/906 908/931/908 f 937/959/937 999/1030/999 1002/1029/1002 f 937/959/937 1002/1029/1002 938/960/938 f 991/1018/991 976/1007/976 1032/1065/1032 f 991/1018/991 1032/1065/1032 1031/1066/1031 f 1034/1067/1034 739/756/739 738/755/738 f 1034/1067/1034 738/755/738 1033/1068/1033 f 1035/1069/1035 1036/1070/1036 1037/1071/1037 f 1035/1069/1035 1037/1071/1037 1034/1067/1034 f 1038/1072/1038 416/408/416 418/407/418 f 1038/1072/1038 418/407/418 967/992/967 f 966/995/966 719/736/719 718/735/718 f 966/995/966 718/735/718 1039/1073/1039 f 1041/1074/1041 1042/1075/1042 1043/1076/1043 f 1041/1074/1041 1043/1076/1043 1040/1077/1040 f 1041/1074/1041 1040/1077/1040 1045/1078/1045 f 1041/1074/1041 1045/1078/1045 1044/1079/1044 f 1043/1076/1043 1046/1080/1046 1047/1081/1047 f 1043/1076/1043 1047/1081/1047 1040/1077/1040 f 883/903/883 1045/1078/1045 1048/1082/1048 f 883/903/883 1048/1082/1048 884/904/884 f 1049/1083/1049 1050/1084/1050 721/739/721 f 1049/1083/1049 721/739/721 720/738/720 f 717/734/717 1050/1084/1050 1039/1073/1039 f 717/734/717 1039/1073/1039 718/735/718 f 889/909/889 760/781/760 763/780/763 f 889/909/889 763/780/763 1051/1085/1051 f 974/1002/974 1052/1086/1052 1053/1087/1053 f 974/1002/974 1053/1087/1053 975/1003/975 f 1053/1087/1053 1054/1088/1054 1042/1075/1042 f 1053/1087/1053 1042/1075/1042 1041/1074/1041 f 1056/1089/1056 1057/1090/1057 1058/1091/1058 f 1056/1089/1056 1058/1091/1058 1055/1092/1055 f 1055/1092/1055 1058/1091/1058 1010/1039/1010 f 1055/1092/1055 1010/1039/1010 1009/1038/1009 f 825/845/825 1059/1093/1059 1060/1094/1060 f 825/845/825 1060/1094/1060 824/846/824 f 1060/1094/1060 1059/1093/1059 1062/1095/1062 f 1060/1094/1060 1062/1095/1062 1061/1096/1061 f 444/1097/444 443/1098/443 1064/1099/1064 f 444/1097/444 1064/1099/1064 1063/1100/1063 f 955/981/955 829/850/829 830/852/830 f 955/981/955 830/852/830 956/978/956 f 855/879/855 845/866/845 987/1015/987 f 855/879/855 987/1015/987 980/1009/980 f 858/878/858 869/889/869 823/843/823 f 858/878/858 823/843/823 822/842/822 f 1066/1101/1066 1067/1102/1067 1068/1103/1068 f 1066/1101/1066 1068/1103/1068 1065/1104/1065 f 1043/1076/1043 1067/1102/1067 1069/1105/1069 f 1043/1076/1043 1069/1105/1069 1046/1080/1046 f 724/741/724 723/740/723 1046/1080/1046 f 724/741/724 1046/1080/1046 1069/1105/1069 f 725/742/725 710/727/710 709/726/709 f 725/742/725 709/726/709 740/759/740 f 923/945/923 922/944/922 730/751/730 f 923/945/923 730/751/730 733/750/733 f 742/761/742 1026/1056/1026 854/875/854 f 742/761/742 854/875/854 735/752/735 f 878/901/878 884/904/884 1048/1082/1048 f 878/901/878 1048/1082/1048 1070/1106/1070 f 839/859/839 1070/1106/1070 841/862/841 f 839/859/839 841/862/841 840/860/840 f 878/901/878 1070/1106/1070 839/859/839 f 878/901/878 839/859/839 879/899/879 f 728/745/728 853/874/853 983/1011/983 f 728/745/728 983/1011/983 729/746/729 f 923/945/923 733/750/733 743/760/743 f 923/945/923 743/760/743 914/936/914 f 1049/1083/1049 453/443/453 416/408/416 f 1049/1083/1049 416/408/416 1038/1072/1038 f 969/994/969 934/956/934 931/953/931 f 969/994/969 931/953/931 930/952/930 f 706/723/706 1071/1107/1071 1072/1108/1072 f 706/723/706 1072/1108/1072 707/724/707 f 856/876/856 981/1008/981 1074/1109/1074 f 856/876/856 1074/1109/1074 1073/1110/1073 f 732/749/732 731/748/731 985/1013/985 f 732/749/732 985/1013/985 984/1012/984 f 789/809/789 940/963/940 1004/1033/1004 f 789/809/789 1004/1033/1004 787/810/787 f 1027/1057/1027 941/964/941 940/963/940 f 1027/1057/1027 940/963/940 789/809/789 f 1075/1111/1075 1076/1112/1076 900/920/900 f 1075/1111/1075 900/920/900 899/919/899 f 228/210/228 866/886/866 898/922/898 f 228/210/228 898/922/898 264/246/264 f 900/920/900 1076/1112/1076 1077/1113/1077 f 900/920/900 1077/1113/1077 902/923/902 f 1077/1113/1077 694/1114/694 677/925/677 f 1077/1113/1077 677/925/677 902/923/902 f 263/247/263 901/921/901 903/924/903 f 263/247/263 903/924/903 265/249/265 f 461/1115/461 886/906/886 836/856/836 f 461/1115/461 836/856/836 462/1116/462 f 871/891/871 870/890/870 1078/1117/1078 f 871/891/871 1078/1117/1078 948/972/948 f 1080/1118/1080 1081/1119/1081 1032/1065/1032 f 1080/1118/1080 1032/1065/1032 1079/1120/1079 f 737/754/737 736/757/736 1012/1043/1012 f 737/754/737 1012/1043/1012 1014/1044/1014 f 875/895/875 874/898/874 977/1004/977 f 875/895/875 977/1004/977 990/1019/990 f 877/897/877 1082/1121/1082 992/1020/992 f 877/897/877 992/1020/992 874/898/874 f 969/994/969 930/952/930 719/736/719 f 969/994/969 719/736/719 966/995/966 f 969/994/969 968/993/968 935/957/935 f 969/994/969 935/957/935 934/956/934 f 1084/1122/1084 1037/1071/1037 1085/1123/1085 f 1084/1122/1084 1085/1123/1085 1083/1124/1083 f 978/1005/978 992/1020/992 1087/1125/1087 f 978/1005/978 1087/1125/1087 1086/1126/1086 f 1086/1126/1086 1088/1127/1088 979/1006/979 f 1086/1126/1086 979/1006/979 978/1005/978 f 1080/1118/1080 1090/1128/1090 1091/1129/1091 f 1080/1118/1080 1091/1129/1091 1089/1130/1089 f 1013/1042/1013 1092/1131/1092 1093/1132/1093 f 1013/1042/1013 1093/1132/1093 756/775/756 f 1035/1069/1035 1034/1067/1034 1033/1068/1033 f 1035/1069/1035 1033/1068/1033 1094/1133/1094 f 921/947/921 1094/1133/1094 1033/1068/1033 f 921/947/921 1033/1068/1033 922/944/922 f 730/751/730 738/755/738 737/754/737 f 730/751/730 737/754/737 731/748/731 f 1014/1044/1014 753/770/753 762/779/762 f 1014/1044/1014 762/779/762 985/1013/985 f 876/896/876 875/895/875 987/1015/987 f 876/896/876 987/1015/987 986/1014/986 f 928/954/928 808/832/808 826/849/826 f 928/954/928 826/849/826 929/951/929 f 1039/1073/1039 1038/1072/1038 967/992/967 f 1039/1073/1039 967/992/967 966/995/966 f 698/715/698 828/848/828 772/793/772 f 698/715/698 772/793/772 699/716/699 f 676/1032/676 939/961/939 964/989/964 f 676/1032/676 964/989/964 673/1061/673 f 1000/1027/1000 810/830/810 809/829/809 f 1000/1027/1000 809/829/809 1001/1028/1001 f 898/922/898 866/886/866 865/888/865 f 898/922/898 865/888/865 899/919/899 f 899/919/899 865/888/865 1095/1134/1095 f 899/919/899 1095/1134/1095 1075/1111/1075 f 857/877/857 870/890/870 869/889/869 f 857/877/857 869/889/869 858/878/858 f 948/972/948 1078/1117/1078 946/969/946 f 948/972/948 946/969/946 1096/1135/1096 f 819/839/819 823/843/823 815/835/815 f 819/839/819 815/835/815 814/838/814 f 911/935/911 1097/1136/1097 818/841/818 f 911/935/911 818/841/818 847/867/847 f 815/835/815 823/843/823 869/889/869 f 815/835/815 869/889/869 868/892/868 f 887/908/887 748/767/748 758/777/758 f 887/908/887 758/777/758 888/910/888 f 761/778/761 760/781/760 758/777/758 f 761/778/761 758/777/758 759/776/759 f 853/874/853 746/763/746 745/762/745 f 853/874/853 745/762/745 983/1011/983 f 1051/1085/1051 988/1017/988 876/896/876 f 1051/1085/1051 876/896/876 986/1014/986 f 877/897/877 876/896/876 988/1017/988 f 877/897/877 988/1017/988 989/1016/989 f 989/1016/989 1015/1045/1015 1082/1121/1082 f 989/1016/989 1082/1121/1082 877/897/877 f 726/747/726 729/746/729 1098/1137/1098 f 726/747/726 1098/1137/1098 918/940/918 f 1100/1138/1100 1101/1139/1101 1102/1140/1102 f 1100/1138/1100 1102/1140/1102 1099/1141/1099 f 1103/1142/1103 488/480/488 294/277/294 f 1103/1142/1103 294/277/294 715/732/715 f 1104/1143/1104 1105/1144/1105 1072/1108/1072 f 1104/1143/1104 1072/1108/1072 1071/1107/1071 f 801/821/801 800/824/800 1002/1029/1002 f 801/821/801 1002/1029/1002 1001/1028/1001 f 1104/1143/1104 1106/1145/1106 958/980/958 f 1104/1143/1104 958/980/958 957/979/957 f 1104/1143/1104 957/979/957 1107/1146/1107 f 1104/1143/1104 1107/1146/1107 1105/1144/1105 f 1056/1089/1056 1108/1147/1108 1064/1099/1064 f 1056/1089/1056 1064/1099/1064 1057/1090/1057 f 495/1148/495 1010/1039/1010 1058/1091/1058 f 495/1148/495 1058/1091/1058 496/1149/496 f 496/1149/496 1058/1091/1058 1057/1090/1057 f 496/1149/496 1057/1090/1057 497/1150/497 f 962/986/962 1052/1086/1052 498/1151/498 f 962/986/962 498/1151/498 330/987/330 f 499/1152/499 498/1151/498 1052/1086/1052 f 499/1152/499 1052/1086/1052 974/1002/974 f 1010/1039/1010 495/1148/495 500/1153/500 f 1010/1039/1010 500/1153/500 1011/1040/1011 f 1109/1154/1109 1054/1088/1054 962/986/962 f 1109/1154/1109 962/986/962 961/985/961 f 499/1152/499 974/1002/974 973/1001/973 f 499/1152/499 973/1001/973 344/1000/344 f 1106/1145/1106 1104/1143/1104 1071/1107/1071 f 1106/1145/1106 1071/1107/1071 1110/1155/1110 f 1071/1107/1071 706/723/706 1102/1140/1102 f 1071/1107/1071 1102/1140/1102 1110/1155/1110 f 1099/1141/1099 1102/1140/1102 706/723/706 f 1099/1141/1099 706/723/706 705/722/705 f 705/722/705 1008/1041/1008 1111/1156/1111 f 705/722/705 1111/1156/1111 1099/1141/1099 f 1011/1040/1011 500/1153/500 505/1157/505 f 1011/1040/1011 505/1157/505 1112/1158/1112 f 1067/1102/1067 1043/1076/1043 1042/1075/1042 f 1067/1102/1067 1042/1075/1042 1068/1103/1068 f 329/984/329 444/1097/444 1063/1100/1063 f 329/984/329 1063/1100/1063 961/985/961 f 1068/1103/1068 1109/1154/1109 1113/1159/1113 f 1068/1103/1068 1113/1159/1113 1065/1104/1065 f 1115/1160/1115 724/741/724 1069/1105/1069 f 1115/1160/1115 1069/1105/1069 1114/1161/1114 f 744/765/744 843/864/843 848/871/848 f 744/765/744 848/871/848 751/768/751 f 509/500/509 850/870/850 849/869/849 f 509/500/509 849/869/849 208/189/208 f 849/869/849 843/864/843 842/863/842 f 849/869/849 842/863/842 851/872/851 f 462/1116/462 836/856/836 835/855/835 f 462/1116/462 835/855/835 510/501/510 f 850/870/850 509/500/509 510/501/510 f 850/870/850 510/501/510 835/855/835 f 795/815/795 960/983/960 971/998/971 f 795/815/795 971/998/971 951/974/951 f 960/983/960 1116/1162/1116 972/997/972 f 960/983/960 972/997/972 971/998/971 f 768/789/768 780/798/780 972/997/972 f 768/789/768 972/997/972 1116/1162/1116 f 716/737/716 929/951/929 826/849/826 f 716/737/716 826/849/826 698/715/698 f 801/821/801 1001/1028/1001 809/829/809 f 801/821/801 809/829/809 1016/1046/1016 f 800/824/800 813/834/813 938/960/938 f 800/824/800 938/960/938 1002/1029/1002 f 813/834/813 964/989/964 939/961/939 f 813/834/813 939/961/939 938/960/938 f 1117/1163/1117 921/947/921 924/946/924 f 1117/1163/1117 924/946/924 954/976/954 f 1094/1133/1094 1118/1164/1118 1119/1165/1119 f 1094/1133/1094 1119/1165/1119 1035/1069/1035 f 1035/1069/1035 1119/1165/1119 1089/1130/1089 f 1035/1069/1035 1089/1130/1089 1036/1070/1036 f 1118/1164/1118 1094/1133/1094 921/947/921 f 1118/1164/1118 921/947/921 1117/1163/1117 f 838/858/838 837/861/837 982/1010/982 f 838/858/838 982/1010/982 750/769/750 f 963/988/963 838/858/838 750/769/750 f 963/988/963 750/769/750 751/768/751 f 729/746/729 983/1011/983 982/1010/982 f 729/746/729 982/1010/982 1098/1137/1098 f 732/749/732 742/761/742 743/760/743 f 732/749/732 743/760/743 733/750/733 f 732/749/732 984/1012/984 1026/1056/1026 f 732/749/732 1026/1056/1026 742/761/742 f 984/1012/984 761/778/761 759/776/759 f 984/1012/984 759/776/759 1026/1056/1026 f 790/811/790 806/826/806 783/801/783 f 790/811/790 783/801/783 782/800/782 f 931/953/931 934/956/934 933/955/933 f 931/953/931 933/955/933 995/1022/995 f 931/953/931 995/1022/995 1016/1046/1016 f 931/953/931 1016/1046/1016 928/954/928 f 996/1024/996 827/847/827 811/831/811 f 996/1024/996 811/831/811 791/812/791 f 1121/1166/1121 861/881/861 864/885/864 f 1121/1166/1121 864/885/864 1120/1167/1120 f 896/917/896 1122/1168/1122 860/880/860 f 896/917/896 860/880/860 859/883/859 f 1024/1053/1024 1023/1052/1023 1025/1055/1025 f 1024/1053/1024 1025/1055/1025 993/1021/993 f 1024/1053/1024 860/880/860 1122/1168/1122 f 1024/1053/1024 1122/1168/1122 1021/1054/1021 f 1124/1169/1124 887/908/887 888/910/888 f 1124/1169/1124 888/910/888 1123/1170/1123 f 951/974/951 971/998/971 798/818/798 f 951/974/951 798/818/798 797/817/797 f 1050/1084/1050 1049/1083/1049 1038/1072/1038 f 1050/1084/1050 1038/1072/1038 1039/1073/1039 f 680/1063/680 1028/1058/1028 404/389/404 f 680/1063/680 404/389/404 46/511/46 f 1028/1058/1028 944/966/944 943/965/943 f 1028/1058/1028 943/965/943 1029/1059/1029 f 1018/1049/1018 932/958/932 521/513/521 f 1018/1049/1018 521/513/521 520/512/520 f 522/514/522 1019/1048/1019 1018/1049/1018 f 522/514/522 1018/1049/1018 520/512/520 f 935/957/935 523/515/523 521/513/521 f 935/957/935 521/513/521 932/958/932 f 935/957/935 968/993/968 524/516/524 f 935/957/935 524/516/524 523/515/523 f 953/977/953 792/816/792 952/975/952 f 953/977/953 952/975/952 1073/1110/1073 f 1073/1110/1073 1074/1109/1074 1125/1171/1125 f 1073/1110/1073 1125/1171/1125 953/977/953 f 1032/1065/1032 1081/1119/1081 1126/1172/1126 f 1032/1065/1032 1126/1172/1126 1031/1066/1031 f 1032/1065/1032 976/1007/976 979/1006/979 f 1032/1065/1032 979/1006/979 1079/1120/1079 f 1073/1110/1073 1127/1173/1127 857/877/857 f 1073/1110/1073 857/877/857 856/876/856 f 857/877/857 1127/1173/1127 1078/1117/1078 f 857/877/857 1078/1117/1078 870/890/870 f 407/397/407 276/258/276 905/928/905 f 407/397/407 905/928/905 1007/1037/1007 f 1006/1036/1006 897/918/897 1030/1064/1030 f 1006/1036/1006 1030/1064/1030 1007/1037/1007 f 822/842/822 845/866/845 855/879/855 f 822/842/822 855/879/855 858/878/858 f 1014/1044/1014 985/1013/985 731/748/731 f 1014/1044/1014 731/748/731 737/754/737 f 1031/1066/1031 1074/1109/1074 981/1008/981 f 1031/1066/1031 981/1008/981 991/1018/991 f 730/751/730 922/944/922 1033/1068/1033 f 730/751/730 1033/1068/1033 738/755/738 f 990/1019/990 980/1009/980 987/1015/987 f 990/1019/990 987/1015/987 875/895/875 f 763/780/763 752/773/752 988/1017/988 f 763/780/763 988/1017/988 1051/1085/1051 f 763/780/763 762/779/762 753/770/753 f 763/780/763 753/770/753 752/773/752 f 980/1009/980 990/1019/990 991/1018/991 f 980/1009/980 991/1018/991 981/1008/981 f 1118/1164/1118 1126/1172/1126 1081/1119/1081 f 1118/1164/1118 1081/1119/1081 1119/1165/1119 f 1126/1172/1126 1125/1171/1125 1074/1109/1074 f 1126/1172/1126 1074/1109/1074 1031/1066/1031 f 1119/1165/1119 1081/1119/1081 1080/1118/1080 f 1119/1165/1119 1080/1118/1080 1089/1130/1089 f 986/1014/986 844/865/844 889/909/889 f 986/1014/986 889/909/889 1051/1085/1051 f 821/844/821 819/839/819 818/841/818 f 821/844/821 818/841/818 1097/1136/1097 f 1022/1051/1022 764/785/764 894/914/894 f 1022/1051/1022 894/914/894 1023/1052/1023 f 1023/1052/1023 894/914/894 893/913/893 f 1023/1052/1023 893/913/893 1025/1055/1025 f 926/950/926 920/942/920 727/744/727 f 926/950/926 727/744/727 726/747/726 f 919/943/919 920/942/920 926/950/926 f 919/943/919 926/950/926 927/949/927 f 1128/1174/1128 1116/1162/1116 960/983/960 f 1128/1174/1128 960/983/960 959/982/959 f 773/790/773 702/719/702 799/820/799 f 773/790/773 799/820/799 774/791/774 f 799/820/799 972/997/972 780/798/780 f 799/820/799 780/798/780 774/791/774 f 772/793/772 828/848/828 970/996/970 f 772/793/772 970/996/970 773/790/773 f 703/720/703 970/996/970 996/1024/996 f 703/720/703 996/1024/996 782/800/782 f 771/788/771 781/799/781 780/798/780 f 771/788/771 780/798/780 768/789/768 f 791/812/791 790/811/790 782/800/782 f 791/812/791 782/800/782 996/1024/996 f 811/831/811 810/830/810 779/796/779 f 811/831/811 779/796/779 791/812/791 f 1027/1057/1027 789/809/789 777/794/777 f 1027/1057/1027 777/794/777 776/797/776 f 927/949/927 925/948/925 769/786/769 f 927/949/927 769/786/769 1128/1174/1128 f 710/727/710 725/742/725 724/741/724 f 710/727/710 724/741/724 1115/1160/1115 f 954/976/954 953/977/953 1125/1171/1125 f 954/976/954 1125/1171/1125 1117/1163/1117 f 1117/1163/1117 1125/1171/1125 1126/1172/1126 f 1117/1163/1117 1126/1172/1126 1118/1164/1118 f 768/789/768 1116/1162/1116 1128/1174/1128 f 768/789/768 1128/1174/1128 769/786/769 f 904/927/904 867/887/867 229/209/229 f 904/927/904 229/209/229 529/521/529 f 948/972/948 1096/1135/1096 998/1025/998 f 948/972/948 998/1025/998 949/971/949 f 1120/1167/1120 864/885/864 873/893/873 f 1120/1167/1120 873/893/873 949/971/949 f 1121/1166/1121 1120/1167/1120 997/1026/997 f 1121/1166/1121 997/1026/997 1129/1175/1129 f 1129/1175/1129 1095/1134/1095 865/888/865 f 1129/1175/1129 865/888/865 1121/1166/1121 f 861/881/861 1121/1166/1121 865/888/865 f 861/881/861 865/888/865 862/882/862 f 1075/1111/1075 890/911/890 1003/1034/1003 f 1075/1111/1075 1003/1034/1003 1076/1112/1076 f 1076/1112/1076 1003/1034/1003 965/991/965 f 1076/1112/1076 965/991/965 1077/1113/1077 f 965/991/965 695/990/695 694/1114/694 f 965/991/965 694/1114/694 1077/1113/1077 f 1075/1111/1075 1095/1134/1095 891/912/891 f 1075/1111/1075 891/912/891 890/911/890 f 895/915/895 894/914/894 764/785/764 f 895/915/895 764/785/764 767/784/767 f 1020/1050/1020 820/840/820 814/838/814 f 1020/1050/1020 814/838/814 817/837/817 f 1123/1170/1123 844/865/844 821/844/821 f 1123/1170/1123 821/844/821 1097/1136/1097 f 1124/1169/1124 1123/1170/1123 1097/1136/1097 f 1124/1169/1124 1097/1136/1097 911/935/911 f 1130/1176/1130 1124/1169/1124 911/935/911 f 1130/1176/1130 911/935/911 912/934/912 f 532/524/532 1130/1176/1130 912/934/912 f 532/524/532 912/934/912 390/376/390 f 973/1001/973 882/902/882 881/905/881 f 973/1001/973 881/905/881 885/907/885 f 833/857/833 836/856/836 886/906/886 f 833/857/833 886/906/886 880/900/880 f 834/854/834 833/857/833 879/899/879 f 834/854/834 879/899/879 963/988/963 f 1067/1102/1067 1066/1101/1066 1114/1161/1114 f 1067/1102/1067 1114/1161/1114 1069/1105/1069 f 809/829/809 808/832/808 928/954/928 f 809/829/809 928/954/928 1016/1046/1016 f 1019/1048/1019 522/514/522 405/390/405 f 1019/1048/1019 405/390/405 1029/1059/1029 f 1131/1177/1131 1085/1123/1085 1037/1071/1037 f 1131/1177/1131 1037/1071/1037 1036/1070/1036 f 1132/1178/1132 1103/1142/1103 715/732/715 f 1132/1178/1132 715/732/715 714/731/714 f 1110/1155/1110 1102/1140/1102 1101/1139/1101 f 1110/1155/1110 1101/1139/1101 1133/1179/1133 f 1111/1156/1111 1112/1158/1112 1135/1180/1135 f 1111/1156/1111 1135/1180/1135 1134/1181/1134 f 1106/1145/1106 1110/1155/1110 1133/1179/1133 f 1106/1145/1106 1133/1179/1133 1136/1182/1136 f 1106/1145/1106 714/731/714 713/730/713 f 1106/1145/1106 713/730/713 958/980/958 f 1112/1158/1112 505/1157/505 539/1183/539 f 1112/1158/1112 539/1183/539 1135/1180/1135 f 883/903/883 882/902/882 975/1003/975 f 883/903/883 975/1003/975 1044/1079/1044 f 704/725/704 1009/1038/1009 1008/1041/1008 f 704/725/704 1008/1041/1008 705/722/705 f 1052/1086/1052 962/986/962 1054/1088/1054 f 1052/1086/1052 1054/1088/1054 1053/1087/1053 f 1055/1092/1055 824/846/824 1060/1094/1060 f 1055/1092/1055 1060/1094/1060 1056/1089/1056 f 1009/1038/1009 704/725/704 824/846/824 f 1009/1038/1009 824/846/824 1055/1092/1055 f 1065/1104/1065 1113/1159/1113 1108/1147/1108 f 1065/1104/1065 1108/1147/1108 1061/1096/1061 f 1068/1103/1068 1042/1075/1042 1054/1088/1054 f 1068/1103/1068 1054/1088/1054 1109/1154/1109 f 1008/1041/1008 1011/1040/1011 1112/1158/1112 f 1008/1041/1008 1112/1158/1112 1111/1156/1111 f 1109/1154/1109 961/985/961 1063/1100/1063 f 1109/1154/1109 1063/1100/1063 1113/1159/1113 f 1134/1181/1134 1100/1138/1100 1099/1141/1099 f 1134/1181/1134 1099/1141/1099 1111/1156/1111 f 947/970/947 952/975/952 951/974/951 f 947/970/947 951/974/951 797/817/797 f 959/982/959 794/814/794 916/938/916 f 959/982/959 916/938/916 919/943/919 f 1098/1137/1098 982/1010/982 837/861/837 f 1098/1137/1098 837/861/837 741/758/741 f 1098/1137/1098 741/758/741 740/759/740 f 1098/1137/1098 740/759/740 918/940/918 f 1040/1077/1040 1047/1081/1047 1048/1082/1048 f 1040/1077/1040 1048/1082/1048 1045/1078/1045 f 1041/1074/1041 1044/1079/1044 975/1003/975 f 1041/1074/1041 975/1003/975 1053/1087/1053 f 1078/1117/1078 1127/1173/1127 947/970/947 f 1078/1117/1078 947/970/947 946/969/946 f 949/971/949 998/1025/998 997/1026/997 f 949/971/949 997/1026/997 1120/1167/1120 f 946/969/946 796/819/796 945/968/945 f 946/969/946 945/968/945 1096/1135/1096 f 998/1025/998 1096/1135/1096 945/968/945 f 998/1025/998 945/968/945 950/973/950 f 997/1026/997 805/825/805 804/828/804 f 997/1026/997 804/828/804 1129/1175/1129 f 1095/1134/1095 1129/1175/1129 804/828/804 f 1095/1134/1095 804/828/804 891/912/891 f 904/927/904 529/521/529 408/398/408 f 904/927/904 408/398/408 1030/1064/1030 f 1024/1053/1024 993/1021/993 863/884/863 f 1024/1053/1024 863/884/863 860/880/860 f 1138/1184/1138 1139/1185/1139 1140/1186/1140 f 1138/1184/1138 1140/1186/1140 1137/1187/1137 f 1141/1188/1141 1142/1189/1142 1137/1187/1137 f 1141/1188/1141 1137/1187/1137 1140/1186/1140 f 1143/1190/1143 1144/1191/1144 1142/1189/1142 f 1143/1190/1143 1142/1189/1142 1141/1188/1141 f 1145/1192/1145 1146/1193/1146 1144/1191/1144 f 1145/1192/1145 1144/1191/1144 1143/1190/1143 f 1147/1194/1147 1148/1195/1148 1146/1193/1146 f 1147/1194/1147 1146/1193/1146 1145/1192/1145 f 1149/1196/1149 1150/1197/1150 1148/1195/1148 f 1149/1196/1149 1148/1195/1148 1147/1194/1147 f 1151/1198/1151 1152/1199/1152 1150/1197/1150 f 1151/1198/1151 1150/1197/1150 1149/1196/1149 f 1154/1200/1154 1155/1201/1155 1156/1202/1156 f 1154/1200/1154 1156/1202/1156 1153/1203/1153 f 1157/1204/1157 1158/1205/1158 1155/1201/1155 f 1157/1204/1157 1155/1201/1155 1154/1200/1154 f 1159/1206/1159 1160/1207/1160 1142/1189/1142 f 1159/1206/1159 1142/1189/1142 1144/1191/1144 f 1161/1208/1161 1159/1206/1159 1144/1191/1144 f 1161/1208/1161 1144/1191/1144 1146/1193/1146 f 1162/1209/1162 1161/1208/1161 1146/1193/1146 f 1162/1209/1162 1146/1193/1146 1148/1195/1148 f 1163/1210/1163 1162/1209/1162 1148/1195/1148 f 1163/1210/1163 1148/1195/1148 1150/1197/1150 f 1150/1197/1150 1152/1199/1152 1164/1211/1164 f 1150/1197/1150 1164/1211/1164 1163/1210/1163 f 1156/1202/1156 1155/1201/1155 1166/1212/1166 f 1156/1202/1156 1166/1212/1166 1165/1213/1165 f 1167/1214/1167 1166/1212/1166 1155/1201/1155 f 1167/1214/1167 1155/1201/1155 1158/1205/1158 f 1169/1215/1169 1167/1214/1167 1158/1205/1158 f 1169/1215/1169 1158/1205/1158 1168/1216/1168 f 1170/1217/1170 1171/1218/1171 1172/1219/1172 f 1170/1217/1170 1172/1219/1172 1139/1185/1139 f 1173/1220/1173 1174/1221/1174 1141/1188/1141 f 1173/1220/1173 1141/1188/1141 1140/1186/1140 f 1141/1188/1141 1174/1221/1174 1175/1222/1175 f 1141/1188/1141 1175/1222/1175 1143/1190/1143 f 1176/1223/1176 1145/1192/1145 1143/1190/1143 f 1176/1223/1176 1143/1190/1143 1175/1222/1175 f 1177/1224/1177 1149/1196/1149 1147/1194/1147 f 1177/1224/1177 1147/1194/1147 1176/1223/1176 f 1177/1224/1177 1178/1225/1178 1151/1198/1151 f 1177/1224/1177 1151/1198/1151 1149/1196/1149 f 1153/1203/1153 1179/1226/1179 1180/1227/1180 f 1153/1203/1153 1180/1227/1180 1154/1200/1154 f 1157/1204/1157 1154/1200/1154 1180/1227/1180 f 1157/1204/1157 1180/1227/1180 1181/1228/1181 f 1157/1204/1157 1181/1228/1181 1182/1229/1182 f 1157/1204/1157 1182/1229/1182 1168/1216/1168 f 1169/1215/1169 1168/1216/1168 1182/1229/1182 f 1169/1215/1169 1182/1229/1182 1183/1230/1183 f 1142/1189/1142 1160/1207/1160 1138/1184/1138 f 1142/1189/1142 1138/1184/1138 1137/1187/1137 f 1170/1217/1170 1185/1231/1185 1186/1232/1186 f 1170/1217/1170 1186/1232/1186 1184/1233/1184 f 1170/1217/1170 1184/1233/1184 1187/1234/1187 f 1170/1217/1170 1187/1234/1187 1171/1218/1171 f 1187/1234/1187 1188/1235/1188 1172/1219/1172 f 1187/1234/1187 1172/1219/1172 1171/1218/1171 f 1172/1219/1172 1188/1235/1188 1140/1186/1140 f 1172/1219/1172 1140/1186/1140 1139/1185/1139 f 1161/1208/1161 1162/1209/1162 1163/1210/1163 f 1161/1208/1161 1163/1210/1163 1189/1236/1189 f 1189/1236/1189 1163/1210/1163 1164/1211/1164 f 1189/1236/1189 1164/1211/1164 1190/1237/1190 f 1165/1213/1165 1164/1211/1164 1152/1199/1152 f 1165/1213/1165 1152/1199/1152 1156/1202/1156 f 1152/1199/1152 1151/1198/1151 1153/1203/1153 f 1152/1199/1152 1153/1203/1153 1156/1202/1156 f 1179/1226/1179 1153/1203/1153 1151/1198/1151 f 1179/1226/1179 1151/1198/1151 1178/1225/1178 f 1189/1236/1189 1160/1207/1160 1159/1206/1159 f 1189/1236/1189 1159/1206/1159 1161/1208/1161 f 1186/1232/1186 1190/1237/1190 1164/1211/1164 f 1186/1232/1186 1164/1211/1164 1165/1213/1165 f 1139/1185/1139 1138/1184/1138 1185/1231/1185 f 1139/1185/1139 1185/1231/1185 1170/1217/1170 f 1169/1215/1169 1188/1235/1188 1187/1234/1187 f 1169/1215/1169 1187/1234/1187 1167/1214/1167 f 1186/1232/1186 1165/1213/1165 1166/1212/1166 f 1186/1232/1186 1166/1212/1166 1184/1233/1184 f 1140/1186/1140 1188/1235/1188 1191/1238/1191 f 1140/1186/1140 1191/1238/1191 1173/1220/1173 f 1191/1238/1191 1188/1235/1188 1169/1215/1169 f 1191/1238/1191 1169/1215/1169 1183/1230/1183 f 1192/1239/1192 1193/1240/1193 1179/1226/1179 f 1192/1239/1192 1179/1226/1179 1178/1225/1178 f 1192/1239/1192 1178/1225/1178 1177/1224/1177 f 1192/1239/1192 1177/1224/1177 1194/1241/1194 f 1180/1227/1180 1193/1240/1193 1072/1108/1072 f 1180/1227/1180 1072/1108/1072 1105/1144/1105 f 1180/1227/1180 1105/1144/1105 1107/1146/1107 f 1180/1227/1180 1107/1146/1107 1181/1228/1181 f 1194/1241/1194 1177/1224/1177 1176/1223/1176 f 1194/1241/1194 1176/1223/1176 1114/1161/1114 f 1062/1095/1062 1194/1241/1194 1114/1161/1114 f 1062/1095/1062 1114/1161/1114 1066/1101/1066 f 707/724/707 1072/1108/1072 1193/1240/1193 f 707/724/707 1193/1240/1193 825/845/825 f 825/845/825 1193/1240/1193 1192/1239/1192 f 825/845/825 1192/1239/1192 1059/1093/1059 f 1173/1220/1173 1191/1238/1191 832/853/832 f 1173/1220/1173 832/853/832 711/728/711 f 1183/1230/1183 1182/1229/1182 1005/1035/1005 f 1183/1230/1183 1005/1035/1005 831/851/831 f 1187/1234/1187 1184/1233/1184 1166/1212/1166 f 1187/1234/1187 1166/1212/1166 1167/1214/1167 f 710/727/710 1115/1160/1115 1175/1222/1175 f 710/727/710 1175/1222/1175 1174/1221/1174 f 1182/1229/1182 1181/1228/1181 1107/1146/1107 f 1182/1229/1182 1107/1146/1107 1005/1035/1005 f 453/443/453 1049/1083/1049 720/738/720 f 453/443/453 720/738/720 598/590/598 f 1123/1170/1123 888/910/888 889/909/889 f 1123/1170/1123 889/909/889 844/865/844 f 916/938/916 794/814/794 793/813/793 f 916/938/916 793/813/793 913/939/913 f 711/728/711 832/853/832 770/787/770 f 711/728/711 770/787/770 708/729/708 f 919/943/919 927/949/927 1128/1174/1128 f 919/943/919 1128/1174/1128 959/982/959 f 925/948/925 708/729/708 770/787/770 f 925/948/925 770/787/770 769/786/769 f 913/939/913 793/813/793 954/976/954 f 913/939/913 954/976/954 924/946/924 f 831/851/831 832/853/832 1191/1238/1191 f 831/851/831 1191/1238/1191 1183/1230/1183 f 895/915/895 767/784/767 766/783/766 f 895/915/895 766/783/766 1006/1036/1006 f 891/912/891 804/828/804 807/827/807 f 891/912/891 807/827/807 788/808/788 f 778/795/778 777/794/777 788/808/788 f 778/795/778 788/808/788 807/827/807 f 810/830/810 1000/1027/1000 776/797/776 f 810/830/810 776/797/776 779/796/779 f 947/970/947 1127/1173/1127 1073/1110/1073 f 947/970/947 1073/1110/1073 952/975/952 f 1106/1145/1106 1136/1182/1136 1132/1178/1132 f 1106/1145/1106 1132/1178/1132 714/731/714 f 1061/1096/1061 1062/1095/1062 1066/1101/1066 f 1061/1096/1061 1066/1101/1066 1065/1104/1065 f 443/1098/443 497/1150/497 1057/1090/1057 f 443/1098/443 1057/1090/1057 1064/1099/1064 f 1064/1099/1064 1108/1147/1108 1113/1159/1113 f 1064/1099/1064 1113/1159/1113 1063/1100/1063 f 1061/1096/1061 1108/1147/1108 1056/1089/1056 f 1061/1096/1061 1056/1089/1056 1060/1094/1060 f 1192/1239/1192 1194/1241/1194 1062/1095/1062 f 1192/1239/1192 1062/1095/1062 1059/1093/1059 f 1173/1220/1173 711/728/711 710/727/710 f 1173/1220/1173 710/727/710 1174/1221/1174 f 880/900/880 881/905/881 884/904/884 f 880/900/880 884/904/884 878/901/878 f 841/862/841 1047/1081/1047 1046/1080/1046 f 841/862/841 1046/1080/1046 723/740/723 f 1070/1106/1070 1048/1082/1048 1047/1081/1047 f 1070/1106/1070 1047/1081/1047 841/862/841 f 461/1115/461 342/999/342 885/907/885 f 461/1115/461 885/907/885 886/906/886 f 1114/1161/1114 1176/1223/1176 1175/1222/1175 f 1114/1161/1114 1175/1222/1175 1115/1160/1115 f 887/908/887 1124/1169/1124 1130/1176/1130 f 887/908/887 1130/1176/1130 852/873/852 f 206/186/206 852/873/852 1130/1176/1130 f 206/186/206 1130/1176/1130 532/524/532 f 681/698/681 599/592/599 1195/1242/1195 f 681/698/681 1195/1242/1195 682/699/682 f 1196/1243/1196 674/691/674 684/702/684 f 1196/1243/1196 684/702/684 1195/1242/1195 f 1197/1244/1197 675/692/675 674/691/674 f 1197/1244/1197 674/691/674 1196/1243/1196 f 689/706/689 690/708/690 675/692/675 f 689/706/689 675/692/675 1197/1244/1197 f 693/710/693 1199/1245/1199 1200/1246/1200 f 693/710/693 1200/1246/1200 1198/1247/1198 f 686/707/686 689/706/689 1197/1244/1197 f 686/707/686 1197/1244/1197 1199/1245/1199 f 1196/1243/1196 1195/1242/1195 1202/1248/1202 f 1196/1243/1196 1202/1248/1202 1201/1249/1201 f 1084/1122/1084 1083/1124/1083 1204/1250/1204 f 1084/1122/1084 1204/1250/1204 1203/1251/1203 f 1092/1131/1092 1013/1042/1013 1203/1251/1203 f 1092/1131/1092 1203/1251/1203 1204/1250/1204 f 1206/1252/1206 1087/1253/1087 1207/1254/1207 f 1206/1252/1206 1207/1254/1207 1205/1255/1205 f 1206/1252/1206 1208/1256/1208 1086/1257/1086 f 1206/1252/1206 1086/1257/1086 1087/1253/1087 f 1091/1258/1091 1090/1259/1090 1210/1260/1210 f 1091/1258/1091 1210/1260/1210 1209/1261/1209 f 1093/1132/1093 1211/1262/1211 757/774/757 f 1093/1132/1093 757/774/757 756/775/756 f 1079/1120/1079 1212/1263/1212 1090/1128/1090 f 1079/1120/1079 1090/1128/1090 1080/1118/1080 f 1079/1120/1079 979/1006/979 1088/1127/1088 f 1079/1120/1079 1088/1127/1088 1212/1263/1212 f 1209/1261/1209 1213/1264/1213 1085/1265/1085 f 1209/1261/1209 1085/1265/1085 1131/1266/1131 f 1089/1130/1089 1091/1129/1091 1131/1177/1131 f 1089/1130/1089 1131/1177/1131 1036/1070/1036 f 1213/1264/1213 1214/1267/1214 1204/1268/1204 f 1213/1264/1213 1204/1268/1204 1083/1269/1083 f 1214/1267/1214 1215/1270/1215 1092/1271/1092 f 1214/1267/1214 1092/1271/1092 1204/1268/1204 f 1015/1045/1015 757/774/757 1211/1262/1211 f 1015/1045/1015 1211/1262/1211 1216/1272/1216 f 1211/1273/1211 1093/1274/1093 1215/1270/1215 f 1211/1273/1211 1215/1270/1215 1217/1275/1217 f 1088/1276/1088 1208/1256/1208 1210/1260/1210 f 1088/1276/1088 1210/1260/1210 1212/1277/1212 f 1216/1278/1216 1211/1273/1211 1217/1275/1217 f 1216/1278/1216 1217/1275/1217 1218/1279/1218 f 1219/1280/1219 1218/1279/1218 1205/1255/1205 f 1219/1280/1219 1205/1255/1205 1207/1254/1207 f 698/715/698 697/714/697 717/734/717 f 698/715/698 717/734/717 716/737/716 f 967/992/967 418/407/418 524/516/524 f 967/992/967 524/516/524 968/993/968 f 598/590/598 720/738/720 712/733/712 f 598/590/598 712/733/712 293/276/293 f 697/714/697 721/739/721 1050/1084/1050 f 697/714/697 1050/1084/1050 717/734/717 f 957/979/957 956/978/956 1005/1035/1005 f 957/979/957 1005/1035/1005 1107/1146/1107 f 1186/1232/1186 1185/1231/1185 1189/1236/1189 f 1186/1232/1186 1189/1236/1189 1190/1237/1190 f 1022/1051/1022 896/917/896 765/782/765 f 1022/1051/1022 765/782/765 764/785/764 f 1122/1168/1122 896/917/896 1022/1051/1022 f 1122/1168/1122 1022/1051/1022 1021/1054/1021 f 678/695/678 1198/1247/1198 625/631/625 f 678/695/678 625/631/625 27/8/27 f 1195/1242/1195 599/592/599 626/632/626 f 1195/1242/1195 626/632/626 1202/1248/1202 f 1202/1248/1202 626/632/626 628/634/628 f 1202/1248/1202 628/634/628 1220/1281/1220 f 1198/1247/1198 1220/1281/1220 628/634/628 f 1198/1247/1198 628/634/628 625/631/625 f 1222/1282/1222 1223/1283/1223 1224/1284/1224 f 1222/1282/1222 1224/1284/1224 1221/1285/1221 f 1226/1286/1226 1227/1287/1227 1228/1288/1228 f 1226/1286/1226 1228/1288/1228 1225/1289/1225 f 1230/1290/1230 1231/1291/1231 1232/1292/1232 f 1230/1290/1230 1232/1292/1232 1229/1293/1229 f 1234/1294/1234 1232/1292/1232 1231/1291/1231 f 1234/1294/1234 1231/1291/1231 1233/1295/1233 f 1236/1296/1236 1237/1297/1237 1238/1298/1238 f 1236/1296/1236 1238/1298/1238 1235/1299/1235 f 1221/1285/1221 1239/1300/1239 1240/1301/1240 f 1221/1285/1221 1240/1301/1240 1233/1295/1233 f 1242/1302/1242 1243/1303/1243 1244/1304/1244 f 1242/1302/1242 1244/1304/1244 1241/1305/1241 f 1237/1297/1237 1245/1306/1245 1246/1307/1246 f 1237/1297/1237 1246/1307/1246 1238/1298/1238 f 1246/1307/1246 1245/1306/1245 1242/1302/1242 f 1246/1307/1246 1242/1302/1242 1241/1305/1241 f 1248/1308/1248 1224/1284/1224 1249/1309/1249 f 1248/1308/1248 1249/1309/1249 1247/1310/1247 f 1249/1309/1249 1250/1311/1250 660/1312/660 f 1249/1309/1249 660/1312/660 659/1313/659 f 661/1314/661 1247/1310/1247 1249/1309/1249 f 661/1314/661 1249/1309/1249 659/1313/659 f 1221/1285/1221 1224/1284/1224 1248/1308/1248 f 1221/1285/1221 1248/1308/1248 1239/1300/1239 f 1231/1291/1231 1222/1282/1222 1221/1285/1221 f 1231/1291/1231 1221/1285/1221 1233/1295/1233 f 1232/1292/1232 1234/1294/1234 1243/1303/1243 f 1232/1292/1232 1243/1303/1243 1242/1302/1242 f 1244/1304/1244 1243/1303/1243 1234/1294/1234 f 1244/1304/1244 1234/1294/1234 1251/1315/1251 f 1240/1301/1240 1251/1315/1251 1234/1294/1234 f 1240/1301/1240 1234/1294/1234 1233/1295/1233 f 1253/1316/1253 1134/1181/1134 1135/1180/1135 f 1253/1316/1253 1135/1180/1135 1252/1317/1252 f 1254/1318/1254 1255/1319/1255 1229/1293/1229 f 1254/1318/1254 1229/1293/1229 1232/1292/1232 f 1254/1318/1254 1225/1289/1225 1228/1288/1228 f 1254/1318/1254 1228/1288/1228 1255/1319/1255 f 667/1320/667 1252/1317/1252 1135/1180/1135 f 667/1320/667 1135/1180/1135 539/1183/539 f 1226/1286/1226 1225/1289/1225 1237/1297/1237 f 1226/1286/1226 1237/1297/1237 1236/1296/1236 f 1245/1306/1245 1254/1318/1254 1232/1292/1232 f 1245/1306/1245 1232/1292/1232 1242/1302/1242 f 1254/1318/1254 1245/1306/1245 1237/1297/1237 f 1254/1318/1254 1237/1297/1237 1225/1289/1225 f 669/674/669 668/675/668 1226/1286/1226 f 669/674/669 1226/1286/1226 1236/1296/1236 f 1230/1290/1230 1256/1321/1256 1222/1282/1222 f 1230/1290/1230 1222/1282/1222 1231/1291/1231 f 1235/1299/1235 671/677/671 669/674/669 f 1235/1299/1235 669/674/669 1236/1296/1236 f 1230/1290/1230 1101/1139/1101 1100/1138/1100 f 1230/1290/1230 1100/1138/1100 1256/1321/1256 f 672/678/672 488/480/488 1103/1142/1103 f 672/678/672 1103/1142/1103 1227/1287/1227 f 1224/1284/1224 1223/1283/1223 1250/1311/1250 f 1224/1284/1224 1250/1311/1250 1249/1309/1249 f 1256/1321/1256 1100/1138/1100 1134/1181/1134 f 1256/1321/1256 1134/1181/1134 1253/1316/1253 f 1227/1287/1227 1103/1142/1103 1132/1178/1132 f 1227/1287/1227 1132/1178/1132 1228/1288/1228 f 1101/1139/1101 1230/1290/1230 1229/1293/1229 f 1101/1139/1101 1229/1293/1229 1133/1179/1133 f 1223/1283/1223 1253/1316/1253 1252/1317/1252 f 1223/1283/1223 1252/1317/1252 1250/1311/1250 f 1255/1319/1255 1136/1182/1136 1133/1179/1133 f 1255/1319/1255 1133/1179/1133 1229/1293/1229 f 1228/1288/1228 1132/1178/1132 1136/1182/1136 f 1228/1288/1228 1136/1182/1136 1255/1319/1255 f 660/1312/660 1250/1311/1250 1252/1317/1252 f 660/1312/660 1252/1317/1252 667/1320/667 f 668/675/668 672/678/672 1227/1287/1227 f 668/675/668 1227/1287/1227 1226/1286/1226 f 1222/1282/1222 1256/1321/1256 1253/1316/1253 f 1222/1282/1222 1253/1316/1253 1223/1283/1223 f 1/1322/1 12/1323/12 1247/1310/1247 f 1/1322/1 1247/1310/1247 661/1314/661 f 10/1324/10 8/1325/8 1240/1301/1240 f 10/1324/10 1240/1301/1240 1239/1300/1239 f 1239/1300/1239 1248/1308/1248 11/1326/11 f 1239/1300/1239 11/1326/11 10/1324/10 f 5/1327/5 3/1328/3 1235/1299/1235 f 5/1327/5 1235/1299/1235 1238/1298/1238 f 9/1329/9 4/1330/4 1246/1307/1246 f 9/1329/9 1246/1307/1246 1241/1305/1241 f 1240/1301/1240 8/1325/8 6/1331/6 f 1240/1301/1240 6/1331/6 1251/1315/1251 f 7/1332/7 9/1329/9 1241/1305/1241 f 7/1332/7 1241/1305/1241 1244/1304/1244 f 11/1326/11 1248/1308/1248 1247/1310/1247 f 11/1326/11 1247/1310/1247 12/1323/12 f 3/1328/3 2/690/2 671/677/671 f 3/1328/3 671/677/671 1235/1299/1235 f 1238/1298/1238 1246/1307/1246 4/1330/4 f 1238/1298/1238 4/1330/4 5/1327/5 f 7/1332/7 1244/1304/1244 1251/1315/1251 f 7/1332/7 1251/1315/1251 6/1331/6 f 1203/1251/1203 1013/1042/1013 1012/1043/1012 f 1203/1251/1203 1012/1043/1012 736/757/736 f 937/959/937 941/964/941 1027/1057/1027 f 937/959/937 1027/1057/1027 999/1030/999 f 1084/1122/1084 739/756/739 1034/1067/1034 f 1084/1122/1084 1034/1067/1034 1037/1071/1037 f 1197/1244/1197 1196/1243/1196 1201/1249/1201 f 1197/1244/1197 1201/1249/1201 1199/1245/1199 f 1203/1251/1203 736/757/736 739/756/739 f 1203/1251/1203 739/756/739 1084/1122/1084 f 936/962/936 784/805/784 941/964/941 f 936/962/936 941/964/941 937/959/937 f 786/806/786 1004/1033/1004 940/963/940 f 786/806/786 940/963/940 785/804/785 f 467/1333/467 612/604/612 387/1334/387 f 612/604/612 624/630/624 387/1334/387 f 621/628/621 387/1334/387 624/630/624 f 604/595/604 44/22/44 28/5/28 f 472/605/472 612/604/612 467/1333/467 f 29/6/29 28/5/28 47/26/47 f 43/21/43 48/25/48 44/22/44 f 30/7/30 266/1335/266 27/8/27 f 424/414/424 239/223/239 425/415/425 f 467/458/467 363/347/363 472/463/472 f 561/552/561 560/553/560 572/564/572 f 549/540/549 551/542/551 579/571/579 f 583/574/583 595/588/595 582/575/582 f 31/12/31 36/13/36 600/591/600 f 39/16/39 44/22/44 603/597/603 f 32/9/32 599/592/599 45/23/45 f 473/626/473 613/607/613 471/606/471 f 477/620/477 478/625/478 620/621/620 f 474/611/474 615/610/615 617/627/617 f 1257/1336/1257 614/609/614 618/616/618 f 1257/1336/1257 620/621/620 622/624/622 f 1257/1336/1257 618/616/618 619/619/619 f 1257/1336/1257 613/607/613 615/610/615 f 614/609/614 1257/1336/1257 615/610/615 f 622/624/622 623/629/623 1257/1336/1257 f 1257/1336/1257 623/629/623 611/603/611 f 624/630/624 623/629/623 621/628/621 f 469/617/469 618/616/618 470/615/470 f 614/609/614 476/608/476 533/614/533 f 610/602/610 1257/1336/1257 611/603/611 f 613/607/613 1257/1336/1257 610/602/610 f 620/621/620 1257/1336/1257 619/619/619 f 541/532/541 592/584/592 562/555/562 f 541/532/541 587/581/587 592/584/592 f 627/633/627 607/599/607 605/596/605 f 627/633/627 605/596/605 604/595/604 f 605/596/605 606/598/606 603/597/603 f 607/599/607 606/598/606 605/596/605 f 1207/1254/1207 1082/1337/1082 1015/1338/1015 f 1219/1280/1219 1207/1254/1207 1015/1338/1015 f 1015/1338/1015 1216/1278/1216 1219/1280/1219 f 693/710/693 1198/1247/1198 678/695/678 f 1207/1254/1207 1087/1253/1087 1082/1337/1082 f 678/695/678 677/697/677 694/712/694 f 695/713/695 692/711/692 693/710/693 f 266/1335/266 679/696/679 27/8/27 f 883/903/883 1044/1079/1044 1045/1078/1045 f 992/1020/992 1082/1121/1082 1087/1125/1087 f 1158/1205/1158 1157/1204/1157 1168/1216/1168 f 1147/1194/1147 1145/1192/1145 1176/1223/1176 f 1193/1240/1193 1180/1227/1180 1179/1226/1179 f 684/702/684 682/699/682 1195/1242/1195 f 693/710/693 686/707/686 1199/1245/1199 f 599/592/599 681/698/681 45/23/45 f 1208/1256/1208 1088/1276/1088 1086/1257/1086 f 1093/1274/1093 1092/1271/1092 1215/1270/1215 f 1210/1260/1210 1090/1259/1090 1212/1277/1212 f 1209/1261/1209 1258/1339/1258 1213/1264/1213 f 1215/1270/1215 1258/1339/1258 1217/1275/1217 f 1213/1264/1213 1258/1339/1258 1214/1267/1214 f 1208/1256/1208 1258/1339/1258 1210/1260/1210 f 1258/1339/1258 1209/1261/1209 1210/1260/1210 f 1218/1279/1218 1217/1275/1217 1258/1339/1258 f 1218/1279/1218 1258/1339/1258 1205/1255/1205 f 1218/1279/1218 1219/1280/1219 1216/1278/1216 f 1213/1264/1213 1083/1269/1083 1085/1265/1085 f 1091/1258/1091 1209/1261/1209 1131/1266/1131 f 1258/1339/1258 1206/1252/1206 1205/1255/1205 f 1258/1339/1258 1208/1256/1208 1206/1252/1206 f 1258/1339/1258 1215/1270/1215 1214/1267/1214 f 1189/1236/1189 1138/1184/1138 1160/1207/1160 f 1185/1231/1185 1138/1184/1138 1189/1236/1189 f 1202/1248/1202 1220/1281/1220 1200/1246/1200 f 1200/1246/1200 1220/1281/1220 1198/1247/1198 f 1201/1249/1201 1200/1246/1200 1199/1245/1199 f 1201/1249/1201 1202/1248/1202 1200/1246/1200 # 2492 faces ================================================ FILE: graphics/tiny-renderer/lesson7.workbook/Geometry.csx ================================================ struct Vec2f { public float x; public float y; public float this [int i] { get { if (i == 0) return x; if (i == 1) return y; throw new InvalidOperationException (); } set { if (i == 0) x = value; else if (i == 1) y = value; else throw new InvalidOperationException (); } } public Vec2f Normalize () { return this / Norm (); } public float Norm () { return (float)Math.Sqrt (x * x + y * y); } public static Vec2f operator / (Vec2f v, float num) { v.x /= num; v.y /= num; return v; } public static Vec2f operator * (Vec2f v, float num) { v.x *= num; v.y *= num; return v; } public static Vec2f operator - (Vec2f a, Vec2f b) { return new Vec2f { x = a.x - b.x, y = a.y - b.y }; } public static Vec2f operator + (Vec2f a, Vec2f b) { return new Vec2f { x = a.x + b.x, y = a.y + b.y }; } } public struct Vec3f { public float x; public float y; public float z; public float this [int i] { get { switch (i) { case 0: return x; case 1: return y; case 2: return z; default: throw new InvalidOperationException (); } } set { switch (i) { case 0: x = value; break; case 1: y = value; break; case 2: z = value; break; default: throw new InvalidOperationException (); } } } public Vec3f Normalize () { return this / Norm (); } public float Norm () { return (float)Math.Sqrt (x * x + y * y + z * z); } public static Vec3f operator - (Vec3f a, Vec3f b) { return new Vec3f { x = a.x - b.x, y = a.y - b.y, z = a.z - b.z }; } public static Vec3f operator / (Vec3f v, float num) { v.x /= num; v.y /= num; v.z /= num; return v; } public static Vec3f operator * (Vec3f v, float num) { v.x *= num; v.y *= num; v.z *= num; return v; } } struct Vec4f { public float x; public float y; public float z; public float h; public float this [int i] { get { switch (i) { case 0: return x; case 1: return y; case 2: return z; case 3: return h; default: throw new InvalidOperationException (); } } set { switch (i) { case 0: x = value; break; case 1: y = value; break; case 2: z = value; break; case 3: h = value; break; default: throw new InvalidOperationException (); } } } public Vec4f Normalize () { var len = Norm (); return this / len; } public float Norm () { return (float)Math.Sqrt (x * x + y * y + z * z + h * h); } public static Vec4f operator - (Vec4f a, Vec4f b) { return new Vec4f { x = a.x - b.x, y = a.y - b.y, z = a.z - b.z, h = a.h - b.h }; } public static Vec4f operator / (Vec4f v, float num) { v.x /= num; v.y /= num; v.z /= num; v.h /= num; return v; } } struct Vec2i { public int x; public int y; public static Vec2i operator - (Vec2i a, Vec2i b) { return new Vec2i { x = a.x - b.x, y = a.y - b.y }; } } struct Vec3i { public int x; public int y; public int z; public static Vec3i operator - (Vec3i a, Vec3i b) { return new Vec3i { x = a.x - b.x, y = a.y - b.y, z = a.z - b.z }; } } static class Geometry { public static Vec3f Cross (Vec3f l, Vec3f r) { return new Vec3f { x = l.y * r.z - l.z * r.y, y = l.z * r.x - l.x * r.z, z = l.x * r.y - l.y * r.x }; } public static float Dot (Vec3f l, Vec3f r) { return l.x * r.x + l.y * r.y + l.z * r.z; } public static Vec4f Embed4D (Vec3f v, float fill = 1) { return new Vec4f { x = v.x, y = v.y, z = v.z, h = fill }; } public static Vec2f Project2D (Vec3f v) { return new Vec2f { x = v.x, y = v.y }; } public static Vec2f Project2D (Vec4f v) { return new Vec2f { x = v.x, y = v.y }; } public static Vec3f Project3D (Vec4f v) { return new Vec3f { x = v.x, y = v.y, z = v.z }; } } ================================================ FILE: graphics/tiny-renderer/lesson7.workbook/Image.csx ================================================ using System.IO; enum Format { GRAYSCALE = 1, BGR = 3, BGRA = 4 } struct Color { // the value stored as little endian: // ARGB -> BGRA // xRGB -> BGRx public readonly int value; public readonly Format format; public byte this [int offset] { get { if (offset > 3) // int has only 4 bytes (0, 1, 2, 3) throw new ArgumentOutOfRangeException (); return (byte)(value >> 8 * (3 - offset)); } } public static Color Red = new Color (red: 255, green: 0, blue: 0, alpha: 255); public static Color Green = new Color (red: 0, green: 255, blue: 0, alpha: 255); public static Color Blue = new Color (red: 0, green: 0, blue: 255, alpha: 255); public static Color Black = new Color (red: 0, green: 0, blue: 0, alpha: 255); public static Color White = new Color (red: 255, green: 255, blue: 255, alpha: 255); public static Color Yellow = new Color (red: 225, green: 225, blue: 0, alpha: 255); public Color (byte red, byte green, byte blue, byte alpha) : this ((blue << 24) | (green << 16) | (red << 8) | alpha, Format.BGRA) { } public Color (byte red, byte green, byte blue) : this ((blue << 24) | (green << 16) | (red << 8) | 0xFF, Format.BGR) { } public Color (byte value) : this (value, Format.GRAYSCALE) { } public Color (int value, Format format) { this.value = value; this.format = format; } public static Color operator * (Color color, float intensivity) { intensivity = Math.Max (0f, Math.Min (1f, intensivity)); var ch0 = (byte)(color [0] * intensivity); var ch1 = (byte)(color [1] * intensivity); var ch2 = (byte)(color [2] * intensivity); var ch3 = color [3]; return new Color (ch0 << 24 | ch1 << 16 | ch2 << 8 | ch3, color.format); } } class Image { internal byte [] buffer; public int Width { get; } public int Height { get; } public Format Format { get; } public int BytesPerRow { get { return Width * (int)Format; } } public Image (int width, int height, Format format) { Width = width; Height = height; Format = format; buffer = new byte [height * BytesPerRow]; } public void VerticalFlip () { var bpp = (int)Format; int bytesPerLine = Width * bpp; var half = Height >> 1; for (int l = 0; l < half; l++) { var l1 = l * bytesPerLine; var l2 = (Height - 1 - l) * bytesPerLine; for (int i = 0; i < bytesPerLine; i++) { byte pixel = buffer [l1 + i]; buffer [l1 + i] = buffer [l2 + i]; buffer [l2 + i] = pixel; } } } public void Clear () { for (int i = 0; i < buffer.Length; i++) buffer [i] = 0; } public Color this [int x, int y] { get { if (x < 0 || x >= Width) throw new ArgumentException ("x"); if (y < 0 || y >= Height) throw new ArgumentException ("y"); var offset = GetOffset (x, y); var len = (int)Format; int value = 0; for (var ch = 0; ch < 4; ch++) value = (value << 8) | (ch < len ? buffer [offset++] : 0xFF); return new Color (value, Format); } set { if (x < 0 || x >= Width) return; //throw new ArgumentException ($"{nameof(x)}={x} {nameof(Width)}={Width}"); if (y < 0 || y >= Height) return; // throw new ArgumentException ($"{nameof(y)}={y} {nameof(Height)}={Height}"); var offset = GetOffset (x, y); var v = value.value; var len = (int)Format; for (int ch = 0; ch < len; ch++) // 0123 buffer [offset++] = (byte)(v >> (3 - ch) * 8); // BGRA } } int GetOffset (int x, int y) { return y * BytesPerRow + x * (int)Format; } public bool WriteToFile (string path, bool rle = true) { var bpp = (int)Format; using (var writer = new BinaryWriter (File.Create (path))) { var header = new TGAHeader { IdLength = 0, // The IDLength set to 0 indicates that there is no image identification field in the TGA file ColorMapType = 0, // a value of 0 indicates that no palette is included BitsPerPixel = (byte)(bpp * 8), Width = (short)Width, Height = (short)Height, DataTypeCode = DataTypeFor (bpp, rle), ImageDescriptor = (byte)(0x20 | (Format == Format.BGRA ? 8 : 0)) // top-left origin }; WriteTo (writer, header); if (!rle) writer.Write (buffer); else UnloadRleData (writer); } return true; } public static Image Load (string path) { using (var reader = new BinaryReader (File.OpenRead (path))) { var header = ReadHeader (reader); var height = header.Height; var width = header.Width; var bytespp = header.BitsPerPixel >> 3; var format = (Format)bytespp; if (width <= 0 || height <= 0) throw new InvalidProgramException ($"bad image size: width={width} height={height}"); if (format != Format.BGR && format != Format.BGRA && format != Format.GRAYSCALE) throw new InvalidProgramException ($"unknown format {format}"); var img = new Image (width, height, format); switch (header.DataTypeCode) { case DataType.UncompressedTrueColorImage: case DataType.UncompressedBlackAndWhiteImage: reader.Read (img.buffer, 0, img.buffer.Length); break; case DataType.RleTrueColorImage: case DataType.RleBlackAndWhiteImage: img.LoadRleData (reader); break; default: throw new InvalidProgramException ($"unsupported image format {header.DataTypeCode}"); } if ((header.ImageDescriptor & 0x20) == 0) img.VerticalFlip (); return img; } } static void WriteTo (BinaryWriter writer, TGAHeader header) { writer.Write (header.IdLength); writer.Write (header.ColorMapType); writer.Write ((byte)header.DataTypeCode); writer.Write (header.ColorMapOrigin); writer.Write (header.ColorMapLength); writer.Write (header.ColorMapDepth); writer.Write (header.OriginX); writer.Write (header.OriginY); writer.Write (header.Width); writer.Write (header.Height); writer.Write (header.BitsPerPixel); writer.Write (header.ImageDescriptor); } static TGAHeader ReadHeader (BinaryReader reader) { var header = new TGAHeader { IdLength = reader.ReadByte (), ColorMapType = reader.ReadByte (), DataTypeCode = (DataType)reader.ReadByte (), ColorMapOrigin = reader.ReadInt16 (), ColorMapLength = reader.ReadInt16 (), ColorMapDepth = reader.ReadByte (), OriginX = reader.ReadInt16 (), OriginY = reader.ReadInt16 (), Width = reader.ReadInt16 (), Height = reader.ReadInt16 (), BitsPerPixel = reader.ReadByte (), ImageDescriptor = reader.ReadByte () }; return header; } bool UnloadRleData (BinaryWriter writer) { const int max_chunk_length = 128; int npixels = Width * Height; int curpix = 0; var bpp = (int)Format; while (curpix < npixels) { int chunkstart = curpix * bpp; int curbyte = curpix * bpp; int run_length = 1; bool literal = true; while (curpix + run_length < npixels && run_length < max_chunk_length && curpix + run_length < curpix + Width) { bool succ_eq = true; for (int t = 0; succ_eq && t < bpp; t++) succ_eq = (buffer [curbyte + t] == buffer [curbyte + t + bpp]); curbyte += bpp; if (1 == run_length) literal = !succ_eq; if (literal && succ_eq) { run_length--; break; } if (!literal && !succ_eq) break; run_length++; } curpix += run_length; writer.Write ((byte)(literal ? run_length - 1 : 128 + (run_length - 1))); writer.Write (buffer, chunkstart, literal ? run_length * bpp : bpp); } return true; } void LoadRleData (BinaryReader reader) { var pixelcount = Width * Height; var currentpixel = 0; var currentbyte = 0; var bytespp = (int)Format; var color = new byte [4]; do { var chunkheader = reader.ReadByte (); if (chunkheader < 128) { chunkheader++; for (int i = 0; i < chunkheader; i++) { for (int t = 0; t < bytespp; t++) buffer [currentbyte++] = reader.ReadByte (); currentpixel++; if (currentpixel > pixelcount) throw new InvalidProgramException ("Too many pixels read"); } } else { chunkheader -= 127; reader.Read (color, 0, bytespp); for (int i = 0; i < chunkheader; i++) { for (int t = 0; t < bytespp; t++) buffer [currentbyte++] = color [t]; currentpixel++; if (currentpixel > pixelcount) throw new InvalidProgramException ("Too many pixels read"); } } } while (currentpixel < pixelcount); } static DataType DataTypeFor (int bpp, bool rle) { var format = (Format)bpp; if (format == Format.GRAYSCALE) return rle ? DataType.RleBlackAndWhiteImage : DataType.UncompressedBlackAndWhiteImage; return rle ? DataType.RleTrueColorImage : DataType.UncompressedTrueColorImage; } } struct TGAHeader { public byte IdLength; public byte ColorMapType; public DataType DataTypeCode; // field #4. Color map specification public short ColorMapOrigin; // index of first color map entry that is included in the file public short ColorMapLength; // number of entries of the color map that are included in the file public byte ColorMapDepth; // number of bits per pixel // field #5. Image specification public short OriginX; // absolute coordinate of lower-left corner for displays where origin is at the lower left public short OriginY; // as for X-origin public short Width; // width in pixels public short Height; // height in pixels public byte BitsPerPixel; // pixel depth public byte ImageDescriptor; // bits 3-0 give the alpha channel depth, bits 5-4 give direction } public enum DataType : byte { NoImageData = 0, // no image data is present UncompressedColorMappedImage = 1, UncompressedTrueColorImage = 2, UncompressedBlackAndWhiteImage = 3, RleColorMappedImage = 9, // run-length encoded color-mapped image RleTrueColorImage = 10, // run-length encoded true-color image RleBlackAndWhiteImage = 11 // run-length encoded black-and-white (grayscale) image } ================================================ FILE: graphics/tiny-renderer/lesson7.workbook/ImageResultHandler.csx ================================================ using XIR = Xamarin.Interactive.Representations; InteractiveAgent.RepresentationManager.AddProvider (img => { XIR.ImageFormat format; switch (img.Format) { case Format.BGRA: format = XIR.ImageFormat.Bgra32; break; case Format.BGR: format = XIR.ImageFormat.Bgr24; break; default: return null; } return new XIR.Image (format, img.buffer, img.Width, img.Height); }); ================================================ FILE: graphics/tiny-renderer/lesson7.workbook/LICENSE.txt ================================================ Tiny Renderer, https://github.com/ssloy/tinyrenderer Copyright Dmitry V. Sokolov This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. ================================================ FILE: graphics/tiny-renderer/lesson7.workbook/Matrix.csx ================================================ using System; public struct Matrix4 { public const int Len = 4; public float R0C0, R0C1, R0C2, R0C3; public float R1C0, R1C1, R1C2, R1C3; public float R2C0, R2C1, R2C2, R2C3; public float R3C0, R3C1, R3C2, R3C3; public float this [int row, int column] { get { switch (row) { case 0: switch (column) { case 0: return R0C0; case 1: return R0C1; case 2: return R0C2; case 3: return R0C3; } break; case 1: switch (column) { case 0: return R1C0; case 1: return R1C1; case 2: return R1C2; case 3: return R1C3; } break; case 2: switch (column) { case 0: return R2C0; case 1: return R2C1; case 2: return R2C2; case 3: return R2C3; } break; case 3: switch (column) { case 0: return R3C0; case 1: return R3C1; case 2: return R3C2; case 3: return R3C3; } break; } throw new IndexOutOfRangeException (); } set { switch (row) { case 0: switch (column) { case 0: R0C0 = value; return; case 1: R0C1 = value; return; case 2: R0C2 = value; return; case 3: R0C3 = value; return; } break; case 1: switch (column) { case 0: R1C0 = value; return; case 1: R1C1 = value; return; case 2: R1C2 = value; return; case 3: R1C3 = value; return; } break; case 2: switch (column) { case 0: R2C0 = value; return; case 1: R2C1 = value; return; case 2: R2C2 = value; return; case 3: R2C3 = value; return; } break; case 3: switch (column) { case 0: R3C0 = value; return; case 1: R3C1 = value; return; case 2: R3C2 = value; return; case 3: R3C3 = value; return; } break; } throw new IndexOutOfRangeException (); } } public Matrix4 Transpose () { return new Matrix4 { R0C0 = R0C0, R0C1 = R1C0, R0C2 = R2C0, R0C3 = R3C0, R1C0 = R0C1, R1C1 = R1C1, R1C2 = R2C1, R1C3 = R3C1, R2C0 = R0C2, R2C1 = R1C2, R2C2 = R2C2, R2C3 = R3C2, R3C0 = R0C3, R3C1 = R1C3, R3C2 = R2C3, R3C3 = R3C3 }; } public static Matrix4 Identity () { return new Matrix4 { R0C0 = 1, R1C1 = 1, R2C2 = 1, R3C3 = 1 }; } public static Matrix4 Zoom (float scale) { return new Matrix4 { R0C0 = scale, R1C1 = scale, R2C2 = scale, R3C3 = scale }; } public static Matrix4 RotationZ (float angle) { var cosangle = (float)Math.Cos (angle); var sinangle = (float)Math.Sin (angle); var R = Identity (); R [0, 0] = R [1, 1] = cosangle; R [0, 1] = -sinangle; R [1, 0] = sinangle; return R; } public static Matrix4 operator * (Matrix4 l, Matrix4 r) { var result = new Matrix4 (); for (int i = 0; i < Len; i++) { for (int j = 0; j < Len; j++) { result [i, j] = 0; for (int k = 0; k < Len; k++) { result [i, j] += l [i, k] * r [k, j]; } } } return result; } public override string ToString () { var sb = new System.Text.StringBuilder (); for (int r = 0; r < Len; r++) { for (int c = 0; c < Len; c++) sb.Append (this[r, c]).Append (" "); sb.AppendLine (); } return sb.ToString (); } } public struct Matrix3 { public const int Len = 3; public float R0C0, R0C1, R0C2; public float R1C0, R1C1, R1C2; public float R2C0, R2C1, R2C2; public float this [int row, int column] { get { switch (row) { case 0: switch (column) { case 0: return R0C0; case 1: return R0C1; case 2: return R0C2; } break; case 1: switch (column) { case 0: return R1C0; case 1: return R1C1; case 2: return R1C2; } break; case 2: switch (column) { case 0: return R2C0; case 1: return R2C1; case 2: return R2C2; } break; } throw new IndexOutOfRangeException (); } set { switch (row) { case 0: switch (column) { case 0: R0C0 = value; return; case 1: R0C1 = value; return; case 2: R0C2 = value; return; } break; case 1: switch (column) { case 0: R1C0 = value; return; case 1: R1C1 = value; return; case 2: R1C2 = value; return; } break; case 2: switch (column) { case 0: R2C0 = value; return; case 1: R2C1 = value; return; case 2: R2C2 = value; return; } break; } throw new IndexOutOfRangeException (); } } public Matrix3 Transpose () { return new Matrix3 { R0C0 = R0C0, R0C1 = R1C0, R0C2 = R2C0, R1C0 = R0C1, R1C1 = R1C1, R1C2 = R2C1, R2C0 = R0C2, R2C1 = R1C2, R2C2 = R2C2 }; } public void SetColumn (int col, Vec3f v) { this [0, col] = v.x; this [1, col] = v.y; this [2, col] = v.z; } public void SetRow (int row, Vec3f v) { this [row, 0] = v.x; this [row, 1] = v.y; this [row, 2] = v.z; } public override string ToString () { var sb = new System.Text.StringBuilder (); for (int r = 0; r < Len; r++) { for (int c = 0; c < Len; c++) sb.Append (this [r, c]).Append (" "); sb.AppendLine (); } return sb.ToString (); } } public struct Matrix2 { public const int Len = 2; public float R0C0, R0C1; public float R1C0, R1C1; public float this [int row, int column] { get { switch (row) { case 0: switch (column) { case 0: return R0C0; case 1: return R0C1; } break; case 1: switch (column) { case 0: return R1C0; case 1: return R1C1; } break; } throw new IndexOutOfRangeException (); } set { switch (row) { case 0: switch (column) { case 0: R0C0 = value; return; case 1: R0C1 = value; return; } break; case 1: switch (column) { case 0: R1C0 = value; return; case 1: R1C1 = value; return; } break; } throw new IndexOutOfRangeException (); } } } // we don't want to declare them in Matrix because we don't need them in lesson which introduces Matrix class static class MatrixHelpers { // For Matrix4 // how to calc inverse Matrix https://en.wikipedia.org/w/index.php?title=Invertible_matrix§ion=4#In_relation_to_its_adjugate public static Matrix4 TransposeInverse (Matrix4 m) { // returns Transpose(Inverse(m)) // where Inverse(m) = Transpose(cofactor) / det(m) // Transpose(Inverse(m)) = Transpose(Transpose(cofactor) / det(m)) = cofactor / det(m) var cofactor = Cofactor (m); float det = 0; for (int i = 0; i < Matrix4.Len; i++) det += m [0, i] * cofactor [0, i]; for (int r = 0; r < Matrix4.Len; r++) { for (int c = 0; c < Matrix4.Len; c++) cofactor [r, c] /= det; } return cofactor; } public static Matrix4 Inverse (Matrix4 m) { // where Inverse(m) = Transpose(Cofactor(m)) / det(m) var cofactor = Cofactor (m); int len = Matrix4.Len; float det = 0; for (int i = 0; i < len; i++) det += m [0, i] * cofactor [0, i]; cofactor = cofactor.Transpose (); for (int r = 0; r < len; r++) { for (int c = 0; c < len; c++) cofactor [r, c] /= det; } return cofactor; } public static Matrix3 Inverse (Matrix3 m) { // where Inverse(m) = Transpose(Cofactor(m)) / det(m) var cofactor = Cofactor (m); int len = Matrix3.Len; float det = 0; for (int i = 0; i < len; i++) det += m [0, i] * cofactor [0, i]; cofactor = cofactor.Transpose (); for (int r = 0; r < len; r++) { for (int c = 0; c < len; c++) cofactor [r, c] /= det; } return cofactor; } static Matrix4 Cofactor (Matrix4 m) { var r = new Matrix4 (); for (int row = 0; row < Matrix4.Len; row++) { for (int col = 0; col < Matrix4.Len; col++) r [row, col] = Cofactor (m, row, col); } return r; } static Matrix3 Cofactor (Matrix3 m) { var r = new Matrix3 (); for (int row = 0; row < Matrix3.Len; row++) { for (int col = 0; col < Matrix3.Len; col++) r [row, col] = Cofactor (m, row, col); } return r; } static float Cofactor (Matrix4 m, int row, int col) { int sign = ((row + col) % 2 == 0) ? 1 : -1; return Det (Minor (m, row, col)) * sign; } static float Cofactor (Matrix3 m, int row, int col) { int sign = ((row + col) % 2 == 0) ? 1 : -1; return Det (Minor (m, row, col)) * sign; } static Matrix3 Minor (Matrix4 m, int row, int col) { var minor = new Matrix3 (); for (int r = 0; r < Matrix3.Len; r++) { for (int c = 0; c < Matrix3.Len; c++) { int y = (r < row) ? r : r + 1; int x = (c < col) ? c : c + 1; minor [r, c] = m [y, x]; } } return minor; } static Matrix2 Minor (Matrix3 m, int row, int col) { var minor = new Matrix2 (); for (int r = 0; r < Matrix2.Len; r++) { for (int c = 0; c < Matrix2.Len; c++) { int y = (r < row) ? r : r + 1; int x = (c < col) ? c : c + 1; minor [r, c] = m [y, x]; } } return minor; } static float Det (Matrix3 m) { float det = 0; det += m [0, 0] * (m [1, 1] * m [2, 2] - m [1, 2] * m [2, 1]); det -= m [0, 1] * (m [1, 0] * m [2, 2] - m [1, 2] * m [2, 0]); det += m [0, 2] * (m [1, 0] * m [2, 1] - m [1, 1] * m [2, 0]); return det; } static float Det (Matrix2 m) { return m [0, 0] * m [1, 1] - m [0, 1] * m [1, 0]; } public static Vec3f Mult (Matrix3 m, Vec3f v) { return new Vec3f { x = m.R0C0 * v.x + m.R0C1 * v.y + m.R0C2 * v.z, y = m.R1C0 * v.x + m.R1C1 * v.y + m.R1C2 * v.z, z = m.R2C0 * v.x + m.R2C1 * v.y + m.R2C2 * v.z }; } public static Vec4f Mult (Matrix4 m, Vec4f v) { return new Vec4f { x = m.R0C0*v.x + m.R0C1*v.y + m.R0C2*v.z + m.R0C3*v.h, y = m.R1C0*v.x + m.R1C1*v.y + m.R1C2*v.z + m.R1C3*v.h, z = m.R2C0*v.x + m.R2C1*v.y + m.R2C2*v.z + m.R2C3*v.h, h = m.R3C0*v.x + m.R3C1*v.y + m.R3C2*v.z + m.R3C3*v.h }; } } ================================================ FILE: graphics/tiny-renderer/lesson7.workbook/Model.csx ================================================ using System.Collections.Generic; using System.Linq; struct Face { public int [] Vertices; public int [] Textures; public int [] Normals; } class Model { public List Vertices { get; } = new List (); public List Faces { get; } = new List (); public List Textures { get; } = new List (); public List Normals { get; } = new List (); public static Model FromFile (string path) { var model = new Model (); string line; using (var reader = new System.IO.StreamReader (path)) { while ((line = reader.ReadLine ()) != null) model.ParseLine (line); } Console.WriteLine ($"v#{model.Vertices.Count} f#{model.Faces.Count}"); return model; } public static Model FromText (string text) { var model = new Model (); var lines = text.Split (new char [] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); foreach (var line in lines) model.ParseLine (line); Console.WriteLine ($"v#{model.Vertices.Count} f#{model.Faces.Count}"); return model; } void ParseLine (string line) { Func parseV3f = strItems => new Vec3f { x = float.Parse (strItems [1]), y = float.Parse (strItems [2]), z = float.Parse (strItems [3]) }; var items = line.Split (new char [] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (line.StartsWith ("v ", StringComparison.InvariantCulture)) { Vertices.Add (parseV3f (items)); } else if (line.StartsWith ("vt ", StringComparison.InvariantCulture)) { Textures.Add (parseV3f (items)); } else if (line.StartsWith ("vn ", StringComparison.InvariantCulture)) { Normals.Add (parseV3f (items)); } else if (line.StartsWith ("f ", StringComparison.InvariantCulture)) { var indexes = items.Skip (1) .SelectMany (s => s.Split (new char [] { '/', ' ' }, StringSplitOptions.RemoveEmptyEntries)) .Select (s => int.Parse (s) - 1) // in wavefront obj all indices start at 1, not zero .ToArray (); Faces.Add (new Face { Vertices = indexes.Where ((v, index) => index % 3 == 0).ToArray (), Textures = indexes.Where ((v, index) => index % 3 == 1).ToArray (), Normals = indexes.Where ((v, index) => index % 3 == 2).ToArray () }); } } public Vec3f Normal (Face face, int nthvert) { int idx = face.Normals [nthvert]; return Normals [idx]; } public Vec3f Vertex (Face face, int nthvert) { int idx = face.Vertices [nthvert]; return Vertices [idx]; } public Vec3f GetUV (Face face, int nthvert) { int idx = face.Textures [nthvert]; return Textures [idx]; } } ================================================ FILE: graphics/tiny-renderer/lesson7.workbook/WpfImageResultHandler.csx ================================================ using System; using System.IO; using System.Windows.Media; using System.Windows.Media.Imaging; using XIR = Xamarin.Interactive.Representations; static PixelFormat ConvertFormat (Format format) { switch (format) { case Format.BGRA: return PixelFormats.Bgra32; case Format.GRAYSCALE: return PixelFormats.Gray8; case Format.BGR: default: return PixelFormats.Bgr24; } } InteractiveAgent.RepresentationManager.AddProvider (img => { var source = BitmapSource.Create (img.Width, img.Height, 96, 96, ConvertFormat (img.Format), null, img.buffer, img.BytesPerRow); var encoder = new PngBitmapEncoder (); var outputFrame = BitmapFrame.Create (source); encoder.Frames.Add (outputFrame); using (var memory = new MemoryStream ()) { encoder.Save (memory); return XIR.Image.FromPng (memory.GetBuffer (), img.Width, img.Height); } }); ================================================ FILE: graphics/tiny-renderer/lesson7.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Matrix.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" #load "lesson1.csx" #load "lesson2.csx" #load "lesson3.csx" #load "lesson4.csx" #load "lesson5.csx" #load "lesson6.csx" #load "lesson6bis.csx" using static Geometry; using static MatrixHelpers; using static ShaderUtils; ``` # Lesson 7: Shadow mapping > ℹ️ This workbook is a port of an [excellent C++ series](https://github.com/ssloy/tinyrenderer/wiki) written by Dmitry Sokolov. We appreciate that original work is available under a license that allowed us to turn it into a Workbook. # **The goal** Well, we are approaching the end of your short course of CG lectures. The goal for today is to compute shadows. **Attention, we are talking about hard shadows here, soft shadows computation is another story.** # **Problem statement** Up to this moment convex objects were shaded correctly by our simple local shading. Local means computation with light direction and the normal vector. Unfortunately, it does not produce correct results for non-convex objects. Here is the image we can got during previous lesson: ```csharp var shader = new TangentShader (diabloModel, viewPort, projection, modelView, light_dir, diabloTexture, diabloTangentMap); var image = Render (diabloModel, shader).Image; image.VerticalFlip(); image ``` Why do not we see a shadow from his horns? Not good. The idea is really simple: we will do a two-pass rendering. First time we will render the image placing the camera at the light source position. It will allow to determine what parts are lit and what parts are hidden from the light. Then in the second pass we do a render taking in account the visibility information. Almost no difficulties here. Let us use this shader: ```csharp class DepthShader : IShader { const float depth = 255f; Matrix3 varyingTri; readonly Model model; readonly Matrix4 transformation; public DepthShader (Model model, Matrix4 transformation) { this.model = model; this.transformation = transformation; } public Vec4f Vertex (Face face, int nthvert) { var glVertex = TransformFace (model, face, nthvert, transformation); varyingTri.SetColumn (nthvert, Project3D (glVertex / glVertex.h)); return glVertex; } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { var p = Mult (varyingTri, bar); color = Color.White * (p.z / depth); return false; } } ``` This shader simply copies the z-buffer into the framebuffer. Here is how it I call it: ```csharp var model = diabloModel; var modelView = LookAt (eye, center, up); var viewPort = Viewport (width / 8, height / 8, width * 3 / 4, height * 3 / 4); var projection = Projection (-1f / (eye - center).Norm ()); var M = viewPort * Projection (0) * LookAt (light_dir, center, up); var depthShader = new DepthShader (model, M); var step1 = Render (model, depthShader); step1.Image.VerticalFlip (); step1.Image ``` I put the camera at the light source position LookAt (light_dir, center, up) and then perform the render. Note that I keep the z-buffer, it is pointed by the **step1.ZBuffer** reference. Also it is useful to note line where I keep the object-to-screen transformation matrix. The second pass is naturally made with another shader: ```csharp class ShadowShader : IShader { Vec3f varyingU = new Vec3f (); Vec3f varyingV = new Vec3f (); Matrix3 varyingTri; readonly Model model; readonly Vec3f lightDir; readonly Matrix4 uniformM; readonly Matrix4 uniformMIT; // transform framebuffer screen coordinates to shadowbuffer screen coordinates readonly Matrix4 uniformShadow; readonly Matrix4 transformation; readonly Image texture; readonly Image normalMap; readonly Image specularMap; readonly float[] shadowbuffer; readonly int width; public ShadowShader (Model model, Matrix4 viewport, Matrix4 projection, Matrix4 modelView, Matrix4 uniformShadow, Vec3f lightDir, Image texture, Image normalMap, Image specularMap, float[] shadowbuffer, int width) { this.model = model; this.lightDir = lightDir.Normalize (); this.texture = texture; this.normalMap = normalMap; this.specularMap = specularMap; this.shadowbuffer = shadowbuffer; this.width = width; uniformM = projection * modelView; uniformMIT = TransposeInverse (uniformM); transformation = viewport * uniformM; this.uniformShadow = uniformShadow; } public Vec4f Vertex (Face face, int nthvert) { UpdateVarayingUV (model, face, nthvert, ref varyingU, ref varyingV); var glVertex = TransformFace (model, face, nthvert, transformation); varyingTri.SetColumn (nthvert, Project3D (glVertex / glVertex.h)); return glVertex; } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { // corresponding point in the shadow buffer var sb_p = Mult (uniformShadow, Embed4D (Mult (varyingTri, bar))); sb_p = sb_p / sb_p.h; int idx = (int)sb_p.x + (int)sb_p.y * width; // index in the shadowbuffer array float shadow = 0.3f + 0.7f * (shadowbuffer [idx] < sb_p.z + 3.5f ? 1f : 0f); var uv = CalcUV (varyingU, varyingV, bar); var n = Transform (uniformMIT, Normal (normalMap, uv)).Normalize (); var l = Transform (uniformM, lightDir).Normalize (); var r = (n * (2 * Dot (n, l)) - l).Normalize (); var diff = Math.Max (0f, Dot (n, l)); var specular = Math.Pow (Math.Max (0f, r.z), Specular (specularMap, uv) + 15); color = GetColor (texture, uv); int v = 0; for (int i = 0; i < 4; i++) v = (v <<= 8) | (byte)Math.Min (255, (int)(5 + color [i] * shadow * (diff + 1.3f * specular))); color = new Color (v, color.format); return false; } } ``` It is a copy of the final shader from the previous lesson with one exception: I declared a constant matrix `Matrix4 uniformShadow`, it allows me to transform screen coordinates of current fragment into screen coordinates inside the shadowbuffer! I'll explain how it is computed a bit later, let us see how I use it: ```csharp /* var sb_p = Mult (uniformShadow, Embed4D (Mult (varyingTri, bar))); sb_p = sb_p / sb_p.h; int idx = (int)sb_p.x + (int)sb_p.y * width; // index in the shadowbuffer array var depth = 255 * shadowbuffer [idx]; float shadow = 0.3f + 0.7f * ((depth < sb_p.z ? 1f : 0f)); */ ``` `Mult (varyingTri, bar)` provides me screen coordinates of the pixel we currently draw; we augment it with 1 (recall the homogeneous coordinates stuff), then transform it with the magic matrix `uniformShadow` and ta-da! We know xyz coordinates in the shadow buffer space. Now to determine whether the current pixel is lit or no it suffices to compare its z-coordinate with the value we stored in the shadow buffer. Let me show you how I call the shader: ```csharp var shadowM = M * Inverse (viewPort * projection * modelView); var shader = new ShadowShader (model, viewPort, projection, modelView, shadowM, light_dir, diabloTexture, diabloNormalMap, diabloSpecularMap, step1.ZBuffer, width); var step2 = Render (model, shader); step2.Image.VerticalFlip (); step2.Image ``` Notice the `sb_p.z + 3.5` in fragment shader? This magic coefficient needed to get rig of artifact is known as the [z-fighting](http://en.wikipedia.org/wiki/Z-fighting). Resolution of our buffers is insufficient to obtain precise results. Try to delete `+ 3.5f` and you will notice ugly shadow rendering. I simply move a bit one z-buffer with respect to another, it is sufficient to remove the artifact. Yes, it creates other problems (can you tell which ones?), but those are generally less visible. The final render is visible in the teaser image. ================================================ FILE: graphics/tiny-renderer/lesson7.workbook/lesson1.csx ================================================ int width = 800; int height = 800; var headModel = Model.FromFile ("obj/african_head.obj"); static void Swap(ref T x, ref T y) { T t = y; y = x; x = t; } static void Swap(T[] arr, int x, int y) { T t = arr[y]; arr[y] = arr[x]; arr[x] = t; } Image Line (Image image, int x0, int y0, int x1, int y1, Color color) { bool steep = false; // if the line is steep, we transpose the image if (Math.Abs (x0-x1) < Math.Abs (y0-y1)) { Swap (ref x0, ref y0); Swap (ref x1, ref y1); steep = true; } if (x0 > x1) { // make it left to right Swap (ref x0, ref x1); Swap (ref y0, ref y1); } // (x0, y0) == (x1, y1) if(x0 == x1) { image [x0, y0] = color; } else { for (int x = x0; x <= x1; x++) { double t = (x-x0) / (double)(x1-x0); int y = (int)Math.Round(y0*(1-t) + y1*t); if (steep) image [y, x] = color; else image [x, y] = color; } } return image; } ================================================ FILE: graphics/tiny-renderer/lesson7.workbook/lesson1.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" ``` # **Lesson 1: Bresenham’s Line Drawing Algorithm** # First attempt The goal of the first lesson is to render the wire mesh. To do this, we should learn how to draw line segments. We can simply read what Bresenham’s line algorithm is, but let’s write code ourselves. How does the simplest code that draws a line segment between `(x0, y0)` and `(x1, y1)` points look like? Apparently, something like this: ```csharp Image Line (Image image, int x0, int y0, int x1, int y1, Color color) { for (double t = 0; t < 1; t += 0.01) { int x = (int) (x0 * (1-t) + x1 * t); int y = (int) (y0 * (1-t) + y1 * t); image [x, y] = color; } return image; } Line (new Image (100, 100, Format.BGR), x0: 13, y0: 20, x1: 80, y1: 40, color: Color.White); ``` # Second attempt The problem with this code (in addition to efficiency) is the choice of the constant, which I took equal to .01. If we take it equal to .1, our line segment will look like this: ```csharp Image Line (Image image, int x0, int y0, int x1, int y1, Color color) { for (int x = x0; x <= x1; x++) { double t = (x-x0)/(double)(x1-x0); int y = (int)(y0*(1-t) + y1*t); image [x, y] = color; } return image; } Line (new Image (100, 100, Format.BGR), x0: 13, y0: 20, x1: 80, y1: 40, color: Color.White); ``` Caution! The first source of errors in such code of my students is the integer division, like: `(x-x0)/(x1-x0)`. Then, if we try to draw the following lines with this code: ```csharp var image = new Image (100, 100, Format.BGR); Line(image, x0: 13, y0: 20, x1: 80, y1: 40, color: Color.White); Line(image, x0: 20, y0: 13, x1: 40, y1: 80, color: Color.Red); Line(image, x0: 80, y0: 40, x1: 13, y1: 20, color: Color.Red); ``` It turns out that one line is good, the second one is with holes, and there’s no third line at all. Note that the first and the third lines (in the code) draw the same line in different colors, and in different directions (with the source and target points flipped). We have already seen the white one, it is drawn well. I was hoping to change the color of the white line to red, but could not do it. It’s a test for symmetry: the result of drawing a line segment should not depend on the order of points: the `(a,b)` line segment should be exactly the same as the `(b,a)` line segment. # Third attempt We fix the missing red line by swapping the points so `x0` is always lower than `x1`. There are holes in one of the line segments due to the fact that its height is greater than the width. My students often suggest the following fix: `if (dx > dy) { for (int x) } else { for (int y) }` Holy cow! ```csharp static void Swap(ref T x, ref T y) { T t = y; y = x; x = t; } static void Swap(T[] arr, int x, int y) { T t = arr[y]; arr[y] = arr[x]; arr[x] = t; } Image Line (Image image, int x0, int y0, int x1, int y1, Color color) { bool steep = false; // if the line is steep, we transpose the image if (Math.Abs (x0-x1) < Math.Abs (y0-y1)) { Swap (ref x0, ref y0); Swap (ref x1, ref y1); steep = true; } if (x0 > x1) { // make it left to right Swap (ref x0, ref x1); Swap (ref y0, ref y1); } // (x0, y0) == (x1, y1) if(x0 == x1) { image [x0, y0] = color; } else { for (int x = x0; x <= x1; x++) { double t = (x-x0) / (double)(x1-x0); int y = (int)Math.Round(y0*(1-t) + y1*t); if (steep) image [y, x] = color; else image [x, y] = color; } } return image; } Line(image, x0: 13, y0: 20, x1: 80, y1: 40, color: Color.White); Line(image, x0: 20, y0: 13, x1: 40, y1: 80, color: Color.Red); Line(image, x0: 80, y0: 40, x1: 13, y1: 20, color: Color.Red); ``` # Wireframe rendering So now we are ready to create a wire render. You can find the snapshot of the code and the test model here. I used the [wavefront obj](http://en.wikipedia.org/wiki/Wavefront_.obj_file) format of the file to store model. All we need for the render is read from the file the array of vertices of the following type: `v 0.608654 -0.568839 -0.416318` are `x,y,z` coordinates, one vertex per file line and faces `f 1193/1240/1193 1180/1227/1180 1179/1226/1179` ```csharp int width = 800, height = 800; var headModel = Model.FromFile ("obj/african_head.obj"); var image = new Image(width, height, Format.BGR); foreach(var face in headModel.Faces) { for(int j=0; j<3; j++) { var v0 = headModel.Vertices[face.Vertices [j]]; var v1 = headModel.Vertices[face.Vertices [(j+1) % 3]]; // scale x from [-1..1] to [0..w] // scale y from [-1..1] to [0..h] int x0 = (int)((v0.x + 1) * width / 2); int y0 = (int)((v0.y + 1) * height / 2); int x1 = (int)((v1.x + 1) * width / 2); int y1 = (int)((v1.y + 1) * height / 2); Line(image, x0, y0, x1, y1, Color.White); } } image.VerticalFlip (); image ``` ================================================ FILE: graphics/tiny-renderer/lesson7.workbook/lesson2.csx ================================================ using static Geometry; var light_dir = new Vec3f { x = 0, y = 0, z = -1 }; var world = new Vec3f [3]; var screen = new Vec3f [3]; void Line (Image image, Vec2i p1, Vec2i p2, Color color) { Line(image, p1.x, p1.y, p2.x, p2.y, color); } void Line (Image image, Vec3f p1, Vec3f p2, Color color) { Line(image, (int)p1.x, (int)p1.y, (int)p2.x, (int)p2.y, color); } void Triangle (Image image, Vec2i[] t, Color color) { Line(image, t[0], t[1], color); Line(image, t[1], t[2], color); Line(image, t[2], t[0], color); } Vec3f Barycentric (Vec3f a, Vec3f b, Vec3f c, Vec2i p) { var pixel = new Vec3f { x = p.x + 0.5f, y = p.y + 0.5f }; var ab = b - a; var ac = c - a; var pa = a - pixel; var r = Cross (new Vec3f { x = ab.x, y = ac.x, z = pa.x }, new Vec3f { x = ab.y, y = ac.y, z = pa.y }); // triangle is degenerate, in this case return smth with negative coordinates if (Math.Abs (r.z) < 1) return new Vec3f { x = -1, y = 1, z = 1 }; return new Vec3f { x = 1 - r.x / r.z - r.y / r.z, y = r.x / r.z, z = r.y / r.z }; } void Triangle (Image image, Vec3f [] coordinates, Color color) { var t0 = coordinates [0]; var t1 = coordinates [1]; var t2 = coordinates [2]; var pMax = new Vec2i { x = (int)Math.Max (0, Math.Max (t0.x, Math.Max (t1.x, t2.x))), y = (int)Math.Max (0, Math.Max (t0.y, Math.Max (t1.y, t2.y))) }; var pMin = new Vec2i { x = (int)Math.Min (image.Width, Math.Min (t0.x, Math.Min (t1.x, t2.x))), y = (int)Math.Min (image.Height, Math.Min (t0.y, Math.Min (t1.y, t2.y))) }; Vec2i p; for (p.x = pMin.x; p.x <= pMax.x; p.x++) { for (p.y = pMin.y; p.y <= pMax.y; p.y++) { var bc = Barycentric (t0, t1, t2, p); if (bc.x < 0 || bc.y < 0 || bc.z < 0) continue; image [p.x, p.y] = color; } } } ================================================ FILE: graphics/tiny-renderer/lesson7.workbook/lesson2.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" #load "lesson1.csx" using static Geometry; ``` # Lesson 2: Triangle rasterization and back face culling # Old-school method: Line sweeping Thus, the task is to draw two-dimensional triangles. For motivated students it normally takes a couple of hours, even if they are bad programmers. Last time we saw Bresenham’s line drawing algorithm. Today’s task is to draw a filled triangle. Funny enough, but this task is not trivial. I don’t know why, but I know that it’s true. Most of my students struggle with this simple task. So, the initial stub will look like this: ```csharp void Line (Image image, Vec2i p1, Vec2i p2, Color color) { Line(image, p1.x, p1.y, p2.x, p2.y, color); } void Line (Image image, Vec3f p1, Vec3f p2, Color color) { Line(image, (int)p1.x, (int)p1.y, (int)p2.x, (int)p2.y, color); } void Triangle (Image image, Vec2i[] t, Color color) { Line(image, t[0], t[1], color); Line(image, t[1], t[2], color); Line(image, t[2], t[0], color); } Vec2i[] t0 = { new Vec2i { x = 10, y = 70 }, new Vec2i { x = 50, y = 160 }, new Vec2i { x = 70, y = 80 } }; Vec2i[] t1 = { new Vec2i { x = 180, y = 50 }, new Vec2i { x = 150, y = 1 }, new Vec2i { x = 70, y = 180 } }; Vec2i[] t2 = { new Vec2i { x = 180, y = 150 }, new Vec2i { x = 120, y = 160 }, new Vec2i { x = 130, y = 180 } }; var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); image.VerticalFlip (); image ``` The code is simple: I provide three triangles for the initial debugging of your code. If we invoke `Line` inside the triangle function, we’ll get the contour of the triangle. How to draw a filled triangle? A good method of drawing a triangle must have the following features: * It should be (surprise!) simple and fast. * It should be symmetrical: the picture should not depend on the order of vertices passed to the drawing function. * If two triangles have two common vertices, there should be no holes between them because of rasterization rounding. We could add more requirements, but let’s do with these ones. Traditionally a line sweeping is used: 1. Sort vertices of the triangle by their y-coordinates 2. Rasterize simultaneously the left and the right sides of the triangle 3. Draw a horizontal line segment between the left and the right boundary points At this point my students start to lose the firm ground: which segment is the left one, which one is right? Besides, there are three segments in a triangle... Usually, after this introduction I leave my students for about an hour: once again, reading my code is much less valuable than comparing your own code with mine. `[One hour passes]` How do I draw a triangle? Once again, if you have a better method, I’d be glad to adopt it. Let us assume that we have three points of the triangle: `t0`, `t1`, `t2`, they are sorted in ascending order by the y-coordinate. Then, the boundary A is between `t0` and `t2`, boundary B is between `t0` and `t1`, and then between `t1` and `t2`. ```csharp void OrderByY (Vec2i[] t) { if(t[0].y > t[1].y) Swap(t, 0, 1); if(t[1].y > t[2].y) Swap(t, 1, 2); if(t[0].y > t[1].y) Swap(t, 0, 1); } void Triangle (Image image, Vec2i[] t, Color color) { OrderByY(t); Line(image, t[0], t[1], Color.Green); Line(image, t[1], t[2], Color.Green); Line(image, t[2], t[0], Color.Red); } var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); // Here boundary A is red, and boundary B is green. image.VerticalFlip (); image ``` Unfortunately, boundary B is made of two parts. Let us draw the bottom half of the triangle by cutting it horizontally: ```csharp void Triangle (Image image, Vec2i[] t, Color color) { OrderByY(t); float height_10 = t[1].y - t[0].y; float height_20 = t[2].y - t[0].y; for(int y=t[0].y; y<=t[1].y; y++) { var alpha = (y-t[0].y) / height_20; var beta = (y-t[0].y) / height_10; // be careful with divisions by zero Vec2i A = new Vec2i { x = t[0].x + (int)((t[2].x-t[0].x)*alpha), y = y}; Vec2i B = new Vec2i { x = t[0].x + (int)((t[1].x-t[0].x)*beta), y = y}; image[A.x, y] = Color.Red; image[B.x, y] = Color.Green; } } var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); image.VerticalFlip (); image ``` Note that the segments are not continuous. Last time when we drew straight lines we struggled to get continuous segments and here I did not bother with rotating the image (remember the xy swapping?). Why? We fill the triangles aftewards, that’s why. If we connect the corresponding pairs of points by horizontal lines, the gaps disappear: ```csharp void Triangle (Image image, Vec2i[] t, Color color) { OrderByY(t); float height_10 = t[1].y - t[0].y; float height_20 = t[2].y - t[0].y; for(int y=t[0].y; y<=t[1].y; y++) { var alpha = (y-t[0].y) / height_20; var beta = (y-t[0].y) / height_10; // be careful with divisions by zero Vec2i A = new Vec2i { x = t[0].x + (int)((t[2].x-t[0].x)*alpha), y = y}; Vec2i B = new Vec2i { x = t[0].x + (int)((t[1].x-t[0].x)*beta), y = y}; Line(image, A, B, Color.White); image[B.x, y] = Color.Green; image[A.x, y] = Color.Red; } } var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); image.VerticalFlip (); image ``` Now, let us draw the second (upper) half of the triangle. We can do this by adding a second loop: ```csharp void Triangle (Image image, Vec2i[] t, Color color) { OrderByY(t); float height_10 = t[1].y - t[0].y; float height_20 = t[2].y - t[0].y; for(int y=t[0].y; y<=t[1].y; y++) { var alpha = (y-t[0].y) / height_20; var beta = (y-t[0].y) / height_10; // be careful with divisions by zero Vec2i A = new Vec2i { x = t[0].x + (int)((t[2].x-t[0].x)*alpha), y = y}; Vec2i B = new Vec2i { x = t[0].x + (int)((t[1].x-t[0].x)*beta), y = y}; if(A.x > B.x) Swap(ref A, ref B); for (int j=A.x; j<=B.x; j++) image[j, y] = color; } float height_21 = t[2].y - t[1].y; for(int y=t[1].y; y<=t[2].y; y++) { var alpha = (y-t[0].y) / height_20; var beta = (y-t[1].y) / height_21; // be careful with divisions by zero Vec2i A = new Vec2i { x = t[0].x + (int)((t[2].x-t[0].x)*alpha), y = y}; Vec2i B = new Vec2i { x = t[1].x + (int)((t[2].x-t[1].x)*beta), y = y}; if(A.x > B.x) Swap(ref A, ref B); for (int j=A.x; j<=B.x; j++) image[j, y] = color; } } var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); image.VerticalFlip (); image ``` This could be enough, but I dislike to see the same code twice. That is why we will make it a bit less readable, but more handy for modifications/maintaining: ```csharp void Triangle (Image image, Vec2i[] t, Color color) { // I dont care about degenerate triangles if(t[0].y == t[1].y && t[1].y == t[2].y) return; OrderByY(t); float height_10 = t[1].y - t[0].y; float total_height = t[2].y - t[0].y; for(int i=0; i t[1].y - t[0].y || t[1].y == t[0].y; float segment_height = second_half ? t[2].y-t[1].y : t[1].y-t[0].y; var alpha = i / total_height; // be careful with divisions by zero var beta = (i - (second_half ? t[1].y-t[0].y : 0)) / segment_height; Vec2i A = new Vec2i { x = t[0].x + (int)((t[2].x-t[0].x)*alpha), y = t[0].y + i }; Vec2i B = new Vec2i { x = second_half ? t[1].x + (int)((t[2].x-t[1].x)*beta) : t[0].x + (int)((t[1].x-t[0].x)*beta), y = t[0].y + i }; if(A.x > B.x) Swap(ref A, ref B); for (int j=A.x; j<=B.x; j++) image[j, t[0].y + i] = color; } } var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); image.VerticalFlip (); image ``` # The method I adopt for my code While not being really complicated, the source code for the line sweeping is a bit messy. Moreover, it is really an old-school approach designed for mono-thread CPU programming. Let us take a look at the following pseudo-code: ```csharp // triangle(Vec2i[] points) { // Vec2i bbox[2] = find_bounding_box(points); // for (each pixel in the bounding box) { // if (inside(points, pixel)) { // put_pixel(pixel); // } // } // } ``` Do you like it? I do. It is really easy to find a bounding box. It is certainly no problem to check whether a point belongs a 2D triangle (or any convex polygon). *Off Topic: if I have to implement some code to check whether a point belongs to a polygon, and this program will run on a plane, I will never get on this plane. Turns out, it is a surprisingly difficult task to solve this problem reliably. But here we just painting pixels. I am okay with that.* There is another thing I like about this pseudocode: a neophyte in programming accepts it with enthusiasm, more experienced programmers often chuckle: “*What an idiot wrote it?*”. And an expert in computer graphics programming will shrug his shoulders and say: “*Well, that’s how it works in real life*”. Massively parallel computations in thousands of threads (i’m talking about regular consumer computers here) change the way of thinking. Okay, let us start: first of all we need to know what the [barycentric coordinates](https://en.wikipedia.org/wiki/Barycentric_coordinate_system) are. Given a 2D triangle ABC and a point P, all in old good Cartesian coordinates `(xy)`. Our goal is to find barycentric coordinates of the point P with respect to the triangle ABC. It means that we look for three numbers `(1 − u − v,u,v)` such that we can find the point P as follows: ![ ](./img/lesson2_f1.png) While being a bit frightening at the first glance, it is really simple: imagine that we put three weights `(1−u−v,u,v)` at the vertices A, B and C, respectively. Then the barycenter of the system is exactly in the point P. We can say the same thing with other words: the point P has coordinates `(u,v)` in the (oblique) basis (A,![](./img/lesson2_ab.png),![](./img/lesson2_ac.png)): ![ ](./img/lesson2_f2.png) So, we have vectors ![](./img/lesson2_ab.png), ![](./img/lesson2_ac.png) and ![](./img/lesson2_ap.png), we need to find two real numbers u and v respecting the following constraint: ![ ](./img/lesson2_f3.png) It is a simple vector equation, or a linear system of two equations with two variables: ![ ](./img/lesson2_f4.png) I am lazy and do not want to solve linear systems in a scholar way. Let us write it in matrix form: ![ ](./img/lesson2_f5.png) It means that we are looking for a vector `(u,v,1)` that is orthogonal to `(ABx,ACx,PAx)` and `(ABy,ACy,PAy)` *at the same time*! I hope you see [where I am heading](https://en.wikipedia.org/wiki/Cross_product). That is a small hint: to find an intersection of two straight lines in a plane (that is exactly what we did here), it is sufficient to compute one cross product. By the way, test yourself: how do we find an equation of a line passing through two given points? So, let us program our new rasterization routine: we iterate through all pixels of a bounding box for a given triangle. For each pixel we compute its barycentric coordinates. If it has at least one negative component, then the pixel is outside of the triangle. Probably it is more clear to see the program directly: ```csharp Vec3f Barycentric (Vec3f a, Vec3f b, Vec3f c, Vec2i p) { var pixel = new Vec3f { x = p.x + 0.5f, y = p.y + 0.5f }; var ab = b - a; var ac = c - a; var pa = a - pixel; var r = Cross (new Vec3f { x = ab.x, y = ac.x, z = pa.x }, new Vec3f { x = ab.y, y = ac.y, z = pa.y }); // triangle is degenerate, in this case return smth with negative coordinates if (Math.Abs (r.z) < 1) return new Vec3f { x = -1, y = 1, z = 1 }; return new Vec3f { x = 1 - r.x / r.z - r.y / r.z, y = r.x / r.z, z = r.y / r.z }; } void Triangle (Image image, Vec3f [] coordinates, Color color) { var t0 = coordinates [0]; var t1 = coordinates [1]; var t2 = coordinates [2]; var pMax = new Vec2i { x = (int)Math.Max (0, Math.Max (t0.x, Math.Max (t1.x, t2.x))), y = (int)Math.Max (0, Math.Max (t0.y, Math.Max (t1.y, t2.y))) }; var pMin = new Vec2i { x = (int)Math.Min (image.Width, Math.Min (t0.x, Math.Min (t1.x, t2.x))), y = (int)Math.Min (image.Height, Math.Min (t0.y, Math.Min (t1.y, t2.y))) }; Vec2i p; for (p.x = pMin.x; p.x <= pMax.x; p.x++) { for (p.y = pMin.y; p.y <= pMax.y; p.y++) { var bc = Barycentric (t0, t1, t2, p); if (bc.x < 0 || bc.y < 0 || bc.z < 0) continue; image [p.x, p.y] = color; } } } ``` # Flat shading render We already know how to draw a model with empty triangles. Let us fill them with a random color. This will help us to see how well we have encoded filling of triangles. Here is the code: ```csharp var image = new Image(width, height, Format.BGR); // Map world coordinates [-1..-1] to screen coordinates [0..width] Func map = v => new Vec3f { x = (int)((v.x+1)*image.Width/2), y = (int)((v.y+1)*image.Height/2) }; var rnd = new Random(); Func rndByte = () => (byte)rnd.Next(255); Func rndColor = () => new Color(rndByte(), rndByte(), rndByte()); var coordinates = new Vec3f[3]; foreach(var face in headModel.Faces) { for(int i=0; i<3; i++) { var vIndex = face.Vertices[i]; var v = headModel.Vertices[vIndex]; coordinates[i] = map(v); } Triangle(image, coordinates, rndColor()); } image.VerticalFlip (); image ``` Let us get rid of these clown-colors and put some lighting. Captain Obvious: ”*At the same light intensity, the polygon is illuminated most brightly when it is orthogonal to the light direction.*” Let us compare: ![ ](./img/lesson2_light1.jpeg) ![](./img/lesson2_light2.jpeg) We get zero illumination if the polygon is parallel to the vector of light. To paraphrase: the intensity of illumination is equal to the scalar product of the light vector and the normal to the given triangle. The normal to the triangle can be calculated simply as the [cross product](https://en.wikipedia.org/wiki/Cross_product) of its two sides. As a side note, at this course we will perform linear computations on the colors. However `(128,128,128)` color is not half as bright as `(255, 255, 255)`. We are going to ignore gamma correction and tolerate the incorrectness of the brightness of our colors. ```csharp var image = new Image (width, height, Format.BGR); var light_dir = new Vec3f { x = 0, y = 0, z = -1 }; var world = new Vec3f [3]; var screen = new Vec3f [3]; foreach (var face in headModel.Faces) { for (int i = 0; i < 3; i++) { var vIndex = face.Vertices [i]; world [i] = headModel.Vertices [vIndex]; screen [i] = map (world [i]); } var n = Cross (world [2] - world [0], world [1] - world [0]).Normalize (); var intensivity = Dot (n, light_dir); if (intensivity > 0) Triangle (image, screen, Color.White * intensivity); } image.VerticalFlip (); image ``` ================================================ FILE: graphics/tiny-renderer/lesson7.workbook/lesson3.csx ================================================ using static Geometry; var headTexture = Image.Load ("obj/african_head_diffuse.tga"); headTexture.VerticalFlip (); float [] InitZBuffer (Image image) { var zbuffer = new float [image.Width * image.Height]; for (int idx = 0; idx < zbuffer.Length; idx++) zbuffer [idx] = float.NegativeInfinity; return zbuffer; } Vec3f Barycentric (Vec2f a, Vec2f b, Vec2f c, Vec2f p) { var ab = b - a; var ac = c - a; var pa = a - p; var r = Cross (new Vec3f { x = ab.x, y = ac.x, z = pa.x }, new Vec3f { x = ab.y, y = ac.y, z = pa.y }); // triangle is degenerate, in this case return smth with negative coordinates // dont forget that r.z is integer. If it is zero then triangle ABC is degenerate if ((int)r.z == 0) return new Vec3f { x = -1, y = 1, z = 1 }; return new Vec3f { x = 1 - (r.x + r.y) / r.z, y = r.x / r.z, z = r.y / r.z }; } void Triangle (Image image, Vec3f [] coordinates, Image texture, Vec2f [] uv, float intensivity, float [] zbuffer) { Vec3f t0 = coordinates [0]; Vec3f t1 = coordinates [1]; Vec3f t2 = coordinates [2]; var pMax = new Vec2i { x = (int)Math.Max (0, Math.Max (t0.x, Math.Max (t1.x, t2.x))), y = (int)Math.Max (0, Math.Max (t0.y, Math.Max (t1.y, t2.y))) }; var pMin = new Vec2i { x = (int)Math.Min (image.Width, Math.Min (t0.x, Math.Min (t1.x, t2.x))), y = (int)Math.Min (image.Height, Math.Min (t0.y, Math.Min (t1.y, t2.y))) }; for (int x = pMin.x; x <= pMax.x; x++) { for (int y = pMin.y; y <= pMax.y; y++) { var pixelCenter = new Vec2f { x = x + 0.5f, y = y + 0.5f }; var bc = Barycentric (Project2D(t0), Project2D(t1), Project2D(t2), pixelCenter); if (bc.x < 0 || bc.y < 0 || bc.z < 0) continue; var z = t0.z * bc.x + t1.z * bc.y + t2.z * bc.z; var u = (int)(uv [0].x * bc.x + uv [1].x * bc.y + uv [2].x * bc.z); var v = (int)(uv [0].y * bc.x + uv [1].y * bc.y + uv [2].y * bc.z); var idx = x + y * image.Width; if (zbuffer [idx] < z) { zbuffer [idx] = z; var color = texture [u, v]; image [x, y] = color * intensivity; } } } } ================================================ FILE: graphics/tiny-renderer/lesson7.workbook/lesson3.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" #load "lesson1.csx" #load "lesson2.csx" using static Geometry; ``` # **Lesson 3: Hidden faces removal (z buffer)** # Introduction Hello, let me introduce you my friend z-buffer of a black guy. He will help us get rid of the visual artifacts of the hidden faces removal we had during the last lesson. ![](./img/lesson3_face1.png) By the way, i'd like to mention that this model i use heavily in the course is created by [Vidar Rapp](https://se.linkedin.com/in/vidarrapp). He kindely granted me a permission to use it for teaching rendering basics and i vandalized it, but i promise you to give back the eyes to the guy. Well, back to the topic, in theory we could just draw all the triangles without discarding any. If we do it properly starting rear-to-front, the front facets will erase the back ones. It is called the [painter's algorithm](http://en.wikipedia.org/wiki/Painter%27s_algorithm). Unfortunately, it comes along with a high computational cost: for each camera movement we need to re-sort all the scene. And then there are dynamic scenes... And this is not even the main problem. The main problem is it is not always possible to determine the correct order. # **Let us try to render a simple scene** Imagine a simple scene made of three triangles: the camera looks up-to-down, we project the colored triangles onto the white screen: ![ ](./img/lesson3_scene1.png) The render should look like this: ![ ](./img/lesson3_scene2.png) Blue facet - is it behind or in front of the red one? The painter's algorithm does not work here. It is possible to split blue facet in two (one in front of the red facet and one behind). And then the one in front of the red one is to be split in two - one in front of the green triangle and one behind... I think you get the problem: in scenes with millions of triangles it is really expensive to compute. It is possible to use [BSP trees](https://en.wikipedia.org/wiki/Binary_space_partitioning) to get it done. By the way, this data structure is constant for moving camera, but it is really messy. And the life is too short to get it messy. # **Even simpler: let us lose a dimension. Y-buffer!** Let us lose a dimension for a while and to cut the above scene along the yellow plane: ![ ](./img/lesson3_scene3.png) I mean, now our scene is made of three line segments (intersection of the yellow plane and each of the triangles), and the final render has a normal width but 1 pixel height: ![ ](./img/lesson3_scene4.png) Our scene is two-dimensional, so it is easy to draw it using the line() function we programmed in the very first lesson. ```csharp var scene = new Image (800, 500, Format.BGR); // scene "2d mesh" Line(scene, new Vec2i {x=20, y=34}, new Vec2i {x=744, y=400}, Color.Red); Line(scene, new Vec2i {x=120, y=434}, new Vec2i {x=444, y=400}, Color.Green); Line(scene, new Vec2i {x=330, y=463}, new Vec2i {x=594, y=200}, Color.Blue); // screen line Line(scene, new Vec2i {x=10, y=10}, new Vec2i{x=790, y=10}, Color.White); scene.VerticalFlip(); // I want to have the origin at the left bottom corner of the image scene // This is how our 2D scene looks like if we look at it sideways: ``` Let us render it. Recall that the render is 1 pixel height. In my source code I create images 16 pixels height for the ease of reading on high resolution screens. `Rasterize()` function writes only in the first line of the image `render` ```csharp void Rasterize(Image image, Vec2i p0, Vec2i p1, int[] ybuffer, Color color) { if (p0.x>p1.x) Swap(ref p0, ref p1); for (int x=p0.x; x<=p1.x; x++) { float t = (x-p0.x)/(float)(p1.x-p0.x); var y = (int)(p0.y*(1-t) + p1.y*t); if (ybuffer[x] < y) { ybuffer[x] = y; image[x, 0] = color; } } } var ybuffer = new int [width]; for (int i = 0; i < width; i++) ybuffer[i] = int.MinValue; var render = new Image (width, 16, Format.BGR); Rasterize(render, new Vec2i{x=20,y=34}, new Vec2i{x=744, y=400}, ybuffer, Color.Red); Rasterize(render, new Vec2i{x=120, y=434}, new Vec2i{x=444,y=400}, ybuffer, Color.Green); Rasterize(render, new Vec2i{x=330, y=463}, new Vec2i{x=594,y=200}, ybuffer, Color.Blue); render ``` It is really-really simple: I iterate through all x-coordinates between `p0.x` and `p1.x` and compute the corresponding y-coordinate of the segment. Then I check what we got in our array `ybuffer` with current `x` index. If the current `y`-value is closer to the camera than the value in the `ybuffer`, then I draw it on the screen and update the `ybuffer`. Let us see it step-by-step. After calling `Rasterize()` on the first (red) segment this is our memory: screen:![](./img/lesson3_rasterize1.png) ybuffer: ![ ](./img/lesson3_rasterize2.png) Here the magenta color indicates the minus infinity, those are places corresponding to the screen we did not touch. All the rest is shown in the shades of gray: clear colors are close to the camera, dark colors far from the camera. Then we draw the green segment. screen:![ ](./img/lesson3_rasterize3.png) ybuffer:![ ](./img/lesson3_rasterize4.png) And finally the blue one. screen:![ ](./img/lesson3_rasterize5.png) ybuffer:![ ](./img/lesson3_rasterize6.png) Congratulations, we just drew a 2D scene on a 1D screen! Let us admire once again the render: ![ ](./img/lesson3_rasterize7.png) # Back to 3D So, for drawing on a 2D screen the z-buffer must be two-dimensional: `var zbuffer = new int[width * height];` Personally I pack a two-dimensional buffer into a one-dimensional, the conversion is trivial: `var idx = x + y* width;` and the back one: `var x = idx % width;`\ `var y = idx % width;` Then in the code I simply iterate through all the triangles and call the rasterizer function with current triangle and a reference to the z-buffer. The only difficulty is how to compute the z-value of a pixel we want to draw. Let us recall how we computed the y-value in the y-buffer example: `int y = p0.y*(1-t) + p1.y*t;` What is the nature of the `t` variable? It turns out that `(1-t, t)` are barycentric coordinates of the point `(x,y)` with respect to the segment `p0, p1: (x,y) = p0*(1-t) + p1*t`. So the idea is to take the barycentric coordinates version of triangle rasterization, and for every pixel we want to draw simply to multiply its barycentric coordinates by the z-values of the vertices of the triangle we rasterize: ```csharp Vec3f Barycentric (Vec2f a, Vec2f b, Vec2f c, Vec2f p) { var ab = b - a; var ac = c - a; var pa = a - p; var r = Cross (new Vec3f { x = ab.x, y = ac.x, z = pa.x }, new Vec3f { x = ab.y, y = ac.y, z = pa.y }); // triangle is degenerate, in this case return smth with negative coordinates // dont forget that r.z is integer. If it is zero then triangle ABC is degenerate if ((int)r.z == 0) return new Vec3f { x = -1, y = 1, z = 1 }; return new Vec3f { x = 1 - (r.x + r.y) / r.z, y = r.x / r.z, z = r.y / r.z }; } void Triangle (Image image, Vec3f [] coordinates, Color color, float [] zbuffer) { Vec3f t0 = coordinates [0]; Vec3f t1 = coordinates [1]; Vec3f t2 = coordinates [2]; var pMax = new Vec2i { x = (int)Math.Max (0, Math.Max (t0.x, Math.Max (t1.x, t2.x))), y = (int)Math.Max (0, Math.Max (t0.y, Math.Max (t1.y, t2.y))) }; var pMin = new Vec2i { x = (int)Math.Min (image.Width, Math.Min (t0.x, Math.Min (t1.x, t2.x))), y = (int)Math.Min (image.Height, Math.Min (t0.y, Math.Min (t1.y, t2.y))) }; for (int x = pMin.x; x <= pMax.x; x++) { for (int y = pMin.y; y <= pMax.y; y++) { var pixelCenter = new Vec2f { x = x + 0.5f, y = y + 0.5f }; var bc = Barycentric (Project2D (t0), Project2D (t1), Project2D (t2), pixelCenter); if (bc.x < 0 || bc.y < 0 || bc.z < 0) continue; var z = t0.z * bc.x + t1.z * bc.y + t2.z * bc.z; var idx = x + y * image.Width; if (zbuffer [idx] < z) { zbuffer [idx] = z; image [x, y] = color; } } } } float [] InitZBuffer (Image image) { var zbuffer = new float [image.Width * image.Height]; for (int idx = 0; idx < zbuffer.Length; idx++) zbuffer [idx] = float.NegativeInfinity; return zbuffer; } var image = new Image(width, height, Format.BGR); Func map = v => new Vec3f { x = (int)((v.x+1)*(image.Width-1)/2 + 0.5f), y = (int)((v.y+1)*(image.Height-1)/2 + 0.5f), z = v.z }; var zbuffer = InitZBuffer(image); foreach(var face in headModel.Faces) { for(int i=0; i<3; i++) { var vIndex = face.Vertices[i]; world[i] = headModel.Vertices[vIndex]; screen[i] = map(world[i]); } Vec3f n = Cross(world[2] - world[0], world[1] - world[0]).Normalize (); var intensivity = Dot(n, light_dir); if(intensivity > 0) Triangle(image, screen, Color.White * intensivity, zbuffer); } image.VerticalFlip (); image ``` # Okay, we just interpolated the z-values. What else can we do? Texture! In the `.obj` file we have lines starting with `vt u v`, they give an array of texture coordinates. The number in the middle (between the slashes) in the facet lines\ `f x/x/x x/x/x x/x/x` are the texture coordinates of this vertex of this triangle. Interpolate it inside the triangle, multiply by the width-height of the texture image and you will get the color to put in your render. ```csharp void Triangle (Image image, Vec3f [] coordinates, Image texture, Vec2f [] uv, float intensivity, float [] zbuffer) { Vec3f t0 = coordinates [0]; Vec3f t1 = coordinates [1]; Vec3f t2 = coordinates [2]; var pMax = new Vec2i { x = (int)Math.Max (0, Math.Max (t0.x, Math.Max (t1.x, t2.x))), y = (int)Math.Max (0, Math.Max (t0.y, Math.Max (t1.y, t2.y))) }; var pMin = new Vec2i { x = (int)Math.Min (image.Width, Math.Min (t0.x, Math.Min (t1.x, t2.x))), y = (int)Math.Min (image.Height, Math.Min (t0.y, Math.Min (t1.y, t2.y))) }; for (int x = pMin.x; x <= pMax.x; x++) { for (int y = pMin.y; y <= pMax.y; y++) { var pixelCenter = new Vec2f { x = x + 0.5f, y = y + 0.5f }; var bc = Barycentric (Project2D(t0), Project2D(t1), Project2D(t2), pixelCenter); if (bc.x < 0 || bc.y < 0 || bc.z < 0) continue; var z = t0.z * bc.x + t1.z * bc.y + t2.z * bc.z; var u = (int)(uv [0].x * bc.x + uv [1].x * bc.y + uv [2].x * bc.z); var v = (int)(uv [0].y * bc.x + uv [1].y * bc.y + uv [2].y * bc.z); var idx = x + y * image.Width; if (zbuffer [idx] < z) { zbuffer [idx] = z; var color = texture [u, v]; image [x, y] = color * intensivity; } } } } var image = new Image(width, height, Format.BGR); var headTexture = Image.Load ("obj/african_head_diffuse.tga"); headTexture.VerticalFlip (); Func uvMap = v => new Vec2f { x = v.x * (headTexture.Width - 1), y = v.y * (headTexture.Height - 1) }; var zbuffer = InitZBuffer(image); var uv = new Vec2f[3]; var model = headModel; foreach(var face in model.Faces) { for(int i=0; i<3; i++) { var vIndex = face.Vertices[i]; world[i] = model.Vertices[vIndex]; screen[i] = map(world[i]); var tIndex = face.Textures[i]; uv[i] = uvMap(model.Textures[tIndex]); } Vec3f n = Cross(world[2] - world[0], world[1] - world[0]).Normalize (); var intensivity = Dot(n, light_dir); if(intensivity > 0) Triangle(image, screen, headTexture, uv, intensivity, zbuffer); } image.VerticalFlip (); image ``` ================================================ FILE: graphics/tiny-renderer/lesson7.workbook/lesson4.csx ================================================ Vec2f[] uv = new Vec2f [3]; Func uvMap = (texture, v) => new Vec2f { x = v.x * (texture.Width - 1), y = v.y * (texture.Height - 1) }; Matrix4 Viewport (int x, int y, int w, int h) { var depth = 255f; var m = Matrix4.Identity (); m [0, 3] = x + w / 2f; m [1, 3] = y + h / 2f; m [2, 3] = depth / 2f; m [0, 0] = w / 2f; m [1, 1] = h / 2f; m [2, 2] = depth / 2f; return m; } Matrix4 Projection (float coeff) { var projection = Matrix4.Identity (); projection [3, 2] = coeff; return projection; } ================================================ FILE: graphics/tiny-renderer/lesson7.workbook/lesson4.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Matrix.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" #load "lesson1.csx" #load "lesson2.csx" #load "lesson3.csx" using static Geometry; using static MatrixHelpers; ``` # **Lesson 4: Perspective projection** # The goal In previous lessons we rendered our model in orthographic projection by simply forgetting the z-coordinate. The goal for today is to learn how to draw in perspective: ![ ](./img/lesson4_the_goal.png) # 2D geometry: Linear transformations A linear transformation on a plane can be represented by a corresponding matrix. If we take a point `(x,y)` then its transformation can be written as follows: ![ ](./img/lesson4_formula1.svg) The simplest (not degenerate) transformation is the identity, it does not move any point: ![ ](./img/lesson4_formula_2d_identity.svg) Diagonal coefficients of the matrix give scaling along coordinate axes. Let us illustrate it, if we take the following transformation: ![ ](./img/lesson4_formula_2d_scale.svg) Then the white object (the white square with one corner chopped) will be transformed into the yellow one. Red and green line segments give unit length vectors aligned with `x` and `y`, respectively. All the images for this article were generated using this code: ```csharp Matrix4 Viewport (int x, int y, int w, int h) { var depth = 255f; var m = Matrix4.Identity (); m [0, 3] = x + w / 2f; m [1, 3] = y + h / 2f; m [2, 3] = depth / 2f; m [0, 0] = w / 2f; m [1, 1] = h / 2f; m [2, 2] = depth / 2f; return m; } Matrix4 Projection (float coeff) { var projection = Matrix4.Identity (); projection [3, 2] = coeff; return projection; } Vec4f Embed4D (Vec3f v, float fill = 1) { return new Vec4f { x = v.x, y = v.y, z = v.z, h = fill }; } Vec3f Project3D (Vec4f v) { return new Vec3f { x = v.x, y = v.y, z = v.z }; } Func map = v => Project3D(v/v.h); void RenderAxes (Image image) { var w = image.Width; var h = image.Height; var vp = Viewport(w/4, w/4, w/2, h/2); // draw the axes var x = new Vec3f { x = 1 }; var y = new Vec3f { y = 1 }; var o = new Vec3f (); o = map(Mult(vp, Embed4D(o))); x = map(Mult(vp, Embed4D(x))); y = map(Mult(vp, Embed4D(y))); Line(image, o, x, Color.Red); Line(image, o, y, Color.Green); } var cube = Model.FromFile("obj/cube.obj"); void RenderCube(Image image, Matrix4 deformation, Color color) { var w = image.Width; var h = image.Height; var vp = Viewport(w/4, w/4, w/2, h/2); var face = cube.Faces[0]; var faceLen = face.Vertices.Length; for(int j=0; j x/(c-z) = x'/c. In other words: ![ ](./img/lesson4_formula_x.svg) By doing the same reasoning for triangles CPB and CP'D, it is easy to find the following expression: ![](./img/lesson4_formula_y.svg) It is really similar to the result we put aside few moments ago, but there we got the result by a single matrix multiplication. We got the law for the coefficient: `r = -1/c` # Let us sum up: the main formula for today *If you simply copy-paste this formula without understanding the above material, I hate you.* So, if we want to compute a central projection with a camera **(important!) camera located on the z-axis with distance c from the origin**, then we embed the point into 4D by augmenting it with 1, then we multiply it with the following matrix, and retro-project it into 3D. ![ ](./img/lesson4_formula_last.svg) We deformed our object in a way, that simply forgetting its z-coordinate we will get a drawing in a perspective. If we want to use the z-buffer, then, naturally, do not forget the z: ```csharp var image = new Image(width, height, Format.BGR); var camera = new Vec3f { z = 3 }; var projection = Projection(-1/camera.z); var viewPort = Viewport(width/8, height/8, width*3/4, height*3/4); Func map = v => { var r4 = Mult (viewPort * projection, Embed4D (v)); var r = Project3D (r4 / r4.h); r.x = (int)(r.x + 0.5f); r.y = (int)(r.y + 0.5f); return r; }; Func uvMap = (texture, v) => new Vec2f { x = v.x * (texture.Width - 1), y = v.y * (texture.Height - 1) }; var model = headModel; var zbuffer = InitZBuffer(image); Vec2f[] uv = new Vec2f [3]; foreach(var face in model.Faces) { for(int i=0; i<3; i++) { var vIndex = face.Vertices[i]; world[i] = model.Vertices[vIndex]; screen[i] = map(world[i]); var tIndex = face.Textures[i]; uv[i] = uvMap(headTexture, model.Textures[tIndex]); } Vec3f n = Cross(world[2] - world[0], world[1] - world[0]).Normalize (); var intensivity = Dot(n, light_dir); if(intensivity > 0) Triangle(image, screen, headTexture, uv, intensivity, zbuffer); } image.VerticalFlip (); image ``` ================================================ FILE: graphics/tiny-renderer/lesson7.workbook/lesson5.csx ================================================ using static Geometry; var eye = new Vec3f { x = 1, y = 1, z = 3 }; var center = new Vec3f { x = 0, y = 0, z = 0 }; var up = new Vec3f { x = 0, y = 1, z = 0 }; Matrix4 LookAt (Vec3f eye, Vec3f center, Vec3f up) { var z = (eye - center).Normalize (); var x = Cross (up, z).Normalize (); var y = Cross (z, x).Normalize (); var Minv = Matrix4.Identity (); Minv [0, 0] = x.x; Minv [0, 1] = x.y; Minv [0, 2] = x.z; Minv [1, 0] = y.x; Minv [1, 1] = y.y; Minv [1, 2] = y.z; Minv [2, 0] = z.x; Minv [2, 1] = z.y; Minv [2, 2] = z.z; var Tr = Matrix4.Identity (); Tr [0, 3] = -center.x; Tr [1, 3] = -center.y; Tr [2, 3] = -center.y; return Minv * Tr; } ================================================ FILE: graphics/tiny-renderer/lesson7.workbook/lesson5.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Matrix.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" #load "lesson1.csx" #load "lesson2.csx" #load "lesson3.csx" #load "lesson4.csx" using static Geometry; using static MatrixHelpers; ``` # Lesson 5: Moving the camera # Change of basis in 3D space In Euclidean space coordinates can be given by a point (the origin) and a basis. What does it mean that point P has coordinates `(x,y,z)` in the frame `(O, i,j,k)`? It means that the vector OP can be expressed as follows: ![ ](./img/lesson5_basis.svg) Now image that we have another frame `(O', i',j',k')`. How do we transform coordinates given in one frame to another? First of all let us note that since `(i,j,k)` and `(i',j',k')` are bases of 3D, there exists a (non degenerate) matrix M such that: ![ ](./img/lesson5_new_basis.svg) Let us draw an illustration: ![](./img/lesson5_sketch1.png) Then let us re-express the vector OP: ![ ](./img/lesson5_change_basis1.svg) Now let us substitute `(i',j',k')` in the right part with the change of basis matrix: ![ ](./img/lesson5_change_basis2.svg) And it gives us the formula to transform coordinates from one frame to another: ![ ](./img/lesson5_change_basis3.svg) # Let us create our own gluLookAt OpenGL and, as a consequence, our tiny renderer are able to draw scenes **only with the camera located on the z-axis.** If we want to move the camera, no problem, we can move all the scene, leaving the camera immobile. Let us put the problem this way: we want to draw a scene with a camera situated in point **e**(eye), the camera should be pointed to the point **c** (center) in such way that a given vector **u**(up) is to be vertical in the final render. Here is an illustration: ![ ](./img/lesson5_change_basis4.png) ```csharp Matrix4 LookAt (Vec3f eye, Vec3f center, Vec3f up) { var z = (eye - center).Normalize (); var x = Cross (up, z).Normalize (); var y = Cross (z, x).Normalize (); var Minv = Matrix4.Identity (); Minv [0, 0] = x.x; Minv [0, 1] = x.y; Minv [0, 2] = x.z; Minv [1, 0] = y.x; Minv [1, 1] = y.y; Minv [1, 2] = y.z; Minv [2, 0] = z.x; Minv [2, 1] = z.y; Minv [2, 2] = z.z; var Tr = Matrix4.Identity (); Tr [0, 3] = -center.x; Tr [1, 3] = -center.y; Tr [2, 3] = -center.y; return Minv * Tr; } ``` Note that `z'` is given by the vector **`ce`** (do not forget to normalize it, it helps later). How do we compute `x'`? Simply by a cross product between **`u`** and **`z'`**. Then we compute `y'`, such that it is orthogonal to already calculated `x'` and `z'` (let me remind you that in our problem settings \*\*`ce` \*\*and **`u`** are not necessarily orthogonal). The very last step is a translation of the origin to the center **c** and our transformation matrix is ready. Now it suffices to get any point with coordinates `(x,y,z,1)` in the model frame, multiply it by the matrix ModelView and we get the coordinates in the camera frame! By the way, the name ModelView comes from OpenGL terminology. # Viewport If you followed this course from the beginning, you should remember strange lines like this one: ```csharp // x = (v.x+1)*(width-1)/2 // y = (v.y+1)*(height-1)/2 ``` What does it mean? It means that i have a point Vec2f v, it belongs to the square \[-1,1\]\*\[-1,1\]. I want to draw it in the image of (width, height) dimensions. Value (v.x\+1) is varying between 0 and 2, (v.x\+1)/2 between 0 and 1, and (v.x\+1)\*width/2 sweeps all the image. Thus we effectively mapped the bi-unit square onto the image. But now we are getting rid of these ugly constructs, and i want to rewrite all the computiations in the matrix form. Let us consider the following C# code: ```csharp /* Matrix4 Viewport (int x, int y, int w, int h) { var depth = 255f; var m = Matrix4.Identity (); m [0, 3] = x + w / 2f; m [1, 3] = y + h / 2f; m [2, 3] = depth / 2f; m [0, 0] = w / 2f; m [1, 1] = h / 2f; m [2, 2] = depth / 2f; return m; } */ ``` This code creates this matrix: ![ ](./img/lesson5_viewport.svg) It means that the bi-unit cube \[-1,1\]*\[-1,1\]*\[-1,1\] is mapped onto the screen cube \[0,w\]*\[0,h\]*\[0,d\]. Right, cube, and not a rectangle, this is because of the depth computations with the z-buffer. Here d is the resolution of the z-buffer. I like to have it equal to 255 because of simplicity of dumping black-and-white images of the z-buffer for debugging. In the OpenGL terminology this matrix is called viewport matrix. # Chain of coordinate transformations So, let us sum up. Our models (characters, for example) are created in their own local frame (**object coordinates**). They are inserted into a scene expressed in **world coordinates**. The transformation from one to another is made with matrix **Model**. Then, we want to express it in the camera frame (**eye coordinates**), the transformation is called **View**. Then, we deform the scene to create a perspective deformation with **Projection** matrix (lesson 4), this matrix transforms the scene to so-called **clip coordinates**. Finally, we draw the scene, and the matrix transforming clip coordinates to the **screen coordinates** is called **Viewport**. Again, if we read a point **v** from the .obj file, then to draw it on the screen it undergoes the following chain of transformations: Viewport \* Projection \* View \* Model \* v As i draw a single object only, the matrix Model is equal to identity, and i merged it with the matrix View: ```csharp var eye = new Vec3f { x = 1, y = 1, z = 3 }; var center = new Vec3f { x = 0, y = 0, z = 0 }; var up = new Vec3f { x = 0, y = 1, z = 0 }; // draw the model var modelView = LookAt(eye, center, up); var viewPort = Viewport(width/8, height/8, width*3/4, height*3/4); var projection = Projection(-1/(eye-center).Norm()); Func map = v => { var r4 = Mult (viewPort * projection * modelView, Embed4D (v)); var r = Project3D (r4 / r4.h); r.x = (int)(r.x + 0.5f); r.y = (int)(r.y + 0.5f); return r; }; var image = new Image(width, height, Format.BGR); var model = headModel; var zbuffer = InitZBuffer(image); foreach(var face in model.Faces) { for(int i=0; i<3; i++) { var vIndex = face.Vertices[i]; world[i] = model.Vertices[vIndex]; screen[i] = map(world[i]); var tIndex = face.Textures[i]; uv[i] = uvMap(headTexture, model.Textures[tIndex]); } Vec3f n = Cross(world[2] - world[0], world[1] - world[0]).Normalize (); var intensivity = Dot(n, light_dir); if(intensivity > 0) Triangle(image, screen, headTexture, uv, intensivity, zbuffer); } image.VerticalFlip (); image ``` # Transformation of normal vectors There is a widely-known fact: * If we have a model and its normal vectors are given by the artist AND this model is transformed with an affine mapping, then normal vectors are to be transformed with a mapping, equal to the transposition of the inverse matrix of the original mapping matrix What-what-what?! I met quite a few programmers who know this fact, but it remains a black magic for them. In fact, it is not so complicated. Take a pencil and draw a 2D triangle `(0,0)`, `(0,1)`, `(1,0)` and a vector **n**, normal to the hypothenuse. Naturally, **n** is equal to `(1,1)`. Then let us stretch all the y-coordinates by a factor of 2, leaving x-coordinates intact. Thus, our triangle becomes `(0,0)`, `(0,2)`, `(1,0)`. If we transform the vector **n** in the same way, it becomes `(1, 2)` and it is no longer orthogonal to the transformed edge of the triangle. Thus, to remove all the black magic fog, we need to understand one simple thing: **we do not need to simply transform normal vectors (as they can become not normal anymore), we need to compute (new) normal vectors to the transformed model.** Back to 3D, we have a vector **n** = (A,B,C). We know that the plane passing through the origin and having **n** for its normal, has an equation `Ax+By+Cz=0`. Let us write it in the matrix form (i do it in homogeneous coordinates from the beginning): ![ ](./img/lesson5_transform_normal1.png) Recall that `(A,B,C)` - is a vector, so we augment it with 0 when embedding into the 4D, and `(x,y,z)` is augmented with 1 since it is a point. Let us insert an identity matrix in between (inverse to M multiplied by M is equal to identity): ![ ](./img/lesson5_transform_normal2.png) The expression in right parentheses - are for the transformed points of the object. In the left - are for normal vectors to the transformed object! In standard convention we usually write coordinates as columns (please let us not raise all the stuff about contra- and co-variant vectors), so we can rewrite the previous expression as follows: ![ ](./img/lesson5_transform_normal2.png) And the left parentheses tell us that a normal to the transformed object can be computed from the old normal by applying the inverse transpose matrix of the affine mapping. Please note that if our transformation matrix M is a composition of uniform scalings, rotations and translations, then M is equal to its inverse transpose, since inverse and transpose are cancelling each other in this case. But since our matrices include perspective deformations, usually this trick does not help. In the current code we do not use the transformation of normal vectors, but in the next lesson it will be very, very handy. Happy coding! ================================================ FILE: graphics/tiny-renderer/lesson7.workbook/lesson6.csx ================================================ using static Geometry; using static MatrixHelpers; using static ShaderUtils; var diabloModel = Model.FromFile ("obj/diablo3_pose.obj"); var diabloTexture = Image.Load ("obj/diablo3_pose_diffuse.tga"); var diabloNormalMap = Image.Load ("obj/diablo3_pose_nm.tga"); var diabloTangentMap = Image.Load ("obj/diablo3_pose_nm_tangent.tga"); var diabloSpecularMap = Image.Load ("obj/diablo3_pose_spec.tga"); diabloTexture.VerticalFlip (); diabloNormalMap.VerticalFlip (); diabloTangentMap.VerticalFlip (); diabloSpecularMap.VerticalFlip (); light_dir = new Vec3f { x = 1, y = 1, z = 1 }; eye = new Vec3f { x = 1, y = 1, z = 3 }; center = new Vec3f { x = 0, y = 0, z = 0 }; up = new Vec3f { x = 0, y = 1, z = 0 }; var modelView = LookAt(eye, center, up); var viewPort = Viewport(width/8, height/8, width*3/4, height*3/4); var projection = Projection(-1f/(eye-center).Norm()); interface IShader { Vec4f Vertex (Face face, int nthvert); bool Fragment (Vec3f fragment, Vec3f bar, out Color color); }; class RenderResult { public Image Image { get; set; } public float [] ZBuffer { get; set; } } RenderResult Render (Model model, IShader shader) { var image = new Image (width, height, Format.BGR); var zbuffer = InitZBuffer (image); var screen_coords = new Vec4f [3]; foreach (var face in model.Faces) { for (int i = 0; i < 3; i++) screen_coords [i] = shader.Vertex (face, i); Triangle (image, screen_coords, shader, zbuffer); } return new RenderResult { Image = image, ZBuffer = zbuffer }; } void Box (Vec4f [] pts, out Vec2i pMin, out Vec2i pMax) { pMax = new Vec2i { x = int.MinValue, y = int.MinValue }; pMin = new Vec2i { x = int.MaxValue, y = int.MaxValue }; for (int i = 0; i < 3; i++) { pMax.x = (int)Math.Max (pMax.x, pts [i].x / pts [i].h); pMax.y = (int)Math.Max (pMax.y, pts [i].y / pts [i].h); pMin.x = (int)Math.Min (pMin.x, pts [i].x / pts [i].h); pMin.y = (int)Math.Min (pMin.y, pts [i].y / pts [i].h); } } void Triangle (Image image, Vec4f [] pts, IShader shader, float [] zbuffer) { Vec2i pMin, pMax; Box (pts, out pMin, out pMax); Color color; for (int x = pMin.x; x <= pMax.x; x++) { for (int y = pMin.y; y <= pMax.y; y++) { var pixelCenter = new Vec2f { x = x + 0.5f, y = y + 0.5f }; var bc = Barycentric (Project2D (pts [0] / pts [0].h), Project2D (pts [1] / pts [1].h), Project2D (pts [2] / pts [2].h), pixelCenter); var z = pts [0].z * bc.x + pts [1].z * bc.y + pts [2].z * bc.z; // z [0..255] var w = pts [0].h * bc.x + pts [1].h * bc.y + pts [2].h * bc.z; var frag_depth = z / w; var idx = x + y * image.Width; if (bc.x < 0 || bc.y < 0 || bc.z < 0 || zbuffer[idx] > frag_depth) continue; var fragment = new Vec3f { x = x, y = y, z = frag_depth }; var discard = shader.Fragment (fragment, bc, out color); if (!discard) { zbuffer [idx] = frag_depth; image [x, y] = color; } } } } static class ShaderUtils { public static Vec4f TransformFace (Model model, Face face, int nthvert, Matrix4 t) { var v = model.Vertex (face, nthvert); // read the vertex from model var glVertex = Embed4D (v); return Mult (t, glVertex); // transform it to screen coordinates } public static void UpdateVarayingUV (Model model, Face face, int nthvert, ref Vec3f varyingU, ref Vec3f varyingV) { var vt = model.GetUV (face, nthvert); varyingU [nthvert] = vt.x; varyingV [nthvert] = vt.y; } public static Vec2f CalcUV (Vec3f varU, Vec3f varV, Vec3f bar) { return new Vec2f { x = Dot (varU, bar), y = Dot (varV, bar) }; } public static Color GetColor (Image texture, Vec2f uvf) { var uvi = CalcXY(texture, uvf); return texture [uvi.x, uvi.y]; } public static Vec3f Transform (Matrix4 t, Vec3f v) { var v4d = Mult (t, Embed4D (v)); return Project3D (v4d); } public static Vec3f Normal (Image normalMap, Vec2f uvf) { // RGB values as xyz. But Color stores data as BGR (zyx) var c = GetColor (normalMap, uvf); return new Vec3f { x = (c [2] / 255f) * 2 - 1, y = (c [1] / 255f) * 2 - 1, z = (c [0] / 255f) * 2 - 1 }; } public static float Specular (Image specularMap, Vec2f uvf) { var uvi = CalcXY (specularMap, uvf); var color = specularMap [uvi.x, uvi.y]; return color[0]; } public static Vec2i CalcXY (Image texture, Vec2f uvf) { return new Vec2i { x = (int)(uvf.x * texture.Width), y = (int)(uvf.y * texture.Height) }; } } class TextureShader : IShader { readonly Model model; readonly Vec3f lightDir; readonly Matrix4 transformation; readonly Image texture; // written by vertex shader, read by fragment shader Vec3f varyingIntensity = new Vec3f (); Vec3f varyingU = new Vec3f (); Vec3f varyingV = new Vec3f (); public TextureShader (Model model, Matrix4 viewPort, Matrix4 projection, Matrix4 modelView, Vec3f lightDir, Image texture) { this.model = model; transformation = viewPort * projection * modelView; this.lightDir = lightDir.Normalize (); this.texture = texture; } public Vec4f Vertex (Face face, int nthvert) { UpdateVarayingUV (model, face, nthvert, ref varyingU, ref varyingV); var n = model.Normal (face, nthvert).Normalize (); varyingIntensity [nthvert] = Math.Max (0, Dot (n, lightDir)); // get diffuse lighting intensity return TransformFace (model, face, nthvert, transformation); } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { // interpolate intensity for the current pixel var intensity = Dot (varyingIntensity, bar); // interpolate uv for the current pixel var uvf = CalcUV (varyingU, varyingV, bar); color = GetColor (texture, uvf) * intensity; return false; } } ================================================ FILE: graphics/tiny-renderer/lesson7.workbook/lesson6.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Matrix.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" #load "lesson1.csx" #load "lesson2.csx" #load "lesson3.csx" #load "lesson4.csx" #load "lesson5.csx" using static Geometry; using static MatrixHelpers; ``` # **Lesson 6: Shaders for the software renderer** Refactoring the source code. IShader. ```csharp interface IShader { Vec4f Vertex (Face face, int nthvert); bool Fragment (Vec3f fragment, Vec3f bar, out Color color); }; class RenderResult { public Image Image { get; set; } public float [] ZBuffer { get; set; } } RenderResult Render (Model model, IShader shader) { var image = new Image (width, height, Format.BGR); var zbuffer = InitZBuffer (image); var screen_coords = new Vec4f [3]; foreach (var face in model.Faces) { for (int i = 0; i < 3; i++) screen_coords [i] = shader.Vertex (face, i); Triangle (image, screen_coords, shader, zbuffer); } return new RenderResult { Image = image, ZBuffer = zbuffer }; } void Box (Vec4f [] pts, out Vec2i pMin, out Vec2i pMax) { pMax = new Vec2i { x = int.MinValue, y = int.MinValue }; pMin = new Vec2i { x = int.MaxValue, y = int.MaxValue }; for (int i = 0; i < 3; i++) { pMax.x = (int)Math.Max (pMax.x, pts [i].x / pts [i].h); pMax.y = (int)Math.Max (pMax.y, pts [i].y / pts [i].h); pMin.x = (int)Math.Min (pMin.x, pts [i].x / pts [i].h); pMin.y = (int)Math.Min (pMin.y, pts [i].y / pts [i].h); } } void Triangle (Image image, Vec4f [] pts, IShader shader, float [] zbuffer) { Vec2i pMin, pMax; Box (pts, out pMin, out pMax); Color color; for (int x = pMin.x; x <= pMax.x; x++) { for (int y = pMin.y; y <= pMax.y; y++) { var pixelCenter = new Vec2f { x = x + 0.5f, y = y + 0.5f }; var bc = Barycentric (Project2D (pts [0] / pts [0].h), Project2D (pts [1] / pts [1].h), Project2D (pts [2] / pts [2].h), pixelCenter); var z = pts [0].z * bc.x + pts [1].z * bc.y + pts [2].z * bc.z; // z [0..255] var w = pts [0].h * bc.x + pts [1].h * bc.y + pts [2].h * bc.z; var frag_depth = z / w; var idx = x + y * image.Width; if (bc.x < 0 || bc.y < 0 || bc.z < 0 || zbuffer[idx] > frag_depth) continue; var fragment = new Vec3f { x = x, y = y, z = frag_depth }; var discard = shader.Fragment (fragment, bc, out color); if (!discard) { zbuffer [idx] = frag_depth; image [x, y] = color; } } } } ``` Let us see how it works. The actual render code: * Parsing the .obj file * Iteration through all triangles of the model and rasterization of each triangle. The last step is the most interesting. Outer loop iterates through all the triangles. Inner loop iterates through all the vertices of the current triangle and calls a vertex shader for each vertex. **The main goal of the vertex shader is to transform the coordinates of the vertices. The secondary goal is to prepare data for the fragment shader.** What happens after that? We call the rasterization routine. What happens inside the rasterizer we do not know (well, okay, we do know since we programmed it!) with one exception. We know that the rasterizer calls **our** routine for each pixel, namely, the fragment shader. Again, for each pixel inside the triangle the rasterizer calls our own callback, the fragment shader. **The main goal of the fragment shader - is to determine the color of the current pixel. Secondary goal - we can discard current pixel by returning true.** The rendering pipeline for the OpenGL 2 can be represented as follows (in fact, it is more or less the same for newer versions too): ![ ](./img/lesson6_opengl2_pipeline.png) Because of the time limits I have for my course, I restrict myself to the OpenGL 2 pipeline and therefore to fragment and vertex shaders only. In newer versions of OpenGL there are other shaders, allowing, for example, to generate geometry on the fly. Okay, in the above image all the stages we can not touch are shown in blue, whereas our callbacks are shown in orange. In fact, our render code - is the \*\*primitive processing \*\*routine. It calls the vertex shader. We do not have primitive assembly here, since we are drawing dumb triangles only (in our code it is merged with the primitive processing). `Triangle` function - is the **rasterizer**, for each point inside the triangle it calls the **fragment shader**, then performs depth checks (z-buffer) and such. That is all. You know what the shaders are and now you can create your own shaders. # **My implementation of shaders shown on Gouraud shading** According to its name, it is a Gouraud shader. Here is the code: ```csharp using static ShaderUtils; class GouraudShader : IShader { readonly Model model; readonly Vec3f lightDir; // written by vertex shader, read by fragment shader protected Vec3f varyingIntensity = new Vec3f (); readonly Matrix4 transformation; public GouraudShader (Model model, Matrix4 viewPort, Matrix4 projection, Matrix4 modelView, Vec3f lightDir) { this.model = model; transformation = viewPort * projection * modelView; this.lightDir = lightDir.Normalize (); } public virtual Vec4f Vertex (Face face, int nthvert) { var n = model.Normal (face, nthvert).Normalize (); // get diffuse lighting intensity varyingIntensity [nthvert] = Math.Max (0, Dot (n, lightDir)); var d = Dot(n, lightDir); return TransformFace (model, face, nthvert, transformation); } public virtual bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { // interpolate intensity for the current pixel var intensity = Dot (varyingIntensity, bar); color = Color.White * intensity; // well duh return false; } } // set of utils which will be used in our shaders static class ShaderUtils { public static Vec4f TransformFace (Model model, Face face, int nthvert, Matrix4 t) { var v = model.Vertex (face, nthvert); // read the vertex from model var glVertex = Embed4D (v); return Mult (t, glVertex); // transform it to screen coordinates } public static void UpdateVarayingUV (Model model, Face face, int nthvert, ref Vec3f varyingU, ref Vec3f varyingV) { var vt = model.GetUV (face, nthvert); varyingU [nthvert] = vt.x; varyingV [nthvert] = vt.y; } public static Vec2f CalcUV (Vec3f varU, Vec3f varV, Vec3f bar) { return new Vec2f { x = Dot (varU, bar), y = Dot (varV, bar) }; } public static Color GetColor (Image texture, Vec2f uvf) { var uvi = CalcXY(texture, uvf); return texture [uvi.x, uvi.y]; } public static Vec3f Transform (Matrix4 t, Vec3f v) { var v4d = Mult (t, Embed4D (v)); return Project3D (v4d); } public static Vec3f Normal (Image normalMap, Vec2f uvf) { // RGB values as xyz. But Color stores data as BGR (zyx) var c = GetColor (normalMap, uvf); return new Vec3f { x = (c [2] / 255f) * 2 - 1, y = (c [1] / 255f) * 2 - 1, z = (c [0] / 255f) * 2 - 1 }; } public static float Specular (Image specularMap, Vec2f uvf) { var uvi = CalcXY (specularMap, uvf); var color = specularMap [uvi.x, uvi.y]; return color[0]; } public static Vec2i CalcXY (Image texture, Vec2f uvf) { return new Vec2i { x = (int)(uvf.x * texture.Width), y = (int)(uvf.y * texture.Height) }; } } var light_dir = new Vec3f { x = 1, y = 1, z = 1 }; var eye = new Vec3f { x = 1, y = 1, z = 3 }; var center = new Vec3f { x = 0, y = 0, z = 0 }; var up = new Vec3f { x = 0, y = 1, z = 0 }; var modelView = LookAt(eye, center, up); var viewPort = Viewport(width/8, height/8, width*3/4, height*3/4); var projection = Projection(-1f/(eye-center).Norm()); var shader = new GouraudShader (headModel, viewPort, projection, modelView, light_dir); var image = Render (headModel, shader).Image; image.VerticalFlip(); image ``` **vayring** is a reserved keyword in GLSL language, I have used VaryingIntensity as a name in order to show the correspondence. In varying variables we store data to be interpolated inside the triangle, and the fragment shaders get the interpolated value (for the current pixel). Fragment routine is called for each pixel inside the triangle we draw; as an input it receives [barycentric coordinates](https://en.wikipedia.org/wiki/Barycentric_coordinate_system) for interpolation of VaryingXXX data. Thus, interpolated intensity can be computed as: VaryingIntensity\[0\]\*bar\[0\] \+ VaryingIntensity\[1\]\*bar\[1\] \+ VaryingIntensity\[2\]\*bar\[2\] or simply as a dot product between two vectors: `Dot(VaryingIntensity,bar)`. In true GLSL, of course, fragment shaders receive ready interpolated values. Notice that the shader returns a bool value. It is easy to understand what it does if we look inside the updated rasterizer: ```csharp /* ... var discard = shader.Fragment (fragment, bc, out color); if (!discard) { zbuffer [idx] = frag_depth; image [x, y] = color; } */ ``` Fragment shader can discard drawing of the current pixel, then the rasterizer simply skips it. It is handy if we want to create binary masks or whatever you want. Of course, the rasterizer can not imagine all the weird stuff you could program, therefore it can not be pre-compiled with your shader. Here we use IShader interface as an intermediate between the two. # **First modification of the shaders** Simple modification of the Gourad shading, where the intensities are allowed to have 6 values only: ```csharp class GouraudShader6 : GouraudShader { public GouraudShader6 (Model model, Matrix4 viewPort, Matrix4 projection, Matrix4 modelView, Vec3f lightDir) : base (model, viewPort, projection, modelView, lightDir) { } public override bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { var intensity = Dot (varyingIntensity, bar); if (intensity > 0.85f) intensity = 1; else if (intensity > 0.60f) intensity = 0.80f; else if (intensity > 0.45f) intensity = 0.60f; else if (intensity > 0.30f) intensity = 0.45f; else if (intensity > 0.15f) intensity = 0.30f; else intensity = 0; color = new Color (255, 155, 0) * intensity; return false; } } var shader = new GouraudShader6 (headModel, viewPort, projection, modelView, light_dir); var image = Render (headModel, shader).Image; image.VerticalFlip(); image ``` # **Textures** I'll skip the [Phong shading](https://en.wikipedia.org/wiki/Phong_shading), but take a look at the article. Remember the homework assignment I gave you for texturing? We had to interpolate uv-coordinates. ```csharp using static ShaderUtils; class TextureShader : IShader { readonly Model model; readonly Vec3f lightDir; readonly Matrix4 transformation; readonly Image texture; // written by vertex shader, read by fragment shader Vec3f varyingIntensity = new Vec3f (); Vec3f varyingU = new Vec3f (); Vec3f varyingV = new Vec3f (); public TextureShader (Model model, Matrix4 viewPort, Matrix4 projection, Matrix4 modelView, Vec3f lightDir, Image texture) { this.model = model; transformation = viewPort * projection * modelView; this.lightDir = lightDir.Normalize (); this.texture = texture; } public Vec4f Vertex (Face face, int nthvert) { UpdateVarayingUV (model, face, nthvert, ref varyingU, ref varyingV); var n = model.Normal (face, nthvert).Normalize (); varyingIntensity [nthvert] = Math.Max (0, Dot (n, lightDir)); // get diffuse lighting intensity return TransformFace (model, face, nthvert, transformation); } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { // interpolate intensity for the current pixel var intensity = Dot (varyingIntensity, bar); // interpolate uv for the current pixel var uvf = CalcUV (varyingU, varyingV, bar); color = GetColor (texture, uvf) * intensity; return false; } } var shader = new TextureShader (headModel, viewPort, projection, modelView, light_dir, headTexture); var image = Render (headModel, shader).Image; image.VerticalFlip(); image ``` # **Normalmapping** Okay, now we have texture coordinates. What can we store in texture images? In fact, almost anything. It can be color, directions, temperature and so on. Let us load this texture: ![ ](./img/lesson6_african_head_nm.png) If we interpret RGB values as xyz directions, this image gives us normal vectors **for each pixel** of our render and not only per vertex as before. By the way, compare this image to another one, it gives exactly the same information, but in another frame: ![ ](./img/lesson6_african_head_nm_tangent.png) One of the images gives normal vectors in global (Cartesian) coordinate system, another one in [Darboux frame](https://en.wikipedia.org/wiki/Darboux_frame) (so-called tangent space). In Darboux frame the z-vector is normal to the object, x - principal curvature direction and y - their cross product. **Exercise 1:** Can you tell which image is represented in Darboux frame and which one is in the global coordinate frame? **Exercise 2:** Can you tell which representation is better and if yes, why is that? **Uniform** is a reserved keyword in GLSL, it allows to pass constants to the shaders. Here I pass the matrix Projection\*ModelView and its inverse transpose to transform the normal vectors (refer to the end of the lesson5). So, computation of the lighting intensity is the same as before with one exception: instead of interpolating normal vectors we retrieve the information from the normal mapping texture (do not forget to transform light vector and normal vectors). ```csharp class NormalMapShader : IShader { Vec3f varyingU = new Vec3f (); Vec3f varyingV = new Vec3f (); readonly Model model; readonly Vec3f lightDir; readonly Matrix4 uniformM; readonly Matrix4 uniformMIT; readonly Matrix4 transformation; readonly Image texture; readonly Image normalMap; public NormalMapShader (Model model, Matrix4 viewport, Matrix4 projection, Matrix4 modelView, Vec3f lightDir, Image texture, Image normalMap) { this.model = model; this.lightDir = lightDir.Normalize (); this.texture = texture; this.normalMap = normalMap; uniformM = projection * modelView; uniformMIT = TransposeInverse (uniformM); transformation = viewport * uniformM; } public Vec4f Vertex (Face face, int nthvert) { UpdateVarayingUV (model, face, nthvert, ref varyingU, ref varyingV); return TransformFace (model, face, nthvert, transformation); } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { var uv = CalcUV (varyingU, varyingV, bar); var n = Transform (uniformMIT, Normal (normalMap, uv)).Normalize (); var l = Transform (uniformM, lightDir).Normalize (); var intensity = Math.Max (0f, Dot (n, l)); color = GetColor (texture, uv) * intensity; return false; } } var headNormalMap = Image.Load ("obj/african_head_nm.tga"); headNormalMap.VerticalFlip (); var shader = new NormalMapShader (headModel, viewPort, projection, modelView, light_dir, headTexture, headNormalMap); var image = Render (headModel, shader).Image; image.VerticalFlip(); image ``` # **Specular mapping** Okay, let us continue the fun. All the computer graphics science is the art to cheat. To (cheaply) trick the eye we use the [Phong's approximation](https://en.wikipedia.org/wiki/Phong_reflection_model) of the lighting model. Phong proposed to consider the final lighting as a (weighted) sum of three light intensities: ambient lighting (constant per scene), diffuse lighting (the one we computed up to this moment) and specular lighting. Take a look at the following image, it speaks for itself: ![ ](./img/lesson6_phong.png) We compute diffuse lighting as a cosine of the angle between the normal vector and the light direction vector. I mean, this supposes that the light is reflected in all directions uniformly. What happens to glossy surfaces? In the limit case (mirror) the pixel is illuminated if and only if we can see the light source reflected by this pixel: ![ ](./img/lesson6_reflection.png) For diffuse lighting we computed the (cosine of) angle between vectors **n** and **l**, and now we are interested in the (cosine of) angle between vectors **r** (reflected light direction) and **v**(view direction). **Exercise 3:** Given vectors **n** and **l**, find vector **r**. *Answer:* If **n** and **l** are normalized, then **r** = 2**n**<**n**,**l**> - **l** For diffused lighting we computed the light intensity as the cosine. But a glossy surface reflects in one direction much more than in others! Okay then, what happens if we take tenth power of the cosine? Recall that all numbers inferior to 1 will decrease when we apply the power. It means that tenth power of the cosine will give smaller radius of the reflected beam. And hundredth power **much** smaller beam radius. This power is stored in a special texture (specular mapping texture) that tells for each point if it is glossy or not.\ \ I think that i do not need to comment anything in the below code at the exception of coefficients: `5 + color [i] * (diff + 1.3f * specular)` I took 5 for the ambient component, 1 for the diffuse component and 1.3 for the specular component. What coefficients to choose - is your choice. Different choices give different appearances for the object. Normally it is for the artist to decide. *Please note that normally the sum of the coefficents must be equal to 1, but you know. I like to create light.* ```csharp class SpecularShader : IShader { Vec3f varyingU = new Vec3f (); Vec3f varyingV = new Vec3f (); readonly Model model; readonly Vec3f lightDir; readonly Matrix4 uniformM; readonly Matrix4 uniformMIT; readonly Matrix4 transformation; readonly Image texture; readonly Image normalMap; readonly Image specularMap; public SpecularShader (Model model, Matrix4 viewport, Matrix4 projection, Matrix4 modelView, Vec3f lightDir, Image texture, Image normalMap, Image specularMap) { this.model = model; this.lightDir = lightDir.Normalize (); this.texture = texture; this.normalMap = normalMap; this.specularMap = specularMap; uniformM = projection * modelView; uniformMIT = TransposeInverse (uniformM); transformation = viewport * uniformM; } public Vec4f Vertex (Face face, int nthvert) { UpdateVarayingUV (model, face, nthvert, ref varyingU, ref varyingV); return TransformFace (model, face, nthvert, transformation); } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { var uv = CalcUV (varyingU, varyingV, bar); var n = Transform (uniformMIT, Normal (normalMap, uv)).Normalize (); var l = Transform (uniformM, lightDir).Normalize (); var r = (n * (2 * Dot (n, l)) - l).Normalize (); var diff = Math.Max (0f, Dot (n, l)); var specular = Math.Pow (Math.Max (0f, r.z), Specular (specularMap, uv) + 15); color = GetColor (texture, uv); int v = 0; for (int i = 0; i < 4; i++) v = (v << 8) | (byte)Math.Min (255, (int)(5 + color [i] * (diff + 1.3f * specular))); color = new Color (v, color.format); return false; } } var headSpecularMap = Image.Load ("./obj/african_head_spec.tga"); var shader = new SpecularShader (headModel, viewPort, projection, modelView, light_dir, headTexture, headNormalMap, headSpecularMap); var image = Render (headModel, shader).Image; image.VerticalFlip(); image ``` ```csharp var diabloModel = Model.FromFile ("obj/diablo3_pose.obj"); var diabloTexture = Image.Load ("obj/diablo3_pose_diffuse.tga"); var diabloNormalMap = Image.Load ("obj/diablo3_pose_nm.tga"); var diabloTangentMap = Image.Load ("obj/diablo3_pose_nm_tangent.tga"); var diabloSpecularMap = Image.Load ("obj/diablo3_pose_spec.tga"); diabloTexture.VerticalFlip (); diabloNormalMap.VerticalFlip (); diabloTangentMap.VerticalFlip (); diabloSpecularMap.VerticalFlip (); var shader = new SpecularShader (diabloModel, viewPort, projection, modelView, light_dir, diabloTexture, diabloNormalMap, diabloSpecularMap); var image = Render (diabloModel, shader).Image; image.VerticalFlip(); image ``` # **Conclusion** We know how to render quite nice scenes, but our lighting is far from being real. In the next articles I will talk about shadows. Enjoy! ================================================ FILE: graphics/tiny-renderer/lesson7.workbook/lesson6bis.csx ================================================ using static Geometry; using static MatrixHelpers; using static ShaderUtils; class TangentShader : IShader { // triangle uv coordinates, written by the vertex shader, read by the fragment shader Vec3f varyingU = new Vec3f (); Vec3f varyingV = new Vec3f (); // normal per vertex to be interpolated by FS Matrix3 varyingNrm = new Matrix3 (); readonly Model model; readonly Vec3f lightDir; readonly Matrix4 uniformM; readonly Matrix4 uniformMIT; readonly Matrix4 transformation; readonly Vec3f[] ndcTri = new Vec3f[3]; // triangle in normalized device coordinates readonly Image texture; readonly Image normalMap; public TangentShader (Model model, Matrix4 viewport, Matrix4 projection, Matrix4 modelView, Vec3f lightDir, Image texture, Image normalMap) { this.model = model; this.lightDir = lightDir.Normalize (); this.texture = texture; this.normalMap = normalMap; uniformM = projection * modelView; uniformMIT = TransposeInverse (uniformM); transformation = viewport * uniformM; } public Vec4f Vertex (Face face, int nthvert) { UpdateVarayingUV (model, face, nthvert, ref varyingU, ref varyingV); var normal = Project3D (Mult (uniformMIT, Embed4D (model.Normal (face, nthvert)))); varyingNrm.SetColumn (nthvert, normal); var glVertex = TransformFace (model, face, nthvert, transformation); ndcTri[nthvert] = Project3D (glVertex / glVertex.h); return glVertex; } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { var bn = Mult(varyingNrm, bar).Normalize (); var uv = CalcUV (varyingU, varyingV, bar); var A = new Matrix3 (); A.SetRow (0, ndcTri [1] - ndcTri [0]); A.SetRow (1, ndcTri [2] - ndcTri [0]); A.SetRow (2, bn); var AI = Inverse (A); var i = Mult (AI, new Vec3f { x = varyingU.y - varyingU.x, y = varyingU.z - varyingU.x }); var j = Mult (AI, new Vec3f { x = varyingV.y - varyingV.x, y = varyingV.z - varyingV.x }); var B = new Matrix3 (); B.SetColumn (0, i.Normalize ()); B.SetColumn (1, j.Normalize ()); B.SetColumn (2, bn); var n = Mult (B, Normal (normalMap, uv)).Normalize (); var l = Transform (uniformM, lightDir).Normalize (); var diff = Math.Max (0f, Dot (n, l)); color = GetColor (texture, uv) * diff; return false; } } ================================================ FILE: graphics/tiny-renderer/lesson7.workbook/lesson6bis.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Matrix.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" #load "lesson1.csx" #load "lesson2.csx" #load "lesson3.csx" #load "lesson4.csx" #load "lesson5.csx" #load "lesson6.csx" using static Geometry; using static MatrixHelpers; using static ShaderUtils; ``` # Lesson 6bis: tangent space normal mapping The subject for today is [normal mapping](https://en.wikipedia.org/wiki/Normal_mapping). What is the main difference between normal mapping and Phong shading? The key is the density of information we have. For Phong shading we use normal vectors given per vertex of triangle mesh (and interpolate it inside triangles), whereas normal mapping textures provide dense information, dramatically improving rendering details. Well, we have already applied normal mapping in previous lesson, however we used the global system of coordinates to store the texture. Today we are talking about [tangent space](https://en.wikipedia.org/wiki/Darboux_frame) normal mapping. So, we have two textures, the left one is given in the global frame (direct transformation from RGB to XYZ normal), whereas the right one in the Darboux frame: ![](./img/lesson6bis_nm.jpg) To use right texture, for each pixel we draw we compute tangent space (Darboux) frame. In this basis one vector (usually z) is orthogonal to our surface, and two others give a plane tangent to the current point. Then we read a (perturbed) normal vector from our texture, transform its coordinates from Darboux frame to the global system coordinates and we are done. Usually normal maps provide small perturbations of normal vectors, thus textures are in dominant blue color. Well, why such a mess? Why not to use global system as we did before? Imagine we want to animate our model. For example, I took the black guy model and opened his mouth. It is obvious that normal vectors are to be modified. ![ ](./img/lesson6bis_mouth.jpg) Left image gives the head with open mouth, but unchanged (global frame) normal texture. Inspect closely the interior of the lower lip. The light coming directly to his face; when the mouth was closed the backside of the lower lip naturally was not lit. Now the mouth is open, but the lip is not lit... The right image was computed with tangent space normal mapping. Therefore, if we have an animated model, then for correct normal mapping in global frame we need to have one texture per frame of the animation, whereas tangent space deforms accordingly to the model and we need one texture only! Here is another example: ![ ](./img/global_vs_tangent_diablo.jpg) These are textures for the Diablo model. Notice that only one hand is drawn in the texture, and only one side of the tail. The artist used the same texture for both arms and for both sides of the tail. It means that in the global coordinate system I can provide normal vectors either for the left side of the tail, either for the right one, but not for both! Same goes for the arms. And I need different information for the left and the right sides, for example, inspect left and right cheekbones in the left image, naturally normal vectors are pointing in the opposite directions! Let us finish with the motivation section and go straight ahead to the computations. # **Starting point, Phong shading** Okay, here is the starting point. The shader is really simple, it is Phong shading. ```csharp class TangentShader : IShader { // triangle uv coordinates, written by the vertex shader, read by the fragment shader Vec3f varyingU = new Vec3f (); Vec3f varyingV = new Vec3f (); // normal per vertex to be interpolated by FS Matrix3 varyingNrm = new Matrix3 (); readonly Model model; readonly Vec3f lightDir; readonly Matrix4 uniformM; readonly Matrix4 uniformMIT; readonly Matrix4 transformation; readonly Image texture; public TangentShader (Model model, Matrix4 viewport, Matrix4 projection, Matrix4 modelView, Vec3f lightDir, Image texture) { this.model = model; this.lightDir = lightDir.Normalize (); this.texture = texture; uniformM = projection * modelView; uniformMIT = TransposeInverse (uniformM); transformation = viewport * uniformM; } public Vec4f Vertex (Face face, int nthvert) { UpdateVarayingUV (model, face, nthvert, ref varyingU, ref varyingV); var normal = Project3D (Mult (uniformMIT, Embed4D (model.Normal (face, nthvert)))); varyingNrm.SetColumn (nthvert, normal); var glVertex = TransformFace (model, face, nthvert, transformation); return glVertex; } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { Vec3f bn = Mult(varyingNrm, bar).Normalize (); var uv = CalcUV (varyingU, varyingV, bar); Vec3f l = Transform (uniformM, lightDir).Normalize (); var diff = Math.Max (0f, Dot (bn, l)); color = GetColor (texture, uv); color *= diff; return false; } } var shader = new TangentShader (headModel, viewPort, projection, modelView, light_dir, headTexture); var image = Render (headModel, shader).Image; image.VerticalFlip(); image ``` For the educational and debugging purposes I am removing the skin texture and apply a regular grid with horizontal red and vertical blue lines: ```csharp var gridTexture = Image.Load ("obj/grid.tga"); var shader = new TangentShader (headModel, viewPort, projection, modelView, light_dir, gridTexture); var image = Render (headModel, shader).Image; image.VerticalFlip(); image ``` Let us remember how Phong shading works: ![ ](./img/lesson6bis_triangle.png) For each vertex of a triangle we have its coordinates p, texture coordinates uv and normal vectors. For shading current fragment our software rasterizer gives us barycentric coordinates of the fragment (alpha, beta, gamma). It means that the coordinates of the fragment can be obtained as p = alpha p0 \+ beta p1 \+ gamma p2. Then in the same way we interpolate texture coordinates and the normal vector: ![ ](./img/lesson6bis_f00.png) Notice that blue and red lines are isolines of u and v, correspondingly. So, for each point of our surface we define a so-called Darboux frame, with x and y axes parallel to blue and red lines, and z axis orthogonal to the surface. This is the frame where tangent space normal map lives. # **How to reconstruct a (3D) linear function from three samples** Okay, so our goal is to compute three vectors (tangent basis) for each pixel we draw. Let us put that aside for a while and imagine a linear function f that for each point (x,y,z) gives a real number f(x,y,z) = Ax \+ By \+ Cz \+ D. The only problem that we do not know A, B, C and D, however we do know three values of the function at three different points of the space (p0, p1, p2): ![ ](./img/lesson6bis_f01.png) ![ ](./img/lesson6bis_gradient_a.png) It is convenient to imagine f as a height map of an inclined plane. We fix three different (non collinear) points on the plane and we know values of f in those points. Red lines inside the triangle show the iso-heights f0, f0 \+ 1 meter, f0 \+ 2 meters and so on. For a linear function we have the isolines are parallel (straight) lines. In fact, I am more interested in the direction, orthogonal to the isolines. If we move along an iso, the height does not change (well duh, it is an iso!). If we deviate a little bit from an iso, the height starts to change a little bit. The steepest ascent we obtain when we move orthogonally to the isolines. Let us recall that the steepest ascent direction for a function is nothing else than its [gradient](https://en.wikipedia.org/wiki/Gradient). For a linear function f(x,y,z) = Ax \+ By \+ Cz \+ D its gradient is a constant vector (A, B, C). Recall that we do not know the values of (A,B,C). We know only three samples of the function. Can we reconstruct A,B and C? Sure thing. So, we have three points p0, p1, p2 and thre values f0, f1, f2. We need to find the vector of the steepest ascent (A,B,C). Let us consider another function defined as g(p) = f(p) - f(p0): ![ ](./img/lesson6bis_gradient_b.png) Obviously that we simply translated our inclined plane, without changing its inclination, therefore the steepest ascent direction for f and g is the same. Let us rewrite the definition of g: ![ ](./img/lesson6bis_f02.png) Please note that superscript x in p^x means x coordinate of the point p and not a power. So, the function g is simply a dot product between vector (p-p0) and (ABC). And we still do not know (A,B,C)! Okay, let us recall what we know. We know that if we go from point p0 to point p2, then the function g will go from zero to f2-f0. In other words, the dot product between vectors (p2-p0) and (ABC) is equal to f2-f0. Same thing for (p1-p0). Therefore, we are looking for the vector ABC, orthogonal to the normal n and respecting two constraints on dot products: ![ ](./img/lesson6bis_f03.png) Let us rewrite this in a matrix form: ![ ](./img/lesson6bis_f04.png) So, we got an easy to solve linear matrix equation Ax = b: ![ ](./img/lesson6bis_f05.png) Please note that I used the letter A for two different things, the meaning should be clear from the context. So, our 3x3 matrix A, multiplied with the unknown vector x=(A,B,C), gives the vector b = (f1-f0, f2-f0, 0). Unknown vector x becomes known when we multiply inverse to A by b. Also note that in the matrix A we have nothing related to the function f. It contains only some information about our triangle. # **Let us compute Darboux basis and apply the perturbation of normals** So, Darboux basis is a triplet of vectors (i,j,n), where n - is the original normal vector, and i, j can be computed as follows: ![ ](./img/lesson6bis_f06.png) Using the normal maps in the tangent space. ```csharp class TangentShader : IShader { // triangle uv coordinates, written by the vertex shader, read by the fragment shader Vec3f varyingU = new Vec3f (); Vec3f varyingV = new Vec3f (); // normal per vertex to be interpolated by FS Matrix3 varyingNrm = new Matrix3 (); readonly Model model; readonly Vec3f lightDir; readonly Matrix4 uniformM; readonly Matrix4 uniformMIT; readonly Matrix4 transformation; readonly Vec3f[] ndcTri = new Vec3f[3]; // triangle in normalized device coordinates readonly Image texture; readonly Image normalMap; public TangentShader (Model model, Matrix4 viewport, Matrix4 projection, Matrix4 modelView, Vec3f lightDir, Image texture, Image normalMap) { this.model = model; this.lightDir = lightDir.Normalize (); this.texture = texture; this.normalMap = normalMap; uniformM = projection * modelView; uniformMIT = TransposeInverse (uniformM); transformation = viewport * uniformM; } public Vec4f Vertex (Face face, int nthvert) { UpdateVarayingUV (model, face, nthvert, ref varyingU, ref varyingV); var normal = Project3D (Mult (uniformMIT, Embed4D (model.Normal (face, nthvert)))); varyingNrm.SetColumn (nthvert, normal); var glVertex = TransformFace (model, face, nthvert, transformation); ndcTri[nthvert] = Project3D (glVertex / glVertex.h); return glVertex; } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { var bn = Mult(varyingNrm, bar).Normalize (); var uv = CalcUV (varyingU, varyingV, bar); var A = new Matrix3 (); A.SetRow (0, ndcTri [1] - ndcTri [0]); A.SetRow (1, ndcTri [2] - ndcTri [0]); A.SetRow (2, bn); var AI = Inverse (A); var i = Mult (AI, new Vec3f { x = varyingU.y - varyingU.x, y = varyingU.z - varyingU.x }); var j = Mult (AI, new Vec3f { x = varyingV.y - varyingV.x, y = varyingV.z - varyingV.x }); var B = new Matrix3 (); B.SetColumn (0, i.Normalize ()); B.SetColumn (1, j.Normalize ()); B.SetColumn (2, bn); var n = Mult (B, Normal (normalMap, uv)).Normalize (); var l = Transform (uniformM, lightDir).Normalize (); var diff = Math.Max (0f, Dot (n, l)); color = GetColor (texture, uv) * diff; return false; } } ``` All is quite straightforward, I compute the matrix A: ```csharp // var A = new Matrix3 (); // A.SetRow (0, ndcTri [1] - ndcTri [0]); // A.SetRow (1, ndcTri [2] - ndcTri [0]); // A.SetRow (2, bn); ``` Then compute two unknown vectors (i,j) of Darboux basis: ```csharp // var AI = Inverse (A); // var i = Mult (AI, new Vec3f { x = varyingU.y - varyingU.x, y = varyingU.z - varyingU.x }); // var j = Mult (AI, new Vec3f { x = varyingV.y - varyingV.x, y = varyingV.z - varyingV.x }); ``` Once we have all the tangent basis, I read the perturbed normal from the texture and apply the basis change from the tangent basis to the global coordinates. Recall that I have already described how to perform change of basis. Here is the final rendered image, compare the details with Phong shading: ```csharp var headTangentMap = Image.Load ("obj/african_head_nm_tangent.tga"); headTangentMap.VerticalFlip (); var shader = new TangentShader (headModel, viewPort, projection, modelView, light_dir, headTexture, headTangentMap); var image = Render (headModel, shader).Image; image.VerticalFlip(); image ``` # **Were you paying attention?** Have you noticed that generally a (flat) triangle has a constant normal vector, whereas I used the interpolated normal in the last row of the matrix A? Why did I do it? Happy coding! ================================================ FILE: graphics/tiny-renderer/lesson7.workbook/obj/diablo3_pose.obj ================================================ v 0.11526 0.700717 0.0677257 v 0.114223 0.654606 0.0821706 v 0.119952 0.67202 0.101202 v 0.12069 0.712368 0.0932415 v 0.120409 0.670105 0.118388 v 0.103434 0.63749 0.102854 v 0.0998313 0.642305 0.121165 v 0.113204 0.661161 0.119513 v 0.110674 0.71474 0.118248 v 0.114329 0.673286 0.128141 v 0.0938038 0.672987 0.125628 v 0.0910976 0.702896 0.120497 v 0.107546 0.664288 0.12793 v 0.116526 0.652831 0.0186975 v 0.122606 0.631867 0.0339156 v 0.123238 0.584561 0.0390644 v 0.113679 0.582153 0.0698344 v 0.107247 0.593611 0.124012 v 0.099392 0.618107 0.132025 v 0.0519629 0.664482 0.148508 v 0.056813 0.67065 0.139722 v 0.0671458 0.660001 0.134186 v 0.0799037 0.658226 0.13039 v 0.0872667 0.645679 0.131726 v 0.0690261 0.645978 0.151671 v 0.0731557 0.627719 0.151074 v 0.0524549 0.654325 0.16232 v 0.0402945 0.655625 0.166186 v 0.0399431 0.667873 0.157259 v 0.0514006 0.648069 0.163058 v 0.0395565 0.644343 0.164429 v 0.0403297 0.634327 0.163322 v 0.048132 0.610076 0.154571 v 0.021597 0.677468 0.15559 v 0.0424033 0.672267 0.161494 v 0.0551611 0.669385 0.152479 v 0.0324219 0.694391 0.157312 v 0.0500123 0.692264 0.158015 v 0.0621024 0.681106 0.149088 v 0.042087 0.725178 0.149141 v 0.0617158 0.711489 0.15088 v 0.0706604 0.695445 0.133782 v 0.0129512 0.710365 0.135873 v 0.0267634 0.736074 0.134696 v 0.0996029 0.759463 0.122043 v 0.127526 0.758813 0.113749 v 0.0634907 0.787228 0.117404 v 0.0781113 0.602994 0.15624 v 0.0661442 0.626208 0.15269 v 0.0892525 0.572418 0.146698 v 0.0501705 0.601641 0.155028 v 0.0637543 0.593944 0.162443 v 0.0649668 0.641321 0.158156 v 0.0678663 0.629969 0.156521 v 0.0497663 0.643588 0.152233 v 0.0475697 0.626384 0.148209 v 0.0605209 0.610199 0.15566 v 0.0599761 0.626419 0.15429 v 0.0643869 0.628457 0.153182 v 0.0578146 0.640741 0.152849 v 0.0813095 0.813025 0.103117 v 0.135047 0.790409 0.0950163 v 0.116789 0.817945 0.0520332 v 0.0892876 0.821565 0.0596598 v 0.0257091 0.775507 0.125488 v 0.0636313 0.679507 0.139194 v 0.0781289 0.671792 0.13872 v 0.0878993 0.595034 0.00293464 v 0.116772 0.566636 0.0537026 v 0.114417 0.562155 0.0744385 v 0.128176 0.558166 0.0246547 v 0.107194 0.567445 0.09651 v 0.0944716 0.545496 0.110902 v 0.0712403 0.535304 0.117264 v 0.112431 0.54474 0.087214 v 0.0971602 0.533775 0.0882684 v 0.0731382 0.524128 0.0962816 v 0.106368 0.520964 0.0665483 v 0.099392 0.514164 0.0756159 v 0.0780586 0.512283 0.0791129 v 0.1141 0.533037 0.0671107 v 0.115436 0.533582 0.0411731 v 0.115752 0.527449 0.0417179 v 0.114469 0.546304 0.0516993 v 0.102151 0.525076 0.0562506 v 0.0970021 0.503198 0.0402242 v 0.100605 0.498208 0.054177 v 0.0863529 0.491407 0.0541595 v 0.0949988 0.486943 0.0309282 v 0.0732963 0.583559 0.000140556 v 0.0795522 0.555653 0.0176783 v 0.0874073 0.557569 0.0307173 v 0.0843848 0.502601 0.03439 v 0.0989175 0.529927 0.0420342 v 0.0913612 0.482164 0.025094 v 0.0906759 0.48197 0.0349172 v 0.00242505 0.842706 0.085773 v -0.0105613 0.872456 0.0789021 v -0.0279935 0.869416 0.0666186 v -0.0107546 0.825273 0.0714863 v -0.00999895 0.80039 0.118951 v -0.0275542 0.855217 0.105806 v 0.00233719 0.823744 0.11222 v -0.0122131 0.863705 0.0988999 v -0.039451 0.902576 0.0606087 v -0.00137068 0.808351 0.0664078 v 0.0207008 0.806207 0.0844902 v 0.0138474 0.77795 0.120374 v -0.00152884 0.759691 0.126718 v -0.0331072 0.875532 0.0913612 v 0.0211577 0.79605 0.104594 v -0.226707 -0.278811 0.0844199 v -0.164271 -0.310688 0.0763188 v -0.190121 -0.154536 0.0547394 v -0.115682 -0.174358 0.0460584 v -0.102748 -0.13025 0.0384494 v -0.268074 -0.269339 0.0650371 v -0.243946 -0.149703 0.0212455 v -0.189084 -0.00231963 -0.0608723 v -0.259147 -0.376006 0.0909394 v -0.140495 -0.0527185 0.0225987 v -0.164921 -0.01086 -0.00980567 v -0.129125 -0.0841915 0.0319474 v -0.116754 -0.0240045 0.0389238 v -0.120655 -0.0525252 0.0430183 v -0.0982849 -0.162391 0.0430007 v -0.203775 -0.406776 0.0984782 v -0.145872 -0.436597 0.059484 v -0.112062 -0.35411 0.0492742 v -0.237813 -0.446297 0.116033 v -0.20511 -0.499332 0.0841563 v -0.272291 -0.426932 0.106158 v -0.270692 -0.459635 0.163568 v -0.233912 -0.504639 0.102661 v -0.283362 -0.512406 0.0865638 v -0.252293 -0.489931 0.130584 v -0.29858 -0.454451 0.1128 v -0.291674 -0.453854 0.139897 v -0.284153 -0.488068 0.128897 v -0.294415 -0.476822 0.0981619 v -0.302639 -0.443292 0.0965276 v -0.311004 -0.454768 0.12489 v -0.320423 -0.453836 0.0878993 v -0.311865 -0.403683 0.0613995 v -0.328718 -0.434137 0.0385899 v -0.328278 -0.278442 -0.00706431 v -0.321495 -0.34311 0.0478333 v -0.297754 -0.253506 -0.137736 v -0.214301 -0.520314 0.0970899 v -0.231346 -0.516958 0.105876 v -0.24356 -0.52411 0.101887 v -0.222419 -0.53743 0.100727 v -0.238007 -0.537219 0.100323 v -0.233315 -0.527818 0.121288 v -0.226268 -0.536639 0.0605033 v -0.180209 -0.502091 0.0646329 v -0.2563 -0.52404 0.0890767 v -0.278617 -0.532422 0.106368 v -0.24739 -0.547007 0.0609426 v -0.272256 -0.556567 0.0515938 v -0.237128 -0.554546 -0.0027238 v -0.329438 -0.473131 0.0214564 v -0.328981 -0.486733 0.0608371 v -0.307384 -0.510948 0.0583242 v -0.214266 -0.520806 0.0641936 v -0.209187 -0.532686 0.0775489 v -0.210118 -0.541472 0.0516817 v -0.18448 -0.526307 0.0144449 v -0.202369 -0.52469 0.046691 v -0.13995 -0.494078 -0.0121604 v -0.076477 -0.16464 -0.246828 v -0.215215 -0.18578 -0.218676 v -0.177468 -0.0685341 -0.2912 v -0.300513 -0.164886 -0.0611535 v -0.328489 -0.511264 -0.0174498 v -0.32754 -0.511071 0.0356377 v -0.294732 -0.547429 -0.00166944 v -0.313974 -0.486012 0.0562506 v -0.113872 -0.083102 0.0324922 v -0.0877061 -0.1322 0.0504868 v -0.0748427 -0.168576 0.02896 v -0.0878115 -0.13336 0.0293466 v -0.106439 -0.0435104 0.0336695 v -0.100411 -0.0729097 0.019664 v -0.0763716 -0.204442 0.0280814 v -0.155678 -0.252803 -0.213914 v -0.270464 -0.298615 -0.174779 v -0.227252 -0.0342143 -0.120321 v -0.229097 -0.0836292 -0.207834 v -0.0959301 -0.172671 -0.22314 v -0.18571 -0.119987 -0.24421 v -0.0694303 -0.201104 0.043317 v -0.0647911 -0.227656 0.0175025 v -0.0861948 -0.217271 0.0386778 v -0.0703792 -0.219379 0.0386251 v -0.099515 -0.241258 0.0468492 v -0.0809229 -0.241837 0.0346185 v -0.361825 -0.347046 -0.0517169 v -0.356465 -0.383352 0.0123713 v -0.365041 -0.413717 -0.0374302 v -0.198011 -0.343672 -0.195164 v -0.222542 -0.382104 -0.170984 v -0.0891119 -0.308386 -0.115946 v -0.0247777 -0.200436 -0.16942 v -0.122096 -0.400907 -0.110357 v -0.0774611 -0.32262 -0.0285383 v -0.0899027 -0.36237 -0.0259375 v -0.0697642 -0.274013 0.00676553 v -0.126085 -0.453625 -0.0196289 v -0.150986 -0.459249 -0.0810108 v -0.343496 -0.37142 -0.228429 v -0.232489 -0.383334 -0.251801 v -0.17195 -0.413577 -0.222964 v -0.319439 -0.410818 -0.323955 v -0.242874 -0.411029 -0.323674 v -0.300373 -0.419147 -0.372492 v -0.241398 -0.423136 -0.377693 v -0.280023 -0.359242 -0.238586 v -0.336608 -0.363635 -0.116596 v -0.341528 -0.467894 -0.310635 v -0.376516 -0.419341 -0.17 v -0.34021 -0.470987 -0.359734 v -0.356922 -0.494693 -0.23154 v -0.3678 -0.432415 -0.235687 v -0.3691 -0.469423 -0.118248 v -0.337117 -0.518838 -0.136945 v -0.268197 -0.578551 -0.134977 v -0.192633 -0.538994 -0.0549854 v -0.157927 -0.511422 -0.0755105 v -0.170052 -0.525604 -0.152884 v -0.146153 -0.481074 -0.182283 v -0.185956 -0.440973 -0.312691 v -0.281376 -0.36418 -0.154307 v -0.159315 -0.374846 -0.160071 v -0.177029 -0.419499 -0.142814 v -0.207623 -0.455523 -0.380628 v -0.20019 -0.524444 -0.379503 v -0.332267 -0.533529 -0.224792 v -0.27563 -0.574175 -0.229923 v -0.175816 -0.507697 -0.257214 v -0.293695 -0.535023 0.0562506 v -0.0170808 -0.191808 -0.0932415 v -0.0249886 -0.115858 -0.00550031 v -0.0118968 -0.173286 -0.0372369 v -0.216093 -0.549345 -0.141426 v -0.23291 -0.571153 -0.356694 v -0.211893 -0.551805 -0.242365 v -0.213334 -0.49464 -0.477524 v -0.24196 -0.540681 -0.524602 v -0.222824 -0.433786 -0.46568 v -0.322303 -0.541771 -0.514656 v -0.347767 -0.520121 -0.487664 v -0.280392 -0.547306 -0.527994 v -0.286262 -0.580027 -0.331002 v -0.335676 -0.543387 -0.345904 v -0.371261 -0.533406 -0.419358 v -0.324289 -0.469845 -0.50427 v -0.359347 -0.47343 -0.451956 v -0.242259 -0.468843 -0.513584 v -0.328155 -0.438284 -0.464064 v -0.274066 -0.472727 -0.520121 v -0.268636 -0.418778 -0.47336 v -0.26405 -0.676959 -0.365744 v -0.223509 -0.587302 -0.461551 v -0.229431 -0.689242 -0.390381 v -0.217798 -0.629336 -0.456683 v -0.244421 -0.666872 -0.48132 v -0.27078 -0.728043 -0.425509 v -0.283204 -0.679841 -0.483376 v -0.276843 -0.784821 -0.410097 v -0.244755 -0.72734 -0.414403 v -0.238868 -0.781991 -0.378519 v -0.24739 -0.767353 -0.363354 v -0.241451 -0.720768 -0.382596 v -0.268583 -0.7146 -0.363898 v -0.251221 -0.79851 -0.377096 v -0.273469 -0.798422 -0.39191 v -0.263188 -0.827716 -0.377482 v -0.25326 -0.811514 -0.363354 v -0.282466 -0.829192 -0.392033 v -0.274997 -0.828366 -0.372615 v -0.275489 -0.81487 -0.357748 v -0.239852 -0.749868 -0.402822 v -0.257881 -0.783801 -0.405107 v -0.234703 -0.689839 -0.458511 v -0.328454 -0.660264 -0.488051 v -0.367167 -0.637666 -0.455101 v -0.388641 -0.741943 -0.435631 v -0.376199 -0.631515 -0.395108 v -0.400098 -0.749288 -0.367958 v -0.383721 -0.823042 -0.261308 v -0.341229 -0.632657 -0.35462 v -0.362352 -0.751995 -0.321882 v -0.42405 -0.853284 -0.300847 v -0.350174 -0.740432 -0.472639 v -0.374196 -0.81292 -0.477929 v -0.319228 -0.757776 -0.318754 v -0.282642 -0.767582 -0.344621 v -0.337117 -0.824061 -0.251221 v -0.378642 -0.839771 -0.211243 v -0.346519 -0.841335 -0.204056 v -0.384265 -0.849313 -0.179577 v -0.353566 -0.852177 -0.173321 v -0.398341 -0.84731 -0.154711 v -0.351914 -0.850033 -0.14466 v -0.403841 -0.868169 -0.125505 v -0.359206 -0.872685 -0.119829 v -0.407268 -0.896601 -0.109988 v -0.428268 -0.941078 -0.0731733 v -0.385618 -0.936808 -0.0554072 v -0.427512 -0.988226 -0.0347064 v -0.40834 -0.985977 -0.0265877 v -0.418638 -1 -0.0334763 v -0.409447 -0.922574 -0.0527537 v -0.368555 -0.903806 -0.104699 v -0.420114 -0.954082 -0.0233543 v -0.420711 -0.984887 -0.0225108 v -0.380716 -0.952641 -0.0529294 v -0.34615 -0.890767 -0.143553 v -0.322708 -0.865621 -0.209732 v -0.305029 -0.838523 -0.25282 v -0.394229 -0.880435 -0.21279 v -0.40298 -0.884916 -0.172548 v -0.339911 -0.878431 -0.173321 v -0.340333 -0.942467 -0.116332 v -0.372263 -0.974871 -0.0709767 v -0.418111 -0.930781 -0.135627 v -0.368063 -0.961059 -0.140565 v -0.395266 -0.987225 -0.105613 v -0.412768 -0.970864 -0.0551963 v -0.405546 -0.98306 -0.078041 v -0.434401 -0.949988 -0.0829438 v -0.430183 -0.963326 -0.099269 v -0.400661 -0.968861 -0.0308228 v -0.415563 -0.977208 -0.0443539 v -0.43173 -0.974168 -0.0451095 v -0.224142 -0.382578 -0.183021 v -0.280744 -0.362475 -0.179102 v -0.344762 -0.376305 -0.133308 v -0.175869 -0.418251 -0.162514 v -0.151408 -0.46742 -0.0904298 v -0.409061 -0.832689 -0.359452 v -0.436527 -0.875479 -0.277827 v -0.409078 -0.870471 -0.240203 v -0.391171 -0.957931 -0.0474467 v -0.428619 -0.95236 -0.0712403 v -0.392612 -0.924736 -0.175588 v -0.355446 -0.943785 -0.177661 v -0.330826 -0.922803 -0.173795 v -0.319826 -0.938302 -0.223263 v -0.383246 -0.93419 -0.226075 v -0.347784 -0.955277 -0.227568 v -0.480494 -0.870594 -0.26296 v -0.466014 -0.867518 -0.233859 v -0.496784 -0.864953 -0.258479 v -0.484782 -0.858591 -0.230099 v -0.519383 -0.873036 -0.246775 v -0.51021 -0.867501 -0.220557 v -0.533916 -0.892402 -0.2382 v -0.52476 -0.883633 -0.21532 v -0.587987 -0.92753 -0.202176 v -0.573015 -0.93013 -0.187977 v -0.603399 -0.965013 -0.185112 v -0.587759 -0.96807 -0.171968 v -0.586863 -0.943134 -0.216779 v -0.594753 -0.980635 -0.201314 v -0.598478 -0.987506 -0.180719 v -0.494025 -0.905792 -0.259076 v -0.524075 -0.915598 -0.247777 v -0.576249 -0.955312 -0.233332 v -0.549134 -0.94679 -0.181686 v -0.488437 -0.883668 -0.221137 v -0.471251 -0.883334 -0.227797 v -0.500105 -0.92268 -0.200366 v -0.542315 -0.9693 -0.213774 v -0.510175 -0.93665 -0.225196 v -0.579254 -0.973834 -0.194496 v -0.562577 -0.97654 -0.205005 v -0.574913 -0.952009 -0.179278 v -0.587583 -0.966858 -0.20931 v -0.586318 -0.976945 -0.189242 v -0.474519 -0.931536 -0.233244 v -0.471128 -0.917724 -0.215742 v -0.419358 -0.91319 -0.226532 v -0.434822 -0.917548 -0.305978 v -0.403086 -0.886515 -0.359224 v -0.386269 -0.851984 -0.4263 v -0.313341 -0.810829 -0.460127 v -0.316188 -0.843602 -0.441131 v -0.336397 -0.967947 -0.279725 v -0.260763 -0.938847 -0.308069 v -0.331336 -0.942554 -0.324307 v -0.331266 -0.886444 -0.370506 v -0.42948 -0.944575 -0.319878 v -0.402225 -0.95707 -0.275103 v -0.289021 -0.878203 -0.359347 v -0.281288 -0.843813 -0.282975 v -0.270323 -0.859347 -0.334481 v -0.24479 -0.877289 -0.243893 v -0.248199 -0.887095 -0.304731 v -0.253963 -0.845781 -0.223509 v -0.303676 -0.75029 -0.466717 v -0.289108 -0.850455 -0.208502 v -0.260588 -0.844603 -0.187889 v -0.228816 -0.848575 -0.203423 v -0.206727 -0.855376 -0.172688 v -0.241908 -0.847099 -0.155889 v -0.203898 -0.870436 -0.156785 v -0.234949 -0.862159 -0.140811 v -0.19541 -0.921221 -0.103943 v -0.216146 -0.921098 -0.103697 v -0.198591 -0.962798 -0.0907462 v -0.213334 -0.965487 -0.0940499 v -0.205005 -0.982515 -0.0964222 v -0.188469 -0.935121 -0.118687 v -0.196746 -0.973518 -0.107019 v -0.22669 -0.884125 -0.210769 v -0.20989 -0.902594 -0.18202 v -0.244526 -0.94744 -0.12315 v -0.259902 -0.893702 -0.160827 v -0.264629 -0.859558 -0.181721 v -0.263751 -0.886901 -0.173022 v -0.23342 -0.952659 -0.161125 v -0.195779 -0.953432 -0.152198 v -0.238007 -0.917232 -0.176185 v -0.212333 -0.960742 -0.113608 v -0.223579 -0.965434 -0.138123 v -0.22379 -0.944452 -0.106509 v -0.197817 -0.949302 -0.126999 v -0.21047 -0.968914 -0.104084 v -0.240818 -0.908744 -0.186219 v -0.307929 -0.903314 -0.210066 v -0.240484 -0.924402 -0.250308 v -0.278231 -0.957896 -0.25159 v -0.268987 -0.933399 -0.223456 v -0.0218079 -0.117158 0.00576388 v -0.00451622 -0.172354 -0.017485 v 0.0111588 -0.124943 0.00857553 v 0.0238112 -0.188258 -0.0190665 v -0.0554599 -0.00961236 0.0186623 v -0.0614171 -0.0116157 0.0119144 v -0.110744 -0.0432116 0.0195761 v -0.0848944 0.0545812 0.00748601 v 0.00130039 -0.0290304 0.0240924 v 0.0115981 0.0488525 -0.00326856 v -0.12735 -0.033775 0.0174498 v -0.137437 0.00885669 0.00472708 v -0.171651 0.0863529 -0.0459706 v -0.154799 0.0739816 -0.0121253 v -0.236794 0.11208 -0.127719 v -0.00829438 -0.198556 -0.0915369 v 0.00970021 -0.244807 -0.25275 v -0.00630865 -0.252961 -0.285629 v -0.126911 -0.230521 -0.328032 v -0.0404702 -0.290022 -0.341757 v -0.15805 -0.313658 -0.37764 v -0.083225 -0.350771 -0.392753 v -0.256054 -0.452518 -0.493463 v -0.20815 -0.500773 -0.534478 v -0.38785 -0.571943 -0.536727 v -0.35831 -0.604172 -0.591642 v -0.540699 -0.660106 -0.534829 v -0.543475 -0.680473 -0.592679 v -0.683214 -0.726338 -0.418321 v -0.724001 -0.750641 -0.408744 v -0.724388 -0.787808 -0.271782 v -0.748234 -0.790022 -0.2689 v -0.211313 -0.245001 -0.433381 v -0.302499 -0.393263 -0.526043 v -0.427301 -0.509964 -0.533318 v -0.554036 -0.612449 -0.514199 v -0.680245 -0.695516 -0.410888 v -0.737585 -0.772502 -0.255017 v -0.178171 -0.180192 -0.381313 v -0.188715 -0.170773 -0.417759 v -0.202053 -0.145064 -0.39212 v -0.206551 -0.151056 -0.425157 v -0.221031 -0.117808 -0.435455 v -0.164482 -0.136752 -0.357045 v -0.188293 -0.11888 -0.377025 v -0.176484 -0.109971 -0.401733 v -0.181826 -0.108793 -0.358328 v -0.109865 -0.184638 -0.285313 v -0.154623 -0.103557 -0.339982 v -0.202105 -0.071293 -0.404562 v -0.154992 -0.0832074 -0.364443 v -0.237673 -0.218747 -0.499807 v -0.233719 -0.194953 -0.539715 v -0.245194 -0.22676 -0.551506 v -0.263188 -0.209345 -0.57783 v -0.23089 -0.256071 -0.488666 v -0.233016 -0.250308 -0.535919 v -0.207043 -0.223298 -0.566162 v -0.206217 -0.240853 -0.557498 v -0.18462 -0.187748 -0.548993 v -0.212754 -0.192264 -0.556426 v -0.241556 -0.20678 -0.578357 v -0.20685 -0.173057 -0.491934 v -0.20866 -0.138597 -0.47705 v -0.218413 -0.113661 -0.525147 v -0.215232 -0.118546 -0.496538 v -0.224581 -0.051998 -0.457843 v -0.201227 -0.0994096 -0.483007 v -0.237444 -0.0798334 -0.476435 v -0.190437 -0.1364 -0.440147 v -0.238042 -0.0523847 -0.479932 v -0.225038 -0.0361825 -0.473184 v -0.204144 -0.026781 -0.448248 v -0.221506 -0.00962994 -0.477858 v -0.204899 -0.0453907 -0.494746 v -0.219309 -0.0796226 -0.49884 v -0.252188 -0.0474643 -0.521035 v -0.151654 -0.104471 -0.517538 v -0.186817 -0.100341 -0.495466 v -0.169595 -0.0330721 -0.360524 v -0.213686 0.0203142 -0.414912 v -0.201771 -0.0223878 -0.43129 v -0.22727 0.0430359 -0.42572 v -0.168734 -0.0770218 -0.383475 v -0.183689 -0.0212104 -0.453045 v -0.137332 -0.0663023 -0.501599 v -0.112677 -0.028714 -0.463185 v -0.295294 -0.356096 -0.576424 v -0.431079 -0.483569 -0.569009 v -0.567901 -0.587179 -0.534109 v -0.692089 -0.676326 -0.409816 v -0.255263 -0.307103 -0.551752 v -0.257512 -0.329192 -0.491811 v -0.271079 -0.273082 -0.567005 v -0.224423 -0.265631 -0.564756 v -0.246758 -0.275191 -0.500949 v -0.250712 -0.3106 -0.564299 v -0.247461 -0.264401 -0.533986 v -0.239676 -0.282202 -0.568868 v -0.745598 -0.785278 -0.25282 v -0.17058 -0.14835 -0.537219 v -0.179348 -0.114329 -0.518979 v -0.191597 -0.00715217 -0.30814 v -0.223983 0.0790953 -0.344287 v -0.260517 0.131884 -0.356869 v -0.214125 0.0328788 -0.389818 v -0.18383 0.0240396 -0.427231 v -0.253137 0.104137 -0.375637 v -0.27867 0.149861 -0.385531 v -0.218202 0.115418 -0.406548 v -0.113731 0.0165009 -0.454627 v -0.106632 0.064545 -0.41971 v -0.0471831 0.182318 0.00604504 v -0.0370084 0.130549 -0.00416479 v 0.0283977 0.118494 -0.0347767 v -0.0450743 0.109514 0.0105788 v -0.0674973 0.0732787 0.00590445 v -0.0687977 0.109936 0.020279 v -0.0988824 0.0630865 0.00678309 v -0.05669 0.128475 -0.0250062 v -0.0825396 0.0679893 -0.0156926 v -0.0641233 0.105279 -0.0112818 v -0.0997083 0.0442132 -0.00295226 v -0.0515236 0.26368 -0.0284329 v -0.0974063 0.409869 0.0412259 v 0.0925034 0.404755 -0.0309634 v 0.0899027 0.504077 -0.0140231 v -0.210681 0.101466 -0.0606263 v -0.165009 0.0900959 -0.0308931 v -0.230907 0.108987 -0.0835589 v -0.250554 0.145661 -0.116578 v -0.200893 0.125663 -0.036534 v -0.23762 0.0883387 -0.157453 v -0.243384 0.101887 -0.219081 v -0.228078 0.108495 -0.156838 v -0.242119 0.0460057 -0.217148 v -0.268724 0.124398 -0.177169 v -0.267652 0.106948 -0.200401 v -0.25869 0.0981092 -0.257196 v -0.259709 0.086968 -0.311461 v -0.245299 0.0941025 -0.28468 v -0.25695 0.14162 -0.257354 v -0.196306 0.118845 -0.202369 v -0.273732 0.14603 -0.312094 v -0.215056 0.115348 -0.267634 v -0.170527 0.115172 -0.243489 v -0.228342 0.113608 -0.289723 v -0.273556 0.141321 -0.210171 v -0.227094 0.121639 -0.194883 v -0.245387 0.132816 -0.1839 v -0.22669 0.12192 -0.242997 v -0.203037 0.127825 -0.0755457 v -0.162478 0.071293 -0.0233016 v -0.199311 0.0553193 -0.0644221 v -0.152181 0.114505 -0.0470777 v -0.147137 0.0883738 -0.0385548 v -0.02353 0.169859 -0.00704673 v -0.0356201 0.185991 -0.0167645 v -0.0239518 0.218184 -0.0281517 v 0.0821706 0.347187 -0.041015 v -0.0566197 0.318332 0.0103152 v -0.0683056 0.370277 0.0193301 v -0.0364461 0.218097 -0.0120901 v -0.043317 0.219098 -0.0370436 v -0.05307 0.172354 -0.0321056 v -0.0248304 0.275858 -0.0146382 v 0.0609602 0.245018 -0.0526834 v -0.0702914 0.389133 0.0130566 v -0.14104 0.178927 -0.0426493 v -0.111201 0.22256 -0.0572172 v -0.142305 0.331863 -0.0111939 v -0.191509 0.13213 -0.126981 v -0.171599 0.222419 -0.119566 v -0.176273 0.291973 -0.0724353 v -0.199294 0.174323 -0.243278 v -0.218009 0.268003 -0.221312 v -0.197079 0.350789 -0.0400134 v -0.255931 0.328243 -0.16898 v -0.265297 0.32204 -0.262398 v -0.295716 0.36794 -0.250501 v -0.238815 0.310301 -0.361508 v -0.164552 0.174815 -0.262345 v -0.192721 0.227779 -0.324852 v -0.225512 0.270411 -0.334271 v -0.206534 0.262538 -0.357906 v -0.28642 0.334306 -0.245914 v -0.287175 0.361561 -0.288827 v -0.101905 0.20634 -0.336221 v -0.211928 0.115524 -0.296419 v -0.0737884 0.120304 -0.331195 v -0.224686 0.145942 -0.351773 v -0.153921 0.104348 -0.353601 v -0.154729 0.134432 -0.300109 v -0.0861421 0.470161 0.0632095 v -0.0696236 0.420026 0.0354971 v -0.116174 0.456788 0.065986 v -0.099269 0.427459 0.0370084 v -0.129213 0.440973 0.0426493 v -0.0952799 0.419798 0.0239693 v -0.104365 0.403015 0.0261659 v -0.0480969 0.358345 0.0105964 v -0.0635434 0.366148 0.00333882 v -0.0767054 0.349594 -0.00279411 v -0.216937 0.325537 -0.317963 v -0.262064 0.35339 -0.277862 v -0.251415 0.353232 -0.298896 v -0.214248 0.287474 -0.268988 v -0.135996 0.272449 -0.331441 v -0.185991 0.352002 -0.366183 v -0.177802 0.298334 -0.299353 v -0.113152 0.272098 -0.350912 v -0.134292 0.34789 -0.371683 v -0.158419 0.209749 -0.320775 v -0.144818 0.381788 -0.391628 v -0.21887 0.291006 -0.323709 v -0.271307 0.36982 -0.273662 v -0.261308 0.383703 -0.295646 v -0.297684 0.401206 -0.397586 v -0.303553 0.405441 -0.369926 v -0.300302 0.425087 -0.348329 v -0.40841 0.456244 -0.431378 v -0.39697 0.473869 -0.44389 v -0.407022 0.47292 -0.407338 v -0.474027 0.488859 -0.474607 v -0.452114 0.485819 -0.465645 v -0.470091 0.486293 -0.452764 v -0.444593 0.465276 -0.442396 v -0.434576 0.480617 -0.454891 v -0.44758 0.479703 -0.426159 v -0.460567 0.471971 -0.460742 v -0.294855 0.443574 -0.346009 v -0.3969 0.493867 -0.432872 v -0.403051 0.493762 -0.411802 v -0.461586 0.496538 -0.458528 v -0.439356 0.495923 -0.443749 v -0.444435 0.494289 -0.432222 v -0.270253 0.463361 -0.397058 v -0.258426 0.427653 -0.419183 v -0.285242 0.464714 -0.364232 v -0.250185 0.415 -0.287913 v -0.163884 0.398587 -0.370242 v -0.219731 0.462746 -0.353495 v -0.188961 0.445067 -0.35411 v -0.361104 0.568288 -0.308245 v -0.354374 0.574403 -0.367589 v -0.300671 0.599989 -0.392384 v -0.312603 0.471637 -0.212051 v -0.386058 0.625136 -0.27078 v -0.440551 0.614206 -0.365181 v -0.428162 0.646558 -0.388518 v -0.435631 0.65566 -0.290444 v -0.412997 0.68636 -0.368063 v -0.319984 0.679524 -0.371999 v -0.342003 0.658823 -0.283327 v -0.419024 0.697079 -0.32218 v -0.347538 0.705813 -0.334007 v -0.150898 0.625716 -0.381893 v -0.217552 0.679577 -0.296735 v -0.172671 0.673479 -0.332232 v -0.117756 0.687766 -0.318455 v -0.274593 0.646874 -0.386726 v -0.281798 0.677837 -0.329421 v -0.351615 0.679278 -0.32863 v -0.320616 0.659386 -0.380259 v -0.148614 0.556022 -0.396496 v -0.315696 0.684708 -0.327171 v -0.223491 0.65812 -0.237216 v -0.345218 0.671054 -0.308368 v -0.278635 0.65436 -0.281763 v -0.268724 0.631164 -0.229431 v -0.307103 0.626401 -0.26108 v -0.190244 0.68701 -0.250308 v -0.138263 0.694531 -0.272678 v -0.22191 0.704495 -0.291621 v -0.450023 0.628686 -0.313236 v -0.43013 0.694039 -0.294784 v -0.524321 0.683882 -0.367483 v -0.508716 0.697167 -0.386058 v -0.526465 0.725723 -0.31835 v -0.496134 0.739325 -0.369979 v -0.524426 0.689189 -0.338225 v -0.511616 0.739975 -0.314009 v -0.56878 0.72973 -0.383703 v -0.572558 0.782993 -0.358873 v -0.575177 0.73994 -0.349489 v -0.573753 0.771307 -0.338277 v -0.503356 0.754279 -0.335097 v -0.573753 0.768566 -0.379872 v -0.6435 0.751379 -0.372492 v -0.642481 0.760517 -0.362932 v -0.631621 0.77621 -0.375321 v -0.63633 0.76296 -0.380997 v -0.659632 0.761062 -0.377588 v -0.185622 0.524198 -0.384898 v -0.195972 0.482902 -0.368678 v -0.180772 0.441324 -0.45837 v -0.208748 0.450216 -0.438776 v -0.174727 0.536727 -0.443257 v -0.207518 0.508523 -0.428971 v -0.219696 0.522564 -0.519102 v -0.21358 0.496345 -0.511967 v -0.22379 0.498998 -0.504956 v -0.212262 0.529558 -0.506203 v -0.224054 0.519822 -0.500984 v 0.0923629 0.459284 -0.0198397 v -0.0165888 0.480195 0.0423329 v -0.0253752 0.461832 0.0294521 v 0.0173268 0.396935 0.00817136 v 0.022792 0.347169 -0.0113345 v 0.0708713 0.278617 -0.0503638 v -0.0942256 0.492742 0.0723122 v -0.144501 0.538379 0.0842617 v -0.121007 0.498225 0.0578322 v -0.17738 0.700137 -0.291727 v -0.197835 0.689418 -0.27085 v -0.094454 0.718676 -0.274576 v -0.18643 0.712456 -0.219748 v -0.132482 0.742681 -0.20374 v -0.0662145 0.766668 -0.220293 v -0.122079 0.76593 -0.171388 v -0.022792 0.82566 -0.153393 v -0.202527 0.718676 -0.194039 v -0.172425 0.7327 -0.191245 v -0.190349 0.696253 -0.212913 v -0.191298 0.731575 -0.162039 v -0.199786 0.700418 -0.184655 v -0.187889 0.720293 -0.151794 v -0.168893 0.765912 -0.128194 v -0.118582 0.757196 -0.141215 v -0.256001 0.688855 -0.215285 v -0.252697 0.664183 -0.237655 v -0.299336 0.51694 -0.317787 v -0.33109 0.484132 -0.307191 v -0.353232 0.496169 -0.348223 v -0.305767 0.472376 -0.350227 v -0.291217 0.558395 -0.371753 v -0.192616 0.558518 -0.389836 v -0.173813 0.725266 -0.155959 v -0.1519 0.741662 -0.109338 v -0.171072 0.73827 -0.132587 v -0.101958 0.792395 -0.147788 v -0.0465856 0.798352 -0.190982 v -0.114364 0.756071 -0.102959 v -0.118177 0.801937 -0.175553 v -0.07479 0.79909 -0.172794 v -0.109004 0.810284 -0.162285 v -0.0652304 0.809756 -0.153991 v -0.0105789 0.847556 -0.114452 v -0.0680596 0.827646 -0.11881 v -0.0867747 0.811689 -0.137051 v -0.0922398 0.784522 -0.0962289 v -0.119864 0.774751 -0.162531 v -0.111921 0.777985 -0.16826 v -0.214582 0.714283 -0.13814 v -0.219661 0.734 -0.107862 v -0.202914 0.686272 -0.107229 v -0.233279 0.688785 -0.156662 v -0.194514 0.694391 -0.0893579 v -0.230028 0.679384 -0.12967 v -0.233016 0.704812 -0.150951 v -0.241205 0.703089 -0.115735 v -0.219327 0.697378 -0.120075 v -0.191702 0.721646 -0.109075 v -0.160897 0.730977 -0.12113 v -0.196763 0.675412 -0.0858961 v -0.233033 0.661213 -0.112413 v -0.0795698 0.802552 -0.103223 v -0.0903596 0.821706 -0.135961 v -0.0982849 0.783924 -0.165132 v -0.103012 0.778863 -0.108723 v -0.0882508 0.757337 -0.119337 v -0.0494324 0.624433 -0.0333006 v -0.158525 0.619741 -0.0540541 v -0.0821179 0.708836 -0.110832 v -0.153165 0.686202 -0.0551963 v -0.0980037 0.604699 -0.0436334 v -0.0140407 0.523776 0.0235476 v -0.112923 0.520789 0.0663375 v -0.188521 0.609057 -0.033652 v -0.150652 0.559062 0.0299968 v -0.222982 0.630021 0.0142516 v -0.202703 0.545865 0.0467613 v -0.174129 0.52165 0.0595192 v -0.186993 0.649211 -0.0749482 v -0.211805 0.605964 -0.0708713 v -0.226531 0.680051 -0.0760728 v -0.236443 0.616016 -0.0921168 v -0.332777 0.47401 -0.181334 v -0.361596 0.500176 -0.114786 v -0.383158 0.42108 -0.117474 v -0.276632 0.657435 -0.172073 v -0.331793 0.511493 -0.219977 v -0.39683 0.498295 -0.216146 v -0.256599 0.664658 -0.123766 v -0.271869 0.626226 -0.129916 v -0.317717 0.629442 -0.1574 v -0.315134 0.531192 -0.134397 v -0.332689 0.496116 -0.155783 v -0.355938 0.566777 -0.148174 v -0.329842 0.531139 -0.115998 v -0.348276 0.502003 -0.126577 v -0.32081 0.521228 -0.148912 v -0.39495 0.413225 0.045953 v -0.403332 0.363143 -0.0164833 v -0.399817 0.398991 -0.0650371 v -0.392489 0.450181 -0.00407692 v -0.346308 0.43491 0.123959 v -0.367518 0.474801 0.0462341 v -0.332373 0.535427 -0.0382912 v -0.28171 0.441078 0.132236 v -0.227849 0.465768 0.117439 v -0.427459 0.387095 0.09108 v -0.435789 0.338453 0.0306997 v -0.381436 0.404456 0.137543 v -0.445981 0.345218 0.129793 v -0.40103 0.37815 0.163304 v -0.343022 0.395828 0.198415 v -0.247057 0.387112 0.149193 v -0.301111 0.351193 0.208554 v -0.502935 0.347099 0.210927 v -0.414561 0.369135 0.26528 v -0.472393 0.369047 0.222507 v -0.525076 0.289671 0.226672 v -0.448547 0.317436 0.0624011 v -0.445647 0.289442 0.112765 v -0.417601 0.287597 0.0317717 v -0.29619 0.500808 0.109813 v -0.37685 0.487435 -0.0773381 v -0.271483 0.550118 0.0389062 v -0.258215 0.567093 0.00386601 v -0.136998 0.472797 0.0573753 v -0.180543 0.516308 0.092644 v -0.501213 0.341177 0.366253 v -0.390398 0.318877 0.236513 v -0.372615 0.303729 0.239026 v -0.359189 0.311127 0.233859 v -0.39017 0.326925 0.273469 v -0.403455 0.34926 0.222015 v -0.507029 0.287281 0.188065 v -0.476048 0.350719 0.460285 v -0.506801 0.306312 0.424876 v -0.502144 0.329262 0.430622 v -0.513303 0.304643 0.4609 v -0.509595 0.322251 0.46554 v -0.506063 0.31719 0.482867 v -0.510579 0.288757 0.368063 v -0.525006 0.295276 0.294152 v -0.514884 0.339683 0.306224 v -0.464573 0.372861 0.314378 v -0.525375 0.258321 0.270218 v -0.509138 0.244122 0.192212 v -0.5223 0.242857 0.214107 v -0.42043 0.246863 0.106316 v -0.508576 0.232155 0.282606 v -0.497733 0.22024 0.196499 v -0.510807 0.219362 0.221734 v -0.505869 0.288423 0.468931 v -0.497188 0.29141 0.425948 v -0.495291 0.25876 0.376164 v -0.477788 0.219239 0.165835 v -0.49327 0.246723 0.15921 v -0.267037 0.352072 -0.149562 v -0.309581 0.383808 -0.237778 v -0.241785 0.297719 0.0423857 v -0.302042 0.39683 -0.224282 v -0.285277 0.271711 -0.000948948 v -0.30698 0.390785 -0.281306 v -0.316698 0.406249 -0.27512 v -0.2731 0.385249 -0.293677 v -0.263452 0.412821 -0.286367 v -0.286156 0.401961 -0.303887 v -0.314079 0.416002 -0.307226 v -0.318156 0.421854 -0.302042 v -0.280621 0.424296 -0.28403 v -0.311935 0.428074 -0.302042 v -0.304098 0.422187 -0.306839 v -0.307331 0.457052 -0.262398 v -0.370822 0.327382 -0.0895688 v -0.343953 0.366218 -0.148139 v -0.300671 0.491583 -0.277616 v -0.335659 0.290637 -0.0737357 v -0.320476 0.46496 -0.312111 v -0.338066 0.474344 -0.340579 v -0.297455 0.435719 -0.267617 v -0.256634 0.516343 -0.333726 v -0.263557 0.467613 -0.353636 v -0.267793 0.493428 -0.353425 v -0.301357 0.455242 -0.326503 v -0.334429 0.500176 -0.33768 v -0.309809 0.493182 -0.353495 v -0.421098 0.275489 0.0633149 v -0.386567 0.326714 -0.0402945 v -0.335378 0.285875 -0.0232489 v -0.203247 0.386761 0.0166415 v -0.149896 0.414297 0.0263241 v -0.167258 0.475011 0.0974941 v -0.148438 0.479405 0.0743682 v -0.35274 0.258619 0.207799 v -0.291727 0.300443 0.118898 v -0.249025 0.347099 0.0987418 v -0.178312 0.408604 -0.0285207 v -0.208185 0.421116 0.0755808 v -0.363195 0.231136 0.119407 v -0.381454 0.243911 0.0394686 v -0.444241 0.202755 0.242646 v -0.429023 0.199294 0.184251 v -0.465821 0.260869 0.409061 v -0.465557 0.22973 0.327733 v -0.415211 0.276596 0.412751 v -0.393597 0.231311 0.322954 v -0.456859 0.366745 0.377236 v -0.379275 0.297403 0.336239 v -0.404 0.318508 0.418778 v -0.410941 0.343268 0.465909 v -0.372035 0.293062 0.278196 v -0.364689 0.249991 0.295505 v -0.381225 0.262714 0.347626 v -0.322198 0.264489 0.169402 v -0.3203 0.246318 0.0940498 v -0.378115 0.221892 0.213018 v -0.356131 0.254033 0.246986 v -0.470144 0.325098 0.522862 v -0.395406 0.31784 0.498172 v -0.395582 0.311356 0.464889 v -0.529013 0.265543 0.56031 v -0.496521 0.275208 0.59101 v -0.453555 0.274734 0.607458 v -0.422012 0.276386 0.605578 v -0.545127 0.249148 0.535286 v -0.449671 0.259937 0.639388 v -0.425755 0.262978 0.637648 v -0.453432 0.243595 0.685306 v -0.43918 0.246811 0.686764 v -0.458844 0.243296 0.700418 v -0.441359 0.248445 0.704003 v -0.461111 0.233473 0.724071 v -0.446245 0.234597 0.726356 v -0.46684 0.212385 0.754261 v -0.467807 0.186237 0.773363 v -0.442291 0.188012 0.777001 v -0.454803 0.197378 0.773047 v -0.446543 0.214723 0.759059 v -0.37337 0.244649 0.570081 v -0.382438 0.288862 0.488543 v -0.416617 0.235072 0.660212 v -0.429603 0.229765 0.707535 v -0.437212 0.17499 0.772731 v -0.433434 0.201701 0.754701 v -0.465382 0.163761 0.788089 v -0.444066 0.169226 0.791094 v -0.457614 0.177345 0.796067 v -0.455699 0.149299 0.809458 v -0.385355 0.257214 0.483657 v -0.438987 0.241152 0.490282 v -0.41428 0.220363 0.525305 v -0.393983 0.231838 0.499772 v -0.421625 0.273398 0.459706 v -0.195111 0.17195 -0.13148 v -0.221857 0.217675 -0.229484 v -0.224985 0.237954 -0.304274 v -0.218975 0.267494 -0.169472 v -0.216445 0.599743 -0.0423681 v -0.249605 0.611078 -0.0264823 v -0.246072 0.579904 -0.0156047 v -0.222595 0.611429 -0.0137947 v -0.304256 0.549028 -0.0794644 v -0.334798 0.551559 -0.0657927 v -0.307472 0.551383 -0.0465153 v -0.289021 0.567603 -0.102098 v -0.29243 0.56096 -0.0901838 v -0.269251 0.558887 -0.0647735 v -0.25876 0.58015 -0.0920817 v -0.279391 0.611588 -0.0779356 v -0.273152 0.576776 -0.102801 v -0.297561 0.552402 -0.12496 v -0.320775 0.592855 -0.0986539 v -0.326837 0.535023 -0.101132 v -0.276948 0.558553 -0.0438091 v -0.299564 0.5724 -0.066109 v -0.230362 0.584156 -0.0659333 v -0.242593 0.581556 -0.0777423 v -0.228728 0.610463 -0.0642639 v -0.233438 0.59825 -0.0768109 v -0.257635 0.570063 -0.044758 v -0.272713 0.570133 -0.0577444 v -0.255369 0.562401 -0.0579904 v -0.247812 0.568552 -0.0716796 v -0.261466 0.562594 -0.0362001 v -0.32877 0.535163 -0.0792535 v -0.470899 0.192792 0.742171 v -0.471145 0.174586 0.765895 v -0.463132 0.2243 0.646997 v -0.468 0.226215 0.696974 v -0.4415 0.16334 0.76419 v -0.438056 0.191192 0.738885 v -0.46264 0.184726 0.733262 v -0.46257 0.162039 0.760974 v -0.444698 0.163533 0.787703 v -0.463554 0.161196 0.785207 v -0.450884 0.150898 0.803694 v -0.459003 0.147823 0.801163 v -0.432099 0.208607 0.696271 v -0.425474 0.212561 0.647243 v -0.459284 0.201719 0.689804 v -0.454363 0.142041 0.808228 v -0.3413 0.250958 0.508997 v -0.347608 0.255158 0.535497 v -0.344744 0.220873 0.540681 v -0.340702 0.215179 0.51557 v -0.339788 0.207184 0.543915 v -0.334727 0.203265 0.518118 v -0.333937 0.192387 0.547271 v -0.329825 0.18694 0.519928 v -0.314202 0.176537 0.534865 v -0.309756 0.176343 0.553826 v -0.30872 0.165888 0.522405 v -0.367571 0.23762 0.495044 v -0.347204 0.191737 0.506976 v -0.314027 0.149158 0.516975 v -0.281728 0.160493 0.547042 v -0.29004 0.156785 0.559484 v -0.287685 0.154465 0.530981 v -0.266106 0.136717 0.553966 v -0.272467 0.130513 0.559941 v -0.271588 0.128633 0.545162 v -0.352986 0.197027 0.551928 v -0.321671 0.166995 0.561698 v -0.328946 0.144378 0.533599 v -0.329913 0.151601 0.555882 v -0.311479 0.14002 0.537167 v -0.312902 0.145872 0.557287 v -0.291252 0.150125 0.53193 v -0.297596 0.152585 0.560995 v -0.364988 0.1839 0.546357 v -0.364443 0.178645 0.521316 v -0.389098 0.217007 0.557797 v -0.265596 0.126419 0.553035 v -0.401311 0.24305 0.616209 v -0.456472 0.223034 0.53186 v -0.407005 0.219362 0.605578 v -0.428812 0.21105 0.570239 v -0.484782 0.249886 0.629547 v -0.501388 0.247215 0.62185 v -0.512002 0.199048 0.670843 v -0.497101 0.202404 0.678136 v -0.518223 0.179682 0.684655 v -0.498524 0.184954 0.695305 v -0.513742 0.153727 0.686747 v -0.492655 0.152339 0.696675 v -0.505114 0.106562 0.691034 v -0.489702 0.109022 0.701262 v -0.49146 0.0842793 0.696974 v -0.498594 0.0740871 0.680754 v -0.472745 0.0792535 0.694707 v -0.468896 0.221295 0.643184 v -0.478913 0.169789 0.684462 v -0.476857 0.112396 0.694057 v -0.461305 0.0847362 0.683074 v -0.481742 0.0503462 0.689716 v -0.483482 0.0493621 0.669525 v -0.465733 0.0555653 0.684198 v -0.466594 0.0331951 0.668629 v -0.469564 0.0414192 0.660458 v -0.462535 0.0429129 0.668032 v -0.517169 0.166186 0.667979 v -0.507152 0.109848 0.668524 v -0.495783 0.0758795 0.664991 v -0.50854 0.214195 0.619091 v -0.461516 0.0807823 0.667944 v -0.469177 0.118986 0.676133 v -0.491846 0.114803 0.656978 v -0.481812 0.0766703 0.653534 v -0.465136 0.0619618 0.679278 v -0.480354 0.0565318 0.664781 v -0.501898 0.157101 0.654061 v -0.47575 0.165062 0.668734 v -0.457544 0.197536 0.633764 v -0.461832 0.0351808 0.660669 v -0.521843 0.23878 0.604822 v -0.535708 0.235441 0.591115 v -0.545373 0.173848 0.626894 v -0.531561 0.178681 0.634169 v -0.547605 0.158981 0.631129 v -0.533265 0.164534 0.643078 v -0.535866 0.131515 0.627245 v -0.523723 0.136154 0.637472 v -0.51267 0.0994974 0.608776 v -0.499649 0.103276 0.616789 v -0.497206 0.0910976 0.602836 v -0.498454 0.0871964 0.588919 v -0.479756 0.0949636 0.598496 v -0.511633 0.210452 0.617193 v -0.512863 0.154641 0.633044 v -0.48791 0.115102 0.608583 v -0.471268 0.10194 0.590026 v -0.479176 0.076108 0.584842 v -0.482445 0.0781815 0.570573 v -0.466278 0.0845956 0.584209 v -0.455014 0.072857 0.550979 v -0.543493 0.145732 0.618125 v -0.514884 0.105911 0.59036 v -0.499016 0.0927846 0.576758 v -0.536183 0.195322 0.585281 v -0.472586 0.109725 0.578217 v -0.493428 0.127139 0.601413 v -0.509208 0.125716 0.590184 v -0.4903 0.102081 0.568288 v -0.465997 0.090342 0.577391 v -0.482199 0.0845605 0.567866 v -0.529663 0.153305 0.603926 v -0.509366 0.155397 0.621253 v -0.523407 0.185727 0.575036 v -0.493358 0.190015 0.606825 v -0.512319 0.245721 0.489158 v -0.525762 0.224757 0.51926 v -0.482339 0.268232 0.453801 v -0.519998 0.277704 0.493621 v -0.542175 0.230907 0.578305 v -0.553667 0.225161 0.564053 v -0.567128 0.187326 0.577795 v -0.558342 0.186676 0.585703 v -0.573103 0.16232 0.583172 v -0.562788 0.163849 0.592574 v -0.56516 0.146803 0.574122 v -0.557551 0.144501 0.584209 v -0.550856 0.125857 0.56205 v -0.542702 0.126068 0.573121 v -0.535761 0.121639 0.561558 v -0.530788 0.128457 0.544055 v -0.52295 0.125171 0.562963 v -0.537184 0.193618 0.581854 v -0.549432 0.168805 0.587073 v -0.536885 0.134713 0.576126 v -0.51998 0.132113 0.564457 v -0.505641 0.12055 0.539398 v -0.508962 0.127491 0.535163 v -0.503567 0.128826 0.54887 v -0.484958 0.135153 0.529733 v -0.566425 0.169841 0.563157 v -0.548782 0.139054 0.549397 v -0.530471 0.137121 0.540224 v -0.549889 0.211208 0.548132 v -0.520754 0.139212 0.561575 v -0.537096 0.140688 0.572137 v -0.543686 0.146188 0.552701 v -0.523723 0.147612 0.543159 v -0.503005 0.133975 0.548729 v -0.509085 0.131181 0.534882 v -0.553316 0.166555 0.558412 v -0.54228 0.167276 0.58073 v -0.53685 0.196183 0.541577 v -0.388834 0.216286 0.528855 v -0.0103153 0.638052 -0.0238288 v -0.0345658 0.629775 -0.019049 v 0.00405933 0.557569 -0.00878644 v 0.0426317 0.577356 -0.0394862 v 0.0241099 0.566988 -0.0196816 v 0.0076969 0.631867 0.00458649 v 0.0390469 0.596791 -0.0216498 v 0.00486768 0.58514 -0.0238639 v -0.0266404 0.585053 -0.0152181 v -0.0916424 0.719766 -0.0684989 v -0.0402945 0.674287 -0.0183461 v -0.103855 0.744473 -0.0815204 v -0.0429129 0.848452 -0.0981092 v -0.092398 0.884441 -0.0697291 v -0.125101 0.830369 -0.0901663 v -0.108389 0.790391 -0.0504165 v -0.0952272 0.788318 -0.00485012 v -0.115524 0.871068 -0.115471 v -0.0911679 0.938144 -0.114979 v -0.0952272 0.926387 -0.137261 v -0.107458 0.964485 -0.149984 v -0.109584 0.95359 -0.159368 v -0.0954029 0.825888 -0.120778 v -0.0910625 0.856799 -0.136928 v -0.078779 0.917917 -0.151337 v -0.0947528 0.955014 -0.166274 v -0.052947 0.868327 -0.112958 v -0.0526658 0.925157 -0.137191 v -0.0896039 0.964643 -0.158894 v -0.0641057 0.949953 -0.146927 v -0.097582 0.969968 -0.151285 v -0.0716796 0.957878 -0.132165 v -0.0365691 0.84977 -0.047148 v -0.0555302 0.884968 -0.0781816 v -0.0588339 0.934506 -0.1141 v -0.0658454 0.862739 -0.127298 v -0.0327733 0.832935 0.00599231 v -0.0683056 0.893034 -0.0646856 v -0.0804485 0.947018 -0.113644 v -0.104031 0.965065 -0.165343 v -0.0224757 0.610234 0.00912029 v -0.0561277 0.648034 0.0549327 v -0.0191193 0.588321 0.0233367 v -0.0485186 0.620251 0.0886198 v -0.0482726 0.623309 0.115998 v -0.0187678 0.599937 0.0937335 v -0.0111939 0.615418 0.124381 v -0.0447756 0.661125 0.110357 v -0.0671107 0.660106 0.104963 v -0.0315257 0.609813 0.071293 v 0.00829438 0.549204 0.0310863 v 0.00829438 0.640758 0.159017 v -0.00133554 0.652778 0.135381 v -0.00307525 0.638421 0.128949 v 0.000843496 0.625013 0.146575 v -0.00405933 0.586089 0.126507 v 0.0165712 0.584402 0.148438 v 0.012301 0.563139 0.116912 v 0.0242681 0.552736 0.138878 v -0.0181703 0.606052 0.112361 v -0.0501529 0.617685 0.105665 v -0.0705549 0.653587 0.0789723 v -0.0394159 0.614259 0.108108 v -0.0376762 0.619654 0.117105 v -0.0309809 0.634626 0.116315 v -0.0120198 0.629986 0.123519 v 0.00490282 0.650019 0.144993 v 0.0281341 0.654096 0.164095 v 0.0247953 0.667065 0.155414 v 0.00774962 0.607616 0.146188 v 0.0350051 0.632148 0.162514 v 0.0241275 0.639616 0.163269 v 0.0169754 0.648455 0.164447 v 0.0116332 0.659175 0.155151 v 0.0440727 0.604523 0.154764 v 0.0376059 0.606843 0.15378 v 0.0292588 0.630918 0.162496 v 0.0313675 0.643763 0.16334 v -0.000984079 0.652128 0.148297 v 0.00660739 0.661266 0.158823 v -0.0127755 0.658103 0.1435 v 0.00296981 0.685341 0.155115 v -0.0103328 0.673725 0.153516 v -0.0257091 0.665835 0.126595 v -0.0210171 0.705778 0.144431 v -0.029663 0.683408 0.144045 v -0.0126173 0.723966 0.131761 v -0.106333 0.734756 -0.0590096 v -0.1128 0.754437 -0.00653711 v -0.0787966 0.707061 0.114751 v 0.0330545 0.585211 0.153288 v 0.0272555 0.599972 0.153182 v 0.059115 0.557112 0.14835 v 0.050434 0.58384 0.154606 v 0.012547 0.636137 0.160159 v 0.00590447 0.623168 0.153745 v 0.0100868 0.612203 0.152216 v 0.014111 0.610234 0.148807 v 0.0298211 0.620919 0.146874 v 0.014234 0.613046 0.149439 v 0.0127755 0.626911 0.149492 v 0.0188205 0.613767 0.151214 v 0.0178716 0.633782 0.149844 v 0.0405933 0.598707 0.154307 v -0.120761 0.744948 0.0342846 v -0.181984 0.660475 0.0333181 v -0.162689 0.638931 -0.042825 v -0.215812 0.575581 0.0540716 v -0.178856 0.511844 0.0236355 v -0.200981 0.54156 0.0800619 v -0.135715 0.517749 0.0859312 v -0.165958 0.54047 0.115787 v -0.0240396 0.530735 0.175166 v -0.0771272 0.523372 0.148016 v -0.0928022 0.541525 0.164482 v -0.12062 0.656592 0.0797455 v -0.104875 0.687379 0.0964046 v -0.143974 0.593382 0.0891119 v -0.126155 0.710136 0.0755105 v -0.0166591 0.53671 0.170421 v -0.0740695 0.562841 0.150582 v -0.142252 0.814308 -0.0267283 v -0.170562 0.813236 0.0110709 v -0.130865 0.792307 0.0589217 v -0.174639 0.808491 -0.0442309 v -0.196113 0.814607 -0.0249886 v -0.21293 0.783485 -0.0637719 v -0.103416 0.844709 0.0578498 v -0.158683 0.850912 0.00551786 v -0.188328 0.840544 -0.0316136 v -0.206832 0.803852 -0.0627878 v -0.129688 0.845078 -0.0156047 v -0.0665483 0.818912 0.00741572 v -0.121762 0.832021 -0.0222297 v -0.162215 0.841142 -0.0418234 v -0.194162 0.795276 -0.0576214 v -0.208045 0.800706 -0.0498366 v -0.0959126 0.758567 0.0898851 v -0.0675851 0.843075 0.0246195 v -0.0274488 0.815063 0.0534566 v -0.077918 0.82942 0.0770042 v -0.0649316 0.749359 0.111447 v -0.101325 0.762995 0.0454258 v -0.0159561 0.854989 -0.072119 v -0.0170808 0.841458 -0.00147615 v -0.0364461 0.783292 0.0993393 v -0.0281693 0.75825 0.120725 v -0.0181527 0.767669 0.117545 v -0.0282747 0.799986 0.0745264 v -0.026904 0.792166 0.0829438 v -0.0282923 0.781218 0.102256 v -0.0383615 0.830422 0.0836116 v -0.0465856 0.861508 0.0766527 v -0.0328788 0.813078 0.110129 v -0.0438091 0.854075 0.0968263 v -0.0117914 0.656328 0.133571 v -0.0192598 0.641848 0.131462 v -0.0913612 0.64473 -0.0213159 v -0.0823288 0.621657 0.0387657 v -0.176607 0.536112 0.00196813 v -0.116262 0.556813 0.037026 v -0.139581 0.586511 -0.015306 v -0.103961 0.538326 0.0664078 v -0.0602221 0.534583 0.120022 v -0.0206305 0.520033 0.164868 v -0.0187854 0.525902 0.156082 v -0.131814 0.576618 0.104576 v -0.0118617 0.526236 0.169139 v 0.0568481 0.578094 -0.0518223 v 0.0632095 0.595544 -0.0297157 v 0.0492391 0.583787 0.00488523 v 0.019418 0.53671 0.0464274 v 0.0210347 0.533459 0.0674621 v 0.0300496 0.528503 0.0214916 v 0.0110885 0.550627 0.0621727 v 0.020982 0.540945 0.0900784 v 0.0417179 0.529276 0.106948 v 0.0491337 0.519014 0.0846835 v 0.0306646 0.519611 0.0811162 v 0.0514884 0.507029 0.0627877 v 0.0406811 0.510614 0.035585 v 0.0437739 0.505325 0.0363406 v 0.0385548 0.509823 0.0614698 v 0.0329315 0.521246 0.0456015 v 0.0592908 0.505729 0.0730679 v 0.0708186 0.489052 0.0519629 v 0.0542649 0.51035 0.0526658 v 0.0745088 0.496292 0.0385372 v 0.0665308 0.547886 0.0225459 v 0.0700453 0.518135 0.0338804 v 0.0848592 0.483815 0.0301726 v -0.419446 0.356096 0.403086 v -0.413717 0.363371 0.323393 v 0.0299793 -0.116772 -0.00943663 v 0.0278881 -0.117035 0.0023196 v 0.0328261 -0.174323 -0.0231435 v 0.0351457 -0.176607 -0.0447756 v 0.0457597 -0.00630867 0.0128809 v 0.0517872 -0.00905004 0.00576388 v 0.107651 0.0463044 -0.031596 v 0.102169 0.0571117 -0.0239869 v 0.0152181 -0.208045 -0.0943662 v 0.0278354 -0.19954 -0.0988824 v 0.0328788 -0.19309 -0.102608 v 0.00843496 -0.221101 -0.18752 v 0.0369733 -0.196236 -0.178874 v 0.114382 0.167241 -0.0716093 v 0.106527 0.129301 -0.0596071 v 0.144027 0.178364 -0.0871964 v 0.10925 0.109321 -0.0409272 v 0.0984782 0.0749657 -0.0309282 v 0.13438 0.109619 -0.0477981 v 0.12055 0.0655643 -0.0350227 v 0.108161 0.105015 -0.0648438 v 0.105648 0.127157 -0.085527 v 0.0997259 0.0685692 -0.0509964 v 0.113644 0.169332 -0.10918 v 0.119443 0.18267 -0.0928022 v 0.172214 0.545127 -0.0801146 v 0.192862 0.504358 -0.0835765 v 0.225249 0.599919 -0.183267 v 0.113907 0.214002 -0.10324 v 0.140038 0.264436 -0.121182 v 0.131867 0.338962 -0.0827681 v 0.159649 0.400169 -0.0818543 v 0.179911 0.300531 -0.144572 v 0.201139 0.358539 -0.155203 v 0.181123 0.34137 -0.139441 v 0.134274 0.213106 -0.104857 v 0.116666 0.214406 -0.123273 v 0.13742 0.254982 -0.142656 v 0.180139 0.331547 -0.170703 v 0.182424 0.350648 -0.157066 v 0.218149 0.459003 -0.139441 v 0.231645 0.475029 -0.169349 v 0.250431 0.527572 -0.192897 v 0.231645 0.542122 -0.17608 v 0.237427 0.455224 -0.162303 v 0.229062 0.448178 -0.176519 v 0.219942 0.462746 -0.168155 v 0.240748 0.503075 -0.204109 v 0.203827 0.402963 -0.158753 v 0.1852 0.490353 -0.0985485 v 0.234931 0.568183 -0.174129 v 0.229677 0.574263 -0.196394 v 0.240625 0.539574 -0.218307 v 0.0274663 0.802411 0.102309 v 0.0202263 0.814185 0.0757741 v -0.183496 0.644396 -0.0129336 v -0.209134 0.549766 0.0197167 v -0.198714 0.522599 0.0515587 v -0.0914491 0.62844 0.0662671 v -0.115383 0.576547 0.0599058 v -0.108161 0.563139 0.0778653 v -0.109637 0.603838 0.0616631 v -0.105718 0.58797 0.0298562 v 0.0795522 0.555671 0.0176783 v 0.0844024 0.502601 0.03439 v 0.0913788 0.482164 0.025094 v 0.319615 -0.279391 -0.0492391 v 0.26542 -0.323744 -0.0486416 v 0.245229 -0.168875 -0.011809 v 0.175711 -0.204601 -0.00776722 v 0.131093 -0.152427 0.0120725 v 0.349541 -0.256388 -0.0736126 v 0.28417 -0.142199 -0.0529821 v 0.173532 0.00755631 -0.0877412 v 0.368221 -0.35534 -0.0836819 v 0.133079 -0.0532984 0.0125997 v 0.156627 -0.00543002 -0.0297684 v 0.132323 -0.0923804 0.0181527 v 0.101993 -0.0188733 0.0320001 v 0.106439 -0.0508207 0.037887 v 0.149053 -0.193354 0.00110707 v 0.32682 -0.398939 -0.0634907 v 0.267968 -0.440604 -0.0848241 v 0.217007 -0.373809 -0.0685517 v 0.372439 -0.428092 -0.0628405 v 0.343936 -0.485028 -0.0888659 v 0.396496 -0.40038 -0.0800267 v 0.420834 -0.434436 -0.0314378 v 0.377394 -0.483394 -0.0817137 v 0.41906 -0.476822 -0.112906 v 0.400011 -0.46619 -0.0599234 v 0.428777 -0.419745 -0.08565 v 0.431097 -0.422328 -0.0587284 v 0.428197 -0.456015 -0.0710997 v 0.425157 -0.441149 -0.100745 v 0.424771 -0.407391 -0.100271 v 0.444118 -0.417408 -0.0785155 v 0.440586 -0.412171 -0.115014 v 0.413085 -0.36613 -0.130144 v 0.427881 -0.38908 -0.159966 v 0.382473 -0.23393 -0.155871 v 0.404685 -0.306558 -0.135838 v 0.307718 -0.187889 -0.250958 v 0.361104 -0.502987 -0.0829087 v 0.3788 -0.495835 -0.0797456 v 0.390205 -0.499139 -0.0882157 v 0.373405 -0.517169 -0.0846835 v 0.387481 -0.512863 -0.0898851 v 0.387956 -0.506414 -0.0679366 v 0.363705 -0.513162 -0.122377 v 0.315468 -0.493182 -0.0992866 v 0.397673 -0.495009 -0.103873 v 0.425491 -0.498014 -0.0964046 v 0.385355 -0.517292 -0.130162 v 0.40704 -0.519067 -0.148034 v 0.35824 -0.524989 -0.182213 v 0.431589 -0.424507 -0.180807 v 0.446825 -0.439321 -0.146874 v 0.431536 -0.467525 -0.145907 v 0.350508 -0.501722 -0.112941 v 0.352775 -0.514902 -0.100921 v 0.347134 -0.521456 -0.126103 v 0.308755 -0.512424 -0.148631 v 0.334815 -0.507556 -0.125751 v 0.253084 -0.494429 -0.153446 v 0.0683584 -0.169156 -0.319492 v 0.199188 -0.144045 -0.250554 v 0.104963 -0.0734018 -0.409623 v 0.31473 -0.122852 -0.14357 v 0.427881 -0.461305 -0.218132 v 0.442607 -0.461006 -0.172794 v 0.4095 -0.503005 -0.198696 v 0.431466 -0.442361 -0.146294 v 0.112923 -0.0907462 0.0221242 v 0.110428 -0.153253 0.0297859 v 0.118845 -0.198538 -0.00574633 v 0.111658 -0.154536 0.00688854 v 0.0916072 -0.0419112 0.0288546 v 0.093716 -0.0783397 0.0125821 v 0.140495 -0.2395 -0.0249359 v 0.151355 -0.217938 -0.267283 v 0.279162 -0.253611 -0.309071 v 0.201789 -0.0121956 -0.147208 v 0.1991 -0.0523144 -0.231715 v 0.108495 -0.165255 -0.268197 v 0.166714 -0.0962113 -0.275876 v 0.136945 -0.241152 -0.00766177 v 0.133431 -0.26289 -0.0405757 v 0.159298 -0.253418 -0.024233 v 0.144185 -0.25927 -0.0205427 v 0.181545 -0.274769 -0.0289425 v 0.159895 -0.277458 -0.0354972 v 0.409851 -0.294099 -0.240801 v 0.433592 -0.333058 -0.185938 v 0.432766 -0.361807 -0.239694 v 0.216374 -0.339244 -0.32863 v 0.255597 -0.383088 -0.322216 v 0.131937 -0.302657 -0.197273 v 0.184989 -0.41254 -0.23096 v 0.152884 -0.338664 -0.117387 v 0.173057 -0.376498 -0.130847 v 0.147524 -0.303659 -0.0683232 v 0.228675 -0.459829 -0.152444 v 0.235546 -0.466489 -0.216058 v 0.347556 -0.362703 -0.420694 v 0.242066 -0.403894 -0.407233 v 0.203019 -0.443662 -0.359294 v 0.307999 -0.418532 -0.501898 v 0.237796 -0.437089 -0.47763 v 0.277756 -0.436791 -0.542772 v 0.223052 -0.455576 -0.529329 v 0.283046 -0.366323 -0.410273 v 0.370928 -0.32761 -0.303061 v 0.34752 -0.466032 -0.493006 v 0.40776 -0.393122 -0.373265 v 0.33239 -0.475029 -0.5391 v 0.393544 -0.478456 -0.420922 v 0.38423 -0.416459 -0.432099 v 0.429445 -0.435947 -0.319299 v 0.410168 -0.494271 -0.323903 v 0.373388 -0.568727 -0.293045 v 0.301515 -0.529944 -0.2062 v 0.257723 -0.516975 -0.212473 v 0.251907 -0.542807 -0.286613 v 0.209398 -0.50963 -0.309247 v 0.197009 -0.478368 -0.447563 v 0.309721 -0.345271 -0.321917 v 0.198573 -0.380628 -0.287878 v 0.231698 -0.430605 -0.282483 v 0.200067 -0.495185 -0.519418 v 0.212684 -0.562805 -0.510667 v 0.387218 -0.520841 -0.402506 v 0.349928 -0.57291 -0.382297 v 0.22205 -0.53794 -0.388219 v 0.423541 -0.493551 -0.14712 v 0.305469 -0.553035 -0.288177 v 0.26238 -0.594788 -0.493481 v 0.273785 -0.569026 -0.380786 v 0.189541 -0.547218 -0.610674 v 0.216093 -0.59217 -0.660229 v 0.181141 -0.483692 -0.607599 v 0.293185 -0.57226 -0.675201 v 0.31791 -0.54091 -0.659122 v 0.252434 -0.589815 -0.674656 v 0.322163 -0.585228 -0.48248 v 0.352441 -0.541894 -0.517186 v 0.362018 -0.536358 -0.599427 v 0.277493 -0.500914 -0.672126 v 0.325098 -0.487295 -0.63271 v 0.197607 -0.521105 -0.656117 v 0.283116 -0.463062 -0.637701 v 0.227516 -0.518416 -0.671652 v 0.21822 -0.460039 -0.630514 v 0.322479 -0.683461 -0.487488 v 0.229958 -0.631181 -0.589534 v 0.287316 -0.705884 -0.494658 v 0.238551 -0.671054 -0.575757 v 0.266808 -0.701807 -0.595913 v 0.322426 -0.739377 -0.53866 v 0.304309 -0.703687 -0.60607 v 0.345341 -0.788089 -0.520262 v 0.302745 -0.741433 -0.516888 v 0.324272 -0.788089 -0.473817 v 0.334815 -0.771202 -0.465171 v 0.309932 -0.73089 -0.485854 v 0.338769 -0.717253 -0.480934 v 0.338927 -0.801708 -0.477718 v 0.35223 -0.799441 -0.501494 v 0.354058 -0.82761 -0.483218 v 0.34926 -0.812621 -0.465997 v 0.364795 -0.827013 -0.505114 v 0.366974 -0.826047 -0.484466 v 0.371701 -0.811672 -0.471427 v 0.308034 -0.760746 -0.499807 v 0.330123 -0.789583 -0.507047 v 0.269989 -0.718237 -0.563069 v 0.339033 -0.676185 -0.628633 v 0.377535 -0.639757 -0.613204 v 0.423505 -0.727762 -0.592029 v 0.401856 -0.620515 -0.559607 v 0.461797 -0.72553 -0.536569 v 0.513303 -0.800513 -0.446912 v 0.383035 -0.622852 -0.510069 v 0.448107 -0.729765 -0.477735 v 0.530296 -0.825572 -0.503884 v 0.376041 -0.738815 -0.609795 v 0.396707 -0.799494 -0.624504 v 0.412663 -0.743243 -0.456507 v 0.372597 -0.76289 -0.464257 v 0.478649 -0.807454 -0.416828 v 0.534478 -0.816434 -0.403859 v 0.507152 -0.819439 -0.384634 v 0.549678 -0.820353 -0.371841 v 0.522915 -0.823674 -0.355709 v 0.570379 -0.816487 -0.34991 v 0.528187 -0.818807 -0.326205 v 0.583489 -0.839648 -0.320616 v 0.54221 -0.842618 -0.302868 v 0.588374 -0.870646 -0.307191 v 0.613521 -0.919376 -0.279619 v 0.577531 -0.914543 -0.250712 v 0.619443 -0.969705 -0.245914 v 0.603328 -0.967209 -0.23277 v 0.610375 -0.981074 -0.243191 v 0.602151 -0.901856 -0.253559 v 0.552525 -0.876568 -0.291902 v 0.617861 -0.936386 -0.230503 v 0.616403 -0.967121 -0.23212 v 0.572277 -0.930271 -0.248164 v 0.525147 -0.860349 -0.323006 v 0.486487 -0.846765 -0.378853 v 0.45417 -0.827013 -0.401873 v 0.552402 -0.855745 -0.409781 v 0.572365 -0.854919 -0.370594 v 0.511827 -0.850947 -0.350244 v 0.53504 -0.916933 -0.301093 v 0.557938 -0.950339 -0.264893 v 0.596405 -0.902963 -0.342337 v 0.567585 -0.936632 -0.340228 v 0.576038 -0.961024 -0.307525 v 0.601132 -0.949812 -0.260324 v 0.587302 -0.959512 -0.281218 v 0.616244 -0.927635 -0.291358 v 0.607669 -0.93918 -0.307331 v 0.596088 -0.949425 -0.233508 v 0.606228 -0.957245 -0.251134 v 0.621797 -0.954996 -0.256001 v 0.253805 -0.386954 -0.335255 v 0.301655 -0.350701 -0.347767 v 0.37706 -0.347028 -0.326345 v 0.224862 -0.434313 -0.30148 v 0.235705 -0.476927 -0.224897 v 0.486803 -0.80705 -0.539311 v 0.564088 -0.845289 -0.496591 v 0.552771 -0.845025 -0.446104 v 0.583383 -0.936545 -0.24609 v 0.613503 -0.930781 -0.27867 v 0.572962 -0.897884 -0.379767 v 0.549714 -0.924085 -0.370365 v 0.524426 -0.904984 -0.351246 v 0.495115 -0.924683 -0.389959 v 0.546199 -0.911451 -0.424367 v 0.519049 -0.937581 -0.409834 v 0.620497 -0.845658 -0.491126 v 0.612501 -0.842372 -0.459723 v 0.638 -0.842741 -0.488314 v 0.631744 -0.836028 -0.458423 v 0.660686 -0.852388 -0.479422 v 0.656187 -0.84629 -0.452378 v 0.676379 -0.870646 -0.472622 v 0.671036 -0.861456 -0.449021 v 0.736899 -0.902436 -0.443082 v 0.724528 -0.905142 -0.426616 v 0.756634 -0.938548 -0.42753 v 0.743419 -0.941781 -0.411978 v 0.734264 -0.918603 -0.456824 v 0.746301 -0.955137 -0.441658 v 0.753576 -0.961041 -0.421731 v 0.632253 -0.881348 -0.491794 v 0.666151 -0.893474 -0.481724 v 0.721787 -0.931853 -0.471128 v 0.702861 -0.922504 -0.41623 v 0.635328 -0.862053 -0.449619 v 0.617861 -0.859558 -0.4541 v 0.653464 -0.898763 -0.432889 v 0.692229 -0.94642 -0.446315 v 0.658419 -0.913665 -0.457614 v 0.731768 -0.948758 -0.432679 v 0.713791 -0.952571 -0.440305 v 0.728816 -0.926581 -0.417636 v 0.737304 -0.941992 -0.448828 v 0.739711 -0.951341 -0.428514 v 0.619952 -0.902717 -0.468773 v 0.622184 -0.891013 -0.448389 v 0.570924 -0.885864 -0.441992 v 0.553175 -0.886849 -0.523407 v 0.486733 -0.862704 -0.544407 v 0.436175 -0.832935 -0.588163 v 0.356834 -0.808614 -0.579535 v 0.370066 -0.837258 -0.56502 v 0.483482 -0.952536 -0.448898 v 0.401293 -0.935525 -0.430816 v 0.452167 -0.928848 -0.482146 v 0.422223 -0.873687 -0.514832 v 0.537448 -0.915563 -0.531227 v 0.538256 -0.931167 -0.479844 v 0.391171 -0.871859 -0.483183 v 0.420536 -0.835378 -0.412048 v 0.38532 -0.855323 -0.451112 v 0.418304 -0.875303 -0.361104 v 0.385689 -0.885583 -0.417513 v 0.43737 -0.84608 -0.344305 v 0.340087 -0.757196 -0.585158 v 0.469634 -0.844937 -0.353952 v 0.463501 -0.850525 -0.319984 v 0.42948 -0.855042 -0.316698 v 0.426792 -0.862317 -0.284293 v 0.46554 -0.856043 -0.287562 v 0.431185 -0.874688 -0.270481 v 0.46633 -0.868836 -0.272713 v 0.445647 -0.914016 -0.213949 v 0.463782 -0.91725 -0.223544 v 0.451376 -0.953414 -0.196095 v 0.462306 -0.958897 -0.205374 v 0.452501 -0.974467 -0.200243 v 0.431255 -0.928303 -0.22075 v 0.440885 -0.965645 -0.207219 v 0.421801 -0.889766 -0.325695 v 0.42159 -0.909043 -0.292342 v 0.476786 -0.950111 -0.248902 v 0.476031 -0.902383 -0.300724 v 0.470407 -0.867255 -0.319176 v 0.473237 -0.895284 -0.313763 v 0.449812 -0.958036 -0.277932 v 0.420008 -0.952061 -0.250079 v 0.448441 -0.924841 -0.300267 v 0.452255 -0.956595 -0.222701 v 0.449724 -0.96619 -0.248445 v 0.467051 -0.941676 -0.225091 v 0.434084 -0.944734 -0.229624 v 0.454609 -0.963044 -0.212034 v 0.446174 -0.916406 -0.31306 v 0.484923 -0.891418 -0.370365 v 0.412944 -0.9234 -0.3704 v 0.448547 -0.950989 -0.393632 v 0.452237 -0.928373 -0.363494 v 0.0993217 -0.0437212 0.013039 v 0.117 -0.0326855 0.00843494 v 0.132956 0.0132675 -0.0162198 v 0.174393 0.0882332 -0.136154 v 0.172284 0.0767757 -0.0868099 v 0.171159 0.108829 -0.285049 v 0.00316311 -0.239694 -0.424384 v -0.0470776 -0.322356 -0.4651 v -0.206288 -0.446754 -0.598162 v -0.387411 -0.551928 -0.631445 v -0.577268 -0.63445 -0.594559 v -0.729255 -0.698028 -0.432784 v -0.756634 -0.767687 -0.272432 v -0.0792359 -0.255087 -0.536024 v -0.261572 -0.388817 -0.610832 v -0.427213 -0.493516 -0.610639 v -0.583787 -0.592222 -0.559713 v -0.7104 -0.676994 -0.421221 v -0.0270973 -0.190806 -0.492918 v -0.0579904 -0.180034 -0.514849 v -0.023407 -0.156609 -0.518012 v -0.0553017 -0.161248 -0.534214 v -0.0514006 -0.128001 -0.550258 v -0.00166942 -0.146557 -0.467385 v -0.00917302 -0.129371 -0.496679 v -0.035708 -0.118283 -0.496187 v 0.007117 -0.119214 -0.480547 v 0.0405405 -0.19309 -0.383492 v 0.0145679 -0.112326 -0.445964 v -0.0222824 -0.0805364 -0.516835 v -0.00671283 -0.090834 -0.457034 v -0.131445 -0.226655 -0.581046 v -0.161038 -0.199944 -0.592732 v -0.186729 -0.231417 -0.598092 v -0.191685 -0.214336 -0.630531 v -0.136365 -0.263962 -0.566109 v -0.184778 -0.254472 -0.576389 v -0.182881 -0.19432 -0.578199 v -0.199258 -0.209767 -0.609725 v -0.121833 -0.178909 -0.554037 v -0.100534 -0.145644 -0.553632 v -0.130584 -0.118546 -0.582259 v -0.109795 -0.124855 -0.567726 v -0.0574456 -0.0602397 -0.560046 v -0.0993393 -0.105314 -0.550575 v -0.0711524 -0.0882332 -0.579341 v -0.0723474 -0.144238 -0.524584 v -0.0709416 -0.0606088 -0.58203 v -0.069729 -0.0438443 -0.568077 v -0.0576565 -0.0340386 -0.537799 v -0.0776895 -0.0167997 -0.565898 v -0.0986539 -0.0506449 -0.559677 v -0.099761 -0.0857555 -0.573349 v -0.100692 -0.0549151 -0.613608 v -0.116982 -0.104435 -0.542157 v 0.00662496 -0.0410502 -0.463958 v -0.0404878 0.0115278 -0.520332 v -0.0445472 -0.0301902 -0.527414 v -0.0606439 0.0340737 -0.528099 v -0.0182758 -0.0848768 -0.478104 v -0.0715566 -0.026781 -0.521632 v -0.237427 -0.307929 -0.574316 v -0.176308 -0.333954 -0.587425 v -0.239694 -0.275841 -0.599304 v -0.156925 -0.283221 -0.579623 v -0.18947 -0.269655 -0.585211 v -0.144132 -0.116473 -0.542983 v 0.0806769 -0.0121428 -0.424314 v -0.00416476 0.0702035 -0.465505 v -0.0435982 0.121868 -0.484852 v -0.0251292 0.0236179 -0.502829 v -0.0629459 0.0179594 -0.50065 v -0.0487998 0.0939092 -0.497382 v -0.0861245 0.139528 -0.506537 v -0.0925386 0.109092 -0.482779 v 0.199487 0.100938 -0.197782 v 0.17738 0.0913612 -0.124627 v 0.19831 0.106421 -0.242382 v 0.175887 0.137174 -0.313728 v 0.206639 0.121463 -0.19787 v 0.162514 0.0891997 -0.289969 v 0.111763 0.0971251 -0.364724 v 0.147348 0.106263 -0.297948 v 0.154588 0.0526482 -0.320616 v 0.144045 0.11635 -0.363319 v 0.133835 0.100376 -0.371753 v 0.0854743 0.0908691 -0.411521 v 0.0331424 0.0769514 -0.462359 v 0.0567427 0.0864408 -0.42709 v 0.0578674 0.132394 -0.418814 v 0.0914666 0.115664 -0.319017 v 0.0016167 0.135241 -0.468404 v 0.0493445 0.109145 -0.391611 v 0.0489404 0.111588 -0.338225 v 0.0333533 0.106052 -0.420044 v 0.108635 0.131322 -0.399483 v 0.111939 0.116701 -0.338611 v 0.12431 0.125769 -0.350754 v 0.0719081 0.115612 -0.379767 v 0.181773 0.124222 -0.225758 v 0.173251 0.074421 -0.0969318 v 0.187168 0.0622078 -0.136506 v 0.161776 0.113239 -0.152321 v 0.156644 0.0894457 -0.11577 v 0.163533 0.173005 -0.186237 v 0.138052 0.21655 -0.187854 v 0.189839 0.314607 -0.241785 v 0.139194 0.129389 -0.254472 v 0.103065 0.216954 -0.298123 v 0.140635 0.300373 -0.309159 v 0.0359189 0.167785 -0.365445 v 0.0516114 0.260623 -0.381559 v 0.184603 0.382684 -0.320423 v 0.12243 0.350279 -0.409394 v 0.048132 0.337785 -0.456929 v 0.0643166 0.384441 -0.477665 v -0.0773381 0.303975 -0.46568 v 0.00256563 0.170052 -0.349875 v -0.0538783 0.223702 -0.407795 v -0.0493797 0.267019 -0.444101 v -0.0796753 0.25999 -0.437142 v 0.0692721 0.35274 -0.468861 v 0.0275191 0.374653 -0.486399 v 0.0205427 0.1086 -0.41363 v -0.0501353 0.13879 -0.453133 v -0.0464977 0.100271 -0.41247 v -0.0154465 0.130267 -0.371507 v -0.0440024 0.319562 -0.428795 v 0.0268162 0.364338 -0.458932 v -0.00581661 0.351791 -0.455365 v 0.0063438 0.282782 -0.404316 v -0.0853337 0.271272 -0.362405 v -0.10846 0.346167 -0.416951 v -0.0374653 0.295681 -0.386321 v -0.0625417 0.206727 -0.376322 v -0.0438442 0.287351 -0.433715 v 0.0339859 0.382596 -0.465118 v 0.00667768 0.391382 -0.464749 v -0.070801 0.407426 -0.540962 v -0.0435104 0.41254 -0.534267 v -0.0234422 0.43969 -0.521738 v -0.0482902 0.500281 -0.651337 v -0.0672513 0.516044 -0.644853 v -0.0307876 0.517503 -0.637455 v -0.0628756 0.544547 -0.724528 v -0.0640882 0.538362 -0.701508 v -0.0449865 0.543862 -0.711173 v -0.0430886 0.519154 -0.686553 v -0.0613995 0.531069 -0.681756 v -0.0303483 0.535427 -0.679946 v -0.0533863 0.527115 -0.708256 v -0.0242681 0.461129 -0.514744 v -0.0612941 0.537131 -0.637367 v -0.0400309 0.539012 -0.633325 v -0.0557762 0.551488 -0.705216 v -0.0525076 0.548237 -0.678892 v -0.0398552 0.548835 -0.678206 v -0.081907 0.478157 -0.513935 v -0.106122 0.434717 -0.514796 v -0.0461814 0.483745 -0.512512 v 0.00878642 0.425755 -0.450708 v -0.115998 0.394985 -0.40161 v -0.0658279 0.470935 -0.449812 v -0.0820652 0.444083 -0.422504 v 0.0177661 0.620304 -0.538432 v -0.03859 0.617158 -0.559537 v -0.0890064 0.628668 -0.521052 v 0.0423505 0.613222 -0.466664 v 0.0536323 0.686571 -0.536639 v -0.00625593 0.673022 -0.629178 v -0.0384669 0.699329 -0.6254 v 0.0489579 0.721295 -0.585 v -0.0350051 0.73755 -0.597828 v -0.0781464 0.71228 -0.518996 v 0.0140231 0.706112 -0.49993 v 0.00576389 0.754613 -0.580378 v -0.0378695 0.747759 -0.522247 v -0.053193 0.699698 -0.395407 v -0.10556 0.682195 -0.37279 v -0.104717 0.669894 -0.489984 v -0.0573753 0.708238 -0.465838 v -0.0261484 0.723351 -0.526465 v -0.0811865 0.691825 -0.525797 v -0.0417882 0.721804 -0.493656 v 0.00660739 0.685288 -0.375514 v -0.00962992 0.716515 -0.512354 v -0.00961234 0.688381 -0.444909 v 0.0383615 0.66833 -0.415703 v 0.026658 0.667786 -0.464433 v -0.0246723 0.706305 -0.348962 v -0.0683584 0.702334 -0.313992 v -0.0517344 0.7256 -0.393684 v 0.0405933 0.695129 -0.611465 v 0.0352335 0.757073 -0.577654 v 0.0150951 0.756932 -0.695357 v -0.0106491 0.764612 -0.688803 v 0.0508909 0.803922 -0.669314 v -0.0103504 0.805117 -0.665255 v 0.0397146 0.765596 -0.681141 v 0.0453731 0.815397 -0.652567 v 0.0115454 0.808333 -0.736443 v 0.0245493 0.863863 -0.72184 v 0.042333 0.823586 -0.724862 v 0.0454082 0.855165 -0.714635 v 0.0204724 0.825221 -0.653516 v 0.00950691 0.847573 -0.734404 v 0.0500826 0.845324 -0.794099 v 0.0562331 0.855147 -0.78765 v 0.037518 0.866833 -0.782062 v 0.0372193 0.854198 -0.790409 v 0.0508558 0.857291 -0.809458 v -0.115981 0.531051 -0.427653 v -0.0912382 0.489737 -0.433873 v -0.149598 0.450497 -0.476435 v -0.14299 0.513847 -0.468949 v -0.202931 0.499982 -0.518047 v -0.201086 0.521492 -0.515271 v 0.24551 0.627122 -0.204091 v -0.0693424 0.71286 -0.356043 v -0.0400134 0.70808 -0.365023 v -0.00474467 0.733877 -0.327874 v -0.0193301 0.755263 -0.270218 v 0.0036903 0.780181 -0.243208 v 0.0229326 0.74602 -0.328753 v 0.0102098 0.754086 -0.299599 v 0.00609778 0.719309 -0.329983 v 0.0434576 0.75992 -0.30206 v 0.0336344 0.728377 -0.324201 v 0.0531227 0.749165 -0.295522 v 0.0597301 0.793361 -0.261589 v 0.0312621 0.774259 -0.225389 v 0.0324395 0.725214 -0.389414 v 0.0169051 0.697308 -0.400467 v -0.00803079 0.556391 -0.494851 v 0.0222648 0.52302 -0.523969 v -0.00615049 0.534162 -0.561224 v -0.0252697 0.499192 -0.523231 v -0.0669877 0.58876 -0.508066 v -0.125417 0.567093 -0.430728 v 0.042825 0.750641 -0.284592 v 0.061628 0.772854 -0.233508 v 0.0597828 0.765438 -0.269286 v 0.0325976 0.812586 -0.209451 v 0.065986 0.777791 -0.199803 v 0.0765473 0.852494 -0.202088 v 0.0429129 0.830651 -0.188346 v 0.073349 0.858293 -0.18158 v 0.0397498 0.837978 -0.164499 v 0.0480969 0.863108 -0.110902 v 0.0721189 0.858996 -0.130742 v 0.0882508 0.835413 -0.0971251 v 0.0114399 0.790057 -0.23588 v 0.0655643 0.817155 -0.217868 v 0.076969 0.750589 -0.313306 v 0.0968439 0.77686 -0.299687 v 0.105226 0.724177 -0.29243 v 0.0745088 0.727182 -0.342143 v 0.103662 0.737919 -0.272274 v 0.0993393 0.720768 -0.328208 v 0.0754929 0.7437 -0.336907 v 0.109865 0.748111 -0.327944 v 0.0984255 0.737075 -0.311426 v 0.0810811 0.760693 -0.274699 v 0.0665483 0.757688 -0.255263 v 0.121094 0.716146 -0.278178 v 0.117931 0.712403 -0.323235 v 0.0691316 0.846431 -0.0978456 v 0.0713985 0.870945 -0.125593 v 0.068868 0.826275 -0.191509 v 0.0580782 0.800214 -0.187871 v 0.086845 0.798914 -0.148578 v 0.114751 0.643904 -0.123924 v 0.148297 0.657769 -0.237269 v 0.101149 0.750343 -0.149756 v 0.10867 0.729361 -0.215478 v 0.125769 0.632622 -0.179788 v 0.183127 0.658788 -0.255931 v 0.213598 0.618933 -0.212913 v 0.2353 0.68701 -0.26043 v 0.246108 0.624381 -0.262942 v 0.246231 0.594612 -0.24428 v 0.134907 0.692247 -0.26716 v 0.15682 0.673374 -0.290022 v 0.14176 0.728904 -0.299564 v 0.14241 0.691157 -0.318385 v 0.0764946 0.682582 -0.44642 v 0.16898 0.688715 -0.44447 v 0.144554 0.645696 -0.50297 v 0.0820827 0.709943 -0.390381 v 0.0476224 0.665009 -0.471971 v 0.0828384 0.701191 -0.526412 v 0.115787 0.719748 -0.348944 v 0.120567 0.709556 -0.362791 v 0.105349 0.729378 -0.41196 v 0.143834 0.710558 -0.388746 v 0.114346 0.702105 -0.422346 v 0.136154 0.738569 -0.429164 v 0.16464 0.704442 -0.400221 v 0.15081 0.694602 -0.431659 v 0.127842 0.713352 -0.399431 v 0.20207 0.501476 -0.500211 v 0.160106 0.53193 -0.529821 v 0.158015 0.590377 -0.519488 v 0.223896 0.560995 -0.485028 v 0.256563 0.454416 -0.452413 v 0.265016 0.527994 -0.443749 v 0.244895 0.63814 -0.399466 v 0.256599 0.444646 -0.385179 v 0.261027 0.474555 -0.31429 v 0.207096 0.454434 -0.539117 v 0.134731 0.469335 -0.554212 v 0.246319 0.427196 -0.491178 v 0.203335 0.399448 -0.562718 v 0.258989 0.384687 -0.510315 v 0.276473 0.37272 -0.454065 v 0.228974 0.39625 -0.360278 v 0.253207 0.32812 -0.415615 v 0.237128 0.345201 -0.636998 v 0.313095 0.320775 -0.570081 v 0.278846 0.350262 -0.607915 v 0.193477 0.292799 -0.652023 v 0.138333 0.431976 -0.568886 v 0.150529 0.375584 -0.569465 v 0.0929076 0.432819 -0.542017 v 0.278477 0.478895 -0.362194 v 0.20316 0.651619 -0.462851 v 0.274787 0.562858 -0.330475 v 0.265578 0.603855 -0.31603 v 0.261045 0.516518 -0.253102 v 0.328911 0.233965 -0.682055 v 0.267494 0.304783 -0.533037 v 0.266896 0.292605 -0.516255 v 0.264665 0.29851 -0.495835 v 0.298281 0.285225 -0.544828 v 0.274013 0.333814 -0.537799 v 0.173778 0.317612 -0.624205 v 0.408217 0.176133 -0.686571 v 0.341563 0.162848 -0.698169 v 0.36258 0.179032 -0.699821 v 0.365058 0.133571 -0.711577 v 0.380136 0.147313 -0.71358 v 0.390925 0.132851 -0.712298 v 0.293062 0.194742 -0.677925 v 0.242277 0.250431 -0.672249 v 0.282694 0.274294 -0.677486 v 0.329842 0.292008 -0.639335 v 0.202474 0.24008 -0.656521 v 0.147296 0.283292 -0.616033 v 0.15617 0.267423 -0.634046 v 0.112185 0.350402 -0.549872 v 0.200401 0.21242 -0.637771 v 0.139212 0.26289 -0.600622 v 0.150617 0.245036 -0.619566 v 0.364531 0.115418 -0.701121 v 0.336063 0.14849 -0.686905 v 0.285084 0.167258 -0.658419 v 0.125576 0.283098 -0.573331 v 0.134274 0.307261 -0.593628 v 0.138597 0.37706 -0.411363 v 0.0770921 0.39987 -0.484308 v 0.0934172 0.420325 -0.4011 v 0.0719608 0.423136 -0.473324 v 0.0955084 0.416072 -0.450866 v 0.0423681 0.409148 -0.500088 v 0.0506801 0.425087 -0.505377 v 0.015675 0.397744 -0.475047 v 0.0168524 0.426598 -0.462113 v 0.0130742 0.419675 -0.490862 v 0.0217727 0.438354 -0.516536 v 0.0273433 0.444013 -0.517538 v 0.0263241 0.441992 -0.475925 v 0.0241451 0.450005 -0.511581 v 0.0173795 0.444259 -0.507029 v 0.0509437 0.486276 -0.487154 v 0.0784276 0.575598 -0.52353 v 0.064176 0.613837 -0.497276 v 0.0314027 0.540769 -0.479809 v 0.0544231 0.526728 -0.505465 v 0.0159737 0.495642 -0.519945 v -0.00274136 0.50717 -0.547218 v 0.0469195 0.453713 -0.483359 v -0.0390293 0.540347 -0.467104 v -0.0466559 0.483991 -0.488384 v -0.0477103 0.51506 -0.489017 v -0.00442836 0.478684 -0.510755 v -0.00618564 0.540382 -0.538151 v -0.0295927 0.52585 -0.525006 v 0.105103 0.401504 -0.546972 v 0.104207 0.515816 -0.532932 v 0.0946122 0.458774 -0.492145 v 0.190279 0.441061 -0.330967 v 0.24117 0.472446 -0.223931 v 0.241345 0.485274 -0.25927 v 0.250237 0.511282 -0.227305 v 0.219573 0.280656 -0.478192 v 0.180069 0.338207 -0.41066 v 0.175535 0.389432 -0.375514 v 0.206165 0.45772 -0.26665 v 0.197782 0.47111 -0.320529 v 0.107388 0.326697 -0.496327 v 0.0789372 0.389432 -0.516852 v 0.179155 0.218009 -0.559572 v 0.14589 0.253084 -0.530506 v 0.317014 0.141936 -0.644554 v 0.245334 0.179243 -0.609971 v 0.346747 0.156943 -0.603592 v 0.270323 0.183056 -0.542403 v 0.369364 0.244579 -0.650564 v 0.32689 0.221769 -0.549643 v 0.38604 0.180666 -0.601237 v 0.425649 0.174639 -0.626156 v 0.287474 0.258268 -0.525024 v 0.274804 0.215232 -0.512705 v 0.311602 0.188767 -0.545812 v 0.184181 0.305539 -0.441377 v 0.130197 0.35998 -0.470566 v 0.195814 0.251643 -0.495115 v 0.247812 0.251415 -0.492145 v 0.434506 0.136682 -0.691509 v 0.435929 0.145978 -0.608934 v 0.408498 0.156117 -0.605332 v 0.438319 0.0318771 -0.703652 v 0.476294 0.0384669 -0.672354 v 0.495976 0.0486416 -0.630812 v 0.498823 0.0632798 -0.604172 v 0.402611 0.0256212 -0.716831 v 0.518399 0.0263768 -0.614206 v 0.52049 0.039943 -0.594243 v 0.552209 -0.00880402 -0.600868 v 0.555829 -0.000369045 -0.588655 v 0.56523 -0.0182758 -0.601606 v 0.571574 -0.0077145 -0.587196 v 0.581064 -0.0372896 -0.593593 v 0.584068 -0.030401 -0.58022 v 0.596633 -0.0694479 -0.582803 v 0.600341 -0.0983025 -0.568517 v 0.605156 -0.0864935 -0.546041 v 0.605964 -0.0835413 -0.561874 v 0.602573 -0.0602046 -0.564914 v 0.461217 0.0783397 -0.548659 v 0.41261 0.136242 -0.587513 v 0.528029 0.0128106 -0.569202 v 0.565881 -0.017854 -0.567462 v 0.595175 -0.0921344 -0.536921 v 0.592767 -0.0619619 -0.548747 v 0.602169 -0.120813 -0.553703 v 0.608108 -0.107915 -0.536639 v 0.616016 -0.11034 -0.550996 v 0.614013 -0.136734 -0.534583 v 0.394229 0.109215 -0.580695 v 0.376797 0.0783046 -0.624732 v 0.402014 0.0526834 -0.590641 v 0.391523 0.0777422 -0.580132 v 0.374794 0.125646 -0.617668 v 0.128036 0.164921 -0.286455 v 0.0497311 0.209609 -0.381893 v -0.020982 0.232278 -0.427002 v 0.102063 0.264014 -0.357713 v 0.18882 0.668875 -0.281447 v 0.216779 0.690577 -0.297807 v 0.236794 0.652673 -0.299213 v 0.217271 0.672934 -0.273504 v 0.197413 0.685763 -0.367044 v 0.218466 0.689558 -0.39089 v 0.226883 0.66594 -0.366218 v 0.165167 0.703265 -0.356817 v 0.182951 0.697255 -0.355094 v 0.202404 0.672249 -0.331389 v 0.159069 0.690542 -0.332654 v 0.173409 0.718518 -0.338752 v 0.155484 0.696394 -0.348065 v 0.147647 0.708326 -0.370348 v 0.176554 0.726742 -0.379538 v 0.179366 0.696781 -0.394897 v 0.22437 0.658402 -0.336625 v 0.212631 0.695357 -0.351105 v 0.172003 0.674217 -0.301568 v 0.165237 0.682476 -0.314554 v 0.166397 0.689154 -0.297596 v 0.158226 0.68513 -0.30749 v 0.21648 0.666011 -0.314905 v 0.213405 0.678259 -0.327575 v 0.200313 0.667206 -0.318982 v 0.17789 0.675869 -0.31712 v 0.228377 0.650371 -0.320915 v 0.200225 0.682301 -0.395336 v 0.576389 -0.080923 -0.580572 v 0.588022 -0.105455 -0.568042 v 0.507715 -0.0106667 -0.609479 v 0.553615 -0.0340386 -0.602766 v 0.581889 -0.0992339 -0.537518 v 0.573736 -0.0651425 -0.551664 v 0.564932 -0.0792008 -0.57175 v 0.57783 -0.108758 -0.55618 v 0.602344 -0.111025 -0.53548 v 0.598461 -0.12062 -0.551611 v 0.609918 -0.130689 -0.532211 v 0.605964 -0.135733 -0.538572 v 0.545689 -0.0302077 -0.563122 v 0.505377 -0.0027238 -0.569747 v 0.535761 -0.0454961 -0.586107 v 0.609426 -0.141075 -0.530559 v 0.413067 0.126893 -0.532193 v 0.438056 0.116877 -0.536059 v 0.432784 0.101799 -0.505571 v 0.408252 0.109461 -0.50188 v 0.43187 0.0954732 -0.489439 v 0.407268 0.104857 -0.486328 v 0.429498 0.0848065 -0.475011 v 0.402594 0.092644 -0.472235 v 0.409693 0.0749657 -0.45243 v 0.425421 0.0643869 -0.447686 v 0.392542 0.0690437 -0.44816 v 0.392981 0.10129 -0.551137 v 0.391171 0.092644 -0.493305 v 0.379644 0.0546867 -0.453168 v 0.410537 0.0548624 -0.420413 v 0.420096 0.044881 -0.427284 v 0.393684 0.0560749 -0.427038 v 0.405335 0.0327558 -0.401979 v 0.407954 0.0237409 -0.407145 v 0.393948 0.0289249 -0.407303 v 0.433575 0.0765121 -0.495009 v 0.428057 0.0499947 -0.45786 v 0.392577 0.0409798 -0.465469 v 0.415598 0.037026 -0.465522 v 0.393122 0.0375004 -0.448652 v 0.413717 0.0333357 -0.449021 v 0.392612 0.0513654 -0.430043 v 0.419692 0.0395389 -0.434225 v 0.421678 0.0610305 -0.500685 v 0.397058 0.0669876 -0.500879 v 0.436931 0.0567075 -0.547324 v 0.399765 0.0241451 -0.400485 v 0.494289 0.0443187 -0.56755 v 0.401188 0.0382385 -0.628335 v 0.473412 0.0279935 -0.564106 v 0.435824 0.025709 -0.587372 v 0.501283 0.00789019 -0.642639 v 0.491723 0.00207358 -0.657488 v 0.510737 -0.0610481 -0.639722 v 0.520174 -0.0554072 -0.626876 v 0.514164 -0.0838225 -0.6364 v 0.527765 -0.0760728 -0.61953 v 0.507785 -0.104348 -0.623168 v 0.518996 -0.101378 -0.603047 v 0.501529 -0.143728 -0.601536 v 0.513478 -0.139493 -0.587847 v 0.505342 -0.16218 -0.583243 v 0.487717 -0.170878 -0.587038 v 0.504903 -0.162109 -0.564264 v 0.50188 -0.0136717 -0.614311 v 0.513355 -0.0773381 -0.596071 v 0.508224 -0.131339 -0.576143 v 0.495361 -0.152532 -0.553703 v 0.495484 -0.191245 -0.56581 v 0.475257 -0.189646 -0.56581 v 0.492373 -0.181809 -0.551155 v 0.474115 -0.201262 -0.545549 v 0.466787 -0.192827 -0.549784 v 0.47517 -0.190911 -0.543879 v 0.493481 -0.0884968 -0.631146 v 0.479809 -0.136348 -0.603434 v 0.47278 -0.166169 -0.583664 v 0.473483 -0.0254279 -0.650072 v 0.479949 -0.154184 -0.551875 v 0.492549 -0.119197 -0.569835 v 0.470759 -0.125066 -0.589569 v 0.463097 -0.160616 -0.569518 v 0.488384 -0.174779 -0.551735 v 0.471796 -0.181334 -0.564141 v 0.478262 -0.0850526 -0.614311 v 0.497171 -0.0737357 -0.592451 v 0.483763 -0.0229677 -0.595385 v 0.467016 -0.197132 -0.540822 v 0.470776 -0.00569362 -0.674639 v 0.455576 -0.00808352 -0.687573 v 0.457562 -0.0733666 -0.665027 v 0.467402 -0.0675676 -0.653464 v 0.455769 -0.0879169 -0.661635 v 0.470038 -0.0832074 -0.649334 v 0.445876 -0.107827 -0.643447 v 0.457509 -0.103662 -0.63257 v 0.426387 -0.129846 -0.616297 v 0.435771 -0.1254 -0.604471 v 0.420694 -0.134749 -0.599445 v 0.406196 -0.136594 -0.599111 v 0.418181 -0.127561 -0.582469 v 0.469757 -0.0288019 -0.651443 v 0.457685 -0.0812744 -0.626296 v 0.429955 -0.110849 -0.594085 v 0.411292 -0.118142 -0.574614 v 0.402084 -0.143799 -0.577971 v 0.387991 -0.140214 -0.580677 v 0.403631 -0.133483 -0.566566 v 0.370189 -0.138509 -0.551611 v 0.438882 -0.0935754 -0.653481 v 0.408832 -0.121182 -0.618406 v 0.394791 -0.129406 -0.599779 v 0.432222 -0.0367624 -0.671107 v 0.400467 -0.108987 -0.576389 v 0.4234 -0.0987067 -0.600446 v 0.411257 -0.100921 -0.615489 v 0.38829 -0.117703 -0.592099 v 0.397691 -0.126823 -0.566812 v 0.386198 -0.133536 -0.581274 v 0.428074 -0.0769866 -0.642656 v 0.446772 -0.0745264 -0.62366 v 0.420026 -0.0341792 -0.657347 v 0.453063 -0.0321583 -0.62793 v 0.358662 0.0625769 -0.692915 v 0.377957 0.0218782 -0.692651 v 0.349471 0.110709 -0.671283 v 0.375655 0.085404 -0.71235 v 0.441219 -0.00864585 -0.693635 v 0.424613 -0.0115629 -0.703652 v 0.418954 -0.0527713 -0.696113 v 0.426528 -0.0531227 -0.687028 v 0.410853 -0.0766528 -0.68933 v 0.42101 -0.0754051 -0.679753 v 0.395758 -0.0803079 -0.675939 v 0.404439 -0.0834359 -0.666995 v 0.376322 -0.0832777 -0.655028 v 0.387007 -0.0848417 -0.646505 v 0.375022 -0.0797983 -0.639458 v 0.362422 -0.064053 -0.639335 v 0.378642 -0.0719959 -0.628844 v 0.428391 -0.0369909 -0.67181 v 0.419815 -0.0633677 -0.67072 v 0.394247 -0.0771096 -0.644677 v 0.383088 -0.0658806 -0.628563 v 0.35636 -0.0587812 -0.613714 v 0.355235 -0.0525955 -0.619847 v 0.36852 -0.0550733 -0.613819 v 0.354901 -0.0347767 -0.601184 v 0.397287 -0.0588515 -0.689084 v 0.371015 -0.0659685 -0.659878 v 0.362633 -0.0551084 -0.642709 v 0.404 -0.0135311 -0.696763 v 0.383439 -0.0591853 -0.632306 v 0.393509 -0.0707659 -0.647946 v 0.377711 -0.0597828 -0.657962 v 0.370049 -0.0449338 -0.640056 v 0.370576 -0.0505219 -0.615225 v 0.356518 -0.0494676 -0.621358 v 0.393069 -0.0537729 -0.676853 v 0.414438 -0.0587636 -0.664763 v 0.391488 -0.0168172 -0.680877 v 0.410484 0.0641409 -0.552121 v 0.102871 0.658261 -0.0631041 v 0.121024 0.65146 -0.094208 v 0.127596 0.573472 -0.0729976 v 0.0750185 0.581661 -0.0556708 v 0.104998 0.578059 -0.0594314 v 0.102871 0.655291 -0.00917304 v 0.0840509 0.604927 -0.0374478 v 0.106509 0.598566 -0.0755281 v 0.129529 0.604207 -0.100341 v 0.123695 0.779303 -0.0699751 v 0.101606 0.7146 -0.016044 v 0.118125 0.805346 -0.0877764 v 0.0132675 0.865726 -0.0939093 v 0.0375356 0.9221 -0.06755 v 0.0895336 0.896338 -0.0741398 v 0.0928022 0.85223 -0.0353917 v 0.0770218 0.841265 0.0080132 v 0.0623836 0.925737 -0.102204 v 0.00576389 0.967736 -0.108618 v 0.0187502 0.960936 -0.130514 v 0.00847011 1 -0.14176 v 0.0176431 0.992479 -0.15067 v 0.0718026 0.877131 -0.108793 v 0.0532633 0.90117 -0.126155 v 0.0110357 0.945524 -0.144625 v 0.00553544 0.985608 -0.159561 v 0.0123889 0.888413 -0.108073 v -0.0163076 0.936334 -0.134467 v -0.00506098 0.990493 -0.153077 v -0.0194707 0.963659 -0.143588 v -0.00254806 0.999104 -0.144537 v -0.0197167 0.973852 -0.128282 v 0.000421748 0.861139 -0.044389 v 0.000474467 0.90219 -0.0739993 v -0.0196113 0.946561 -0.111166 v 0.0279935 0.891593 -0.120286 v 0.0138123 0.848592 0.00926086 v 0.00954205 0.91674 -0.0609251 v -0.00832953 0.969054 -0.108829 v 0.00736302 0.999157 -0.157558 v 0.123379 0.805363 -0.0418761 v 0.110551 0.823077 0.0101395 v 0.214248 0.782255 0.0628932 v 0.220838 0.756809 -0.0141989 v 0.28656 0.729993 0.091572 v 0.298563 0.657189 0.0578498 v 0.289899 0.69244 0.116719 v 0.259674 0.63155 0.114821 v 0.257003 0.670474 0.147348 v 0.138281 0.580607 0.187291 v 0.189506 0.605332 0.167926 v 0.189962 0.628422 0.185587 v 0.159913 0.742822 0.100675 v 0.213088 0.703125 0.11577 v 0.129547 0.581643 0.181334 v 0.164605 0.63619 0.1684 v 0.103943 0.889977 -0.00834712 v 0.122571 0.903332 0.0329491 v 0.0952799 0.861807 0.0758092 v 0.136067 0.903982 -0.0210347 v 0.147594 0.920255 0.000667753 v 0.184005 0.905493 -0.034144 v 0.0506976 0.891224 0.0661969 v 0.0925562 0.928127 0.0242681 v 0.127632 0.937652 -0.00801324 v 0.167504 0.918901 -0.034847 v 0.0749482 0.907971 -0.000333902 v 0.0480969 0.851843 0.00903242 v 0.0766527 0.893017 -0.00741575 v 0.107317 0.92398 -0.0217025 v 0.161231 0.904509 -0.031104 v 0.168506 0.916441 -0.02172 v 0.0276421 0.872825 0.0308052 v 0.00883914 0.827734 0.0575335 v 0.0361825 0.863828 0.0831547 v 0.156451 0.720609 -0.00374304 v 0.153674 0.694197 0.0563736 v 0.290532 0.680332 0.0269743 v 0.220188 0.660299 0.0603451 v 0.231505 0.700858 0.00569359 v 0.217956 0.637384 0.0884441 v 0.173215 0.606333 0.137455 v 0.142867 0.570274 0.177082 v 0.139282 0.574474 0.167873 v 0.2104 0.681809 0.130127 v 0.131656 0.570344 0.179858 v 0.0881278 0.595016 0.00268863 v 0.128264 0.558201 0.0246547 v 0.115524 0.533617 0.0411731 v 0.11584 0.527484 0.0417179 v 0.0849823 0.499508 0.039328 v 0.0874952 0.557604 0.0307173 v 0.0989878 0.529944 0.0420518 v 0.0950866 0.486961 0.0309282 v 0.388992 0.221172 -0.621499 v 0.347503 0.278723 -0.594384 v 0.230767 0.771711 0.0179946 v 0.300162 0.706305 0.0577268 v 0.302516 0.67666 0.0889713 v 0.153604 0.703757 0.0845605 v 0.203054 0.674428 0.0836819 v 0.202193 0.658525 0.101026 v 0.182863 0.693741 0.0835061 v 0.192844 0.679717 0.0521562 # 2519 vertices vt 0.644 0.154 0.599 vt 0.632 0.188 0.600 vt 0.640 0.183 0.600 vt 0.656 0.168 0.599 vt 0.643 0.221 0.601 vt 0.656 0.202 0.601 vt 0.639 0.194 0.600 vt 0.621 0.228 0.601 vt 0.586 0.119 0.597 vt 0.562 0.130 0.598 vt 0.578 0.188 0.600 vt 0.615 0.158 0.599 vt 0.614 0.081 0.598 vt 0.644 0.095 0.597 vt 0.695 0.188 0.602 vt 0.671 0.180 0.600 vt 0.673 0.195 0.601 vt 0.684 0.201 0.602 vt 0.647 0.189 0.600 vt 0.595 0.214 0.600 vt 0.703 0.208 0.602 vt 0.713 0.199 0.602 vt 0.719 0.214 0.603 vt 0.724 0.204 0.603 vt 0.715 0.196 0.602 vt 0.728 0.196 0.602 vt 0.735 0.206 0.602 vt 0.734 0.198 0.602 vt 0.734 0.218 0.603 vt 0.730 0.165 0.600 vt 0.731 0.189 0.602 vt 0.734 0.188 0.602 vt 0.733 0.162 0.600 vt 0.734 0.227 0.602 vt 0.716 0.218 0.603 vt 0.703 0.212 0.603 vt 0.717 0.236 0.602 vt 0.702 0.230 0.602 vt 0.694 0.221 0.602 vt 0.697 0.257 0.602 vt 0.682 0.239 0.602 vt 0.673 0.225 0.602 vt 0.734 0.260 0.602 vt 0.710 0.276 0.602 vt 0.637 0.273 0.601 vt 0.598 0.264 0.601 vt 0.659 0.309 0.601 vt 0.704 0.152 0.599 vt 0.706 0.125 0.597 vt 0.682 0.130 0.598 vt 0.677 0.154 0.599 vt 0.719 0.150 0.599 vt 0.733 0.122 0.597 vt 0.703 0.187 0.602 vt 0.703 0.177 0.601 vt 0.699 0.172 0.601 vt 0.707 0.175 0.602 vt 0.711 0.186 0.606 vt 0.717 0.188 0.606 vt 0.706 0.173 0.601 vt 0.717 0.161 0.601 vt 0.730 0.159 0.599 vt 0.624 0.324 0.601 vt 0.578 0.291 0.600 vt 0.734 0.303 0.601 vt 0.700 0.310 0.601 vt 0.715 0.317 0.601 vt 0.673 0.210 0.602 vt 0.692 0.216 0.602 vt 0.691 0.211 0.602 vt 0.641 0.070 0.597 vt 0.662 0.081 0.596 vt 0.676 0.098 0.596 vt 0.705 0.093 0.595 vt 0.733 0.096 0.595 vt 0.686 0.077 0.596 vt 0.704 0.073 0.595 vt 0.733 0.077 0.595 vt 0.711 0.057 0.595 vt 0.697 0.054 0.595 vt 0.661 0.057 0.597 vt 0.682 0.060 0.596 vt 0.674 0.039 0.597 vt 0.670 0.043 0.597 vt 0.694 0.044 0.596 vt 0.719 0.033 0.595 vt 0.711 0.023 0.596 vt 0.733 0.053 0.594 vt 0.734 0.032 0.594 vt 0.275 0.976 0.506 vt 0.271 0.991 0.510 vt 0.241 0.990 0.536 vt 0.236 0.970 0.540 vt 0.325 0.976 0.455 vt 0.322 0.987 0.457 vt 0.299 0.955 0.477 vt 0.305 0.955 0.472 vt 0.302 0.969 0.479 vt 0.339 0.984 0.440 vt 0.336 0.990 0.443 vt 0.733 0.014 0.595 vt 0.727 0.011 0.596 vt 0.298 0.668 0.427 vt 0.321 0.707 0.450 vt 0.332 0.693 0.450 vt 0.323 0.665 0.434 vt 0.339 0.678 0.447 vt 0.337 0.640 0.426 vt 0.307 0.634 0.413 vt 0.288 0.655 0.417 vt 0.352 0.621 0.416 vt 0.352 0.584 0.395 vt 0.333 0.597 0.401 vt 0.320 0.616 0.409 vt 0.597 0.747 -0.465 vt 0.621 0.733 -0.465 vt 0.638 0.776 -0.437 vt 0.611 0.783 -0.437 vt 0.648 0.761 -0.440 vt 0.645 0.778 -0.437 vt 0.644 0.754 -0.446 vt 0.579 0.752 -0.465 vt 0.590 0.787 -0.440 vt 0.542 0.754 -0.462 vt 0.556 0.791 -0.451 vt 0.606 0.693 -0.456 vt 0.634 0.678 -0.468 vt 0.643 0.715 -0.465 vt 0.572 0.710 -0.457 vt 0.571 0.695 -0.460 vt 0.593 0.685 -0.461 vt 0.563 0.668 -0.455 vt 0.566 0.684 -0.426 vt 0.561 0.686 -0.437 vt 0.553 0.670 -0.459 vt 0.547 0.707 -0.450 vt 0.554 0.695 -0.446 vt 0.541 0.682 -0.446 vt 0.525 0.688 -0.442 vt 0.556 0.654 -0.501 vt 0.569 0.652 -0.505 vt 0.576 0.668 -0.453 vt 0.603 0.655 -0.496 vt 0.586 0.664 -0.492 vt 0.585 0.658 -0.494 vt 0.595 0.649 -0.493 vt 0.577 0.651 -0.498 vt 0.586 0.642 -0.488 vt 0.577 0.645 -0.494 vt 0.570 0.634 -0.513 vt 0.582 0.634 -0.511 vt 0.563 0.651 -0.516 vt 0.557 0.631 -0.502 vt 0.521 0.674 -0.487 vt 0.533 0.670 -0.497 vt 0.588 0.624 -0.500 vt 0.564 0.611 -0.444 vt 0.609 0.620 -0.451 vt 0.597 0.626 -0.482 vt 0.454 0.857 -0.466 vt 0.462 0.834 -0.465 vt 0.497 0.846 -0.461 vt 0.485 0.886 -0.467 vt 0.525 0.846 -0.458 vt 0.518 0.777 -0.462 vt 0.563 0.844 -0.459 vt 0.645 0.790 -0.437 vt 0.643 0.805 -0.440 vt 0.636 0.805 -0.444 vt 0.640 0.813 -0.425 vt 0.650 0.809 -0.442 vt 0.644 0.817 -0.430 vt 0.653 0.790 -0.438 vt 0.657 0.776 -0.440 vt 0.654 0.769 -0.436 vt 0.467 0.802 -0.465 vt 0.470 0.774 -0.467 vt 0.499 0.775 -0.465 vt 0.498 0.818 -0.462 vt 0.661 0.741 -0.451 vt 0.651 0.753 -0.447 vt 0.517 0.713 -0.454 vt 0.544 0.728 -0.465 vt 0.512 0.735 -0.456 vt 0.499 0.707 -0.479 vt 0.386 0.562 -0.685 vt 0.424 0.552 -0.685 vt 0.411 0.596 -0.685 vt 0.388 0.597 -0.685 vt 0.423 0.813 -0.467 vt 0.431 0.768 -0.467 vt 0.441 0.742 -0.469 vt 0.449 0.721 -0.469 vt 0.460 0.745 -0.469 vt 0.456 0.760 -0.468 vt 0.408 0.746 -0.469 vt 0.413 0.734 -0.469 vt 0.667 0.706 -0.465 vt 0.670 0.722 -0.461 vt 0.430 0.709 -0.454 vt 0.397 0.522 -0.685 vt 0.389 0.523 -0.685 vt 0.387 0.496 -0.685 vt 0.395 0.491 -0.685 vt 0.389 0.442 -0.685 vt 0.409 0.461 -0.685 vt 0.384 0.469 -0.685 vt 0.367 0.448 -0.685 vt 0.457 0.478 -0.685 vt 0.437 0.450 -0.685 vt 0.453 0.440 -0.697 vt 0.468 0.464 -0.696 vt 0.445 0.513 -0.685 vt 0.425 0.499 -0.685 vt 0.477 0.499 -0.685 vt 0.495 0.484 -0.696 vt 0.497 0.445 -0.646 vt 0.510 0.452 -0.642 vt 0.423 0.527 -0.685 vt 0.462 0.528 -0.685 vt 0.474 0.542 -0.685 vt 0.445 0.562 -0.685 vt 0.367 0.420 -0.685 vt 0.334 0.432 -0.685 vt 0.351 0.404 -0.685 vt 0.323 0.418 -0.685 vt 0.422 0.427 -0.685 vt 0.395 0.403 -0.685 vt 0.474 0.760 -0.468 vt 0.493 0.756 -0.468 vt 0.379 0.470 -0.685 vt 0.447 0.388 -0.709 vt 0.448 0.419 -0.705 vt 0.485 0.401 -0.627 vt 0.480 0.420 -0.637 vt 0.478 0.587 -0.685 vt 0.496 0.568 -0.685 vt 0.486 0.600 -0.685 vt 0.515 0.584 -0.685 vt 0.395 0.801 -0.468 vt 0.678 0.800 -0.452 vt 0.660 0.758 -0.446 vt 0.688 0.779 -0.457 vt 0.706 0.767 -0.457 vt 0.467 0.627 -0.685 vt 0.501 0.611 -0.685 vt 0.487 0.631 -0.685 vt 0.538 0.562 -0.685 vt 0.550 0.583 -0.685 vt 0.528 0.603 -0.685 vt 0.513 0.398 -0.667 vt 0.523 0.406 -0.679 vt 0.502 0.418 -0.600 vt 0.496 0.414 -0.604 vt 0.521 0.549 -0.685 vt 0.508 0.511 -0.685 vt 0.486 0.431 -0.620 vt 0.506 0.432 -0.616 vt 0.527 0.421 -0.676 vt 0.545 0.559 -0.712 vt 0.584 0.532 -0.709 vt 0.583 0.550 -0.708 vt 0.551 0.566 -0.701 vt 0.612 0.550 -0.709 vt 0.598 0.562 -0.709 vt 0.589 0.564 -0.710 vt 0.594 0.551 -0.709 vt 0.598 0.537 -0.709 vt 0.611 0.577 -0.710 vt 0.610 0.570 -0.709 vt 0.619 0.561 -0.709 vt 0.617 0.570 -0.710 vt 0.589 0.577 -0.701 vt 0.629 0.566 -0.710 vt 0.625 0.558 -0.709 vt 0.632 0.555 -0.709 vt 0.632 0.565 -0.709 vt 0.620 0.536 -0.709 vt 0.576 0.387 -0.709 vt 0.605 0.396 -0.709 vt 0.603 0.416 -0.709 vt 0.574 0.413 -0.709 vt 0.609 0.439 -0.709 vt 0.570 0.439 -0.708 vt 0.620 0.466 -0.709 vt 0.572 0.467 -0.708 vt 0.572 0.490 -0.708 vt 0.623 0.493 -0.709 vt 0.538 0.492 -0.708 vt 0.531 0.463 -0.706 vt 0.555 0.509 -0.709 vt 0.623 0.515 -0.709 vt 0.627 0.419 -0.709 vt 0.647 0.429 -0.709 vt 0.524 0.437 -0.666 vt 0.521 0.356 -0.709 vt 0.554 0.364 -0.708 vt 0.662 0.494 -0.709 vt 0.661 0.511 -0.709 vt 0.681 0.501 -0.709 vt 0.680 0.507 -0.709 vt 0.752 0.685 -0.953 vt 0.738 0.692 -0.953 vt 0.731 0.679 -0.953 vt 0.746 0.673 -0.953 vt 0.726 0.671 -0.953 vt 0.742 0.665 -0.954 vt 0.721 0.659 -0.954 vt 0.737 0.654 -0.954 vt 0.716 0.649 -0.955 vt 0.733 0.642 -0.955 vt 0.720 0.620 -0.957 vt 0.711 0.625 -0.957 vt 0.705 0.612 -0.959 vt 0.710 0.605 -0.958 vt 0.700 0.603 -0.961 vt 0.703 0.601 -0.958 vt 0.699 0.629 -0.957 vt 0.694 0.612 -0.958 vt 0.695 0.604 -0.958 vt 0.713 0.676 -0.954 vt 0.698 0.655 -0.954 vt 0.749 0.652 -0.954 vt 0.756 0.664 -0.953 vt 0.681 0.514 -0.709 vt 0.665 0.524 -0.709 vt 0.766 0.677 -0.953 vt 0.684 0.487 -0.709 vt 0.694 0.494 -0.709 vt 0.717 0.692 -0.953 vt 0.748 0.630 -0.954 vt 0.766 0.647 -0.954 vt 0.722 0.614 -0.956 vt 0.733 0.611 -0.955 vt 0.778 0.662 -0.953 vt 0.695 0.631 -0.956 vt 0.690 0.637 -0.955 vt 0.678 0.661 -0.954 vt 0.674 0.640 -0.954 vt 0.747 0.602 -0.954 vt 0.762 0.619 -0.954 vt 0.720 0.599 -0.956 vt 0.733 0.598 -0.955 vt 0.677 0.627 -0.955 vt 0.686 0.617 -0.956 vt 0.718 0.610 -0.957 vt 0.711 0.598 -0.957 vt 0.695 0.626 -0.957 vt 0.688 0.610 -0.957 vt 0.696 0.597 -0.957 vt 0.414 0.480 -0.685 vt 0.360 0.450 -0.685 vt 0.331 0.436 -0.685 vt 0.652 0.454 -0.709 vt 0.698 0.676 -0.954 vt 0.682 0.679 -0.954 vt 0.773 0.634 -0.954 vt 0.695 0.697 -0.953 vt 0.679 0.699 -0.953 vt 0.793 0.639 -0.953 vt 0.788 0.651 -0.953 vt 0.861 0.723 -0.888 vt 0.883 0.735 -0.890 vt 0.863 0.747 -0.890 vt 0.848 0.731 -0.892 vt 0.845 0.726 -0.890 vt 0.855 0.720 -0.882 vt 0.840 0.719 -0.901 vt 0.848 0.713 -0.894 vt 0.833 0.714 -0.922 vt 0.844 0.708 -0.911 vt 0.826 0.685 -0.961 vt 0.820 0.689 -0.959 vt 0.810 0.676 -0.999 vt 0.816 0.672 -1.002 vt 0.813 0.691 -0.977 vt 0.801 0.679 -1.017 vt 0.831 0.733 -0.932 vt 0.823 0.719 -0.947 vt 0.835 0.680 -0.979 vt 0.855 0.694 -0.951 vt 0.859 0.711 -0.910 vt 0.864 0.716 -0.907 vt 0.869 0.703 -0.942 vt 0.808 0.696 -0.991 vt 0.809 0.722 -0.968 vt 0.794 0.706 -1.006 vt 0.848 0.669 -1.006 vt 0.862 0.685 -0.968 vt 0.825 0.666 -1.010 vt 0.824 0.676 -0.985 vt 0.816 0.666 -1.013 vt 0.803 0.685 -1.003 vt 0.795 0.684 -1.010 vt 0.796 0.678 -1.013 vt 0.817 0.738 -0.955 vt 0.876 0.697 -0.955 vt 0.668 0.471 -0.709 vt 0.672 0.442 -0.708 vt 0.691 0.461 -0.709 vt 0.848 0.762 -0.935 vt 0.629 0.397 -0.709 vt 0.644 0.401 -0.709 vt 0.741 0.427 -0.750 vt 0.741 0.443 -0.728 vt 0.718 0.446 -0.708 vt 0.721 0.422 -0.704 vt 0.746 0.415 -0.734 vt 0.733 0.401 -0.694 vt 0.699 0.454 -0.709 vt 0.702 0.418 -0.714 vt 0.711 0.392 -0.725 vt 0.675 0.413 -0.707 vt 0.679 0.396 -0.703 vt 0.840 0.774 -0.966 vt 0.817 0.772 -0.983 vt 0.659 0.538 -0.709 vt 0.651 0.559 -0.709 vt 0.648 0.573 -0.709 vt 0.693 0.558 -0.709 vt 0.679 0.577 -0.709 vt 0.668 0.560 -0.709 vt 0.684 0.544 -0.709 vt 0.685 0.525 -0.709 vt 0.686 0.533 -0.709 vt 0.913 0.704 -0.983 vt 0.887 0.717 -0.934 vt 0.628 0.574 -0.709 vt 0.623 0.597 -0.709 vt 0.610 0.598 -0.709 vt 0.591 0.597 -0.711 vt 0.711 0.753 -0.884 vt 0.725 0.749 -0.889 vt 0.736 0.760 -0.893 vt 0.723 0.763 -0.883 vt 0.737 0.743 -0.895 vt 0.747 0.754 -0.900 vt 0.742 0.740 -0.909 vt 0.752 0.751 -0.914 vt 0.788 0.725 -1.001 vt 0.774 0.734 -0.957 vt 0.769 0.729 -0.962 vt 0.786 0.720 -1.007 vt 0.780 0.738 -0.972 vt 0.794 0.729 -1.014 vt 0.747 0.772 -0.931 vt 0.762 0.763 -0.952 vt 0.734 0.726 -0.947 vt 0.762 0.715 -0.999 vt 0.724 0.741 -0.908 vt 0.726 0.729 -0.939 vt 0.785 0.751 -0.999 vt 0.790 0.765 -1.007 vt 0.771 0.773 -0.970 vt 0.734 0.713 -0.970 vt 0.751 0.704 -1.007 vt 0.779 0.713 -1.005 vt 0.787 0.716 -1.012 vt 0.773 0.720 -0.989 vt 0.799 0.731 -1.012 vt 0.798 0.739 -1.005 vt 0.787 0.741 -0.991 vt 0.762 0.775 -0.961 vt 0.726 0.715 -0.961 vt 0.757 0.794 -0.975 vt 0.740 0.793 -0.968 vt 0.703 0.714 -0.975 vt 0.700 0.733 -0.937 vt 0.022 0.649 0.173 vt 0.019 0.619 0.173 vt 0.014 0.626 0.173 vt 0.017 0.652 0.173 vt 0.006 0.626 0.173 vt 0.006 0.652 0.173 vt 0.006 0.694 0.173 vt 0.029 0.699 0.173 vt 0.033 0.697 0.173 vt 0.659 0.833 -0.454 vt 0.646 0.821 -0.443 vt 0.049 0.730 0.173 vt 0.057 0.726 0.173 vt 0.006 0.734 0.173 vt 0.638 0.852 -0.457 vt 0.628 0.839 -0.451 vt 0.636 0.824 -0.446 vt 0.615 0.835 -0.450 vt 0.630 0.817 -0.442 vt 0.013 0.588 0.173 vt 0.006 0.588 0.173 vt 0.017 0.588 0.172 vt 0.022 0.546 0.111 vt 0.006 0.532 0.117 vt 0.203 0.940 -0.291 vt 0.213 0.950 -0.291 vt 0.264 0.917 -0.291 vt 0.225 0.894 -0.291 vt 0.281 0.893 -0.291 vt 0.238 0.881 -0.291 vt 0.291 0.865 -0.291 vt 0.255 0.859 -0.291 vt 0.289 0.825 -0.291 vt 0.261 0.832 -0.291 vt 0.268 0.756 -0.291 vt 0.236 0.767 -0.291 vt 0.226 0.700 -0.291 vt 0.203 0.715 -0.291 vt 0.183 0.647 -0.292 vt 0.165 0.659 -0.292 vt 0.146 0.581 -0.292 vt 0.126 0.574 -0.292 vt 0.121 0.528 -0.292 vt 0.116 0.525 -0.292 vt 0.328 0.815 -0.291 vt 0.314 0.767 -0.291 vt 0.295 0.734 -0.291 vt 0.249 0.684 -0.291 vt 0.201 0.637 -0.292 vt 0.158 0.579 -0.292 vt 0.123 0.522 -0.292 vt 0.322 0.855 -0.291 vt 0.338 0.844 -0.290 vt 0.363 0.821 -0.291 vt 0.330 0.862 -0.290 vt 0.340 0.851 -0.290 vt 0.319 0.881 -0.290 vt 0.330 0.878 -0.290 vt 0.325 0.888 -0.290 vt 0.320 0.900 -0.291 vt 0.333 0.900 -0.290 vt 0.342 0.894 -0.290 vt 0.353 0.802 -0.291 vt 0.368 0.799 -0.290 vt 0.368 0.783 -0.285 vt 0.364 0.783 -0.291 vt 0.355 0.777 -0.291 vt 0.340 0.792 -0.291 vt 0.377 0.783 -0.291 vt 0.369 0.773 -0.291 vt 0.381 0.805 -0.291 vt 0.374 0.796 -0.291 vt 0.368 0.782 -0.284 vt 0.314 0.932 -0.291 vt 0.364 0.837 -0.290 vt 0.349 0.852 -0.290 vt 0.374 0.850 -0.290 vt 0.376 0.877 -0.290 vt 0.370 0.877 -0.290 vt 0.374 0.890 -0.290 vt 0.380 0.880 -0.290 vt 0.343 0.876 -0.290 vt 0.385 0.850 -0.290 vt 0.389 0.841 -0.290 vt 0.373 0.840 -0.290 vt 0.379 0.858 -0.290 vt 0.385 0.871 -0.290 vt 0.345 0.913 -0.290 vt 0.398 0.846 -0.291 vt 0.404 0.867 -0.291 vt 0.385 0.891 -0.290 vt 0.386 0.908 -0.290 vt 0.411 0.901 -0.291 vt 0.409 0.889 -0.291 vt 0.315 0.721 -0.291 vt 0.262 0.675 -0.291 vt 0.211 0.632 -0.292 vt 0.163 0.577 -0.292 vt 0.335 0.781 -0.291 vt 0.347 0.772 -0.291 vt 0.372 0.918 -0.290 vt 0.335 0.938 -0.291 vt 0.372 0.939 -0.290 vt 0.385 0.932 -0.287 vt 0.381 0.927 -0.292 vt 0.392 0.922 -0.290 vt 0.419 0.914 -0.291 vt 0.006 0.768 0.173 vt 0.043 0.760 0.173 vt 0.046 0.742 0.173 vt 0.042 0.774 0.173 vt 0.056 0.776 0.173 vt 0.056 0.763 0.173 vt 0.049 0.797 0.173 vt 0.060 0.798 0.173 vt 0.564 0.899 -0.417 vt 0.556 0.895 -0.436 vt 0.545 0.910 -0.381 vt 0.540 0.908 -0.399 vt 0.534 0.892 -0.435 vt 0.535 0.915 -0.422 vt 0.553 0.926 -0.441 vt 0.533 0.931 -0.422 vt 0.524 0.931 -0.385 vt 0.601 0.873 -0.460 vt 0.605 0.872 -0.459 vt 0.612 0.875 -0.459 vt 0.606 0.880 -0.452 vt 0.006 0.921 0.173 vt 0.042 0.914 0.173 vt 0.035 0.886 0.173 vt 0.006 0.890 0.173 vt 0.048 0.804 0.173 vt 0.046 0.816 0.173 vt 0.055 0.821 0.173 vt 0.064 0.840 0.173 vt 0.044 0.821 0.173 vt 0.052 0.847 0.173 vt 0.040 0.795 0.173 vt 0.379 0.374 0.257 vt 0.397 0.365 0.257 vt 0.417 0.331 0.257 vt 0.395 0.331 0.257 vt 0.369 0.339 0.257 vt 0.357 0.348 0.257 vt 0.416 0.362 0.257 vt 0.432 0.356 0.257 vt 0.118 0.199 0.365 vt 0.138 0.210 0.372 vt 0.133 0.232 0.365 vt 0.098 0.201 0.360 vt 0.390 0.287 0.257 vt 0.399 0.237 0.257 vt 0.379 0.242 0.257 vt 0.374 0.298 0.257 vt 0.392 0.203 0.257 vt 0.375 0.199 0.257 vt 0.364 0.236 0.257 vt 0.393 0.185 0.257 vt 0.379 0.181 0.257 vt 0.519 0.123 0.194 vt 0.504 0.133 0.211 vt 0.498 0.157 0.248 vt 0.531 0.162 0.263 vt 0.413 0.942 -0.291 vt 0.438 0.941 -0.291 vt 0.384 0.962 -0.291 vt 0.412 0.962 -0.291 vt 0.395 0.939 -0.294 vt 0.395 0.986 -0.291 vt 0.376 0.973 -0.291 vt 0.498 0.055 0.095 vt 0.491 0.083 0.156 vt 0.506 0.088 0.158 vt 0.521 0.069 0.118 vt 0.355 0.382 0.257 vt 0.370 0.379 0.257 vt 0.083 0.929 0.173 vt 0.109 0.962 0.173 vt 0.117 0.953 0.173 vt 0.098 0.934 0.173 vt 0.092 0.923 0.173 vt 0.094 0.928 0.173 vt 0.097 0.920 0.173 vt 0.118 0.942 0.173 vt 0.078 0.901 0.173 vt 0.085 0.881 0.173 vt 0.078 0.890 0.168 vt 0.069 0.885 0.173 vt 0.470 0.350 0.257 vt 0.466 0.318 0.257 vt 0.548 0.208 0.346 vt 0.562 0.190 0.346 vt 0.544 0.158 0.263 vt 0.569 0.217 0.399 vt 0.573 0.203 0.382 vt 0.803 0.618 0.349 vt 0.802 0.627 0.353 vt 0.809 0.631 0.373 vt 0.817 0.623 0.386 vt 0.786 0.610 0.318 vt 0.838 0.598 0.408 vt 0.835 0.588 0.402 vt 0.846 0.608 0.435 vt 0.890 0.638 0.432 vt 0.911 0.637 0.402 vt 0.920 0.588 0.479 vt 0.911 0.586 0.497 vt 0.887 0.576 0.499 vt 0.882 0.567 0.479 vt 0.925 0.574 0.493 vt 0.916 0.572 0.508 vt 0.900 0.564 0.511 vt 0.896 0.558 0.493 vt 0.925 0.564 0.500 vt 0.918 0.564 0.514 vt 0.911 0.558 0.517 vt 0.907 0.552 0.500 vt 0.902 0.583 0.521 vt 0.877 0.626 0.476 vt 0.853 0.614 0.458 vt 0.895 0.580 0.522 vt 0.914 0.561 0.527 vt 0.909 0.569 0.526 vt 0.905 0.567 0.526 vt 0.865 0.619 0.481 vt 0.828 0.632 0.426 vt 0.858 0.642 0.476 vt 0.858 0.656 0.452 vt 0.870 0.675 0.399 vt 0.936 0.481 0.530 vt 0.900 0.508 0.615 vt 0.913 0.530 0.614 vt 0.936 0.499 0.553 vt 0.902 0.477 0.613 vt 0.867 0.503 0.683 vt 0.797 0.433 0.635 vt 0.770 0.443 0.614 vt 0.760 0.479 0.665 vt 0.778 0.485 0.697 vt 0.799 0.492 0.741 vt 0.813 0.454 0.703 vt 0.847 0.519 0.718 vt 0.855 0.482 0.715 vt 0.830 0.513 0.759 vt 0.819 0.504 0.759 vt 0.829 0.478 0.733 vt 0.872 0.434 0.726 vt 0.868 0.411 0.712 vt 0.821 0.436 0.685 vt 0.846 0.450 0.726 vt 0.821 0.456 0.726 vt 0.840 0.463 0.736 vt 0.831 0.472 0.761 vt 0.843 0.479 0.726 vt 0.867 0.459 0.704 vt 0.878 0.473 0.678 vt 0.319 0.117 0.426 vt 0.330 0.095 0.408 vt 0.337 0.110 0.409 vt 0.328 0.119 0.417 vt 0.858 0.530 0.687 vt 0.753 0.522 0.747 vt 0.765 0.522 0.759 vt 0.808 0.551 0.799 vt 0.824 0.558 0.757 vt 0.783 0.530 0.806 vt 0.796 0.539 0.826 vt 0.805 0.543 0.814 vt 0.875 0.545 0.665 vt 0.831 0.568 0.747 vt 0.795 0.572 0.815 vt 0.805 0.583 0.799 vt 0.755 0.549 0.799 vt 0.766 0.559 0.843 vt 0.784 0.565 0.850 vt 0.775 0.562 0.861 vt 0.750 0.584 0.830 vt 0.756 0.582 0.841 vt 0.767 0.589 0.841 vt 0.769 0.593 0.830 vt 0.762 0.582 0.856 vt 0.810 0.388 0.581 vt 0.798 0.378 0.543 vt 0.782 0.420 0.591 vt 0.961 0.985 0.382 vt 0.947 0.980 0.399 vt 0.959 0.938 0.454 vt 0.972 0.944 0.444 vt 0.918 0.921 0.543 vt 0.908 0.902 0.575 vt 0.933 0.899 0.550 vt 0.941 0.918 0.522 vt 0.928 0.961 0.452 vt 0.923 0.942 0.497 vt 0.973 0.905 0.505 vt 0.977 0.906 0.501 vt 0.965 0.892 0.538 vt 0.967 0.898 0.528 vt 0.006 0.949 0.173 vt 0.063 0.948 0.173 vt 0.070 0.868 0.173 vt 0.006 0.853 0.173 vt 0.293 0.111 0.446 vt 0.304 0.108 0.435 vt 0.303 0.115 0.440 vt 0.290 0.118 0.449 vt 0.282 0.106 0.451 vt 0.277 0.108 0.452 vt 0.947 0.645 0.476 vt 0.960 0.631 0.484 vt 0.953 0.621 0.516 vt 0.932 0.645 0.497 vt 0.845 0.391 0.653 vt 0.267 0.092 0.439 vt 0.292 0.099 0.441 vt 0.278 0.102 0.449 vt 0.267 0.100 0.447 vt 0.299 0.045 0.396 vt 0.307 0.058 0.404 vt 0.279 0.070 0.423 vt 0.269 0.058 0.420 vt 0.288 0.029 0.389 vt 0.266 0.039 0.406 vt 0.257 0.025 0.395 vt 0.277 0.011 0.381 vt 0.251 0.125 0.456 vt 0.263 0.135 0.458 vt 0.256 0.138 0.459 vt 0.243 0.124 0.453 vt 0.230 0.042 0.396 vt 0.255 0.047 0.442 vt 0.256 0.045 0.457 vt 0.234 0.058 0.410 vt 0.257 0.085 0.433 vt 0.257 0.098 0.443 vt 0.231 0.101 0.436 vt 0.223 0.076 0.415 vt 0.190 0.114 0.418 vt 0.181 0.094 0.409 vt 0.209 0.129 0.436 vt 0.229 0.128 0.449 vt 0.210 0.144 0.444 vt 0.228 0.141 0.458 vt 0.266 0.150 0.460 vt 0.244 0.144 0.463 vt 0.265 0.144 0.457 vt 0.284 0.252 0.376 vt 0.251 0.260 0.377 vt 0.258 0.236 0.390 vt 0.289 0.230 0.388 vt 0.280 0.276 0.366 vt 0.250 0.284 0.365 vt 0.212 0.270 0.374 vt 0.223 0.288 0.364 vt 0.279 0.290 0.360 vt 0.255 0.308 0.356 vt 0.223 0.310 0.356 vt 0.199 0.303 0.359 vt 0.185 0.262 0.371 vt 0.177 0.311 0.356 vt 0.165 0.278 0.364 vt 0.209 0.343 0.348 vt 0.186 0.346 0.348 vt 0.267 0.205 0.416 vt 0.295 0.211 0.405 vt 0.234 0.239 0.387 vt 0.240 0.197 0.422 vt 0.199 0.238 0.383 vt 0.205 0.202 0.409 vt 0.235 0.351 0.345 vt 0.248 0.349 0.345 vt 0.251 0.386 0.336 vt 0.229 0.388 0.336 vt 0.216 0.364 0.343 vt 0.209 0.388 0.336 vt 0.197 0.355 0.345 vt 0.188 0.357 0.345 vt 0.269 0.410 0.332 vt 0.266 0.431 0.327 vt 0.255 0.433 0.326 vt 0.248 0.409 0.331 vt 0.268 0.445 0.325 vt 0.260 0.447 0.324 vt 0.275 0.448 0.325 vt 0.261 0.453 0.323 vt 0.267 0.381 0.336 vt 0.228 0.413 0.331 vt 0.286 0.352 0.343 vt 0.285 0.344 0.345 vt 0.295 0.345 0.345 vt 0.293 0.354 0.342 vt 0.280 0.372 0.338 vt 0.290 0.376 0.338 vt 0.286 0.331 0.348 vt 0.282 0.312 0.354 vt 0.304 0.315 0.354 vt 0.298 0.334 0.348 vt 0.274 0.431 0.329 vt 0.282 0.412 0.332 vt 0.241 0.445 0.325 vt 0.298 0.284 0.364 vt 0.310 0.258 0.374 vt 0.329 0.212 0.396 vt 0.320 0.234 0.385 vt 0.475 0.201 0.257 vt 0.465 0.241 0.257 vt 0.481 0.242 0.257 vt 0.481 0.203 0.257 vt 0.493 0.218 0.257 vt 0.488 0.201 0.257 vt 0.367 0.022 0.372 vt 0.384 0.023 0.393 vt 0.387 0.049 0.417 vt 0.375 0.047 0.398 vt 0.410 0.055 0.452 vt 0.392 0.072 0.442 vt 0.389 0.068 0.435 vt 0.384 0.069 0.427 vt 0.816 0.627 0.389 vt 0.824 0.635 0.423 vt 0.425 0.079 0.423 vt 0.424 0.101 0.389 vt 0.410 0.092 0.409 vt 0.415 0.072 0.437 vt 0.383 0.075 0.434 vt 0.396 0.078 0.434 vt 0.351 0.217 0.382 vt 0.337 0.243 0.377 vt 0.353 0.236 0.372 vt 0.360 0.258 0.369 vt 0.306 0.191 0.446 vt 0.315 0.180 0.422 vt 0.333 0.190 0.402 vt 0.968 0.585 0.515 vt 0.983 0.599 0.526 vt 0.985 0.588 0.499 vt 0.975 0.577 0.490 vt 0.958 0.563 0.479 vt 0.965 0.554 0.452 vt 0.984 0.660 0.426 vt 0.982 0.628 0.475 vt 0.974 0.542 0.423 vt 0.971 0.550 0.437 vt 0.983 0.570 0.475 vt 0.979 0.539 0.426 vt 0.948 0.581 0.530 vt 0.952 0.599 0.553 vt 0.972 0.599 0.532 vt 0.143 0.197 0.377 vt 0.153 0.202 0.383 vt 0.152 0.219 0.378 vt 0.146 0.310 0.354 vt 0.147 0.283 0.360 vt 0.164 0.349 0.347 vt 0.151 0.329 0.350 vt 0.151 0.247 0.367 vt 0.172 0.239 0.376 vt 0.117 0.341 0.348 vt 0.114 0.323 0.351 vt 0.320 0.341 0.346 vt 0.327 0.317 0.352 vt 0.318 0.294 0.360 vt 0.342 0.306 0.356 vt 0.334 0.262 0.369 vt 0.355 0.272 0.363 vt 0.318 0.362 0.342 vt 0.291 0.425 0.332 vt 0.286 0.439 0.329 vt 0.160 0.455 0.334 vt 0.162 0.440 0.336 vt 0.181 0.432 0.334 vt 0.184 0.450 0.331 vt 0.142 0.416 0.339 vt 0.163 0.399 0.339 vt 0.200 0.432 0.331 vt 0.203 0.450 0.328 vt 0.176 0.404 0.337 vt 0.185 0.398 0.336 vt 0.189 0.377 0.341 vt 0.201 0.371 0.342 vt 0.171 0.383 0.340 vt 0.149 0.359 0.345 vt 0.168 0.365 0.344 vt 0.129 0.383 0.342 vt 0.125 0.364 0.345 vt 0.090 0.293 0.352 vt 0.112 0.282 0.355 vt 0.216 0.448 0.327 vt 0.247 0.465 0.321 vt 0.216 0.464 0.323 vt 0.203 0.465 0.325 vt 0.268 0.497 0.314 vt 0.283 0.485 0.316 vt 0.236 0.501 0.318 vt 0.249 0.504 0.315 vt 0.280 0.457 0.323 vt 0.292 0.474 0.319 vt 0.261 0.517 0.312 vt 0.272 0.513 0.311 vt 0.292 0.498 0.312 vt 0.284 0.506 0.311 vt 0.245 0.518 0.313 vt 0.236 0.514 0.315 vt 0.301 0.485 0.315 vt 0.297 0.491 0.313 vt 0.233 0.538 0.310 vt 0.228 0.535 0.311 vt 0.231 0.544 0.309 vt 0.225 0.541 0.310 vt 0.225 0.553 0.308 vt 0.220 0.550 0.308 vt 0.219 0.565 0.306 vt 0.212 0.562 0.307 vt 0.205 0.493 0.322 vt 0.198 0.487 0.324 vt 0.216 0.542 0.313 vt 0.222 0.525 0.318 vt 0.205 0.560 0.312 vt 0.203 0.571 0.306 vt 0.198 0.570 0.309 vt 0.204 0.580 0.303 vt 0.210 0.570 0.304 vt 0.213 0.576 0.305 vt 0.208 0.585 0.309 vt 0.199 0.579 0.307 vt 0.198 0.590 0.309 vt 0.202 0.591 0.311 vt 0.196 0.588 0.310 vt 0.189 0.479 0.327 vt 0.192 0.466 0.328 vt 0.413 0.279 0.257 vt 0.421 0.232 0.257 vt 0.420 0.203 0.257 vt 0.211 0.163 0.451 vt 0.209 0.165 0.460 vt 0.218 0.150 0.456 vt 0.260 0.159 0.467 vt 0.251 0.154 0.471 vt 0.273 0.164 0.459 vt 0.265 0.164 0.464 vt 0.234 0.187 0.439 vt 0.208 0.187 0.428 vt 0.225 0.178 0.447 vt 0.236 0.150 0.466 vt 0.243 0.152 0.467 vt 0.232 0.155 0.465 vt 0.229 0.149 0.464 vt 0.211 0.175 0.448 vt 0.222 0.170 0.456 vt 0.219 0.176 0.447 vt 0.270 0.189 0.433 vt 0.255 0.180 0.445 vt 0.261 0.177 0.452 vt 0.274 0.184 0.440 vt 0.235 0.549 0.311 vt 0.225 0.570 0.310 vt 0.217 0.580 0.310 vt 0.250 0.533 0.312 vt 0.192 0.569 0.313 vt 0.200 0.555 0.317 vt 0.230 0.573 0.316 vt 0.220 0.585 0.315 vt 0.990 0.300 -0.059 vt 0.991 0.318 -0.059 vt 0.982 0.319 -0.059 vt 0.979 0.302 -0.059 vt 0.992 0.329 -0.059 vt 0.984 0.330 -0.059 vt 0.991 0.339 -0.060 vt 0.988 0.340 -0.060 vt 0.976 0.280 -0.059 vt 0.988 0.278 -0.059 vt 0.971 0.257 -0.059 vt 0.986 0.256 -0.059 vt 0.242 0.556 0.316 vt 0.253 0.541 0.315 vt 0.213 0.520 0.322 vt 0.208 0.538 0.318 vt 0.196 0.503 0.322 vt 0.189 0.497 0.323 vt 0.191 0.508 0.322 vt 0.185 0.501 0.323 vt 0.186 0.513 0.322 vt 0.179 0.505 0.323 vt 0.179 0.497 0.325 vt 0.166 0.512 0.324 vt 0.160 0.508 0.327 vt 0.163 0.525 0.324 vt 0.173 0.514 0.322 vt 0.175 0.521 0.323 vt 0.167 0.529 0.325 vt 0.159 0.519 0.325 vt 0.155 0.532 0.325 vt 0.156 0.535 0.327 vt 0.151 0.529 0.327 vt 0.195 0.515 0.323 vt 0.179 0.526 0.325 vt 0.211 0.505 0.322 vt 0.155 0.501 0.329 vt 0.170 0.493 0.328 vt 0.197 0.522 0.326 vt 0.183 0.533 0.328 vt 0.940 0.076 -0.059 vt 0.959 0.078 -0.059 vt 0.958 0.089 -0.059 vt 0.939 0.088 -0.059 vt 0.966 0.079 -0.060 vt 0.965 0.089 -0.060 vt 0.976 0.079 -0.060 vt 0.972 0.092 -0.060 vt 0.987 0.086 -0.063 vt 0.986 0.093 -0.064 vt 0.925 0.090 -0.059 vt 0.922 0.076 -0.059 vt 0.210 0.519 0.325 vt 0.172 0.480 0.330 vt 0.225 0.507 0.320 vt 0.977 0.223 -0.059 vt 0.960 0.205 -0.059 vt 0.977 0.199 -0.059 vt 0.989 0.207 -0.059 vt 0.221 0.509 0.324 vt 0.990 0.237 -0.059 vt 0.277 0.540 0.307 vt 0.270 0.543 0.307 vt 0.280 0.549 0.305 vt 0.273 0.551 0.305 vt 0.283 0.557 0.304 vt 0.275 0.562 0.304 vt 0.287 0.574 0.301 vt 0.280 0.576 0.302 vt 0.266 0.557 0.308 vt 0.256 0.532 0.312 vt 0.275 0.578 0.305 vt 0.281 0.589 0.297 vt 0.276 0.591 0.304 vt 0.289 0.595 0.286 vt 0.285 0.583 0.295 vt 0.292 0.585 0.297 vt 0.296 0.596 0.297 vt 0.284 0.599 0.297 vt 0.293 0.605 0.292 vt 0.297 0.604 0.300 vt 0.288 0.606 0.299 vt 0.287 0.549 0.307 vt 0.295 0.570 0.306 vt 0.298 0.585 0.303 vt 0.285 0.520 0.310 vt 0.272 0.596 0.309 vt 0.268 0.579 0.312 vt 0.302 0.568 0.312 vt 0.304 0.586 0.309 vt 0.955 0.307 -0.059 vt 0.948 0.325 -0.059 vt 0.938 0.322 -0.059 vt 0.943 0.302 -0.059 vt 0.945 0.335 -0.059 vt 0.937 0.332 -0.059 vt 0.939 0.343 -0.059 vt 0.935 0.341 -0.059 vt 0.949 0.279 -0.059 vt 0.962 0.282 -0.059 vt 0.953 0.248 -0.059 vt 0.296 0.548 0.313 vt 0.294 0.526 0.313 vt 0.259 0.559 0.313 vt 0.311 0.515 0.307 vt 0.306 0.520 0.307 vt 0.315 0.517 0.306 vt 0.311 0.523 0.306 vt 0.323 0.524 0.304 vt 0.319 0.529 0.304 vt 0.333 0.531 0.303 vt 0.330 0.535 0.302 vt 0.310 0.532 0.308 vt 0.290 0.518 0.310 vt 0.327 0.542 0.306 vt 0.337 0.543 0.300 vt 0.337 0.548 0.306 vt 0.346 0.541 0.297 vt 0.337 0.536 0.299 vt 0.342 0.534 0.301 vt 0.351 0.539 0.299 vt 0.344 0.547 0.302 vt 0.322 0.517 0.308 vt 0.339 0.526 0.307 vt 0.346 0.531 0.305 vt 0.308 0.498 0.313 vt 0.335 0.553 0.312 vt 0.322 0.546 0.312 vt 0.340 0.517 0.313 vt 0.351 0.529 0.309 vt 0.932 0.243 -0.059 vt 0.927 0.260 -0.059 vt 0.917 0.257 -0.059 vt 0.923 0.240 -0.059 vt 0.924 0.270 -0.059 vt 0.914 0.267 -0.059 vt 0.927 0.219 -0.059 vt 0.939 0.224 -0.059 vt 0.930 0.194 -0.059 vt 0.950 0.203 -0.059 vt 0.326 0.509 0.314 vt 0.313 0.498 0.315 vt 0.306 0.537 0.313 vt 0.917 0.159 -0.059 vt 0.918 0.137 -0.059 vt 0.954 0.131 -0.059 vt 0.953 0.158 -0.059 vt 0.293 0.453 0.326 vt 0.301 0.463 0.324 vt 0.490 0.357 0.257 vt 0.515 0.310 0.257 vt 0.316 0.486 0.313 vt 0.316 0.491 0.312 vt 0.325 0.486 0.311 vt 0.325 0.491 0.311 vt 0.331 0.484 0.310 vt 0.332 0.489 0.310 vt 0.339 0.484 0.310 vt 0.340 0.489 0.310 vt 0.323 0.496 0.313 vt 0.310 0.496 0.313 vt 0.340 0.494 0.313 vt 0.348 0.489 0.310 vt 0.350 0.493 0.314 vt 0.356 0.484 0.310 vt 0.344 0.486 0.309 vt 0.348 0.480 0.311 vt 0.356 0.481 0.310 vt 0.355 0.489 0.313 vt 0.323 0.478 0.316 vt 0.339 0.476 0.315 vt 0.348 0.477 0.314 vt 0.306 0.478 0.318 vt 0.351 0.497 0.318 vt 0.339 0.498 0.317 vt 0.339 0.471 0.319 vt 0.350 0.472 0.319 vt 0.907 0.217 -0.059 vt 0.897 0.228 -0.059 vt 0.891 0.223 -0.059 vt 0.898 0.211 -0.059 vt 0.892 0.236 -0.059 vt 0.885 0.233 -0.059 vt 0.909 0.197 -0.059 vt 0.920 0.203 -0.059 vt 0.918 0.178 -0.059 vt 0.324 0.472 0.320 vt 0.310 0.470 0.322 vt 0.323 0.500 0.316 vt 0.176 0.085 0.401 vt 0.215 0.062 0.397 vt 0.153 0.089 0.396 vt 0.162 0.098 0.403 vt 0.145 0.098 0.397 vt 0.142 0.089 0.391 vt 0.137 0.117 0.393 vt 0.108 0.087 0.373 vt 0.147 0.068 0.378 vt 0.166 0.059 0.379 vt 0.171 0.074 0.392 vt 0.141 0.078 0.384 vt 0.953 0.836 0.434 vt 0.972 0.813 0.434 vt 0.986 0.844 0.428 vt 0.934 0.863 0.427 vt 0.075 0.646 0.962 vt 0.074 0.608 0.962 vt 0.090 0.585 0.962 vt 0.101 0.665 0.963 vt 0.100 0.713 0.964 vt 0.089 0.720 0.963 vt 0.079 0.677 0.963 vt 0.101 0.745 0.969 vt 0.096 0.746 0.962 vt 0.063 0.684 0.962 vt 0.058 0.658 0.962 vt 0.079 0.725 0.963 vt 0.091 0.752 0.963 vt 0.053 0.625 0.962 vt 0.164 0.685 0.962 vt 0.150 0.699 0.962 vt 0.142 0.688 0.962 vt 0.147 0.671 0.962 vt 0.104 0.747 0.962 vt 0.110 0.728 0.964 vt 0.117 0.733 0.963 vt 0.108 0.750 0.963 vt 0.116 0.710 0.963 vt 0.125 0.721 0.963 vt 0.125 0.672 0.963 vt 0.133 0.639 0.962 vt 0.160 0.712 0.962 vt 0.134 0.738 0.962 vt 0.114 0.667 0.963 vt 0.105 0.715 0.963 vt 0.161 0.043 0.599 vt 0.176 0.031 0.599 vt 0.186 0.055 0.382 vt 0.821 0.154 0.598 vt 0.830 0.180 0.599 vt 0.837 0.187 0.599 vt 0.846 0.183 0.599 vt 0.824 0.224 0.601 vt 0.847 0.227 0.600 vt 0.830 0.192 0.600 vt 0.813 0.199 0.600 vt 0.879 0.119 0.598 vt 0.850 0.158 0.598 vt 0.888 0.188 0.599 vt 0.903 0.130 0.599 vt 0.851 0.081 0.598 vt 0.822 0.095 0.597 vt 0.771 0.186 0.601 vt 0.785 0.197 0.601 vt 0.795 0.191 0.600 vt 0.797 0.177 0.600 vt 0.822 0.187 0.600 vt 0.873 0.214 0.600 vt 0.812 0.166 0.599 vt 0.766 0.207 0.602 vt 0.755 0.198 0.602 vt 0.750 0.214 0.602 vt 0.745 0.203 0.602 vt 0.753 0.195 0.602 vt 0.740 0.196 0.602 vt 0.737 0.165 0.600 vt 0.737 0.188 0.602 vt 0.753 0.218 0.602 vt 0.766 0.212 0.602 vt 0.751 0.237 0.602 vt 0.767 0.231 0.602 vt 0.777 0.219 0.602 vt 0.769 0.259 0.602 vt 0.784 0.243 0.602 vt 0.798 0.225 0.601 vt 0.758 0.276 0.602 vt 0.884 0.834 0.418 vt 0.846 0.815 0.389 vt 0.881 0.797 0.403 vt 0.905 0.808 0.417 vt 0.832 0.274 0.601 vt 0.870 0.264 0.600 vt 0.807 0.309 0.601 vt 0.763 0.151 0.599 vt 0.790 0.152 0.598 vt 0.785 0.129 0.597 vt 0.760 0.125 0.597 vt 0.748 0.150 0.599 vt 0.765 0.185 0.601 vt 0.764 0.175 0.601 vt 0.769 0.171 0.600 vt 0.760 0.174 0.601 vt 0.757 0.185 0.606 vt 0.751 0.187 0.606 vt 0.750 0.160 0.600 vt 0.761 0.172 0.600 vt 0.737 0.158 0.599 vt 0.844 0.324 0.601 vt 0.891 0.292 0.600 vt 0.888 0.768 0.401 vt 0.910 0.771 0.408 vt 0.752 0.937 0.721 vt 0.801 0.920 0.721 vt 0.816 0.938 0.722 vt 0.759 0.960 0.721 vt 0.736 0.957 0.721 vt 0.731 0.939 0.720 vt 0.700 0.960 0.721 vt 0.644 0.938 0.720 vt 0.655 0.926 0.719 vt 0.709 0.931 0.720 vt 0.612 0.920 0.701 vt 0.606 0.925 0.711 vt 0.730 0.896 0.720 vt 0.777 0.879 0.721 vt 0.704 0.902 0.720 vt 0.611 0.917 0.708 vt 0.653 0.913 0.717 vt 0.188 0.806 0.906 vt 0.220 0.794 0.906 vt 0.241 0.834 0.906 vt 0.191 0.856 0.906 vt 0.185 0.773 0.907 vt 0.205 0.767 0.906 vt 0.151 0.854 0.906 vt 0.160 0.807 0.906 vt 0.167 0.777 0.909 vt 0.119 0.850 0.906 vt 0.135 0.806 0.906 vt 0.148 0.779 0.908 vt 0.099 0.841 0.906 vt 0.124 0.803 0.906 vt 0.195 0.746 0.906 vt 0.183 0.749 0.906 vt 0.174 0.743 0.905 vt 0.195 0.900 0.906 vt 0.148 0.876 0.906 vt 0.971 0.755 0.431 vt 0.954 0.793 0.436 vt 0.943 0.747 0.431 vt 0.976 0.691 0.417 vt 0.952 0.704 0.423 vt 0.778 0.337 0.601 vt 0.769 0.309 0.601 vt 0.756 0.316 0.601 vt 0.770 0.334 0.601 vt 0.111 0.890 0.906 vt 0.771 0.353 0.601 vt 0.774 0.363 0.601 vt 0.405 0.669 0.427 vt 0.381 0.665 0.434 vt 0.371 0.694 0.450 vt 0.381 0.708 0.450 vt 0.367 0.640 0.426 vt 0.364 0.678 0.447 vt 0.416 0.655 0.417 vt 0.397 0.634 0.413 vt 0.372 0.598 0.401 vt 0.385 0.617 0.409 vt 0.796 0.204 0.601 vt 0.777 0.208 0.602 vt 0.785 0.214 0.602 vt 0.755 0.850 0.721 vt 0.756 0.817 0.721 vt 0.790 0.811 0.722 vt 0.779 0.847 0.721 vt 0.894 0.935 0.722 vt 0.864 0.975 0.722 vt 0.828 0.951 0.722 vt 0.893 0.927 0.722 vt 0.685 0.872 0.720 vt 0.669 0.827 0.721 vt 0.685 0.818 0.721 vt 0.706 0.858 0.720 vt 0.785 0.851 0.722 vt 0.764 0.862 0.721 vt 0.743 0.867 0.721 vt 0.716 0.874 0.720 vt 0.733 0.854 0.721 vt 0.625 0.885 0.720 vt 0.662 0.857 0.721 vt 0.643 0.895 0.718 vt 0.610 0.909 0.717 vt 0.604 0.909 0.717 vt 0.692 0.883 0.720 vt 0.136 0.074 0.377 vt 0.138 0.067 0.371 vt 0.134 0.056 0.365 vt 0.143 0.055 0.370 vt 0.825 0.070 0.597 vt 0.804 0.081 0.597 vt 0.789 0.097 0.596 vt 0.761 0.093 0.595 vt 0.780 0.077 0.596 vt 0.762 0.073 0.595 vt 0.770 0.054 0.595 vt 0.754 0.051 0.595 vt 0.805 0.057 0.597 vt 0.796 0.043 0.597 vt 0.792 0.039 0.597 vt 0.784 0.060 0.596 vt 0.746 0.033 0.595 vt 0.772 0.044 0.596 vt 0.755 0.024 0.596 vt 0.944 0.389 0.506 vt 0.988 0.393 0.540 vt 0.982 0.369 0.536 vt 0.948 0.371 0.510 vt 0.887 0.372 0.457 vt 0.893 0.379 0.455 vt 0.909 0.408 0.477 vt 0.912 0.391 0.479 vt 0.904 0.406 0.472 vt 0.877 0.372 0.443 vt 0.879 0.381 0.440 vt 0.741 0.011 0.596 vt 0.214 0.421 0.330 vt 0.029 0.141 0.173 vt 0.024 0.143 0.173 vt 0.022 0.118 0.173 vt 0.027 0.110 0.173 vt 0.014 0.144 0.173 vt 0.014 0.118 0.173 vt 0.036 0.190 0.173 vt 0.014 0.186 0.173 vt 0.040 0.189 0.173 vt 0.064 0.218 0.173 vt 0.056 0.222 0.173 vt 0.014 0.225 0.173 vt 0.014 0.080 0.173 vt 0.021 0.080 0.173 vt 0.025 0.080 0.172 vt 0.014 0.024 0.117 vt 0.029 0.038 0.111 vt 0.014 0.260 0.173 vt 0.053 0.233 0.173 vt 0.050 0.252 0.173 vt 0.063 0.255 0.173 vt 0.064 0.268 0.173 vt 0.050 0.266 0.173 vt 0.057 0.289 0.173 vt 0.067 0.290 0.173 vt 0.014 0.412 0.173 vt 0.014 0.382 0.173 vt 0.042 0.377 0.173 vt 0.050 0.406 0.173 vt 0.062 0.313 0.173 vt 0.054 0.307 0.173 vt 0.056 0.296 0.173 vt 0.072 0.332 0.173 vt 0.059 0.339 0.173 vt 0.051 0.313 0.173 vt 0.047 0.286 0.173 vt 0.090 0.421 0.173 vt 0.105 0.426 0.173 vt 0.124 0.445 0.173 vt 0.116 0.454 0.173 vt 0.100 0.415 0.173 vt 0.105 0.412 0.173 vt 0.102 0.419 0.173 vt 0.126 0.433 0.173 vt 0.085 0.393 0.173 vt 0.077 0.377 0.173 vt 0.086 0.382 0.168 vt 0.093 0.372 0.173 vt 0.071 0.440 0.173 vt 0.014 0.441 0.173 vt 0.014 0.345 0.173 vt 0.077 0.359 0.173 vt 0.691 0.337 0.601 vt 0.700 0.334 0.601 vt 0.696 0.362 0.601 vt 0.698 0.353 0.601 vt 0.765 0.978 0.721 vt 0.740 0.975 0.721 vt 0.799 0.868 0.721 vt 0.597 0.747 -0.465 vt 0.611 0.783 -0.437 vt 0.638 0.776 -0.437 vt 0.621 0.733 -0.465 vt 0.648 0.761 -0.440 vt 0.644 0.754 -0.446 vt 0.645 0.778 -0.437 vt 0.579 0.752 -0.465 vt 0.590 0.787 -0.440 vt 0.542 0.754 -0.462 vt 0.556 0.791 -0.451 vt 0.643 0.715 -0.465 vt 0.634 0.678 -0.468 vt 0.606 0.693 -0.456 vt 0.593 0.685 -0.461 vt 0.571 0.695 -0.460 vt 0.572 0.710 -0.457 vt 0.563 0.668 -0.455 vt 0.553 0.670 -0.459 vt 0.561 0.686 -0.437 vt 0.566 0.684 -0.426 vt 0.554 0.695 -0.446 vt 0.547 0.707 -0.450 vt 0.541 0.682 -0.446 vt 0.525 0.688 -0.442 vt 0.576 0.668 -0.453 vt 0.569 0.652 -0.505 vt 0.556 0.654 -0.501 vt 0.603 0.655 -0.496 vt 0.595 0.649 -0.493 vt 0.585 0.658 -0.494 vt 0.586 0.664 -0.492 vt 0.577 0.651 -0.498 vt 0.586 0.642 -0.488 vt 0.582 0.634 -0.511 vt 0.570 0.634 -0.513 vt 0.577 0.645 -0.494 vt 0.557 0.631 -0.502 vt 0.563 0.651 -0.516 vt 0.533 0.670 -0.497 vt 0.521 0.674 -0.487 vt 0.588 0.624 -0.500 vt 0.597 0.626 -0.482 vt 0.609 0.620 -0.451 vt 0.564 0.611 -0.444 vt 0.454 0.857 -0.466 vt 0.485 0.886 -0.467 vt 0.497 0.846 -0.461 vt 0.462 0.834 -0.465 vt 0.525 0.846 -0.458 vt 0.563 0.844 -0.459 vt 0.518 0.777 -0.462 vt 0.645 0.790 -0.437 vt 0.636 0.805 -0.444 vt 0.643 0.805 -0.440 vt 0.640 0.813 -0.425 vt 0.644 0.817 -0.430 vt 0.650 0.809 -0.442 vt 0.653 0.790 -0.438 vt 0.657 0.776 -0.440 vt 0.654 0.769 -0.436 vt 0.467 0.802 -0.465 vt 0.498 0.818 -0.462 vt 0.499 0.775 -0.465 vt 0.470 0.774 -0.467 vt 0.651 0.753 -0.447 vt 0.661 0.741 -0.451 vt 0.517 0.713 -0.454 vt 0.512 0.735 -0.456 vt 0.544 0.728 -0.465 vt 0.499 0.707 -0.479 vt 0.386 0.562 -0.685 vt 0.388 0.597 -0.685 vt 0.411 0.596 -0.685 vt 0.424 0.552 -0.685 vt 0.431 0.768 -0.467 vt 0.423 0.813 -0.467 vt 0.441 0.742 -0.469 vt 0.456 0.760 -0.468 vt 0.460 0.745 -0.469 vt 0.449 0.721 -0.469 vt 0.408 0.746 -0.469 vt 0.413 0.734 -0.469 vt 0.667 0.706 -0.465 vt 0.670 0.722 -0.461 vt 0.430 0.709 -0.454 vt 0.397 0.522 -0.685 vt 0.395 0.491 -0.685 vt 0.387 0.496 -0.685 vt 0.389 0.523 -0.685 vt 0.389 0.442 -0.685 vt 0.367 0.448 -0.685 vt 0.384 0.469 -0.685 vt 0.409 0.461 -0.685 vt 0.457 0.478 -0.685 vt 0.468 0.464 -0.696 vt 0.453 0.440 -0.697 vt 0.437 0.450 -0.685 vt 0.445 0.513 -0.685 vt 0.477 0.499 -0.685 vt 0.425 0.499 -0.685 vt 0.495 0.484 -0.696 vt 0.510 0.452 -0.642 vt 0.497 0.445 -0.646 vt 0.462 0.528 -0.685 vt 0.423 0.527 -0.685 vt 0.474 0.542 -0.685 vt 0.445 0.562 -0.685 vt 0.367 0.420 -0.685 vt 0.334 0.432 -0.685 vt 0.351 0.404 -0.685 vt 0.323 0.418 -0.685 vt 0.422 0.427 -0.685 vt 0.395 0.403 -0.685 vt 0.474 0.760 -0.468 vt 0.493 0.756 -0.468 vt 0.379 0.470 -0.685 vt 0.448 0.419 -0.705 vt 0.447 0.388 -0.709 vt 0.480 0.420 -0.637 vt 0.485 0.401 -0.627 vt 0.478 0.587 -0.685 vt 0.496 0.568 -0.685 vt 0.486 0.600 -0.685 vt 0.515 0.584 -0.685 vt 0.395 0.801 -0.468 vt 0.678 0.800 -0.452 vt 0.688 0.779 -0.457 vt 0.660 0.758 -0.446 vt 0.706 0.767 -0.457 vt 0.467 0.627 -0.685 vt 0.487 0.631 -0.685 vt 0.501 0.611 -0.685 vt 0.538 0.562 -0.685 vt 0.528 0.603 -0.685 vt 0.550 0.583 -0.685 vt 0.513 0.398 -0.667 vt 0.496 0.414 -0.604 vt 0.502 0.418 -0.600 vt 0.523 0.406 -0.679 vt 0.521 0.549 -0.685 vt 0.508 0.511 -0.685 vt 0.486 0.431 -0.620 vt 0.506 0.432 -0.616 vt 0.527 0.421 -0.676 vt 0.545 0.559 -0.712 vt 0.551 0.566 -0.701 vt 0.583 0.550 -0.708 vt 0.584 0.532 -0.709 vt 0.612 0.550 -0.709 vt 0.594 0.551 -0.709 vt 0.589 0.564 -0.710 vt 0.598 0.562 -0.709 vt 0.598 0.537 -0.709 vt 0.611 0.577 -0.710 vt 0.617 0.570 -0.710 vt 0.619 0.561 -0.709 vt 0.610 0.570 -0.709 vt 0.589 0.577 -0.701 vt 0.629 0.566 -0.710 vt 0.632 0.565 -0.709 vt 0.632 0.555 -0.709 vt 0.625 0.558 -0.709 vt 0.620 0.536 -0.709 vt 0.576 0.387 -0.709 vt 0.574 0.413 -0.709 vt 0.603 0.416 -0.709 vt 0.605 0.396 -0.709 vt 0.570 0.439 -0.708 vt 0.609 0.439 -0.709 vt 0.572 0.467 -0.708 vt 0.620 0.466 -0.709 vt 0.572 0.490 -0.708 vt 0.623 0.493 -0.709 vt 0.538 0.492 -0.708 vt 0.531 0.463 -0.706 vt 0.623 0.515 -0.709 vt 0.555 0.509 -0.709 vt 0.627 0.419 -0.709 vt 0.647 0.429 -0.709 vt 0.524 0.437 -0.666 vt 0.521 0.356 -0.709 vt 0.554 0.364 -0.708 vt 0.661 0.511 -0.709 vt 0.662 0.494 -0.709 vt 0.680 0.507 -0.709 vt 0.681 0.501 -0.709 vt 0.752 0.685 -0.953 vt 0.746 0.673 -0.953 vt 0.731 0.679 -0.953 vt 0.738 0.692 -0.953 vt 0.742 0.665 -0.954 vt 0.726 0.671 -0.953 vt 0.737 0.654 -0.954 vt 0.721 0.659 -0.954 vt 0.733 0.642 -0.955 vt 0.716 0.649 -0.955 vt 0.720 0.620 -0.957 vt 0.710 0.605 -0.958 vt 0.705 0.612 -0.959 vt 0.711 0.625 -0.957 vt 0.703 0.601 -0.958 vt 0.700 0.603 -0.961 vt 0.699 0.629 -0.957 vt 0.694 0.612 -0.958 vt 0.695 0.604 -0.958 vt 0.713 0.676 -0.954 vt 0.698 0.655 -0.954 vt 0.756 0.664 -0.953 vt 0.749 0.652 -0.954 vt 0.665 0.524 -0.709 vt 0.681 0.514 -0.709 vt 0.766 0.677 -0.953 vt 0.694 0.494 -0.709 vt 0.684 0.487 -0.709 vt 0.717 0.692 -0.953 vt 0.766 0.647 -0.954 vt 0.748 0.630 -0.954 vt 0.733 0.611 -0.955 vt 0.722 0.614 -0.956 vt 0.778 0.662 -0.953 vt 0.695 0.631 -0.956 vt 0.690 0.637 -0.955 vt 0.674 0.640 -0.954 vt 0.678 0.661 -0.954 vt 0.762 0.619 -0.954 vt 0.747 0.602 -0.954 vt 0.733 0.598 -0.955 vt 0.720 0.599 -0.956 vt 0.677 0.627 -0.955 vt 0.686 0.617 -0.956 vt 0.711 0.598 -0.957 vt 0.718 0.610 -0.957 vt 0.688 0.610 -0.957 vt 0.695 0.626 -0.957 vt 0.696 0.597 -0.957 vt 0.414 0.480 -0.685 vt 0.360 0.450 -0.685 vt 0.331 0.436 -0.685 vt 0.652 0.454 -0.709 vt 0.682 0.679 -0.954 vt 0.698 0.676 -0.954 vt 0.773 0.634 -0.954 vt 0.679 0.699 -0.953 vt 0.695 0.697 -0.953 vt 0.788 0.651 -0.953 vt 0.793 0.639 -0.953 vt 0.861 0.723 -0.888 vt 0.848 0.731 -0.892 vt 0.863 0.747 -0.890 vt 0.883 0.735 -0.890 vt 0.855 0.720 -0.882 vt 0.845 0.726 -0.890 vt 0.848 0.713 -0.894 vt 0.840 0.719 -0.901 vt 0.844 0.708 -0.911 vt 0.833 0.714 -0.922 vt 0.826 0.685 -0.961 vt 0.816 0.672 -1.002 vt 0.810 0.676 -0.999 vt 0.820 0.689 -0.959 vt 0.813 0.691 -0.977 vt 0.801 0.679 -1.017 vt 0.831 0.733 -0.932 vt 0.823 0.719 -0.947 vt 0.855 0.694 -0.951 vt 0.835 0.680 -0.979 vt 0.864 0.716 -0.907 vt 0.859 0.711 -0.910 vt 0.869 0.703 -0.942 vt 0.808 0.696 -0.991 vt 0.794 0.706 -1.006 vt 0.809 0.722 -0.968 vt 0.862 0.685 -0.968 vt 0.848 0.669 -1.006 vt 0.825 0.666 -1.010 vt 0.816 0.666 -1.013 vt 0.824 0.676 -0.985 vt 0.796 0.678 -1.013 vt 0.795 0.684 -1.010 vt 0.803 0.685 -1.003 vt 0.817 0.738 -0.955 vt 0.876 0.697 -0.955 vt 0.668 0.471 -0.709 vt 0.691 0.461 -0.709 vt 0.672 0.442 -0.708 vt 0.848 0.762 -0.935 vt 0.629 0.397 -0.709 vt 0.644 0.401 -0.709 vt 0.741 0.427 -0.750 vt 0.721 0.422 -0.704 vt 0.718 0.446 -0.708 vt 0.741 0.443 -0.728 vt 0.746 0.415 -0.734 vt 0.733 0.401 -0.694 vt 0.702 0.418 -0.714 vt 0.699 0.454 -0.709 vt 0.711 0.392 -0.725 vt 0.675 0.413 -0.707 vt 0.679 0.396 -0.703 vt 0.840 0.774 -0.966 vt 0.817 0.772 -0.983 vt 0.659 0.538 -0.709 vt 0.648 0.573 -0.709 vt 0.651 0.559 -0.709 vt 0.693 0.558 -0.709 vt 0.684 0.544 -0.709 vt 0.668 0.560 -0.709 vt 0.679 0.577 -0.709 vt 0.686 0.533 -0.709 vt 0.685 0.525 -0.709 vt 0.913 0.704 -0.983 vt 0.887 0.717 -0.934 vt 0.628 0.574 -0.709 vt 0.623 0.597 -0.709 vt 0.610 0.598 -0.709 vt 0.591 0.597 -0.711 vt 0.711 0.753 -0.884 vt 0.723 0.763 -0.883 vt 0.736 0.760 -0.893 vt 0.725 0.749 -0.889 vt 0.747 0.754 -0.900 vt 0.737 0.743 -0.895 vt 0.752 0.751 -0.914 vt 0.742 0.740 -0.909 vt 0.788 0.725 -1.001 vt 0.786 0.720 -1.007 vt 0.769 0.729 -0.962 vt 0.774 0.734 -0.957 vt 0.780 0.738 -0.972 vt 0.794 0.729 -1.014 vt 0.747 0.772 -0.931 vt 0.762 0.763 -0.952 vt 0.762 0.715 -0.999 vt 0.734 0.726 -0.947 vt 0.724 0.741 -0.908 vt 0.726 0.729 -0.939 vt 0.785 0.751 -0.999 vt 0.771 0.773 -0.970 vt 0.790 0.765 -1.007 vt 0.751 0.704 -1.007 vt 0.734 0.713 -0.970 vt 0.779 0.713 -1.005 vt 0.773 0.720 -0.989 vt 0.787 0.716 -1.012 vt 0.787 0.741 -0.991 vt 0.798 0.739 -1.005 vt 0.799 0.731 -1.012 vt 0.762 0.775 -0.961 vt 0.726 0.715 -0.961 vt 0.740 0.793 -0.968 vt 0.757 0.794 -0.975 vt 0.703 0.714 -0.975 vt 0.700 0.733 -0.937 vt 0.646 0.821 -0.443 vt 0.659 0.833 -0.454 vt 0.636 0.824 -0.446 vt 0.628 0.839 -0.451 vt 0.638 0.852 -0.457 vt 0.630 0.817 -0.442 vt 0.615 0.835 -0.450 vt 0.203 0.940 -0.291 vt 0.225 0.894 -0.291 vt 0.264 0.917 -0.291 vt 0.213 0.950 -0.291 vt 0.238 0.881 -0.291 vt 0.281 0.893 -0.291 vt 0.255 0.859 -0.291 vt 0.291 0.865 -0.291 vt 0.261 0.832 -0.291 vt 0.289 0.825 -0.291 vt 0.236 0.767 -0.291 vt 0.268 0.756 -0.291 vt 0.203 0.715 -0.291 vt 0.226 0.700 -0.291 vt 0.165 0.659 -0.292 vt 0.183 0.647 -0.292 vt 0.126 0.574 -0.292 vt 0.146 0.581 -0.292 vt 0.116 0.525 -0.292 vt 0.121 0.528 -0.292 vt 0.314 0.767 -0.291 vt 0.328 0.815 -0.291 vt 0.249 0.684 -0.291 vt 0.295 0.734 -0.291 vt 0.201 0.637 -0.292 vt 0.158 0.579 -0.292 vt 0.123 0.522 -0.292 vt 0.322 0.855 -0.291 vt 0.363 0.821 -0.291 vt 0.338 0.844 -0.290 vt 0.340 0.851 -0.290 vt 0.330 0.862 -0.290 vt 0.330 0.878 -0.290 vt 0.319 0.881 -0.290 vt 0.325 0.888 -0.290 vt 0.320 0.900 -0.291 vt 0.342 0.894 -0.290 vt 0.333 0.900 -0.290 vt 0.353 0.802 -0.291 vt 0.364 0.783 -0.291 vt 0.368 0.783 -0.285 vt 0.368 0.799 -0.290 vt 0.340 0.792 -0.291 vt 0.355 0.777 -0.291 vt 0.369 0.773 -0.291 vt 0.377 0.783 -0.291 vt 0.374 0.796 -0.291 vt 0.381 0.805 -0.291 vt 0.368 0.782 -0.284 vt 0.314 0.932 -0.291 vt 0.364 0.837 -0.290 vt 0.374 0.850 -0.290 vt 0.349 0.852 -0.290 vt 0.376 0.877 -0.290 vt 0.380 0.880 -0.290 vt 0.374 0.890 -0.290 vt 0.370 0.877 -0.290 vt 0.343 0.876 -0.290 vt 0.373 0.840 -0.290 vt 0.389 0.841 -0.290 vt 0.385 0.850 -0.290 vt 0.379 0.858 -0.290 vt 0.385 0.871 -0.290 vt 0.345 0.913 -0.290 vt 0.398 0.846 -0.291 vt 0.404 0.867 -0.291 vt 0.385 0.891 -0.290 vt 0.409 0.889 -0.291 vt 0.411 0.901 -0.291 vt 0.386 0.908 -0.290 vt 0.262 0.675 -0.291 vt 0.315 0.721 -0.291 vt 0.211 0.632 -0.292 vt 0.163 0.577 -0.292 vt 0.335 0.781 -0.291 vt 0.347 0.772 -0.291 vt 0.372 0.918 -0.290 vt 0.372 0.939 -0.290 vt 0.335 0.938 -0.291 vt 0.381 0.927 -0.292 vt 0.385 0.932 -0.287 vt 0.419 0.914 -0.291 vt 0.392 0.922 -0.290 vt 0.564 0.899 -0.417 vt 0.556 0.895 -0.436 vt 0.534 0.892 -0.435 vt 0.540 0.908 -0.399 vt 0.545 0.910 -0.381 vt 0.535 0.915 -0.422 vt 0.524 0.931 -0.385 vt 0.533 0.931 -0.422 vt 0.553 0.926 -0.441 vt 0.601 0.873 -0.460 vt 0.606 0.880 -0.452 vt 0.612 0.875 -0.459 vt 0.605 0.872 -0.459 vt 0.379 0.374 0.257 vt 0.395 0.331 0.257 vt 0.417 0.331 0.257 vt 0.397 0.365 0.257 vt 0.357 0.348 0.257 vt 0.369 0.339 0.257 vt 0.432 0.356 0.257 vt 0.416 0.362 0.257 vt 0.118 0.199 0.365 vt 0.098 0.201 0.360 vt 0.133 0.232 0.365 vt 0.138 0.210 0.372 vt 0.390 0.287 0.257 vt 0.374 0.298 0.257 vt 0.379 0.242 0.257 vt 0.399 0.237 0.257 vt 0.364 0.236 0.257 vt 0.375 0.199 0.257 vt 0.392 0.203 0.257 vt 0.393 0.185 0.257 vt 0.379 0.181 0.257 vt 0.519 0.123 0.194 vt 0.531 0.162 0.263 vt 0.498 0.157 0.248 vt 0.504 0.133 0.211 vt 0.438 0.941 -0.291 vt 0.413 0.942 -0.291 vt 0.384 0.962 -0.291 vt 0.395 0.939 -0.294 vt 0.412 0.962 -0.291 vt 0.395 0.986 -0.291 vt 0.376 0.973 -0.291 vt 0.498 0.055 0.095 vt 0.521 0.069 0.118 vt 0.506 0.088 0.158 vt 0.491 0.083 0.156 vt 0.370 0.379 0.257 vt 0.355 0.382 0.257 vt 0.466 0.318 0.257 vt 0.470 0.350 0.257 vt 0.544 0.158 0.263 vt 0.562 0.190 0.346 vt 0.548 0.208 0.346 vt 0.573 0.203 0.382 vt 0.569 0.217 0.399 vt 0.803 0.618 0.349 vt 0.817 0.623 0.386 vt 0.809 0.631 0.373 vt 0.802 0.627 0.353 vt 0.786 0.610 0.318 vt 0.835 0.588 0.402 vt 0.838 0.598 0.408 vt 0.846 0.608 0.435 vt 0.890 0.638 0.432 vt 0.911 0.586 0.497 vt 0.920 0.588 0.479 vt 0.911 0.637 0.402 vt 0.882 0.567 0.479 vt 0.887 0.576 0.499 vt 0.916 0.572 0.508 vt 0.925 0.574 0.493 vt 0.896 0.558 0.493 vt 0.900 0.564 0.511 vt 0.918 0.564 0.514 vt 0.925 0.564 0.500 vt 0.911 0.558 0.517 vt 0.907 0.552 0.500 vt 0.877 0.626 0.476 vt 0.902 0.583 0.521 vt 0.895 0.580 0.522 vt 0.853 0.614 0.458 vt 0.909 0.569 0.526 vt 0.914 0.561 0.527 vt 0.905 0.567 0.526 vt 0.865 0.619 0.481 vt 0.858 0.642 0.476 vt 0.828 0.632 0.426 vt 0.870 0.675 0.399 vt 0.858 0.656 0.452 vt 0.936 0.481 0.530 vt 0.936 0.499 0.553 vt 0.913 0.530 0.614 vt 0.900 0.508 0.615 vt 0.867 0.503 0.683 vt 0.902 0.477 0.613 vt 0.797 0.433 0.635 vt 0.778 0.485 0.697 vt 0.760 0.479 0.665 vt 0.770 0.443 0.614 vt 0.813 0.454 0.703 vt 0.799 0.492 0.741 vt 0.847 0.519 0.718 vt 0.830 0.513 0.759 vt 0.855 0.482 0.715 vt 0.829 0.478 0.733 vt 0.819 0.504 0.759 vt 0.872 0.434 0.726 vt 0.846 0.450 0.726 vt 0.821 0.436 0.685 vt 0.868 0.411 0.712 vt 0.821 0.456 0.726 vt 0.840 0.463 0.736 vt 0.831 0.472 0.761 vt 0.867 0.459 0.704 vt 0.843 0.479 0.726 vt 0.878 0.473 0.678 vt 0.319 0.117 0.426 vt 0.328 0.119 0.417 vt 0.337 0.110 0.409 vt 0.330 0.095 0.408 vt 0.858 0.530 0.687 vt 0.765 0.522 0.759 vt 0.753 0.522 0.747 vt 0.824 0.558 0.757 vt 0.808 0.551 0.799 vt 0.783 0.530 0.806 vt 0.805 0.543 0.814 vt 0.796 0.539 0.826 vt 0.875 0.545 0.665 vt 0.831 0.568 0.747 vt 0.805 0.583 0.799 vt 0.795 0.572 0.815 vt 0.766 0.559 0.843 vt 0.755 0.549 0.799 vt 0.784 0.565 0.850 vt 0.775 0.562 0.861 vt 0.756 0.582 0.841 vt 0.750 0.584 0.830 vt 0.769 0.593 0.830 vt 0.767 0.589 0.841 vt 0.762 0.582 0.856 vt 0.810 0.388 0.581 vt 0.782 0.420 0.591 vt 0.798 0.378 0.543 vt 0.961 0.985 0.382 vt 0.972 0.944 0.444 vt 0.959 0.938 0.454 vt 0.947 0.980 0.399 vt 0.918 0.921 0.543 vt 0.941 0.918 0.522 vt 0.933 0.899 0.550 vt 0.908 0.902 0.575 vt 0.928 0.961 0.452 vt 0.923 0.942 0.497 vt 0.977 0.906 0.501 vt 0.973 0.905 0.505 vt 0.967 0.898 0.528 vt 0.965 0.892 0.538 vt 0.293 0.111 0.446 vt 0.290 0.118 0.449 vt 0.303 0.115 0.440 vt 0.304 0.108 0.435 vt 0.282 0.106 0.451 vt 0.277 0.108 0.452 vt 0.947 0.645 0.476 vt 0.932 0.645 0.497 vt 0.953 0.621 0.516 vt 0.960 0.631 0.484 vt 0.845 0.391 0.653 vt 0.267 0.092 0.439 vt 0.267 0.100 0.447 vt 0.278 0.102 0.449 vt 0.292 0.099 0.441 vt 0.299 0.045 0.396 vt 0.269 0.058 0.420 vt 0.279 0.070 0.423 vt 0.307 0.058 0.404 vt 0.288 0.029 0.389 vt 0.277 0.011 0.381 vt 0.257 0.025 0.395 vt 0.266 0.039 0.406 vt 0.251 0.125 0.456 vt 0.243 0.124 0.453 vt 0.256 0.138 0.459 vt 0.263 0.135 0.458 vt 0.230 0.042 0.396 vt 0.234 0.058 0.410 vt 0.256 0.045 0.457 vt 0.255 0.047 0.442 vt 0.257 0.085 0.433 vt 0.223 0.076 0.415 vt 0.231 0.101 0.436 vt 0.257 0.098 0.443 vt 0.190 0.114 0.418 vt 0.181 0.094 0.409 vt 0.209 0.129 0.436 vt 0.229 0.128 0.449 vt 0.210 0.144 0.444 vt 0.228 0.141 0.458 vt 0.266 0.150 0.460 vt 0.265 0.144 0.457 vt 0.244 0.144 0.463 vt 0.284 0.252 0.376 vt 0.289 0.230 0.388 vt 0.258 0.236 0.390 vt 0.251 0.260 0.377 vt 0.250 0.284 0.365 vt 0.280 0.276 0.366 vt 0.212 0.270 0.374 vt 0.223 0.288 0.364 vt 0.255 0.308 0.356 vt 0.279 0.290 0.360 vt 0.223 0.310 0.356 vt 0.199 0.303 0.359 vt 0.185 0.262 0.371 vt 0.165 0.278 0.364 vt 0.177 0.311 0.356 vt 0.186 0.346 0.348 vt 0.209 0.343 0.348 vt 0.267 0.205 0.416 vt 0.295 0.211 0.405 vt 0.240 0.197 0.422 vt 0.234 0.239 0.387 vt 0.205 0.202 0.409 vt 0.199 0.238 0.383 vt 0.235 0.351 0.345 vt 0.229 0.388 0.336 vt 0.251 0.386 0.336 vt 0.248 0.349 0.345 vt 0.216 0.364 0.343 vt 0.209 0.388 0.336 vt 0.197 0.355 0.345 vt 0.188 0.357 0.345 vt 0.269 0.410 0.332 vt 0.248 0.409 0.331 vt 0.255 0.433 0.326 vt 0.266 0.431 0.327 vt 0.260 0.447 0.324 vt 0.268 0.445 0.325 vt 0.261 0.453 0.323 vt 0.275 0.448 0.325 vt 0.267 0.381 0.336 vt 0.228 0.413 0.331 vt 0.286 0.352 0.343 vt 0.293 0.354 0.342 vt 0.295 0.345 0.345 vt 0.285 0.344 0.345 vt 0.280 0.372 0.338 vt 0.290 0.376 0.338 vt 0.286 0.331 0.348 vt 0.298 0.334 0.348 vt 0.304 0.315 0.354 vt 0.282 0.312 0.354 vt 0.274 0.431 0.329 vt 0.282 0.412 0.332 vt 0.241 0.445 0.325 vt 0.298 0.284 0.364 vt 0.310 0.258 0.374 vt 0.320 0.234 0.385 vt 0.329 0.212 0.396 vt 0.475 0.201 0.257 vt 0.481 0.203 0.257 vt 0.481 0.242 0.257 vt 0.465 0.241 0.257 vt 0.493 0.218 0.257 vt 0.488 0.201 0.257 vt 0.367 0.022 0.372 vt 0.375 0.047 0.398 vt 0.387 0.049 0.417 vt 0.384 0.023 0.393 vt 0.389 0.068 0.435 vt 0.392 0.072 0.442 vt 0.410 0.055 0.452 vt 0.384 0.069 0.427 vt 0.824 0.635 0.423 vt 0.816 0.627 0.389 vt 0.425 0.079 0.423 vt 0.415 0.072 0.437 vt 0.410 0.092 0.409 vt 0.424 0.101 0.389 vt 0.383 0.075 0.434 vt 0.396 0.078 0.434 vt 0.337 0.243 0.377 vt 0.351 0.217 0.382 vt 0.353 0.236 0.372 vt 0.360 0.258 0.369 vt 0.333 0.190 0.402 vt 0.315 0.180 0.422 vt 0.306 0.191 0.446 vt 0.968 0.585 0.515 vt 0.975 0.577 0.490 vt 0.985 0.588 0.499 vt 0.983 0.599 0.526 vt 0.958 0.563 0.479 vt 0.965 0.554 0.452 vt 0.982 0.628 0.475 vt 0.984 0.660 0.426 vt 0.971 0.550 0.437 vt 0.983 0.570 0.475 vt 0.974 0.542 0.423 vt 0.979 0.539 0.426 vt 0.972 0.599 0.532 vt 0.952 0.599 0.553 vt 0.948 0.581 0.530 vt 0.152 0.219 0.378 vt 0.153 0.202 0.383 vt 0.143 0.197 0.377 vt 0.147 0.283 0.360 vt 0.146 0.310 0.354 vt 0.151 0.329 0.350 vt 0.164 0.349 0.347 vt 0.151 0.247 0.367 vt 0.172 0.239 0.376 vt 0.114 0.323 0.351 vt 0.117 0.341 0.348 vt 0.320 0.341 0.346 vt 0.327 0.317 0.352 vt 0.318 0.294 0.360 vt 0.342 0.306 0.356 vt 0.334 0.262 0.369 vt 0.355 0.272 0.363 vt 0.318 0.362 0.342 vt 0.286 0.439 0.329 vt 0.291 0.425 0.332 vt 0.160 0.455 0.334 vt 0.184 0.450 0.331 vt 0.181 0.432 0.334 vt 0.162 0.440 0.336 vt 0.163 0.399 0.339 vt 0.142 0.416 0.339 vt 0.203 0.450 0.328 vt 0.200 0.432 0.331 vt 0.185 0.398 0.336 vt 0.176 0.404 0.337 vt 0.201 0.371 0.342 vt 0.189 0.377 0.341 vt 0.171 0.383 0.340 vt 0.168 0.365 0.344 vt 0.149 0.359 0.345 vt 0.129 0.383 0.342 vt 0.125 0.364 0.345 vt 0.112 0.282 0.355 vt 0.090 0.293 0.352 vt 0.216 0.448 0.327 vt 0.216 0.464 0.323 vt 0.247 0.465 0.321 vt 0.203 0.465 0.325 vt 0.268 0.497 0.314 vt 0.283 0.485 0.316 vt 0.236 0.501 0.318 vt 0.249 0.504 0.315 vt 0.280 0.457 0.323 vt 0.292 0.474 0.319 vt 0.261 0.517 0.312 vt 0.272 0.513 0.311 vt 0.284 0.506 0.311 vt 0.292 0.498 0.312 vt 0.236 0.514 0.315 vt 0.245 0.518 0.313 vt 0.297 0.491 0.313 vt 0.301 0.485 0.315 vt 0.228 0.535 0.311 vt 0.233 0.538 0.310 vt 0.225 0.541 0.310 vt 0.231 0.544 0.309 vt 0.220 0.550 0.308 vt 0.225 0.553 0.308 vt 0.212 0.562 0.307 vt 0.219 0.565 0.306 vt 0.198 0.487 0.324 vt 0.205 0.493 0.322 vt 0.222 0.525 0.318 vt 0.216 0.542 0.313 vt 0.205 0.560 0.312 vt 0.198 0.570 0.309 vt 0.203 0.571 0.306 vt 0.204 0.580 0.303 vt 0.208 0.585 0.309 vt 0.213 0.576 0.305 vt 0.210 0.570 0.304 vt 0.199 0.579 0.307 vt 0.198 0.590 0.309 vt 0.202 0.591 0.311 vt 0.196 0.588 0.310 vt 0.192 0.466 0.328 vt 0.189 0.479 0.327 vt 0.413 0.279 0.257 vt 0.421 0.232 0.257 vt 0.420 0.203 0.257 vt 0.211 0.163 0.451 vt 0.218 0.150 0.456 vt 0.209 0.165 0.460 vt 0.251 0.154 0.471 vt 0.260 0.159 0.467 vt 0.273 0.164 0.459 vt 0.265 0.164 0.464 vt 0.234 0.187 0.439 vt 0.225 0.178 0.447 vt 0.208 0.187 0.428 vt 0.236 0.150 0.466 vt 0.229 0.149 0.464 vt 0.232 0.155 0.465 vt 0.243 0.152 0.467 vt 0.219 0.176 0.447 vt 0.222 0.170 0.456 vt 0.211 0.175 0.448 vt 0.270 0.189 0.433 vt 0.274 0.184 0.440 vt 0.261 0.177 0.452 vt 0.255 0.180 0.445 vt 0.235 0.549 0.311 vt 0.225 0.570 0.310 vt 0.217 0.580 0.310 vt 0.250 0.533 0.312 vt 0.192 0.569 0.313 vt 0.200 0.555 0.317 vt 0.230 0.573 0.316 vt 0.220 0.585 0.315 vt 0.990 0.300 -0.059 vt 0.979 0.302 -0.059 vt 0.982 0.319 -0.059 vt 0.991 0.318 -0.059 vt 0.992 0.329 -0.059 vt 0.984 0.330 -0.059 vt 0.991 0.339 -0.060 vt 0.988 0.340 -0.060 vt 0.976 0.280 -0.059 vt 0.988 0.278 -0.059 vt 0.971 0.257 -0.059 vt 0.986 0.256 -0.059 vt 0.242 0.556 0.316 vt 0.253 0.541 0.315 vt 0.213 0.520 0.322 vt 0.208 0.538 0.318 vt 0.189 0.497 0.323 vt 0.196 0.503 0.322 vt 0.185 0.501 0.323 vt 0.191 0.508 0.322 vt 0.179 0.505 0.323 vt 0.186 0.513 0.322 vt 0.179 0.497 0.325 vt 0.160 0.508 0.327 vt 0.166 0.512 0.324 vt 0.163 0.525 0.324 vt 0.167 0.529 0.325 vt 0.175 0.521 0.323 vt 0.173 0.514 0.322 vt 0.159 0.519 0.325 vt 0.155 0.532 0.325 vt 0.156 0.535 0.327 vt 0.151 0.529 0.327 vt 0.195 0.515 0.323 vt 0.179 0.526 0.325 vt 0.211 0.505 0.322 vt 0.155 0.501 0.329 vt 0.170 0.493 0.328 vt 0.197 0.522 0.326 vt 0.183 0.533 0.328 vt 0.940 0.076 -0.059 vt 0.939 0.088 -0.059 vt 0.958 0.089 -0.059 vt 0.959 0.078 -0.059 vt 0.966 0.079 -0.060 vt 0.965 0.089 -0.060 vt 0.976 0.079 -0.060 vt 0.972 0.092 -0.060 vt 0.987 0.086 -0.063 vt 0.986 0.093 -0.064 vt 0.925 0.090 -0.059 vt 0.922 0.076 -0.059 vt 0.210 0.519 0.325 vt 0.172 0.480 0.330 vt 0.225 0.507 0.320 vt 0.977 0.223 -0.059 vt 0.989 0.207 -0.059 vt 0.977 0.199 -0.059 vt 0.960 0.205 -0.059 vt 0.221 0.509 0.324 vt 0.990 0.237 -0.059 vt 0.270 0.543 0.307 vt 0.277 0.540 0.307 vt 0.273 0.551 0.305 vt 0.280 0.549 0.305 vt 0.275 0.562 0.304 vt 0.283 0.557 0.304 vt 0.280 0.576 0.302 vt 0.287 0.574 0.301 vt 0.256 0.532 0.312 vt 0.266 0.557 0.308 vt 0.275 0.578 0.305 vt 0.276 0.591 0.304 vt 0.281 0.589 0.297 vt 0.289 0.595 0.286 vt 0.296 0.596 0.297 vt 0.292 0.585 0.297 vt 0.285 0.583 0.295 vt 0.284 0.599 0.297 vt 0.293 0.605 0.292 vt 0.297 0.604 0.300 vt 0.288 0.606 0.299 vt 0.287 0.549 0.307 vt 0.295 0.570 0.306 vt 0.298 0.585 0.303 vt 0.285 0.520 0.310 vt 0.268 0.579 0.312 vt 0.272 0.596 0.309 vt 0.302 0.568 0.312 vt 0.304 0.586 0.309 vt 0.955 0.307 -0.059 vt 0.943 0.302 -0.059 vt 0.938 0.322 -0.059 vt 0.948 0.325 -0.059 vt 0.945 0.335 -0.059 vt 0.937 0.332 -0.059 vt 0.939 0.343 -0.059 vt 0.935 0.341 -0.059 vt 0.949 0.279 -0.059 vt 0.962 0.282 -0.059 vt 0.953 0.248 -0.059 vt 0.296 0.548 0.313 vt 0.294 0.526 0.313 vt 0.259 0.559 0.313 vt 0.306 0.520 0.307 vt 0.311 0.515 0.307 vt 0.311 0.523 0.306 vt 0.315 0.517 0.306 vt 0.319 0.529 0.304 vt 0.323 0.524 0.304 vt 0.330 0.535 0.302 vt 0.333 0.531 0.303 vt 0.290 0.518 0.310 vt 0.310 0.532 0.308 vt 0.327 0.542 0.306 vt 0.337 0.548 0.306 vt 0.337 0.543 0.300 vt 0.346 0.541 0.297 vt 0.351 0.539 0.299 vt 0.342 0.534 0.301 vt 0.337 0.536 0.299 vt 0.344 0.547 0.302 vt 0.322 0.517 0.308 vt 0.339 0.526 0.307 vt 0.346 0.531 0.305 vt 0.308 0.498 0.313 vt 0.335 0.553 0.312 vt 0.322 0.546 0.312 vt 0.340 0.517 0.313 vt 0.351 0.529 0.309 vt 0.932 0.243 -0.059 vt 0.923 0.240 -0.059 vt 0.917 0.257 -0.059 vt 0.927 0.260 -0.059 vt 0.924 0.270 -0.059 vt 0.914 0.267 -0.059 vt 0.927 0.219 -0.059 vt 0.939 0.224 -0.059 vt 0.930 0.194 -0.059 vt 0.950 0.203 -0.059 vt 0.326 0.509 0.314 vt 0.313 0.498 0.315 vt 0.306 0.537 0.313 vt 0.917 0.159 -0.059 vt 0.953 0.158 -0.059 vt 0.954 0.131 -0.059 vt 0.918 0.137 -0.059 vt 0.293 0.453 0.326 vt 0.301 0.463 0.324 vt 0.515 0.310 0.257 vt 0.490 0.357 0.257 vt 0.316 0.491 0.312 vt 0.316 0.486 0.313 vt 0.325 0.491 0.311 vt 0.325 0.486 0.311 vt 0.332 0.489 0.310 vt 0.331 0.484 0.310 vt 0.340 0.489 0.310 vt 0.339 0.484 0.310 vt 0.310 0.496 0.313 vt 0.323 0.496 0.313 vt 0.340 0.494 0.313 vt 0.350 0.493 0.314 vt 0.348 0.489 0.310 vt 0.356 0.484 0.310 vt 0.356 0.481 0.310 vt 0.348 0.480 0.311 vt 0.344 0.486 0.309 vt 0.355 0.489 0.313 vt 0.323 0.478 0.316 vt 0.339 0.476 0.315 vt 0.348 0.477 0.314 vt 0.306 0.478 0.318 vt 0.351 0.497 0.318 vt 0.339 0.498 0.317 vt 0.339 0.471 0.319 vt 0.350 0.472 0.319 vt 0.907 0.217 -0.059 vt 0.898 0.211 -0.059 vt 0.891 0.223 -0.059 vt 0.897 0.228 -0.059 vt 0.892 0.236 -0.059 vt 0.885 0.233 -0.059 vt 0.909 0.197 -0.059 vt 0.920 0.203 -0.059 vt 0.918 0.178 -0.059 vt 0.324 0.472 0.320 vt 0.310 0.470 0.322 vt 0.323 0.500 0.316 vt 0.215 0.062 0.397 vt 0.176 0.085 0.401 vt 0.153 0.089 0.396 vt 0.142 0.089 0.391 vt 0.145 0.098 0.397 vt 0.162 0.098 0.403 vt 0.137 0.117 0.393 vt 0.108 0.087 0.373 vt 0.147 0.068 0.378 vt 0.141 0.078 0.384 vt 0.171 0.074 0.392 vt 0.166 0.059 0.379 vt 0.953 0.836 0.434 vt 0.934 0.863 0.427 vt 0.986 0.844 0.428 vt 0.972 0.813 0.434 vt 0.075 0.646 0.962 vt 0.101 0.665 0.963 vt 0.090 0.585 0.962 vt 0.074 0.608 0.962 vt 0.100 0.713 0.964 vt 0.079 0.677 0.963 vt 0.089 0.720 0.963 vt 0.096 0.746 0.962 vt 0.101 0.745 0.969 vt 0.063 0.684 0.962 vt 0.058 0.658 0.962 vt 0.079 0.725 0.963 vt 0.091 0.752 0.963 vt 0.053 0.625 0.962 vt 0.164 0.685 0.962 vt 0.147 0.671 0.962 vt 0.142 0.688 0.962 vt 0.150 0.699 0.962 vt 0.104 0.747 0.962 vt 0.108 0.750 0.963 vt 0.117 0.733 0.963 vt 0.110 0.728 0.964 vt 0.125 0.721 0.963 vt 0.116 0.710 0.963 vt 0.125 0.672 0.963 vt 0.133 0.639 0.962 vt 0.134 0.738 0.962 vt 0.160 0.712 0.962 vt 0.105 0.715 0.963 vt 0.114 0.667 0.963 vt 0.161 0.043 0.599 vt 0.186 0.055 0.382 vt 0.176 0.031 0.599 vt 0.884 0.834 0.418 vt 0.905 0.808 0.417 vt 0.881 0.797 0.403 vt 0.846 0.815 0.389 vt 0.888 0.768 0.401 vt 0.910 0.771 0.408 vt 0.752 0.937 0.721 vt 0.759 0.960 0.721 vt 0.816 0.938 0.722 vt 0.801 0.920 0.721 vt 0.736 0.957 0.721 vt 0.731 0.939 0.720 vt 0.700 0.960 0.721 vt 0.709 0.931 0.720 vt 0.655 0.926 0.719 vt 0.644 0.938 0.720 vt 0.612 0.920 0.701 vt 0.606 0.925 0.711 vt 0.777 0.879 0.721 vt 0.730 0.896 0.720 vt 0.704 0.902 0.720 vt 0.653 0.913 0.717 vt 0.611 0.917 0.708 vt 0.188 0.806 0.906 vt 0.191 0.856 0.906 vt 0.241 0.834 0.906 vt 0.220 0.794 0.906 vt 0.185 0.773 0.907 vt 0.205 0.767 0.906 vt 0.151 0.854 0.906 vt 0.160 0.807 0.906 vt 0.167 0.777 0.909 vt 0.119 0.850 0.906 vt 0.135 0.806 0.906 vt 0.148 0.779 0.908 vt 0.124 0.803 0.906 vt 0.099 0.841 0.906 vt 0.195 0.746 0.906 vt 0.183 0.749 0.906 vt 0.174 0.743 0.905 vt 0.195 0.900 0.906 vt 0.148 0.876 0.906 vt 0.971 0.755 0.431 vt 0.943 0.747 0.431 vt 0.954 0.793 0.436 vt 0.976 0.691 0.417 vt 0.952 0.704 0.423 vt 0.111 0.890 0.906 vt 0.755 0.850 0.721 vt 0.779 0.847 0.721 vt 0.790 0.811 0.722 vt 0.756 0.817 0.721 vt 0.894 0.935 0.722 vt 0.828 0.951 0.722 vt 0.864 0.975 0.722 vt 0.904 0.978 0.721 vt 0.685 0.872 0.720 vt 0.685 0.818 0.721 vt 0.669 0.827 0.721 vt 0.662 0.857 0.721 vt 0.764 0.862 0.721 vt 0.785 0.851 0.722 vt 0.743 0.867 0.721 vt 0.733 0.854 0.721 vt 0.706 0.858 0.720 vt 0.716 0.874 0.720 vt 0.625 0.885 0.720 vt 0.643 0.895 0.718 vt 0.610 0.909 0.717 vt 0.604 0.909 0.717 vt 0.692 0.883 0.720 vt 0.136 0.074 0.377 vt 0.138 0.067 0.371 vt 0.134 0.056 0.365 vt 0.143 0.055 0.370 vt 0.944 0.389 0.506 vt 0.948 0.371 0.510 vt 0.982 0.369 0.536 vt 0.988 0.393 0.540 vt 0.893 0.379 0.455 vt 0.887 0.372 0.457 vt 0.909 0.408 0.477 vt 0.904 0.406 0.472 vt 0.912 0.391 0.479 vt 0.877 0.372 0.443 vt 0.879 0.381 0.440 vt 0.214 0.421 0.330 vt 0.765 0.978 0.721 vt 0.740 0.975 0.721 vt 0.799 0.868 0.721 vt 0.619 0.182 0.599 vt 0.733 0.144 0.598 vt 0.723 0.176 0.596 vt 0.712 0.174 0.600 vt 0.563 0.337 0.616 vt 0.589 0.348 0.604 vt 0.562 0.075 0.607 vt 0.613 0.056 0.591 vt 0.637 0.035 0.604 vt 0.687 0.032 0.597 vt 0.734 0.006 0.596 vt 0.281 0.943 0.494 vt 0.351 0.673 0.445 vt 0.350 0.730 0.468 vt 0.351 0.694 0.455 vt 0.593 0.846 -0.455 vt 0.640 0.820 -0.420 vt 0.573 0.682 -0.408 vt 0.553 0.683 -0.421 vt 0.583 0.651 -0.475 vt 0.601 0.639 -0.491 vt 0.531 0.626 -0.447 vt 0.538 0.653 -0.511 vt 0.529 0.660 -0.506 vt 0.545 0.641 -0.514 vt 0.616 0.646 -0.504 vt 0.592 0.630 -0.504 vt 0.648 0.640 -0.468 vt 0.437 0.628 -0.685 vt 0.420 0.613 -0.685 vt 0.527 0.653 -0.492 vt 0.510 0.640 -0.443 vt 0.649 0.787 -0.420 vt 0.654 0.764 -0.418 vt 0.653 0.759 -0.433 vt 0.501 0.744 -0.468 vt 0.658 0.665 -0.468 vt 0.438 0.697 -0.491 vt 0.450 0.649 -0.685 vt 0.474 0.655 -0.685 vt 0.547 0.524 -0.709 vt 0.528 0.525 -0.708 vt 0.499 0.369 -0.697 vt 0.568 0.575 -0.720 vt 0.554 0.586 -0.723 vt 0.564 0.596 -0.696 vt 0.613 0.558 -0.709 vt 0.698 0.510 -0.709 vt 0.300 0.430 -0.685 vt 0.683 0.473 -0.709 vt 0.701 0.483 -0.709 vt 0.714 0.492 -0.709 vt 0.805 0.670 -1.024 vt 0.836 0.665 -1.013 vt 0.792 0.694 -1.013 vt 0.741 0.458 -0.752 vt 0.703 0.574 -0.710 vt 0.795 0.722 -1.024 vt 0.767 0.704 -1.015 vt 0.798 0.753 -1.015 vt 0.730 0.778 -0.915 vt 0.729 0.554 -0.937 vt 0.726 0.573 -0.831 vt 0.710 0.560 -0.852 vt 0.609 0.865 -0.458 vt 0.617 0.861 -0.457 vt 0.343 0.860 -0.290 vt 0.342 0.888 -0.290 vt 0.378 0.838 -0.290 vt 0.371 0.864 -0.290 vt 0.374 0.872 -0.291 vt 0.379 0.866 -0.246 vt 0.375 0.908 -0.290 vt 0.371 0.896 -0.290 vt 0.379 0.905 -0.290 vt 0.492 0.904 -0.459 vt 0.336 0.740 -0.291 vt 0.333 0.746 -0.291 vt 0.346 0.750 -0.291 vt 0.342 0.756 -0.291 vt 0.356 0.761 -0.291 vt 0.118 0.520 -0.292 vt 0.389 0.825 -0.291 vt 0.387 0.925 -0.262 vt 0.048 0.758 0.173 vt 0.054 0.734 0.173 vt 0.061 0.742 0.173 vt 0.640 0.862 -0.460 vt 0.059 0.979 0.173 vt 0.117 0.988 0.173 vt 0.061 0.959 0.173 vt 0.576 0.888 -0.406 vt 0.589 0.865 -0.461 vt 0.584 0.882 -0.410 vt 0.589 0.886 -0.402 vt 0.585 0.893 -0.415 vt 0.573 0.899 -0.388 vt 0.560 0.906 -0.441 vt 0.547 0.916 -0.399 vt 0.540 0.913 -0.377 vt 0.360 0.961 -0.290 vt 0.373 0.951 -0.256 vt 0.362 0.949 -0.295 vt 0.519 0.920 -0.431 vt 0.511 0.928 -0.430 vt 0.374 0.966 -0.291 vt 0.547 0.942 -0.405 vt 0.526 0.940 -0.403 vt 0.550 0.921 -0.418 vt 0.580 0.910 -0.445 vt 0.006 0.834 0.173 vt 0.077 0.888 0.183 vt 0.449 0.282 0.257 vt 0.479 0.051 0.100 vt 0.444 0.043 0.119 vt 0.432 0.255 0.257 vt 0.461 0.209 0.257 vt 0.449 0.205 0.257 vt 0.402 0.182 0.257 vt 0.390 0.164 0.257 vt 0.466 0.191 0.257 vt 0.483 0.175 0.298 vt 0.515 0.190 0.292 vt 0.420 0.181 0.257 vt 0.481 0.285 0.257 vt 0.457 0.189 0.257 vt 0.469 0.185 0.257 vt 0.434 0.178 0.257 vt 0.451 0.183 0.257 vt 0.520 0.211 0.318 vt 0.542 0.123 0.193 vt 0.551 0.080 0.107 vt 0.889 0.682 0.346 vt 0.916 0.688 0.318 vt 0.919 0.555 0.518 vt 0.993 0.520 0.543 vt 0.992 0.501 0.497 vt 0.942 0.525 0.591 vt 0.316 0.159 0.424 vt 0.318 0.136 0.427 vt 0.338 0.152 0.409 vt 0.335 0.167 0.406 vt 0.383 0.100 0.375 vt 0.356 0.108 0.394 vt 0.348 0.088 0.393 vt 0.339 0.128 0.404 vt 0.338 0.125 0.414 vt 0.757 0.592 0.841 vt 0.943 0.660 0.452 vt 0.973 0.893 0.530 vt 0.111 0.974 0.173 vt 0.006 0.974 0.173 vt 0.168 0.154 0.405 vt 0.178 0.161 0.411 vt 0.159 0.169 0.397 vt 0.121 0.975 0.173 vt 0.329 0.077 0.404 vt 0.298 0.083 0.425 vt 0.283 0.074 0.424 vt 0.260 0.064 0.448 vt 0.268 0.076 0.426 vt 0.300 0.140 0.439 vt 0.311 0.144 0.433 vt 0.956 0.501 0.544 vt 0.819 0.374 0.575 vt 0.266 0.050 0.414 vt 0.250 0.073 0.424 vt 0.253 0.060 0.417 vt 0.254 0.051 0.427 vt 0.255 0.035 0.419 vt 0.254 0.037 0.416 vt 0.241 0.028 0.395 vt 0.275 0.127 0.461 vt 0.270 0.119 0.459 vt 0.263 0.114 0.480 vt 0.261 0.106 0.451 vt 0.277 0.133 0.454 vt 0.249 0.114 0.452 vt 0.264 0.127 0.479 vt 0.260 0.125 0.465 vt 0.287 0.152 0.447 vt 0.184 0.152 0.421 vt 0.193 0.173 0.429 vt 0.182 0.174 0.411 vt 0.245 0.132 0.459 vt 0.300 0.171 0.432 vt 0.284 0.171 0.452 vt 0.281 0.163 0.460 vt 0.274 0.175 0.482 vt 0.250 0.185 0.436 vt 0.164 0.208 0.388 vt 0.270 0.356 0.342 vt 0.270 0.341 0.347 vt 0.297 0.296 0.359 vt 0.157 0.188 0.388 vt 0.144 0.175 0.386 vt 0.129 0.958 0.173 vt 0.494 0.243 0.257 vt 0.400 0.029 0.419 vt 0.350 0.036 0.373 vt 0.364 0.064 0.409 vt 0.352 0.052 0.389 vt 0.427 0.055 0.479 vt 0.973 0.619 0.494 vt 0.985 0.611 0.499 vt 0.940 0.614 0.544 vt 0.968 0.611 0.520 vt 0.507 0.282 0.257 vt 0.121 0.192 0.368 vt 0.134 0.253 0.361 vt 0.301 0.395 0.336 vt 0.186 0.473 0.330 vt 0.983 0.184 -0.059 vt 0.964 0.180 -0.059 vt 0.176 0.469 0.332 vt 0.217 0.164 0.460 vt 0.245 0.188 0.433 vt 0.251 0.161 0.472 vt 0.255 0.171 0.463 vt 0.244 0.168 0.464 vt 0.243 0.177 0.453 vt 0.244 0.162 0.481 vt 0.230 0.169 0.459 vt 0.227 0.172 0.460 vt 0.237 0.178 0.464 vt 0.228 0.165 0.461 vt 0.232 0.146 0.470 vt 0.236 0.146 0.465 vt 0.210 0.587 0.312 vt 0.196 0.578 0.310 vt 0.197 0.592 0.312 vt 0.990 0.344 -0.060 vt 0.176 0.535 0.328 vt 0.170 0.531 0.327 vt 0.157 0.518 0.327 vt 0.152 0.509 0.329 vt 0.152 0.534 0.327 vt 0.989 0.090 -0.058 vt 0.299 0.595 0.303 vt 0.281 0.600 0.302 vt 0.294 0.608 0.301 vt 0.935 0.346 -0.059 vt 0.358 0.551 0.309 vt 0.914 0.284 -0.059 vt 0.353 0.537 0.303 vt 0.344 0.550 0.307 vt 0.927 0.112 -0.059 vt 0.365 0.486 0.317 vt 0.883 0.245 -0.060 vt 0.357 0.480 0.312 vt 0.356 0.491 0.316 vt 0.991 0.220 -0.059 vt 0.220 0.056 0.399 vt 0.841 0.831 0.393 vt 0.829 0.813 0.379 vt 0.858 0.858 0.410 vt 0.468 0.690 0.962 vt 0.483 0.681 0.962 vt 0.478 0.704 0.962 vt 0.174 0.698 0.962 vt 0.112 0.757 0.963 vt 0.109 0.595 0.962 vt 0.123 0.601 0.962 vt 0.101 0.755 0.963 vt 0.745 0.176 0.596 vt 0.756 0.173 0.600 vt 0.905 0.338 0.601 vt 0.878 0.898 0.722 vt 0.855 0.884 0.722 vt 0.820 0.876 0.722 vt 0.218 0.872 0.906 vt 0.183 0.732 0.906 vt 0.086 0.812 0.906 vt 0.122 0.781 0.906 vt 0.146 0.755 0.906 vt 0.164 0.738 0.906 vt 0.146 0.923 0.906 vt 0.125 0.908 0.906 vt 0.917 0.743 0.428 vt 0.180 0.930 0.906 vt 0.879 0.349 0.601 vt 0.953 0.683 0.417 vt 0.955 0.673 0.413 vt 0.716 0.822 0.721 vt 0.811 0.978 0.722 vt 0.904 0.978 0.721 vt 0.604 0.916 0.715 vt 0.904 0.074 0.599 vt 0.853 0.056 0.598 vt 0.829 0.035 0.598 vt 0.779 0.031 0.597 vt 0.493 0.680 0.946 vt 0.940 0.431 0.494 vt 0.055 0.249 0.173 vt 0.062 0.225 0.173 vt 0.068 0.234 0.173 vt 0.067 0.471 0.173 vt 0.068 0.450 0.173 vt 0.124 0.480 0.173 vt 0.014 0.325 0.173 vt 0.085 0.380 0.183 vt 0.119 0.465 0.173 vt 0.014 0.465 0.173 vt 0.129 0.467 0.173 vt 0.136 0.449 0.173 vt 0.593 0.846 -0.455 vt 0.640 0.820 -0.420 vt 0.573 0.682 -0.408 vt 0.553 0.683 -0.421 vt 0.583 0.651 -0.475 vt 0.601 0.639 -0.491 vt 0.531 0.626 -0.447 vt 0.538 0.653 -0.511 vt 0.529 0.660 -0.506 vt 0.545 0.641 -0.514 vt 0.616 0.646 -0.504 vt 0.592 0.630 -0.504 vt 0.648 0.640 -0.468 vt 0.437 0.628 -0.685 vt 0.420 0.613 -0.685 vt 0.527 0.653 -0.492 vt 0.510 0.640 -0.443 vt 0.649 0.787 -0.420 vt 0.654 0.764 -0.418 vt 0.653 0.759 -0.433 vt 0.501 0.744 -0.468 vt 0.658 0.665 -0.468 vt 0.438 0.697 -0.491 vt 0.450 0.649 -0.685 vt 0.474 0.655 -0.685 vt 0.547 0.524 -0.709 vt 0.528 0.525 -0.708 vt 0.499 0.369 -0.697 vt 0.568 0.575 -0.720 vt 0.554 0.586 -0.723 vt 0.564 0.596 -0.696 vt 0.613 0.558 -0.709 vt 0.698 0.510 -0.709 vt 0.300 0.430 -0.685 vt 0.683 0.473 -0.709 vt 0.714 0.492 -0.709 vt 0.701 0.483 -0.709 vt 0.805 0.670 -1.024 vt 0.836 0.665 -1.013 vt 0.792 0.694 -1.013 vt 0.741 0.458 -0.752 vt 0.703 0.574 -0.710 vt 0.795 0.722 -1.024 vt 0.767 0.704 -1.015 vt 0.798 0.753 -1.015 vt 0.730 0.778 -0.915 vt 0.729 0.554 -0.937 vt 0.710 0.560 -0.852 vt 0.726 0.573 -0.831 vt 0.609 0.865 -0.458 vt 0.617 0.861 -0.457 vt 0.343 0.860 -0.290 vt 0.342 0.888 -0.290 vt 0.378 0.838 -0.290 vt 0.371 0.864 -0.290 vt 0.379 0.866 -0.246 vt 0.374 0.872 -0.291 vt 0.375 0.908 -0.290 vt 0.371 0.896 -0.290 vt 0.379 0.905 -0.290 vt 0.492 0.904 -0.459 vt 0.336 0.740 -0.291 vt 0.333 0.746 -0.291 vt 0.346 0.750 -0.291 vt 0.342 0.756 -0.291 vt 0.356 0.761 -0.291 vt 0.118 0.520 -0.292 vt 0.389 0.825 -0.291 vt 0.387 0.925 -0.262 vt 0.640 0.862 -0.460 vt 0.576 0.888 -0.406 vt 0.589 0.865 -0.461 vt 0.584 0.882 -0.410 vt 0.585 0.893 -0.415 vt 0.589 0.886 -0.402 vt 0.573 0.899 -0.388 vt 0.560 0.906 -0.441 vt 0.547 0.916 -0.399 vt 0.540 0.913 -0.377 vt 0.360 0.961 -0.290 vt 0.362 0.949 -0.295 vt 0.373 0.951 -0.256 vt 0.519 0.920 -0.431 vt 0.511 0.928 -0.430 vt 0.374 0.966 -0.291 vt 0.526 0.940 -0.403 vt 0.547 0.942 -0.405 vt 0.550 0.921 -0.418 vt 0.580 0.910 -0.445 vt 0.449 0.282 0.257 vt 0.479 0.051 0.100 vt 0.444 0.043 0.119 vt 0.432 0.255 0.257 vt 0.461 0.209 0.257 vt 0.449 0.205 0.257 vt 0.402 0.182 0.257 vt 0.390 0.164 0.257 vt 0.466 0.191 0.257 vt 0.483 0.175 0.298 vt 0.515 0.190 0.292 vt 0.420 0.181 0.257 vt 0.481 0.285 0.257 vt 0.457 0.189 0.257 vt 0.469 0.185 0.257 vt 0.434 0.178 0.257 vt 0.451 0.183 0.257 vt 0.520 0.211 0.318 vt 0.542 0.123 0.193 vt 0.551 0.080 0.107 vt 0.889 0.682 0.346 vt 0.916 0.688 0.318 vt 0.919 0.555 0.518 vt 0.993 0.520 0.543 vt 0.942 0.525 0.591 vt 0.992 0.501 0.497 vt 0.316 0.159 0.424 vt 0.338 0.152 0.409 vt 0.318 0.136 0.427 vt 0.335 0.167 0.406 vt 0.383 0.100 0.375 vt 0.348 0.088 0.393 vt 0.356 0.108 0.394 vt 0.338 0.125 0.414 vt 0.339 0.128 0.404 vt 0.757 0.592 0.841 vt 0.943 0.660 0.452 vt 0.973 0.893 0.530 vt 0.168 0.154 0.405 vt 0.159 0.169 0.397 vt 0.178 0.161 0.411 vt 0.329 0.077 0.404 vt 0.298 0.083 0.425 vt 0.283 0.074 0.424 vt 0.260 0.064 0.448 vt 0.268 0.076 0.426 vt 0.300 0.140 0.439 vt 0.311 0.144 0.433 vt 0.956 0.501 0.544 vt 0.819 0.374 0.575 vt 0.266 0.050 0.414 vt 0.250 0.073 0.424 vt 0.253 0.060 0.417 vt 0.254 0.051 0.427 vt 0.255 0.035 0.419 vt 0.254 0.037 0.416 vt 0.241 0.028 0.395 vt 0.270 0.119 0.459 vt 0.275 0.127 0.461 vt 0.263 0.114 0.480 vt 0.261 0.106 0.451 vt 0.277 0.133 0.454 vt 0.249 0.114 0.452 vt 0.264 0.127 0.479 vt 0.260 0.125 0.465 vt 0.287 0.152 0.447 vt 0.184 0.152 0.421 vt 0.193 0.173 0.429 vt 0.182 0.174 0.411 vt 0.245 0.132 0.459 vt 0.300 0.171 0.432 vt 0.284 0.171 0.452 vt 0.281 0.163 0.460 vt 0.274 0.175 0.482 vt 0.250 0.185 0.436 vt 0.164 0.208 0.388 vt 0.270 0.356 0.342 vt 0.270 0.341 0.347 vt 0.297 0.296 0.359 vt 0.157 0.188 0.388 vt 0.144 0.175 0.386 vt 0.494 0.243 0.257 vt 0.400 0.029 0.419 vt 0.350 0.036 0.373 vt 0.364 0.064 0.409 vt 0.352 0.052 0.389 vt 0.427 0.055 0.479 vt 0.985 0.611 0.499 vt 0.973 0.619 0.494 vt 0.940 0.614 0.544 vt 0.968 0.611 0.520 vt 0.507 0.282 0.257 vt 0.121 0.192 0.368 vt 0.134 0.253 0.361 vt 0.301 0.395 0.336 vt 0.186 0.473 0.330 vt 0.983 0.184 -0.059 vt 0.964 0.180 -0.059 vt 0.176 0.469 0.332 vt 0.217 0.164 0.460 vt 0.245 0.188 0.433 vt 0.251 0.161 0.472 vt 0.244 0.168 0.464 vt 0.255 0.171 0.463 vt 0.243 0.177 0.453 vt 0.244 0.162 0.481 vt 0.230 0.169 0.459 vt 0.227 0.172 0.460 vt 0.237 0.178 0.464 vt 0.228 0.165 0.461 vt 0.236 0.146 0.465 vt 0.232 0.146 0.470 vt 0.210 0.587 0.312 vt 0.196 0.578 0.310 vt 0.197 0.592 0.312 vt 0.990 0.344 -0.060 vt 0.176 0.535 0.328 vt 0.170 0.531 0.327 vt 0.157 0.518 0.327 vt 0.152 0.509 0.329 vt 0.152 0.534 0.327 vt 0.989 0.090 -0.058 vt 0.299 0.595 0.303 vt 0.281 0.600 0.302 vt 0.294 0.608 0.301 vt 0.935 0.346 -0.059 vt 0.358 0.551 0.309 vt 0.914 0.284 -0.059 vt 0.353 0.537 0.303 vt 0.344 0.550 0.307 vt 0.927 0.112 -0.059 vt 0.365 0.486 0.317 vt 0.883 0.245 -0.060 vt 0.357 0.480 0.312 vt 0.356 0.491 0.316 vt 0.991 0.220 -0.059 vt 0.220 0.056 0.399 vt 0.841 0.831 0.393 vt 0.829 0.813 0.379 vt 0.858 0.858 0.410 vt 0.468 0.690 0.962 vt 0.478 0.704 0.962 vt 0.483 0.681 0.962 vt 0.174 0.698 0.962 vt 0.112 0.757 0.963 vt 0.109 0.595 0.962 vt 0.123 0.601 0.962 vt 0.101 0.755 0.963 vt 0.878 0.898 0.722 vt 0.893 0.927 0.722 vt 0.855 0.884 0.722 vt 0.820 0.876 0.722 vt 0.218 0.872 0.906 vt 0.183 0.732 0.906 vt 0.086 0.812 0.906 vt 0.122 0.781 0.906 vt 0.146 0.755 0.906 vt 0.164 0.738 0.906 vt 0.125 0.908 0.906 vt 0.146 0.923 0.906 vt 0.917 0.743 0.428 vt 0.180 0.930 0.906 vt 0.955 0.673 0.413 vt 0.953 0.683 0.417 vt 0.716 0.822 0.721 vt 0.811 0.978 0.722 vt 0.604 0.916 0.715 vt 0.493 0.680 0.946 vt 0.940 0.431 0.494 # 3263 texture vertices vn 0.760 -0.649 0.033 vn 0.982 -0.127 0.139 vn 0.978 -0.195 -0.079 vn 0.740 -0.425 0.521 vn 0.924 -0.223 0.310 vn 0.963 -0.145 0.228 vn 0.830 -0.154 0.537 vn 0.718 -0.501 0.483 vn 0.563 0.011 0.826 vn 0.487 -0.038 0.872 vn 0.220 0.118 0.968 vn 0.355 0.055 0.933 vn 0.347 -0.199 0.916 vn 0.941 -0.019 -0.339 vn 0.968 -0.027 -0.251 vn 0.990 0.074 -0.116 vn 0.973 -0.011 0.231 vn 0.926 -0.053 0.374 vn 0.783 0.176 0.596 vn 0.798 0.109 0.592 vn 0.718 -0.257 0.646 vn 0.410 0.238 0.881 vn 0.418 0.124 0.900 vn 0.561 0.192 0.805 vn 0.677 0.407 0.614 vn 0.572 0.121 0.811 vn 0.479 0.413 0.775 vn 0.056 0.253 0.966 vn 0.070 -0.036 0.997 vn 0.233 -0.432 0.871 vn 0.207 -0.259 0.943 vn 0.476 -0.109 0.873 vn 0.118 0.100 0.988 vn -0.115 0.133 0.984 vn 0.094 -0.325 0.941 vn 0.667 -0.504 0.549 vn -0.310 0.255 0.916 vn 0.287 0.104 0.952 vn 0.810 -0.225 0.542 vn -0.172 0.397 0.901 vn 0.458 0.123 0.881 vn 0.654 -0.051 0.754 vn -0.188 0.392 0.901 vn -0.268 0.311 0.912 vn 0.293 0.239 0.926 vn 0.401 0.117 0.909 vn 0.055 0.424 0.904 vn 0.475 0.141 0.868 vn 0.114 -0.170 0.979 vn 0.619 -0.352 0.702 vn -0.300 -0.035 0.953 vn -0.006 -0.019 1.000 vn 0.321 -0.104 0.941 vn 0.152 -0.317 0.936 vn 0.191 -0.631 0.752 vn 0.365 0.080 0.928 vn -0.037 0.280 0.959 vn -0.101 0.072 0.992 vn -0.160 -0.184 0.970 vn -0.349 -0.486 0.801 vn 0.338 0.508 0.792 vn 0.374 0.621 0.689 vn 0.317 0.920 0.232 vn 0.761 0.631 0.151 vn -0.054 0.443 0.895 vn 0.639 -0.190 0.746 vn 0.371 -0.106 0.922 vn 0.557 -0.288 -0.779 vn 0.964 -0.251 0.091 vn 0.984 0.034 0.176 vn 0.737 -0.570 -0.364 vn 0.936 -0.122 0.329 vn 0.653 -0.556 0.514 vn 0.242 -0.799 0.551 vn 0.866 -0.263 0.426 vn 0.465 -0.602 0.650 vn 0.179 -0.803 0.569 vn 0.685 -0.704 -0.187 vn 0.599 -0.614 0.513 vn 0.123 -0.776 0.619 vn 0.918 -0.375 0.126 vn 0.731 0.062 -0.680 vn 0.606 -0.592 -0.532 vn 0.946 0.121 -0.301 vn 0.772 -0.611 -0.177 vn 0.816 0.071 -0.574 vn 0.848 -0.483 0.218 vn 0.195 -0.811 0.552 vn 0.920 -0.189 -0.343 vn 0.349 -0.682 -0.643 vn 0.503 -0.320 -0.803 vn 0.565 -0.384 -0.730 vn 0.046 0.040 -0.998 vn 0.510 -0.351 -0.785 vn 0.217 -0.525 -0.823 vn 0.282 -0.947 0.151 vn 0.888 0.390 -0.245 vn 0.814 0.524 -0.250 vn 0.108 -0.109 -0.988 vn 0.010 0.148 -0.989 vn -0.110 0.152 0.982 vn -0.177 0.366 0.913 vn 0.533 0.387 0.753 vn 0.510 0.578 0.637 vn -0.246 0.841 -0.482 vn -0.275 0.958 -0.084 vn -0.116 0.904 0.411 vn 0.000 0.451 0.893 vn -0.165 0.231 0.959 vn -0.256 0.654 0.712 vn 0.118 0.737 0.665 vn -0.106 0.203 0.973 vn 0.327 0.060 0.943 vn -0.164 0.318 0.934 vn 0.185 0.107 0.977 vn 0.090 0.361 0.928 vn -0.552 0.308 0.775 vn -0.638 0.446 0.627 vn -0.838 0.216 0.501 vn -0.297 0.215 0.930 vn -0.491 0.350 0.797 vn -0.663 0.301 0.686 vn -0.077 0.082 0.994 vn 0.116 0.881 0.459 vn -0.078 -0.036 0.996 vn 0.206 -0.039 0.978 vn 0.321 0.056 0.946 vn 0.741 -0.240 0.627 vn 0.726 -0.196 0.659 vn 0.508 0.244 0.826 vn 0.647 -0.292 0.704 vn -0.246 0.582 0.775 vn 0.011 0.107 0.994 vn 0.395 -0.145 0.907 vn -0.752 -0.300 0.588 vn 0.451 -0.532 0.717 vn -0.320 0.482 0.816 vn -0.806 0.309 0.505 vn -0.602 -0.614 0.511 vn -0.551 -0.627 0.550 vn -0.519 0.642 0.565 vn -0.268 0.165 0.949 vn -0.936 0.107 0.336 vn -0.718 0.204 0.666 vn -0.927 -0.040 0.372 vn -0.885 0.378 0.273 vn -0.697 0.219 0.683 vn -0.861 0.186 -0.473 vn 0.873 -0.079 0.481 vn 0.033 0.557 0.830 vn -0.744 0.039 0.667 vn 0.566 -0.760 0.320 vn -0.417 -0.808 0.417 vn -0.107 -0.049 0.993 vn 0.257 -0.940 0.223 vn 0.621 -0.556 0.553 vn -0.148 -0.639 0.755 vn -0.188 -0.217 0.958 vn 0.190 -0.931 0.311 vn -0.191 -0.951 0.245 vn 0.205 -0.974 0.092 vn -0.971 -0.112 0.213 vn -0.572 0.320 0.755 vn -0.677 -0.534 0.505 vn 0.810 -0.250 0.530 vn 0.266 -0.124 0.956 vn 0.449 -0.856 0.258 vn 0.592 -0.786 0.179 vn 0.892 0.192 0.410 vn 0.855 -0.512 0.083 vn -0.566 -0.817 0.110 vn -0.412 -0.131 -0.901 vn -0.850 -0.420 -0.319 vn -0.923 0.376 0.080 vn -0.865 -0.486 0.124 vn -0.829 -0.508 0.234 vn -0.503 -0.859 0.096 vn -0.771 0.070 0.633 vn 0.343 0.015 0.939 vn 0.313 0.538 0.783 vn 0.597 -0.000 0.802 vn 0.652 0.430 0.624 vn 0.910 0.206 0.360 vn 0.522 0.064 0.850 vn 0.735 0.360 0.574 vn 0.175 -0.315 -0.933 vn -0.543 -0.057 -0.838 vn -0.966 0.219 0.138 vn -0.865 0.038 -0.500 vn 0.003 -0.667 -0.745 vn -0.486 -0.352 -0.800 vn 0.341 0.722 0.602 vn 0.832 -0.177 0.525 vn 0.224 0.046 0.974 vn 0.587 -0.278 0.760 vn 0.445 0.026 0.895 vn 0.665 -0.173 0.727 vn -0.970 0.221 -0.106 vn -0.909 0.022 0.415 vn -0.987 -0.069 0.143 vn 0.002 -0.351 -0.936 vn 0.357 0.418 -0.835 vn 0.793 -0.448 -0.412 vn -0.004 -0.977 -0.215 vn 0.771 -0.436 -0.464 vn 0.940 -0.341 0.024 vn 0.941 -0.335 0.042 vn 0.884 -0.266 0.386 vn 0.929 -0.369 0.002 vn 0.934 -0.201 -0.296 vn -0.588 0.783 -0.204 vn 0.444 0.862 -0.246 vn 0.779 0.616 -0.119 vn -0.552 0.731 -0.402 vn 0.294 0.889 -0.350 vn -0.363 0.925 -0.115 vn 0.399 0.914 -0.075 vn 0.077 0.975 -0.206 vn -0.815 0.405 -0.414 vn -0.975 0.106 -0.196 vn -0.980 0.197 -0.038 vn -0.950 0.303 0.070 vn -0.941 -0.332 -0.065 vn -0.964 0.105 -0.243 vn -0.943 -0.322 0.084 vn -0.756 -0.651 0.069 vn -0.089 -0.996 0.024 vn 0.520 -0.852 0.051 vn 0.846 -0.530 -0.065 vn 0.735 -0.677 -0.013 vn 0.994 -0.085 -0.072 vn 0.833 0.445 -0.329 vn -0.370 0.633 -0.680 vn 0.492 -0.420 -0.762 vn 0.884 0.116 -0.452 vn 0.883 0.434 -0.178 vn 0.966 -0.241 -0.096 vn -0.732 -0.679 0.061 vn -0.121 -0.992 0.037 vn 0.899 -0.393 -0.193 vn -0.787 -0.558 0.263 vn 0.208 -0.962 0.177 vn -0.367 -0.312 0.876 vn 0.047 -0.811 0.583 vn 0.459 -0.888 -0.012 vn 0.758 -0.604 0.245 vn 0.550 -0.835 -0.017 vn 0.937 0.051 -0.345 vn 0.518 -0.182 -0.836 vn 0.689 0.645 -0.332 vn -0.514 -0.024 -0.857 vn -0.835 0.062 -0.546 vn -0.038 -0.139 -0.990 vn -0.077 -0.689 0.721 vn -0.897 -0.200 0.394 vn -0.991 0.118 0.062 vn -0.522 0.406 -0.750 vn -0.906 0.385 -0.173 vn 0.439 0.453 -0.776 vn -0.576 0.766 -0.285 vn -0.044 0.405 -0.913 vn 0.031 0.903 -0.428 vn 0.716 -0.013 0.698 vn 0.996 -0.061 -0.065 vn 0.896 -0.016 0.443 vn 0.980 -0.031 -0.199 vn 0.504 -0.347 -0.791 vn 0.556 -0.472 -0.684 vn 0.193 -0.411 -0.891 vn 0.397 -0.602 -0.693 vn 0.783 -0.440 -0.439 vn 0.936 -0.327 0.128 vn 0.753 0.055 0.655 vn 0.897 -0.093 0.432 vn 0.745 0.018 0.667 vn 0.852 -0.431 -0.298 vn 0.630 -0.425 -0.651 vn 0.611 -0.778 -0.143 vn 0.756 -0.431 0.493 vn 0.785 -0.384 -0.486 vn 0.763 -0.644 0.060 vn 0.860 -0.182 0.477 vn 0.945 0.022 -0.327 vn 0.449 -0.556 -0.699 vn 0.688 -0.538 -0.487 vn -0.366 -0.169 -0.915 vn -0.877 0.016 -0.480 vn -0.905 0.113 -0.410 vn -0.958 0.144 0.247 vn -0.943 0.275 0.185 vn -0.512 0.707 0.488 vn -0.606 0.130 0.785 vn -0.376 0.533 0.758 vn -0.936 0.352 -0.018 vn -0.334 0.028 -0.942 vn -0.421 -0.347 -0.838 vn 0.324 0.427 0.844 vn 0.640 0.169 0.750 vn 0.183 0.776 0.603 vn -0.497 0.815 0.298 vn 0.380 0.844 0.378 vn -0.504 0.861 -0.065 vn 0.504 0.844 0.185 vn -0.598 0.801 0.032 vn 0.561 0.758 0.334 vn -0.669 0.539 0.511 vn 0.498 0.419 0.759 vn -0.662 0.643 0.385 vn -0.891 0.399 0.214 vn 0.614 0.444 0.652 vn -0.890 -0.435 -0.134 vn 0.791 -0.441 0.423 vn 0.009 -0.994 -0.113 vn -0.217 0.780 0.587 vn 0.509 0.521 0.685 vn -0.324 0.399 0.858 vn -0.346 -0.233 0.909 vn 0.619 -0.066 0.783 vn 0.915 0.183 0.360 vn 0.460 0.516 0.723 vn 0.286 0.849 0.444 vn -0.939 0.172 0.298 vn -0.965 0.107 -0.241 vn 0.900 0.264 0.347 vn 0.935 -0.249 0.253 vn 0.605 -0.668 0.433 vn -0.889 -0.174 -0.424 vn 0.152 -0.899 -0.411 vn -0.058 -0.939 -0.340 vn -0.028 -0.995 -0.094 vn -0.298 -0.926 0.234 vn -0.991 -0.046 0.125 vn -0.832 -0.493 -0.254 vn 0.835 -0.269 0.480 vn 0.328 -0.722 -0.610 vn -0.893 -0.390 -0.226 vn 0.460 0.887 -0.039 vn 0.078 0.995 0.056 vn -0.651 0.755 -0.075 vn 0.764 0.642 0.067 vn 0.991 0.038 -0.130 vn -0.966 -0.017 -0.259 vn -0.572 0.759 -0.312 vn -0.572 0.609 0.550 vn 0.776 -0.536 0.332 vn -0.963 -0.241 0.117 vn -0.763 -0.553 -0.335 vn 0.147 -0.987 -0.065 vn 0.905 -0.313 0.290 vn 0.344 -0.760 0.551 vn -0.572 -0.715 0.403 vn 0.051 -0.946 0.320 vn -0.149 0.697 -0.701 vn 0.250 0.824 0.508 vn -0.252 0.683 -0.685 vn 0.191 0.900 0.391 vn -0.665 0.554 -0.501 vn -0.264 0.738 0.621 vn -0.669 0.495 -0.554 vn -0.350 0.701 0.621 vn -0.778 0.625 0.069 vn -0.238 0.563 0.791 vn -0.954 0.169 0.248 vn 0.126 -0.137 0.983 vn -0.815 0.214 -0.538 vn -0.298 -0.733 -0.611 vn -0.310 -0.870 0.383 vn -0.490 -0.312 -0.814 vn -0.192 -0.244 -0.951 vn -0.431 -0.335 -0.838 vn 0.316 -0.157 0.936 vn 0.275 0.315 0.908 vn 0.247 0.297 0.922 vn 0.433 -0.193 0.880 vn 0.467 -0.867 -0.174 vn 0.375 -0.864 -0.335 vn 0.395 -0.909 0.134 vn 0.109 -0.993 0.037 vn 0.247 -0.024 0.969 vn -0.249 -0.611 -0.752 vn 0.603 -0.779 0.172 vn -0.084 -0.987 0.138 vn 0.342 -0.262 0.902 vn -0.101 -0.283 0.954 vn -0.729 0.234 -0.644 vn -0.650 -0.419 -0.634 vn -0.590 -0.581 -0.561 vn 0.529 -0.373 -0.762 vn 0.366 -0.623 -0.691 vn 0.097 -0.989 -0.115 vn 0.601 -0.647 -0.469 vn 0.096 -0.766 -0.636 vn 0.094 -0.764 -0.638 vn -0.512 -0.618 -0.596 vn -0.241 -0.958 0.153 vn 0.634 -0.472 -0.613 vn 0.771 0.624 0.127 vn 0.964 0.097 -0.247 vn 0.877 0.335 -0.344 vn 0.928 0.183 -0.324 vn 0.347 0.926 -0.151 vn 0.530 -0.233 -0.816 vn -0.355 0.751 0.558 vn -0.319 0.921 0.225 vn 0.559 0.762 -0.329 vn 0.825 0.563 -0.042 vn -0.242 0.821 0.518 vn 0.882 0.441 0.163 vn -0.203 0.593 0.779 vn 0.596 0.400 0.696 vn -0.344 0.341 0.875 vn 0.495 -0.080 0.865 vn -0.734 -0.251 0.631 vn -0.072 -0.969 0.238 vn 0.999 -0.017 0.039 vn 0.583 -0.718 -0.381 vn 0.907 -0.117 -0.405 vn 0.720 -0.256 -0.645 vn -0.833 -0.373 0.409 vn -0.953 -0.155 0.258 vn -0.724 0.305 0.619 vn -0.828 -0.272 0.490 vn -0.393 -0.655 -0.645 vn 0.692 -0.566 -0.447 vn -0.372 -0.583 -0.722 vn -0.417 -0.893 -0.167 vn -0.177 -0.981 -0.080 vn -0.697 -0.162 0.699 vn 0.764 -0.636 -0.106 vn -0.728 -0.566 -0.386 vn -0.055 -0.990 -0.126 vn 0.259 -0.224 0.940 vn 0.889 -0.457 -0.016 vn 0.317 -0.925 0.211 vn 0.213 -0.782 0.586 vn -0.597 -0.363 0.715 vn -0.548 -0.587 0.596 vn 0.131 -0.281 0.951 vn 0.280 -0.763 0.582 vn -0.390 -0.091 0.916 vn -0.376 -0.088 0.922 vn 0.644 0.508 0.572 vn -0.161 -0.046 0.986 vn 0.088 0.021 0.996 vn 0.175 0.322 0.931 vn -0.345 0.638 0.689 vn -0.281 0.186 0.942 vn -0.470 0.090 0.878 vn -0.356 0.779 0.515 vn -0.926 0.227 -0.302 vn -0.486 -0.847 0.215 vn 0.252 -0.921 0.298 vn 0.191 -0.935 0.299 vn -0.584 -0.352 0.732 vn 0.352 -0.788 0.505 vn -0.468 -0.350 0.812 vn 0.374 -0.779 0.503 vn -0.268 -0.322 0.908 vn 0.592 -0.795 0.132 vn 0.177 -0.424 0.888 vn 0.487 -0.836 -0.253 vn 0.533 -0.606 0.591 vn 0.091 -0.779 -0.620 vn 0.755 -0.595 0.275 vn -0.395 -0.809 -0.435 vn 0.720 -0.637 0.276 vn -0.528 -0.849 0.025 vn -0.860 0.099 0.501 vn -0.663 0.370 0.651 vn -0.277 0.351 0.894 vn 0.298 0.229 0.927 vn 0.785 0.116 0.609 vn 0.258 0.429 0.866 vn -0.823 -0.146 0.549 vn -0.973 -0.163 0.163 vn -0.855 -0.225 0.467 vn -0.728 -0.586 -0.356 vn -0.732 0.455 -0.508 vn -0.791 -0.318 0.523 vn -0.901 -0.020 0.434 vn -0.927 0.369 -0.065 vn -0.773 0.127 0.622 vn -0.668 -0.301 0.680 vn -0.896 -0.042 0.443 vn -0.591 0.643 -0.487 vn -0.928 0.155 0.340 vn -0.938 0.179 0.297 vn -0.523 0.852 0.037 vn -0.632 -0.728 -0.267 vn -0.772 0.032 -0.634 vn -0.938 0.287 0.194 vn -0.932 0.181 -0.314 vn -0.575 -0.150 -0.804 vn -0.625 -0.005 -0.781 vn -0.360 0.754 -0.549 vn 0.041 0.839 -0.543 vn 0.009 0.137 -0.991 vn -0.970 0.242 0.009 vn -0.945 0.028 0.326 vn -0.679 0.521 -0.518 vn -0.898 0.423 0.117 vn -0.770 0.206 0.604 vn -0.823 -0.359 -0.441 vn -0.876 -0.468 0.115 vn -0.987 -0.040 -0.158 vn -0.830 0.491 0.265 vn -0.905 0.423 -0.033 vn -0.658 0.583 0.476 vn -0.476 0.831 -0.287 vn 0.061 0.536 -0.842 vn -0.164 -0.537 -0.828 vn -0.606 0.332 -0.722 vn -0.463 0.467 -0.753 vn -0.487 0.250 -0.837 vn -0.926 -0.366 0.093 vn -0.891 0.157 0.426 vn -0.978 -0.204 -0.049 vn -0.646 0.764 -0.003 vn -0.809 0.260 0.527 vn -0.110 0.709 -0.696 vn -0.362 0.687 -0.630 vn -0.465 0.466 -0.753 vn -0.667 0.669 -0.327 vn -0.624 0.763 0.169 vn -0.335 0.803 0.493 vn 0.158 0.771 0.617 vn -0.937 0.091 -0.339 vn -0.870 0.151 0.470 vn -0.752 0.322 -0.576 vn -0.398 0.785 -0.475 vn -0.862 0.422 0.280 vn -0.677 0.511 -0.529 vn -0.587 0.808 0.054 vn -0.714 0.182 -0.676 vn -0.279 -0.419 0.864 vn -0.535 0.193 -0.823 vn -0.124 0.702 -0.702 vn -0.898 -0.392 -0.200 vn -0.902 -0.422 -0.092 vn -0.783 0.125 0.609 vn -0.932 -0.332 -0.143 vn -0.157 0.491 -0.857 vn -0.862 -0.475 -0.175 vn -0.783 0.535 -0.318 vn -0.092 0.492 -0.866 vn -0.457 0.435 -0.776 vn -0.435 0.721 -0.539 vn -0.324 0.559 0.763 vn -0.084 0.215 0.973 vn 0.322 0.189 0.927 vn 0.207 0.288 0.935 vn -0.156 0.026 0.987 vn -0.386 0.535 0.751 vn -0.778 0.382 0.499 vn -0.577 0.233 0.783 vn -0.547 0.619 0.564 vn -0.804 0.576 0.147 vn -0.305 0.193 0.933 vn -0.278 -0.353 0.893 vn -0.440 -0.005 0.898 vn 0.529 -0.209 0.823 vn 0.470 0.195 0.861 vn -0.833 0.016 0.554 vn -0.333 0.767 0.549 vn -0.828 0.096 0.552 vn -0.740 0.646 -0.186 vn -0.388 0.558 0.734 vn -0.956 -0.071 0.283 vn -0.800 0.516 -0.307 vn -0.486 0.849 0.209 vn -0.966 -0.248 -0.066 vn -0.738 0.279 0.614 vn -0.912 -0.361 -0.194 vn -0.990 -0.124 -0.070 vn -0.914 -0.394 -0.096 vn -0.993 -0.044 0.111 vn -0.479 0.873 -0.090 vn -0.716 0.692 -0.088 vn -0.607 0.789 -0.090 vn 0.043 0.981 -0.190 vn -0.674 0.640 -0.369 vn -0.207 0.792 0.575 vn -0.556 0.688 -0.465 vn 0.315 0.928 -0.199 vn 0.250 0.916 0.314 vn 0.139 0.958 0.251 vn -0.208 0.919 0.336 vn -0.654 0.425 0.626 vn -0.613 -0.170 0.772 vn -0.527 0.307 0.792 vn -0.137 0.481 0.866 vn 0.409 0.165 0.897 vn -0.257 0.531 0.808 vn 0.160 0.262 0.952 vn 0.524 -0.219 0.823 vn -0.308 -0.357 0.881 vn -0.318 0.700 0.639 vn -0.085 0.547 0.833 vn -0.526 0.126 0.841 vn -0.676 0.248 0.694 vn 0.106 -0.341 0.934 vn 0.500 -0.047 0.865 vn -0.055 -0.486 0.872 vn -0.507 0.290 0.812 vn -0.418 -0.012 0.908 vn -0.364 -0.279 0.888 vn -0.737 0.671 0.083 vn -0.859 -0.033 0.511 vn -0.683 -0.477 0.553 vn -0.798 -0.478 -0.369 vn -0.914 -0.404 0.038 vn 0.076 -0.801 0.593 vn -0.801 -0.517 0.301 vn -0.603 -0.654 -0.456 vn -0.873 -0.475 -0.109 vn -0.646 0.577 -0.500 vn -0.612 -0.425 -0.667 vn -0.436 -0.705 -0.559 vn -0.950 -0.284 -0.128 vn -0.207 -0.385 -0.899 vn -0.868 -0.496 -0.014 vn -0.449 0.200 -0.871 vn -0.486 -0.172 -0.857 vn -0.027 0.994 0.102 vn -0.382 0.470 -0.796 vn 0.142 0.980 0.136 vn 0.166 0.919 -0.357 vn -0.382 0.790 -0.479 vn 0.168 -0.286 0.943 vn 0.195 -0.414 0.889 vn -0.199 -0.251 0.947 vn -0.225 -0.814 0.536 vn -0.046 -0.638 0.769 vn -0.408 -0.156 0.900 vn -0.374 -0.630 0.681 vn 0.225 -0.034 0.974 vn -0.476 0.250 0.843 vn -0.419 -0.308 0.854 vn -0.414 -0.753 -0.512 vn -0.506 -0.280 -0.816 vn -0.823 -0.488 -0.291 vn -0.919 -0.259 -0.296 vn -0.284 -0.218 -0.934 vn -0.118 -0.531 -0.839 vn -0.566 0.180 -0.805 vn -0.498 -0.314 -0.809 vn -0.505 -0.382 -0.774 vn -0.313 -0.522 -0.794 vn -0.430 -0.692 -0.579 vn -0.758 0.519 0.396 vn -0.480 -0.086 -0.873 vn -0.931 -0.259 -0.256 vn -0.315 -0.812 -0.491 vn -0.686 -0.683 0.253 vn -0.727 -0.169 0.666 vn -0.309 -0.926 -0.215 vn 0.194 -0.040 -0.980 vn -0.519 -0.222 0.825 vn -0.627 0.167 -0.761 vn 0.526 0.137 -0.839 vn -0.913 0.044 0.405 vn -0.300 -0.952 -0.063 vn 0.357 -0.040 -0.933 vn -0.609 -0.173 0.774 vn -0.235 -0.897 -0.375 vn -0.465 0.438 0.770 vn 0.227 0.864 -0.450 vn -0.152 0.816 0.557 vn -0.155 0.978 -0.137 vn 0.185 0.939 -0.292 vn -0.347 0.788 0.509 vn 0.320 0.845 -0.429 vn 0.281 -0.005 -0.960 vn -0.026 0.918 0.395 vn -0.861 -0.151 -0.486 vn -0.409 -0.471 -0.782 vn 0.009 0.269 -0.963 vn -0.526 0.135 -0.840 vn -0.712 -0.692 0.122 vn -0.370 -0.688 -0.625 vn -0.095 -0.158 -0.983 vn -0.853 -0.148 -0.501 vn -0.463 -0.051 0.885 vn -0.500 -0.756 -0.422 vn -0.083 -0.093 -0.992 vn -0.332 -0.158 0.930 vn 0.303 0.720 -0.624 vn -0.099 0.722 -0.684 vn 0.024 0.703 0.711 vn 0.415 0.907 0.075 vn -0.439 0.898 0.024 vn -0.497 0.486 -0.719 vn -0.576 0.788 -0.217 vn -0.001 0.829 -0.559 vn -0.315 0.885 -0.342 vn 0.105 0.507 -0.856 vn 0.150 0.989 0.004 vn -0.458 0.889 -0.004 vn -0.134 0.368 -0.920 vn -0.521 0.391 -0.759 vn 0.312 0.859 0.406 vn -0.518 0.750 -0.411 vn 0.096 0.854 0.511 vn -0.225 0.843 0.488 vn -0.851 0.522 0.064 vn -0.293 0.503 0.813 vn -0.449 0.878 -0.169 vn -0.261 0.866 -0.426 vn -0.767 0.641 0.036 vn -0.572 -0.652 0.497 vn 0.161 0.583 0.796 vn -0.600 -0.735 -0.314 vn -0.122 -0.149 -0.981 vn -0.462 -0.186 0.867 vn 0.381 0.659 -0.649 vn -0.665 -0.612 0.427 vn -0.039 0.457 0.889 vn -0.327 -0.517 -0.791 vn 0.146 0.988 -0.040 vn -0.522 -0.606 0.600 vn -0.221 0.474 0.853 vn 0.393 0.902 0.176 vn 0.189 0.527 -0.829 vn -0.448 -0.891 -0.080 vn -0.529 0.046 0.848 vn -0.296 0.921 -0.252 vn -0.151 0.008 -0.989 vn -0.967 0.003 -0.256 vn -0.714 0.242 -0.657 vn -0.826 -0.233 -0.514 vn -0.341 -0.771 -0.538 vn -0.876 -0.476 -0.081 vn -0.195 0.967 -0.166 vn -0.894 0.393 0.216 vn -0.502 0.426 -0.753 vn -0.415 -0.584 -0.698 vn -0.880 -0.367 -0.302 vn -0.182 0.969 -0.168 vn -0.906 0.417 0.080 vn 0.529 -0.135 0.838 vn 0.388 -0.162 0.907 vn 0.333 -0.409 0.850 vn 0.333 -0.215 0.918 vn 0.365 -0.255 0.896 vn 0.525 -0.231 0.819 vn -0.032 -0.064 0.997 vn -0.052 0.368 0.928 vn -0.177 -0.213 0.961 vn 0.128 0.981 -0.149 vn -0.365 0.847 0.386 vn -0.374 0.794 -0.478 vn -0.659 0.593 -0.463 vn -0.369 0.814 -0.449 vn -0.382 0.769 -0.512 vn -0.500 0.797 -0.339 vn -0.273 0.868 -0.414 vn -0.892 0.397 -0.215 vn -0.404 0.856 -0.324 vn -0.722 0.610 -0.325 vn -0.523 0.764 0.378 vn -0.747 0.652 -0.130 vn -0.530 0.848 0.002 vn -0.558 0.739 0.378 vn -0.464 0.840 0.281 vn -0.583 0.744 -0.325 vn -0.336 0.315 -0.888 vn -0.648 -0.101 -0.755 vn -0.876 0.135 0.462 vn -0.855 0.322 -0.406 vn -0.166 -0.540 -0.825 vn -0.244 -0.596 -0.765 vn -0.102 -0.059 -0.993 vn -0.633 0.771 0.067 vn -0.381 0.542 0.749 vn -0.842 0.445 0.305 vn -0.488 0.871 0.060 vn -0.341 0.788 -0.513 vn -0.186 0.396 0.899 vn -0.748 0.154 -0.646 vn -0.239 0.149 -0.959 vn -0.470 0.880 -0.066 vn -0.182 0.890 -0.417 vn -0.242 0.894 -0.378 vn -0.013 0.483 -0.876 vn -0.795 0.592 -0.133 vn -0.967 -0.099 -0.233 vn -0.545 0.819 0.178 vn -0.235 -0.111 0.966 vn -0.541 0.822 -0.180 vn -0.616 0.704 0.353 vn -0.803 0.227 0.551 vn -0.777 0.623 -0.093 vn -0.600 0.354 0.718 vn -0.703 0.355 0.616 vn -0.710 0.597 -0.375 vn -0.649 0.269 0.712 vn -0.105 0.350 0.931 vn 0.158 0.806 0.570 vn -0.578 0.471 0.666 vn -0.438 0.545 0.715 vn -0.667 0.534 0.520 vn -0.761 0.119 -0.637 vn -0.801 0.531 -0.275 vn 0.052 -0.869 -0.491 vn 0.023 0.716 0.698 vn -0.598 0.132 0.791 vn -0.574 0.153 0.804 vn -0.042 0.524 0.851 vn -0.597 0.098 0.796 vn -0.117 0.442 0.889 vn -0.013 0.584 0.812 vn 0.298 0.498 0.815 vn 0.265 0.334 0.904 vn 0.009 0.950 0.313 vn 0.175 0.757 0.630 vn -0.452 0.816 0.360 vn -0.413 0.084 0.907 vn 0.100 0.680 0.727 vn -0.305 0.267 0.914 vn -0.540 0.575 0.615 vn -0.436 0.765 0.474 vn -0.688 0.274 0.671 vn -0.405 0.913 0.045 vn -0.749 0.643 -0.162 vn -0.967 -0.096 -0.234 vn -0.820 0.572 0.016 vn -0.672 0.325 -0.666 vn -0.604 0.460 -0.650 vn -0.609 0.502 0.614 vn -0.649 0.358 0.672 vn -0.891 0.451 -0.057 vn -0.239 0.864 -0.443 vn -0.820 0.316 -0.477 vn -0.457 0.855 -0.247 vn -0.768 0.630 0.119 vn -0.786 0.460 -0.413 vn -0.605 0.791 -0.085 vn -0.870 0.490 0.059 vn -0.961 0.022 -0.276 vn -0.979 -0.013 -0.205 vn -0.932 0.354 0.080 vn -0.485 0.716 0.502 vn -0.753 0.576 0.318 vn -0.670 0.713 0.205 vn 0.079 0.489 0.869 vn 0.344 0.130 0.930 vn -0.783 0.620 0.047 vn -0.889 0.100 -0.446 vn -0.561 0.753 0.345 vn -0.838 0.506 -0.202 vn -0.464 0.857 0.224 vn -0.053 0.693 0.719 vn 0.760 -0.051 0.648 vn 0.620 0.033 0.784 vn -0.756 0.584 -0.296 vn 0.506 0.860 -0.069 vn -0.282 0.950 -0.133 vn -0.968 0.140 -0.206 vn -0.963 -0.112 -0.244 vn -0.871 -0.156 -0.467 vn -0.704 -0.499 -0.504 vn -0.279 0.642 0.715 vn -0.876 0.474 -0.089 vn -0.240 0.880 0.409 vn -0.293 0.897 0.331 vn 0.349 0.032 0.937 vn 0.416 0.656 0.629 vn -0.807 0.578 0.121 vn 0.669 0.635 0.386 vn 0.763 0.337 0.551 vn 0.370 0.022 0.929 vn 0.866 0.500 0.025 vn 0.342 0.846 0.409 vn -0.846 0.150 -0.511 vn -0.309 0.919 0.244 vn -0.992 -0.128 -0.022 vn -0.867 0.499 0.006 vn -0.980 -0.118 0.159 vn -0.878 0.450 0.161 vn -0.831 0.520 0.198 vn -0.975 -0.136 0.178 vn -0.992 0.073 0.100 vn -0.840 0.536 0.082 vn -0.223 0.973 0.066 vn -0.962 -0.249 0.109 vn -0.840 -0.244 -0.484 vn -0.929 -0.255 -0.267 vn -0.489 -0.722 -0.490 vn -0.635 -0.735 0.237 vn -0.562 -0.763 -0.320 vn -0.628 -0.775 -0.074 vn -0.912 -0.238 -0.335 vn -0.787 -0.615 0.050 vn -0.643 -0.695 0.323 vn -0.466 -0.743 -0.480 vn -0.761 -0.219 -0.611 vn -0.282 -0.956 -0.087 vn -0.954 -0.280 0.106 vn 0.768 -0.622 0.152 vn -0.996 -0.037 -0.081 vn 0.369 -0.873 -0.318 vn -0.635 -0.671 -0.382 vn -0.997 -0.017 0.078 vn -0.201 -0.493 -0.846 vn 0.028 -0.113 -0.993 vn 0.192 -0.222 -0.956 vn -0.539 -0.213 -0.815 vn -0.916 0.312 -0.251 vn -0.275 -0.079 -0.958 vn -0.359 0.854 -0.376 vn 0.222 0.460 -0.859 vn -0.995 -0.069 0.075 vn -0.694 -0.536 -0.481 vn 0.166 -0.786 0.595 vn -0.992 -0.046 0.121 vn 0.219 -0.922 -0.318 vn -0.711 -0.700 0.058 vn -0.636 -0.711 -0.300 vn -0.991 -0.047 -0.124 vn -0.495 -0.156 -0.855 vn -0.075 -0.446 -0.892 vn -0.077 0.401 -0.913 vn -0.348 -0.842 -0.413 vn -0.299 0.954 0.008 vn -0.086 0.405 -0.910 vn -0.766 -0.560 -0.315 vn -0.792 -0.486 -0.370 vn -0.180 -0.857 -0.482 vn 0.885 -0.350 0.308 vn 0.047 -0.871 0.489 vn 0.572 -0.143 0.808 vn 0.826 0.106 0.553 vn 0.830 -0.349 0.435 vn 0.789 -0.498 0.360 vn 0.820 -0.428 0.379 vn 0.193 -0.639 0.745 vn 0.707 -0.504 0.495 vn 0.226 -0.968 -0.113 vn -0.279 -0.862 -0.424 vn -0.013 -0.991 0.137 vn 0.036 -0.985 -0.167 vn -0.130 -0.932 0.338 vn -0.162 -0.935 0.314 vn 0.631 -0.713 0.306 vn 0.430 -0.839 0.333 vn -0.146 0.982 0.120 vn 0.947 0.268 0.179 vn 0.988 0.145 0.053 vn 0.558 0.807 0.194 vn 0.943 0.323 0.076 vn 0.913 -0.374 0.161 vn 0.860 -0.317 0.400 vn 0.764 -0.576 0.292 vn 0.499 -0.864 0.063 vn 0.565 -0.818 0.111 vn 0.970 -0.190 0.149 vn -0.188 0.884 0.428 vn 0.641 0.739 0.211 vn 0.968 0.095 -0.233 vn -0.716 0.639 0.280 vn -0.429 0.755 0.495 vn -0.134 0.856 0.498 vn 0.371 0.804 0.465 vn -0.925 0.283 -0.254 vn -0.342 0.820 0.459 vn 0.389 0.835 0.389 vn -0.577 0.817 -0.010 vn 0.207 0.953 0.222 vn -0.626 0.779 0.016 vn 0.302 0.927 0.224 vn -0.586 0.729 0.354 vn 0.269 0.804 0.530 vn -0.710 0.557 0.431 vn -0.838 0.361 0.410 vn 0.643 0.454 0.616 vn -0.140 0.654 0.743 vn 0.263 0.741 0.618 vn 0.731 0.035 0.681 vn 0.739 0.225 -0.635 vn 0.957 0.021 0.288 vn 0.926 0.264 0.270 vn 0.978 -0.115 0.176 vn 0.950 0.191 0.249 vn -0.961 -0.146 0.234 vn 0.826 0.142 0.545 vn -0.226 0.528 0.818 vn -0.168 0.044 0.985 vn 0.427 -0.230 -0.874 vn -0.005 -0.815 -0.579 vn -0.104 -0.928 -0.358 vn 0.028 -0.783 -0.621 vn 0.438 -0.758 -0.484 vn -0.942 0.064 0.329 vn -0.975 -0.181 0.127 vn -0.900 -0.342 -0.272 vn -0.765 -0.610 0.207 vn -0.290 0.917 -0.275 vn -0.611 0.783 0.111 vn -0.694 0.530 0.487 vn -0.581 0.813 -0.031 vn -0.502 0.852 0.150 vn -0.755 0.633 -0.170 vn -0.418 0.875 0.245 vn -0.222 0.905 -0.363 vn -0.323 0.642 0.696 vn -0.262 0.955 0.141 vn -0.075 0.930 0.359 vn -0.209 0.958 0.195 vn -0.654 0.751 -0.090 vn -0.672 0.701 -0.240 vn -0.354 0.929 0.110 vn -0.844 0.516 0.145 vn -0.279 0.942 0.187 vn -0.332 0.915 -0.228 vn -0.738 0.552 0.388 vn -0.678 0.423 0.601 vn -0.234 0.841 0.487 vn -0.755 0.605 0.250 vn -0.743 0.669 -0.016 vn -0.524 0.765 -0.374 vn -0.424 0.840 -0.339 vn -0.417 0.834 0.361 vn -0.575 0.809 0.123 vn -0.700 0.671 -0.245 vn -0.978 -0.153 -0.142 vn -0.979 -0.205 -0.017 vn -0.876 0.031 0.482 vn -0.982 0.170 -0.085 vn 0.575 -0.772 -0.271 vn 0.754 -0.582 -0.305 vn -0.368 -0.779 -0.508 vn -0.364 -0.856 -0.366 vn 0.735 -0.678 0.008 vn -0.495 -0.842 -0.214 vn 0.925 -0.375 0.059 vn -0.570 -0.759 -0.314 vn 0.784 -0.620 -0.018 vn 0.681 -0.723 0.113 vn -0.517 -0.842 -0.158 vn 0.123 -0.920 0.372 vn 0.887 0.255 -0.385 vn 0.829 0.419 0.370 vn 0.871 0.190 0.454 vn 0.960 0.118 -0.255 vn 0.702 0.411 0.582 vn 0.877 0.298 -0.377 vn 0.598 0.682 0.421 vn 0.757 0.516 -0.400 vn 0.590 0.781 -0.206 vn 0.429 0.773 0.467 vn 0.559 0.449 -0.697 vn 0.186 -0.322 -0.928 vn 0.045 -0.207 -0.977 vn 0.094 -0.516 -0.851 vn 0.724 0.690 0.017 vn 0.372 0.420 0.828 vn 0.618 0.186 -0.764 vn 0.939 0.293 0.181 vn -0.026 -0.547 0.837 vn 0.144 -0.743 -0.654 vn 0.116 0.013 0.993 vn -0.061 0.116 0.991 vn -0.485 -0.857 -0.175 vn -0.469 -0.604 0.645 vn 0.113 -0.993 -0.019 vn -0.023 -0.773 0.634 vn 0.209 -0.793 -0.572 vn -0.015 -0.442 0.897 vn -0.612 -0.551 0.567 vn -0.665 -0.589 -0.459 vn 0.059 -0.891 0.450 vn 0.654 -0.755 0.051 vn 0.893 0.120 0.435 vn 0.046 -0.922 -0.385 vn 0.645 -0.727 0.235 vn 0.144 -0.981 -0.127 vn -0.280 0.675 0.683 vn -0.612 0.565 0.554 vn -0.804 0.488 0.341 vn 0.091 0.685 0.723 vn -0.867 0.216 0.450 vn 0.044 0.425 0.904 vn -0.824 -0.108 0.557 vn 0.070 0.083 0.994 vn -0.843 -0.146 0.518 vn -0.061 0.020 0.998 vn -0.406 -0.266 0.875 vn -0.909 -0.384 0.164 vn 0.443 -0.096 0.891 vn 0.048 0.166 0.985 vn 0.788 0.200 0.583 vn 0.675 0.151 0.722 vn 0.937 0.058 0.344 vn -0.303 -0.630 0.715 vn -0.762 -0.553 -0.337 vn 0.766 -0.259 0.589 vn 0.100 -0.980 0.172 vn -0.122 -0.060 -0.991 vn 0.979 0.155 -0.132 vn -0.956 -0.145 -0.255 vn -0.889 -0.179 -0.421 vn -0.786 -0.317 -0.531 vn -0.899 -0.051 0.434 vn 0.859 -0.066 -0.508 vn 0.956 0.205 -0.211 vn 0.008 0.026 -1.000 vn 0.048 -0.202 -0.978 vn 0.952 -0.091 -0.291 vn -0.015 -0.196 -0.981 vn -0.253 -0.479 -0.841 vn 0.932 -0.288 -0.221 vn 0.458 -0.888 0.035 vn 0.592 -0.482 -0.647 vn -0.622 0.463 0.632 vn -0.822 0.392 0.414 vn -0.904 0.246 0.350 vn -0.054 0.455 0.889 vn -0.932 -0.041 0.360 vn -0.139 0.207 0.968 vn -0.717 -0.568 0.404 vn 0.015 -0.354 0.935 vn -0.575 -0.750 0.326 vn 0.247 -0.488 0.837 vn -0.070 -0.832 0.551 vn -0.609 -0.793 -0.006 vn 0.561 -0.321 0.763 vn -0.193 0.040 0.980 vn 0.677 0.078 0.732 vn 0.788 0.202 0.581 vn 0.863 0.257 0.434 vn 0.007 -0.915 0.403 vn -0.535 -0.731 -0.424 vn 0.795 -0.291 0.532 vn 0.585 -0.308 -0.750 vn -0.907 -0.295 -0.300 vn -0.798 -0.283 -0.532 vn -0.729 -0.360 -0.582 vn -0.964 -0.264 -0.027 vn 0.643 0.634 -0.430 vn 0.681 0.698 -0.224 vn -0.142 0.495 -0.857 vn -0.188 0.288 -0.939 vn 0.858 0.450 -0.247 vn -0.282 0.048 -0.958 vn -0.200 -0.266 -0.943 vn 0.992 0.005 -0.123 vn 0.339 -0.881 -0.329 vn 0.412 -0.886 -0.213 vn -0.504 -0.544 -0.670 vn -0.418 -0.546 -0.726 vn -0.359 -0.847 -0.393 vn -0.925 0.134 -0.356 vn -0.810 0.330 0.485 vn -0.932 0.351 0.094 vn -0.917 0.325 0.233 vn -0.286 0.268 0.920 vn -0.934 -0.169 0.315 vn -0.223 -0.093 0.970 vn -0.876 -0.482 -0.007 vn -0.302 -0.508 0.807 vn -0.634 -0.757 -0.157 vn -0.085 -0.770 0.633 vn -0.078 -0.996 0.048 vn -0.399 -0.617 -0.678 vn 0.402 -0.690 0.602 vn -0.091 -0.267 0.959 vn 0.420 -0.047 0.906 vn 0.494 -0.143 0.858 vn 0.611 -0.030 0.791 vn 0.231 -0.943 -0.239 vn -0.221 -0.377 -0.899 vn 0.665 -0.409 0.625 vn 0.840 0.271 -0.470 vn -0.791 -0.011 -0.612 vn -0.581 -0.062 -0.811 vn -0.372 0.073 -0.925 vn -0.819 -0.039 -0.573 vn 0.504 0.662 0.554 vn 0.767 0.543 0.343 vn 0.149 0.782 -0.605 vn 0.112 0.904 -0.413 vn 0.693 0.564 0.450 vn -0.068 0.424 -0.903 vn 0.224 -0.097 -0.970 vn 0.883 -0.317 0.345 vn -0.141 -0.617 -0.774 vn -0.415 -0.828 -0.377 vn -0.420 -0.354 0.835 vn -0.266 0.155 0.951 vn 0.210 0.575 0.790 vn 0.502 0.103 0.859 vn 0.362 0.532 0.765 vn -0.468 -0.654 -0.594 vn -0.438 -0.861 0.257 vn 0.317 0.301 0.899 vn -0.011 0.362 0.932 vn -0.734 -0.461 -0.500 vn -0.363 -0.866 -0.345 vn -0.950 -0.156 -0.272 vn 0.437 0.768 -0.468 vn -0.660 0.501 0.560 vn -0.992 -0.074 -0.103 vn -0.996 -0.083 0.024 vn -0.983 -0.010 -0.184 vn -0.956 0.119 -0.270 vn -0.762 0.404 0.506 vn -0.953 -0.185 -0.239 vn -0.794 0.524 0.307 vn -0.895 -0.233 -0.381 vn -0.348 -0.450 -0.823 vn -0.212 -0.264 -0.941 vn 0.018 -0.306 -0.952 vn 0.117 -0.065 -0.991 vn 0.924 -0.014 -0.383 vn 0.916 0.065 -0.397 vn 0.491 0.704 -0.513 vn 0.794 0.405 -0.453 vn -0.045 0.991 0.126 vn 0.493 0.828 0.268 vn 0.420 0.896 0.142 vn 0.893 0.414 0.179 vn 0.781 0.497 0.378 vn 0.587 -0.233 -0.775 vn -0.203 0.860 0.468 vn 0.190 0.722 0.665 vn -0.086 0.719 0.690 vn -0.390 0.532 -0.752 vn -0.519 -0.418 -0.745 vn -0.257 -0.964 -0.073 vn -0.689 -0.568 -0.451 vn -0.695 -0.688 -0.210 vn -0.497 -0.339 0.799 vn -0.696 -0.701 0.155 vn -0.676 -0.188 0.712 vn -0.439 -0.195 0.877 vn -0.581 -0.375 0.723 vn -0.760 -0.649 -0.025 vn -0.719 -0.544 -0.433 vn -0.729 0.042 0.684 vn -0.531 -0.641 0.554 vn -0.588 -0.069 0.806 vn -0.864 -0.067 0.499 vn -0.798 -0.460 0.389 vn -0.524 -0.290 0.801 vn -0.811 -0.535 0.236 vn -0.521 -0.606 0.601 vn -0.627 -0.631 0.458 vn -0.683 -0.703 0.200 vn -0.439 -0.787 0.433 vn -0.375 -0.817 0.438 vn -0.298 -0.397 0.868 vn -0.377 -0.065 0.924 vn -0.533 -0.169 0.829 vn -0.794 -0.381 0.473 vn -0.148 0.250 0.957 vn -0.138 0.216 0.967 vn -0.619 -0.288 0.730 vn -0.007 -0.217 0.976 vn -0.153 -0.371 0.916 vn -0.319 0.137 0.938 vn -0.173 -0.112 0.979 vn -0.051 -0.075 0.996 vn -0.300 -0.084 0.950 vn -0.447 -0.392 0.804 vn -0.048 -0.087 0.995 vn -0.338 -0.813 0.475 vn -0.023 -0.362 0.932 vn -0.610 -0.662 0.436 vn -0.014 0.346 0.938 vn -0.422 -0.114 0.899 vn -0.609 -0.439 0.660 vn -0.179 0.377 0.908 vn -0.554 -0.205 0.807 vn -0.054 0.377 0.925 vn -0.904 0.033 -0.426 vn -0.899 0.432 -0.071 vn -0.524 -0.007 0.852 vn -0.176 -0.181 0.968 vn -0.188 0.036 0.982 vn 0.075 -0.594 0.801 vn -0.218 -0.188 0.958 vn -0.068 -0.524 0.849 vn -0.331 -0.304 0.893 vn -0.073 -0.388 0.919 vn -0.131 -0.286 0.949 vn -0.468 -0.176 0.866 vn 0.102 -0.104 0.989 vn 0.449 -0.241 0.860 vn -0.092 0.074 0.993 vn 0.093 -0.660 0.745 vn -0.114 -0.011 0.993 vn -0.805 0.575 0.148 vn -0.842 0.455 0.289 vn -0.381 -0.103 -0.919 vn -0.934 0.167 0.317 vn -0.107 -0.902 -0.417 vn -0.778 -0.212 0.592 vn 0.063 -0.994 0.088 vn -0.590 -0.212 0.779 vn 0.025 -0.104 0.994 vn -0.114 -0.969 0.217 vn -0.407 -0.064 0.911 vn -0.272 -0.114 0.955 vn -0.540 -0.178 0.823 vn 0.012 0.452 0.892 vn -0.746 0.276 0.606 vn 0.654 0.683 0.324 vn 0.212 0.928 0.305 vn 0.165 -0.687 -0.707 vn -0.767 -0.463 0.444 vn -0.823 -0.291 0.488 vn 0.486 -0.781 -0.392 vn -0.734 -0.389 0.557 vn -0.482 -0.809 -0.337 vn -0.199 0.798 0.569 vn -0.419 0.850 0.319 vn -0.631 0.773 -0.067 vn -0.453 0.379 -0.807 vn 0.278 0.862 -0.423 vn 0.055 0.995 -0.078 vn 0.457 0.238 -0.857 vn 0.206 0.606 -0.768 vn 0.602 -0.712 -0.363 vn -0.811 -0.274 0.517 vn -0.692 0.203 0.692 vn 0.486 0.844 -0.226 vn 0.191 0.904 0.383 vn 0.007 0.698 0.716 vn -0.374 0.316 0.872 vn -0.996 0.091 0.019 vn -0.292 0.956 -0.021 vn -0.313 0.883 0.351 vn 0.003 0.659 0.752 vn -0.279 0.382 0.881 vn -0.398 0.325 0.858 vn 0.214 0.751 0.625 vn -0.564 0.750 0.344 vn -0.660 0.456 0.596 vn -0.843 -0.281 -0.459 vn -0.909 -0.092 -0.407 vn -0.789 -0.068 0.611 vn -0.852 0.114 0.512 vn -0.518 -0.545 0.660 vn -0.369 -0.335 0.867 vn 0.462 -0.585 -0.667 vn 0.734 -0.677 0.056 vn -0.049 -0.573 -0.818 vn 0.816 -0.403 -0.414 vn 0.390 -0.494 -0.777 vn 0.777 -0.413 -0.476 vn 0.725 -0.245 -0.643 vn 0.208 -0.969 0.130 vn 0.672 -0.229 -0.704 vn 0.058 0.853 0.519 vn 0.916 -0.274 0.293 vn 0.445 -0.063 0.893 vn 0.223 -0.971 0.082 vn -0.263 -0.619 -0.740 vn -0.693 -0.714 -0.104 vn -0.847 -0.529 0.039 vn -0.100 -0.897 -0.431 vn -0.829 -0.550 0.104 vn -0.805 -0.549 0.226 vn -0.271 -0.851 0.449 vn -0.114 -0.814 0.569 vn -0.604 -0.735 0.308 vn -0.111 -0.989 -0.101 vn -0.639 -0.293 -0.711 vn -0.215 -0.838 -0.502 vn -0.498 -0.864 0.072 vn -0.783 -0.405 -0.471 vn -0.231 -0.861 0.453 vn -0.472 -0.871 0.134 vn -0.221 -0.961 -0.166 vn -0.655 -0.288 -0.698 vn -0.047 -0.428 -0.902 vn -0.541 -0.441 -0.716 vn -0.621 -0.609 -0.494 vn 0.577 0.806 0.132 vn 0.588 0.804 0.092 vn 0.588 -0.246 0.771 vn 0.743 -0.174 0.646 vn 0.903 -0.254 0.347 vn 0.256 -0.796 0.549 vn 0.346 0.168 0.923 vn 0.468 -0.041 0.883 vn 0.570 0.233 0.788 vn 0.431 0.129 0.893 vn 0.121 -0.979 0.164 vn 0.699 -0.710 0.092 vn 0.085 -0.982 0.169 vn 0.083 -0.987 0.138 vn 0.055 -0.984 -0.169 vn 0.438 0.296 0.849 vn 0.779 0.186 0.599 vn 0.912 0.409 0.023 vn 0.329 0.590 0.738 vn 0.433 0.340 0.835 vn 0.914 0.405 0.031 vn 0.977 0.213 0.009 vn 0.870 -0.105 -0.482 vn 0.965 -0.031 0.260 vn 0.915 0.343 0.212 vn 0.978 -0.142 -0.154 vn 0.840 0.488 0.236 vn 0.593 0.442 0.673 vn 0.795 -0.235 0.559 vn 0.602 0.525 0.601 vn 0.676 0.328 0.659 vn 0.779 -0.407 0.478 vn 0.653 -0.265 0.709 vn 0.707 -0.205 0.677 vn 0.870 -0.491 0.050 vn 0.690 0.722 -0.052 vn 0.770 -0.098 0.630 vn 0.866 0.469 0.171 vn 0.994 -0.098 0.043 vn 0.876 -0.451 0.168 vn 0.919 -0.380 -0.110 vn 0.944 0.310 -0.112 vn 0.827 -0.092 0.554 vn 0.872 -0.489 -0.013 vn 0.973 0.201 0.111 vn 0.934 0.103 0.342 vn 0.962 0.269 0.049 vn 0.960 -0.212 -0.185 vn 0.996 0.089 -0.019 vn 0.970 -0.212 0.117 vn 0.917 -0.333 0.219 vn 0.789 -0.347 0.507 vn 0.968 0.147 0.202 vn 0.987 0.035 0.154 vn 0.949 0.179 0.260 vn -0.466 0.559 0.685 vn -0.708 0.420 0.569 vn -0.876 0.301 -0.377 vn -0.864 -0.276 -0.421 vn -0.669 -0.732 0.126 vn 0.416 -0.566 0.712 vn 0.969 0.124 0.212 vn 0.775 0.607 -0.177 vn 0.705 -0.345 0.619 vn 0.916 -0.400 0.036 vn 0.856 -0.107 -0.506 vn 0.993 0.066 -0.102 vn 0.479 0.656 -0.583 vn 0.413 -0.041 0.910 vn 0.048 -0.245 0.968 vn 0.405 0.076 0.911 vn 0.148 -0.245 0.958 vn 0.292 0.082 0.953 vn 0.736 0.218 0.641 vn 0.697 0.428 0.575 vn 0.888 0.333 0.317 vn 0.582 0.159 0.798 vn 0.593 0.315 0.741 vn 0.689 0.375 0.620 vn 0.305 -0.046 0.951 vn -0.172 0.914 0.367 vn 0.026 -0.071 0.997 vn 0.122 -0.325 0.938 vn 0.051 -0.132 0.990 vn -0.393 -0.478 0.785 vn -0.386 -0.514 0.766 vn -0.234 0.062 0.970 vn -0.274 -0.489 0.828 vn 0.342 0.588 0.733 vn 0.298 0.049 0.953 vn -0.010 -0.292 0.956 vn 0.948 -0.137 0.287 vn -0.044 -0.666 0.744 vn 0.459 0.498 0.736 vn 0.833 0.478 0.277 vn 0.858 -0.467 0.215 vn 0.831 -0.492 0.260 vn 0.504 0.726 0.468 vn 0.528 0.180 0.830 vn 0.944 0.327 0.050 vn 0.827 0.340 0.447 vn 0.981 0.179 0.071 vn 0.855 0.508 0.101 vn 0.844 0.247 0.476 vn 0.538 0.571 -0.619 vn -0.609 -0.338 0.718 vn 0.125 0.473 0.872 vn 0.892 0.182 0.414 vn -0.232 -0.900 0.369 vn 0.700 -0.698 0.152 vn 0.445 -0.079 0.892 vn 0.061 -0.984 0.168 vn -0.233 -0.726 0.647 vn 0.533 -0.626 0.569 vn 0.546 -0.221 0.808 vn 0.162 -0.960 0.228 vn 0.477 -0.878 0.045 vn 0.111 -0.974 0.197 vn 0.987 0.127 -0.098 vn 0.706 0.411 0.576 vn 0.903 -0.377 0.204 vn -0.488 -0.488 0.724 vn 0.101 -0.247 0.964 vn -0.125 -0.953 0.275 vn -0.255 -0.912 0.321 vn -0.698 -0.105 0.708 vn -0.626 -0.702 0.339 vn 0.700 -0.662 -0.269 vn 0.182 0.169 -0.969 vn 0.696 -0.284 -0.660 vn 0.796 0.605 -0.005 vn 0.966 -0.233 -0.114 vn 0.955 -0.278 -0.100 vn 0.747 -0.664 -0.030 vn 0.904 0.215 0.370 vn -0.211 -0.271 0.939 vn -0.445 0.386 0.808 vn -0.351 -0.500 0.792 vn -0.633 -0.011 0.774 vn -0.949 0.132 0.285 vn -0.474 -0.177 0.862 vn -0.537 -0.128 0.834 vn -0.443 -0.053 -0.895 vn 0.137 0.388 -0.911 vn 0.899 0.438 0.017 vn 0.826 0.267 -0.497 vn 0.189 -0.679 -0.709 vn 0.729 -0.212 -0.651 vn -0.337 0.429 0.838 vn -0.564 -0.582 0.587 vn 0.107 -0.317 0.942 vn -0.180 -0.649 0.739 vn -0.079 -0.358 0.930 vn -0.317 -0.550 0.773 vn 0.800 0.460 -0.385 vn 0.971 0.211 0.114 vn 0.963 0.192 -0.189 vn -0.369 -0.086 -0.925 vn -0.687 0.327 -0.650 vn -0.842 -0.453 -0.292 vn -0.818 -0.538 -0.203 vn -0.817 -0.551 0.169 vn -0.777 -0.567 0.273 vn -0.623 -0.600 0.501 vn -0.760 -0.590 0.273 vn -0.907 -0.422 0.006 vn 0.287 0.840 -0.460 vn -0.722 0.671 -0.167 vn -0.930 0.360 0.077 vn 0.198 0.786 -0.585 vn -0.612 0.743 -0.271 vn 0.050 0.963 -0.266 vn -0.630 0.777 0.014 vn -0.403 0.869 -0.287 vn 0.486 0.560 -0.671 vn 0.808 0.308 -0.503 vn 0.840 0.398 -0.368 vn 0.806 0.537 -0.250 vn 0.931 -0.070 -0.359 vn 0.785 0.305 -0.539 vn 0.983 -0.064 -0.174 vn 0.920 -0.379 -0.098 vn 0.421 -0.901 0.106 vn -0.194 -0.929 0.315 vn -0.633 -0.727 0.267 vn -0.486 -0.828 0.279 vn -0.906 -0.342 0.248 vn -0.981 0.184 -0.063 vn -0.084 0.671 -0.737 vn -0.726 -0.375 -0.577 vn -0.984 -0.082 -0.158 vn -0.979 0.178 0.098 vn -0.850 -0.476 0.226 vn 0.884 -0.431 -0.182 vn 0.400 -0.916 -0.009 vn -0.768 -0.630 0.119 vn 0.931 -0.361 -0.061 vn -0.174 -0.960 0.218 vn -0.491 -0.715 0.498 vn -0.269 -0.945 0.186 vn -0.966 -0.257 -0.034 vn -0.646 -0.453 -0.614 vn -0.910 0.386 -0.148 vn 0.273 -0.085 -0.958 vn 0.615 0.150 -0.774 vn -0.169 -0.327 -0.930 vn 0.454 -0.524 0.721 vn 0.988 0.132 0.081 vn 0.895 0.354 -0.270 vn 0.167 0.390 -0.906 vn 0.680 0.559 -0.474 vn -0.738 0.184 -0.649 vn 0.244 0.826 -0.509 vn -0.310 0.242 -0.919 vn -0.390 0.788 -0.477 vn -0.408 0.037 0.912 vn -0.923 -0.304 0.236 vn -0.694 -0.047 0.718 vn -0.939 -0.335 0.074 vn -0.508 -0.692 -0.513 vn -0.617 -0.709 -0.340 vn -0.287 -0.659 -0.696 vn -0.487 -0.761 -0.428 vn -0.733 -0.679 -0.034 vn -0.699 -0.454 0.552 vn -0.400 0.038 0.916 vn -0.630 -0.156 0.761 vn -0.381 0.058 0.923 vn -0.794 -0.595 0.126 vn -0.757 -0.587 -0.288 vn -0.459 -0.877 0.144 vn -0.346 -0.499 0.795 vn -0.854 -0.516 -0.063 vn -0.537 -0.739 0.406 vn -0.513 -0.287 0.809 vn -0.980 -0.136 0.147 vn -0.565 -0.728 -0.388 vn -0.608 -0.787 -0.107 vn 0.148 -0.309 -0.939 vn 0.682 0.098 -0.724 vn 0.638 0.177 -0.749 vn 0.908 0.411 -0.080 vn 0.853 0.477 -0.214 vn 0.591 0.779 0.209 vn 0.715 0.442 0.541 vn 0.543 0.647 0.535 vn 0.652 0.553 -0.519 vn -0.038 -0.069 -0.997 vn -0.001 -0.321 -0.947 vn -0.013 0.428 0.904 vn -0.272 0.154 0.950 vn 0.064 0.745 0.665 vn 0.521 0.853 0.028 vn -0.299 0.859 0.415 vn 0.380 0.889 -0.257 vn -0.502 0.842 0.197 vn 0.564 0.817 -0.119 vn -0.478 0.762 0.436 vn 0.792 0.494 0.359 vn -0.271 0.412 0.870 vn 0.756 0.580 0.302 vn 0.946 0.324 0.005 vn -0.399 0.421 0.815 vn 0.787 -0.467 -0.402 vn -0.681 -0.437 0.588 vn -0.112 -0.977 -0.179 vn 0.416 0.712 0.565 vn -0.385 0.428 0.818 vn 0.568 0.303 0.765 vn 0.556 -0.332 0.762 vn -0.456 -0.095 0.885 vn -0.870 -0.010 0.494 vn -0.095 0.609 0.788 vn -0.117 0.770 0.627 vn 0.951 0.285 -0.119 vn 0.873 0.269 -0.407 vn -0.848 0.073 0.525 vn -0.912 -0.301 0.280 vn -0.624 -0.610 0.488 vn 0.896 -0.054 -0.440 vn -0.002 -0.866 -0.500 vn -0.092 -0.940 -0.330 vn -0.072 -0.983 -0.169 vn 0.268 -0.957 0.108 vn 0.989 -0.123 -0.086 vn 0.765 -0.536 -0.358 vn -0.696 -0.268 0.666 vn -0.530 -0.646 -0.550 vn 0.770 -0.413 -0.486 vn -0.726 0.687 -0.030 vn -0.323 0.940 -0.109 vn 0.412 0.830 -0.377 vn -0.891 0.391 0.232 vn -0.959 -0.215 0.183 vn 0.684 0.139 -0.716 vn 0.317 0.788 -0.527 vn 0.685 0.676 0.273 vn -0.698 -0.522 0.491 vn 0.940 -0.300 -0.162 vn 0.829 -0.265 -0.492 vn 0.140 -0.983 -0.117 vn -0.715 -0.558 0.420 vn 0.109 -0.795 0.596 vn 0.817 -0.577 0.015 vn 0.262 -0.937 0.231 vn 0.106 0.711 -0.695 vn -0.052 0.858 0.510 vn 0.239 0.689 -0.684 vn -0.046 0.905 0.422 vn 0.611 0.538 -0.581 vn 0.367 0.735 0.570 vn 0.586 0.503 -0.635 vn 0.412 0.725 0.552 vn 0.750 0.657 -0.070 vn 0.319 0.607 0.728 vn 0.972 0.219 0.087 vn 0.037 -0.106 0.994 vn 0.714 0.224 -0.663 vn 0.233 -0.743 -0.628 vn 0.409 -0.841 0.355 vn 0.321 -0.303 -0.897 vn 0.109 -0.270 -0.957 vn 0.321 -0.356 -0.878 vn -0.207 -0.114 0.972 vn -0.169 0.266 0.949 vn -0.026 0.243 0.970 vn -0.397 -0.183 0.899 vn -0.471 -0.880 -0.055 vn -0.463 -0.858 -0.222 vn -0.325 -0.919 0.223 vn -0.058 -0.994 0.088 vn -0.092 0.002 0.996 vn 0.157 -0.627 -0.763 vn -0.529 -0.797 0.290 vn 0.140 -0.988 -0.070 vn -0.192 -0.377 0.906 vn 0.518 -0.277 0.809 vn 0.346 0.214 -0.913 vn 0.231 -0.299 -0.926 vn 0.310 -0.509 -0.803 vn -0.766 -0.495 -0.411 vn -0.585 -0.689 -0.428 vn -0.005 -0.993 -0.114 vn -0.670 -0.731 -0.133 vn -0.328 -0.769 -0.548 vn -0.319 -0.771 -0.551 vn 0.180 -0.571 -0.801 vn 0.378 -0.923 -0.065 vn -0.796 -0.558 -0.236 vn -0.636 0.485 0.600 vn -0.956 -0.051 0.288 vn -0.925 0.273 0.264 vn -0.972 0.039 0.230 vn -0.413 0.876 0.250 vn -0.754 -0.442 -0.487 vn 0.563 0.751 0.345 vn 0.458 0.870 0.183 vn -0.648 0.750 0.133 vn -0.705 0.589 0.396 vn 0.533 0.774 0.341 vn -0.662 0.547 0.513 vn 0.617 0.605 0.503 vn -0.142 0.575 0.805 vn 0.757 0.384 0.529 vn -0.011 0.114 0.993 vn 0.925 -0.288 0.248 vn 0.099 -0.929 0.357 vn -0.852 0.152 0.502 vn -0.753 -0.653 0.083 vn -0.982 -0.118 0.148 vn -0.944 -0.255 -0.211 vn 0.895 -0.444 0.048 vn 0.938 -0.241 -0.250 vn 0.959 0.257 0.118 vn 0.941 -0.330 -0.080 vn 0.006 -0.787 -0.617 vn -0.862 -0.505 0.044 vn -0.059 -0.697 -0.715 vn 0.205 -0.964 -0.168 vn 0.029 -0.999 0.046 vn 0.933 -0.187 0.307 vn -0.771 -0.510 0.381 vn 0.395 -0.725 -0.565 vn -0.070 -0.986 -0.150 vn 0.393 -0.253 0.884 vn -0.721 -0.559 0.410 vn -0.026 -0.960 0.280 vn 0.257 -0.844 0.470 vn -0.742 0.471 0.477 vn 0.402 0.685 0.608 vn 0.407 0.415 0.814 vn 0.736 0.551 0.393 vn 0.620 0.767 0.164 vn 0.467 -0.213 -0.858 vn 0.860 -0.422 -0.286 vn 0.807 -0.531 -0.259 vn 0.552 -0.343 -0.760 vn 0.087 -0.188 -0.978 vn -0.504 0.019 -0.864 vn -0.899 0.184 -0.398 vn -0.902 0.335 0.274 vn 0.677 -0.120 -0.726 vn -0.042 0.264 -0.964 vn -0.458 0.526 -0.717 vn -0.653 0.682 -0.330 vn -0.561 0.813 0.157 vn 0.750 -0.276 -0.601 vn 0.439 -0.264 -0.859 vn 0.717 -0.321 -0.619 vn -0.157 -0.570 -0.806 vn -0.102 0.462 -0.881 vn 0.786 -0.358 -0.504 vn 0.751 -0.081 -0.655 vn 0.383 0.336 -0.861 vn 0.890 0.065 -0.451 vn 0.890 -0.353 -0.290 vn 0.807 -0.022 -0.590 vn -0.116 0.674 -0.729 vn 0.721 0.127 -0.681 vn 0.541 -0.092 -0.836 vn 0.319 0.748 -0.582 vn -0.324 -0.780 -0.536 vn -0.286 0.012 -0.958 vn 0.374 -0.068 -0.925 vn -0.200 0.006 -0.980 vn -0.339 0.919 -0.201 vn -0.891 0.321 -0.320 vn 0.314 0.090 -0.945 vn 0.630 -0.161 -0.760 vn -0.079 0.497 -0.864 vn 0.536 0.300 -0.789 vn 0.905 0.134 -0.405 vn -0.101 -0.380 -0.920 vn 0.461 -0.518 -0.720 vn 0.191 -0.114 -0.975 vn 0.651 0.412 -0.638 vn 0.415 0.422 -0.806 vn 0.746 0.547 -0.380 vn -0.077 0.837 -0.541 vn -0.732 0.580 -0.359 vn -0.696 -0.462 -0.549 vn -0.333 0.327 -0.884 vn -0.535 0.309 -0.787 vn 0.573 -0.178 -0.800 vn 0.608 0.411 -0.679 vn 0.590 0.030 -0.807 vn -0.176 0.887 -0.427 vn 0.825 0.255 -0.505 vn -0.533 0.689 -0.492 vn -0.561 0.084 -0.823 vn 0.292 0.016 -0.956 vn -0.605 0.346 -0.717 vn 0.367 0.130 -0.921 vn 0.094 0.467 -0.879 vn -0.531 0.731 -0.429 vn 0.642 0.040 -0.765 vn 0.442 0.194 -0.875 vn 0.602 0.536 -0.593 vn 0.474 0.218 -0.853 vn -0.633 0.479 -0.608 vn 0.241 0.126 -0.962 vn -0.486 0.596 -0.639 vn -0.950 0.195 -0.245 vn 0.992 -0.072 -0.104 vn 0.677 0.736 -0.020 vn 0.961 0.143 -0.237 vn 0.119 0.376 -0.919 vn 0.829 0.548 -0.110 vn 0.816 0.064 -0.575 vn 0.246 0.228 -0.942 vn 0.462 0.846 -0.268 vn 0.887 0.019 -0.462 vn 0.866 0.383 -0.322 vn 0.458 -0.515 -0.725 vn 0.684 0.213 -0.698 vn 0.484 0.021 -0.875 vn 0.556 0.369 -0.745 vn -0.236 0.834 -0.499 vn 0.450 0.753 -0.479 vn -0.349 0.819 -0.455 vn -0.293 0.956 -0.014 vn 0.241 0.647 -0.723 vn 0.447 0.893 -0.051 vn -0.345 0.442 -0.828 vn -0.447 0.894 0.020 vn 0.044 0.980 0.196 vn 0.043 0.987 0.154 vn 0.400 0.915 0.056 vn 0.794 0.531 0.296 vn 0.856 0.238 0.458 vn 0.835 0.451 0.317 vn 0.467 0.705 0.534 vn 0.958 0.271 0.088 vn 0.995 -0.004 0.099 vn 0.905 -0.401 -0.140 vn 0.635 0.641 -0.431 vn 0.887 -0.074 -0.457 vn 0.800 -0.469 -0.374 vn 0.166 -0.549 -0.819 vn 0.483 -0.407 -0.775 vn 0.878 -0.219 -0.426 vn 0.706 -0.453 -0.544 vn -0.067 -0.633 -0.772 vn 0.305 -0.406 -0.862 vn -0.309 0.541 -0.782 vn -0.151 -0.420 -0.895 vn -0.298 -0.737 -0.607 vn 0.297 -0.259 -0.919 vn -0.699 -0.466 -0.543 vn 0.431 -0.420 -0.799 vn -0.614 0.162 -0.772 vn 0.113 0.993 -0.025 vn -0.090 0.966 0.241 vn -0.412 0.906 0.096 vn -0.091 0.802 -0.590 vn -0.259 -0.776 -0.576 vn -0.438 -0.339 -0.833 vn 0.096 -0.522 -0.847 vn 0.217 -0.274 -0.937 vn -0.712 -0.242 -0.659 vn -0.726 -0.485 -0.487 vn -0.497 0.132 -0.857 vn -0.543 -0.538 -0.645 vn 0.601 0.583 -0.546 vn -0.558 -0.059 -0.828 vn 0.215 -0.267 -0.939 vn -0.283 -0.716 -0.638 vn 0.543 -0.603 -0.585 vn 0.914 -0.143 -0.379 vn 0.091 -0.820 -0.565 vn -0.940 -0.142 -0.311 vn 0.992 -0.075 -0.097 vn -0.422 0.195 -0.885 vn -0.994 -0.065 0.083 vn 0.749 0.271 -0.604 vn 0.258 -0.852 -0.456 vn -0.973 -0.185 -0.137 vn 0.980 0.047 -0.192 vn -0.054 -0.867 -0.496 vn 0.902 0.430 -0.026 vn -0.634 0.761 0.139 vn 0.457 0.840 0.294 vn -0.241 0.967 -0.081 vn -0.511 0.845 0.161 vn 0.460 0.886 0.059 vn -0.614 0.759 0.217 vn -0.977 0.002 -0.214 vn 0.311 0.900 0.307 vn -0.026 -0.067 -0.997 vn -0.572 -0.451 -0.685 vn -0.876 0.262 -0.404 vn -0.548 0.212 -0.809 vn 0.550 -0.536 -0.640 vn -0.244 -0.674 -0.697 vn -0.788 -0.252 -0.562 vn 0.246 0.298 -0.922 vn 0.991 0.134 0.028 vn -0.000 -0.690 -0.724 vn -0.815 -0.192 -0.547 vn 0.993 0.026 0.117 vn -0.821 0.568 0.059 vn -0.697 0.641 -0.321 vn 0.463 0.762 0.452 vn -0.293 0.810 0.509 vn 0.040 0.963 -0.267 vn -0.060 0.861 -0.504 vn -0.627 0.764 -0.152 vn -0.895 0.375 -0.242 vn -0.259 0.926 0.274 vn 0.025 0.955 -0.297 vn -0.819 0.276 -0.503 vn 0.050 0.823 0.565 vn -0.282 0.783 -0.554 vn 0.256 0.866 0.431 vn 0.384 0.913 0.137 vn -0.077 0.865 -0.496 vn 0.810 0.556 0.184 vn -0.105 0.921 -0.376 vn -0.404 0.849 -0.341 vn 0.241 0.782 -0.574 vn 0.815 -0.465 -0.346 vn 0.511 0.630 0.585 vn 0.134 -0.636 -0.760 vn -0.776 -0.238 -0.583 vn 1.000 0.012 -0.021 vn -0.865 0.490 0.109 vn 0.787 -0.416 -0.456 vn 0.707 0.558 0.435 vn -0.448 -0.533 -0.718 vn -0.292 0.929 0.227 vn 0.874 -0.417 -0.248 vn 0.752 0.605 0.261 vn -0.195 0.823 0.534 vn -0.912 0.377 -0.160 vn 0.300 -0.789 -0.535 vn 0.967 0.248 -0.061 vn -0.270 0.925 -0.268 vn -0.801 -0.080 -0.593 vn 0.202 0.161 -0.966 vn -0.307 0.273 -0.912 vn -0.114 -0.164 -0.980 vn 0.313 -0.473 -0.824 vn 0.546 0.482 -0.686 vn 0.143 -0.305 -0.942 vn 0.421 0.511 -0.750 vn 0.590 0.776 0.224 vn -0.333 0.926 0.176 vn 0.352 0.935 -0.048 vn -0.211 0.654 -0.727 vn -0.354 0.822 -0.445 vn -0.213 0.835 -0.508 vn 0.132 0.546 -0.827 vn -0.259 0.880 -0.399 vn -0.074 0.707 -0.703 vn 0.417 0.892 -0.176 vn 0.087 0.772 -0.629 vn 0.027 0.933 -0.359 vn 0.495 0.839 -0.228 vn 0.430 0.770 -0.472 vn -0.205 0.802 -0.561 vn -0.704 0.262 -0.660 vn -0.260 -0.116 -0.959 vn 0.785 0.297 -0.544 vn -0.026 0.384 -0.923 vn -0.624 -0.481 -0.616 vn -0.451 -0.607 -0.654 vn -0.817 -0.160 -0.555 vn 0.208 0.878 -0.431 vn 0.584 0.810 0.048 vn 0.559 0.622 -0.548 vn -0.086 0.886 -0.456 vn 0.818 0.449 -0.359 vn 0.329 0.471 -0.818 vn -0.217 0.651 -0.727 vn 0.164 0.975 -0.152 vn -0.370 0.879 -0.302 vn -0.158 0.480 -0.863 vn 0.939 0.206 -0.275 vn 0.821 0.475 -0.317 vn 0.064 0.560 -0.826 vn 0.644 0.675 -0.358 vn -0.071 0.884 -0.461 vn 0.407 0.872 -0.271 vn 0.761 0.607 -0.229 vn 0.088 0.789 -0.608 vn 0.784 0.614 0.096 vn 0.694 0.691 -0.202 vn -0.151 0.685 -0.713 vn 0.837 0.508 -0.204 vn 0.785 0.491 0.378 vn 0.232 0.893 0.385 vn 0.758 0.651 0.038 vn 0.586 0.794 0.163 vn 0.478 0.862 -0.169 vn 0.575 0.406 -0.710 vn 0.502 0.858 -0.107 vn 0.347 -0.372 -0.861 vn 0.846 0.333 -0.417 vn 0.897 0.192 -0.397 vn 0.976 0.213 -0.044 vn 0.557 0.657 0.509 vn 0.936 0.254 -0.244 vn 0.839 0.542 0.038 vn 0.741 0.562 0.368 vn 0.066 0.864 0.499 vn 0.236 0.860 0.453 vn 0.477 0.879 -0.018 vn 0.906 0.298 0.300 vn 0.933 0.205 0.295 vn 0.767 0.559 0.313 vn 0.507 0.798 0.326 vn 0.432 0.900 -0.054 vn 0.614 0.785 -0.084 vn -0.355 0.926 -0.127 vn 0.380 0.840 -0.387 vn 0.352 0.333 -0.875 vn -0.144 0.908 -0.393 vn -0.870 0.417 -0.263 vn -0.224 0.639 -0.736 vn 0.570 0.816 -0.097 vn 0.338 0.941 0.032 vn -0.152 0.863 -0.481 vn -0.004 0.988 0.155 vn -0.242 0.672 -0.700 vn -0.053 0.897 -0.439 vn 0.463 0.781 -0.419 vn 0.155 0.767 -0.622 vn 0.034 0.975 0.221 vn 0.644 0.206 -0.737 vn 0.313 0.140 -0.939 vn 0.287 0.261 -0.922 vn 0.676 0.170 -0.717 vn 0.931 0.127 -0.343 vn 0.893 0.096 -0.440 vn 0.858 0.449 -0.249 vn 0.928 -0.340 0.151 vn 0.618 -0.670 0.412 vn 0.568 0.425 -0.705 vn -0.187 0.460 -0.868 vn 0.833 0.328 -0.445 vn 0.335 0.553 -0.763 vn 0.822 0.487 -0.294 vn 0.996 0.029 0.078 vn 0.343 -0.516 0.785 vn 0.553 -0.572 0.606 vn -0.002 0.705 -0.709 vn 0.733 0.578 0.359 vn 0.466 0.829 -0.308 vn -0.397 0.288 -0.871 vn -0.157 0.183 -0.971 vn -0.345 0.275 -0.897 vn -0.799 0.140 -0.585 vn 0.955 -0.291 0.051 vn 0.625 0.537 -0.566 vn 0.990 0.136 0.046 vn 0.941 0.328 0.083 vn 0.932 -0.169 0.319 vn 0.145 0.355 -0.923 vn 0.830 0.153 0.536 vn 0.847 0.094 0.523 vn 0.791 -0.564 0.237 vn 0.663 0.255 0.704 vn 0.931 0.227 0.286 vn -0.507 0.477 -0.718 vn 0.598 0.540 -0.592 vn -0.450 -0.025 -0.893 vn 0.010 0.355 -0.935 vn -0.233 -0.283 -0.930 vn 0.082 0.177 -0.981 vn 0.155 0.080 -0.985 vn -0.359 -0.187 -0.914 vn -0.261 -0.007 -0.965 vn 0.083 0.363 -0.928 vn 0.584 0.671 -0.457 vn -0.450 -0.248 -0.858 vn -0.798 0.171 -0.578 vn -0.693 0.008 -0.721 vn -0.830 -0.113 -0.547 vn -0.551 -0.691 -0.467 vn -0.914 -0.329 -0.235 vn -0.782 -0.506 -0.363 vn -0.661 -0.153 -0.735 vn -0.674 -0.447 -0.588 vn -0.534 -0.666 -0.521 vn -0.956 -0.272 -0.113 vn -0.791 0.168 -0.588 vn 0.848 0.071 -0.526 vn 0.609 -0.175 -0.773 vn 0.526 0.057 0.849 vn 0.624 0.051 -0.780 vn -0.240 -0.238 -0.941 vn -0.053 -0.603 -0.796 vn 0.556 0.042 -0.830 vn -0.561 -0.403 -0.723 vn -0.880 -0.141 -0.454 vn -0.926 -0.222 -0.305 vn -0.489 -0.166 -0.856 vn 0.200 0.391 -0.898 vn -0.734 -0.069 -0.676 vn -0.185 0.884 -0.429 vn -0.883 0.450 -0.132 vn 0.098 -0.235 -0.967 vn -0.388 0.206 -0.898 vn -0.607 0.148 -0.781 vn 0.100 0.181 -0.978 vn -0.637 -0.154 -0.755 vn 0.510 -0.467 -0.722 vn 0.114 -0.555 -0.824 vn 0.396 0.112 -0.911 vn -0.515 -0.112 -0.850 vn -0.710 -0.440 -0.550 vn -0.853 0.293 -0.431 vn -0.138 -0.733 -0.666 vn -0.005 0.955 -0.297 vn -0.841 0.325 -0.433 vn -0.604 -0.088 -0.792 vn -0.310 -0.012 -0.951 vn -0.803 -0.169 -0.572 vn 0.940 -0.281 -0.195 vn 0.876 -0.482 -0.015 vn 0.715 -0.697 0.047 vn 0.948 -0.075 0.310 vn 0.295 -0.623 0.724 vn -0.372 -0.656 0.657 vn -0.294 -0.549 0.783 vn 0.853 -0.472 -0.225 vn 0.592 -0.721 0.360 vn -0.845 -0.400 0.355 vn -0.979 -0.182 -0.096 vn -0.547 -0.813 0.200 vn -0.696 -0.637 0.330 vn -0.461 -0.885 0.058 vn -0.465 -0.885 -0.000 vn 0.004 -0.759 0.652 vn -0.145 -0.842 0.520 vn 0.660 0.632 -0.406 vn 0.657 0.056 0.752 vn 0.481 0.032 0.876 vn 0.807 0.528 0.265 vn 0.603 0.155 0.782 vn 0.216 -0.391 0.895 vn 0.391 -0.546 0.741 vn -0.328 -0.682 0.653 vn -0.724 -0.434 0.536 vn -0.260 -0.677 0.688 vn 0.341 -0.236 0.910 vn 0.700 0.350 -0.622 vn 0.692 0.666 0.280 vn 0.063 0.406 0.912 vn 0.486 0.042 -0.873 vn 0.742 0.141 -0.656 vn 0.829 0.357 -0.430 vn 0.817 0.576 0.008 vn -0.143 -0.155 -0.978 vn 0.761 0.266 -0.591 vn 0.739 0.673 0.040 vn 0.389 0.340 -0.856 vn 0.659 0.731 -0.175 vn 0.399 0.272 -0.876 vn 0.659 0.748 -0.083 vn 0.660 0.110 -0.743 vn 0.866 0.500 0.011 vn 0.632 -0.110 -0.767 vn 0.509 -0.306 -0.805 vn 0.779 0.374 0.503 vn 0.964 0.099 -0.245 vn 0.910 0.411 0.048 vn 0.780 0.054 0.624 vn -0.448 0.780 0.437 vn 0.295 0.362 0.884 vn 0.389 0.530 0.754 vn 0.126 0.297 0.946 vn 0.338 0.484 0.807 vn 0.103 -0.670 -0.735 vn 0.569 0.257 0.781 vn 0.965 -0.070 -0.252 vn 0.874 -0.484 0.037 vn -0.880 0.356 0.314 vn -0.888 -0.308 0.341 vn -0.736 -0.608 0.298 vn -0.912 -0.276 0.302 vn -0.692 -0.229 0.684 vn 0.824 -0.055 -0.563 vn 0.624 -0.216 -0.751 vn 0.176 -0.408 -0.896 vn 0.612 -0.596 -0.520 vn -0.165 0.922 0.351 vn 0.328 0.943 -0.057 vn 0.835 0.538 -0.117 vn 0.232 0.972 -0.047 vn 0.492 0.870 0.024 vn 0.401 0.850 -0.341 vn 0.822 0.562 0.097 vn -0.196 0.950 0.244 vn 0.711 0.692 0.123 vn 0.220 0.904 0.366 vn -0.087 0.836 0.541 vn 0.045 0.980 0.193 vn -0.233 0.918 0.320 vn -0.113 0.926 0.361 vn 0.325 0.944 -0.052 vn 0.647 0.661 -0.380 vn 0.801 0.578 0.157 vn 0.206 0.970 0.127 vn 0.456 0.847 0.272 vn 0.475 0.876 0.081 vn 0.292 0.852 0.434 vn -0.060 0.985 0.164 vn 0.671 0.711 -0.211 vn 0.223 0.969 -0.104 vn 0.134 0.982 -0.130 vn 0.251 0.889 0.383 vn 0.800 0.599 0.043 vn 0.397 0.836 -0.378 vn -0.225 -0.521 -0.823 vn -0.144 -0.611 -0.778 vn 0.377 -0.591 -0.713 vn -0.006 -0.321 -0.947 vn -0.599 -0.193 0.777 vn -0.533 0.055 0.845 vn -0.837 -0.538 -0.095 vn -0.750 -0.660 -0.033 vn -0.303 -0.172 0.937 vn -0.613 -0.780 -0.122 vn -0.103 0.127 0.987 vn -0.664 -0.707 -0.243 vn -0.307 -0.088 0.948 vn -0.227 -0.282 0.932 vn -0.556 -0.821 -0.132 vn -0.123 -0.806 0.578 vn -0.245 0.912 0.329 vn 0.641 0.671 0.372 vn 0.688 0.591 0.421 vn -0.157 0.905 0.396 vn 0.773 0.525 0.357 vn -0.143 0.884 0.445 vn 0.758 0.456 0.467 vn -0.245 0.782 0.572 vn 0.127 0.788 0.602 vn 0.792 0.429 0.435 vn -0.506 0.717 0.479 vn -0.986 0.146 0.085 vn -0.936 0.345 0.065 vn -0.995 -0.067 0.074 vn 0.303 0.657 0.690 vn 0.913 0.015 0.408 vn -0.621 0.554 0.554 vn 0.271 0.297 0.915 vn 0.492 -0.865 0.099 vn -0.926 -0.340 0.165 vn 0.956 -0.229 0.184 vn 0.938 -0.346 0.017 vn -0.539 -0.739 -0.403 vn 0.317 -0.883 -0.345 vn -0.481 -0.854 0.197 vn 0.212 -0.972 0.096 vn -0.878 -0.414 0.242 vn 0.587 -0.803 0.102 vn 0.348 -0.925 -0.153 vn -0.769 -0.552 -0.324 vn 0.063 -0.821 0.567 vn -0.319 -0.605 0.729 vn 0.523 0.308 0.795 vn -0.758 -0.512 0.403 vn -0.076 -0.407 0.910 vn -0.534 -0.658 0.531 vn 0.886 0.085 -0.457 vn 0.702 -0.091 -0.707 vn 0.449 -0.108 -0.887 vn 0.958 0.261 -0.117 vn 0.408 -0.328 -0.852 vn 0.998 0.029 -0.048 vn 0.421 -0.536 -0.732 vn 0.980 -0.193 0.056 vn 0.390 -0.477 -0.787 vn 0.973 -0.208 -0.097 vn 0.782 -0.488 -0.388 vn 0.022 -0.601 -0.799 vn 0.914 -0.128 0.384 vn 0.946 -0.316 0.070 vn 0.663 0.255 0.704 vn 0.790 0.177 0.586 vn 0.443 0.219 0.870 vn 0.597 -0.778 -0.198 vn -0.481 -0.655 -0.583 vn 0.629 -0.163 0.760 vn 0.058 -0.947 0.317 vn -0.998 0.060 -0.032 vn -0.008 0.388 0.921 vn -0.393 -0.383 -0.836 vn -0.553 -0.310 -0.774 vn -0.647 -0.403 -0.647 vn 0.276 -0.627 -0.729 vn -0.420 0.207 0.884 vn -0.095 0.495 0.864 vn -0.969 0.244 0.050 vn -0.986 -0.037 0.165 vn -0.199 0.169 0.965 vn -0.993 -0.049 0.104 vn -0.984 -0.168 -0.054 vn -0.263 0.199 0.944 vn -0.340 -0.507 0.792 vn -0.636 -0.237 0.734 vn 0.711 -0.217 -0.669 vn 0.480 -0.268 -0.835 vn 0.340 -0.309 -0.888 vn 0.992 -0.035 -0.125 vn 0.228 -0.448 -0.864 vn 0.970 -0.195 -0.143 vn 0.198 -0.781 -0.592 vn 0.834 -0.542 0.104 vn 0.161 -0.877 -0.452 vn 0.772 -0.566 0.289 vn 0.419 -0.907 0.037 vn -0.168 -0.868 -0.467 vn 0.753 -0.339 0.563 vn 0.864 -0.499 -0.064 vn 0.740 0.070 0.669 vn 0.665 0.227 0.711 vn 0.534 0.321 0.782 vn 0.273 -0.953 0.134 vn -0.562 -0.733 -0.384 vn 0.551 -0.241 0.799 vn -0.734 -0.106 0.671 vn -0.486 -0.404 -0.775 vn -0.629 -0.324 -0.707 vn -0.683 -0.377 -0.625 vn -0.224 -0.624 -0.749 vn -0.289 0.777 0.559 vn -0.060 0.817 0.574 vn -0.798 0.574 -0.185 vn -0.905 0.387 -0.177 vn -0.115 0.604 0.789 vn -0.963 0.145 -0.228 vn -0.993 0.102 -0.060 vn -0.100 0.400 0.911 vn -0.669 -0.372 0.643 vn -0.565 -0.396 0.724 vn -0.917 -0.290 -0.274 vn -0.884 -0.401 -0.238 vn -0.915 -0.401 -0.039 vn -0.367 -0.027 -0.930 vn 0.511 -0.346 -0.787 vn 0.199 -0.245 -0.949 vn 0.265 -0.295 -0.918 vn 0.909 -0.343 -0.236 vn 0.079 -0.705 -0.705 vn 0.768 -0.640 -0.027 vn -0.348 -0.761 -0.548 vn 0.407 -0.910 0.081 vn -0.563 -0.785 -0.259 vn 0.176 -0.922 0.346 vn -0.414 -0.843 0.342 vn -0.906 -0.366 -0.212 vn 0.269 -0.645 0.716 vn 0.711 -0.694 0.117 vn 0.810 -0.274 0.518 vn 0.731 -0.273 0.626 vn 0.740 -0.110 0.663 vn -0.602 -0.587 0.541 vn -0.986 -0.031 -0.165 vn 0.433 -0.333 0.838 vn -0.264 0.740 0.619 vn -0.631 -0.103 -0.769 vn -0.796 0.087 -0.599 vn -0.821 0.297 -0.488 vn -0.521 -0.286 -0.804 vn 0.827 0.498 0.263 vn 0.635 0.609 0.475 vn -0.089 0.947 -0.308 vn 0.028 0.955 -0.295 vn 0.690 0.547 0.473 vn -0.643 0.694 -0.325 vn -0.830 0.546 0.112 vn 0.276 0.006 0.961 vn -0.952 -0.304 0.013 vn -0.672 -0.707 0.219 vn 0.934 -0.149 0.326 vn 0.985 0.017 0.174 vn 0.500 0.578 0.645 vn 0.398 0.039 0.917 vn 0.334 0.517 0.788 vn 0.955 -0.164 -0.249 vn 0.835 -0.550 -0.015 vn 0.605 0.237 0.760 vn 0.803 0.445 0.397 vn 0.924 0.019 -0.383 vn 0.850 -0.455 -0.265 vn 0.890 0.361 -0.278 vn -0.728 0.410 -0.549 vn 0.274 0.757 0.593 vn 0.860 0.509 0.047 vn 0.862 0.482 0.159 vn 0.850 0.525 -0.047 vn 0.755 0.639 -0.147 vn 0.343 0.737 0.583 vn 0.923 0.356 -0.144 vn 0.318 0.865 0.388 vn 0.910 0.323 -0.259 vn 0.621 -0.057 -0.782 vn 0.448 -0.053 -0.893 vn 0.269 -0.243 -0.932 vn 0.066 -0.081 -0.995 vn -0.700 -0.507 -0.503 vn -0.732 -0.441 -0.520 vn -0.728 0.332 -0.599 vn -0.818 -0.092 -0.568 vn -0.531 0.842 0.093 vn -0.897 0.406 0.176 vn -0.795 0.585 0.163 vn -0.987 -0.082 0.140 vn -0.959 -0.031 0.283 vn -0.250 -0.479 -0.841 vn -0.296 0.827 0.478 vn -0.487 0.543 0.684 vn -0.401 0.614 0.680 vn 0.116 0.696 -0.709 vn 0.718 0.651 -0.246 vn 0.504 0.863 0.034 vn 0.395 0.836 0.382 vn 0.511 0.205 -0.835 vn 0.628 0.647 0.433 vn 0.680 -0.658 -0.324 vn 0.674 0.234 0.701 vn 0.519 -0.843 0.144 vn 0.473 0.201 0.858 vn -0.097 -0.142 0.985 vn 0.570 -0.772 0.280 vn 0.213 0.139 0.967 vn 0.157 0.019 0.987 vn -0.383 0.331 0.862 vn -0.961 0.187 0.203 vn -0.734 0.638 0.235 vn 0.345 -0.632 -0.694 vn 0.827 0.027 0.561 vn 0.766 0.196 0.612 vn 0.093 -0.902 -0.421 vn 0.742 0.065 0.667 vn 0.892 -0.386 -0.235 vn -0.356 0.741 0.569 vn -0.187 0.922 0.339 vn 0.093 0.996 -0.012 vn 0.268 0.600 -0.753 vn -0.671 0.566 -0.478 vn -0.450 0.881 -0.144 vn -0.411 -0.020 -0.911 vn -0.403 0.419 -0.814 vn -0.046 -0.910 -0.412 vn 0.747 0.204 0.633 vn -0.864 0.404 -0.301 vn -0.809 0.495 0.318 vn -0.495 0.535 0.685 vn 0.097 -0.760 -0.642 vn -0.223 -0.975 -0.004 vn 0.591 -0.333 -0.735 vn -0.383 -0.783 -0.491 vn 0.043 -0.563 -0.825 vn -0.343 -0.752 -0.563 vn -0.372 -0.581 -0.724 vn 0.354 -0.925 0.141 vn -0.325 -0.537 -0.779 vn -0.594 0.652 0.470 vn -0.636 -0.751 0.178 vn 0.656 -0.582 -0.480 vn -0.110 -0.595 -0.796 vn -0.006 -0.206 -0.979 vn -0.033 -0.090 -0.995 vn 0.951 0.194 -0.239 vn 0.525 -0.349 -0.776 vn 0.273 -0.239 -0.932 vn 0.244 0.667 -0.704 vn 0.804 0.501 0.320 vn 0.816 0.492 0.303 vn 0.600 0.754 -0.267 vn 0.922 0.331 -0.202 vn 0.951 -0.170 0.258 vn -0.121 -0.731 0.672 vn -0.882 -0.470 0.025 vn -0.937 0.051 -0.344 vn -0.464 -0.711 0.529 vn -0.495 -0.865 -0.077 # 2519 vertex normals g objDiablo3 s 1 f 6/1/6 5/2/5 8/3/8 f 6/1/6 8/3/8 7/4/7 f 12/5/12 11/6/11 10/7/10 f 12/5/12 10/7/10 9/8/9 f 15/9/15 14/10/14 1/11/1 f 15/9/15 1/11/1 2/12/2 f 16/13/16 15/9/15 2/12/2 f 16/13/16 2/12/2 17/14/17 f 25/15/25 24/16/24 23/17/23 f 25/15/25 23/17/23 22/18/22 f 5/2/5 10/7/10 13/19/13 f 5/2/5 13/19/13 8/3/8 f 9/8/9 10/7/10 5/2/5 f 9/8/9 5/2/5 4/20/4 f 13/19/13 24/16/24 7/4/7 f 13/19/13 7/4/7 8/3/8 f 11/6/11 23/17/23 24/16/24 f 11/6/11 24/16/24 13/19/13 f 20/21/20 27/22/27 25/15/25 f 20/21/20 25/15/25 22/18/22 f 29/23/29 28/24/28 27/22/27 f 29/23/29 27/22/27 20/21/20 f 30/25/30 27/22/27 28/24/28 f 30/25/30 28/24/28 31/26/31 f 31/26/31 28/24/28 1255/27/1255 f 31/26/31 1255/27/1255 1265/28/1265 f 1256/29/1256 1255/27/1255 28/24/28 f 1256/29/1256 28/24/28 29/23/29 f 33/30/33 32/31/32 1258/32/1258 f 33/30/33 1258/32/1258 1262/33/1262 f 1258/32/1258 32/31/32 31/26/31 f 1258/32/1258 31/26/31 1265/28/1265 f 34/34/34 1256/29/1256 29/23/29 f 34/34/34 29/23/29 35/35/35 f 35/35/35 29/23/29 20/21/20 f 35/35/35 20/21/20 36/36/36 f 37/37/37 34/34/34 35/35/35 f 37/37/37 35/35/35 38/38/38 f 35/35/35 36/36/36 39/39/39 f 35/35/35 39/39/39 38/38/38 f 40/40/40 37/37/37 38/38/38 f 40/40/40 38/38/38 41/41/41 f 41/41/41 38/38/38 39/39/39 f 41/41/41 39/39/39 42/42/42 f 43/43/43 37/37/37 40/40/40 f 43/43/43 40/40/40 44/44/44 f 45/45/45 12/5/12 9/8/9 f 45/45/45 9/8/9 46/46/46 f 41/41/41 42/42/42 12/5/12 f 41/41/41 12/5/12 45/45/45 f 47/47/47 44/44/44 40/40/40 f 47/47/47 40/40/40 45/45/45 f 48/48/48 50/49/50 18/50/18 f 48/48/48 18/50/18 19/51/19 f 52/52/52 1280/53/1280 50/49/50 f 52/52/52 50/49/50 48/48/48 f 53/54/53 25/15/25 27/22/27 f 53/54/53 27/22/27 30/25/30 f 54/55/54 26/56/26 25/15/25 f 54/55/54 25/15/25 53/54/53 f 59/57/59 54/55/54 53/54/53 f 59/57/59 53/54/53 60/58/60 f 30/25/30 55/59/55 60/58/60 f 30/25/30 60/58/60 53/54/53 f 48/48/48 49/60/49 57/61/57 f 48/48/48 57/61/57 52/52/52 f 52/52/52 57/61/57 33/30/33 f 52/52/52 33/30/33 51/62/51 f 61/63/61 45/45/45 46/46/46 f 61/63/61 46/46/46 62/64/62 f 109/65/109 44/44/44 65/66/65 f 109/65/109 65/66/65 108/67/108 f 67/68/67 42/42/42 66/69/66 f 67/68/67 66/69/66 21/70/21 f 69/71/69 16/13/16 17/14/17 f 69/71/69 17/14/17 70/72/70 f 17/14/17 6/1/6 18/50/18 f 17/14/17 18/50/18 72/73/72 f 72/73/72 18/50/18 50/49/50 f 72/73/72 50/49/50 73/74/73 f 73/74/73 50/49/50 1280/53/1280 f 73/74/73 1280/53/1280 74/75/74 f 75/76/75 72/73/72 73/74/73 f 75/76/75 73/74/73 76/77/76 f 76/77/76 73/74/73 74/75/74 f 76/77/76 74/75/74 77/78/77 f 75/76/75 76/77/76 79/79/79 f 75/76/75 79/79/79 78/80/78 f 84/81/84 81/82/81 83/83/83 f 84/81/84 83/83/83 82/84/82 f 85/85/85 79/79/79 87/86/87 f 85/85/85 87/86/87 86/87/86 f 79/79/79 80/88/80 88/89/88 f 79/79/79 88/89/88 87/86/87 f 85/85/85 83/83/83 81/82/81 f 85/85/85 81/82/81 78/80/78 f 92/90/92 91/91/91 90/92/90 f 92/90/92 90/92/90 68/93/68 f 92/90/92 86/94/86 93/95/93 f 92/90/92 93/95/93 91/91/91 f 82/96/82 83/97/83 94/98/94 f 82/96/82 94/98/94 92/90/92 f 86/94/86 89/99/89 95/100/95 f 86/94/86 95/100/95 93/95/93 f 96/101/96 89/102/89 87/86/87 f 96/101/96 87/86/87 88/89/88 f 100/103/100 99/104/99 98/105/98 f 100/103/100 98/105/98 97/106/97 f 97/106/97 98/105/98 104/107/104 f 97/106/97 104/107/104 103/108/103 f 97/106/97 107/109/107 106/110/106 f 97/106/97 106/110/106 100/103/100 f 101/111/101 109/112/109 108/113/108 f 101/111/101 108/113/108 103/108/103 f 103/108/103 111/114/111 107/109/107 f 103/108/103 107/109/107 97/106/97 f 112/115/112 113/116/113 115/117/115 f 112/115/112 115/117/115 114/118/114 f 194/119/194 126/120/126 115/117/115 f 194/119/194 115/117/115 196/121/196 f 117/122/117 112/115/112 114/118/114 f 117/122/117 114/118/114 118/123/118 f 146/124/146 117/122/117 118/123/118 f 146/124/146 118/123/118 174/125/174 f 113/116/113 127/126/127 128/127/128 f 113/116/113 128/127/128 129/128/129 f 127/126/127 120/129/120 132/130/132 f 127/126/127 132/130/132 130/131/130 f 139/132/139 138/133/138 137/134/137 f 139/132/139 137/134/137 140/135/140 f 120/129/120 144/136/144 141/137/141 f 120/129/120 141/137/141 132/130/132 f 143/138/143 141/137/141 144/136/144 f 143/138/143 144/136/144 145/139/145 f 139/132/139 135/140/135 157/141/157 f 139/132/139 157/141/157 136/142/136 f 131/143/131 134/144/134 150/145/150 f 131/143/131 150/145/150 149/146/149 f 134/144/134 157/141/157 151/147/151 f 134/144/134 151/147/151 150/145/150 f 152/148/152 153/149/153 159/150/159 f 152/148/152 159/150/159 155/151/155 f 157/141/157 158/152/158 160/153/160 f 157/141/157 160/153/160 159/150/159 f 143/138/143 145/139/145 162/154/162 f 143/138/143 162/154/162 178/155/178 f 153/149/153 151/147/151 157/141/157 f 153/149/153 157/141/157 159/150/159 f 167/156/167 161/157/161 168/158/168 f 167/156/167 168/158/168 169/159/169 f 171/160/171 190/161/190 191/162/191 f 171/160/171 191/162/191 173/163/173 f 189/164/189 148/165/148 174/125/174 f 189/164/189 174/125/174 188/166/188 f 116/167/116 179/168/179 123/169/123 f 116/167/116 123/169/123 115/117/115 f 125/170/125 179/168/179 184/171/184 f 125/170/125 184/171/184 183/172/183 f 179/168/179 116/167/116 182/173/182 f 179/168/179 182/173/182 184/171/184 f 181/174/181 126/120/126 194/119/194 f 181/174/181 194/119/194 185/175/185 f 186/176/186 201/177/201 187/178/187 f 186/176/186 187/178/187 172/179/172 f 172/179/172 191/162/191 190/161/190 f 172/179/172 190/161/190 186/176/186 f 129/128/129 208/180/208 197/181/197 f 129/128/129 197/181/197 196/121/196 f 199/182/199 147/183/147 146/124/146 f 199/182/199 146/124/146 198/184/198 f 200/185/200 162/154/162 145/139/145 f 200/185/200 145/139/145 199/182/199 f 200/186/200 225/187/225 175/188/175 f 200/186/200 175/188/175 162/189/162 f 186/176/186 190/161/190 204/190/204 f 186/176/186 204/190/204 203/191/203 f 205/192/205 210/193/210 235/194/235 f 205/192/205 235/194/235 234/195/234 f 206/196/206 207/197/207 205/192/205 f 206/196/206 205/192/205 203/191/203 f 207/198/207 206/199/206 208/180/208 f 207/198/207 208/180/208 129/128/129 f 205/192/205 207/197/207 209/200/209 f 205/192/205 209/200/209 210/193/210 f 339/201/339 219/202/219 233/203/233 f 339/201/339 233/203/233 338/204/338 f 213/205/213 212/206/212 337/207/337 f 213/205/213 337/207/337 340/208/340 f 214/209/214 215/210/215 217/211/217 f 214/209/214 217/211/217 216/212/216 f 224/213/224 211/214/211 214/209/214 f 224/213/224 214/209/214 220/215/220 f 214/209/214 216/212/216 222/216/222 f 214/209/214 222/216/222 220/215/220 f 216/212/216 260/217/260 258/218/258 f 216/212/216 258/218/258 222/216/222 f 225/187/225 221/219/221 224/213/224 f 225/187/225 224/213/224 223/220/223 f 238/221/238 226/222/226 225/187/225 f 238/221/238 225/187/225 223/220/223 f 231/223/231 213/205/213 340/208/340 f 231/223/231 340/208/340 341/224/341 f 230/225/230 231/223/231 341/224/341 f 230/225/230 341/224/341 229/226/229 f 232/227/232 213/205/213 231/223/231 f 232/227/232 231/223/231 240/228/240 f 212/206/212 213/205/213 232/227/232 f 212/206/212 232/227/232 215/210/215 f 202/229/202 233/230/233 187/178/187 f 202/229/202 187/178/187 201/177/201 f 202/231/202 337/207/337 338/204/338 f 202/231/202 338/204/338 233/203/233 f 202/229/202 201/177/201 234/195/234 f 202/229/202 234/195/234 235/194/235 f 232/227/232 240/228/240 237/232/237 f 232/227/232 237/232/237 236/233/236 f 236/233/236 237/232/237 248/234/248 f 236/233/236 248/234/248 250/235/250 f 215/210/215 232/227/232 236/233/236 f 215/210/215 236/233/236 217/211/217 f 227/236/227 226/222/226 238/221/238 f 227/236/227 238/221/238 239/237/239 f 245/238/245 227/236/227 239/237/239 f 245/238/245 239/237/239 247/239/247 f 242/240/242 206/196/206 203/191/203 f 242/240/242 203/191/203 204/190/204 f 243/241/243 181/174/181 193/242/193 f 243/241/243 193/242/193 244/243/244 f 208/180/208 242/244/242 244/243/244 f 208/180/208 244/243/244 193/242/193 f 228/245/228 245/238/245 230/246/230 f 228/245/228 230/246/230 229/247/229 f 246/248/246 237/249/237 240/250/240 f 246/248/246 240/250/240 247/239/247 f 249/251/249 253/252/253 261/253/261 f 249/251/249 261/253/261 259/254/259 f 254/255/254 246/248/246 247/239/247 f 254/255/254 247/239/247 239/237/239 f 238/221/238 255/256/255 254/255/254 f 238/221/238 254/255/254 239/237/239 f 255/256/255 238/221/238 223/220/223 f 255/256/255 223/220/223 220/215/220 f 261/253/261 262/257/262 250/235/250 f 261/253/261 250/235/250 259/254/259 f 257/258/257 260/217/260 262/257/262 f 257/258/257 262/257/262 261/253/261 f 251/259/251 257/258/257 261/253/261 f 251/259/251 261/253/261 253/252/253 f 264/260/264 263/261/263 265/262/265 f 264/260/264 265/262/265 266/263/266 f 273/264/273 283/265/283 271/266/271 f 273/264/273 271/266/271 274/267/274 f 274/267/274 265/262/265 263/261/263 f 274/267/274 263/261/263 275/268/275 f 270/269/270 284/270/284 276/271/276 f 270/269/270 276/271/276 277/272/277 f 268/273/268 271/266/271 283/265/283 f 268/273/268 283/265/283 284/270/284 f 278/274/278 279/275/279 282/276/282 f 278/274/278 282/276/282 281/277/281 f 279/275/279 273/264/273 298/278/298 f 279/275/279 298/278/298 282/276/282 f 273/264/273 274/267/274 275/268/275 f 273/264/273 275/268/275 298/278/298 f 269/279/269 402/280/402 295/281/295 f 269/279/269 295/281/295 286/282/286 f 286/282/286 295/281/295 288/283/288 f 286/282/286 288/283/288 287/284/287 f 287/284/287 288/283/288 290/285/290 f 287/284/287 290/285/290 289/286/289 f 292/287/292 289/286/289 290/285/290 f 292/287/292 290/285/290 293/288/293 f 255/289/255 256/290/256 289/286/289 f 255/289/255 289/286/289 292/287/292 f 263/261/263 254/291/254 297/292/297 f 263/261/263 297/292/297 298/278/298 f 292/287/292 293/288/293 297/292/297 f 292/287/292 297/292/297 254/291/254 f 296/293/296 387/294/387 288/283/288 f 296/293/296 288/283/288 295/281/295 f 286/282/286 251/259/251 253/252/253 f 286/282/286 253/252/253 269/279/269 f 287/284/287 289/286/289 256/290/256 f 287/284/287 256/290/256 252/295/252 f 251/259/251 286/282/286 287/284/287 f 251/259/251 287/284/287 252/295/252 f 266/296/266 267/297/267 253/252/253 f 266/296/266 253/252/253 249/251/249 f 293/288/293 291/298/291 299/299/299 f 293/288/293 299/299/299 297/292/297 f 299/299/299 291/298/291 300/300/300 f 299/299/299 300/300/300 301/301/301 f 301/302/301 300/303/300 302/304/302 f 301/302/301 302/304/302 303/305/303 f 303/305/303 302/304/302 304/306/304 f 303/305/303 304/306/304 305/307/305 f 305/307/305 304/306/304 306/308/306 f 305/307/305 306/308/306 307/309/307 f 306/308/306 308/310/308 315/311/315 f 306/308/306 315/311/315 307/309/307 f 310/312/310 314/313/314 316/314/316 f 310/312/310 316/314/316 334/315/334 f 316/314/316 317/316/317 312/317/312 f 316/314/316 312/317/312 334/315/334 f 309/318/309 336/319/336 316/314/316 f 309/318/309 316/314/316 314/313/314 f 336/319/336 311/320/311 317/316/317 f 336/319/336 317/316/317 316/314/316 f 323/321/323 327/322/327 308/310/308 f 323/321/323 308/310/308 306/308/306 f 305/307/305 319/323/319 324/324/324 f 305/307/305 324/324/324 303/305/303 f 299/299/299 301/301/301 320/325/320 f 299/299/299 320/325/320 321/326/321 f 303/305/303 324/324/324 320/327/320 f 303/305/303 320/327/320 301/302/301 f 300/300/300 291/298/291 344/328/344 f 300/300/300 344/328/344 322/329/322 f 302/304/302 300/303/300 322/330/322 f 302/304/302 322/330/322 323/321/323 f 319/323/319 315/311/315 325/331/325 f 319/323/319 325/331/325 349/332/349 f 325/331/325 315/311/315 318/333/318 f 325/331/325 318/333/318 326/334/326 f 320/327/320 324/324/324 349/332/349 f 320/327/320 349/332/349 432/335/432 f 332/336/332 308/310/308 327/322/327 f 332/336/332 327/322/327 333/337/333 f 333/337/333 327/322/327 328/338/328 f 333/337/333 328/338/328 329/339/329 f 325/331/325 326/334/326 329/340/329 f 325/331/325 329/340/329 328/341/328 f 326/334/326 318/333/318 330/342/330 f 326/334/326 330/342/330 331/343/331 f 331/344/331 330/345/330 332/336/332 f 331/344/331 332/336/332 333/337/333 f 330/342/330 345/346/345 334/315/334 f 330/342/330 334/315/334 335/347/335 f 336/319/336 346/348/346 330/345/330 f 336/319/336 330/345/330 335/349/335 f 312/317/312 313/350/313 335/347/335 f 312/317/312 335/347/335 334/315/334 f 335/349/335 313/350/313 311/320/311 f 335/349/335 311/320/311 336/319/336 f 337/207/337 212/206/212 218/351/218 f 337/207/337 218/351/218 338/204/338 f 338/204/338 218/351/218 211/214/211 f 338/204/338 211/214/211 339/201/339 f 202/231/202 235/352/235 340/208/340 f 202/231/202 340/208/340 337/207/337 f 235/352/235 210/353/210 341/224/341 f 235/352/235 341/224/341 340/208/340 f 342/354/342 290/285/290 288/283/288 f 342/354/342 288/283/288 387/294/387 f 328/338/328 327/322/327 347/355/347 f 328/338/328 347/355/347 348/356/348 f 325/331/325 328/341/328 348/357/348 f 325/331/325 348/357/348 349/332/349 f 348/356/348 347/355/347 351/358/351 f 348/356/348 351/358/351 352/359/352 f 349/332/349 348/357/348 352/360/352 f 349/332/349 352/360/352 350/361/350 f 347/355/347 323/321/323 322/330/322 f 347/355/347 322/330/322 351/358/351 f 354/362/354 344/363/344 343/364/343 f 354/362/354 343/364/343 353/365/353 f 354/362/354 353/365/353 355/366/355 f 354/362/354 355/366/355 356/367/356 f 356/367/356 355/366/355 357/368/357 f 356/367/356 357/368/357 358/369/358 f 357/368/357 359/370/359 360/371/360 f 357/368/357 360/371/360 358/369/358 f 362/372/362 361/373/361 363/374/363 f 362/372/362 363/374/363 364/375/364 f 365/376/365 366/377/366 363/374/363 f 365/376/365 363/374/363 361/373/361 f 368/378/368 369/379/369 359/370/359 f 368/378/368 359/370/359 357/368/357 f 362/372/362 371/380/371 374/381/374 f 362/372/362 374/381/374 360/371/360 f 356/367/356 372/382/372 373/383/373 f 356/367/356 373/383/373 354/362/354 f 372/382/372 360/371/360 374/381/374 f 372/382/372 374/381/374 383/384/383 f 370/385/370 369/379/369 376/386/376 f 370/385/370 376/386/376 375/387/375 f 374/381/374 371/380/371 375/388/375 f 374/381/374 375/388/375 376/389/376 f 377/390/377 379/391/379 364/375/364 f 377/390/377 364/375/364 381/392/381 f 366/377/366 380/393/380 377/394/377 f 366/377/366 377/394/377 381/395/381 f 376/386/376 369/379/369 368/378/368 f 376/386/376 368/378/368 382/396/382 f 374/381/374 376/389/376 382/397/382 f 374/381/374 382/397/382 383/384/383 f 294/398/294 342/354/342 386/399/386 f 294/398/294 386/399/386 385/400/385 f 353/365/353 343/364/343 385/401/385 f 353/365/353 385/401/385 368/378/368 f 296/293/296 295/281/295 402/280/402 f 296/293/296 402/280/402 388/402/388 f 387/294/387 296/293/296 388/402/388 f 387/294/387 388/402/388 389/403/389 f 352/404/352 351/405/351 395/406/395 f 352/404/352 395/406/395 390/407/390 f 350/408/350 352/404/352 390/407/390 f 350/408/350 390/407/390 434/409/434 f 390/407/390 395/406/395 394/410/394 f 390/407/390 394/410/394 392/411/392 f 434/409/434 390/407/390 392/411/392 f 434/409/434 392/411/392 391/412/391 f 392/411/392 394/410/394 386/399/386 f 392/411/392 386/399/386 393/413/393 f 391/412/391 392/411/392 393/413/393 f 391/412/391 393/413/393 396/414/396 f 359/370/359 369/379/369 370/385/370 f 359/370/359 370/385/370 365/376/365 f 394/415/394 395/416/395 382/396/382 f 394/415/394 382/396/382 368/378/368 f 297/292/297 321/326/321 397/417/397 f 297/292/297 397/417/397 298/278/298 f 281/277/281 282/276/282 398/418/398 f 281/277/281 398/418/398 396/419/396 f 433/420/433 391/421/391 400/422/400 f 433/420/433 400/422/400 399/423/399 f 396/419/396 398/418/398 400/422/400 f 396/419/396 400/422/400 391/421/391 f 298/278/298 397/417/397 398/418/398 f 298/278/298 398/418/398 282/276/282 f 321/326/321 403/424/403 401/425/401 f 321/326/321 401/425/401 397/417/397 f 395/426/395 384/427/384 383/384/383 f 395/426/395 383/384/383 382/397/382 f 280/428/280 281/277/281 396/419/396 f 280/428/280 396/419/396 389/429/389 f 280/428/280 389/429/389 388/430/388 f 280/428/280 388/430/388 277/272/277 f 402/431/402 270/269/270 277/272/277 f 402/431/402 277/272/277 388/430/388 f 403/432/403 404/433/404 405/434/405 f 403/432/403 405/434/405 401/435/401 f 404/433/404 407/436/407 406/437/406 f 404/433/404 406/437/406 405/434/405 f 406/437/406 407/436/407 409/438/409 f 406/437/406 409/438/409 408/439/408 f 412/440/412 410/441/410 411/442/411 f 412/440/412 411/442/411 413/443/413 f 415/444/415 410/441/410 412/440/412 f 415/444/415 412/440/412 416/445/416 f 417/446/417 406/437/406 408/439/408 f 417/446/417 408/439/408 418/447/418 f 411/442/411 409/438/409 420/448/420 f 411/442/411 420/448/420 419/449/419 f 421/450/421 422/451/422 420/448/420 f 421/450/421 420/448/420 409/438/409 f 424/452/424 423/453/423 425/454/425 f 424/452/424 425/454/425 418/447/418 f 420/448/420 425/455/425 423/456/423 f 420/448/420 423/456/423 419/449/419 f 426/457/426 430/458/430 413/443/413 f 426/457/426 413/443/413 428/459/428 f 416/445/416 430/460/430 426/461/426 f 416/445/416 426/461/426 429/462/429 f 425/454/425 431/463/431 417/446/417 f 425/454/425 417/446/417 418/447/418 f 420/448/420 422/451/422 431/464/431 f 420/448/420 431/464/431 425/455/425 f 408/439/408 415/444/415 424/452/424 f 408/439/408 424/452/424 418/447/418 f 431/463/431 435/465/435 433/466/433 f 431/463/431 433/466/433 417/446/417 f 435/467/435 431/464/431 422/451/422 f 435/467/435 422/451/422 432/468/432 f 243/469/243 244/470/244 437/471/437 f 243/469/243 437/471/437 436/472/436 f 436/472/436 437/471/437 439/473/439 f 436/472/436 439/473/439 438/474/438 f 436/472/436 438/474/438 444/475/444 f 436/472/436 444/475/444 440/476/440 f 436/472/436 440/476/440 441/477/441 f 436/472/436 441/477/441 243/469/243 f 184/171/184 243/241/243 441/478/441 f 184/171/184 441/478/441 442/479/442 f 441/477/441 440/476/440 443/480/443 f 441/477/441 443/480/443 558/481/558 f 443/480/443 440/476/440 444/475/444 f 443/480/443 444/475/444 445/482/445 f 441/478/441 558/483/558 447/484/447 f 441/478/441 447/484/447 446/485/446 f 446/485/446 447/484/447 122/486/122 f 446/485/446 122/486/122 121/487/121 f 439/473/439 437/471/437 451/488/451 f 439/473/439 451/488/451 1389/489/1389 f 451/488/451 437/471/437 244/470/244 f 451/488/451 244/470/244 242/490/242 f 1389/489/1389 451/488/451 204/491/204 f 1389/489/1389 204/491/204 1392/492/1392 f 1392/493/1392 204/494/204 171/495/171 f 1392/493/1392 171/495/171 452/496/452 f 452/496/452 171/495/171 483/497/483 f 452/496/452 483/497/483 453/498/453 f 453/498/453 483/497/483 454/499/454 f 453/498/453 454/499/454 455/500/455 f 455/500/455 454/499/454 456/501/456 f 455/500/455 456/501/456 457/502/457 f 457/502/457 456/501/456 458/503/458 f 457/502/457 458/503/458 459/504/459 f 459/504/459 458/503/458 460/505/460 f 459/504/459 460/505/460 461/506/461 f 461/506/461 460/505/460 462/507/462 f 461/506/461 462/507/462 463/508/463 f 463/508/463 462/507/462 464/509/464 f 463/508/463 464/509/464 465/510/465 f 465/510/465 464/509/464 466/511/466 f 465/510/465 466/511/466 467/512/467 f 458/503/458 456/501/456 468/513/468 f 458/503/458 468/513/468 528/514/528 f 460/505/460 458/503/458 469/515/469 f 460/505/460 469/515/469 470/516/470 f 462/507/462 460/505/460 470/516/470 f 462/507/462 470/516/470 471/517/471 f 464/509/464 462/507/462 471/517/471 f 464/509/464 471/517/471 472/518/472 f 466/511/466 464/509/464 472/518/472 f 466/511/466 472/518/472 473/519/473 f 468/513/468 456/501/456 454/499/454 f 468/513/468 454/499/454 474/520/474 f 468/513/468 474/520/474 475/521/475 f 468/513/468 475/521/475 498/522/498 f 475/521/475 474/520/474 476/523/476 f 475/521/475 476/523/476 477/524/477 f 476/523/476 474/520/474 479/525/479 f 476/523/476 479/525/479 480/526/480 f 482/527/482 479/525/479 483/497/483 f 482/527/482 483/497/483 484/528/484 f 482/527/482 484/528/484 486/529/486 f 482/527/482 486/529/486 519/530/519 f 487/531/487 488/532/488 490/533/490 f 487/531/487 490/533/490 489/534/489 f 487/531/487 489/534/489 492/535/492 f 487/531/487 492/535/492 491/536/491 f 492/535/492 489/534/489 493/537/493 f 492/535/492 493/537/493 494/538/494 f 488/532/488 498/522/498 495/539/495 f 488/532/488 495/539/495 496/540/496 f 490/533/490 488/532/488 496/540/496 f 490/533/490 496/540/496 497/541/497 f 171/495/171 173/542/173 484/528/484 f 171/495/171 484/528/484 483/497/483 f 479/525/479 474/520/474 454/499/454 f 479/525/479 454/499/454 483/497/483 f 489/534/489 490/533/490 497/541/497 f 489/534/489 497/541/497 493/537/493 f 499/543/499 475/521/475 505/544/505 f 499/543/499 505/544/505 503/545/503 f 507/546/507 502/547/502 508/548/508 f 507/546/507 508/548/508 509/549/509 f 481/550/481 519/530/519 508/548/508 f 481/550/481 508/548/508 502/547/502 f 503/545/503 514/551/514 537/552/537 f 503/545/503 537/552/537 501/553/501 f 511/554/511 510/555/510 514/551/514 f 511/554/511 514/551/514 503/545/503 f 515/556/515 486/529/486 484/528/484 f 515/556/515 484/528/484 173/542/173 f 513/557/513 514/551/514 510/555/510 f 513/557/513 510/555/510 521/558/521 f 520/559/520 542/560/542 546/561/546 f 520/559/520 546/561/546 522/562/522 f 470/516/470 469/515/469 523/563/523 f 470/516/470 523/563/523 524/564/524 f 471/517/471 470/516/470 524/564/524 f 471/517/471 524/564/524 525/565/525 f 472/518/472 471/517/471 525/565/525 f 472/518/472 525/565/525 526/566/526 f 531/567/531 491/536/491 492/535/492 f 531/567/531 492/535/492 533/568/533 f 541/569/541 515/556/515 538/570/538 f 541/569/541 538/570/538 539/571/539 f 539/571/539 540/572/540 543/573/543 f 539/571/539 543/573/543 541/569/541 f 542/560/542 545/574/545 547/575/547 f 542/560/542 547/575/547 546/561/546 f 550/576/550 551/577/551 552/578/552 f 550/576/550 552/578/552 445/482/445 f 551/577/551 549/579/549 555/580/555 f 551/577/551 555/580/555 557/581/557 f 548/582/548 600/583/600 555/580/555 f 548/582/548 555/580/555 549/579/549 f 450/584/450 568/585/568 189/164/189 f 450/584/450 189/164/189 188/166/188 f 568/585/568 572/586/572 573/587/573 f 568/585/568 573/587/573 571/588/571 f 569/589/569 578/590/578 586/591/586 f 569/589/569 586/591/586 577/592/577 f 448/593/448 564/594/564 591/595/591 f 448/593/448 591/595/591 590/596/590 f 561/597/561 743/598/743 744/599/744 f 561/597/561 744/599/744 595/600/595 f 600/583/600 593/601/593 598/602/598 f 600/583/600 598/602/598 599/603/599 f 559/604/559 599/603/599 594/605/594 f 559/604/559 594/605/594 601/606/601 f 594/605/594 598/602/598 593/601/593 f 594/605/594 593/601/593 592/607/592 f 555/608/555 600/609/600 605/610/605 f 555/608/555 605/610/605 604/611/604 f 604/611/604 590/612/590 591/613/591 f 604/611/604 591/613/591 555/608/555 f 605/610/605 600/609/600 599/614/599 f 605/610/605 599/614/599 559/615/559 f 635/616/635 930/617/930 936/618/936 f 635/616/635 936/618/936 603/619/603 f 993/620/993 994/621/994 610/622/610 f 993/620/993 610/622/610 607/623/607 f 610/622/610 995/624/995 618/625/618 f 610/622/610 618/625/618 617/626/617 f 619/627/619 620/628/620 618/625/618 f 619/627/619 618/625/618 995/624/995 f 648/629/648 618/630/618 620/631/620 f 648/629/648 620/631/620 643/632/643 f 547/575/547 545/574/545 627/633/627 f 547/575/547 627/633/627 625/634/625 f 624/635/624 628/636/628 627/633/627 f 624/635/624 627/633/627 626/637/626 f 581/638/581 628/636/628 624/635/624 f 581/638/581 624/635/624 580/639/580 f 581/640/581 610/641/610 617/642/617 f 581/640/581 617/642/617 628/643/628 f 555/608/555 591/613/591 556/644/556 f 555/608/555 556/644/556 557/645/557 f 630/646/630 629/647/629 631/648/631 f 630/646/630 631/648/631 632/649/632 f 560/650/560 630/646/630 634/651/634 f 560/650/560 634/651/634 635/652/635 f 632/649/632 631/648/631 633/653/633 f 632/649/632 633/653/633 634/651/634 f 603/654/603 638/655/638 637/656/637 f 603/654/603 637/656/637 636/657/636 f 559/615/559 638/658/638 606/659/606 f 559/615/559 606/659/606 605/610/605 f 643/632/643 644/660/644 647/661/647 f 643/632/643 647/661/647 646/662/646 f 647/661/647 644/660/644 676/663/676 f 647/661/647 676/663/676 649/664/649 f 641/665/641 640/666/640 651/667/651 f 641/665/641 651/667/651 652/668/652 f 639/669/639 641/665/641 654/670/654 f 639/669/639 654/670/654 653/671/653 f 641/665/641 652/668/652 655/672/655 f 641/665/641 655/672/655 654/670/654 f 673/673/673 653/674/653 656/675/656 f 673/673/673 656/675/656 657/676/657 f 654/670/654 655/672/655 658/677/658 f 654/670/654 658/677/658 656/678/656 f 656/675/656 662/679/662 663/680/663 f 656/675/656 663/680/663 657/676/657 f 656/678/656 658/677/658 664/681/664 f 656/678/656 664/681/664 662/682/662 f 662/679/662 665/683/665 660/684/660 f 662/679/662 660/684/660 663/680/663 f 661/685/661 665/686/665 662/682/662 f 661/685/661 662/682/662 664/681/664 f 673/673/673 657/676/657 667/687/667 f 673/673/673 667/687/667 672/688/672 f 658/677/658 655/672/655 666/689/666 f 658/677/658 666/689/666 668/690/668 f 663/680/663 660/684/660 669/691/669 f 663/680/663 669/691/669 670/692/670 f 664/681/664 658/677/658 668/690/668 f 664/681/664 668/690/668 671/693/671 f 657/676/657 663/680/663 670/692/670 f 657/676/657 670/692/670 667/687/667 f 661/685/661 664/681/664 671/693/671 f 661/685/661 671/693/671 669/691/669 f 671/693/671 668/690/668 667/687/667 f 671/693/671 667/687/667 670/692/670 f 668/690/668 674/694/674 672/688/672 f 668/690/668 672/688/672 667/687/667 f 674/694/674 666/689/666 675/695/675 f 674/694/674 675/695/675 677/696/677 f 675/695/675 666/689/666 655/672/655 f 675/695/675 655/672/655 652/668/652 f 673/673/673 672/688/672 678/697/678 f 673/673/673 678/697/678 676/698/676 f 915/699/915 679/700/679 680/701/680 f 915/699/915 680/701/680 767/702/767 f 915/699/915 682/703/682 683/704/683 f 915/699/915 683/704/683 679/700/679 f 681/705/681 680/706/680 684/707/684 f 681/705/681 684/707/684 685/708/685 f 681/705/681 685/708/685 687/709/687 f 681/705/681 687/709/687 699/710/699 f 686/711/686 683/704/683 689/712/689 f 686/711/686 689/712/689 711/713/711 f 687/709/687 690/714/690 698/715/698 f 687/709/687 698/715/698 699/710/699 f 693/716/693 694/717/694 696/718/696 f 693/716/693 696/718/696 697/719/697 f 688/720/688 701/721/701 697/719/697 f 688/720/688 697/719/697 696/718/696 f 691/722/691 688/720/688 699/710/699 f 691/722/691 699/710/699 698/715/698 f 697/719/697 701/721/701 703/723/703 f 697/719/697 703/723/703 704/724/704 f 706/725/706 689/712/689 683/704/683 f 706/725/706 683/704/683 682/703/682 f 707/726/707 708/727/708 749/728/749 f 707/726/707 749/728/749 750/729/750 f 679/700/679 683/704/683 686/711/686 f 679/700/679 686/711/686 710/730/710 f 685/708/685 684/707/684 712/731/712 f 685/708/685 712/731/712 713/732/713 f 710/730/710 686/711/686 714/733/714 f 710/730/710 714/733/714 716/734/716 f 715/735/715 687/709/687 685/708/685 f 715/735/715 685/708/685 713/732/713 f 711/713/711 690/714/690 722/736/722 f 711/713/711 722/736/722 717/737/717 f 690/714/690 687/709/687 715/735/715 f 690/714/690 715/735/715 722/736/722 f 684/738/684 710/730/710 716/734/716 f 684/738/684 716/734/716 712/739/712 f 686/711/686 711/713/711 717/737/717 f 686/711/686 717/737/717 714/733/714 f 712/739/712 716/734/716 720/740/720 f 712/739/712 720/740/720 718/741/718 f 715/735/715 713/732/713 718/742/718 f 715/735/715 718/742/718 723/743/723 f 714/733/714 717/737/717 721/744/721 f 714/733/714 721/744/721 720/740/720 f 721/744/721 717/737/717 722/736/722 f 721/744/721 722/736/722 719/745/719 f 723/743/723 719/745/719 722/736/722 f 723/743/723 722/736/722 715/735/715 f 718/742/718 724/746/724 727/747/727 f 718/742/718 727/747/727 723/743/723 f 720/740/720 721/744/721 725/748/725 f 720/740/720 725/748/725 724/749/724 f 721/744/721 719/745/719 726/750/726 f 721/744/721 726/750/726 725/748/725 f 723/743/723 727/747/727 726/750/726 f 723/743/723 726/750/726 719/745/719 f 772/751/772 729/752/729 771/753/771 f 772/751/772 771/753/771 681/705/681 f 649/754/649 676/755/676 732/756/732 f 649/754/649 732/756/732 731/757/731 f 729/758/729 700/759/700 733/760/733 f 729/758/729 733/760/733 734/761/734 f 678/762/678 730/763/730 734/761/734 f 678/762/678 734/761/734 732/756/732 f 732/756/732 737/764/737 736/765/736 f 732/756/732 736/765/736 731/757/731 f 734/761/734 733/760/733 738/766/738 f 734/761/734 738/766/738 739/767/739 f 734/761/734 739/767/739 737/764/737 f 734/761/734 737/764/737 732/756/732 f 743/598/743 561/597/561 740/768/740 f 743/598/743 740/768/740 742/769/742 f 743/598/743 603/654/603 636/657/636 f 743/598/743 636/657/636 744/599/744 f 744/599/744 596/770/596 601/606/601 f 744/599/744 601/606/601 745/771/745 f 757/772/757 752/773/752 759/774/759 f 757/772/757 759/774/759 761/775/761 f 760/776/760 757/772/757 761/775/761 f 760/776/760 761/775/761 762/777/762 f 677/778/677 921/779/921 922/780/922 f 677/778/677 922/780/922 730/781/730 f 681/705/681 696/718/696 692/782/692 f 681/705/681 692/782/692 772/751/772 f 763/783/763 758/784/758 773/785/773 f 763/783/763 773/785/773 775/786/775 f 760/776/760 762/777/762 773/785/773 f 760/776/760 773/785/773 758/784/758 f 777/787/777 754/788/754 787/789/787 f 777/787/777 787/789/787 776/790/776 f 756/791/756 782/792/782 784/793/784 f 756/791/756 784/793/784 783/794/783 f 791/795/791 794/796/794 801/797/801 f 791/795/791 801/797/801 800/798/800 f 786/799/786 781/800/781 779/801/779 f 786/799/786 779/801/779 806/802/806 f 774/803/774 799/804/799 810/805/810 f 774/803/774 810/805/810 809/806/809 f 811/807/811 807/808/807 809/806/809 f 811/807/811 809/806/809 810/805/810 f 808/809/808 811/807/811 810/805/810 f 808/809/808 810/805/810 819/810/819 f 814/811/814 808/809/808 819/810/819 f 814/811/814 819/810/819 820/812/820 f 830/813/830 822/814/822 801/797/801 f 830/813/830 801/797/801 829/815/829 f 839/816/839 838/817/838 841/818/841 f 839/816/839 841/818/841 840/819/840 f 838/817/838 839/816/839 848/820/848 f 838/817/838 848/820/848 847/821/847 f 842/822/842 838/817/838 847/821/847 f 842/822/842 847/821/847 849/823/849 f 847/821/847 848/820/848 859/824/859 f 847/821/847 859/824/859 850/825/850 f 849/823/849 847/821/847 850/825/850 f 849/823/849 850/825/850 851/826/851 f 852/827/852 845/828/845 842/822/842 f 852/827/852 842/822/842 849/823/849 f 845/828/845 852/827/852 854/829/854 f 845/828/845 854/829/854 853/830/853 f 852/827/852 873/831/873 871/832/871 f 852/827/852 871/832/871 854/829/854 f 863/833/863 825/834/825 840/819/840 f 863/833/863 840/819/840 841/818/841 f 863/833/863 841/818/841 843/835/843 f 863/833/863 843/835/843 844/836/844 f 843/835/843 862/837/862 864/838/864 f 843/835/843 864/838/864 844/836/844 f 857/839/857 855/840/855 883/841/883 f 857/839/857 883/841/883 884/842/884 f 856/843/856 857/839/857 884/842/884 f 856/843/856 884/842/884 1380/844/1380 f 869/845/869 870/846/870 871/832/871 f 869/845/869 871/832/871 873/831/873 f 851/826/851 850/825/850 855/840/855 f 851/826/851 855/840/855 857/839/857 f 881/847/881 876/848/876 877/849/877 f 881/847/881 877/849/877 868/850/868 f 877/849/877 876/848/876 878/851/878 f 877/849/877 878/851/878 879/852/879 f 879/852/879 878/851/878 892/853/892 f 879/852/879 892/853/892 880/854/880 f 881/847/881 868/850/868 883/841/883 f 881/847/881 883/841/883 882/855/882 f 868/850/868 946/856/946 884/842/884 f 868/850/868 884/842/884 883/841/883 f 887/857/887 886/858/886 890/859/890 f 887/857/887 890/859/890 891/860/891 f 885/861/885 887/857/887 891/860/891 f 885/861/885 891/860/891 889/862/889 f 896/863/896 860/864/860 888/865/888 f 896/863/896 888/865/888 895/866/895 f 878/851/878 876/848/876 893/867/893 f 878/851/878 893/867/893 892/853/892 f 876/848/876 881/847/881 894/868/894 f 876/848/876 894/868/894 893/867/893 f 881/847/881 885/861/885 889/862/889 f 881/847/881 889/862/889 894/868/894 f 875/869/875 877/849/877 879/852/879 f 875/869/875 879/852/879 880/854/880 f 895/866/895 890/859/890 886/858/886 f 895/866/895 886/858/886 896/863/896 f 861/870/861 848/820/848 839/816/839 f 861/870/861 839/816/839 927/871/927 f 825/834/825 914/872/914 913/873/913 f 825/834/825 913/873/913 840/819/840 f 520/559/520 522/562/522 521/558/521 f 520/559/520 521/558/521 510/555/510 f 615/874/615 613/875/613 897/876/897 f 615/874/615 897/876/897 898/877/898 f 901/878/901 900/879/900 898/877/898 f 901/878/901 898/877/898 897/876/897 f 615/880/615 898/881/898 903/882/903 f 615/880/615 903/882/903 902/883/902 f 903/882/903 919/884/919 910/885/910 f 903/882/903 910/885/910 908/886/908 f 902/883/902 903/882/903 908/886/908 f 902/883/902 908/886/908 907/887/907 f 675/695/675 652/668/652 904/888/904 f 675/695/675 904/888/904 905/889/905 f 905/890/905 904/891/904 906/892/906 f 905/890/905 906/892/906 909/893/909 f 910/885/910 911/894/911 907/887/907 f 910/885/910 907/887/907 908/886/908 f 910/885/910 919/884/919 909/893/909 f 910/885/910 909/893/909 911/895/911 f 913/873/913 914/872/914 915/896/915 f 913/873/913 915/896/915 916/897/916 f 912/898/912 900/899/900 916/897/916 f 912/898/912 916/897/916 915/896/915 f 914/872/914 828/900/828 827/901/827 f 914/872/914 827/901/827 682/902/682 f 768/903/768 769/904/769 918/905/918 f 768/903/768 918/905/918 917/906/917 f 912/907/912 768/903/768 917/906/917 f 912/907/912 917/906/917 919/908/919 f 921/779/921 677/778/677 675/909/675 f 921/779/921 675/909/675 923/910/923 f 905/911/905 909/912/909 923/913/923 f 905/911/905 923/913/923 675/914/675 f 919/908/919 917/906/917 923/913/923 f 919/908/919 923/913/923 909/912/909 f 768/903/768 915/915/915 767/916/767 f 768/903/768 767/916/767 924/917/924 f 930/617/930 633/918/633 932/919/932 f 930/617/930 932/919/932 931/920/931 f 853/830/853 854/829/854 934/921/934 f 853/830/853 934/921/934 935/922/935 f 854/829/854 871/832/871 933/923/933 f 854/829/854 933/923/933 953/924/953 f 930/617/930 931/920/931 937/925/937 f 930/617/930 937/925/937 936/618/936 f 853/830/853 937/925/937 846/926/846 f 853/830/853 846/926/846 845/828/845 f 953/924/953 938/927/938 954/928/954 f 953/924/953 954/928/954 934/921/934 f 941/929/941 895/866/895 888/865/888 f 941/929/941 888/865/888 938/930/938 f 939/931/939 954/932/954 938/930/938 f 939/931/939 938/930/938 888/865/888 f 861/870/861 927/871/927 928/933/928 f 861/870/861 928/933/928 939/931/939 f 939/931/939 928/933/928 901/934/901 f 939/931/939 901/934/901 954/932/954 f 890/859/890 895/866/895 941/929/941 f 890/859/890 941/929/941 940/935/940 f 892/853/892 893/867/893 942/936/942 f 892/853/892 942/936/942 1151/937/1151 f 1151/938/1151 942/939/942 944/940/944 f 1151/938/1151 944/940/944 992/941/992 f 942/939/942 943/942/943 945/943/945 f 942/939/942 945/943/945 944/940/944 f 944/940/944 948/944/948 959/945/959 f 944/940/944 959/945/959 992/941/992 f 948/944/948 944/940/944 952/946/952 f 948/944/948 952/946/952 947/947/947 f 947/947/947 950/948/950 872/949/872 f 947/947/947 872/949/872 1380/844/1380 f 951/950/951 950/948/950 947/947/947 f 951/950/951 947/947/947 952/946/952 f 945/943/945 955/951/955 956/952/956 f 945/943/945 956/952/956 951/950/951 f 870/846/870 869/845/869 872/949/872 f 870/846/870 872/949/872 950/948/950 f 951/950/951 956/952/956 870/846/870 f 951/950/951 870/846/870 950/948/950 f 940/953/940 941/954/941 955/951/955 f 940/953/940 955/951/955 945/943/945 f 955/951/955 941/954/941 938/927/938 f 955/951/955 938/927/938 953/924/953 f 954/928/954 901/955/901 899/956/899 f 954/928/954 899/956/899 934/921/934 f 949/957/949 875/869/875 957/958/957 f 949/957/949 957/958/957 958/959/958 f 949/957/949 958/959/958 979/960/979 f 949/957/949 979/960/979 959/945/959 f 961/961/961 957/958/957 880/854/880 f 961/961/961 880/854/880 960/962/960 f 963/963/963 958/959/958 957/958/957 f 963/963/963 957/958/957 962/964/962 f 1152/965/1152 964/966/964 960/962/960 f 1152/965/1152 960/962/960 880/854/880 f 1077/967/1077 962/964/962 961/961/961 f 1077/967/1077 961/961/961 1078/968/1078 f 961/961/961 960/962/960 1115/969/1115 f 961/961/961 1115/969/1115 1114/970/1114 f 963/963/963 962/964/962 965/971/965 f 963/963/963 965/971/965 966/972/966 f 960/962/960 964/966/964 1154/973/1154 f 960/962/960 1154/973/1154 1153/974/1153 f 966/972/966 965/971/965 967/975/967 f 966/972/966 967/975/967 968/976/968 f 968/976/968 967/975/967 969/977/969 f 968/976/968 969/977/969 970/978/970 f 970/978/970 969/977/969 971/979/971 f 970/978/970 971/979/971 972/980/972 f 972/980/972 971/979/971 973/981/973 f 972/980/972 973/981/973 977/982/977 f 958/959/958 1042/983/1042 1041/984/1041 f 958/959/958 1041/984/1041 979/960/979 f 966/972/966 968/976/968 981/985/981 f 966/972/966 981/985/981 980/986/980 f 972/980/972 977/982/977 983/987/983 f 972/980/972 983/987/983 981/985/981 f 983/987/983 977/982/977 975/988/975 f 983/987/983 975/988/975 982/989/982 f 986/990/986 976/991/976 974/992/974 f 986/990/986 974/992/974 984/993/984 f 975/988/975 976/991/976 986/990/986 f 975/988/975 986/990/986 985/994/985 f 987/995/987 986/990/986 984/993/984 f 987/995/987 984/993/984 1036/996/1036 f 985/994/985 986/990/986 987/995/987 f 985/994/985 987/995/987 1035/997/1035 f 979/960/979 1041/984/1041 1052/998/1052 f 979/960/979 1052/998/1052 988/999/988 f 992/941/992 959/945/959 979/960/979 f 992/941/992 979/960/979 988/999/988 f 608/1000/608 611/1001/611 994/621/994 f 608/1000/608 994/621/994 993/620/993 f 995/624/995 994/621/994 611/1001/611 f 995/624/995 611/1001/611 642/1002/642 f 1000/1003/1000 816/1004/816 814/811/814 f 1000/1003/1000 814/811/814 997/1005/997 f 830/813/830 1010/1006/1010 1009/1007/1009 f 830/813/830 1009/1007/1009 822/814/822 f 837/1008/837 832/1009/832 1010/1006/1010 f 837/1008/837 1010/1006/1010 830/813/830 f 1003/1010/1003 844/836/844 865/1011/865 f 1003/1010/1003 865/1011/865 1013/1012/1013 f 1016/1013/1016 1007/1014/1007 1022/1015/1022 f 1016/1013/1016 1022/1015/1022 1015/1016/1015 f 865/1011/865 999/1017/999 1019/1018/1019 f 865/1011/865 1019/1018/1019 1023/1019/1023 f 824/1020/824 1012/1021/1012 835/1022/835 f 824/1020/824 835/1022/835 836/1023/836 f 1028/1024/1028 1025/1025/1025 973/981/973 f 1028/1024/1028 973/981/973 971/979/971 f 1025/1025/1025 1026/1026/1026 974/992/974 f 1025/1025/1025 974/992/974 973/981/973 f 1027/1027/1027 1028/1024/1028 967/975/967 f 1027/1027/1027 967/975/967 965/971/965 f 1029/1028/1029 1030/1029/1030 983/987/983 f 1029/1028/1029 983/987/983 982/989/982 f 1031/1030/1031 1032/1031/1032 1026/1026/1026 f 1031/1030/1031 1026/1026/1026 1025/1025/1025 f 1030/1032/1030 1029/1033/1029 1032/1034/1032 f 1030/1032/1030 1032/1034/1032 1031/1035/1031 f 1033/1036/1033 1034/1037/1034 1032/1034/1032 f 1033/1036/1033 1032/1034/1032 1029/1033/1029 f 1035/1038/1035 1036/1039/1036 1034/1037/1034 f 1035/1038/1035 1034/1037/1034 1033/1036/1033 f 1039/1040/1039 1037/1041/1037 1030/1032/1030 f 1039/1040/1039 1030/1032/1030 1031/1035/1031 f 1112/1042/1112 1038/1043/1038 1037/1041/1037 f 1112/1042/1112 1037/1041/1037 1039/1040/1039 f 1028/1024/1028 1039/1044/1039 1031/1030/1031 f 1028/1024/1028 1031/1030/1031 1025/1025/1025 f 1027/1027/1027 1112/1045/1112 1039/1044/1039 f 1027/1027/1027 1039/1044/1039 1028/1024/1028 f 1038/1046/1038 980/986/980 981/985/981 f 1038/1046/1038 981/985/981 1037/1047/1037 f 1041/984/1041 1042/983/1042 1043/1048/1043 f 1041/984/1041 1043/1048/1043 1044/1049/1044 f 1044/1049/1044 1043/1048/1043 1045/1050/1045 f 1044/1049/1044 1045/1050/1045 1046/1051/1046 f 1046/1051/1046 1045/1050/1045 1047/1052/1047 f 1046/1051/1046 1047/1052/1047 1048/1053/1048 f 1041/984/1041 1044/1049/1044 1053/1054/1053 f 1041/984/1041 1053/1054/1053 1052/998/1052 f 1053/1054/1053 1048/1053/1048 1051/1055/1051 f 1053/1054/1053 1051/1055/1051 1054/1056/1054 f 1055/1057/1055 1049/1058/1049 1050/1059/1050 f 1055/1057/1055 1050/1059/1050 1056/1060/1056 f 1051/1055/1051 1049/1058/1049 1055/1057/1055 f 1051/1055/1051 1055/1057/1055 1057/1061/1057 f 1058/1062/1058 1055/1057/1055 1056/1060/1056 f 1058/1062/1058 1056/1060/1056 1059/1063/1059 f 1057/1061/1057 1055/1057/1055 1058/1062/1058 f 1057/1061/1057 1058/1062/1058 1060/1064/1060 f 1061/1065/1061 1062/1066/1062 1050/1059/1050 f 1061/1065/1061 1050/1059/1050 1047/1052/1047 f 978/1067/978 1061/1065/1061 1043/1048/1043 f 978/1067/978 1043/1048/1043 1042/983/1042 f 1063/1068/1063 1070/1069/1070 1053/1054/1053 f 1063/1068/1063 1053/1054/1053 1054/1056/1054 f 1069/1070/1069 1064/1071/1064 1062/1066/1062 f 1069/1070/1069 1062/1066/1062 1061/1065/1061 f 1070/1072/1070 1063/1073/1063 1064/1074/1064 f 1070/1072/1070 1064/1074/1064 1069/1075/1069 f 1065/1076/1065 1066/1077/1066 1064/1074/1064 f 1065/1076/1065 1064/1074/1064 1063/1073/1063 f 1067/1078/1067 1068/1079/1068 1066/1077/1066 f 1067/1078/1067 1066/1077/1066 1065/1076/1065 f 1060/1080/1060 1059/1081/1059 1068/1079/1068 f 1060/1080/1060 1068/1079/1068 1067/1078/1067 f 1071/1082/1071 1187/1083/1187 1070/1072/1070 f 1071/1082/1071 1070/1072/1070 1069/1075/1069 f 1061/1065/1061 978/1067/978 1071/1084/1071 f 1061/1065/1061 1071/1084/1071 1069/1070/1069 f 1187/1085/1187 1052/998/1052 1053/1054/1053 f 1187/1085/1187 1053/1054/1053 1070/1069/1070 f 1073/1086/1073 963/963/963 966/972/966 f 1073/1086/1073 966/972/966 980/986/980 f 1076/1087/1076 1074/1088/1074 990/1089/990 f 1076/1087/1076 990/1089/990 1187/1090/1187 f 1073/1086/1073 980/986/980 1038/1046/1038 f 1073/1086/1073 1038/1046/1038 1075/1091/1075 f 1075/1092/1075 1038/1043/1038 1112/1042/1112 f 1075/1092/1075 1112/1042/1112 1076/1087/1076 f 981/985/981 983/987/983 1030/1029/1030 f 981/985/981 1030/1029/1030 1037/1047/1037 f 1077/967/1077 1078/968/1078 1079/1093/1079 f 1077/967/1077 1079/1093/1079 1080/1094/1080 f 1080/1094/1080 1079/1093/1079 1081/1095/1081 f 1080/1094/1080 1081/1095/1081 1082/1096/1082 f 1082/1096/1082 1081/1095/1081 1083/1097/1083 f 1082/1096/1082 1083/1097/1083 1084/1098/1084 f 1084/1098/1084 1083/1097/1083 1085/1099/1085 f 1084/1098/1084 1085/1099/1085 1086/1100/1086 f 1077/967/1077 1080/1094/1080 1091/1101/1091 f 1077/967/1077 1091/1101/1091 1090/1102/1090 f 1084/1098/1084 1086/1100/1086 1092/1103/1092 f 1084/1098/1084 1092/1103/1092 1091/1101/1091 f 1092/1103/1092 1086/1100/1086 1089/1104/1089 f 1092/1103/1092 1089/1104/1089 1093/1105/1093 f 1094/1106/1094 1087/1107/1087 1088/1108/1088 f 1094/1106/1094 1088/1108/1088 1095/1109/1095 f 1089/1104/1089 1087/1107/1087 1094/1106/1094 f 1089/1104/1089 1094/1106/1094 1096/1110/1096 f 1097/1111/1097 1094/1106/1094 1095/1109/1095 f 1097/1111/1097 1095/1109/1095 1098/1112/1098 f 1096/1110/1096 1094/1106/1094 1097/1111/1097 f 1096/1110/1096 1097/1111/1097 1099/1113/1099 f 1100/1114/1100 1101/1115/1101 1085/1099/1085 f 1100/1114/1100 1085/1099/1085 1083/1097/1083 f 1101/1115/1101 1102/1116/1102 1088/1108/1088 f 1101/1115/1101 1088/1108/1088 1085/1099/1085 f 1103/1117/1103 1100/1114/1100 1079/1093/1079 f 1103/1117/1103 1079/1093/1079 1078/968/1078 f 1093/1105/1093 1104/1118/1104 1105/1119/1105 f 1093/1105/1093 1105/1119/1105 1092/1103/1092 f 1106/1120/1106 1107/1121/1107 1102/1116/1102 f 1106/1120/1106 1102/1116/1102 1101/1115/1101 f 1105/1122/1105 1104/1123/1104 1107/1124/1107 f 1105/1122/1105 1107/1124/1107 1106/1125/1106 f 1108/1126/1108 1109/1127/1109 1107/1124/1107 f 1108/1126/1108 1107/1124/1107 1104/1123/1104 f 1099/1128/1099 1098/1129/1098 1109/1127/1109 f 1099/1128/1099 1109/1127/1109 1108/1126/1108 f 1110/1130/1110 1111/1131/1111 1105/1122/1105 f 1110/1130/1110 1105/1122/1105 1106/1125/1106 f 1148/1132/1148 1112/1042/1112 1111/1131/1111 f 1148/1132/1148 1111/1131/1111 1110/1130/1110 f 1100/1114/1100 1110/1133/1110 1106/1120/1106 f 1100/1114/1100 1106/1120/1106 1101/1115/1101 f 1103/1117/1103 1148/1134/1148 1110/1133/1110 f 1103/1117/1103 1110/1133/1110 1100/1114/1100 f 1112/1045/1112 1090/1102/1090 1091/1101/1091 f 1112/1045/1112 1091/1101/1091 1111/1135/1111 f 1091/1101/1091 1092/1103/1092 1105/1119/1105 f 1091/1101/1091 1105/1119/1105 1111/1135/1111 f 1077/967/1077 1090/1102/1090 1027/1027/1027 f 1077/967/1077 1027/1027/1027 965/971/965 f 1114/970/1114 1115/969/1115 1116/1136/1116 f 1114/970/1114 1116/1136/1116 1117/1137/1117 f 1117/1137/1117 1116/1136/1116 1118/1138/1118 f 1117/1137/1117 1118/1138/1118 1119/1139/1119 f 1119/1139/1119 1118/1138/1118 1120/1140/1120 f 1119/1139/1119 1120/1140/1120 1121/1141/1121 f 1121/1141/1121 1120/1140/1120 1122/1142/1122 f 1121/1141/1121 1122/1142/1122 1123/1143/1123 f 1114/970/1114 1117/1137/1117 1128/1144/1128 f 1114/970/1114 1128/1144/1128 1127/1145/1127 f 1121/1141/1121 1123/1143/1123 1129/1146/1129 f 1121/1141/1121 1129/1146/1129 1128/1144/1128 f 1129/1146/1129 1123/1143/1123 1126/1147/1126 f 1129/1146/1129 1126/1147/1126 1130/1148/1130 f 1131/1149/1131 1124/1150/1124 1125/1151/1125 f 1131/1149/1131 1125/1151/1125 1132/1152/1132 f 1126/1147/1126 1124/1150/1124 1131/1149/1131 f 1126/1147/1126 1131/1149/1131 1133/1153/1133 f 1135/1154/1135 1136/1155/1136 1122/1142/1122 f 1135/1154/1135 1122/1142/1122 1120/1140/1120 f 1136/1155/1136 1137/1156/1137 1125/1151/1125 f 1136/1155/1136 1125/1151/1125 1122/1142/1122 f 1138/1157/1138 1135/1154/1135 1116/1136/1116 f 1138/1157/1138 1116/1136/1116 1115/969/1115 f 1139/1158/1139 1140/1159/1140 1129/1146/1129 f 1139/1158/1139 1129/1146/1129 1130/1148/1130 f 1141/1160/1141 1142/1161/1142 1137/1156/1137 f 1141/1160/1141 1137/1156/1137 1136/1155/1136 f 1140/1162/1140 1139/1163/1139 1142/1164/1142 f 1140/1162/1140 1142/1164/1142 1141/1165/1141 f 1143/1166/1143 1144/1167/1144 1142/1164/1142 f 1143/1166/1143 1142/1164/1142 1139/1163/1139 f 1145/1168/1145 1146/1169/1146 1140/1162/1140 f 1145/1168/1145 1140/1162/1140 1141/1165/1141 f 1147/1170/1147 1148/1171/1148 1146/1169/1146 f 1147/1170/1147 1146/1169/1146 1145/1168/1145 f 1135/1154/1135 1145/1172/1145 1141/1160/1141 f 1135/1154/1135 1141/1160/1141 1136/1155/1136 f 1138/1157/1138 1147/1173/1147 1145/1172/1145 f 1138/1157/1138 1145/1172/1145 1135/1154/1135 f 1148/1134/1148 1127/1145/1127 1128/1144/1128 f 1148/1134/1148 1128/1144/1128 1146/1174/1146 f 1128/1144/1128 1129/1146/1129 1140/1159/1140 f 1128/1144/1128 1140/1159/1140 1146/1174/1146 f 1103/1117/1103 1078/968/1078 1114/970/1114 f 1103/1117/1103 1114/970/1114 1127/1145/1127 f 1148/1132/1148 1074/1088/1074 1076/1087/1076 f 1148/1132/1148 1076/1087/1076 1112/1042/1112 f 1150/1175/1150 1149/1176/1149 989/1177/989 f 1150/1175/1150 989/1177/989 1074/1178/1074 f 1149/1179/1149 1152/965/1152 892/853/892 f 1149/1179/1149 892/853/892 1151/937/1151 f 964/966/964 1152/965/1152 1149/1179/1149 f 964/966/964 1149/1179/1149 1150/1180/1150 f 606/659/606 638/658/638 603/1181/603 f 606/659/606 603/1181/603 936/1182/936 f 1153/974/1153 1154/973/1154 1155/1183/1155 f 1153/974/1153 1155/1183/1155 1156/1184/1156 f 1156/1184/1156 1155/1183/1155 1157/1185/1157 f 1156/1184/1156 1157/1185/1157 1158/1186/1158 f 1158/1186/1158 1157/1185/1157 1159/1187/1159 f 1158/1186/1158 1159/1187/1159 1160/1188/1160 f 1160/1188/1160 1159/1187/1159 1161/1189/1161 f 1160/1188/1160 1161/1189/1161 1162/1190/1162 f 1153/974/1153 1156/1184/1156 1167/1191/1167 f 1153/974/1153 1167/1191/1167 1166/1192/1166 f 1160/1188/1160 1162/1190/1162 1168/1193/1168 f 1160/1188/1160 1168/1193/1168 1167/1191/1167 f 1168/1193/1168 1162/1190/1162 1165/1194/1165 f 1168/1193/1168 1165/1194/1165 1169/1195/1169 f 1170/1196/1170 1163/1197/1163 1164/1198/1164 f 1170/1196/1170 1164/1198/1164 1171/1199/1171 f 1165/1194/1165 1163/1197/1163 1170/1196/1170 f 1165/1194/1165 1170/1196/1170 1172/1200/1172 f 1174/1201/1174 1175/1202/1175 1161/1189/1161 f 1174/1201/1174 1161/1189/1161 1159/1187/1159 f 1175/1202/1175 1176/1203/1176 1164/1198/1164 f 1175/1202/1175 1164/1198/1164 1161/1189/1161 f 1177/1204/1177 1174/1201/1174 1155/1183/1155 f 1177/1204/1177 1155/1183/1155 1154/973/1154 f 1178/1205/1178 1179/1206/1179 1168/1193/1168 f 1178/1205/1178 1168/1193/1168 1169/1195/1169 f 1180/1207/1180 1181/1208/1181 1176/1203/1176 f 1180/1207/1180 1176/1203/1176 1175/1202/1175 f 1179/1209/1179 1178/1210/1178 1181/1211/1181 f 1179/1209/1179 1181/1211/1181 1180/1212/1180 f 1182/1213/1182 1183/1214/1183 1181/1211/1181 f 1182/1213/1182 1181/1211/1181 1178/1210/1178 f 1184/1215/1184 1185/1216/1185 1179/1209/1179 f 1184/1215/1184 1179/1209/1179 1180/1212/1180 f 1186/1217/1186 1147/1170/1147 1185/1216/1185 f 1186/1217/1186 1185/1216/1185 1184/1215/1184 f 1174/1201/1174 1184/1218/1184 1180/1207/1180 f 1174/1201/1174 1180/1207/1180 1175/1202/1175 f 1177/1204/1177 1186/1219/1186 1184/1218/1184 f 1177/1204/1177 1184/1218/1184 1174/1201/1174 f 1147/1173/1147 1166/1192/1166 1167/1191/1167 f 1147/1173/1147 1167/1191/1167 1185/1220/1185 f 1167/1191/1167 1168/1193/1168 1179/1206/1179 f 1167/1191/1167 1179/1206/1179 1185/1220/1185 f 1138/1157/1138 1115/969/1115 1153/974/1153 f 1138/1157/1138 1153/974/1153 1166/1192/1166 f 1074/1178/1074 1148/1171/1148 1147/1170/1147 f 1074/1178/1074 1147/1170/1147 1186/1217/1186 f 1177/1204/1177 964/966/964 1150/1180/1150 f 1177/1204/1177 1150/1180/1150 1186/1219/1186 f 963/963/963 1073/1086/1073 978/1067/978 f 963/963/963 978/1067/978 1042/983/1042 f 1075/1091/1075 1071/1084/1071 978/1067/978 f 1075/1091/1075 978/1067/978 1073/1086/1073 f 807/808/807 1189/1221/1189 1197/1222/1197 f 807/808/807 1197/1222/1197 809/806/809 f 1195/1223/1195 1196/1224/1196 1190/1225/1190 f 1195/1223/1195 1190/1225/1190 1192/1226/1192 f 812/1227/812 562/1228/562 1192/1226/1192 f 812/1227/812 1192/1226/1192 1190/1225/1190 f 1194/1229/1194 1193/1230/1193 1188/1231/1188 f 1194/1229/1194 1188/1231/1188 1191/1232/1191 f 1195/1223/1195 1191/1232/1191 1188/1231/1188 f 1195/1223/1195 1188/1231/1188 1189/1221/1189 f 1196/1224/1196 1195/1223/1195 1189/1221/1189 f 1196/1224/1196 1189/1221/1189 807/808/807 f 1200/1233/1200 1331/1234/1331 783/1235/783 f 1200/1233/1200 783/1235/783 784/1236/784 f 1202/1237/1202 1203/1238/1203 1204/1239/1204 f 1202/1237/1202 1204/1239/1204 1201/1240/1201 f 1206/1241/1206 1207/1242/1207 1205/1243/1205 f 1206/1241/1206 1205/1243/1205 1201/1240/1201 f 1206/1241/1206 1208/1244/1208 1209/1245/1209 f 1206/1241/1206 1209/1245/1209 1207/1242/1207 f 1211/1246/1211 1210/1247/1210 1202/1237/1202 f 1211/1246/1211 1202/1237/1202 1205/1243/1205 f 1212/1248/1212 1211/1246/1211 1205/1243/1205 f 1212/1248/1212 1205/1243/1205 1207/1242/1207 f 1209/1245/1209 1213/1249/1213 1212/1248/1212 f 1209/1245/1209 1212/1248/1212 1207/1242/1207 f 1202/1237/1202 1210/1247/1210 786/1250/786 f 1202/1237/1202 786/1250/786 1203/1238/1203 f 784/1251/784 1223/1252/1223 1214/1253/1214 f 784/1251/784 1214/1253/1214 1200/1254/1200 f 1218/1255/1218 1219/1256/1219 1217/1257/1217 f 1218/1255/1218 1217/1257/1217 1216/1258/1216 f 1219/1256/1219 1222/1259/1222 1215/1260/1215 f 1219/1256/1219 1215/1260/1215 1217/1257/1217 f 1222/1259/1222 1221/1261/1221 1214/1253/1214 f 1222/1259/1222 1214/1253/1214 1215/1260/1215 f 1221/1261/1221 1220/1262/1220 1200/1254/1200 f 1221/1261/1221 1200/1254/1200 1214/1253/1214 f 1215/1260/1215 1223/1252/1223 1211/1263/1211 f 1215/1260/1215 1211/1263/1211 1212/1264/1212 f 1206/1241/1206 1201/1240/1201 1225/1265/1225 f 1206/1241/1206 1225/1265/1225 1226/1266/1226 f 1206/1241/1206 1226/1266/1226 1218/1255/1218 f 1206/1241/1206 1218/1255/1218 1208/1244/1208 f 1228/1267/1228 1229/1268/1229 1198/1269/1198 f 1228/1267/1228 1198/1269/1198 1193/1230/1193 f 1233/1270/1233 1250/1271/1250 1248/1272/1248 f 1233/1270/1233 1248/1272/1248 1231/1273/1231 f 1235/1274/1235 1236/1275/1236 1232/1276/1232 f 1235/1274/1235 1232/1276/1232 1252/1277/1252 f 1230/1278/1230 1237/1279/1237 1229/1280/1229 f 1230/1278/1230 1229/1280/1229 1228/1281/1228 f 1238/1282/1238 1362/1283/1362 1237/1279/1237 f 1238/1282/1238 1237/1279/1237 1230/1278/1230 f 1242/1284/1242 1241/1285/1241 1253/1286/1253 f 1242/1284/1242 1253/1286/1253 1234/1287/1234 f 1248/1272/1248 1250/1271/1250 1251/1288/1251 f 1248/1272/1248 1251/1288/1251 1232/1276/1232 f 1236/1275/1236 1249/1289/1249 1248/1272/1248 f 1236/1275/1236 1248/1272/1248 1232/1276/1232 f 1251/1288/1251 1250/1271/1250 1247/1290/1247 f 1251/1288/1251 1247/1290/1247 1234/1287/1234 f 1252/1277/1252 1251/1288/1251 1234/1287/1234 f 1252/1277/1252 1234/1287/1234 1253/1286/1253 f 1254/1291/1254 1241/1285/1241 1242/1284/1242 f 1254/1291/1254 1242/1284/1242 1239/1292/1239 f 1261/1293/1261 1254/1291/1254 1239/1292/1239 f 1261/1293/1261 1239/1292/1239 1260/1294/1260 f 1282/1295/1282 1259/1296/1259 1260/1294/1260 f 1282/1295/1282 1260/1294/1260 1239/1292/1239 f 1259/1296/1259 1265/28/1265 1255/27/1255 f 1259/1296/1259 1255/27/1255 1260/1294/1260 f 1256/29/1256 1261/1293/1261 1260/1294/1260 f 1256/29/1256 1260/1294/1260 1255/27/1255 f 1263/1297/1263 1262/33/1262 1258/32/1258 f 1263/1297/1263 1258/32/1258 1264/1298/1264 f 1258/32/1258 1265/28/1265 1259/1296/1259 f 1258/32/1258 1259/1296/1259 1264/1298/1264 f 34/34/34 1267/1299/1267 1261/1293/1261 f 34/34/34 1261/1293/1261 1256/29/1256 f 1267/1299/1267 1266/1300/1266 1254/1291/1254 f 1267/1299/1267 1254/1291/1254 1261/1293/1261 f 1269/1301/1269 1270/1302/1270 1267/1299/1267 f 1269/1301/1269 1267/1299/1267 34/34/34 f 1267/1299/1267 1270/1302/1270 1268/1303/1268 f 1267/1299/1267 1268/1303/1268 1266/1300/1266 f 1272/1304/1272 1273/1305/1273 1270/1302/1270 f 1272/1304/1272 1270/1302/1270 1269/1301/1269 f 1273/1305/1273 1271/1306/1271 1268/1303/1268 f 1273/1305/1273 1268/1303/1268 1270/1302/1270 f 43/43/43 1274/1307/1274 1272/1304/1272 f 43/43/43 1272/1304/1272 1269/1301/1269 f 1203/1308/1203 1275/1309/1275 1276/1310/1276 f 1203/1308/1203 1276/1310/1276 1204/1311/1204 f 1277/1312/1277 1304/1313/1304 1236/1275/1236 f 1277/1312/1277 1236/1275/1236 1235/1274/1235 f 1273/1305/1273 1277/1312/1277 1235/1274/1235 f 1273/1305/1273 1235/1274/1235 1271/1306/1271 f 1329/1314/1329 1277/1312/1277 1272/1304/1272 f 1329/1314/1329 1272/1304/1272 1274/1307/1274 f 1244/1315/1244 1243/1316/1243 1245/1317/1245 f 1244/1315/1244 1245/1317/1245 1246/1318/1246 f 1278/1319/1278 1244/1315/1244 1246/1318/1246 f 1278/1319/1278 1246/1318/1246 1280/53/1280 f 1283/1320/1283 1282/1295/1282 1239/1292/1239 f 1283/1320/1283 1239/1292/1239 1242/1284/1242 f 1284/1321/1284 1283/1320/1283 1242/1284/1242 f 1284/1321/1284 1242/1284/1242 1257/1322/1257 f 1287/1323/1287 1288/1324/1288 1283/1320/1283 f 1287/1323/1287 1283/1320/1283 1284/1321/1284 f 1282/1295/1282 1283/1320/1283 1288/1324/1288 f 1282/1295/1282 1288/1324/1288 1290/1325/1290 f 1244/1315/1244 1278/1319/1278 1279/1326/1279 f 1244/1315/1244 1279/1326/1279 1285/1327/1285 f 1278/1319/1278 1291/1328/1291 1263/1297/1263 f 1278/1319/1278 1263/1297/1263 1279/1326/1279 f 1325/1329/1325 1306/1330/1306 1304/1313/1304 f 1325/1329/1325 1304/1313/1304 1277/1312/1277 f 1292/1331/1292 1330/1332/1330 1204/1311/1204 f 1292/1331/1292 1204/1311/1204 1276/1310/1276 f 1295/1333/1295 1293/1334/1293 1436/1335/1436 f 1295/1333/1295 1436/1335/1436 1437/1336/1437 f 1438/1337/1438 1297/1338/1297 1295/1333/1295 f 1438/1337/1438 1295/1333/1295 1437/1336/1437 f 1298/1339/1298 1301/1340/1301 1302/1341/1302 f 1298/1339/1298 1302/1341/1302 1299/1342/1299 f 1300/1343/1300 1302/1341/1302 1301/1340/1301 f 1300/1343/1300 1301/1340/1301 1352/1344/1352 f 1295/1333/1295 1305/1345/1305 1303/1346/1303 f 1295/1333/1295 1303/1346/1303 1293/1334/1293 f 1299/1342/1299 1354/1347/1354 1305/1345/1305 f 1299/1342/1299 1305/1345/1305 1297/1338/1297 f 1300/1343/1300 1307/1348/1307 1308/1349/1308 f 1300/1343/1300 1308/1349/1308 1302/1341/1302 f 1302/1341/1302 1308/1349/1308 1354/1347/1354 f 1302/1341/1302 1354/1347/1354 1299/1342/1299 f 1310/1350/1310 1309/1351/1309 1204/1352/1204 f 1310/1350/1310 1204/1352/1204 1311/1353/1311 f 1313/1354/1313 1312/1355/1312 1309/1351/1309 f 1313/1354/1313 1309/1351/1309 1310/1350/1310 f 1315/1356/1315 1316/1357/1316 1310/1350/1310 f 1315/1356/1315 1310/1350/1310 1311/1353/1311 f 1316/1357/1316 1317/1358/1317 1313/1354/1313 f 1316/1357/1316 1313/1354/1313 1310/1350/1310 f 1326/1359/1326 1319/1360/1319 1316/1357/1316 f 1326/1359/1326 1316/1357/1316 1315/1356/1315 f 1316/1357/1316 1319/1360/1319 1322/1361/1322 f 1316/1357/1316 1322/1361/1322 1317/1358/1317 f 1326/1359/1326 1320/1362/1320 1321/1363/1321 f 1326/1359/1326 1321/1363/1321 1319/1360/1319 f 1323/1364/1323 1312/1355/1312 1313/1354/1313 f 1323/1364/1323 1313/1354/1313 1324/1365/1324 f 1317/1358/1317 1318/1366/1318 1324/1365/1324 f 1317/1358/1317 1324/1365/1324 1313/1354/1313 f 1325/1367/1325 1328/1368/1328 1315/1356/1315 f 1325/1367/1325 1315/1356/1315 1311/1353/1311 f 1332/1369/1332 1331/1234/1331 1220/1370/1220 f 1332/1369/1332 1220/1370/1220 1224/1371/1224 f 106/1372/106 1332/1369/1332 1224/1371/1224 f 106/1372/106 1224/1371/1224 1327/1373/1327 f 1333/1374/1333 1334/1375/1334 1335/1376/1335 f 1333/1374/1333 1335/1376/1335 1338/1377/1338 f 109/65/109 1334/1375/1334 1274/1307/1274 f 109/65/109 1274/1307/1274 43/43/43 f 1315/1356/1315 1328/1368/1328 1327/1378/1327 f 1315/1356/1315 1327/1378/1327 1326/1359/1326 f 1333/1374/1333 1338/1377/1338 1337/1379/1337 f 1333/1374/1333 1337/1379/1337 1336/1380/1336 f 100/1381/100 1339/1382/1339 1340/1383/1340 f 100/1381/100 1340/1383/1340 99/1384/99 f 1339/1382/1339 1341/1385/1341 1342/1386/1342 f 1339/1382/1339 1342/1386/1342 1340/1383/1340 f 1339/1382/1339 100/1381/100 106/1387/106 f 1339/1382/1339 106/1387/106 1337/1388/1337 f 101/111/101 1341/1385/1341 1335/1389/1335 f 101/111/101 1335/1389/1335 109/112/109 f 1341/1385/1341 1339/1382/1339 1337/1388/1337 f 1341/1385/1341 1337/1388/1337 1338/1390/1338 f 1344/1391/1344 1240/1392/1240 1343/1393/1343 f 1344/1391/1344 1343/1393/1343 1271/1306/1271 f 1346/1394/1346 1345/1395/1345 1198/1396/1198 f 1346/1394/1346 1198/1396/1198 1229/1397/1229 f 1197/1398/1197 1345/1399/1345 1294/1400/1294 f 1197/1398/1197 1294/1400/1294 1275/1401/1275 f 1350/1402/1350 1296/1403/1296 1347/1404/1347 f 1350/1402/1350 1347/1404/1347 1348/1405/1348 f 1346/1394/1346 1229/1397/1229 1249/1406/1249 f 1346/1394/1346 1249/1406/1249 1439/1407/1439 f 1442/1408/1442 1440/1409/1440 1348/1405/1348 f 1442/1408/1442 1348/1405/1348 1443/1410/1443 f 1301/1411/1301 1298/1412/1298 1350/1402/1350 f 1301/1411/1301 1350/1402/1350 1351/1413/1351 f 1353/1414/1353 1352/1415/1352 1301/1411/1301 f 1353/1414/1353 1301/1411/1301 1351/1413/1351 f 1351/1413/1351 1308/1349/1308 1307/1348/1307 f 1351/1413/1351 1307/1348/1307 1353/1414/1353 f 1441/1416/1441 1308/1349/1308 1351/1413/1351 f 1441/1416/1441 1351/1413/1351 1350/1402/1350 f 1440/1409/1440 1441/1416/1441 1350/1402/1350 f 1440/1409/1440 1350/1402/1350 1348/1405/1348 f 1356/1417/1356 1357/1418/1357 1194/1229/1194 f 1356/1417/1356 1194/1229/1194 1191/1232/1191 f 90/1419/90 1358/1420/1358 1194/1229/1194 f 90/1419/90 1194/1229/1194 1357/1418/1357 f 1359/1421/1359 1360/1422/1360 1362/1283/1362 f 1359/1421/1359 1362/1283/1362 1238/1282/1238 f 1362/1283/1362 1363/1423/1363 1245/1317/1245 f 1362/1283/1362 1245/1317/1245 1233/1270/1233 f 1363/1423/1363 1364/1424/1364 1246/1318/1246 f 1363/1423/1363 1246/1318/1246 1245/1317/1245 f 1364/1424/1364 74/75/74 1280/53/1280 f 1364/1424/1364 1280/53/1280 1246/1318/1246 f 1366/1425/1366 1365/1426/1365 1364/1424/1364 f 1366/1425/1366 1364/1424/1364 1363/1423/1363 f 1365/1426/1365 77/78/77 74/75/74 f 1365/1426/1365 74/75/74 1364/1424/1364 f 1366/1425/1366 1367/1427/1367 1372/1428/1372 f 1366/1425/1366 1372/1428/1372 1365/1426/1365 f 1371/1429/1371 1368/1430/1368 1369/1431/1369 f 1371/1429/1371 1369/1431/1369 1370/1432/1370 f 1373/1433/1373 1372/1428/1372 1374/1434/1374 f 1373/1433/1373 1374/1434/1374 1375/1435/1375 f 1372/1428/1372 1373/1433/1373 88/89/88 f 1372/1428/1372 88/89/88 80/88/80 f 1374/1434/1374 1367/1427/1367 1370/1432/1370 f 1374/1434/1374 1370/1432/1370 1369/1431/1369 f 1376/1436/1376 1358/1437/1358 90/1438/90 f 1376/1436/1376 90/1438/90 91/1439/91 f 1376/1436/1376 91/1439/91 93/1440/93 f 1376/1436/1376 93/1440/93 1375/1441/1375 f 1368/1442/1368 1376/1436/1376 1377/1443/1377 f 1368/1442/1368 1377/1443/1377 1369/1444/1369 f 95/1445/95 1378/1446/1378 1375/1441/1375 f 95/1445/95 1375/1441/1375 93/1440/93 f 1373/1433/1373 1378/1447/1378 96/101/96 f 1373/1433/1373 96/101/96 88/89/88 f 948/944/948 1379/1448/1379 949/957/949 f 948/944/948 949/957/949 959/945/959 f 947/947/947 1380/844/1380 1379/1448/1379 f 947/947/947 1379/1448/1379 948/944/948 f 1381/1449/1381 1382/1450/1382 1383/1451/1383 f 1381/1449/1381 1383/1451/1383 1384/1452/1384 f 1382/1450/1382 438/1453/438 439/1454/439 f 1382/1450/1382 439/1454/439 1383/1451/1383 f 1382/1450/1382 1385/1455/1385 444/1456/444 f 1382/1450/1382 444/1456/444 438/1453/438 f 1382/1450/1382 1381/1449/1381 1386/1457/1386 f 1382/1450/1382 1386/1457/1386 1385/1455/1385 f 1386/1457/1386 1387/1458/1387 1388/1459/1388 f 1386/1457/1386 1388/1459/1388 1385/1455/1385 f 1388/1459/1388 445/1460/445 444/1456/444 f 1388/1459/1388 444/1456/444 1385/1455/1385 f 439/1454/439 1389/1461/1389 1390/1462/1390 f 439/1454/439 1390/1462/1390 1383/1451/1383 f 1390/1462/1390 1391/1463/1391 1384/1452/1384 f 1390/1462/1390 1384/1452/1384 1383/1451/1383 f 1389/1461/1389 1392/1464/1392 1393/1465/1393 f 1389/1461/1389 1393/1465/1393 1390/1462/1390 f 550/1466/550 445/1460/445 1398/1467/1398 f 550/1466/550 1398/1467/1398 1397/1468/1397 f 1397/1468/1397 1401/1469/1401 1402/1470/1402 f 1397/1468/1397 1402/1470/1402 1395/1471/1395 f 1396/1472/1396 1395/1471/1395 1402/1470/1402 f 1396/1472/1396 1402/1470/1402 1404/1473/1404 f 561/1474/561 595/1475/595 1411/1476/1411 f 561/1474/561 1411/1476/1411 1412/1477/1412 f 1404/1473/1404 1417/1478/1417 1416/1479/1416 f 1404/1473/1404 1416/1479/1416 1405/1480/1405 f 1418/1481/1418 1410/1482/1410 1409/1483/1409 f 1418/1481/1418 1409/1483/1409 1417/1478/1417 f 1409/1483/1409 1394/1484/1394 1405/1480/1405 f 1409/1483/1409 1405/1480/1405 1416/1479/1416 f 1421/1485/1421 1422/1486/1422 1423/1487/1423 f 1421/1485/1421 1423/1487/1423 1424/1488/1424 f 1425/1489/1425 1426/1490/1426 1427/1491/1427 f 1425/1489/1425 1427/1491/1427 1421/1485/1421 f 1422/1486/1422 1427/1491/1427 1428/1492/1428 f 1422/1486/1422 1428/1492/1428 1423/1487/1423 f 1429/1493/1429 1415/1494/1415 1420/1495/1420 f 1429/1493/1429 1420/1495/1420 1419/1496/1419 f 1412/1477/1412 1430/1497/1430 740/1498/740 f 1412/1477/1412 740/1498/740 561/1474/561 f 1412/1477/1412 1411/1476/1411 1415/1494/1415 f 1412/1477/1412 1415/1494/1415 1429/1493/1429 f 1411/1476/1411 745/1499/745 1410/1482/1410 f 1411/1476/1411 1410/1482/1410 1413/1500/1413 f 1434/1501/1434 111/1502/111 108/67/108 f 1434/1501/1434 108/67/108 65/66/65 f 1434/1501/1434 1435/1503/1435 107/1504/107 f 1434/1501/1434 107/1504/107 111/1502/111 f 1437/1336/1437 1436/1335/1436 1294/1400/1294 f 1437/1336/1437 1294/1400/1294 1347/1505/1347 f 1296/1506/1296 1438/1337/1438 1437/1336/1437 f 1296/1506/1296 1437/1336/1437 1347/1505/1347 f 1303/1346/1303 1439/1407/1439 1249/1406/1249 f 1303/1346/1303 1249/1406/1249 1304/1507/1304 f 1354/1347/1354 1441/1416/1441 1440/1409/1440 f 1354/1347/1354 1440/1409/1440 1305/1345/1305 f 1447/1508/1447 1449/1509/1449 1450/1510/1450 f 1447/1508/1447 1450/1510/1450 1448/1511/1448 f 1529/1512/1529 1531/1513/1531 1450/1510/1450 f 1529/1512/1529 1450/1510/1450 1461/1514/1461 f 1452/1515/1452 1453/1516/1453 1449/1509/1449 f 1452/1515/1452 1449/1509/1449 1447/1508/1447 f 1481/1517/1481 1509/1518/1509 1453/1516/1453 f 1481/1517/1481 1453/1516/1453 1452/1515/1452 f 1448/1511/1448 1464/1519/1464 1463/1520/1463 f 1448/1511/1448 1463/1520/1463 1462/1521/1462 f 1462/1521/1462 1465/1522/1465 1467/1523/1467 f 1462/1521/1462 1467/1523/1467 1455/1524/1455 f 1474/1525/1474 1475/1526/1475 1472/1527/1472 f 1474/1525/1474 1472/1527/1472 1473/1528/1473 f 1455/1524/1455 1467/1523/1467 1476/1529/1476 f 1455/1524/1455 1476/1529/1476 1479/1530/1479 f 1478/1531/1478 1480/1532/1480 1479/1530/1479 f 1478/1531/1478 1479/1530/1479 1476/1529/1476 f 1474/1525/1474 1471/1533/1471 1492/1534/1492 f 1474/1525/1474 1492/1534/1492 1470/1535/1470 f 1466/1536/1466 1484/1537/1484 1485/1538/1485 f 1466/1536/1466 1485/1538/1485 1469/1539/1469 f 1469/1539/1469 1485/1538/1485 1486/1540/1486 f 1469/1539/1469 1486/1540/1486 1492/1534/1492 f 1487/1541/1487 1490/1542/1490 1494/1543/1494 f 1487/1541/1487 1494/1543/1494 1488/1544/1488 f 1492/1534/1492 1494/1543/1494 1495/1545/1495 f 1492/1534/1492 1495/1545/1495 1493/1546/1493 f 1478/1531/1478 1513/1547/1513 1497/1548/1497 f 1478/1531/1478 1497/1548/1497 1480/1532/1480 f 1488/1544/1488 1494/1543/1494 1492/1534/1492 f 1488/1544/1488 1492/1534/1492 1486/1540/1486 f 1502/1549/1502 1504/1550/1504 1503/1551/1503 f 1502/1549/1502 1503/1551/1503 1496/1552/1496 f 1506/1553/1506 1508/1554/1508 1526/1555/1526 f 1506/1553/1506 1526/1555/1526 1525/1556/1525 f 1524/1557/1524 1523/1558/1523 1509/1518/1509 f 1524/1557/1524 1509/1518/1509 1483/1559/1483 f 1451/1560/1451 1450/1510/1450 1458/1561/1458 f 1451/1560/1451 1458/1561/1458 1514/1562/1514 f 1460/1563/1460 1518/1564/1518 1519/1565/1519 f 1460/1563/1460 1519/1565/1519 1514/1562/1514 f 1514/1562/1514 1519/1565/1519 1517/1566/1517 f 1514/1562/1514 1517/1566/1517 1451/1560/1451 f 1516/1567/1516 1520/1568/1520 1529/1512/1529 f 1516/1567/1516 1529/1512/1529 1461/1514/1461 f 1521/1569/1521 1507/1570/1507 1522/1571/1522 f 1521/1569/1521 1522/1571/1522 1536/1572/1536 f 1507/1570/1507 1521/1569/1521 1525/1556/1525 f 1507/1570/1507 1525/1556/1525 1526/1555/1526 f 1464/1519/1464 1531/1513/1531 1532/1573/1532 f 1464/1519/1464 1532/1573/1532 1542/1574/1542 f 1534/1575/1534 1533/1576/1533 1481/1517/1481 f 1534/1575/1534 1481/1517/1481 1482/1577/1482 f 1535/1578/1535 1534/1575/1534 1480/1532/1480 f 1535/1578/1535 1480/1532/1480 1497/1548/1497 f 1535/1579/1535 1497/1580/1497 1510/1581/1510 f 1535/1579/1535 1510/1581/1510 1559/1582/1559 f 1521/1569/1521 1538/1583/1538 1393/1584/1393 f 1521/1569/1521 1393/1584/1393 1525/1556/1525 f 1539/1585/1539 1568/1586/1568 1569/1587/1569 f 1539/1585/1539 1569/1587/1569 1544/1588/1544 f 1540/1589/1540 1538/1583/1538 1539/1585/1539 f 1540/1589/1540 1539/1585/1539 1541/1590/1541 f 1541/1591/1541 1464/1519/1464 1542/1574/1542 f 1541/1591/1541 1542/1574/1542 1540/1592/1540 f 1539/1585/1539 1544/1588/1544 1543/1593/1543 f 1539/1585/1539 1543/1593/1543 1541/1590/1541 f 1670/1594/1670 1669/1595/1669 1567/1596/1567 f 1670/1594/1670 1567/1596/1567 1553/1597/1553 f 1547/1598/1547 1671/1599/1671 1668/1600/1668 f 1547/1598/1547 1668/1600/1668 1546/1601/1546 f 1548/1602/1548 1550/1603/1550 1551/1604/1551 f 1548/1602/1548 1551/1604/1551 1549/1605/1549 f 1558/1606/1558 1554/1607/1554 1548/1602/1548 f 1558/1606/1558 1548/1602/1548 1545/1608/1545 f 1548/1602/1548 1554/1607/1554 1556/1609/1556 f 1548/1602/1548 1556/1609/1556 1550/1603/1550 f 1550/1603/1550 1556/1609/1556 1589/1610/1589 f 1550/1603/1550 1589/1610/1589 1591/1611/1591 f 1559/1582/1559 1557/1612/1557 1558/1606/1558 f 1559/1582/1559 1558/1606/1558 1555/1613/1555 f 1572/1614/1572 1557/1612/1557 1559/1582/1559 f 1572/1614/1572 1559/1582/1559 1560/1615/1560 f 1565/1616/1565 1672/1617/1672 1671/1599/1671 f 1565/1616/1565 1671/1599/1671 1547/1598/1547 f 1564/1618/1564 1563/1619/1563 1672/1617/1672 f 1564/1618/1564 1672/1617/1672 1565/1616/1565 f 1566/1620/1566 1574/1621/1574 1565/1616/1565 f 1566/1620/1566 1565/1616/1565 1547/1598/1547 f 1546/1601/1546 1549/1605/1549 1566/1620/1566 f 1546/1601/1546 1566/1620/1566 1547/1598/1547 f 1537/1622/1537 1536/1572/1536 1522/1571/1522 f 1537/1622/1537 1522/1571/1522 1567/1623/1567 f 1537/1624/1537 1567/1596/1567 1669/1595/1669 f 1537/1624/1537 1669/1595/1669 1668/1600/1668 f 1537/1622/1537 1569/1587/1569 1568/1586/1568 f 1537/1622/1537 1568/1586/1568 1536/1572/1536 f 1566/1620/1566 1570/1625/1570 1571/1626/1571 f 1566/1620/1566 1571/1626/1571 1574/1621/1574 f 1570/1625/1570 1581/1627/1581 1579/1628/1579 f 1570/1625/1570 1579/1628/1579 1571/1626/1571 f 1549/1605/1549 1551/1604/1551 1570/1625/1570 f 1549/1605/1549 1570/1625/1570 1566/1620/1566 f 1561/1629/1561 1573/1630/1573 1572/1614/1572 f 1561/1629/1561 1572/1614/1572 1560/1615/1560 f 1576/1631/1576 1578/1632/1578 1573/1630/1573 f 1576/1631/1576 1573/1630/1573 1561/1629/1561 f 1391/1633/1391 1393/1584/1393 1538/1583/1538 f 1391/1633/1391 1538/1583/1538 1540/1589/1540 f 1381/1634/1381 1384/1635/1384 1528/1636/1528 f 1381/1634/1381 1528/1636/1528 1516/1567/1516 f 1542/1574/1542 1528/1636/1528 1384/1635/1384 f 1542/1574/1542 1384/1635/1384 1391/1637/1391 f 1562/1638/1562 1563/1639/1563 1564/1640/1564 f 1562/1638/1562 1564/1640/1564 1576/1631/1576 f 1577/1641/1577 1578/1632/1578 1574/1642/1574 f 1577/1641/1577 1574/1642/1574 1571/1643/1571 f 1580/1644/1580 1590/1645/1590 1592/1646/1592 f 1580/1644/1580 1592/1646/1592 1584/1647/1584 f 1585/1648/1585 1573/1630/1573 1578/1632/1578 f 1585/1648/1585 1578/1632/1578 1577/1641/1577 f 1572/1614/1572 1573/1630/1573 1585/1648/1585 f 1572/1614/1572 1585/1648/1585 1586/1649/1586 f 1586/1649/1586 1554/1607/1554 1557/1612/1557 f 1586/1649/1586 1557/1612/1557 1572/1614/1572 f 1592/1646/1592 1590/1645/1590 1581/1627/1581 f 1592/1646/1592 1581/1627/1581 1593/1650/1593 f 1588/1651/1588 1592/1646/1592 1593/1650/1593 f 1588/1651/1588 1593/1650/1593 1591/1611/1591 f 1582/1652/1582 1584/1647/1584 1592/1646/1592 f 1582/1652/1582 1592/1646/1592 1588/1651/1588 f 1595/1653/1595 1597/1654/1597 1596/1655/1596 f 1595/1653/1595 1596/1655/1596 1594/1656/1594 f 1604/1657/1604 1605/1658/1605 1602/1659/1602 f 1604/1657/1604 1602/1659/1602 1614/1660/1614 f 1605/1658/1605 1606/1661/1606 1594/1656/1594 f 1605/1658/1605 1594/1656/1594 1596/1655/1596 f 1601/1662/1601 1608/1663/1608 1607/1664/1607 f 1601/1662/1601 1607/1664/1607 1615/1665/1615 f 1599/1666/1599 1615/1665/1615 1614/1660/1614 f 1599/1666/1599 1614/1660/1614 1602/1659/1602 f 1609/1667/1609 1612/1668/1612 1613/1669/1613 f 1609/1667/1609 1613/1669/1613 1610/1670/1610 f 1610/1670/1610 1613/1669/1613 1629/1671/1629 f 1610/1670/1610 1629/1671/1629 1604/1657/1604 f 1604/1657/1604 1629/1671/1629 1606/1661/1606 f 1604/1657/1604 1606/1661/1606 1605/1658/1605 f 1600/1672/1600 1617/1673/1617 1626/1674/1626 f 1600/1672/1600 1626/1674/1626 1733/1675/1733 f 1617/1673/1617 1618/1676/1618 1619/1677/1619 f 1617/1673/1617 1619/1677/1619 1626/1674/1626 f 1618/1676/1618 1620/1678/1620 1621/1679/1621 f 1618/1676/1618 1621/1679/1621 1619/1677/1619 f 1623/1680/1623 1624/1681/1624 1621/1679/1621 f 1623/1680/1623 1621/1679/1621 1620/1678/1620 f 1586/1682/1586 1623/1680/1623 1620/1678/1620 f 1586/1682/1586 1620/1678/1620 1587/1683/1587 f 1594/1656/1594 1629/1671/1629 1628/1684/1628 f 1594/1656/1594 1628/1684/1628 1585/1685/1585 f 1623/1680/1623 1585/1685/1585 1628/1684/1628 f 1623/1680/1623 1628/1684/1628 1624/1681/1624 f 1627/1686/1627 1626/1674/1626 1619/1677/1619 f 1627/1686/1627 1619/1677/1619 1718/1687/1718 f 1617/1673/1617 1600/1672/1600 1584/1647/1584 f 1617/1673/1617 1584/1647/1584 1582/1652/1582 f 1618/1676/1618 1583/1688/1583 1587/1683/1587 f 1618/1676/1618 1587/1683/1587 1620/1678/1620 f 1582/1652/1582 1583/1688/1583 1618/1676/1618 f 1582/1652/1582 1618/1676/1618 1617/1673/1617 f 1597/1689/1597 1580/1644/1580 1584/1647/1584 f 1597/1689/1597 1584/1647/1584 1598/1690/1598 f 1624/1681/1624 1628/1684/1628 1630/1691/1630 f 1624/1681/1624 1630/1691/1630 1622/1692/1622 f 1630/1691/1630 1632/1693/1632 1631/1694/1631 f 1630/1691/1630 1631/1694/1631 1622/1692/1622 f 1632/1695/1632 1634/1696/1634 1633/1697/1633 f 1632/1695/1632 1633/1697/1633 1631/1698/1631 f 1634/1696/1634 1636/1699/1636 1635/1700/1635 f 1634/1696/1634 1635/1700/1635 1633/1697/1633 f 1636/1699/1636 1638/1701/1638 1637/1702/1637 f 1636/1699/1636 1637/1702/1637 1635/1700/1635 f 1637/1702/1637 1638/1701/1638 1646/1703/1646 f 1637/1702/1637 1646/1703/1646 1639/1704/1639 f 1641/1705/1641 1665/1706/1665 1647/1707/1647 f 1641/1705/1641 1647/1707/1647 1645/1708/1645 f 1647/1707/1647 1665/1706/1665 1643/1709/1643 f 1647/1707/1647 1643/1709/1643 1648/1710/1648 f 1640/1711/1640 1645/1708/1645 1647/1707/1647 f 1640/1711/1640 1647/1707/1647 1667/1712/1667 f 1667/1712/1667 1647/1707/1647 1648/1710/1648 f 1667/1712/1667 1648/1710/1648 1642/1713/1642 f 1654/1714/1654 1637/1702/1637 1639/1704/1639 f 1654/1714/1654 1639/1704/1639 1658/1715/1658 f 1636/1699/1636 1634/1696/1634 1655/1716/1655 f 1636/1699/1636 1655/1716/1655 1650/1717/1650 f 1630/1691/1630 1652/1718/1652 1651/1719/1651 f 1630/1691/1630 1651/1719/1651 1632/1693/1632 f 1634/1696/1634 1632/1695/1632 1651/1720/1651 f 1634/1696/1634 1651/1720/1651 1655/1716/1655 f 1631/1694/1631 1653/1721/1653 1675/1722/1675 f 1631/1694/1631 1675/1722/1675 1622/1692/1622 f 1633/1697/1633 1654/1714/1654 1653/1723/1653 f 1633/1697/1633 1653/1723/1653 1631/1698/1631 f 1650/1717/1650 1680/1724/1680 1656/1725/1656 f 1650/1717/1650 1656/1725/1656 1646/1703/1646 f 1656/1725/1656 1657/1726/1657 1649/1727/1649 f 1656/1725/1656 1649/1727/1649 1646/1703/1646 f 1651/1720/1651 1763/1728/1763 1680/1724/1680 f 1651/1720/1651 1680/1724/1680 1655/1716/1655 f 1663/1729/1663 1664/1730/1664 1658/1715/1658 f 1663/1729/1663 1658/1715/1658 1639/1704/1639 f 1664/1730/1664 1660/1731/1660 1659/1732/1659 f 1664/1730/1664 1659/1732/1659 1658/1715/1658 f 1656/1725/1656 1659/1733/1659 1660/1734/1660 f 1656/1725/1656 1660/1734/1660 1657/1726/1657 f 1657/1726/1657 1662/1735/1662 1661/1736/1661 f 1657/1726/1657 1661/1736/1661 1649/1727/1649 f 1662/1737/1662 1664/1730/1664 1663/1729/1663 f 1662/1737/1662 1663/1729/1663 1661/1738/1661 f 1661/1736/1661 1666/1739/1666 1665/1706/1665 f 1661/1736/1661 1665/1706/1665 1676/1740/1676 f 1667/1712/1667 1666/1741/1666 1661/1738/1661 f 1667/1712/1667 1661/1738/1661 1677/1742/1677 f 1643/1709/1643 1665/1706/1665 1666/1739/1666 f 1643/1709/1643 1666/1739/1666 1644/1743/1644 f 1666/1741/1666 1667/1712/1667 1642/1713/1642 f 1666/1741/1666 1642/1713/1642 1644/1743/1644 f 1668/1600/1668 1669/1595/1669 1552/1744/1552 f 1668/1600/1668 1552/1744/1552 1546/1601/1546 f 1669/1595/1669 1670/1594/1670 1545/1608/1545 f 1669/1595/1669 1545/1608/1545 1552/1744/1552 f 1537/1624/1537 1668/1600/1668 1671/1599/1671 f 1537/1624/1537 1671/1599/1671 1569/1745/1569 f 1569/1745/1569 1671/1599/1671 1672/1617/1672 f 1569/1745/1569 1672/1617/1672 1544/1746/1544 f 1673/1747/1673 1718/1687/1718 1619/1677/1619 f 1673/1747/1673 1619/1677/1619 1621/1679/1621 f 1659/1732/1659 1679/1748/1679 1678/1749/1678 f 1659/1732/1659 1678/1749/1678 1658/1715/1658 f 1656/1725/1656 1680/1724/1680 1679/1750/1679 f 1656/1725/1656 1679/1750/1679 1659/1733/1659 f 1679/1748/1679 1683/1751/1683 1682/1752/1682 f 1679/1748/1679 1682/1752/1682 1678/1749/1678 f 1680/1724/1680 1681/1753/1681 1683/1754/1683 f 1680/1724/1680 1683/1754/1683 1679/1750/1679 f 1678/1749/1678 1682/1752/1682 1653/1723/1653 f 1678/1749/1678 1653/1723/1653 1654/1714/1654 f 1685/1755/1685 1684/1756/1684 1674/1757/1674 f 1685/1755/1685 1674/1757/1674 1675/1758/1675 f 1685/1755/1685 1687/1759/1687 1686/1760/1686 f 1685/1755/1685 1686/1760/1686 1684/1756/1684 f 1687/1759/1687 1689/1761/1689 1688/1762/1688 f 1687/1759/1687 1688/1762/1688 1686/1760/1686 f 1688/1762/1688 1689/1761/1689 1691/1763/1691 f 1688/1762/1688 1691/1763/1691 1690/1764/1690 f 1693/1765/1693 1695/1766/1695 1694/1767/1694 f 1693/1765/1693 1694/1767/1694 1692/1768/1692 f 1696/1769/1696 1692/1768/1692 1694/1767/1694 f 1696/1769/1696 1694/1767/1694 1697/1770/1697 f 1699/1771/1699 1688/1762/1688 1690/1764/1690 f 1699/1771/1699 1690/1764/1690 1700/1772/1700 f 1693/1765/1693 1691/1763/1691 1705/1773/1705 f 1693/1765/1693 1705/1773/1705 1702/1774/1702 f 1687/1759/1687 1685/1755/1685 1704/1775/1704 f 1687/1759/1687 1704/1775/1704 1703/1776/1703 f 1703/1776/1703 1714/1777/1714 1705/1773/1705 f 1703/1776/1703 1705/1773/1705 1691/1763/1691 f 1701/1778/1701 1706/1779/1706 1707/1780/1707 f 1701/1778/1701 1707/1780/1707 1700/1772/1700 f 1705/1773/1705 1707/1781/1707 1706/1782/1706 f 1705/1773/1705 1706/1782/1706 1702/1774/1702 f 1708/1783/1708 1712/1784/1712 1695/1766/1695 f 1708/1783/1708 1695/1766/1695 1710/1785/1710 f 1697/1770/1697 1712/1786/1712 1708/1787/1708 f 1697/1770/1697 1708/1787/1708 1711/1788/1711 f 1707/1780/1707 1713/1789/1713 1699/1771/1699 f 1707/1780/1707 1699/1771/1699 1700/1772/1700 f 1705/1773/1705 1714/1777/1714 1713/1790/1713 f 1705/1773/1705 1713/1790/1713 1707/1781/1707 f 1625/1791/1625 1716/1792/1716 1717/1793/1717 f 1625/1791/1625 1717/1793/1717 1673/1747/1673 f 1684/1756/1684 1699/1771/1699 1716/1794/1716 f 1684/1756/1684 1716/1794/1716 1674/1757/1674 f 1627/1686/1627 1719/1795/1719 1733/1675/1733 f 1627/1686/1627 1733/1675/1733 1626/1674/1626 f 1718/1687/1718 1720/1796/1720 1719/1795/1719 f 1718/1687/1718 1719/1795/1719 1627/1686/1627 f 1683/1797/1683 1721/1798/1721 1726/1799/1726 f 1683/1797/1683 1726/1799/1726 1682/1800/1682 f 1681/1801/1681 1765/1802/1765 1721/1798/1721 f 1681/1801/1681 1721/1798/1721 1683/1797/1683 f 1721/1798/1721 1723/1803/1723 1725/1804/1725 f 1721/1798/1721 1725/1804/1725 1726/1799/1726 f 1765/1802/1765 1722/1805/1722 1723/1803/1723 f 1765/1802/1765 1723/1803/1723 1721/1798/1721 f 1723/1803/1723 1724/1806/1724 1717/1793/1717 f 1723/1803/1723 1717/1793/1717 1725/1804/1725 f 1722/1805/1722 1727/1807/1727 1724/1806/1724 f 1722/1805/1722 1724/1806/1724 1723/1803/1723 f 1690/1764/1690 1696/1769/1696 1701/1778/1701 f 1690/1764/1690 1701/1778/1701 1700/1772/1700 f 1725/1808/1725 1699/1771/1699 1713/1789/1713 f 1725/1808/1725 1713/1789/1713 1726/1809/1726 f 1628/1684/1628 1629/1671/1629 1728/1810/1728 f 1628/1684/1628 1728/1810/1728 1652/1718/1652 f 1612/1668/1612 1727/1811/1727 1729/1812/1729 f 1612/1668/1612 1729/1812/1729 1613/1669/1613 f 1764/1813/1764 1730/1814/1730 1731/1815/1731 f 1764/1813/1764 1731/1815/1731 1722/1816/1722 f 1727/1811/1727 1722/1816/1722 1731/1815/1731 f 1727/1811/1727 1731/1815/1731 1729/1812/1729 f 1629/1671/1629 1613/1669/1613 1729/1812/1729 f 1629/1671/1629 1729/1812/1729 1728/1810/1728 f 1652/1718/1652 1728/1810/1728 1732/1817/1732 f 1652/1718/1652 1732/1817/1732 1734/1818/1734 f 1726/1819/1726 1713/1790/1713 1714/1777/1714 f 1726/1819/1726 1714/1777/1714 1715/1820/1715 f 1611/1821/1611 1720/1822/1720 1727/1811/1727 f 1611/1821/1611 1727/1811/1727 1612/1668/1612 f 1611/1821/1611 1608/1663/1608 1719/1823/1719 f 1611/1821/1611 1719/1823/1719 1720/1822/1720 f 1733/1824/1733 1719/1823/1719 1608/1663/1608 f 1733/1824/1733 1608/1663/1608 1601/1662/1601 f 1734/1825/1734 1732/1826/1732 1736/1827/1736 f 1734/1825/1734 1736/1827/1736 1735/1828/1735 f 1735/1828/1735 1736/1827/1736 1737/1829/1737 f 1735/1828/1735 1737/1829/1737 1738/1830/1738 f 1737/1829/1737 1739/1831/1739 1740/1832/1740 f 1737/1829/1737 1740/1832/1740 1738/1830/1738 f 1743/1833/1743 1744/1834/1744 1742/1835/1742 f 1743/1833/1743 1742/1835/1742 1741/1836/1741 f 1746/1837/1746 1747/1838/1747 1743/1833/1743 f 1746/1837/1746 1743/1833/1743 1741/1836/1741 f 1748/1839/1748 1749/1840/1749 1739/1831/1739 f 1748/1839/1748 1739/1831/1739 1737/1829/1737 f 1742/1835/1742 1750/1841/1750 1751/1842/1751 f 1742/1835/1742 1751/1842/1751 1740/1832/1740 f 1752/1843/1752 1740/1832/1740 1751/1842/1751 f 1752/1843/1752 1751/1842/1751 1753/1844/1753 f 1755/1845/1755 1749/1840/1749 1756/1846/1756 f 1755/1845/1755 1756/1846/1756 1754/1847/1754 f 1751/1842/1751 1750/1841/1750 1754/1848/1754 f 1751/1842/1751 1754/1848/1754 1756/1849/1756 f 1757/1850/1757 1759/1851/1759 1744/1834/1744 f 1757/1850/1757 1744/1834/1744 1761/1852/1761 f 1747/1838/1747 1760/1853/1760 1757/1854/1757 f 1747/1838/1747 1757/1854/1757 1761/1855/1761 f 1756/1846/1756 1749/1840/1749 1748/1839/1748 f 1756/1846/1756 1748/1839/1748 1762/1856/1762 f 1751/1842/1751 1756/1849/1756 1762/1857/1762 f 1751/1842/1751 1762/1857/1762 1753/1844/1753 f 1739/1831/1739 1749/1840/1749 1755/1845/1755 f 1739/1831/1739 1755/1845/1755 1746/1837/1746 f 1762/1856/1762 1748/1839/1748 1764/1858/1764 f 1762/1856/1762 1764/1858/1764 1766/1859/1766 f 1766/1860/1766 1763/1861/1763 1753/1844/1753 f 1766/1860/1766 1753/1844/1753 1762/1857/1762 f 1519/1565/1519 1767/1862/1767 1386/1863/1386 f 1519/1565/1519 1386/1863/1386 1381/1634/1381 f 1386/1863/1386 1768/1864/1768 1769/1865/1769 f 1386/1863/1386 1769/1865/1769 1387/1866/1387 f 1768/1864/1768 1456/1867/1456 1457/1868/1457 f 1768/1864/1768 1457/1868/1457 1769/1865/1769 f 1392/1869/1392 452/1870/452 1506/1871/1506 f 1392/1869/1392 1506/1871/1506 1393/1872/1393 f 452/1870/452 453/1873/453 1794/1874/1794 f 452/1870/452 1794/1874/1794 1506/1871/1506 f 453/1873/453 455/1875/455 1773/1876/1773 f 453/1873/453 1773/1876/1773 1794/1874/1794 f 455/1875/455 457/1877/457 1774/1878/1774 f 455/1875/455 1774/1878/1774 1773/1876/1773 f 457/1877/457 459/1879/459 1775/1880/1775 f 457/1877/457 1775/1880/1775 1774/1878/1774 f 459/1879/459 461/1881/461 1776/1882/1776 f 459/1879/459 1776/1882/1776 1775/1880/1775 f 461/1881/461 463/1883/463 1777/1884/1777 f 461/1881/461 1777/1884/1777 1776/1882/1776 f 463/1883/463 465/1885/465 1778/1886/1778 f 463/1883/463 1778/1886/1778 1777/1884/1777 f 465/1885/465 467/1887/467 1779/1888/1779 f 465/1885/465 1779/1888/1779 1778/1886/1778 f 1775/1880/1775 1829/1889/1829 1780/1890/1780 f 1775/1880/1775 1780/1890/1780 1774/1878/1774 f 1776/1882/1776 1782/1891/1782 1781/1892/1781 f 1776/1882/1776 1781/1892/1781 1775/1880/1775 f 1777/1884/1777 1783/1893/1783 1782/1891/1782 f 1777/1884/1777 1782/1891/1782 1776/1882/1776 f 1778/1886/1778 1784/1894/1784 1783/1893/1783 f 1778/1886/1778 1783/1893/1783 1777/1884/1777 f 1779/1888/1779 473/1895/473 1784/1894/1784 f 1779/1888/1779 1784/1894/1784 1778/1886/1778 f 1780/1890/1780 1785/1896/1785 1773/1876/1773 f 1780/1890/1780 1773/1876/1773 1774/1878/1774 f 1780/1890/1780 1806/1897/1806 1786/1898/1786 f 1780/1890/1780 1786/1898/1786 1785/1896/1785 f 1786/1898/1786 1788/1899/1788 1787/1900/1787 f 1786/1898/1786 1787/1900/1787 1785/1896/1785 f 1787/1900/1787 1791/1901/1791 1790/1902/1790 f 1787/1900/1787 1790/1902/1790 1785/1896/1785 f 1793/1903/1793 1795/1904/1795 1794/1874/1794 f 1793/1903/1793 1794/1874/1794 1790/1902/1790 f 1793/1903/1793 1826/1905/1826 1797/1906/1797 f 1793/1903/1793 1797/1906/1797 1795/1904/1795 f 1798/1907/1798 1800/1908/1800 1801/1909/1801 f 1798/1907/1798 1801/1909/1801 1799/1910/1799 f 1798/1907/1798 1802/1911/1802 1803/1912/1803 f 1798/1907/1798 1803/1912/1803 1800/1908/1800 f 1803/1912/1803 494/1913/494 493/1914/493 f 1803/1912/1803 493/1914/493 1800/1908/1800 f 1799/1910/1799 1804/1915/1804 495/1916/495 f 1799/1910/1799 495/1916/495 1806/1897/1806 f 1801/1909/1801 1805/1917/1805 1804/1915/1804 f 1801/1909/1801 1804/1915/1804 1799/1910/1799 f 1506/1871/1506 1794/1874/1794 1795/1904/1795 f 1506/1871/1506 1795/1904/1795 1508/1918/1508 f 1790/1902/1790 1794/1874/1794 1773/1876/1773 f 1790/1902/1790 1773/1876/1773 1785/1896/1785 f 1800/1908/1800 493/1914/493 1805/1917/1805 f 1800/1908/1800 1805/1917/1805 1801/1909/1801 f 1807/1919/1807 1811/1920/1811 1813/1921/1813 f 1807/1919/1807 1813/1921/1813 1786/1898/1786 f 1815/1922/1815 1817/1923/1817 1816/1924/1816 f 1815/1922/1815 1816/1924/1816 1810/1925/1810 f 1792/1926/1792 1810/1925/1810 1816/1924/1816 f 1792/1926/1792 1816/1924/1816 1826/1905/1826 f 1811/1920/1811 1809/1927/1809 1833/1928/1833 f 1811/1920/1811 1833/1928/1833 1821/1929/1821 f 1819/1930/1819 1811/1920/1811 1821/1929/1821 f 1819/1930/1819 1821/1929/1821 1818/1931/1818 f 1822/1932/1822 1508/1918/1508 1795/1904/1795 f 1822/1932/1822 1795/1904/1795 1797/1906/1797 f 513/1933/513 521/1934/521 1818/1931/1818 f 513/1933/513 1818/1931/1818 1821/1929/1821 f 1827/1935/1827 522/1936/522 546/1937/546 f 1827/1935/1827 546/1937/546 1838/1938/1838 f 1782/1891/1782 524/1939/524 523/1940/523 f 1782/1891/1782 523/1940/523 1781/1892/1781 f 1783/1893/1783 525/1941/525 524/1939/524 f 1783/1893/1783 524/1939/524 1782/1891/1782 f 1784/1894/1784 526/1942/526 525/1941/525 f 1784/1894/1784 525/1941/525 1783/1893/1783 f 1831/1943/1831 1832/1944/1832 1803/1912/1803 f 1831/1943/1831 1803/1912/1803 1802/1911/1802 f 1837/1945/1837 1835/1946/1835 1834/1947/1834 f 1837/1945/1837 1834/1947/1834 1822/1932/1822 f 1835/1946/1835 1837/1945/1837 1839/1948/1839 f 1835/1946/1835 1839/1948/1839 1836/1949/1836 f 1838/1938/1838 546/1937/546 547/1950/547 f 1838/1938/1838 547/1950/547 1841/1951/1841 f 1772/1952/1772 1523/1558/1523 1524/1557/1524 f 1772/1952/1772 1524/1557/1524 1847/1953/1847 f 1847/1953/1847 1850/1954/1850 1852/1955/1852 f 1847/1953/1847 1852/1955/1852 1851/1956/1851 f 1848/1957/1848 1856/1958/1856 1865/1959/1865 f 1848/1957/1848 1865/1959/1865 1857/1960/1857 f 1770/1961/1770 1869/1962/1869 1870/1963/1870 f 1770/1961/1770 1870/1963/1870 1843/1964/1843 f 1402/1965/1402 1871/1966/1871 1872/1967/1872 f 1402/1965/1402 1872/1967/1872 1404/1968/1404 f 1871/1966/1871 1402/1965/1402 1870/1969/1870 f 1871/1966/1871 1870/1969/1870 1869/1970/1869 f 1872/1967/1872 1418/1971/1418 1417/1972/1417 f 1872/1967/1872 1417/1972/1417 1404/1968/1404 f 1426/1973/1426 1429/1974/1429 2164/1975/2164 f 1426/1973/1426 2164/1975/2164 2158/1976/2158 f 2221/1977/2221 1874/1978/1874 1877/1979/1877 f 2221/1977/2221 1877/1979/1877 2222/1980/2222 f 1877/1979/1877 1884/1981/1884 1885/1982/1885 f 1877/1979/1877 1885/1982/1885 2223/1983/2223 f 1886/1984/1886 2223/1983/2223 1885/1982/1885 f 1886/1984/1886 1885/1982/1885 1887/1985/1887 f 1901/1986/1901 1898/1987/1898 1887/1988/1887 f 1901/1986/1901 1887/1988/1887 1885/1989/1885 f 547/1950/547 625/1990/625 1892/1991/1892 f 547/1950/547 1892/1991/1892 1841/1951/1841 f 1890/1992/1890 1891/1993/1891 1892/1991/1892 f 1890/1992/1890 1892/1991/1892 1893/1994/1893 f 1860/1995/1860 1859/1996/1859 1890/1992/1890 f 1860/1995/1860 1890/1992/1890 1893/1994/1893 f 1860/1997/1860 1893/1998/1893 1884/1999/1884 f 1860/1997/1860 1884/1999/1884 1877/2000/1877 f 1402/1965/1402 1401/2001/1401 1403/2002/1403 f 1402/1965/1402 1403/2002/1403 1870/1969/1870 f 1418/1971/1418 1872/1967/1872 1873/2003/1873 f 1418/1971/1418 1873/2003/1873 1419/2004/1419 f 1898/1987/1898 646/2005/646 647/2006/647 f 1898/1987/1898 647/2006/647 1899/2007/1899 f 647/2006/647 649/2008/649 1928/2009/1928 f 647/2006/647 1928/2009/1928 1899/2007/1899 f 1896/2010/1896 1904/2011/1904 1903/2012/1903 f 1896/2010/1896 1903/2012/1903 1895/2013/1895 f 1894/2014/1894 1905/2015/1905 1906/2016/1906 f 1894/2014/1894 1906/2016/1906 1896/2010/1896 f 1896/2010/1896 1906/2016/1906 1907/2017/1907 f 1896/2010/1896 1907/2017/1907 1904/2011/1904 f 1925/2018/1925 1909/2019/1909 1908/2020/1908 f 1925/2018/1925 1908/2020/1908 1905/2021/1905 f 1906/2016/1906 1908/2022/1908 1910/2023/1910 f 1906/2016/1906 1910/2023/1910 1907/2017/1907 f 1908/2020/1908 1909/2019/1909 1915/2024/1915 f 1908/2020/1908 1915/2024/1915 1914/2025/1914 f 1908/2022/1908 1914/2026/1914 1916/2027/1916 f 1908/2022/1908 1916/2027/1916 1910/2023/1910 f 1914/2025/1914 1915/2024/1915 1912/2028/1912 f 1914/2025/1914 1912/2028/1912 1917/2029/1917 f 1913/2030/1913 1916/2027/1916 1914/2026/1914 f 1913/2030/1913 1914/2026/1914 1917/2031/1917 f 1925/2018/1925 1924/2032/1924 1919/2033/1919 f 1925/2018/1925 1919/2033/1919 1909/2019/1909 f 1910/2023/1910 1920/2034/1920 1918/2035/1918 f 1910/2023/1910 1918/2035/1918 1907/2017/1907 f 1915/2024/1915 1922/2036/1922 1921/2037/1921 f 1915/2024/1915 1921/2037/1921 1912/2028/1912 f 1916/2027/1916 1923/2038/1923 1920/2034/1920 f 1916/2027/1916 1920/2034/1920 1910/2023/1910 f 1909/2019/1909 1919/2033/1919 1922/2036/1922 f 1909/2019/1909 1922/2036/1922 1915/2024/1915 f 1913/2030/1913 1921/2037/1921 1923/2038/1923 f 1913/2030/1913 1923/2038/1923 1916/2027/1916 f 1923/2038/1923 1922/2036/1922 1919/2033/1919 f 1923/2038/1923 1919/2033/1919 1920/2034/1920 f 1920/2034/1920 1919/2033/1919 1924/2032/1924 f 1920/2034/1920 1924/2032/1924 1926/2039/1926 f 1926/2039/1926 1929/2040/1929 1927/2041/1927 f 1926/2039/1926 1927/2041/1927 1918/2035/1918 f 1927/2041/1927 1904/2011/1904 1907/2017/1907 f 1927/2041/1927 1907/2017/1907 1918/2035/1918 f 1925/2018/1925 1928/2042/1928 1930/2043/1930 f 1925/2018/1925 1930/2043/1930 1924/2032/1924 f 2143/2044/2143 2000/2045/2000 1932/2046/1932 f 2143/2044/2143 1932/2046/1932 1931/2047/1931 f 2143/2044/2143 1931/2047/1931 1935/2048/1935 f 2143/2044/2143 1935/2048/1935 1934/2049/1934 f 1933/2050/1933 1937/2051/1937 1936/2052/1936 f 1933/2050/1933 1936/2052/1936 1932/2053/1932 f 1933/2050/1933 1949/2054/1949 1939/2055/1939 f 1933/2050/1933 1939/2055/1939 1937/2051/1937 f 1938/2056/1938 1960/2057/1960 1941/2058/1941 f 1938/2056/1938 1941/2058/1941 1935/2048/1935 f 1939/2055/1939 1949/2054/1949 1948/2059/1948 f 1939/2055/1939 1948/2059/1948 1942/2060/1942 f 1944/2061/1944 1947/2062/1947 1946/2063/1946 f 1944/2061/1944 1946/2063/1946 1945/2064/1945 f 1940/2065/1940 1946/2063/1946 1947/2062/1947 f 1940/2065/1940 1947/2062/1947 1950/2066/1950 f 1943/2067/1943 1948/2059/1948 1949/2054/1949 f 1943/2067/1943 1949/2054/1949 1940/2065/1940 f 1947/2062/1947 1953/2068/1953 1952/2069/1952 f 1947/2062/1947 1952/2069/1952 1950/2066/1950 f 1955/2070/1955 1934/2049/1934 1935/2048/1935 f 1955/2070/1955 1935/2048/1935 1941/2058/1941 f 1956/2071/1956 1986/2072/1986 1985/2073/1985 f 1956/2071/1956 1985/2073/1985 1957/2074/1957 f 1931/2047/1931 1959/2075/1959 1938/2056/1938 f 1931/2047/1931 1938/2056/1938 1935/2048/1935 f 1937/2051/1937 1962/2076/1962 1961/2077/1961 f 1937/2051/1937 1961/2077/1961 1936/2052/1936 f 1959/2075/1959 1965/2078/1965 1963/2079/1963 f 1959/2075/1959 1963/2079/1963 1938/2056/1938 f 1964/2080/1964 1962/2076/1962 1937/2051/1937 f 1964/2080/1964 1937/2051/1937 1939/2055/1939 f 1960/2057/1960 1966/2081/1966 1971/2082/1971 f 1960/2057/1960 1971/2082/1971 1942/2060/1942 f 1942/2060/1942 1971/2082/1971 1964/2080/1964 f 1942/2060/1942 1964/2080/1964 1939/2055/1939 f 1936/2083/1936 1961/2084/1961 1965/2078/1965 f 1936/2083/1936 1965/2078/1965 1959/2075/1959 f 1938/2056/1938 1963/2079/1963 1966/2081/1966 f 1938/2056/1938 1966/2081/1966 1960/2057/1960 f 1961/2084/1961 1967/2085/1967 1969/2086/1969 f 1961/2084/1961 1969/2086/1969 1965/2078/1965 f 1964/2080/1964 1972/2087/1972 1967/2088/1967 f 1964/2080/1964 1967/2088/1967 1962/2076/1962 f 1963/2079/1963 1969/2086/1969 1970/2089/1970 f 1963/2079/1963 1970/2089/1970 1966/2081/1966 f 1970/2089/1970 1968/2090/1968 1971/2082/1971 f 1970/2089/1970 1971/2082/1971 1966/2081/1966 f 1972/2087/1972 1964/2080/1964 1971/2082/1971 f 1972/2087/1972 1971/2082/1971 1968/2090/1968 f 1967/2088/1967 1972/2087/1972 1976/2091/1976 f 1967/2088/1967 1976/2091/1976 1973/2092/1973 f 1969/2086/1969 1973/2093/1973 1974/2094/1974 f 1969/2086/1969 1974/2094/1974 1970/2089/1970 f 1970/2089/1970 1974/2094/1974 1975/2095/1975 f 1970/2089/1970 1975/2095/1975 1968/2090/1968 f 1972/2087/1972 1968/2090/1968 1975/2095/1975 f 1972/2087/1972 1975/2095/1975 1976/2091/1976 f 2005/2096/2005 1933/2050/1933 2004/2097/2004 f 2005/2096/2005 2004/2097/2004 1978/2098/1978 f 649/2099/649 731/2100/731 1980/2101/1980 f 649/2099/649 1980/2101/1980 1928/2102/1928 f 1978/2103/1978 1981/2104/1981 733/2105/733 f 1978/2103/1978 733/2105/733 700/2106/700 f 1930/2107/1930 1980/2101/1980 1981/2104/1981 f 1930/2107/1930 1981/2104/1981 1979/2108/1979 f 1980/2101/1980 731/2100/731 736/2109/736 f 1980/2101/1980 736/2109/736 1982/2110/1982 f 1981/2104/1981 1983/2111/1983 738/2112/738 f 1981/2104/1981 738/2112/738 733/2105/733 f 1981/2104/1981 1980/2101/1980 1982/2110/1982 f 1981/2104/1981 1982/2110/1982 1983/2111/1983 f 1990/2113/1990 1994/2114/1994 1992/2115/1992 f 1990/2113/1990 1992/2115/1992 1987/2116/1987 f 1993/2117/1993 1995/2118/1995 1994/2114/1994 f 1993/2117/1993 1994/2114/1994 1990/2113/1990 f 1929/2119/1929 1979/2120/1979 2150/2121/2150 f 1929/2119/1929 2150/2121/2150 2149/2122/2149 f 1933/2050/1933 2005/2096/2005 692/2123/692 f 1933/2050/1933 692/2123/692 1946/2063/1946 f 1996/2124/1996 2008/2125/2008 2006/2126/2006 f 1996/2124/1996 2006/2126/2006 1991/2127/1991 f 1993/2117/1993 1991/2127/1991 2006/2126/2006 f 1993/2117/1993 2006/2126/2006 1995/2118/1995 f 777/2128/777 2009/2129/2009 2018/2130/2018 f 777/2128/777 2018/2130/2018 754/2131/754 f 756/2132/756 783/2133/783 2015/2134/2015 f 756/2132/756 2015/2134/2015 2014/2135/2014 f 2022/2136/2022 2031/2137/2031 2032/2138/2032 f 2022/2136/2022 2032/2138/2032 2025/2139/2025 f 2017/2140/2017 2037/2141/2037 2011/2142/2011 f 2017/2140/2017 2011/2142/2011 2013/2143/2013 f 2007/2144/2007 2040/2145/2040 2041/2146/2041 f 2007/2144/2007 2041/2146/2041 2030/2147/2030 f 2042/2148/2042 2041/2146/2041 2040/2145/2040 f 2042/2148/2042 2040/2145/2040 2038/2149/2038 f 2039/2150/2039 2048/2151/2048 2041/2146/2041 f 2039/2150/2039 2041/2146/2041 2042/2148/2042 f 2043/2152/2043 2049/2153/2049 2048/2151/2048 f 2043/2152/2043 2048/2151/2048 2039/2150/2039 f 2059/2154/2059 2058/2155/2058 2032/2138/2032 f 2059/2154/2059 2032/2138/2032 2051/2156/2051 f 2068/2157/2068 2069/2158/2069 2070/2159/2070 f 2068/2157/2068 2070/2159/2070 2067/2160/2067 f 2067/2160/2067 2076/2161/2076 2077/2162/2077 f 2067/2160/2067 2077/2162/2077 2068/2157/2068 f 2071/2163/2071 2078/2164/2078 2076/2161/2076 f 2071/2163/2071 2076/2161/2076 2067/2160/2067 f 2076/2161/2076 2079/2165/2079 2088/2166/2088 f 2076/2161/2076 2088/2166/2088 2077/2162/2077 f 2078/2164/2078 2080/2167/2080 2079/2165/2079 f 2078/2164/2078 2079/2165/2079 2076/2161/2076 f 2081/2168/2081 2078/2164/2078 2071/2163/2071 f 2081/2168/2081 2071/2163/2071 2074/2169/2074 f 2074/2169/2074 2082/2170/2082 2083/2171/2083 f 2074/2169/2074 2083/2171/2083 2081/2168/2081 f 2081/2168/2081 2083/2171/2083 2099/2172/2099 f 2081/2168/2081 2099/2172/2099 2101/2173/2101 f 2092/2174/2092 2070/2159/2070 2069/2158/2069 f 2092/2174/2092 2069/2158/2069 2054/2175/2054 f 2092/2174/2092 2073/2176/2073 2072/2177/2072 f 2092/2174/2092 2072/2177/2072 2070/2159/2070 f 2072/2177/2072 2073/2176/2073 2093/2178/2093 f 2072/2177/2072 2093/2178/2093 2091/2179/2091 f 2086/2180/2086 2112/2181/2112 2111/2182/2111 f 2086/2180/2086 2111/2182/2111 2084/2183/2084 f 2085/2184/2085 2511/2185/2511 2112/2181/2112 f 2085/2184/2085 2112/2181/2112 2086/2180/2086 f 2097/2186/2097 2101/2173/2101 2099/2172/2099 f 2097/2186/2097 2099/2172/2099 2098/2187/2098 f 2080/2167/2080 2086/2180/2086 2084/2183/2084 f 2080/2167/2080 2084/2183/2084 2079/2165/2079 f 2109/2188/2109 2096/2189/2096 2105/2190/2105 f 2109/2188/2109 2105/2190/2105 2104/2191/2104 f 2105/2190/2105 2107/2192/2107 2106/2193/2106 f 2105/2190/2105 2106/2193/2106 2104/2191/2104 f 2107/2192/2107 2108/2194/2108 2120/2195/2120 f 2107/2192/2107 2120/2195/2120 2106/2193/2106 f 2109/2188/2109 2110/2196/2110 2111/2182/2111 f 2109/2188/2109 2111/2182/2111 2096/2189/2096 f 2096/2189/2096 2111/2182/2111 2112/2181/2112 f 2096/2189/2096 2112/2181/2112 2174/2197/2174 f 2115/2198/2115 2119/2199/2119 2118/2200/2118 f 2115/2198/2115 2118/2200/2118 2114/2201/2114 f 2113/2202/2113 2117/2203/2117 2119/2199/2119 f 2113/2202/2113 2119/2199/2119 2115/2198/2115 f 2124/2204/2124 2123/2205/2123 2116/2206/2116 f 2124/2204/2124 2116/2206/2116 2089/2207/2089 f 2106/2193/2106 2120/2195/2120 2121/2208/2121 f 2106/2193/2106 2121/2208/2121 2104/2191/2104 f 2104/2191/2104 2121/2208/2121 2122/2209/2122 f 2104/2191/2104 2122/2209/2122 2109/2188/2109 f 2109/2188/2109 2122/2209/2122 2117/2203/2117 f 2109/2188/2109 2117/2203/2117 2113/2202/2113 f 2103/2210/2103 2108/2194/2108 2107/2192/2107 f 2103/2210/2103 2107/2192/2107 2105/2190/2105 f 2123/2205/2123 2124/2204/2124 2114/2201/2114 f 2123/2205/2123 2114/2201/2114 2118/2200/2118 f 2090/2211/2090 2155/2212/2155 2068/2157/2068 f 2090/2211/2090 2068/2157/2068 2077/2162/2077 f 2054/2175/2054 2069/2158/2069 2141/2213/2141 f 2054/2175/2054 2141/2213/2141 2142/2214/2142 f 1827/1935/1827 1818/1931/1818 521/1934/521 f 1827/1935/1827 521/1934/521 522/1936/522 f 1882/2215/1882 2126/2216/2126 2125/2217/2125 f 1882/2215/1882 2125/2217/2125 1880/2218/1880 f 2129/2219/2129 2125/2217/2125 2126/2216/2126 f 2129/2219/2129 2126/2216/2126 2128/2220/2128 f 1882/2221/1882 2130/2222/2130 2131/2223/2131 f 1882/2221/1882 2131/2223/2131 2126/2224/2126 f 2131/2223/2131 2136/2225/2136 2138/2226/2138 f 2131/2223/2131 2138/2226/2138 2147/2227/2147 f 2130/2222/2130 2135/2228/2135 2136/2225/2136 f 2130/2222/2130 2136/2225/2136 2131/2223/2131 f 1927/2041/1927 2133/2229/2133 2132/2230/2132 f 1927/2041/1927 2132/2230/2132 1904/2011/1904 f 2133/2231/2133 2137/2232/2137 2134/2233/2134 f 2133/2231/2133 2134/2233/2134 2132/2234/2132 f 2138/2226/2138 2136/2225/2136 2135/2228/2135 f 2138/2226/2138 2135/2228/2135 2139/2235/2139 f 2138/2226/2138 2139/2236/2139 2137/2232/2137 f 2138/2226/2138 2137/2232/2137 2147/2227/2147 f 2141/2213/2141 2144/2237/2144 2143/2238/2143 f 2141/2213/2141 2143/2238/2143 2142/2214/2142 f 2140/2239/2140 2143/2238/2143 2144/2237/2144 f 2140/2239/2140 2144/2237/2144 2128/2240/2128 f 2142/2214/2142 1934/2241/1934 2056/2242/2056 f 2142/2214/2142 2056/2242/2056 2057/2243/2057 f 2001/2244/2001 2145/2245/2145 2146/2246/2146 f 2001/2244/2001 2146/2246/2146 2002/2247/2002 f 2140/2248/2140 2147/2249/2147 2145/2245/2145 f 2140/2248/2140 2145/2245/2145 2001/2244/2001 f 2149/2122/2149 2151/2250/2151 1927/2251/1927 f 2149/2122/2149 1927/2251/1927 1929/2119/1929 f 2147/2249/2147 2137/2252/2137 2151/2253/2151 f 2147/2249/2147 2151/2253/2151 2145/2245/2145 f 2133/2254/2133 1927/2255/1927 2151/2253/2151 f 2133/2254/2133 2151/2253/2151 2137/2252/2137 f 2001/2244/2001 2152/2256/2152 2000/2257/2000 f 2001/2244/2001 2000/2257/2000 2143/2258/2143 f 2158/1976/2158 2159/2259/2159 2160/2260/2160 f 2158/1976/2158 2160/2260/2160 1428/2261/1428 f 2082/2170/2082 2163/2262/2163 2162/2263/2162 f 2082/2170/2082 2162/2263/2162 2083/2171/2083 f 2083/2171/2083 2181/2264/2181 2161/2265/2161 f 2083/2171/2083 2161/2265/2161 2099/2172/2099 f 2158/1976/2158 2164/1975/2164 2165/2266/2165 f 2158/1976/2158 2165/2266/2165 2159/2259/2159 f 2082/2170/2082 2074/2169/2074 2075/2267/2075 f 2082/2170/2082 2075/2267/2075 2165/2266/2165 f 2181/2264/2181 2162/2263/2162 2182/2268/2182 f 2181/2264/2181 2182/2268/2182 2166/2269/2166 f 2169/2270/2169 2166/2271/2166 2116/2206/2116 f 2169/2270/2169 2116/2206/2116 2123/2205/2123 f 2167/2272/2167 2116/2206/2116 2166/2271/2166 f 2167/2272/2167 2166/2271/2166 2182/2273/2182 f 2090/2211/2090 2167/2272/2167 2156/2274/2156 f 2090/2211/2090 2156/2274/2156 2155/2212/2155 f 2167/2272/2167 2182/2273/2182 2129/2275/2129 f 2167/2272/2167 2129/2275/2129 2156/2274/2156 f 2118/2200/2118 2168/2276/2168 2169/2270/2169 f 2118/2200/2118 2169/2270/2169 2123/2205/2123 f 2120/2195/2120 2379/2277/2379 2170/2278/2170 f 2120/2195/2120 2170/2278/2170 2121/2208/2121 f 2379/2279/2379 2220/2280/2220 2172/2281/2172 f 2379/2279/2379 2172/2281/2172 2170/2282/2170 f 2170/2282/2170 2172/2281/2172 2173/2283/2173 f 2170/2282/2170 2173/2283/2173 2171/2284/2171 f 2172/2281/2172 2220/2280/2220 2187/2285/2187 f 2172/2281/2172 2187/2285/2187 2176/2286/2176 f 2176/2286/2176 2175/2287/2175 2180/2288/2180 f 2176/2286/2176 2180/2288/2180 2172/2281/2172 f 2175/2287/2175 2511/2185/2511 2100/2289/2100 f 2175/2287/2175 2100/2289/2100 2178/2290/2178 f 2179/2291/2179 2180/2288/2180 2175/2287/2175 f 2179/2291/2179 2175/2287/2175 2178/2290/2178 f 2173/2283/2173 2179/2291/2179 2184/2292/2184 f 2173/2283/2173 2184/2292/2184 2183/2293/2183 f 2098/2187/2098 2178/2290/2178 2100/2289/2100 f 2098/2187/2098 2100/2289/2100 2097/2186/2097 f 2179/2291/2179 2178/2290/2178 2098/2187/2098 f 2179/2291/2179 2098/2187/2098 2184/2292/2184 f 2168/2294/2168 2173/2283/2173 2183/2293/2183 f 2168/2294/2168 2183/2293/2183 2169/2295/2169 f 2183/2293/2183 2181/2264/2181 2166/2269/2166 f 2183/2293/2183 2166/2269/2166 2169/2295/2169 f 2182/2268/2182 2162/2263/2162 2127/2296/2127 f 2182/2268/2182 2127/2296/2127 2129/2297/2129 f 2177/2298/2177 2186/2299/2186 2185/2300/2185 f 2177/2298/2177 2185/2300/2185 2103/2210/2103 f 2177/2298/2177 2187/2285/2187 2207/2301/2207 f 2177/2298/2177 2207/2301/2207 2186/2299/2186 f 2189/2302/2189 2188/2303/2188 2108/2194/2108 f 2189/2302/2189 2108/2194/2108 2185/2300/2185 f 2191/2304/2191 2190/2305/2190 2185/2300/2185 f 2191/2304/2191 2185/2300/2185 2186/2299/2186 f 2380/2306/2380 2108/2194/2108 2188/2303/2188 f 2380/2306/2380 2188/2303/2188 2192/2307/2192 f 2305/2308/2305 2306/2309/2306 2189/2302/2189 f 2305/2308/2305 2189/2302/2189 2190/2305/2190 f 2189/2302/2189 2342/2310/2342 2343/2311/2343 f 2189/2302/2189 2343/2311/2343 2188/2303/2188 f 2191/2304/2191 2194/2312/2194 2193/2313/2193 f 2191/2304/2191 2193/2313/2193 2190/2305/2190 f 2188/2303/2188 2381/2314/2381 2382/2315/2382 f 2188/2303/2188 2382/2315/2382 2192/2307/2192 f 2194/2312/2194 2196/2316/2196 2195/2317/2195 f 2194/2312/2194 2195/2317/2195 2193/2313/2193 f 2196/2316/2196 2198/2318/2198 2197/2319/2197 f 2196/2316/2196 2197/2319/2197 2195/2317/2195 f 2198/2318/2198 2200/2320/2200 2199/2321/2199 f 2198/2318/2198 2199/2321/2199 2197/2319/2197 f 2200/2320/2200 2205/2322/2205 2201/2323/2201 f 2200/2320/2200 2201/2323/2201 2199/2321/2199 f 2186/2299/2186 2207/2301/2207 2269/2324/2269 f 2186/2299/2186 2269/2324/2269 2270/2325/2270 f 2194/2312/2194 2208/2326/2208 2209/2327/2209 f 2194/2312/2194 2209/2327/2209 2196/2316/2196 f 2200/2320/2200 2209/2327/2209 2211/2328/2211 f 2200/2320/2200 2211/2328/2211 2205/2322/2205 f 2211/2328/2211 2210/2329/2210 2203/2330/2203 f 2211/2328/2211 2203/2330/2203 2205/2322/2205 f 2214/2331/2214 2212/2332/2212 2202/2333/2202 f 2214/2331/2214 2202/2333/2202 2204/2334/2204 f 2203/2330/2203 2213/2335/2213 2214/2331/2214 f 2203/2330/2203 2214/2331/2214 2204/2334/2204 f 2215/2336/2215 2264/2337/2264 2212/2332/2212 f 2215/2336/2215 2212/2332/2212 2214/2331/2214 f 2213/2335/2213 2263/2338/2263 2215/2336/2215 f 2213/2335/2213 2215/2336/2215 2214/2331/2214 f 2207/2301/2207 2216/2339/2216 2280/2340/2280 f 2207/2301/2207 2280/2340/2280 2269/2324/2269 f 2220/2280/2220 2216/2339/2216 2207/2301/2207 f 2220/2280/2220 2207/2301/2207 2187/2285/2187 f 1875/2341/1875 2221/1977/2221 2222/1980/2222 f 1875/2341/1875 2222/1980/2222 1878/2342/1878 f 2223/1983/2223 1897/2343/1897 1878/2342/1878 f 2223/1983/2223 1878/2342/1878 2222/1980/2222 f 2228/2344/2228 2225/2345/2225 2043/2152/2043 f 2228/2344/2228 2043/2152/2043 2045/2346/2045 f 2059/2154/2059 2051/2156/2051 2237/2347/2237 f 2059/2154/2059 2237/2347/2237 2238/2348/2238 f 2066/2349/2066 2059/2154/2059 2238/2348/2238 f 2066/2349/2066 2238/2348/2238 2061/2350/2061 f 2231/2351/2231 2241/2352/2241 2094/2353/2094 f 2231/2351/2231 2094/2353/2094 2073/2176/2073 f 2244/2354/2244 2243/2355/2243 2250/2356/2250 f 2244/2354/2244 2250/2356/2250 2235/2357/2235 f 2094/2353/2094 2251/2358/2251 2247/2359/2247 f 2094/2353/2094 2247/2359/2247 2227/2360/2227 f 2053/2361/2053 2065/2362/2065 2064/2363/2064 f 2053/2361/2053 2064/2363/2064 2240/2364/2240 f 2256/2365/2256 2199/2321/2199 2201/2323/2201 f 2256/2365/2256 2201/2323/2201 2253/2366/2253 f 2253/2366/2253 2201/2323/2201 2202/2333/2202 f 2253/2366/2253 2202/2333/2202 2254/2367/2254 f 2255/2368/2255 2193/2313/2193 2195/2317/2195 f 2255/2368/2255 2195/2317/2195 2256/2365/2256 f 2257/2369/2257 2210/2329/2210 2211/2328/2211 f 2257/2369/2257 2211/2328/2211 2258/2370/2258 f 2259/2371/2259 2253/2366/2253 2254/2367/2254 f 2259/2371/2259 2254/2367/2254 2260/2372/2260 f 2258/2373/2258 2259/2374/2259 2260/2375/2260 f 2258/2373/2258 2260/2375/2260 2257/2376/2257 f 2261/2377/2261 2257/2376/2257 2260/2375/2260 f 2261/2377/2261 2260/2375/2260 2262/2378/2262 f 2263/2379/2263 2261/2377/2261 2262/2378/2262 f 2263/2379/2263 2262/2378/2262 2264/2380/2264 f 2267/2381/2267 2259/2374/2259 2258/2373/2258 f 2267/2381/2267 2258/2373/2258 2265/2382/2265 f 2340/2383/2340 2267/2381/2267 2265/2382/2265 f 2340/2383/2340 2265/2382/2265 2266/2384/2266 f 2256/2365/2256 2253/2366/2253 2259/2371/2259 f 2256/2365/2256 2259/2371/2259 2267/2385/2267 f 2255/2368/2255 2256/2365/2256 2267/2385/2267 f 2255/2368/2255 2267/2385/2267 2340/2386/2340 f 2266/2387/2266 2265/2388/2265 2209/2327/2209 f 2266/2387/2266 2209/2327/2209 2208/2326/2208 f 2269/2324/2269 2272/2389/2272 2271/2390/2271 f 2269/2324/2269 2271/2390/2271 2270/2325/2270 f 2272/2389/2272 2274/2391/2274 2273/2392/2273 f 2272/2389/2272 2273/2392/2273 2271/2390/2271 f 2274/2391/2274 2276/2393/2276 2275/2394/2275 f 2274/2391/2274 2275/2394/2275 2273/2392/2273 f 2269/2324/2269 2280/2340/2280 2281/2395/2281 f 2269/2324/2269 2281/2395/2281 2272/2389/2272 f 2281/2395/2281 2282/2396/2282 2279/2397/2279 f 2281/2395/2281 2279/2397/2279 2276/2393/2276 f 2283/2398/2283 2284/2399/2284 2278/2400/2278 f 2283/2398/2283 2278/2400/2278 2277/2401/2277 f 2279/2397/2279 2285/2402/2285 2283/2398/2283 f 2279/2397/2279 2283/2398/2283 2277/2401/2277 f 2286/2403/2286 2287/2404/2287 2284/2399/2284 f 2286/2403/2286 2284/2399/2284 2283/2398/2283 f 2285/2402/2285 2288/2405/2288 2286/2403/2286 f 2285/2402/2285 2286/2403/2286 2283/2398/2283 f 2289/2406/2289 2275/2394/2275 2278/2400/2278 f 2289/2406/2289 2278/2400/2278 2290/2407/2290 f 2206/2408/2206 2270/2325/2270 2271/2390/2271 f 2206/2408/2206 2271/2390/2271 2289/2406/2289 f 2291/2409/2291 2282/2396/2282 2281/2395/2281 f 2291/2409/2291 2281/2395/2281 2298/2410/2298 f 2297/2411/2297 2289/2406/2289 2290/2407/2290 f 2297/2411/2297 2290/2407/2290 2292/2412/2292 f 2298/2413/2298 2297/2414/2297 2292/2415/2292 f 2298/2413/2298 2292/2415/2292 2291/2416/2291 f 2293/2417/2293 2291/2416/2291 2292/2415/2292 f 2293/2417/2293 2292/2415/2292 2294/2418/2294 f 2295/2419/2295 2293/2417/2293 2294/2418/2294 f 2295/2419/2295 2294/2418/2294 2296/2420/2296 f 2288/2421/2288 2295/2419/2295 2296/2420/2296 f 2288/2421/2288 2296/2420/2296 2287/2422/2287 f 2299/2423/2299 2297/2414/2297 2298/2413/2298 f 2299/2423/2299 2298/2413/2298 2415/2424/2415 f 2289/2406/2289 2297/2411/2297 2299/2425/2299 f 2289/2406/2289 2299/2425/2299 2206/2408/2206 f 2415/2426/2415 2298/2410/2298 2281/2395/2281 f 2415/2426/2415 2281/2395/2281 2280/2340/2280 f 2301/2427/2301 2208/2326/2208 2194/2312/2194 f 2301/2427/2301 2194/2312/2194 2191/2304/2191 f 2304/2428/2304 2415/2429/2415 2218/2430/2218 f 2304/2428/2304 2218/2430/2218 2302/2431/2302 f 2301/2427/2301 2303/2432/2303 2266/2387/2266 f 2301/2427/2301 2266/2387/2266 2208/2326/2208 f 2303/2433/2303 2304/2428/2304 2340/2383/2340 f 2303/2433/2303 2340/2383/2340 2266/2384/2266 f 2209/2327/2209 2265/2388/2265 2258/2370/2258 f 2209/2327/2209 2258/2370/2258 2211/2328/2211 f 2305/2308/2305 2308/2434/2308 2307/2435/2307 f 2305/2308/2305 2307/2435/2307 2306/2309/2306 f 2308/2434/2308 2310/2436/2310 2309/2437/2309 f 2308/2434/2308 2309/2437/2309 2307/2435/2307 f 2310/2436/2310 2312/2438/2312 2311/2439/2311 f 2310/2436/2310 2311/2439/2311 2309/2437/2309 f 2312/2438/2312 2314/2440/2314 2313/2441/2313 f 2312/2438/2312 2313/2441/2313 2311/2439/2311 f 2305/2308/2305 2318/2442/2318 2319/2443/2319 f 2305/2308/2305 2319/2443/2319 2308/2434/2308 f 2312/2438/2312 2319/2443/2319 2320/2444/2320 f 2312/2438/2312 2320/2444/2320 2314/2440/2314 f 2320/2444/2320 2321/2445/2321 2317/2446/2317 f 2320/2444/2320 2317/2446/2317 2314/2440/2314 f 2322/2447/2322 2323/2448/2323 2316/2449/2316 f 2322/2447/2322 2316/2449/2316 2315/2450/2315 f 2317/2446/2317 2324/2451/2324 2322/2447/2322 f 2317/2446/2317 2322/2447/2322 2315/2450/2315 f 2325/2452/2325 2326/2453/2326 2323/2448/2323 f 2325/2452/2325 2323/2448/2323 2322/2447/2322 f 2324/2451/2324 2327/2454/2327 2325/2452/2325 f 2324/2451/2324 2325/2452/2325 2322/2447/2322 f 2328/2455/2328 2311/2439/2311 2313/2441/2313 f 2328/2455/2328 2313/2441/2313 2329/2456/2329 f 2329/2456/2329 2313/2441/2313 2316/2449/2316 f 2329/2456/2329 2316/2449/2316 2330/2457/2330 f 2331/2458/2331 2306/2309/2306 2307/2435/2307 f 2331/2458/2331 2307/2435/2307 2328/2455/2328 f 2321/2445/2321 2320/2444/2320 2333/2459/2333 f 2321/2445/2321 2333/2459/2333 2332/2460/2332 f 2334/2461/2334 2329/2456/2329 2330/2457/2330 f 2334/2461/2334 2330/2457/2330 2335/2462/2335 f 2333/2463/2333 2334/2464/2334 2335/2465/2335 f 2333/2463/2333 2335/2465/2335 2332/2466/2332 f 2336/2467/2336 2332/2466/2332 2335/2465/2335 f 2336/2467/2336 2335/2465/2335 2337/2468/2337 f 2327/2469/2327 2336/2467/2336 2337/2468/2337 f 2327/2469/2327 2337/2468/2337 2326/2470/2326 f 2338/2471/2338 2334/2464/2334 2333/2463/2333 f 2338/2471/2338 2333/2463/2333 2339/2472/2339 f 2376/2473/2376 2338/2471/2338 2339/2472/2339 f 2376/2473/2376 2339/2472/2339 2340/2383/2340 f 2328/2455/2328 2329/2456/2329 2334/2461/2334 f 2328/2455/2328 2334/2461/2334 2338/2474/2338 f 2331/2458/2331 2328/2455/2328 2338/2474/2338 f 2331/2458/2331 2338/2474/2338 2376/2475/2376 f 2340/2386/2340 2339/2476/2339 2319/2443/2319 f 2340/2386/2340 2319/2443/2319 2318/2442/2318 f 2319/2443/2319 2339/2476/2339 2333/2459/2333 f 2319/2443/2319 2333/2459/2333 2320/2444/2320 f 2305/2308/2305 2193/2313/2193 2255/2368/2255 f 2305/2308/2305 2255/2368/2255 2318/2442/2318 f 2342/2310/2342 2345/2477/2345 2344/2478/2344 f 2342/2310/2342 2344/2478/2344 2343/2311/2343 f 2345/2477/2345 2347/2479/2347 2346/2480/2346 f 2345/2477/2345 2346/2480/2346 2344/2478/2344 f 2347/2479/2347 2349/2481/2349 2348/2482/2348 f 2347/2479/2347 2348/2482/2348 2346/2480/2346 f 2349/2481/2349 2351/2483/2351 2350/2484/2350 f 2349/2481/2349 2350/2484/2350 2348/2482/2348 f 2342/2310/2342 2355/2485/2355 2356/2486/2356 f 2342/2310/2342 2356/2486/2356 2345/2477/2345 f 2349/2481/2349 2356/2486/2356 2357/2487/2357 f 2349/2481/2349 2357/2487/2357 2351/2483/2351 f 2357/2487/2357 2358/2488/2358 2354/2489/2354 f 2357/2487/2357 2354/2489/2354 2351/2483/2351 f 2359/2490/2359 2360/2491/2360 2353/2492/2353 f 2359/2490/2359 2353/2492/2353 2352/2493/2352 f 2354/2489/2354 2361/2494/2361 2359/2490/2359 f 2354/2489/2354 2359/2490/2359 2352/2493/2352 f 2363/2495/2363 2348/2482/2348 2350/2484/2350 f 2363/2495/2363 2350/2484/2350 2364/2496/2364 f 2364/2496/2364 2350/2484/2350 2353/2492/2353 f 2364/2496/2364 2353/2492/2353 2365/2497/2365 f 2366/2498/2366 2343/2311/2343 2344/2478/2344 f 2366/2498/2366 2344/2478/2344 2363/2495/2363 f 2367/2499/2367 2358/2488/2358 2357/2487/2357 f 2367/2499/2367 2357/2487/2357 2368/2500/2368 f 2369/2501/2369 2364/2496/2364 2365/2497/2365 f 2369/2501/2369 2365/2497/2365 2370/2502/2370 f 2368/2503/2368 2369/2504/2369 2370/2505/2370 f 2368/2503/2368 2370/2505/2370 2367/2506/2367 f 2371/2507/2371 2367/2506/2367 2370/2505/2370 f 2371/2507/2371 2370/2505/2370 2372/2508/2372 f 2373/2509/2373 2369/2504/2369 2368/2503/2368 f 2373/2509/2373 2368/2503/2368 2374/2510/2374 f 2375/2511/2375 2373/2509/2373 2374/2510/2374 f 2375/2511/2375 2374/2510/2374 2376/2512/2376 f 2363/2495/2363 2364/2496/2364 2369/2501/2369 f 2363/2495/2363 2369/2501/2369 2373/2513/2373 f 2366/2498/2366 2363/2495/2363 2373/2513/2373 f 2366/2498/2366 2373/2513/2373 2375/2514/2375 f 2376/2475/2376 2374/2515/2374 2356/2486/2356 f 2376/2475/2376 2356/2486/2356 2355/2485/2355 f 2356/2486/2356 2374/2515/2374 2368/2500/2368 f 2356/2486/2356 2368/2500/2368 2357/2487/2357 f 2331/2458/2331 2355/2485/2355 2342/2310/2342 f 2331/2458/2331 2342/2310/2342 2306/2309/2306 f 2376/2473/2376 2340/2383/2340 2304/2428/2304 f 2376/2473/2376 2304/2428/2304 2302/2431/2302 f 2378/2516/2378 2302/2517/2302 2217/2518/2217 f 2378/2516/2378 2217/2518/2217 2377/2519/2377 f 2377/2520/2377 2379/2277/2379 2120/2195/2120 f 2377/2520/2377 2120/2195/2120 2380/2306/2380 f 2192/2307/2192 2378/2521/2378 2377/2520/2377 f 2192/2307/2192 2377/2520/2377 2380/2306/2380 f 1873/2003/1873 2164/2522/2164 1429/2523/1429 f 1873/2003/1873 1429/2523/1429 1419/2004/1419 f 2381/2314/2381 2384/2524/2384 2383/2525/2383 f 2381/2314/2381 2383/2525/2383 2382/2315/2382 f 2384/2524/2384 2386/2526/2386 2385/2527/2385 f 2384/2524/2384 2385/2527/2385 2383/2525/2383 f 2386/2526/2386 2388/2528/2388 2387/2529/2387 f 2386/2526/2386 2387/2529/2387 2385/2527/2385 f 2388/2528/2388 2390/2530/2390 2389/2531/2389 f 2388/2528/2388 2389/2531/2389 2387/2529/2387 f 2381/2314/2381 2394/2532/2394 2395/2533/2395 f 2381/2314/2381 2395/2533/2395 2384/2524/2384 f 2388/2528/2388 2395/2533/2395 2396/2534/2396 f 2388/2528/2388 2396/2534/2396 2390/2530/2390 f 2396/2534/2396 2397/2535/2397 2393/2536/2393 f 2396/2534/2396 2393/2536/2393 2390/2530/2390 f 2398/2537/2398 2399/2538/2399 2392/2539/2392 f 2398/2537/2398 2392/2539/2392 2391/2540/2391 f 2393/2536/2393 2400/2541/2400 2398/2537/2398 f 2393/2536/2393 2398/2537/2398 2391/2540/2391 f 2402/2542/2402 2387/2529/2387 2389/2531/2389 f 2402/2542/2402 2389/2531/2389 2403/2543/2403 f 2403/2543/2403 2389/2531/2389 2392/2539/2392 f 2403/2543/2403 2392/2539/2392 2404/2544/2404 f 2405/2545/2405 2382/2315/2382 2383/2525/2383 f 2405/2545/2405 2383/2525/2383 2402/2542/2402 f 2406/2546/2406 2397/2535/2397 2396/2534/2396 f 2406/2546/2406 2396/2534/2396 2407/2547/2407 f 2408/2548/2408 2403/2543/2403 2404/2544/2404 f 2408/2548/2408 2404/2544/2404 2409/2549/2409 f 2407/2550/2407 2408/2551/2408 2409/2552/2409 f 2407/2550/2407 2409/2552/2409 2406/2553/2406 f 2410/2554/2410 2406/2553/2406 2409/2552/2409 f 2410/2554/2410 2409/2552/2409 2411/2555/2411 f 2412/2556/2412 2408/2551/2408 2407/2550/2407 f 2412/2556/2412 2407/2550/2407 2413/2557/2413 f 2414/2558/2414 2412/2556/2412 2413/2557/2413 f 2414/2558/2414 2413/2557/2413 2375/2511/2375 f 2402/2542/2402 2403/2543/2403 2408/2548/2408 f 2402/2542/2402 2408/2548/2408 2412/2559/2412 f 2405/2545/2405 2402/2542/2402 2412/2559/2412 f 2405/2545/2405 2412/2559/2412 2414/2560/2414 f 2375/2514/2375 2413/2561/2413 2395/2533/2395 f 2375/2514/2375 2395/2533/2395 2394/2532/2394 f 2395/2533/2395 2413/2561/2413 2407/2547/2407 f 2395/2533/2395 2407/2547/2407 2396/2534/2396 f 2366/2498/2366 2394/2532/2394 2381/2314/2381 f 2366/2498/2366 2381/2314/2381 2343/2311/2343 f 2302/2517/2302 2414/2558/2414 2375/2511/2375 f 2302/2517/2302 2375/2511/2375 2376/2512/2376 f 2405/2545/2405 2414/2560/2414 2378/2521/2378 f 2405/2545/2405 2378/2521/2378 2192/2307/2192 f 2191/2304/2191 2270/2325/2270 2206/2408/2206 f 2191/2304/2191 2206/2408/2206 2301/2427/2301 f 2303/2432/2303 2301/2427/2301 2206/2408/2206 f 2303/2432/2303 2206/2408/2206 2299/2425/2299 f 2038/2149/2038 2040/2145/2040 2425/2562/2425 f 2038/2149/2038 2425/2562/2425 2417/2563/2417 f 2423/2564/2423 2420/2565/2420 2418/2566/2418 f 2423/2564/2423 2418/2566/2418 2424/2567/2424 f 1406/2568/1406 2418/2566/2418 2420/2565/2420 f 1406/2568/1406 2420/2565/2420 562/2569/562 f 2422/2570/2422 2419/2571/2419 2416/2572/2416 f 2422/2570/2422 2416/2572/2416 2421/2573/2421 f 2423/2564/2423 2417/2563/2417 2416/2572/2416 f 2423/2564/2423 2416/2572/2416 2419/2571/2419 f 2424/2567/2424 2038/2149/2038 2417/2563/2417 f 2424/2567/2424 2417/2563/2417 2423/2564/2423 f 2428/2574/2428 2015/2575/2015 783/2576/783 f 2428/2574/2428 783/2576/783 1331/2577/1331 f 2430/2578/2430 2429/2579/2429 2432/2580/2432 f 2430/2578/2430 2432/2580/2432 2431/2581/2431 f 2434/2582/2434 2429/2579/2429 2433/2583/2433 f 2434/2582/2434 2433/2583/2433 2435/2584/2435 f 2434/2582/2434 2435/2584/2435 2437/2585/2437 f 2434/2582/2434 2437/2585/2437 2436/2586/2436 f 2439/2587/2439 2433/2583/2433 2430/2578/2430 f 2439/2587/2439 2430/2578/2430 2438/2588/2438 f 2440/2589/2440 2435/2584/2435 2433/2583/2433 f 2440/2589/2440 2433/2583/2433 2439/2587/2439 f 2437/2585/2437 2435/2584/2435 2440/2589/2440 f 2437/2585/2437 2440/2589/2440 2441/2590/2441 f 2430/2578/2430 2431/2581/2431 2017/2591/2017 f 2430/2578/2430 2017/2591/2017 2438/2588/2438 f 2015/2592/2015 2428/2593/2428 2442/2594/2442 f 2015/2592/2015 2442/2594/2442 2451/2595/2451 f 2446/2596/2446 2444/2597/2444 2445/2598/2445 f 2446/2596/2446 2445/2598/2445 2447/2599/2447 f 2447/2599/2447 2445/2598/2445 2443/2600/2443 f 2447/2599/2447 2443/2600/2443 2450/2601/2450 f 2450/2601/2450 2443/2600/2443 2442/2594/2442 f 2450/2601/2450 2442/2594/2442 2449/2602/2449 f 2449/2602/2449 2442/2594/2442 2428/2593/2428 f 2449/2602/2449 2428/2593/2428 2448/2603/2448 f 2443/2600/2443 2440/2604/2440 2439/2605/2439 f 2443/2600/2443 2439/2605/2439 2451/2595/2451 f 2434/2582/2434 2454/2606/2454 2453/2607/2453 f 2434/2582/2434 2453/2607/2453 2429/2579/2429 f 2434/2582/2434 2436/2586/2436 2446/2596/2446 f 2434/2582/2434 2446/2596/2446 2454/2606/2454 f 14/2608/14 2421/2573/2421 2426/2609/2426 f 14/2608/14 2426/2609/2426 1/2610/1 f 2431/2611/2431 2432/2612/2432 2457/2613/2457 f 2431/2611/2431 2457/2613/2457 2456/2614/2456 f 63/2615/63 2457/2613/2457 2432/2612/2432 f 63/2615/63 2432/2612/2432 64/2616/64 f 2460/2617/2460 2513/2618/2513 2512/2619/2512 f 2460/2617/2460 2512/2619/2512 2458/2620/2458 f 2514/2621/2514 2513/2618/2513 2460/2617/2460 f 2514/2621/2514 2460/2617/2460 2462/2622/2462 f 2463/2623/2463 2464/2624/2464 2467/2625/2467 f 2463/2623/2463 2467/2625/2467 2466/2626/2466 f 2465/2627/2465 2498/2628/2498 2466/2626/2466 f 2465/2627/2465 2466/2626/2466 2467/2625/2467 f 2460/2617/2460 2458/2620/2458 2468/2629/2468 f 2460/2617/2460 2468/2629/2468 2469/2630/2469 f 2464/2624/2464 2462/2622/2462 2469/2630/2469 f 2464/2624/2464 2469/2630/2469 2500/2631/2500 f 2465/2627/2465 2467/2625/2467 2471/2632/2471 f 2465/2627/2465 2471/2632/2471 2470/2633/2470 f 2467/2625/2467 2464/2624/2464 2500/2631/2500 f 2467/2625/2467 2500/2631/2500 2471/2632/2471 f 2473/2634/2473 2474/2635/2474 2432/2636/2432 f 2473/2634/2473 2432/2636/2432 2472/2637/2472 f 2476/2638/2476 2473/2634/2473 2472/2637/2472 f 2476/2638/2476 2472/2637/2472 2475/2639/2475 f 2478/2640/2478 2474/2635/2474 2473/2634/2473 f 2478/2640/2478 2473/2634/2473 2479/2641/2479 f 2479/2641/2479 2473/2634/2473 2476/2638/2476 f 2479/2641/2479 2476/2638/2476 2480/2642/2480 f 2488/2643/2488 2478/2640/2478 2479/2641/2479 f 2488/2643/2488 2479/2641/2479 2482/2644/2482 f 2479/2641/2479 2480/2642/2480 2485/2645/2485 f 2479/2641/2479 2485/2645/2485 2482/2644/2482 f 2488/2643/2488 2482/2644/2482 2484/2646/2484 f 2488/2643/2488 2484/2646/2484 2483/2647/2483 f 2486/2648/2486 2487/2649/2487 2476/2638/2476 f 2486/2648/2486 2476/2638/2476 2475/2639/2475 f 2480/2642/2480 2476/2638/2476 2487/2649/2487 f 2480/2642/2480 2487/2649/2487 2481/2650/2481 f 61/2651/61 2474/2635/2474 2478/2640/2478 f 61/2651/61 2478/2640/2478 2490/2652/2490 f 1332/2653/1332 2452/2654/2452 2448/2655/2448 f 1332/2653/1332 2448/2655/2448 1331/2577/1331 f 106/2656/106 2489/2657/2489 2452/2654/2452 f 106/2656/106 2452/2654/2452 1332/2653/1332 f 2478/2640/2478 2488/2643/2488 2489/2658/2489 f 2478/2640/2478 2489/2658/2489 2490/2652/2490 f 2492/2659/2492 1/2660/1 2426/2661/2426 f 2492/2659/2492 2426/2661/2426 2491/2662/2491 f 2425/2663/2425 2459/2664/2459 2491/2665/2491 f 2425/2663/2425 2491/2665/2491 2426/2666/2426 f 2496/2667/2496 2493/2668/2493 2461/2669/2461 f 2496/2667/2496 2461/2669/2461 2463/2670/2463 f 2492/2659/2492 2515/2671/2515 4/2672/4 f 2492/2659/2492 4/2672/4 1/2660/1 f 2518/2673/2518 2519/2674/2519 2494/2675/2494 f 2518/2673/2518 2494/2675/2494 2516/2676/2516 f 2466/2677/2466 2497/2678/2497 2496/2667/2496 f 2466/2677/2466 2496/2667/2496 2463/2670/2463 f 2499/2679/2499 2497/2678/2497 2466/2677/2466 f 2499/2679/2499 2466/2677/2466 2498/2680/2498 f 2497/2678/2497 2499/2679/2499 2470/2633/2470 f 2497/2678/2497 2470/2633/2470 2471/2632/2471 f 2517/2681/2517 2496/2667/2496 2497/2678/2497 f 2517/2681/2517 2497/2678/2497 2471/2632/2471 f 2516/2676/2516 2494/2675/2494 2496/2667/2496 f 2516/2676/2516 2496/2667/2496 2517/2681/2517 f 1356/2682/1356 2419/2571/2419 2422/2570/2422 f 1356/2682/1356 2422/2570/2422 1357/2683/1357 f 90/2684/90 1357/2683/1357 2422/2570/2422 f 90/2684/90 2422/2570/2422 2502/2685/2502 f 2507/2686/2507 1444/2687/1444 90/2688/90 f 2507/2686/2507 90/2688/90 2502/2689/2502 f 2507/2686/2507 2506/2690/2506 1445/2691/1445 f 2507/2686/2507 1445/2691/1445 1444/2687/1444 f 2504/2692/2504 2505/2693/2505 2508/2694/2508 f 2504/2692/2504 2508/2694/2508 2507/2686/2507 f 1446/2695/1446 1445/2691/1445 2506/2690/2506 f 1446/2695/1446 2506/2690/2506 2509/2696/2509 f 2176/2286/2176 2187/2285/2187 2177/2298/2177 f 2176/2286/2176 2177/2298/2177 2510/2697/2510 f 2175/2287/2175 2176/2286/2176 2510/2697/2510 f 2175/2287/2175 2510/2697/2510 2511/2185/2511 f 2513/2618/2513 2493/2698/2493 2459/2664/2459 f 2513/2618/2513 2459/2664/2459 2512/2619/2512 f 2461/2699/2461 2493/2698/2493 2513/2618/2513 f 2461/2699/2461 2513/2618/2513 2514/2621/2514 f 2468/2629/2468 46/2700/46 4/2672/4 f 2468/2629/2468 4/2672/4 2515/2671/2515 f 2500/2631/2500 2469/2630/2469 2516/2676/2516 f 2500/2631/2500 2516/2676/2516 2517/2681/2517 f 1/11/1 3/2701/3 2/12/2 f 1/11/1 4/20/4 3/2701/3 f 3/2701/3 4/20/4 5/2/5 f 5/2/5 6/1/6 3/2701/3 f 10/7/10 11/6/11 13/19/13 f 7/4/7 19/51/19 18/50/18 f 2/12/2 3/2701/3 6/1/6 f 20/21/20 22/18/22 21/70/21 f 25/15/25 26/56/26 24/16/24 f 19/51/19 7/4/7 24/16/24 f 24/16/24 26/56/26 19/51/19 f 37/37/37 43/43/43 34/34/34 f 46/46/46 9/8/9 4/20/4 f 41/41/41 45/45/45 40/40/40 f 26/56/26 49/60/49 48/48/48 f 19/51/19 26/56/26 48/48/48 f 1262/33/1262 51/62/51 33/30/33 f 1262/33/1262 1281/2702/1281 51/62/51 f 52/52/52 1281/2702/1281 1280/53/1280 f 49/60/49 26/56/26 54/55/54 f 31/26/31 55/59/55 30/25/30 f 32/31/32 56/2703/56 31/26/31 f 33/30/33 56/2703/56 32/31/32 f 57/61/57 58/2704/58 56/2703/56 f 57/61/57 56/2703/56 33/30/33 f 54/55/54 59/57/59 49/60/49 f 58/2704/58 60/58/60 56/2703/56 f 60/58/60 58/2704/58 59/57/59 f 58/2704/58 49/60/49 59/57/59 f 58/2704/58 57/61/57 49/60/49 f 60/58/60 55/59/55 56/2703/56 f 55/59/55 31/26/31 56/2703/56 f 51/62/51 1281/2702/1281 52/52/52 f 63/2705/63 61/63/61 62/64/62 f 63/2705/63 64/2706/64 61/63/61 f 45/45/45 61/63/61 47/47/47 f 47/47/47 65/66/65 44/44/44 f 109/65/109 43/43/43 44/44/44 f 21/70/21 36/36/36 20/21/20 f 21/70/21 66/69/66 36/36/36 f 39/39/39 66/69/66 42/42/42 f 36/36/36 66/69/66 39/39/39 f 12/5/12 67/68/67 11/6/11 f 11/6/11 67/68/67 23/17/23 f 22/18/22 67/68/67 21/70/21 f 23/17/23 67/68/67 22/18/22 f 42/42/42 67/68/67 12/5/12 f 68/2707/68 14/10/14 15/9/15 f 68/2707/68 15/9/15 16/13/16 f 69/71/69 71/2708/71 16/13/16 f 2/12/2 6/1/6 17/14/17 f 77/78/77 80/88/80 79/79/79 f 77/78/77 79/79/79 76/77/76 f 72/73/72 70/72/70 17/14/17 f 70/72/70 72/73/72 75/76/75 f 75/76/75 81/82/81 70/72/70 f 84/81/84 70/72/70 81/82/81 f 84/81/84 69/71/69 70/72/70 f 81/82/81 75/76/75 78/80/78 f 86/87/86 87/86/87 89/102/89 f 79/79/79 85/85/85 78/80/78 f 7/4/7 18/50/18 6/1/6 f 92/2709/92 69/71/69 84/81/84 f 69/71/69 92/2709/92 71/2708/71 f 82/84/82 92/2709/92 84/81/84 f 86/87/86 94/2710/94 85/85/85 f 92/90/92 94/98/94 86/94/86 f 85/85/85 94/2710/94 83/83/83 f 89/102/89 96/101/96 95/2711/95 f 68/93/68 71/2712/71 92/90/92 f 71/2708/71 68/2707/68 16/13/16 f 101/111/101 103/108/103 102/2713/102 f 102/2713/102 103/108/103 104/107/104 f 98/105/98 99/104/99 105/2714/105 f 110/2715/110 104/107/104 105/2714/105 f 102/2713/102 104/107/104 110/2715/110 f 103/108/103 108/113/108 111/114/111 f 105/2714/105 104/107/104 98/105/98 f 114/118/114 121/487/121 122/486/122 f 126/120/126 116/167/116 115/117/115 f 113/116/113 112/115/112 127/126/127 f 112/115/112 117/122/117 120/129/120 f 122/486/122 119/2716/119 118/123/118 f 446/485/446 121/487/121 124/2717/124 f 114/118/114 115/117/115 123/169/123 f 121/487/121 125/170/125 124/2717/124 f 121/487/121 123/169/123 125/170/125 f 118/123/118 119/2716/119 174/125/174 f 174/125/174 148/165/148 146/124/146 f 127/126/127 130/131/130 131/143/131 f 130/131/130 132/130/132 133/2718/133 f 133/2718/133 136/142/136 130/131/130 f 134/144/134 131/143/131 130/131/130 f 136/142/136 133/2718/133 139/132/139 f 157/141/157 134/144/134 136/142/136 f 136/142/136 134/144/134 130/131/130 f 132/130/132 137/134/137 138/133/138 f 138/133/138 133/2718/133 132/130/132 f 140/135/140 135/140/135 139/132/139 f 133/2718/133 138/133/138 139/132/139 f 137/134/137 132/130/132 141/137/141 f 141/137/141 143/138/143 142/2719/142 f 142/2719/142 137/134/137 141/137/141 f 145/139/145 144/136/144 199/182/199 f 117/122/117 146/124/146 147/183/147 f 147/183/147 120/129/120 117/122/117 f 144/136/144 120/129/120 147/183/147 f 119/2716/119 188/166/188 174/125/174 f 149/146/149 150/145/150 154/2720/154 f 150/145/150 151/147/151 154/2720/154 f 153/149/153 152/148/152 154/2720/154 f 149/146/149 154/2720/154 152/148/152 f 153/149/153 154/2720/154 151/147/151 f 159/150/159 161/157/161 155/151/155 f 149/146/149 152/148/152 165/2721/165 f 157/141/157 135/140/135 158/152/158 f 160/153/160 177/2722/177 161/157/161 f 137/134/137 142/2719/142 140/135/140 f 142/2719/142 143/138/143 164/2723/164 f 140/135/140 142/2719/142 164/2723/164 f 140/135/140 164/2723/164 135/140/135 f 178/155/178 162/154/162 163/2724/163 f 158/152/158 135/140/135 241/2725/241 f 135/140/135 164/2723/164 241/2725/241 f 160/153/160 158/152/158 241/2725/241 f 152/148/152 155/151/155 165/2721/165 f 131/143/131 149/146/149 165/2721/165 f 165/2721/165 156/2726/156 131/143/131 f 165/2721/165 155/151/155 166/2727/166 f 166/2727/166 155/151/155 167/156/167 f 155/151/155 161/157/161 167/156/167 f 169/159/169 166/2727/166 167/156/167 f 169/159/169 165/2721/165 166/2727/166 f 156/2726/156 165/2721/165 168/158/168 f 165/2721/165 169/159/169 168/158/168 f 156/2726/156 170/2728/170 128/127/128 f 156/2726/156 168/158/168 170/2728/170 f 131/143/131 128/127/128 127/126/127 f 571/588/571 173/163/173 191/162/191 f 118/123/118 114/118/114 122/486/122 f 172/179/172 148/165/148 189/164/189 f 161/2729/161 177/2730/177 227/236/227 f 176/2731/176 177/2722/177 164/2723/164 f 163/2724/163 162/154/162 176/2731/176 f 162/154/162 175/2732/175 176/2731/176 f 176/2731/176 175/2732/175 177/2722/177 f 163/2724/163 164/2723/164 178/155/178 f 178/155/178 164/2723/164 143/138/143 f 164/2723/164 163/2724/163 176/2731/176 f 121/487/121 114/118/114 123/169/123 f 125/170/125 123/169/123 179/168/179 f 116/167/116 126/120/126 180/2733/180 f 116/167/116 180/2733/180 182/173/182 f 180/2733/180 181/174/181 182/173/182 f 180/2733/180 126/120/126 181/174/181 f 124/2717/124 125/170/125 183/172/183 f 185/175/185 194/119/194 192/2734/192 f 148/165/148 172/179/172 187/178/187 f 568/585/568 571/588/571 189/164/189 f 191/162/191 189/164/189 571/588/571 f 194/119/194 195/2735/195 192/2734/192 f 185/175/185 192/2734/192 193/242/193 f 192/2734/192 195/2735/195 193/242/193 f 113/116/113 129/128/129 196/121/196 f 197/181/197 208/180/208 193/242/193 f 181/174/181 185/175/185 193/242/193 f 115/117/115 113/116/113 196/121/196 f 193/242/193 195/2735/195 197/181/197 f 197/181/197 195/2735/195 194/119/194 f 197/181/197 194/119/194 196/121/196 f 198/184/198 219/2736/219 200/185/200 f 200/185/200 199/182/199 198/184/198 f 148/165/148 198/184/198 146/124/146 f 148/165/148 219/2736/219 198/184/198 f 148/165/148 187/178/187 219/2736/219 f 219/2736/219 187/178/187 233/230/233 f 186/176/186 203/191/203 234/195/234 f 129/128/129 128/127/128 207/198/207 f 207/198/207 128/127/128 209/2737/209 f 128/127/128 170/2728/170 209/2737/209 f 209/200/209 170/2738/170 210/193/210 f 218/351/218 212/206/212 215/210/215 f 216/212/216 217/211/217 262/257/262 f 214/209/214 211/214/211 218/351/218 f 211/214/211 224/213/224 221/219/221 f 220/215/220 223/220/223 224/213/224 f 219/202/219 339/201/339 200/186/200 f 225/187/225 226/222/226 175/188/175 f 226/222/226 177/2730/177 175/188/175 f 168/2739/168 228/245/228 170/2740/170 f 168/2739/168 161/2729/161 228/245/228 f 228/245/228 227/236/227 245/238/245 f 228/245/228 229/247/229 170/2740/170 f 231/223/231 230/225/230 240/228/240 f 203/191/203 205/192/205 234/195/234 f 234/195/234 201/177/201 186/176/186 f 217/211/217 236/233/236 250/235/250 f 230/246/230 247/239/247 240/250/240 f 164/2723/164 177/2722/177 241/2725/241 f 241/2725/241 177/2722/177 160/153/160 f 161/157/161 159/150/159 160/153/160 f 191/162/191 172/179/172 189/164/189 f 243/241/243 182/173/182 181/174/181 f 243/241/243 184/171/184 182/173/182 f 206/199/206 242/244/242 208/180/208 f 161/2729/161 227/236/227 228/245/228 f 247/239/247 230/246/230 245/238/245 f 226/222/226 227/236/227 177/2730/177 f 246/2741/246 264/260/264 237/2742/237 f 248/234/248 264/2743/264 249/251/249 f 250/235/250 262/257/262 217/211/217 f 216/212/216 262/257/262 260/217/260 f 248/234/248 249/251/249 259/254/259 f 257/258/257 251/259/251 252/295/252 f 260/217/260 257/258/257 258/218/258 f 220/215/220 222/216/222 255/256/255 f 222/216/222 256/290/256 255/289/255 f 258/218/258 252/295/252 256/290/256 f 257/258/257 252/295/252 258/218/258 f 250/235/250 248/234/248 259/254/259 f 218/351/218 215/210/215 214/209/214 f 246/2741/246 263/261/263 264/260/264 f 266/263/266 265/262/265 285/2744/285 f 267/2745/267 285/2744/285 269/2746/269 f 269/2746/269 268/273/268 402/431/402 f 271/266/271 265/262/265 274/267/274 f 270/269/270 268/273/268 284/270/284 f 246/2741/246 254/291/254 263/261/263 f 273/264/273 276/271/276 272/2747/272 f 276/271/276 273/264/273 279/275/279 f 284/270/284 272/2747/272 276/271/276 f 277/272/277 278/274/278 280/428/280 f 278/274/278 281/277/281 280/428/280 f 279/275/279 278/274/278 276/271/276 f 276/271/276 278/274/278 277/272/277 f 273/264/273 272/2747/272 283/265/283 f 283/265/283 272/2747/272 284/270/284 f 285/2744/285 265/262/265 271/266/271 f 285/2744/285 271/266/271 268/273/268 f 285/2744/285 267/2745/267 266/263/266 f 285/2744/285 268/273/268 269/2746/269 f 254/291/254 255/289/255 292/287/292 f 290/285/290 342/354/342 294/398/294 f 294/398/294 291/298/291 290/285/290 f 298/278/298 275/268/275 263/261/263 f 290/285/290 291/298/291 293/288/293 f 249/251/249 264/2743/264 266/296/266 f 267/297/267 269/279/269 253/252/253 f 308/310/308 314/313/314 315/311/315 f 312/317/312 317/316/317 313/350/313 f 308/310/308 309/318/309 314/313/314 f 314/313/314 310/312/310 315/311/315 f 317/316/317 311/320/311 313/350/313 f 306/308/306 304/306/304 323/321/323 f 309/318/309 308/310/308 332/336/332 f 315/311/315 310/312/310 318/333/318 f 305/307/305 307/309/307 319/323/319 f 307/309/307 315/311/315 319/323/319 f 320/325/320 403/424/403 321/326/321 f 323/321/323 304/306/304 302/304/302 f 324/324/324 319/323/319 349/332/349 f 403/424/403 320/325/320 432/2748/432 f 331/344/331 333/337/333 329/339/329 f 329/340/329 326/334/326 331/343/331 f 318/333/318 310/312/310 345/346/345 f 336/319/336 309/318/309 346/348/346 f 339/201/339 211/214/211 221/219/221 f 339/201/339 221/219/221 200/186/200 f 221/219/221 225/187/225 200/186/200 f 170/2749/170 341/224/341 210/353/210 f 291/298/291 343/2750/343 344/328/344 f 310/312/310 334/315/334 345/346/345 f 309/318/309 332/336/332 346/348/346 f 330/342/330 318/333/318 345/346/345 f 346/348/346 332/336/332 330/345/330 f 347/355/347 327/322/327 323/321/323 f 322/329/322 384/2751/384 351/2752/351 f 344/328/344 384/2751/384 322/329/322 f 359/370/359 361/373/361 360/371/360 f 363/374/363 367/2753/367 364/375/364 f 359/370/359 365/376/365 361/373/361 f 361/373/361 362/372/362 360/371/360 f 366/377/366 367/2753/367 363/374/363 f 357/368/357 355/366/355 368/378/368 f 356/367/356 358/369/358 372/382/372 f 358/369/358 360/371/360 372/382/372 f 368/378/368 355/366/355 353/365/353 f 373/383/373 372/382/372 383/384/383 f 371/380/371 377/390/377 378/2754/378 f 378/2755/378 377/394/377 370/385/370 f 378/2755/378 370/385/370 375/387/375 f 375/388/375 371/380/371 378/2754/378 f 371/380/371 362/372/362 379/391/379 f 366/377/366 365/376/365 380/393/380 f 367/2753/367 381/392/381 364/375/364 f 381/395/381 367/2753/367 366/377/366 f 362/372/362 364/375/364 379/391/379 f 365/376/365 370/385/370 380/393/380 f 377/390/377 371/380/371 379/391/379 f 380/393/380 370/385/370 377/394/377 f 373/383/373 383/384/383 384/427/384 f 344/363/344 354/362/354 373/383/373 f 373/383/373 384/427/384 344/363/344 f 343/2750/343 294/398/294 385/400/385 f 291/298/291 294/398/294 343/2750/343 f 386/399/386 342/354/342 387/294/387 f 351/405/351 384/2756/384 395/406/395 f 349/332/349 350/361/350 432/335/432 f 393/413/393 386/399/386 387/294/387 f 396/414/396 393/413/393 389/403/389 f 385/400/385 386/399/386 394/410/394 f 393/413/393 387/294/387 389/403/389 f 297/292/297 299/299/299 321/326/321 f 434/2757/434 391/421/391 433/420/433 f 400/422/400 398/418/398 397/417/397 f 397/417/397 399/423/399 400/422/400 f 368/378/368 385/401/385 394/415/394 f 401/425/401 399/423/399 397/417/397 f 268/273/268 270/269/270 402/431/402 f 408/439/408 409/438/409 410/441/410 f 412/440/412 413/443/413 414/2758/414 f 408/439/408 410/441/410 415/444/415 f 410/441/410 409/438/409 411/442/411 f 416/445/416 412/440/412 414/2758/414 f 406/437/406 417/446/417 405/434/405 f 404/433/404 421/450/421 407/436/407 f 407/436/407 421/450/421 409/438/409 f 419/449/419 427/2759/427 426/457/426 f 427/2760/427 424/452/424 426/461/426 f 427/2760/427 423/453/423 424/452/424 f 423/456/423 427/2759/427 419/449/419 f 419/449/419 428/459/428 411/442/411 f 416/445/416 429/462/429 415/444/415 f 413/443/413 430/458/430 414/2758/414 f 430/460/430 416/445/416 414/2758/414 f 411/442/411 428/459/428 413/443/413 f 415/444/415 429/462/429 424/452/424 f 426/457/426 428/459/428 419/449/419 f 429/462/429 426/461/426 424/452/424 f 421/450/421 432/468/432 422/451/422 f 403/432/403 421/450/421 404/433/404 f 421/450/421 403/432/403 432/468/432 f 405/434/405 417/446/417 399/2761/399 f 417/446/417 433/466/433 399/2761/399 f 405/434/405 399/2761/399 401/435/401 f 432/2762/432 350/2763/350 435/2764/435 f 435/2764/435 434/2757/434 433/420/433 f 350/2763/350 434/2757/434 435/2764/435 f 441/478/441 446/485/446 442/479/442 f 183/172/183 442/479/442 124/2717/124 f 183/172/183 184/171/184 442/479/442 f 442/479/442 446/485/446 124/2717/124 f 588/2765/588 564/594/564 119/2716/119 f 447/484/447 558/483/558 449/2766/449 f 449/2766/449 122/486/122 447/484/447 f 451/488/451 242/490/242 204/491/204 f 477/524/477 476/523/476 478/2767/478 f 478/2767/478 480/526/480 481/550/481 f 478/2767/478 476/523/476 480/526/480 f 481/550/481 480/526/480 485/2768/485 f 480/526/480 479/525/479 482/527/482 f 480/526/480 482/527/482 485/2768/485 f 482/527/482 519/530/519 485/2768/485 f 498/522/498 488/532/488 487/531/487 f 487/531/487 468/513/468 498/522/498 f 468/513/468 487/531/487 491/536/491 f 497/541/497 496/540/496 493/537/493 f 171/160/171 204/190/204 190/161/190 f 475/521/475 499/543/499 498/522/498 f 498/522/498 501/553/501 500/2769/500 f 499/543/499 503/545/503 501/553/501 f 475/521/475 477/524/477 505/544/505 f 477/524/477 478/2767/478 505/544/505 f 478/2767/478 481/550/481 505/544/505 f 481/550/481 504/2770/504 505/544/505 f 481/550/481 502/547/502 504/2770/504 f 504/2770/504 503/545/503 505/544/505 f 504/2770/504 506/2771/506 512/2772/512 f 504/2770/504 502/547/502 506/2771/506 f 506/2771/506 502/547/502 507/546/507 f 506/2771/506 507/546/507 510/555/510 f 510/555/510 512/2772/512 506/2771/506 f 507/546/507 509/549/509 510/555/510 f 481/550/481 485/2768/485 519/530/519 f 503/545/503 504/2770/504 511/554/511 f 504/2770/504 512/2772/512 511/554/511 f 510/555/510 511/554/511 512/2772/512 f 514/551/514 513/557/513 537/552/537 f 500/2769/500 501/553/501 537/552/537 f 498/522/498 499/543/499 501/553/501 f 516/2773/516 517/2774/517 519/530/519 f 517/2774/517 508/548/508 519/530/519 f 517/2774/517 516/2773/516 518/2775/518 f 519/530/519 515/556/515 516/2773/516 f 486/529/486 515/556/515 519/530/519 f 515/556/515 173/542/173 538/570/538 f 173/163/173 571/588/571 538/2776/538 f 508/548/508 517/2774/517 520/559/520 f 520/559/520 509/549/509 508/548/508 f 517/2774/517 518/2775/518 520/559/520 f 520/559/520 510/555/510 509/549/509 f 518/2775/518 516/2773/516 542/560/542 f 542/560/542 520/559/520 518/2775/518 f 526/566/526 473/519/473 472/518/472 f 532/2777/532 523/563/523 527/2778/527 f 523/563/523 469/515/469 527/2778/527 f 534/2779/534 527/2778/527 529/2780/529 f 529/2780/529 528/514/528 531/567/531 f 527/2778/527 469/515/469 528/514/528 f 529/2780/529 531/567/531 533/568/533 f 530/2781/530 492/535/492 494/538/494 f 534/2779/534 532/2777/532 527/2778/527 f 492/535/492 530/2781/530 533/568/533 f 533/568/533 530/2781/530 529/2780/529 f 528/514/528 469/515/469 458/503/458 f 529/2780/529 530/2781/530 534/2779/534 f 468/513/468 491/536/491 531/567/531 f 531/567/531 528/514/528 468/513/468 f 528/514/528 529/2780/529 527/2778/527 f 535/2782/535 467/512/467 466/511/466 f 466/511/466 473/519/473 535/2782/535 f 496/540/496 495/539/495 493/537/493 f 498/522/498 500/2769/500 536/2783/536 f 500/2769/500 537/552/537 536/2783/536 f 513/557/513 536/2783/536 537/552/537 f 495/539/495 498/522/498 536/2783/536 f 516/2773/516 515/556/515 541/569/541 f 541/569/541 542/560/542 516/2773/516 f 541/569/541 543/573/543 542/560/542 f 543/573/543 540/572/540 544/2784/544 f 543/573/543 544/2784/544 545/574/545 f 542/560/542 543/573/543 545/574/545 f 592/607/592 548/582/548 549/579/549 f 549/579/549 551/577/551 550/576/550 f 552/578/552 443/480/443 445/482/445 f 552/578/552 551/577/551 553/2785/553 f 554/2786/554 558/481/558 443/480/443 f 443/480/443 552/578/552 554/2786/554 f 557/581/557 553/2785/553 551/577/551 f 553/2785/553 557/581/557 556/2787/556 f 554/2786/554 552/578/552 556/2787/556 f 556/2787/556 552/578/552 553/2785/553 f 556/2787/556 558/481/558 554/2786/554 f 558/483/558 556/2788/556 449/2766/449 f 548/582/548 592/607/592 593/601/593 f 812/2789/812 813/2790/813 741/2791/741 f 565/2792/565 450/584/450 188/166/188 f 564/594/564 448/593/448 119/2716/119 f 119/2716/119 448/593/448 589/2793/589 f 119/2716/119 589/2793/589 188/166/188 f 563/2794/563 565/2792/565 188/166/188 f 563/2794/563 567/2795/567 587/2796/587 f 565/2792/565 587/2796/587 566/2797/566 f 566/2797/566 450/584/450 565/2792/565 f 587/2796/587 565/2792/565 563/2794/563 f 569/589/569 571/588/571 573/587/573 f 568/585/568 570/2798/570 572/586/572 f 570/2798/570 585/2799/585 572/586/572 f 572/586/572 583/2800/583 573/587/573 f 573/587/573 583/2800/583 569/589/569 f 576/2801/576 579/2802/579 575/2803/575 f 571/588/571 569/589/569 574/2804/574 f 579/2802/579 539/571/539 575/2803/575 f 539/571/539 538/570/538 575/2803/575 f 575/2803/575 538/570/538 576/2801/576 f 576/2805/576 574/2804/574 577/592/577 f 577/592/577 574/2804/574 569/589/569 f 538/2776/538 574/2804/574 576/2805/576 f 574/2804/574 538/2776/538 571/588/571 f 576/2801/576 582/2806/582 579/2802/579 f 586/591/586 581/2807/581 580/2808/580 f 578/590/578 581/2807/581 586/591/586 f 576/2801/576 580/639/580 582/2806/582 f 580/2808/580 576/2805/576 577/592/577 f 569/589/569 584/2809/584 578/590/578 f 578/590/578 584/2809/584 570/2798/570 f 569/589/569 583/2800/583 584/2809/584 f 583/2800/583 572/586/572 585/2799/585 f 570/2798/570 584/2809/584 585/2799/585 f 585/2799/585 584/2809/584 583/2800/583 f 580/2808/580 577/592/577 586/591/586 f 570/2798/570 568/585/568 450/584/450 f 450/584/450 566/2797/566 607/2810/607 f 566/2797/566 587/2796/587 607/2810/607 f 607/2810/607 570/2798/570 450/584/450 f 607/2810/607 578/590/578 570/2798/570 f 587/2796/587 567/2795/567 590/596/590 f 567/2795/567 448/593/448 590/596/590 f 119/2716/119 122/486/122 588/2765/588 f 448/593/448 567/2795/567 589/2793/589 f 589/2793/589 567/2795/567 563/2794/563 f 589/2793/589 563/2794/563 188/166/188 f 122/486/122 449/2766/449 588/2765/588 f 564/594/564 588/2765/588 591/595/591 f 449/2766/449 556/2788/556 588/2765/588 f 549/579/549 550/576/550 592/607/592 f 550/576/550 602/2811/602 592/607/592 f 602/2811/602 601/606/601 594/605/594 f 745/771/745 595/600/595 744/599/744 f 596/770/596 636/657/636 597/2812/597 f 598/602/598 594/605/594 599/603/599 f 548/582/548 593/601/593 600/583/600 f 596/770/596 559/604/559 601/606/601 f 559/604/559 596/770/596 638/655/638 f 602/2811/602 594/605/594 592/607/592 f 607/2810/607 587/2796/587 590/596/590 f 607/623/607 590/612/590 604/611/604 f 638/655/638 597/2812/597 637/656/637 f 637/656/637 597/2812/597 636/657/636 f 604/611/604 993/620/993 607/623/607 f 605/610/605 606/659/606 609/2813/609 f 604/611/604 605/610/605 608/1000/608 f 578/2814/578 607/2815/607 610/641/610 f 610/641/610 581/640/581 578/2814/578 f 610/622/610 994/621/994 995/624/995 f 609/2813/609 897/876/897 613/875/613 f 996/2816/996 621/2817/621 611/1001/611 f 611/1001/611 621/2817/621 614/2818/614 f 609/2813/609 613/875/613 996/2816/996 f 609/2813/609 608/1000/608 605/610/605 f 642/1002/642 650/2819/650 619/627/619 f 619/627/619 616/2820/616 620/628/620 f 613/875/613 615/874/615 621/2817/621 f 621/2817/621 615/874/615 622/2821/622 f 614/2818/614 621/2817/621 622/2821/622 f 614/2818/614 642/1002/642 611/1001/611 f 619/627/619 995/624/995 642/1002/642 f 616/2822/616 645/2823/645 643/632/643 f 650/2819/650 642/1002/642 645/2824/645 f 617/642/617 618/630/618 648/629/648 f 620/631/620 616/2822/616 643/632/643 f 628/636/628 625/634/625 627/633/627 f 624/635/624 626/637/626 540/572/540 f 626/637/626 545/574/545 544/2784/544 f 626/637/626 544/2784/544 540/572/540 f 624/635/624 540/572/540 539/571/539 f 539/571/539 579/2802/579 624/635/624 f 579/2802/579 582/2806/582 624/635/624 f 545/574/545 626/637/626 627/633/627 f 624/635/624 582/2806/582 580/639/580 f 591/595/591 588/2765/588 556/2788/556 f 630/646/630 632/649/632 634/651/634 f 603/654/603 560/650/560 635/652/635 f 936/1182/936 612/2825/612 606/659/606 f 596/770/596 597/2812/597 638/655/638 f 630/646/630 560/650/560 603/654/603 f 614/2818/614 622/2821/622 640/2826/640 f 622/2821/622 651/2827/651 640/2826/640 f 622/2821/622 615/874/615 651/2827/651 f 614/2818/614 639/2828/639 642/1002/642 f 639/2828/639 645/2824/645 642/1002/642 f 614/2818/614 640/2826/640 641/2829/641 f 639/2830/639 644/660/644 645/2823/645 f 644/660/644 643/632/643 645/2823/645 f 623/2831/623 643/632/643 646/662/646 f 643/632/643 623/2831/623 648/629/648 f 625/2832/625 628/643/628 617/642/617 f 648/629/648 623/2831/623 625/2832/625 f 617/642/617 648/629/648 625/2832/625 f 645/2824/645 616/2820/616 650/2819/650 f 650/2819/650 616/2820/616 619/627/619 f 614/2818/614 641/2829/641 639/2828/639 f 644/2833/644 639/2834/639 653/674/653 f 644/2833/644 653/674/653 673/673/673 f 653/671/653 654/670/654 656/678/656 f 665/683/665 659/2835/659 660/684/660 f 661/685/661 659/2835/659 665/686/665 f 661/685/661 669/691/669 659/2835/659 f 669/691/669 660/684/660 659/2835/659 f 671/693/671 670/692/670 669/691/669 f 668/690/668 666/689/666 674/694/674 f 673/673/673 676/698/676 644/2833/644 f 672/688/672 674/694/674 677/696/677 f 672/688/672 677/696/677 678/697/678 f 729/2836/729 730/2837/730 771/2838/771 f 680/701/680 679/700/679 684/738/684 f 679/700/679 710/730/710 684/738/684 f 690/714/690 703/723/703 698/715/698 f 705/2839/705 702/2840/702 704/2841/704 f 705/2839/705 706/2842/706 682/902/682 f 692/2843/692 694/2844/694 695/2845/695 f 681/705/681 699/710/699 696/718/696 f 699/710/699 688/720/688 696/718/696 f 696/718/696 694/717/694 692/782/692 f 688/720/688 691/722/691 701/721/701 f 701/721/701 691/722/691 703/723/703 f 703/723/703 691/722/691 698/715/698 f 704/724/704 703/723/703 689/712/689 f 706/2842/706 705/2839/705 704/2841/704 f 694/2844/694 693/2846/693 709/2847/709 f 704/724/704 689/712/689 706/725/706 f 708/727/708 695/2845/695 694/2844/694 f 693/2846/693 750/729/750 709/2847/709 f 694/2844/694 749/728/749 708/727/708 f 689/712/689 690/714/690 711/713/711 f 720/740/720 716/734/716 714/733/714 f 718/742/718 713/732/713 712/731/712 f 690/714/690 689/712/689 703/723/703 f 718/741/718 720/740/720 724/749/724 f 724/749/724 725/748/725 728/2848/728 f 725/748/725 726/750/726 728/2848/728 f 726/750/726 727/747/727 728/2848/728 f 727/747/727 724/746/724 728/2848/728 f 730/781/730 678/2849/678 677/778/677 f 676/755/676 678/762/678 732/756/732 f 730/763/730 729/758/729 734/761/734 f 737/764/737 735/2850/735 736/765/736 f 738/766/738 735/2850/735 739/767/739 f 739/767/739 735/2850/735 737/764/737 f 609/2813/609 606/659/606 612/2825/612 f 629/647/629 742/769/742 741/2791/741 f 813/2790/813 746/2851/746 741/2791/741 f 741/2791/741 740/768/740 562/2852/562 f 629/647/629 630/646/630 742/769/742 f 742/769/742 740/768/740 741/2791/741 f 742/769/742 630/646/630 743/598/743 f 743/598/743 630/646/630 603/654/603 f 744/599/744 636/657/636 596/770/596 f 601/606/601 602/2811/602 745/771/745 f 741/2791/741 562/2852/562 812/2789/812 f 746/2851/746 629/647/629 741/2791/741 f 813/2853/813 747/2854/747 748/2855/748 f 748/2856/748 746/2851/746 813/2790/813 f 629/647/629 746/2851/746 748/2856/748 f 694/2844/694 709/2847/709 749/728/749 f 749/728/749 709/2847/709 750/729/750 f 693/2846/693 704/2841/704 750/729/750 f 693/716/693 697/719/697 704/724/704 f 704/2841/704 702/2840/702 750/729/750 f 702/2840/702 707/726/707 750/729/750 f 695/2845/695 708/727/708 751/2857/751 f 751/2857/751 753/2858/753 754/788/754 f 753/2858/753 755/2859/755 754/788/754 f 788/2860/788 776/790/776 787/789/787 f 751/2857/751 752/773/752 753/2858/753 f 753/2858/753 752/773/752 758/784/758 f 752/773/752 757/772/757 758/784/758 f 752/773/752 707/726/707 759/774/759 f 758/784/758 757/772/757 760/776/760 f 755/2859/755 753/2858/753 763/783/763 f 753/2858/753 758/784/758 763/783/763 f 763/783/763 774/803/774 764/2861/764 f 759/774/759 707/726/707 765/2862/765 f 765/2862/765 707/726/707 702/2840/702 f 702/2840/702 705/2839/705 766/2863/766 f 765/2862/765 702/2840/702 766/2863/766 f 705/2839/705 765/2862/765 766/2863/766 f 765/2862/765 761/775/761 759/774/759 f 771/2838/771 730/2837/730 920/2864/920 f 924/917/924 769/904/769 768/903/768 f 767/702/767 680/701/680 771/2838/771 f 771/753/771 680/706/680 681/705/681 f 692/782/692 700/2865/700 772/751/772 f 772/751/772 700/2865/700 729/752/729 f 708/727/708 707/726/707 751/2857/751 f 707/726/707 752/773/752 751/2857/751 f 763/783/763 799/804/799 774/803/774 f 775/786/775 773/785/773 762/777/762 f 763/783/763 775/786/775 799/804/799 f 776/790/776 780/2866/780 777/787/777 f 764/2861/764 788/2860/788 787/789/787 f 788/2860/788 764/2861/764 778/2867/778 f 764/2861/764 774/803/774 778/2867/778 f 764/2861/764 755/2859/755 763/783/763 f 788/2860/788 778/2867/778 805/2868/805 f 805/2868/805 776/790/776 788/2860/788 f 804/2869/804 780/2866/780 805/2868/805 f 780/2866/780 776/790/776 805/2868/805 f 782/792/782 756/791/756 780/2866/780 f 780/2866/780 756/791/756 777/787/777 f 782/792/782 803/2870/803 784/793/784 f 785/2871/785 782/792/782 781/800/781 f 785/2871/785 781/800/781 802/2872/802 f 754/788/754 755/2859/755 787/789/787 f 787/789/787 755/2859/755 764/2861/764 f 761/775/761 795/2873/795 789/2874/789 f 762/777/762 789/2874/789 790/2875/790 f 775/786/775 762/777/762 798/2876/798 f 790/2875/790 789/2874/789 791/795/791 f 761/775/761 765/2862/765 792/2877/792 f 789/2874/789 762/777/762 761/775/761 f 761/775/761 792/2877/792 795/2873/795 f 762/777/762 790/2875/790 798/2876/798 f 798/2876/798 799/804/799 775/786/775 f 790/2875/790 793/2878/793 798/2876/798 f 790/2875/790 791/795/791 793/2878/793 f 795/2873/795 796/2879/796 789/2874/789 f 795/2873/795 792/2877/792 796/2879/796 f 796/2879/796 792/2877/792 794/796/794 f 796/2879/796 794/796/794 797/2880/797 f 797/2880/797 789/2874/789 796/2879/796 f 794/796/794 791/795/791 797/2880/797 f 797/2880/797 791/795/791 789/2874/789 f 792/2877/792 765/2862/765 826/2881/826 f 798/2876/798 793/2878/793 799/804/799 f 802/2872/802 803/2870/803 785/2871/785 f 803/2870/803 802/2872/802 784/793/784 f 804/2869/804 805/2868/805 806/802/806 f 780/2866/780 779/801/779 781/800/781 f 804/2869/804 779/801/779 780/2866/780 f 780/2866/780 781/800/781 782/792/782 f 779/801/779 804/2869/804 806/802/806 f 806/802/806 805/2868/805 778/2867/778 f 800/798/800 793/2878/793 791/795/791 f 799/804/799 793/2878/793 810/805/810 f 793/2878/793 800/798/800 810/805/810 f 809/806/809 806/802/806 778/2867/778 f 811/807/811 812/1227/812 1196/1224/1196 f 813/2853/813 811/807/811 815/2882/815 f 808/809/808 814/811/814 815/2882/815 f 815/2882/815 814/811/814 816/1004/816 f 815/2882/815 816/1004/816 817/2883/817 f 747/2854/747 813/2853/813 815/2882/815 f 747/2854/747 815/2882/815 818/2884/818 f 815/2882/815 817/2883/817 818/2884/818 f 818/2884/818 748/2855/748 747/2854/747 f 820/812/820 819/810/819 821/2885/821 f 821/2885/821 819/810/819 800/798/800 f 800/798/800 801/797/801 821/2885/821 f 822/814/822 820/812/820 821/2885/821 f 821/2885/821 801/797/801 822/814/822 f 765/2862/765 705/2839/705 826/2881/826 f 705/2839/705 823/2886/823 826/2881/826 f 824/1020/824 823/2886/823 828/900/828 f 828/900/828 825/834/825 824/1020/824 f 833/2887/833 823/2886/823 836/1023/836 f 825/834/825 828/900/828 914/872/914 f 823/2886/823 827/901/827 828/900/828 f 827/901/827 823/2886/823 705/2839/705 f 826/2881/826 830/813/830 829/815/829 f 829/815/829 801/797/801 794/796/794 f 792/2877/792 826/2881/826 829/815/829 f 829/815/829 794/796/794 792/2877/792 f 830/813/830 826/2881/826 831/2888/831 f 830/813/830 831/2888/831 837/1008/837 f 831/2888/831 833/2887/833 837/1008/837 f 837/1008/837 833/2887/833 834/2889/834 f 832/1009/832 834/2889/834 835/1022/835 f 835/1022/835 834/2889/834 836/1023/836 f 823/2886/823 824/1020/824 836/1023/836 f 836/1023/836 834/2889/834 833/2887/833 f 834/2889/834 832/1009/832 837/1008/837 f 831/2888/831 826/2881/826 833/2887/833 f 833/2887/833 826/2881/826 823/2886/823 f 824/1020/824 825/834/825 863/833/863 f 841/818/841 838/817/838 843/835/843 f 824/1020/824 863/833/863 1024/2890/1024 f 865/1011/865 844/836/844 864/838/864 f 862/837/862 842/822/842 845/828/845 f 846/926/846 867/2891/867 862/837/862 f 862/837/862 845/828/845 846/926/846 f 851/826/851 873/831/873 852/827/852 f 849/823/849 851/826/851 852/827/852 f 858/2892/858 855/840/855 874/2893/874 f 857/839/857 856/843/856 873/831/873 f 859/824/859 861/870/861 926/2894/926 f 859/824/859 848/820/848 861/870/861 f 838/817/838 842/822/842 843/835/843 f 843/835/843 842/822/842 862/837/862 f 867/2891/867 864/838/864 862/837/862 f 927/871/927 839/816/839 840/819/840 f 840/819/840 913/873/913 927/871/927 f 864/838/864 818/2884/818 865/1011/865 f 865/1011/865 818/2884/818 817/2883/817 f 748/2855/748 818/2884/818 866/2895/866 f 629/2896/629 748/2855/748 866/2895/866 f 866/2897/866 633/653/633 631/648/631 f 631/648/631 629/647/629 866/2897/866 f 866/2895/866 867/2891/867 932/919/932 f 855/840/855 858/2892/858 883/841/883 f 858/2892/858 882/855/882 883/841/883 f 873/831/873 872/949/872 869/845/869 f 872/949/872 856/843/856 1380/844/1380 f 856/843/856 872/949/872 873/831/873 f 873/831/873 851/826/851 857/839/857 f 855/840/855 850/825/850 874/2893/874 f 874/2893/874 850/825/850 860/864/860 f 946/856/946 868/850/868 875/869/875 f 946/856/946 875/869/875 949/957/949 f 877/849/877 875/869/875 868/850/868 f 882/855/882 858/2892/858 885/861/885 f 885/861/885 881/847/881 882/855/882 f 946/856/946 1380/844/1380 884/842/884 f 858/2892/858 887/857/887 885/861/885 f 874/2893/874 886/858/886 887/857/887 f 887/857/887 858/2892/858 874/2893/874 f 860/864/860 926/2894/926 888/865/888 f 896/863/896 874/2893/874 860/864/860 f 896/863/896 886/858/886 874/2893/874 f 897/876/897 899/2898/899 901/878/901 f 898/881/898 900/2899/900 903/882/903 f 900/2899/900 919/884/919 903/882/903 f 902/883/902 651/2900/651 615/880/615 f 651/2900/651 902/883/902 906/2901/906 f 902/883/902 907/887/907 906/2901/906 f 906/2901/906 904/2902/904 651/2900/651 f 904/888/904 652/668/652 651/667/651 f 906/2901/906 907/887/907 911/894/911 f 911/895/911 909/893/909 906/892/906 f 919/884/919 900/2899/900 912/2903/912 f 927/871/927 913/873/913 916/897/916 f 915/915/915 768/903/768 912/907/912 f 827/901/827 705/2839/705 682/902/682 f 915/896/915 914/872/914 682/902/682 f 769/904/769 770/2904/770 918/2905/918 f 770/2904/770 921/779/921 923/910/923 f 918/2905/918 770/2904/770 923/910/923 f 767/916/767 920/2906/920 922/780/922 f 920/2864/920 767/702/767 771/2838/771 f 921/779/921 925/2907/925 922/780/922 f 922/780/922 925/2907/925 767/916/767 f 923/913/923 917/906/917 918/905/918 f 922/780/922 920/2906/920 730/781/730 f 770/2904/770 769/904/769 925/2907/925 f 925/2907/925 769/904/769 924/917/924 f 925/2907/925 924/917/924 767/916/767 f 921/779/921 770/2904/770 925/2907/925 f 900/899/900 901/934/901 928/933/928 f 928/933/928 927/871/927 916/897/916 f 928/933/928 916/897/916 900/899/900 f 899/2898/899 897/876/897 612/2825/612 f 899/2898/899 612/2825/612 929/2908/929 f 612/2825/612 936/1182/936 929/2908/929 f 609/2813/609 612/2825/612 897/876/897 f 634/2909/634 633/918/633 930/617/930 f 635/616/635 634/2909/634 930/617/930 f 932/919/932 867/2891/867 931/920/931 f 867/2891/867 846/926/846 931/920/931 f 932/919/932 633/918/633 866/2895/866 f 811/807/811 813/2853/813 812/1227/812 f 854/829/854 953/924/953 934/921/934 f 937/925/937 931/920/931 846/926/846 f 853/830/853 935/922/935 937/925/937 f 936/618/936 937/925/937 929/2910/929 f 933/923/933 955/951/955 953/924/953 f 888/865/888 926/2894/926 939/931/939 f 926/2894/926 861/870/861 939/931/939 f 933/923/933 871/832/871 870/846/870 f 889/862/889 940/935/940 943/2911/943 f 891/860/891 890/859/890 940/935/940 f 889/862/889 891/860/891 940/935/940 f 894/868/894 889/862/889 943/2911/943 f 893/867/893 894/868/894 942/936/942 f 894/868/894 943/2911/943 942/936/942 f 946/856/946 1379/1448/1379 1380/844/1380 f 1379/1448/1379 946/856/946 949/957/949 f 945/943/945 943/942/943 940/953/940 f 952/946/952 945/943/945 951/950/951 f 944/940/944 945/943/945 952/946/952 f 955/951/955 933/923/933 956/952/956 f 956/952/956 933/923/933 870/846/870 f 935/922/935 899/956/899 929/2910/929 f 929/2910/929 937/925/937 935/922/935 f 935/922/935 934/921/934 899/956/899 f 875/869/875 880/854/880 957/958/957 f 957/958/957 961/961/961 962/964/962 f 1115/969/1115 960/962/960 1153/974/1153 f 1078/968/1078 961/961/961 1114/970/1114 f 965/971/965 962/964/962 1077/967/1077 f 973/981/973 976/991/976 977/982/977 f 973/981/973 974/992/974 976/991/976 f 976/991/976 975/988/975 977/982/977 f 968/976/968 970/978/970 981/985/981 f 970/978/970 972/980/972 981/985/981 f 969/977/969 967/975/967 1028/1024/1028 f 971/979/971 969/977/969 1028/1024/1028 f 988/999/988 1052/998/1052 991/2912/991 f 988/999/988 991/2912/991 992/941/992 f 1187/1090/1187 990/1089/990 991/2913/991 f 1052/998/1052 1187/1085/1187 991/2912/991 f 991/2913/991 990/1089/990 989/2914/989 f 991/2912/991 989/2915/989 992/941/992 f 604/611/604 608/1000/608 993/620/993 f 611/1001/611 608/1000/608 996/2816/996 f 996/2816/996 608/1000/608 609/2813/609 f 996/2816/996 613/875/613 621/2817/621 f 997/1005/997 998/2916/998 1000/1003/1000 f 1000/1003/1000 817/2883/817 816/1004/816 f 814/811/814 820/812/820 997/1005/997 f 998/2916/998 999/1017/999 1000/1003/1000 f 1000/1003/1000 999/1017/999 817/2883/817 f 999/1017/999 865/1011/865 817/2883/817 f 1002/2917/1002 844/836/844 1003/1010/1003 f 1004/2918/1004 1011/2919/1011 1005/2920/1005 f 1011/2919/1011 1001/2921/1001 1005/2920/1005 f 1004/2918/1004 1005/2920/1005 1008/2922/1008 f 1005/2920/1005 1006/2923/1006 1008/2922/1008 f 1006/2923/1006 1022/1015/1022 1008/2922/1008 f 1022/1015/1022 1007/1014/1007 1008/2922/1008 f 1008/2922/1008 1009/1007/1009 1004/2918/1004 f 1008/2922/1008 1007/1014/1007 1009/1007/1009 f 1004/2918/1004 1010/1006/1010 1011/2919/1011 f 1004/2918/1004 1009/1007/1009 1010/1006/1010 f 1009/1007/1009 1007/1014/1007 822/814/822 f 1010/1006/1010 832/1009/832 1011/2919/1011 f 1001/2921/1001 1011/2919/1011 1012/1021/1012 f 1012/1021/1012 1011/2919/1011 835/1022/835 f 832/1009/832 835/1022/835 1011/2919/1011 f 1023/1019/1023 1019/1018/1019 1020/2924/1020 f 1003/1010/1003 1013/1012/1013 1014/2925/1014 f 1001/2921/1001 1003/1010/1003 1014/2925/1014 f 1003/1010/1003 1001/2921/1001 1002/2917/1002 f 1014/2925/1014 1006/2923/1006 1001/2921/1001 f 1006/2923/1006 1005/2920/1005 1001/2921/1001 f 1014/2925/1014 1013/1012/1013 1006/2923/1006 f 1006/2923/1006 1021/2926/1021 1022/1015/1022 f 1022/1015/1022 998/2916/998 997/1005/997 f 1022/1015/1022 997/1005/997 1015/1016/1015 f 997/1005/997 820/812/820 1015/1016/1015 f 822/814/822 1007/1014/1007 1016/1013/1016 f 1016/1013/1016 1017/2927/1017 1018/2928/1018 f 1016/1013/1016 1015/1016/1015 1017/2927/1017 f 1015/1016/1015 820/812/820 1017/2927/1017 f 1017/2927/1017 820/812/820 1018/2928/1018 f 820/812/820 822/814/822 1018/2928/1018 f 1018/2928/1018 822/814/822 1016/1013/1016 f 1019/1018/1019 999/1017/999 998/2916/998 f 1019/1018/1019 998/2916/998 1021/2926/1021 f 1021/2926/1021 998/2916/998 1022/1015/1022 f 1023/1019/1023 1013/1012/1013 865/1011/865 f 1020/2924/1020 1019/1018/1019 1021/2926/1021 f 1023/1019/1023 1020/2924/1020 1013/1012/1013 f 1013/1012/1013 1020/2924/1020 1006/2923/1006 f 1006/2923/1006 1020/2924/1020 1021/2926/1021 f 844/836/844 1002/2917/1002 1024/2890/1024 f 1001/2921/1001 1012/1021/1012 1024/2890/1024 f 1024/2890/1024 1012/1021/1012 824/1020/824 f 1024/2890/1024 1002/2917/1002 1001/2921/1001 f 844/836/844 1024/2890/1024 863/833/863 f 811/807/811 808/809/808 815/2882/815 f 926/2894/926 860/864/860 859/824/859 f 860/864/860 850/825/850 859/824/859 f 1026/1026/1026 984/993/984 974/992/974 f 985/994/985 982/989/982 975/988/975 f 1026/1026/1026 1032/1031/1032 1034/2929/1034 f 984/993/984 1026/1026/1026 1034/2929/1034 f 984/993/984 1034/2929/1034 1036/996/1036 f 1035/997/1035 1033/2930/1033 985/994/985 f 1033/2930/1033 1029/1028/1029 982/989/982 f 982/989/982 985/994/985 1033/2930/1033 f 987/995/987 1036/996/1036 1040/2931/1040 f 1035/997/1035 987/995/987 1040/2931/1040 f 1036/1039/1036 1035/1038/1035 1040/2932/1040 f 1047/1052/1047 1049/1058/1049 1048/1053/1048 f 1047/1052/1047 1050/1059/1050 1049/1058/1049 f 1049/1058/1049 1051/1055/1051 1048/1053/1048 f 1044/1049/1044 1046/1051/1046 1053/1054/1053 f 1046/1051/1046 1048/1053/1048 1053/1054/1053 f 1045/1050/1045 1043/1048/1043 1061/1065/1061 f 1047/1052/1047 1045/1050/1045 1061/1065/1061 f 1062/1066/1062 1056/1060/1056 1050/1059/1050 f 1057/1061/1057 1054/1056/1054 1051/1055/1051 f 1062/1066/1062 1064/1071/1064 1066/2933/1066 f 1056/1060/1056 1062/1066/1062 1068/2934/1068 f 1056/1060/1056 1068/2934/1068 1059/1063/1059 f 1060/1064/1060 1067/2935/1067 1057/1061/1057 f 1054/1056/1054 1067/2935/1067 1065/2936/1065 f 1065/2936/1065 1063/1068/1063 1054/1056/1054 f 1054/1056/1054 1057/1061/1057 1067/2935/1067 f 1062/1066/1062 1066/2933/1066 1068/2934/1068 f 1058/1062/1058 1059/1063/1059 1072/2937/1072 f 1060/1064/1060 1058/1062/1058 1072/2937/1072 f 1059/1081/1059 1060/1080/1060 1072/2938/1072 f 989/2914/989 990/1089/990 1074/1088/1074 f 1085/1099/1085 1087/1107/1087 1086/1100/1086 f 1085/1099/1085 1088/1108/1088 1087/1107/1087 f 1087/1107/1087 1089/1104/1089 1086/1100/1086 f 1080/1094/1080 1082/1096/1082 1091/1101/1091 f 1082/1096/1082 1084/1098/1084 1091/1101/1091 f 1081/1095/1081 1079/1093/1079 1100/1114/1100 f 1083/1097/1083 1081/1095/1081 1100/1114/1100 f 1102/1116/1102 1095/1109/1095 1088/1108/1088 f 1096/1110/1096 1093/1105/1093 1089/1104/1089 f 1102/1116/1102 1107/1121/1107 1109/2939/1109 f 1095/1109/1095 1102/1116/1102 1109/2939/1109 f 1095/1109/1095 1109/2939/1109 1098/1112/1098 f 1099/1113/1099 1108/2940/1108 1096/1110/1096 f 1108/2940/1108 1104/1118/1104 1093/1105/1093 f 1093/1105/1093 1096/1110/1096 1108/2940/1108 f 1097/1111/1097 1098/1112/1098 1113/2941/1113 f 1099/1113/1099 1097/1111/1097 1113/2941/1113 f 1098/1129/1098 1099/1128/1099 1113/2942/1113 f 1090/1102/1090 1112/1045/1112 1027/1027/1027 f 1122/1142/1122 1124/1150/1124 1123/1143/1123 f 1122/1142/1122 1125/1151/1125 1124/1150/1124 f 1124/1150/1124 1126/1147/1126 1123/1143/1123 f 1117/1137/1117 1119/1139/1119 1128/1144/1128 f 1119/1139/1119 1121/1141/1121 1128/1144/1128 f 1134/2943/1134 1131/1149/1131 1132/1152/1132 f 1133/1153/1133 1131/1149/1131 1134/2943/1134 f 1118/1138/1118 1116/1136/1116 1135/1154/1135 f 1120/1140/1120 1118/1138/1118 1135/1154/1135 f 1137/1156/1137 1132/1152/1132 1125/1151/1125 f 1133/1153/1133 1130/1148/1130 1126/1147/1126 f 1144/1167/1144 1143/1166/1143 1134/2944/1134 f 1137/1156/1137 1142/1161/1142 1144/2945/1144 f 1132/1152/1132 1137/1156/1137 1144/2945/1144 f 1132/1152/1132 1144/2945/1144 1134/2943/1134 f 1134/2943/1134 1143/2946/1143 1133/1153/1133 f 1143/2946/1143 1139/1158/1139 1130/1148/1130 f 1130/1148/1130 1133/1153/1133 1143/2946/1143 f 1127/1145/1127 1148/1134/1148 1103/1117/1103 f 1186/1217/1186 1150/1175/1150 1074/1178/1074 f 992/941/992 989/2915/989 1151/938/1151 f 989/1177/989 1149/1176/1149 1151/2947/1151 f 880/854/880 892/853/892 1152/965/1152 f 144/136/144 147/183/147 199/182/199 f 222/216/222 258/218/258 256/290/256 f 264/2743/264 248/234/248 237/232/237 f 229/226/229 341/224/341 170/2749/170 f 128/127/128 131/143/131 156/2726/156 f 112/115/112 120/129/120 127/126/127 f 864/838/864 867/2891/867 818/2884/818 f 867/2891/867 866/2895/866 818/2884/818 f 1161/1189/1161 1163/1197/1163 1162/1190/1162 f 1161/1189/1161 1164/1198/1164 1163/1197/1163 f 1163/1197/1163 1165/1194/1165 1162/1190/1162 f 1156/1184/1156 1158/1186/1158 1167/1191/1167 f 1158/1186/1158 1160/1188/1160 1167/1191/1167 f 1173/2948/1173 1170/1196/1170 1171/1199/1171 f 1172/1200/1172 1170/1196/1170 1173/2948/1173 f 1157/1185/1157 1155/1183/1155 1174/1201/1174 f 1159/1187/1159 1157/1185/1157 1174/1201/1174 f 1176/1203/1176 1171/1199/1171 1164/1198/1164 f 1172/1200/1172 1169/1195/1169 1165/1194/1165 f 1183/1214/1183 1182/1213/1182 1173/2949/1173 f 1176/1203/1176 1181/1208/1181 1183/2950/1183 f 1171/1199/1171 1176/1203/1176 1183/2950/1183 f 1171/1199/1171 1183/2950/1183 1173/2948/1173 f 1173/2948/1173 1182/2951/1182 1172/1200/1172 f 1182/2951/1182 1178/1205/1178 1169/1195/1169 f 1169/1195/1169 1172/1200/1172 1182/2951/1182 f 1166/1192/1166 1147/1173/1147 1138/1157/1138 f 1177/1204/1177 1154/973/1154 964/966/964 f 1071/2952/1071 1075/1092/1075 1076/1087/1076 f 1071/2952/1071 1076/1087/1076 1187/1090/1187 f 1042/983/1042 958/959/958 963/963/963 f 1189/1221/1189 1188/1231/1188 1197/1222/1197 f 1195/1223/1195 1192/1226/1192 1191/1232/1191 f 812/1227/812 1190/1225/1190 1196/1224/1196 f 562/1228/562 1191/1232/1191 1192/1226/1192 f 1196/1224/1196 807/808/807 811/807/811 f 1188/1231/1188 1198/1269/1198 1197/1222/1197 f 1188/1231/1188 1193/1230/1193 1198/1269/1198 f 786/799/786 806/802/806 1199/2953/1199 f 1199/2954/1199 1197/2955/1197 1275/1309/1275 f 1203/1308/1203 786/2956/786 1199/2954/1199 f 1199/2954/1199 1275/1309/1275 1203/1308/1203 f 809/806/809 1197/1222/1197 1199/2953/1199 f 1199/2953/1199 806/802/806 809/806/809 f 1202/1237/1202 1201/1240/1201 1205/1243/1205 f 784/2957/784 802/2958/802 1210/2959/1210 f 1215/1260/1215 1214/1253/1214 1223/1252/1223 f 1210/2960/1210 1211/1263/1211 784/1251/784 f 782/792/782 785/2871/785 803/2870/803 f 1212/1264/1212 1217/1257/1217 1215/1260/1215 f 1213/2961/1213 1216/1258/1216 1217/1257/1217 f 1217/1257/1217 1212/1264/1212 1213/2961/1213 f 784/1251/784 1211/1263/1211 1223/1252/1223 f 1201/1240/1201 1320/2962/1320 1225/1265/1225 f 1224/2963/1224 1220/1262/1220 1225/1265/1225 f 1225/1265/1225 1220/1262/1220 1221/1261/1221 f 1225/1265/1225 1221/1261/1221 1222/1259/1222 f 1225/1265/1225 1222/1259/1222 1226/1266/1226 f 1226/1266/1226 1222/1259/1222 1219/1256/1219 f 1226/1266/1226 1219/1256/1219 1218/1255/1218 f 1209/1245/1209 1208/1244/1208 1227/2964/1227 f 1213/1249/1213 1209/1245/1209 1227/2964/1227 f 1216/1258/1216 1213/2961/1213 1227/2964/1227 f 1218/1255/1218 1216/1258/1216 1227/2964/1227 f 1208/1244/1208 1218/1255/1218 1227/2964/1227 f 1331/1234/1331 1200/1233/1200 1220/1370/1220 f 1229/1280/1229 1237/1279/1237 1231/1273/1231 f 1229/1280/1229 1231/1273/1231 1249/1289/1249 f 1231/1273/1231 1248/1272/1248 1249/1289/1249 f 1233/1270/1233 1247/1290/1247 1250/1271/1250 f 1232/1276/1232 1251/1288/1251 1252/1277/1252 f 1247/1290/1247 1245/1317/1245 1243/1316/1243 f 1237/1279/1237 1233/1270/1233 1231/1273/1231 f 1254/1291/1254 1240/1392/1240 1241/1285/1241 f 1242/1284/1242 1234/1287/1234 1257/1322/1257 f 1243/1316/1243 1234/1287/1234 1247/1290/1247 f 1234/1287/1234 1243/1316/1243 1257/1322/1257 f 1269/1301/1269 34/34/34 43/43/43 f 1201/1240/1201 1204/1239/1204 1320/2962/1320 f 1320/2962/1320 1224/2963/1224 1225/1265/1225 f 1304/1313/1304 1249/1289/1249 1236/1275/1236 f 1273/1305/1273 1272/1304/1272 1277/1312/1277 f 1257/1322/1257 1244/1315/1244 1285/1327/1285 f 1243/1316/1243 1244/1315/1244 1257/1322/1257 f 1262/33/1262 1263/1297/1263 1291/1328/1291 f 1262/33/1262 1291/1328/1291 1281/2702/1281 f 1278/1319/1278 1280/53/1280 1281/2702/1281 f 1285/1327/1285 1284/1321/1284 1257/1322/1257 f 1259/1296/1259 1282/1295/1282 1290/1325/1290 f 1264/1298/1264 1259/1296/1259 1286/2965/1286 f 1263/1297/1263 1264/1298/1264 1286/2965/1286 f 1279/1326/1279 1286/2965/1286 1289/2966/1289 f 1279/1326/1279 1263/1297/1263 1286/2965/1286 f 1284/1321/1284 1285/1327/1285 1287/1323/1287 f 1289/2966/1289 1286/2965/1286 1288/1324/1288 f 1288/1324/1288 1287/1323/1287 1289/2966/1289 f 1289/2966/1289 1287/1323/1287 1285/1327/1285 f 1289/2966/1289 1285/1327/1285 1279/1326/1279 f 1288/1324/1288 1286/2965/1286 1290/1325/1290 f 1290/1325/1290 1286/2965/1286 1259/1296/1259 f 1291/1328/1291 1278/1319/1278 1281/2702/1281 f 1292/2967/1292 1306/1330/1306 1325/1329/1325 f 1276/2968/1276 1275/1401/1275 1436/1335/1436 f 1292/2969/1292 1276/2968/1276 1293/1334/1293 f 1438/1337/1438 1298/1339/1298 1299/1342/1299 f 1293/1334/1293 1303/1346/1303 1306/2970/1306 f 1295/1333/1295 1297/1338/1297 1305/1345/1305 f 1292/2969/1292 1293/1334/1293 1306/2970/1306 f 1204/1352/1204 1330/2971/1330 1311/1353/1311 f 1324/1365/1324 1314/2972/1314 1323/1364/1323 f 1314/2972/1314 1324/1365/1324 1318/1366/1318 f 1319/1360/1319 1321/1363/1321 1322/1361/1322 f 1321/1363/1321 1320/1362/1320 1204/2973/1204 f 1204/2973/1204 1309/2974/1309 1321/1363/1321 f 1322/1361/1322 1321/1363/1321 1309/2974/1309 f 1309/2974/1309 1312/2975/1312 1322/1361/1322 f 1322/1361/1322 1318/1366/1318 1317/1358/1317 f 1312/2975/1312 1318/1366/1318 1322/1361/1322 f 1323/2976/1323 1314/2972/1314 1318/1366/1318 f 1318/1366/1318 1312/2975/1312 1323/2976/1323 f 1328/1368/1328 1333/2977/1333 1336/2978/1336 f 1320/1362/1320 1326/1359/1326 1327/1378/1327 f 1224/1371/1224 1320/2979/1320 1327/1373/1327 f 1329/2980/1329 1333/2977/1333 1328/1368/1328 f 1328/1368/1328 1325/1367/1325 1329/2980/1329 f 1292/2967/1292 1325/1329/1325 1330/2981/1330 f 1330/2971/1330 1325/1367/1325 1311/1353/1311 f 106/1372/106 1336/2982/1336 1337/2983/1337 f 1333/1374/1333 1329/1314/1329 1334/1375/1334 f 1277/1312/1277 1329/1314/1329 1325/1329/1325 f 1329/1314/1329 1274/1307/1274 1334/1375/1334 f 1334/1375/1334 109/65/109 1335/1376/1335 f 106/1372/106 1327/1373/1327 1336/2982/1336 f 1336/2978/1336 1327/1378/1327 1328/1368/1328 f 101/111/101 102/2713/102 1341/1385/1341 f 102/2713/102 1342/1386/1342 1341/1385/1341 f 1340/1383/1340 105/2714/105 99/1384/99 f 110/2715/110 105/2714/105 1342/1386/1342 f 102/2713/102 110/2715/110 1342/1386/1342 f 1341/1385/1341 1338/1390/1338 1335/1389/1335 f 105/2714/105 1340/1383/1340 1342/1386/1342 f 1240/1392/1240 1254/1291/1254 1266/1300/1266 f 1240/1392/1240 1266/1300/1266 1343/1393/1343 f 1268/1303/1268 1271/1306/1271 1343/1393/1343 f 1266/1300/1266 1268/1303/1268 1343/1393/1343 f 1235/1274/1235 1252/1277/1252 1344/1391/1344 f 1252/1277/1252 1253/1286/1253 1344/1391/1344 f 1241/1285/1241 1240/1392/1240 1344/1391/1344 f 1253/1286/1253 1241/1285/1241 1344/1391/1344 f 1271/1306/1271 1235/1274/1235 1344/1391/1344 f 1443/1410/1443 1348/1405/1348 1345/1395/1345 f 1348/1405/1348 1347/1404/1347 1349/2984/1349 f 1349/2985/1349 1347/1505/1347 1294/1400/1294 f 1294/1400/1294 1345/1399/1345 1349/2985/1349 f 1345/1399/1345 1197/1398/1197 1198/2986/1198 f 1350/1402/1350 1298/1412/1298 1296/1403/1296 f 1300/1343/1300 1352/1344/1352 1355/2987/1355 f 1307/1348/1307 1300/1343/1300 1355/2987/1355 f 1352/1415/1352 1353/1414/1353 1355/2987/1355 f 1353/1414/1353 1307/1348/1307 1355/2987/1355 f 1191/1232/1191 562/1228/562 1356/1417/1356 f 1193/1230/1193 1194/1229/1194 1358/1420/1358 f 1358/1420/1358 1228/1267/1228 1193/1230/1193 f 1358/2988/1358 1230/1278/1230 1228/1281/1228 f 1358/2988/1358 1238/1282/1238 1230/1278/1230 f 1359/1421/1359 1238/1282/1238 1361/2989/1361 f 1237/1279/1237 1362/1283/1362 1233/1270/1233 f 77/78/77 1372/1428/1372 80/88/80 f 77/78/77 1365/1426/1365 1372/1428/1372 f 1363/1423/1363 1362/1283/1362 1360/1422/1360 f 1360/1422/1360 1366/1425/1366 1363/1423/1363 f 1366/1425/1366 1360/1422/1360 1370/1432/1370 f 1371/1429/1371 1370/1432/1370 1360/1422/1360 f 1371/1429/1371 1360/1422/1360 1359/1421/1359 f 1370/1432/1370 1367/1427/1367 1366/1425/1366 f 1375/1435/1375 1378/1447/1378 1373/1433/1373 f 1372/1428/1372 1367/1427/1367 1374/1434/1374 f 1247/1290/1247 1233/1270/1233 1245/1317/1245 f 1376/2990/1376 1371/1429/1371 1359/1421/1359 f 1359/1421/1359 1361/2989/1361 1376/2990/1376 f 1368/1430/1368 1371/1429/1371 1376/2990/1376 f 1375/1435/1375 1374/1434/1374 1377/2991/1377 f 1376/1436/1376 1375/1441/1375 1377/1443/1377 f 1374/1434/1374 1369/1431/1369 1377/2991/1377 f 1378/1447/1378 95/2711/95 96/101/96 f 810/805/810 800/798/800 819/810/819 f 781/800/781 786/799/786 802/2872/802 f 802/2958/802 786/2992/786 1210/2959/1210 f 809/806/809 778/2867/778 774/803/774 f 1358/1437/1358 1376/1436/1376 1361/2993/1361 f 1361/2989/1361 1238/1282/1238 1358/2988/1358 f 1390/1462/1390 1393/1465/1393 1391/1463/1391 f 1394/1484/1394 1395/1471/1395 1396/1472/1396 f 1395/1471/1395 550/1466/550 1397/1468/1397 f 1398/1467/1398 445/1460/445 1388/1459/1388 f 1398/1467/1398 1399/2994/1399 1397/1468/1397 f 1400/2995/1400 1388/1459/1388 1387/1458/1387 f 1388/1459/1388 1400/2995/1400 1398/1467/1398 f 1401/1469/1401 1397/1468/1397 1399/2994/1399 f 1399/2994/1399 1403/2996/1403 1401/1469/1401 f 1400/2995/1400 1403/2996/1403 1398/1467/1398 f 1403/2996/1403 1399/2994/1399 1398/1467/1398 f 1403/2996/1403 1400/2995/1400 1387/1458/1387 f 1396/1472/1396 1405/1480/1405 1394/1484/1394 f 1406/2997/1406 1407/2998/1407 1408/2999/1408 f 1395/1471/1395 1394/1484/1394 550/1466/550 f 550/1466/550 1394/1484/1394 602/3000/602 f 602/3000/602 1409/1483/1409 1410/1482/1410 f 745/1499/745 1411/1476/1411 595/1475/595 f 1413/1500/1413 1414/3001/1414 1415/1494/1415 f 1416/1479/1416 1417/1478/1417 1409/1483/1409 f 1396/1472/1396 1404/1473/1404 1405/1480/1405 f 1413/1500/1413 1410/1482/1410 1418/1481/1418 f 1418/1481/1418 1419/1496/1419 1413/1500/1413 f 602/3000/602 1394/1484/1394 1409/1483/1409 f 1419/1496/1419 1420/1495/1420 1414/3001/1414 f 1420/1495/1420 1415/1494/1415 1414/3001/1414 f 1421/1485/1421 1427/1491/1427 1422/1486/1422 f 1429/1493/1429 1426/1490/1426 1425/1489/1425 f 1413/1500/1413 1419/1496/1419 1414/3001/1414 f 1421/1485/1421 1429/1493/1429 1425/1489/1425 f 1424/1488/1424 1407/2998/1407 1430/1497/1430 f 1408/2999/1408 1407/2998/1407 1431/3002/1431 f 1407/2998/1407 562/3003/562 740/1498/740 f 1424/1488/1424 1430/1497/1430 1421/1485/1421 f 1430/1497/1430 1407/2998/1407 740/1498/740 f 1430/1497/1430 1412/1477/1412 1421/1485/1421 f 1412/1477/1412 1429/1493/1429 1421/1485/1421 f 1411/1476/1411 1413/1500/1413 1415/1494/1415 f 1410/1482/1410 745/1499/745 602/3000/602 f 1407/2998/1407 1406/2997/1406 562/3003/562 f 1431/3002/1431 1407/2998/1407 1424/1488/1424 f 1432/3004/1432 1408/2999/1408 1431/3002/1431 f 1424/1488/1424 1432/3004/1432 1431/3002/1431 f 1433/3005/1433 1423/1487/1423 1428/1492/1428 f 1423/1487/1423 1433/3005/1433 1424/1488/1424 f 1434/1501/1434 65/66/65 47/47/47 f 1436/1335/1436 1293/1334/1293 1276/2968/1276 f 1275/1401/1275 1294/1400/1294 1436/1335/1436 f 1438/1337/1438 1296/1506/1296 1298/1339/1298 f 1299/1342/1299 1297/1338/1297 1438/1337/1438 f 1303/1346/1303 1304/1507/1304 1306/2970/1306 f 1439/1407/1439 1303/1346/1303 1442/1408/1442 f 1441/1416/1441 1354/1347/1354 1308/1349/1308 f 1305/1345/1305 1440/1409/1440 1442/1408/1442 f 1442/1408/1442 1303/1346/1303 1305/1345/1305 f 1346/1394/1346 1439/1407/1439 1442/1408/1442 f 1345/1395/1345 1346/1394/1346 1443/1410/1443 f 1443/1410/1443 1346/1394/1346 1442/1408/1442 f 1348/1405/1348 1349/2984/1349 1345/1395/1345 f 1449/1509/1449 1457/1868/1457 1456/1867/1456 f 1461/1514/1461 1450/1510/1450 1451/1560/1451 f 1448/1511/1448 1462/1521/1462 1447/1508/1447 f 1447/1508/1447 1455/1524/1455 1452/1515/1452 f 1457/1868/1457 1453/1516/1453 1454/3006/1454 f 1768/1864/1768 1459/3007/1459 1456/1867/1456 f 1449/1509/1449 1458/1561/1458 1450/1510/1450 f 1456/1867/1456 1459/3007/1459 1460/1563/1460 f 1456/1867/1456 1460/1563/1460 1458/1561/1458 f 1453/1516/1453 1509/1518/1509 1454/3006/1454 f 1509/1518/1509 1481/1517/1481 1483/1559/1483 f 1462/1521/1462 1466/1536/1466 1465/1522/1465 f 1465/1522/1465 1468/3008/1468 1467/1523/1467 f 1468/3008/1468 1465/1522/1465 1471/1533/1471 f 1469/1539/1469 1465/1522/1465 1466/1536/1466 f 1471/1533/1471 1474/1525/1474 1468/3008/1468 f 1492/1534/1492 1471/1533/1471 1469/1539/1469 f 1471/1533/1471 1465/1522/1465 1469/1539/1469 f 1467/1523/1467 1473/1528/1473 1472/1527/1472 f 1473/1528/1473 1467/1523/1467 1468/3008/1468 f 1475/1526/1475 1474/1525/1474 1470/1535/1470 f 1468/3008/1468 1474/1525/1474 1473/1528/1473 f 1472/1527/1472 1476/1529/1476 1467/1523/1467 f 1476/1529/1476 1477/3009/1477 1478/1531/1478 f 1477/3009/1477 1476/1529/1476 1472/1527/1472 f 1480/1532/1480 1534/1575/1534 1479/1530/1479 f 1452/1515/1452 1482/1577/1482 1481/1517/1481 f 1482/1577/1482 1452/1515/1452 1455/1524/1455 f 1479/1530/1479 1482/1577/1482 1455/1524/1455 f 1454/3006/1454 1509/1518/1509 1523/1558/1523 f 1484/1537/1484 1489/3010/1489 1485/1538/1485 f 1485/1538/1485 1489/3010/1489 1486/1540/1486 f 1488/1544/1488 1489/3010/1489 1487/1541/1487 f 1484/1537/1484 1487/1541/1487 1489/3010/1489 f 1488/1544/1488 1486/1540/1486 1489/3010/1489 f 1494/1543/1494 1490/1542/1490 1496/1552/1496 f 1484/1537/1484 1500/3011/1500 1487/1541/1487 f 1492/1534/1492 1493/1546/1493 1470/1535/1470 f 1495/1545/1495 1496/1552/1496 1512/3012/1512 f 1472/1527/1472 1475/1526/1475 1477/3009/1477 f 1477/3009/1477 1499/3013/1499 1478/1531/1478 f 1475/1526/1475 1499/3013/1499 1477/3009/1477 f 1475/1526/1475 1470/1535/1470 1499/3013/1499 f 1513/1547/1513 1498/3014/1498 1497/1548/1497 f 1493/1546/1493 1575/3015/1575 1470/1535/1470 f 1470/1535/1470 1575/3015/1575 1499/3013/1499 f 1495/1545/1495 1575/3015/1575 1493/1546/1493 f 1487/1541/1487 1500/3011/1500 1490/1542/1490 f 1466/1536/1466 1500/3011/1500 1484/1537/1484 f 1500/3011/1500 1466/1536/1466 1491/3016/1491 f 1500/3011/1500 1501/3017/1501 1490/1542/1490 f 1501/3017/1501 1502/1549/1502 1490/1542/1490 f 1490/1542/1490 1502/1549/1502 1496/1552/1496 f 1504/1550/1504 1502/1549/1502 1501/3017/1501 f 1504/1550/1504 1501/3017/1501 1500/3011/1500 f 1491/3016/1491 1503/1551/1503 1500/3011/1500 f 1500/3011/1500 1503/1551/1503 1504/1550/1504 f 1491/3016/1491 1463/1520/1463 1505/3018/1505 f 1491/3016/1491 1505/3018/1505 1503/1551/1503 f 1466/1536/1466 1462/1521/1462 1463/1520/1463 f 1850/1954/1850 1526/1555/1526 1508/1554/1508 f 1453/1516/1453 1457/1868/1457 1449/1509/1449 f 1507/1570/1507 1524/1557/1524 1483/1559/1483 f 1496/3019/1496 1561/1629/1561 1512/3020/1512 f 1511/3021/1511 1499/3013/1499 1512/3012/1512 f 1498/3014/1498 1511/3021/1511 1497/1548/1497 f 1497/1548/1497 1511/3021/1511 1510/3022/1510 f 1511/3021/1511 1512/3012/1512 1510/3022/1510 f 1498/3014/1498 1513/1547/1513 1499/3013/1499 f 1513/1547/1513 1478/1531/1478 1499/3013/1499 f 1499/3013/1499 1511/3021/1511 1498/3014/1498 f 1456/1867/1456 1458/1561/1458 1449/1509/1449 f 1460/1563/1460 1514/1562/1514 1458/1561/1458 f 1451/1560/1451 1515/3023/1515 1461/1514/1461 f 1451/1560/1451 1517/1566/1517 1515/3023/1515 f 1515/3023/1515 1517/1566/1517 1516/1567/1516 f 1515/3023/1515 1516/1567/1516 1461/1514/1461 f 1459/3007/1459 1518/1564/1518 1460/1563/1460 f 1520/1568/1520 1527/3024/1527 1529/1512/1529 f 1483/1559/1483 1522/1571/1522 1507/1570/1507 f 1847/1953/1847 1524/1557/1524 1850/1954/1850 f 1526/1555/1526 1850/1954/1850 1524/1557/1524 f 1529/1512/1529 1527/3024/1527 1530/3025/1530 f 1520/1568/1520 1528/1636/1528 1527/3024/1527 f 1527/3024/1527 1528/1636/1528 1530/3025/1530 f 1448/1511/1448 1531/1513/1531 1464/1519/1464 f 1532/1573/1532 1528/1636/1528 1542/1574/1542 f 1516/1567/1516 1528/1636/1528 1520/1568/1520 f 1450/1510/1450 1531/1513/1531 1448/1511/1448 f 1528/1636/1528 1532/1573/1532 1530/3025/1530 f 1532/1573/1532 1529/1512/1529 1530/3025/1530 f 1532/1573/1532 1531/1513/1531 1529/1512/1529 f 1533/1576/1533 1535/1578/1535 1553/3026/1553 f 1535/1578/1535 1533/1576/1533 1534/1575/1534 f 1483/1559/1483 1481/1517/1481 1533/1576/1533 f 1483/1559/1483 1533/1576/1533 1553/3026/1553 f 1483/1559/1483 1553/3026/1553 1522/1571/1522 f 1553/3026/1553 1567/1623/1567 1522/1571/1522 f 1521/1569/1521 1568/1586/1568 1538/1583/1538 f 1464/1519/1464 1541/1591/1541 1463/1520/1463 f 1541/1591/1541 1543/3027/1543 1463/1520/1463 f 1463/1520/1463 1543/3027/1543 1505/3018/1505 f 1543/1593/1543 1544/1588/1544 1505/3028/1505 f 1552/1744/1552 1549/1605/1549 1546/1601/1546 f 1550/1603/1550 1593/1650/1593 1551/1604/1551 f 1548/1602/1548 1552/1744/1552 1545/1608/1545 f 1545/1608/1545 1555/1613/1555 1558/1606/1558 f 1554/1607/1554 1558/1606/1558 1557/1612/1557 f 1553/1597/1553 1535/1579/1535 1670/1594/1670 f 1559/1582/1559 1510/1581/1510 1560/1615/1560 f 1560/1615/1560 1510/1581/1510 1512/3020/1512 f 1503/3029/1503 1505/3030/1505 1562/1638/1562 f 1503/3029/1503 1562/1638/1562 1496/3019/1496 f 1562/1638/1562 1576/1631/1576 1561/1629/1561 f 1562/1638/1562 1505/3030/1505 1563/1639/1563 f 1565/1616/1565 1574/1621/1574 1564/1618/1564 f 1538/1583/1538 1568/1586/1568 1539/1585/1539 f 1568/1586/1568 1521/1569/1521 1536/1572/1536 f 1551/1604/1551 1581/1627/1581 1570/1625/1570 f 1564/1640/1564 1574/1642/1574 1578/1632/1578 f 1499/3013/1499 1575/3015/1575 1512/3012/1512 f 1575/3015/1575 1495/1545/1495 1512/3012/1512 f 1496/1552/1496 1495/1545/1495 1494/1543/1494 f 1526/1555/1526 1524/1557/1524 1507/1570/1507 f 1381/1634/1381 1516/1567/1516 1517/1566/1517 f 1381/1634/1381 1517/1566/1517 1519/1565/1519 f 1540/1592/1540 1542/1574/1542 1391/1637/1391 f 1496/3019/1496 1562/1638/1562 1561/1629/1561 f 1578/1632/1578 1576/1631/1576 1564/1640/1564 f 1560/1615/1560 1512/3020/1512 1561/1629/1561 f 1577/3031/1577 1571/3032/1571 1595/1653/1595 f 1579/1628/1579 1580/1644/1580 1595/3033/1595 f 1581/1627/1581 1551/1604/1551 1593/1650/1593 f 1550/1603/1550 1591/1611/1591 1593/1650/1593 f 1579/1628/1579 1590/1645/1590 1580/1644/1580 f 1588/1651/1588 1583/1688/1583 1582/1652/1582 f 1591/1611/1591 1589/1610/1589 1588/1651/1588 f 1554/1607/1554 1586/1649/1586 1556/1609/1556 f 1556/1609/1556 1586/1682/1586 1587/1683/1587 f 1589/1610/1589 1587/1683/1587 1583/1688/1583 f 1588/1651/1588 1589/1610/1589 1583/1688/1583 f 1581/1627/1581 1590/1645/1590 1579/1628/1579 f 1552/1744/1552 1548/1602/1548 1549/1605/1549 f 1577/3031/1577 1595/1653/1595 1594/1656/1594 f 1597/1654/1597 1616/3034/1616 1596/1655/1596 f 1598/3035/1598 1600/3036/1600 1616/3034/1616 f 1600/3036/1600 1733/1824/1733 1599/1666/1599 f 1602/1659/1602 1605/1658/1605 1596/1655/1596 f 1601/1662/1601 1615/1665/1615 1599/1666/1599 f 1577/3031/1577 1594/1656/1594 1585/1685/1585 f 1604/1657/1604 1603/3037/1603 1607/1664/1607 f 1607/1664/1607 1610/1670/1610 1604/1657/1604 f 1615/1665/1615 1607/1664/1607 1603/3037/1603 f 1608/1663/1608 1611/1821/1611 1609/1667/1609 f 1609/1667/1609 1611/1821/1611 1612/1668/1612 f 1610/1670/1610 1607/1664/1607 1609/1667/1609 f 1607/1664/1607 1608/1663/1608 1609/1667/1609 f 1604/1657/1604 1614/1660/1614 1603/3037/1603 f 1614/1660/1614 1615/1665/1615 1603/3037/1603 f 1616/3034/1616 1602/1659/1602 1596/1655/1596 f 1616/3034/1616 1599/1666/1599 1602/1659/1602 f 1616/3034/1616 1597/1654/1597 1598/3035/1598 f 1616/3034/1616 1600/3036/1600 1599/1666/1599 f 1585/1685/1585 1623/1680/1623 1586/1682/1586 f 1621/1679/1621 1625/1791/1625 1673/1747/1673 f 1625/1791/1625 1621/1679/1621 1622/1692/1622 f 1629/1671/1629 1594/1656/1594 1606/1661/1606 f 1621/1679/1621 1624/1681/1624 1622/1692/1622 f 1580/1644/1580 1597/1689/1597 1595/3033/1595 f 1598/1690/1598 1584/1647/1584 1600/1672/1600 f 1639/1704/1639 1646/1703/1646 1645/1708/1645 f 1643/1709/1643 1644/1743/1644 1648/1710/1648 f 1639/1704/1639 1645/1708/1645 1640/1711/1640 f 1645/1708/1645 1646/1703/1646 1641/1705/1641 f 1648/1710/1648 1644/1743/1644 1642/1713/1642 f 1637/1702/1637 1654/1714/1654 1635/1700/1635 f 1640/1711/1640 1663/1729/1663 1639/1704/1639 f 1646/1703/1646 1649/1727/1649 1641/1705/1641 f 1636/1699/1636 1650/1717/1650 1638/1701/1638 f 1638/1701/1638 1650/1717/1650 1646/1703/1646 f 1651/1719/1651 1652/1718/1652 1734/1818/1734 f 1654/1714/1654 1633/1697/1633 1635/1700/1635 f 1655/1716/1655 1680/1724/1680 1650/1717/1650 f 1734/1818/1734 1763/3038/1763 1651/1719/1651 f 1662/1737/1662 1660/1731/1660 1664/1730/1664 f 1660/1734/1660 1662/1735/1662 1657/1726/1657 f 1649/1727/1649 1676/1740/1676 1641/1705/1641 f 1667/1712/1667 1677/1742/1677 1640/1711/1640 f 1670/1594/1670 1555/1613/1555 1545/1608/1545 f 1670/1594/1670 1535/1579/1535 1555/1613/1555 f 1555/1613/1555 1535/1579/1535 1559/1582/1559 f 1505/3039/1505 1544/1746/1544 1672/1617/1672 f 1622/1692/1622 1675/1722/1675 1674/3040/1674 f 1641/1705/1641 1676/1740/1676 1665/1706/1665 f 1640/1711/1640 1677/1742/1677 1663/1729/1663 f 1661/1736/1661 1676/1740/1676 1649/1727/1649 f 1677/1742/1677 1661/1738/1661 1663/1729/1663 f 1678/1749/1678 1654/1714/1654 1658/1715/1658 f 1653/1721/1653 1682/3041/1682 1715/3042/1715 f 1675/1722/1675 1653/1721/1653 1715/3042/1715 f 1690/1764/1690 1691/1763/1691 1692/1768/1692 f 1694/1767/1694 1695/1766/1695 1698/3043/1698 f 1690/1764/1690 1692/1768/1692 1696/1769/1696 f 1692/1768/1692 1691/1763/1691 1693/1765/1693 f 1697/1770/1697 1694/1767/1694 1698/3043/1698 f 1688/1762/1688 1699/1771/1699 1686/1760/1686 f 1687/1759/1687 1703/1776/1703 1689/1761/1689 f 1689/1761/1689 1703/1776/1703 1691/1763/1691 f 1699/1771/1699 1684/1756/1684 1686/1760/1686 f 1704/1775/1704 1714/1777/1714 1703/1776/1703 f 1702/1774/1702 1709/3044/1709 1708/1783/1708 f 1709/3045/1709 1701/1778/1701 1708/1787/1708 f 1709/3045/1709 1706/1779/1706 1701/1778/1701 f 1706/1782/1706 1709/3044/1709 1702/1774/1702 f 1702/1774/1702 1710/1785/1710 1693/1765/1693 f 1697/1770/1697 1711/1788/1711 1696/1769/1696 f 1698/3043/1698 1695/1766/1695 1712/1784/1712 f 1712/1786/1712 1697/1770/1697 1698/3043/1698 f 1693/1765/1693 1710/1785/1710 1695/1766/1695 f 1696/1769/1696 1711/1788/1711 1701/1778/1701 f 1708/1783/1708 1710/1785/1710 1702/1774/1702 f 1711/1788/1711 1708/1787/1708 1701/1778/1701 f 1704/1775/1704 1715/1820/1715 1714/1777/1714 f 1675/1758/1675 1704/1775/1704 1685/1755/1685 f 1704/1775/1704 1675/1758/1675 1715/1820/1715 f 1674/3040/1674 1716/1792/1716 1625/1791/1625 f 1622/1692/1622 1674/3040/1674 1625/1791/1625 f 1717/1793/1717 1718/1687/1718 1673/1747/1673 f 1682/1800/1682 1726/1799/1726 1715/3046/1715 f 1680/1724/1680 1763/1728/1763 1681/1753/1681 f 1724/1806/1724 1718/1687/1718 1717/1793/1717 f 1727/1807/1727 1720/1796/1720 1724/1806/1724 f 1716/1792/1716 1725/1804/1725 1717/1793/1717 f 1724/1806/1724 1720/1796/1720 1718/1687/1718 f 1628/1684/1628 1652/1718/1652 1630/1691/1630 f 1765/3047/1765 1764/1813/1764 1722/1816/1722 f 1731/1815/1731 1728/1810/1728 1729/1812/1729 f 1728/1810/1728 1731/1815/1731 1730/1814/1730 f 1699/1771/1699 1725/1808/1725 1716/1794/1716 f 1732/1817/1732 1728/1810/1728 1730/1814/1730 f 1599/1666/1599 1733/1824/1733 1601/1662/1601 f 1739/1831/1739 1741/1836/1741 1740/1832/1740 f 1743/1833/1743 1745/3048/1745 1744/1834/1744 f 1739/1831/1739 1746/1837/1746 1741/1836/1741 f 1741/1836/1741 1742/1835/1742 1740/1832/1740 f 1747/1838/1747 1745/3048/1745 1743/1833/1743 f 1737/1829/1737 1736/1827/1736 1748/1839/1748 f 1735/1828/1735 1738/1830/1738 1752/1843/1752 f 1738/1830/1738 1740/1832/1740 1752/1843/1752 f 1750/1841/1750 1757/1850/1757 1758/3049/1758 f 1758/3050/1758 1757/1854/1757 1755/1845/1755 f 1758/3050/1758 1755/1845/1755 1754/1847/1754 f 1754/1848/1754 1750/1841/1750 1758/3049/1758 f 1750/1841/1750 1742/1835/1742 1759/1851/1759 f 1747/1838/1747 1746/1837/1746 1760/1853/1760 f 1744/1834/1744 1745/3048/1745 1761/1852/1761 f 1761/1855/1761 1745/3048/1745 1747/1838/1747 f 1742/1835/1742 1744/1834/1744 1759/1851/1759 f 1746/1837/1746 1755/1845/1755 1760/1853/1760 f 1757/1850/1757 1750/1841/1750 1759/1851/1759 f 1760/1853/1760 1755/1845/1755 1757/1854/1757 f 1752/1843/1752 1753/1844/1753 1763/1861/1763 f 1734/1825/1734 1735/1828/1735 1752/1843/1752 f 1752/1843/1752 1763/1861/1763 1734/1825/1734 f 1736/1827/1736 1730/3051/1730 1748/1839/1748 f 1748/1839/1748 1730/3051/1730 1764/1858/1764 f 1736/1827/1736 1732/1826/1732 1730/3051/1730 f 1763/3052/1763 1766/3053/1766 1681/3054/1681 f 1766/3053/1766 1764/1813/1764 1765/3047/1765 f 1681/3054/1681 1766/3053/1766 1765/3047/1765 f 1386/1863/1386 1767/1862/1767 1768/1864/1768 f 1518/1564/1518 1459/3007/1459 1767/1862/1767 f 1518/1564/1518 1767/1862/1767 1519/1565/1519 f 1767/1862/1767 1459/3007/1459 1768/1864/1768 f 1867/3055/1867 1454/3006/1454 1843/1964/1843 f 1769/1865/1769 1771/3056/1771 1387/1866/1387 f 1771/3056/1771 1769/1865/1769 1457/1868/1457 f 1788/1899/1788 1789/3057/1789 1787/1900/1787 f 1789/3057/1789 1792/1926/1792 1791/1901/1791 f 1789/3057/1789 1791/1901/1791 1787/1900/1787 f 1792/1926/1792 1796/3058/1796 1791/1901/1791 f 1791/1901/1791 1793/1903/1793 1790/1902/1790 f 1791/1901/1791 1796/3058/1796 1793/1903/1793 f 1793/1903/1793 1796/3058/1796 1826/1905/1826 f 1806/1897/1806 1798/1907/1798 1799/1910/1799 f 1798/1907/1798 1806/1897/1806 1780/1890/1780 f 1780/1890/1780 1802/1911/1802 1798/1907/1798 f 1805/1917/1805 493/1914/493 1804/1915/1804 f 1506/1553/1506 1525/1556/1525 1393/1584/1393 f 1786/1898/1786 1806/1897/1806 1807/1919/1807 f 1806/1897/1806 1808/3059/1808 1809/1927/1809 f 1807/1919/1807 1809/1927/1809 1811/1920/1811 f 1786/1898/1786 1813/1921/1813 1788/1899/1788 f 1788/1899/1788 1813/1921/1813 1789/3057/1789 f 1789/3057/1789 1813/1921/1813 1792/1926/1792 f 1792/1926/1792 1813/1921/1813 1812/3060/1812 f 1792/1926/1792 1812/3060/1812 1810/1925/1810 f 1812/3060/1812 1813/1921/1813 1811/1920/1811 f 1812/3060/1812 1820/3061/1820 1814/3062/1814 f 1812/3060/1812 1814/3062/1814 1810/1925/1810 f 1814/3062/1814 1815/1922/1815 1810/1925/1810 f 1814/3062/1814 1818/1931/1818 1815/1922/1815 f 1818/1931/1818 1814/3062/1814 1820/3061/1820 f 1815/1922/1815 1818/1931/1818 1817/1923/1817 f 1792/1926/1792 1826/1905/1826 1796/3058/1796 f 1811/1920/1811 1819/1930/1819 1812/3060/1812 f 1812/3060/1812 1819/1930/1819 1820/3061/1820 f 1818/1931/1818 1820/3061/1820 1819/1930/1819 f 1821/1929/1821 1833/1928/1833 513/1933/513 f 1808/3059/1808 1833/1928/1833 1809/1927/1809 f 1806/1897/1806 1809/1927/1809 1807/1919/1807 f 1823/3063/1823 1826/1905/1826 1824/3064/1824 f 1824/3064/1824 1826/1905/1826 1816/1924/1816 f 1824/3064/1824 1825/3065/1825 1823/3063/1823 f 1826/1905/1826 1823/3063/1823 1822/1932/1822 f 1797/1906/1797 1826/1905/1826 1822/1932/1822 f 1822/1932/1822 1834/1947/1834 1508/1918/1508 f 1508/1554/1508 1834/3066/1834 1850/1954/1850 f 1816/1924/1816 1827/1935/1827 1824/3064/1824 f 1827/1935/1827 1816/1924/1816 1817/1923/1817 f 1824/3064/1824 1827/1935/1827 1825/3065/1825 f 1827/1935/1827 1817/1923/1817 1818/1931/1818 f 1825/3065/1825 1838/1938/1838 1823/3063/1823 f 1838/1938/1838 1825/3065/1825 1827/1935/1827 f 526/1942/526 1784/1894/1784 473/1895/473 f 532/3067/532 1828/3068/1828 523/1940/523 f 523/1940/523 1828/3068/1828 1781/1892/1781 f 534/3069/534 1830/3070/1830 1828/3068/1828 f 1830/3070/1830 1831/1943/1831 1829/1889/1829 f 1828/3068/1828 1829/1889/1829 1781/1892/1781 f 1830/3070/1830 1832/1944/1832 1831/1943/1831 f 530/3071/530 494/1913/494 1803/1912/1803 f 534/3069/534 1828/3068/1828 532/3067/532 f 1803/1912/1803 1832/1944/1832 530/3071/530 f 1832/1944/1832 1830/3070/1830 530/3071/530 f 1829/1889/1829 1775/1880/1775 1781/1892/1781 f 1830/3070/1830 534/3069/534 530/3071/530 f 1780/1890/1780 1831/1943/1831 1802/1911/1802 f 1831/1943/1831 1780/1890/1780 1829/1889/1829 f 1829/1889/1829 1828/3068/1828 1830/3070/1830 f 535/3072/535 1779/1888/1779 467/1887/467 f 1779/1888/1779 535/3072/535 473/1895/473 f 1804/1915/1804 493/1914/493 495/1916/495 f 1806/1897/1806 536/3073/536 1808/3059/1808 f 1808/3059/1808 536/3073/536 1833/1928/1833 f 513/1933/513 1833/1928/1833 536/3073/536 f 495/1916/495 536/3073/536 1806/1897/1806 f 1823/3063/1823 1837/1945/1837 1822/1932/1822 f 1837/1945/1837 1823/3063/1823 1838/1938/1838 f 1837/1945/1837 1838/1938/1838 1839/1948/1839 f 1839/1948/1839 1840/3074/1840 1836/1949/1836 f 1839/1948/1839 1841/1951/1841 1840/3074/1840 f 1838/1938/1838 1841/1951/1841 1839/1948/1839 f 1387/1866/1387 1771/3056/1771 1403/3075/1403 f 1844/3076/1844 1523/1558/1523 1772/1952/1772 f 1843/1964/1843 1454/3006/1454 1770/1961/1770 f 1454/3006/1454 1868/3077/1868 1770/1961/1770 f 1454/3006/1454 1523/1558/1523 1868/3077/1868 f 1842/3078/1842 1523/1558/1523 1844/3076/1844 f 1842/3078/1842 1866/3079/1866 1846/3080/1846 f 1844/3076/1844 1845/3081/1845 1866/3079/1866 f 1845/3081/1845 1844/3076/1844 1772/1952/1772 f 1866/3079/1866 1842/3078/1842 1844/3076/1844 f 1848/1957/1848 1852/1955/1852 1850/1954/1850 f 1847/1953/1847 1851/1956/1851 1849/3082/1849 f 1849/3082/1849 1851/1956/1851 1864/3083/1864 f 1851/1956/1851 1852/1955/1852 1862/3084/1862 f 1852/1955/1852 1848/1957/1848 1862/3084/1862 f 1855/3085/1855 1854/3086/1854 1858/3087/1858 f 1850/1954/1850 1853/3088/1853 1848/1957/1848 f 1858/3087/1858 1854/3086/1854 1835/1946/1835 f 1835/1946/1835 1854/3086/1854 1834/1947/1834 f 1854/3086/1854 1855/3085/1855 1834/1947/1834 f 1855/3089/1855 1856/1958/1856 1853/3088/1853 f 1856/1958/1856 1848/1957/1848 1853/3088/1853 f 1834/3066/1834 1855/3089/1855 1853/3088/1853 f 1853/3088/1853 1850/1954/1850 1834/3066/1834 f 1855/3085/1855 1858/3087/1858 1861/3090/1861 f 1865/1959/1865 1859/3091/1859 1860/3092/1860 f 1857/1960/1857 1865/1959/1865 1860/3092/1860 f 1855/3085/1855 1861/3090/1861 1859/1996/1859 f 1859/3091/1859 1856/1958/1856 1855/3089/1855 f 1848/1957/1848 1857/1960/1857 1863/3093/1863 f 1857/1960/1857 1849/3082/1849 1863/3093/1863 f 1848/1957/1848 1863/3093/1863 1862/3084/1862 f 1862/3084/1862 1864/3083/1864 1851/1956/1851 f 1849/3082/1849 1864/3083/1864 1863/3093/1863 f 1864/3083/1864 1862/3084/1862 1863/3093/1863 f 1859/3091/1859 1865/1959/1865 1856/1958/1856 f 1849/3082/1849 1772/1952/1772 1847/1953/1847 f 1772/1952/1772 1874/3094/1874 1845/3081/1845 f 1845/3081/1845 1874/3094/1874 1866/3079/1866 f 1874/3094/1874 1772/1952/1772 1849/3082/1849 f 1874/3094/1874 1849/3082/1849 1857/1960/1857 f 1866/3079/1866 1869/1962/1869 1846/3080/1846 f 1846/3080/1846 1869/1962/1869 1770/1961/1770 f 1454/3006/1454 1867/3055/1867 1457/1868/1457 f 1770/1961/1770 1868/3077/1868 1846/3080/1846 f 1868/3077/1868 1842/3078/1842 1846/3080/1846 f 1868/3077/1868 1523/1558/1523 1842/3078/1842 f 1457/1868/1457 1867/3055/1867 1771/3056/1771 f 1843/1964/1843 1870/1963/1870 1867/3055/1867 f 1771/3056/1771 1867/3055/1867 1403/3075/1403 f 1874/3094/1874 1869/1962/1869 1866/3079/1866 f 1874/1978/1874 1871/1966/1871 1869/1970/1869 f 1871/1966/1871 1874/1978/1874 2221/1977/2221 f 1872/1967/1872 1876/3095/1876 1873/2003/1873 f 1871/1966/1871 1875/2341/1875 1872/1967/1872 f 1857/3096/1857 1877/2000/1877 1874/3097/1874 f 1877/2000/1877 1857/3096/1857 1860/1997/1860 f 1877/1979/1877 2223/1983/2223 2222/1980/2222 f 1876/3095/1876 1880/2218/1880 2125/2217/2125 f 2224/3098/2224 1878/2342/1878 1888/3099/1888 f 1878/2342/1878 1881/3100/1881 1888/3099/1888 f 1876/3095/1876 2224/3098/2224 1880/2218/1880 f 1876/3095/1876 1872/1967/1872 1875/2341/1875 f 1897/2343/1897 1886/1984/1886 1902/3101/1902 f 1886/1984/1886 1887/1985/1887 1883/3102/1883 f 1880/2218/1880 1888/3099/1888 1882/2215/1882 f 1888/3099/1888 1889/3103/1889 1882/2215/1882 f 1881/3100/1881 1889/3103/1889 1888/3099/1888 f 1881/3100/1881 1878/2342/1878 1897/2343/1897 f 1886/1984/1886 1897/2343/1897 2223/1983/2223 f 1883/3104/1883 1898/1987/1898 1900/3105/1900 f 1902/3101/1902 1900/3106/1900 1897/2343/1897 f 1884/1999/1884 1901/1986/1901 1885/1989/1885 f 1887/1988/1887 1898/1987/1898 1883/3104/1883 f 1893/1994/1893 1892/1991/1892 625/1990/625 f 1890/1992/1890 1836/1949/1836 1891/1993/1891 f 1891/1993/1891 1840/3074/1840 1841/1951/1841 f 1891/1993/1891 1836/1949/1836 1840/3074/1840 f 1890/1992/1890 1835/1946/1835 1836/1949/1836 f 1835/1946/1835 1890/1992/1890 1858/3087/1858 f 1858/3087/1858 1890/1992/1890 1861/3090/1861 f 1841/1951/1841 1892/1991/1892 1891/1993/1891 f 1890/1992/1890 1859/1996/1859 1861/3090/1861 f 1870/1963/1870 1403/3075/1403 1867/3055/1867 f 2164/2522/2164 1873/2003/1873 1879/3107/1879 f 1881/3100/1881 1895/3108/1895 1889/3103/1889 f 1889/3103/1889 1895/3108/1895 1903/3109/1903 f 1889/3103/1889 1903/3109/1903 1882/2215/1882 f 1881/3100/1881 1897/2343/1897 1894/3110/1894 f 1894/3110/1894 1897/2343/1897 1900/3106/1900 f 1881/3100/1881 1896/3111/1896 1895/3108/1895 f 1894/3112/1894 1900/3105/1900 1899/2007/1899 f 1899/2007/1899 1900/3105/1900 1898/1987/1898 f 623/3113/623 646/2005/646 1898/1987/1898 f 1898/1987/1898 1901/1986/1901 623/3113/623 f 625/3114/625 1884/1999/1884 1893/1998/1893 f 1901/1986/1901 625/3114/625 623/3113/623 f 1884/1999/1884 625/3114/625 1901/1986/1901 f 1900/3106/1900 1902/3101/1902 1883/3102/1883 f 1902/3101/1902 1886/1984/1886 1883/3102/1883 f 1881/3100/1881 1894/3110/1894 1896/3111/1896 f 1899/3115/1899 1905/2021/1905 1894/3116/1894 f 1899/3115/1899 1925/2018/1925 1905/2021/1905 f 1905/2015/1905 1908/2022/1908 1906/2016/1906 f 1917/2029/1917 1912/2028/1912 1911/3117/1911 f 1913/2030/1913 1917/2031/1917 1911/3117/1911 f 1913/2030/1913 1911/3117/1911 1921/2037/1921 f 1921/2037/1921 1911/3117/1911 1912/2028/1912 f 1923/2038/1923 1921/2037/1921 1922/2036/1922 f 1920/2034/1920 1926/2039/1926 1918/2035/1918 f 1925/2018/1925 1899/3115/1899 1928/2042/1928 f 1924/2032/1924 1929/2040/1929 1926/2039/1926 f 1924/2032/1924 1930/2043/1930 1929/2040/1929 f 1978/3118/1978 2004/3119/2004 1979/3120/1979 f 1932/2046/1932 1936/2083/1936 1931/2047/1931 f 1931/2047/1931 1936/2083/1936 1959/2075/1959 f 1942/2060/1942 1948/2059/1948 1952/2069/1952 f 1954/3121/1954 1953/3122/1953 1951/3123/1951 f 1954/3121/1954 1934/2241/1934 1955/3124/1955 f 692/3125/692 695/3126/695 1945/3127/1945 f 1933/2050/1933 1946/2063/1946 1949/2054/1949 f 1949/2054/1949 1946/2063/1946 1940/2065/1940 f 1946/2063/1946 692/2123/692 1945/2064/1945 f 1940/2065/1940 1950/2066/1950 1943/2067/1943 f 1950/2066/1950 1952/2069/1952 1943/2067/1943 f 1952/2069/1952 1948/2059/1948 1943/2067/1943 f 1953/2068/1953 1941/2058/1941 1952/2069/1952 f 1955/3124/1955 1953/3122/1953 1954/3121/1954 f 1945/3127/1945 1958/3128/1958 1944/3129/1944 f 1953/2068/1953 1955/2070/1955 1941/2058/1941 f 1957/2074/1957 1945/3127/1945 695/3126/695 f 1944/3129/1944 1958/3128/1958 1986/2072/1986 f 1945/3127/1945 1957/2074/1957 1985/2073/1985 f 1941/2058/1941 1960/2057/1960 1942/2060/1942 f 1969/2086/1969 1963/2079/1963 1965/2078/1965 f 1967/2088/1967 1961/2077/1961 1962/2076/1962 f 1942/2060/1942 1952/2069/1952 1941/2058/1941 f 1967/2085/1967 1973/2093/1973 1969/2086/1969 f 1973/2093/1973 1977/3130/1977 1974/2094/1974 f 1974/2094/1974 1977/3130/1977 1975/2095/1975 f 1975/2095/1975 1977/3130/1977 1976/2091/1976 f 1976/2091/1976 1977/3130/1977 1973/2092/1973 f 1979/2120/1979 1929/2119/1929 1930/3131/1930 f 1928/2102/1928 1980/2101/1980 1930/2107/1930 f 1979/2108/1979 1981/2104/1981 1978/2103/1978 f 1982/2110/1982 736/2109/736 735/3132/735 f 738/2112/738 1983/2111/1983 735/3132/735 f 1983/2111/1983 1982/2110/1982 735/3132/735 f 1876/3095/1876 1879/3107/1879 1873/2003/1873 f 1408/3133/1408 1432/3134/1432 1984/3135/1984 f 1945/3127/1945 1985/2073/1985 1958/3128/1958 f 1985/2073/1985 1986/2072/1986 1958/3128/1958 f 1944/3129/1944 1986/2072/1986 1953/3122/1953 f 1944/2061/1944 1953/2068/1953 1947/2062/1947 f 1953/3122/1953 1986/2072/1986 1951/3123/1951 f 1951/3123/1951 1986/2072/1986 1956/2071/1956 f 695/3126/695 751/3136/751 1957/2074/1957 f 751/3136/751 754/2131/754 1988/3137/1988 f 1988/3137/1988 754/2131/754 1989/3138/1989 f 2019/3139/2019 2018/2130/2018 2009/2129/2009 f 751/3136/751 1988/3137/1988 1987/2116/1987 f 1988/3137/1988 1991/2127/1991 1987/2116/1987 f 1987/2116/1987 1991/2127/1991 1990/2113/1990 f 1987/2116/1987 1992/2115/1992 1956/2071/1956 f 1991/2127/1991 1993/2117/1993 1990/2113/1990 f 1989/3138/1989 1996/2124/1996 1988/3137/1988 f 1988/3137/1988 1996/2124/1996 1991/2127/1991 f 1996/2124/1996 1997/3140/1997 2007/2144/2007 f 1992/2115/1992 1998/3141/1998 1956/2071/1956 f 1998/3141/1998 1951/3123/1951 1956/2071/1956 f 1951/3123/1951 1999/3142/1999 1954/3121/1954 f 1998/3141/1998 1999/3142/1999 1951/3123/1951 f 1954/3121/1954 1999/3142/1999 1998/3141/1998 f 1998/3141/1998 1992/2115/1992 1994/2114/1994 f 2004/3119/2004 2148/3143/2148 1979/3120/1979 f 2152/2256/2152 2001/2244/2001 2002/2247/2002 f 2000/2045/2000 2004/3119/2004 1932/2046/1932 f 2004/2097/2004 1933/2050/1933 1932/2053/1932 f 692/2123/692 2005/2096/2005 700/3144/700 f 2005/2096/2005 1978/2098/1978 700/3144/700 f 1957/2074/1957 751/3136/751 1956/2071/1956 f 1956/2071/1956 751/3136/751 1987/2116/1987 f 1996/2124/1996 2007/2144/2007 2030/2147/2030 f 2008/2125/2008 1995/2118/1995 2006/2126/2006 f 1996/2124/1996 2030/2147/2030 2008/2125/2008 f 2009/2129/2009 777/2128/777 2012/3145/2012 f 1997/3140/1997 2018/2130/2018 2019/3139/2019 f 2019/3139/2019 2010/3146/2010 1997/3140/1997 f 1997/3140/1997 2010/3146/2010 2007/2144/2007 f 1997/3140/1997 1996/2124/1996 1989/3138/1989 f 2019/3139/2019 2036/3147/2036 2010/3146/2010 f 2036/3147/2036 2019/3139/2019 2009/2129/2009 f 2035/3148/2035 2036/3147/2036 2012/3145/2012 f 2012/3145/2012 2036/3147/2036 2009/2129/2009 f 2014/2135/2014 2012/3145/2012 756/2132/756 f 2012/3145/2012 777/2128/777 756/2132/756 f 2014/2135/2014 2015/2134/2015 2034/3149/2034 f 2016/3150/2016 2013/2143/2013 2014/2135/2014 f 2016/3150/2016 2033/3151/2033 2013/2143/2013 f 754/2131/754 2018/2130/2018 1989/3138/1989 f 2018/2130/2018 1997/3140/1997 1989/3138/1989 f 1994/2114/1994 2020/3152/2020 2026/3153/2026 f 1995/2118/1995 2021/3154/2021 2020/3152/2020 f 2008/2125/2008 2029/3155/2029 1995/2118/1995 f 2021/3154/2021 2022/2136/2022 2020/3152/2020 f 1994/2114/1994 2023/3156/2023 1998/3141/1998 f 2020/3152/2020 1994/2114/1994 1995/2118/1995 f 1994/2114/1994 2026/3153/2026 2023/3156/2023 f 1995/2118/1995 2029/3155/2029 2021/3154/2021 f 2029/3155/2029 2008/2125/2008 2030/2147/2030 f 2021/3154/2021 2029/3155/2029 2024/3157/2024 f 2021/3154/2021 2024/3157/2024 2022/2136/2022 f 2026/3153/2026 2020/3152/2020 2027/3158/2027 f 2026/3153/2026 2027/3158/2027 2023/3156/2023 f 2027/3158/2027 2025/2139/2025 2023/3156/2023 f 2027/3158/2027 2028/3159/2028 2025/2139/2025 f 2028/3159/2028 2027/3158/2027 2020/3152/2020 f 2025/2139/2025 2028/3159/2028 2022/2136/2022 f 2028/3159/2028 2020/3152/2020 2022/2136/2022 f 2023/3156/2023 2055/3160/2055 1998/3141/1998 f 2029/3155/2029 2030/2147/2030 2024/3157/2024 f 2033/3151/2033 2016/3150/2016 2034/3149/2034 f 2034/3149/2034 2015/2134/2015 2033/3151/2033 f 2035/3148/2035 2037/2141/2037 2036/3147/2036 f 2012/3145/2012 2013/2143/2013 2011/2142/2011 f 2035/3148/2035 2012/3145/2012 2011/2142/2011 f 2012/3145/2012 2014/2135/2014 2013/2143/2013 f 2011/2142/2011 2037/2141/2037 2035/3148/2035 f 2037/2141/2037 2010/3146/2010 2036/3147/2036 f 2031/2137/2031 2022/2136/2022 2024/3157/2024 f 2030/2147/2030 2041/2146/2041 2024/3157/2024 f 2024/3157/2024 2041/2146/2041 2031/2137/2031 f 2040/2145/2040 2010/3146/2010 2037/2141/2037 f 2042/2148/2042 2424/2567/2424 1406/2568/1406 f 1408/3133/1408 2044/3161/2044 2042/2148/2042 f 2039/2150/2039 2044/3161/2044 2043/2152/2043 f 2044/3161/2044 2045/2346/2045 2043/2152/2043 f 2044/3161/2044 2046/3162/2046 2045/2346/2045 f 1984/3135/1984 2044/3161/2044 1408/3133/1408 f 1984/3135/1984 2047/3163/2047 2044/3161/2044 f 2044/3161/2044 2047/3163/2047 2046/3162/2046 f 2047/3163/2047 1984/3135/1984 1432/3134/1432 f 2049/2153/2049 2050/3164/2050 2048/2151/2048 f 2050/3164/2050 2031/2137/2031 2048/2151/2048 f 2031/2137/2031 2050/3164/2050 2032/2138/2032 f 2051/2156/2051 2050/3164/2050 2049/2153/2049 f 2050/3164/2050 2051/2156/2051 2032/2138/2032 f 1998/3141/1998 2055/3160/2055 1954/3121/1954 f 1954/3121/1954 2055/3160/2055 2052/3165/2052 f 2053/2361/2053 2057/2243/2057 2052/3165/2052 f 2057/2243/2057 2053/2361/2053 2054/2175/2054 f 2062/3166/2062 2065/2362/2065 2052/3165/2052 f 2054/2175/2054 2142/2214/2142 2057/2243/2057 f 2052/3165/2052 2057/2243/2057 2056/2242/2056 f 2056/2242/2056 1954/3121/1954 2052/3165/2052 f 2055/3160/2055 2058/2155/2058 2059/2154/2059 f 2058/2155/2058 2025/2139/2025 2032/2138/2032 f 2023/3156/2023 2058/2155/2058 2055/3160/2055 f 2058/2155/2058 2023/3156/2023 2025/2139/2025 f 2059/2154/2059 2060/3167/2060 2055/3160/2055 f 2059/2154/2059 2066/2349/2066 2060/3167/2060 f 2060/3167/2060 2066/2349/2066 2062/3166/2062 f 2066/2349/2066 2063/3168/2063 2062/3166/2062 f 2061/2350/2061 2064/2363/2064 2063/3168/2063 f 2064/2363/2064 2065/2362/2065 2063/3168/2063 f 2052/3165/2052 2065/2362/2065 2053/2361/2053 f 2065/2362/2065 2062/3166/2062 2063/3168/2063 f 2063/3168/2063 2066/2349/2066 2061/2350/2061 f 2060/3167/2060 2062/3166/2062 2055/3160/2055 f 2062/3166/2062 2052/3165/2052 2055/3160/2055 f 2053/2361/2053 2092/2174/2092 2054/2175/2054 f 2070/2159/2070 2072/2177/2072 2067/2160/2067 f 2053/2361/2053 2252/3169/2252 2092/2174/2092 f 2094/2353/2094 2093/2178/2093 2073/2176/2073 f 2091/2179/2091 2074/2169/2074 2071/2163/2071 f 2075/2267/2075 2091/2179/2091 2095/3170/2095 f 2091/2179/2091 2075/2267/2075 2074/2169/2074 f 2080/2167/2080 2081/2168/2081 2101/2173/2101 f 2078/2164/2078 2081/2168/2081 2080/2167/2080 f 2087/3171/2087 2102/3172/2102 2084/2183/2084 f 2086/2180/2086 2101/2173/2101 2085/2184/2085 f 2088/2166/2088 2154/3173/2154 2090/2211/2090 f 2088/2166/2088 2090/2211/2090 2077/2162/2077 f 2067/2160/2067 2072/2177/2072 2071/2163/2071 f 2072/2177/2072 2091/2179/2091 2071/2163/2071 f 2095/3170/2095 2091/2179/2091 2093/2178/2093 f 2155/2212/2155 2069/2158/2069 2068/2157/2068 f 2069/2158/2069 2155/2212/2155 2141/2213/2141 f 2093/2178/2093 2094/2353/2094 2047/3163/2047 f 2094/2353/2094 2046/3162/2046 2047/3163/2047 f 1432/3134/1432 1433/3174/1433 2047/3163/2047 f 1424/3175/1424 1433/3174/1433 1432/3134/1432 f 1433/3174/1433 2160/2260/2160 2095/3170/2095 f 2084/2183/2084 2111/2182/2111 2087/3171/2087 f 2087/3171/2087 2111/2182/2111 2110/2196/2110 f 2101/2173/2101 2097/2186/2097 2100/2289/2100 f 2100/2289/2100 2511/2185/2511 2085/2184/2085 f 2085/2184/2085 2101/2173/2101 2100/2289/2100 f 2101/2173/2101 2086/2180/2086 2080/2167/2080 f 2084/2183/2084 2102/3172/2102 2079/2165/2079 f 2102/3172/2102 2089/2207/2089 2079/2165/2079 f 2174/2197/2174 2103/2210/2103 2096/2189/2096 f 2174/2197/2174 2177/2298/2177 2103/2210/2103 f 2105/2190/2105 2096/2189/2096 2103/2210/2103 f 2110/2196/2110 2113/2202/2113 2087/3171/2087 f 2113/2202/2113 2110/2196/2110 2109/2188/2109 f 2174/2197/2174 2112/2181/2112 2511/2185/2511 f 2087/3171/2087 2113/2202/2113 2115/2198/2115 f 2102/3172/2102 2115/2198/2115 2114/2201/2114 f 2115/2198/2115 2102/3172/2102 2087/3171/2087 f 2089/2207/2089 2116/2206/2116 2154/3173/2154 f 2124/2204/2124 2089/2207/2089 2102/3172/2102 f 2124/2204/2124 2102/3172/2102 2114/2201/2114 f 2125/2217/2125 2129/2219/2129 2127/3176/2127 f 2126/2224/2126 2131/2223/2131 2128/3177/2128 f 2128/3177/2128 2131/2223/2131 2147/2227/2147 f 2130/2222/2130 1882/2221/1882 1903/3178/1903 f 1903/3178/1903 2134/3179/2134 2130/2222/2130 f 2130/2222/2130 2134/3179/2134 2135/2228/2135 f 2134/3179/2134 1903/3178/1903 2132/3180/2132 f 2132/2230/2132 1903/2012/1903 1904/2011/1904 f 2134/3179/2134 2139/2235/2139 2135/2228/2135 f 2139/2236/2139 2134/2233/2134 2137/2232/2137 f 2147/2227/2147 2140/3181/2140 2128/3177/2128 f 2155/2212/2155 2144/2237/2144 2141/2213/2141 f 2143/2258/2143 2140/2248/2140 2001/2244/2001 f 2056/2242/2056 1934/2241/1934 1954/3121/1954 f 2143/2238/2143 1934/2241/1934 2142/2214/2142 f 2002/2247/2002 2146/3182/2146 2003/3183/2003 f 2003/3183/2003 2151/2250/2151 2149/2122/2149 f 2146/3182/2146 2151/2250/2151 2003/3183/2003 f 2000/2257/2000 2150/2121/2150 2148/3184/2148 f 2148/3143/2148 2004/3119/2004 2000/2045/2000 f 2149/2122/2149 2150/2121/2150 2153/3185/2153 f 2150/2121/2150 2000/2257/2000 2153/3185/2153 f 2151/2253/2151 2146/2246/2146 2145/2245/2145 f 2150/2121/2150 1979/2120/1979 2148/3184/2148 f 2003/3183/2003 2153/3185/2153 2002/2247/2002 f 2153/3185/2153 2152/2256/2152 2002/2247/2002 f 2153/3185/2153 2000/2257/2000 2152/2256/2152 f 2149/2122/2149 2153/3185/2153 2003/3183/2003 f 2128/2240/2128 2156/2274/2156 2129/2275/2129 f 2156/2274/2156 2144/2237/2144 2155/2212/2155 f 2156/2274/2156 2128/2240/2128 2144/2237/2144 f 2127/3176/2127 1879/3107/1879 2125/2217/2125 f 2127/3176/2127 2157/3186/2157 1879/3107/1879 f 1879/3107/1879 2157/3186/2157 2164/2522/2164 f 1876/3095/1876 2125/2217/2125 1879/3107/1879 f 1427/3187/1427 2158/1976/2158 1428/2261/1428 f 1426/1973/1426 2158/1976/2158 1427/3187/1427 f 2160/2260/2160 2159/2259/2159 2095/3170/2095 f 2095/3170/2095 2159/2259/2159 2075/2267/2075 f 2160/2260/2160 1433/3174/1433 1428/2261/1428 f 2042/2148/2042 1406/2568/1406 1408/3133/1408 f 2083/2171/2083 2162/2263/2162 2181/2264/2181 f 2165/2266/2165 2075/2267/2075 2159/2259/2159 f 2082/2170/2082 2165/2266/2165 2163/2262/2163 f 2164/1975/2164 2157/3188/2157 2165/2266/2165 f 2161/2265/2161 2181/2264/2181 2183/2293/2183 f 2116/2206/2116 2167/2272/2167 2154/3173/2154 f 2154/3173/2154 2167/2272/2167 2090/2211/2090 f 2161/2265/2161 2098/2187/2098 2099/2172/2099 f 2117/2203/2117 2171/3189/2171 2168/2276/2168 f 2119/2199/2119 2168/2276/2168 2118/2200/2118 f 2117/2203/2117 2168/2276/2168 2119/2199/2119 f 2122/2209/2122 2171/3189/2171 2117/2203/2117 f 2121/2208/2121 2170/2278/2170 2122/2209/2122 f 2122/2209/2122 2170/2278/2170 2171/3189/2171 f 2174/2197/2174 2511/2185/2511 2510/2697/2510 f 2510/2697/2510 2177/2298/2177 2174/2197/2174 f 2173/2283/2173 2168/2294/2168 2171/2284/2171 f 2180/2288/2180 2179/2291/2179 2173/2283/2173 f 2172/2281/2172 2180/2288/2180 2173/2283/2173 f 2183/2293/2183 2184/2292/2184 2161/2265/2161 f 2184/2292/2184 2098/2187/2098 2161/2265/2161 f 2163/2262/2163 2157/3188/2157 2127/2296/2127 f 2157/3188/2157 2163/2262/2163 2165/2266/2165 f 2163/2262/2163 2127/2296/2127 2162/2263/2162 f 2103/2210/2103 2185/2300/2185 2108/2194/2108 f 2185/2300/2185 2190/2305/2190 2189/2302/2189 f 2343/2311/2343 2381/2314/2381 2188/2303/2188 f 2306/2309/2306 2342/2310/2342 2189/2302/2189 f 2193/2313/2193 2305/2308/2305 2190/2305/2190 f 2201/2323/2201 2205/2322/2205 2204/2334/2204 f 2201/2323/2201 2204/2334/2204 2202/2333/2202 f 2204/2334/2204 2205/2322/2205 2203/2330/2203 f 2196/2316/2196 2209/2327/2209 2198/2318/2198 f 2198/2318/2198 2209/2327/2209 2200/2320/2200 f 2197/2319/2197 2256/2365/2256 2195/2317/2195 f 2199/2321/2199 2256/2365/2256 2197/2319/2197 f 2216/2339/2216 2219/3190/2219 2280/2340/2280 f 2216/2339/2216 2220/2280/2220 2219/3190/2219 f 2415/2429/2415 2219/3191/2219 2218/2430/2218 f 2280/2340/2280 2219/3190/2219 2415/2426/2415 f 2219/3191/2219 2217/3192/2217 2218/2430/2218 f 2219/3190/2219 2220/2280/2220 2217/3193/2217 f 1871/1966/1871 2221/1977/2221 1875/2341/1875 f 1878/2342/1878 2224/3098/2224 1875/2341/1875 f 2224/3098/2224 1876/3095/1876 1875/2341/1875 f 2224/3098/2224 1888/3099/1888 1880/2218/1880 f 2225/2345/2225 2228/2344/2228 2226/3194/2226 f 2228/2344/2228 2045/2346/2045 2046/3162/2046 f 2043/2152/2043 2225/2345/2225 2049/2153/2049 f 2226/3194/2226 2228/2344/2228 2227/2360/2227 f 2228/2344/2228 2046/3162/2046 2227/2360/2227 f 2227/2360/2227 2046/3162/2046 2094/2353/2094 f 2230/3195/2230 2231/2351/2231 2073/2176/2073 f 2232/3196/2232 2233/3197/2233 2239/3198/2239 f 2239/3198/2239 2233/3197/2233 2229/3199/2229 f 2232/3196/2232 2236/3200/2236 2233/3197/2233 f 2233/3197/2233 2236/3200/2236 2234/3201/2234 f 2234/3201/2234 2236/3200/2236 2250/2356/2250 f 2250/2356/2250 2236/3200/2236 2235/2357/2235 f 2236/3200/2236 2232/3196/2232 2237/2347/2237 f 2236/3200/2236 2237/2347/2237 2235/2357/2235 f 2232/3196/2232 2239/3198/2239 2238/2348/2238 f 2232/3196/2232 2238/2348/2238 2237/2347/2237 f 2237/2347/2237 2051/2156/2051 2235/2357/2235 f 2238/2348/2238 2239/3198/2239 2061/2350/2061 f 2229/3199/2229 2240/2364/2240 2239/3198/2239 f 2240/2364/2240 2064/2363/2064 2239/3198/2239 f 2061/2350/2061 2239/3198/2239 2064/2363/2064 f 2251/2358/2251 2248/3202/2248 2247/2359/2247 f 2231/2351/2231 2242/3203/2242 2241/2352/2241 f 2229/3199/2229 2242/3203/2242 2231/2351/2231 f 2231/2351/2231 2230/3195/2230 2229/3199/2229 f 2242/3203/2242 2229/3199/2229 2234/3201/2234 f 2234/3201/2234 2229/3199/2229 2233/3197/2233 f 2242/3203/2242 2234/3201/2234 2241/2352/2241 f 2234/3201/2234 2250/2356/2250 2249/3204/2249 f 2250/2356/2250 2225/2345/2225 2226/3194/2226 f 2250/2356/2250 2243/2355/2243 2225/2345/2225 f 2225/2345/2225 2243/2355/2243 2049/2153/2049 f 2051/2156/2051 2244/2354/2244 2235/2357/2235 f 2244/2354/2244 2246/3205/2246 2245/3206/2245 f 2244/2354/2244 2245/3206/2245 2243/2355/2243 f 2243/2355/2243 2245/3206/2245 2049/2153/2049 f 2245/3206/2245 2246/3205/2246 2049/2153/2049 f 2049/2153/2049 2246/3205/2246 2051/2156/2051 f 2246/3205/2246 2244/2354/2244 2051/2156/2051 f 2247/2359/2247 2226/3194/2226 2227/2360/2227 f 2247/2359/2247 2249/3204/2249 2226/3194/2226 f 2249/3204/2249 2250/2356/2250 2226/3194/2226 f 2251/2358/2251 2094/2353/2094 2241/2352/2241 f 2248/3202/2248 2249/3204/2249 2247/2359/2247 f 2251/2358/2251 2241/2352/2241 2248/3202/2248 f 2241/2352/2241 2234/3201/2234 2248/3202/2248 f 2234/3201/2234 2249/3204/2249 2248/3202/2248 f 2073/2176/2073 2252/3169/2252 2230/3195/2230 f 2229/3199/2229 2252/3169/2252 2240/2364/2240 f 2252/3169/2252 2053/2361/2053 2240/2364/2240 f 2252/3169/2252 2229/3199/2229 2230/3195/2230 f 2073/2176/2073 2092/2174/2092 2252/3169/2252 f 2042/2148/2042 2044/3161/2044 2039/2150/2039 f 2154/3173/2154 2088/2166/2088 2089/2207/2089 f 2089/2207/2089 2088/2166/2088 2079/2165/2079 f 2254/2367/2254 2202/2333/2202 2212/2332/2212 f 2213/2335/2213 2203/2330/2203 2210/2329/2210 f 2254/2367/2254 2262/3207/2262 2260/2372/2260 f 2212/2332/2212 2262/3207/2262 2254/2367/2254 f 2212/2332/2212 2264/2337/2264 2262/3207/2262 f 2263/2338/2263 2213/2335/2213 2261/3208/2261 f 2261/3208/2261 2210/2329/2210 2257/2369/2257 f 2210/2329/2210 2261/3208/2261 2213/2335/2213 f 2215/2336/2215 2268/3209/2268 2264/2337/2264 f 2263/2338/2263 2268/3209/2268 2215/2336/2215 f 2264/2380/2264 2268/3210/2268 2263/2379/2263 f 2275/2394/2275 2276/2393/2276 2277/2401/2277 f 2275/2394/2275 2277/2401/2277 2278/2400/2278 f 2277/2401/2277 2276/2393/2276 2279/2397/2279 f 2272/2389/2272 2281/2395/2281 2274/2391/2274 f 2274/2391/2274 2281/2395/2281 2276/2393/2276 f 2273/2392/2273 2289/2406/2289 2271/2390/2271 f 2275/2394/2275 2289/2406/2289 2273/2392/2273 f 2290/2407/2290 2278/2400/2278 2284/2399/2284 f 2285/2402/2285 2279/2397/2279 2282/2396/2282 f 2290/2407/2290 2294/3211/2294 2292/2412/2292 f 2284/2399/2284 2296/3212/2296 2290/2407/2290 f 2284/2399/2284 2287/2404/2287 2296/3212/2296 f 2288/2405/2288 2285/2402/2285 2295/3213/2295 f 2282/2396/2282 2293/3214/2293 2295/3213/2295 f 2293/3214/2293 2282/2396/2282 2291/2409/2291 f 2282/2396/2282 2295/3213/2295 2285/2402/2285 f 2290/2407/2290 2296/3212/2296 2294/3211/2294 f 2286/2403/2286 2300/3215/2300 2287/2404/2287 f 2288/2405/2288 2300/3215/2300 2286/2403/2286 f 2287/2422/2287 2300/3216/2300 2288/2421/2288 f 2217/3192/2217 2302/2431/2302 2218/2430/2218 f 2313/2441/2313 2314/2440/2314 2315/2450/2315 f 2313/2441/2313 2315/2450/2315 2316/2449/2316 f 2315/2450/2315 2314/2440/2314 2317/2446/2317 f 2308/2434/2308 2319/2443/2319 2310/2436/2310 f 2310/2436/2310 2319/2443/2319 2312/2438/2312 f 2309/2437/2309 2328/2455/2328 2307/2435/2307 f 2311/2439/2311 2328/2455/2328 2309/2437/2309 f 2330/2457/2330 2316/2449/2316 2323/2448/2323 f 2324/2451/2324 2317/2446/2317 2321/2445/2321 f 2330/2457/2330 2337/3217/2337 2335/2462/2335 f 2323/2448/2323 2337/3217/2337 2330/2457/2330 f 2323/2448/2323 2326/2453/2326 2337/3217/2337 f 2327/2454/2327 2324/2451/2324 2336/3218/2336 f 2336/3218/2336 2321/2445/2321 2332/2460/2332 f 2321/2445/2321 2336/3218/2336 2324/2451/2324 f 2325/2452/2325 2341/3219/2341 2326/2453/2326 f 2327/2454/2327 2341/3219/2341 2325/2452/2325 f 2326/2470/2326 2341/3220/2341 2327/2469/2327 f 2318/2442/2318 2255/2368/2255 2340/2386/2340 f 2350/2484/2350 2351/2483/2351 2352/2493/2352 f 2350/2484/2350 2352/2493/2352 2353/2492/2353 f 2352/2493/2352 2351/2483/2351 2354/2489/2354 f 2345/2477/2345 2356/2486/2356 2347/2479/2347 f 2347/2479/2347 2356/2486/2356 2349/2481/2349 f 2362/3221/2362 2360/2491/2360 2359/2490/2359 f 2361/2494/2361 2362/3221/2362 2359/2490/2359 f 2346/2480/2346 2363/2495/2363 2344/2478/2344 f 2348/2482/2348 2363/2495/2363 2346/2480/2346 f 2365/2497/2365 2353/2492/2353 2360/2491/2360 f 2361/2494/2361 2354/2489/2354 2358/2488/2358 f 2372/2508/2372 2362/3222/2362 2371/2507/2371 f 2365/2497/2365 2372/3223/2372 2370/2502/2370 f 2360/2491/2360 2372/3223/2372 2365/2497/2365 f 2360/2491/2360 2362/3221/2362 2372/3223/2372 f 2362/3221/2362 2361/2494/2361 2371/3224/2371 f 2371/3224/2371 2358/2488/2358 2367/2499/2367 f 2358/2488/2358 2371/3224/2371 2361/2494/2361 f 2355/2485/2355 2331/2458/2331 2376/2475/2376 f 2414/2558/2414 2302/2517/2302 2378/2516/2378 f 2220/2280/2220 2379/2279/2379 2217/3193/2217 f 2217/2518/2217 2379/3225/2379 2377/2519/2377 f 2108/2194/2108 2380/2306/2380 2120/2195/2120 f 1479/1530/1479 1534/1575/1534 1482/1577/1482 f 1556/1609/1556 1587/1683/1587 1589/1610/1589 f 1595/3033/1595 1571/1626/1571 1579/1628/1579 f 1563/1619/1563 1505/3039/1505 1672/1617/1672 f 1463/1520/1463 1491/3016/1491 1466/1536/1466 f 1447/1508/1447 1462/1521/1462 1455/1524/1455 f 2093/2178/2093 2047/3163/2047 2095/3170/2095 f 2095/3170/2095 2047/3163/2047 1433/3174/1433 f 2389/2531/2389 2390/2530/2390 2391/2540/2391 f 2389/2531/2389 2391/2540/2391 2392/2539/2392 f 2391/2540/2391 2390/2530/2390 2393/2536/2393 f 2384/2524/2384 2395/2533/2395 2386/2526/2386 f 2386/2526/2386 2395/2533/2395 2388/2528/2388 f 2401/3226/2401 2399/2538/2399 2398/2537/2398 f 2400/2541/2400 2401/3226/2401 2398/2537/2398 f 2385/2527/2385 2402/2542/2402 2383/2525/2383 f 2387/2529/2387 2402/2542/2402 2385/2527/2385 f 2404/2544/2404 2392/2539/2392 2399/2538/2399 f 2400/2541/2400 2393/2536/2393 2397/2535/2397 f 2411/2555/2411 2401/3227/2401 2410/2554/2410 f 2404/2544/2404 2411/3228/2411 2409/2549/2409 f 2399/2538/2399 2411/3228/2411 2404/2544/2404 f 2399/2538/2399 2401/3226/2401 2411/3228/2411 f 2401/3226/2401 2400/2541/2400 2410/3229/2410 f 2410/3229/2410 2397/2535/2397 2406/2546/2406 f 2397/2535/2397 2410/3229/2410 2400/2541/2400 f 2394/2532/2394 2366/2498/2366 2375/2514/2375 f 2405/2545/2405 2192/2307/2192 2382/2315/2382 f 2299/3230/2299 2304/2428/2304 2303/2433/2303 f 2299/3230/2299 2415/2429/2415 2304/2428/2304 f 2270/2325/2270 2191/2304/2191 2186/2299/2186 f 2417/2563/2417 2425/2562/2425 2416/2572/2416 f 2423/2564/2423 2419/2571/2419 2420/2565/2420 f 1406/2568/1406 2424/2567/2424 2418/2566/2418 f 562/2569/562 2420/2565/2420 2419/2571/2419 f 2424/2567/2424 2042/2148/2042 2038/2149/2038 f 2416/2572/2416 2425/2562/2425 2426/2609/2426 f 2416/2572/2416 2426/2609/2426 2421/2573/2421 f 2017/2140/2017 2427/3231/2427 2037/2141/2037 f 2427/3232/2427 2456/2614/2456 2425/3233/2425 f 2431/2611/2431 2427/3232/2427 2017/3234/2017 f 2427/3232/2427 2431/2611/2431 2456/2614/2456 f 2040/2145/2040 2427/3231/2427 2425/2562/2425 f 2427/3231/2427 2040/2145/2040 2037/2141/2037 f 2430/2578/2430 2433/2583/2433 2429/2579/2429 f 2015/3235/2015 2438/3236/2438 2033/3237/2033 f 2443/2600/2443 2451/2595/2451 2442/2594/2442 f 2438/3238/2438 2015/2592/2015 2439/2605/2439 f 2014/2135/2014 2034/3149/2034 2016/3150/2016 f 2440/2604/2440 2443/2600/2443 2445/2598/2445 f 2441/3239/2441 2445/2598/2445 2444/2597/2444 f 2445/2598/2445 2441/3239/2441 2440/2604/2440 f 2015/2592/2015 2451/2595/2451 2439/2605/2439 f 2429/2579/2429 2453/2607/2453 2483/3240/2483 f 2452/3241/2452 2453/2607/2453 2448/2603/2448 f 2453/2607/2453 2449/2602/2449 2448/2603/2448 f 2453/2607/2453 2450/2601/2450 2449/2602/2449 f 2453/2607/2453 2454/2606/2454 2450/2601/2450 f 2454/2606/2454 2447/2599/2447 2450/2601/2450 f 2454/2606/2454 2446/2596/2446 2447/2599/2447 f 2437/2585/2437 2455/3242/2455 2436/2586/2436 f 2441/2590/2441 2455/3242/2455 2437/2585/2437 f 2444/2597/2444 2455/3242/2455 2441/3239/2441 f 2446/2596/2446 2455/3242/2455 2444/2597/2444 f 2436/2586/2436 2455/3242/2455 2446/2596/2446 f 1331/2577/1331 2448/2655/2448 2428/2574/2428 f 2429/2579/2429 2483/3240/2483 2432/2580/2432 f 2483/3240/2483 2453/2607/2453 2452/3241/2452 f 2457/3243/2457 2512/2619/2512 2456/3244/2456 f 63/3245/63 2458/2620/2458 2457/3243/2457 f 2514/2621/2514 2464/2624/2464 2463/2623/2463 f 2458/2620/2458 62/3246/62 2468/2629/2468 f 2460/2617/2460 2469/2630/2469 2462/2622/2462 f 63/3245/63 62/3246/62 2458/2620/2458 f 2432/2636/2432 2474/2635/2474 64/3247/64 f 2487/2649/2487 2486/2648/2486 2477/3248/2477 f 2477/3248/2477 2481/2650/2481 2487/2649/2487 f 2482/2644/2482 2485/2645/2485 2484/2646/2484 f 2484/2646/2484 2432/3249/2432 2483/2647/2483 f 2432/3249/2432 2484/2646/2484 2472/3250/2472 f 2485/2645/2485 2472/3250/2472 2484/2646/2484 f 2472/3250/2472 2485/2645/2485 2475/3251/2475 f 2485/2645/2485 2480/2642/2480 2481/2650/2481 f 2475/3251/2475 2485/2645/2485 2481/2650/2481 f 2486/3252/2486 2481/2650/2481 2477/3248/2477 f 2481/2650/2481 2486/3252/2486 2475/3251/2475 f 2490/2652/2490 1435/3253/1435 1434/3254/1434 f 2483/2647/2483 2489/2658/2489 2488/2643/2488 f 2452/2654/2452 2489/2657/2489 2483/3255/2483 f 47/3256/47 2490/2652/2490 1434/3254/1434 f 2490/2652/2490 47/3256/47 61/2651/61 f 64/3247/64 2474/2635/2474 61/2651/61 f 106/2656/106 107/3257/107 1435/3258/1435 f 106/2656/106 1435/3258/1435 2489/2657/2489 f 1435/3253/1435 2490/2652/2490 2489/2658/2489 f 2519/2674/2519 2491/2662/2491 2494/2675/2494 f 2494/2675/2494 2495/3259/2495 2493/2668/2493 f 2495/3260/2495 2459/2664/2459 2493/2698/2493 f 2459/2664/2459 2495/3260/2495 2491/2665/2491 f 2425/2663/2425 2456/3244/2456 2459/2664/2459 f 2493/2668/2493 2496/2667/2496 2494/2675/2494 f 2465/2627/2465 2501/3261/2501 2498/2628/2498 f 2470/2633/2470 2501/3261/2501 2465/2627/2465 f 2498/2680/2498 2501/3261/2501 2499/2679/2499 f 2499/2679/2499 2501/3261/2501 2470/2633/2470 f 2419/2571/2419 1356/2682/1356 562/2569/562 f 2421/2573/2421 2502/2685/2502 2422/2570/2422 f 2502/2685/2502 2421/2573/2421 14/2608/14 f 2507/2686/2507 2508/2694/2508 2506/2690/2506 f 2041/2146/2041 2048/2151/2048 2031/2137/2031 f 2013/2143/2013 2033/3151/2033 2017/2140/2017 f 2033/3237/2033 2438/3236/2438 2017/3262/2017 f 2040/2145/2040 2007/2144/2007 2010/3146/2010 f 2502/2689/2502 2503/3263/2503 2507/2686/2507 f 2512/2619/2512 2457/3243/2457 2458/2620/2458 f 2456/3244/2456 2512/2619/2512 2459/2664/2459 f 2514/2621/2514 2463/2623/2463 2461/2699/2461 f 2464/2624/2464 2514/2621/2514 2462/2622/2462 f 2468/2629/2468 62/3246/62 46/2700/46 f 2515/2671/2515 2518/2673/2518 2468/2629/2468 f 2517/2681/2517 2471/2632/2471 2500/2631/2500 f 2469/2630/2469 2518/2673/2518 2516/2676/2516 f 2518/2673/2518 2469/2630/2469 2468/2629/2468 f 2492/2659/2492 2518/2673/2518 2515/2671/2515 f 2491/2662/2491 2519/2674/2519 2492/2659/2492 f 2519/2674/2519 2518/2673/2518 2492/2659/2492 f 2494/2675/2494 2491/2662/2491 2495/3259/2495 # 5022 faces g ================================================ FILE: graphics/tiny-renderer/lesson8.workbook/Geometry.csx ================================================ struct Vec2f { public float x; public float y; public float this [int i] { get { if (i == 0) return x; if (i == 1) return y; throw new InvalidOperationException (); } set { if (i == 0) x = value; else if (i == 1) y = value; else throw new InvalidOperationException (); } } public Vec2f Normalize () { return this / Norm (); } public float Norm () { return (float)Math.Sqrt (x * x + y * y); } public static Vec2f operator / (Vec2f v, float num) { v.x /= num; v.y /= num; return v; } public static Vec2f operator * (Vec2f v, float num) { v.x *= num; v.y *= num; return v; } public static Vec2f operator - (Vec2f a, Vec2f b) { return new Vec2f { x = a.x - b.x, y = a.y - b.y }; } public static Vec2f operator + (Vec2f a, Vec2f b) { return new Vec2f { x = a.x + b.x, y = a.y + b.y }; } } public struct Vec3f { public float x; public float y; public float z; public float this [int i] { get { switch (i) { case 0: return x; case 1: return y; case 2: return z; default: throw new InvalidOperationException (); } } set { switch (i) { case 0: x = value; break; case 1: y = value; break; case 2: z = value; break; default: throw new InvalidOperationException (); } } } public Vec3f Normalize () { return this / Norm (); } public float Norm () { return (float)Math.Sqrt (x * x + y * y + z * z); } public static Vec3f operator - (Vec3f a, Vec3f b) { return new Vec3f { x = a.x - b.x, y = a.y - b.y, z = a.z - b.z }; } public static Vec3f operator / (Vec3f v, float num) { v.x /= num; v.y /= num; v.z /= num; return v; } public static Vec3f operator * (Vec3f v, float num) { v.x *= num; v.y *= num; v.z *= num; return v; } } struct Vec4f { public float x; public float y; public float z; public float h; public float this [int i] { get { switch (i) { case 0: return x; case 1: return y; case 2: return z; case 3: return h; default: throw new InvalidOperationException (); } } set { switch (i) { case 0: x = value; break; case 1: y = value; break; case 2: z = value; break; case 3: h = value; break; default: throw new InvalidOperationException (); } } } public Vec4f Normalize () { var len = Norm (); return this / len; } public float Norm () { return (float)Math.Sqrt (x * x + y * y + z * z + h * h); } public static Vec4f operator - (Vec4f a, Vec4f b) { return new Vec4f { x = a.x - b.x, y = a.y - b.y, z = a.z - b.z, h = a.h - b.h }; } public static Vec4f operator / (Vec4f v, float num) { v.x /= num; v.y /= num; v.z /= num; v.h /= num; return v; } } struct Vec2i { public int x; public int y; public static Vec2i operator - (Vec2i a, Vec2i b) { return new Vec2i { x = a.x - b.x, y = a.y - b.y }; } } struct Vec3i { public int x; public int y; public int z; public static Vec3i operator - (Vec3i a, Vec3i b) { return new Vec3i { x = a.x - b.x, y = a.y - b.y, z = a.z - b.z }; } } static class Geometry { public static Vec3f Cross (Vec3f l, Vec3f r) { return new Vec3f { x = l.y * r.z - l.z * r.y, y = l.z * r.x - l.x * r.z, z = l.x * r.y - l.y * r.x }; } public static float Dot (Vec3f l, Vec3f r) { return l.x * r.x + l.y * r.y + l.z * r.z; } public static Vec4f Embed4D (Vec3f v, float fill = 1) { return new Vec4f { x = v.x, y = v.y, z = v.z, h = fill }; } public static Vec2f Project2D (Vec3f v) { return new Vec2f { x = v.x, y = v.y }; } public static Vec2f Project2D (Vec4f v) { return new Vec2f { x = v.x, y = v.y }; } public static Vec3f Project3D (Vec4f v) { return new Vec3f { x = v.x, y = v.y, z = v.z }; } } ================================================ FILE: graphics/tiny-renderer/lesson8.workbook/Image.csx ================================================ using System.IO; enum Format { GRAYSCALE = 1, BGR = 3, BGRA = 4 } struct Color { // the value stored as little endian: // ARGB -> BGRA // xRGB -> BGRx public readonly int value; public readonly Format format; public byte this [int offset] { get { if (offset > 3) // int has only 4 bytes (0, 1, 2, 3) throw new ArgumentOutOfRangeException (); return (byte)(value >> 8 * (3 - offset)); } } public static Color Red = new Color (red: 255, green: 0, blue: 0, alpha: 255); public static Color Green = new Color (red: 0, green: 255, blue: 0, alpha: 255); public static Color Blue = new Color (red: 0, green: 0, blue: 255, alpha: 255); public static Color Black = new Color (red: 0, green: 0, blue: 0, alpha: 255); public static Color White = new Color (red: 255, green: 255, blue: 255, alpha: 255); public static Color Yellow = new Color (red: 225, green: 225, blue: 0, alpha: 255); public Color (byte red, byte green, byte blue, byte alpha) : this ((blue << 24) | (green << 16) | (red << 8) | alpha, Format.BGRA) { } public Color (byte red, byte green, byte blue) : this ((blue << 24) | (green << 16) | (red << 8) | 0xFF, Format.BGR) { } public Color (byte value) : this (value, Format.GRAYSCALE) { } public Color (int value, Format format) { this.value = value; this.format = format; } public static Color operator * (Color color, float intensivity) { intensivity = Math.Max (0f, Math.Min (1f, intensivity)); var ch0 = (byte)(color [0] * intensivity); var ch1 = (byte)(color [1] * intensivity); var ch2 = (byte)(color [2] * intensivity); var ch3 = color [3]; return new Color (ch0 << 24 | ch1 << 16 | ch2 << 8 | ch3, color.format); } } class Image { internal byte [] buffer; public int Width { get; } public int Height { get; } public Format Format { get; } public int BytesPerRow { get { return Width * (int)Format; } } public Image (int width, int height, Format format) { Width = width; Height = height; Format = format; buffer = new byte [height * BytesPerRow]; } public void VerticalFlip () { var bpp = (int)Format; int bytesPerLine = Width * bpp; var half = Height >> 1; for (int l = 0; l < half; l++) { var l1 = l * bytesPerLine; var l2 = (Height - 1 - l) * bytesPerLine; for (int i = 0; i < bytesPerLine; i++) { byte pixel = buffer [l1 + i]; buffer [l1 + i] = buffer [l2 + i]; buffer [l2 + i] = pixel; } } } public void Clear () { for (int i = 0; i < buffer.Length; i++) buffer [i] = 0; } public Color this [int x, int y] { get { if (x < 0 || x >= Width) throw new ArgumentException ("x"); if (y < 0 || y >= Height) throw new ArgumentException ("y"); var offset = GetOffset (x, y); var len = (int)Format; int value = 0; for (var ch = 0; ch < 4; ch++) value = (value << 8) | (ch < len ? buffer [offset++] : 0xFF); return new Color (value, Format); } set { if (x < 0 || x >= Width) return; //throw new ArgumentException ($"{nameof(x)}={x} {nameof(Width)}={Width}"); if (y < 0 || y >= Height) return; // throw new ArgumentException ($"{nameof(y)}={y} {nameof(Height)}={Height}"); var offset = GetOffset (x, y); var v = value.value; var len = (int)Format; for (int ch = 0; ch < len; ch++) // 0123 buffer [offset++] = (byte)(v >> (3 - ch) * 8); // BGRA } } int GetOffset (int x, int y) { return y * BytesPerRow + x * (int)Format; } public bool WriteToFile (string path, bool rle = true) { var bpp = (int)Format; using (var writer = new BinaryWriter (File.Create (path))) { var header = new TGAHeader { IdLength = 0, // The IDLength set to 0 indicates that there is no image identification field in the TGA file ColorMapType = 0, // a value of 0 indicates that no palette is included BitsPerPixel = (byte)(bpp * 8), Width = (short)Width, Height = (short)Height, DataTypeCode = DataTypeFor (bpp, rle), ImageDescriptor = (byte)(0x20 | (Format == Format.BGRA ? 8 : 0)) // top-left origin }; WriteTo (writer, header); if (!rle) writer.Write (buffer); else UnloadRleData (writer); } return true; } public static Image Load (string path) { using (var reader = new BinaryReader (File.OpenRead (path))) { var header = ReadHeader (reader); var height = header.Height; var width = header.Width; var bytespp = header.BitsPerPixel >> 3; var format = (Format)bytespp; if (width <= 0 || height <= 0) throw new InvalidProgramException ($"bad image size: width={width} height={height}"); if (format != Format.BGR && format != Format.BGRA && format != Format.GRAYSCALE) throw new InvalidProgramException ($"unknown format {format}"); var img = new Image (width, height, format); switch (header.DataTypeCode) { case DataType.UncompressedTrueColorImage: case DataType.UncompressedBlackAndWhiteImage: reader.Read (img.buffer, 0, img.buffer.Length); break; case DataType.RleTrueColorImage: case DataType.RleBlackAndWhiteImage: img.LoadRleData (reader); break; default: throw new InvalidProgramException ($"unsupported image format {header.DataTypeCode}"); } if ((header.ImageDescriptor & 0x20) == 0) img.VerticalFlip (); return img; } } static void WriteTo (BinaryWriter writer, TGAHeader header) { writer.Write (header.IdLength); writer.Write (header.ColorMapType); writer.Write ((byte)header.DataTypeCode); writer.Write (header.ColorMapOrigin); writer.Write (header.ColorMapLength); writer.Write (header.ColorMapDepth); writer.Write (header.OriginX); writer.Write (header.OriginY); writer.Write (header.Width); writer.Write (header.Height); writer.Write (header.BitsPerPixel); writer.Write (header.ImageDescriptor); } static TGAHeader ReadHeader (BinaryReader reader) { var header = new TGAHeader { IdLength = reader.ReadByte (), ColorMapType = reader.ReadByte (), DataTypeCode = (DataType)reader.ReadByte (), ColorMapOrigin = reader.ReadInt16 (), ColorMapLength = reader.ReadInt16 (), ColorMapDepth = reader.ReadByte (), OriginX = reader.ReadInt16 (), OriginY = reader.ReadInt16 (), Width = reader.ReadInt16 (), Height = reader.ReadInt16 (), BitsPerPixel = reader.ReadByte (), ImageDescriptor = reader.ReadByte () }; return header; } bool UnloadRleData (BinaryWriter writer) { const int max_chunk_length = 128; int npixels = Width * Height; int curpix = 0; var bpp = (int)Format; while (curpix < npixels) { int chunkstart = curpix * bpp; int curbyte = curpix * bpp; int run_length = 1; bool literal = true; while (curpix + run_length < npixels && run_length < max_chunk_length && curpix + run_length < curpix + Width) { bool succ_eq = true; for (int t = 0; succ_eq && t < bpp; t++) succ_eq = (buffer [curbyte + t] == buffer [curbyte + t + bpp]); curbyte += bpp; if (1 == run_length) literal = !succ_eq; if (literal && succ_eq) { run_length--; break; } if (!literal && !succ_eq) break; run_length++; } curpix += run_length; writer.Write ((byte)(literal ? run_length - 1 : 128 + (run_length - 1))); writer.Write (buffer, chunkstart, literal ? run_length * bpp : bpp); } return true; } void LoadRleData (BinaryReader reader) { var pixelcount = Width * Height; var currentpixel = 0; var currentbyte = 0; var bytespp = (int)Format; var color = new byte [4]; do { var chunkheader = reader.ReadByte (); if (chunkheader < 128) { chunkheader++; for (int i = 0; i < chunkheader; i++) { for (int t = 0; t < bytespp; t++) buffer [currentbyte++] = reader.ReadByte (); currentpixel++; if (currentpixel > pixelcount) throw new InvalidProgramException ("Too many pixels read"); } } else { chunkheader -= 127; reader.Read (color, 0, bytespp); for (int i = 0; i < chunkheader; i++) { for (int t = 0; t < bytespp; t++) buffer [currentbyte++] = color [t]; currentpixel++; if (currentpixel > pixelcount) throw new InvalidProgramException ("Too many pixels read"); } } } while (currentpixel < pixelcount); } static DataType DataTypeFor (int bpp, bool rle) { var format = (Format)bpp; if (format == Format.GRAYSCALE) return rle ? DataType.RleBlackAndWhiteImage : DataType.UncompressedBlackAndWhiteImage; return rle ? DataType.RleTrueColorImage : DataType.UncompressedTrueColorImage; } } struct TGAHeader { public byte IdLength; public byte ColorMapType; public DataType DataTypeCode; // field #4. Color map specification public short ColorMapOrigin; // index of first color map entry that is included in the file public short ColorMapLength; // number of entries of the color map that are included in the file public byte ColorMapDepth; // number of bits per pixel // field #5. Image specification public short OriginX; // absolute coordinate of lower-left corner for displays where origin is at the lower left public short OriginY; // as for X-origin public short Width; // width in pixels public short Height; // height in pixels public byte BitsPerPixel; // pixel depth public byte ImageDescriptor; // bits 3-0 give the alpha channel depth, bits 5-4 give direction } public enum DataType : byte { NoImageData = 0, // no image data is present UncompressedColorMappedImage = 1, UncompressedTrueColorImage = 2, UncompressedBlackAndWhiteImage = 3, RleColorMappedImage = 9, // run-length encoded color-mapped image RleTrueColorImage = 10, // run-length encoded true-color image RleBlackAndWhiteImage = 11 // run-length encoded black-and-white (grayscale) image } ================================================ FILE: graphics/tiny-renderer/lesson8.workbook/ImageResultHandler.csx ================================================ using XIR = Xamarin.Interactive.Representations; InteractiveAgent.RepresentationManager.AddProvider (img => { XIR.ImageFormat format; switch (img.Format) { case Format.BGRA: format = XIR.ImageFormat.Bgra32; break; case Format.BGR: format = XIR.ImageFormat.Bgr24; break; default: return null; } return new XIR.Image (format, img.buffer, img.Width, img.Height); }); ================================================ FILE: graphics/tiny-renderer/lesson8.workbook/LICENSE.txt ================================================ Tiny Renderer, https://github.com/ssloy/tinyrenderer Copyright Dmitry V. Sokolov This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. ================================================ FILE: graphics/tiny-renderer/lesson8.workbook/Matrix.csx ================================================ using System; public struct Matrix4 { public const int Len = 4; public float R0C0, R0C1, R0C2, R0C3; public float R1C0, R1C1, R1C2, R1C3; public float R2C0, R2C1, R2C2, R2C3; public float R3C0, R3C1, R3C2, R3C3; public float this [int row, int column] { get { switch (row) { case 0: switch (column) { case 0: return R0C0; case 1: return R0C1; case 2: return R0C2; case 3: return R0C3; } break; case 1: switch (column) { case 0: return R1C0; case 1: return R1C1; case 2: return R1C2; case 3: return R1C3; } break; case 2: switch (column) { case 0: return R2C0; case 1: return R2C1; case 2: return R2C2; case 3: return R2C3; } break; case 3: switch (column) { case 0: return R3C0; case 1: return R3C1; case 2: return R3C2; case 3: return R3C3; } break; } throw new IndexOutOfRangeException (); } set { switch (row) { case 0: switch (column) { case 0: R0C0 = value; return; case 1: R0C1 = value; return; case 2: R0C2 = value; return; case 3: R0C3 = value; return; } break; case 1: switch (column) { case 0: R1C0 = value; return; case 1: R1C1 = value; return; case 2: R1C2 = value; return; case 3: R1C3 = value; return; } break; case 2: switch (column) { case 0: R2C0 = value; return; case 1: R2C1 = value; return; case 2: R2C2 = value; return; case 3: R2C3 = value; return; } break; case 3: switch (column) { case 0: R3C0 = value; return; case 1: R3C1 = value; return; case 2: R3C2 = value; return; case 3: R3C3 = value; return; } break; } throw new IndexOutOfRangeException (); } } public Matrix4 Transpose () { return new Matrix4 { R0C0 = R0C0, R0C1 = R1C0, R0C2 = R2C0, R0C3 = R3C0, R1C0 = R0C1, R1C1 = R1C1, R1C2 = R2C1, R1C3 = R3C1, R2C0 = R0C2, R2C1 = R1C2, R2C2 = R2C2, R2C3 = R3C2, R3C0 = R0C3, R3C1 = R1C3, R3C2 = R2C3, R3C3 = R3C3 }; } public static Matrix4 Identity () { return new Matrix4 { R0C0 = 1, R1C1 = 1, R2C2 = 1, R3C3 = 1 }; } public static Matrix4 Zoom (float scale) { return new Matrix4 { R0C0 = scale, R1C1 = scale, R2C2 = scale, R3C3 = scale }; } public static Matrix4 RotationZ (float angle) { var cosangle = (float)Math.Cos (angle); var sinangle = (float)Math.Sin (angle); var R = Identity (); R [0, 0] = R [1, 1] = cosangle; R [0, 1] = -sinangle; R [1, 0] = sinangle; return R; } public static Matrix4 operator * (Matrix4 l, Matrix4 r) { var result = new Matrix4 (); for (int i = 0; i < Len; i++) { for (int j = 0; j < Len; j++) { result [i, j] = 0; for (int k = 0; k < Len; k++) { result [i, j] += l [i, k] * r [k, j]; } } } return result; } public override string ToString () { var sb = new System.Text.StringBuilder (); for (int r = 0; r < Len; r++) { for (int c = 0; c < Len; c++) sb.Append (this[r, c]).Append (" "); sb.AppendLine (); } return sb.ToString (); } } public struct Matrix3 { public const int Len = 3; public float R0C0, R0C1, R0C2; public float R1C0, R1C1, R1C2; public float R2C0, R2C1, R2C2; public float this [int row, int column] { get { switch (row) { case 0: switch (column) { case 0: return R0C0; case 1: return R0C1; case 2: return R0C2; } break; case 1: switch (column) { case 0: return R1C0; case 1: return R1C1; case 2: return R1C2; } break; case 2: switch (column) { case 0: return R2C0; case 1: return R2C1; case 2: return R2C2; } break; } throw new IndexOutOfRangeException (); } set { switch (row) { case 0: switch (column) { case 0: R0C0 = value; return; case 1: R0C1 = value; return; case 2: R0C2 = value; return; } break; case 1: switch (column) { case 0: R1C0 = value; return; case 1: R1C1 = value; return; case 2: R1C2 = value; return; } break; case 2: switch (column) { case 0: R2C0 = value; return; case 1: R2C1 = value; return; case 2: R2C2 = value; return; } break; } throw new IndexOutOfRangeException (); } } public Matrix3 Transpose () { return new Matrix3 { R0C0 = R0C0, R0C1 = R1C0, R0C2 = R2C0, R1C0 = R0C1, R1C1 = R1C1, R1C2 = R2C1, R2C0 = R0C2, R2C1 = R1C2, R2C2 = R2C2 }; } public void SetColumn (int col, Vec3f v) { this [0, col] = v.x; this [1, col] = v.y; this [2, col] = v.z; } public void SetRow (int row, Vec3f v) { this [row, 0] = v.x; this [row, 1] = v.y; this [row, 2] = v.z; } public override string ToString () { var sb = new System.Text.StringBuilder (); for (int r = 0; r < Len; r++) { for (int c = 0; c < Len; c++) sb.Append (this [r, c]).Append (" "); sb.AppendLine (); } return sb.ToString (); } } public struct Matrix2 { public const int Len = 2; public float R0C0, R0C1; public float R1C0, R1C1; public float this [int row, int column] { get { switch (row) { case 0: switch (column) { case 0: return R0C0; case 1: return R0C1; } break; case 1: switch (column) { case 0: return R1C0; case 1: return R1C1; } break; } throw new IndexOutOfRangeException (); } set { switch (row) { case 0: switch (column) { case 0: R0C0 = value; return; case 1: R0C1 = value; return; } break; case 1: switch (column) { case 0: R1C0 = value; return; case 1: R1C1 = value; return; } break; } throw new IndexOutOfRangeException (); } } } // we don't want to declare them in Matrix because we don't need them in lesson which introduces Matrix class static class MatrixHelpers { // For Matrix4 // how to calc inverse Matrix https://en.wikipedia.org/w/index.php?title=Invertible_matrix§ion=4#In_relation_to_its_adjugate public static Matrix4 TransposeInverse (Matrix4 m) { // returns Transpose(Inverse(m)) // where Inverse(m) = Transpose(cofactor) / det(m) // Transpose(Inverse(m)) = Transpose(Transpose(cofactor) / det(m)) = cofactor / det(m) var cofactor = Cofactor (m); float det = 0; for (int i = 0; i < Matrix4.Len; i++) det += m [0, i] * cofactor [0, i]; for (int r = 0; r < Matrix4.Len; r++) { for (int c = 0; c < Matrix4.Len; c++) cofactor [r, c] /= det; } return cofactor; } public static Matrix4 Inverse (Matrix4 m) { // where Inverse(m) = Transpose(Cofactor(m)) / det(m) var cofactor = Cofactor (m); int len = Matrix4.Len; float det = 0; for (int i = 0; i < len; i++) det += m [0, i] * cofactor [0, i]; cofactor = cofactor.Transpose (); for (int r = 0; r < len; r++) { for (int c = 0; c < len; c++) cofactor [r, c] /= det; } return cofactor; } public static Matrix3 Inverse (Matrix3 m) { // where Inverse(m) = Transpose(Cofactor(m)) / det(m) var cofactor = Cofactor (m); int len = Matrix3.Len; float det = 0; for (int i = 0; i < len; i++) det += m [0, i] * cofactor [0, i]; cofactor = cofactor.Transpose (); for (int r = 0; r < len; r++) { for (int c = 0; c < len; c++) cofactor [r, c] /= det; } return cofactor; } static Matrix4 Cofactor (Matrix4 m) { var r = new Matrix4 (); for (int row = 0; row < Matrix4.Len; row++) { for (int col = 0; col < Matrix4.Len; col++) r [row, col] = Cofactor (m, row, col); } return r; } static Matrix3 Cofactor (Matrix3 m) { var r = new Matrix3 (); for (int row = 0; row < Matrix3.Len; row++) { for (int col = 0; col < Matrix3.Len; col++) r [row, col] = Cofactor (m, row, col); } return r; } static float Cofactor (Matrix4 m, int row, int col) { int sign = ((row + col) % 2 == 0) ? 1 : -1; return Det (Minor (m, row, col)) * sign; } static float Cofactor (Matrix3 m, int row, int col) { int sign = ((row + col) % 2 == 0) ? 1 : -1; return Det (Minor (m, row, col)) * sign; } static Matrix3 Minor (Matrix4 m, int row, int col) { var minor = new Matrix3 (); for (int r = 0; r < Matrix3.Len; r++) { for (int c = 0; c < Matrix3.Len; c++) { int y = (r < row) ? r : r + 1; int x = (c < col) ? c : c + 1; minor [r, c] = m [y, x]; } } return minor; } static Matrix2 Minor (Matrix3 m, int row, int col) { var minor = new Matrix2 (); for (int r = 0; r < Matrix2.Len; r++) { for (int c = 0; c < Matrix2.Len; c++) { int y = (r < row) ? r : r + 1; int x = (c < col) ? c : c + 1; minor [r, c] = m [y, x]; } } return minor; } static float Det (Matrix3 m) { float det = 0; det += m [0, 0] * (m [1, 1] * m [2, 2] - m [1, 2] * m [2, 1]); det -= m [0, 1] * (m [1, 0] * m [2, 2] - m [1, 2] * m [2, 0]); det += m [0, 2] * (m [1, 0] * m [2, 1] - m [1, 1] * m [2, 0]); return det; } static float Det (Matrix2 m) { return m [0, 0] * m [1, 1] - m [0, 1] * m [1, 0]; } public static Vec3f Mult (Matrix3 m, Vec3f v) { return new Vec3f { x = m.R0C0 * v.x + m.R0C1 * v.y + m.R0C2 * v.z, y = m.R1C0 * v.x + m.R1C1 * v.y + m.R1C2 * v.z, z = m.R2C0 * v.x + m.R2C1 * v.y + m.R2C2 * v.z }; } public static Vec4f Mult (Matrix4 m, Vec4f v) { return new Vec4f { x = m.R0C0*v.x + m.R0C1*v.y + m.R0C2*v.z + m.R0C3*v.h, y = m.R1C0*v.x + m.R1C1*v.y + m.R1C2*v.z + m.R1C3*v.h, z = m.R2C0*v.x + m.R2C1*v.y + m.R2C2*v.z + m.R2C3*v.h, h = m.R3C0*v.x + m.R3C1*v.y + m.R3C2*v.z + m.R3C3*v.h }; } } ================================================ FILE: graphics/tiny-renderer/lesson8.workbook/Model.csx ================================================ using System.Collections.Generic; using System.Linq; struct Face { public int [] Vertices; public int [] Textures; public int [] Normals; } class Model { public List Vertices { get; } = new List (); public List Faces { get; } = new List (); public List Textures { get; } = new List (); public List Normals { get; } = new List (); public static Model FromFile (string path) { var model = new Model (); string line; using (var reader = new System.IO.StreamReader (path)) { while ((line = reader.ReadLine ()) != null) model.ParseLine (line); } Console.WriteLine ($"v#{model.Vertices.Count} f#{model.Faces.Count}"); return model; } public static Model FromText (string text) { var model = new Model (); var lines = text.Split (new char [] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); foreach (var line in lines) model.ParseLine (line); Console.WriteLine ($"v#{model.Vertices.Count} f#{model.Faces.Count}"); return model; } void ParseLine (string line) { Func parseV3f = strItems => new Vec3f { x = float.Parse (strItems [1]), y = float.Parse (strItems [2]), z = float.Parse (strItems [3]) }; var items = line.Split (new char [] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (line.StartsWith ("v ", StringComparison.InvariantCulture)) { Vertices.Add (parseV3f (items)); } else if (line.StartsWith ("vt ", StringComparison.InvariantCulture)) { Textures.Add (parseV3f (items)); } else if (line.StartsWith ("vn ", StringComparison.InvariantCulture)) { Normals.Add (parseV3f (items)); } else if (line.StartsWith ("f ", StringComparison.InvariantCulture)) { var indexes = items.Skip (1) .SelectMany (s => s.Split (new char [] { '/', ' ' }, StringSplitOptions.RemoveEmptyEntries)) .Select (s => int.Parse (s) - 1) // in wavefront obj all indices start at 1, not zero .ToArray (); Faces.Add (new Face { Vertices = indexes.Where ((v, index) => index % 3 == 0).ToArray (), Textures = indexes.Where ((v, index) => index % 3 == 1).ToArray (), Normals = indexes.Where ((v, index) => index % 3 == 2).ToArray () }); } } public Vec3f Normal (Face face, int nthvert) { int idx = face.Normals [nthvert]; return Normals [idx]; } public Vec3f Vertex (Face face, int nthvert) { int idx = face.Vertices [nthvert]; return Vertices [idx]; } public Vec3f GetUV (Face face, int nthvert) { int idx = face.Textures [nthvert]; return Textures [idx]; } } ================================================ FILE: graphics/tiny-renderer/lesson8.workbook/WpfImageResultHandler.csx ================================================ using System; using System.IO; using System.Windows.Media; using System.Windows.Media.Imaging; using XIR = Xamarin.Interactive.Representations; static PixelFormat ConvertFormat (Format format) { switch (format) { case Format.BGRA: return PixelFormats.Bgra32; case Format.GRAYSCALE: return PixelFormats.Gray8; case Format.BGR: default: return PixelFormats.Bgr24; } } InteractiveAgent.RepresentationManager.AddProvider (img => { var source = BitmapSource.Create (img.Width, img.Height, 96, 96, ConvertFormat (img.Format), null, img.buffer, img.BytesPerRow); var encoder = new PngBitmapEncoder (); var outputFrame = BitmapFrame.Create (source); encoder.Frames.Add (outputFrame); using (var memory = new MemoryStream ()) { encoder.Save (memory); return XIR.Image.FromPng (memory.GetBuffer (), img.Width, img.Height); } }); ================================================ FILE: graphics/tiny-renderer/lesson8.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Matrix.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" #load "lesson1.csx" #load "lesson2.csx" #load "lesson3.csx" #load "lesson4.csx" #load "lesson5.csx" #load "lesson6.csx" #load "lesson6bis.csx" using static Geometry; using static MatrixHelpers; using static ShaderUtils; ``` # Lesson 8: Ambient occlusion > ℹ️ This workbook is a port of an [excellent C++ series](https://github.com/ssloy/tinyrenderer/wiki) written by Dmitry Sokolov. We appreciate that original work is available under a license that allowed us to turn it into a Workbook. In previous lectures we used local illumination model. In other words, for computing illumination of a current pixel we did not take into account its neighbors. [Phong reflection model](https://en.wikipedia.org/wiki/Phong_reflection_model) is a famous example of such approach: ![ ](./img/lesson6_phong.png) In this model final illumination intensity for a point is a sum of three components: ambient intensity, constant for all points in the scene, diffuse and specular highlights depending on normal vectors. Wait a minute, why did he choose **constant** ambient component? # **Second attempt in the global illumination: ambient occlusion** Well, I was not 100% right: we did use a bit global illumination when we computed shadow mapping. Let us check another possibility to improve our renders (note that one does not exclude another!). Here is an example where I used only ambient component of the Phong reflection model: ![ ](./img/lesson8_goal.png) **No diffuse component, no specular. Ambient only, however it is easy to see that I did not choose it to be constant.** Okay, the problem is stated as follows: let us ambient intensity for each point of our scene. When we previously supposed constant ambient illumination, it means that we supposed our scene so nice that all light was reflected everywhere equally. A bit strong hypothesis that is. Of course, it was made back in the old days where computing power was severely limited. Nowadays, we can spend a bit more to get more realistic images. Global illumination is more expensive than the local is. Recall that for shadow mapping we were forced to do two-passes rendering, thus roughly dividing our FPS by 2. # **Brute force attempt** Let us suppose that our object is surrounded by a hemisphere, emitting light uniformly (cloudy sky). Then let us choose randomly, say, a thousand points at the hemisphere, render the object thousand times and to compute what parts of the model were visible. **Question:** Do you know how to pick **uniformly** a thousand points on a (hemi-)sphere? Something like this: ![ ](./img/lesson8_sphere.png) If we simply pick randomly a longitude and a latitude, we will obtain an accumulation of points near the poles, thus breaking our assumption on uniform lighting of the sky. [Check the answer](http://mathworld.wolfram.com/SpherePointPicking.html). **Question:** where do we store the visibility information? ```csharp Vec3f RandPointOnUnitSphere () { var rnd = new Random (); var u = rnd.NextDouble (); var v = rnd.NextDouble (); var theta = 2 * Math.PI * u; var phi = Math.Acos(2 * v - 1); return new Vec3f { x = (float)(Math.Sin (phi) * Math.Cos (theta)), y = (float)(Math.Sin (phi) * Math.Sin (theta)), z = (float)Math.Cos (phi) }; } ``` Since we are in the brute force section, then the answer is obvious: in a texture! Thus, we do a two-pass rendering for each point we picked on the sphere, here is the first shader and the resulting image: ```csharp class ZShader : IShader { const float depth = 255f; readonly Model model; readonly Matrix4 transformation; public ZShader (Model model, Matrix4 viewport, Matrix4 projection, Matrix4 modelView) { this.model = model; transformation = viewport * projection * modelView; } public Vec4f Vertex (Face face, int nthvert) { return TransformFace (model, face, nthvert, transformation); } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { color = Color.White * (fragment.z / depth); return false; } } var zshader = new ZShader (diabloModel, viewPort, projection, modelView); var step1 = Render (diabloModel, zshader).Image; step1.VerticalFlip(); step1 ``` This image is not very interesting for us, we are more interested in its z-buffer, exactly as in the previous lesson. Then we do another pass: ```csharp class OcclusionShader : IShader { Vec3f varyingU = new Vec3f (); Vec3f varyingV = new Vec3f (); readonly Model model; readonly Matrix4 transformation; readonly Image occlusion; readonly float [] shadowbuffer; readonly int width; public OcclusionShader (Model model, Matrix4 viewport, Matrix4 projection, Matrix4 modelView, Image occlusion, float [] shadowbuffer, int width) { this.model = model; this.occlusion = occlusion; this.shadowbuffer = shadowbuffer; this.width = width; transformation = viewport * projection * modelView; } public Vec4f Vertex (Face face, int nthvert) { UpdateVarayingUV (model, face, nthvert, ref varyingU, ref varyingV); return TransformFace (model, face, nthvert, transformation); } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { var uvf = CalcUV (varyingU, varyingV, bar); var uvi = CalcXY (occlusion, uvf); var index = (int)(fragment.x + fragment.y * width); if (Math.Abs(shadowbuffer [index] - (byte)fragment.z) <= 1e-2) occlusion [uvi.x, uvi.y] = Color.White; color = Color.White; return false; } } ``` The resulting image is not interesting either, it will simply draw a white image. However, this line I like: `occlusion [uvi.x, uvi.y] = Color.White;` occlusion - is initially clear image; this line tells us that if the fragment is visible, then we put a white point in this image using fragment's texture coordinates. Here is the resulting occlusion image for one point we choose on the hemisphere: ![](./img/occlusion.png) **Question:** Why are there holes in obviously visible triangles? **Question:** Why are there triangles more densely covered than others? Well, we repeat above procedure a thousand times, compute average of all occl images. ```csharp var rnd = new Random (); var screen_coords = new Vec4f [3]; var frame = new Image (width, height, Format.BGR); var shadowbuffer = InitZBuffer (frame); var zbuffer = InitZBuffer (frame); var total = new Image (1024, 1024, Format.BGR); var occl = new Image (1024, 1024, Format.BGR); const int nrenders = 1; for (int iter = 1; iter <= nrenders; iter++) { for (int i = 0; i < shadowbuffer.Length; i++) { shadowbuffer [i] = 0; zbuffer [i] = 0; } var vUp = new Vec3f { x = (float)rnd.NextDouble (), y = (float)rnd.NextDouble (), z = (float)rnd.NextDouble () }; var spLocation = RandPointOnUnitSphere (); spLocation.y = Math.Abs (spLocation.y); frame.Clear (); var mvM = LookAt (spLocation, center, vUp); var pM = Projection (0); var zshader = new ZShader (diabloModel, viewPort, pM, mvM); foreach (var face in diabloModel.Faces) { for (int i = 0; i < 3; i++) screen_coords [i] = zshader.Vertex (face, i); Triangle (frame, screen_coords, zshader, shadowbuffer); } //frame.VerticalFlip (); //frame.WriteToFile ("framebuffer.tga"); occl.Clear (); var shader = new OcclusionShader (diabloModel, viewPort, pM, mvM, occl, shadowbuffer, frame.Width); foreach (var face in diabloModel.Faces) { for (int i = 0; i < 3; i++) screen_coords [i] = shader.Vertex (face, i); Triangle (frame, screen_coords, shader, zbuffer); } for (int i = 0; i < total.Width; i++) { for (int j = 0; j < total.Height; j++) { float prev = total [i, j] [0]; float curr = occl [i, j] [0]; var val = (byte)((prev * (iter - 1) + curr) / iter + 0.5f); total [i, j] = new Color (val, val, val); } } } // total.VerticalFlip (); // total.WriteToFile ("total-occlusion.tga"); ``` Here is the average visible texture: ![](./img/total-occlusion.png) Cool, looks like something we could want. Let us draw our Diable without any lighting computation, simply by putting above texture: ```csharp var aoTexture = Image.Load ("obj/diablo3-total-occlusion.tga"); aoTexture.VerticalFlip (); class AOShader : IShader { Vec3f varyingU = new Vec3f (); Vec3f varyingV = new Vec3f (); readonly Model model; readonly Matrix4 transformation; readonly Image aoImage; public AOShader (Model model, Matrix4 viewport, Matrix4 projection, Matrix4 modelView, Image aoImage) { this.model = model; this.aoImage = aoImage; transformation = viewport * projection * modelView; } public Vec4f Vertex (Face face, int nthvert) { UpdateVarayingUV (model, face, nthvert, ref varyingU, ref varyingV); return TransformFace (model, face, nthvert, transformation); } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { var uvf = CalcUV (varyingU, varyingV, bar); var uvi = CalcXY (aoImage, uvf); var t = aoImage [uvi.x, uvi.y] [0]; color = new Color (t, t, t); return false; } } var shader = new AOShader (diabloModel, viewPort, projection, modelView, aoTexture); var image = Render (diabloModel, shader).Image; image.VerticalFlip(); image ``` **Question:** Wow, he is in a bad mood... Why? This question is linked to the previous one. Did you notice that in Diablo's texture there is one arm only? The artist (in this case [Samuel Sharit](https://www.linkedin.com/in/samuelsharit)) is practical and did not want to waste precious resources. He simply said that the arms are textured in the same way and both arms can have same texture coordinates. Roughly it means that our lighting computing will count arms twice, thus quadrupling the light energy in the final render. ## **Let us sum up** This method allows to precompute ambient occlusion for scenes with static geometry. Computation time depends on the number of samples you choose, but in practice it does not matter since we compute it once and use as a texture afterwards. Advantage of this method is its flexibility and ability to compute much more complex lighting than a simple uniform hemisphere. Disadvantage - for doubled texture coordinates the computation is not correct, we need to put some scotch tape to repair it (see the teaser image for this lesson). # **Screen space ambient occlusion** Well, we see that global illumination is still an expensive thing, it requires visibility computations for many points. Let us try to find a compromise between computing time and rendering quality. Here is an image I want to compute (recall that in this lesson I do not use other lighting besides the ambient one): ![ ](./img/lesson8_goal2.png) Here is the shader to compute the image: ```csharp class ZShader : IShader { readonly Model model; readonly Matrix4 transformation; public ZShader (Model model, Matrix4 viewport, Matrix4 projection, Matrix4 modelView) { this.model = model; transformation = viewport * projection * modelView; } public Vec4f Vertex (Face face, int nthvert) { return TransformFace (model, face, nthvert, transformation); } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { color = Color.Black; return false; } }; ``` What-what-what?! `color = Color.Black;` ?! Yes, that is right. At the moment I am only interested in the z-buffer, the image will appear after a post-processing step. Here is the complete code with our "empty" shader call and the post-processing routine (takes a few mins to render): ```csharp float MaxElevationAngle (float [] zbuffer, Vec2f p, Vec2f dir, int width, int height) { float maxangle = 0; for (float t = 0; t < 1000; t += 1) { Vec2f cur = p + dir * t; if (cur.x >= width || cur.y >= height || cur.x < 0 || cur.y < 0) return maxangle; var distance = (p - cur).Norm (); if (distance < 1) continue; float elevation = zbuffer [(int)cur.x + (int)cur.y * width] - zbuffer [(int)p.x + (int)p.y * width]; maxangle = (float)Math.Max (maxangle, Math.Atan (elevation / distance)); } return maxangle; } Image RenderAO(Model model) { var shader = new ZShader (model, viewPort, projection, modelView); var result = Render (model, shader); var image = result.Image; var zbuffer = result.ZBuffer; for (int x = 0; x < image.Width; x++) { for (int y = 0; y < image.Height; y++) { if (zbuffer [x + y * image.Width] < -1e5) continue; double total = 0; for (var a = 0.0; a < 2 * Math.PI - 0.001; a += Math.PI / 4) { total += Math.PI / 2 - MaxElevationAngle (zbuffer, new Vec2f { x = x, y = y }, new Vec2f { x = (float)Math.Cos (a), y = (float)Math.Sin (a) }, image.Width, image.Height); } total /= (Math.PI / 2) * 8; var v = (byte)(Math.Min (255, total * 255)); image [x, y] = new Color (v, v, v); } } return image; } var image = RenderAO(diabloModel); image.VerticalFlip (); image ``` The empty shader call gives us the z-buffer. As for the post-processing: for each pixel of our image I emit a number of rays (eight here) in all directions around the pixel. The z-buffer is a height map, you can imagine it as a landscape. What i want to compute is the slope in each of our 8 directions. The function `MaxElevationAngle` gives the maximum slope we encounter for each ray we cast. If all eight rays have zero elevation, then the current pixel is well visible, the terrain around is flat. If the angle is near 90°, then current pixel is well-hidden in a kind of a valley, and receives little ambient light. In theory we need to compute the [solid angle](https://en.wikipedia.org/wiki/Solid_angle) for each point of the z-buffer, but we approximate it as a sum of (90°-max_elevation_angle) / 8. Here is an ambient-occlusion-only render of our friend: ```csharp var image = RenderAO(headModel); image.VerticalFlip (); image ``` Enjoy! ================================================ FILE: graphics/tiny-renderer/lesson8.workbook/lesson1.csx ================================================ int width = 800; int height = 800; var headModel = Model.FromFile ("obj/african_head.obj"); static void Swap(ref T x, ref T y) { T t = y; y = x; x = t; } static void Swap(T[] arr, int x, int y) { T t = arr[y]; arr[y] = arr[x]; arr[x] = t; } Image Line (Image image, int x0, int y0, int x1, int y1, Color color) { bool steep = false; // if the line is steep, we transpose the image if (Math.Abs (x0-x1) < Math.Abs (y0-y1)) { Swap (ref x0, ref y0); Swap (ref x1, ref y1); steep = true; } if (x0 > x1) { // make it left to right Swap (ref x0, ref x1); Swap (ref y0, ref y1); } // (x0, y0) == (x1, y1) if(x0 == x1) { image [x0, y0] = color; } else { for (int x = x0; x <= x1; x++) { double t = (x-x0) / (double)(x1-x0); int y = (int)Math.Round(y0*(1-t) + y1*t); if (steep) image [y, x] = color; else image [x, y] = color; } } return image; } ================================================ FILE: graphics/tiny-renderer/lesson8.workbook/lesson1.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" ``` # **Lesson 1: Bresenham’s Line Drawing Algorithm** # First attempt The goal of the first lesson is to render the wire mesh. To do this, we should learn how to draw line segments. We can simply read what Bresenham’s line algorithm is, but let’s write code ourselves. How does the simplest code that draws a line segment between `(x0, y0)` and `(x1, y1)` points look like? Apparently, something like this: ```csharp Image Line (Image image, int x0, int y0, int x1, int y1, Color color) { for (double t = 0; t < 1; t += 0.01) { int x = (int) (x0 * (1-t) + x1 * t); int y = (int) (y0 * (1-t) + y1 * t); image [x, y] = color; } return image; } Line (new Image (100, 100, Format.BGR), x0: 13, y0: 20, x1: 80, y1: 40, color: Color.White); ``` # Second attempt The problem with this code (in addition to efficiency) is the choice of the constant, which I took equal to .01. If we take it equal to .1, our line segment will look like this: ```csharp Image Line (Image image, int x0, int y0, int x1, int y1, Color color) { for (int x = x0; x <= x1; x++) { double t = (x-x0)/(double)(x1-x0); int y = (int)(y0*(1-t) + y1*t); image [x, y] = color; } return image; } Line (new Image (100, 100, Format.BGR), x0: 13, y0: 20, x1: 80, y1: 40, color: Color.White); ``` Caution! The first source of errors in such code of my students is the integer division, like: `(x-x0)/(x1-x0)`. Then, if we try to draw the following lines with this code: ```csharp var image = new Image (100, 100, Format.BGR); Line(image, x0: 13, y0: 20, x1: 80, y1: 40, color: Color.White); Line(image, x0: 20, y0: 13, x1: 40, y1: 80, color: Color.Red); Line(image, x0: 80, y0: 40, x1: 13, y1: 20, color: Color.Red); ``` It turns out that one line is good, the second one is with holes, and there’s no third line at all. Note that the first and the third lines (in the code) draw the same line in different colors, and in different directions (with the source and target points flipped). We have already seen the white one, it is drawn well. I was hoping to change the color of the white line to red, but could not do it. It’s a test for symmetry: the result of drawing a line segment should not depend on the order of points: the `(a,b)` line segment should be exactly the same as the `(b,a)` line segment. # Third attempt We fix the missing red line by swapping the points so `x0` is always lower than `x1`. There are holes in one of the line segments due to the fact that its height is greater than the width. My students often suggest the following fix: `if (dx > dy) { for (int x) } else { for (int y) }` Holy cow! ```csharp static void Swap(ref T x, ref T y) { T t = y; y = x; x = t; } static void Swap(T[] arr, int x, int y) { T t = arr[y]; arr[y] = arr[x]; arr[x] = t; } Image Line (Image image, int x0, int y0, int x1, int y1, Color color) { bool steep = false; // if the line is steep, we transpose the image if (Math.Abs (x0-x1) < Math.Abs (y0-y1)) { Swap (ref x0, ref y0); Swap (ref x1, ref y1); steep = true; } if (x0 > x1) { // make it left to right Swap (ref x0, ref x1); Swap (ref y0, ref y1); } // (x0, y0) == (x1, y1) if(x0 == x1) { image [x0, y0] = color; } else { for (int x = x0; x <= x1; x++) { double t = (x-x0) / (double)(x1-x0); int y = (int)Math.Round(y0*(1-t) + y1*t); if (steep) image [y, x] = color; else image [x, y] = color; } } return image; } Line(image, x0: 13, y0: 20, x1: 80, y1: 40, color: Color.White); Line(image, x0: 20, y0: 13, x1: 40, y1: 80, color: Color.Red); Line(image, x0: 80, y0: 40, x1: 13, y1: 20, color: Color.Red); ``` # Wireframe rendering So now we are ready to create a wire render. You can find the snapshot of the code and the test model here. I used the [wavefront obj](http://en.wikipedia.org/wiki/Wavefront_.obj_file) format of the file to store model. All we need for the render is read from the file the array of vertices of the following type: `v 0.608654 -0.568839 -0.416318` are `x,y,z` coordinates, one vertex per file line and faces `f 1193/1240/1193 1180/1227/1180 1179/1226/1179` ```csharp int width = 800, height = 800; var headModel = Model.FromFile ("obj/african_head.obj"); var image = new Image(width, height, Format.BGR); foreach(var face in headModel.Faces) { for(int j=0; j<3; j++) { var v0 = headModel.Vertices[face.Vertices [j]]; var v1 = headModel.Vertices[face.Vertices [(j+1) % 3]]; // scale x from [-1..1] to [0..w] // scale y from [-1..1] to [0..h] int x0 = (int)((v0.x + 1) * width / 2); int y0 = (int)((v0.y + 1) * height / 2); int x1 = (int)((v1.x + 1) * width / 2); int y1 = (int)((v1.y + 1) * height / 2); Line(image, x0, y0, x1, y1, Color.White); } } image.VerticalFlip (); image ``` ================================================ FILE: graphics/tiny-renderer/lesson8.workbook/lesson2.csx ================================================ using static Geometry; var light_dir = new Vec3f { x = 0, y = 0, z = -1 }; var world = new Vec3f [3]; var screen = new Vec3f [3]; void Line (Image image, Vec2i p1, Vec2i p2, Color color) { Line(image, p1.x, p1.y, p2.x, p2.y, color); } void Line (Image image, Vec3f p1, Vec3f p2, Color color) { Line(image, (int)p1.x, (int)p1.y, (int)p2.x, (int)p2.y, color); } void Triangle (Image image, Vec2i[] t, Color color) { Line(image, t[0], t[1], color); Line(image, t[1], t[2], color); Line(image, t[2], t[0], color); } Vec3f Barycentric (Vec3f a, Vec3f b, Vec3f c, Vec2i p) { var pixel = new Vec3f { x = p.x + 0.5f, y = p.y + 0.5f }; var ab = b - a; var ac = c - a; var pa = a - pixel; var r = Cross (new Vec3f { x = ab.x, y = ac.x, z = pa.x }, new Vec3f { x = ab.y, y = ac.y, z = pa.y }); // triangle is degenerate, in this case return smth with negative coordinates if (Math.Abs (r.z) < 1) return new Vec3f { x = -1, y = 1, z = 1 }; return new Vec3f { x = 1 - r.x / r.z - r.y / r.z, y = r.x / r.z, z = r.y / r.z }; } void Triangle (Image image, Vec3f [] coordinates, Color color) { var t0 = coordinates [0]; var t1 = coordinates [1]; var t2 = coordinates [2]; var pMax = new Vec2i { x = (int)Math.Max (0, Math.Max (t0.x, Math.Max (t1.x, t2.x))), y = (int)Math.Max (0, Math.Max (t0.y, Math.Max (t1.y, t2.y))) }; var pMin = new Vec2i { x = (int)Math.Min (image.Width, Math.Min (t0.x, Math.Min (t1.x, t2.x))), y = (int)Math.Min (image.Height, Math.Min (t0.y, Math.Min (t1.y, t2.y))) }; Vec2i p; for (p.x = pMin.x; p.x <= pMax.x; p.x++) { for (p.y = pMin.y; p.y <= pMax.y; p.y++) { var bc = Barycentric (t0, t1, t2, p); if (bc.x < 0 || bc.y < 0 || bc.z < 0) continue; image [p.x, p.y] = color; } } } ================================================ FILE: graphics/tiny-renderer/lesson8.workbook/lesson2.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" #load "lesson1.csx" using static Geometry; ``` # Lesson 2: Triangle rasterization and back face culling # Old-school method: Line sweeping Thus, the task is to draw two-dimensional triangles. For motivated students it normally takes a couple of hours, even if they are bad programmers. Last time we saw Bresenham’s line drawing algorithm. Today’s task is to draw a filled triangle. Funny enough, but this task is not trivial. I don’t know why, but I know that it’s true. Most of my students struggle with this simple task. So, the initial stub will look like this: ```csharp void Line (Image image, Vec2i p1, Vec2i p2, Color color) { Line(image, p1.x, p1.y, p2.x, p2.y, color); } void Line (Image image, Vec3f p1, Vec3f p2, Color color) { Line(image, (int)p1.x, (int)p1.y, (int)p2.x, (int)p2.y, color); } void Triangle (Image image, Vec2i[] t, Color color) { Line(image, t[0], t[1], color); Line(image, t[1], t[2], color); Line(image, t[2], t[0], color); } Vec2i[] t0 = { new Vec2i { x = 10, y = 70 }, new Vec2i { x = 50, y = 160 }, new Vec2i { x = 70, y = 80 } }; Vec2i[] t1 = { new Vec2i { x = 180, y = 50 }, new Vec2i { x = 150, y = 1 }, new Vec2i { x = 70, y = 180 } }; Vec2i[] t2 = { new Vec2i { x = 180, y = 150 }, new Vec2i { x = 120, y = 160 }, new Vec2i { x = 130, y = 180 } }; var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); image.VerticalFlip (); image ``` The code is simple: I provide three triangles for the initial debugging of your code. If we invoke `Line` inside the triangle function, we’ll get the contour of the triangle. How to draw a filled triangle? A good method of drawing a triangle must have the following features: * It should be (surprise!) simple and fast. * It should be symmetrical: the picture should not depend on the order of vertices passed to the drawing function. * If two triangles have two common vertices, there should be no holes between them because of rasterization rounding. We could add more requirements, but let’s do with these ones. Traditionally a line sweeping is used: 1. Sort vertices of the triangle by their y-coordinates 2. Rasterize simultaneously the left and the right sides of the triangle 3. Draw a horizontal line segment between the left and the right boundary points At this point my students start to lose the firm ground: which segment is the left one, which one is right? Besides, there are three segments in a triangle... Usually, after this introduction I leave my students for about an hour: once again, reading my code is much less valuable than comparing your own code with mine. `[One hour passes]` How do I draw a triangle? Once again, if you have a better method, I’d be glad to adopt it. Let us assume that we have three points of the triangle: `t0`, `t1`, `t2`, they are sorted in ascending order by the y-coordinate. Then, the boundary A is between `t0` and `t2`, boundary B is between `t0` and `t1`, and then between `t1` and `t2`. ```csharp void OrderByY (Vec2i[] t) { if(t[0].y > t[1].y) Swap(t, 0, 1); if(t[1].y > t[2].y) Swap(t, 1, 2); if(t[0].y > t[1].y) Swap(t, 0, 1); } void Triangle (Image image, Vec2i[] t, Color color) { OrderByY(t); Line(image, t[0], t[1], Color.Green); Line(image, t[1], t[2], Color.Green); Line(image, t[2], t[0], Color.Red); } var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); // Here boundary A is red, and boundary B is green. image.VerticalFlip (); image ``` Unfortunately, boundary B is made of two parts. Let us draw the bottom half of the triangle by cutting it horizontally: ```csharp void Triangle (Image image, Vec2i[] t, Color color) { OrderByY(t); float height_10 = t[1].y - t[0].y; float height_20 = t[2].y - t[0].y; for(int y=t[0].y; y<=t[1].y; y++) { var alpha = (y-t[0].y) / height_20; var beta = (y-t[0].y) / height_10; // be careful with divisions by zero Vec2i A = new Vec2i { x = t[0].x + (int)((t[2].x-t[0].x)*alpha), y = y}; Vec2i B = new Vec2i { x = t[0].x + (int)((t[1].x-t[0].x)*beta), y = y}; image[A.x, y] = Color.Red; image[B.x, y] = Color.Green; } } var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); image.VerticalFlip (); image ``` Note that the segments are not continuous. Last time when we drew straight lines we struggled to get continuous segments and here I did not bother with rotating the image (remember the xy swapping?). Why? We fill the triangles aftewards, that’s why. If we connect the corresponding pairs of points by horizontal lines, the gaps disappear: ```csharp void Triangle (Image image, Vec2i[] t, Color color) { OrderByY(t); float height_10 = t[1].y - t[0].y; float height_20 = t[2].y - t[0].y; for(int y=t[0].y; y<=t[1].y; y++) { var alpha = (y-t[0].y) / height_20; var beta = (y-t[0].y) / height_10; // be careful with divisions by zero Vec2i A = new Vec2i { x = t[0].x + (int)((t[2].x-t[0].x)*alpha), y = y}; Vec2i B = new Vec2i { x = t[0].x + (int)((t[1].x-t[0].x)*beta), y = y}; Line(image, A, B, Color.White); image[B.x, y] = Color.Green; image[A.x, y] = Color.Red; } } var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); image.VerticalFlip (); image ``` Now, let us draw the second (upper) half of the triangle. We can do this by adding a second loop: ```csharp void Triangle (Image image, Vec2i[] t, Color color) { OrderByY(t); float height_10 = t[1].y - t[0].y; float height_20 = t[2].y - t[0].y; for(int y=t[0].y; y<=t[1].y; y++) { var alpha = (y-t[0].y) / height_20; var beta = (y-t[0].y) / height_10; // be careful with divisions by zero Vec2i A = new Vec2i { x = t[0].x + (int)((t[2].x-t[0].x)*alpha), y = y}; Vec2i B = new Vec2i { x = t[0].x + (int)((t[1].x-t[0].x)*beta), y = y}; if(A.x > B.x) Swap(ref A, ref B); for (int j=A.x; j<=B.x; j++) image[j, y] = color; } float height_21 = t[2].y - t[1].y; for(int y=t[1].y; y<=t[2].y; y++) { var alpha = (y-t[0].y) / height_20; var beta = (y-t[1].y) / height_21; // be careful with divisions by zero Vec2i A = new Vec2i { x = t[0].x + (int)((t[2].x-t[0].x)*alpha), y = y}; Vec2i B = new Vec2i { x = t[1].x + (int)((t[2].x-t[1].x)*beta), y = y}; if(A.x > B.x) Swap(ref A, ref B); for (int j=A.x; j<=B.x; j++) image[j, y] = color; } } var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); image.VerticalFlip (); image ``` This could be enough, but I dislike to see the same code twice. That is why we will make it a bit less readable, but more handy for modifications/maintaining: ```csharp void Triangle (Image image, Vec2i[] t, Color color) { // I dont care about degenerate triangles if(t[0].y == t[1].y && t[1].y == t[2].y) return; OrderByY(t); float height_10 = t[1].y - t[0].y; float total_height = t[2].y - t[0].y; for(int i=0; i t[1].y - t[0].y || t[1].y == t[0].y; float segment_height = second_half ? t[2].y-t[1].y : t[1].y-t[0].y; var alpha = i / total_height; // be careful with divisions by zero var beta = (i - (second_half ? t[1].y-t[0].y : 0)) / segment_height; Vec2i A = new Vec2i { x = t[0].x + (int)((t[2].x-t[0].x)*alpha), y = t[0].y + i }; Vec2i B = new Vec2i { x = second_half ? t[1].x + (int)((t[2].x-t[1].x)*beta) : t[0].x + (int)((t[1].x-t[0].x)*beta), y = t[0].y + i }; if(A.x > B.x) Swap(ref A, ref B); for (int j=A.x; j<=B.x; j++) image[j, t[0].y + i] = color; } } var image = new Image (200, 200, Format.BGR); Triangle (image, t0, Color.Red); Triangle (image, t1, Color.White); Triangle (image, t2, Color.Green); image.VerticalFlip (); image ``` # The method I adopt for my code While not being really complicated, the source code for the line sweeping is a bit messy. Moreover, it is really an old-school approach designed for mono-thread CPU programming. Let us take a look at the following pseudo-code: ```csharp // triangle(Vec2i[] points) { // Vec2i bbox[2] = find_bounding_box(points); // for (each pixel in the bounding box) { // if (inside(points, pixel)) { // put_pixel(pixel); // } // } // } ``` Do you like it? I do. It is really easy to find a bounding box. It is certainly no problem to check whether a point belongs a 2D triangle (or any convex polygon). *Off Topic: if I have to implement some code to check whether a point belongs to a polygon, and this program will run on a plane, I will never get on this plane. Turns out, it is a surprisingly difficult task to solve this problem reliably. But here we just painting pixels. I am okay with that.* There is another thing I like about this pseudocode: a neophyte in programming accepts it with enthusiasm, more experienced programmers often chuckle: “*What an idiot wrote it?*”. And an expert in computer graphics programming will shrug his shoulders and say: “*Well, that’s how it works in real life*”. Massively parallel computations in thousands of threads (i’m talking about regular consumer computers here) change the way of thinking. Okay, let us start: first of all we need to know what the [barycentric coordinates](https://en.wikipedia.org/wiki/Barycentric_coordinate_system) are. Given a 2D triangle ABC and a point P, all in old good Cartesian coordinates `(xy)`. Our goal is to find barycentric coordinates of the point P with respect to the triangle ABC. It means that we look for three numbers `(1 − u − v,u,v)` such that we can find the point P as follows: ![ ](./img/lesson2_f1.png) While being a bit frightening at the first glance, it is really simple: imagine that we put three weights `(1−u−v,u,v)` at the vertices A, B and C, respectively. Then the barycenter of the system is exactly in the point P. We can say the same thing with other words: the point P has coordinates `(u,v)` in the (oblique) basis (A,![](./img/lesson2_ab.png),![](./img/lesson2_ac.png)): ![ ](./img/lesson2_f2.png) So, we have vectors ![](./img/lesson2_ab.png), ![](./img/lesson2_ac.png) and ![](./img/lesson2_ap.png), we need to find two real numbers u and v respecting the following constraint: ![ ](./img/lesson2_f3.png) It is a simple vector equation, or a linear system of two equations with two variables: ![ ](./img/lesson2_f4.png) I am lazy and do not want to solve linear systems in a scholar way. Let us write it in matrix form: ![ ](./img/lesson2_f5.png) It means that we are looking for a vector `(u,v,1)` that is orthogonal to `(ABx,ACx,PAx)` and `(ABy,ACy,PAy)` *at the same time*! I hope you see [where I am heading](https://en.wikipedia.org/wiki/Cross_product). That is a small hint: to find an intersection of two straight lines in a plane (that is exactly what we did here), it is sufficient to compute one cross product. By the way, test yourself: how do we find an equation of a line passing through two given points? So, let us program our new rasterization routine: we iterate through all pixels of a bounding box for a given triangle. For each pixel we compute its barycentric coordinates. If it has at least one negative component, then the pixel is outside of the triangle. Probably it is more clear to see the program directly: ```csharp Vec3f Barycentric (Vec3f a, Vec3f b, Vec3f c, Vec2i p) { var pixel = new Vec3f { x = p.x + 0.5f, y = p.y + 0.5f }; var ab = b - a; var ac = c - a; var pa = a - pixel; var r = Cross (new Vec3f { x = ab.x, y = ac.x, z = pa.x }, new Vec3f { x = ab.y, y = ac.y, z = pa.y }); // triangle is degenerate, in this case return smth with negative coordinates if (Math.Abs (r.z) < 1) return new Vec3f { x = -1, y = 1, z = 1 }; return new Vec3f { x = 1 - r.x / r.z - r.y / r.z, y = r.x / r.z, z = r.y / r.z }; } void Triangle (Image image, Vec3f [] coordinates, Color color) { var t0 = coordinates [0]; var t1 = coordinates [1]; var t2 = coordinates [2]; var pMax = new Vec2i { x = (int)Math.Max (0, Math.Max (t0.x, Math.Max (t1.x, t2.x))), y = (int)Math.Max (0, Math.Max (t0.y, Math.Max (t1.y, t2.y))) }; var pMin = new Vec2i { x = (int)Math.Min (image.Width, Math.Min (t0.x, Math.Min (t1.x, t2.x))), y = (int)Math.Min (image.Height, Math.Min (t0.y, Math.Min (t1.y, t2.y))) }; Vec2i p; for (p.x = pMin.x; p.x <= pMax.x; p.x++) { for (p.y = pMin.y; p.y <= pMax.y; p.y++) { var bc = Barycentric (t0, t1, t2, p); if (bc.x < 0 || bc.y < 0 || bc.z < 0) continue; image [p.x, p.y] = color; } } } ``` # Flat shading render We already know how to draw a model with empty triangles. Let us fill them with a random color. This will help us to see how well we have encoded filling of triangles. Here is the code: ```csharp var image = new Image(width, height, Format.BGR); // Map world coordinates [-1..-1] to screen coordinates [0..width] Func map = v => new Vec3f { x = (int)((v.x+1)*image.Width/2), y = (int)((v.y+1)*image.Height/2) }; var rnd = new Random(); Func rndByte = () => (byte)rnd.Next(255); Func rndColor = () => new Color(rndByte(), rndByte(), rndByte()); var coordinates = new Vec3f[3]; foreach(var face in headModel.Faces) { for(int i=0; i<3; i++) { var vIndex = face.Vertices[i]; var v = headModel.Vertices[vIndex]; coordinates[i] = map(v); } Triangle(image, coordinates, rndColor()); } image.VerticalFlip (); image ``` Let us get rid of these clown-colors and put some lighting. Captain Obvious: ”*At the same light intensity, the polygon is illuminated most brightly when it is orthogonal to the light direction.*” Let us compare: ![ ](./img/lesson2_light1.jpeg) ![](./img/lesson2_light2.jpeg) We get zero illumination if the polygon is parallel to the vector of light. To paraphrase: the intensity of illumination is equal to the scalar product of the light vector and the normal to the given triangle. The normal to the triangle can be calculated simply as the [cross product](https://en.wikipedia.org/wiki/Cross_product) of its two sides. As a side note, at this course we will perform linear computations on the colors. However `(128,128,128)` color is not half as bright as `(255, 255, 255)`. We are going to ignore gamma correction and tolerate the incorrectness of the brightness of our colors. ```csharp var image = new Image (width, height, Format.BGR); var light_dir = new Vec3f { x = 0, y = 0, z = -1 }; var world = new Vec3f [3]; var screen = new Vec3f [3]; foreach (var face in headModel.Faces) { for (int i = 0; i < 3; i++) { var vIndex = face.Vertices [i]; world [i] = headModel.Vertices [vIndex]; screen [i] = map (world [i]); } var n = Cross (world [2] - world [0], world [1] - world [0]).Normalize (); var intensivity = Dot (n, light_dir); if (intensivity > 0) Triangle (image, screen, Color.White * intensivity); } image.VerticalFlip (); image ``` ================================================ FILE: graphics/tiny-renderer/lesson8.workbook/lesson3.csx ================================================ using static Geometry; var headTexture = Image.Load ("obj/african_head_diffuse.tga"); headTexture.VerticalFlip (); float [] InitZBuffer (Image image) { var zbuffer = new float [image.Width * image.Height]; for (int idx = 0; idx < zbuffer.Length; idx++) zbuffer [idx] = float.NegativeInfinity; return zbuffer; } Vec3f Barycentric (Vec2f a, Vec2f b, Vec2f c, Vec2f p) { var ab = b - a; var ac = c - a; var pa = a - p; var r = Cross (new Vec3f { x = ab.x, y = ac.x, z = pa.x }, new Vec3f { x = ab.y, y = ac.y, z = pa.y }); // triangle is degenerate, in this case return smth with negative coordinates // dont forget that r.z is integer. If it is zero then triangle ABC is degenerate if ((int)r.z == 0) return new Vec3f { x = -1, y = 1, z = 1 }; return new Vec3f { x = 1 - (r.x + r.y) / r.z, y = r.x / r.z, z = r.y / r.z }; } void Triangle (Image image, Vec3f [] coordinates, Image texture, Vec2f [] uv, float intensivity, float [] zbuffer) { Vec3f t0 = coordinates [0]; Vec3f t1 = coordinates [1]; Vec3f t2 = coordinates [2]; var pMax = new Vec2i { x = (int)Math.Max (0, Math.Max (t0.x, Math.Max (t1.x, t2.x))), y = (int)Math.Max (0, Math.Max (t0.y, Math.Max (t1.y, t2.y))) }; var pMin = new Vec2i { x = (int)Math.Min (image.Width, Math.Min (t0.x, Math.Min (t1.x, t2.x))), y = (int)Math.Min (image.Height, Math.Min (t0.y, Math.Min (t1.y, t2.y))) }; for (int x = pMin.x; x <= pMax.x; x++) { for (int y = pMin.y; y <= pMax.y; y++) { var pixelCenter = new Vec2f { x = x + 0.5f, y = y + 0.5f }; var bc = Barycentric (Project2D(t0), Project2D(t1), Project2D(t2), pixelCenter); if (bc.x < 0 || bc.y < 0 || bc.z < 0) continue; var z = t0.z * bc.x + t1.z * bc.y + t2.z * bc.z; var u = (int)(uv [0].x * bc.x + uv [1].x * bc.y + uv [2].x * bc.z); var v = (int)(uv [0].y * bc.x + uv [1].y * bc.y + uv [2].y * bc.z); var idx = x + y * image.Width; if (zbuffer [idx] < z) { zbuffer [idx] = z; var color = texture [u, v]; image [x, y] = color * intensivity; } } } } ================================================ FILE: graphics/tiny-renderer/lesson8.workbook/lesson3.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" #load "lesson1.csx" #load "lesson2.csx" using static Geometry; ``` # **Lesson 3: Hidden faces removal (z buffer)** # Introduction Hello, let me introduce you my friend z-buffer of a black guy. He will help us get rid of the visual artifacts of the hidden faces removal we had during the last lesson. ![](./img/lesson3_face1.png) By the way, i'd like to mention that this model i use heavily in the course is created by [Vidar Rapp](https://se.linkedin.com/in/vidarrapp). He kindely granted me a permission to use it for teaching rendering basics and i vandalized it, but i promise you to give back the eyes to the guy. Well, back to the topic, in theory we could just draw all the triangles without discarding any. If we do it properly starting rear-to-front, the front facets will erase the back ones. It is called the [painter's algorithm](http://en.wikipedia.org/wiki/Painter%27s_algorithm). Unfortunately, it comes along with a high computational cost: for each camera movement we need to re-sort all the scene. And then there are dynamic scenes... And this is not even the main problem. The main problem is it is not always possible to determine the correct order. # **Let us try to render a simple scene** Imagine a simple scene made of three triangles: the camera looks up-to-down, we project the colored triangles onto the white screen: ![ ](./img/lesson3_scene1.png) The render should look like this: ![ ](./img/lesson3_scene2.png) Blue facet - is it behind or in front of the red one? The painter's algorithm does not work here. It is possible to split blue facet in two (one in front of the red facet and one behind). And then the one in front of the red one is to be split in two - one in front of the green triangle and one behind... I think you get the problem: in scenes with millions of triangles it is really expensive to compute. It is possible to use [BSP trees](https://en.wikipedia.org/wiki/Binary_space_partitioning) to get it done. By the way, this data structure is constant for moving camera, but it is really messy. And the life is too short to get it messy. # **Even simpler: let us lose a dimension. Y-buffer!** Let us lose a dimension for a while and to cut the above scene along the yellow plane: ![ ](./img/lesson3_scene3.png) I mean, now our scene is made of three line segments (intersection of the yellow plane and each of the triangles), and the final render has a normal width but 1 pixel height: ![ ](./img/lesson3_scene4.png) Our scene is two-dimensional, so it is easy to draw it using the line() function we programmed in the very first lesson. ```csharp var scene = new Image (800, 500, Format.BGR); // scene "2d mesh" Line(scene, new Vec2i {x=20, y=34}, new Vec2i {x=744, y=400}, Color.Red); Line(scene, new Vec2i {x=120, y=434}, new Vec2i {x=444, y=400}, Color.Green); Line(scene, new Vec2i {x=330, y=463}, new Vec2i {x=594, y=200}, Color.Blue); // screen line Line(scene, new Vec2i {x=10, y=10}, new Vec2i{x=790, y=10}, Color.White); scene.VerticalFlip(); // I want to have the origin at the left bottom corner of the image scene // This is how our 2D scene looks like if we look at it sideways: ``` Let us render it. Recall that the render is 1 pixel height. In my source code I create images 16 pixels height for the ease of reading on high resolution screens. `Rasterize()` function writes only in the first line of the image `render` ```csharp void Rasterize(Image image, Vec2i p0, Vec2i p1, int[] ybuffer, Color color) { if (p0.x>p1.x) Swap(ref p0, ref p1); for (int x=p0.x; x<=p1.x; x++) { float t = (x-p0.x)/(float)(p1.x-p0.x); var y = (int)(p0.y*(1-t) + p1.y*t); if (ybuffer[x] < y) { ybuffer[x] = y; image[x, 0] = color; } } } var ybuffer = new int [width]; for (int i = 0; i < width; i++) ybuffer[i] = int.MinValue; var render = new Image (width, 16, Format.BGR); Rasterize(render, new Vec2i{x=20,y=34}, new Vec2i{x=744, y=400}, ybuffer, Color.Red); Rasterize(render, new Vec2i{x=120, y=434}, new Vec2i{x=444,y=400}, ybuffer, Color.Green); Rasterize(render, new Vec2i{x=330, y=463}, new Vec2i{x=594,y=200}, ybuffer, Color.Blue); render ``` It is really-really simple: I iterate through all x-coordinates between `p0.x` and `p1.x` and compute the corresponding y-coordinate of the segment. Then I check what we got in our array `ybuffer` with current `x` index. If the current `y`-value is closer to the camera than the value in the `ybuffer`, then I draw it on the screen and update the `ybuffer`. Let us see it step-by-step. After calling `Rasterize()` on the first (red) segment this is our memory: screen:![](./img/lesson3_rasterize1.png) ybuffer: ![ ](./img/lesson3_rasterize2.png) Here the magenta color indicates the minus infinity, those are places corresponding to the screen we did not touch. All the rest is shown in the shades of gray: clear colors are close to the camera, dark colors far from the camera. Then we draw the green segment. screen:![ ](./img/lesson3_rasterize3.png) ybuffer:![ ](./img/lesson3_rasterize4.png) And finally the blue one. screen:![ ](./img/lesson3_rasterize5.png) ybuffer:![ ](./img/lesson3_rasterize6.png) Congratulations, we just drew a 2D scene on a 1D screen! Let us admire once again the render: ![ ](./img/lesson3_rasterize7.png) # Back to 3D So, for drawing on a 2D screen the z-buffer must be two-dimensional: `var zbuffer = new int[width * height];` Personally I pack a two-dimensional buffer into a one-dimensional, the conversion is trivial: `var idx = x + y* width;` and the back one: `var x = idx % width;`\ `var y = idx % width;` Then in the code I simply iterate through all the triangles and call the rasterizer function with current triangle and a reference to the z-buffer. The only difficulty is how to compute the z-value of a pixel we want to draw. Let us recall how we computed the y-value in the y-buffer example: `int y = p0.y*(1-t) + p1.y*t;` What is the nature of the `t` variable? It turns out that `(1-t, t)` are barycentric coordinates of the point `(x,y)` with respect to the segment `p0, p1: (x,y) = p0*(1-t) + p1*t`. So the idea is to take the barycentric coordinates version of triangle rasterization, and for every pixel we want to draw simply to multiply its barycentric coordinates by the z-values of the vertices of the triangle we rasterize: ```csharp Vec3f Barycentric (Vec2f a, Vec2f b, Vec2f c, Vec2f p) { var ab = b - a; var ac = c - a; var pa = a - p; var r = Cross (new Vec3f { x = ab.x, y = ac.x, z = pa.x }, new Vec3f { x = ab.y, y = ac.y, z = pa.y }); // triangle is degenerate, in this case return smth with negative coordinates // dont forget that r.z is integer. If it is zero then triangle ABC is degenerate if ((int)r.z == 0) return new Vec3f { x = -1, y = 1, z = 1 }; return new Vec3f { x = 1 - (r.x + r.y) / r.z, y = r.x / r.z, z = r.y / r.z }; } void Triangle (Image image, Vec3f [] coordinates, Color color, float [] zbuffer) { Vec3f t0 = coordinates [0]; Vec3f t1 = coordinates [1]; Vec3f t2 = coordinates [2]; var pMax = new Vec2i { x = (int)Math.Max (0, Math.Max (t0.x, Math.Max (t1.x, t2.x))), y = (int)Math.Max (0, Math.Max (t0.y, Math.Max (t1.y, t2.y))) }; var pMin = new Vec2i { x = (int)Math.Min (image.Width, Math.Min (t0.x, Math.Min (t1.x, t2.x))), y = (int)Math.Min (image.Height, Math.Min (t0.y, Math.Min (t1.y, t2.y))) }; for (int x = pMin.x; x <= pMax.x; x++) { for (int y = pMin.y; y <= pMax.y; y++) { var pixelCenter = new Vec2f { x = x + 0.5f, y = y + 0.5f }; var bc = Barycentric (Project2D (t0), Project2D (t1), Project2D (t2), pixelCenter); if (bc.x < 0 || bc.y < 0 || bc.z < 0) continue; var z = t0.z * bc.x + t1.z * bc.y + t2.z * bc.z; var idx = x + y * image.Width; if (zbuffer [idx] < z) { zbuffer [idx] = z; image [x, y] = color; } } } } float [] InitZBuffer (Image image) { var zbuffer = new float [image.Width * image.Height]; for (int idx = 0; idx < zbuffer.Length; idx++) zbuffer [idx] = float.NegativeInfinity; return zbuffer; } var image = new Image(width, height, Format.BGR); Func map = v => new Vec3f { x = (int)((v.x+1)*(image.Width-1)/2 + 0.5f), y = (int)((v.y+1)*(image.Height-1)/2 + 0.5f), z = v.z }; var zbuffer = InitZBuffer(image); foreach(var face in headModel.Faces) { for(int i=0; i<3; i++) { var vIndex = face.Vertices[i]; world[i] = headModel.Vertices[vIndex]; screen[i] = map(world[i]); } Vec3f n = Cross(world[2] - world[0], world[1] - world[0]).Normalize (); var intensivity = Dot(n, light_dir); if(intensivity > 0) Triangle(image, screen, Color.White * intensivity, zbuffer); } image.VerticalFlip (); image ``` # Okay, we just interpolated the z-values. What else can we do? Texture! In the `.obj` file we have lines starting with `vt u v`, they give an array of texture coordinates. The number in the middle (between the slashes) in the facet lines\ `f x/x/x x/x/x x/x/x` are the texture coordinates of this vertex of this triangle. Interpolate it inside the triangle, multiply by the width-height of the texture image and you will get the color to put in your render. ```csharp void Triangle (Image image, Vec3f [] coordinates, Image texture, Vec2f [] uv, float intensivity, float [] zbuffer) { Vec3f t0 = coordinates [0]; Vec3f t1 = coordinates [1]; Vec3f t2 = coordinates [2]; var pMax = new Vec2i { x = (int)Math.Max (0, Math.Max (t0.x, Math.Max (t1.x, t2.x))), y = (int)Math.Max (0, Math.Max (t0.y, Math.Max (t1.y, t2.y))) }; var pMin = new Vec2i { x = (int)Math.Min (image.Width, Math.Min (t0.x, Math.Min (t1.x, t2.x))), y = (int)Math.Min (image.Height, Math.Min (t0.y, Math.Min (t1.y, t2.y))) }; for (int x = pMin.x; x <= pMax.x; x++) { for (int y = pMin.y; y <= pMax.y; y++) { var pixelCenter = new Vec2f { x = x + 0.5f, y = y + 0.5f }; var bc = Barycentric (Project2D(t0), Project2D(t1), Project2D(t2), pixelCenter); if (bc.x < 0 || bc.y < 0 || bc.z < 0) continue; var z = t0.z * bc.x + t1.z * bc.y + t2.z * bc.z; var u = (int)(uv [0].x * bc.x + uv [1].x * bc.y + uv [2].x * bc.z); var v = (int)(uv [0].y * bc.x + uv [1].y * bc.y + uv [2].y * bc.z); var idx = x + y * image.Width; if (zbuffer [idx] < z) { zbuffer [idx] = z; var color = texture [u, v]; image [x, y] = color * intensivity; } } } } var image = new Image(width, height, Format.BGR); var headTexture = Image.Load ("obj/african_head_diffuse.tga"); headTexture.VerticalFlip (); Func uvMap = v => new Vec2f { x = v.x * (headTexture.Width - 1), y = v.y * (headTexture.Height - 1) }; var zbuffer = InitZBuffer(image); var uv = new Vec2f[3]; var model = headModel; foreach(var face in model.Faces) { for(int i=0; i<3; i++) { var vIndex = face.Vertices[i]; world[i] = model.Vertices[vIndex]; screen[i] = map(world[i]); var tIndex = face.Textures[i]; uv[i] = uvMap(model.Textures[tIndex]); } Vec3f n = Cross(world[2] - world[0], world[1] - world[0]).Normalize (); var intensivity = Dot(n, light_dir); if(intensivity > 0) Triangle(image, screen, headTexture, uv, intensivity, zbuffer); } image.VerticalFlip (); image ``` ================================================ FILE: graphics/tiny-renderer/lesson8.workbook/lesson4.csx ================================================ Vec2f[] uv = new Vec2f [3]; Func uvMap = (texture, v) => new Vec2f { x = v.x * (texture.Width - 1), y = v.y * (texture.Height - 1) }; Matrix4 Viewport (int x, int y, int w, int h) { var depth = 255f; var m = Matrix4.Identity (); m [0, 3] = x + w / 2f; m [1, 3] = y + h / 2f; m [2, 3] = depth / 2f; m [0, 0] = w / 2f; m [1, 1] = h / 2f; m [2, 2] = depth / 2f; return m; } Matrix4 Projection (float coeff) { var projection = Matrix4.Identity (); projection [3, 2] = coeff; return projection; } ================================================ FILE: graphics/tiny-renderer/lesson8.workbook/lesson4.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Matrix.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" #load "lesson1.csx" #load "lesson2.csx" #load "lesson3.csx" using static Geometry; using static MatrixHelpers; ``` # **Lesson 4: Perspective projection** # The goal In previous lessons we rendered our model in orthographic projection by simply forgetting the z-coordinate. The goal for today is to learn how to draw in perspective: ![ ](./img/lesson4_the_goal.png) # 2D geometry: Linear transformations A linear transformation on a plane can be represented by a corresponding matrix. If we take a point `(x,y)` then its transformation can be written as follows: ![ ](./img/lesson4_formula1.svg) The simplest (not degenerate) transformation is the identity, it does not move any point: ![ ](./img/lesson4_formula_2d_identity.svg) Diagonal coefficients of the matrix give scaling along coordinate axes. Let us illustrate it, if we take the following transformation: ![ ](./img/lesson4_formula_2d_scale.svg) Then the white object (the white square with one corner chopped) will be transformed into the yellow one. Red and green line segments give unit length vectors aligned with `x` and `y`, respectively. All the images for this article were generated using this code: ```csharp Matrix4 Viewport (int x, int y, int w, int h) { var depth = 255f; var m = Matrix4.Identity (); m [0, 3] = x + w / 2f; m [1, 3] = y + h / 2f; m [2, 3] = depth / 2f; m [0, 0] = w / 2f; m [1, 1] = h / 2f; m [2, 2] = depth / 2f; return m; } Matrix4 Projection (float coeff) { var projection = Matrix4.Identity (); projection [3, 2] = coeff; return projection; } Vec4f Embed4D (Vec3f v, float fill = 1) { return new Vec4f { x = v.x, y = v.y, z = v.z, h = fill }; } Vec3f Project3D (Vec4f v) { return new Vec3f { x = v.x, y = v.y, z = v.z }; } Func map = v => Project3D(v/v.h); void RenderAxes (Image image) { var w = image.Width; var h = image.Height; var vp = Viewport(w/4, w/4, w/2, h/2); // draw the axes var x = new Vec3f { x = 1 }; var y = new Vec3f { y = 1 }; var o = new Vec3f (); o = map(Mult(vp, Embed4D(o))); x = map(Mult(vp, Embed4D(x))); y = map(Mult(vp, Embed4D(y))); Line(image, o, x, Color.Red); Line(image, o, y, Color.Green); } var cube = Model.FromFile("obj/cube.obj"); void RenderCube(Image image, Matrix4 deformation, Color color) { var w = image.Width; var h = image.Height; var vp = Viewport(w/4, w/4, w/2, h/2); var face = cube.Faces[0]; var faceLen = face.Vertices.Length; for(int j=0; j x/(c-z) = x'/c. In other words: ![ ](./img/lesson4_formula_x.svg) By doing the same reasoning for triangles CPB and CP'D, it is easy to find the following expression: ![](./img/lesson4_formula_y.svg) It is really similar to the result we put aside few moments ago, but there we got the result by a single matrix multiplication. We got the law for the coefficient: `r = -1/c` # Let us sum up: the main formula for today *If you simply copy-paste this formula without understanding the above material, I hate you.* So, if we want to compute a central projection with a camera **(important!) camera located on the z-axis with distance c from the origin**, then we embed the point into 4D by augmenting it with 1, then we multiply it with the following matrix, and retro-project it into 3D. ![ ](./img/lesson4_formula_last.svg) We deformed our object in a way, that simply forgetting its z-coordinate we will get a drawing in a perspective. If we want to use the z-buffer, then, naturally, do not forget the z: ```csharp var image = new Image(width, height, Format.BGR); var camera = new Vec3f { z = 3 }; var projection = Projection(-1/camera.z); var viewPort = Viewport(width/8, height/8, width*3/4, height*3/4); Func map = v => { var r4 = Mult (viewPort * projection, Embed4D (v)); var r = Project3D (r4 / r4.h); r.x = (int)(r.x + 0.5f); r.y = (int)(r.y + 0.5f); return r; }; Func uvMap = (texture, v) => new Vec2f { x = v.x * (texture.Width - 1), y = v.y * (texture.Height - 1) }; var model = headModel; var zbuffer = InitZBuffer(image); Vec2f[] uv = new Vec2f [3]; foreach(var face in model.Faces) { for(int i=0; i<3; i++) { var vIndex = face.Vertices[i]; world[i] = model.Vertices[vIndex]; screen[i] = map(world[i]); var tIndex = face.Textures[i]; uv[i] = uvMap(headTexture, model.Textures[tIndex]); } Vec3f n = Cross(world[2] - world[0], world[1] - world[0]).Normalize (); var intensivity = Dot(n, light_dir); if(intensivity > 0) Triangle(image, screen, headTexture, uv, intensivity, zbuffer); } image.VerticalFlip (); image ``` ================================================ FILE: graphics/tiny-renderer/lesson8.workbook/lesson5.csx ================================================ using static Geometry; var eye = new Vec3f { x = 1, y = 1, z = 3 }; var center = new Vec3f { x = 0, y = 0, z = 0 }; var up = new Vec3f { x = 0, y = 1, z = 0 }; Matrix4 LookAt (Vec3f eye, Vec3f center, Vec3f up) { var z = (eye - center).Normalize (); var x = Cross (up, z).Normalize (); var y = Cross (z, x).Normalize (); var Minv = Matrix4.Identity (); Minv [0, 0] = x.x; Minv [0, 1] = x.y; Minv [0, 2] = x.z; Minv [1, 0] = y.x; Minv [1, 1] = y.y; Minv [1, 2] = y.z; Minv [2, 0] = z.x; Minv [2, 1] = z.y; Minv [2, 2] = z.z; var Tr = Matrix4.Identity (); Tr [0, 3] = -center.x; Tr [1, 3] = -center.y; Tr [2, 3] = -center.y; return Minv * Tr; } ================================================ FILE: graphics/tiny-renderer/lesson8.workbook/lesson5.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Matrix.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" #load "lesson1.csx" #load "lesson2.csx" #load "lesson3.csx" #load "lesson4.csx" using static Geometry; using static MatrixHelpers; ``` # Lesson 5: Moving the camera # Change of basis in 3D space In Euclidean space coordinates can be given by a point (the origin) and a basis. What does it mean that point P has coordinates `(x,y,z)` in the frame `(O, i,j,k)`? It means that the vector OP can be expressed as follows: ![ ](./img/lesson5_basis.svg) Now image that we have another frame `(O', i',j',k')`. How do we transform coordinates given in one frame to another? First of all let us note that since `(i,j,k)` and `(i',j',k')` are bases of 3D, there exists a (non degenerate) matrix M such that: ![ ](./img/lesson5_new_basis.svg) Let us draw an illustration: ![](./img/lesson5_sketch1.png) Then let us re-express the vector OP: ![ ](./img/lesson5_change_basis1.svg) Now let us substitute `(i',j',k')` in the right part with the change of basis matrix: ![ ](./img/lesson5_change_basis2.svg) And it gives us the formula to transform coordinates from one frame to another: ![ ](./img/lesson5_change_basis3.svg) # Let us create our own gluLookAt OpenGL and, as a consequence, our tiny renderer are able to draw scenes **only with the camera located on the z-axis.** If we want to move the camera, no problem, we can move all the scene, leaving the camera immobile. Let us put the problem this way: we want to draw a scene with a camera situated in point **e**(eye), the camera should be pointed to the point **c** (center) in such way that a given vector **u**(up) is to be vertical in the final render. Here is an illustration: ![ ](./img/lesson5_change_basis4.png) ```csharp Matrix4 LookAt (Vec3f eye, Vec3f center, Vec3f up) { var z = (eye - center).Normalize (); var x = Cross (up, z).Normalize (); var y = Cross (z, x).Normalize (); var Minv = Matrix4.Identity (); Minv [0, 0] = x.x; Minv [0, 1] = x.y; Minv [0, 2] = x.z; Minv [1, 0] = y.x; Minv [1, 1] = y.y; Minv [1, 2] = y.z; Minv [2, 0] = z.x; Minv [2, 1] = z.y; Minv [2, 2] = z.z; var Tr = Matrix4.Identity (); Tr [0, 3] = -center.x; Tr [1, 3] = -center.y; Tr [2, 3] = -center.y; return Minv * Tr; } ``` Note that `z'` is given by the vector **`ce`** (do not forget to normalize it, it helps later). How do we compute `x'`? Simply by a cross product between **`u`** and **`z'`**. Then we compute `y'`, such that it is orthogonal to already calculated `x'` and `z'` (let me remind you that in our problem settings \*\*`ce` \*\*and **`u`** are not necessarily orthogonal). The very last step is a translation of the origin to the center **c** and our transformation matrix is ready. Now it suffices to get any point with coordinates `(x,y,z,1)` in the model frame, multiply it by the matrix ModelView and we get the coordinates in the camera frame! By the way, the name ModelView comes from OpenGL terminology. # Viewport If you followed this course from the beginning, you should remember strange lines like this one: ```csharp // x = (v.x+1)*(width-1)/2 // y = (v.y+1)*(height-1)/2 ``` What does it mean? It means that i have a point Vec2f v, it belongs to the square \[-1,1\]\*\[-1,1\]. I want to draw it in the image of (width, height) dimensions. Value (v.x\+1) is varying between 0 and 2, (v.x\+1)/2 between 0 and 1, and (v.x\+1)\*width/2 sweeps all the image. Thus we effectively mapped the bi-unit square onto the image. But now we are getting rid of these ugly constructs, and i want to rewrite all the computiations in the matrix form. Let us consider the following C# code: ```csharp /* Matrix4 Viewport (int x, int y, int w, int h) { var depth = 255f; var m = Matrix4.Identity (); m [0, 3] = x + w / 2f; m [1, 3] = y + h / 2f; m [2, 3] = depth / 2f; m [0, 0] = w / 2f; m [1, 1] = h / 2f; m [2, 2] = depth / 2f; return m; } */ ``` This code creates this matrix: ![ ](./img/lesson5_viewport.svg) It means that the bi-unit cube \[-1,1\]*\[-1,1\]*\[-1,1\] is mapped onto the screen cube \[0,w\]*\[0,h\]*\[0,d\]. Right, cube, and not a rectangle, this is because of the depth computations with the z-buffer. Here d is the resolution of the z-buffer. I like to have it equal to 255 because of simplicity of dumping black-and-white images of the z-buffer for debugging. In the OpenGL terminology this matrix is called viewport matrix. # Chain of coordinate transformations So, let us sum up. Our models (characters, for example) are created in their own local frame (**object coordinates**). They are inserted into a scene expressed in **world coordinates**. The transformation from one to another is made with matrix **Model**. Then, we want to express it in the camera frame (**eye coordinates**), the transformation is called **View**. Then, we deform the scene to create a perspective deformation with **Projection** matrix (lesson 4), this matrix transforms the scene to so-called **clip coordinates**. Finally, we draw the scene, and the matrix transforming clip coordinates to the **screen coordinates** is called **Viewport**. Again, if we read a point **v** from the .obj file, then to draw it on the screen it undergoes the following chain of transformations: Viewport \* Projection \* View \* Model \* v As i draw a single object only, the matrix Model is equal to identity, and i merged it with the matrix View: ```csharp var eye = new Vec3f { x = 1, y = 1, z = 3 }; var center = new Vec3f { x = 0, y = 0, z = 0 }; var up = new Vec3f { x = 0, y = 1, z = 0 }; // draw the model var modelView = LookAt(eye, center, up); var viewPort = Viewport(width/8, height/8, width*3/4, height*3/4); var projection = Projection(-1/(eye-center).Norm()); Func map = v => { var r4 = Mult (viewPort * projection * modelView, Embed4D (v)); var r = Project3D (r4 / r4.h); r.x = (int)(r.x + 0.5f); r.y = (int)(r.y + 0.5f); return r; }; var image = new Image(width, height, Format.BGR); var model = headModel; var zbuffer = InitZBuffer(image); foreach(var face in model.Faces) { for(int i=0; i<3; i++) { var vIndex = face.Vertices[i]; world[i] = model.Vertices[vIndex]; screen[i] = map(world[i]); var tIndex = face.Textures[i]; uv[i] = uvMap(headTexture, model.Textures[tIndex]); } Vec3f n = Cross(world[2] - world[0], world[1] - world[0]).Normalize (); var intensivity = Dot(n, light_dir); if(intensivity > 0) Triangle(image, screen, headTexture, uv, intensivity, zbuffer); } image.VerticalFlip (); image ``` # Transformation of normal vectors There is a widely-known fact: * If we have a model and its normal vectors are given by the artist AND this model is transformed with an affine mapping, then normal vectors are to be transformed with a mapping, equal to the transposition of the inverse matrix of the original mapping matrix What-what-what?! I met quite a few programmers who know this fact, but it remains a black magic for them. In fact, it is not so complicated. Take a pencil and draw a 2D triangle `(0,0)`, `(0,1)`, `(1,0)` and a vector **n**, normal to the hypothenuse. Naturally, **n** is equal to `(1,1)`. Then let us stretch all the y-coordinates by a factor of 2, leaving x-coordinates intact. Thus, our triangle becomes `(0,0)`, `(0,2)`, `(1,0)`. If we transform the vector **n** in the same way, it becomes `(1, 2)` and it is no longer orthogonal to the transformed edge of the triangle. Thus, to remove all the black magic fog, we need to understand one simple thing: **we do not need to simply transform normal vectors (as they can become not normal anymore), we need to compute (new) normal vectors to the transformed model.** Back to 3D, we have a vector **n** = (A,B,C). We know that the plane passing through the origin and having **n** for its normal, has an equation `Ax+By+Cz=0`. Let us write it in the matrix form (i do it in homogeneous coordinates from the beginning): ![ ](./img/lesson5_transform_normal1.png) Recall that `(A,B,C)` - is a vector, so we augment it with 0 when embedding into the 4D, and `(x,y,z)` is augmented with 1 since it is a point. Let us insert an identity matrix in between (inverse to M multiplied by M is equal to identity): ![ ](./img/lesson5_transform_normal2.png) The expression in right parentheses - are for the transformed points of the object. In the left - are for normal vectors to the transformed object! In standard convention we usually write coordinates as columns (please let us not raise all the stuff about contra- and co-variant vectors), so we can rewrite the previous expression as follows: ![ ](./img/lesson5_transform_normal2.png) And the left parentheses tell us that a normal to the transformed object can be computed from the old normal by applying the inverse transpose matrix of the affine mapping. Please note that if our transformation matrix M is a composition of uniform scalings, rotations and translations, then M is equal to its inverse transpose, since inverse and transpose are cancelling each other in this case. But since our matrices include perspective deformations, usually this trick does not help. In the current code we do not use the transformation of normal vectors, but in the next lesson it will be very, very handy. Happy coding! ================================================ FILE: graphics/tiny-renderer/lesson8.workbook/lesson6.csx ================================================ using static Geometry; using static MatrixHelpers; using static ShaderUtils; var diabloModel = Model.FromFile ("obj/diablo3_pose.obj"); var diabloTexture = Image.Load ("obj/diablo3_pose_diffuse.tga"); var diabloNormalMap = Image.Load ("obj/diablo3_pose_nm.tga"); var diabloTangentMap = Image.Load ("obj/diablo3_pose_nm_tangent.tga"); var diabloSpecularMap = Image.Load ("obj/diablo3_pose_spec.tga"); diabloTexture.VerticalFlip (); diabloNormalMap.VerticalFlip (); diabloTangentMap.VerticalFlip (); diabloSpecularMap.VerticalFlip (); light_dir = new Vec3f { x = 1, y = 1, z = 1 }; eye = new Vec3f { x = 1, y = 1, z = 3 }; center = new Vec3f { x = 0, y = 0, z = 0 }; up = new Vec3f { x = 0, y = 1, z = 0 }; var modelView = LookAt(eye, center, up); var viewPort = Viewport(width/8, height/8, width*3/4, height*3/4); var projection = Projection(-1f/(eye-center).Norm()); interface IShader { Vec4f Vertex (Face face, int nthvert); bool Fragment (Vec3f fragment, Vec3f bar, out Color color); }; class RenderResult { public Image Image { get; set; } public float [] ZBuffer { get; set; } } RenderResult Render (Model model, IShader shader) { var image = new Image (width, height, Format.BGR); var zbuffer = InitZBuffer (image); var screen_coords = new Vec4f [3]; foreach (var face in model.Faces) { for (int i = 0; i < 3; i++) screen_coords [i] = shader.Vertex (face, i); Triangle (image, screen_coords, shader, zbuffer); } return new RenderResult { Image = image, ZBuffer = zbuffer }; } void Box (Vec4f [] pts, out Vec2i pMin, out Vec2i pMax) { pMax = new Vec2i { x = int.MinValue, y = int.MinValue }; pMin = new Vec2i { x = int.MaxValue, y = int.MaxValue }; for (int i = 0; i < 3; i++) { pMax.x = (int)Math.Max (pMax.x, pts [i].x / pts [i].h); pMax.y = (int)Math.Max (pMax.y, pts [i].y / pts [i].h); pMin.x = (int)Math.Min (pMin.x, pts [i].x / pts [i].h); pMin.y = (int)Math.Min (pMin.y, pts [i].y / pts [i].h); } } void Triangle (Image image, Vec4f [] pts, IShader shader, float [] zbuffer) { Vec2i pMin, pMax; Box (pts, out pMin, out pMax); Color color; for (int x = pMin.x; x <= pMax.x; x++) { for (int y = pMin.y; y <= pMax.y; y++) { var pixelCenter = new Vec2f { x = x + 0.5f, y = y + 0.5f }; var bc = Barycentric (Project2D (pts [0] / pts [0].h), Project2D (pts [1] / pts [1].h), Project2D (pts [2] / pts [2].h), pixelCenter); var z = pts [0].z * bc.x + pts [1].z * bc.y + pts [2].z * bc.z; // z [0..255] var w = pts [0].h * bc.x + pts [1].h * bc.y + pts [2].h * bc.z; var frag_depth = z / w; var idx = x + y * image.Width; if (bc.x < 0 || bc.y < 0 || bc.z < 0 || zbuffer[idx] > frag_depth) continue; var fragment = new Vec3f { x = x, y = y, z = frag_depth }; var discard = shader.Fragment (fragment, bc, out color); if (!discard) { zbuffer [idx] = frag_depth; image [x, y] = color; } } } } static class ShaderUtils { public static Vec4f TransformFace (Model model, Face face, int nthvert, Matrix4 t) { var v = model.Vertex (face, nthvert); // read the vertex from model var glVertex = Embed4D (v); return Mult (t, glVertex); // transform it to screen coordinates } public static void UpdateVarayingUV (Model model, Face face, int nthvert, ref Vec3f varyingU, ref Vec3f varyingV) { var vt = model.GetUV (face, nthvert); varyingU [nthvert] = vt.x; varyingV [nthvert] = vt.y; } public static Vec2f CalcUV (Vec3f varU, Vec3f varV, Vec3f bar) { return new Vec2f { x = Dot (varU, bar), y = Dot (varV, bar) }; } public static Color GetColor (Image texture, Vec2f uvf) { var uvi = CalcXY(texture, uvf); return texture [uvi.x, uvi.y]; } public static Vec3f Transform (Matrix4 t, Vec3f v) { var v4d = Mult (t, Embed4D (v)); return Project3D (v4d); } public static Vec3f Normal (Image normalMap, Vec2f uvf) { // RGB values as xyz. But Color stores data as BGR (zyx) var c = GetColor (normalMap, uvf); return new Vec3f { x = (c [2] / 255f) * 2 - 1, y = (c [1] / 255f) * 2 - 1, z = (c [0] / 255f) * 2 - 1 }; } public static float Specular (Image specularMap, Vec2f uvf) { var uvi = CalcXY (specularMap, uvf); var color = specularMap [uvi.x, uvi.y]; return color[0]; } public static Vec2i CalcXY (Image texture, Vec2f uvf) { return new Vec2i { x = (int)(uvf.x * texture.Width), y = (int)(uvf.y * texture.Height) }; } } class TextureShader : IShader { readonly Model model; readonly Vec3f lightDir; readonly Matrix4 transformation; readonly Image texture; // written by vertex shader, read by fragment shader Vec3f varyingIntensity = new Vec3f (); Vec3f varyingU = new Vec3f (); Vec3f varyingV = new Vec3f (); public TextureShader (Model model, Matrix4 viewPort, Matrix4 projection, Matrix4 modelView, Vec3f lightDir, Image texture) { this.model = model; transformation = viewPort * projection * modelView; this.lightDir = lightDir.Normalize (); this.texture = texture; } public Vec4f Vertex (Face face, int nthvert) { UpdateVarayingUV (model, face, nthvert, ref varyingU, ref varyingV); var n = model.Normal (face, nthvert).Normalize (); varyingIntensity [nthvert] = Math.Max (0, Dot (n, lightDir)); // get diffuse lighting intensity return TransformFace (model, face, nthvert, transformation); } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { // interpolate intensity for the current pixel var intensity = Dot (varyingIntensity, bar); // interpolate uv for the current pixel var uvf = CalcUV (varyingU, varyingV, bar); color = GetColor (texture, uvf) * intensity; return false; } } ================================================ FILE: graphics/tiny-renderer/lesson8.workbook/lesson6.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Matrix.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" #load "lesson1.csx" #load "lesson2.csx" #load "lesson3.csx" #load "lesson4.csx" #load "lesson5.csx" using static Geometry; using static MatrixHelpers; ``` # **Lesson 6: Shaders for the software renderer** Refactoring the source code. IShader. ```csharp interface IShader { Vec4f Vertex (Face face, int nthvert); bool Fragment (Vec3f fragment, Vec3f bar, out Color color); }; class RenderResult { public Image Image { get; set; } public float [] ZBuffer { get; set; } } RenderResult Render (Model model, IShader shader) { var image = new Image (width, height, Format.BGR); var zbuffer = InitZBuffer (image); var screen_coords = new Vec4f [3]; foreach (var face in model.Faces) { for (int i = 0; i < 3; i++) screen_coords [i] = shader.Vertex (face, i); Triangle (image, screen_coords, shader, zbuffer); } return new RenderResult { Image = image, ZBuffer = zbuffer }; } void Box (Vec4f [] pts, out Vec2i pMin, out Vec2i pMax) { pMax = new Vec2i { x = int.MinValue, y = int.MinValue }; pMin = new Vec2i { x = int.MaxValue, y = int.MaxValue }; for (int i = 0; i < 3; i++) { pMax.x = (int)Math.Max (pMax.x, pts [i].x / pts [i].h); pMax.y = (int)Math.Max (pMax.y, pts [i].y / pts [i].h); pMin.x = (int)Math.Min (pMin.x, pts [i].x / pts [i].h); pMin.y = (int)Math.Min (pMin.y, pts [i].y / pts [i].h); } } void Triangle (Image image, Vec4f [] pts, IShader shader, float [] zbuffer) { Vec2i pMin, pMax; Box (pts, out pMin, out pMax); Color color; for (int x = pMin.x; x <= pMax.x; x++) { for (int y = pMin.y; y <= pMax.y; y++) { var pixelCenter = new Vec2f { x = x + 0.5f, y = y + 0.5f }; var bc = Barycentric (Project2D (pts [0] / pts [0].h), Project2D (pts [1] / pts [1].h), Project2D (pts [2] / pts [2].h), pixelCenter); var z = pts [0].z * bc.x + pts [1].z * bc.y + pts [2].z * bc.z; // z [0..255] var w = pts [0].h * bc.x + pts [1].h * bc.y + pts [2].h * bc.z; var frag_depth = z / w; var idx = x + y * image.Width; if (bc.x < 0 || bc.y < 0 || bc.z < 0 || zbuffer[idx] > frag_depth) continue; var fragment = new Vec3f { x = x, y = y, z = frag_depth }; var discard = shader.Fragment (fragment, bc, out color); if (!discard) { zbuffer [idx] = frag_depth; image [x, y] = color; } } } } ``` Let us see how it works. The actual render code: * Parsing the .obj file * Iteration through all triangles of the model and rasterization of each triangle. The last step is the most interesting. Outer loop iterates through all the triangles. Inner loop iterates through all the vertices of the current triangle and calls a vertex shader for each vertex. **The main goal of the vertex shader is to transform the coordinates of the vertices. The secondary goal is to prepare data for the fragment shader.** What happens after that? We call the rasterization routine. What happens inside the rasterizer we do not know (well, okay, we do know since we programmed it!) with one exception. We know that the rasterizer calls **our** routine for each pixel, namely, the fragment shader. Again, for each pixel inside the triangle the rasterizer calls our own callback, the fragment shader. **The main goal of the fragment shader - is to determine the color of the current pixel. Secondary goal - we can discard current pixel by returning true.** The rendering pipeline for the OpenGL 2 can be represented as follows (in fact, it is more or less the same for newer versions too): ![ ](./img/lesson6_opengl2_pipeline.png) Because of the time limits I have for my course, I restrict myself to the OpenGL 2 pipeline and therefore to fragment and vertex shaders only. In newer versions of OpenGL there are other shaders, allowing, for example, to generate geometry on the fly. Okay, in the above image all the stages we can not touch are shown in blue, whereas our callbacks are shown in orange. In fact, our render code - is the \*\*primitive processing \*\*routine. It calls the vertex shader. We do not have primitive assembly here, since we are drawing dumb triangles only (in our code it is merged with the primitive processing). `Triangle` function - is the **rasterizer**, for each point inside the triangle it calls the **fragment shader**, then performs depth checks (z-buffer) and such. That is all. You know what the shaders are and now you can create your own shaders. # **My implementation of shaders shown on Gouraud shading** According to its name, it is a Gouraud shader. Here is the code: ```csharp using static ShaderUtils; class GouraudShader : IShader { readonly Model model; readonly Vec3f lightDir; // written by vertex shader, read by fragment shader protected Vec3f varyingIntensity = new Vec3f (); readonly Matrix4 transformation; public GouraudShader (Model model, Matrix4 viewPort, Matrix4 projection, Matrix4 modelView, Vec3f lightDir) { this.model = model; transformation = viewPort * projection * modelView; this.lightDir = lightDir.Normalize (); } public virtual Vec4f Vertex (Face face, int nthvert) { var n = model.Normal (face, nthvert).Normalize (); // get diffuse lighting intensity varyingIntensity [nthvert] = Math.Max (0, Dot (n, lightDir)); var d = Dot(n, lightDir); return TransformFace (model, face, nthvert, transformation); } public virtual bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { // interpolate intensity for the current pixel var intensity = Dot (varyingIntensity, bar); color = Color.White * intensity; // well duh return false; } } // set of utils which will be used in our shaders static class ShaderUtils { public static Vec4f TransformFace (Model model, Face face, int nthvert, Matrix4 t) { var v = model.Vertex (face, nthvert); // read the vertex from model var glVertex = Embed4D (v); return Mult (t, glVertex); // transform it to screen coordinates } public static void UpdateVarayingUV (Model model, Face face, int nthvert, ref Vec3f varyingU, ref Vec3f varyingV) { var vt = model.GetUV (face, nthvert); varyingU [nthvert] = vt.x; varyingV [nthvert] = vt.y; } public static Vec2f CalcUV (Vec3f varU, Vec3f varV, Vec3f bar) { return new Vec2f { x = Dot (varU, bar), y = Dot (varV, bar) }; } public static Color GetColor (Image texture, Vec2f uvf) { var uvi = CalcXY(texture, uvf); return texture [uvi.x, uvi.y]; } public static Vec3f Transform (Matrix4 t, Vec3f v) { var v4d = Mult (t, Embed4D (v)); return Project3D (v4d); } public static Vec3f Normal (Image normalMap, Vec2f uvf) { // RGB values as xyz. But Color stores data as BGR (zyx) var c = GetColor (normalMap, uvf); return new Vec3f { x = (c [2] / 255f) * 2 - 1, y = (c [1] / 255f) * 2 - 1, z = (c [0] / 255f) * 2 - 1 }; } public static float Specular (Image specularMap, Vec2f uvf) { var uvi = CalcXY (specularMap, uvf); var color = specularMap [uvi.x, uvi.y]; return color[0]; } public static Vec2i CalcXY (Image texture, Vec2f uvf) { return new Vec2i { x = (int)(uvf.x * texture.Width), y = (int)(uvf.y * texture.Height) }; } } var light_dir = new Vec3f { x = 1, y = 1, z = 1 }; var eye = new Vec3f { x = 1, y = 1, z = 3 }; var center = new Vec3f { x = 0, y = 0, z = 0 }; var up = new Vec3f { x = 0, y = 1, z = 0 }; var modelView = LookAt(eye, center, up); var viewPort = Viewport(width/8, height/8, width*3/4, height*3/4); var projection = Projection(-1f/(eye-center).Norm()); var shader = new GouraudShader (headModel, viewPort, projection, modelView, light_dir); var image = Render (headModel, shader).Image; image.VerticalFlip(); image ``` **vayring** is a reserved keyword in GLSL language, I have used VaryingIntensity as a name in order to show the correspondence. In varying variables we store data to be interpolated inside the triangle, and the fragment shaders get the interpolated value (for the current pixel). Fragment routine is called for each pixel inside the triangle we draw; as an input it receives [barycentric coordinates](https://en.wikipedia.org/wiki/Barycentric_coordinate_system) for interpolation of VaryingXXX data. Thus, interpolated intensity can be computed as: VaryingIntensity\[0\]\*bar\[0\] \+ VaryingIntensity\[1\]\*bar\[1\] \+ VaryingIntensity\[2\]\*bar\[2\] or simply as a dot product between two vectors: `Dot(VaryingIntensity,bar)`. In true GLSL, of course, fragment shaders receive ready interpolated values. Notice that the shader returns a bool value. It is easy to understand what it does if we look inside the updated rasterizer: ```csharp /* ... var discard = shader.Fragment (fragment, bc, out color); if (!discard) { zbuffer [idx] = frag_depth; image [x, y] = color; } */ ``` Fragment shader can discard drawing of the current pixel, then the rasterizer simply skips it. It is handy if we want to create binary masks or whatever you want. Of course, the rasterizer can not imagine all the weird stuff you could program, therefore it can not be pre-compiled with your shader. Here we use IShader interface as an intermediate between the two. # **First modification of the shaders** Simple modification of the Gourad shading, where the intensities are allowed to have 6 values only: ```csharp class GouraudShader6 : GouraudShader { public GouraudShader6 (Model model, Matrix4 viewPort, Matrix4 projection, Matrix4 modelView, Vec3f lightDir) : base (model, viewPort, projection, modelView, lightDir) { } public override bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { var intensity = Dot (varyingIntensity, bar); if (intensity > 0.85f) intensity = 1; else if (intensity > 0.60f) intensity = 0.80f; else if (intensity > 0.45f) intensity = 0.60f; else if (intensity > 0.30f) intensity = 0.45f; else if (intensity > 0.15f) intensity = 0.30f; else intensity = 0; color = new Color (255, 155, 0) * intensity; return false; } } var shader = new GouraudShader6 (headModel, viewPort, projection, modelView, light_dir); var image = Render (headModel, shader).Image; image.VerticalFlip(); image ``` # **Textures** I'll skip the [Phong shading](https://en.wikipedia.org/wiki/Phong_shading), but take a look at the article. Remember the homework assignment I gave you for texturing? We had to interpolate uv-coordinates. ```csharp using static ShaderUtils; class TextureShader : IShader { readonly Model model; readonly Vec3f lightDir; readonly Matrix4 transformation; readonly Image texture; // written by vertex shader, read by fragment shader Vec3f varyingIntensity = new Vec3f (); Vec3f varyingU = new Vec3f (); Vec3f varyingV = new Vec3f (); public TextureShader (Model model, Matrix4 viewPort, Matrix4 projection, Matrix4 modelView, Vec3f lightDir, Image texture) { this.model = model; transformation = viewPort * projection * modelView; this.lightDir = lightDir.Normalize (); this.texture = texture; } public Vec4f Vertex (Face face, int nthvert) { UpdateVarayingUV (model, face, nthvert, ref varyingU, ref varyingV); var n = model.Normal (face, nthvert).Normalize (); varyingIntensity [nthvert] = Math.Max (0, Dot (n, lightDir)); // get diffuse lighting intensity return TransformFace (model, face, nthvert, transformation); } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { // interpolate intensity for the current pixel var intensity = Dot (varyingIntensity, bar); // interpolate uv for the current pixel var uvf = CalcUV (varyingU, varyingV, bar); color = GetColor (texture, uvf) * intensity; return false; } } var shader = new TextureShader (headModel, viewPort, projection, modelView, light_dir, headTexture); var image = Render (headModel, shader).Image; image.VerticalFlip(); image ``` # **Normalmapping** Okay, now we have texture coordinates. What can we store in texture images? In fact, almost anything. It can be color, directions, temperature and so on. Let us load this texture: ![ ](./img/lesson6_african_head_nm.png) If we interpret RGB values as xyz directions, this image gives us normal vectors **for each pixel** of our render and not only per vertex as before. By the way, compare this image to another one, it gives exactly the same information, but in another frame: ![ ](./img/lesson6_african_head_nm_tangent.png) One of the images gives normal vectors in global (Cartesian) coordinate system, another one in [Darboux frame](https://en.wikipedia.org/wiki/Darboux_frame) (so-called tangent space). In Darboux frame the z-vector is normal to the object, x - principal curvature direction and y - their cross product. **Exercise 1:** Can you tell which image is represented in Darboux frame and which one is in the global coordinate frame? **Exercise 2:** Can you tell which representation is better and if yes, why is that? **Uniform** is a reserved keyword in GLSL, it allows to pass constants to the shaders. Here I pass the matrix Projection\*ModelView and its inverse transpose to transform the normal vectors (refer to the end of the lesson5). So, computation of the lighting intensity is the same as before with one exception: instead of interpolating normal vectors we retrieve the information from the normal mapping texture (do not forget to transform light vector and normal vectors). ```csharp class NormalMapShader : IShader { Vec3f varyingU = new Vec3f (); Vec3f varyingV = new Vec3f (); readonly Model model; readonly Vec3f lightDir; readonly Matrix4 uniformM; readonly Matrix4 uniformMIT; readonly Matrix4 transformation; readonly Image texture; readonly Image normalMap; public NormalMapShader (Model model, Matrix4 viewport, Matrix4 projection, Matrix4 modelView, Vec3f lightDir, Image texture, Image normalMap) { this.model = model; this.lightDir = lightDir.Normalize (); this.texture = texture; this.normalMap = normalMap; uniformM = projection * modelView; uniformMIT = TransposeInverse (uniformM); transformation = viewport * uniformM; } public Vec4f Vertex (Face face, int nthvert) { UpdateVarayingUV (model, face, nthvert, ref varyingU, ref varyingV); return TransformFace (model, face, nthvert, transformation); } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { var uv = CalcUV (varyingU, varyingV, bar); var n = Transform (uniformMIT, Normal (normalMap, uv)).Normalize (); var l = Transform (uniformM, lightDir).Normalize (); var intensity = Math.Max (0f, Dot (n, l)); color = GetColor (texture, uv) * intensity; return false; } } var headNormalMap = Image.Load ("obj/african_head_nm.tga"); headNormalMap.VerticalFlip (); var shader = new NormalMapShader (headModel, viewPort, projection, modelView, light_dir, headTexture, headNormalMap); var image = Render (headModel, shader).Image; image.VerticalFlip(); image ``` # **Specular mapping** Okay, let us continue the fun. All the computer graphics science is the art to cheat. To (cheaply) trick the eye we use the [Phong's approximation](https://en.wikipedia.org/wiki/Phong_reflection_model) of the lighting model. Phong proposed to consider the final lighting as a (weighted) sum of three light intensities: ambient lighting (constant per scene), diffuse lighting (the one we computed up to this moment) and specular lighting. Take a look at the following image, it speaks for itself: ![ ](./img/lesson6_phong.png) We compute diffuse lighting as a cosine of the angle between the normal vector and the light direction vector. I mean, this supposes that the light is reflected in all directions uniformly. What happens to glossy surfaces? In the limit case (mirror) the pixel is illuminated if and only if we can see the light source reflected by this pixel: ![ ](./img/lesson6_reflection.png) For diffuse lighting we computed the (cosine of) angle between vectors **n** and **l**, and now we are interested in the (cosine of) angle between vectors **r** (reflected light direction) and **v**(view direction). **Exercise 3:** Given vectors **n** and **l**, find vector **r**. *Answer:* If **n** and **l** are normalized, then **r** = 2**n**<**n**,**l**> - **l** For diffused lighting we computed the light intensity as the cosine. But a glossy surface reflects in one direction much more than in others! Okay then, what happens if we take tenth power of the cosine? Recall that all numbers inferior to 1 will decrease when we apply the power. It means that tenth power of the cosine will give smaller radius of the reflected beam. And hundredth power **much** smaller beam radius. This power is stored in a special texture (specular mapping texture) that tells for each point if it is glossy or not.\ \ I think that i do not need to comment anything in the below code at the exception of coefficients: `5 + color [i] * (diff + 1.3f * specular)` I took 5 for the ambient component, 1 for the diffuse component and 1.3 for the specular component. What coefficients to choose - is your choice. Different choices give different appearances for the object. Normally it is for the artist to decide. *Please note that normally the sum of the coefficents must be equal to 1, but you know. I like to create light.* ```csharp class SpecularShader : IShader { Vec3f varyingU = new Vec3f (); Vec3f varyingV = new Vec3f (); readonly Model model; readonly Vec3f lightDir; readonly Matrix4 uniformM; readonly Matrix4 uniformMIT; readonly Matrix4 transformation; readonly Image texture; readonly Image normalMap; readonly Image specularMap; public SpecularShader (Model model, Matrix4 viewport, Matrix4 projection, Matrix4 modelView, Vec3f lightDir, Image texture, Image normalMap, Image specularMap) { this.model = model; this.lightDir = lightDir.Normalize (); this.texture = texture; this.normalMap = normalMap; this.specularMap = specularMap; uniformM = projection * modelView; uniformMIT = TransposeInverse (uniformM); transformation = viewport * uniformM; } public Vec4f Vertex (Face face, int nthvert) { UpdateVarayingUV (model, face, nthvert, ref varyingU, ref varyingV); return TransformFace (model, face, nthvert, transformation); } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { var uv = CalcUV (varyingU, varyingV, bar); var n = Transform (uniformMIT, Normal (normalMap, uv)).Normalize (); var l = Transform (uniformM, lightDir).Normalize (); var r = (n * (2 * Dot (n, l)) - l).Normalize (); var diff = Math.Max (0f, Dot (n, l)); var specular = Math.Pow (Math.Max (0f, r.z), Specular (specularMap, uv) + 15); color = GetColor (texture, uv); int v = 0; for (int i = 0; i < 4; i++) v = (v << 8) | (byte)Math.Min (255, (int)(5 + color [i] * (diff + 1.3f * specular))); color = new Color (v, color.format); return false; } } var headSpecularMap = Image.Load ("./obj/african_head_spec.tga"); var shader = new SpecularShader (headModel, viewPort, projection, modelView, light_dir, headTexture, headNormalMap, headSpecularMap); var image = Render (headModel, shader).Image; image.VerticalFlip(); image ``` ```csharp var diabloModel = Model.FromFile ("obj/diablo3_pose.obj"); var diabloTexture = Image.Load ("obj/diablo3_pose_diffuse.tga"); var diabloNormalMap = Image.Load ("obj/diablo3_pose_nm.tga"); var diabloTangentMap = Image.Load ("obj/diablo3_pose_nm_tangent.tga"); var diabloSpecularMap = Image.Load ("obj/diablo3_pose_spec.tga"); diabloTexture.VerticalFlip (); diabloNormalMap.VerticalFlip (); diabloTangentMap.VerticalFlip (); diabloSpecularMap.VerticalFlip (); var shader = new SpecularShader (diabloModel, viewPort, projection, modelView, light_dir, diabloTexture, diabloNormalMap, diabloSpecularMap); var image = Render (diabloModel, shader).Image; image.VerticalFlip(); image ``` # **Conclusion** We know how to render quite nice scenes, but our lighting is far from being real. In the next articles I will talk about shadows. Enjoy! ================================================ FILE: graphics/tiny-renderer/lesson8.workbook/lesson6bis.csx ================================================ using static Geometry; using static MatrixHelpers; using static ShaderUtils; class TangentShader : IShader { // triangle uv coordinates, written by the vertex shader, read by the fragment shader Vec3f varyingU = new Vec3f (); Vec3f varyingV = new Vec3f (); // normal per vertex to be interpolated by FS Matrix3 varyingNrm = new Matrix3 (); readonly Model model; readonly Vec3f lightDir; readonly Matrix4 uniformM; readonly Matrix4 uniformMIT; readonly Matrix4 transformation; readonly Vec3f[] ndcTri = new Vec3f[3]; // triangle in normalized device coordinates readonly Image texture; readonly Image normalMap; public TangentShader (Model model, Matrix4 viewport, Matrix4 projection, Matrix4 modelView, Vec3f lightDir, Image texture, Image normalMap) { this.model = model; this.lightDir = lightDir.Normalize (); this.texture = texture; this.normalMap = normalMap; uniformM = projection * modelView; uniformMIT = TransposeInverse (uniformM); transformation = viewport * uniformM; } public Vec4f Vertex (Face face, int nthvert) { UpdateVarayingUV (model, face, nthvert, ref varyingU, ref varyingV); var normal = Project3D (Mult (uniformMIT, Embed4D (model.Normal (face, nthvert)))); varyingNrm.SetColumn (nthvert, normal); var glVertex = TransformFace (model, face, nthvert, transformation); ndcTri[nthvert] = Project3D (glVertex / glVertex.h); return glVertex; } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { var bn = Mult(varyingNrm, bar).Normalize (); var uv = CalcUV (varyingU, varyingV, bar); var A = new Matrix3 (); A.SetRow (0, ndcTri [1] - ndcTri [0]); A.SetRow (1, ndcTri [2] - ndcTri [0]); A.SetRow (2, bn); var AI = Inverse (A); var i = Mult (AI, new Vec3f { x = varyingU.y - varyingU.x, y = varyingU.z - varyingU.x }); var j = Mult (AI, new Vec3f { x = varyingV.y - varyingV.x, y = varyingV.z - varyingV.x }); var B = new Matrix3 (); B.SetColumn (0, i.Normalize ()); B.SetColumn (1, j.Normalize ()); B.SetColumn (2, bn); var n = Mult (B, Normal (normalMap, uv)).Normalize (); var l = Transform (uniformM, lightDir).Normalize (); var diff = Math.Max (0f, Dot (n, l)); color = GetColor (texture, uv) * diff; return false; } } ================================================ FILE: graphics/tiny-renderer/lesson8.workbook/lesson6bis.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Matrix.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" #load "lesson1.csx" #load "lesson2.csx" #load "lesson3.csx" #load "lesson4.csx" #load "lesson5.csx" #load "lesson6.csx" using static Geometry; using static MatrixHelpers; using static ShaderUtils; ``` # Lesson 6bis: tangent space normal mapping The subject for today is [normal mapping](https://en.wikipedia.org/wiki/Normal_mapping). What is the main difference between normal mapping and Phong shading? The key is the density of information we have. For Phong shading we use normal vectors given per vertex of triangle mesh (and interpolate it inside triangles), whereas normal mapping textures provide dense information, dramatically improving rendering details. Well, we have already applied normal mapping in previous lesson, however we used the global system of coordinates to store the texture. Today we are talking about [tangent space](https://en.wikipedia.org/wiki/Darboux_frame) normal mapping. So, we have two textures, the left one is given in the global frame (direct transformation from RGB to XYZ normal), whereas the right one in the Darboux frame: ![](./img/lesson6bis_nm.jpg) To use right texture, for each pixel we draw we compute tangent space (Darboux) frame. In this basis one vector (usually z) is orthogonal to our surface, and two others give a plane tangent to the current point. Then we read a (perturbed) normal vector from our texture, transform its coordinates from Darboux frame to the global system coordinates and we are done. Usually normal maps provide small perturbations of normal vectors, thus textures are in dominant blue color. Well, why such a mess? Why not to use global system as we did before? Imagine we want to animate our model. For example, I took the black guy model and opened his mouth. It is obvious that normal vectors are to be modified. ![ ](./img/lesson6bis_mouth.jpg) Left image gives the head with open mouth, but unchanged (global frame) normal texture. Inspect closely the interior of the lower lip. The light coming directly to his face; when the mouth was closed the backside of the lower lip naturally was not lit. Now the mouth is open, but the lip is not lit... The right image was computed with tangent space normal mapping. Therefore, if we have an animated model, then for correct normal mapping in global frame we need to have one texture per frame of the animation, whereas tangent space deforms accordingly to the model and we need one texture only! Here is another example: ![ ](./img/global_vs_tangent_diablo.jpg) These are textures for the Diablo model. Notice that only one hand is drawn in the texture, and only one side of the tail. The artist used the same texture for both arms and for both sides of the tail. It means that in the global coordinate system I can provide normal vectors either for the left side of the tail, either for the right one, but not for both! Same goes for the arms. And I need different information for the left and the right sides, for example, inspect left and right cheekbones in the left image, naturally normal vectors are pointing in the opposite directions! Let us finish with the motivation section and go straight ahead to the computations. # **Starting point, Phong shading** Okay, here is the starting point. The shader is really simple, it is Phong shading. ```csharp class TangentShader : IShader { // triangle uv coordinates, written by the vertex shader, read by the fragment shader Vec3f varyingU = new Vec3f (); Vec3f varyingV = new Vec3f (); // normal per vertex to be interpolated by FS Matrix3 varyingNrm = new Matrix3 (); readonly Model model; readonly Vec3f lightDir; readonly Matrix4 uniformM; readonly Matrix4 uniformMIT; readonly Matrix4 transformation; readonly Image texture; public TangentShader (Model model, Matrix4 viewport, Matrix4 projection, Matrix4 modelView, Vec3f lightDir, Image texture) { this.model = model; this.lightDir = lightDir.Normalize (); this.texture = texture; uniformM = projection * modelView; uniformMIT = TransposeInverse (uniformM); transformation = viewport * uniformM; } public Vec4f Vertex (Face face, int nthvert) { UpdateVarayingUV (model, face, nthvert, ref varyingU, ref varyingV); var normal = Project3D (Mult (uniformMIT, Embed4D (model.Normal (face, nthvert)))); varyingNrm.SetColumn (nthvert, normal); var glVertex = TransformFace (model, face, nthvert, transformation); return glVertex; } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { Vec3f bn = Mult(varyingNrm, bar).Normalize (); var uv = CalcUV (varyingU, varyingV, bar); Vec3f l = Transform (uniformM, lightDir).Normalize (); var diff = Math.Max (0f, Dot (bn, l)); color = GetColor (texture, uv); color *= diff; return false; } } var shader = new TangentShader (headModel, viewPort, projection, modelView, light_dir, headTexture); var image = Render (headModel, shader).Image; image.VerticalFlip(); image ``` For the educational and debugging purposes I am removing the skin texture and apply a regular grid with horizontal red and vertical blue lines: ```csharp var gridTexture = Image.Load ("obj/grid.tga"); var shader = new TangentShader (headModel, viewPort, projection, modelView, light_dir, gridTexture); var image = Render (headModel, shader).Image; image.VerticalFlip(); image ``` Let us remember how Phong shading works: ![ ](./img/lesson6bis_triangle.png) For each vertex of a triangle we have its coordinates p, texture coordinates uv and normal vectors. For shading current fragment our software rasterizer gives us barycentric coordinates of the fragment (alpha, beta, gamma). It means that the coordinates of the fragment can be obtained as p = alpha p0 \+ beta p1 \+ gamma p2. Then in the same way we interpolate texture coordinates and the normal vector: ![ ](./img/lesson6bis_f00.png) Notice that blue and red lines are isolines of u and v, correspondingly. So, for each point of our surface we define a so-called Darboux frame, with x and y axes parallel to blue and red lines, and z axis orthogonal to the surface. This is the frame where tangent space normal map lives. # **How to reconstruct a (3D) linear function from three samples** Okay, so our goal is to compute three vectors (tangent basis) for each pixel we draw. Let us put that aside for a while and imagine a linear function f that for each point (x,y,z) gives a real number f(x,y,z) = Ax \+ By \+ Cz \+ D. The only problem that we do not know A, B, C and D, however we do know three values of the function at three different points of the space (p0, p1, p2): ![ ](./img/lesson6bis_f01.png) ![ ](./img/lesson6bis_gradient_a.png) It is convenient to imagine f as a height map of an inclined plane. We fix three different (non collinear) points on the plane and we know values of f in those points. Red lines inside the triangle show the iso-heights f0, f0 \+ 1 meter, f0 \+ 2 meters and so on. For a linear function we have the isolines are parallel (straight) lines. In fact, I am more interested in the direction, orthogonal to the isolines. If we move along an iso, the height does not change (well duh, it is an iso!). If we deviate a little bit from an iso, the height starts to change a little bit. The steepest ascent we obtain when we move orthogonally to the isolines. Let us recall that the steepest ascent direction for a function is nothing else than its [gradient](https://en.wikipedia.org/wiki/Gradient). For a linear function f(x,y,z) = Ax \+ By \+ Cz \+ D its gradient is a constant vector (A, B, C). Recall that we do not know the values of (A,B,C). We know only three samples of the function. Can we reconstruct A,B and C? Sure thing. So, we have three points p0, p1, p2 and thre values f0, f1, f2. We need to find the vector of the steepest ascent (A,B,C). Let us consider another function defined as g(p) = f(p) - f(p0): ![ ](./img/lesson6bis_gradient_b.png) Obviously that we simply translated our inclined plane, without changing its inclination, therefore the steepest ascent direction for f and g is the same. Let us rewrite the definition of g: ![ ](./img/lesson6bis_f02.png) Please note that superscript x in p^x means x coordinate of the point p and not a power. So, the function g is simply a dot product between vector (p-p0) and (ABC). And we still do not know (A,B,C)! Okay, let us recall what we know. We know that if we go from point p0 to point p2, then the function g will go from zero to f2-f0. In other words, the dot product between vectors (p2-p0) and (ABC) is equal to f2-f0. Same thing for (p1-p0). Therefore, we are looking for the vector ABC, orthogonal to the normal n and respecting two constraints on dot products: ![ ](./img/lesson6bis_f03.png) Let us rewrite this in a matrix form: ![ ](./img/lesson6bis_f04.png) So, we got an easy to solve linear matrix equation Ax = b: ![ ](./img/lesson6bis_f05.png) Please note that I used the letter A for two different things, the meaning should be clear from the context. So, our 3x3 matrix A, multiplied with the unknown vector x=(A,B,C), gives the vector b = (f1-f0, f2-f0, 0). Unknown vector x becomes known when we multiply inverse to A by b. Also note that in the matrix A we have nothing related to the function f. It contains only some information about our triangle. # **Let us compute Darboux basis and apply the perturbation of normals** So, Darboux basis is a triplet of vectors (i,j,n), where n - is the original normal vector, and i, j can be computed as follows: ![ ](./img/lesson6bis_f06.png) Using the normal maps in the tangent space. ```csharp class TangentShader : IShader { // triangle uv coordinates, written by the vertex shader, read by the fragment shader Vec3f varyingU = new Vec3f (); Vec3f varyingV = new Vec3f (); // normal per vertex to be interpolated by FS Matrix3 varyingNrm = new Matrix3 (); readonly Model model; readonly Vec3f lightDir; readonly Matrix4 uniformM; readonly Matrix4 uniformMIT; readonly Matrix4 transformation; readonly Vec3f[] ndcTri = new Vec3f[3]; // triangle in normalized device coordinates readonly Image texture; readonly Image normalMap; public TangentShader (Model model, Matrix4 viewport, Matrix4 projection, Matrix4 modelView, Vec3f lightDir, Image texture, Image normalMap) { this.model = model; this.lightDir = lightDir.Normalize (); this.texture = texture; this.normalMap = normalMap; uniformM = projection * modelView; uniformMIT = TransposeInverse (uniformM); transformation = viewport * uniformM; } public Vec4f Vertex (Face face, int nthvert) { UpdateVarayingUV (model, face, nthvert, ref varyingU, ref varyingV); var normal = Project3D (Mult (uniformMIT, Embed4D (model.Normal (face, nthvert)))); varyingNrm.SetColumn (nthvert, normal); var glVertex = TransformFace (model, face, nthvert, transformation); ndcTri[nthvert] = Project3D (glVertex / glVertex.h); return glVertex; } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { var bn = Mult(varyingNrm, bar).Normalize (); var uv = CalcUV (varyingU, varyingV, bar); var A = new Matrix3 (); A.SetRow (0, ndcTri [1] - ndcTri [0]); A.SetRow (1, ndcTri [2] - ndcTri [0]); A.SetRow (2, bn); var AI = Inverse (A); var i = Mult (AI, new Vec3f { x = varyingU.y - varyingU.x, y = varyingU.z - varyingU.x }); var j = Mult (AI, new Vec3f { x = varyingV.y - varyingV.x, y = varyingV.z - varyingV.x }); var B = new Matrix3 (); B.SetColumn (0, i.Normalize ()); B.SetColumn (1, j.Normalize ()); B.SetColumn (2, bn); var n = Mult (B, Normal (normalMap, uv)).Normalize (); var l = Transform (uniformM, lightDir).Normalize (); var diff = Math.Max (0f, Dot (n, l)); color = GetColor (texture, uv) * diff; return false; } } ``` All is quite straightforward, I compute the matrix A: ```csharp // var A = new Matrix3 (); // A.SetRow (0, ndcTri [1] - ndcTri [0]); // A.SetRow (1, ndcTri [2] - ndcTri [0]); // A.SetRow (2, bn); ``` Then compute two unknown vectors (i,j) of Darboux basis: ```csharp // var AI = Inverse (A); // var i = Mult (AI, new Vec3f { x = varyingU.y - varyingU.x, y = varyingU.z - varyingU.x }); // var j = Mult (AI, new Vec3f { x = varyingV.y - varyingV.x, y = varyingV.z - varyingV.x }); ``` Once we have all the tangent basis, I read the perturbed normal from the texture and apply the basis change from the tangent basis to the global coordinates. Recall that I have already described how to perform change of basis. Here is the final rendered image, compare the details with Phong shading: ```csharp var headTangentMap = Image.Load ("obj/african_head_nm_tangent.tga"); headTangentMap.VerticalFlip (); var shader = new TangentShader (headModel, viewPort, projection, modelView, light_dir, headTexture, headTangentMap); var image = Render (headModel, shader).Image; image.VerticalFlip(); image ``` # **Were you paying attention?** Have you noticed that generally a (flat) triangle has a constant normal vector, whereas I used the interpolated normal in the last row of the matrix A? Why did I do it? Happy coding! ================================================ FILE: graphics/tiny-renderer/lesson8.workbook/lesson7.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacNet45 - WPF --- ```csharp #load "Geometry.csx" #load "Matrix.csx" #load "Image.csx" #load "Model.csx" #load "ImageResultHandler.csx" #load "lesson1.csx" #load "lesson2.csx" #load "lesson3.csx" #load "lesson4.csx" #load "lesson5.csx" #load "lesson6.csx" #load "lesson6bis.csx" using static Geometry; using static MatrixHelpers; using static ShaderUtils; ``` # Lesson 7: Shadow mapping # **The goal** Well, we are approaching the end of your short course of CG lectures. The goal for today is to compute shadows. **Attention, we are talking about hard shadows here, soft shadows computation is another story.** # **Problem statement** Up to this moment convex objects were shaded correctly by our simple local shading. Local means computation with light direction and the normal vector. Unfortunately, it does not produce correct results for non-convex objects. Here is the image we can got during previous lesson: ```csharp var shader = new TangentShader (diabloModel, viewPort, projection, modelView, light_dir, diabloTexture, diabloTangentMap); var image = Render (diabloModel, shader).Image; image.VerticalFlip(); image ``` Why do not we see a shadow from his horns? Not good. The idea is really simple: we will do a two-pass rendering. First time we will render the image placing the camera at the light source position. It will allow to determine what parts are lit and what parts are hidden from the light. Then in the second pass we do a render taking in account the visibility information. Almost no difficulties here. Let us use this shader: ```csharp class DepthShader : IShader { const float depth = 255f; Matrix3 varyingTri; readonly Model model; readonly Matrix4 transformation; public DepthShader (Model model, Matrix4 transformation) { this.model = model; this.transformation = transformation; } public Vec4f Vertex (Face face, int nthvert) { var glVertex = TransformFace (model, face, nthvert, transformation); varyingTri.SetColumn (nthvert, Project3D (glVertex / glVertex.h)); return glVertex; } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { var p = Mult (varyingTri, bar); color = Color.White * (p.z / depth); return false; } } ``` This shader simply copies the z-buffer into the framebuffer. Here is how it I call it: ```csharp var model = diabloModel; var modelView = LookAt (eye, center, up); var viewPort = Viewport (width / 8, height / 8, width * 3 / 4, height * 3 / 4); var projection = Projection (-1f / (eye - center).Norm ()); var M = viewPort * Projection (0) * LookAt (light_dir, center, up); var depthShader = new DepthShader (model, M); var step1 = Render (model, depthShader); step1.Image.VerticalFlip (); step1.Image ``` I put the camera at the light source position LookAt (light_dir, center, up) and then perform the render. Note that I keep the z-buffer, it is pointed by the **step1.ZBuffer** reference. Also it is useful to note line where I keep the object-to-screen transformation matrix. The second pass is naturally made with another shader: ```csharp class ShadowShader : IShader { Vec3f varyingU = new Vec3f (); Vec3f varyingV = new Vec3f (); Matrix3 varyingTri; readonly Model model; readonly Vec3f lightDir; readonly Matrix4 uniformM; readonly Matrix4 uniformMIT; // transform framebuffer screen coordinates to shadowbuffer screen coordinates readonly Matrix4 uniformShadow; readonly Matrix4 transformation; readonly Image texture; readonly Image normalMap; readonly Image specularMap; readonly float[] shadowbuffer; readonly int width; public ShadowShader (Model model, Matrix4 viewport, Matrix4 projection, Matrix4 modelView, Matrix4 uniformShadow, Vec3f lightDir, Image texture, Image normalMap, Image specularMap, float[] shadowbuffer, int width) { this.model = model; this.lightDir = lightDir.Normalize (); this.texture = texture; this.normalMap = normalMap; this.specularMap = specularMap; this.shadowbuffer = shadowbuffer; this.width = width; uniformM = projection * modelView; uniformMIT = TransposeInverse (uniformM); transformation = viewport * uniformM; this.uniformShadow = uniformShadow; } public Vec4f Vertex (Face face, int nthvert) { UpdateVarayingUV (model, face, nthvert, ref varyingU, ref varyingV); var glVertex = TransformFace (model, face, nthvert, transformation); varyingTri.SetColumn (nthvert, Project3D (glVertex / glVertex.h)); return glVertex; } public bool Fragment (Vec3f fragment, Vec3f bar, out Color color) { // corresponding point in the shadow buffer var sb_p = Mult (uniformShadow, Embed4D (Mult (varyingTri, bar))); sb_p = sb_p / sb_p.h; int idx = (int)sb_p.x + (int)sb_p.y * width; // index in the shadowbuffer array float shadow = 0.3f + 0.7f * (shadowbuffer [idx] < sb_p.z + 3.5f ? 1f : 0f); var uv = CalcUV (varyingU, varyingV, bar); var n = Transform (uniformMIT, Normal (normalMap, uv)).Normalize (); var l = Transform (uniformM, lightDir).Normalize (); var r = (n * (2 * Dot (n, l)) - l).Normalize (); var diff = Math.Max (0f, Dot (n, l)); var specular = Math.Pow (Math.Max (0f, r.z), Specular (specularMap, uv) + 15); color = GetColor (texture, uv); int v = 0; for (int i = 0; i < 4; i++) v = (v <<= 8) | (byte)Math.Min (255, (int)(5 + color [i] * shadow * (diff + 1.3f * specular))); color = new Color (v, color.format); return false; } } ``` It is a copy of the final shader from the previous lesson with one exception: I declared a constant matrix `Matrix4 uniformShadow`, it allows me to transform screen coordinates of current fragment into screen coordinates inside the shadowbuffer! I'll explain how it is computed a bit later, let us see how I use it: ```csharp /* var sb_p = Mult (uniformShadow, Embed4D (Mult (varyingTri, bar))); sb_p = sb_p / sb_p.h; int idx = (int)sb_p.x + (int)sb_p.y * width; // index in the shadowbuffer array var depth = 255 * shadowbuffer [idx]; float shadow = 0.3f + 0.7f * ((depth < sb_p.z ? 1f : 0f)); */ ``` `Mult (varyingTri, bar)` provides me screen coordinates of the pixel we currently draw; we augment it with 1 (recall the homogeneous coordinates stuff), then transform it with the magic matrix `uniformShadow` and ta-da! We know xyz coordinates in the shadow buffer space. Now to determine whether the current pixel is lit or no it suffices to compare its z-coordinate with the value we stored in the shadow buffer. Let me show you how I call the shader: ```csharp var shadowM = M * Inverse (viewPort * projection * modelView); var shader = new ShadowShader (model, viewPort, projection, modelView, shadowM, light_dir, diabloTexture, diabloNormalMap, diabloSpecularMap, step1.ZBuffer, width); var step2 = Render (model, shader); step2.Image.VerticalFlip (); step2.Image ``` Notice the `sb_p.z + 3.5` in fragment shader? This magic coefficient needed to get rig of artifact is known as the [z-fighting](http://en.wikipedia.org/wiki/Z-fighting). Resolution of our buffers is insufficient to obtain precise results. Try to delete `+ 3.5f` and you will notice ugly shadow rendering. I simply move a bit one z-buffer with respect to another, it is sufficient to remove the artifact. Yes, it creates other problems (can you tell which ones?), but those are generally less visible. The final render is visible in the teaser image. ================================================ FILE: graphics/tiny-renderer/lesson8.workbook/obj/diablo3_pose.obj ================================================ v 0.11526 0.700717 0.0677257 v 0.114223 0.654606 0.0821706 v 0.119952 0.67202 0.101202 v 0.12069 0.712368 0.0932415 v 0.120409 0.670105 0.118388 v 0.103434 0.63749 0.102854 v 0.0998313 0.642305 0.121165 v 0.113204 0.661161 0.119513 v 0.110674 0.71474 0.118248 v 0.114329 0.673286 0.128141 v 0.0938038 0.672987 0.125628 v 0.0910976 0.702896 0.120497 v 0.107546 0.664288 0.12793 v 0.116526 0.652831 0.0186975 v 0.122606 0.631867 0.0339156 v 0.123238 0.584561 0.0390644 v 0.113679 0.582153 0.0698344 v 0.107247 0.593611 0.124012 v 0.099392 0.618107 0.132025 v 0.0519629 0.664482 0.148508 v 0.056813 0.67065 0.139722 v 0.0671458 0.660001 0.134186 v 0.0799037 0.658226 0.13039 v 0.0872667 0.645679 0.131726 v 0.0690261 0.645978 0.151671 v 0.0731557 0.627719 0.151074 v 0.0524549 0.654325 0.16232 v 0.0402945 0.655625 0.166186 v 0.0399431 0.667873 0.157259 v 0.0514006 0.648069 0.163058 v 0.0395565 0.644343 0.164429 v 0.0403297 0.634327 0.163322 v 0.048132 0.610076 0.154571 v 0.021597 0.677468 0.15559 v 0.0424033 0.672267 0.161494 v 0.0551611 0.669385 0.152479 v 0.0324219 0.694391 0.157312 v 0.0500123 0.692264 0.158015 v 0.0621024 0.681106 0.149088 v 0.042087 0.725178 0.149141 v 0.0617158 0.711489 0.15088 v 0.0706604 0.695445 0.133782 v 0.0129512 0.710365 0.135873 v 0.0267634 0.736074 0.134696 v 0.0996029 0.759463 0.122043 v 0.127526 0.758813 0.113749 v 0.0634907 0.787228 0.117404 v 0.0781113 0.602994 0.15624 v 0.0661442 0.626208 0.15269 v 0.0892525 0.572418 0.146698 v 0.0501705 0.601641 0.155028 v 0.0637543 0.593944 0.162443 v 0.0649668 0.641321 0.158156 v 0.0678663 0.629969 0.156521 v 0.0497663 0.643588 0.152233 v 0.0475697 0.626384 0.148209 v 0.0605209 0.610199 0.15566 v 0.0599761 0.626419 0.15429 v 0.0643869 0.628457 0.153182 v 0.0578146 0.640741 0.152849 v 0.0813095 0.813025 0.103117 v 0.135047 0.790409 0.0950163 v 0.116789 0.817945 0.0520332 v 0.0892876 0.821565 0.0596598 v 0.0257091 0.775507 0.125488 v 0.0636313 0.679507 0.139194 v 0.0781289 0.671792 0.13872 v 0.0878993 0.595034 0.00293464 v 0.116772 0.566636 0.0537026 v 0.114417 0.562155 0.0744385 v 0.128176 0.558166 0.0246547 v 0.107194 0.567445 0.09651 v 0.0944716 0.545496 0.110902 v 0.0712403 0.535304 0.117264 v 0.112431 0.54474 0.087214 v 0.0971602 0.533775 0.0882684 v 0.0731382 0.524128 0.0962816 v 0.106368 0.520964 0.0665483 v 0.099392 0.514164 0.0756159 v 0.0780586 0.512283 0.0791129 v 0.1141 0.533037 0.0671107 v 0.115436 0.533582 0.0411731 v 0.115752 0.527449 0.0417179 v 0.114469 0.546304 0.0516993 v 0.102151 0.525076 0.0562506 v 0.0970021 0.503198 0.0402242 v 0.100605 0.498208 0.054177 v 0.0863529 0.491407 0.0541595 v 0.0949988 0.486943 0.0309282 v 0.0732963 0.583559 0.000140556 v 0.0795522 0.555653 0.0176783 v 0.0874073 0.557569 0.0307173 v 0.0843848 0.502601 0.03439 v 0.0989175 0.529927 0.0420342 v 0.0913612 0.482164 0.025094 v 0.0906759 0.48197 0.0349172 v 0.00242505 0.842706 0.085773 v -0.0105613 0.872456 0.0789021 v -0.0279935 0.869416 0.0666186 v -0.0107546 0.825273 0.0714863 v -0.00999895 0.80039 0.118951 v -0.0275542 0.855217 0.105806 v 0.00233719 0.823744 0.11222 v -0.0122131 0.863705 0.0988999 v -0.039451 0.902576 0.0606087 v -0.00137068 0.808351 0.0664078 v 0.0207008 0.806207 0.0844902 v 0.0138474 0.77795 0.120374 v -0.00152884 0.759691 0.126718 v -0.0331072 0.875532 0.0913612 v 0.0211577 0.79605 0.104594 v -0.226707 -0.278811 0.0844199 v -0.164271 -0.310688 0.0763188 v -0.190121 -0.154536 0.0547394 v -0.115682 -0.174358 0.0460584 v -0.102748 -0.13025 0.0384494 v -0.268074 -0.269339 0.0650371 v -0.243946 -0.149703 0.0212455 v -0.189084 -0.00231963 -0.0608723 v -0.259147 -0.376006 0.0909394 v -0.140495 -0.0527185 0.0225987 v -0.164921 -0.01086 -0.00980567 v -0.129125 -0.0841915 0.0319474 v -0.116754 -0.0240045 0.0389238 v -0.120655 -0.0525252 0.0430183 v -0.0982849 -0.162391 0.0430007 v -0.203775 -0.406776 0.0984782 v -0.145872 -0.436597 0.059484 v -0.112062 -0.35411 0.0492742 v -0.237813 -0.446297 0.116033 v -0.20511 -0.499332 0.0841563 v -0.272291 -0.426932 0.106158 v -0.270692 -0.459635 0.163568 v -0.233912 -0.504639 0.102661 v -0.283362 -0.512406 0.0865638 v -0.252293 -0.489931 0.130584 v -0.29858 -0.454451 0.1128 v -0.291674 -0.453854 0.139897 v -0.284153 -0.488068 0.128897 v -0.294415 -0.476822 0.0981619 v -0.302639 -0.443292 0.0965276 v -0.311004 -0.454768 0.12489 v -0.320423 -0.453836 0.0878993 v -0.311865 -0.403683 0.0613995 v -0.328718 -0.434137 0.0385899 v -0.328278 -0.278442 -0.00706431 v -0.321495 -0.34311 0.0478333 v -0.297754 -0.253506 -0.137736 v -0.214301 -0.520314 0.0970899 v -0.231346 -0.516958 0.105876 v -0.24356 -0.52411 0.101887 v -0.222419 -0.53743 0.100727 v -0.238007 -0.537219 0.100323 v -0.233315 -0.527818 0.121288 v -0.226268 -0.536639 0.0605033 v -0.180209 -0.502091 0.0646329 v -0.2563 -0.52404 0.0890767 v -0.278617 -0.532422 0.106368 v -0.24739 -0.547007 0.0609426 v -0.272256 -0.556567 0.0515938 v -0.237128 -0.554546 -0.0027238 v -0.329438 -0.473131 0.0214564 v -0.328981 -0.486733 0.0608371 v -0.307384 -0.510948 0.0583242 v -0.214266 -0.520806 0.0641936 v -0.209187 -0.532686 0.0775489 v -0.210118 -0.541472 0.0516817 v -0.18448 -0.526307 0.0144449 v -0.202369 -0.52469 0.046691 v -0.13995 -0.494078 -0.0121604 v -0.076477 -0.16464 -0.246828 v -0.215215 -0.18578 -0.218676 v -0.177468 -0.0685341 -0.2912 v -0.300513 -0.164886 -0.0611535 v -0.328489 -0.511264 -0.0174498 v -0.32754 -0.511071 0.0356377 v -0.294732 -0.547429 -0.00166944 v -0.313974 -0.486012 0.0562506 v -0.113872 -0.083102 0.0324922 v -0.0877061 -0.1322 0.0504868 v -0.0748427 -0.168576 0.02896 v -0.0878115 -0.13336 0.0293466 v -0.106439 -0.0435104 0.0336695 v -0.100411 -0.0729097 0.019664 v -0.0763716 -0.204442 0.0280814 v -0.155678 -0.252803 -0.213914 v -0.270464 -0.298615 -0.174779 v -0.227252 -0.0342143 -0.120321 v -0.229097 -0.0836292 -0.207834 v -0.0959301 -0.172671 -0.22314 v -0.18571 -0.119987 -0.24421 v -0.0694303 -0.201104 0.043317 v -0.0647911 -0.227656 0.0175025 v -0.0861948 -0.217271 0.0386778 v -0.0703792 -0.219379 0.0386251 v -0.099515 -0.241258 0.0468492 v -0.0809229 -0.241837 0.0346185 v -0.361825 -0.347046 -0.0517169 v -0.356465 -0.383352 0.0123713 v -0.365041 -0.413717 -0.0374302 v -0.198011 -0.343672 -0.195164 v -0.222542 -0.382104 -0.170984 v -0.0891119 -0.308386 -0.115946 v -0.0247777 -0.200436 -0.16942 v -0.122096 -0.400907 -0.110357 v -0.0774611 -0.32262 -0.0285383 v -0.0899027 -0.36237 -0.0259375 v -0.0697642 -0.274013 0.00676553 v -0.126085 -0.453625 -0.0196289 v -0.150986 -0.459249 -0.0810108 v -0.343496 -0.37142 -0.228429 v -0.232489 -0.383334 -0.251801 v -0.17195 -0.413577 -0.222964 v -0.319439 -0.410818 -0.323955 v -0.242874 -0.411029 -0.323674 v -0.300373 -0.419147 -0.372492 v -0.241398 -0.423136 -0.377693 v -0.280023 -0.359242 -0.238586 v -0.336608 -0.363635 -0.116596 v -0.341528 -0.467894 -0.310635 v -0.376516 -0.419341 -0.17 v -0.34021 -0.470987 -0.359734 v -0.356922 -0.494693 -0.23154 v -0.3678 -0.432415 -0.235687 v -0.3691 -0.469423 -0.118248 v -0.337117 -0.518838 -0.136945 v -0.268197 -0.578551 -0.134977 v -0.192633 -0.538994 -0.0549854 v -0.157927 -0.511422 -0.0755105 v -0.170052 -0.525604 -0.152884 v -0.146153 -0.481074 -0.182283 v -0.185956 -0.440973 -0.312691 v -0.281376 -0.36418 -0.154307 v -0.159315 -0.374846 -0.160071 v -0.177029 -0.419499 -0.142814 v -0.207623 -0.455523 -0.380628 v -0.20019 -0.524444 -0.379503 v -0.332267 -0.533529 -0.224792 v -0.27563 -0.574175 -0.229923 v -0.175816 -0.507697 -0.257214 v -0.293695 -0.535023 0.0562506 v -0.0170808 -0.191808 -0.0932415 v -0.0249886 -0.115858 -0.00550031 v -0.0118968 -0.173286 -0.0372369 v -0.216093 -0.549345 -0.141426 v -0.23291 -0.571153 -0.356694 v -0.211893 -0.551805 -0.242365 v -0.213334 -0.49464 -0.477524 v -0.24196 -0.540681 -0.524602 v -0.222824 -0.433786 -0.46568 v -0.322303 -0.541771 -0.514656 v -0.347767 -0.520121 -0.487664 v -0.280392 -0.547306 -0.527994 v -0.286262 -0.580027 -0.331002 v -0.335676 -0.543387 -0.345904 v -0.371261 -0.533406 -0.419358 v -0.324289 -0.469845 -0.50427 v -0.359347 -0.47343 -0.451956 v -0.242259 -0.468843 -0.513584 v -0.328155 -0.438284 -0.464064 v -0.274066 -0.472727 -0.520121 v -0.268636 -0.418778 -0.47336 v -0.26405 -0.676959 -0.365744 v -0.223509 -0.587302 -0.461551 v -0.229431 -0.689242 -0.390381 v -0.217798 -0.629336 -0.456683 v -0.244421 -0.666872 -0.48132 v -0.27078 -0.728043 -0.425509 v -0.283204 -0.679841 -0.483376 v -0.276843 -0.784821 -0.410097 v -0.244755 -0.72734 -0.414403 v -0.238868 -0.781991 -0.378519 v -0.24739 -0.767353 -0.363354 v -0.241451 -0.720768 -0.382596 v -0.268583 -0.7146 -0.363898 v -0.251221 -0.79851 -0.377096 v -0.273469 -0.798422 -0.39191 v -0.263188 -0.827716 -0.377482 v -0.25326 -0.811514 -0.363354 v -0.282466 -0.829192 -0.392033 v -0.274997 -0.828366 -0.372615 v -0.275489 -0.81487 -0.357748 v -0.239852 -0.749868 -0.402822 v -0.257881 -0.783801 -0.405107 v -0.234703 -0.689839 -0.458511 v -0.328454 -0.660264 -0.488051 v -0.367167 -0.637666 -0.455101 v -0.388641 -0.741943 -0.435631 v -0.376199 -0.631515 -0.395108 v -0.400098 -0.749288 -0.367958 v -0.383721 -0.823042 -0.261308 v -0.341229 -0.632657 -0.35462 v -0.362352 -0.751995 -0.321882 v -0.42405 -0.853284 -0.300847 v -0.350174 -0.740432 -0.472639 v -0.374196 -0.81292 -0.477929 v -0.319228 -0.757776 -0.318754 v -0.282642 -0.767582 -0.344621 v -0.337117 -0.824061 -0.251221 v -0.378642 -0.839771 -0.211243 v -0.346519 -0.841335 -0.204056 v -0.384265 -0.849313 -0.179577 v -0.353566 -0.852177 -0.173321 v -0.398341 -0.84731 -0.154711 v -0.351914 -0.850033 -0.14466 v -0.403841 -0.868169 -0.125505 v -0.359206 -0.872685 -0.119829 v -0.407268 -0.896601 -0.109988 v -0.428268 -0.941078 -0.0731733 v -0.385618 -0.936808 -0.0554072 v -0.427512 -0.988226 -0.0347064 v -0.40834 -0.985977 -0.0265877 v -0.418638 -1 -0.0334763 v -0.409447 -0.922574 -0.0527537 v -0.368555 -0.903806 -0.104699 v -0.420114 -0.954082 -0.0233543 v -0.420711 -0.984887 -0.0225108 v -0.380716 -0.952641 -0.0529294 v -0.34615 -0.890767 -0.143553 v -0.322708 -0.865621 -0.209732 v -0.305029 -0.838523 -0.25282 v -0.394229 -0.880435 -0.21279 v -0.40298 -0.884916 -0.172548 v -0.339911 -0.878431 -0.173321 v -0.340333 -0.942467 -0.116332 v -0.372263 -0.974871 -0.0709767 v -0.418111 -0.930781 -0.135627 v -0.368063 -0.961059 -0.140565 v -0.395266 -0.987225 -0.105613 v -0.412768 -0.970864 -0.0551963 v -0.405546 -0.98306 -0.078041 v -0.434401 -0.949988 -0.0829438 v -0.430183 -0.963326 -0.099269 v -0.400661 -0.968861 -0.0308228 v -0.415563 -0.977208 -0.0443539 v -0.43173 -0.974168 -0.0451095 v -0.224142 -0.382578 -0.183021 v -0.280744 -0.362475 -0.179102 v -0.344762 -0.376305 -0.133308 v -0.175869 -0.418251 -0.162514 v -0.151408 -0.46742 -0.0904298 v -0.409061 -0.832689 -0.359452 v -0.436527 -0.875479 -0.277827 v -0.409078 -0.870471 -0.240203 v -0.391171 -0.957931 -0.0474467 v -0.428619 -0.95236 -0.0712403 v -0.392612 -0.924736 -0.175588 v -0.355446 -0.943785 -0.177661 v -0.330826 -0.922803 -0.173795 v -0.319826 -0.938302 -0.223263 v -0.383246 -0.93419 -0.226075 v -0.347784 -0.955277 -0.227568 v -0.480494 -0.870594 -0.26296 v -0.466014 -0.867518 -0.233859 v -0.496784 -0.864953 -0.258479 v -0.484782 -0.858591 -0.230099 v -0.519383 -0.873036 -0.246775 v -0.51021 -0.867501 -0.220557 v -0.533916 -0.892402 -0.2382 v -0.52476 -0.883633 -0.21532 v -0.587987 -0.92753 -0.202176 v -0.573015 -0.93013 -0.187977 v -0.603399 -0.965013 -0.185112 v -0.587759 -0.96807 -0.171968 v -0.586863 -0.943134 -0.216779 v -0.594753 -0.980635 -0.201314 v -0.598478 -0.987506 -0.180719 v -0.494025 -0.905792 -0.259076 v -0.524075 -0.915598 -0.247777 v -0.576249 -0.955312 -0.233332 v -0.549134 -0.94679 -0.181686 v -0.488437 -0.883668 -0.221137 v -0.471251 -0.883334 -0.227797 v -0.500105 -0.92268 -0.200366 v -0.542315 -0.9693 -0.213774 v -0.510175 -0.93665 -0.225196 v -0.579254 -0.973834 -0.194496 v -0.562577 -0.97654 -0.205005 v -0.574913 -0.952009 -0.179278 v -0.587583 -0.966858 -0.20931 v -0.586318 -0.976945 -0.189242 v -0.474519 -0.931536 -0.233244 v -0.471128 -0.917724 -0.215742 v -0.419358 -0.91319 -0.226532 v -0.434822 -0.917548 -0.305978 v -0.403086 -0.886515 -0.359224 v -0.386269 -0.851984 -0.4263 v -0.313341 -0.810829 -0.460127 v -0.316188 -0.843602 -0.441131 v -0.336397 -0.967947 -0.279725 v -0.260763 -0.938847 -0.308069 v -0.331336 -0.942554 -0.324307 v -0.331266 -0.886444 -0.370506 v -0.42948 -0.944575 -0.319878 v -0.402225 -0.95707 -0.275103 v -0.289021 -0.878203 -0.359347 v -0.281288 -0.843813 -0.282975 v -0.270323 -0.859347 -0.334481 v -0.24479 -0.877289 -0.243893 v -0.248199 -0.887095 -0.304731 v -0.253963 -0.845781 -0.223509 v -0.303676 -0.75029 -0.466717 v -0.289108 -0.850455 -0.208502 v -0.260588 -0.844603 -0.187889 v -0.228816 -0.848575 -0.203423 v -0.206727 -0.855376 -0.172688 v -0.241908 -0.847099 -0.155889 v -0.203898 -0.870436 -0.156785 v -0.234949 -0.862159 -0.140811 v -0.19541 -0.921221 -0.103943 v -0.216146 -0.921098 -0.103697 v -0.198591 -0.962798 -0.0907462 v -0.213334 -0.965487 -0.0940499 v -0.205005 -0.982515 -0.0964222 v -0.188469 -0.935121 -0.118687 v -0.196746 -0.973518 -0.107019 v -0.22669 -0.884125 -0.210769 v -0.20989 -0.902594 -0.18202 v -0.244526 -0.94744 -0.12315 v -0.259902 -0.893702 -0.160827 v -0.264629 -0.859558 -0.181721 v -0.263751 -0.886901 -0.173022 v -0.23342 -0.952659 -0.161125 v -0.195779 -0.953432 -0.152198 v -0.238007 -0.917232 -0.176185 v -0.212333 -0.960742 -0.113608 v -0.223579 -0.965434 -0.138123 v -0.22379 -0.944452 -0.106509 v -0.197817 -0.949302 -0.126999 v -0.21047 -0.968914 -0.104084 v -0.240818 -0.908744 -0.186219 v -0.307929 -0.903314 -0.210066 v -0.240484 -0.924402 -0.250308 v -0.278231 -0.957896 -0.25159 v -0.268987 -0.933399 -0.223456 v -0.0218079 -0.117158 0.00576388 v -0.00451622 -0.172354 -0.017485 v 0.0111588 -0.124943 0.00857553 v 0.0238112 -0.188258 -0.0190665 v -0.0554599 -0.00961236 0.0186623 v -0.0614171 -0.0116157 0.0119144 v -0.110744 -0.0432116 0.0195761 v -0.0848944 0.0545812 0.00748601 v 0.00130039 -0.0290304 0.0240924 v 0.0115981 0.0488525 -0.00326856 v -0.12735 -0.033775 0.0174498 v -0.137437 0.00885669 0.00472708 v -0.171651 0.0863529 -0.0459706 v -0.154799 0.0739816 -0.0121253 v -0.236794 0.11208 -0.127719 v -0.00829438 -0.198556 -0.0915369 v 0.00970021 -0.244807 -0.25275 v -0.00630865 -0.252961 -0.285629 v -0.126911 -0.230521 -0.328032 v -0.0404702 -0.290022 -0.341757 v -0.15805 -0.313658 -0.37764 v -0.083225 -0.350771 -0.392753 v -0.256054 -0.452518 -0.493463 v -0.20815 -0.500773 -0.534478 v -0.38785 -0.571943 -0.536727 v -0.35831 -0.604172 -0.591642 v -0.540699 -0.660106 -0.534829 v -0.543475 -0.680473 -0.592679 v -0.683214 -0.726338 -0.418321 v -0.724001 -0.750641 -0.408744 v -0.724388 -0.787808 -0.271782 v -0.748234 -0.790022 -0.2689 v -0.211313 -0.245001 -0.433381 v -0.302499 -0.393263 -0.526043 v -0.427301 -0.509964 -0.533318 v -0.554036 -0.612449 -0.514199 v -0.680245 -0.695516 -0.410888 v -0.737585 -0.772502 -0.255017 v -0.178171 -0.180192 -0.381313 v -0.188715 -0.170773 -0.417759 v -0.202053 -0.145064 -0.39212 v -0.206551 -0.151056 -0.425157 v -0.221031 -0.117808 -0.435455 v -0.164482 -0.136752 -0.357045 v -0.188293 -0.11888 -0.377025 v -0.176484 -0.109971 -0.401733 v -0.181826 -0.108793 -0.358328 v -0.109865 -0.184638 -0.285313 v -0.154623 -0.103557 -0.339982 v -0.202105 -0.071293 -0.404562 v -0.154992 -0.0832074 -0.364443 v -0.237673 -0.218747 -0.499807 v -0.233719 -0.194953 -0.539715 v -0.245194 -0.22676 -0.551506 v -0.263188 -0.209345 -0.57783 v -0.23089 -0.256071 -0.488666 v -0.233016 -0.250308 -0.535919 v -0.207043 -0.223298 -0.566162 v -0.206217 -0.240853 -0.557498 v -0.18462 -0.187748 -0.548993 v -0.212754 -0.192264 -0.556426 v -0.241556 -0.20678 -0.578357 v -0.20685 -0.173057 -0.491934 v -0.20866 -0.138597 -0.47705 v -0.218413 -0.113661 -0.525147 v -0.215232 -0.118546 -0.496538 v -0.224581 -0.051998 -0.457843 v -0.201227 -0.0994096 -0.483007 v -0.237444 -0.0798334 -0.476435 v -0.190437 -0.1364 -0.440147 v -0.238042 -0.0523847 -0.479932 v -0.225038 -0.0361825 -0.473184 v -0.204144 -0.026781 -0.448248 v -0.221506 -0.00962994 -0.477858 v -0.204899 -0.0453907 -0.494746 v -0.219309 -0.0796226 -0.49884 v -0.252188 -0.0474643 -0.521035 v -0.151654 -0.104471 -0.517538 v -0.186817 -0.100341 -0.495466 v -0.169595 -0.0330721 -0.360524 v -0.213686 0.0203142 -0.414912 v -0.201771 -0.0223878 -0.43129 v -0.22727 0.0430359 -0.42572 v -0.168734 -0.0770218 -0.383475 v -0.183689 -0.0212104 -0.453045 v -0.137332 -0.0663023 -0.501599 v -0.112677 -0.028714 -0.463185 v -0.295294 -0.356096 -0.576424 v -0.431079 -0.483569 -0.569009 v -0.567901 -0.587179 -0.534109 v -0.692089 -0.676326 -0.409816 v -0.255263 -0.307103 -0.551752 v -0.257512 -0.329192 -0.491811 v -0.271079 -0.273082 -0.567005 v -0.224423 -0.265631 -0.564756 v -0.246758 -0.275191 -0.500949 v -0.250712 -0.3106 -0.564299 v -0.247461 -0.264401 -0.533986 v -0.239676 -0.282202 -0.568868 v -0.745598 -0.785278 -0.25282 v -0.17058 -0.14835 -0.537219 v -0.179348 -0.114329 -0.518979 v -0.191597 -0.00715217 -0.30814 v -0.223983 0.0790953 -0.344287 v -0.260517 0.131884 -0.356869 v -0.214125 0.0328788 -0.389818 v -0.18383 0.0240396 -0.427231 v -0.253137 0.104137 -0.375637 v -0.27867 0.149861 -0.385531 v -0.218202 0.115418 -0.406548 v -0.113731 0.0165009 -0.454627 v -0.106632 0.064545 -0.41971 v -0.0471831 0.182318 0.00604504 v -0.0370084 0.130549 -0.00416479 v 0.0283977 0.118494 -0.0347767 v -0.0450743 0.109514 0.0105788 v -0.0674973 0.0732787 0.00590445 v -0.0687977 0.109936 0.020279 v -0.0988824 0.0630865 0.00678309 v -0.05669 0.128475 -0.0250062 v -0.0825396 0.0679893 -0.0156926 v -0.0641233 0.105279 -0.0112818 v -0.0997083 0.0442132 -0.00295226 v -0.0515236 0.26368 -0.0284329 v -0.0974063 0.409869 0.0412259 v 0.0925034 0.404755 -0.0309634 v 0.0899027 0.504077 -0.0140231 v -0.210681 0.101466 -0.0606263 v -0.165009 0.0900959 -0.0308931 v -0.230907 0.108987 -0.0835589 v -0.250554 0.145661 -0.116578 v -0.200893 0.125663 -0.036534 v -0.23762 0.0883387 -0.157453 v -0.243384 0.101887 -0.219081 v -0.228078 0.108495 -0.156838 v -0.242119 0.0460057 -0.217148 v -0.268724 0.124398 -0.177169 v -0.267652 0.106948 -0.200401 v -0.25869 0.0981092 -0.257196 v -0.259709 0.086968 -0.311461 v -0.245299 0.0941025 -0.28468 v -0.25695 0.14162 -0.257354 v -0.196306 0.118845 -0.202369 v -0.273732 0.14603 -0.312094 v -0.215056 0.115348 -0.267634 v -0.170527 0.115172 -0.243489 v -0.228342 0.113608 -0.289723 v -0.273556 0.141321 -0.210171 v -0.227094 0.121639 -0.194883 v -0.245387 0.132816 -0.1839 v -0.22669 0.12192 -0.242997 v -0.203037 0.127825 -0.0755457 v -0.162478 0.071293 -0.0233016 v -0.199311 0.0553193 -0.0644221 v -0.152181 0.114505 -0.0470777 v -0.147137 0.0883738 -0.0385548 v -0.02353 0.169859 -0.00704673 v -0.0356201 0.185991 -0.0167645 v -0.0239518 0.218184 -0.0281517 v 0.0821706 0.347187 -0.041015 v -0.0566197 0.318332 0.0103152 v -0.0683056 0.370277 0.0193301 v -0.0364461 0.218097 -0.0120901 v -0.043317 0.219098 -0.0370436 v -0.05307 0.172354 -0.0321056 v -0.0248304 0.275858 -0.0146382 v 0.0609602 0.245018 -0.0526834 v -0.0702914 0.389133 0.0130566 v -0.14104 0.178927 -0.0426493 v -0.111201 0.22256 -0.0572172 v -0.142305 0.331863 -0.0111939 v -0.191509 0.13213 -0.126981 v -0.171599 0.222419 -0.119566 v -0.176273 0.291973 -0.0724353 v -0.199294 0.174323 -0.243278 v -0.218009 0.268003 -0.221312 v -0.197079 0.350789 -0.0400134 v -0.255931 0.328243 -0.16898 v -0.265297 0.32204 -0.262398 v -0.295716 0.36794 -0.250501 v -0.238815 0.310301 -0.361508 v -0.164552 0.174815 -0.262345 v -0.192721 0.227779 -0.324852 v -0.225512 0.270411 -0.334271 v -0.206534 0.262538 -0.357906 v -0.28642 0.334306 -0.245914 v -0.287175 0.361561 -0.288827 v -0.101905 0.20634 -0.336221 v -0.211928 0.115524 -0.296419 v -0.0737884 0.120304 -0.331195 v -0.224686 0.145942 -0.351773 v -0.153921 0.104348 -0.353601 v -0.154729 0.134432 -0.300109 v -0.0861421 0.470161 0.0632095 v -0.0696236 0.420026 0.0354971 v -0.116174 0.456788 0.065986 v -0.099269 0.427459 0.0370084 v -0.129213 0.440973 0.0426493 v -0.0952799 0.419798 0.0239693 v -0.104365 0.403015 0.0261659 v -0.0480969 0.358345 0.0105964 v -0.0635434 0.366148 0.00333882 v -0.0767054 0.349594 -0.00279411 v -0.216937 0.325537 -0.317963 v -0.262064 0.35339 -0.277862 v -0.251415 0.353232 -0.298896 v -0.214248 0.287474 -0.268988 v -0.135996 0.272449 -0.331441 v -0.185991 0.352002 -0.366183 v -0.177802 0.298334 -0.299353 v -0.113152 0.272098 -0.350912 v -0.134292 0.34789 -0.371683 v -0.158419 0.209749 -0.320775 v -0.144818 0.381788 -0.391628 v -0.21887 0.291006 -0.323709 v -0.271307 0.36982 -0.273662 v -0.261308 0.383703 -0.295646 v -0.297684 0.401206 -0.397586 v -0.303553 0.405441 -0.369926 v -0.300302 0.425087 -0.348329 v -0.40841 0.456244 -0.431378 v -0.39697 0.473869 -0.44389 v -0.407022 0.47292 -0.407338 v -0.474027 0.488859 -0.474607 v -0.452114 0.485819 -0.465645 v -0.470091 0.486293 -0.452764 v -0.444593 0.465276 -0.442396 v -0.434576 0.480617 -0.454891 v -0.44758 0.479703 -0.426159 v -0.460567 0.471971 -0.460742 v -0.294855 0.443574 -0.346009 v -0.3969 0.493867 -0.432872 v -0.403051 0.493762 -0.411802 v -0.461586 0.496538 -0.458528 v -0.439356 0.495923 -0.443749 v -0.444435 0.494289 -0.432222 v -0.270253 0.463361 -0.397058 v -0.258426 0.427653 -0.419183 v -0.285242 0.464714 -0.364232 v -0.250185 0.415 -0.287913 v -0.163884 0.398587 -0.370242 v -0.219731 0.462746 -0.353495 v -0.188961 0.445067 -0.35411 v -0.361104 0.568288 -0.308245 v -0.354374 0.574403 -0.367589 v -0.300671 0.599989 -0.392384 v -0.312603 0.471637 -0.212051 v -0.386058 0.625136 -0.27078 v -0.440551 0.614206 -0.365181 v -0.428162 0.646558 -0.388518 v -0.435631 0.65566 -0.290444 v -0.412997 0.68636 -0.368063 v -0.319984 0.679524 -0.371999 v -0.342003 0.658823 -0.283327 v -0.419024 0.697079 -0.32218 v -0.347538 0.705813 -0.334007 v -0.150898 0.625716 -0.381893 v -0.217552 0.679577 -0.296735 v -0.172671 0.673479 -0.332232 v -0.117756 0.687766 -0.318455 v -0.274593 0.646874 -0.386726 v -0.281798 0.677837 -0.329421 v -0.351615 0.679278 -0.32863 v -0.320616 0.659386 -0.380259 v -0.148614 0.556022 -0.396496 v -0.315696 0.684708 -0.327171 v -0.223491 0.65812 -0.237216 v -0.345218 0.671054 -0.308368 v -0.278635 0.65436 -0.281763 v -0.268724 0.631164 -0.229431 v -0.307103 0.626401 -0.26108 v -0.190244 0.68701 -0.250308 v -0.138263 0.694531 -0.272678 v -0.22191 0.704495 -0.291621 v -0.450023 0.628686 -0.313236 v -0.43013 0.694039 -0.294784 v -0.524321 0.683882 -0.367483 v -0.508716 0.697167 -0.386058 v -0.526465 0.725723 -0.31835 v -0.496134 0.739325 -0.369979 v -0.524426 0.689189 -0.338225 v -0.511616 0.739975 -0.314009 v -0.56878 0.72973 -0.383703 v -0.572558 0.782993 -0.358873 v -0.575177 0.73994 -0.349489 v -0.573753 0.771307 -0.338277 v -0.503356 0.754279 -0.335097 v -0.573753 0.768566 -0.379872 v -0.6435 0.751379 -0.372492 v -0.642481 0.760517 -0.362932 v -0.631621 0.77621 -0.375321 v -0.63633 0.76296 -0.380997 v -0.659632 0.761062 -0.377588 v -0.185622 0.524198 -0.384898 v -0.195972 0.482902 -0.368678 v -0.180772 0.441324 -0.45837 v -0.208748 0.450216 -0.438776 v -0.174727 0.536727 -0.443257 v -0.207518 0.508523 -0.428971 v -0.219696 0.522564 -0.519102 v -0.21358 0.496345 -0.511967 v -0.22379 0.498998 -0.504956 v -0.212262 0.529558 -0.506203 v -0.224054 0.519822 -0.500984 v 0.0923629 0.459284 -0.0198397 v -0.0165888 0.480195 0.0423329 v -0.0253752 0.461832 0.0294521 v 0.0173268 0.396935 0.00817136 v 0.022792 0.347169 -0.0113345 v 0.0708713 0.278617 -0.0503638 v -0.0942256 0.492742 0.0723122 v -0.144501 0.538379 0.0842617 v -0.121007 0.498225 0.0578322 v -0.17738 0.700137 -0.291727 v -0.197835 0.689418 -0.27085 v -0.094454 0.718676 -0.274576 v -0.18643 0.712456 -0.219748 v -0.132482 0.742681 -0.20374 v -0.0662145 0.766668 -0.220293 v -0.122079 0.76593 -0.171388 v -0.022792 0.82566 -0.153393 v -0.202527 0.718676 -0.194039 v -0.172425 0.7327 -0.191245 v -0.190349 0.696253 -0.212913 v -0.191298 0.731575 -0.162039 v -0.199786 0.700418 -0.184655 v -0.187889 0.720293 -0.151794 v -0.168893 0.765912 -0.128194 v -0.118582 0.757196 -0.141215 v -0.256001 0.688855 -0.215285 v -0.252697 0.664183 -0.237655 v -0.299336 0.51694 -0.317787 v -0.33109 0.484132 -0.307191 v -0.353232 0.496169 -0.348223 v -0.305767 0.472376 -0.350227 v -0.291217 0.558395 -0.371753 v -0.192616 0.558518 -0.389836 v -0.173813 0.725266 -0.155959 v -0.1519 0.741662 -0.109338 v -0.171072 0.73827 -0.132587 v -0.101958 0.792395 -0.147788 v -0.0465856 0.798352 -0.190982 v -0.114364 0.756071 -0.102959 v -0.118177 0.801937 -0.175553 v -0.07479 0.79909 -0.172794 v -0.109004 0.810284 -0.162285 v -0.0652304 0.809756 -0.153991 v -0.0105789 0.847556 -0.114452 v -0.0680596 0.827646 -0.11881 v -0.0867747 0.811689 -0.137051 v -0.0922398 0.784522 -0.0962289 v -0.119864 0.774751 -0.162531 v -0.111921 0.777985 -0.16826 v -0.214582 0.714283 -0.13814 v -0.219661 0.734 -0.107862 v -0.202914 0.686272 -0.107229 v -0.233279 0.688785 -0.156662 v -0.194514 0.694391 -0.0893579 v -0.230028 0.679384 -0.12967 v -0.233016 0.704812 -0.150951 v -0.241205 0.703089 -0.115735 v -0.219327 0.697378 -0.120075 v -0.191702 0.721646 -0.109075 v -0.160897 0.730977 -0.12113 v -0.196763 0.675412 -0.0858961 v -0.233033 0.661213 -0.112413 v -0.0795698 0.802552 -0.103223 v -0.0903596 0.821706 -0.135961 v -0.0982849 0.783924 -0.165132 v -0.103012 0.778863 -0.108723 v -0.0882508 0.757337 -0.119337 v -0.0494324 0.624433 -0.0333006 v -0.158525 0.619741 -0.0540541 v -0.0821179 0.708836 -0.110832 v -0.153165 0.686202 -0.0551963 v -0.0980037 0.604699 -0.0436334 v -0.0140407 0.523776 0.0235476 v -0.112923 0.520789 0.0663375 v -0.188521 0.609057 -0.033652 v -0.150652 0.559062 0.0299968 v -0.222982 0.630021 0.0142516 v -0.202703 0.545865 0.0467613 v -0.174129 0.52165 0.0595192 v -0.186993 0.649211 -0.0749482 v -0.211805 0.605964 -0.0708713 v -0.226531 0.680051 -0.0760728 v -0.236443 0.616016 -0.0921168 v -0.332777 0.47401 -0.181334 v -0.361596 0.500176 -0.114786 v -0.383158 0.42108 -0.117474 v -0.276632 0.657435 -0.172073 v -0.331793 0.511493 -0.219977 v -0.39683 0.498295 -0.216146 v -0.256599 0.664658 -0.123766 v -0.271869 0.626226 -0.129916 v -0.317717 0.629442 -0.1574 v -0.315134 0.531192 -0.134397 v -0.332689 0.496116 -0.155783 v -0.355938 0.566777 -0.148174 v -0.329842 0.531139 -0.115998 v -0.348276 0.502003 -0.126577 v -0.32081 0.521228 -0.148912 v -0.39495 0.413225 0.045953 v -0.403332 0.363143 -0.0164833 v -0.399817 0.398991 -0.0650371 v -0.392489 0.450181 -0.00407692 v -0.346308 0.43491 0.123959 v -0.367518 0.474801 0.0462341 v -0.332373 0.535427 -0.0382912 v -0.28171 0.441078 0.132236 v -0.227849 0.465768 0.117439 v -0.427459 0.387095 0.09108 v -0.435789 0.338453 0.0306997 v -0.381436 0.404456 0.137543 v -0.445981 0.345218 0.129793 v -0.40103 0.37815 0.163304 v -0.343022 0.395828 0.198415 v -0.247057 0.387112 0.149193 v -0.301111 0.351193 0.208554 v -0.502935 0.347099 0.210927 v -0.414561 0.369135 0.26528 v -0.472393 0.369047 0.222507 v -0.525076 0.289671 0.226672 v -0.448547 0.317436 0.0624011 v -0.445647 0.289442 0.112765 v -0.417601 0.287597 0.0317717 v -0.29619 0.500808 0.109813 v -0.37685 0.487435 -0.0773381 v -0.271483 0.550118 0.0389062 v -0.258215 0.567093 0.00386601 v -0.136998 0.472797 0.0573753 v -0.180543 0.516308 0.092644 v -0.501213 0.341177 0.366253 v -0.390398 0.318877 0.236513 v -0.372615 0.303729 0.239026 v -0.359189 0.311127 0.233859 v -0.39017 0.326925 0.273469 v -0.403455 0.34926 0.222015 v -0.507029 0.287281 0.188065 v -0.476048 0.350719 0.460285 v -0.506801 0.306312 0.424876 v -0.502144 0.329262 0.430622 v -0.513303 0.304643 0.4609 v -0.509595 0.322251 0.46554 v -0.506063 0.31719 0.482867 v -0.510579 0.288757 0.368063 v -0.525006 0.295276 0.294152 v -0.514884 0.339683 0.306224 v -0.464573 0.372861 0.314378 v -0.525375 0.258321 0.270218 v -0.509138 0.244122 0.192212 v -0.5223 0.242857 0.214107 v -0.42043 0.246863 0.106316 v -0.508576 0.232155 0.282606 v -0.497733 0.22024 0.196499 v -0.510807 0.219362 0.221734 v -0.505869 0.288423 0.468931 v -0.497188 0.29141 0.425948 v -0.495291 0.25876 0.376164 v -0.477788 0.219239 0.165835 v -0.49327 0.246723 0.15921 v -0.267037 0.352072 -0.149562 v -0.309581 0.383808 -0.237778 v -0.241785 0.297719 0.0423857 v -0.302042 0.39683 -0.224282 v -0.285277 0.271711 -0.000948948 v -0.30698 0.390785 -0.281306 v -0.316698 0.406249 -0.27512 v -0.2731 0.385249 -0.293677 v -0.263452 0.412821 -0.286367 v -0.286156 0.401961 -0.303887 v -0.314079 0.416002 -0.307226 v -0.318156 0.421854 -0.302042 v -0.280621 0.424296 -0.28403 v -0.311935 0.428074 -0.302042 v -0.304098 0.422187 -0.306839 v -0.307331 0.457052 -0.262398 v -0.370822 0.327382 -0.0895688 v -0.343953 0.366218 -0.148139 v -0.300671 0.491583 -0.277616 v -0.335659 0.290637 -0.0737357 v -0.320476 0.46496 -0.312111 v -0.338066 0.474344 -0.340579 v -0.297455 0.435719 -0.267617 v -0.256634 0.516343 -0.333726 v -0.263557 0.467613 -0.353636 v -0.267793 0.493428 -0.353425 v -0.301357 0.455242 -0.326503 v -0.334429 0.500176 -0.33768 v -0.309809 0.493182 -0.353495 v -0.421098 0.275489 0.0633149 v -0.386567 0.326714 -0.0402945 v -0.335378 0.285875 -0.0232489 v -0.203247 0.386761 0.0166415 v -0.149896 0.414297 0.0263241 v -0.167258 0.475011 0.0974941 v -0.148438 0.479405 0.0743682 v -0.35274 0.258619 0.207799 v -0.291727 0.300443 0.118898 v -0.249025 0.347099 0.0987418 v -0.178312 0.408604 -0.0285207 v -0.208185 0.421116 0.0755808 v -0.363195 0.231136 0.119407 v -0.381454 0.243911 0.0394686 v -0.444241 0.202755 0.242646 v -0.429023 0.199294 0.184251 v -0.465821 0.260869 0.409061 v -0.465557 0.22973 0.327733 v -0.415211 0.276596 0.412751 v -0.393597 0.231311 0.322954 v -0.456859 0.366745 0.377236 v -0.379275 0.297403 0.336239 v -0.404 0.318508 0.418778 v -0.410941 0.343268 0.465909 v -0.372035 0.293062 0.278196 v -0.364689 0.249991 0.295505 v -0.381225 0.262714 0.347626 v -0.322198 0.264489 0.169402 v -0.3203 0.246318 0.0940498 v -0.378115 0.221892 0.213018 v -0.356131 0.254033 0.246986 v -0.470144 0.325098 0.522862 v -0.395406 0.31784 0.498172 v -0.395582 0.311356 0.464889 v -0.529013 0.265543 0.56031 v -0.496521 0.275208 0.59101 v -0.453555 0.274734 0.607458 v -0.422012 0.276386 0.605578 v -0.545127 0.249148 0.535286 v -0.449671 0.259937 0.639388 v -0.425755 0.262978 0.637648 v -0.453432 0.243595 0.685306 v -0.43918 0.246811 0.686764 v -0.458844 0.243296 0.700418 v -0.441359 0.248445 0.704003 v -0.461111 0.233473 0.724071 v -0.446245 0.234597 0.726356 v -0.46684 0.212385 0.754261 v -0.467807 0.186237 0.773363 v -0.442291 0.188012 0.777001 v -0.454803 0.197378 0.773047 v -0.446543 0.214723 0.759059 v -0.37337 0.244649 0.570081 v -0.382438 0.288862 0.488543 v -0.416617 0.235072 0.660212 v -0.429603 0.229765 0.707535 v -0.437212 0.17499 0.772731 v -0.433434 0.201701 0.754701 v -0.465382 0.163761 0.788089 v -0.444066 0.169226 0.791094 v -0.457614 0.177345 0.796067 v -0.455699 0.149299 0.809458 v -0.385355 0.257214 0.483657 v -0.438987 0.241152 0.490282 v -0.41428 0.220363 0.525305 v -0.393983 0.231838 0.499772 v -0.421625 0.273398 0.459706 v -0.195111 0.17195 -0.13148 v -0.221857 0.217675 -0.229484 v -0.224985 0.237954 -0.304274 v -0.218975 0.267494 -0.169472 v -0.216445 0.599743 -0.0423681 v -0.249605 0.611078 -0.0264823 v -0.246072 0.579904 -0.0156047 v -0.222595 0.611429 -0.0137947 v -0.304256 0.549028 -0.0794644 v -0.334798 0.551559 -0.0657927 v -0.307472 0.551383 -0.0465153 v -0.289021 0.567603 -0.102098 v -0.29243 0.56096 -0.0901838 v -0.269251 0.558887 -0.0647735 v -0.25876 0.58015 -0.0920817 v -0.279391 0.611588 -0.0779356 v -0.273152 0.576776 -0.102801 v -0.297561 0.552402 -0.12496 v -0.320775 0.592855 -0.0986539 v -0.326837 0.535023 -0.101132 v -0.276948 0.558553 -0.0438091 v -0.299564 0.5724 -0.066109 v -0.230362 0.584156 -0.0659333 v -0.242593 0.581556 -0.0777423 v -0.228728 0.610463 -0.0642639 v -0.233438 0.59825 -0.0768109 v -0.257635 0.570063 -0.044758 v -0.272713 0.570133 -0.0577444 v -0.255369 0.562401 -0.0579904 v -0.247812 0.568552 -0.0716796 v -0.261466 0.562594 -0.0362001 v -0.32877 0.535163 -0.0792535 v -0.470899 0.192792 0.742171 v -0.471145 0.174586 0.765895 v -0.463132 0.2243 0.646997 v -0.468 0.226215 0.696974 v -0.4415 0.16334 0.76419 v -0.438056 0.191192 0.738885 v -0.46264 0.184726 0.733262 v -0.46257 0.162039 0.760974 v -0.444698 0.163533 0.787703 v -0.463554 0.161196 0.785207 v -0.450884 0.150898 0.803694 v -0.459003 0.147823 0.801163 v -0.432099 0.208607 0.696271 v -0.425474 0.212561 0.647243 v -0.459284 0.201719 0.689804 v -0.454363 0.142041 0.808228 v -0.3413 0.250958 0.508997 v -0.347608 0.255158 0.535497 v -0.344744 0.220873 0.540681 v -0.340702 0.215179 0.51557 v -0.339788 0.207184 0.543915 v -0.334727 0.203265 0.518118 v -0.333937 0.192387 0.547271 v -0.329825 0.18694 0.519928 v -0.314202 0.176537 0.534865 v -0.309756 0.176343 0.553826 v -0.30872 0.165888 0.522405 v -0.367571 0.23762 0.495044 v -0.347204 0.191737 0.506976 v -0.314027 0.149158 0.516975 v -0.281728 0.160493 0.547042 v -0.29004 0.156785 0.559484 v -0.287685 0.154465 0.530981 v -0.266106 0.136717 0.553966 v -0.272467 0.130513 0.559941 v -0.271588 0.128633 0.545162 v -0.352986 0.197027 0.551928 v -0.321671 0.166995 0.561698 v -0.328946 0.144378 0.533599 v -0.329913 0.151601 0.555882 v -0.311479 0.14002 0.537167 v -0.312902 0.145872 0.557287 v -0.291252 0.150125 0.53193 v -0.297596 0.152585 0.560995 v -0.364988 0.1839 0.546357 v -0.364443 0.178645 0.521316 v -0.389098 0.217007 0.557797 v -0.265596 0.126419 0.553035 v -0.401311 0.24305 0.616209 v -0.456472 0.223034 0.53186 v -0.407005 0.219362 0.605578 v -0.428812 0.21105 0.570239 v -0.484782 0.249886 0.629547 v -0.501388 0.247215 0.62185 v -0.512002 0.199048 0.670843 v -0.497101 0.202404 0.678136 v -0.518223 0.179682 0.684655 v -0.498524 0.184954 0.695305 v -0.513742 0.153727 0.686747 v -0.492655 0.152339 0.696675 v -0.505114 0.106562 0.691034 v -0.489702 0.109022 0.701262 v -0.49146 0.0842793 0.696974 v -0.498594 0.0740871 0.680754 v -0.472745 0.0792535 0.694707 v -0.468896 0.221295 0.643184 v -0.478913 0.169789 0.684462 v -0.476857 0.112396 0.694057 v -0.461305 0.0847362 0.683074 v -0.481742 0.0503462 0.689716 v -0.483482 0.0493621 0.669525 v -0.465733 0.0555653 0.684198 v -0.466594 0.0331951 0.668629 v -0.469564 0.0414192 0.660458 v -0.462535 0.0429129 0.668032 v -0.517169 0.166186 0.667979 v -0.507152 0.109848 0.668524 v -0.495783 0.0758795 0.664991 v -0.50854 0.214195 0.619091 v -0.461516 0.0807823 0.667944 v -0.469177 0.118986 0.676133 v -0.491846 0.114803 0.656978 v -0.481812 0.0766703 0.653534 v -0.465136 0.0619618 0.679278 v -0.480354 0.0565318 0.664781 v -0.501898 0.157101 0.654061 v -0.47575 0.165062 0.668734 v -0.457544 0.197536 0.633764 v -0.461832 0.0351808 0.660669 v -0.521843 0.23878 0.604822 v -0.535708 0.235441 0.591115 v -0.545373 0.173848 0.626894 v -0.531561 0.178681 0.634169 v -0.547605 0.158981 0.631129 v -0.533265 0.164534 0.643078 v -0.535866 0.131515 0.627245 v -0.523723 0.136154 0.637472 v -0.51267 0.0994974 0.608776 v -0.499649 0.103276 0.616789 v -0.497206 0.0910976 0.602836 v -0.498454 0.0871964 0.588919 v -0.479756 0.0949636 0.598496 v -0.511633 0.210452 0.617193 v -0.512863 0.154641 0.633044 v -0.48791 0.115102 0.608583 v -0.471268 0.10194 0.590026 v -0.479176 0.076108 0.584842 v -0.482445 0.0781815 0.570573 v -0.466278 0.0845956 0.584209 v -0.455014 0.072857 0.550979 v -0.543493 0.145732 0.618125 v -0.514884 0.105911 0.59036 v -0.499016 0.0927846 0.576758 v -0.536183 0.195322 0.585281 v -0.472586 0.109725 0.578217 v -0.493428 0.127139 0.601413 v -0.509208 0.125716 0.590184 v -0.4903 0.102081 0.568288 v -0.465997 0.090342 0.577391 v -0.482199 0.0845605 0.567866 v -0.529663 0.153305 0.603926 v -0.509366 0.155397 0.621253 v -0.523407 0.185727 0.575036 v -0.493358 0.190015 0.606825 v -0.512319 0.245721 0.489158 v -0.525762 0.224757 0.51926 v -0.482339 0.268232 0.453801 v -0.519998 0.277704 0.493621 v -0.542175 0.230907 0.578305 v -0.553667 0.225161 0.564053 v -0.567128 0.187326 0.577795 v -0.558342 0.186676 0.585703 v -0.573103 0.16232 0.583172 v -0.562788 0.163849 0.592574 v -0.56516 0.146803 0.574122 v -0.557551 0.144501 0.584209 v -0.550856 0.125857 0.56205 v -0.542702 0.126068 0.573121 v -0.535761 0.121639 0.561558 v -0.530788 0.128457 0.544055 v -0.52295 0.125171 0.562963 v -0.537184 0.193618 0.581854 v -0.549432 0.168805 0.587073 v -0.536885 0.134713 0.576126 v -0.51998 0.132113 0.564457 v -0.505641 0.12055 0.539398 v -0.508962 0.127491 0.535163 v -0.503567 0.128826 0.54887 v -0.484958 0.135153 0.529733 v -0.566425 0.169841 0.563157 v -0.548782 0.139054 0.549397 v -0.530471 0.137121 0.540224 v -0.549889 0.211208 0.548132 v -0.520754 0.139212 0.561575 v -0.537096 0.140688 0.572137 v -0.543686 0.146188 0.552701 v -0.523723 0.147612 0.543159 v -0.503005 0.133975 0.548729 v -0.509085 0.131181 0.534882 v -0.553316 0.166555 0.558412 v -0.54228 0.167276 0.58073 v -0.53685 0.196183 0.541577 v -0.388834 0.216286 0.528855 v -0.0103153 0.638052 -0.0238288 v -0.0345658 0.629775 -0.019049 v 0.00405933 0.557569 -0.00878644 v 0.0426317 0.577356 -0.0394862 v 0.0241099 0.566988 -0.0196816 v 0.0076969 0.631867 0.00458649 v 0.0390469 0.596791 -0.0216498 v 0.00486768 0.58514 -0.0238639 v -0.0266404 0.585053 -0.0152181 v -0.0916424 0.719766 -0.0684989 v -0.0402945 0.674287 -0.0183461 v -0.103855 0.744473 -0.0815204 v -0.0429129 0.848452 -0.0981092 v -0.092398 0.884441 -0.0697291 v -0.125101 0.830369 -0.0901663 v -0.108389 0.790391 -0.0504165 v -0.0952272 0.788318 -0.00485012 v -0.115524 0.871068 -0.115471 v -0.0911679 0.938144 -0.114979 v -0.0952272 0.926387 -0.137261 v -0.107458 0.964485 -0.149984 v -0.109584 0.95359 -0.159368 v -0.0954029 0.825888 -0.120778 v -0.0910625 0.856799 -0.136928 v -0.078779 0.917917 -0.151337 v -0.0947528 0.955014 -0.166274 v -0.052947 0.868327 -0.112958 v -0.0526658 0.925157 -0.137191 v -0.0896039 0.964643 -0.158894 v -0.0641057 0.949953 -0.146927 v -0.097582 0.969968 -0.151285 v -0.0716796 0.957878 -0.132165 v -0.0365691 0.84977 -0.047148 v -0.0555302 0.884968 -0.0781816 v -0.0588339 0.934506 -0.1141 v -0.0658454 0.862739 -0.127298 v -0.0327733 0.832935 0.00599231 v -0.0683056 0.893034 -0.0646856 v -0.0804485 0.947018 -0.113644 v -0.104031 0.965065 -0.165343 v -0.0224757 0.610234 0.00912029 v -0.0561277 0.648034 0.0549327 v -0.0191193 0.588321 0.0233367 v -0.0485186 0.620251 0.0886198 v -0.0482726 0.623309 0.115998 v -0.0187678 0.599937 0.0937335 v -0.0111939 0.615418 0.124381 v -0.0447756 0.661125 0.110357 v -0.0671107 0.660106 0.104963 v -0.0315257 0.609813 0.071293 v 0.00829438 0.549204 0.0310863 v 0.00829438 0.640758 0.159017 v -0.00133554 0.652778 0.135381 v -0.00307525 0.638421 0.128949 v 0.000843496 0.625013 0.146575 v -0.00405933 0.586089 0.126507 v 0.0165712 0.584402 0.148438 v 0.012301 0.563139 0.116912 v 0.0242681 0.552736 0.138878 v -0.0181703 0.606052 0.112361 v -0.0501529 0.617685 0.105665 v -0.0705549 0.653587 0.0789723 v -0.0394159 0.614259 0.108108 v -0.0376762 0.619654 0.117105 v -0.0309809 0.634626 0.116315 v -0.0120198 0.629986 0.123519 v 0.00490282 0.650019 0.144993 v 0.0281341 0.654096 0.164095 v 0.0247953 0.667065 0.155414 v 0.00774962 0.607616 0.146188 v 0.0350051 0.632148 0.162514 v 0.0241275 0.639616 0.163269 v 0.0169754 0.648455 0.164447 v 0.0116332 0.659175 0.155151 v 0.0440727 0.604523 0.154764 v 0.0376059 0.606843 0.15378 v 0.0292588 0.630918 0.162496 v 0.0313675 0.643763 0.16334 v -0.000984079 0.652128 0.148297 v 0.00660739 0.661266 0.158823 v -0.0127755 0.658103 0.1435 v 0.00296981 0.685341 0.155115 v -0.0103328 0.673725 0.153516 v -0.0257091 0.665835 0.126595 v -0.0210171 0.705778 0.144431 v -0.029663 0.683408 0.144045 v -0.0126173 0.723966 0.131761 v -0.106333 0.734756 -0.0590096 v -0.1128 0.754437 -0.00653711 v -0.0787966 0.707061 0.114751 v 0.0330545 0.585211 0.153288 v 0.0272555 0.599972 0.153182 v 0.059115 0.557112 0.14835 v 0.050434 0.58384 0.154606 v 0.012547 0.636137 0.160159 v 0.00590447 0.623168 0.153745 v 0.0100868 0.612203 0.152216 v 0.014111 0.610234 0.148807 v 0.0298211 0.620919 0.146874 v 0.014234 0.613046 0.149439 v 0.0127755 0.626911 0.149492 v 0.0188205 0.613767 0.151214 v 0.0178716 0.633782 0.149844 v 0.0405933 0.598707 0.154307 v -0.120761 0.744948 0.0342846 v -0.181984 0.660475 0.0333181 v -0.162689 0.638931 -0.042825 v -0.215812 0.575581 0.0540716 v -0.178856 0.511844 0.0236355 v -0.200981 0.54156 0.0800619 v -0.135715 0.517749 0.0859312 v -0.165958 0.54047 0.115787 v -0.0240396 0.530735 0.175166 v -0.0771272 0.523372 0.148016 v -0.0928022 0.541525 0.164482 v -0.12062 0.656592 0.0797455 v -0.104875 0.687379 0.0964046 v -0.143974 0.593382 0.0891119 v -0.126155 0.710136 0.0755105 v -0.0166591 0.53671 0.170421 v -0.0740695 0.562841 0.150582 v -0.142252 0.814308 -0.0267283 v -0.170562 0.813236 0.0110709 v -0.130865 0.792307 0.0589217 v -0.174639 0.808491 -0.0442309 v -0.196113 0.814607 -0.0249886 v -0.21293 0.783485 -0.0637719 v -0.103416 0.844709 0.0578498 v -0.158683 0.850912 0.00551786 v -0.188328 0.840544 -0.0316136 v -0.206832 0.803852 -0.0627878 v -0.129688 0.845078 -0.0156047 v -0.0665483 0.818912 0.00741572 v -0.121762 0.832021 -0.0222297 v -0.162215 0.841142 -0.0418234 v -0.194162 0.795276 -0.0576214 v -0.208045 0.800706 -0.0498366 v -0.0959126 0.758567 0.0898851 v -0.0675851 0.843075 0.0246195 v -0.0274488 0.815063 0.0534566 v -0.077918 0.82942 0.0770042 v -0.0649316 0.749359 0.111447 v -0.101325 0.762995 0.0454258 v -0.0159561 0.854989 -0.072119 v -0.0170808 0.841458 -0.00147615 v -0.0364461 0.783292 0.0993393 v -0.0281693 0.75825 0.120725 v -0.0181527 0.767669 0.117545 v -0.0282747 0.799986 0.0745264 v -0.026904 0.792166 0.0829438 v -0.0282923 0.781218 0.102256 v -0.0383615 0.830422 0.0836116 v -0.0465856 0.861508 0.0766527 v -0.0328788 0.813078 0.110129 v -0.0438091 0.854075 0.0968263 v -0.0117914 0.656328 0.133571 v -0.0192598 0.641848 0.131462 v -0.0913612 0.64473 -0.0213159 v -0.0823288 0.621657 0.0387657 v -0.176607 0.536112 0.00196813 v -0.116262 0.556813 0.037026 v -0.139581 0.586511 -0.015306 v -0.103961 0.538326 0.0664078 v -0.0602221 0.534583 0.120022 v -0.0206305 0.520033 0.164868 v -0.0187854 0.525902 0.156082 v -0.131814 0.576618 0.104576 v -0.0118617 0.526236 0.169139 v 0.0568481 0.578094 -0.0518223 v 0.0632095 0.595544 -0.0297157 v 0.0492391 0.583787 0.00488523 v 0.019418 0.53671 0.0464274 v 0.0210347 0.533459 0.0674621 v 0.0300496 0.528503 0.0214916 v 0.0110885 0.550627 0.0621727 v 0.020982 0.540945 0.0900784 v 0.0417179 0.529276 0.106948 v 0.0491337 0.519014 0.0846835 v 0.0306646 0.519611 0.0811162 v 0.0514884 0.507029 0.0627877 v 0.0406811 0.510614 0.035585 v 0.0437739 0.505325 0.0363406 v 0.0385548 0.509823 0.0614698 v 0.0329315 0.521246 0.0456015 v 0.0592908 0.505729 0.0730679 v 0.0708186 0.489052 0.0519629 v 0.0542649 0.51035 0.0526658 v 0.0745088 0.496292 0.0385372 v 0.0665308 0.547886 0.0225459 v 0.0700453 0.518135 0.0338804 v 0.0848592 0.483815 0.0301726 v -0.419446 0.356096 0.403086 v -0.413717 0.363371 0.323393 v 0.0299793 -0.116772 -0.00943663 v 0.0278881 -0.117035 0.0023196 v 0.0328261 -0.174323 -0.0231435 v 0.0351457 -0.176607 -0.0447756 v 0.0457597 -0.00630867 0.0128809 v 0.0517872 -0.00905004 0.00576388 v 0.107651 0.0463044 -0.031596 v 0.102169 0.0571117 -0.0239869 v 0.0152181 -0.208045 -0.0943662 v 0.0278354 -0.19954 -0.0988824 v 0.0328788 -0.19309 -0.102608 v 0.00843496 -0.221101 -0.18752 v 0.0369733 -0.196236 -0.178874 v 0.114382 0.167241 -0.0716093 v 0.106527 0.129301 -0.0596071 v 0.144027 0.178364 -0.0871964 v 0.10925 0.109321 -0.0409272 v 0.0984782 0.0749657 -0.0309282 v 0.13438 0.109619 -0.0477981 v 0.12055 0.0655643 -0.0350227 v 0.108161 0.105015 -0.0648438 v 0.105648 0.127157 -0.085527 v 0.0997259 0.0685692 -0.0509964 v 0.113644 0.169332 -0.10918 v 0.119443 0.18267 -0.0928022 v 0.172214 0.545127 -0.0801146 v 0.192862 0.504358 -0.0835765 v 0.225249 0.599919 -0.183267 v 0.113907 0.214002 -0.10324 v 0.140038 0.264436 -0.121182 v 0.131867 0.338962 -0.0827681 v 0.159649 0.400169 -0.0818543 v 0.179911 0.300531 -0.144572 v 0.201139 0.358539 -0.155203 v 0.181123 0.34137 -0.139441 v 0.134274 0.213106 -0.104857 v 0.116666 0.214406 -0.123273 v 0.13742 0.254982 -0.142656 v 0.180139 0.331547 -0.170703 v 0.182424 0.350648 -0.157066 v 0.218149 0.459003 -0.139441 v 0.231645 0.475029 -0.169349 v 0.250431 0.527572 -0.192897 v 0.231645 0.542122 -0.17608 v 0.237427 0.455224 -0.162303 v 0.229062 0.448178 -0.176519 v 0.219942 0.462746 -0.168155 v 0.240748 0.503075 -0.204109 v 0.203827 0.402963 -0.158753 v 0.1852 0.490353 -0.0985485 v 0.234931 0.568183 -0.174129 v 0.229677 0.574263 -0.196394 v 0.240625 0.539574 -0.218307 v 0.0274663 0.802411 0.102309 v 0.0202263 0.814185 0.0757741 v -0.183496 0.644396 -0.0129336 v -0.209134 0.549766 0.0197167 v -0.198714 0.522599 0.0515587 v -0.0914491 0.62844 0.0662671 v -0.115383 0.576547 0.0599058 v -0.108161 0.563139 0.0778653 v -0.109637 0.603838 0.0616631 v -0.105718 0.58797 0.0298562 v 0.0795522 0.555671 0.0176783 v 0.0844024 0.502601 0.03439 v 0.0913788 0.482164 0.025094 v 0.319615 -0.279391 -0.0492391 v 0.26542 -0.323744 -0.0486416 v 0.245229 -0.168875 -0.011809 v 0.175711 -0.204601 -0.00776722 v 0.131093 -0.152427 0.0120725 v 0.349541 -0.256388 -0.0736126 v 0.28417 -0.142199 -0.0529821 v 0.173532 0.00755631 -0.0877412 v 0.368221 -0.35534 -0.0836819 v 0.133079 -0.0532984 0.0125997 v 0.156627 -0.00543002 -0.0297684 v 0.132323 -0.0923804 0.0181527 v 0.101993 -0.0188733 0.0320001 v 0.106439 -0.0508207 0.037887 v 0.149053 -0.193354 0.00110707 v 0.32682 -0.398939 -0.0634907 v 0.267968 -0.440604 -0.0848241 v 0.217007 -0.373809 -0.0685517 v 0.372439 -0.428092 -0.0628405 v 0.343936 -0.485028 -0.0888659 v 0.396496 -0.40038 -0.0800267 v 0.420834 -0.434436 -0.0314378 v 0.377394 -0.483394 -0.0817137 v 0.41906 -0.476822 -0.112906 v 0.400011 -0.46619 -0.0599234 v 0.428777 -0.419745 -0.08565 v 0.431097 -0.422328 -0.0587284 v 0.428197 -0.456015 -0.0710997 v 0.425157 -0.441149 -0.100745 v 0.424771 -0.407391 -0.100271 v 0.444118 -0.417408 -0.0785155 v 0.440586 -0.412171 -0.115014 v 0.413085 -0.36613 -0.130144 v 0.427881 -0.38908 -0.159966 v 0.382473 -0.23393 -0.155871 v 0.404685 -0.306558 -0.135838 v 0.307718 -0.187889 -0.250958 v 0.361104 -0.502987 -0.0829087 v 0.3788 -0.495835 -0.0797456 v 0.390205 -0.499139 -0.0882157 v 0.373405 -0.517169 -0.0846835 v 0.387481 -0.512863 -0.0898851 v 0.387956 -0.506414 -0.0679366 v 0.363705 -0.513162 -0.122377 v 0.315468 -0.493182 -0.0992866 v 0.397673 -0.495009 -0.103873 v 0.425491 -0.498014 -0.0964046 v 0.385355 -0.517292 -0.130162 v 0.40704 -0.519067 -0.148034 v 0.35824 -0.524989 -0.182213 v 0.431589 -0.424507 -0.180807 v 0.446825 -0.439321 -0.146874 v 0.431536 -0.467525 -0.145907 v 0.350508 -0.501722 -0.112941 v 0.352775 -0.514902 -0.100921 v 0.347134 -0.521456 -0.126103 v 0.308755 -0.512424 -0.148631 v 0.334815 -0.507556 -0.125751 v 0.253084 -0.494429 -0.153446 v 0.0683584 -0.169156 -0.319492 v 0.199188 -0.144045 -0.250554 v 0.104963 -0.0734018 -0.409623 v 0.31473 -0.122852 -0.14357 v 0.427881 -0.461305 -0.218132 v 0.442607 -0.461006 -0.172794 v 0.4095 -0.503005 -0.198696 v 0.431466 -0.442361 -0.146294 v 0.112923 -0.0907462 0.0221242 v 0.110428 -0.153253 0.0297859 v 0.118845 -0.198538 -0.00574633 v 0.111658 -0.154536 0.00688854 v 0.0916072 -0.0419112 0.0288546 v 0.093716 -0.0783397 0.0125821 v 0.140495 -0.2395 -0.0249359 v 0.151355 -0.217938 -0.267283 v 0.279162 -0.253611 -0.309071 v 0.201789 -0.0121956 -0.147208 v 0.1991 -0.0523144 -0.231715 v 0.108495 -0.165255 -0.268197 v 0.166714 -0.0962113 -0.275876 v 0.136945 -0.241152 -0.00766177 v 0.133431 -0.26289 -0.0405757 v 0.159298 -0.253418 -0.024233 v 0.144185 -0.25927 -0.0205427 v 0.181545 -0.274769 -0.0289425 v 0.159895 -0.277458 -0.0354972 v 0.409851 -0.294099 -0.240801 v 0.433592 -0.333058 -0.185938 v 0.432766 -0.361807 -0.239694 v 0.216374 -0.339244 -0.32863 v 0.255597 -0.383088 -0.322216 v 0.131937 -0.302657 -0.197273 v 0.184989 -0.41254 -0.23096 v 0.152884 -0.338664 -0.117387 v 0.173057 -0.376498 -0.130847 v 0.147524 -0.303659 -0.0683232 v 0.228675 -0.459829 -0.152444 v 0.235546 -0.466489 -0.216058 v 0.347556 -0.362703 -0.420694 v 0.242066 -0.403894 -0.407233 v 0.203019 -0.443662 -0.359294 v 0.307999 -0.418532 -0.501898 v 0.237796 -0.437089 -0.47763 v 0.277756 -0.436791 -0.542772 v 0.223052 -0.455576 -0.529329 v 0.283046 -0.366323 -0.410273 v 0.370928 -0.32761 -0.303061 v 0.34752 -0.466032 -0.493006 v 0.40776 -0.393122 -0.373265 v 0.33239 -0.475029 -0.5391 v 0.393544 -0.478456 -0.420922 v 0.38423 -0.416459 -0.432099 v 0.429445 -0.435947 -0.319299 v 0.410168 -0.494271 -0.323903 v 0.373388 -0.568727 -0.293045 v 0.301515 -0.529944 -0.2062 v 0.257723 -0.516975 -0.212473 v 0.251907 -0.542807 -0.286613 v 0.209398 -0.50963 -0.309247 v 0.197009 -0.478368 -0.447563 v 0.309721 -0.345271 -0.321917 v 0.198573 -0.380628 -0.287878 v 0.231698 -0.430605 -0.282483 v 0.200067 -0.495185 -0.519418 v 0.212684 -0.562805 -0.510667 v 0.387218 -0.520841 -0.402506 v 0.349928 -0.57291 -0.382297 v 0.22205 -0.53794 -0.388219 v 0.423541 -0.493551 -0.14712 v 0.305469 -0.553035 -0.288177 v 0.26238 -0.594788 -0.493481 v 0.273785 -0.569026 -0.380786 v 0.189541 -0.547218 -0.610674 v 0.216093 -0.59217 -0.660229 v 0.181141 -0.483692 -0.607599 v 0.293185 -0.57226 -0.675201 v 0.31791 -0.54091 -0.659122 v 0.252434 -0.589815 -0.674656 v 0.322163 -0.585228 -0.48248 v 0.352441 -0.541894 -0.517186 v 0.362018 -0.536358 -0.599427 v 0.277493 -0.500914 -0.672126 v 0.325098 -0.487295 -0.63271 v 0.197607 -0.521105 -0.656117 v 0.283116 -0.463062 -0.637701 v 0.227516 -0.518416 -0.671652 v 0.21822 -0.460039 -0.630514 v 0.322479 -0.683461 -0.487488 v 0.229958 -0.631181 -0.589534 v 0.287316 -0.705884 -0.494658 v 0.238551 -0.671054 -0.575757 v 0.266808 -0.701807 -0.595913 v 0.322426 -0.739377 -0.53866 v 0.304309 -0.703687 -0.60607 v 0.345341 -0.788089 -0.520262 v 0.302745 -0.741433 -0.516888 v 0.324272 -0.788089 -0.473817 v 0.334815 -0.771202 -0.465171 v 0.309932 -0.73089 -0.485854 v 0.338769 -0.717253 -0.480934 v 0.338927 -0.801708 -0.477718 v 0.35223 -0.799441 -0.501494 v 0.354058 -0.82761 -0.483218 v 0.34926 -0.812621 -0.465997 v 0.364795 -0.827013 -0.505114 v 0.366974 -0.826047 -0.484466 v 0.371701 -0.811672 -0.471427 v 0.308034 -0.760746 -0.499807 v 0.330123 -0.789583 -0.507047 v 0.269989 -0.718237 -0.563069 v 0.339033 -0.676185 -0.628633 v 0.377535 -0.639757 -0.613204 v 0.423505 -0.727762 -0.592029 v 0.401856 -0.620515 -0.559607 v 0.461797 -0.72553 -0.536569 v 0.513303 -0.800513 -0.446912 v 0.383035 -0.622852 -0.510069 v 0.448107 -0.729765 -0.477735 v 0.530296 -0.825572 -0.503884 v 0.376041 -0.738815 -0.609795 v 0.396707 -0.799494 -0.624504 v 0.412663 -0.743243 -0.456507 v 0.372597 -0.76289 -0.464257 v 0.478649 -0.807454 -0.416828 v 0.534478 -0.816434 -0.403859 v 0.507152 -0.819439 -0.384634 v 0.549678 -0.820353 -0.371841 v 0.522915 -0.823674 -0.355709 v 0.570379 -0.816487 -0.34991 v 0.528187 -0.818807 -0.326205 v 0.583489 -0.839648 -0.320616 v 0.54221 -0.842618 -0.302868 v 0.588374 -0.870646 -0.307191 v 0.613521 -0.919376 -0.279619 v 0.577531 -0.914543 -0.250712 v 0.619443 -0.969705 -0.245914 v 0.603328 -0.967209 -0.23277 v 0.610375 -0.981074 -0.243191 v 0.602151 -0.901856 -0.253559 v 0.552525 -0.876568 -0.291902 v 0.617861 -0.936386 -0.230503 v 0.616403 -0.967121 -0.23212 v 0.572277 -0.930271 -0.248164 v 0.525147 -0.860349 -0.323006 v 0.486487 -0.846765 -0.378853 v 0.45417 -0.827013 -0.401873 v 0.552402 -0.855745 -0.409781 v 0.572365 -0.854919 -0.370594 v 0.511827 -0.850947 -0.350244 v 0.53504 -0.916933 -0.301093 v 0.557938 -0.950339 -0.264893 v 0.596405 -0.902963 -0.342337 v 0.567585 -0.936632 -0.340228 v 0.576038 -0.961024 -0.307525 v 0.601132 -0.949812 -0.260324 v 0.587302 -0.959512 -0.281218 v 0.616244 -0.927635 -0.291358 v 0.607669 -0.93918 -0.307331 v 0.596088 -0.949425 -0.233508 v 0.606228 -0.957245 -0.251134 v 0.621797 -0.954996 -0.256001 v 0.253805 -0.386954 -0.335255 v 0.301655 -0.350701 -0.347767 v 0.37706 -0.347028 -0.326345 v 0.224862 -0.434313 -0.30148 v 0.235705 -0.476927 -0.224897 v 0.486803 -0.80705 -0.539311 v 0.564088 -0.845289 -0.496591 v 0.552771 -0.845025 -0.446104 v 0.583383 -0.936545 -0.24609 v 0.613503 -0.930781 -0.27867 v 0.572962 -0.897884 -0.379767 v 0.549714 -0.924085 -0.370365 v 0.524426 -0.904984 -0.351246 v 0.495115 -0.924683 -0.389959 v 0.546199 -0.911451 -0.424367 v 0.519049 -0.937581 -0.409834 v 0.620497 -0.845658 -0.491126 v 0.612501 -0.842372 -0.459723 v 0.638 -0.842741 -0.488314 v 0.631744 -0.836028 -0.458423 v 0.660686 -0.852388 -0.479422 v 0.656187 -0.84629 -0.452378 v 0.676379 -0.870646 -0.472622 v 0.671036 -0.861456 -0.449021 v 0.736899 -0.902436 -0.443082 v 0.724528 -0.905142 -0.426616 v 0.756634 -0.938548 -0.42753 v 0.743419 -0.941781 -0.411978 v 0.734264 -0.918603 -0.456824 v 0.746301 -0.955137 -0.441658 v 0.753576 -0.961041 -0.421731 v 0.632253 -0.881348 -0.491794 v 0.666151 -0.893474 -0.481724 v 0.721787 -0.931853 -0.471128 v 0.702861 -0.922504 -0.41623 v 0.635328 -0.862053 -0.449619 v 0.617861 -0.859558 -0.4541 v 0.653464 -0.898763 -0.432889 v 0.692229 -0.94642 -0.446315 v 0.658419 -0.913665 -0.457614 v 0.731768 -0.948758 -0.432679 v 0.713791 -0.952571 -0.440305 v 0.728816 -0.926581 -0.417636 v 0.737304 -0.941992 -0.448828 v 0.739711 -0.951341 -0.428514 v 0.619952 -0.902717 -0.468773 v 0.622184 -0.891013 -0.448389 v 0.570924 -0.885864 -0.441992 v 0.553175 -0.886849 -0.523407 v 0.486733 -0.862704 -0.544407 v 0.436175 -0.832935 -0.588163 v 0.356834 -0.808614 -0.579535 v 0.370066 -0.837258 -0.56502 v 0.483482 -0.952536 -0.448898 v 0.401293 -0.935525 -0.430816 v 0.452167 -0.928848 -0.482146 v 0.422223 -0.873687 -0.514832 v 0.537448 -0.915563 -0.531227 v 0.538256 -0.931167 -0.479844 v 0.391171 -0.871859 -0.483183 v 0.420536 -0.835378 -0.412048 v 0.38532 -0.855323 -0.451112 v 0.418304 -0.875303 -0.361104 v 0.385689 -0.885583 -0.417513 v 0.43737 -0.84608 -0.344305 v 0.340087 -0.757196 -0.585158 v 0.469634 -0.844937 -0.353952 v 0.463501 -0.850525 -0.319984 v 0.42948 -0.855042 -0.316698 v 0.426792 -0.862317 -0.284293 v 0.46554 -0.856043 -0.287562 v 0.431185 -0.874688 -0.270481 v 0.46633 -0.868836 -0.272713 v 0.445647 -0.914016 -0.213949 v 0.463782 -0.91725 -0.223544 v 0.451376 -0.953414 -0.196095 v 0.462306 -0.958897 -0.205374 v 0.452501 -0.974467 -0.200243 v 0.431255 -0.928303 -0.22075 v 0.440885 -0.965645 -0.207219 v 0.421801 -0.889766 -0.325695 v 0.42159 -0.909043 -0.292342 v 0.476786 -0.950111 -0.248902 v 0.476031 -0.902383 -0.300724 v 0.470407 -0.867255 -0.319176 v 0.473237 -0.895284 -0.313763 v 0.449812 -0.958036 -0.277932 v 0.420008 -0.952061 -0.250079 v 0.448441 -0.924841 -0.300267 v 0.452255 -0.956595 -0.222701 v 0.449724 -0.96619 -0.248445 v 0.467051 -0.941676 -0.225091 v 0.434084 -0.944734 -0.229624 v 0.454609 -0.963044 -0.212034 v 0.446174 -0.916406 -0.31306 v 0.484923 -0.891418 -0.370365 v 0.412944 -0.9234 -0.3704 v 0.448547 -0.950989 -0.393632 v 0.452237 -0.928373 -0.363494 v 0.0993217 -0.0437212 0.013039 v 0.117 -0.0326855 0.00843494 v 0.132956 0.0132675 -0.0162198 v 0.174393 0.0882332 -0.136154 v 0.172284 0.0767757 -0.0868099 v 0.171159 0.108829 -0.285049 v 0.00316311 -0.239694 -0.424384 v -0.0470776 -0.322356 -0.4651 v -0.206288 -0.446754 -0.598162 v -0.387411 -0.551928 -0.631445 v -0.577268 -0.63445 -0.594559 v -0.729255 -0.698028 -0.432784 v -0.756634 -0.767687 -0.272432 v -0.0792359 -0.255087 -0.536024 v -0.261572 -0.388817 -0.610832 v -0.427213 -0.493516 -0.610639 v -0.583787 -0.592222 -0.559713 v -0.7104 -0.676994 -0.421221 v -0.0270973 -0.190806 -0.492918 v -0.0579904 -0.180034 -0.514849 v -0.023407 -0.156609 -0.518012 v -0.0553017 -0.161248 -0.534214 v -0.0514006 -0.128001 -0.550258 v -0.00166942 -0.146557 -0.467385 v -0.00917302 -0.129371 -0.496679 v -0.035708 -0.118283 -0.496187 v 0.007117 -0.119214 -0.480547 v 0.0405405 -0.19309 -0.383492 v 0.0145679 -0.112326 -0.445964 v -0.0222824 -0.0805364 -0.516835 v -0.00671283 -0.090834 -0.457034 v -0.131445 -0.226655 -0.581046 v -0.161038 -0.199944 -0.592732 v -0.186729 -0.231417 -0.598092 v -0.191685 -0.214336 -0.630531 v -0.136365 -0.263962 -0.566109 v -0.184778 -0.254472 -0.576389 v -0.182881 -0.19432 -0.578199 v -0.199258 -0.209767 -0.609725 v -0.121833 -0.178909 -0.554037 v -0.100534 -0.145644 -0.553632 v -0.130584 -0.118546 -0.582259 v -0.109795 -0.124855 -0.567726 v -0.0574456 -0.0602397 -0.560046 v -0.0993393 -0.105314 -0.550575 v -0.0711524 -0.0882332 -0.579341 v -0.0723474 -0.144238 -0.524584 v -0.0709416 -0.0606088 -0.58203 v -0.069729 -0.0438443 -0.568077 v -0.0576565 -0.0340386 -0.537799 v -0.0776895 -0.0167997 -0.565898 v -0.0986539 -0.0506449 -0.559677 v -0.099761 -0.0857555 -0.573349 v -0.100692 -0.0549151 -0.613608 v -0.116982 -0.104435 -0.542157 v 0.00662496 -0.0410502 -0.463958 v -0.0404878 0.0115278 -0.520332 v -0.0445472 -0.0301902 -0.527414 v -0.0606439 0.0340737 -0.528099 v -0.0182758 -0.0848768 -0.478104 v -0.0715566 -0.026781 -0.521632 v -0.237427 -0.307929 -0.574316 v -0.176308 -0.333954 -0.587425 v -0.239694 -0.275841 -0.599304 v -0.156925 -0.283221 -0.579623 v -0.18947 -0.269655 -0.585211 v -0.144132 -0.116473 -0.542983 v 0.0806769 -0.0121428 -0.424314 v -0.00416476 0.0702035 -0.465505 v -0.0435982 0.121868 -0.484852 v -0.0251292 0.0236179 -0.502829 v -0.0629459 0.0179594 -0.50065 v -0.0487998 0.0939092 -0.497382 v -0.0861245 0.139528 -0.506537 v -0.0925386 0.109092 -0.482779 v 0.199487 0.100938 -0.197782 v 0.17738 0.0913612 -0.124627 v 0.19831 0.106421 -0.242382 v 0.175887 0.137174 -0.313728 v 0.206639 0.121463 -0.19787 v 0.162514 0.0891997 -0.289969 v 0.111763 0.0971251 -0.364724 v 0.147348 0.106263 -0.297948 v 0.154588 0.0526482 -0.320616 v 0.144045 0.11635 -0.363319 v 0.133835 0.100376 -0.371753 v 0.0854743 0.0908691 -0.411521 v 0.0331424 0.0769514 -0.462359 v 0.0567427 0.0864408 -0.42709 v 0.0578674 0.132394 -0.418814 v 0.0914666 0.115664 -0.319017 v 0.0016167 0.135241 -0.468404 v 0.0493445 0.109145 -0.391611 v 0.0489404 0.111588 -0.338225 v 0.0333533 0.106052 -0.420044 v 0.108635 0.131322 -0.399483 v 0.111939 0.116701 -0.338611 v 0.12431 0.125769 -0.350754 v 0.0719081 0.115612 -0.379767 v 0.181773 0.124222 -0.225758 v 0.173251 0.074421 -0.0969318 v 0.187168 0.0622078 -0.136506 v 0.161776 0.113239 -0.152321 v 0.156644 0.0894457 -0.11577 v 0.163533 0.173005 -0.186237 v 0.138052 0.21655 -0.187854 v 0.189839 0.314607 -0.241785 v 0.139194 0.129389 -0.254472 v 0.103065 0.216954 -0.298123 v 0.140635 0.300373 -0.309159 v 0.0359189 0.167785 -0.365445 v 0.0516114 0.260623 -0.381559 v 0.184603 0.382684 -0.320423 v 0.12243 0.350279 -0.409394 v 0.048132 0.337785 -0.456929 v 0.0643166 0.384441 -0.477665 v -0.0773381 0.303975 -0.46568 v 0.00256563 0.170052 -0.349875 v -0.0538783 0.223702 -0.407795 v -0.0493797 0.267019 -0.444101 v -0.0796753 0.25999 -0.437142 v 0.0692721 0.35274 -0.468861 v 0.0275191 0.374653 -0.486399 v 0.0205427 0.1086 -0.41363 v -0.0501353 0.13879 -0.453133 v -0.0464977 0.100271 -0.41247 v -0.0154465 0.130267 -0.371507 v -0.0440024 0.319562 -0.428795 v 0.0268162 0.364338 -0.458932 v -0.00581661 0.351791 -0.455365 v 0.0063438 0.282782 -0.404316 v -0.0853337 0.271272 -0.362405 v -0.10846 0.346167 -0.416951 v -0.0374653 0.295681 -0.386321 v -0.0625417 0.206727 -0.376322 v -0.0438442 0.287351 -0.433715 v 0.0339859 0.382596 -0.465118 v 0.00667768 0.391382 -0.464749 v -0.070801 0.407426 -0.540962 v -0.0435104 0.41254 -0.534267 v -0.0234422 0.43969 -0.521738 v -0.0482902 0.500281 -0.651337 v -0.0672513 0.516044 -0.644853 v -0.0307876 0.517503 -0.637455 v -0.0628756 0.544547 -0.724528 v -0.0640882 0.538362 -0.701508 v -0.0449865 0.543862 -0.711173 v -0.0430886 0.519154 -0.686553 v -0.0613995 0.531069 -0.681756 v -0.0303483 0.535427 -0.679946 v -0.0533863 0.527115 -0.708256 v -0.0242681 0.461129 -0.514744 v -0.0612941 0.537131 -0.637367 v -0.0400309 0.539012 -0.633325 v -0.0557762 0.551488 -0.705216 v -0.0525076 0.548237 -0.678892 v -0.0398552 0.548835 -0.678206 v -0.081907 0.478157 -0.513935 v -0.106122 0.434717 -0.514796 v -0.0461814 0.483745 -0.512512 v 0.00878642 0.425755 -0.450708 v -0.115998 0.394985 -0.40161 v -0.0658279 0.470935 -0.449812 v -0.0820652 0.444083 -0.422504 v 0.0177661 0.620304 -0.538432 v -0.03859 0.617158 -0.559537 v -0.0890064 0.628668 -0.521052 v 0.0423505 0.613222 -0.466664 v 0.0536323 0.686571 -0.536639 v -0.00625593 0.673022 -0.629178 v -0.0384669 0.699329 -0.6254 v 0.0489579 0.721295 -0.585 v -0.0350051 0.73755 -0.597828 v -0.0781464 0.71228 -0.518996 v 0.0140231 0.706112 -0.49993 v 0.00576389 0.754613 -0.580378 v -0.0378695 0.747759 -0.522247 v -0.053193 0.699698 -0.395407 v -0.10556 0.682195 -0.37279 v -0.104717 0.669894 -0.489984 v -0.0573753 0.708238 -0.465838 v -0.0261484 0.723351 -0.526465 v -0.0811865 0.691825 -0.525797 v -0.0417882 0.721804 -0.493656 v 0.00660739 0.685288 -0.375514 v -0.00962992 0.716515 -0.512354 v -0.00961234 0.688381 -0.444909 v 0.0383615 0.66833 -0.415703 v 0.026658 0.667786 -0.464433 v -0.0246723 0.706305 -0.348962 v -0.0683584 0.702334 -0.313992 v -0.0517344 0.7256 -0.393684 v 0.0405933 0.695129 -0.611465 v 0.0352335 0.757073 -0.577654 v 0.0150951 0.756932 -0.695357 v -0.0106491 0.764612 -0.688803 v 0.0508909 0.803922 -0.669314 v -0.0103504 0.805117 -0.665255 v 0.0397146 0.765596 -0.681141 v 0.0453731 0.815397 -0.652567 v 0.0115454 0.808333 -0.736443 v 0.0245493 0.863863 -0.72184 v 0.042333 0.823586 -0.724862 v 0.0454082 0.855165 -0.714635 v 0.0204724 0.825221 -0.653516 v 0.00950691 0.847573 -0.734404 v 0.0500826 0.845324 -0.794099 v 0.0562331 0.855147 -0.78765 v 0.037518 0.866833 -0.782062 v 0.0372193 0.854198 -0.790409 v 0.0508558 0.857291 -0.809458 v -0.115981 0.531051 -0.427653 v -0.0912382 0.489737 -0.433873 v -0.149598 0.450497 -0.476435 v -0.14299 0.513847 -0.468949 v -0.202931 0.499982 -0.518047 v -0.201086 0.521492 -0.515271 v 0.24551 0.627122 -0.204091 v -0.0693424 0.71286 -0.356043 v -0.0400134 0.70808 -0.365023 v -0.00474467 0.733877 -0.327874 v -0.0193301 0.755263 -0.270218 v 0.0036903 0.780181 -0.243208 v 0.0229326 0.74602 -0.328753 v 0.0102098 0.754086 -0.299599 v 0.00609778 0.719309 -0.329983 v 0.0434576 0.75992 -0.30206 v 0.0336344 0.728377 -0.324201 v 0.0531227 0.749165 -0.295522 v 0.0597301 0.793361 -0.261589 v 0.0312621 0.774259 -0.225389 v 0.0324395 0.725214 -0.389414 v 0.0169051 0.697308 -0.400467 v -0.00803079 0.556391 -0.494851 v 0.0222648 0.52302 -0.523969 v -0.00615049 0.534162 -0.561224 v -0.0252697 0.499192 -0.523231 v -0.0669877 0.58876 -0.508066 v -0.125417 0.567093 -0.430728 v 0.042825 0.750641 -0.284592 v 0.061628 0.772854 -0.233508 v 0.0597828 0.765438 -0.269286 v 0.0325976 0.812586 -0.209451 v 0.065986 0.777791 -0.199803 v 0.0765473 0.852494 -0.202088 v 0.0429129 0.830651 -0.188346 v 0.073349 0.858293 -0.18158 v 0.0397498 0.837978 -0.164499 v 0.0480969 0.863108 -0.110902 v 0.0721189 0.858996 -0.130742 v 0.0882508 0.835413 -0.0971251 v 0.0114399 0.790057 -0.23588 v 0.0655643 0.817155 -0.217868 v 0.076969 0.750589 -0.313306 v 0.0968439 0.77686 -0.299687 v 0.105226 0.724177 -0.29243 v 0.0745088 0.727182 -0.342143 v 0.103662 0.737919 -0.272274 v 0.0993393 0.720768 -0.328208 v 0.0754929 0.7437 -0.336907 v 0.109865 0.748111 -0.327944 v 0.0984255 0.737075 -0.311426 v 0.0810811 0.760693 -0.274699 v 0.0665483 0.757688 -0.255263 v 0.121094 0.716146 -0.278178 v 0.117931 0.712403 -0.323235 v 0.0691316 0.846431 -0.0978456 v 0.0713985 0.870945 -0.125593 v 0.068868 0.826275 -0.191509 v 0.0580782 0.800214 -0.187871 v 0.086845 0.798914 -0.148578 v 0.114751 0.643904 -0.123924 v 0.148297 0.657769 -0.237269 v 0.101149 0.750343 -0.149756 v 0.10867 0.729361 -0.215478 v 0.125769 0.632622 -0.179788 v 0.183127 0.658788 -0.255931 v 0.213598 0.618933 -0.212913 v 0.2353 0.68701 -0.26043 v 0.246108 0.624381 -0.262942 v 0.246231 0.594612 -0.24428 v 0.134907 0.692247 -0.26716 v 0.15682 0.673374 -0.290022 v 0.14176 0.728904 -0.299564 v 0.14241 0.691157 -0.318385 v 0.0764946 0.682582 -0.44642 v 0.16898 0.688715 -0.44447 v 0.144554 0.645696 -0.50297 v 0.0820827 0.709943 -0.390381 v 0.0476224 0.665009 -0.471971 v 0.0828384 0.701191 -0.526412 v 0.115787 0.719748 -0.348944 v 0.120567 0.709556 -0.362791 v 0.105349 0.729378 -0.41196 v 0.143834 0.710558 -0.388746 v 0.114346 0.702105 -0.422346 v 0.136154 0.738569 -0.429164 v 0.16464 0.704442 -0.400221 v 0.15081 0.694602 -0.431659 v 0.127842 0.713352 -0.399431 v 0.20207 0.501476 -0.500211 v 0.160106 0.53193 -0.529821 v 0.158015 0.590377 -0.519488 v 0.223896 0.560995 -0.485028 v 0.256563 0.454416 -0.452413 v 0.265016 0.527994 -0.443749 v 0.244895 0.63814 -0.399466 v 0.256599 0.444646 -0.385179 v 0.261027 0.474555 -0.31429 v 0.207096 0.454434 -0.539117 v 0.134731 0.469335 -0.554212 v 0.246319 0.427196 -0.491178 v 0.203335 0.399448 -0.562718 v 0.258989 0.384687 -0.510315 v 0.276473 0.37272 -0.454065 v 0.228974 0.39625 -0.360278 v 0.253207 0.32812 -0.415615 v 0.237128 0.345201 -0.636998 v 0.313095 0.320775 -0.570081 v 0.278846 0.350262 -0.607915 v 0.193477 0.292799 -0.652023 v 0.138333 0.431976 -0.568886 v 0.150529 0.375584 -0.569465 v 0.0929076 0.432819 -0.542017 v 0.278477 0.478895 -0.362194 v 0.20316 0.651619 -0.462851 v 0.274787 0.562858 -0.330475 v 0.265578 0.603855 -0.31603 v 0.261045 0.516518 -0.253102 v 0.328911 0.233965 -0.682055 v 0.267494 0.304783 -0.533037 v 0.266896 0.292605 -0.516255 v 0.264665 0.29851 -0.495835 v 0.298281 0.285225 -0.544828 v 0.274013 0.333814 -0.537799 v 0.173778 0.317612 -0.624205 v 0.408217 0.176133 -0.686571 v 0.341563 0.162848 -0.698169 v 0.36258 0.179032 -0.699821 v 0.365058 0.133571 -0.711577 v 0.380136 0.147313 -0.71358 v 0.390925 0.132851 -0.712298 v 0.293062 0.194742 -0.677925 v 0.242277 0.250431 -0.672249 v 0.282694 0.274294 -0.677486 v 0.329842 0.292008 -0.639335 v 0.202474 0.24008 -0.656521 v 0.147296 0.283292 -0.616033 v 0.15617 0.267423 -0.634046 v 0.112185 0.350402 -0.549872 v 0.200401 0.21242 -0.637771 v 0.139212 0.26289 -0.600622 v 0.150617 0.245036 -0.619566 v 0.364531 0.115418 -0.701121 v 0.336063 0.14849 -0.686905 v 0.285084 0.167258 -0.658419 v 0.125576 0.283098 -0.573331 v 0.134274 0.307261 -0.593628 v 0.138597 0.37706 -0.411363 v 0.0770921 0.39987 -0.484308 v 0.0934172 0.420325 -0.4011 v 0.0719608 0.423136 -0.473324 v 0.0955084 0.416072 -0.450866 v 0.0423681 0.409148 -0.500088 v 0.0506801 0.425087 -0.505377 v 0.015675 0.397744 -0.475047 v 0.0168524 0.426598 -0.462113 v 0.0130742 0.419675 -0.490862 v 0.0217727 0.438354 -0.516536 v 0.0273433 0.444013 -0.517538 v 0.0263241 0.441992 -0.475925 v 0.0241451 0.450005 -0.511581 v 0.0173795 0.444259 -0.507029 v 0.0509437 0.486276 -0.487154 v 0.0784276 0.575598 -0.52353 v 0.064176 0.613837 -0.497276 v 0.0314027 0.540769 -0.479809 v 0.0544231 0.526728 -0.505465 v 0.0159737 0.495642 -0.519945 v -0.00274136 0.50717 -0.547218 v 0.0469195 0.453713 -0.483359 v -0.0390293 0.540347 -0.467104 v -0.0466559 0.483991 -0.488384 v -0.0477103 0.51506 -0.489017 v -0.00442836 0.478684 -0.510755 v -0.00618564 0.540382 -0.538151 v -0.0295927 0.52585 -0.525006 v 0.105103 0.401504 -0.546972 v 0.104207 0.515816 -0.532932 v 0.0946122 0.458774 -0.492145 v 0.190279 0.441061 -0.330967 v 0.24117 0.472446 -0.223931 v 0.241345 0.485274 -0.25927 v 0.250237 0.511282 -0.227305 v 0.219573 0.280656 -0.478192 v 0.180069 0.338207 -0.41066 v 0.175535 0.389432 -0.375514 v 0.206165 0.45772 -0.26665 v 0.197782 0.47111 -0.320529 v 0.107388 0.326697 -0.496327 v 0.0789372 0.389432 -0.516852 v 0.179155 0.218009 -0.559572 v 0.14589 0.253084 -0.530506 v 0.317014 0.141936 -0.644554 v 0.245334 0.179243 -0.609971 v 0.346747 0.156943 -0.603592 v 0.270323 0.183056 -0.542403 v 0.369364 0.244579 -0.650564 v 0.32689 0.221769 -0.549643 v 0.38604 0.180666 -0.601237 v 0.425649 0.174639 -0.626156 v 0.287474 0.258268 -0.525024 v 0.274804 0.215232 -0.512705 v 0.311602 0.188767 -0.545812 v 0.184181 0.305539 -0.441377 v 0.130197 0.35998 -0.470566 v 0.195814 0.251643 -0.495115 v 0.247812 0.251415 -0.492145 v 0.434506 0.136682 -0.691509 v 0.435929 0.145978 -0.608934 v 0.408498 0.156117 -0.605332 v 0.438319 0.0318771 -0.703652 v 0.476294 0.0384669 -0.672354 v 0.495976 0.0486416 -0.630812 v 0.498823 0.0632798 -0.604172 v 0.402611 0.0256212 -0.716831 v 0.518399 0.0263768 -0.614206 v 0.52049 0.039943 -0.594243 v 0.552209 -0.00880402 -0.600868 v 0.555829 -0.000369045 -0.588655 v 0.56523 -0.0182758 -0.601606 v 0.571574 -0.0077145 -0.587196 v 0.581064 -0.0372896 -0.593593 v 0.584068 -0.030401 -0.58022 v 0.596633 -0.0694479 -0.582803 v 0.600341 -0.0983025 -0.568517 v 0.605156 -0.0864935 -0.546041 v 0.605964 -0.0835413 -0.561874 v 0.602573 -0.0602046 -0.564914 v 0.461217 0.0783397 -0.548659 v 0.41261 0.136242 -0.587513 v 0.528029 0.0128106 -0.569202 v 0.565881 -0.017854 -0.567462 v 0.595175 -0.0921344 -0.536921 v 0.592767 -0.0619619 -0.548747 v 0.602169 -0.120813 -0.553703 v 0.608108 -0.107915 -0.536639 v 0.616016 -0.11034 -0.550996 v 0.614013 -0.136734 -0.534583 v 0.394229 0.109215 -0.580695 v 0.376797 0.0783046 -0.624732 v 0.402014 0.0526834 -0.590641 v 0.391523 0.0777422 -0.580132 v 0.374794 0.125646 -0.617668 v 0.128036 0.164921 -0.286455 v 0.0497311 0.209609 -0.381893 v -0.020982 0.232278 -0.427002 v 0.102063 0.264014 -0.357713 v 0.18882 0.668875 -0.281447 v 0.216779 0.690577 -0.297807 v 0.236794 0.652673 -0.299213 v 0.217271 0.672934 -0.273504 v 0.197413 0.685763 -0.367044 v 0.218466 0.689558 -0.39089 v 0.226883 0.66594 -0.366218 v 0.165167 0.703265 -0.356817 v 0.182951 0.697255 -0.355094 v 0.202404 0.672249 -0.331389 v 0.159069 0.690542 -0.332654 v 0.173409 0.718518 -0.338752 v 0.155484 0.696394 -0.348065 v 0.147647 0.708326 -0.370348 v 0.176554 0.726742 -0.379538 v 0.179366 0.696781 -0.394897 v 0.22437 0.658402 -0.336625 v 0.212631 0.695357 -0.351105 v 0.172003 0.674217 -0.301568 v 0.165237 0.682476 -0.314554 v 0.166397 0.689154 -0.297596 v 0.158226 0.68513 -0.30749 v 0.21648 0.666011 -0.314905 v 0.213405 0.678259 -0.327575 v 0.200313 0.667206 -0.318982 v 0.17789 0.675869 -0.31712 v 0.228377 0.650371 -0.320915 v 0.200225 0.682301 -0.395336 v 0.576389 -0.080923 -0.580572 v 0.588022 -0.105455 -0.568042 v 0.507715 -0.0106667 -0.609479 v 0.553615 -0.0340386 -0.602766 v 0.581889 -0.0992339 -0.537518 v 0.573736 -0.0651425 -0.551664 v 0.564932 -0.0792008 -0.57175 v 0.57783 -0.108758 -0.55618 v 0.602344 -0.111025 -0.53548 v 0.598461 -0.12062 -0.551611 v 0.609918 -0.130689 -0.532211 v 0.605964 -0.135733 -0.538572 v 0.545689 -0.0302077 -0.563122 v 0.505377 -0.0027238 -0.569747 v 0.535761 -0.0454961 -0.586107 v 0.609426 -0.141075 -0.530559 v 0.413067 0.126893 -0.532193 v 0.438056 0.116877 -0.536059 v 0.432784 0.101799 -0.505571 v 0.408252 0.109461 -0.50188 v 0.43187 0.0954732 -0.489439 v 0.407268 0.104857 -0.486328 v 0.429498 0.0848065 -0.475011 v 0.402594 0.092644 -0.472235 v 0.409693 0.0749657 -0.45243 v 0.425421 0.0643869 -0.447686 v 0.392542 0.0690437 -0.44816 v 0.392981 0.10129 -0.551137 v 0.391171 0.092644 -0.493305 v 0.379644 0.0546867 -0.453168 v 0.410537 0.0548624 -0.420413 v 0.420096 0.044881 -0.427284 v 0.393684 0.0560749 -0.427038 v 0.405335 0.0327558 -0.401979 v 0.407954 0.0237409 -0.407145 v 0.393948 0.0289249 -0.407303 v 0.433575 0.0765121 -0.495009 v 0.428057 0.0499947 -0.45786 v 0.392577 0.0409798 -0.465469 v 0.415598 0.037026 -0.465522 v 0.393122 0.0375004 -0.448652 v 0.413717 0.0333357 -0.449021 v 0.392612 0.0513654 -0.430043 v 0.419692 0.0395389 -0.434225 v 0.421678 0.0610305 -0.500685 v 0.397058 0.0669876 -0.500879 v 0.436931 0.0567075 -0.547324 v 0.399765 0.0241451 -0.400485 v 0.494289 0.0443187 -0.56755 v 0.401188 0.0382385 -0.628335 v 0.473412 0.0279935 -0.564106 v 0.435824 0.025709 -0.587372 v 0.501283 0.00789019 -0.642639 v 0.491723 0.00207358 -0.657488 v 0.510737 -0.0610481 -0.639722 v 0.520174 -0.0554072 -0.626876 v 0.514164 -0.0838225 -0.6364 v 0.527765 -0.0760728 -0.61953 v 0.507785 -0.104348 -0.623168 v 0.518996 -0.101378 -0.603047 v 0.501529 -0.143728 -0.601536 v 0.513478 -0.139493 -0.587847 v 0.505342 -0.16218 -0.583243 v 0.487717 -0.170878 -0.587038 v 0.504903 -0.162109 -0.564264 v 0.50188 -0.0136717 -0.614311 v 0.513355 -0.0773381 -0.596071 v 0.508224 -0.131339 -0.576143 v 0.495361 -0.152532 -0.553703 v 0.495484 -0.191245 -0.56581 v 0.475257 -0.189646 -0.56581 v 0.492373 -0.181809 -0.551155 v 0.474115 -0.201262 -0.545549 v 0.466787 -0.192827 -0.549784 v 0.47517 -0.190911 -0.543879 v 0.493481 -0.0884968 -0.631146 v 0.479809 -0.136348 -0.603434 v 0.47278 -0.166169 -0.583664 v 0.473483 -0.0254279 -0.650072 v 0.479949 -0.154184 -0.551875 v 0.492549 -0.119197 -0.569835 v 0.470759 -0.125066 -0.589569 v 0.463097 -0.160616 -0.569518 v 0.488384 -0.174779 -0.551735 v 0.471796 -0.181334 -0.564141 v 0.478262 -0.0850526 -0.614311 v 0.497171 -0.0737357 -0.592451 v 0.483763 -0.0229677 -0.595385 v 0.467016 -0.197132 -0.540822 v 0.470776 -0.00569362 -0.674639 v 0.455576 -0.00808352 -0.687573 v 0.457562 -0.0733666 -0.665027 v 0.467402 -0.0675676 -0.653464 v 0.455769 -0.0879169 -0.661635 v 0.470038 -0.0832074 -0.649334 v 0.445876 -0.107827 -0.643447 v 0.457509 -0.103662 -0.63257 v 0.426387 -0.129846 -0.616297 v 0.435771 -0.1254 -0.604471 v 0.420694 -0.134749 -0.599445 v 0.406196 -0.136594 -0.599111 v 0.418181 -0.127561 -0.582469 v 0.469757 -0.0288019 -0.651443 v 0.457685 -0.0812744 -0.626296 v 0.429955 -0.110849 -0.594085 v 0.411292 -0.118142 -0.574614 v 0.402084 -0.143799 -0.577971 v 0.387991 -0.140214 -0.580677 v 0.403631 -0.133483 -0.566566 v 0.370189 -0.138509 -0.551611 v 0.438882 -0.0935754 -0.653481 v 0.408832 -0.121182 -0.618406 v 0.394791 -0.129406 -0.599779 v 0.432222 -0.0367624 -0.671107 v 0.400467 -0.108987 -0.576389 v 0.4234 -0.0987067 -0.600446 v 0.411257 -0.100921 -0.615489 v 0.38829 -0.117703 -0.592099 v 0.397691 -0.126823 -0.566812 v 0.386198 -0.133536 -0.581274 v 0.428074 -0.0769866 -0.642656 v 0.446772 -0.0745264 -0.62366 v 0.420026 -0.0341792 -0.657347 v 0.453063 -0.0321583 -0.62793 v 0.358662 0.0625769 -0.692915 v 0.377957 0.0218782 -0.692651 v 0.349471 0.110709 -0.671283 v 0.375655 0.085404 -0.71235 v 0.441219 -0.00864585 -0.693635 v 0.424613 -0.0115629 -0.703652 v 0.418954 -0.0527713 -0.696113 v 0.426528 -0.0531227 -0.687028 v 0.410853 -0.0766528 -0.68933 v 0.42101 -0.0754051 -0.679753 v 0.395758 -0.0803079 -0.675939 v 0.404439 -0.0834359 -0.666995 v 0.376322 -0.0832777 -0.655028 v 0.387007 -0.0848417 -0.646505 v 0.375022 -0.0797983 -0.639458 v 0.362422 -0.064053 -0.639335 v 0.378642 -0.0719959 -0.628844 v 0.428391 -0.0369909 -0.67181 v 0.419815 -0.0633677 -0.67072 v 0.394247 -0.0771096 -0.644677 v 0.383088 -0.0658806 -0.628563 v 0.35636 -0.0587812 -0.613714 v 0.355235 -0.0525955 -0.619847 v 0.36852 -0.0550733 -0.613819 v 0.354901 -0.0347767 -0.601184 v 0.397287 -0.0588515 -0.689084 v 0.371015 -0.0659685 -0.659878 v 0.362633 -0.0551084 -0.642709 v 0.404 -0.0135311 -0.696763 v 0.383439 -0.0591853 -0.632306 v 0.393509 -0.0707659 -0.647946 v 0.377711 -0.0597828 -0.657962 v 0.370049 -0.0449338 -0.640056 v 0.370576 -0.0505219 -0.615225 v 0.356518 -0.0494676 -0.621358 v 0.393069 -0.0537729 -0.676853 v 0.414438 -0.0587636 -0.664763 v 0.391488 -0.0168172 -0.680877 v 0.410484 0.0641409 -0.552121 v 0.102871 0.658261 -0.0631041 v 0.121024 0.65146 -0.094208 v 0.127596 0.573472 -0.0729976 v 0.0750185 0.581661 -0.0556708 v 0.104998 0.578059 -0.0594314 v 0.102871 0.655291 -0.00917304 v 0.0840509 0.604927 -0.0374478 v 0.106509 0.598566 -0.0755281 v 0.129529 0.604207 -0.100341 v 0.123695 0.779303 -0.0699751 v 0.101606 0.7146 -0.016044 v 0.118125 0.805346 -0.0877764 v 0.0132675 0.865726 -0.0939093 v 0.0375356 0.9221 -0.06755 v 0.0895336 0.896338 -0.0741398 v 0.0928022 0.85223 -0.0353917 v 0.0770218 0.841265 0.0080132 v 0.0623836 0.925737 -0.102204 v 0.00576389 0.967736 -0.108618 v 0.0187502 0.960936 -0.130514 v 0.00847011 1 -0.14176 v 0.0176431 0.992479 -0.15067 v 0.0718026 0.877131 -0.108793 v 0.0532633 0.90117 -0.126155 v 0.0110357 0.945524 -0.144625 v 0.00553544 0.985608 -0.159561 v 0.0123889 0.888413 -0.108073 v -0.0163076 0.936334 -0.134467 v -0.00506098 0.990493 -0.153077 v -0.0194707 0.963659 -0.143588 v -0.00254806 0.999104 -0.144537 v -0.0197167 0.973852 -0.128282 v 0.000421748 0.861139 -0.044389 v 0.000474467 0.90219 -0.0739993 v -0.0196113 0.946561 -0.111166 v 0.0279935 0.891593 -0.120286 v 0.0138123 0.848592 0.00926086 v 0.00954205 0.91674 -0.0609251 v -0.00832953 0.969054 -0.108829 v 0.00736302 0.999157 -0.157558 v 0.123379 0.805363 -0.0418761 v 0.110551 0.823077 0.0101395 v 0.214248 0.782255 0.0628932 v 0.220838 0.756809 -0.0141989 v 0.28656 0.729993 0.091572 v 0.298563 0.657189 0.0578498 v 0.289899 0.69244 0.116719 v 0.259674 0.63155 0.114821 v 0.257003 0.670474 0.147348 v 0.138281 0.580607 0.187291 v 0.189506 0.605332 0.167926 v 0.189962 0.628422 0.185587 v 0.159913 0.742822 0.100675 v 0.213088 0.703125 0.11577 v 0.129547 0.581643 0.181334 v 0.164605 0.63619 0.1684 v 0.103943 0.889977 -0.00834712 v 0.122571 0.903332 0.0329491 v 0.0952799 0.861807 0.0758092 v 0.136067 0.903982 -0.0210347 v 0.147594 0.920255 0.000667753 v 0.184005 0.905493 -0.034144 v 0.0506976 0.891224 0.0661969 v 0.0925562 0.928127 0.0242681 v 0.127632 0.937652 -0.00801324 v 0.167504 0.918901 -0.034847 v 0.0749482 0.907971 -0.000333902 v 0.0480969 0.851843 0.00903242 v 0.0766527 0.893017 -0.00741575 v 0.107317 0.92398 -0.0217025 v 0.161231 0.904509 -0.031104 v 0.168506 0.916441 -0.02172 v 0.0276421 0.872825 0.0308052 v 0.00883914 0.827734 0.0575335 v 0.0361825 0.863828 0.0831547 v 0.156451 0.720609 -0.00374304 v 0.153674 0.694197 0.0563736 v 0.290532 0.680332 0.0269743 v 0.220188 0.660299 0.0603451 v 0.231505 0.700858 0.00569359 v 0.217956 0.637384 0.0884441 v 0.173215 0.606333 0.137455 v 0.142867 0.570274 0.177082 v 0.139282 0.574474 0.167873 v 0.2104 0.681809 0.130127 v 0.131656 0.570344 0.179858 v 0.0881278 0.595016 0.00268863 v 0.128264 0.558201 0.0246547 v 0.115524 0.533617 0.0411731 v 0.11584 0.527484 0.0417179 v 0.0849823 0.499508 0.039328 v 0.0874952 0.557604 0.0307173 v 0.0989878 0.529944 0.0420518 v 0.0950866 0.486961 0.0309282 v 0.388992 0.221172 -0.621499 v 0.347503 0.278723 -0.594384 v 0.230767 0.771711 0.0179946 v 0.300162 0.706305 0.0577268 v 0.302516 0.67666 0.0889713 v 0.153604 0.703757 0.0845605 v 0.203054 0.674428 0.0836819 v 0.202193 0.658525 0.101026 v 0.182863 0.693741 0.0835061 v 0.192844 0.679717 0.0521562 # 2519 vertices vt 0.644 0.154 0.599 vt 0.632 0.188 0.600 vt 0.640 0.183 0.600 vt 0.656 0.168 0.599 vt 0.643 0.221 0.601 vt 0.656 0.202 0.601 vt 0.639 0.194 0.600 vt 0.621 0.228 0.601 vt 0.586 0.119 0.597 vt 0.562 0.130 0.598 vt 0.578 0.188 0.600 vt 0.615 0.158 0.599 vt 0.614 0.081 0.598 vt 0.644 0.095 0.597 vt 0.695 0.188 0.602 vt 0.671 0.180 0.600 vt 0.673 0.195 0.601 vt 0.684 0.201 0.602 vt 0.647 0.189 0.600 vt 0.595 0.214 0.600 vt 0.703 0.208 0.602 vt 0.713 0.199 0.602 vt 0.719 0.214 0.603 vt 0.724 0.204 0.603 vt 0.715 0.196 0.602 vt 0.728 0.196 0.602 vt 0.735 0.206 0.602 vt 0.734 0.198 0.602 vt 0.734 0.218 0.603 vt 0.730 0.165 0.600 vt 0.731 0.189 0.602 vt 0.734 0.188 0.602 vt 0.733 0.162 0.600 vt 0.734 0.227 0.602 vt 0.716 0.218 0.603 vt 0.703 0.212 0.603 vt 0.717 0.236 0.602 vt 0.702 0.230 0.602 vt 0.694 0.221 0.602 vt 0.697 0.257 0.602 vt 0.682 0.239 0.602 vt 0.673 0.225 0.602 vt 0.734 0.260 0.602 vt 0.710 0.276 0.602 vt 0.637 0.273 0.601 vt 0.598 0.264 0.601 vt 0.659 0.309 0.601 vt 0.704 0.152 0.599 vt 0.706 0.125 0.597 vt 0.682 0.130 0.598 vt 0.677 0.154 0.599 vt 0.719 0.150 0.599 vt 0.733 0.122 0.597 vt 0.703 0.187 0.602 vt 0.703 0.177 0.601 vt 0.699 0.172 0.601 vt 0.707 0.175 0.602 vt 0.711 0.186 0.606 vt 0.717 0.188 0.606 vt 0.706 0.173 0.601 vt 0.717 0.161 0.601 vt 0.730 0.159 0.599 vt 0.624 0.324 0.601 vt 0.578 0.291 0.600 vt 0.734 0.303 0.601 vt 0.700 0.310 0.601 vt 0.715 0.317 0.601 vt 0.673 0.210 0.602 vt 0.692 0.216 0.602 vt 0.691 0.211 0.602 vt 0.641 0.070 0.597 vt 0.662 0.081 0.596 vt 0.676 0.098 0.596 vt 0.705 0.093 0.595 vt 0.733 0.096 0.595 vt 0.686 0.077 0.596 vt 0.704 0.073 0.595 vt 0.733 0.077 0.595 vt 0.711 0.057 0.595 vt 0.697 0.054 0.595 vt 0.661 0.057 0.597 vt 0.682 0.060 0.596 vt 0.674 0.039 0.597 vt 0.670 0.043 0.597 vt 0.694 0.044 0.596 vt 0.719 0.033 0.595 vt 0.711 0.023 0.596 vt 0.733 0.053 0.594 vt 0.734 0.032 0.594 vt 0.275 0.976 0.506 vt 0.271 0.991 0.510 vt 0.241 0.990 0.536 vt 0.236 0.970 0.540 vt 0.325 0.976 0.455 vt 0.322 0.987 0.457 vt 0.299 0.955 0.477 vt 0.305 0.955 0.472 vt 0.302 0.969 0.479 vt 0.339 0.984 0.440 vt 0.336 0.990 0.443 vt 0.733 0.014 0.595 vt 0.727 0.011 0.596 vt 0.298 0.668 0.427 vt 0.321 0.707 0.450 vt 0.332 0.693 0.450 vt 0.323 0.665 0.434 vt 0.339 0.678 0.447 vt 0.337 0.640 0.426 vt 0.307 0.634 0.413 vt 0.288 0.655 0.417 vt 0.352 0.621 0.416 vt 0.352 0.584 0.395 vt 0.333 0.597 0.401 vt 0.320 0.616 0.409 vt 0.597 0.747 -0.465 vt 0.621 0.733 -0.465 vt 0.638 0.776 -0.437 vt 0.611 0.783 -0.437 vt 0.648 0.761 -0.440 vt 0.645 0.778 -0.437 vt 0.644 0.754 -0.446 vt 0.579 0.752 -0.465 vt 0.590 0.787 -0.440 vt 0.542 0.754 -0.462 vt 0.556 0.791 -0.451 vt 0.606 0.693 -0.456 vt 0.634 0.678 -0.468 vt 0.643 0.715 -0.465 vt 0.572 0.710 -0.457 vt 0.571 0.695 -0.460 vt 0.593 0.685 -0.461 vt 0.563 0.668 -0.455 vt 0.566 0.684 -0.426 vt 0.561 0.686 -0.437 vt 0.553 0.670 -0.459 vt 0.547 0.707 -0.450 vt 0.554 0.695 -0.446 vt 0.541 0.682 -0.446 vt 0.525 0.688 -0.442 vt 0.556 0.654 -0.501 vt 0.569 0.652 -0.505 vt 0.576 0.668 -0.453 vt 0.603 0.655 -0.496 vt 0.586 0.664 -0.492 vt 0.585 0.658 -0.494 vt 0.595 0.649 -0.493 vt 0.577 0.651 -0.498 vt 0.586 0.642 -0.488 vt 0.577 0.645 -0.494 vt 0.570 0.634 -0.513 vt 0.582 0.634 -0.511 vt 0.563 0.651 -0.516 vt 0.557 0.631 -0.502 vt 0.521 0.674 -0.487 vt 0.533 0.670 -0.497 vt 0.588 0.624 -0.500 vt 0.564 0.611 -0.444 vt 0.609 0.620 -0.451 vt 0.597 0.626 -0.482 vt 0.454 0.857 -0.466 vt 0.462 0.834 -0.465 vt 0.497 0.846 -0.461 vt 0.485 0.886 -0.467 vt 0.525 0.846 -0.458 vt 0.518 0.777 -0.462 vt 0.563 0.844 -0.459 vt 0.645 0.790 -0.437 vt 0.643 0.805 -0.440 vt 0.636 0.805 -0.444 vt 0.640 0.813 -0.425 vt 0.650 0.809 -0.442 vt 0.644 0.817 -0.430 vt 0.653 0.790 -0.438 vt 0.657 0.776 -0.440 vt 0.654 0.769 -0.436 vt 0.467 0.802 -0.465 vt 0.470 0.774 -0.467 vt 0.499 0.775 -0.465 vt 0.498 0.818 -0.462 vt 0.661 0.741 -0.451 vt 0.651 0.753 -0.447 vt 0.517 0.713 -0.454 vt 0.544 0.728 -0.465 vt 0.512 0.735 -0.456 vt 0.499 0.707 -0.479 vt 0.386 0.562 -0.685 vt 0.424 0.552 -0.685 vt 0.411 0.596 -0.685 vt 0.388 0.597 -0.685 vt 0.423 0.813 -0.467 vt 0.431 0.768 -0.467 vt 0.441 0.742 -0.469 vt 0.449 0.721 -0.469 vt 0.460 0.745 -0.469 vt 0.456 0.760 -0.468 vt 0.408 0.746 -0.469 vt 0.413 0.734 -0.469 vt 0.667 0.706 -0.465 vt 0.670 0.722 -0.461 vt 0.430 0.709 -0.454 vt 0.397 0.522 -0.685 vt 0.389 0.523 -0.685 vt 0.387 0.496 -0.685 vt 0.395 0.491 -0.685 vt 0.389 0.442 -0.685 vt 0.409 0.461 -0.685 vt 0.384 0.469 -0.685 vt 0.367 0.448 -0.685 vt 0.457 0.478 -0.685 vt 0.437 0.450 -0.685 vt 0.453 0.440 -0.697 vt 0.468 0.464 -0.696 vt 0.445 0.513 -0.685 vt 0.425 0.499 -0.685 vt 0.477 0.499 -0.685 vt 0.495 0.484 -0.696 vt 0.497 0.445 -0.646 vt 0.510 0.452 -0.642 vt 0.423 0.527 -0.685 vt 0.462 0.528 -0.685 vt 0.474 0.542 -0.685 vt 0.445 0.562 -0.685 vt 0.367 0.420 -0.685 vt 0.334 0.432 -0.685 vt 0.351 0.404 -0.685 vt 0.323 0.418 -0.685 vt 0.422 0.427 -0.685 vt 0.395 0.403 -0.685 vt 0.474 0.760 -0.468 vt 0.493 0.756 -0.468 vt 0.379 0.470 -0.685 vt 0.447 0.388 -0.709 vt 0.448 0.419 -0.705 vt 0.485 0.401 -0.627 vt 0.480 0.420 -0.637 vt 0.478 0.587 -0.685 vt 0.496 0.568 -0.685 vt 0.486 0.600 -0.685 vt 0.515 0.584 -0.685 vt 0.395 0.801 -0.468 vt 0.678 0.800 -0.452 vt 0.660 0.758 -0.446 vt 0.688 0.779 -0.457 vt 0.706 0.767 -0.457 vt 0.467 0.627 -0.685 vt 0.501 0.611 -0.685 vt 0.487 0.631 -0.685 vt 0.538 0.562 -0.685 vt 0.550 0.583 -0.685 vt 0.528 0.603 -0.685 vt 0.513 0.398 -0.667 vt 0.523 0.406 -0.679 vt 0.502 0.418 -0.600 vt 0.496 0.414 -0.604 vt 0.521 0.549 -0.685 vt 0.508 0.511 -0.685 vt 0.486 0.431 -0.620 vt 0.506 0.432 -0.616 vt 0.527 0.421 -0.676 vt 0.545 0.559 -0.712 vt 0.584 0.532 -0.709 vt 0.583 0.550 -0.708 vt 0.551 0.566 -0.701 vt 0.612 0.550 -0.709 vt 0.598 0.562 -0.709 vt 0.589 0.564 -0.710 vt 0.594 0.551 -0.709 vt 0.598 0.537 -0.709 vt 0.611 0.577 -0.710 vt 0.610 0.570 -0.709 vt 0.619 0.561 -0.709 vt 0.617 0.570 -0.710 vt 0.589 0.577 -0.701 vt 0.629 0.566 -0.710 vt 0.625 0.558 -0.709 vt 0.632 0.555 -0.709 vt 0.632 0.565 -0.709 vt 0.620 0.536 -0.709 vt 0.576 0.387 -0.709 vt 0.605 0.396 -0.709 vt 0.603 0.416 -0.709 vt 0.574 0.413 -0.709 vt 0.609 0.439 -0.709 vt 0.570 0.439 -0.708 vt 0.620 0.466 -0.709 vt 0.572 0.467 -0.708 vt 0.572 0.490 -0.708 vt 0.623 0.493 -0.709 vt 0.538 0.492 -0.708 vt 0.531 0.463 -0.706 vt 0.555 0.509 -0.709 vt 0.623 0.515 -0.709 vt 0.627 0.419 -0.709 vt 0.647 0.429 -0.709 vt 0.524 0.437 -0.666 vt 0.521 0.356 -0.709 vt 0.554 0.364 -0.708 vt 0.662 0.494 -0.709 vt 0.661 0.511 -0.709 vt 0.681 0.501 -0.709 vt 0.680 0.507 -0.709 vt 0.752 0.685 -0.953 vt 0.738 0.692 -0.953 vt 0.731 0.679 -0.953 vt 0.746 0.673 -0.953 vt 0.726 0.671 -0.953 vt 0.742 0.665 -0.954 vt 0.721 0.659 -0.954 vt 0.737 0.654 -0.954 vt 0.716 0.649 -0.955 vt 0.733 0.642 -0.955 vt 0.720 0.620 -0.957 vt 0.711 0.625 -0.957 vt 0.705 0.612 -0.959 vt 0.710 0.605 -0.958 vt 0.700 0.603 -0.961 vt 0.703 0.601 -0.958 vt 0.699 0.629 -0.957 vt 0.694 0.612 -0.958 vt 0.695 0.604 -0.958 vt 0.713 0.676 -0.954 vt 0.698 0.655 -0.954 vt 0.749 0.652 -0.954 vt 0.756 0.664 -0.953 vt 0.681 0.514 -0.709 vt 0.665 0.524 -0.709 vt 0.766 0.677 -0.953 vt 0.684 0.487 -0.709 vt 0.694 0.494 -0.709 vt 0.717 0.692 -0.953 vt 0.748 0.630 -0.954 vt 0.766 0.647 -0.954 vt 0.722 0.614 -0.956 vt 0.733 0.611 -0.955 vt 0.778 0.662 -0.953 vt 0.695 0.631 -0.956 vt 0.690 0.637 -0.955 vt 0.678 0.661 -0.954 vt 0.674 0.640 -0.954 vt 0.747 0.602 -0.954 vt 0.762 0.619 -0.954 vt 0.720 0.599 -0.956 vt 0.733 0.598 -0.955 vt 0.677 0.627 -0.955 vt 0.686 0.617 -0.956 vt 0.718 0.610 -0.957 vt 0.711 0.598 -0.957 vt 0.695 0.626 -0.957 vt 0.688 0.610 -0.957 vt 0.696 0.597 -0.957 vt 0.414 0.480 -0.685 vt 0.360 0.450 -0.685 vt 0.331 0.436 -0.685 vt 0.652 0.454 -0.709 vt 0.698 0.676 -0.954 vt 0.682 0.679 -0.954 vt 0.773 0.634 -0.954 vt 0.695 0.697 -0.953 vt 0.679 0.699 -0.953 vt 0.793 0.639 -0.953 vt 0.788 0.651 -0.953 vt 0.861 0.723 -0.888 vt 0.883 0.735 -0.890 vt 0.863 0.747 -0.890 vt 0.848 0.731 -0.892 vt 0.845 0.726 -0.890 vt 0.855 0.720 -0.882 vt 0.840 0.719 -0.901 vt 0.848 0.713 -0.894 vt 0.833 0.714 -0.922 vt 0.844 0.708 -0.911 vt 0.826 0.685 -0.961 vt 0.820 0.689 -0.959 vt 0.810 0.676 -0.999 vt 0.816 0.672 -1.002 vt 0.813 0.691 -0.977 vt 0.801 0.679 -1.017 vt 0.831 0.733 -0.932 vt 0.823 0.719 -0.947 vt 0.835 0.680 -0.979 vt 0.855 0.694 -0.951 vt 0.859 0.711 -0.910 vt 0.864 0.716 -0.907 vt 0.869 0.703 -0.942 vt 0.808 0.696 -0.991 vt 0.809 0.722 -0.968 vt 0.794 0.706 -1.006 vt 0.848 0.669 -1.006 vt 0.862 0.685 -0.968 vt 0.825 0.666 -1.010 vt 0.824 0.676 -0.985 vt 0.816 0.666 -1.013 vt 0.803 0.685 -1.003 vt 0.795 0.684 -1.010 vt 0.796 0.678 -1.013 vt 0.817 0.738 -0.955 vt 0.876 0.697 -0.955 vt 0.668 0.471 -0.709 vt 0.672 0.442 -0.708 vt 0.691 0.461 -0.709 vt 0.848 0.762 -0.935 vt 0.629 0.397 -0.709 vt 0.644 0.401 -0.709 vt 0.741 0.427 -0.750 vt 0.741 0.443 -0.728 vt 0.718 0.446 -0.708 vt 0.721 0.422 -0.704 vt 0.746 0.415 -0.734 vt 0.733 0.401 -0.694 vt 0.699 0.454 -0.709 vt 0.702 0.418 -0.714 vt 0.711 0.392 -0.725 vt 0.675 0.413 -0.707 vt 0.679 0.396 -0.703 vt 0.840 0.774 -0.966 vt 0.817 0.772 -0.983 vt 0.659 0.538 -0.709 vt 0.651 0.559 -0.709 vt 0.648 0.573 -0.709 vt 0.693 0.558 -0.709 vt 0.679 0.577 -0.709 vt 0.668 0.560 -0.709 vt 0.684 0.544 -0.709 vt 0.685 0.525 -0.709 vt 0.686 0.533 -0.709 vt 0.913 0.704 -0.983 vt 0.887 0.717 -0.934 vt 0.628 0.574 -0.709 vt 0.623 0.597 -0.709 vt 0.610 0.598 -0.709 vt 0.591 0.597 -0.711 vt 0.711 0.753 -0.884 vt 0.725 0.749 -0.889 vt 0.736 0.760 -0.893 vt 0.723 0.763 -0.883 vt 0.737 0.743 -0.895 vt 0.747 0.754 -0.900 vt 0.742 0.740 -0.909 vt 0.752 0.751 -0.914 vt 0.788 0.725 -1.001 vt 0.774 0.734 -0.957 vt 0.769 0.729 -0.962 vt 0.786 0.720 -1.007 vt 0.780 0.738 -0.972 vt 0.794 0.729 -1.014 vt 0.747 0.772 -0.931 vt 0.762 0.763 -0.952 vt 0.734 0.726 -0.947 vt 0.762 0.715 -0.999 vt 0.724 0.741 -0.908 vt 0.726 0.729 -0.939 vt 0.785 0.751 -0.999 vt 0.790 0.765 -1.007 vt 0.771 0.773 -0.970 vt 0.734 0.713 -0.970 vt 0.751 0.704 -1.007 vt 0.779 0.713 -1.005 vt 0.787 0.716 -1.012 vt 0.773 0.720 -0.989 vt 0.799 0.731 -1.012 vt 0.798 0.739 -1.005 vt 0.787 0.741 -0.991 vt 0.762 0.775 -0.961 vt 0.726 0.715 -0.961 vt 0.757 0.794 -0.975 vt 0.740 0.793 -0.968 vt 0.703 0.714 -0.975 vt 0.700 0.733 -0.937 vt 0.022 0.649 0.173 vt 0.019 0.619 0.173 vt 0.014 0.626 0.173 vt 0.017 0.652 0.173 vt 0.006 0.626 0.173 vt 0.006 0.652 0.173 vt 0.006 0.694 0.173 vt 0.029 0.699 0.173 vt 0.033 0.697 0.173 vt 0.659 0.833 -0.454 vt 0.646 0.821 -0.443 vt 0.049 0.730 0.173 vt 0.057 0.726 0.173 vt 0.006 0.734 0.173 vt 0.638 0.852 -0.457 vt 0.628 0.839 -0.451 vt 0.636 0.824 -0.446 vt 0.615 0.835 -0.450 vt 0.630 0.817 -0.442 vt 0.013 0.588 0.173 vt 0.006 0.588 0.173 vt 0.017 0.588 0.172 vt 0.022 0.546 0.111 vt 0.006 0.532 0.117 vt 0.203 0.940 -0.291 vt 0.213 0.950 -0.291 vt 0.264 0.917 -0.291 vt 0.225 0.894 -0.291 vt 0.281 0.893 -0.291 vt 0.238 0.881 -0.291 vt 0.291 0.865 -0.291 vt 0.255 0.859 -0.291 vt 0.289 0.825 -0.291 vt 0.261 0.832 -0.291 vt 0.268 0.756 -0.291 vt 0.236 0.767 -0.291 vt 0.226 0.700 -0.291 vt 0.203 0.715 -0.291 vt 0.183 0.647 -0.292 vt 0.165 0.659 -0.292 vt 0.146 0.581 -0.292 vt 0.126 0.574 -0.292 vt 0.121 0.528 -0.292 vt 0.116 0.525 -0.292 vt 0.328 0.815 -0.291 vt 0.314 0.767 -0.291 vt 0.295 0.734 -0.291 vt 0.249 0.684 -0.291 vt 0.201 0.637 -0.292 vt 0.158 0.579 -0.292 vt 0.123 0.522 -0.292 vt 0.322 0.855 -0.291 vt 0.338 0.844 -0.290 vt 0.363 0.821 -0.291 vt 0.330 0.862 -0.290 vt 0.340 0.851 -0.290 vt 0.319 0.881 -0.290 vt 0.330 0.878 -0.290 vt 0.325 0.888 -0.290 vt 0.320 0.900 -0.291 vt 0.333 0.900 -0.290 vt 0.342 0.894 -0.290 vt 0.353 0.802 -0.291 vt 0.368 0.799 -0.290 vt 0.368 0.783 -0.285 vt 0.364 0.783 -0.291 vt 0.355 0.777 -0.291 vt 0.340 0.792 -0.291 vt 0.377 0.783 -0.291 vt 0.369 0.773 -0.291 vt 0.381 0.805 -0.291 vt 0.374 0.796 -0.291 vt 0.368 0.782 -0.284 vt 0.314 0.932 -0.291 vt 0.364 0.837 -0.290 vt 0.349 0.852 -0.290 vt 0.374 0.850 -0.290 vt 0.376 0.877 -0.290 vt 0.370 0.877 -0.290 vt 0.374 0.890 -0.290 vt 0.380 0.880 -0.290 vt 0.343 0.876 -0.290 vt 0.385 0.850 -0.290 vt 0.389 0.841 -0.290 vt 0.373 0.840 -0.290 vt 0.379 0.858 -0.290 vt 0.385 0.871 -0.290 vt 0.345 0.913 -0.290 vt 0.398 0.846 -0.291 vt 0.404 0.867 -0.291 vt 0.385 0.891 -0.290 vt 0.386 0.908 -0.290 vt 0.411 0.901 -0.291 vt 0.409 0.889 -0.291 vt 0.315 0.721 -0.291 vt 0.262 0.675 -0.291 vt 0.211 0.632 -0.292 vt 0.163 0.577 -0.292 vt 0.335 0.781 -0.291 vt 0.347 0.772 -0.291 vt 0.372 0.918 -0.290 vt 0.335 0.938 -0.291 vt 0.372 0.939 -0.290 vt 0.385 0.932 -0.287 vt 0.381 0.927 -0.292 vt 0.392 0.922 -0.290 vt 0.419 0.914 -0.291 vt 0.006 0.768 0.173 vt 0.043 0.760 0.173 vt 0.046 0.742 0.173 vt 0.042 0.774 0.173 vt 0.056 0.776 0.173 vt 0.056 0.763 0.173 vt 0.049 0.797 0.173 vt 0.060 0.798 0.173 vt 0.564 0.899 -0.417 vt 0.556 0.895 -0.436 vt 0.545 0.910 -0.381 vt 0.540 0.908 -0.399 vt 0.534 0.892 -0.435 vt 0.535 0.915 -0.422 vt 0.553 0.926 -0.441 vt 0.533 0.931 -0.422 vt 0.524 0.931 -0.385 vt 0.601 0.873 -0.460 vt 0.605 0.872 -0.459 vt 0.612 0.875 -0.459 vt 0.606 0.880 -0.452 vt 0.006 0.921 0.173 vt 0.042 0.914 0.173 vt 0.035 0.886 0.173 vt 0.006 0.890 0.173 vt 0.048 0.804 0.173 vt 0.046 0.816 0.173 vt 0.055 0.821 0.173 vt 0.064 0.840 0.173 vt 0.044 0.821 0.173 vt 0.052 0.847 0.173 vt 0.040 0.795 0.173 vt 0.379 0.374 0.257 vt 0.397 0.365 0.257 vt 0.417 0.331 0.257 vt 0.395 0.331 0.257 vt 0.369 0.339 0.257 vt 0.357 0.348 0.257 vt 0.416 0.362 0.257 vt 0.432 0.356 0.257 vt 0.118 0.199 0.365 vt 0.138 0.210 0.372 vt 0.133 0.232 0.365 vt 0.098 0.201 0.360 vt 0.390 0.287 0.257 vt 0.399 0.237 0.257 vt 0.379 0.242 0.257 vt 0.374 0.298 0.257 vt 0.392 0.203 0.257 vt 0.375 0.199 0.257 vt 0.364 0.236 0.257 vt 0.393 0.185 0.257 vt 0.379 0.181 0.257 vt 0.519 0.123 0.194 vt 0.504 0.133 0.211 vt 0.498 0.157 0.248 vt 0.531 0.162 0.263 vt 0.413 0.942 -0.291 vt 0.438 0.941 -0.291 vt 0.384 0.962 -0.291 vt 0.412 0.962 -0.291 vt 0.395 0.939 -0.294 vt 0.395 0.986 -0.291 vt 0.376 0.973 -0.291 vt 0.498 0.055 0.095 vt 0.491 0.083 0.156 vt 0.506 0.088 0.158 vt 0.521 0.069 0.118 vt 0.355 0.382 0.257 vt 0.370 0.379 0.257 vt 0.083 0.929 0.173 vt 0.109 0.962 0.173 vt 0.117 0.953 0.173 vt 0.098 0.934 0.173 vt 0.092 0.923 0.173 vt 0.094 0.928 0.173 vt 0.097 0.920 0.173 vt 0.118 0.942 0.173 vt 0.078 0.901 0.173 vt 0.085 0.881 0.173 vt 0.078 0.890 0.168 vt 0.069 0.885 0.173 vt 0.470 0.350 0.257 vt 0.466 0.318 0.257 vt 0.548 0.208 0.346 vt 0.562 0.190 0.346 vt 0.544 0.158 0.263 vt 0.569 0.217 0.399 vt 0.573 0.203 0.382 vt 0.803 0.618 0.349 vt 0.802 0.627 0.353 vt 0.809 0.631 0.373 vt 0.817 0.623 0.386 vt 0.786 0.610 0.318 vt 0.838 0.598 0.408 vt 0.835 0.588 0.402 vt 0.846 0.608 0.435 vt 0.890 0.638 0.432 vt 0.911 0.637 0.402 vt 0.920 0.588 0.479 vt 0.911 0.586 0.497 vt 0.887 0.576 0.499 vt 0.882 0.567 0.479 vt 0.925 0.574 0.493 vt 0.916 0.572 0.508 vt 0.900 0.564 0.511 vt 0.896 0.558 0.493 vt 0.925 0.564 0.500 vt 0.918 0.564 0.514 vt 0.911 0.558 0.517 vt 0.907 0.552 0.500 vt 0.902 0.583 0.521 vt 0.877 0.626 0.476 vt 0.853 0.614 0.458 vt 0.895 0.580 0.522 vt 0.914 0.561 0.527 vt 0.909 0.569 0.526 vt 0.905 0.567 0.526 vt 0.865 0.619 0.481 vt 0.828 0.632 0.426 vt 0.858 0.642 0.476 vt 0.858 0.656 0.452 vt 0.870 0.675 0.399 vt 0.936 0.481 0.530 vt 0.900 0.508 0.615 vt 0.913 0.530 0.614 vt 0.936 0.499 0.553 vt 0.902 0.477 0.613 vt 0.867 0.503 0.683 vt 0.797 0.433 0.635 vt 0.770 0.443 0.614 vt 0.760 0.479 0.665 vt 0.778 0.485 0.697 vt 0.799 0.492 0.741 vt 0.813 0.454 0.703 vt 0.847 0.519 0.718 vt 0.855 0.482 0.715 vt 0.830 0.513 0.759 vt 0.819 0.504 0.759 vt 0.829 0.478 0.733 vt 0.872 0.434 0.726 vt 0.868 0.411 0.712 vt 0.821 0.436 0.685 vt 0.846 0.450 0.726 vt 0.821 0.456 0.726 vt 0.840 0.463 0.736 vt 0.831 0.472 0.761 vt 0.843 0.479 0.726 vt 0.867 0.459 0.704 vt 0.878 0.473 0.678 vt 0.319 0.117 0.426 vt 0.330 0.095 0.408 vt 0.337 0.110 0.409 vt 0.328 0.119 0.417 vt 0.858 0.530 0.687 vt 0.753 0.522 0.747 vt 0.765 0.522 0.759 vt 0.808 0.551 0.799 vt 0.824 0.558 0.757 vt 0.783 0.530 0.806 vt 0.796 0.539 0.826 vt 0.805 0.543 0.814 vt 0.875 0.545 0.665 vt 0.831 0.568 0.747 vt 0.795 0.572 0.815 vt 0.805 0.583 0.799 vt 0.755 0.549 0.799 vt 0.766 0.559 0.843 vt 0.784 0.565 0.850 vt 0.775 0.562 0.861 vt 0.750 0.584 0.830 vt 0.756 0.582 0.841 vt 0.767 0.589 0.841 vt 0.769 0.593 0.830 vt 0.762 0.582 0.856 vt 0.810 0.388 0.581 vt 0.798 0.378 0.543 vt 0.782 0.420 0.591 vt 0.961 0.985 0.382 vt 0.947 0.980 0.399 vt 0.959 0.938 0.454 vt 0.972 0.944 0.444 vt 0.918 0.921 0.543 vt 0.908 0.902 0.575 vt 0.933 0.899 0.550 vt 0.941 0.918 0.522 vt 0.928 0.961 0.452 vt 0.923 0.942 0.497 vt 0.973 0.905 0.505 vt 0.977 0.906 0.501 vt 0.965 0.892 0.538 vt 0.967 0.898 0.528 vt 0.006 0.949 0.173 vt 0.063 0.948 0.173 vt 0.070 0.868 0.173 vt 0.006 0.853 0.173 vt 0.293 0.111 0.446 vt 0.304 0.108 0.435 vt 0.303 0.115 0.440 vt 0.290 0.118 0.449 vt 0.282 0.106 0.451 vt 0.277 0.108 0.452 vt 0.947 0.645 0.476 vt 0.960 0.631 0.484 vt 0.953 0.621 0.516 vt 0.932 0.645 0.497 vt 0.845 0.391 0.653 vt 0.267 0.092 0.439 vt 0.292 0.099 0.441 vt 0.278 0.102 0.449 vt 0.267 0.100 0.447 vt 0.299 0.045 0.396 vt 0.307 0.058 0.404 vt 0.279 0.070 0.423 vt 0.269 0.058 0.420 vt 0.288 0.029 0.389 vt 0.266 0.039 0.406 vt 0.257 0.025 0.395 vt 0.277 0.011 0.381 vt 0.251 0.125 0.456 vt 0.263 0.135 0.458 vt 0.256 0.138 0.459 vt 0.243 0.124 0.453 vt 0.230 0.042 0.396 vt 0.255 0.047 0.442 vt 0.256 0.045 0.457 vt 0.234 0.058 0.410 vt 0.257 0.085 0.433 vt 0.257 0.098 0.443 vt 0.231 0.101 0.436 vt 0.223 0.076 0.415 vt 0.190 0.114 0.418 vt 0.181 0.094 0.409 vt 0.209 0.129 0.436 vt 0.229 0.128 0.449 vt 0.210 0.144 0.444 vt 0.228 0.141 0.458 vt 0.266 0.150 0.460 vt 0.244 0.144 0.463 vt 0.265 0.144 0.457 vt 0.284 0.252 0.376 vt 0.251 0.260 0.377 vt 0.258 0.236 0.390 vt 0.289 0.230 0.388 vt 0.280 0.276 0.366 vt 0.250 0.284 0.365 vt 0.212 0.270 0.374 vt 0.223 0.288 0.364 vt 0.279 0.290 0.360 vt 0.255 0.308 0.356 vt 0.223 0.310 0.356 vt 0.199 0.303 0.359 vt 0.185 0.262 0.371 vt 0.177 0.311 0.356 vt 0.165 0.278 0.364 vt 0.209 0.343 0.348 vt 0.186 0.346 0.348 vt 0.267 0.205 0.416 vt 0.295 0.211 0.405 vt 0.234 0.239 0.387 vt 0.240 0.197 0.422 vt 0.199 0.238 0.383 vt 0.205 0.202 0.409 vt 0.235 0.351 0.345 vt 0.248 0.349 0.345 vt 0.251 0.386 0.336 vt 0.229 0.388 0.336 vt 0.216 0.364 0.343 vt 0.209 0.388 0.336 vt 0.197 0.355 0.345 vt 0.188 0.357 0.345 vt 0.269 0.410 0.332 vt 0.266 0.431 0.327 vt 0.255 0.433 0.326 vt 0.248 0.409 0.331 vt 0.268 0.445 0.325 vt 0.260 0.447 0.324 vt 0.275 0.448 0.325 vt 0.261 0.453 0.323 vt 0.267 0.381 0.336 vt 0.228 0.413 0.331 vt 0.286 0.352 0.343 vt 0.285 0.344 0.345 vt 0.295 0.345 0.345 vt 0.293 0.354 0.342 vt 0.280 0.372 0.338 vt 0.290 0.376 0.338 vt 0.286 0.331 0.348 vt 0.282 0.312 0.354 vt 0.304 0.315 0.354 vt 0.298 0.334 0.348 vt 0.274 0.431 0.329 vt 0.282 0.412 0.332 vt 0.241 0.445 0.325 vt 0.298 0.284 0.364 vt 0.310 0.258 0.374 vt 0.329 0.212 0.396 vt 0.320 0.234 0.385 vt 0.475 0.201 0.257 vt 0.465 0.241 0.257 vt 0.481 0.242 0.257 vt 0.481 0.203 0.257 vt 0.493 0.218 0.257 vt 0.488 0.201 0.257 vt 0.367 0.022 0.372 vt 0.384 0.023 0.393 vt 0.387 0.049 0.417 vt 0.375 0.047 0.398 vt 0.410 0.055 0.452 vt 0.392 0.072 0.442 vt 0.389 0.068 0.435 vt 0.384 0.069 0.427 vt 0.816 0.627 0.389 vt 0.824 0.635 0.423 vt 0.425 0.079 0.423 vt 0.424 0.101 0.389 vt 0.410 0.092 0.409 vt 0.415 0.072 0.437 vt 0.383 0.075 0.434 vt 0.396 0.078 0.434 vt 0.351 0.217 0.382 vt 0.337 0.243 0.377 vt 0.353 0.236 0.372 vt 0.360 0.258 0.369 vt 0.306 0.191 0.446 vt 0.315 0.180 0.422 vt 0.333 0.190 0.402 vt 0.968 0.585 0.515 vt 0.983 0.599 0.526 vt 0.985 0.588 0.499 vt 0.975 0.577 0.490 vt 0.958 0.563 0.479 vt 0.965 0.554 0.452 vt 0.984 0.660 0.426 vt 0.982 0.628 0.475 vt 0.974 0.542 0.423 vt 0.971 0.550 0.437 vt 0.983 0.570 0.475 vt 0.979 0.539 0.426 vt 0.948 0.581 0.530 vt 0.952 0.599 0.553 vt 0.972 0.599 0.532 vt 0.143 0.197 0.377 vt 0.153 0.202 0.383 vt 0.152 0.219 0.378 vt 0.146 0.310 0.354 vt 0.147 0.283 0.360 vt 0.164 0.349 0.347 vt 0.151 0.329 0.350 vt 0.151 0.247 0.367 vt 0.172 0.239 0.376 vt 0.117 0.341 0.348 vt 0.114 0.323 0.351 vt 0.320 0.341 0.346 vt 0.327 0.317 0.352 vt 0.318 0.294 0.360 vt 0.342 0.306 0.356 vt 0.334 0.262 0.369 vt 0.355 0.272 0.363 vt 0.318 0.362 0.342 vt 0.291 0.425 0.332 vt 0.286 0.439 0.329 vt 0.160 0.455 0.334 vt 0.162 0.440 0.336 vt 0.181 0.432 0.334 vt 0.184 0.450 0.331 vt 0.142 0.416 0.339 vt 0.163 0.399 0.339 vt 0.200 0.432 0.331 vt 0.203 0.450 0.328 vt 0.176 0.404 0.337 vt 0.185 0.398 0.336 vt 0.189 0.377 0.341 vt 0.201 0.371 0.342 vt 0.171 0.383 0.340 vt 0.149 0.359 0.345 vt 0.168 0.365 0.344 vt 0.129 0.383 0.342 vt 0.125 0.364 0.345 vt 0.090 0.293 0.352 vt 0.112 0.282 0.355 vt 0.216 0.448 0.327 vt 0.247 0.465 0.321 vt 0.216 0.464 0.323 vt 0.203 0.465 0.325 vt 0.268 0.497 0.314 vt 0.283 0.485 0.316 vt 0.236 0.501 0.318 vt 0.249 0.504 0.315 vt 0.280 0.457 0.323 vt 0.292 0.474 0.319 vt 0.261 0.517 0.312 vt 0.272 0.513 0.311 vt 0.292 0.498 0.312 vt 0.284 0.506 0.311 vt 0.245 0.518 0.313 vt 0.236 0.514 0.315 vt 0.301 0.485 0.315 vt 0.297 0.491 0.313 vt 0.233 0.538 0.310 vt 0.228 0.535 0.311 vt 0.231 0.544 0.309 vt 0.225 0.541 0.310 vt 0.225 0.553 0.308 vt 0.220 0.550 0.308 vt 0.219 0.565 0.306 vt 0.212 0.562 0.307 vt 0.205 0.493 0.322 vt 0.198 0.487 0.324 vt 0.216 0.542 0.313 vt 0.222 0.525 0.318 vt 0.205 0.560 0.312 vt 0.203 0.571 0.306 vt 0.198 0.570 0.309 vt 0.204 0.580 0.303 vt 0.210 0.570 0.304 vt 0.213 0.576 0.305 vt 0.208 0.585 0.309 vt 0.199 0.579 0.307 vt 0.198 0.590 0.309 vt 0.202 0.591 0.311 vt 0.196 0.588 0.310 vt 0.189 0.479 0.327 vt 0.192 0.466 0.328 vt 0.413 0.279 0.257 vt 0.421 0.232 0.257 vt 0.420 0.203 0.257 vt 0.211 0.163 0.451 vt 0.209 0.165 0.460 vt 0.218 0.150 0.456 vt 0.260 0.159 0.467 vt 0.251 0.154 0.471 vt 0.273 0.164 0.459 vt 0.265 0.164 0.464 vt 0.234 0.187 0.439 vt 0.208 0.187 0.428 vt 0.225 0.178 0.447 vt 0.236 0.150 0.466 vt 0.243 0.152 0.467 vt 0.232 0.155 0.465 vt 0.229 0.149 0.464 vt 0.211 0.175 0.448 vt 0.222 0.170 0.456 vt 0.219 0.176 0.447 vt 0.270 0.189 0.433 vt 0.255 0.180 0.445 vt 0.261 0.177 0.452 vt 0.274 0.184 0.440 vt 0.235 0.549 0.311 vt 0.225 0.570 0.310 vt 0.217 0.580 0.310 vt 0.250 0.533 0.312 vt 0.192 0.569 0.313 vt 0.200 0.555 0.317 vt 0.230 0.573 0.316 vt 0.220 0.585 0.315 vt 0.990 0.300 -0.059 vt 0.991 0.318 -0.059 vt 0.982 0.319 -0.059 vt 0.979 0.302 -0.059 vt 0.992 0.329 -0.059 vt 0.984 0.330 -0.059 vt 0.991 0.339 -0.060 vt 0.988 0.340 -0.060 vt 0.976 0.280 -0.059 vt 0.988 0.278 -0.059 vt 0.971 0.257 -0.059 vt 0.986 0.256 -0.059 vt 0.242 0.556 0.316 vt 0.253 0.541 0.315 vt 0.213 0.520 0.322 vt 0.208 0.538 0.318 vt 0.196 0.503 0.322 vt 0.189 0.497 0.323 vt 0.191 0.508 0.322 vt 0.185 0.501 0.323 vt 0.186 0.513 0.322 vt 0.179 0.505 0.323 vt 0.179 0.497 0.325 vt 0.166 0.512 0.324 vt 0.160 0.508 0.327 vt 0.163 0.525 0.324 vt 0.173 0.514 0.322 vt 0.175 0.521 0.323 vt 0.167 0.529 0.325 vt 0.159 0.519 0.325 vt 0.155 0.532 0.325 vt 0.156 0.535 0.327 vt 0.151 0.529 0.327 vt 0.195 0.515 0.323 vt 0.179 0.526 0.325 vt 0.211 0.505 0.322 vt 0.155 0.501 0.329 vt 0.170 0.493 0.328 vt 0.197 0.522 0.326 vt 0.183 0.533 0.328 vt 0.940 0.076 -0.059 vt 0.959 0.078 -0.059 vt 0.958 0.089 -0.059 vt 0.939 0.088 -0.059 vt 0.966 0.079 -0.060 vt 0.965 0.089 -0.060 vt 0.976 0.079 -0.060 vt 0.972 0.092 -0.060 vt 0.987 0.086 -0.063 vt 0.986 0.093 -0.064 vt 0.925 0.090 -0.059 vt 0.922 0.076 -0.059 vt 0.210 0.519 0.325 vt 0.172 0.480 0.330 vt 0.225 0.507 0.320 vt 0.977 0.223 -0.059 vt 0.960 0.205 -0.059 vt 0.977 0.199 -0.059 vt 0.989 0.207 -0.059 vt 0.221 0.509 0.324 vt 0.990 0.237 -0.059 vt 0.277 0.540 0.307 vt 0.270 0.543 0.307 vt 0.280 0.549 0.305 vt 0.273 0.551 0.305 vt 0.283 0.557 0.304 vt 0.275 0.562 0.304 vt 0.287 0.574 0.301 vt 0.280 0.576 0.302 vt 0.266 0.557 0.308 vt 0.256 0.532 0.312 vt 0.275 0.578 0.305 vt 0.281 0.589 0.297 vt 0.276 0.591 0.304 vt 0.289 0.595 0.286 vt 0.285 0.583 0.295 vt 0.292 0.585 0.297 vt 0.296 0.596 0.297 vt 0.284 0.599 0.297 vt 0.293 0.605 0.292 vt 0.297 0.604 0.300 vt 0.288 0.606 0.299 vt 0.287 0.549 0.307 vt 0.295 0.570 0.306 vt 0.298 0.585 0.303 vt 0.285 0.520 0.310 vt 0.272 0.596 0.309 vt 0.268 0.579 0.312 vt 0.302 0.568 0.312 vt 0.304 0.586 0.309 vt 0.955 0.307 -0.059 vt 0.948 0.325 -0.059 vt 0.938 0.322 -0.059 vt 0.943 0.302 -0.059 vt 0.945 0.335 -0.059 vt 0.937 0.332 -0.059 vt 0.939 0.343 -0.059 vt 0.935 0.341 -0.059 vt 0.949 0.279 -0.059 vt 0.962 0.282 -0.059 vt 0.953 0.248 -0.059 vt 0.296 0.548 0.313 vt 0.294 0.526 0.313 vt 0.259 0.559 0.313 vt 0.311 0.515 0.307 vt 0.306 0.520 0.307 vt 0.315 0.517 0.306 vt 0.311 0.523 0.306 vt 0.323 0.524 0.304 vt 0.319 0.529 0.304 vt 0.333 0.531 0.303 vt 0.330 0.535 0.302 vt 0.310 0.532 0.308 vt 0.290 0.518 0.310 vt 0.327 0.542 0.306 vt 0.337 0.543 0.300 vt 0.337 0.548 0.306 vt 0.346 0.541 0.297 vt 0.337 0.536 0.299 vt 0.342 0.534 0.301 vt 0.351 0.539 0.299 vt 0.344 0.547 0.302 vt 0.322 0.517 0.308 vt 0.339 0.526 0.307 vt 0.346 0.531 0.305 vt 0.308 0.498 0.313 vt 0.335 0.553 0.312 vt 0.322 0.546 0.312 vt 0.340 0.517 0.313 vt 0.351 0.529 0.309 vt 0.932 0.243 -0.059 vt 0.927 0.260 -0.059 vt 0.917 0.257 -0.059 vt 0.923 0.240 -0.059 vt 0.924 0.270 -0.059 vt 0.914 0.267 -0.059 vt 0.927 0.219 -0.059 vt 0.939 0.224 -0.059 vt 0.930 0.194 -0.059 vt 0.950 0.203 -0.059 vt 0.326 0.509 0.314 vt 0.313 0.498 0.315 vt 0.306 0.537 0.313 vt 0.917 0.159 -0.059 vt 0.918 0.137 -0.059 vt 0.954 0.131 -0.059 vt 0.953 0.158 -0.059 vt 0.293 0.453 0.326 vt 0.301 0.463 0.324 vt 0.490 0.357 0.257 vt 0.515 0.310 0.257 vt 0.316 0.486 0.313 vt 0.316 0.491 0.312 vt 0.325 0.486 0.311 vt 0.325 0.491 0.311 vt 0.331 0.484 0.310 vt 0.332 0.489 0.310 vt 0.339 0.484 0.310 vt 0.340 0.489 0.310 vt 0.323 0.496 0.313 vt 0.310 0.496 0.313 vt 0.340 0.494 0.313 vt 0.348 0.489 0.310 vt 0.350 0.493 0.314 vt 0.356 0.484 0.310 vt 0.344 0.486 0.309 vt 0.348 0.480 0.311 vt 0.356 0.481 0.310 vt 0.355 0.489 0.313 vt 0.323 0.478 0.316 vt 0.339 0.476 0.315 vt 0.348 0.477 0.314 vt 0.306 0.478 0.318 vt 0.351 0.497 0.318 vt 0.339 0.498 0.317 vt 0.339 0.471 0.319 vt 0.350 0.472 0.319 vt 0.907 0.217 -0.059 vt 0.897 0.228 -0.059 vt 0.891 0.223 -0.059 vt 0.898 0.211 -0.059 vt 0.892 0.236 -0.059 vt 0.885 0.233 -0.059 vt 0.909 0.197 -0.059 vt 0.920 0.203 -0.059 vt 0.918 0.178 -0.059 vt 0.324 0.472 0.320 vt 0.310 0.470 0.322 vt 0.323 0.500 0.316 vt 0.176 0.085 0.401 vt 0.215 0.062 0.397 vt 0.153 0.089 0.396 vt 0.162 0.098 0.403 vt 0.145 0.098 0.397 vt 0.142 0.089 0.391 vt 0.137 0.117 0.393 vt 0.108 0.087 0.373 vt 0.147 0.068 0.378 vt 0.166 0.059 0.379 vt 0.171 0.074 0.392 vt 0.141 0.078 0.384 vt 0.953 0.836 0.434 vt 0.972 0.813 0.434 vt 0.986 0.844 0.428 vt 0.934 0.863 0.427 vt 0.075 0.646 0.962 vt 0.074 0.608 0.962 vt 0.090 0.585 0.962 vt 0.101 0.665 0.963 vt 0.100 0.713 0.964 vt 0.089 0.720 0.963 vt 0.079 0.677 0.963 vt 0.101 0.745 0.969 vt 0.096 0.746 0.962 vt 0.063 0.684 0.962 vt 0.058 0.658 0.962 vt 0.079 0.725 0.963 vt 0.091 0.752 0.963 vt 0.053 0.625 0.962 vt 0.164 0.685 0.962 vt 0.150 0.699 0.962 vt 0.142 0.688 0.962 vt 0.147 0.671 0.962 vt 0.104 0.747 0.962 vt 0.110 0.728 0.964 vt 0.117 0.733 0.963 vt 0.108 0.750 0.963 vt 0.116 0.710 0.963 vt 0.125 0.721 0.963 vt 0.125 0.672 0.963 vt 0.133 0.639 0.962 vt 0.160 0.712 0.962 vt 0.134 0.738 0.962 vt 0.114 0.667 0.963 vt 0.105 0.715 0.963 vt 0.161 0.043 0.599 vt 0.176 0.031 0.599 vt 0.186 0.055 0.382 vt 0.821 0.154 0.598 vt 0.830 0.180 0.599 vt 0.837 0.187 0.599 vt 0.846 0.183 0.599 vt 0.824 0.224 0.601 vt 0.847 0.227 0.600 vt 0.830 0.192 0.600 vt 0.813 0.199 0.600 vt 0.879 0.119 0.598 vt 0.850 0.158 0.598 vt 0.888 0.188 0.599 vt 0.903 0.130 0.599 vt 0.851 0.081 0.598 vt 0.822 0.095 0.597 vt 0.771 0.186 0.601 vt 0.785 0.197 0.601 vt 0.795 0.191 0.600 vt 0.797 0.177 0.600 vt 0.822 0.187 0.600 vt 0.873 0.214 0.600 vt 0.812 0.166 0.599 vt 0.766 0.207 0.602 vt 0.755 0.198 0.602 vt 0.750 0.214 0.602 vt 0.745 0.203 0.602 vt 0.753 0.195 0.602 vt 0.740 0.196 0.602 vt 0.737 0.165 0.600 vt 0.737 0.188 0.602 vt 0.753 0.218 0.602 vt 0.766 0.212 0.602 vt 0.751 0.237 0.602 vt 0.767 0.231 0.602 vt 0.777 0.219 0.602 vt 0.769 0.259 0.602 vt 0.784 0.243 0.602 vt 0.798 0.225 0.601 vt 0.758 0.276 0.602 vt 0.884 0.834 0.418 vt 0.846 0.815 0.389 vt 0.881 0.797 0.403 vt 0.905 0.808 0.417 vt 0.832 0.274 0.601 vt 0.870 0.264 0.600 vt 0.807 0.309 0.601 vt 0.763 0.151 0.599 vt 0.790 0.152 0.598 vt 0.785 0.129 0.597 vt 0.760 0.125 0.597 vt 0.748 0.150 0.599 vt 0.765 0.185 0.601 vt 0.764 0.175 0.601 vt 0.769 0.171 0.600 vt 0.760 0.174 0.601 vt 0.757 0.185 0.606 vt 0.751 0.187 0.606 vt 0.750 0.160 0.600 vt 0.761 0.172 0.600 vt 0.737 0.158 0.599 vt 0.844 0.324 0.601 vt 0.891 0.292 0.600 vt 0.888 0.768 0.401 vt 0.910 0.771 0.408 vt 0.752 0.937 0.721 vt 0.801 0.920 0.721 vt 0.816 0.938 0.722 vt 0.759 0.960 0.721 vt 0.736 0.957 0.721 vt 0.731 0.939 0.720 vt 0.700 0.960 0.721 vt 0.644 0.938 0.720 vt 0.655 0.926 0.719 vt 0.709 0.931 0.720 vt 0.612 0.920 0.701 vt 0.606 0.925 0.711 vt 0.730 0.896 0.720 vt 0.777 0.879 0.721 vt 0.704 0.902 0.720 vt 0.611 0.917 0.708 vt 0.653 0.913 0.717 vt 0.188 0.806 0.906 vt 0.220 0.794 0.906 vt 0.241 0.834 0.906 vt 0.191 0.856 0.906 vt 0.185 0.773 0.907 vt 0.205 0.767 0.906 vt 0.151 0.854 0.906 vt 0.160 0.807 0.906 vt 0.167 0.777 0.909 vt 0.119 0.850 0.906 vt 0.135 0.806 0.906 vt 0.148 0.779 0.908 vt 0.099 0.841 0.906 vt 0.124 0.803 0.906 vt 0.195 0.746 0.906 vt 0.183 0.749 0.906 vt 0.174 0.743 0.905 vt 0.195 0.900 0.906 vt 0.148 0.876 0.906 vt 0.971 0.755 0.431 vt 0.954 0.793 0.436 vt 0.943 0.747 0.431 vt 0.976 0.691 0.417 vt 0.952 0.704 0.423 vt 0.778 0.337 0.601 vt 0.769 0.309 0.601 vt 0.756 0.316 0.601 vt 0.770 0.334 0.601 vt 0.111 0.890 0.906 vt 0.771 0.353 0.601 vt 0.774 0.363 0.601 vt 0.405 0.669 0.427 vt 0.381 0.665 0.434 vt 0.371 0.694 0.450 vt 0.381 0.708 0.450 vt 0.367 0.640 0.426 vt 0.364 0.678 0.447 vt 0.416 0.655 0.417 vt 0.397 0.634 0.413 vt 0.372 0.598 0.401 vt 0.385 0.617 0.409 vt 0.796 0.204 0.601 vt 0.777 0.208 0.602 vt 0.785 0.214 0.602 vt 0.755 0.850 0.721 vt 0.756 0.817 0.721 vt 0.790 0.811 0.722 vt 0.779 0.847 0.721 vt 0.894 0.935 0.722 vt 0.864 0.975 0.722 vt 0.828 0.951 0.722 vt 0.893 0.927 0.722 vt 0.685 0.872 0.720 vt 0.669 0.827 0.721 vt 0.685 0.818 0.721 vt 0.706 0.858 0.720 vt 0.785 0.851 0.722 vt 0.764 0.862 0.721 vt 0.743 0.867 0.721 vt 0.716 0.874 0.720 vt 0.733 0.854 0.721 vt 0.625 0.885 0.720 vt 0.662 0.857 0.721 vt 0.643 0.895 0.718 vt 0.610 0.909 0.717 vt 0.604 0.909 0.717 vt 0.692 0.883 0.720 vt 0.136 0.074 0.377 vt 0.138 0.067 0.371 vt 0.134 0.056 0.365 vt 0.143 0.055 0.370 vt 0.825 0.070 0.597 vt 0.804 0.081 0.597 vt 0.789 0.097 0.596 vt 0.761 0.093 0.595 vt 0.780 0.077 0.596 vt 0.762 0.073 0.595 vt 0.770 0.054 0.595 vt 0.754 0.051 0.595 vt 0.805 0.057 0.597 vt 0.796 0.043 0.597 vt 0.792 0.039 0.597 vt 0.784 0.060 0.596 vt 0.746 0.033 0.595 vt 0.772 0.044 0.596 vt 0.755 0.024 0.596 vt 0.944 0.389 0.506 vt 0.988 0.393 0.540 vt 0.982 0.369 0.536 vt 0.948 0.371 0.510 vt 0.887 0.372 0.457 vt 0.893 0.379 0.455 vt 0.909 0.408 0.477 vt 0.912 0.391 0.479 vt 0.904 0.406 0.472 vt 0.877 0.372 0.443 vt 0.879 0.381 0.440 vt 0.741 0.011 0.596 vt 0.214 0.421 0.330 vt 0.029 0.141 0.173 vt 0.024 0.143 0.173 vt 0.022 0.118 0.173 vt 0.027 0.110 0.173 vt 0.014 0.144 0.173 vt 0.014 0.118 0.173 vt 0.036 0.190 0.173 vt 0.014 0.186 0.173 vt 0.040 0.189 0.173 vt 0.064 0.218 0.173 vt 0.056 0.222 0.173 vt 0.014 0.225 0.173 vt 0.014 0.080 0.173 vt 0.021 0.080 0.173 vt 0.025 0.080 0.172 vt 0.014 0.024 0.117 vt 0.029 0.038 0.111 vt 0.014 0.260 0.173 vt 0.053 0.233 0.173 vt 0.050 0.252 0.173 vt 0.063 0.255 0.173 vt 0.064 0.268 0.173 vt 0.050 0.266 0.173 vt 0.057 0.289 0.173 vt 0.067 0.290 0.173 vt 0.014 0.412 0.173 vt 0.014 0.382 0.173 vt 0.042 0.377 0.173 vt 0.050 0.406 0.173 vt 0.062 0.313 0.173 vt 0.054 0.307 0.173 vt 0.056 0.296 0.173 vt 0.072 0.332 0.173 vt 0.059 0.339 0.173 vt 0.051 0.313 0.173 vt 0.047 0.286 0.173 vt 0.090 0.421 0.173 vt 0.105 0.426 0.173 vt 0.124 0.445 0.173 vt 0.116 0.454 0.173 vt 0.100 0.415 0.173 vt 0.105 0.412 0.173 vt 0.102 0.419 0.173 vt 0.126 0.433 0.173 vt 0.085 0.393 0.173 vt 0.077 0.377 0.173 vt 0.086 0.382 0.168 vt 0.093 0.372 0.173 vt 0.071 0.440 0.173 vt 0.014 0.441 0.173 vt 0.014 0.345 0.173 vt 0.077 0.359 0.173 vt 0.691 0.337 0.601 vt 0.700 0.334 0.601 vt 0.696 0.362 0.601 vt 0.698 0.353 0.601 vt 0.765 0.978 0.721 vt 0.740 0.975 0.721 vt 0.799 0.868 0.721 vt 0.597 0.747 -0.465 vt 0.611 0.783 -0.437 vt 0.638 0.776 -0.437 vt 0.621 0.733 -0.465 vt 0.648 0.761 -0.440 vt 0.644 0.754 -0.446 vt 0.645 0.778 -0.437 vt 0.579 0.752 -0.465 vt 0.590 0.787 -0.440 vt 0.542 0.754 -0.462 vt 0.556 0.791 -0.451 vt 0.643 0.715 -0.465 vt 0.634 0.678 -0.468 vt 0.606 0.693 -0.456 vt 0.593 0.685 -0.461 vt 0.571 0.695 -0.460 vt 0.572 0.710 -0.457 vt 0.563 0.668 -0.455 vt 0.553 0.670 -0.459 vt 0.561 0.686 -0.437 vt 0.566 0.684 -0.426 vt 0.554 0.695 -0.446 vt 0.547 0.707 -0.450 vt 0.541 0.682 -0.446 vt 0.525 0.688 -0.442 vt 0.576 0.668 -0.453 vt 0.569 0.652 -0.505 vt 0.556 0.654 -0.501 vt 0.603 0.655 -0.496 vt 0.595 0.649 -0.493 vt 0.585 0.658 -0.494 vt 0.586 0.664 -0.492 vt 0.577 0.651 -0.498 vt 0.586 0.642 -0.488 vt 0.582 0.634 -0.511 vt 0.570 0.634 -0.513 vt 0.577 0.645 -0.494 vt 0.557 0.631 -0.502 vt 0.563 0.651 -0.516 vt 0.533 0.670 -0.497 vt 0.521 0.674 -0.487 vt 0.588 0.624 -0.500 vt 0.597 0.626 -0.482 vt 0.609 0.620 -0.451 vt 0.564 0.611 -0.444 vt 0.454 0.857 -0.466 vt 0.485 0.886 -0.467 vt 0.497 0.846 -0.461 vt 0.462 0.834 -0.465 vt 0.525 0.846 -0.458 vt 0.563 0.844 -0.459 vt 0.518 0.777 -0.462 vt 0.645 0.790 -0.437 vt 0.636 0.805 -0.444 vt 0.643 0.805 -0.440 vt 0.640 0.813 -0.425 vt 0.644 0.817 -0.430 vt 0.650 0.809 -0.442 vt 0.653 0.790 -0.438 vt 0.657 0.776 -0.440 vt 0.654 0.769 -0.436 vt 0.467 0.802 -0.465 vt 0.498 0.818 -0.462 vt 0.499 0.775 -0.465 vt 0.470 0.774 -0.467 vt 0.651 0.753 -0.447 vt 0.661 0.741 -0.451 vt 0.517 0.713 -0.454 vt 0.512 0.735 -0.456 vt 0.544 0.728 -0.465 vt 0.499 0.707 -0.479 vt 0.386 0.562 -0.685 vt 0.388 0.597 -0.685 vt 0.411 0.596 -0.685 vt 0.424 0.552 -0.685 vt 0.431 0.768 -0.467 vt 0.423 0.813 -0.467 vt 0.441 0.742 -0.469 vt 0.456 0.760 -0.468 vt 0.460 0.745 -0.469 vt 0.449 0.721 -0.469 vt 0.408 0.746 -0.469 vt 0.413 0.734 -0.469 vt 0.667 0.706 -0.465 vt 0.670 0.722 -0.461 vt 0.430 0.709 -0.454 vt 0.397 0.522 -0.685 vt 0.395 0.491 -0.685 vt 0.387 0.496 -0.685 vt 0.389 0.523 -0.685 vt 0.389 0.442 -0.685 vt 0.367 0.448 -0.685 vt 0.384 0.469 -0.685 vt 0.409 0.461 -0.685 vt 0.457 0.478 -0.685 vt 0.468 0.464 -0.696 vt 0.453 0.440 -0.697 vt 0.437 0.450 -0.685 vt 0.445 0.513 -0.685 vt 0.477 0.499 -0.685 vt 0.425 0.499 -0.685 vt 0.495 0.484 -0.696 vt 0.510 0.452 -0.642 vt 0.497 0.445 -0.646 vt 0.462 0.528 -0.685 vt 0.423 0.527 -0.685 vt 0.474 0.542 -0.685 vt 0.445 0.562 -0.685 vt 0.367 0.420 -0.685 vt 0.334 0.432 -0.685 vt 0.351 0.404 -0.685 vt 0.323 0.418 -0.685 vt 0.422 0.427 -0.685 vt 0.395 0.403 -0.685 vt 0.474 0.760 -0.468 vt 0.493 0.756 -0.468 vt 0.379 0.470 -0.685 vt 0.448 0.419 -0.705 vt 0.447 0.388 -0.709 vt 0.480 0.420 -0.637 vt 0.485 0.401 -0.627 vt 0.478 0.587 -0.685 vt 0.496 0.568 -0.685 vt 0.486 0.600 -0.685 vt 0.515 0.584 -0.685 vt 0.395 0.801 -0.468 vt 0.678 0.800 -0.452 vt 0.688 0.779 -0.457 vt 0.660 0.758 -0.446 vt 0.706 0.767 -0.457 vt 0.467 0.627 -0.685 vt 0.487 0.631 -0.685 vt 0.501 0.611 -0.685 vt 0.538 0.562 -0.685 vt 0.528 0.603 -0.685 vt 0.550 0.583 -0.685 vt 0.513 0.398 -0.667 vt 0.496 0.414 -0.604 vt 0.502 0.418 -0.600 vt 0.523 0.406 -0.679 vt 0.521 0.549 -0.685 vt 0.508 0.511 -0.685 vt 0.486 0.431 -0.620 vt 0.506 0.432 -0.616 vt 0.527 0.421 -0.676 vt 0.545 0.559 -0.712 vt 0.551 0.566 -0.701 vt 0.583 0.550 -0.708 vt 0.584 0.532 -0.709 vt 0.612 0.550 -0.709 vt 0.594 0.551 -0.709 vt 0.589 0.564 -0.710 vt 0.598 0.562 -0.709 vt 0.598 0.537 -0.709 vt 0.611 0.577 -0.710 vt 0.617 0.570 -0.710 vt 0.619 0.561 -0.709 vt 0.610 0.570 -0.709 vt 0.589 0.577 -0.701 vt 0.629 0.566 -0.710 vt 0.632 0.565 -0.709 vt 0.632 0.555 -0.709 vt 0.625 0.558 -0.709 vt 0.620 0.536 -0.709 vt 0.576 0.387 -0.709 vt 0.574 0.413 -0.709 vt 0.603 0.416 -0.709 vt 0.605 0.396 -0.709 vt 0.570 0.439 -0.708 vt 0.609 0.439 -0.709 vt 0.572 0.467 -0.708 vt 0.620 0.466 -0.709 vt 0.572 0.490 -0.708 vt 0.623 0.493 -0.709 vt 0.538 0.492 -0.708 vt 0.531 0.463 -0.706 vt 0.623 0.515 -0.709 vt 0.555 0.509 -0.709 vt 0.627 0.419 -0.709 vt 0.647 0.429 -0.709 vt 0.524 0.437 -0.666 vt 0.521 0.356 -0.709 vt 0.554 0.364 -0.708 vt 0.661 0.511 -0.709 vt 0.662 0.494 -0.709 vt 0.680 0.507 -0.709 vt 0.681 0.501 -0.709 vt 0.752 0.685 -0.953 vt 0.746 0.673 -0.953 vt 0.731 0.679 -0.953 vt 0.738 0.692 -0.953 vt 0.742 0.665 -0.954 vt 0.726 0.671 -0.953 vt 0.737 0.654 -0.954 vt 0.721 0.659 -0.954 vt 0.733 0.642 -0.955 vt 0.716 0.649 -0.955 vt 0.720 0.620 -0.957 vt 0.710 0.605 -0.958 vt 0.705 0.612 -0.959 vt 0.711 0.625 -0.957 vt 0.703 0.601 -0.958 vt 0.700 0.603 -0.961 vt 0.699 0.629 -0.957 vt 0.694 0.612 -0.958 vt 0.695 0.604 -0.958 vt 0.713 0.676 -0.954 vt 0.698 0.655 -0.954 vt 0.756 0.664 -0.953 vt 0.749 0.652 -0.954 vt 0.665 0.524 -0.709 vt 0.681 0.514 -0.709 vt 0.766 0.677 -0.953 vt 0.694 0.494 -0.709 vt 0.684 0.487 -0.709 vt 0.717 0.692 -0.953 vt 0.766 0.647 -0.954 vt 0.748 0.630 -0.954 vt 0.733 0.611 -0.955 vt 0.722 0.614 -0.956 vt 0.778 0.662 -0.953 vt 0.695 0.631 -0.956 vt 0.690 0.637 -0.955 vt 0.674 0.640 -0.954 vt 0.678 0.661 -0.954 vt 0.762 0.619 -0.954 vt 0.747 0.602 -0.954 vt 0.733 0.598 -0.955 vt 0.720 0.599 -0.956 vt 0.677 0.627 -0.955 vt 0.686 0.617 -0.956 vt 0.711 0.598 -0.957 vt 0.718 0.610 -0.957 vt 0.688 0.610 -0.957 vt 0.695 0.626 -0.957 vt 0.696 0.597 -0.957 vt 0.414 0.480 -0.685 vt 0.360 0.450 -0.685 vt 0.331 0.436 -0.685 vt 0.652 0.454 -0.709 vt 0.682 0.679 -0.954 vt 0.698 0.676 -0.954 vt 0.773 0.634 -0.954 vt 0.679 0.699 -0.953 vt 0.695 0.697 -0.953 vt 0.788 0.651 -0.953 vt 0.793 0.639 -0.953 vt 0.861 0.723 -0.888 vt 0.848 0.731 -0.892 vt 0.863 0.747 -0.890 vt 0.883 0.735 -0.890 vt 0.855 0.720 -0.882 vt 0.845 0.726 -0.890 vt 0.848 0.713 -0.894 vt 0.840 0.719 -0.901 vt 0.844 0.708 -0.911 vt 0.833 0.714 -0.922 vt 0.826 0.685 -0.961 vt 0.816 0.672 -1.002 vt 0.810 0.676 -0.999 vt 0.820 0.689 -0.959 vt 0.813 0.691 -0.977 vt 0.801 0.679 -1.017 vt 0.831 0.733 -0.932 vt 0.823 0.719 -0.947 vt 0.855 0.694 -0.951 vt 0.835 0.680 -0.979 vt 0.864 0.716 -0.907 vt 0.859 0.711 -0.910 vt 0.869 0.703 -0.942 vt 0.808 0.696 -0.991 vt 0.794 0.706 -1.006 vt 0.809 0.722 -0.968 vt 0.862 0.685 -0.968 vt 0.848 0.669 -1.006 vt 0.825 0.666 -1.010 vt 0.816 0.666 -1.013 vt 0.824 0.676 -0.985 vt 0.796 0.678 -1.013 vt 0.795 0.684 -1.010 vt 0.803 0.685 -1.003 vt 0.817 0.738 -0.955 vt 0.876 0.697 -0.955 vt 0.668 0.471 -0.709 vt 0.691 0.461 -0.709 vt 0.672 0.442 -0.708 vt 0.848 0.762 -0.935 vt 0.629 0.397 -0.709 vt 0.644 0.401 -0.709 vt 0.741 0.427 -0.750 vt 0.721 0.422 -0.704 vt 0.718 0.446 -0.708 vt 0.741 0.443 -0.728 vt 0.746 0.415 -0.734 vt 0.733 0.401 -0.694 vt 0.702 0.418 -0.714 vt 0.699 0.454 -0.709 vt 0.711 0.392 -0.725 vt 0.675 0.413 -0.707 vt 0.679 0.396 -0.703 vt 0.840 0.774 -0.966 vt 0.817 0.772 -0.983 vt 0.659 0.538 -0.709 vt 0.648 0.573 -0.709 vt 0.651 0.559 -0.709 vt 0.693 0.558 -0.709 vt 0.684 0.544 -0.709 vt 0.668 0.560 -0.709 vt 0.679 0.577 -0.709 vt 0.686 0.533 -0.709 vt 0.685 0.525 -0.709 vt 0.913 0.704 -0.983 vt 0.887 0.717 -0.934 vt 0.628 0.574 -0.709 vt 0.623 0.597 -0.709 vt 0.610 0.598 -0.709 vt 0.591 0.597 -0.711 vt 0.711 0.753 -0.884 vt 0.723 0.763 -0.883 vt 0.736 0.760 -0.893 vt 0.725 0.749 -0.889 vt 0.747 0.754 -0.900 vt 0.737 0.743 -0.895 vt 0.752 0.751 -0.914 vt 0.742 0.740 -0.909 vt 0.788 0.725 -1.001 vt 0.786 0.720 -1.007 vt 0.769 0.729 -0.962 vt 0.774 0.734 -0.957 vt 0.780 0.738 -0.972 vt 0.794 0.729 -1.014 vt 0.747 0.772 -0.931 vt 0.762 0.763 -0.952 vt 0.762 0.715 -0.999 vt 0.734 0.726 -0.947 vt 0.724 0.741 -0.908 vt 0.726 0.729 -0.939 vt 0.785 0.751 -0.999 vt 0.771 0.773 -0.970 vt 0.790 0.765 -1.007 vt 0.751 0.704 -1.007 vt 0.734 0.713 -0.970 vt 0.779 0.713 -1.005 vt 0.773 0.720 -0.989 vt 0.787 0.716 -1.012 vt 0.787 0.741 -0.991 vt 0.798 0.739 -1.005 vt 0.799 0.731 -1.012 vt 0.762 0.775 -0.961 vt 0.726 0.715 -0.961 vt 0.740 0.793 -0.968 vt 0.757 0.794 -0.975 vt 0.703 0.714 -0.975 vt 0.700 0.733 -0.937 vt 0.646 0.821 -0.443 vt 0.659 0.833 -0.454 vt 0.636 0.824 -0.446 vt 0.628 0.839 -0.451 vt 0.638 0.852 -0.457 vt 0.630 0.817 -0.442 vt 0.615 0.835 -0.450 vt 0.203 0.940 -0.291 vt 0.225 0.894 -0.291 vt 0.264 0.917 -0.291 vt 0.213 0.950 -0.291 vt 0.238 0.881 -0.291 vt 0.281 0.893 -0.291 vt 0.255 0.859 -0.291 vt 0.291 0.865 -0.291 vt 0.261 0.832 -0.291 vt 0.289 0.825 -0.291 vt 0.236 0.767 -0.291 vt 0.268 0.756 -0.291 vt 0.203 0.715 -0.291 vt 0.226 0.700 -0.291 vt 0.165 0.659 -0.292 vt 0.183 0.647 -0.292 vt 0.126 0.574 -0.292 vt 0.146 0.581 -0.292 vt 0.116 0.525 -0.292 vt 0.121 0.528 -0.292 vt 0.314 0.767 -0.291 vt 0.328 0.815 -0.291 vt 0.249 0.684 -0.291 vt 0.295 0.734 -0.291 vt 0.201 0.637 -0.292 vt 0.158 0.579 -0.292 vt 0.123 0.522 -0.292 vt 0.322 0.855 -0.291 vt 0.363 0.821 -0.291 vt 0.338 0.844 -0.290 vt 0.340 0.851 -0.290 vt 0.330 0.862 -0.290 vt 0.330 0.878 -0.290 vt 0.319 0.881 -0.290 vt 0.325 0.888 -0.290 vt 0.320 0.900 -0.291 vt 0.342 0.894 -0.290 vt 0.333 0.900 -0.290 vt 0.353 0.802 -0.291 vt 0.364 0.783 -0.291 vt 0.368 0.783 -0.285 vt 0.368 0.799 -0.290 vt 0.340 0.792 -0.291 vt 0.355 0.777 -0.291 vt 0.369 0.773 -0.291 vt 0.377 0.783 -0.291 vt 0.374 0.796 -0.291 vt 0.381 0.805 -0.291 vt 0.368 0.782 -0.284 vt 0.314 0.932 -0.291 vt 0.364 0.837 -0.290 vt 0.374 0.850 -0.290 vt 0.349 0.852 -0.290 vt 0.376 0.877 -0.290 vt 0.380 0.880 -0.290 vt 0.374 0.890 -0.290 vt 0.370 0.877 -0.290 vt 0.343 0.876 -0.290 vt 0.373 0.840 -0.290 vt 0.389 0.841 -0.290 vt 0.385 0.850 -0.290 vt 0.379 0.858 -0.290 vt 0.385 0.871 -0.290 vt 0.345 0.913 -0.290 vt 0.398 0.846 -0.291 vt 0.404 0.867 -0.291 vt 0.385 0.891 -0.290 vt 0.409 0.889 -0.291 vt 0.411 0.901 -0.291 vt 0.386 0.908 -0.290 vt 0.262 0.675 -0.291 vt 0.315 0.721 -0.291 vt 0.211 0.632 -0.292 vt 0.163 0.577 -0.292 vt 0.335 0.781 -0.291 vt 0.347 0.772 -0.291 vt 0.372 0.918 -0.290 vt 0.372 0.939 -0.290 vt 0.335 0.938 -0.291 vt 0.381 0.927 -0.292 vt 0.385 0.932 -0.287 vt 0.419 0.914 -0.291 vt 0.392 0.922 -0.290 vt 0.564 0.899 -0.417 vt 0.556 0.895 -0.436 vt 0.534 0.892 -0.435 vt 0.540 0.908 -0.399 vt 0.545 0.910 -0.381 vt 0.535 0.915 -0.422 vt 0.524 0.931 -0.385 vt 0.533 0.931 -0.422 vt 0.553 0.926 -0.441 vt 0.601 0.873 -0.460 vt 0.606 0.880 -0.452 vt 0.612 0.875 -0.459 vt 0.605 0.872 -0.459 vt 0.379 0.374 0.257 vt 0.395 0.331 0.257 vt 0.417 0.331 0.257 vt 0.397 0.365 0.257 vt 0.357 0.348 0.257 vt 0.369 0.339 0.257 vt 0.432 0.356 0.257 vt 0.416 0.362 0.257 vt 0.118 0.199 0.365 vt 0.098 0.201 0.360 vt 0.133 0.232 0.365 vt 0.138 0.210 0.372 vt 0.390 0.287 0.257 vt 0.374 0.298 0.257 vt 0.379 0.242 0.257 vt 0.399 0.237 0.257 vt 0.364 0.236 0.257 vt 0.375 0.199 0.257 vt 0.392 0.203 0.257 vt 0.393 0.185 0.257 vt 0.379 0.181 0.257 vt 0.519 0.123 0.194 vt 0.531 0.162 0.263 vt 0.498 0.157 0.248 vt 0.504 0.133 0.211 vt 0.438 0.941 -0.291 vt 0.413 0.942 -0.291 vt 0.384 0.962 -0.291 vt 0.395 0.939 -0.294 vt 0.412 0.962 -0.291 vt 0.395 0.986 -0.291 vt 0.376 0.973 -0.291 vt 0.498 0.055 0.095 vt 0.521 0.069 0.118 vt 0.506 0.088 0.158 vt 0.491 0.083 0.156 vt 0.370 0.379 0.257 vt 0.355 0.382 0.257 vt 0.466 0.318 0.257 vt 0.470 0.350 0.257 vt 0.544 0.158 0.263 vt 0.562 0.190 0.346 vt 0.548 0.208 0.346 vt 0.573 0.203 0.382 vt 0.569 0.217 0.399 vt 0.803 0.618 0.349 vt 0.817 0.623 0.386 vt 0.809 0.631 0.373 vt 0.802 0.627 0.353 vt 0.786 0.610 0.318 vt 0.835 0.588 0.402 vt 0.838 0.598 0.408 vt 0.846 0.608 0.435 vt 0.890 0.638 0.432 vt 0.911 0.586 0.497 vt 0.920 0.588 0.479 vt 0.911 0.637 0.402 vt 0.882 0.567 0.479 vt 0.887 0.576 0.499 vt 0.916 0.572 0.508 vt 0.925 0.574 0.493 vt 0.896 0.558 0.493 vt 0.900 0.564 0.511 vt 0.918 0.564 0.514 vt 0.925 0.564 0.500 vt 0.911 0.558 0.517 vt 0.907 0.552 0.500 vt 0.877 0.626 0.476 vt 0.902 0.583 0.521 vt 0.895 0.580 0.522 vt 0.853 0.614 0.458 vt 0.909 0.569 0.526 vt 0.914 0.561 0.527 vt 0.905 0.567 0.526 vt 0.865 0.619 0.481 vt 0.858 0.642 0.476 vt 0.828 0.632 0.426 vt 0.870 0.675 0.399 vt 0.858 0.656 0.452 vt 0.936 0.481 0.530 vt 0.936 0.499 0.553 vt 0.913 0.530 0.614 vt 0.900 0.508 0.615 vt 0.867 0.503 0.683 vt 0.902 0.477 0.613 vt 0.797 0.433 0.635 vt 0.778 0.485 0.697 vt 0.760 0.479 0.665 vt 0.770 0.443 0.614 vt 0.813 0.454 0.703 vt 0.799 0.492 0.741 vt 0.847 0.519 0.718 vt 0.830 0.513 0.759 vt 0.855 0.482 0.715 vt 0.829 0.478 0.733 vt 0.819 0.504 0.759 vt 0.872 0.434 0.726 vt 0.846 0.450 0.726 vt 0.821 0.436 0.685 vt 0.868 0.411 0.712 vt 0.821 0.456 0.726 vt 0.840 0.463 0.736 vt 0.831 0.472 0.761 vt 0.867 0.459 0.704 vt 0.843 0.479 0.726 vt 0.878 0.473 0.678 vt 0.319 0.117 0.426 vt 0.328 0.119 0.417 vt 0.337 0.110 0.409 vt 0.330 0.095 0.408 vt 0.858 0.530 0.687 vt 0.765 0.522 0.759 vt 0.753 0.522 0.747 vt 0.824 0.558 0.757 vt 0.808 0.551 0.799 vt 0.783 0.530 0.806 vt 0.805 0.543 0.814 vt 0.796 0.539 0.826 vt 0.875 0.545 0.665 vt 0.831 0.568 0.747 vt 0.805 0.583 0.799 vt 0.795 0.572 0.815 vt 0.766 0.559 0.843 vt 0.755 0.549 0.799 vt 0.784 0.565 0.850 vt 0.775 0.562 0.861 vt 0.756 0.582 0.841 vt 0.750 0.584 0.830 vt 0.769 0.593 0.830 vt 0.767 0.589 0.841 vt 0.762 0.582 0.856 vt 0.810 0.388 0.581 vt 0.782 0.420 0.591 vt 0.798 0.378 0.543 vt 0.961 0.985 0.382 vt 0.972 0.944 0.444 vt 0.959 0.938 0.454 vt 0.947 0.980 0.399 vt 0.918 0.921 0.543 vt 0.941 0.918 0.522 vt 0.933 0.899 0.550 vt 0.908 0.902 0.575 vt 0.928 0.961 0.452 vt 0.923 0.942 0.497 vt 0.977 0.906 0.501 vt 0.973 0.905 0.505 vt 0.967 0.898 0.528 vt 0.965 0.892 0.538 vt 0.293 0.111 0.446 vt 0.290 0.118 0.449 vt 0.303 0.115 0.440 vt 0.304 0.108 0.435 vt 0.282 0.106 0.451 vt 0.277 0.108 0.452 vt 0.947 0.645 0.476 vt 0.932 0.645 0.497 vt 0.953 0.621 0.516 vt 0.960 0.631 0.484 vt 0.845 0.391 0.653 vt 0.267 0.092 0.439 vt 0.267 0.100 0.447 vt 0.278 0.102 0.449 vt 0.292 0.099 0.441 vt 0.299 0.045 0.396 vt 0.269 0.058 0.420 vt 0.279 0.070 0.423 vt 0.307 0.058 0.404 vt 0.288 0.029 0.389 vt 0.277 0.011 0.381 vt 0.257 0.025 0.395 vt 0.266 0.039 0.406 vt 0.251 0.125 0.456 vt 0.243 0.124 0.453 vt 0.256 0.138 0.459 vt 0.263 0.135 0.458 vt 0.230 0.042 0.396 vt 0.234 0.058 0.410 vt 0.256 0.045 0.457 vt 0.255 0.047 0.442 vt 0.257 0.085 0.433 vt 0.223 0.076 0.415 vt 0.231 0.101 0.436 vt 0.257 0.098 0.443 vt 0.190 0.114 0.418 vt 0.181 0.094 0.409 vt 0.209 0.129 0.436 vt 0.229 0.128 0.449 vt 0.210 0.144 0.444 vt 0.228 0.141 0.458 vt 0.266 0.150 0.460 vt 0.265 0.144 0.457 vt 0.244 0.144 0.463 vt 0.284 0.252 0.376 vt 0.289 0.230 0.388 vt 0.258 0.236 0.390 vt 0.251 0.260 0.377 vt 0.250 0.284 0.365 vt 0.280 0.276 0.366 vt 0.212 0.270 0.374 vt 0.223 0.288 0.364 vt 0.255 0.308 0.356 vt 0.279 0.290 0.360 vt 0.223 0.310 0.356 vt 0.199 0.303 0.359 vt 0.185 0.262 0.371 vt 0.165 0.278 0.364 vt 0.177 0.311 0.356 vt 0.186 0.346 0.348 vt 0.209 0.343 0.348 vt 0.267 0.205 0.416 vt 0.295 0.211 0.405 vt 0.240 0.197 0.422 vt 0.234 0.239 0.387 vt 0.205 0.202 0.409 vt 0.199 0.238 0.383 vt 0.235 0.351 0.345 vt 0.229 0.388 0.336 vt 0.251 0.386 0.336 vt 0.248 0.349 0.345 vt 0.216 0.364 0.343 vt 0.209 0.388 0.336 vt 0.197 0.355 0.345 vt 0.188 0.357 0.345 vt 0.269 0.410 0.332 vt 0.248 0.409 0.331 vt 0.255 0.433 0.326 vt 0.266 0.431 0.327 vt 0.260 0.447 0.324 vt 0.268 0.445 0.325 vt 0.261 0.453 0.323 vt 0.275 0.448 0.325 vt 0.267 0.381 0.336 vt 0.228 0.413 0.331 vt 0.286 0.352 0.343 vt 0.293 0.354 0.342 vt 0.295 0.345 0.345 vt 0.285 0.344 0.345 vt 0.280 0.372 0.338 vt 0.290 0.376 0.338 vt 0.286 0.331 0.348 vt 0.298 0.334 0.348 vt 0.304 0.315 0.354 vt 0.282 0.312 0.354 vt 0.274 0.431 0.329 vt 0.282 0.412 0.332 vt 0.241 0.445 0.325 vt 0.298 0.284 0.364 vt 0.310 0.258 0.374 vt 0.320 0.234 0.385 vt 0.329 0.212 0.396 vt 0.475 0.201 0.257 vt 0.481 0.203 0.257 vt 0.481 0.242 0.257 vt 0.465 0.241 0.257 vt 0.493 0.218 0.257 vt 0.488 0.201 0.257 vt 0.367 0.022 0.372 vt 0.375 0.047 0.398 vt 0.387 0.049 0.417 vt 0.384 0.023 0.393 vt 0.389 0.068 0.435 vt 0.392 0.072 0.442 vt 0.410 0.055 0.452 vt 0.384 0.069 0.427 vt 0.824 0.635 0.423 vt 0.816 0.627 0.389 vt 0.425 0.079 0.423 vt 0.415 0.072 0.437 vt 0.410 0.092 0.409 vt 0.424 0.101 0.389 vt 0.383 0.075 0.434 vt 0.396 0.078 0.434 vt 0.337 0.243 0.377 vt 0.351 0.217 0.382 vt 0.353 0.236 0.372 vt 0.360 0.258 0.369 vt 0.333 0.190 0.402 vt 0.315 0.180 0.422 vt 0.306 0.191 0.446 vt 0.968 0.585 0.515 vt 0.975 0.577 0.490 vt 0.985 0.588 0.499 vt 0.983 0.599 0.526 vt 0.958 0.563 0.479 vt 0.965 0.554 0.452 vt 0.982 0.628 0.475 vt 0.984 0.660 0.426 vt 0.971 0.550 0.437 vt 0.983 0.570 0.475 vt 0.974 0.542 0.423 vt 0.979 0.539 0.426 vt 0.972 0.599 0.532 vt 0.952 0.599 0.553 vt 0.948 0.581 0.530 vt 0.152 0.219 0.378 vt 0.153 0.202 0.383 vt 0.143 0.197 0.377 vt 0.147 0.283 0.360 vt 0.146 0.310 0.354 vt 0.151 0.329 0.350 vt 0.164 0.349 0.347 vt 0.151 0.247 0.367 vt 0.172 0.239 0.376 vt 0.114 0.323 0.351 vt 0.117 0.341 0.348 vt 0.320 0.341 0.346 vt 0.327 0.317 0.352 vt 0.318 0.294 0.360 vt 0.342 0.306 0.356 vt 0.334 0.262 0.369 vt 0.355 0.272 0.363 vt 0.318 0.362 0.342 vt 0.286 0.439 0.329 vt 0.291 0.425 0.332 vt 0.160 0.455 0.334 vt 0.184 0.450 0.331 vt 0.181 0.432 0.334 vt 0.162 0.440 0.336 vt 0.163 0.399 0.339 vt 0.142 0.416 0.339 vt 0.203 0.450 0.328 vt 0.200 0.432 0.331 vt 0.185 0.398 0.336 vt 0.176 0.404 0.337 vt 0.201 0.371 0.342 vt 0.189 0.377 0.341 vt 0.171 0.383 0.340 vt 0.168 0.365 0.344 vt 0.149 0.359 0.345 vt 0.129 0.383 0.342 vt 0.125 0.364 0.345 vt 0.112 0.282 0.355 vt 0.090 0.293 0.352 vt 0.216 0.448 0.327 vt 0.216 0.464 0.323 vt 0.247 0.465 0.321 vt 0.203 0.465 0.325 vt 0.268 0.497 0.314 vt 0.283 0.485 0.316 vt 0.236 0.501 0.318 vt 0.249 0.504 0.315 vt 0.280 0.457 0.323 vt 0.292 0.474 0.319 vt 0.261 0.517 0.312 vt 0.272 0.513 0.311 vt 0.284 0.506 0.311 vt 0.292 0.498 0.312 vt 0.236 0.514 0.315 vt 0.245 0.518 0.313 vt 0.297 0.491 0.313 vt 0.301 0.485 0.315 vt 0.228 0.535 0.311 vt 0.233 0.538 0.310 vt 0.225 0.541 0.310 vt 0.231 0.544 0.309 vt 0.220 0.550 0.308 vt 0.225 0.553 0.308 vt 0.212 0.562 0.307 vt 0.219 0.565 0.306 vt 0.198 0.487 0.324 vt 0.205 0.493 0.322 vt 0.222 0.525 0.318 vt 0.216 0.542 0.313 vt 0.205 0.560 0.312 vt 0.198 0.570 0.309 vt 0.203 0.571 0.306 vt 0.204 0.580 0.303 vt 0.208 0.585 0.309 vt 0.213 0.576 0.305 vt 0.210 0.570 0.304 vt 0.199 0.579 0.307 vt 0.198 0.590 0.309 vt 0.202 0.591 0.311 vt 0.196 0.588 0.310 vt 0.192 0.466 0.328 vt 0.189 0.479 0.327 vt 0.413 0.279 0.257 vt 0.421 0.232 0.257 vt 0.420 0.203 0.257 vt 0.211 0.163 0.451 vt 0.218 0.150 0.456 vt 0.209 0.165 0.460 vt 0.251 0.154 0.471 vt 0.260 0.159 0.467 vt 0.273 0.164 0.459 vt 0.265 0.164 0.464 vt 0.234 0.187 0.439 vt 0.225 0.178 0.447 vt 0.208 0.187 0.428 vt 0.236 0.150 0.466 vt 0.229 0.149 0.464 vt 0.232 0.155 0.465 vt 0.243 0.152 0.467 vt 0.219 0.176 0.447 vt 0.222 0.170 0.456 vt 0.211 0.175 0.448 vt 0.270 0.189 0.433 vt 0.274 0.184 0.440 vt 0.261 0.177 0.452 vt 0.255 0.180 0.445 vt 0.235 0.549 0.311 vt 0.225 0.570 0.310 vt 0.217 0.580 0.310 vt 0.250 0.533 0.312 vt 0.192 0.569 0.313 vt 0.200 0.555 0.317 vt 0.230 0.573 0.316 vt 0.220 0.585 0.315 vt 0.990 0.300 -0.059 vt 0.979 0.302 -0.059 vt 0.982 0.319 -0.059 vt 0.991 0.318 -0.059 vt 0.992 0.329 -0.059 vt 0.984 0.330 -0.059 vt 0.991 0.339 -0.060 vt 0.988 0.340 -0.060 vt 0.976 0.280 -0.059 vt 0.988 0.278 -0.059 vt 0.971 0.257 -0.059 vt 0.986 0.256 -0.059 vt 0.242 0.556 0.316 vt 0.253 0.541 0.315 vt 0.213 0.520 0.322 vt 0.208 0.538 0.318 vt 0.189 0.497 0.323 vt 0.196 0.503 0.322 vt 0.185 0.501 0.323 vt 0.191 0.508 0.322 vt 0.179 0.505 0.323 vt 0.186 0.513 0.322 vt 0.179 0.497 0.325 vt 0.160 0.508 0.327 vt 0.166 0.512 0.324 vt 0.163 0.525 0.324 vt 0.167 0.529 0.325 vt 0.175 0.521 0.323 vt 0.173 0.514 0.322 vt 0.159 0.519 0.325 vt 0.155 0.532 0.325 vt 0.156 0.535 0.327 vt 0.151 0.529 0.327 vt 0.195 0.515 0.323 vt 0.179 0.526 0.325 vt 0.211 0.505 0.322 vt 0.155 0.501 0.329 vt 0.170 0.493 0.328 vt 0.197 0.522 0.326 vt 0.183 0.533 0.328 vt 0.940 0.076 -0.059 vt 0.939 0.088 -0.059 vt 0.958 0.089 -0.059 vt 0.959 0.078 -0.059 vt 0.966 0.079 -0.060 vt 0.965 0.089 -0.060 vt 0.976 0.079 -0.060 vt 0.972 0.092 -0.060 vt 0.987 0.086 -0.063 vt 0.986 0.093 -0.064 vt 0.925 0.090 -0.059 vt 0.922 0.076 -0.059 vt 0.210 0.519 0.325 vt 0.172 0.480 0.330 vt 0.225 0.507 0.320 vt 0.977 0.223 -0.059 vt 0.989 0.207 -0.059 vt 0.977 0.199 -0.059 vt 0.960 0.205 -0.059 vt 0.221 0.509 0.324 vt 0.990 0.237 -0.059 vt 0.270 0.543 0.307 vt 0.277 0.540 0.307 vt 0.273 0.551 0.305 vt 0.280 0.549 0.305 vt 0.275 0.562 0.304 vt 0.283 0.557 0.304 vt 0.280 0.576 0.302 vt 0.287 0.574 0.301 vt 0.256 0.532 0.312 vt 0.266 0.557 0.308 vt 0.275 0.578 0.305 vt 0.276 0.591 0.304 vt 0.281 0.589 0.297 vt 0.289 0.595 0.286 vt 0.296 0.596 0.297 vt 0.292 0.585 0.297 vt 0.285 0.583 0.295 vt 0.284 0.599 0.297 vt 0.293 0.605 0.292 vt 0.297 0.604 0.300 vt 0.288 0.606 0.299 vt 0.287 0.549 0.307 vt 0.295 0.570 0.306 vt 0.298 0.585 0.303 vt 0.285 0.520 0.310 vt 0.268 0.579 0.312 vt 0.272 0.596 0.309 vt 0.302 0.568 0.312 vt 0.304 0.586 0.309 vt 0.955 0.307 -0.059 vt 0.943 0.302 -0.059 vt 0.938 0.322 -0.059 vt 0.948 0.325 -0.059 vt 0.945 0.335 -0.059 vt 0.937 0.332 -0.059 vt 0.939 0.343 -0.059 vt 0.935 0.341 -0.059 vt 0.949 0.279 -0.059 vt 0.962 0.282 -0.059 vt 0.953 0.248 -0.059 vt 0.296 0.548 0.313 vt 0.294 0.526 0.313 vt 0.259 0.559 0.313 vt 0.306 0.520 0.307 vt 0.311 0.515 0.307 vt 0.311 0.523 0.306 vt 0.315 0.517 0.306 vt 0.319 0.529 0.304 vt 0.323 0.524 0.304 vt 0.330 0.535 0.302 vt 0.333 0.531 0.303 vt 0.290 0.518 0.310 vt 0.310 0.532 0.308 vt 0.327 0.542 0.306 vt 0.337 0.548 0.306 vt 0.337 0.543 0.300 vt 0.346 0.541 0.297 vt 0.351 0.539 0.299 vt 0.342 0.534 0.301 vt 0.337 0.536 0.299 vt 0.344 0.547 0.302 vt 0.322 0.517 0.308 vt 0.339 0.526 0.307 vt 0.346 0.531 0.305 vt 0.308 0.498 0.313 vt 0.335 0.553 0.312 vt 0.322 0.546 0.312 vt 0.340 0.517 0.313 vt 0.351 0.529 0.309 vt 0.932 0.243 -0.059 vt 0.923 0.240 -0.059 vt 0.917 0.257 -0.059 vt 0.927 0.260 -0.059 vt 0.924 0.270 -0.059 vt 0.914 0.267 -0.059 vt 0.927 0.219 -0.059 vt 0.939 0.224 -0.059 vt 0.930 0.194 -0.059 vt 0.950 0.203 -0.059 vt 0.326 0.509 0.314 vt 0.313 0.498 0.315 vt 0.306 0.537 0.313 vt 0.917 0.159 -0.059 vt 0.953 0.158 -0.059 vt 0.954 0.131 -0.059 vt 0.918 0.137 -0.059 vt 0.293 0.453 0.326 vt 0.301 0.463 0.324 vt 0.515 0.310 0.257 vt 0.490 0.357 0.257 vt 0.316 0.491 0.312 vt 0.316 0.486 0.313 vt 0.325 0.491 0.311 vt 0.325 0.486 0.311 vt 0.332 0.489 0.310 vt 0.331 0.484 0.310 vt 0.340 0.489 0.310 vt 0.339 0.484 0.310 vt 0.310 0.496 0.313 vt 0.323 0.496 0.313 vt 0.340 0.494 0.313 vt 0.350 0.493 0.314 vt 0.348 0.489 0.310 vt 0.356 0.484 0.310 vt 0.356 0.481 0.310 vt 0.348 0.480 0.311 vt 0.344 0.486 0.309 vt 0.355 0.489 0.313 vt 0.323 0.478 0.316 vt 0.339 0.476 0.315 vt 0.348 0.477 0.314 vt 0.306 0.478 0.318 vt 0.351 0.497 0.318 vt 0.339 0.498 0.317 vt 0.339 0.471 0.319 vt 0.350 0.472 0.319 vt 0.907 0.217 -0.059 vt 0.898 0.211 -0.059 vt 0.891 0.223 -0.059 vt 0.897 0.228 -0.059 vt 0.892 0.236 -0.059 vt 0.885 0.233 -0.059 vt 0.909 0.197 -0.059 vt 0.920 0.203 -0.059 vt 0.918 0.178 -0.059 vt 0.324 0.472 0.320 vt 0.310 0.470 0.322 vt 0.323 0.500 0.316 vt 0.215 0.062 0.397 vt 0.176 0.085 0.401 vt 0.153 0.089 0.396 vt 0.142 0.089 0.391 vt 0.145 0.098 0.397 vt 0.162 0.098 0.403 vt 0.137 0.117 0.393 vt 0.108 0.087 0.373 vt 0.147 0.068 0.378 vt 0.141 0.078 0.384 vt 0.171 0.074 0.392 vt 0.166 0.059 0.379 vt 0.953 0.836 0.434 vt 0.934 0.863 0.427 vt 0.986 0.844 0.428 vt 0.972 0.813 0.434 vt 0.075 0.646 0.962 vt 0.101 0.665 0.963 vt 0.090 0.585 0.962 vt 0.074 0.608 0.962 vt 0.100 0.713 0.964 vt 0.079 0.677 0.963 vt 0.089 0.720 0.963 vt 0.096 0.746 0.962 vt 0.101 0.745 0.969 vt 0.063 0.684 0.962 vt 0.058 0.658 0.962 vt 0.079 0.725 0.963 vt 0.091 0.752 0.963 vt 0.053 0.625 0.962 vt 0.164 0.685 0.962 vt 0.147 0.671 0.962 vt 0.142 0.688 0.962 vt 0.150 0.699 0.962 vt 0.104 0.747 0.962 vt 0.108 0.750 0.963 vt 0.117 0.733 0.963 vt 0.110 0.728 0.964 vt 0.125 0.721 0.963 vt 0.116 0.710 0.963 vt 0.125 0.672 0.963 vt 0.133 0.639 0.962 vt 0.134 0.738 0.962 vt 0.160 0.712 0.962 vt 0.105 0.715 0.963 vt 0.114 0.667 0.963 vt 0.161 0.043 0.599 vt 0.186 0.055 0.382 vt 0.176 0.031 0.599 vt 0.884 0.834 0.418 vt 0.905 0.808 0.417 vt 0.881 0.797 0.403 vt 0.846 0.815 0.389 vt 0.888 0.768 0.401 vt 0.910 0.771 0.408 vt 0.752 0.937 0.721 vt 0.759 0.960 0.721 vt 0.816 0.938 0.722 vt 0.801 0.920 0.721 vt 0.736 0.957 0.721 vt 0.731 0.939 0.720 vt 0.700 0.960 0.721 vt 0.709 0.931 0.720 vt 0.655 0.926 0.719 vt 0.644 0.938 0.720 vt 0.612 0.920 0.701 vt 0.606 0.925 0.711 vt 0.777 0.879 0.721 vt 0.730 0.896 0.720 vt 0.704 0.902 0.720 vt 0.653 0.913 0.717 vt 0.611 0.917 0.708 vt 0.188 0.806 0.906 vt 0.191 0.856 0.906 vt 0.241 0.834 0.906 vt 0.220 0.794 0.906 vt 0.185 0.773 0.907 vt 0.205 0.767 0.906 vt 0.151 0.854 0.906 vt 0.160 0.807 0.906 vt 0.167 0.777 0.909 vt 0.119 0.850 0.906 vt 0.135 0.806 0.906 vt 0.148 0.779 0.908 vt 0.124 0.803 0.906 vt 0.099 0.841 0.906 vt 0.195 0.746 0.906 vt 0.183 0.749 0.906 vt 0.174 0.743 0.905 vt 0.195 0.900 0.906 vt 0.148 0.876 0.906 vt 0.971 0.755 0.431 vt 0.943 0.747 0.431 vt 0.954 0.793 0.436 vt 0.976 0.691 0.417 vt 0.952 0.704 0.423 vt 0.111 0.890 0.906 vt 0.755 0.850 0.721 vt 0.779 0.847 0.721 vt 0.790 0.811 0.722 vt 0.756 0.817 0.721 vt 0.894 0.935 0.722 vt 0.828 0.951 0.722 vt 0.864 0.975 0.722 vt 0.904 0.978 0.721 vt 0.685 0.872 0.720 vt 0.685 0.818 0.721 vt 0.669 0.827 0.721 vt 0.662 0.857 0.721 vt 0.764 0.862 0.721 vt 0.785 0.851 0.722 vt 0.743 0.867 0.721 vt 0.733 0.854 0.721 vt 0.706 0.858 0.720 vt 0.716 0.874 0.720 vt 0.625 0.885 0.720 vt 0.643 0.895 0.718 vt 0.610 0.909 0.717 vt 0.604 0.909 0.717 vt 0.692 0.883 0.720 vt 0.136 0.074 0.377 vt 0.138 0.067 0.371 vt 0.134 0.056 0.365 vt 0.143 0.055 0.370 vt 0.944 0.389 0.506 vt 0.948 0.371 0.510 vt 0.982 0.369 0.536 vt 0.988 0.393 0.540 vt 0.893 0.379 0.455 vt 0.887 0.372 0.457 vt 0.909 0.408 0.477 vt 0.904 0.406 0.472 vt 0.912 0.391 0.479 vt 0.877 0.372 0.443 vt 0.879 0.381 0.440 vt 0.214 0.421 0.330 vt 0.765 0.978 0.721 vt 0.740 0.975 0.721 vt 0.799 0.868 0.721 vt 0.619 0.182 0.599 vt 0.733 0.144 0.598 vt 0.723 0.176 0.596 vt 0.712 0.174 0.600 vt 0.563 0.337 0.616 vt 0.589 0.348 0.604 vt 0.562 0.075 0.607 vt 0.613 0.056 0.591 vt 0.637 0.035 0.604 vt 0.687 0.032 0.597 vt 0.734 0.006 0.596 vt 0.281 0.943 0.494 vt 0.351 0.673 0.445 vt 0.350 0.730 0.468 vt 0.351 0.694 0.455 vt 0.593 0.846 -0.455 vt 0.640 0.820 -0.420 vt 0.573 0.682 -0.408 vt 0.553 0.683 -0.421 vt 0.583 0.651 -0.475 vt 0.601 0.639 -0.491 vt 0.531 0.626 -0.447 vt 0.538 0.653 -0.511 vt 0.529 0.660 -0.506 vt 0.545 0.641 -0.514 vt 0.616 0.646 -0.504 vt 0.592 0.630 -0.504 vt 0.648 0.640 -0.468 vt 0.437 0.628 -0.685 vt 0.420 0.613 -0.685 vt 0.527 0.653 -0.492 vt 0.510 0.640 -0.443 vt 0.649 0.787 -0.420 vt 0.654 0.764 -0.418 vt 0.653 0.759 -0.433 vt 0.501 0.744 -0.468 vt 0.658 0.665 -0.468 vt 0.438 0.697 -0.491 vt 0.450 0.649 -0.685 vt 0.474 0.655 -0.685 vt 0.547 0.524 -0.709 vt 0.528 0.525 -0.708 vt 0.499 0.369 -0.697 vt 0.568 0.575 -0.720 vt 0.554 0.586 -0.723 vt 0.564 0.596 -0.696 vt 0.613 0.558 -0.709 vt 0.698 0.510 -0.709 vt 0.300 0.430 -0.685 vt 0.683 0.473 -0.709 vt 0.701 0.483 -0.709 vt 0.714 0.492 -0.709 vt 0.805 0.670 -1.024 vt 0.836 0.665 -1.013 vt 0.792 0.694 -1.013 vt 0.741 0.458 -0.752 vt 0.703 0.574 -0.710 vt 0.795 0.722 -1.024 vt 0.767 0.704 -1.015 vt 0.798 0.753 -1.015 vt 0.730 0.778 -0.915 vt 0.729 0.554 -0.937 vt 0.726 0.573 -0.831 vt 0.710 0.560 -0.852 vt 0.609 0.865 -0.458 vt 0.617 0.861 -0.457 vt 0.343 0.860 -0.290 vt 0.342 0.888 -0.290 vt 0.378 0.838 -0.290 vt 0.371 0.864 -0.290 vt 0.374 0.872 -0.291 vt 0.379 0.866 -0.246 vt 0.375 0.908 -0.290 vt 0.371 0.896 -0.290 vt 0.379 0.905 -0.290 vt 0.492 0.904 -0.459 vt 0.336 0.740 -0.291 vt 0.333 0.746 -0.291 vt 0.346 0.750 -0.291 vt 0.342 0.756 -0.291 vt 0.356 0.761 -0.291 vt 0.118 0.520 -0.292 vt 0.389 0.825 -0.291 vt 0.387 0.925 -0.262 vt 0.048 0.758 0.173 vt 0.054 0.734 0.173 vt 0.061 0.742 0.173 vt 0.640 0.862 -0.460 vt 0.059 0.979 0.173 vt 0.117 0.988 0.173 vt 0.061 0.959 0.173 vt 0.576 0.888 -0.406 vt 0.589 0.865 -0.461 vt 0.584 0.882 -0.410 vt 0.589 0.886 -0.402 vt 0.585 0.893 -0.415 vt 0.573 0.899 -0.388 vt 0.560 0.906 -0.441 vt 0.547 0.916 -0.399 vt 0.540 0.913 -0.377 vt 0.360 0.961 -0.290 vt 0.373 0.951 -0.256 vt 0.362 0.949 -0.295 vt 0.519 0.920 -0.431 vt 0.511 0.928 -0.430 vt 0.374 0.966 -0.291 vt 0.547 0.942 -0.405 vt 0.526 0.940 -0.403 vt 0.550 0.921 -0.418 vt 0.580 0.910 -0.445 vt 0.006 0.834 0.173 vt 0.077 0.888 0.183 vt 0.449 0.282 0.257 vt 0.479 0.051 0.100 vt 0.444 0.043 0.119 vt 0.432 0.255 0.257 vt 0.461 0.209 0.257 vt 0.449 0.205 0.257 vt 0.402 0.182 0.257 vt 0.390 0.164 0.257 vt 0.466 0.191 0.257 vt 0.483 0.175 0.298 vt 0.515 0.190 0.292 vt 0.420 0.181 0.257 vt 0.481 0.285 0.257 vt 0.457 0.189 0.257 vt 0.469 0.185 0.257 vt 0.434 0.178 0.257 vt 0.451 0.183 0.257 vt 0.520 0.211 0.318 vt 0.542 0.123 0.193 vt 0.551 0.080 0.107 vt 0.889 0.682 0.346 vt 0.916 0.688 0.318 vt 0.919 0.555 0.518 vt 0.993 0.520 0.543 vt 0.992 0.501 0.497 vt 0.942 0.525 0.591 vt 0.316 0.159 0.424 vt 0.318 0.136 0.427 vt 0.338 0.152 0.409 vt 0.335 0.167 0.406 vt 0.383 0.100 0.375 vt 0.356 0.108 0.394 vt 0.348 0.088 0.393 vt 0.339 0.128 0.404 vt 0.338 0.125 0.414 vt 0.757 0.592 0.841 vt 0.943 0.660 0.452 vt 0.973 0.893 0.530 vt 0.111 0.974 0.173 vt 0.006 0.974 0.173 vt 0.168 0.154 0.405 vt 0.178 0.161 0.411 vt 0.159 0.169 0.397 vt 0.121 0.975 0.173 vt 0.329 0.077 0.404 vt 0.298 0.083 0.425 vt 0.283 0.074 0.424 vt 0.260 0.064 0.448 vt 0.268 0.076 0.426 vt 0.300 0.140 0.439 vt 0.311 0.144 0.433 vt 0.956 0.501 0.544 vt 0.819 0.374 0.575 vt 0.266 0.050 0.414 vt 0.250 0.073 0.424 vt 0.253 0.060 0.417 vt 0.254 0.051 0.427 vt 0.255 0.035 0.419 vt 0.254 0.037 0.416 vt 0.241 0.028 0.395 vt 0.275 0.127 0.461 vt 0.270 0.119 0.459 vt 0.263 0.114 0.480 vt 0.261 0.106 0.451 vt 0.277 0.133 0.454 vt 0.249 0.114 0.452 vt 0.264 0.127 0.479 vt 0.260 0.125 0.465 vt 0.287 0.152 0.447 vt 0.184 0.152 0.421 vt 0.193 0.173 0.429 vt 0.182 0.174 0.411 vt 0.245 0.132 0.459 vt 0.300 0.171 0.432 vt 0.284 0.171 0.452 vt 0.281 0.163 0.460 vt 0.274 0.175 0.482 vt 0.250 0.185 0.436 vt 0.164 0.208 0.388 vt 0.270 0.356 0.342 vt 0.270 0.341 0.347 vt 0.297 0.296 0.359 vt 0.157 0.188 0.388 vt 0.144 0.175 0.386 vt 0.129 0.958 0.173 vt 0.494 0.243 0.257 vt 0.400 0.029 0.419 vt 0.350 0.036 0.373 vt 0.364 0.064 0.409 vt 0.352 0.052 0.389 vt 0.427 0.055 0.479 vt 0.973 0.619 0.494 vt 0.985 0.611 0.499 vt 0.940 0.614 0.544 vt 0.968 0.611 0.520 vt 0.507 0.282 0.257 vt 0.121 0.192 0.368 vt 0.134 0.253 0.361 vt 0.301 0.395 0.336 vt 0.186 0.473 0.330 vt 0.983 0.184 -0.059 vt 0.964 0.180 -0.059 vt 0.176 0.469 0.332 vt 0.217 0.164 0.460 vt 0.245 0.188 0.433 vt 0.251 0.161 0.472 vt 0.255 0.171 0.463 vt 0.244 0.168 0.464 vt 0.243 0.177 0.453 vt 0.244 0.162 0.481 vt 0.230 0.169 0.459 vt 0.227 0.172 0.460 vt 0.237 0.178 0.464 vt 0.228 0.165 0.461 vt 0.232 0.146 0.470 vt 0.236 0.146 0.465 vt 0.210 0.587 0.312 vt 0.196 0.578 0.310 vt 0.197 0.592 0.312 vt 0.990 0.344 -0.060 vt 0.176 0.535 0.328 vt 0.170 0.531 0.327 vt 0.157 0.518 0.327 vt 0.152 0.509 0.329 vt 0.152 0.534 0.327 vt 0.989 0.090 -0.058 vt 0.299 0.595 0.303 vt 0.281 0.600 0.302 vt 0.294 0.608 0.301 vt 0.935 0.346 -0.059 vt 0.358 0.551 0.309 vt 0.914 0.284 -0.059 vt 0.353 0.537 0.303 vt 0.344 0.550 0.307 vt 0.927 0.112 -0.059 vt 0.365 0.486 0.317 vt 0.883 0.245 -0.060 vt 0.357 0.480 0.312 vt 0.356 0.491 0.316 vt 0.991 0.220 -0.059 vt 0.220 0.056 0.399 vt 0.841 0.831 0.393 vt 0.829 0.813 0.379 vt 0.858 0.858 0.410 vt 0.468 0.690 0.962 vt 0.483 0.681 0.962 vt 0.478 0.704 0.962 vt 0.174 0.698 0.962 vt 0.112 0.757 0.963 vt 0.109 0.595 0.962 vt 0.123 0.601 0.962 vt 0.101 0.755 0.963 vt 0.745 0.176 0.596 vt 0.756 0.173 0.600 vt 0.905 0.338 0.601 vt 0.878 0.898 0.722 vt 0.855 0.884 0.722 vt 0.820 0.876 0.722 vt 0.218 0.872 0.906 vt 0.183 0.732 0.906 vt 0.086 0.812 0.906 vt 0.122 0.781 0.906 vt 0.146 0.755 0.906 vt 0.164 0.738 0.906 vt 0.146 0.923 0.906 vt 0.125 0.908 0.906 vt 0.917 0.743 0.428 vt 0.180 0.930 0.906 vt 0.879 0.349 0.601 vt 0.953 0.683 0.417 vt 0.955 0.673 0.413 vt 0.716 0.822 0.721 vt 0.811 0.978 0.722 vt 0.904 0.978 0.721 vt 0.604 0.916 0.715 vt 0.904 0.074 0.599 vt 0.853 0.056 0.598 vt 0.829 0.035 0.598 vt 0.779 0.031 0.597 vt 0.493 0.680 0.946 vt 0.940 0.431 0.494 vt 0.055 0.249 0.173 vt 0.062 0.225 0.173 vt 0.068 0.234 0.173 vt 0.067 0.471 0.173 vt 0.068 0.450 0.173 vt 0.124 0.480 0.173 vt 0.014 0.325 0.173 vt 0.085 0.380 0.183 vt 0.119 0.465 0.173 vt 0.014 0.465 0.173 vt 0.129 0.467 0.173 vt 0.136 0.449 0.173 vt 0.593 0.846 -0.455 vt 0.640 0.820 -0.420 vt 0.573 0.682 -0.408 vt 0.553 0.683 -0.421 vt 0.583 0.651 -0.475 vt 0.601 0.639 -0.491 vt 0.531 0.626 -0.447 vt 0.538 0.653 -0.511 vt 0.529 0.660 -0.506 vt 0.545 0.641 -0.514 vt 0.616 0.646 -0.504 vt 0.592 0.630 -0.504 vt 0.648 0.640 -0.468 vt 0.437 0.628 -0.685 vt 0.420 0.613 -0.685 vt 0.527 0.653 -0.492 vt 0.510 0.640 -0.443 vt 0.649 0.787 -0.420 vt 0.654 0.764 -0.418 vt 0.653 0.759 -0.433 vt 0.501 0.744 -0.468 vt 0.658 0.665 -0.468 vt 0.438 0.697 -0.491 vt 0.450 0.649 -0.685 vt 0.474 0.655 -0.685 vt 0.547 0.524 -0.709 vt 0.528 0.525 -0.708 vt 0.499 0.369 -0.697 vt 0.568 0.575 -0.720 vt 0.554 0.586 -0.723 vt 0.564 0.596 -0.696 vt 0.613 0.558 -0.709 vt 0.698 0.510 -0.709 vt 0.300 0.430 -0.685 vt 0.683 0.473 -0.709 vt 0.714 0.492 -0.709 vt 0.701 0.483 -0.709 vt 0.805 0.670 -1.024 vt 0.836 0.665 -1.013 vt 0.792 0.694 -1.013 vt 0.741 0.458 -0.752 vt 0.703 0.574 -0.710 vt 0.795 0.722 -1.024 vt 0.767 0.704 -1.015 vt 0.798 0.753 -1.015 vt 0.730 0.778 -0.915 vt 0.729 0.554 -0.937 vt 0.710 0.560 -0.852 vt 0.726 0.573 -0.831 vt 0.609 0.865 -0.458 vt 0.617 0.861 -0.457 vt 0.343 0.860 -0.290 vt 0.342 0.888 -0.290 vt 0.378 0.838 -0.290 vt 0.371 0.864 -0.290 vt 0.379 0.866 -0.246 vt 0.374 0.872 -0.291 vt 0.375 0.908 -0.290 vt 0.371 0.896 -0.290 vt 0.379 0.905 -0.290 vt 0.492 0.904 -0.459 vt 0.336 0.740 -0.291 vt 0.333 0.746 -0.291 vt 0.346 0.750 -0.291 vt 0.342 0.756 -0.291 vt 0.356 0.761 -0.291 vt 0.118 0.520 -0.292 vt 0.389 0.825 -0.291 vt 0.387 0.925 -0.262 vt 0.640 0.862 -0.460 vt 0.576 0.888 -0.406 vt 0.589 0.865 -0.461 vt 0.584 0.882 -0.410 vt 0.585 0.893 -0.415 vt 0.589 0.886 -0.402 vt 0.573 0.899 -0.388 vt 0.560 0.906 -0.441 vt 0.547 0.916 -0.399 vt 0.540 0.913 -0.377 vt 0.360 0.961 -0.290 vt 0.362 0.949 -0.295 vt 0.373 0.951 -0.256 vt 0.519 0.920 -0.431 vt 0.511 0.928 -0.430 vt 0.374 0.966 -0.291 vt 0.526 0.940 -0.403 vt 0.547 0.942 -0.405 vt 0.550 0.921 -0.418 vt 0.580 0.910 -0.445 vt 0.449 0.282 0.257 vt 0.479 0.051 0.100 vt 0.444 0.043 0.119 vt 0.432 0.255 0.257 vt 0.461 0.209 0.257 vt 0.449 0.205 0.257 vt 0.402 0.182 0.257 vt 0.390 0.164 0.257 vt 0.466 0.191 0.257 vt 0.483 0.175 0.298 vt 0.515 0.190 0.292 vt 0.420 0.181 0.257 vt 0.481 0.285 0.257 vt 0.457 0.189 0.257 vt 0.469 0.185 0.257 vt 0.434 0.178 0.257 vt 0.451 0.183 0.257 vt 0.520 0.211 0.318 vt 0.542 0.123 0.193 vt 0.551 0.080 0.107 vt 0.889 0.682 0.346 vt 0.916 0.688 0.318 vt 0.919 0.555 0.518 vt 0.993 0.520 0.543 vt 0.942 0.525 0.591 vt 0.992 0.501 0.497 vt 0.316 0.159 0.424 vt 0.338 0.152 0.409 vt 0.318 0.136 0.427 vt 0.335 0.167 0.406 vt 0.383 0.100 0.375 vt 0.348 0.088 0.393 vt 0.356 0.108 0.394 vt 0.338 0.125 0.414 vt 0.339 0.128 0.404 vt 0.757 0.592 0.841 vt 0.943 0.660 0.452 vt 0.973 0.893 0.530 vt 0.168 0.154 0.405 vt 0.159 0.169 0.397 vt 0.178 0.161 0.411 vt 0.329 0.077 0.404 vt 0.298 0.083 0.425 vt 0.283 0.074 0.424 vt 0.260 0.064 0.448 vt 0.268 0.076 0.426 vt 0.300 0.140 0.439 vt 0.311 0.144 0.433 vt 0.956 0.501 0.544 vt 0.819 0.374 0.575 vt 0.266 0.050 0.414 vt 0.250 0.073 0.424 vt 0.253 0.060 0.417 vt 0.254 0.051 0.427 vt 0.255 0.035 0.419 vt 0.254 0.037 0.416 vt 0.241 0.028 0.395 vt 0.270 0.119 0.459 vt 0.275 0.127 0.461 vt 0.263 0.114 0.480 vt 0.261 0.106 0.451 vt 0.277 0.133 0.454 vt 0.249 0.114 0.452 vt 0.264 0.127 0.479 vt 0.260 0.125 0.465 vt 0.287 0.152 0.447 vt 0.184 0.152 0.421 vt 0.193 0.173 0.429 vt 0.182 0.174 0.411 vt 0.245 0.132 0.459 vt 0.300 0.171 0.432 vt 0.284 0.171 0.452 vt 0.281 0.163 0.460 vt 0.274 0.175 0.482 vt 0.250 0.185 0.436 vt 0.164 0.208 0.388 vt 0.270 0.356 0.342 vt 0.270 0.341 0.347 vt 0.297 0.296 0.359 vt 0.157 0.188 0.388 vt 0.144 0.175 0.386 vt 0.494 0.243 0.257 vt 0.400 0.029 0.419 vt 0.350 0.036 0.373 vt 0.364 0.064 0.409 vt 0.352 0.052 0.389 vt 0.427 0.055 0.479 vt 0.985 0.611 0.499 vt 0.973 0.619 0.494 vt 0.940 0.614 0.544 vt 0.968 0.611 0.520 vt 0.507 0.282 0.257 vt 0.121 0.192 0.368 vt 0.134 0.253 0.361 vt 0.301 0.395 0.336 vt 0.186 0.473 0.330 vt 0.983 0.184 -0.059 vt 0.964 0.180 -0.059 vt 0.176 0.469 0.332 vt 0.217 0.164 0.460 vt 0.245 0.188 0.433 vt 0.251 0.161 0.472 vt 0.244 0.168 0.464 vt 0.255 0.171 0.463 vt 0.243 0.177 0.453 vt 0.244 0.162 0.481 vt 0.230 0.169 0.459 vt 0.227 0.172 0.460 vt 0.237 0.178 0.464 vt 0.228 0.165 0.461 vt 0.236 0.146 0.465 vt 0.232 0.146 0.470 vt 0.210 0.587 0.312 vt 0.196 0.578 0.310 vt 0.197 0.592 0.312 vt 0.990 0.344 -0.060 vt 0.176 0.535 0.328 vt 0.170 0.531 0.327 vt 0.157 0.518 0.327 vt 0.152 0.509 0.329 vt 0.152 0.534 0.327 vt 0.989 0.090 -0.058 vt 0.299 0.595 0.303 vt 0.281 0.600 0.302 vt 0.294 0.608 0.301 vt 0.935 0.346 -0.059 vt 0.358 0.551 0.309 vt 0.914 0.284 -0.059 vt 0.353 0.537 0.303 vt 0.344 0.550 0.307 vt 0.927 0.112 -0.059 vt 0.365 0.486 0.317 vt 0.883 0.245 -0.060 vt 0.357 0.480 0.312 vt 0.356 0.491 0.316 vt 0.991 0.220 -0.059 vt 0.220 0.056 0.399 vt 0.841 0.831 0.393 vt 0.829 0.813 0.379 vt 0.858 0.858 0.410 vt 0.468 0.690 0.962 vt 0.478 0.704 0.962 vt 0.483 0.681 0.962 vt 0.174 0.698 0.962 vt 0.112 0.757 0.963 vt 0.109 0.595 0.962 vt 0.123 0.601 0.962 vt 0.101 0.755 0.963 vt 0.878 0.898 0.722 vt 0.893 0.927 0.722 vt 0.855 0.884 0.722 vt 0.820 0.876 0.722 vt 0.218 0.872 0.906 vt 0.183 0.732 0.906 vt 0.086 0.812 0.906 vt 0.122 0.781 0.906 vt 0.146 0.755 0.906 vt 0.164 0.738 0.906 vt 0.125 0.908 0.906 vt 0.146 0.923 0.906 vt 0.917 0.743 0.428 vt 0.180 0.930 0.906 vt 0.955 0.673 0.413 vt 0.953 0.683 0.417 vt 0.716 0.822 0.721 vt 0.811 0.978 0.722 vt 0.604 0.916 0.715 vt 0.493 0.680 0.946 vt 0.940 0.431 0.494 # 3263 texture vertices vn 0.760 -0.649 0.033 vn 0.982 -0.127 0.139 vn 0.978 -0.195 -0.079 vn 0.740 -0.425 0.521 vn 0.924 -0.223 0.310 vn 0.963 -0.145 0.228 vn 0.830 -0.154 0.537 vn 0.718 -0.501 0.483 vn 0.563 0.011 0.826 vn 0.487 -0.038 0.872 vn 0.220 0.118 0.968 vn 0.355 0.055 0.933 vn 0.347 -0.199 0.916 vn 0.941 -0.019 -0.339 vn 0.968 -0.027 -0.251 vn 0.990 0.074 -0.116 vn 0.973 -0.011 0.231 vn 0.926 -0.053 0.374 vn 0.783 0.176 0.596 vn 0.798 0.109 0.592 vn 0.718 -0.257 0.646 vn 0.410 0.238 0.881 vn 0.418 0.124 0.900 vn 0.561 0.192 0.805 vn 0.677 0.407 0.614 vn 0.572 0.121 0.811 vn 0.479 0.413 0.775 vn 0.056 0.253 0.966 vn 0.070 -0.036 0.997 vn 0.233 -0.432 0.871 vn 0.207 -0.259 0.943 vn 0.476 -0.109 0.873 vn 0.118 0.100 0.988 vn -0.115 0.133 0.984 vn 0.094 -0.325 0.941 vn 0.667 -0.504 0.549 vn -0.310 0.255 0.916 vn 0.287 0.104 0.952 vn 0.810 -0.225 0.542 vn -0.172 0.397 0.901 vn 0.458 0.123 0.881 vn 0.654 -0.051 0.754 vn -0.188 0.392 0.901 vn -0.268 0.311 0.912 vn 0.293 0.239 0.926 vn 0.401 0.117 0.909 vn 0.055 0.424 0.904 vn 0.475 0.141 0.868 vn 0.114 -0.170 0.979 vn 0.619 -0.352 0.702 vn -0.300 -0.035 0.953 vn -0.006 -0.019 1.000 vn 0.321 -0.104 0.941 vn 0.152 -0.317 0.936 vn 0.191 -0.631 0.752 vn 0.365 0.080 0.928 vn -0.037 0.280 0.959 vn -0.101 0.072 0.992 vn -0.160 -0.184 0.970 vn -0.349 -0.486 0.801 vn 0.338 0.508 0.792 vn 0.374 0.621 0.689 vn 0.317 0.920 0.232 vn 0.761 0.631 0.151 vn -0.054 0.443 0.895 vn 0.639 -0.190 0.746 vn 0.371 -0.106 0.922 vn 0.557 -0.288 -0.779 vn 0.964 -0.251 0.091 vn 0.984 0.034 0.176 vn 0.737 -0.570 -0.364 vn 0.936 -0.122 0.329 vn 0.653 -0.556 0.514 vn 0.242 -0.799 0.551 vn 0.866 -0.263 0.426 vn 0.465 -0.602 0.650 vn 0.179 -0.803 0.569 vn 0.685 -0.704 -0.187 vn 0.599 -0.614 0.513 vn 0.123 -0.776 0.619 vn 0.918 -0.375 0.126 vn 0.731 0.062 -0.680 vn 0.606 -0.592 -0.532 vn 0.946 0.121 -0.301 vn 0.772 -0.611 -0.177 vn 0.816 0.071 -0.574 vn 0.848 -0.483 0.218 vn 0.195 -0.811 0.552 vn 0.920 -0.189 -0.343 vn 0.349 -0.682 -0.643 vn 0.503 -0.320 -0.803 vn 0.565 -0.384 -0.730 vn 0.046 0.040 -0.998 vn 0.510 -0.351 -0.785 vn 0.217 -0.525 -0.823 vn 0.282 -0.947 0.151 vn 0.888 0.390 -0.245 vn 0.814 0.524 -0.250 vn 0.108 -0.109 -0.988 vn 0.010 0.148 -0.989 vn -0.110 0.152 0.982 vn -0.177 0.366 0.913 vn 0.533 0.387 0.753 vn 0.510 0.578 0.637 vn -0.246 0.841 -0.482 vn -0.275 0.958 -0.084 vn -0.116 0.904 0.411 vn 0.000 0.451 0.893 vn -0.165 0.231 0.959 vn -0.256 0.654 0.712 vn 0.118 0.737 0.665 vn -0.106 0.203 0.973 vn 0.327 0.060 0.943 vn -0.164 0.318 0.934 vn 0.185 0.107 0.977 vn 0.090 0.361 0.928 vn -0.552 0.308 0.775 vn -0.638 0.446 0.627 vn -0.838 0.216 0.501 vn -0.297 0.215 0.930 vn -0.491 0.350 0.797 vn -0.663 0.301 0.686 vn -0.077 0.082 0.994 vn 0.116 0.881 0.459 vn -0.078 -0.036 0.996 vn 0.206 -0.039 0.978 vn 0.321 0.056 0.946 vn 0.741 -0.240 0.627 vn 0.726 -0.196 0.659 vn 0.508 0.244 0.826 vn 0.647 -0.292 0.704 vn -0.246 0.582 0.775 vn 0.011 0.107 0.994 vn 0.395 -0.145 0.907 vn -0.752 -0.300 0.588 vn 0.451 -0.532 0.717 vn -0.320 0.482 0.816 vn -0.806 0.309 0.505 vn -0.602 -0.614 0.511 vn -0.551 -0.627 0.550 vn -0.519 0.642 0.565 vn -0.268 0.165 0.949 vn -0.936 0.107 0.336 vn -0.718 0.204 0.666 vn -0.927 -0.040 0.372 vn -0.885 0.378 0.273 vn -0.697 0.219 0.683 vn -0.861 0.186 -0.473 vn 0.873 -0.079 0.481 vn 0.033 0.557 0.830 vn -0.744 0.039 0.667 vn 0.566 -0.760 0.320 vn -0.417 -0.808 0.417 vn -0.107 -0.049 0.993 vn 0.257 -0.940 0.223 vn 0.621 -0.556 0.553 vn -0.148 -0.639 0.755 vn -0.188 -0.217 0.958 vn 0.190 -0.931 0.311 vn -0.191 -0.951 0.245 vn 0.205 -0.974 0.092 vn -0.971 -0.112 0.213 vn -0.572 0.320 0.755 vn -0.677 -0.534 0.505 vn 0.810 -0.250 0.530 vn 0.266 -0.124 0.956 vn 0.449 -0.856 0.258 vn 0.592 -0.786 0.179 vn 0.892 0.192 0.410 vn 0.855 -0.512 0.083 vn -0.566 -0.817 0.110 vn -0.412 -0.131 -0.901 vn -0.850 -0.420 -0.319 vn -0.923 0.376 0.080 vn -0.865 -0.486 0.124 vn -0.829 -0.508 0.234 vn -0.503 -0.859 0.096 vn -0.771 0.070 0.633 vn 0.343 0.015 0.939 vn 0.313 0.538 0.783 vn 0.597 -0.000 0.802 vn 0.652 0.430 0.624 vn 0.910 0.206 0.360 vn 0.522 0.064 0.850 vn 0.735 0.360 0.574 vn 0.175 -0.315 -0.933 vn -0.543 -0.057 -0.838 vn -0.966 0.219 0.138 vn -0.865 0.038 -0.500 vn 0.003 -0.667 -0.745 vn -0.486 -0.352 -0.800 vn 0.341 0.722 0.602 vn 0.832 -0.177 0.525 vn 0.224 0.046 0.974 vn 0.587 -0.278 0.760 vn 0.445 0.026 0.895 vn 0.665 -0.173 0.727 vn -0.970 0.221 -0.106 vn -0.909 0.022 0.415 vn -0.987 -0.069 0.143 vn 0.002 -0.351 -0.936 vn 0.357 0.418 -0.835 vn 0.793 -0.448 -0.412 vn -0.004 -0.977 -0.215 vn 0.771 -0.436 -0.464 vn 0.940 -0.341 0.024 vn 0.941 -0.335 0.042 vn 0.884 -0.266 0.386 vn 0.929 -0.369 0.002 vn 0.934 -0.201 -0.296 vn -0.588 0.783 -0.204 vn 0.444 0.862 -0.246 vn 0.779 0.616 -0.119 vn -0.552 0.731 -0.402 vn 0.294 0.889 -0.350 vn -0.363 0.925 -0.115 vn 0.399 0.914 -0.075 vn 0.077 0.975 -0.206 vn -0.815 0.405 -0.414 vn -0.975 0.106 -0.196 vn -0.980 0.197 -0.038 vn -0.950 0.303 0.070 vn -0.941 -0.332 -0.065 vn -0.964 0.105 -0.243 vn -0.943 -0.322 0.084 vn -0.756 -0.651 0.069 vn -0.089 -0.996 0.024 vn 0.520 -0.852 0.051 vn 0.846 -0.530 -0.065 vn 0.735 -0.677 -0.013 vn 0.994 -0.085 -0.072 vn 0.833 0.445 -0.329 vn -0.370 0.633 -0.680 vn 0.492 -0.420 -0.762 vn 0.884 0.116 -0.452 vn 0.883 0.434 -0.178 vn 0.966 -0.241 -0.096 vn -0.732 -0.679 0.061 vn -0.121 -0.992 0.037 vn 0.899 -0.393 -0.193 vn -0.787 -0.558 0.263 vn 0.208 -0.962 0.177 vn -0.367 -0.312 0.876 vn 0.047 -0.811 0.583 vn 0.459 -0.888 -0.012 vn 0.758 -0.604 0.245 vn 0.550 -0.835 -0.017 vn 0.937 0.051 -0.345 vn 0.518 -0.182 -0.836 vn 0.689 0.645 -0.332 vn -0.514 -0.024 -0.857 vn -0.835 0.062 -0.546 vn -0.038 -0.139 -0.990 vn -0.077 -0.689 0.721 vn -0.897 -0.200 0.394 vn -0.991 0.118 0.062 vn -0.522 0.406 -0.750 vn -0.906 0.385 -0.173 vn 0.439 0.453 -0.776 vn -0.576 0.766 -0.285 vn -0.044 0.405 -0.913 vn 0.031 0.903 -0.428 vn 0.716 -0.013 0.698 vn 0.996 -0.061 -0.065 vn 0.896 -0.016 0.443 vn 0.980 -0.031 -0.199 vn 0.504 -0.347 -0.791 vn 0.556 -0.472 -0.684 vn 0.193 -0.411 -0.891 vn 0.397 -0.602 -0.693 vn 0.783 -0.440 -0.439 vn 0.936 -0.327 0.128 vn 0.753 0.055 0.655 vn 0.897 -0.093 0.432 vn 0.745 0.018 0.667 vn 0.852 -0.431 -0.298 vn 0.630 -0.425 -0.651 vn 0.611 -0.778 -0.143 vn 0.756 -0.431 0.493 vn 0.785 -0.384 -0.486 vn 0.763 -0.644 0.060 vn 0.860 -0.182 0.477 vn 0.945 0.022 -0.327 vn 0.449 -0.556 -0.699 vn 0.688 -0.538 -0.487 vn -0.366 -0.169 -0.915 vn -0.877 0.016 -0.480 vn -0.905 0.113 -0.410 vn -0.958 0.144 0.247 vn -0.943 0.275 0.185 vn -0.512 0.707 0.488 vn -0.606 0.130 0.785 vn -0.376 0.533 0.758 vn -0.936 0.352 -0.018 vn -0.334 0.028 -0.942 vn -0.421 -0.347 -0.838 vn 0.324 0.427 0.844 vn 0.640 0.169 0.750 vn 0.183 0.776 0.603 vn -0.497 0.815 0.298 vn 0.380 0.844 0.378 vn -0.504 0.861 -0.065 vn 0.504 0.844 0.185 vn -0.598 0.801 0.032 vn 0.561 0.758 0.334 vn -0.669 0.539 0.511 vn 0.498 0.419 0.759 vn -0.662 0.643 0.385 vn -0.891 0.399 0.214 vn 0.614 0.444 0.652 vn -0.890 -0.435 -0.134 vn 0.791 -0.441 0.423 vn 0.009 -0.994 -0.113 vn -0.217 0.780 0.587 vn 0.509 0.521 0.685 vn -0.324 0.399 0.858 vn -0.346 -0.233 0.909 vn 0.619 -0.066 0.783 vn 0.915 0.183 0.360 vn 0.460 0.516 0.723 vn 0.286 0.849 0.444 vn -0.939 0.172 0.298 vn -0.965 0.107 -0.241 vn 0.900 0.264 0.347 vn 0.935 -0.249 0.253 vn 0.605 -0.668 0.433 vn -0.889 -0.174 -0.424 vn 0.152 -0.899 -0.411 vn -0.058 -0.939 -0.340 vn -0.028 -0.995 -0.094 vn -0.298 -0.926 0.234 vn -0.991 -0.046 0.125 vn -0.832 -0.493 -0.254 vn 0.835 -0.269 0.480 vn 0.328 -0.722 -0.610 vn -0.893 -0.390 -0.226 vn 0.460 0.887 -0.039 vn 0.078 0.995 0.056 vn -0.651 0.755 -0.075 vn 0.764 0.642 0.067 vn 0.991 0.038 -0.130 vn -0.966 -0.017 -0.259 vn -0.572 0.759 -0.312 vn -0.572 0.609 0.550 vn 0.776 -0.536 0.332 vn -0.963 -0.241 0.117 vn -0.763 -0.553 -0.335 vn 0.147 -0.987 -0.065 vn 0.905 -0.313 0.290 vn 0.344 -0.760 0.551 vn -0.572 -0.715 0.403 vn 0.051 -0.946 0.320 vn -0.149 0.697 -0.701 vn 0.250 0.824 0.508 vn -0.252 0.683 -0.685 vn 0.191 0.900 0.391 vn -0.665 0.554 -0.501 vn -0.264 0.738 0.621 vn -0.669 0.495 -0.554 vn -0.350 0.701 0.621 vn -0.778 0.625 0.069 vn -0.238 0.563 0.791 vn -0.954 0.169 0.248 vn 0.126 -0.137 0.983 vn -0.815 0.214 -0.538 vn -0.298 -0.733 -0.611 vn -0.310 -0.870 0.383 vn -0.490 -0.312 -0.814 vn -0.192 -0.244 -0.951 vn -0.431 -0.335 -0.838 vn 0.316 -0.157 0.936 vn 0.275 0.315 0.908 vn 0.247 0.297 0.922 vn 0.433 -0.193 0.880 vn 0.467 -0.867 -0.174 vn 0.375 -0.864 -0.335 vn 0.395 -0.909 0.134 vn 0.109 -0.993 0.037 vn 0.247 -0.024 0.969 vn -0.249 -0.611 -0.752 vn 0.603 -0.779 0.172 vn -0.084 -0.987 0.138 vn 0.342 -0.262 0.902 vn -0.101 -0.283 0.954 vn -0.729 0.234 -0.644 vn -0.650 -0.419 -0.634 vn -0.590 -0.581 -0.561 vn 0.529 -0.373 -0.762 vn 0.366 -0.623 -0.691 vn 0.097 -0.989 -0.115 vn 0.601 -0.647 -0.469 vn 0.096 -0.766 -0.636 vn 0.094 -0.764 -0.638 vn -0.512 -0.618 -0.596 vn -0.241 -0.958 0.153 vn 0.634 -0.472 -0.613 vn 0.771 0.624 0.127 vn 0.964 0.097 -0.247 vn 0.877 0.335 -0.344 vn 0.928 0.183 -0.324 vn 0.347 0.926 -0.151 vn 0.530 -0.233 -0.816 vn -0.355 0.751 0.558 vn -0.319 0.921 0.225 vn 0.559 0.762 -0.329 vn 0.825 0.563 -0.042 vn -0.242 0.821 0.518 vn 0.882 0.441 0.163 vn -0.203 0.593 0.779 vn 0.596 0.400 0.696 vn -0.344 0.341 0.875 vn 0.495 -0.080 0.865 vn -0.734 -0.251 0.631 vn -0.072 -0.969 0.238 vn 0.999 -0.017 0.039 vn 0.583 -0.718 -0.381 vn 0.907 -0.117 -0.405 vn 0.720 -0.256 -0.645 vn -0.833 -0.373 0.409 vn -0.953 -0.155 0.258 vn -0.724 0.305 0.619 vn -0.828 -0.272 0.490 vn -0.393 -0.655 -0.645 vn 0.692 -0.566 -0.447 vn -0.372 -0.583 -0.722 vn -0.417 -0.893 -0.167 vn -0.177 -0.981 -0.080 vn -0.697 -0.162 0.699 vn 0.764 -0.636 -0.106 vn -0.728 -0.566 -0.386 vn -0.055 -0.990 -0.126 vn 0.259 -0.224 0.940 vn 0.889 -0.457 -0.016 vn 0.317 -0.925 0.211 vn 0.213 -0.782 0.586 vn -0.597 -0.363 0.715 vn -0.548 -0.587 0.596 vn 0.131 -0.281 0.951 vn 0.280 -0.763 0.582 vn -0.390 -0.091 0.916 vn -0.376 -0.088 0.922 vn 0.644 0.508 0.572 vn -0.161 -0.046 0.986 vn 0.088 0.021 0.996 vn 0.175 0.322 0.931 vn -0.345 0.638 0.689 vn -0.281 0.186 0.942 vn -0.470 0.090 0.878 vn -0.356 0.779 0.515 vn -0.926 0.227 -0.302 vn -0.486 -0.847 0.215 vn 0.252 -0.921 0.298 vn 0.191 -0.935 0.299 vn -0.584 -0.352 0.732 vn 0.352 -0.788 0.505 vn -0.468 -0.350 0.812 vn 0.374 -0.779 0.503 vn -0.268 -0.322 0.908 vn 0.592 -0.795 0.132 vn 0.177 -0.424 0.888 vn 0.487 -0.836 -0.253 vn 0.533 -0.606 0.591 vn 0.091 -0.779 -0.620 vn 0.755 -0.595 0.275 vn -0.395 -0.809 -0.435 vn 0.720 -0.637 0.276 vn -0.528 -0.849 0.025 vn -0.860 0.099 0.501 vn -0.663 0.370 0.651 vn -0.277 0.351 0.894 vn 0.298 0.229 0.927 vn 0.785 0.116 0.609 vn 0.258 0.429 0.866 vn -0.823 -0.146 0.549 vn -0.973 -0.163 0.163 vn -0.855 -0.225 0.467 vn -0.728 -0.586 -0.356 vn -0.732 0.455 -0.508 vn -0.791 -0.318 0.523 vn -0.901 -0.020 0.434 vn -0.927 0.369 -0.065 vn -0.773 0.127 0.622 vn -0.668 -0.301 0.680 vn -0.896 -0.042 0.443 vn -0.591 0.643 -0.487 vn -0.928 0.155 0.340 vn -0.938 0.179 0.297 vn -0.523 0.852 0.037 vn -0.632 -0.728 -0.267 vn -0.772 0.032 -0.634 vn -0.938 0.287 0.194 vn -0.932 0.181 -0.314 vn -0.575 -0.150 -0.804 vn -0.625 -0.005 -0.781 vn -0.360 0.754 -0.549 vn 0.041 0.839 -0.543 vn 0.009 0.137 -0.991 vn -0.970 0.242 0.009 vn -0.945 0.028 0.326 vn -0.679 0.521 -0.518 vn -0.898 0.423 0.117 vn -0.770 0.206 0.604 vn -0.823 -0.359 -0.441 vn -0.876 -0.468 0.115 vn -0.987 -0.040 -0.158 vn -0.830 0.491 0.265 vn -0.905 0.423 -0.033 vn -0.658 0.583 0.476 vn -0.476 0.831 -0.287 vn 0.061 0.536 -0.842 vn -0.164 -0.537 -0.828 vn -0.606 0.332 -0.722 vn -0.463 0.467 -0.753 vn -0.487 0.250 -0.837 vn -0.926 -0.366 0.093 vn -0.891 0.157 0.426 vn -0.978 -0.204 -0.049 vn -0.646 0.764 -0.003 vn -0.809 0.260 0.527 vn -0.110 0.709 -0.696 vn -0.362 0.687 -0.630 vn -0.465 0.466 -0.753 vn -0.667 0.669 -0.327 vn -0.624 0.763 0.169 vn -0.335 0.803 0.493 vn 0.158 0.771 0.617 vn -0.937 0.091 -0.339 vn -0.870 0.151 0.470 vn -0.752 0.322 -0.576 vn -0.398 0.785 -0.475 vn -0.862 0.422 0.280 vn -0.677 0.511 -0.529 vn -0.587 0.808 0.054 vn -0.714 0.182 -0.676 vn -0.279 -0.419 0.864 vn -0.535 0.193 -0.823 vn -0.124 0.702 -0.702 vn -0.898 -0.392 -0.200 vn -0.902 -0.422 -0.092 vn -0.783 0.125 0.609 vn -0.932 -0.332 -0.143 vn -0.157 0.491 -0.857 vn -0.862 -0.475 -0.175 vn -0.783 0.535 -0.318 vn -0.092 0.492 -0.866 vn -0.457 0.435 -0.776 vn -0.435 0.721 -0.539 vn -0.324 0.559 0.763 vn -0.084 0.215 0.973 vn 0.322 0.189 0.927 vn 0.207 0.288 0.935 vn -0.156 0.026 0.987 vn -0.386 0.535 0.751 vn -0.778 0.382 0.499 vn -0.577 0.233 0.783 vn -0.547 0.619 0.564 vn -0.804 0.576 0.147 vn -0.305 0.193 0.933 vn -0.278 -0.353 0.893 vn -0.440 -0.005 0.898 vn 0.529 -0.209 0.823 vn 0.470 0.195 0.861 vn -0.833 0.016 0.554 vn -0.333 0.767 0.549 vn -0.828 0.096 0.552 vn -0.740 0.646 -0.186 vn -0.388 0.558 0.734 vn -0.956 -0.071 0.283 vn -0.800 0.516 -0.307 vn -0.486 0.849 0.209 vn -0.966 -0.248 -0.066 vn -0.738 0.279 0.614 vn -0.912 -0.361 -0.194 vn -0.990 -0.124 -0.070 vn -0.914 -0.394 -0.096 vn -0.993 -0.044 0.111 vn -0.479 0.873 -0.090 vn -0.716 0.692 -0.088 vn -0.607 0.789 -0.090 vn 0.043 0.981 -0.190 vn -0.674 0.640 -0.369 vn -0.207 0.792 0.575 vn -0.556 0.688 -0.465 vn 0.315 0.928 -0.199 vn 0.250 0.916 0.314 vn 0.139 0.958 0.251 vn -0.208 0.919 0.336 vn -0.654 0.425 0.626 vn -0.613 -0.170 0.772 vn -0.527 0.307 0.792 vn -0.137 0.481 0.866 vn 0.409 0.165 0.897 vn -0.257 0.531 0.808 vn 0.160 0.262 0.952 vn 0.524 -0.219 0.823 vn -0.308 -0.357 0.881 vn -0.318 0.700 0.639 vn -0.085 0.547 0.833 vn -0.526 0.126 0.841 vn -0.676 0.248 0.694 vn 0.106 -0.341 0.934 vn 0.500 -0.047 0.865 vn -0.055 -0.486 0.872 vn -0.507 0.290 0.812 vn -0.418 -0.012 0.908 vn -0.364 -0.279 0.888 vn -0.737 0.671 0.083 vn -0.859 -0.033 0.511 vn -0.683 -0.477 0.553 vn -0.798 -0.478 -0.369 vn -0.914 -0.404 0.038 vn 0.076 -0.801 0.593 vn -0.801 -0.517 0.301 vn -0.603 -0.654 -0.456 vn -0.873 -0.475 -0.109 vn -0.646 0.577 -0.500 vn -0.612 -0.425 -0.667 vn -0.436 -0.705 -0.559 vn -0.950 -0.284 -0.128 vn -0.207 -0.385 -0.899 vn -0.868 -0.496 -0.014 vn -0.449 0.200 -0.871 vn -0.486 -0.172 -0.857 vn -0.027 0.994 0.102 vn -0.382 0.470 -0.796 vn 0.142 0.980 0.136 vn 0.166 0.919 -0.357 vn -0.382 0.790 -0.479 vn 0.168 -0.286 0.943 vn 0.195 -0.414 0.889 vn -0.199 -0.251 0.947 vn -0.225 -0.814 0.536 vn -0.046 -0.638 0.769 vn -0.408 -0.156 0.900 vn -0.374 -0.630 0.681 vn 0.225 -0.034 0.974 vn -0.476 0.250 0.843 vn -0.419 -0.308 0.854 vn -0.414 -0.753 -0.512 vn -0.506 -0.280 -0.816 vn -0.823 -0.488 -0.291 vn -0.919 -0.259 -0.296 vn -0.284 -0.218 -0.934 vn -0.118 -0.531 -0.839 vn -0.566 0.180 -0.805 vn -0.498 -0.314 -0.809 vn -0.505 -0.382 -0.774 vn -0.313 -0.522 -0.794 vn -0.430 -0.692 -0.579 vn -0.758 0.519 0.396 vn -0.480 -0.086 -0.873 vn -0.931 -0.259 -0.256 vn -0.315 -0.812 -0.491 vn -0.686 -0.683 0.253 vn -0.727 -0.169 0.666 vn -0.309 -0.926 -0.215 vn 0.194 -0.040 -0.980 vn -0.519 -0.222 0.825 vn -0.627 0.167 -0.761 vn 0.526 0.137 -0.839 vn -0.913 0.044 0.405 vn -0.300 -0.952 -0.063 vn 0.357 -0.040 -0.933 vn -0.609 -0.173 0.774 vn -0.235 -0.897 -0.375 vn -0.465 0.438 0.770 vn 0.227 0.864 -0.450 vn -0.152 0.816 0.557 vn -0.155 0.978 -0.137 vn 0.185 0.939 -0.292 vn -0.347 0.788 0.509 vn 0.320 0.845 -0.429 vn 0.281 -0.005 -0.960 vn -0.026 0.918 0.395 vn -0.861 -0.151 -0.486 vn -0.409 -0.471 -0.782 vn 0.009 0.269 -0.963 vn -0.526 0.135 -0.840 vn -0.712 -0.692 0.122 vn -0.370 -0.688 -0.625 vn -0.095 -0.158 -0.983 vn -0.853 -0.148 -0.501 vn -0.463 -0.051 0.885 vn -0.500 -0.756 -0.422 vn -0.083 -0.093 -0.992 vn -0.332 -0.158 0.930 vn 0.303 0.720 -0.624 vn -0.099 0.722 -0.684 vn 0.024 0.703 0.711 vn 0.415 0.907 0.075 vn -0.439 0.898 0.024 vn -0.497 0.486 -0.719 vn -0.576 0.788 -0.217 vn -0.001 0.829 -0.559 vn -0.315 0.885 -0.342 vn 0.105 0.507 -0.856 vn 0.150 0.989 0.004 vn -0.458 0.889 -0.004 vn -0.134 0.368 -0.920 vn -0.521 0.391 -0.759 vn 0.312 0.859 0.406 vn -0.518 0.750 -0.411 vn 0.096 0.854 0.511 vn -0.225 0.843 0.488 vn -0.851 0.522 0.064 vn -0.293 0.503 0.813 vn -0.449 0.878 -0.169 vn -0.261 0.866 -0.426 vn -0.767 0.641 0.036 vn -0.572 -0.652 0.497 vn 0.161 0.583 0.796 vn -0.600 -0.735 -0.314 vn -0.122 -0.149 -0.981 vn -0.462 -0.186 0.867 vn 0.381 0.659 -0.649 vn -0.665 -0.612 0.427 vn -0.039 0.457 0.889 vn -0.327 -0.517 -0.791 vn 0.146 0.988 -0.040 vn -0.522 -0.606 0.600 vn -0.221 0.474 0.853 vn 0.393 0.902 0.176 vn 0.189 0.527 -0.829 vn -0.448 -0.891 -0.080 vn -0.529 0.046 0.848 vn -0.296 0.921 -0.252 vn -0.151 0.008 -0.989 vn -0.967 0.003 -0.256 vn -0.714 0.242 -0.657 vn -0.826 -0.233 -0.514 vn -0.341 -0.771 -0.538 vn -0.876 -0.476 -0.081 vn -0.195 0.967 -0.166 vn -0.894 0.393 0.216 vn -0.502 0.426 -0.753 vn -0.415 -0.584 -0.698 vn -0.880 -0.367 -0.302 vn -0.182 0.969 -0.168 vn -0.906 0.417 0.080 vn 0.529 -0.135 0.838 vn 0.388 -0.162 0.907 vn 0.333 -0.409 0.850 vn 0.333 -0.215 0.918 vn 0.365 -0.255 0.896 vn 0.525 -0.231 0.819 vn -0.032 -0.064 0.997 vn -0.052 0.368 0.928 vn -0.177 -0.213 0.961 vn 0.128 0.981 -0.149 vn -0.365 0.847 0.386 vn -0.374 0.794 -0.478 vn -0.659 0.593 -0.463 vn -0.369 0.814 -0.449 vn -0.382 0.769 -0.512 vn -0.500 0.797 -0.339 vn -0.273 0.868 -0.414 vn -0.892 0.397 -0.215 vn -0.404 0.856 -0.324 vn -0.722 0.610 -0.325 vn -0.523 0.764 0.378 vn -0.747 0.652 -0.130 vn -0.530 0.848 0.002 vn -0.558 0.739 0.378 vn -0.464 0.840 0.281 vn -0.583 0.744 -0.325 vn -0.336 0.315 -0.888 vn -0.648 -0.101 -0.755 vn -0.876 0.135 0.462 vn -0.855 0.322 -0.406 vn -0.166 -0.540 -0.825 vn -0.244 -0.596 -0.765 vn -0.102 -0.059 -0.993 vn -0.633 0.771 0.067 vn -0.381 0.542 0.749 vn -0.842 0.445 0.305 vn -0.488 0.871 0.060 vn -0.341 0.788 -0.513 vn -0.186 0.396 0.899 vn -0.748 0.154 -0.646 vn -0.239 0.149 -0.959 vn -0.470 0.880 -0.066 vn -0.182 0.890 -0.417 vn -0.242 0.894 -0.378 vn -0.013 0.483 -0.876 vn -0.795 0.592 -0.133 vn -0.967 -0.099 -0.233 vn -0.545 0.819 0.178 vn -0.235 -0.111 0.966 vn -0.541 0.822 -0.180 vn -0.616 0.704 0.353 vn -0.803 0.227 0.551 vn -0.777 0.623 -0.093 vn -0.600 0.354 0.718 vn -0.703 0.355 0.616 vn -0.710 0.597 -0.375 vn -0.649 0.269 0.712 vn -0.105 0.350 0.931 vn 0.158 0.806 0.570 vn -0.578 0.471 0.666 vn -0.438 0.545 0.715 vn -0.667 0.534 0.520 vn -0.761 0.119 -0.637 vn -0.801 0.531 -0.275 vn 0.052 -0.869 -0.491 vn 0.023 0.716 0.698 vn -0.598 0.132 0.791 vn -0.574 0.153 0.804 vn -0.042 0.524 0.851 vn -0.597 0.098 0.796 vn -0.117 0.442 0.889 vn -0.013 0.584 0.812 vn 0.298 0.498 0.815 vn 0.265 0.334 0.904 vn 0.009 0.950 0.313 vn 0.175 0.757 0.630 vn -0.452 0.816 0.360 vn -0.413 0.084 0.907 vn 0.100 0.680 0.727 vn -0.305 0.267 0.914 vn -0.540 0.575 0.615 vn -0.436 0.765 0.474 vn -0.688 0.274 0.671 vn -0.405 0.913 0.045 vn -0.749 0.643 -0.162 vn -0.967 -0.096 -0.234 vn -0.820 0.572 0.016 vn -0.672 0.325 -0.666 vn -0.604 0.460 -0.650 vn -0.609 0.502 0.614 vn -0.649 0.358 0.672 vn -0.891 0.451 -0.057 vn -0.239 0.864 -0.443 vn -0.820 0.316 -0.477 vn -0.457 0.855 -0.247 vn -0.768 0.630 0.119 vn -0.786 0.460 -0.413 vn -0.605 0.791 -0.085 vn -0.870 0.490 0.059 vn -0.961 0.022 -0.276 vn -0.979 -0.013 -0.205 vn -0.932 0.354 0.080 vn -0.485 0.716 0.502 vn -0.753 0.576 0.318 vn -0.670 0.713 0.205 vn 0.079 0.489 0.869 vn 0.344 0.130 0.930 vn -0.783 0.620 0.047 vn -0.889 0.100 -0.446 vn -0.561 0.753 0.345 vn -0.838 0.506 -0.202 vn -0.464 0.857 0.224 vn -0.053 0.693 0.719 vn 0.760 -0.051 0.648 vn 0.620 0.033 0.784 vn -0.756 0.584 -0.296 vn 0.506 0.860 -0.069 vn -0.282 0.950 -0.133 vn -0.968 0.140 -0.206 vn -0.963 -0.112 -0.244 vn -0.871 -0.156 -0.467 vn -0.704 -0.499 -0.504 vn -0.279 0.642 0.715 vn -0.876 0.474 -0.089 vn -0.240 0.880 0.409 vn -0.293 0.897 0.331 vn 0.349 0.032 0.937 vn 0.416 0.656 0.629 vn -0.807 0.578 0.121 vn 0.669 0.635 0.386 vn 0.763 0.337 0.551 vn 0.370 0.022 0.929 vn 0.866 0.500 0.025 vn 0.342 0.846 0.409 vn -0.846 0.150 -0.511 vn -0.309 0.919 0.244 vn -0.992 -0.128 -0.022 vn -0.867 0.499 0.006 vn -0.980 -0.118 0.159 vn -0.878 0.450 0.161 vn -0.831 0.520 0.198 vn -0.975 -0.136 0.178 vn -0.992 0.073 0.100 vn -0.840 0.536 0.082 vn -0.223 0.973 0.066 vn -0.962 -0.249 0.109 vn -0.840 -0.244 -0.484 vn -0.929 -0.255 -0.267 vn -0.489 -0.722 -0.490 vn -0.635 -0.735 0.237 vn -0.562 -0.763 -0.320 vn -0.628 -0.775 -0.074 vn -0.912 -0.238 -0.335 vn -0.787 -0.615 0.050 vn -0.643 -0.695 0.323 vn -0.466 -0.743 -0.480 vn -0.761 -0.219 -0.611 vn -0.282 -0.956 -0.087 vn -0.954 -0.280 0.106 vn 0.768 -0.622 0.152 vn -0.996 -0.037 -0.081 vn 0.369 -0.873 -0.318 vn -0.635 -0.671 -0.382 vn -0.997 -0.017 0.078 vn -0.201 -0.493 -0.846 vn 0.028 -0.113 -0.993 vn 0.192 -0.222 -0.956 vn -0.539 -0.213 -0.815 vn -0.916 0.312 -0.251 vn -0.275 -0.079 -0.958 vn -0.359 0.854 -0.376 vn 0.222 0.460 -0.859 vn -0.995 -0.069 0.075 vn -0.694 -0.536 -0.481 vn 0.166 -0.786 0.595 vn -0.992 -0.046 0.121 vn 0.219 -0.922 -0.318 vn -0.711 -0.700 0.058 vn -0.636 -0.711 -0.300 vn -0.991 -0.047 -0.124 vn -0.495 -0.156 -0.855 vn -0.075 -0.446 -0.892 vn -0.077 0.401 -0.913 vn -0.348 -0.842 -0.413 vn -0.299 0.954 0.008 vn -0.086 0.405 -0.910 vn -0.766 -0.560 -0.315 vn -0.792 -0.486 -0.370 vn -0.180 -0.857 -0.482 vn 0.885 -0.350 0.308 vn 0.047 -0.871 0.489 vn 0.572 -0.143 0.808 vn 0.826 0.106 0.553 vn 0.830 -0.349 0.435 vn 0.789 -0.498 0.360 vn 0.820 -0.428 0.379 vn 0.193 -0.639 0.745 vn 0.707 -0.504 0.495 vn 0.226 -0.968 -0.113 vn -0.279 -0.862 -0.424 vn -0.013 -0.991 0.137 vn 0.036 -0.985 -0.167 vn -0.130 -0.932 0.338 vn -0.162 -0.935 0.314 vn 0.631 -0.713 0.306 vn 0.430 -0.839 0.333 vn -0.146 0.982 0.120 vn 0.947 0.268 0.179 vn 0.988 0.145 0.053 vn 0.558 0.807 0.194 vn 0.943 0.323 0.076 vn 0.913 -0.374 0.161 vn 0.860 -0.317 0.400 vn 0.764 -0.576 0.292 vn 0.499 -0.864 0.063 vn 0.565 -0.818 0.111 vn 0.970 -0.190 0.149 vn -0.188 0.884 0.428 vn 0.641 0.739 0.211 vn 0.968 0.095 -0.233 vn -0.716 0.639 0.280 vn -0.429 0.755 0.495 vn -0.134 0.856 0.498 vn 0.371 0.804 0.465 vn -0.925 0.283 -0.254 vn -0.342 0.820 0.459 vn 0.389 0.835 0.389 vn -0.577 0.817 -0.010 vn 0.207 0.953 0.222 vn -0.626 0.779 0.016 vn 0.302 0.927 0.224 vn -0.586 0.729 0.354 vn 0.269 0.804 0.530 vn -0.710 0.557 0.431 vn -0.838 0.361 0.410 vn 0.643 0.454 0.616 vn -0.140 0.654 0.743 vn 0.263 0.741 0.618 vn 0.731 0.035 0.681 vn 0.739 0.225 -0.635 vn 0.957 0.021 0.288 vn 0.926 0.264 0.270 vn 0.978 -0.115 0.176 vn 0.950 0.191 0.249 vn -0.961 -0.146 0.234 vn 0.826 0.142 0.545 vn -0.226 0.528 0.818 vn -0.168 0.044 0.985 vn 0.427 -0.230 -0.874 vn -0.005 -0.815 -0.579 vn -0.104 -0.928 -0.358 vn 0.028 -0.783 -0.621 vn 0.438 -0.758 -0.484 vn -0.942 0.064 0.329 vn -0.975 -0.181 0.127 vn -0.900 -0.342 -0.272 vn -0.765 -0.610 0.207 vn -0.290 0.917 -0.275 vn -0.611 0.783 0.111 vn -0.694 0.530 0.487 vn -0.581 0.813 -0.031 vn -0.502 0.852 0.150 vn -0.755 0.633 -0.170 vn -0.418 0.875 0.245 vn -0.222 0.905 -0.363 vn -0.323 0.642 0.696 vn -0.262 0.955 0.141 vn -0.075 0.930 0.359 vn -0.209 0.958 0.195 vn -0.654 0.751 -0.090 vn -0.672 0.701 -0.240 vn -0.354 0.929 0.110 vn -0.844 0.516 0.145 vn -0.279 0.942 0.187 vn -0.332 0.915 -0.228 vn -0.738 0.552 0.388 vn -0.678 0.423 0.601 vn -0.234 0.841 0.487 vn -0.755 0.605 0.250 vn -0.743 0.669 -0.016 vn -0.524 0.765 -0.374 vn -0.424 0.840 -0.339 vn -0.417 0.834 0.361 vn -0.575 0.809 0.123 vn -0.700 0.671 -0.245 vn -0.978 -0.153 -0.142 vn -0.979 -0.205 -0.017 vn -0.876 0.031 0.482 vn -0.982 0.170 -0.085 vn 0.575 -0.772 -0.271 vn 0.754 -0.582 -0.305 vn -0.368 -0.779 -0.508 vn -0.364 -0.856 -0.366 vn 0.735 -0.678 0.008 vn -0.495 -0.842 -0.214 vn 0.925 -0.375 0.059 vn -0.570 -0.759 -0.314 vn 0.784 -0.620 -0.018 vn 0.681 -0.723 0.113 vn -0.517 -0.842 -0.158 vn 0.123 -0.920 0.372 vn 0.887 0.255 -0.385 vn 0.829 0.419 0.370 vn 0.871 0.190 0.454 vn 0.960 0.118 -0.255 vn 0.702 0.411 0.582 vn 0.877 0.298 -0.377 vn 0.598 0.682 0.421 vn 0.757 0.516 -0.400 vn 0.590 0.781 -0.206 vn 0.429 0.773 0.467 vn 0.559 0.449 -0.697 vn 0.186 -0.322 -0.928 vn 0.045 -0.207 -0.977 vn 0.094 -0.516 -0.851 vn 0.724 0.690 0.017 vn 0.372 0.420 0.828 vn 0.618 0.186 -0.764 vn 0.939 0.293 0.181 vn -0.026 -0.547 0.837 vn 0.144 -0.743 -0.654 vn 0.116 0.013 0.993 vn -0.061 0.116 0.991 vn -0.485 -0.857 -0.175 vn -0.469 -0.604 0.645 vn 0.113 -0.993 -0.019 vn -0.023 -0.773 0.634 vn 0.209 -0.793 -0.572 vn -0.015 -0.442 0.897 vn -0.612 -0.551 0.567 vn -0.665 -0.589 -0.459 vn 0.059 -0.891 0.450 vn 0.654 -0.755 0.051 vn 0.893 0.120 0.435 vn 0.046 -0.922 -0.385 vn 0.645 -0.727 0.235 vn 0.144 -0.981 -0.127 vn -0.280 0.675 0.683 vn -0.612 0.565 0.554 vn -0.804 0.488 0.341 vn 0.091 0.685 0.723 vn -0.867 0.216 0.450 vn 0.044 0.425 0.904 vn -0.824 -0.108 0.557 vn 0.070 0.083 0.994 vn -0.843 -0.146 0.518 vn -0.061 0.020 0.998 vn -0.406 -0.266 0.875 vn -0.909 -0.384 0.164 vn 0.443 -0.096 0.891 vn 0.048 0.166 0.985 vn 0.788 0.200 0.583 vn 0.675 0.151 0.722 vn 0.937 0.058 0.344 vn -0.303 -0.630 0.715 vn -0.762 -0.553 -0.337 vn 0.766 -0.259 0.589 vn 0.100 -0.980 0.172 vn -0.122 -0.060 -0.991 vn 0.979 0.155 -0.132 vn -0.956 -0.145 -0.255 vn -0.889 -0.179 -0.421 vn -0.786 -0.317 -0.531 vn -0.899 -0.051 0.434 vn 0.859 -0.066 -0.508 vn 0.956 0.205 -0.211 vn 0.008 0.026 -1.000 vn 0.048 -0.202 -0.978 vn 0.952 -0.091 -0.291 vn -0.015 -0.196 -0.981 vn -0.253 -0.479 -0.841 vn 0.932 -0.288 -0.221 vn 0.458 -0.888 0.035 vn 0.592 -0.482 -0.647 vn -0.622 0.463 0.632 vn -0.822 0.392 0.414 vn -0.904 0.246 0.350 vn -0.054 0.455 0.889 vn -0.932 -0.041 0.360 vn -0.139 0.207 0.968 vn -0.717 -0.568 0.404 vn 0.015 -0.354 0.935 vn -0.575 -0.750 0.326 vn 0.247 -0.488 0.837 vn -0.070 -0.832 0.551 vn -0.609 -0.793 -0.006 vn 0.561 -0.321 0.763 vn -0.193 0.040 0.980 vn 0.677 0.078 0.732 vn 0.788 0.202 0.581 vn 0.863 0.257 0.434 vn 0.007 -0.915 0.403 vn -0.535 -0.731 -0.424 vn 0.795 -0.291 0.532 vn 0.585 -0.308 -0.750 vn -0.907 -0.295 -0.300 vn -0.798 -0.283 -0.532 vn -0.729 -0.360 -0.582 vn -0.964 -0.264 -0.027 vn 0.643 0.634 -0.430 vn 0.681 0.698 -0.224 vn -0.142 0.495 -0.857 vn -0.188 0.288 -0.939 vn 0.858 0.450 -0.247 vn -0.282 0.048 -0.958 vn -0.200 -0.266 -0.943 vn 0.992 0.005 -0.123 vn 0.339 -0.881 -0.329 vn 0.412 -0.886 -0.213 vn -0.504 -0.544 -0.670 vn -0.418 -0.546 -0.726 vn -0.359 -0.847 -0.393 vn -0.925 0.134 -0.356 vn -0.810 0.330 0.485 vn -0.932 0.351 0.094 vn -0.917 0.325 0.233 vn -0.286 0.268 0.920 vn -0.934 -0.169 0.315 vn -0.223 -0.093 0.970 vn -0.876 -0.482 -0.007 vn -0.302 -0.508 0.807 vn -0.634 -0.757 -0.157 vn -0.085 -0.770 0.633 vn -0.078 -0.996 0.048 vn -0.399 -0.617 -0.678 vn 0.402 -0.690 0.602 vn -0.091 -0.267 0.959 vn 0.420 -0.047 0.906 vn 0.494 -0.143 0.858 vn 0.611 -0.030 0.791 vn 0.231 -0.943 -0.239 vn -0.221 -0.377 -0.899 vn 0.665 -0.409 0.625 vn 0.840 0.271 -0.470 vn -0.791 -0.011 -0.612 vn -0.581 -0.062 -0.811 vn -0.372 0.073 -0.925 vn -0.819 -0.039 -0.573 vn 0.504 0.662 0.554 vn 0.767 0.543 0.343 vn 0.149 0.782 -0.605 vn 0.112 0.904 -0.413 vn 0.693 0.564 0.450 vn -0.068 0.424 -0.903 vn 0.224 -0.097 -0.970 vn 0.883 -0.317 0.345 vn -0.141 -0.617 -0.774 vn -0.415 -0.828 -0.377 vn -0.420 -0.354 0.835 vn -0.266 0.155 0.951 vn 0.210 0.575 0.790 vn 0.502 0.103 0.859 vn 0.362 0.532 0.765 vn -0.468 -0.654 -0.594 vn -0.438 -0.861 0.257 vn 0.317 0.301 0.899 vn -0.011 0.362 0.932 vn -0.734 -0.461 -0.500 vn -0.363 -0.866 -0.345 vn -0.950 -0.156 -0.272 vn 0.437 0.768 -0.468 vn -0.660 0.501 0.560 vn -0.992 -0.074 -0.103 vn -0.996 -0.083 0.024 vn -0.983 -0.010 -0.184 vn -0.956 0.119 -0.270 vn -0.762 0.404 0.506 vn -0.953 -0.185 -0.239 vn -0.794 0.524 0.307 vn -0.895 -0.233 -0.381 vn -0.348 -0.450 -0.823 vn -0.212 -0.264 -0.941 vn 0.018 -0.306 -0.952 vn 0.117 -0.065 -0.991 vn 0.924 -0.014 -0.383 vn 0.916 0.065 -0.397 vn 0.491 0.704 -0.513 vn 0.794 0.405 -0.453 vn -0.045 0.991 0.126 vn 0.493 0.828 0.268 vn 0.420 0.896 0.142 vn 0.893 0.414 0.179 vn 0.781 0.497 0.378 vn 0.587 -0.233 -0.775 vn -0.203 0.860 0.468 vn 0.190 0.722 0.665 vn -0.086 0.719 0.690 vn -0.390 0.532 -0.752 vn -0.519 -0.418 -0.745 vn -0.257 -0.964 -0.073 vn -0.689 -0.568 -0.451 vn -0.695 -0.688 -0.210 vn -0.497 -0.339 0.799 vn -0.696 -0.701 0.155 vn -0.676 -0.188 0.712 vn -0.439 -0.195 0.877 vn -0.581 -0.375 0.723 vn -0.760 -0.649 -0.025 vn -0.719 -0.544 -0.433 vn -0.729 0.042 0.684 vn -0.531 -0.641 0.554 vn -0.588 -0.069 0.806 vn -0.864 -0.067 0.499 vn -0.798 -0.460 0.389 vn -0.524 -0.290 0.801 vn -0.811 -0.535 0.236 vn -0.521 -0.606 0.601 vn -0.627 -0.631 0.458 vn -0.683 -0.703 0.200 vn -0.439 -0.787 0.433 vn -0.375 -0.817 0.438 vn -0.298 -0.397 0.868 vn -0.377 -0.065 0.924 vn -0.533 -0.169 0.829 vn -0.794 -0.381 0.473 vn -0.148 0.250 0.957 vn -0.138 0.216 0.967 vn -0.619 -0.288 0.730 vn -0.007 -0.217 0.976 vn -0.153 -0.371 0.916 vn -0.319 0.137 0.938 vn -0.173 -0.112 0.979 vn -0.051 -0.075 0.996 vn -0.300 -0.084 0.950 vn -0.447 -0.392 0.804 vn -0.048 -0.087 0.995 vn -0.338 -0.813 0.475 vn -0.023 -0.362 0.932 vn -0.610 -0.662 0.436 vn -0.014 0.346 0.938 vn -0.422 -0.114 0.899 vn -0.609 -0.439 0.660 vn -0.179 0.377 0.908 vn -0.554 -0.205 0.807 vn -0.054 0.377 0.925 vn -0.904 0.033 -0.426 vn -0.899 0.432 -0.071 vn -0.524 -0.007 0.852 vn -0.176 -0.181 0.968 vn -0.188 0.036 0.982 vn 0.075 -0.594 0.801 vn -0.218 -0.188 0.958 vn -0.068 -0.524 0.849 vn -0.331 -0.304 0.893 vn -0.073 -0.388 0.919 vn -0.131 -0.286 0.949 vn -0.468 -0.176 0.866 vn 0.102 -0.104 0.989 vn 0.449 -0.241 0.860 vn -0.092 0.074 0.993 vn 0.093 -0.660 0.745 vn -0.114 -0.011 0.993 vn -0.805 0.575 0.148 vn -0.842 0.455 0.289 vn -0.381 -0.103 -0.919 vn -0.934 0.167 0.317 vn -0.107 -0.902 -0.417 vn -0.778 -0.212 0.592 vn 0.063 -0.994 0.088 vn -0.590 -0.212 0.779 vn 0.025 -0.104 0.994 vn -0.114 -0.969 0.217 vn -0.407 -0.064 0.911 vn -0.272 -0.114 0.955 vn -0.540 -0.178 0.823 vn 0.012 0.452 0.892 vn -0.746 0.276 0.606 vn 0.654 0.683 0.324 vn 0.212 0.928 0.305 vn 0.165 -0.687 -0.707 vn -0.767 -0.463 0.444 vn -0.823 -0.291 0.488 vn 0.486 -0.781 -0.392 vn -0.734 -0.389 0.557 vn -0.482 -0.809 -0.337 vn -0.199 0.798 0.569 vn -0.419 0.850 0.319 vn -0.631 0.773 -0.067 vn -0.453 0.379 -0.807 vn 0.278 0.862 -0.423 vn 0.055 0.995 -0.078 vn 0.457 0.238 -0.857 vn 0.206 0.606 -0.768 vn 0.602 -0.712 -0.363 vn -0.811 -0.274 0.517 vn -0.692 0.203 0.692 vn 0.486 0.844 -0.226 vn 0.191 0.904 0.383 vn 0.007 0.698 0.716 vn -0.374 0.316 0.872 vn -0.996 0.091 0.019 vn -0.292 0.956 -0.021 vn -0.313 0.883 0.351 vn 0.003 0.659 0.752 vn -0.279 0.382 0.881 vn -0.398 0.325 0.858 vn 0.214 0.751 0.625 vn -0.564 0.750 0.344 vn -0.660 0.456 0.596 vn -0.843 -0.281 -0.459 vn -0.909 -0.092 -0.407 vn -0.789 -0.068 0.611 vn -0.852 0.114 0.512 vn -0.518 -0.545 0.660 vn -0.369 -0.335 0.867 vn 0.462 -0.585 -0.667 vn 0.734 -0.677 0.056 vn -0.049 -0.573 -0.818 vn 0.816 -0.403 -0.414 vn 0.390 -0.494 -0.777 vn 0.777 -0.413 -0.476 vn 0.725 -0.245 -0.643 vn 0.208 -0.969 0.130 vn 0.672 -0.229 -0.704 vn 0.058 0.853 0.519 vn 0.916 -0.274 0.293 vn 0.445 -0.063 0.893 vn 0.223 -0.971 0.082 vn -0.263 -0.619 -0.740 vn -0.693 -0.714 -0.104 vn -0.847 -0.529 0.039 vn -0.100 -0.897 -0.431 vn -0.829 -0.550 0.104 vn -0.805 -0.549 0.226 vn -0.271 -0.851 0.449 vn -0.114 -0.814 0.569 vn -0.604 -0.735 0.308 vn -0.111 -0.989 -0.101 vn -0.639 -0.293 -0.711 vn -0.215 -0.838 -0.502 vn -0.498 -0.864 0.072 vn -0.783 -0.405 -0.471 vn -0.231 -0.861 0.453 vn -0.472 -0.871 0.134 vn -0.221 -0.961 -0.166 vn -0.655 -0.288 -0.698 vn -0.047 -0.428 -0.902 vn -0.541 -0.441 -0.716 vn -0.621 -0.609 -0.494 vn 0.577 0.806 0.132 vn 0.588 0.804 0.092 vn 0.588 -0.246 0.771 vn 0.743 -0.174 0.646 vn 0.903 -0.254 0.347 vn 0.256 -0.796 0.549 vn 0.346 0.168 0.923 vn 0.468 -0.041 0.883 vn 0.570 0.233 0.788 vn 0.431 0.129 0.893 vn 0.121 -0.979 0.164 vn 0.699 -0.710 0.092 vn 0.085 -0.982 0.169 vn 0.083 -0.987 0.138 vn 0.055 -0.984 -0.169 vn 0.438 0.296 0.849 vn 0.779 0.186 0.599 vn 0.912 0.409 0.023 vn 0.329 0.590 0.738 vn 0.433 0.340 0.835 vn 0.914 0.405 0.031 vn 0.977 0.213 0.009 vn 0.870 -0.105 -0.482 vn 0.965 -0.031 0.260 vn 0.915 0.343 0.212 vn 0.978 -0.142 -0.154 vn 0.840 0.488 0.236 vn 0.593 0.442 0.673 vn 0.795 -0.235 0.559 vn 0.602 0.525 0.601 vn 0.676 0.328 0.659 vn 0.779 -0.407 0.478 vn 0.653 -0.265 0.709 vn 0.707 -0.205 0.677 vn 0.870 -0.491 0.050 vn 0.690 0.722 -0.052 vn 0.770 -0.098 0.630 vn 0.866 0.469 0.171 vn 0.994 -0.098 0.043 vn 0.876 -0.451 0.168 vn 0.919 -0.380 -0.110 vn 0.944 0.310 -0.112 vn 0.827 -0.092 0.554 vn 0.872 -0.489 -0.013 vn 0.973 0.201 0.111 vn 0.934 0.103 0.342 vn 0.962 0.269 0.049 vn 0.960 -0.212 -0.185 vn 0.996 0.089 -0.019 vn 0.970 -0.212 0.117 vn 0.917 -0.333 0.219 vn 0.789 -0.347 0.507 vn 0.968 0.147 0.202 vn 0.987 0.035 0.154 vn 0.949 0.179 0.260 vn -0.466 0.559 0.685 vn -0.708 0.420 0.569 vn -0.876 0.301 -0.377 vn -0.864 -0.276 -0.421 vn -0.669 -0.732 0.126 vn 0.416 -0.566 0.712 vn 0.969 0.124 0.212 vn 0.775 0.607 -0.177 vn 0.705 -0.345 0.619 vn 0.916 -0.400 0.036 vn 0.856 -0.107 -0.506 vn 0.993 0.066 -0.102 vn 0.479 0.656 -0.583 vn 0.413 -0.041 0.910 vn 0.048 -0.245 0.968 vn 0.405 0.076 0.911 vn 0.148 -0.245 0.958 vn 0.292 0.082 0.953 vn 0.736 0.218 0.641 vn 0.697 0.428 0.575 vn 0.888 0.333 0.317 vn 0.582 0.159 0.798 vn 0.593 0.315 0.741 vn 0.689 0.375 0.620 vn 0.305 -0.046 0.951 vn -0.172 0.914 0.367 vn 0.026 -0.071 0.997 vn 0.122 -0.325 0.938 vn 0.051 -0.132 0.990 vn -0.393 -0.478 0.785 vn -0.386 -0.514 0.766 vn -0.234 0.062 0.970 vn -0.274 -0.489 0.828 vn 0.342 0.588 0.733 vn 0.298 0.049 0.953 vn -0.010 -0.292 0.956 vn 0.948 -0.137 0.287 vn -0.044 -0.666 0.744 vn 0.459 0.498 0.736 vn 0.833 0.478 0.277 vn 0.858 -0.467 0.215 vn 0.831 -0.492 0.260 vn 0.504 0.726 0.468 vn 0.528 0.180 0.830 vn 0.944 0.327 0.050 vn 0.827 0.340 0.447 vn 0.981 0.179 0.071 vn 0.855 0.508 0.101 vn 0.844 0.247 0.476 vn 0.538 0.571 -0.619 vn -0.609 -0.338 0.718 vn 0.125 0.473 0.872 vn 0.892 0.182 0.414 vn -0.232 -0.900 0.369 vn 0.700 -0.698 0.152 vn 0.445 -0.079 0.892 vn 0.061 -0.984 0.168 vn -0.233 -0.726 0.647 vn 0.533 -0.626 0.569 vn 0.546 -0.221 0.808 vn 0.162 -0.960 0.228 vn 0.477 -0.878 0.045 vn 0.111 -0.974 0.197 vn 0.987 0.127 -0.098 vn 0.706 0.411 0.576 vn 0.903 -0.377 0.204 vn -0.488 -0.488 0.724 vn 0.101 -0.247 0.964 vn -0.125 -0.953 0.275 vn -0.255 -0.912 0.321 vn -0.698 -0.105 0.708 vn -0.626 -0.702 0.339 vn 0.700 -0.662 -0.269 vn 0.182 0.169 -0.969 vn 0.696 -0.284 -0.660 vn 0.796 0.605 -0.005 vn 0.966 -0.233 -0.114 vn 0.955 -0.278 -0.100 vn 0.747 -0.664 -0.030 vn 0.904 0.215 0.370 vn -0.211 -0.271 0.939 vn -0.445 0.386 0.808 vn -0.351 -0.500 0.792 vn -0.633 -0.011 0.774 vn -0.949 0.132 0.285 vn -0.474 -0.177 0.862 vn -0.537 -0.128 0.834 vn -0.443 -0.053 -0.895 vn 0.137 0.388 -0.911 vn 0.899 0.438 0.017 vn 0.826 0.267 -0.497 vn 0.189 -0.679 -0.709 vn 0.729 -0.212 -0.651 vn -0.337 0.429 0.838 vn -0.564 -0.582 0.587 vn 0.107 -0.317 0.942 vn -0.180 -0.649 0.739 vn -0.079 -0.358 0.930 vn -0.317 -0.550 0.773 vn 0.800 0.460 -0.385 vn 0.971 0.211 0.114 vn 0.963 0.192 -0.189 vn -0.369 -0.086 -0.925 vn -0.687 0.327 -0.650 vn -0.842 -0.453 -0.292 vn -0.818 -0.538 -0.203 vn -0.817 -0.551 0.169 vn -0.777 -0.567 0.273 vn -0.623 -0.600 0.501 vn -0.760 -0.590 0.273 vn -0.907 -0.422 0.006 vn 0.287 0.840 -0.460 vn -0.722 0.671 -0.167 vn -0.930 0.360 0.077 vn 0.198 0.786 -0.585 vn -0.612 0.743 -0.271 vn 0.050 0.963 -0.266 vn -0.630 0.777 0.014 vn -0.403 0.869 -0.287 vn 0.486 0.560 -0.671 vn 0.808 0.308 -0.503 vn 0.840 0.398 -0.368 vn 0.806 0.537 -0.250 vn 0.931 -0.070 -0.359 vn 0.785 0.305 -0.539 vn 0.983 -0.064 -0.174 vn 0.920 -0.379 -0.098 vn 0.421 -0.901 0.106 vn -0.194 -0.929 0.315 vn -0.633 -0.727 0.267 vn -0.486 -0.828 0.279 vn -0.906 -0.342 0.248 vn -0.981 0.184 -0.063 vn -0.084 0.671 -0.737 vn -0.726 -0.375 -0.577 vn -0.984 -0.082 -0.158 vn -0.979 0.178 0.098 vn -0.850 -0.476 0.226 vn 0.884 -0.431 -0.182 vn 0.400 -0.916 -0.009 vn -0.768 -0.630 0.119 vn 0.931 -0.361 -0.061 vn -0.174 -0.960 0.218 vn -0.491 -0.715 0.498 vn -0.269 -0.945 0.186 vn -0.966 -0.257 -0.034 vn -0.646 -0.453 -0.614 vn -0.910 0.386 -0.148 vn 0.273 -0.085 -0.958 vn 0.615 0.150 -0.774 vn -0.169 -0.327 -0.930 vn 0.454 -0.524 0.721 vn 0.988 0.132 0.081 vn 0.895 0.354 -0.270 vn 0.167 0.390 -0.906 vn 0.680 0.559 -0.474 vn -0.738 0.184 -0.649 vn 0.244 0.826 -0.509 vn -0.310 0.242 -0.919 vn -0.390 0.788 -0.477 vn -0.408 0.037 0.912 vn -0.923 -0.304 0.236 vn -0.694 -0.047 0.718 vn -0.939 -0.335 0.074 vn -0.508 -0.692 -0.513 vn -0.617 -0.709 -0.340 vn -0.287 -0.659 -0.696 vn -0.487 -0.761 -0.428 vn -0.733 -0.679 -0.034 vn -0.699 -0.454 0.552 vn -0.400 0.038 0.916 vn -0.630 -0.156 0.761 vn -0.381 0.058 0.923 vn -0.794 -0.595 0.126 vn -0.757 -0.587 -0.288 vn -0.459 -0.877 0.144 vn -0.346 -0.499 0.795 vn -0.854 -0.516 -0.063 vn -0.537 -0.739 0.406 vn -0.513 -0.287 0.809 vn -0.980 -0.136 0.147 vn -0.565 -0.728 -0.388 vn -0.608 -0.787 -0.107 vn 0.148 -0.309 -0.939 vn 0.682 0.098 -0.724 vn 0.638 0.177 -0.749 vn 0.908 0.411 -0.080 vn 0.853 0.477 -0.214 vn 0.591 0.779 0.209 vn 0.715 0.442 0.541 vn 0.543 0.647 0.535 vn 0.652 0.553 -0.519 vn -0.038 -0.069 -0.997 vn -0.001 -0.321 -0.947 vn -0.013 0.428 0.904 vn -0.272 0.154 0.950 vn 0.064 0.745 0.665 vn 0.521 0.853 0.028 vn -0.299 0.859 0.415 vn 0.380 0.889 -0.257 vn -0.502 0.842 0.197 vn 0.564 0.817 -0.119 vn -0.478 0.762 0.436 vn 0.792 0.494 0.359 vn -0.271 0.412 0.870 vn 0.756 0.580 0.302 vn 0.946 0.324 0.005 vn -0.399 0.421 0.815 vn 0.787 -0.467 -0.402 vn -0.681 -0.437 0.588 vn -0.112 -0.977 -0.179 vn 0.416 0.712 0.565 vn -0.385 0.428 0.818 vn 0.568 0.303 0.765 vn 0.556 -0.332 0.762 vn -0.456 -0.095 0.885 vn -0.870 -0.010 0.494 vn -0.095 0.609 0.788 vn -0.117 0.770 0.627 vn 0.951 0.285 -0.119 vn 0.873 0.269 -0.407 vn -0.848 0.073 0.525 vn -0.912 -0.301 0.280 vn -0.624 -0.610 0.488 vn 0.896 -0.054 -0.440 vn -0.002 -0.866 -0.500 vn -0.092 -0.940 -0.330 vn -0.072 -0.983 -0.169 vn 0.268 -0.957 0.108 vn 0.989 -0.123 -0.086 vn 0.765 -0.536 -0.358 vn -0.696 -0.268 0.666 vn -0.530 -0.646 -0.550 vn 0.770 -0.413 -0.486 vn -0.726 0.687 -0.030 vn -0.323 0.940 -0.109 vn 0.412 0.830 -0.377 vn -0.891 0.391 0.232 vn -0.959 -0.215 0.183 vn 0.684 0.139 -0.716 vn 0.317 0.788 -0.527 vn 0.685 0.676 0.273 vn -0.698 -0.522 0.491 vn 0.940 -0.300 -0.162 vn 0.829 -0.265 -0.492 vn 0.140 -0.983 -0.117 vn -0.715 -0.558 0.420 vn 0.109 -0.795 0.596 vn 0.817 -0.577 0.015 vn 0.262 -0.937 0.231 vn 0.106 0.711 -0.695 vn -0.052 0.858 0.510 vn 0.239 0.689 -0.684 vn -0.046 0.905 0.422 vn 0.611 0.538 -0.581 vn 0.367 0.735 0.570 vn 0.586 0.503 -0.635 vn 0.412 0.725 0.552 vn 0.750 0.657 -0.070 vn 0.319 0.607 0.728 vn 0.972 0.219 0.087 vn 0.037 -0.106 0.994 vn 0.714 0.224 -0.663 vn 0.233 -0.743 -0.628 vn 0.409 -0.841 0.355 vn 0.321 -0.303 -0.897 vn 0.109 -0.270 -0.957 vn 0.321 -0.356 -0.878 vn -0.207 -0.114 0.972 vn -0.169 0.266 0.949 vn -0.026 0.243 0.970 vn -0.397 -0.183 0.899 vn -0.471 -0.880 -0.055 vn -0.463 -0.858 -0.222 vn -0.325 -0.919 0.223 vn -0.058 -0.994 0.088 vn -0.092 0.002 0.996 vn 0.157 -0.627 -0.763 vn -0.529 -0.797 0.290 vn 0.140 -0.988 -0.070 vn -0.192 -0.377 0.906 vn 0.518 -0.277 0.809 vn 0.346 0.214 -0.913 vn 0.231 -0.299 -0.926 vn 0.310 -0.509 -0.803 vn -0.766 -0.495 -0.411 vn -0.585 -0.689 -0.428 vn -0.005 -0.993 -0.114 vn -0.670 -0.731 -0.133 vn -0.328 -0.769 -0.548 vn -0.319 -0.771 -0.551 vn 0.180 -0.571 -0.801 vn 0.378 -0.923 -0.065 vn -0.796 -0.558 -0.236 vn -0.636 0.485 0.600 vn -0.956 -0.051 0.288 vn -0.925 0.273 0.264 vn -0.972 0.039 0.230 vn -0.413 0.876 0.250 vn -0.754 -0.442 -0.487 vn 0.563 0.751 0.345 vn 0.458 0.870 0.183 vn -0.648 0.750 0.133 vn -0.705 0.589 0.396 vn 0.533 0.774 0.341 vn -0.662 0.547 0.513 vn 0.617 0.605 0.503 vn -0.142 0.575 0.805 vn 0.757 0.384 0.529 vn -0.011 0.114 0.993 vn 0.925 -0.288 0.248 vn 0.099 -0.929 0.357 vn -0.852 0.152 0.502 vn -0.753 -0.653 0.083 vn -0.982 -0.118 0.148 vn -0.944 -0.255 -0.211 vn 0.895 -0.444 0.048 vn 0.938 -0.241 -0.250 vn 0.959 0.257 0.118 vn 0.941 -0.330 -0.080 vn 0.006 -0.787 -0.617 vn -0.862 -0.505 0.044 vn -0.059 -0.697 -0.715 vn 0.205 -0.964 -0.168 vn 0.029 -0.999 0.046 vn 0.933 -0.187 0.307 vn -0.771 -0.510 0.381 vn 0.395 -0.725 -0.565 vn -0.070 -0.986 -0.150 vn 0.393 -0.253 0.884 vn -0.721 -0.559 0.410 vn -0.026 -0.960 0.280 vn 0.257 -0.844 0.470 vn -0.742 0.471 0.477 vn 0.402 0.685 0.608 vn 0.407 0.415 0.814 vn 0.736 0.551 0.393 vn 0.620 0.767 0.164 vn 0.467 -0.213 -0.858 vn 0.860 -0.422 -0.286 vn 0.807 -0.531 -0.259 vn 0.552 -0.343 -0.760 vn 0.087 -0.188 -0.978 vn -0.504 0.019 -0.864 vn -0.899 0.184 -0.398 vn -0.902 0.335 0.274 vn 0.677 -0.120 -0.726 vn -0.042 0.264 -0.964 vn -0.458 0.526 -0.717 vn -0.653 0.682 -0.330 vn -0.561 0.813 0.157 vn 0.750 -0.276 -0.601 vn 0.439 -0.264 -0.859 vn 0.717 -0.321 -0.619 vn -0.157 -0.570 -0.806 vn -0.102 0.462 -0.881 vn 0.786 -0.358 -0.504 vn 0.751 -0.081 -0.655 vn 0.383 0.336 -0.861 vn 0.890 0.065 -0.451 vn 0.890 -0.353 -0.290 vn 0.807 -0.022 -0.590 vn -0.116 0.674 -0.729 vn 0.721 0.127 -0.681 vn 0.541 -0.092 -0.836 vn 0.319 0.748 -0.582 vn -0.324 -0.780 -0.536 vn -0.286 0.012 -0.958 vn 0.374 -0.068 -0.925 vn -0.200 0.006 -0.980 vn -0.339 0.919 -0.201 vn -0.891 0.321 -0.320 vn 0.314 0.090 -0.945 vn 0.630 -0.161 -0.760 vn -0.079 0.497 -0.864 vn 0.536 0.300 -0.789 vn 0.905 0.134 -0.405 vn -0.101 -0.380 -0.920 vn 0.461 -0.518 -0.720 vn 0.191 -0.114 -0.975 vn 0.651 0.412 -0.638 vn 0.415 0.422 -0.806 vn 0.746 0.547 -0.380 vn -0.077 0.837 -0.541 vn -0.732 0.580 -0.359 vn -0.696 -0.462 -0.549 vn -0.333 0.327 -0.884 vn -0.535 0.309 -0.787 vn 0.573 -0.178 -0.800 vn 0.608 0.411 -0.679 vn 0.590 0.030 -0.807 vn -0.176 0.887 -0.427 vn 0.825 0.255 -0.505 vn -0.533 0.689 -0.492 vn -0.561 0.084 -0.823 vn 0.292 0.016 -0.956 vn -0.605 0.346 -0.717 vn 0.367 0.130 -0.921 vn 0.094 0.467 -0.879 vn -0.531 0.731 -0.429 vn 0.642 0.040 -0.765 vn 0.442 0.194 -0.875 vn 0.602 0.536 -0.593 vn 0.474 0.218 -0.853 vn -0.633 0.479 -0.608 vn 0.241 0.126 -0.962 vn -0.486 0.596 -0.639 vn -0.950 0.195 -0.245 vn 0.992 -0.072 -0.104 vn 0.677 0.736 -0.020 vn 0.961 0.143 -0.237 vn 0.119 0.376 -0.919 vn 0.829 0.548 -0.110 vn 0.816 0.064 -0.575 vn 0.246 0.228 -0.942 vn 0.462 0.846 -0.268 vn 0.887 0.019 -0.462 vn 0.866 0.383 -0.322 vn 0.458 -0.515 -0.725 vn 0.684 0.213 -0.698 vn 0.484 0.021 -0.875 vn 0.556 0.369 -0.745 vn -0.236 0.834 -0.499 vn 0.450 0.753 -0.479 vn -0.349 0.819 -0.455 vn -0.293 0.956 -0.014 vn 0.241 0.647 -0.723 vn 0.447 0.893 -0.051 vn -0.345 0.442 -0.828 vn -0.447 0.894 0.020 vn 0.044 0.980 0.196 vn 0.043 0.987 0.154 vn 0.400 0.915 0.056 vn 0.794 0.531 0.296 vn 0.856 0.238 0.458 vn 0.835 0.451 0.317 vn 0.467 0.705 0.534 vn 0.958 0.271 0.088 vn 0.995 -0.004 0.099 vn 0.905 -0.401 -0.140 vn 0.635 0.641 -0.431 vn 0.887 -0.074 -0.457 vn 0.800 -0.469 -0.374 vn 0.166 -0.549 -0.819 vn 0.483 -0.407 -0.775 vn 0.878 -0.219 -0.426 vn 0.706 -0.453 -0.544 vn -0.067 -0.633 -0.772 vn 0.305 -0.406 -0.862 vn -0.309 0.541 -0.782 vn -0.151 -0.420 -0.895 vn -0.298 -0.737 -0.607 vn 0.297 -0.259 -0.919 vn -0.699 -0.466 -0.543 vn 0.431 -0.420 -0.799 vn -0.614 0.162 -0.772 vn 0.113 0.993 -0.025 vn -0.090 0.966 0.241 vn -0.412 0.906 0.096 vn -0.091 0.802 -0.590 vn -0.259 -0.776 -0.576 vn -0.438 -0.339 -0.833 vn 0.096 -0.522 -0.847 vn 0.217 -0.274 -0.937 vn -0.712 -0.242 -0.659 vn -0.726 -0.485 -0.487 vn -0.497 0.132 -0.857 vn -0.543 -0.538 -0.645 vn 0.601 0.583 -0.546 vn -0.558 -0.059 -0.828 vn 0.215 -0.267 -0.939 vn -0.283 -0.716 -0.638 vn 0.543 -0.603 -0.585 vn 0.914 -0.143 -0.379 vn 0.091 -0.820 -0.565 vn -0.940 -0.142 -0.311 vn 0.992 -0.075 -0.097 vn -0.422 0.195 -0.885 vn -0.994 -0.065 0.083 vn 0.749 0.271 -0.604 vn 0.258 -0.852 -0.456 vn -0.973 -0.185 -0.137 vn 0.980 0.047 -0.192 vn -0.054 -0.867 -0.496 vn 0.902 0.430 -0.026 vn -0.634 0.761 0.139 vn 0.457 0.840 0.294 vn -0.241 0.967 -0.081 vn -0.511 0.845 0.161 vn 0.460 0.886 0.059 vn -0.614 0.759 0.217 vn -0.977 0.002 -0.214 vn 0.311 0.900 0.307 vn -0.026 -0.067 -0.997 vn -0.572 -0.451 -0.685 vn -0.876 0.262 -0.404 vn -0.548 0.212 -0.809 vn 0.550 -0.536 -0.640 vn -0.244 -0.674 -0.697 vn -0.788 -0.252 -0.562 vn 0.246 0.298 -0.922 vn 0.991 0.134 0.028 vn -0.000 -0.690 -0.724 vn -0.815 -0.192 -0.547 vn 0.993 0.026 0.117 vn -0.821 0.568 0.059 vn -0.697 0.641 -0.321 vn 0.463 0.762 0.452 vn -0.293 0.810 0.509 vn 0.040 0.963 -0.267 vn -0.060 0.861 -0.504 vn -0.627 0.764 -0.152 vn -0.895 0.375 -0.242 vn -0.259 0.926 0.274 vn 0.025 0.955 -0.297 vn -0.819 0.276 -0.503 vn 0.050 0.823 0.565 vn -0.282 0.783 -0.554 vn 0.256 0.866 0.431 vn 0.384 0.913 0.137 vn -0.077 0.865 -0.496 vn 0.810 0.556 0.184 vn -0.105 0.921 -0.376 vn -0.404 0.849 -0.341 vn 0.241 0.782 -0.574 vn 0.815 -0.465 -0.346 vn 0.511 0.630 0.585 vn 0.134 -0.636 -0.760 vn -0.776 -0.238 -0.583 vn 1.000 0.012 -0.021 vn -0.865 0.490 0.109 vn 0.787 -0.416 -0.456 vn 0.707 0.558 0.435 vn -0.448 -0.533 -0.718 vn -0.292 0.929 0.227 vn 0.874 -0.417 -0.248 vn 0.752 0.605 0.261 vn -0.195 0.823 0.534 vn -0.912 0.377 -0.160 vn 0.300 -0.789 -0.535 vn 0.967 0.248 -0.061 vn -0.270 0.925 -0.268 vn -0.801 -0.080 -0.593 vn 0.202 0.161 -0.966 vn -0.307 0.273 -0.912 vn -0.114 -0.164 -0.980 vn 0.313 -0.473 -0.824 vn 0.546 0.482 -0.686 vn 0.143 -0.305 -0.942 vn 0.421 0.511 -0.750 vn 0.590 0.776 0.224 vn -0.333 0.926 0.176 vn 0.352 0.935 -0.048 vn -0.211 0.654 -0.727 vn -0.354 0.822 -0.445 vn -0.213 0.835 -0.508 vn 0.132 0.546 -0.827 vn -0.259 0.880 -0.399 vn -0.074 0.707 -0.703 vn 0.417 0.892 -0.176 vn 0.087 0.772 -0.629 vn 0.027 0.933 -0.359 vn 0.495 0.839 -0.228 vn 0.430 0.770 -0.472 vn -0.205 0.802 -0.561 vn -0.704 0.262 -0.660 vn -0.260 -0.116 -0.959 vn 0.785 0.297 -0.544 vn -0.026 0.384 -0.923 vn -0.624 -0.481 -0.616 vn -0.451 -0.607 -0.654 vn -0.817 -0.160 -0.555 vn 0.208 0.878 -0.431 vn 0.584 0.810 0.048 vn 0.559 0.622 -0.548 vn -0.086 0.886 -0.456 vn 0.818 0.449 -0.359 vn 0.329 0.471 -0.818 vn -0.217 0.651 -0.727 vn 0.164 0.975 -0.152 vn -0.370 0.879 -0.302 vn -0.158 0.480 -0.863 vn 0.939 0.206 -0.275 vn 0.821 0.475 -0.317 vn 0.064 0.560 -0.826 vn 0.644 0.675 -0.358 vn -0.071 0.884 -0.461 vn 0.407 0.872 -0.271 vn 0.761 0.607 -0.229 vn 0.088 0.789 -0.608 vn 0.784 0.614 0.096 vn 0.694 0.691 -0.202 vn -0.151 0.685 -0.713 vn 0.837 0.508 -0.204 vn 0.785 0.491 0.378 vn 0.232 0.893 0.385 vn 0.758 0.651 0.038 vn 0.586 0.794 0.163 vn 0.478 0.862 -0.169 vn 0.575 0.406 -0.710 vn 0.502 0.858 -0.107 vn 0.347 -0.372 -0.861 vn 0.846 0.333 -0.417 vn 0.897 0.192 -0.397 vn 0.976 0.213 -0.044 vn 0.557 0.657 0.509 vn 0.936 0.254 -0.244 vn 0.839 0.542 0.038 vn 0.741 0.562 0.368 vn 0.066 0.864 0.499 vn 0.236 0.860 0.453 vn 0.477 0.879 -0.018 vn 0.906 0.298 0.300 vn 0.933 0.205 0.295 vn 0.767 0.559 0.313 vn 0.507 0.798 0.326 vn 0.432 0.900 -0.054 vn 0.614 0.785 -0.084 vn -0.355 0.926 -0.127 vn 0.380 0.840 -0.387 vn 0.352 0.333 -0.875 vn -0.144 0.908 -0.393 vn -0.870 0.417 -0.263 vn -0.224 0.639 -0.736 vn 0.570 0.816 -0.097 vn 0.338 0.941 0.032 vn -0.152 0.863 -0.481 vn -0.004 0.988 0.155 vn -0.242 0.672 -0.700 vn -0.053 0.897 -0.439 vn 0.463 0.781 -0.419 vn 0.155 0.767 -0.622 vn 0.034 0.975 0.221 vn 0.644 0.206 -0.737 vn 0.313 0.140 -0.939 vn 0.287 0.261 -0.922 vn 0.676 0.170 -0.717 vn 0.931 0.127 -0.343 vn 0.893 0.096 -0.440 vn 0.858 0.449 -0.249 vn 0.928 -0.340 0.151 vn 0.618 -0.670 0.412 vn 0.568 0.425 -0.705 vn -0.187 0.460 -0.868 vn 0.833 0.328 -0.445 vn 0.335 0.553 -0.763 vn 0.822 0.487 -0.294 vn 0.996 0.029 0.078 vn 0.343 -0.516 0.785 vn 0.553 -0.572 0.606 vn -0.002 0.705 -0.709 vn 0.733 0.578 0.359 vn 0.466 0.829 -0.308 vn -0.397 0.288 -0.871 vn -0.157 0.183 -0.971 vn -0.345 0.275 -0.897 vn -0.799 0.140 -0.585 vn 0.955 -0.291 0.051 vn 0.625 0.537 -0.566 vn 0.990 0.136 0.046 vn 0.941 0.328 0.083 vn 0.932 -0.169 0.319 vn 0.145 0.355 -0.923 vn 0.830 0.153 0.536 vn 0.847 0.094 0.523 vn 0.791 -0.564 0.237 vn 0.663 0.255 0.704 vn 0.931 0.227 0.286 vn -0.507 0.477 -0.718 vn 0.598 0.540 -0.592 vn -0.450 -0.025 -0.893 vn 0.010 0.355 -0.935 vn -0.233 -0.283 -0.930 vn 0.082 0.177 -0.981 vn 0.155 0.080 -0.985 vn -0.359 -0.187 -0.914 vn -0.261 -0.007 -0.965 vn 0.083 0.363 -0.928 vn 0.584 0.671 -0.457 vn -0.450 -0.248 -0.858 vn -0.798 0.171 -0.578 vn -0.693 0.008 -0.721 vn -0.830 -0.113 -0.547 vn -0.551 -0.691 -0.467 vn -0.914 -0.329 -0.235 vn -0.782 -0.506 -0.363 vn -0.661 -0.153 -0.735 vn -0.674 -0.447 -0.588 vn -0.534 -0.666 -0.521 vn -0.956 -0.272 -0.113 vn -0.791 0.168 -0.588 vn 0.848 0.071 -0.526 vn 0.609 -0.175 -0.773 vn 0.526 0.057 0.849 vn 0.624 0.051 -0.780 vn -0.240 -0.238 -0.941 vn -0.053 -0.603 -0.796 vn 0.556 0.042 -0.830 vn -0.561 -0.403 -0.723 vn -0.880 -0.141 -0.454 vn -0.926 -0.222 -0.305 vn -0.489 -0.166 -0.856 vn 0.200 0.391 -0.898 vn -0.734 -0.069 -0.676 vn -0.185 0.884 -0.429 vn -0.883 0.450 -0.132 vn 0.098 -0.235 -0.967 vn -0.388 0.206 -0.898 vn -0.607 0.148 -0.781 vn 0.100 0.181 -0.978 vn -0.637 -0.154 -0.755 vn 0.510 -0.467 -0.722 vn 0.114 -0.555 -0.824 vn 0.396 0.112 -0.911 vn -0.515 -0.112 -0.850 vn -0.710 -0.440 -0.550 vn -0.853 0.293 -0.431 vn -0.138 -0.733 -0.666 vn -0.005 0.955 -0.297 vn -0.841 0.325 -0.433 vn -0.604 -0.088 -0.792 vn -0.310 -0.012 -0.951 vn -0.803 -0.169 -0.572 vn 0.940 -0.281 -0.195 vn 0.876 -0.482 -0.015 vn 0.715 -0.697 0.047 vn 0.948 -0.075 0.310 vn 0.295 -0.623 0.724 vn -0.372 -0.656 0.657 vn -0.294 -0.549 0.783 vn 0.853 -0.472 -0.225 vn 0.592 -0.721 0.360 vn -0.845 -0.400 0.355 vn -0.979 -0.182 -0.096 vn -0.547 -0.813 0.200 vn -0.696 -0.637 0.330 vn -0.461 -0.885 0.058 vn -0.465 -0.885 -0.000 vn 0.004 -0.759 0.652 vn -0.145 -0.842 0.520 vn 0.660 0.632 -0.406 vn 0.657 0.056 0.752 vn 0.481 0.032 0.876 vn 0.807 0.528 0.265 vn 0.603 0.155 0.782 vn 0.216 -0.391 0.895 vn 0.391 -0.546 0.741 vn -0.328 -0.682 0.653 vn -0.724 -0.434 0.536 vn -0.260 -0.677 0.688 vn 0.341 -0.236 0.910 vn 0.700 0.350 -0.622 vn 0.692 0.666 0.280 vn 0.063 0.406 0.912 vn 0.486 0.042 -0.873 vn 0.742 0.141 -0.656 vn 0.829 0.357 -0.430 vn 0.817 0.576 0.008 vn -0.143 -0.155 -0.978 vn 0.761 0.266 -0.591 vn 0.739 0.673 0.040 vn 0.389 0.340 -0.856 vn 0.659 0.731 -0.175 vn 0.399 0.272 -0.876 vn 0.659 0.748 -0.083 vn 0.660 0.110 -0.743 vn 0.866 0.500 0.011 vn 0.632 -0.110 -0.767 vn 0.509 -0.306 -0.805 vn 0.779 0.374 0.503 vn 0.964 0.099 -0.245 vn 0.910 0.411 0.048 vn 0.780 0.054 0.624 vn -0.448 0.780 0.437 vn 0.295 0.362 0.884 vn 0.389 0.530 0.754 vn 0.126 0.297 0.946 vn 0.338 0.484 0.807 vn 0.103 -0.670 -0.735 vn 0.569 0.257 0.781 vn 0.965 -0.070 -0.252 vn 0.874 -0.484 0.037 vn -0.880 0.356 0.314 vn -0.888 -0.308 0.341 vn -0.736 -0.608 0.298 vn -0.912 -0.276 0.302 vn -0.692 -0.229 0.684 vn 0.824 -0.055 -0.563 vn 0.624 -0.216 -0.751 vn 0.176 -0.408 -0.896 vn 0.612 -0.596 -0.520 vn -0.165 0.922 0.351 vn 0.328 0.943 -0.057 vn 0.835 0.538 -0.117 vn 0.232 0.972 -0.047 vn 0.492 0.870 0.024 vn 0.401 0.850 -0.341 vn 0.822 0.562 0.097 vn -0.196 0.950 0.244 vn 0.711 0.692 0.123 vn 0.220 0.904 0.366 vn -0.087 0.836 0.541 vn 0.045 0.980 0.193 vn -0.233 0.918 0.320 vn -0.113 0.926 0.361 vn 0.325 0.944 -0.052 vn 0.647 0.661 -0.380 vn 0.801 0.578 0.157 vn 0.206 0.970 0.127 vn 0.456 0.847 0.272 vn 0.475 0.876 0.081 vn 0.292 0.852 0.434 vn -0.060 0.985 0.164 vn 0.671 0.711 -0.211 vn 0.223 0.969 -0.104 vn 0.134 0.982 -0.130 vn 0.251 0.889 0.383 vn 0.800 0.599 0.043 vn 0.397 0.836 -0.378 vn -0.225 -0.521 -0.823 vn -0.144 -0.611 -0.778 vn 0.377 -0.591 -0.713 vn -0.006 -0.321 -0.947 vn -0.599 -0.193 0.777 vn -0.533 0.055 0.845 vn -0.837 -0.538 -0.095 vn -0.750 -0.660 -0.033 vn -0.303 -0.172 0.937 vn -0.613 -0.780 -0.122 vn -0.103 0.127 0.987 vn -0.664 -0.707 -0.243 vn -0.307 -0.088 0.948 vn -0.227 -0.282 0.932 vn -0.556 -0.821 -0.132 vn -0.123 -0.806 0.578 vn -0.245 0.912 0.329 vn 0.641 0.671 0.372 vn 0.688 0.591 0.421 vn -0.157 0.905 0.396 vn 0.773 0.525 0.357 vn -0.143 0.884 0.445 vn 0.758 0.456 0.467 vn -0.245 0.782 0.572 vn 0.127 0.788 0.602 vn 0.792 0.429 0.435 vn -0.506 0.717 0.479 vn -0.986 0.146 0.085 vn -0.936 0.345 0.065 vn -0.995 -0.067 0.074 vn 0.303 0.657 0.690 vn 0.913 0.015 0.408 vn -0.621 0.554 0.554 vn 0.271 0.297 0.915 vn 0.492 -0.865 0.099 vn -0.926 -0.340 0.165 vn 0.956 -0.229 0.184 vn 0.938 -0.346 0.017 vn -0.539 -0.739 -0.403 vn 0.317 -0.883 -0.345 vn -0.481 -0.854 0.197 vn 0.212 -0.972 0.096 vn -0.878 -0.414 0.242 vn 0.587 -0.803 0.102 vn 0.348 -0.925 -0.153 vn -0.769 -0.552 -0.324 vn 0.063 -0.821 0.567 vn -0.319 -0.605 0.729 vn 0.523 0.308 0.795 vn -0.758 -0.512 0.403 vn -0.076 -0.407 0.910 vn -0.534 -0.658 0.531 vn 0.886 0.085 -0.457 vn 0.702 -0.091 -0.707 vn 0.449 -0.108 -0.887 vn 0.958 0.261 -0.117 vn 0.408 -0.328 -0.852 vn 0.998 0.029 -0.048 vn 0.421 -0.536 -0.732 vn 0.980 -0.193 0.056 vn 0.390 -0.477 -0.787 vn 0.973 -0.208 -0.097 vn 0.782 -0.488 -0.388 vn 0.022 -0.601 -0.799 vn 0.914 -0.128 0.384 vn 0.946 -0.316 0.070 vn 0.663 0.255 0.704 vn 0.790 0.177 0.586 vn 0.443 0.219 0.870 vn 0.597 -0.778 -0.198 vn -0.481 -0.655 -0.583 vn 0.629 -0.163 0.760 vn 0.058 -0.947 0.317 vn -0.998 0.060 -0.032 vn -0.008 0.388 0.921 vn -0.393 -0.383 -0.836 vn -0.553 -0.310 -0.774 vn -0.647 -0.403 -0.647 vn 0.276 -0.627 -0.729 vn -0.420 0.207 0.884 vn -0.095 0.495 0.864 vn -0.969 0.244 0.050 vn -0.986 -0.037 0.165 vn -0.199 0.169 0.965 vn -0.993 -0.049 0.104 vn -0.984 -0.168 -0.054 vn -0.263 0.199 0.944 vn -0.340 -0.507 0.792 vn -0.636 -0.237 0.734 vn 0.711 -0.217 -0.669 vn 0.480 -0.268 -0.835 vn 0.340 -0.309 -0.888 vn 0.992 -0.035 -0.125 vn 0.228 -0.448 -0.864 vn 0.970 -0.195 -0.143 vn 0.198 -0.781 -0.592 vn 0.834 -0.542 0.104 vn 0.161 -0.877 -0.452 vn 0.772 -0.566 0.289 vn 0.419 -0.907 0.037 vn -0.168 -0.868 -0.467 vn 0.753 -0.339 0.563 vn 0.864 -0.499 -0.064 vn 0.740 0.070 0.669 vn 0.665 0.227 0.711 vn 0.534 0.321 0.782 vn 0.273 -0.953 0.134 vn -0.562 -0.733 -0.384 vn 0.551 -0.241 0.799 vn -0.734 -0.106 0.671 vn -0.486 -0.404 -0.775 vn -0.629 -0.324 -0.707 vn -0.683 -0.377 -0.625 vn -0.224 -0.624 -0.749 vn -0.289 0.777 0.559 vn -0.060 0.817 0.574 vn -0.798 0.574 -0.185 vn -0.905 0.387 -0.177 vn -0.115 0.604 0.789 vn -0.963 0.145 -0.228 vn -0.993 0.102 -0.060 vn -0.100 0.400 0.911 vn -0.669 -0.372 0.643 vn -0.565 -0.396 0.724 vn -0.917 -0.290 -0.274 vn -0.884 -0.401 -0.238 vn -0.915 -0.401 -0.039 vn -0.367 -0.027 -0.930 vn 0.511 -0.346 -0.787 vn 0.199 -0.245 -0.949 vn 0.265 -0.295 -0.918 vn 0.909 -0.343 -0.236 vn 0.079 -0.705 -0.705 vn 0.768 -0.640 -0.027 vn -0.348 -0.761 -0.548 vn 0.407 -0.910 0.081 vn -0.563 -0.785 -0.259 vn 0.176 -0.922 0.346 vn -0.414 -0.843 0.342 vn -0.906 -0.366 -0.212 vn 0.269 -0.645 0.716 vn 0.711 -0.694 0.117 vn 0.810 -0.274 0.518 vn 0.731 -0.273 0.626 vn 0.740 -0.110 0.663 vn -0.602 -0.587 0.541 vn -0.986 -0.031 -0.165 vn 0.433 -0.333 0.838 vn -0.264 0.740 0.619 vn -0.631 -0.103 -0.769 vn -0.796 0.087 -0.599 vn -0.821 0.297 -0.488 vn -0.521 -0.286 -0.804 vn 0.827 0.498 0.263 vn 0.635 0.609 0.475 vn -0.089 0.947 -0.308 vn 0.028 0.955 -0.295 vn 0.690 0.547 0.473 vn -0.643 0.694 -0.325 vn -0.830 0.546 0.112 vn 0.276 0.006 0.961 vn -0.952 -0.304 0.013 vn -0.672 -0.707 0.219 vn 0.934 -0.149 0.326 vn 0.985 0.017 0.174 vn 0.500 0.578 0.645 vn 0.398 0.039 0.917 vn 0.334 0.517 0.788 vn 0.955 -0.164 -0.249 vn 0.835 -0.550 -0.015 vn 0.605 0.237 0.760 vn 0.803 0.445 0.397 vn 0.924 0.019 -0.383 vn 0.850 -0.455 -0.265 vn 0.890 0.361 -0.278 vn -0.728 0.410 -0.549 vn 0.274 0.757 0.593 vn 0.860 0.509 0.047 vn 0.862 0.482 0.159 vn 0.850 0.525 -0.047 vn 0.755 0.639 -0.147 vn 0.343 0.737 0.583 vn 0.923 0.356 -0.144 vn 0.318 0.865 0.388 vn 0.910 0.323 -0.259 vn 0.621 -0.057 -0.782 vn 0.448 -0.053 -0.893 vn 0.269 -0.243 -0.932 vn 0.066 -0.081 -0.995 vn -0.700 -0.507 -0.503 vn -0.732 -0.441 -0.520 vn -0.728 0.332 -0.599 vn -0.818 -0.092 -0.568 vn -0.531 0.842 0.093 vn -0.897 0.406 0.176 vn -0.795 0.585 0.163 vn -0.987 -0.082 0.140 vn -0.959 -0.031 0.283 vn -0.250 -0.479 -0.841 vn -0.296 0.827 0.478 vn -0.487 0.543 0.684 vn -0.401 0.614 0.680 vn 0.116 0.696 -0.709 vn 0.718 0.651 -0.246 vn 0.504 0.863 0.034 vn 0.395 0.836 0.382 vn 0.511 0.205 -0.835 vn 0.628 0.647 0.433 vn 0.680 -0.658 -0.324 vn 0.674 0.234 0.701 vn 0.519 -0.843 0.144 vn 0.473 0.201 0.858 vn -0.097 -0.142 0.985 vn 0.570 -0.772 0.280 vn 0.213 0.139 0.967 vn 0.157 0.019 0.987 vn -0.383 0.331 0.862 vn -0.961 0.187 0.203 vn -0.734 0.638 0.235 vn 0.345 -0.632 -0.694 vn 0.827 0.027 0.561 vn 0.766 0.196 0.612 vn 0.093 -0.902 -0.421 vn 0.742 0.065 0.667 vn 0.892 -0.386 -0.235 vn -0.356 0.741 0.569 vn -0.187 0.922 0.339 vn 0.093 0.996 -0.012 vn 0.268 0.600 -0.753 vn -0.671 0.566 -0.478 vn -0.450 0.881 -0.144 vn -0.411 -0.020 -0.911 vn -0.403 0.419 -0.814 vn -0.046 -0.910 -0.412 vn 0.747 0.204 0.633 vn -0.864 0.404 -0.301 vn -0.809 0.495 0.318 vn -0.495 0.535 0.685 vn 0.097 -0.760 -0.642 vn -0.223 -0.975 -0.004 vn 0.591 -0.333 -0.735 vn -0.383 -0.783 -0.491 vn 0.043 -0.563 -0.825 vn -0.343 -0.752 -0.563 vn -0.372 -0.581 -0.724 vn 0.354 -0.925 0.141 vn -0.325 -0.537 -0.779 vn -0.594 0.652 0.470 vn -0.636 -0.751 0.178 vn 0.656 -0.582 -0.480 vn -0.110 -0.595 -0.796 vn -0.006 -0.206 -0.979 vn -0.033 -0.090 -0.995 vn 0.951 0.194 -0.239 vn 0.525 -0.349 -0.776 vn 0.273 -0.239 -0.932 vn 0.244 0.667 -0.704 vn 0.804 0.501 0.320 vn 0.816 0.492 0.303 vn 0.600 0.754 -0.267 vn 0.922 0.331 -0.202 vn 0.951 -0.170 0.258 vn -0.121 -0.731 0.672 vn -0.882 -0.470 0.025 vn -0.937 0.051 -0.344 vn -0.464 -0.711 0.529 vn -0.495 -0.865 -0.077 # 2519 vertex normals g objDiablo3 s 1 f 6/1/6 5/2/5 8/3/8 f 6/1/6 8/3/8 7/4/7 f 12/5/12 11/6/11 10/7/10 f 12/5/12 10/7/10 9/8/9 f 15/9/15 14/10/14 1/11/1 f 15/9/15 1/11/1 2/12/2 f 16/13/16 15/9/15 2/12/2 f 16/13/16 2/12/2 17/14/17 f 25/15/25 24/16/24 23/17/23 f 25/15/25 23/17/23 22/18/22 f 5/2/5 10/7/10 13/19/13 f 5/2/5 13/19/13 8/3/8 f 9/8/9 10/7/10 5/2/5 f 9/8/9 5/2/5 4/20/4 f 13/19/13 24/16/24 7/4/7 f 13/19/13 7/4/7 8/3/8 f 11/6/11 23/17/23 24/16/24 f 11/6/11 24/16/24 13/19/13 f 20/21/20 27/22/27 25/15/25 f 20/21/20 25/15/25 22/18/22 f 29/23/29 28/24/28 27/22/27 f 29/23/29 27/22/27 20/21/20 f 30/25/30 27/22/27 28/24/28 f 30/25/30 28/24/28 31/26/31 f 31/26/31 28/24/28 1255/27/1255 f 31/26/31 1255/27/1255 1265/28/1265 f 1256/29/1256 1255/27/1255 28/24/28 f 1256/29/1256 28/24/28 29/23/29 f 33/30/33 32/31/32 1258/32/1258 f 33/30/33 1258/32/1258 1262/33/1262 f 1258/32/1258 32/31/32 31/26/31 f 1258/32/1258 31/26/31 1265/28/1265 f 34/34/34 1256/29/1256 29/23/29 f 34/34/34 29/23/29 35/35/35 f 35/35/35 29/23/29 20/21/20 f 35/35/35 20/21/20 36/36/36 f 37/37/37 34/34/34 35/35/35 f 37/37/37 35/35/35 38/38/38 f 35/35/35 36/36/36 39/39/39 f 35/35/35 39/39/39 38/38/38 f 40/40/40 37/37/37 38/38/38 f 40/40/40 38/38/38 41/41/41 f 41/41/41 38/38/38 39/39/39 f 41/41/41 39/39/39 42/42/42 f 43/43/43 37/37/37 40/40/40 f 43/43/43 40/40/40 44/44/44 f 45/45/45 12/5/12 9/8/9 f 45/45/45 9/8/9 46/46/46 f 41/41/41 42/42/42 12/5/12 f 41/41/41 12/5/12 45/45/45 f 47/47/47 44/44/44 40/40/40 f 47/47/47 40/40/40 45/45/45 f 48/48/48 50/49/50 18/50/18 f 48/48/48 18/50/18 19/51/19 f 52/52/52 1280/53/1280 50/49/50 f 52/52/52 50/49/50 48/48/48 f 53/54/53 25/15/25 27/22/27 f 53/54/53 27/22/27 30/25/30 f 54/55/54 26/56/26 25/15/25 f 54/55/54 25/15/25 53/54/53 f 59/57/59 54/55/54 53/54/53 f 59/57/59 53/54/53 60/58/60 f 30/25/30 55/59/55 60/58/60 f 30/25/30 60/58/60 53/54/53 f 48/48/48 49/60/49 57/61/57 f 48/48/48 57/61/57 52/52/52 f 52/52/52 57/61/57 33/30/33 f 52/52/52 33/30/33 51/62/51 f 61/63/61 45/45/45 46/46/46 f 61/63/61 46/46/46 62/64/62 f 109/65/109 44/44/44 65/66/65 f 109/65/109 65/66/65 108/67/108 f 67/68/67 42/42/42 66/69/66 f 67/68/67 66/69/66 21/70/21 f 69/71/69 16/13/16 17/14/17 f 69/71/69 17/14/17 70/72/70 f 17/14/17 6/1/6 18/50/18 f 17/14/17 18/50/18 72/73/72 f 72/73/72 18/50/18 50/49/50 f 72/73/72 50/49/50 73/74/73 f 73/74/73 50/49/50 1280/53/1280 f 73/74/73 1280/53/1280 74/75/74 f 75/76/75 72/73/72 73/74/73 f 75/76/75 73/74/73 76/77/76 f 76/77/76 73/74/73 74/75/74 f 76/77/76 74/75/74 77/78/77 f 75/76/75 76/77/76 79/79/79 f 75/76/75 79/79/79 78/80/78 f 84/81/84 81/82/81 83/83/83 f 84/81/84 83/83/83 82/84/82 f 85/85/85 79/79/79 87/86/87 f 85/85/85 87/86/87 86/87/86 f 79/79/79 80/88/80 88/89/88 f 79/79/79 88/89/88 87/86/87 f 85/85/85 83/83/83 81/82/81 f 85/85/85 81/82/81 78/80/78 f 92/90/92 91/91/91 90/92/90 f 92/90/92 90/92/90 68/93/68 f 92/90/92 86/94/86 93/95/93 f 92/90/92 93/95/93 91/91/91 f 82/96/82 83/97/83 94/98/94 f 82/96/82 94/98/94 92/90/92 f 86/94/86 89/99/89 95/100/95 f 86/94/86 95/100/95 93/95/93 f 96/101/96 89/102/89 87/86/87 f 96/101/96 87/86/87 88/89/88 f 100/103/100 99/104/99 98/105/98 f 100/103/100 98/105/98 97/106/97 f 97/106/97 98/105/98 104/107/104 f 97/106/97 104/107/104 103/108/103 f 97/106/97 107/109/107 106/110/106 f 97/106/97 106/110/106 100/103/100 f 101/111/101 109/112/109 108/113/108 f 101/111/101 108/113/108 103/108/103 f 103/108/103 111/114/111 107/109/107 f 103/108/103 107/109/107 97/106/97 f 112/115/112 113/116/113 115/117/115 f 112/115/112 115/117/115 114/118/114 f 194/119/194 126/120/126 115/117/115 f 194/119/194 115/117/115 196/121/196 f 117/122/117 112/115/112 114/118/114 f 117/122/117 114/118/114 118/123/118 f 146/124/146 117/122/117 118/123/118 f 146/124/146 118/123/118 174/125/174 f 113/116/113 127/126/127 128/127/128 f 113/116/113 128/127/128 129/128/129 f 127/126/127 120/129/120 132/130/132 f 127/126/127 132/130/132 130/131/130 f 139/132/139 138/133/138 137/134/137 f 139/132/139 137/134/137 140/135/140 f 120/129/120 144/136/144 141/137/141 f 120/129/120 141/137/141 132/130/132 f 143/138/143 141/137/141 144/136/144 f 143/138/143 144/136/144 145/139/145 f 139/132/139 135/140/135 157/141/157 f 139/132/139 157/141/157 136/142/136 f 131/143/131 134/144/134 150/145/150 f 131/143/131 150/145/150 149/146/149 f 134/144/134 157/141/157 151/147/151 f 134/144/134 151/147/151 150/145/150 f 152/148/152 153/149/153 159/150/159 f 152/148/152 159/150/159 155/151/155 f 157/141/157 158/152/158 160/153/160 f 157/141/157 160/153/160 159/150/159 f 143/138/143 145/139/145 162/154/162 f 143/138/143 162/154/162 178/155/178 f 153/149/153 151/147/151 157/141/157 f 153/149/153 157/141/157 159/150/159 f 167/156/167 161/157/161 168/158/168 f 167/156/167 168/158/168 169/159/169 f 171/160/171 190/161/190 191/162/191 f 171/160/171 191/162/191 173/163/173 f 189/164/189 148/165/148 174/125/174 f 189/164/189 174/125/174 188/166/188 f 116/167/116 179/168/179 123/169/123 f 116/167/116 123/169/123 115/117/115 f 125/170/125 179/168/179 184/171/184 f 125/170/125 184/171/184 183/172/183 f 179/168/179 116/167/116 182/173/182 f 179/168/179 182/173/182 184/171/184 f 181/174/181 126/120/126 194/119/194 f 181/174/181 194/119/194 185/175/185 f 186/176/186 201/177/201 187/178/187 f 186/176/186 187/178/187 172/179/172 f 172/179/172 191/162/191 190/161/190 f 172/179/172 190/161/190 186/176/186 f 129/128/129 208/180/208 197/181/197 f 129/128/129 197/181/197 196/121/196 f 199/182/199 147/183/147 146/124/146 f 199/182/199 146/124/146 198/184/198 f 200/185/200 162/154/162 145/139/145 f 200/185/200 145/139/145 199/182/199 f 200/186/200 225/187/225 175/188/175 f 200/186/200 175/188/175 162/189/162 f 186/176/186 190/161/190 204/190/204 f 186/176/186 204/190/204 203/191/203 f 205/192/205 210/193/210 235/194/235 f 205/192/205 235/194/235 234/195/234 f 206/196/206 207/197/207 205/192/205 f 206/196/206 205/192/205 203/191/203 f 207/198/207 206/199/206 208/180/208 f 207/198/207 208/180/208 129/128/129 f 205/192/205 207/197/207 209/200/209 f 205/192/205 209/200/209 210/193/210 f 339/201/339 219/202/219 233/203/233 f 339/201/339 233/203/233 338/204/338 f 213/205/213 212/206/212 337/207/337 f 213/205/213 337/207/337 340/208/340 f 214/209/214 215/210/215 217/211/217 f 214/209/214 217/211/217 216/212/216 f 224/213/224 211/214/211 214/209/214 f 224/213/224 214/209/214 220/215/220 f 214/209/214 216/212/216 222/216/222 f 214/209/214 222/216/222 220/215/220 f 216/212/216 260/217/260 258/218/258 f 216/212/216 258/218/258 222/216/222 f 225/187/225 221/219/221 224/213/224 f 225/187/225 224/213/224 223/220/223 f 238/221/238 226/222/226 225/187/225 f 238/221/238 225/187/225 223/220/223 f 231/223/231 213/205/213 340/208/340 f 231/223/231 340/208/340 341/224/341 f 230/225/230 231/223/231 341/224/341 f 230/225/230 341/224/341 229/226/229 f 232/227/232 213/205/213 231/223/231 f 232/227/232 231/223/231 240/228/240 f 212/206/212 213/205/213 232/227/232 f 212/206/212 232/227/232 215/210/215 f 202/229/202 233/230/233 187/178/187 f 202/229/202 187/178/187 201/177/201 f 202/231/202 337/207/337 338/204/338 f 202/231/202 338/204/338 233/203/233 f 202/229/202 201/177/201 234/195/234 f 202/229/202 234/195/234 235/194/235 f 232/227/232 240/228/240 237/232/237 f 232/227/232 237/232/237 236/233/236 f 236/233/236 237/232/237 248/234/248 f 236/233/236 248/234/248 250/235/250 f 215/210/215 232/227/232 236/233/236 f 215/210/215 236/233/236 217/211/217 f 227/236/227 226/222/226 238/221/238 f 227/236/227 238/221/238 239/237/239 f 245/238/245 227/236/227 239/237/239 f 245/238/245 239/237/239 247/239/247 f 242/240/242 206/196/206 203/191/203 f 242/240/242 203/191/203 204/190/204 f 243/241/243 181/174/181 193/242/193 f 243/241/243 193/242/193 244/243/244 f 208/180/208 242/244/242 244/243/244 f 208/180/208 244/243/244 193/242/193 f 228/245/228 245/238/245 230/246/230 f 228/245/228 230/246/230 229/247/229 f 246/248/246 237/249/237 240/250/240 f 246/248/246 240/250/240 247/239/247 f 249/251/249 253/252/253 261/253/261 f 249/251/249 261/253/261 259/254/259 f 254/255/254 246/248/246 247/239/247 f 254/255/254 247/239/247 239/237/239 f 238/221/238 255/256/255 254/255/254 f 238/221/238 254/255/254 239/237/239 f 255/256/255 238/221/238 223/220/223 f 255/256/255 223/220/223 220/215/220 f 261/253/261 262/257/262 250/235/250 f 261/253/261 250/235/250 259/254/259 f 257/258/257 260/217/260 262/257/262 f 257/258/257 262/257/262 261/253/261 f 251/259/251 257/258/257 261/253/261 f 251/259/251 261/253/261 253/252/253 f 264/260/264 263/261/263 265/262/265 f 264/260/264 265/262/265 266/263/266 f 273/264/273 283/265/283 271/266/271 f 273/264/273 271/266/271 274/267/274 f 274/267/274 265/262/265 263/261/263 f 274/267/274 263/261/263 275/268/275 f 270/269/270 284/270/284 276/271/276 f 270/269/270 276/271/276 277/272/277 f 268/273/268 271/266/271 283/265/283 f 268/273/268 283/265/283 284/270/284 f 278/274/278 279/275/279 282/276/282 f 278/274/278 282/276/282 281/277/281 f 279/275/279 273/264/273 298/278/298 f 279/275/279 298/278/298 282/276/282 f 273/264/273 274/267/274 275/268/275 f 273/264/273 275/268/275 298/278/298 f 269/279/269 402/280/402 295/281/295 f 269/279/269 295/281/295 286/282/286 f 286/282/286 295/281/295 288/283/288 f 286/282/286 288/283/288 287/284/287 f 287/284/287 288/283/288 290/285/290 f 287/284/287 290/285/290 289/286/289 f 292/287/292 289/286/289 290/285/290 f 292/287/292 290/285/290 293/288/293 f 255/289/255 256/290/256 289/286/289 f 255/289/255 289/286/289 292/287/292 f 263/261/263 254/291/254 297/292/297 f 263/261/263 297/292/297 298/278/298 f 292/287/292 293/288/293 297/292/297 f 292/287/292 297/292/297 254/291/254 f 296/293/296 387/294/387 288/283/288 f 296/293/296 288/283/288 295/281/295 f 286/282/286 251/259/251 253/252/253 f 286/282/286 253/252/253 269/279/269 f 287/284/287 289/286/289 256/290/256 f 287/284/287 256/290/256 252/295/252 f 251/259/251 286/282/286 287/284/287 f 251/259/251 287/284/287 252/295/252 f 266/296/266 267/297/267 253/252/253 f 266/296/266 253/252/253 249/251/249 f 293/288/293 291/298/291 299/299/299 f 293/288/293 299/299/299 297/292/297 f 299/299/299 291/298/291 300/300/300 f 299/299/299 300/300/300 301/301/301 f 301/302/301 300/303/300 302/304/302 f 301/302/301 302/304/302 303/305/303 f 303/305/303 302/304/302 304/306/304 f 303/305/303 304/306/304 305/307/305 f 305/307/305 304/306/304 306/308/306 f 305/307/305 306/308/306 307/309/307 f 306/308/306 308/310/308 315/311/315 f 306/308/306 315/311/315 307/309/307 f 310/312/310 314/313/314 316/314/316 f 310/312/310 316/314/316 334/315/334 f 316/314/316 317/316/317 312/317/312 f 316/314/316 312/317/312 334/315/334 f 309/318/309 336/319/336 316/314/316 f 309/318/309 316/314/316 314/313/314 f 336/319/336 311/320/311 317/316/317 f 336/319/336 317/316/317 316/314/316 f 323/321/323 327/322/327 308/310/308 f 323/321/323 308/310/308 306/308/306 f 305/307/305 319/323/319 324/324/324 f 305/307/305 324/324/324 303/305/303 f 299/299/299 301/301/301 320/325/320 f 299/299/299 320/325/320 321/326/321 f 303/305/303 324/324/324 320/327/320 f 303/305/303 320/327/320 301/302/301 f 300/300/300 291/298/291 344/328/344 f 300/300/300 344/328/344 322/329/322 f 302/304/302 300/303/300 322/330/322 f 302/304/302 322/330/322 323/321/323 f 319/323/319 315/311/315 325/331/325 f 319/323/319 325/331/325 349/332/349 f 325/331/325 315/311/315 318/333/318 f 325/331/325 318/333/318 326/334/326 f 320/327/320 324/324/324 349/332/349 f 320/327/320 349/332/349 432/335/432 f 332/336/332 308/310/308 327/322/327 f 332/336/332 327/322/327 333/337/333 f 333/337/333 327/322/327 328/338/328 f 333/337/333 328/338/328 329/339/329 f 325/331/325 326/334/326 329/340/329 f 325/331/325 329/340/329 328/341/328 f 326/334/326 318/333/318 330/342/330 f 326/334/326 330/342/330 331/343/331 f 331/344/331 330/345/330 332/336/332 f 331/344/331 332/336/332 333/337/333 f 330/342/330 345/346/345 334/315/334 f 330/342/330 334/315/334 335/347/335 f 336/319/336 346/348/346 330/345/330 f 336/319/336 330/345/330 335/349/335 f 312/317/312 313/350/313 335/347/335 f 312/317/312 335/347/335 334/315/334 f 335/349/335 313/350/313 311/320/311 f 335/349/335 311/320/311 336/319/336 f 337/207/337 212/206/212 218/351/218 f 337/207/337 218/351/218 338/204/338 f 338/204/338 218/351/218 211/214/211 f 338/204/338 211/214/211 339/201/339 f 202/231/202 235/352/235 340/208/340 f 202/231/202 340/208/340 337/207/337 f 235/352/235 210/353/210 341/224/341 f 235/352/235 341/224/341 340/208/340 f 342/354/342 290/285/290 288/283/288 f 342/354/342 288/283/288 387/294/387 f 328/338/328 327/322/327 347/355/347 f 328/338/328 347/355/347 348/356/348 f 325/331/325 328/341/328 348/357/348 f 325/331/325 348/357/348 349/332/349 f 348/356/348 347/355/347 351/358/351 f 348/356/348 351/358/351 352/359/352 f 349/332/349 348/357/348 352/360/352 f 349/332/349 352/360/352 350/361/350 f 347/355/347 323/321/323 322/330/322 f 347/355/347 322/330/322 351/358/351 f 354/362/354 344/363/344 343/364/343 f 354/362/354 343/364/343 353/365/353 f 354/362/354 353/365/353 355/366/355 f 354/362/354 355/366/355 356/367/356 f 356/367/356 355/366/355 357/368/357 f 356/367/356 357/368/357 358/369/358 f 357/368/357 359/370/359 360/371/360 f 357/368/357 360/371/360 358/369/358 f 362/372/362 361/373/361 363/374/363 f 362/372/362 363/374/363 364/375/364 f 365/376/365 366/377/366 363/374/363 f 365/376/365 363/374/363 361/373/361 f 368/378/368 369/379/369 359/370/359 f 368/378/368 359/370/359 357/368/357 f 362/372/362 371/380/371 374/381/374 f 362/372/362 374/381/374 360/371/360 f 356/367/356 372/382/372 373/383/373 f 356/367/356 373/383/373 354/362/354 f 372/382/372 360/371/360 374/381/374 f 372/382/372 374/381/374 383/384/383 f 370/385/370 369/379/369 376/386/376 f 370/385/370 376/386/376 375/387/375 f 374/381/374 371/380/371 375/388/375 f 374/381/374 375/388/375 376/389/376 f 377/390/377 379/391/379 364/375/364 f 377/390/377 364/375/364 381/392/381 f 366/377/366 380/393/380 377/394/377 f 366/377/366 377/394/377 381/395/381 f 376/386/376 369/379/369 368/378/368 f 376/386/376 368/378/368 382/396/382 f 374/381/374 376/389/376 382/397/382 f 374/381/374 382/397/382 383/384/383 f 294/398/294 342/354/342 386/399/386 f 294/398/294 386/399/386 385/400/385 f 353/365/353 343/364/343 385/401/385 f 353/365/353 385/401/385 368/378/368 f 296/293/296 295/281/295 402/280/402 f 296/293/296 402/280/402 388/402/388 f 387/294/387 296/293/296 388/402/388 f 387/294/387 388/402/388 389/403/389 f 352/404/352 351/405/351 395/406/395 f 352/404/352 395/406/395 390/407/390 f 350/408/350 352/404/352 390/407/390 f 350/408/350 390/407/390 434/409/434 f 390/407/390 395/406/395 394/410/394 f 390/407/390 394/410/394 392/411/392 f 434/409/434 390/407/390 392/411/392 f 434/409/434 392/411/392 391/412/391 f 392/411/392 394/410/394 386/399/386 f 392/411/392 386/399/386 393/413/393 f 391/412/391 392/411/392 393/413/393 f 391/412/391 393/413/393 396/414/396 f 359/370/359 369/379/369 370/385/370 f 359/370/359 370/385/370 365/376/365 f 394/415/394 395/416/395 382/396/382 f 394/415/394 382/396/382 368/378/368 f 297/292/297 321/326/321 397/417/397 f 297/292/297 397/417/397 298/278/298 f 281/277/281 282/276/282 398/418/398 f 281/277/281 398/418/398 396/419/396 f 433/420/433 391/421/391 400/422/400 f 433/420/433 400/422/400 399/423/399 f 396/419/396 398/418/398 400/422/400 f 396/419/396 400/422/400 391/421/391 f 298/278/298 397/417/397 398/418/398 f 298/278/298 398/418/398 282/276/282 f 321/326/321 403/424/403 401/425/401 f 321/326/321 401/425/401 397/417/397 f 395/426/395 384/427/384 383/384/383 f 395/426/395 383/384/383 382/397/382 f 280/428/280 281/277/281 396/419/396 f 280/428/280 396/419/396 389/429/389 f 280/428/280 389/429/389 388/430/388 f 280/428/280 388/430/388 277/272/277 f 402/431/402 270/269/270 277/272/277 f 402/431/402 277/272/277 388/430/388 f 403/432/403 404/433/404 405/434/405 f 403/432/403 405/434/405 401/435/401 f 404/433/404 407/436/407 406/437/406 f 404/433/404 406/437/406 405/434/405 f 406/437/406 407/436/407 409/438/409 f 406/437/406 409/438/409 408/439/408 f 412/440/412 410/441/410 411/442/411 f 412/440/412 411/442/411 413/443/413 f 415/444/415 410/441/410 412/440/412 f 415/444/415 412/440/412 416/445/416 f 417/446/417 406/437/406 408/439/408 f 417/446/417 408/439/408 418/447/418 f 411/442/411 409/438/409 420/448/420 f 411/442/411 420/448/420 419/449/419 f 421/450/421 422/451/422 420/448/420 f 421/450/421 420/448/420 409/438/409 f 424/452/424 423/453/423 425/454/425 f 424/452/424 425/454/425 418/447/418 f 420/448/420 425/455/425 423/456/423 f 420/448/420 423/456/423 419/449/419 f 426/457/426 430/458/430 413/443/413 f 426/457/426 413/443/413 428/459/428 f 416/445/416 430/460/430 426/461/426 f 416/445/416 426/461/426 429/462/429 f 425/454/425 431/463/431 417/446/417 f 425/454/425 417/446/417 418/447/418 f 420/448/420 422/451/422 431/464/431 f 420/448/420 431/464/431 425/455/425 f 408/439/408 415/444/415 424/452/424 f 408/439/408 424/452/424 418/447/418 f 431/463/431 435/465/435 433/466/433 f 431/463/431 433/466/433 417/446/417 f 435/467/435 431/464/431 422/451/422 f 435/467/435 422/451/422 432/468/432 f 243/469/243 244/470/244 437/471/437 f 243/469/243 437/471/437 436/472/436 f 436/472/436 437/471/437 439/473/439 f 436/472/436 439/473/439 438/474/438 f 436/472/436 438/474/438 444/475/444 f 436/472/436 444/475/444 440/476/440 f 436/472/436 440/476/440 441/477/441 f 436/472/436 441/477/441 243/469/243 f 184/171/184 243/241/243 441/478/441 f 184/171/184 441/478/441 442/479/442 f 441/477/441 440/476/440 443/480/443 f 441/477/441 443/480/443 558/481/558 f 443/480/443 440/476/440 444/475/444 f 443/480/443 444/475/444 445/482/445 f 441/478/441 558/483/558 447/484/447 f 441/478/441 447/484/447 446/485/446 f 446/485/446 447/484/447 122/486/122 f 446/485/446 122/486/122 121/487/121 f 439/473/439 437/471/437 451/488/451 f 439/473/439 451/488/451 1389/489/1389 f 451/488/451 437/471/437 244/470/244 f 451/488/451 244/470/244 242/490/242 f 1389/489/1389 451/488/451 204/491/204 f 1389/489/1389 204/491/204 1392/492/1392 f 1392/493/1392 204/494/204 171/495/171 f 1392/493/1392 171/495/171 452/496/452 f 452/496/452 171/495/171 483/497/483 f 452/496/452 483/497/483 453/498/453 f 453/498/453 483/497/483 454/499/454 f 453/498/453 454/499/454 455/500/455 f 455/500/455 454/499/454 456/501/456 f 455/500/455 456/501/456 457/502/457 f 457/502/457 456/501/456 458/503/458 f 457/502/457 458/503/458 459/504/459 f 459/504/459 458/503/458 460/505/460 f 459/504/459 460/505/460 461/506/461 f 461/506/461 460/505/460 462/507/462 f 461/506/461 462/507/462 463/508/463 f 463/508/463 462/507/462 464/509/464 f 463/508/463 464/509/464 465/510/465 f 465/510/465 464/509/464 466/511/466 f 465/510/465 466/511/466 467/512/467 f 458/503/458 456/501/456 468/513/468 f 458/503/458 468/513/468 528/514/528 f 460/505/460 458/503/458 469/515/469 f 460/505/460 469/515/469 470/516/470 f 462/507/462 460/505/460 470/516/470 f 462/507/462 470/516/470 471/517/471 f 464/509/464 462/507/462 471/517/471 f 464/509/464 471/517/471 472/518/472 f 466/511/466 464/509/464 472/518/472 f 466/511/466 472/518/472 473/519/473 f 468/513/468 456/501/456 454/499/454 f 468/513/468 454/499/454 474/520/474 f 468/513/468 474/520/474 475/521/475 f 468/513/468 475/521/475 498/522/498 f 475/521/475 474/520/474 476/523/476 f 475/521/475 476/523/476 477/524/477 f 476/523/476 474/520/474 479/525/479 f 476/523/476 479/525/479 480/526/480 f 482/527/482 479/525/479 483/497/483 f 482/527/482 483/497/483 484/528/484 f 482/527/482 484/528/484 486/529/486 f 482/527/482 486/529/486 519/530/519 f 487/531/487 488/532/488 490/533/490 f 487/531/487 490/533/490 489/534/489 f 487/531/487 489/534/489 492/535/492 f 487/531/487 492/535/492 491/536/491 f 492/535/492 489/534/489 493/537/493 f 492/535/492 493/537/493 494/538/494 f 488/532/488 498/522/498 495/539/495 f 488/532/488 495/539/495 496/540/496 f 490/533/490 488/532/488 496/540/496 f 490/533/490 496/540/496 497/541/497 f 171/495/171 173/542/173 484/528/484 f 171/495/171 484/528/484 483/497/483 f 479/525/479 474/520/474 454/499/454 f 479/525/479 454/499/454 483/497/483 f 489/534/489 490/533/490 497/541/497 f 489/534/489 497/541/497 493/537/493 f 499/543/499 475/521/475 505/544/505 f 499/543/499 505/544/505 503/545/503 f 507/546/507 502/547/502 508/548/508 f 507/546/507 508/548/508 509/549/509 f 481/550/481 519/530/519 508/548/508 f 481/550/481 508/548/508 502/547/502 f 503/545/503 514/551/514 537/552/537 f 503/545/503 537/552/537 501/553/501 f 511/554/511 510/555/510 514/551/514 f 511/554/511 514/551/514 503/545/503 f 515/556/515 486/529/486 484/528/484 f 515/556/515 484/528/484 173/542/173 f 513/557/513 514/551/514 510/555/510 f 513/557/513 510/555/510 521/558/521 f 520/559/520 542/560/542 546/561/546 f 520/559/520 546/561/546 522/562/522 f 470/516/470 469/515/469 523/563/523 f 470/516/470 523/563/523 524/564/524 f 471/517/471 470/516/470 524/564/524 f 471/517/471 524/564/524 525/565/525 f 472/518/472 471/517/471 525/565/525 f 472/518/472 525/565/525 526/566/526 f 531/567/531 491/536/491 492/535/492 f 531/567/531 492/535/492 533/568/533 f 541/569/541 515/556/515 538/570/538 f 541/569/541 538/570/538 539/571/539 f 539/571/539 540/572/540 543/573/543 f 539/571/539 543/573/543 541/569/541 f 542/560/542 545/574/545 547/575/547 f 542/560/542 547/575/547 546/561/546 f 550/576/550 551/577/551 552/578/552 f 550/576/550 552/578/552 445/482/445 f 551/577/551 549/579/549 555/580/555 f 551/577/551 555/580/555 557/581/557 f 548/582/548 600/583/600 555/580/555 f 548/582/548 555/580/555 549/579/549 f 450/584/450 568/585/568 189/164/189 f 450/584/450 189/164/189 188/166/188 f 568/585/568 572/586/572 573/587/573 f 568/585/568 573/587/573 571/588/571 f 569/589/569 578/590/578 586/591/586 f 569/589/569 586/591/586 577/592/577 f 448/593/448 564/594/564 591/595/591 f 448/593/448 591/595/591 590/596/590 f 561/597/561 743/598/743 744/599/744 f 561/597/561 744/599/744 595/600/595 f 600/583/600 593/601/593 598/602/598 f 600/583/600 598/602/598 599/603/599 f 559/604/559 599/603/599 594/605/594 f 559/604/559 594/605/594 601/606/601 f 594/605/594 598/602/598 593/601/593 f 594/605/594 593/601/593 592/607/592 f 555/608/555 600/609/600 605/610/605 f 555/608/555 605/610/605 604/611/604 f 604/611/604 590/612/590 591/613/591 f 604/611/604 591/613/591 555/608/555 f 605/610/605 600/609/600 599/614/599 f 605/610/605 599/614/599 559/615/559 f 635/616/635 930/617/930 936/618/936 f 635/616/635 936/618/936 603/619/603 f 993/620/993 994/621/994 610/622/610 f 993/620/993 610/622/610 607/623/607 f 610/622/610 995/624/995 618/625/618 f 610/622/610 618/625/618 617/626/617 f 619/627/619 620/628/620 618/625/618 f 619/627/619 618/625/618 995/624/995 f 648/629/648 618/630/618 620/631/620 f 648/629/648 620/631/620 643/632/643 f 547/575/547 545/574/545 627/633/627 f 547/575/547 627/633/627 625/634/625 f 624/635/624 628/636/628 627/633/627 f 624/635/624 627/633/627 626/637/626 f 581/638/581 628/636/628 624/635/624 f 581/638/581 624/635/624 580/639/580 f 581/640/581 610/641/610 617/642/617 f 581/640/581 617/642/617 628/643/628 f 555/608/555 591/613/591 556/644/556 f 555/608/555 556/644/556 557/645/557 f 630/646/630 629/647/629 631/648/631 f 630/646/630 631/648/631 632/649/632 f 560/650/560 630/646/630 634/651/634 f 560/650/560 634/651/634 635/652/635 f 632/649/632 631/648/631 633/653/633 f 632/649/632 633/653/633 634/651/634 f 603/654/603 638/655/638 637/656/637 f 603/654/603 637/656/637 636/657/636 f 559/615/559 638/658/638 606/659/606 f 559/615/559 606/659/606 605/610/605 f 643/632/643 644/660/644 647/661/647 f 643/632/643 647/661/647 646/662/646 f 647/661/647 644/660/644 676/663/676 f 647/661/647 676/663/676 649/664/649 f 641/665/641 640/666/640 651/667/651 f 641/665/641 651/667/651 652/668/652 f 639/669/639 641/665/641 654/670/654 f 639/669/639 654/670/654 653/671/653 f 641/665/641 652/668/652 655/672/655 f 641/665/641 655/672/655 654/670/654 f 673/673/673 653/674/653 656/675/656 f 673/673/673 656/675/656 657/676/657 f 654/670/654 655/672/655 658/677/658 f 654/670/654 658/677/658 656/678/656 f 656/675/656 662/679/662 663/680/663 f 656/675/656 663/680/663 657/676/657 f 656/678/656 658/677/658 664/681/664 f 656/678/656 664/681/664 662/682/662 f 662/679/662 665/683/665 660/684/660 f 662/679/662 660/684/660 663/680/663 f 661/685/661 665/686/665 662/682/662 f 661/685/661 662/682/662 664/681/664 f 673/673/673 657/676/657 667/687/667 f 673/673/673 667/687/667 672/688/672 f 658/677/658 655/672/655 666/689/666 f 658/677/658 666/689/666 668/690/668 f 663/680/663 660/684/660 669/691/669 f 663/680/663 669/691/669 670/692/670 f 664/681/664 658/677/658 668/690/668 f 664/681/664 668/690/668 671/693/671 f 657/676/657 663/680/663 670/692/670 f 657/676/657 670/692/670 667/687/667 f 661/685/661 664/681/664 671/693/671 f 661/685/661 671/693/671 669/691/669 f 671/693/671 668/690/668 667/687/667 f 671/693/671 667/687/667 670/692/670 f 668/690/668 674/694/674 672/688/672 f 668/690/668 672/688/672 667/687/667 f 674/694/674 666/689/666 675/695/675 f 674/694/674 675/695/675 677/696/677 f 675/695/675 666/689/666 655/672/655 f 675/695/675 655/672/655 652/668/652 f 673/673/673 672/688/672 678/697/678 f 673/673/673 678/697/678 676/698/676 f 915/699/915 679/700/679 680/701/680 f 915/699/915 680/701/680 767/702/767 f 915/699/915 682/703/682 683/704/683 f 915/699/915 683/704/683 679/700/679 f 681/705/681 680/706/680 684/707/684 f 681/705/681 684/707/684 685/708/685 f 681/705/681 685/708/685 687/709/687 f 681/705/681 687/709/687 699/710/699 f 686/711/686 683/704/683 689/712/689 f 686/711/686 689/712/689 711/713/711 f 687/709/687 690/714/690 698/715/698 f 687/709/687 698/715/698 699/710/699 f 693/716/693 694/717/694 696/718/696 f 693/716/693 696/718/696 697/719/697 f 688/720/688 701/721/701 697/719/697 f 688/720/688 697/719/697 696/718/696 f 691/722/691 688/720/688 699/710/699 f 691/722/691 699/710/699 698/715/698 f 697/719/697 701/721/701 703/723/703 f 697/719/697 703/723/703 704/724/704 f 706/725/706 689/712/689 683/704/683 f 706/725/706 683/704/683 682/703/682 f 707/726/707 708/727/708 749/728/749 f 707/726/707 749/728/749 750/729/750 f 679/700/679 683/704/683 686/711/686 f 679/700/679 686/711/686 710/730/710 f 685/708/685 684/707/684 712/731/712 f 685/708/685 712/731/712 713/732/713 f 710/730/710 686/711/686 714/733/714 f 710/730/710 714/733/714 716/734/716 f 715/735/715 687/709/687 685/708/685 f 715/735/715 685/708/685 713/732/713 f 711/713/711 690/714/690 722/736/722 f 711/713/711 722/736/722 717/737/717 f 690/714/690 687/709/687 715/735/715 f 690/714/690 715/735/715 722/736/722 f 684/738/684 710/730/710 716/734/716 f 684/738/684 716/734/716 712/739/712 f 686/711/686 711/713/711 717/737/717 f 686/711/686 717/737/717 714/733/714 f 712/739/712 716/734/716 720/740/720 f 712/739/712 720/740/720 718/741/718 f 715/735/715 713/732/713 718/742/718 f 715/735/715 718/742/718 723/743/723 f 714/733/714 717/737/717 721/744/721 f 714/733/714 721/744/721 720/740/720 f 721/744/721 717/737/717 722/736/722 f 721/744/721 722/736/722 719/745/719 f 723/743/723 719/745/719 722/736/722 f 723/743/723 722/736/722 715/735/715 f 718/742/718 724/746/724 727/747/727 f 718/742/718 727/747/727 723/743/723 f 720/740/720 721/744/721 725/748/725 f 720/740/720 725/748/725 724/749/724 f 721/744/721 719/745/719 726/750/726 f 721/744/721 726/750/726 725/748/725 f 723/743/723 727/747/727 726/750/726 f 723/743/723 726/750/726 719/745/719 f 772/751/772 729/752/729 771/753/771 f 772/751/772 771/753/771 681/705/681 f 649/754/649 676/755/676 732/756/732 f 649/754/649 732/756/732 731/757/731 f 729/758/729 700/759/700 733/760/733 f 729/758/729 733/760/733 734/761/734 f 678/762/678 730/763/730 734/761/734 f 678/762/678 734/761/734 732/756/732 f 732/756/732 737/764/737 736/765/736 f 732/756/732 736/765/736 731/757/731 f 734/761/734 733/760/733 738/766/738 f 734/761/734 738/766/738 739/767/739 f 734/761/734 739/767/739 737/764/737 f 734/761/734 737/764/737 732/756/732 f 743/598/743 561/597/561 740/768/740 f 743/598/743 740/768/740 742/769/742 f 743/598/743 603/654/603 636/657/636 f 743/598/743 636/657/636 744/599/744 f 744/599/744 596/770/596 601/606/601 f 744/599/744 601/606/601 745/771/745 f 757/772/757 752/773/752 759/774/759 f 757/772/757 759/774/759 761/775/761 f 760/776/760 757/772/757 761/775/761 f 760/776/760 761/775/761 762/777/762 f 677/778/677 921/779/921 922/780/922 f 677/778/677 922/780/922 730/781/730 f 681/705/681 696/718/696 692/782/692 f 681/705/681 692/782/692 772/751/772 f 763/783/763 758/784/758 773/785/773 f 763/783/763 773/785/773 775/786/775 f 760/776/760 762/777/762 773/785/773 f 760/776/760 773/785/773 758/784/758 f 777/787/777 754/788/754 787/789/787 f 777/787/777 787/789/787 776/790/776 f 756/791/756 782/792/782 784/793/784 f 756/791/756 784/793/784 783/794/783 f 791/795/791 794/796/794 801/797/801 f 791/795/791 801/797/801 800/798/800 f 786/799/786 781/800/781 779/801/779 f 786/799/786 779/801/779 806/802/806 f 774/803/774 799/804/799 810/805/810 f 774/803/774 810/805/810 809/806/809 f 811/807/811 807/808/807 809/806/809 f 811/807/811 809/806/809 810/805/810 f 808/809/808 811/807/811 810/805/810 f 808/809/808 810/805/810 819/810/819 f 814/811/814 808/809/808 819/810/819 f 814/811/814 819/810/819 820/812/820 f 830/813/830 822/814/822 801/797/801 f 830/813/830 801/797/801 829/815/829 f 839/816/839 838/817/838 841/818/841 f 839/816/839 841/818/841 840/819/840 f 838/817/838 839/816/839 848/820/848 f 838/817/838 848/820/848 847/821/847 f 842/822/842 838/817/838 847/821/847 f 842/822/842 847/821/847 849/823/849 f 847/821/847 848/820/848 859/824/859 f 847/821/847 859/824/859 850/825/850 f 849/823/849 847/821/847 850/825/850 f 849/823/849 850/825/850 851/826/851 f 852/827/852 845/828/845 842/822/842 f 852/827/852 842/822/842 849/823/849 f 845/828/845 852/827/852 854/829/854 f 845/828/845 854/829/854 853/830/853 f 852/827/852 873/831/873 871/832/871 f 852/827/852 871/832/871 854/829/854 f 863/833/863 825/834/825 840/819/840 f 863/833/863 840/819/840 841/818/841 f 863/833/863 841/818/841 843/835/843 f 863/833/863 843/835/843 844/836/844 f 843/835/843 862/837/862 864/838/864 f 843/835/843 864/838/864 844/836/844 f 857/839/857 855/840/855 883/841/883 f 857/839/857 883/841/883 884/842/884 f 856/843/856 857/839/857 884/842/884 f 856/843/856 884/842/884 1380/844/1380 f 869/845/869 870/846/870 871/832/871 f 869/845/869 871/832/871 873/831/873 f 851/826/851 850/825/850 855/840/855 f 851/826/851 855/840/855 857/839/857 f 881/847/881 876/848/876 877/849/877 f 881/847/881 877/849/877 868/850/868 f 877/849/877 876/848/876 878/851/878 f 877/849/877 878/851/878 879/852/879 f 879/852/879 878/851/878 892/853/892 f 879/852/879 892/853/892 880/854/880 f 881/847/881 868/850/868 883/841/883 f 881/847/881 883/841/883 882/855/882 f 868/850/868 946/856/946 884/842/884 f 868/850/868 884/842/884 883/841/883 f 887/857/887 886/858/886 890/859/890 f 887/857/887 890/859/890 891/860/891 f 885/861/885 887/857/887 891/860/891 f 885/861/885 891/860/891 889/862/889 f 896/863/896 860/864/860 888/865/888 f 896/863/896 888/865/888 895/866/895 f 878/851/878 876/848/876 893/867/893 f 878/851/878 893/867/893 892/853/892 f 876/848/876 881/847/881 894/868/894 f 876/848/876 894/868/894 893/867/893 f 881/847/881 885/861/885 889/862/889 f 881/847/881 889/862/889 894/868/894 f 875/869/875 877/849/877 879/852/879 f 875/869/875 879/852/879 880/854/880 f 895/866/895 890/859/890 886/858/886 f 895/866/895 886/858/886 896/863/896 f 861/870/861 848/820/848 839/816/839 f 861/870/861 839/816/839 927/871/927 f 825/834/825 914/872/914 913/873/913 f 825/834/825 913/873/913 840/819/840 f 520/559/520 522/562/522 521/558/521 f 520/559/520 521/558/521 510/555/510 f 615/874/615 613/875/613 897/876/897 f 615/874/615 897/876/897 898/877/898 f 901/878/901 900/879/900 898/877/898 f 901/878/901 898/877/898 897/876/897 f 615/880/615 898/881/898 903/882/903 f 615/880/615 903/882/903 902/883/902 f 903/882/903 919/884/919 910/885/910 f 903/882/903 910/885/910 908/886/908 f 902/883/902 903/882/903 908/886/908 f 902/883/902 908/886/908 907/887/907 f 675/695/675 652/668/652 904/888/904 f 675/695/675 904/888/904 905/889/905 f 905/890/905 904/891/904 906/892/906 f 905/890/905 906/892/906 909/893/909 f 910/885/910 911/894/911 907/887/907 f 910/885/910 907/887/907 908/886/908 f 910/885/910 919/884/919 909/893/909 f 910/885/910 909/893/909 911/895/911 f 913/873/913 914/872/914 915/896/915 f 913/873/913 915/896/915 916/897/916 f 912/898/912 900/899/900 916/897/916 f 912/898/912 916/897/916 915/896/915 f 914/872/914 828/900/828 827/901/827 f 914/872/914 827/901/827 682/902/682 f 768/903/768 769/904/769 918/905/918 f 768/903/768 918/905/918 917/906/917 f 912/907/912 768/903/768 917/906/917 f 912/907/912 917/906/917 919/908/919 f 921/779/921 677/778/677 675/909/675 f 921/779/921 675/909/675 923/910/923 f 905/911/905 909/912/909 923/913/923 f 905/911/905 923/913/923 675/914/675 f 919/908/919 917/906/917 923/913/923 f 919/908/919 923/913/923 909/912/909 f 768/903/768 915/915/915 767/916/767 f 768/903/768 767/916/767 924/917/924 f 930/617/930 633/918/633 932/919/932 f 930/617/930 932/919/932 931/920/931 f 853/830/853 854/829/854 934/921/934 f 853/830/853 934/921/934 935/922/935 f 854/829/854 871/832/871 933/923/933 f 854/829/854 933/923/933 953/924/953 f 930/617/930 931/920/931 937/925/937 f 930/617/930 937/925/937 936/618/936 f 853/830/853 937/925/937 846/926/846 f 853/830/853 846/926/846 845/828/845 f 953/924/953 938/927/938 954/928/954 f 953/924/953 954/928/954 934/921/934 f 941/929/941 895/866/895 888/865/888 f 941/929/941 888/865/888 938/930/938 f 939/931/939 954/932/954 938/930/938 f 939/931/939 938/930/938 888/865/888 f 861/870/861 927/871/927 928/933/928 f 861/870/861 928/933/928 939/931/939 f 939/931/939 928/933/928 901/934/901 f 939/931/939 901/934/901 954/932/954 f 890/859/890 895/866/895 941/929/941 f 890/859/890 941/929/941 940/935/940 f 892/853/892 893/867/893 942/936/942 f 892/853/892 942/936/942 1151/937/1151 f 1151/938/1151 942/939/942 944/940/944 f 1151/938/1151 944/940/944 992/941/992 f 942/939/942 943/942/943 945/943/945 f 942/939/942 945/943/945 944/940/944 f 944/940/944 948/944/948 959/945/959 f 944/940/944 959/945/959 992/941/992 f 948/944/948 944/940/944 952/946/952 f 948/944/948 952/946/952 947/947/947 f 947/947/947 950/948/950 872/949/872 f 947/947/947 872/949/872 1380/844/1380 f 951/950/951 950/948/950 947/947/947 f 951/950/951 947/947/947 952/946/952 f 945/943/945 955/951/955 956/952/956 f 945/943/945 956/952/956 951/950/951 f 870/846/870 869/845/869 872/949/872 f 870/846/870 872/949/872 950/948/950 f 951/950/951 956/952/956 870/846/870 f 951/950/951 870/846/870 950/948/950 f 940/953/940 941/954/941 955/951/955 f 940/953/940 955/951/955 945/943/945 f 955/951/955 941/954/941 938/927/938 f 955/951/955 938/927/938 953/924/953 f 954/928/954 901/955/901 899/956/899 f 954/928/954 899/956/899 934/921/934 f 949/957/949 875/869/875 957/958/957 f 949/957/949 957/958/957 958/959/958 f 949/957/949 958/959/958 979/960/979 f 949/957/949 979/960/979 959/945/959 f 961/961/961 957/958/957 880/854/880 f 961/961/961 880/854/880 960/962/960 f 963/963/963 958/959/958 957/958/957 f 963/963/963 957/958/957 962/964/962 f 1152/965/1152 964/966/964 960/962/960 f 1152/965/1152 960/962/960 880/854/880 f 1077/967/1077 962/964/962 961/961/961 f 1077/967/1077 961/961/961 1078/968/1078 f 961/961/961 960/962/960 1115/969/1115 f 961/961/961 1115/969/1115 1114/970/1114 f 963/963/963 962/964/962 965/971/965 f 963/963/963 965/971/965 966/972/966 f 960/962/960 964/966/964 1154/973/1154 f 960/962/960 1154/973/1154 1153/974/1153 f 966/972/966 965/971/965 967/975/967 f 966/972/966 967/975/967 968/976/968 f 968/976/968 967/975/967 969/977/969 f 968/976/968 969/977/969 970/978/970 f 970/978/970 969/977/969 971/979/971 f 970/978/970 971/979/971 972/980/972 f 972/980/972 971/979/971 973/981/973 f 972/980/972 973/981/973 977/982/977 f 958/959/958 1042/983/1042 1041/984/1041 f 958/959/958 1041/984/1041 979/960/979 f 966/972/966 968/976/968 981/985/981 f 966/972/966 981/985/981 980/986/980 f 972/980/972 977/982/977 983/987/983 f 972/980/972 983/987/983 981/985/981 f 983/987/983 977/982/977 975/988/975 f 983/987/983 975/988/975 982/989/982 f 986/990/986 976/991/976 974/992/974 f 986/990/986 974/992/974 984/993/984 f 975/988/975 976/991/976 986/990/986 f 975/988/975 986/990/986 985/994/985 f 987/995/987 986/990/986 984/993/984 f 987/995/987 984/993/984 1036/996/1036 f 985/994/985 986/990/986 987/995/987 f 985/994/985 987/995/987 1035/997/1035 f 979/960/979 1041/984/1041 1052/998/1052 f 979/960/979 1052/998/1052 988/999/988 f 992/941/992 959/945/959 979/960/979 f 992/941/992 979/960/979 988/999/988 f 608/1000/608 611/1001/611 994/621/994 f 608/1000/608 994/621/994 993/620/993 f 995/624/995 994/621/994 611/1001/611 f 995/624/995 611/1001/611 642/1002/642 f 1000/1003/1000 816/1004/816 814/811/814 f 1000/1003/1000 814/811/814 997/1005/997 f 830/813/830 1010/1006/1010 1009/1007/1009 f 830/813/830 1009/1007/1009 822/814/822 f 837/1008/837 832/1009/832 1010/1006/1010 f 837/1008/837 1010/1006/1010 830/813/830 f 1003/1010/1003 844/836/844 865/1011/865 f 1003/1010/1003 865/1011/865 1013/1012/1013 f 1016/1013/1016 1007/1014/1007 1022/1015/1022 f 1016/1013/1016 1022/1015/1022 1015/1016/1015 f 865/1011/865 999/1017/999 1019/1018/1019 f 865/1011/865 1019/1018/1019 1023/1019/1023 f 824/1020/824 1012/1021/1012 835/1022/835 f 824/1020/824 835/1022/835 836/1023/836 f 1028/1024/1028 1025/1025/1025 973/981/973 f 1028/1024/1028 973/981/973 971/979/971 f 1025/1025/1025 1026/1026/1026 974/992/974 f 1025/1025/1025 974/992/974 973/981/973 f 1027/1027/1027 1028/1024/1028 967/975/967 f 1027/1027/1027 967/975/967 965/971/965 f 1029/1028/1029 1030/1029/1030 983/987/983 f 1029/1028/1029 983/987/983 982/989/982 f 1031/1030/1031 1032/1031/1032 1026/1026/1026 f 1031/1030/1031 1026/1026/1026 1025/1025/1025 f 1030/1032/1030 1029/1033/1029 1032/1034/1032 f 1030/1032/1030 1032/1034/1032 1031/1035/1031 f 1033/1036/1033 1034/1037/1034 1032/1034/1032 f 1033/1036/1033 1032/1034/1032 1029/1033/1029 f 1035/1038/1035 1036/1039/1036 1034/1037/1034 f 1035/1038/1035 1034/1037/1034 1033/1036/1033 f 1039/1040/1039 1037/1041/1037 1030/1032/1030 f 1039/1040/1039 1030/1032/1030 1031/1035/1031 f 1112/1042/1112 1038/1043/1038 1037/1041/1037 f 1112/1042/1112 1037/1041/1037 1039/1040/1039 f 1028/1024/1028 1039/1044/1039 1031/1030/1031 f 1028/1024/1028 1031/1030/1031 1025/1025/1025 f 1027/1027/1027 1112/1045/1112 1039/1044/1039 f 1027/1027/1027 1039/1044/1039 1028/1024/1028 f 1038/1046/1038 980/986/980 981/985/981 f 1038/1046/1038 981/985/981 1037/1047/1037 f 1041/984/1041 1042/983/1042 1043/1048/1043 f 1041/984/1041 1043/1048/1043 1044/1049/1044 f 1044/1049/1044 1043/1048/1043 1045/1050/1045 f 1044/1049/1044 1045/1050/1045 1046/1051/1046 f 1046/1051/1046 1045/1050/1045 1047/1052/1047 f 1046/1051/1046 1047/1052/1047 1048/1053/1048 f 1041/984/1041 1044/1049/1044 1053/1054/1053 f 1041/984/1041 1053/1054/1053 1052/998/1052 f 1053/1054/1053 1048/1053/1048 1051/1055/1051 f 1053/1054/1053 1051/1055/1051 1054/1056/1054 f 1055/1057/1055 1049/1058/1049 1050/1059/1050 f 1055/1057/1055 1050/1059/1050 1056/1060/1056 f 1051/1055/1051 1049/1058/1049 1055/1057/1055 f 1051/1055/1051 1055/1057/1055 1057/1061/1057 f 1058/1062/1058 1055/1057/1055 1056/1060/1056 f 1058/1062/1058 1056/1060/1056 1059/1063/1059 f 1057/1061/1057 1055/1057/1055 1058/1062/1058 f 1057/1061/1057 1058/1062/1058 1060/1064/1060 f 1061/1065/1061 1062/1066/1062 1050/1059/1050 f 1061/1065/1061 1050/1059/1050 1047/1052/1047 f 978/1067/978 1061/1065/1061 1043/1048/1043 f 978/1067/978 1043/1048/1043 1042/983/1042 f 1063/1068/1063 1070/1069/1070 1053/1054/1053 f 1063/1068/1063 1053/1054/1053 1054/1056/1054 f 1069/1070/1069 1064/1071/1064 1062/1066/1062 f 1069/1070/1069 1062/1066/1062 1061/1065/1061 f 1070/1072/1070 1063/1073/1063 1064/1074/1064 f 1070/1072/1070 1064/1074/1064 1069/1075/1069 f 1065/1076/1065 1066/1077/1066 1064/1074/1064 f 1065/1076/1065 1064/1074/1064 1063/1073/1063 f 1067/1078/1067 1068/1079/1068 1066/1077/1066 f 1067/1078/1067 1066/1077/1066 1065/1076/1065 f 1060/1080/1060 1059/1081/1059 1068/1079/1068 f 1060/1080/1060 1068/1079/1068 1067/1078/1067 f 1071/1082/1071 1187/1083/1187 1070/1072/1070 f 1071/1082/1071 1070/1072/1070 1069/1075/1069 f 1061/1065/1061 978/1067/978 1071/1084/1071 f 1061/1065/1061 1071/1084/1071 1069/1070/1069 f 1187/1085/1187 1052/998/1052 1053/1054/1053 f 1187/1085/1187 1053/1054/1053 1070/1069/1070 f 1073/1086/1073 963/963/963 966/972/966 f 1073/1086/1073 966/972/966 980/986/980 f 1076/1087/1076 1074/1088/1074 990/1089/990 f 1076/1087/1076 990/1089/990 1187/1090/1187 f 1073/1086/1073 980/986/980 1038/1046/1038 f 1073/1086/1073 1038/1046/1038 1075/1091/1075 f 1075/1092/1075 1038/1043/1038 1112/1042/1112 f 1075/1092/1075 1112/1042/1112 1076/1087/1076 f 981/985/981 983/987/983 1030/1029/1030 f 981/985/981 1030/1029/1030 1037/1047/1037 f 1077/967/1077 1078/968/1078 1079/1093/1079 f 1077/967/1077 1079/1093/1079 1080/1094/1080 f 1080/1094/1080 1079/1093/1079 1081/1095/1081 f 1080/1094/1080 1081/1095/1081 1082/1096/1082 f 1082/1096/1082 1081/1095/1081 1083/1097/1083 f 1082/1096/1082 1083/1097/1083 1084/1098/1084 f 1084/1098/1084 1083/1097/1083 1085/1099/1085 f 1084/1098/1084 1085/1099/1085 1086/1100/1086 f 1077/967/1077 1080/1094/1080 1091/1101/1091 f 1077/967/1077 1091/1101/1091 1090/1102/1090 f 1084/1098/1084 1086/1100/1086 1092/1103/1092 f 1084/1098/1084 1092/1103/1092 1091/1101/1091 f 1092/1103/1092 1086/1100/1086 1089/1104/1089 f 1092/1103/1092 1089/1104/1089 1093/1105/1093 f 1094/1106/1094 1087/1107/1087 1088/1108/1088 f 1094/1106/1094 1088/1108/1088 1095/1109/1095 f 1089/1104/1089 1087/1107/1087 1094/1106/1094 f 1089/1104/1089 1094/1106/1094 1096/1110/1096 f 1097/1111/1097 1094/1106/1094 1095/1109/1095 f 1097/1111/1097 1095/1109/1095 1098/1112/1098 f 1096/1110/1096 1094/1106/1094 1097/1111/1097 f 1096/1110/1096 1097/1111/1097 1099/1113/1099 f 1100/1114/1100 1101/1115/1101 1085/1099/1085 f 1100/1114/1100 1085/1099/1085 1083/1097/1083 f 1101/1115/1101 1102/1116/1102 1088/1108/1088 f 1101/1115/1101 1088/1108/1088 1085/1099/1085 f 1103/1117/1103 1100/1114/1100 1079/1093/1079 f 1103/1117/1103 1079/1093/1079 1078/968/1078 f 1093/1105/1093 1104/1118/1104 1105/1119/1105 f 1093/1105/1093 1105/1119/1105 1092/1103/1092 f 1106/1120/1106 1107/1121/1107 1102/1116/1102 f 1106/1120/1106 1102/1116/1102 1101/1115/1101 f 1105/1122/1105 1104/1123/1104 1107/1124/1107 f 1105/1122/1105 1107/1124/1107 1106/1125/1106 f 1108/1126/1108 1109/1127/1109 1107/1124/1107 f 1108/1126/1108 1107/1124/1107 1104/1123/1104 f 1099/1128/1099 1098/1129/1098 1109/1127/1109 f 1099/1128/1099 1109/1127/1109 1108/1126/1108 f 1110/1130/1110 1111/1131/1111 1105/1122/1105 f 1110/1130/1110 1105/1122/1105 1106/1125/1106 f 1148/1132/1148 1112/1042/1112 1111/1131/1111 f 1148/1132/1148 1111/1131/1111 1110/1130/1110 f 1100/1114/1100 1110/1133/1110 1106/1120/1106 f 1100/1114/1100 1106/1120/1106 1101/1115/1101 f 1103/1117/1103 1148/1134/1148 1110/1133/1110 f 1103/1117/1103 1110/1133/1110 1100/1114/1100 f 1112/1045/1112 1090/1102/1090 1091/1101/1091 f 1112/1045/1112 1091/1101/1091 1111/1135/1111 f 1091/1101/1091 1092/1103/1092 1105/1119/1105 f 1091/1101/1091 1105/1119/1105 1111/1135/1111 f 1077/967/1077 1090/1102/1090 1027/1027/1027 f 1077/967/1077 1027/1027/1027 965/971/965 f 1114/970/1114 1115/969/1115 1116/1136/1116 f 1114/970/1114 1116/1136/1116 1117/1137/1117 f 1117/1137/1117 1116/1136/1116 1118/1138/1118 f 1117/1137/1117 1118/1138/1118 1119/1139/1119 f 1119/1139/1119 1118/1138/1118 1120/1140/1120 f 1119/1139/1119 1120/1140/1120 1121/1141/1121 f 1121/1141/1121 1120/1140/1120 1122/1142/1122 f 1121/1141/1121 1122/1142/1122 1123/1143/1123 f 1114/970/1114 1117/1137/1117 1128/1144/1128 f 1114/970/1114 1128/1144/1128 1127/1145/1127 f 1121/1141/1121 1123/1143/1123 1129/1146/1129 f 1121/1141/1121 1129/1146/1129 1128/1144/1128 f 1129/1146/1129 1123/1143/1123 1126/1147/1126 f 1129/1146/1129 1126/1147/1126 1130/1148/1130 f 1131/1149/1131 1124/1150/1124 1125/1151/1125 f 1131/1149/1131 1125/1151/1125 1132/1152/1132 f 1126/1147/1126 1124/1150/1124 1131/1149/1131 f 1126/1147/1126 1131/1149/1131 1133/1153/1133 f 1135/1154/1135 1136/1155/1136 1122/1142/1122 f 1135/1154/1135 1122/1142/1122 1120/1140/1120 f 1136/1155/1136 1137/1156/1137 1125/1151/1125 f 1136/1155/1136 1125/1151/1125 1122/1142/1122 f 1138/1157/1138 1135/1154/1135 1116/1136/1116 f 1138/1157/1138 1116/1136/1116 1115/969/1115 f 1139/1158/1139 1140/1159/1140 1129/1146/1129 f 1139/1158/1139 1129/1146/1129 1130/1148/1130 f 1141/1160/1141 1142/1161/1142 1137/1156/1137 f 1141/1160/1141 1137/1156/1137 1136/1155/1136 f 1140/1162/1140 1139/1163/1139 1142/1164/1142 f 1140/1162/1140 1142/1164/1142 1141/1165/1141 f 1143/1166/1143 1144/1167/1144 1142/1164/1142 f 1143/1166/1143 1142/1164/1142 1139/1163/1139 f 1145/1168/1145 1146/1169/1146 1140/1162/1140 f 1145/1168/1145 1140/1162/1140 1141/1165/1141 f 1147/1170/1147 1148/1171/1148 1146/1169/1146 f 1147/1170/1147 1146/1169/1146 1145/1168/1145 f 1135/1154/1135 1145/1172/1145 1141/1160/1141 f 1135/1154/1135 1141/1160/1141 1136/1155/1136 f 1138/1157/1138 1147/1173/1147 1145/1172/1145 f 1138/1157/1138 1145/1172/1145 1135/1154/1135 f 1148/1134/1148 1127/1145/1127 1128/1144/1128 f 1148/1134/1148 1128/1144/1128 1146/1174/1146 f 1128/1144/1128 1129/1146/1129 1140/1159/1140 f 1128/1144/1128 1140/1159/1140 1146/1174/1146 f 1103/1117/1103 1078/968/1078 1114/970/1114 f 1103/1117/1103 1114/970/1114 1127/1145/1127 f 1148/1132/1148 1074/1088/1074 1076/1087/1076 f 1148/1132/1148 1076/1087/1076 1112/1042/1112 f 1150/1175/1150 1149/1176/1149 989/1177/989 f 1150/1175/1150 989/1177/989 1074/1178/1074 f 1149/1179/1149 1152/965/1152 892/853/892 f 1149/1179/1149 892/853/892 1151/937/1151 f 964/966/964 1152/965/1152 1149/1179/1149 f 964/966/964 1149/1179/1149 1150/1180/1150 f 606/659/606 638/658/638 603/1181/603 f 606/659/606 603/1181/603 936/1182/936 f 1153/974/1153 1154/973/1154 1155/1183/1155 f 1153/974/1153 1155/1183/1155 1156/1184/1156 f 1156/1184/1156 1155/1183/1155 1157/1185/1157 f 1156/1184/1156 1157/1185/1157 1158/1186/1158 f 1158/1186/1158 1157/1185/1157 1159/1187/1159 f 1158/1186/1158 1159/1187/1159 1160/1188/1160 f 1160/1188/1160 1159/1187/1159 1161/1189/1161 f 1160/1188/1160 1161/1189/1161 1162/1190/1162 f 1153/974/1153 1156/1184/1156 1167/1191/1167 f 1153/974/1153 1167/1191/1167 1166/1192/1166 f 1160/1188/1160 1162/1190/1162 1168/1193/1168 f 1160/1188/1160 1168/1193/1168 1167/1191/1167 f 1168/1193/1168 1162/1190/1162 1165/1194/1165 f 1168/1193/1168 1165/1194/1165 1169/1195/1169 f 1170/1196/1170 1163/1197/1163 1164/1198/1164 f 1170/1196/1170 1164/1198/1164 1171/1199/1171 f 1165/1194/1165 1163/1197/1163 1170/1196/1170 f 1165/1194/1165 1170/1196/1170 1172/1200/1172 f 1174/1201/1174 1175/1202/1175 1161/1189/1161 f 1174/1201/1174 1161/1189/1161 1159/1187/1159 f 1175/1202/1175 1176/1203/1176 1164/1198/1164 f 1175/1202/1175 1164/1198/1164 1161/1189/1161 f 1177/1204/1177 1174/1201/1174 1155/1183/1155 f 1177/1204/1177 1155/1183/1155 1154/973/1154 f 1178/1205/1178 1179/1206/1179 1168/1193/1168 f 1178/1205/1178 1168/1193/1168 1169/1195/1169 f 1180/1207/1180 1181/1208/1181 1176/1203/1176 f 1180/1207/1180 1176/1203/1176 1175/1202/1175 f 1179/1209/1179 1178/1210/1178 1181/1211/1181 f 1179/1209/1179 1181/1211/1181 1180/1212/1180 f 1182/1213/1182 1183/1214/1183 1181/1211/1181 f 1182/1213/1182 1181/1211/1181 1178/1210/1178 f 1184/1215/1184 1185/1216/1185 1179/1209/1179 f 1184/1215/1184 1179/1209/1179 1180/1212/1180 f 1186/1217/1186 1147/1170/1147 1185/1216/1185 f 1186/1217/1186 1185/1216/1185 1184/1215/1184 f 1174/1201/1174 1184/1218/1184 1180/1207/1180 f 1174/1201/1174 1180/1207/1180 1175/1202/1175 f 1177/1204/1177 1186/1219/1186 1184/1218/1184 f 1177/1204/1177 1184/1218/1184 1174/1201/1174 f 1147/1173/1147 1166/1192/1166 1167/1191/1167 f 1147/1173/1147 1167/1191/1167 1185/1220/1185 f 1167/1191/1167 1168/1193/1168 1179/1206/1179 f 1167/1191/1167 1179/1206/1179 1185/1220/1185 f 1138/1157/1138 1115/969/1115 1153/974/1153 f 1138/1157/1138 1153/974/1153 1166/1192/1166 f 1074/1178/1074 1148/1171/1148 1147/1170/1147 f 1074/1178/1074 1147/1170/1147 1186/1217/1186 f 1177/1204/1177 964/966/964 1150/1180/1150 f 1177/1204/1177 1150/1180/1150 1186/1219/1186 f 963/963/963 1073/1086/1073 978/1067/978 f 963/963/963 978/1067/978 1042/983/1042 f 1075/1091/1075 1071/1084/1071 978/1067/978 f 1075/1091/1075 978/1067/978 1073/1086/1073 f 807/808/807 1189/1221/1189 1197/1222/1197 f 807/808/807 1197/1222/1197 809/806/809 f 1195/1223/1195 1196/1224/1196 1190/1225/1190 f 1195/1223/1195 1190/1225/1190 1192/1226/1192 f 812/1227/812 562/1228/562 1192/1226/1192 f 812/1227/812 1192/1226/1192 1190/1225/1190 f 1194/1229/1194 1193/1230/1193 1188/1231/1188 f 1194/1229/1194 1188/1231/1188 1191/1232/1191 f 1195/1223/1195 1191/1232/1191 1188/1231/1188 f 1195/1223/1195 1188/1231/1188 1189/1221/1189 f 1196/1224/1196 1195/1223/1195 1189/1221/1189 f 1196/1224/1196 1189/1221/1189 807/808/807 f 1200/1233/1200 1331/1234/1331 783/1235/783 f 1200/1233/1200 783/1235/783 784/1236/784 f 1202/1237/1202 1203/1238/1203 1204/1239/1204 f 1202/1237/1202 1204/1239/1204 1201/1240/1201 f 1206/1241/1206 1207/1242/1207 1205/1243/1205 f 1206/1241/1206 1205/1243/1205 1201/1240/1201 f 1206/1241/1206 1208/1244/1208 1209/1245/1209 f 1206/1241/1206 1209/1245/1209 1207/1242/1207 f 1211/1246/1211 1210/1247/1210 1202/1237/1202 f 1211/1246/1211 1202/1237/1202 1205/1243/1205 f 1212/1248/1212 1211/1246/1211 1205/1243/1205 f 1212/1248/1212 1205/1243/1205 1207/1242/1207 f 1209/1245/1209 1213/1249/1213 1212/1248/1212 f 1209/1245/1209 1212/1248/1212 1207/1242/1207 f 1202/1237/1202 1210/1247/1210 786/1250/786 f 1202/1237/1202 786/1250/786 1203/1238/1203 f 784/1251/784 1223/1252/1223 1214/1253/1214 f 784/1251/784 1214/1253/1214 1200/1254/1200 f 1218/1255/1218 1219/1256/1219 1217/1257/1217 f 1218/1255/1218 1217/1257/1217 1216/1258/1216 f 1219/1256/1219 1222/1259/1222 1215/1260/1215 f 1219/1256/1219 1215/1260/1215 1217/1257/1217 f 1222/1259/1222 1221/1261/1221 1214/1253/1214 f 1222/1259/1222 1214/1253/1214 1215/1260/1215 f 1221/1261/1221 1220/1262/1220 1200/1254/1200 f 1221/1261/1221 1200/1254/1200 1214/1253/1214 f 1215/1260/1215 1223/1252/1223 1211/1263/1211 f 1215/1260/1215 1211/1263/1211 1212/1264/1212 f 1206/1241/1206 1201/1240/1201 1225/1265/1225 f 1206/1241/1206 1225/1265/1225 1226/1266/1226 f 1206/1241/1206 1226/1266/1226 1218/1255/1218 f 1206/1241/1206 1218/1255/1218 1208/1244/1208 f 1228/1267/1228 1229/1268/1229 1198/1269/1198 f 1228/1267/1228 1198/1269/1198 1193/1230/1193 f 1233/1270/1233 1250/1271/1250 1248/1272/1248 f 1233/1270/1233 1248/1272/1248 1231/1273/1231 f 1235/1274/1235 1236/1275/1236 1232/1276/1232 f 1235/1274/1235 1232/1276/1232 1252/1277/1252 f 1230/1278/1230 1237/1279/1237 1229/1280/1229 f 1230/1278/1230 1229/1280/1229 1228/1281/1228 f 1238/1282/1238 1362/1283/1362 1237/1279/1237 f 1238/1282/1238 1237/1279/1237 1230/1278/1230 f 1242/1284/1242 1241/1285/1241 1253/1286/1253 f 1242/1284/1242 1253/1286/1253 1234/1287/1234 f 1248/1272/1248 1250/1271/1250 1251/1288/1251 f 1248/1272/1248 1251/1288/1251 1232/1276/1232 f 1236/1275/1236 1249/1289/1249 1248/1272/1248 f 1236/1275/1236 1248/1272/1248 1232/1276/1232 f 1251/1288/1251 1250/1271/1250 1247/1290/1247 f 1251/1288/1251 1247/1290/1247 1234/1287/1234 f 1252/1277/1252 1251/1288/1251 1234/1287/1234 f 1252/1277/1252 1234/1287/1234 1253/1286/1253 f 1254/1291/1254 1241/1285/1241 1242/1284/1242 f 1254/1291/1254 1242/1284/1242 1239/1292/1239 f 1261/1293/1261 1254/1291/1254 1239/1292/1239 f 1261/1293/1261 1239/1292/1239 1260/1294/1260 f 1282/1295/1282 1259/1296/1259 1260/1294/1260 f 1282/1295/1282 1260/1294/1260 1239/1292/1239 f 1259/1296/1259 1265/28/1265 1255/27/1255 f 1259/1296/1259 1255/27/1255 1260/1294/1260 f 1256/29/1256 1261/1293/1261 1260/1294/1260 f 1256/29/1256 1260/1294/1260 1255/27/1255 f 1263/1297/1263 1262/33/1262 1258/32/1258 f 1263/1297/1263 1258/32/1258 1264/1298/1264 f 1258/32/1258 1265/28/1265 1259/1296/1259 f 1258/32/1258 1259/1296/1259 1264/1298/1264 f 34/34/34 1267/1299/1267 1261/1293/1261 f 34/34/34 1261/1293/1261 1256/29/1256 f 1267/1299/1267 1266/1300/1266 1254/1291/1254 f 1267/1299/1267 1254/1291/1254 1261/1293/1261 f 1269/1301/1269 1270/1302/1270 1267/1299/1267 f 1269/1301/1269 1267/1299/1267 34/34/34 f 1267/1299/1267 1270/1302/1270 1268/1303/1268 f 1267/1299/1267 1268/1303/1268 1266/1300/1266 f 1272/1304/1272 1273/1305/1273 1270/1302/1270 f 1272/1304/1272 1270/1302/1270 1269/1301/1269 f 1273/1305/1273 1271/1306/1271 1268/1303/1268 f 1273/1305/1273 1268/1303/1268 1270/1302/1270 f 43/43/43 1274/1307/1274 1272/1304/1272 f 43/43/43 1272/1304/1272 1269/1301/1269 f 1203/1308/1203 1275/1309/1275 1276/1310/1276 f 1203/1308/1203 1276/1310/1276 1204/1311/1204 f 1277/1312/1277 1304/1313/1304 1236/1275/1236 f 1277/1312/1277 1236/1275/1236 1235/1274/1235 f 1273/1305/1273 1277/1312/1277 1235/1274/1235 f 1273/1305/1273 1235/1274/1235 1271/1306/1271 f 1329/1314/1329 1277/1312/1277 1272/1304/1272 f 1329/1314/1329 1272/1304/1272 1274/1307/1274 f 1244/1315/1244 1243/1316/1243 1245/1317/1245 f 1244/1315/1244 1245/1317/1245 1246/1318/1246 f 1278/1319/1278 1244/1315/1244 1246/1318/1246 f 1278/1319/1278 1246/1318/1246 1280/53/1280 f 1283/1320/1283 1282/1295/1282 1239/1292/1239 f 1283/1320/1283 1239/1292/1239 1242/1284/1242 f 1284/1321/1284 1283/1320/1283 1242/1284/1242 f 1284/1321/1284 1242/1284/1242 1257/1322/1257 f 1287/1323/1287 1288/1324/1288 1283/1320/1283 f 1287/1323/1287 1283/1320/1283 1284/1321/1284 f 1282/1295/1282 1283/1320/1283 1288/1324/1288 f 1282/1295/1282 1288/1324/1288 1290/1325/1290 f 1244/1315/1244 1278/1319/1278 1279/1326/1279 f 1244/1315/1244 1279/1326/1279 1285/1327/1285 f 1278/1319/1278 1291/1328/1291 1263/1297/1263 f 1278/1319/1278 1263/1297/1263 1279/1326/1279 f 1325/1329/1325 1306/1330/1306 1304/1313/1304 f 1325/1329/1325 1304/1313/1304 1277/1312/1277 f 1292/1331/1292 1330/1332/1330 1204/1311/1204 f 1292/1331/1292 1204/1311/1204 1276/1310/1276 f 1295/1333/1295 1293/1334/1293 1436/1335/1436 f 1295/1333/1295 1436/1335/1436 1437/1336/1437 f 1438/1337/1438 1297/1338/1297 1295/1333/1295 f 1438/1337/1438 1295/1333/1295 1437/1336/1437 f 1298/1339/1298 1301/1340/1301 1302/1341/1302 f 1298/1339/1298 1302/1341/1302 1299/1342/1299 f 1300/1343/1300 1302/1341/1302 1301/1340/1301 f 1300/1343/1300 1301/1340/1301 1352/1344/1352 f 1295/1333/1295 1305/1345/1305 1303/1346/1303 f 1295/1333/1295 1303/1346/1303 1293/1334/1293 f 1299/1342/1299 1354/1347/1354 1305/1345/1305 f 1299/1342/1299 1305/1345/1305 1297/1338/1297 f 1300/1343/1300 1307/1348/1307 1308/1349/1308 f 1300/1343/1300 1308/1349/1308 1302/1341/1302 f 1302/1341/1302 1308/1349/1308 1354/1347/1354 f 1302/1341/1302 1354/1347/1354 1299/1342/1299 f 1310/1350/1310 1309/1351/1309 1204/1352/1204 f 1310/1350/1310 1204/1352/1204 1311/1353/1311 f 1313/1354/1313 1312/1355/1312 1309/1351/1309 f 1313/1354/1313 1309/1351/1309 1310/1350/1310 f 1315/1356/1315 1316/1357/1316 1310/1350/1310 f 1315/1356/1315 1310/1350/1310 1311/1353/1311 f 1316/1357/1316 1317/1358/1317 1313/1354/1313 f 1316/1357/1316 1313/1354/1313 1310/1350/1310 f 1326/1359/1326 1319/1360/1319 1316/1357/1316 f 1326/1359/1326 1316/1357/1316 1315/1356/1315 f 1316/1357/1316 1319/1360/1319 1322/1361/1322 f 1316/1357/1316 1322/1361/1322 1317/1358/1317 f 1326/1359/1326 1320/1362/1320 1321/1363/1321 f 1326/1359/1326 1321/1363/1321 1319/1360/1319 f 1323/1364/1323 1312/1355/1312 1313/1354/1313 f 1323/1364/1323 1313/1354/1313 1324/1365/1324 f 1317/1358/1317 1318/1366/1318 1324/1365/1324 f 1317/1358/1317 1324/1365/1324 1313/1354/1313 f 1325/1367/1325 1328/1368/1328 1315/1356/1315 f 1325/1367/1325 1315/1356/1315 1311/1353/1311 f 1332/1369/1332 1331/1234/1331 1220/1370/1220 f 1332/1369/1332 1220/1370/1220 1224/1371/1224 f 106/1372/106 1332/1369/1332 1224/1371/1224 f 106/1372/106 1224/1371/1224 1327/1373/1327 f 1333/1374/1333 1334/1375/1334 1335/1376/1335 f 1333/1374/1333 1335/1376/1335 1338/1377/1338 f 109/65/109 1334/1375/1334 1274/1307/1274 f 109/65/109 1274/1307/1274 43/43/43 f 1315/1356/1315 1328/1368/1328 1327/1378/1327 f 1315/1356/1315 1327/1378/1327 1326/1359/1326 f 1333/1374/1333 1338/1377/1338 1337/1379/1337 f 1333/1374/1333 1337/1379/1337 1336/1380/1336 f 100/1381/100 1339/1382/1339 1340/1383/1340 f 100/1381/100 1340/1383/1340 99/1384/99 f 1339/1382/1339 1341/1385/1341 1342/1386/1342 f 1339/1382/1339 1342/1386/1342 1340/1383/1340 f 1339/1382/1339 100/1381/100 106/1387/106 f 1339/1382/1339 106/1387/106 1337/1388/1337 f 101/111/101 1341/1385/1341 1335/1389/1335 f 101/111/101 1335/1389/1335 109/112/109 f 1341/1385/1341 1339/1382/1339 1337/1388/1337 f 1341/1385/1341 1337/1388/1337 1338/1390/1338 f 1344/1391/1344 1240/1392/1240 1343/1393/1343 f 1344/1391/1344 1343/1393/1343 1271/1306/1271 f 1346/1394/1346 1345/1395/1345 1198/1396/1198 f 1346/1394/1346 1198/1396/1198 1229/1397/1229 f 1197/1398/1197 1345/1399/1345 1294/1400/1294 f 1197/1398/1197 1294/1400/1294 1275/1401/1275 f 1350/1402/1350 1296/1403/1296 1347/1404/1347 f 1350/1402/1350 1347/1404/1347 1348/1405/1348 f 1346/1394/1346 1229/1397/1229 1249/1406/1249 f 1346/1394/1346 1249/1406/1249 1439/1407/1439 f 1442/1408/1442 1440/1409/1440 1348/1405/1348 f 1442/1408/1442 1348/1405/1348 1443/1410/1443 f 1301/1411/1301 1298/1412/1298 1350/1402/1350 f 1301/1411/1301 1350/1402/1350 1351/1413/1351 f 1353/1414/1353 1352/1415/1352 1301/1411/1301 f 1353/1414/1353 1301/1411/1301 1351/1413/1351 f 1351/1413/1351 1308/1349/1308 1307/1348/1307 f 1351/1413/1351 1307/1348/1307 1353/1414/1353 f 1441/1416/1441 1308/1349/1308 1351/1413/1351 f 1441/1416/1441 1351/1413/1351 1350/1402/1350 f 1440/1409/1440 1441/1416/1441 1350/1402/1350 f 1440/1409/1440 1350/1402/1350 1348/1405/1348 f 1356/1417/1356 1357/1418/1357 1194/1229/1194 f 1356/1417/1356 1194/1229/1194 1191/1232/1191 f 90/1419/90 1358/1420/1358 1194/1229/1194 f 90/1419/90 1194/1229/1194 1357/1418/1357 f 1359/1421/1359 1360/1422/1360 1362/1283/1362 f 1359/1421/1359 1362/1283/1362 1238/1282/1238 f 1362/1283/1362 1363/1423/1363 1245/1317/1245 f 1362/1283/1362 1245/1317/1245 1233/1270/1233 f 1363/1423/1363 1364/1424/1364 1246/1318/1246 f 1363/1423/1363 1246/1318/1246 1245/1317/1245 f 1364/1424/1364 74/75/74 1280/53/1280 f 1364/1424/1364 1280/53/1280 1246/1318/1246 f 1366/1425/1366 1365/1426/1365 1364/1424/1364 f 1366/1425/1366 1364/1424/1364 1363/1423/1363 f 1365/1426/1365 77/78/77 74/75/74 f 1365/1426/1365 74/75/74 1364/1424/1364 f 1366/1425/1366 1367/1427/1367 1372/1428/1372 f 1366/1425/1366 1372/1428/1372 1365/1426/1365 f 1371/1429/1371 1368/1430/1368 1369/1431/1369 f 1371/1429/1371 1369/1431/1369 1370/1432/1370 f 1373/1433/1373 1372/1428/1372 1374/1434/1374 f 1373/1433/1373 1374/1434/1374 1375/1435/1375 f 1372/1428/1372 1373/1433/1373 88/89/88 f 1372/1428/1372 88/89/88 80/88/80 f 1374/1434/1374 1367/1427/1367 1370/1432/1370 f 1374/1434/1374 1370/1432/1370 1369/1431/1369 f 1376/1436/1376 1358/1437/1358 90/1438/90 f 1376/1436/1376 90/1438/90 91/1439/91 f 1376/1436/1376 91/1439/91 93/1440/93 f 1376/1436/1376 93/1440/93 1375/1441/1375 f 1368/1442/1368 1376/1436/1376 1377/1443/1377 f 1368/1442/1368 1377/1443/1377 1369/1444/1369 f 95/1445/95 1378/1446/1378 1375/1441/1375 f 95/1445/95 1375/1441/1375 93/1440/93 f 1373/1433/1373 1378/1447/1378 96/101/96 f 1373/1433/1373 96/101/96 88/89/88 f 948/944/948 1379/1448/1379 949/957/949 f 948/944/948 949/957/949 959/945/959 f 947/947/947 1380/844/1380 1379/1448/1379 f 947/947/947 1379/1448/1379 948/944/948 f 1381/1449/1381 1382/1450/1382 1383/1451/1383 f 1381/1449/1381 1383/1451/1383 1384/1452/1384 f 1382/1450/1382 438/1453/438 439/1454/439 f 1382/1450/1382 439/1454/439 1383/1451/1383 f 1382/1450/1382 1385/1455/1385 444/1456/444 f 1382/1450/1382 444/1456/444 438/1453/438 f 1382/1450/1382 1381/1449/1381 1386/1457/1386 f 1382/1450/1382 1386/1457/1386 1385/1455/1385 f 1386/1457/1386 1387/1458/1387 1388/1459/1388 f 1386/1457/1386 1388/1459/1388 1385/1455/1385 f 1388/1459/1388 445/1460/445 444/1456/444 f 1388/1459/1388 444/1456/444 1385/1455/1385 f 439/1454/439 1389/1461/1389 1390/1462/1390 f 439/1454/439 1390/1462/1390 1383/1451/1383 f 1390/1462/1390 1391/1463/1391 1384/1452/1384 f 1390/1462/1390 1384/1452/1384 1383/1451/1383 f 1389/1461/1389 1392/1464/1392 1393/1465/1393 f 1389/1461/1389 1393/1465/1393 1390/1462/1390 f 550/1466/550 445/1460/445 1398/1467/1398 f 550/1466/550 1398/1467/1398 1397/1468/1397 f 1397/1468/1397 1401/1469/1401 1402/1470/1402 f 1397/1468/1397 1402/1470/1402 1395/1471/1395 f 1396/1472/1396 1395/1471/1395 1402/1470/1402 f 1396/1472/1396 1402/1470/1402 1404/1473/1404 f 561/1474/561 595/1475/595 1411/1476/1411 f 561/1474/561 1411/1476/1411 1412/1477/1412 f 1404/1473/1404 1417/1478/1417 1416/1479/1416 f 1404/1473/1404 1416/1479/1416 1405/1480/1405 f 1418/1481/1418 1410/1482/1410 1409/1483/1409 f 1418/1481/1418 1409/1483/1409 1417/1478/1417 f 1409/1483/1409 1394/1484/1394 1405/1480/1405 f 1409/1483/1409 1405/1480/1405 1416/1479/1416 f 1421/1485/1421 1422/1486/1422 1423/1487/1423 f 1421/1485/1421 1423/1487/1423 1424/1488/1424 f 1425/1489/1425 1426/1490/1426 1427/1491/1427 f 1425/1489/1425 1427/1491/1427 1421/1485/1421 f 1422/1486/1422 1427/1491/1427 1428/1492/1428 f 1422/1486/1422 1428/1492/1428 1423/1487/1423 f 1429/1493/1429 1415/1494/1415 1420/1495/1420 f 1429/1493/1429 1420/1495/1420 1419/1496/1419 f 1412/1477/1412 1430/1497/1430 740/1498/740 f 1412/1477/1412 740/1498/740 561/1474/561 f 1412/1477/1412 1411/1476/1411 1415/1494/1415 f 1412/1477/1412 1415/1494/1415 1429/1493/1429 f 1411/1476/1411 745/1499/745 1410/1482/1410 f 1411/1476/1411 1410/1482/1410 1413/1500/1413 f 1434/1501/1434 111/1502/111 108/67/108 f 1434/1501/1434 108/67/108 65/66/65 f 1434/1501/1434 1435/1503/1435 107/1504/107 f 1434/1501/1434 107/1504/107 111/1502/111 f 1437/1336/1437 1436/1335/1436 1294/1400/1294 f 1437/1336/1437 1294/1400/1294 1347/1505/1347 f 1296/1506/1296 1438/1337/1438 1437/1336/1437 f 1296/1506/1296 1437/1336/1437 1347/1505/1347 f 1303/1346/1303 1439/1407/1439 1249/1406/1249 f 1303/1346/1303 1249/1406/1249 1304/1507/1304 f 1354/1347/1354 1441/1416/1441 1440/1409/1440 f 1354/1347/1354 1440/1409/1440 1305/1345/1305 f 1447/1508/1447 1449/1509/1449 1450/1510/1450 f 1447/1508/1447 1450/1510/1450 1448/1511/1448 f 1529/1512/1529 1531/1513/1531 1450/1510/1450 f 1529/1512/1529 1450/1510/1450 1461/1514/1461 f 1452/1515/1452 1453/1516/1453 1449/1509/1449 f 1452/1515/1452 1449/1509/1449 1447/1508/1447 f 1481/1517/1481 1509/1518/1509 1453/1516/1453 f 1481/1517/1481 1453/1516/1453 1452/1515/1452 f 1448/1511/1448 1464/1519/1464 1463/1520/1463 f 1448/1511/1448 1463/1520/1463 1462/1521/1462 f 1462/1521/1462 1465/1522/1465 1467/1523/1467 f 1462/1521/1462 1467/1523/1467 1455/1524/1455 f 1474/1525/1474 1475/1526/1475 1472/1527/1472 f 1474/1525/1474 1472/1527/1472 1473/1528/1473 f 1455/1524/1455 1467/1523/1467 1476/1529/1476 f 1455/1524/1455 1476/1529/1476 1479/1530/1479 f 1478/1531/1478 1480/1532/1480 1479/1530/1479 f 1478/1531/1478 1479/1530/1479 1476/1529/1476 f 1474/1525/1474 1471/1533/1471 1492/1534/1492 f 1474/1525/1474 1492/1534/1492 1470/1535/1470 f 1466/1536/1466 1484/1537/1484 1485/1538/1485 f 1466/1536/1466 1485/1538/1485 1469/1539/1469 f 1469/1539/1469 1485/1538/1485 1486/1540/1486 f 1469/1539/1469 1486/1540/1486 1492/1534/1492 f 1487/1541/1487 1490/1542/1490 1494/1543/1494 f 1487/1541/1487 1494/1543/1494 1488/1544/1488 f 1492/1534/1492 1494/1543/1494 1495/1545/1495 f 1492/1534/1492 1495/1545/1495 1493/1546/1493 f 1478/1531/1478 1513/1547/1513 1497/1548/1497 f 1478/1531/1478 1497/1548/1497 1480/1532/1480 f 1488/1544/1488 1494/1543/1494 1492/1534/1492 f 1488/1544/1488 1492/1534/1492 1486/1540/1486 f 1502/1549/1502 1504/1550/1504 1503/1551/1503 f 1502/1549/1502 1503/1551/1503 1496/1552/1496 f 1506/1553/1506 1508/1554/1508 1526/1555/1526 f 1506/1553/1506 1526/1555/1526 1525/1556/1525 f 1524/1557/1524 1523/1558/1523 1509/1518/1509 f 1524/1557/1524 1509/1518/1509 1483/1559/1483 f 1451/1560/1451 1450/1510/1450 1458/1561/1458 f 1451/1560/1451 1458/1561/1458 1514/1562/1514 f 1460/1563/1460 1518/1564/1518 1519/1565/1519 f 1460/1563/1460 1519/1565/1519 1514/1562/1514 f 1514/1562/1514 1519/1565/1519 1517/1566/1517 f 1514/1562/1514 1517/1566/1517 1451/1560/1451 f 1516/1567/1516 1520/1568/1520 1529/1512/1529 f 1516/1567/1516 1529/1512/1529 1461/1514/1461 f 1521/1569/1521 1507/1570/1507 1522/1571/1522 f 1521/1569/1521 1522/1571/1522 1536/1572/1536 f 1507/1570/1507 1521/1569/1521 1525/1556/1525 f 1507/1570/1507 1525/1556/1525 1526/1555/1526 f 1464/1519/1464 1531/1513/1531 1532/1573/1532 f 1464/1519/1464 1532/1573/1532 1542/1574/1542 f 1534/1575/1534 1533/1576/1533 1481/1517/1481 f 1534/1575/1534 1481/1517/1481 1482/1577/1482 f 1535/1578/1535 1534/1575/1534 1480/1532/1480 f 1535/1578/1535 1480/1532/1480 1497/1548/1497 f 1535/1579/1535 1497/1580/1497 1510/1581/1510 f 1535/1579/1535 1510/1581/1510 1559/1582/1559 f 1521/1569/1521 1538/1583/1538 1393/1584/1393 f 1521/1569/1521 1393/1584/1393 1525/1556/1525 f 1539/1585/1539 1568/1586/1568 1569/1587/1569 f 1539/1585/1539 1569/1587/1569 1544/1588/1544 f 1540/1589/1540 1538/1583/1538 1539/1585/1539 f 1540/1589/1540 1539/1585/1539 1541/1590/1541 f 1541/1591/1541 1464/1519/1464 1542/1574/1542 f 1541/1591/1541 1542/1574/1542 1540/1592/1540 f 1539/1585/1539 1544/1588/1544 1543/1593/1543 f 1539/1585/1539 1543/1593/1543 1541/1590/1541 f 1670/1594/1670 1669/1595/1669 1567/1596/1567 f 1670/1594/1670 1567/1596/1567 1553/1597/1553 f 1547/1598/1547 1671/1599/1671 1668/1600/1668 f 1547/1598/1547 1668/1600/1668 1546/1601/1546 f 1548/1602/1548 1550/1603/1550 1551/1604/1551 f 1548/1602/1548 1551/1604/1551 1549/1605/1549 f 1558/1606/1558 1554/1607/1554 1548/1602/1548 f 1558/1606/1558 1548/1602/1548 1545/1608/1545 f 1548/1602/1548 1554/1607/1554 1556/1609/1556 f 1548/1602/1548 1556/1609/1556 1550/1603/1550 f 1550/1603/1550 1556/1609/1556 1589/1610/1589 f 1550/1603/1550 1589/1610/1589 1591/1611/1591 f 1559/1582/1559 1557/1612/1557 1558/1606/1558 f 1559/1582/1559 1558/1606/1558 1555/1613/1555 f 1572/1614/1572 1557/1612/1557 1559/1582/1559 f 1572/1614/1572 1559/1582/1559 1560/1615/1560 f 1565/1616/1565 1672/1617/1672 1671/1599/1671 f 1565/1616/1565 1671/1599/1671 1547/1598/1547 f 1564/1618/1564 1563/1619/1563 1672/1617/1672 f 1564/1618/1564 1672/1617/1672 1565/1616/1565 f 1566/1620/1566 1574/1621/1574 1565/1616/1565 f 1566/1620/1566 1565/1616/1565 1547/1598/1547 f 1546/1601/1546 1549/1605/1549 1566/1620/1566 f 1546/1601/1546 1566/1620/1566 1547/1598/1547 f 1537/1622/1537 1536/1572/1536 1522/1571/1522 f 1537/1622/1537 1522/1571/1522 1567/1623/1567 f 1537/1624/1537 1567/1596/1567 1669/1595/1669 f 1537/1624/1537 1669/1595/1669 1668/1600/1668 f 1537/1622/1537 1569/1587/1569 1568/1586/1568 f 1537/1622/1537 1568/1586/1568 1536/1572/1536 f 1566/1620/1566 1570/1625/1570 1571/1626/1571 f 1566/1620/1566 1571/1626/1571 1574/1621/1574 f 1570/1625/1570 1581/1627/1581 1579/1628/1579 f 1570/1625/1570 1579/1628/1579 1571/1626/1571 f 1549/1605/1549 1551/1604/1551 1570/1625/1570 f 1549/1605/1549 1570/1625/1570 1566/1620/1566 f 1561/1629/1561 1573/1630/1573 1572/1614/1572 f 1561/1629/1561 1572/1614/1572 1560/1615/1560 f 1576/1631/1576 1578/1632/1578 1573/1630/1573 f 1576/1631/1576 1573/1630/1573 1561/1629/1561 f 1391/1633/1391 1393/1584/1393 1538/1583/1538 f 1391/1633/1391 1538/1583/1538 1540/1589/1540 f 1381/1634/1381 1384/1635/1384 1528/1636/1528 f 1381/1634/1381 1528/1636/1528 1516/1567/1516 f 1542/1574/1542 1528/1636/1528 1384/1635/1384 f 1542/1574/1542 1384/1635/1384 1391/1637/1391 f 1562/1638/1562 1563/1639/1563 1564/1640/1564 f 1562/1638/1562 1564/1640/1564 1576/1631/1576 f 1577/1641/1577 1578/1632/1578 1574/1642/1574 f 1577/1641/1577 1574/1642/1574 1571/1643/1571 f 1580/1644/1580 1590/1645/1590 1592/1646/1592 f 1580/1644/1580 1592/1646/1592 1584/1647/1584 f 1585/1648/1585 1573/1630/1573 1578/1632/1578 f 1585/1648/1585 1578/1632/1578 1577/1641/1577 f 1572/1614/1572 1573/1630/1573 1585/1648/1585 f 1572/1614/1572 1585/1648/1585 1586/1649/1586 f 1586/1649/1586 1554/1607/1554 1557/1612/1557 f 1586/1649/1586 1557/1612/1557 1572/1614/1572 f 1592/1646/1592 1590/1645/1590 1581/1627/1581 f 1592/1646/1592 1581/1627/1581 1593/1650/1593 f 1588/1651/1588 1592/1646/1592 1593/1650/1593 f 1588/1651/1588 1593/1650/1593 1591/1611/1591 f 1582/1652/1582 1584/1647/1584 1592/1646/1592 f 1582/1652/1582 1592/1646/1592 1588/1651/1588 f 1595/1653/1595 1597/1654/1597 1596/1655/1596 f 1595/1653/1595 1596/1655/1596 1594/1656/1594 f 1604/1657/1604 1605/1658/1605 1602/1659/1602 f 1604/1657/1604 1602/1659/1602 1614/1660/1614 f 1605/1658/1605 1606/1661/1606 1594/1656/1594 f 1605/1658/1605 1594/1656/1594 1596/1655/1596 f 1601/1662/1601 1608/1663/1608 1607/1664/1607 f 1601/1662/1601 1607/1664/1607 1615/1665/1615 f 1599/1666/1599 1615/1665/1615 1614/1660/1614 f 1599/1666/1599 1614/1660/1614 1602/1659/1602 f 1609/1667/1609 1612/1668/1612 1613/1669/1613 f 1609/1667/1609 1613/1669/1613 1610/1670/1610 f 1610/1670/1610 1613/1669/1613 1629/1671/1629 f 1610/1670/1610 1629/1671/1629 1604/1657/1604 f 1604/1657/1604 1629/1671/1629 1606/1661/1606 f 1604/1657/1604 1606/1661/1606 1605/1658/1605 f 1600/1672/1600 1617/1673/1617 1626/1674/1626 f 1600/1672/1600 1626/1674/1626 1733/1675/1733 f 1617/1673/1617 1618/1676/1618 1619/1677/1619 f 1617/1673/1617 1619/1677/1619 1626/1674/1626 f 1618/1676/1618 1620/1678/1620 1621/1679/1621 f 1618/1676/1618 1621/1679/1621 1619/1677/1619 f 1623/1680/1623 1624/1681/1624 1621/1679/1621 f 1623/1680/1623 1621/1679/1621 1620/1678/1620 f 1586/1682/1586 1623/1680/1623 1620/1678/1620 f 1586/1682/1586 1620/1678/1620 1587/1683/1587 f 1594/1656/1594 1629/1671/1629 1628/1684/1628 f 1594/1656/1594 1628/1684/1628 1585/1685/1585 f 1623/1680/1623 1585/1685/1585 1628/1684/1628 f 1623/1680/1623 1628/1684/1628 1624/1681/1624 f 1627/1686/1627 1626/1674/1626 1619/1677/1619 f 1627/1686/1627 1619/1677/1619 1718/1687/1718 f 1617/1673/1617 1600/1672/1600 1584/1647/1584 f 1617/1673/1617 1584/1647/1584 1582/1652/1582 f 1618/1676/1618 1583/1688/1583 1587/1683/1587 f 1618/1676/1618 1587/1683/1587 1620/1678/1620 f 1582/1652/1582 1583/1688/1583 1618/1676/1618 f 1582/1652/1582 1618/1676/1618 1617/1673/1617 f 1597/1689/1597 1580/1644/1580 1584/1647/1584 f 1597/1689/1597 1584/1647/1584 1598/1690/1598 f 1624/1681/1624 1628/1684/1628 1630/1691/1630 f 1624/1681/1624 1630/1691/1630 1622/1692/1622 f 1630/1691/1630 1632/1693/1632 1631/1694/1631 f 1630/1691/1630 1631/1694/1631 1622/1692/1622 f 1632/1695/1632 1634/1696/1634 1633/1697/1633 f 1632/1695/1632 1633/1697/1633 1631/1698/1631 f 1634/1696/1634 1636/1699/1636 1635/1700/1635 f 1634/1696/1634 1635/1700/1635 1633/1697/1633 f 1636/1699/1636 1638/1701/1638 1637/1702/1637 f 1636/1699/1636 1637/1702/1637 1635/1700/1635 f 1637/1702/1637 1638/1701/1638 1646/1703/1646 f 1637/1702/1637 1646/1703/1646 1639/1704/1639 f 1641/1705/1641 1665/1706/1665 1647/1707/1647 f 1641/1705/1641 1647/1707/1647 1645/1708/1645 f 1647/1707/1647 1665/1706/1665 1643/1709/1643 f 1647/1707/1647 1643/1709/1643 1648/1710/1648 f 1640/1711/1640 1645/1708/1645 1647/1707/1647 f 1640/1711/1640 1647/1707/1647 1667/1712/1667 f 1667/1712/1667 1647/1707/1647 1648/1710/1648 f 1667/1712/1667 1648/1710/1648 1642/1713/1642 f 1654/1714/1654 1637/1702/1637 1639/1704/1639 f 1654/1714/1654 1639/1704/1639 1658/1715/1658 f 1636/1699/1636 1634/1696/1634 1655/1716/1655 f 1636/1699/1636 1655/1716/1655 1650/1717/1650 f 1630/1691/1630 1652/1718/1652 1651/1719/1651 f 1630/1691/1630 1651/1719/1651 1632/1693/1632 f 1634/1696/1634 1632/1695/1632 1651/1720/1651 f 1634/1696/1634 1651/1720/1651 1655/1716/1655 f 1631/1694/1631 1653/1721/1653 1675/1722/1675 f 1631/1694/1631 1675/1722/1675 1622/1692/1622 f 1633/1697/1633 1654/1714/1654 1653/1723/1653 f 1633/1697/1633 1653/1723/1653 1631/1698/1631 f 1650/1717/1650 1680/1724/1680 1656/1725/1656 f 1650/1717/1650 1656/1725/1656 1646/1703/1646 f 1656/1725/1656 1657/1726/1657 1649/1727/1649 f 1656/1725/1656 1649/1727/1649 1646/1703/1646 f 1651/1720/1651 1763/1728/1763 1680/1724/1680 f 1651/1720/1651 1680/1724/1680 1655/1716/1655 f 1663/1729/1663 1664/1730/1664 1658/1715/1658 f 1663/1729/1663 1658/1715/1658 1639/1704/1639 f 1664/1730/1664 1660/1731/1660 1659/1732/1659 f 1664/1730/1664 1659/1732/1659 1658/1715/1658 f 1656/1725/1656 1659/1733/1659 1660/1734/1660 f 1656/1725/1656 1660/1734/1660 1657/1726/1657 f 1657/1726/1657 1662/1735/1662 1661/1736/1661 f 1657/1726/1657 1661/1736/1661 1649/1727/1649 f 1662/1737/1662 1664/1730/1664 1663/1729/1663 f 1662/1737/1662 1663/1729/1663 1661/1738/1661 f 1661/1736/1661 1666/1739/1666 1665/1706/1665 f 1661/1736/1661 1665/1706/1665 1676/1740/1676 f 1667/1712/1667 1666/1741/1666 1661/1738/1661 f 1667/1712/1667 1661/1738/1661 1677/1742/1677 f 1643/1709/1643 1665/1706/1665 1666/1739/1666 f 1643/1709/1643 1666/1739/1666 1644/1743/1644 f 1666/1741/1666 1667/1712/1667 1642/1713/1642 f 1666/1741/1666 1642/1713/1642 1644/1743/1644 f 1668/1600/1668 1669/1595/1669 1552/1744/1552 f 1668/1600/1668 1552/1744/1552 1546/1601/1546 f 1669/1595/1669 1670/1594/1670 1545/1608/1545 f 1669/1595/1669 1545/1608/1545 1552/1744/1552 f 1537/1624/1537 1668/1600/1668 1671/1599/1671 f 1537/1624/1537 1671/1599/1671 1569/1745/1569 f 1569/1745/1569 1671/1599/1671 1672/1617/1672 f 1569/1745/1569 1672/1617/1672 1544/1746/1544 f 1673/1747/1673 1718/1687/1718 1619/1677/1619 f 1673/1747/1673 1619/1677/1619 1621/1679/1621 f 1659/1732/1659 1679/1748/1679 1678/1749/1678 f 1659/1732/1659 1678/1749/1678 1658/1715/1658 f 1656/1725/1656 1680/1724/1680 1679/1750/1679 f 1656/1725/1656 1679/1750/1679 1659/1733/1659 f 1679/1748/1679 1683/1751/1683 1682/1752/1682 f 1679/1748/1679 1682/1752/1682 1678/1749/1678 f 1680/1724/1680 1681/1753/1681 1683/1754/1683 f 1680/1724/1680 1683/1754/1683 1679/1750/1679 f 1678/1749/1678 1682/1752/1682 1653/1723/1653 f 1678/1749/1678 1653/1723/1653 1654/1714/1654 f 1685/1755/1685 1684/1756/1684 1674/1757/1674 f 1685/1755/1685 1674/1757/1674 1675/1758/1675 f 1685/1755/1685 1687/1759/1687 1686/1760/1686 f 1685/1755/1685 1686/1760/1686 1684/1756/1684 f 1687/1759/1687 1689/1761/1689 1688/1762/1688 f 1687/1759/1687 1688/1762/1688 1686/1760/1686 f 1688/1762/1688 1689/1761/1689 1691/1763/1691 f 1688/1762/1688 1691/1763/1691 1690/1764/1690 f 1693/1765/1693 1695/1766/1695 1694/1767/1694 f 1693/1765/1693 1694/1767/1694 1692/1768/1692 f 1696/1769/1696 1692/1768/1692 1694/1767/1694 f 1696/1769/1696 1694/1767/1694 1697/1770/1697 f 1699/1771/1699 1688/1762/1688 1690/1764/1690 f 1699/1771/1699 1690/1764/1690 1700/1772/1700 f 1693/1765/1693 1691/1763/1691 1705/1773/1705 f 1693/1765/1693 1705/1773/1705 1702/1774/1702 f 1687/1759/1687 1685/1755/1685 1704/1775/1704 f 1687/1759/1687 1704/1775/1704 1703/1776/1703 f 1703/1776/1703 1714/1777/1714 1705/1773/1705 f 1703/1776/1703 1705/1773/1705 1691/1763/1691 f 1701/1778/1701 1706/1779/1706 1707/1780/1707 f 1701/1778/1701 1707/1780/1707 1700/1772/1700 f 1705/1773/1705 1707/1781/1707 1706/1782/1706 f 1705/1773/1705 1706/1782/1706 1702/1774/1702 f 1708/1783/1708 1712/1784/1712 1695/1766/1695 f 1708/1783/1708 1695/1766/1695 1710/1785/1710 f 1697/1770/1697 1712/1786/1712 1708/1787/1708 f 1697/1770/1697 1708/1787/1708 1711/1788/1711 f 1707/1780/1707 1713/1789/1713 1699/1771/1699 f 1707/1780/1707 1699/1771/1699 1700/1772/1700 f 1705/1773/1705 1714/1777/1714 1713/1790/1713 f 1705/1773/1705 1713/1790/1713 1707/1781/1707 f 1625/1791/1625 1716/1792/1716 1717/1793/1717 f 1625/1791/1625 1717/1793/1717 1673/1747/1673 f 1684/1756/1684 1699/1771/1699 1716/1794/1716 f 1684/1756/1684 1716/1794/1716 1674/1757/1674 f 1627/1686/1627 1719/1795/1719 1733/1675/1733 f 1627/1686/1627 1733/1675/1733 1626/1674/1626 f 1718/1687/1718 1720/1796/1720 1719/1795/1719 f 1718/1687/1718 1719/1795/1719 1627/1686/1627 f 1683/1797/1683 1721/1798/1721 1726/1799/1726 f 1683/1797/1683 1726/1799/1726 1682/1800/1682 f 1681/1801/1681 1765/1802/1765 1721/1798/1721 f 1681/1801/1681 1721/1798/1721 1683/1797/1683 f 1721/1798/1721 1723/1803/1723 1725/1804/1725 f 1721/1798/1721 1725/1804/1725 1726/1799/1726 f 1765/1802/1765 1722/1805/1722 1723/1803/1723 f 1765/1802/1765 1723/1803/1723 1721/1798/1721 f 1723/1803/1723 1724/1806/1724 1717/1793/1717 f 1723/1803/1723 1717/1793/1717 1725/1804/1725 f 1722/1805/1722 1727/1807/1727 1724/1806/1724 f 1722/1805/1722 1724/1806/1724 1723/1803/1723 f 1690/1764/1690 1696/1769/1696 1701/1778/1701 f 1690/1764/1690 1701/1778/1701 1700/1772/1700 f 1725/1808/1725 1699/1771/1699 1713/1789/1713 f 1725/1808/1725 1713/1789/1713 1726/1809/1726 f 1628/1684/1628 1629/1671/1629 1728/1810/1728 f 1628/1684/1628 1728/1810/1728 1652/1718/1652 f 1612/1668/1612 1727/1811/1727 1729/1812/1729 f 1612/1668/1612 1729/1812/1729 1613/1669/1613 f 1764/1813/1764 1730/1814/1730 1731/1815/1731 f 1764/1813/1764 1731/1815/1731 1722/1816/1722 f 1727/1811/1727 1722/1816/1722 1731/1815/1731 f 1727/1811/1727 1731/1815/1731 1729/1812/1729 f 1629/1671/1629 1613/1669/1613 1729/1812/1729 f 1629/1671/1629 1729/1812/1729 1728/1810/1728 f 1652/1718/1652 1728/1810/1728 1732/1817/1732 f 1652/1718/1652 1732/1817/1732 1734/1818/1734 f 1726/1819/1726 1713/1790/1713 1714/1777/1714 f 1726/1819/1726 1714/1777/1714 1715/1820/1715 f 1611/1821/1611 1720/1822/1720 1727/1811/1727 f 1611/1821/1611 1727/1811/1727 1612/1668/1612 f 1611/1821/1611 1608/1663/1608 1719/1823/1719 f 1611/1821/1611 1719/1823/1719 1720/1822/1720 f 1733/1824/1733 1719/1823/1719 1608/1663/1608 f 1733/1824/1733 1608/1663/1608 1601/1662/1601 f 1734/1825/1734 1732/1826/1732 1736/1827/1736 f 1734/1825/1734 1736/1827/1736 1735/1828/1735 f 1735/1828/1735 1736/1827/1736 1737/1829/1737 f 1735/1828/1735 1737/1829/1737 1738/1830/1738 f 1737/1829/1737 1739/1831/1739 1740/1832/1740 f 1737/1829/1737 1740/1832/1740 1738/1830/1738 f 1743/1833/1743 1744/1834/1744 1742/1835/1742 f 1743/1833/1743 1742/1835/1742 1741/1836/1741 f 1746/1837/1746 1747/1838/1747 1743/1833/1743 f 1746/1837/1746 1743/1833/1743 1741/1836/1741 f 1748/1839/1748 1749/1840/1749 1739/1831/1739 f 1748/1839/1748 1739/1831/1739 1737/1829/1737 f 1742/1835/1742 1750/1841/1750 1751/1842/1751 f 1742/1835/1742 1751/1842/1751 1740/1832/1740 f 1752/1843/1752 1740/1832/1740 1751/1842/1751 f 1752/1843/1752 1751/1842/1751 1753/1844/1753 f 1755/1845/1755 1749/1840/1749 1756/1846/1756 f 1755/1845/1755 1756/1846/1756 1754/1847/1754 f 1751/1842/1751 1750/1841/1750 1754/1848/1754 f 1751/1842/1751 1754/1848/1754 1756/1849/1756 f 1757/1850/1757 1759/1851/1759 1744/1834/1744 f 1757/1850/1757 1744/1834/1744 1761/1852/1761 f 1747/1838/1747 1760/1853/1760 1757/1854/1757 f 1747/1838/1747 1757/1854/1757 1761/1855/1761 f 1756/1846/1756 1749/1840/1749 1748/1839/1748 f 1756/1846/1756 1748/1839/1748 1762/1856/1762 f 1751/1842/1751 1756/1849/1756 1762/1857/1762 f 1751/1842/1751 1762/1857/1762 1753/1844/1753 f 1739/1831/1739 1749/1840/1749 1755/1845/1755 f 1739/1831/1739 1755/1845/1755 1746/1837/1746 f 1762/1856/1762 1748/1839/1748 1764/1858/1764 f 1762/1856/1762 1764/1858/1764 1766/1859/1766 f 1766/1860/1766 1763/1861/1763 1753/1844/1753 f 1766/1860/1766 1753/1844/1753 1762/1857/1762 f 1519/1565/1519 1767/1862/1767 1386/1863/1386 f 1519/1565/1519 1386/1863/1386 1381/1634/1381 f 1386/1863/1386 1768/1864/1768 1769/1865/1769 f 1386/1863/1386 1769/1865/1769 1387/1866/1387 f 1768/1864/1768 1456/1867/1456 1457/1868/1457 f 1768/1864/1768 1457/1868/1457 1769/1865/1769 f 1392/1869/1392 452/1870/452 1506/1871/1506 f 1392/1869/1392 1506/1871/1506 1393/1872/1393 f 452/1870/452 453/1873/453 1794/1874/1794 f 452/1870/452 1794/1874/1794 1506/1871/1506 f 453/1873/453 455/1875/455 1773/1876/1773 f 453/1873/453 1773/1876/1773 1794/1874/1794 f 455/1875/455 457/1877/457 1774/1878/1774 f 455/1875/455 1774/1878/1774 1773/1876/1773 f 457/1877/457 459/1879/459 1775/1880/1775 f 457/1877/457 1775/1880/1775 1774/1878/1774 f 459/1879/459 461/1881/461 1776/1882/1776 f 459/1879/459 1776/1882/1776 1775/1880/1775 f 461/1881/461 463/1883/463 1777/1884/1777 f 461/1881/461 1777/1884/1777 1776/1882/1776 f 463/1883/463 465/1885/465 1778/1886/1778 f 463/1883/463 1778/1886/1778 1777/1884/1777 f 465/1885/465 467/1887/467 1779/1888/1779 f 465/1885/465 1779/1888/1779 1778/1886/1778 f 1775/1880/1775 1829/1889/1829 1780/1890/1780 f 1775/1880/1775 1780/1890/1780 1774/1878/1774 f 1776/1882/1776 1782/1891/1782 1781/1892/1781 f 1776/1882/1776 1781/1892/1781 1775/1880/1775 f 1777/1884/1777 1783/1893/1783 1782/1891/1782 f 1777/1884/1777 1782/1891/1782 1776/1882/1776 f 1778/1886/1778 1784/1894/1784 1783/1893/1783 f 1778/1886/1778 1783/1893/1783 1777/1884/1777 f 1779/1888/1779 473/1895/473 1784/1894/1784 f 1779/1888/1779 1784/1894/1784 1778/1886/1778 f 1780/1890/1780 1785/1896/1785 1773/1876/1773 f 1780/1890/1780 1773/1876/1773 1774/1878/1774 f 1780/1890/1780 1806/1897/1806 1786/1898/1786 f 1780/1890/1780 1786/1898/1786 1785/1896/1785 f 1786/1898/1786 1788/1899/1788 1787/1900/1787 f 1786/1898/1786 1787/1900/1787 1785/1896/1785 f 1787/1900/1787 1791/1901/1791 1790/1902/1790 f 1787/1900/1787 1790/1902/1790 1785/1896/1785 f 1793/1903/1793 1795/1904/1795 1794/1874/1794 f 1793/1903/1793 1794/1874/1794 1790/1902/1790 f 1793/1903/1793 1826/1905/1826 1797/1906/1797 f 1793/1903/1793 1797/1906/1797 1795/1904/1795 f 1798/1907/1798 1800/1908/1800 1801/1909/1801 f 1798/1907/1798 1801/1909/1801 1799/1910/1799 f 1798/1907/1798 1802/1911/1802 1803/1912/1803 f 1798/1907/1798 1803/1912/1803 1800/1908/1800 f 1803/1912/1803 494/1913/494 493/1914/493 f 1803/1912/1803 493/1914/493 1800/1908/1800 f 1799/1910/1799 1804/1915/1804 495/1916/495 f 1799/1910/1799 495/1916/495 1806/1897/1806 f 1801/1909/1801 1805/1917/1805 1804/1915/1804 f 1801/1909/1801 1804/1915/1804 1799/1910/1799 f 1506/1871/1506 1794/1874/1794 1795/1904/1795 f 1506/1871/1506 1795/1904/1795 1508/1918/1508 f 1790/1902/1790 1794/1874/1794 1773/1876/1773 f 1790/1902/1790 1773/1876/1773 1785/1896/1785 f 1800/1908/1800 493/1914/493 1805/1917/1805 f 1800/1908/1800 1805/1917/1805 1801/1909/1801 f 1807/1919/1807 1811/1920/1811 1813/1921/1813 f 1807/1919/1807 1813/1921/1813 1786/1898/1786 f 1815/1922/1815 1817/1923/1817 1816/1924/1816 f 1815/1922/1815 1816/1924/1816 1810/1925/1810 f 1792/1926/1792 1810/1925/1810 1816/1924/1816 f 1792/1926/1792 1816/1924/1816 1826/1905/1826 f 1811/1920/1811 1809/1927/1809 1833/1928/1833 f 1811/1920/1811 1833/1928/1833 1821/1929/1821 f 1819/1930/1819 1811/1920/1811 1821/1929/1821 f 1819/1930/1819 1821/1929/1821 1818/1931/1818 f 1822/1932/1822 1508/1918/1508 1795/1904/1795 f 1822/1932/1822 1795/1904/1795 1797/1906/1797 f 513/1933/513 521/1934/521 1818/1931/1818 f 513/1933/513 1818/1931/1818 1821/1929/1821 f 1827/1935/1827 522/1936/522 546/1937/546 f 1827/1935/1827 546/1937/546 1838/1938/1838 f 1782/1891/1782 524/1939/524 523/1940/523 f 1782/1891/1782 523/1940/523 1781/1892/1781 f 1783/1893/1783 525/1941/525 524/1939/524 f 1783/1893/1783 524/1939/524 1782/1891/1782 f 1784/1894/1784 526/1942/526 525/1941/525 f 1784/1894/1784 525/1941/525 1783/1893/1783 f 1831/1943/1831 1832/1944/1832 1803/1912/1803 f 1831/1943/1831 1803/1912/1803 1802/1911/1802 f 1837/1945/1837 1835/1946/1835 1834/1947/1834 f 1837/1945/1837 1834/1947/1834 1822/1932/1822 f 1835/1946/1835 1837/1945/1837 1839/1948/1839 f 1835/1946/1835 1839/1948/1839 1836/1949/1836 f 1838/1938/1838 546/1937/546 547/1950/547 f 1838/1938/1838 547/1950/547 1841/1951/1841 f 1772/1952/1772 1523/1558/1523 1524/1557/1524 f 1772/1952/1772 1524/1557/1524 1847/1953/1847 f 1847/1953/1847 1850/1954/1850 1852/1955/1852 f 1847/1953/1847 1852/1955/1852 1851/1956/1851 f 1848/1957/1848 1856/1958/1856 1865/1959/1865 f 1848/1957/1848 1865/1959/1865 1857/1960/1857 f 1770/1961/1770 1869/1962/1869 1870/1963/1870 f 1770/1961/1770 1870/1963/1870 1843/1964/1843 f 1402/1965/1402 1871/1966/1871 1872/1967/1872 f 1402/1965/1402 1872/1967/1872 1404/1968/1404 f 1871/1966/1871 1402/1965/1402 1870/1969/1870 f 1871/1966/1871 1870/1969/1870 1869/1970/1869 f 1872/1967/1872 1418/1971/1418 1417/1972/1417 f 1872/1967/1872 1417/1972/1417 1404/1968/1404 f 1426/1973/1426 1429/1974/1429 2164/1975/2164 f 1426/1973/1426 2164/1975/2164 2158/1976/2158 f 2221/1977/2221 1874/1978/1874 1877/1979/1877 f 2221/1977/2221 1877/1979/1877 2222/1980/2222 f 1877/1979/1877 1884/1981/1884 1885/1982/1885 f 1877/1979/1877 1885/1982/1885 2223/1983/2223 f 1886/1984/1886 2223/1983/2223 1885/1982/1885 f 1886/1984/1886 1885/1982/1885 1887/1985/1887 f 1901/1986/1901 1898/1987/1898 1887/1988/1887 f 1901/1986/1901 1887/1988/1887 1885/1989/1885 f 547/1950/547 625/1990/625 1892/1991/1892 f 547/1950/547 1892/1991/1892 1841/1951/1841 f 1890/1992/1890 1891/1993/1891 1892/1991/1892 f 1890/1992/1890 1892/1991/1892 1893/1994/1893 f 1860/1995/1860 1859/1996/1859 1890/1992/1890 f 1860/1995/1860 1890/1992/1890 1893/1994/1893 f 1860/1997/1860 1893/1998/1893 1884/1999/1884 f 1860/1997/1860 1884/1999/1884 1877/2000/1877 f 1402/1965/1402 1401/2001/1401 1403/2002/1403 f 1402/1965/1402 1403/2002/1403 1870/1969/1870 f 1418/1971/1418 1872/1967/1872 1873/2003/1873 f 1418/1971/1418 1873/2003/1873 1419/2004/1419 f 1898/1987/1898 646/2005/646 647/2006/647 f 1898/1987/1898 647/2006/647 1899/2007/1899 f 647/2006/647 649/2008/649 1928/2009/1928 f 647/2006/647 1928/2009/1928 1899/2007/1899 f 1896/2010/1896 1904/2011/1904 1903/2012/1903 f 1896/2010/1896 1903/2012/1903 1895/2013/1895 f 1894/2014/1894 1905/2015/1905 1906/2016/1906 f 1894/2014/1894 1906/2016/1906 1896/2010/1896 f 1896/2010/1896 1906/2016/1906 1907/2017/1907 f 1896/2010/1896 1907/2017/1907 1904/2011/1904 f 1925/2018/1925 1909/2019/1909 1908/2020/1908 f 1925/2018/1925 1908/2020/1908 1905/2021/1905 f 1906/2016/1906 1908/2022/1908 1910/2023/1910 f 1906/2016/1906 1910/2023/1910 1907/2017/1907 f 1908/2020/1908 1909/2019/1909 1915/2024/1915 f 1908/2020/1908 1915/2024/1915 1914/2025/1914 f 1908/2022/1908 1914/2026/1914 1916/2027/1916 f 1908/2022/1908 1916/2027/1916 1910/2023/1910 f 1914/2025/1914 1915/2024/1915 1912/2028/1912 f 1914/2025/1914 1912/2028/1912 1917/2029/1917 f 1913/2030/1913 1916/2027/1916 1914/2026/1914 f 1913/2030/1913 1914/2026/1914 1917/2031/1917 f 1925/2018/1925 1924/2032/1924 1919/2033/1919 f 1925/2018/1925 1919/2033/1919 1909/2019/1909 f 1910/2023/1910 1920/2034/1920 1918/2035/1918 f 1910/2023/1910 1918/2035/1918 1907/2017/1907 f 1915/2024/1915 1922/2036/1922 1921/2037/1921 f 1915/2024/1915 1921/2037/1921 1912/2028/1912 f 1916/2027/1916 1923/2038/1923 1920/2034/1920 f 1916/2027/1916 1920/2034/1920 1910/2023/1910 f 1909/2019/1909 1919/2033/1919 1922/2036/1922 f 1909/2019/1909 1922/2036/1922 1915/2024/1915 f 1913/2030/1913 1921/2037/1921 1923/2038/1923 f 1913/2030/1913 1923/2038/1923 1916/2027/1916 f 1923/2038/1923 1922/2036/1922 1919/2033/1919 f 1923/2038/1923 1919/2033/1919 1920/2034/1920 f 1920/2034/1920 1919/2033/1919 1924/2032/1924 f 1920/2034/1920 1924/2032/1924 1926/2039/1926 f 1926/2039/1926 1929/2040/1929 1927/2041/1927 f 1926/2039/1926 1927/2041/1927 1918/2035/1918 f 1927/2041/1927 1904/2011/1904 1907/2017/1907 f 1927/2041/1927 1907/2017/1907 1918/2035/1918 f 1925/2018/1925 1928/2042/1928 1930/2043/1930 f 1925/2018/1925 1930/2043/1930 1924/2032/1924 f 2143/2044/2143 2000/2045/2000 1932/2046/1932 f 2143/2044/2143 1932/2046/1932 1931/2047/1931 f 2143/2044/2143 1931/2047/1931 1935/2048/1935 f 2143/2044/2143 1935/2048/1935 1934/2049/1934 f 1933/2050/1933 1937/2051/1937 1936/2052/1936 f 1933/2050/1933 1936/2052/1936 1932/2053/1932 f 1933/2050/1933 1949/2054/1949 1939/2055/1939 f 1933/2050/1933 1939/2055/1939 1937/2051/1937 f 1938/2056/1938 1960/2057/1960 1941/2058/1941 f 1938/2056/1938 1941/2058/1941 1935/2048/1935 f 1939/2055/1939 1949/2054/1949 1948/2059/1948 f 1939/2055/1939 1948/2059/1948 1942/2060/1942 f 1944/2061/1944 1947/2062/1947 1946/2063/1946 f 1944/2061/1944 1946/2063/1946 1945/2064/1945 f 1940/2065/1940 1946/2063/1946 1947/2062/1947 f 1940/2065/1940 1947/2062/1947 1950/2066/1950 f 1943/2067/1943 1948/2059/1948 1949/2054/1949 f 1943/2067/1943 1949/2054/1949 1940/2065/1940 f 1947/2062/1947 1953/2068/1953 1952/2069/1952 f 1947/2062/1947 1952/2069/1952 1950/2066/1950 f 1955/2070/1955 1934/2049/1934 1935/2048/1935 f 1955/2070/1955 1935/2048/1935 1941/2058/1941 f 1956/2071/1956 1986/2072/1986 1985/2073/1985 f 1956/2071/1956 1985/2073/1985 1957/2074/1957 f 1931/2047/1931 1959/2075/1959 1938/2056/1938 f 1931/2047/1931 1938/2056/1938 1935/2048/1935 f 1937/2051/1937 1962/2076/1962 1961/2077/1961 f 1937/2051/1937 1961/2077/1961 1936/2052/1936 f 1959/2075/1959 1965/2078/1965 1963/2079/1963 f 1959/2075/1959 1963/2079/1963 1938/2056/1938 f 1964/2080/1964 1962/2076/1962 1937/2051/1937 f 1964/2080/1964 1937/2051/1937 1939/2055/1939 f 1960/2057/1960 1966/2081/1966 1971/2082/1971 f 1960/2057/1960 1971/2082/1971 1942/2060/1942 f 1942/2060/1942 1971/2082/1971 1964/2080/1964 f 1942/2060/1942 1964/2080/1964 1939/2055/1939 f 1936/2083/1936 1961/2084/1961 1965/2078/1965 f 1936/2083/1936 1965/2078/1965 1959/2075/1959 f 1938/2056/1938 1963/2079/1963 1966/2081/1966 f 1938/2056/1938 1966/2081/1966 1960/2057/1960 f 1961/2084/1961 1967/2085/1967 1969/2086/1969 f 1961/2084/1961 1969/2086/1969 1965/2078/1965 f 1964/2080/1964 1972/2087/1972 1967/2088/1967 f 1964/2080/1964 1967/2088/1967 1962/2076/1962 f 1963/2079/1963 1969/2086/1969 1970/2089/1970 f 1963/2079/1963 1970/2089/1970 1966/2081/1966 f 1970/2089/1970 1968/2090/1968 1971/2082/1971 f 1970/2089/1970 1971/2082/1971 1966/2081/1966 f 1972/2087/1972 1964/2080/1964 1971/2082/1971 f 1972/2087/1972 1971/2082/1971 1968/2090/1968 f 1967/2088/1967 1972/2087/1972 1976/2091/1976 f 1967/2088/1967 1976/2091/1976 1973/2092/1973 f 1969/2086/1969 1973/2093/1973 1974/2094/1974 f 1969/2086/1969 1974/2094/1974 1970/2089/1970 f 1970/2089/1970 1974/2094/1974 1975/2095/1975 f 1970/2089/1970 1975/2095/1975 1968/2090/1968 f 1972/2087/1972 1968/2090/1968 1975/2095/1975 f 1972/2087/1972 1975/2095/1975 1976/2091/1976 f 2005/2096/2005 1933/2050/1933 2004/2097/2004 f 2005/2096/2005 2004/2097/2004 1978/2098/1978 f 649/2099/649 731/2100/731 1980/2101/1980 f 649/2099/649 1980/2101/1980 1928/2102/1928 f 1978/2103/1978 1981/2104/1981 733/2105/733 f 1978/2103/1978 733/2105/733 700/2106/700 f 1930/2107/1930 1980/2101/1980 1981/2104/1981 f 1930/2107/1930 1981/2104/1981 1979/2108/1979 f 1980/2101/1980 731/2100/731 736/2109/736 f 1980/2101/1980 736/2109/736 1982/2110/1982 f 1981/2104/1981 1983/2111/1983 738/2112/738 f 1981/2104/1981 738/2112/738 733/2105/733 f 1981/2104/1981 1980/2101/1980 1982/2110/1982 f 1981/2104/1981 1982/2110/1982 1983/2111/1983 f 1990/2113/1990 1994/2114/1994 1992/2115/1992 f 1990/2113/1990 1992/2115/1992 1987/2116/1987 f 1993/2117/1993 1995/2118/1995 1994/2114/1994 f 1993/2117/1993 1994/2114/1994 1990/2113/1990 f 1929/2119/1929 1979/2120/1979 2150/2121/2150 f 1929/2119/1929 2150/2121/2150 2149/2122/2149 f 1933/2050/1933 2005/2096/2005 692/2123/692 f 1933/2050/1933 692/2123/692 1946/2063/1946 f 1996/2124/1996 2008/2125/2008 2006/2126/2006 f 1996/2124/1996 2006/2126/2006 1991/2127/1991 f 1993/2117/1993 1991/2127/1991 2006/2126/2006 f 1993/2117/1993 2006/2126/2006 1995/2118/1995 f 777/2128/777 2009/2129/2009 2018/2130/2018 f 777/2128/777 2018/2130/2018 754/2131/754 f 756/2132/756 783/2133/783 2015/2134/2015 f 756/2132/756 2015/2134/2015 2014/2135/2014 f 2022/2136/2022 2031/2137/2031 2032/2138/2032 f 2022/2136/2022 2032/2138/2032 2025/2139/2025 f 2017/2140/2017 2037/2141/2037 2011/2142/2011 f 2017/2140/2017 2011/2142/2011 2013/2143/2013 f 2007/2144/2007 2040/2145/2040 2041/2146/2041 f 2007/2144/2007 2041/2146/2041 2030/2147/2030 f 2042/2148/2042 2041/2146/2041 2040/2145/2040 f 2042/2148/2042 2040/2145/2040 2038/2149/2038 f 2039/2150/2039 2048/2151/2048 2041/2146/2041 f 2039/2150/2039 2041/2146/2041 2042/2148/2042 f 2043/2152/2043 2049/2153/2049 2048/2151/2048 f 2043/2152/2043 2048/2151/2048 2039/2150/2039 f 2059/2154/2059 2058/2155/2058 2032/2138/2032 f 2059/2154/2059 2032/2138/2032 2051/2156/2051 f 2068/2157/2068 2069/2158/2069 2070/2159/2070 f 2068/2157/2068 2070/2159/2070 2067/2160/2067 f 2067/2160/2067 2076/2161/2076 2077/2162/2077 f 2067/2160/2067 2077/2162/2077 2068/2157/2068 f 2071/2163/2071 2078/2164/2078 2076/2161/2076 f 2071/2163/2071 2076/2161/2076 2067/2160/2067 f 2076/2161/2076 2079/2165/2079 2088/2166/2088 f 2076/2161/2076 2088/2166/2088 2077/2162/2077 f 2078/2164/2078 2080/2167/2080 2079/2165/2079 f 2078/2164/2078 2079/2165/2079 2076/2161/2076 f 2081/2168/2081 2078/2164/2078 2071/2163/2071 f 2081/2168/2081 2071/2163/2071 2074/2169/2074 f 2074/2169/2074 2082/2170/2082 2083/2171/2083 f 2074/2169/2074 2083/2171/2083 2081/2168/2081 f 2081/2168/2081 2083/2171/2083 2099/2172/2099 f 2081/2168/2081 2099/2172/2099 2101/2173/2101 f 2092/2174/2092 2070/2159/2070 2069/2158/2069 f 2092/2174/2092 2069/2158/2069 2054/2175/2054 f 2092/2174/2092 2073/2176/2073 2072/2177/2072 f 2092/2174/2092 2072/2177/2072 2070/2159/2070 f 2072/2177/2072 2073/2176/2073 2093/2178/2093 f 2072/2177/2072 2093/2178/2093 2091/2179/2091 f 2086/2180/2086 2112/2181/2112 2111/2182/2111 f 2086/2180/2086 2111/2182/2111 2084/2183/2084 f 2085/2184/2085 2511/2185/2511 2112/2181/2112 f 2085/2184/2085 2112/2181/2112 2086/2180/2086 f 2097/2186/2097 2101/2173/2101 2099/2172/2099 f 2097/2186/2097 2099/2172/2099 2098/2187/2098 f 2080/2167/2080 2086/2180/2086 2084/2183/2084 f 2080/2167/2080 2084/2183/2084 2079/2165/2079 f 2109/2188/2109 2096/2189/2096 2105/2190/2105 f 2109/2188/2109 2105/2190/2105 2104/2191/2104 f 2105/2190/2105 2107/2192/2107 2106/2193/2106 f 2105/2190/2105 2106/2193/2106 2104/2191/2104 f 2107/2192/2107 2108/2194/2108 2120/2195/2120 f 2107/2192/2107 2120/2195/2120 2106/2193/2106 f 2109/2188/2109 2110/2196/2110 2111/2182/2111 f 2109/2188/2109 2111/2182/2111 2096/2189/2096 f 2096/2189/2096 2111/2182/2111 2112/2181/2112 f 2096/2189/2096 2112/2181/2112 2174/2197/2174 f 2115/2198/2115 2119/2199/2119 2118/2200/2118 f 2115/2198/2115 2118/2200/2118 2114/2201/2114 f 2113/2202/2113 2117/2203/2117 2119/2199/2119 f 2113/2202/2113 2119/2199/2119 2115/2198/2115 f 2124/2204/2124 2123/2205/2123 2116/2206/2116 f 2124/2204/2124 2116/2206/2116 2089/2207/2089 f 2106/2193/2106 2120/2195/2120 2121/2208/2121 f 2106/2193/2106 2121/2208/2121 2104/2191/2104 f 2104/2191/2104 2121/2208/2121 2122/2209/2122 f 2104/2191/2104 2122/2209/2122 2109/2188/2109 f 2109/2188/2109 2122/2209/2122 2117/2203/2117 f 2109/2188/2109 2117/2203/2117 2113/2202/2113 f 2103/2210/2103 2108/2194/2108 2107/2192/2107 f 2103/2210/2103 2107/2192/2107 2105/2190/2105 f 2123/2205/2123 2124/2204/2124 2114/2201/2114 f 2123/2205/2123 2114/2201/2114 2118/2200/2118 f 2090/2211/2090 2155/2212/2155 2068/2157/2068 f 2090/2211/2090 2068/2157/2068 2077/2162/2077 f 2054/2175/2054 2069/2158/2069 2141/2213/2141 f 2054/2175/2054 2141/2213/2141 2142/2214/2142 f 1827/1935/1827 1818/1931/1818 521/1934/521 f 1827/1935/1827 521/1934/521 522/1936/522 f 1882/2215/1882 2126/2216/2126 2125/2217/2125 f 1882/2215/1882 2125/2217/2125 1880/2218/1880 f 2129/2219/2129 2125/2217/2125 2126/2216/2126 f 2129/2219/2129 2126/2216/2126 2128/2220/2128 f 1882/2221/1882 2130/2222/2130 2131/2223/2131 f 1882/2221/1882 2131/2223/2131 2126/2224/2126 f 2131/2223/2131 2136/2225/2136 2138/2226/2138 f 2131/2223/2131 2138/2226/2138 2147/2227/2147 f 2130/2222/2130 2135/2228/2135 2136/2225/2136 f 2130/2222/2130 2136/2225/2136 2131/2223/2131 f 1927/2041/1927 2133/2229/2133 2132/2230/2132 f 1927/2041/1927 2132/2230/2132 1904/2011/1904 f 2133/2231/2133 2137/2232/2137 2134/2233/2134 f 2133/2231/2133 2134/2233/2134 2132/2234/2132 f 2138/2226/2138 2136/2225/2136 2135/2228/2135 f 2138/2226/2138 2135/2228/2135 2139/2235/2139 f 2138/2226/2138 2139/2236/2139 2137/2232/2137 f 2138/2226/2138 2137/2232/2137 2147/2227/2147 f 2141/2213/2141 2144/2237/2144 2143/2238/2143 f 2141/2213/2141 2143/2238/2143 2142/2214/2142 f 2140/2239/2140 2143/2238/2143 2144/2237/2144 f 2140/2239/2140 2144/2237/2144 2128/2240/2128 f 2142/2214/2142 1934/2241/1934 2056/2242/2056 f 2142/2214/2142 2056/2242/2056 2057/2243/2057 f 2001/2244/2001 2145/2245/2145 2146/2246/2146 f 2001/2244/2001 2146/2246/2146 2002/2247/2002 f 2140/2248/2140 2147/2249/2147 2145/2245/2145 f 2140/2248/2140 2145/2245/2145 2001/2244/2001 f 2149/2122/2149 2151/2250/2151 1927/2251/1927 f 2149/2122/2149 1927/2251/1927 1929/2119/1929 f 2147/2249/2147 2137/2252/2137 2151/2253/2151 f 2147/2249/2147 2151/2253/2151 2145/2245/2145 f 2133/2254/2133 1927/2255/1927 2151/2253/2151 f 2133/2254/2133 2151/2253/2151 2137/2252/2137 f 2001/2244/2001 2152/2256/2152 2000/2257/2000 f 2001/2244/2001 2000/2257/2000 2143/2258/2143 f 2158/1976/2158 2159/2259/2159 2160/2260/2160 f 2158/1976/2158 2160/2260/2160 1428/2261/1428 f 2082/2170/2082 2163/2262/2163 2162/2263/2162 f 2082/2170/2082 2162/2263/2162 2083/2171/2083 f 2083/2171/2083 2181/2264/2181 2161/2265/2161 f 2083/2171/2083 2161/2265/2161 2099/2172/2099 f 2158/1976/2158 2164/1975/2164 2165/2266/2165 f 2158/1976/2158 2165/2266/2165 2159/2259/2159 f 2082/2170/2082 2074/2169/2074 2075/2267/2075 f 2082/2170/2082 2075/2267/2075 2165/2266/2165 f 2181/2264/2181 2162/2263/2162 2182/2268/2182 f 2181/2264/2181 2182/2268/2182 2166/2269/2166 f 2169/2270/2169 2166/2271/2166 2116/2206/2116 f 2169/2270/2169 2116/2206/2116 2123/2205/2123 f 2167/2272/2167 2116/2206/2116 2166/2271/2166 f 2167/2272/2167 2166/2271/2166 2182/2273/2182 f 2090/2211/2090 2167/2272/2167 2156/2274/2156 f 2090/2211/2090 2156/2274/2156 2155/2212/2155 f 2167/2272/2167 2182/2273/2182 2129/2275/2129 f 2167/2272/2167 2129/2275/2129 2156/2274/2156 f 2118/2200/2118 2168/2276/2168 2169/2270/2169 f 2118/2200/2118 2169/2270/2169 2123/2205/2123 f 2120/2195/2120 2379/2277/2379 2170/2278/2170 f 2120/2195/2120 2170/2278/2170 2121/2208/2121 f 2379/2279/2379 2220/2280/2220 2172/2281/2172 f 2379/2279/2379 2172/2281/2172 2170/2282/2170 f 2170/2282/2170 2172/2281/2172 2173/2283/2173 f 2170/2282/2170 2173/2283/2173 2171/2284/2171 f 2172/2281/2172 2220/2280/2220 2187/2285/2187 f 2172/2281/2172 2187/2285/2187 2176/2286/2176 f 2176/2286/2176 2175/2287/2175 2180/2288/2180 f 2176/2286/2176 2180/2288/2180 2172/2281/2172 f 2175/2287/2175 2511/2185/2511 2100/2289/2100 f 2175/2287/2175 2100/2289/2100 2178/2290/2178 f 2179/2291/2179 2180/2288/2180 2175/2287/2175 f 2179/2291/2179 2175/2287/2175 2178/2290/2178 f 2173/2283/2173 2179/2291/2179 2184/2292/2184 f 2173/2283/2173 2184/2292/2184 2183/2293/2183 f 2098/2187/2098 2178/2290/2178 2100/2289/2100 f 2098/2187/2098 2100/2289/2100 2097/2186/2097 f 2179/2291/2179 2178/2290/2178 2098/2187/2098 f 2179/2291/2179 2098/2187/2098 2184/2292/2184 f 2168/2294/2168 2173/2283/2173 2183/2293/2183 f 2168/2294/2168 2183/2293/2183 2169/2295/2169 f 2183/2293/2183 2181/2264/2181 2166/2269/2166 f 2183/2293/2183 2166/2269/2166 2169/2295/2169 f 2182/2268/2182 2162/2263/2162 2127/2296/2127 f 2182/2268/2182 2127/2296/2127 2129/2297/2129 f 2177/2298/2177 2186/2299/2186 2185/2300/2185 f 2177/2298/2177 2185/2300/2185 2103/2210/2103 f 2177/2298/2177 2187/2285/2187 2207/2301/2207 f 2177/2298/2177 2207/2301/2207 2186/2299/2186 f 2189/2302/2189 2188/2303/2188 2108/2194/2108 f 2189/2302/2189 2108/2194/2108 2185/2300/2185 f 2191/2304/2191 2190/2305/2190 2185/2300/2185 f 2191/2304/2191 2185/2300/2185 2186/2299/2186 f 2380/2306/2380 2108/2194/2108 2188/2303/2188 f 2380/2306/2380 2188/2303/2188 2192/2307/2192 f 2305/2308/2305 2306/2309/2306 2189/2302/2189 f 2305/2308/2305 2189/2302/2189 2190/2305/2190 f 2189/2302/2189 2342/2310/2342 2343/2311/2343 f 2189/2302/2189 2343/2311/2343 2188/2303/2188 f 2191/2304/2191 2194/2312/2194 2193/2313/2193 f 2191/2304/2191 2193/2313/2193 2190/2305/2190 f 2188/2303/2188 2381/2314/2381 2382/2315/2382 f 2188/2303/2188 2382/2315/2382 2192/2307/2192 f 2194/2312/2194 2196/2316/2196 2195/2317/2195 f 2194/2312/2194 2195/2317/2195 2193/2313/2193 f 2196/2316/2196 2198/2318/2198 2197/2319/2197 f 2196/2316/2196 2197/2319/2197 2195/2317/2195 f 2198/2318/2198 2200/2320/2200 2199/2321/2199 f 2198/2318/2198 2199/2321/2199 2197/2319/2197 f 2200/2320/2200 2205/2322/2205 2201/2323/2201 f 2200/2320/2200 2201/2323/2201 2199/2321/2199 f 2186/2299/2186 2207/2301/2207 2269/2324/2269 f 2186/2299/2186 2269/2324/2269 2270/2325/2270 f 2194/2312/2194 2208/2326/2208 2209/2327/2209 f 2194/2312/2194 2209/2327/2209 2196/2316/2196 f 2200/2320/2200 2209/2327/2209 2211/2328/2211 f 2200/2320/2200 2211/2328/2211 2205/2322/2205 f 2211/2328/2211 2210/2329/2210 2203/2330/2203 f 2211/2328/2211 2203/2330/2203 2205/2322/2205 f 2214/2331/2214 2212/2332/2212 2202/2333/2202 f 2214/2331/2214 2202/2333/2202 2204/2334/2204 f 2203/2330/2203 2213/2335/2213 2214/2331/2214 f 2203/2330/2203 2214/2331/2214 2204/2334/2204 f 2215/2336/2215 2264/2337/2264 2212/2332/2212 f 2215/2336/2215 2212/2332/2212 2214/2331/2214 f 2213/2335/2213 2263/2338/2263 2215/2336/2215 f 2213/2335/2213 2215/2336/2215 2214/2331/2214 f 2207/2301/2207 2216/2339/2216 2280/2340/2280 f 2207/2301/2207 2280/2340/2280 2269/2324/2269 f 2220/2280/2220 2216/2339/2216 2207/2301/2207 f 2220/2280/2220 2207/2301/2207 2187/2285/2187 f 1875/2341/1875 2221/1977/2221 2222/1980/2222 f 1875/2341/1875 2222/1980/2222 1878/2342/1878 f 2223/1983/2223 1897/2343/1897 1878/2342/1878 f 2223/1983/2223 1878/2342/1878 2222/1980/2222 f 2228/2344/2228 2225/2345/2225 2043/2152/2043 f 2228/2344/2228 2043/2152/2043 2045/2346/2045 f 2059/2154/2059 2051/2156/2051 2237/2347/2237 f 2059/2154/2059 2237/2347/2237 2238/2348/2238 f 2066/2349/2066 2059/2154/2059 2238/2348/2238 f 2066/2349/2066 2238/2348/2238 2061/2350/2061 f 2231/2351/2231 2241/2352/2241 2094/2353/2094 f 2231/2351/2231 2094/2353/2094 2073/2176/2073 f 2244/2354/2244 2243/2355/2243 2250/2356/2250 f 2244/2354/2244 2250/2356/2250 2235/2357/2235 f 2094/2353/2094 2251/2358/2251 2247/2359/2247 f 2094/2353/2094 2247/2359/2247 2227/2360/2227 f 2053/2361/2053 2065/2362/2065 2064/2363/2064 f 2053/2361/2053 2064/2363/2064 2240/2364/2240 f 2256/2365/2256 2199/2321/2199 2201/2323/2201 f 2256/2365/2256 2201/2323/2201 2253/2366/2253 f 2253/2366/2253 2201/2323/2201 2202/2333/2202 f 2253/2366/2253 2202/2333/2202 2254/2367/2254 f 2255/2368/2255 2193/2313/2193 2195/2317/2195 f 2255/2368/2255 2195/2317/2195 2256/2365/2256 f 2257/2369/2257 2210/2329/2210 2211/2328/2211 f 2257/2369/2257 2211/2328/2211 2258/2370/2258 f 2259/2371/2259 2253/2366/2253 2254/2367/2254 f 2259/2371/2259 2254/2367/2254 2260/2372/2260 f 2258/2373/2258 2259/2374/2259 2260/2375/2260 f 2258/2373/2258 2260/2375/2260 2257/2376/2257 f 2261/2377/2261 2257/2376/2257 2260/2375/2260 f 2261/2377/2261 2260/2375/2260 2262/2378/2262 f 2263/2379/2263 2261/2377/2261 2262/2378/2262 f 2263/2379/2263 2262/2378/2262 2264/2380/2264 f 2267/2381/2267 2259/2374/2259 2258/2373/2258 f 2267/2381/2267 2258/2373/2258 2265/2382/2265 f 2340/2383/2340 2267/2381/2267 2265/2382/2265 f 2340/2383/2340 2265/2382/2265 2266/2384/2266 f 2256/2365/2256 2253/2366/2253 2259/2371/2259 f 2256/2365/2256 2259/2371/2259 2267/2385/2267 f 2255/2368/2255 2256/2365/2256 2267/2385/2267 f 2255/2368/2255 2267/2385/2267 2340/2386/2340 f 2266/2387/2266 2265/2388/2265 2209/2327/2209 f 2266/2387/2266 2209/2327/2209 2208/2326/2208 f 2269/2324/2269 2272/2389/2272 2271/2390/2271 f 2269/2324/2269 2271/2390/2271 2270/2325/2270 f 2272/2389/2272 2274/2391/2274 2273/2392/2273 f 2272/2389/2272 2273/2392/2273 2271/2390/2271 f 2274/2391/2274 2276/2393/2276 2275/2394/2275 f 2274/2391/2274 2275/2394/2275 2273/2392/2273 f 2269/2324/2269 2280/2340/2280 2281/2395/2281 f 2269/2324/2269 2281/2395/2281 2272/2389/2272 f 2281/2395/2281 2282/2396/2282 2279/2397/2279 f 2281/2395/2281 2279/2397/2279 2276/2393/2276 f 2283/2398/2283 2284/2399/2284 2278/2400/2278 f 2283/2398/2283 2278/2400/2278 2277/2401/2277 f 2279/2397/2279 2285/2402/2285 2283/2398/2283 f 2279/2397/2279 2283/2398/2283 2277/2401/2277 f 2286/2403/2286 2287/2404/2287 2284/2399/2284 f 2286/2403/2286 2284/2399/2284 2283/2398/2283 f 2285/2402/2285 2288/2405/2288 2286/2403/2286 f 2285/2402/2285 2286/2403/2286 2283/2398/2283 f 2289/2406/2289 2275/2394/2275 2278/2400/2278 f 2289/2406/2289 2278/2400/2278 2290/2407/2290 f 2206/2408/2206 2270/2325/2270 2271/2390/2271 f 2206/2408/2206 2271/2390/2271 2289/2406/2289 f 2291/2409/2291 2282/2396/2282 2281/2395/2281 f 2291/2409/2291 2281/2395/2281 2298/2410/2298 f 2297/2411/2297 2289/2406/2289 2290/2407/2290 f 2297/2411/2297 2290/2407/2290 2292/2412/2292 f 2298/2413/2298 2297/2414/2297 2292/2415/2292 f 2298/2413/2298 2292/2415/2292 2291/2416/2291 f 2293/2417/2293 2291/2416/2291 2292/2415/2292 f 2293/2417/2293 2292/2415/2292 2294/2418/2294 f 2295/2419/2295 2293/2417/2293 2294/2418/2294 f 2295/2419/2295 2294/2418/2294 2296/2420/2296 f 2288/2421/2288 2295/2419/2295 2296/2420/2296 f 2288/2421/2288 2296/2420/2296 2287/2422/2287 f 2299/2423/2299 2297/2414/2297 2298/2413/2298 f 2299/2423/2299 2298/2413/2298 2415/2424/2415 f 2289/2406/2289 2297/2411/2297 2299/2425/2299 f 2289/2406/2289 2299/2425/2299 2206/2408/2206 f 2415/2426/2415 2298/2410/2298 2281/2395/2281 f 2415/2426/2415 2281/2395/2281 2280/2340/2280 f 2301/2427/2301 2208/2326/2208 2194/2312/2194 f 2301/2427/2301 2194/2312/2194 2191/2304/2191 f 2304/2428/2304 2415/2429/2415 2218/2430/2218 f 2304/2428/2304 2218/2430/2218 2302/2431/2302 f 2301/2427/2301 2303/2432/2303 2266/2387/2266 f 2301/2427/2301 2266/2387/2266 2208/2326/2208 f 2303/2433/2303 2304/2428/2304 2340/2383/2340 f 2303/2433/2303 2340/2383/2340 2266/2384/2266 f 2209/2327/2209 2265/2388/2265 2258/2370/2258 f 2209/2327/2209 2258/2370/2258 2211/2328/2211 f 2305/2308/2305 2308/2434/2308 2307/2435/2307 f 2305/2308/2305 2307/2435/2307 2306/2309/2306 f 2308/2434/2308 2310/2436/2310 2309/2437/2309 f 2308/2434/2308 2309/2437/2309 2307/2435/2307 f 2310/2436/2310 2312/2438/2312 2311/2439/2311 f 2310/2436/2310 2311/2439/2311 2309/2437/2309 f 2312/2438/2312 2314/2440/2314 2313/2441/2313 f 2312/2438/2312 2313/2441/2313 2311/2439/2311 f 2305/2308/2305 2318/2442/2318 2319/2443/2319 f 2305/2308/2305 2319/2443/2319 2308/2434/2308 f 2312/2438/2312 2319/2443/2319 2320/2444/2320 f 2312/2438/2312 2320/2444/2320 2314/2440/2314 f 2320/2444/2320 2321/2445/2321 2317/2446/2317 f 2320/2444/2320 2317/2446/2317 2314/2440/2314 f 2322/2447/2322 2323/2448/2323 2316/2449/2316 f 2322/2447/2322 2316/2449/2316 2315/2450/2315 f 2317/2446/2317 2324/2451/2324 2322/2447/2322 f 2317/2446/2317 2322/2447/2322 2315/2450/2315 f 2325/2452/2325 2326/2453/2326 2323/2448/2323 f 2325/2452/2325 2323/2448/2323 2322/2447/2322 f 2324/2451/2324 2327/2454/2327 2325/2452/2325 f 2324/2451/2324 2325/2452/2325 2322/2447/2322 f 2328/2455/2328 2311/2439/2311 2313/2441/2313 f 2328/2455/2328 2313/2441/2313 2329/2456/2329 f 2329/2456/2329 2313/2441/2313 2316/2449/2316 f 2329/2456/2329 2316/2449/2316 2330/2457/2330 f 2331/2458/2331 2306/2309/2306 2307/2435/2307 f 2331/2458/2331 2307/2435/2307 2328/2455/2328 f 2321/2445/2321 2320/2444/2320 2333/2459/2333 f 2321/2445/2321 2333/2459/2333 2332/2460/2332 f 2334/2461/2334 2329/2456/2329 2330/2457/2330 f 2334/2461/2334 2330/2457/2330 2335/2462/2335 f 2333/2463/2333 2334/2464/2334 2335/2465/2335 f 2333/2463/2333 2335/2465/2335 2332/2466/2332 f 2336/2467/2336 2332/2466/2332 2335/2465/2335 f 2336/2467/2336 2335/2465/2335 2337/2468/2337 f 2327/2469/2327 2336/2467/2336 2337/2468/2337 f 2327/2469/2327 2337/2468/2337 2326/2470/2326 f 2338/2471/2338 2334/2464/2334 2333/2463/2333 f 2338/2471/2338 2333/2463/2333 2339/2472/2339 f 2376/2473/2376 2338/2471/2338 2339/2472/2339 f 2376/2473/2376 2339/2472/2339 2340/2383/2340 f 2328/2455/2328 2329/2456/2329 2334/2461/2334 f 2328/2455/2328 2334/2461/2334 2338/2474/2338 f 2331/2458/2331 2328/2455/2328 2338/2474/2338 f 2331/2458/2331 2338/2474/2338 2376/2475/2376 f 2340/2386/2340 2339/2476/2339 2319/2443/2319 f 2340/2386/2340 2319/2443/2319 2318/2442/2318 f 2319/2443/2319 2339/2476/2339 2333/2459/2333 f 2319/2443/2319 2333/2459/2333 2320/2444/2320 f 2305/2308/2305 2193/2313/2193 2255/2368/2255 f 2305/2308/2305 2255/2368/2255 2318/2442/2318 f 2342/2310/2342 2345/2477/2345 2344/2478/2344 f 2342/2310/2342 2344/2478/2344 2343/2311/2343 f 2345/2477/2345 2347/2479/2347 2346/2480/2346 f 2345/2477/2345 2346/2480/2346 2344/2478/2344 f 2347/2479/2347 2349/2481/2349 2348/2482/2348 f 2347/2479/2347 2348/2482/2348 2346/2480/2346 f 2349/2481/2349 2351/2483/2351 2350/2484/2350 f 2349/2481/2349 2350/2484/2350 2348/2482/2348 f 2342/2310/2342 2355/2485/2355 2356/2486/2356 f 2342/2310/2342 2356/2486/2356 2345/2477/2345 f 2349/2481/2349 2356/2486/2356 2357/2487/2357 f 2349/2481/2349 2357/2487/2357 2351/2483/2351 f 2357/2487/2357 2358/2488/2358 2354/2489/2354 f 2357/2487/2357 2354/2489/2354 2351/2483/2351 f 2359/2490/2359 2360/2491/2360 2353/2492/2353 f 2359/2490/2359 2353/2492/2353 2352/2493/2352 f 2354/2489/2354 2361/2494/2361 2359/2490/2359 f 2354/2489/2354 2359/2490/2359 2352/2493/2352 f 2363/2495/2363 2348/2482/2348 2350/2484/2350 f 2363/2495/2363 2350/2484/2350 2364/2496/2364 f 2364/2496/2364 2350/2484/2350 2353/2492/2353 f 2364/2496/2364 2353/2492/2353 2365/2497/2365 f 2366/2498/2366 2343/2311/2343 2344/2478/2344 f 2366/2498/2366 2344/2478/2344 2363/2495/2363 f 2367/2499/2367 2358/2488/2358 2357/2487/2357 f 2367/2499/2367 2357/2487/2357 2368/2500/2368 f 2369/2501/2369 2364/2496/2364 2365/2497/2365 f 2369/2501/2369 2365/2497/2365 2370/2502/2370 f 2368/2503/2368 2369/2504/2369 2370/2505/2370 f 2368/2503/2368 2370/2505/2370 2367/2506/2367 f 2371/2507/2371 2367/2506/2367 2370/2505/2370 f 2371/2507/2371 2370/2505/2370 2372/2508/2372 f 2373/2509/2373 2369/2504/2369 2368/2503/2368 f 2373/2509/2373 2368/2503/2368 2374/2510/2374 f 2375/2511/2375 2373/2509/2373 2374/2510/2374 f 2375/2511/2375 2374/2510/2374 2376/2512/2376 f 2363/2495/2363 2364/2496/2364 2369/2501/2369 f 2363/2495/2363 2369/2501/2369 2373/2513/2373 f 2366/2498/2366 2363/2495/2363 2373/2513/2373 f 2366/2498/2366 2373/2513/2373 2375/2514/2375 f 2376/2475/2376 2374/2515/2374 2356/2486/2356 f 2376/2475/2376 2356/2486/2356 2355/2485/2355 f 2356/2486/2356 2374/2515/2374 2368/2500/2368 f 2356/2486/2356 2368/2500/2368 2357/2487/2357 f 2331/2458/2331 2355/2485/2355 2342/2310/2342 f 2331/2458/2331 2342/2310/2342 2306/2309/2306 f 2376/2473/2376 2340/2383/2340 2304/2428/2304 f 2376/2473/2376 2304/2428/2304 2302/2431/2302 f 2378/2516/2378 2302/2517/2302 2217/2518/2217 f 2378/2516/2378 2217/2518/2217 2377/2519/2377 f 2377/2520/2377 2379/2277/2379 2120/2195/2120 f 2377/2520/2377 2120/2195/2120 2380/2306/2380 f 2192/2307/2192 2378/2521/2378 2377/2520/2377 f 2192/2307/2192 2377/2520/2377 2380/2306/2380 f 1873/2003/1873 2164/2522/2164 1429/2523/1429 f 1873/2003/1873 1429/2523/1429 1419/2004/1419 f 2381/2314/2381 2384/2524/2384 2383/2525/2383 f 2381/2314/2381 2383/2525/2383 2382/2315/2382 f 2384/2524/2384 2386/2526/2386 2385/2527/2385 f 2384/2524/2384 2385/2527/2385 2383/2525/2383 f 2386/2526/2386 2388/2528/2388 2387/2529/2387 f 2386/2526/2386 2387/2529/2387 2385/2527/2385 f 2388/2528/2388 2390/2530/2390 2389/2531/2389 f 2388/2528/2388 2389/2531/2389 2387/2529/2387 f 2381/2314/2381 2394/2532/2394 2395/2533/2395 f 2381/2314/2381 2395/2533/2395 2384/2524/2384 f 2388/2528/2388 2395/2533/2395 2396/2534/2396 f 2388/2528/2388 2396/2534/2396 2390/2530/2390 f 2396/2534/2396 2397/2535/2397 2393/2536/2393 f 2396/2534/2396 2393/2536/2393 2390/2530/2390 f 2398/2537/2398 2399/2538/2399 2392/2539/2392 f 2398/2537/2398 2392/2539/2392 2391/2540/2391 f 2393/2536/2393 2400/2541/2400 2398/2537/2398 f 2393/2536/2393 2398/2537/2398 2391/2540/2391 f 2402/2542/2402 2387/2529/2387 2389/2531/2389 f 2402/2542/2402 2389/2531/2389 2403/2543/2403 f 2403/2543/2403 2389/2531/2389 2392/2539/2392 f 2403/2543/2403 2392/2539/2392 2404/2544/2404 f 2405/2545/2405 2382/2315/2382 2383/2525/2383 f 2405/2545/2405 2383/2525/2383 2402/2542/2402 f 2406/2546/2406 2397/2535/2397 2396/2534/2396 f 2406/2546/2406 2396/2534/2396 2407/2547/2407 f 2408/2548/2408 2403/2543/2403 2404/2544/2404 f 2408/2548/2408 2404/2544/2404 2409/2549/2409 f 2407/2550/2407 2408/2551/2408 2409/2552/2409 f 2407/2550/2407 2409/2552/2409 2406/2553/2406 f 2410/2554/2410 2406/2553/2406 2409/2552/2409 f 2410/2554/2410 2409/2552/2409 2411/2555/2411 f 2412/2556/2412 2408/2551/2408 2407/2550/2407 f 2412/2556/2412 2407/2550/2407 2413/2557/2413 f 2414/2558/2414 2412/2556/2412 2413/2557/2413 f 2414/2558/2414 2413/2557/2413 2375/2511/2375 f 2402/2542/2402 2403/2543/2403 2408/2548/2408 f 2402/2542/2402 2408/2548/2408 2412/2559/2412 f 2405/2545/2405 2402/2542/2402 2412/2559/2412 f 2405/2545/2405 2412/2559/2412 2414/2560/2414 f 2375/2514/2375 2413/2561/2413 2395/2533/2395 f 2375/2514/2375 2395/2533/2395 2394/2532/2394 f 2395/2533/2395 2413/2561/2413 2407/2547/2407 f 2395/2533/2395 2407/2547/2407 2396/2534/2396 f 2366/2498/2366 2394/2532/2394 2381/2314/2381 f 2366/2498/2366 2381/2314/2381 2343/2311/2343 f 2302/2517/2302 2414/2558/2414 2375/2511/2375 f 2302/2517/2302 2375/2511/2375 2376/2512/2376 f 2405/2545/2405 2414/2560/2414 2378/2521/2378 f 2405/2545/2405 2378/2521/2378 2192/2307/2192 f 2191/2304/2191 2270/2325/2270 2206/2408/2206 f 2191/2304/2191 2206/2408/2206 2301/2427/2301 f 2303/2432/2303 2301/2427/2301 2206/2408/2206 f 2303/2432/2303 2206/2408/2206 2299/2425/2299 f 2038/2149/2038 2040/2145/2040 2425/2562/2425 f 2038/2149/2038 2425/2562/2425 2417/2563/2417 f 2423/2564/2423 2420/2565/2420 2418/2566/2418 f 2423/2564/2423 2418/2566/2418 2424/2567/2424 f 1406/2568/1406 2418/2566/2418 2420/2565/2420 f 1406/2568/1406 2420/2565/2420 562/2569/562 f 2422/2570/2422 2419/2571/2419 2416/2572/2416 f 2422/2570/2422 2416/2572/2416 2421/2573/2421 f 2423/2564/2423 2417/2563/2417 2416/2572/2416 f 2423/2564/2423 2416/2572/2416 2419/2571/2419 f 2424/2567/2424 2038/2149/2038 2417/2563/2417 f 2424/2567/2424 2417/2563/2417 2423/2564/2423 f 2428/2574/2428 2015/2575/2015 783/2576/783 f 2428/2574/2428 783/2576/783 1331/2577/1331 f 2430/2578/2430 2429/2579/2429 2432/2580/2432 f 2430/2578/2430 2432/2580/2432 2431/2581/2431 f 2434/2582/2434 2429/2579/2429 2433/2583/2433 f 2434/2582/2434 2433/2583/2433 2435/2584/2435 f 2434/2582/2434 2435/2584/2435 2437/2585/2437 f 2434/2582/2434 2437/2585/2437 2436/2586/2436 f 2439/2587/2439 2433/2583/2433 2430/2578/2430 f 2439/2587/2439 2430/2578/2430 2438/2588/2438 f 2440/2589/2440 2435/2584/2435 2433/2583/2433 f 2440/2589/2440 2433/2583/2433 2439/2587/2439 f 2437/2585/2437 2435/2584/2435 2440/2589/2440 f 2437/2585/2437 2440/2589/2440 2441/2590/2441 f 2430/2578/2430 2431/2581/2431 2017/2591/2017 f 2430/2578/2430 2017/2591/2017 2438/2588/2438 f 2015/2592/2015 2428/2593/2428 2442/2594/2442 f 2015/2592/2015 2442/2594/2442 2451/2595/2451 f 2446/2596/2446 2444/2597/2444 2445/2598/2445 f 2446/2596/2446 2445/2598/2445 2447/2599/2447 f 2447/2599/2447 2445/2598/2445 2443/2600/2443 f 2447/2599/2447 2443/2600/2443 2450/2601/2450 f 2450/2601/2450 2443/2600/2443 2442/2594/2442 f 2450/2601/2450 2442/2594/2442 2449/2602/2449 f 2449/2602/2449 2442/2594/2442 2428/2593/2428 f 2449/2602/2449 2428/2593/2428 2448/2603/2448 f 2443/2600/2443 2440/2604/2440 2439/2605/2439 f 2443/2600/2443 2439/2605/2439 2451/2595/2451 f 2434/2582/2434 2454/2606/2454 2453/2607/2453 f 2434/2582/2434 2453/2607/2453 2429/2579/2429 f 2434/2582/2434 2436/2586/2436 2446/2596/2446 f 2434/2582/2434 2446/2596/2446 2454/2606/2454 f 14/2608/14 2421/2573/2421 2426/2609/2426 f 14/2608/14 2426/2609/2426 1/2610/1 f 2431/2611/2431 2432/2612/2432 2457/2613/2457 f 2431/2611/2431 2457/2613/2457 2456/2614/2456 f 63/2615/63 2457/2613/2457 2432/2612/2432 f 63/2615/63 2432/2612/2432 64/2616/64 f 2460/2617/2460 2513/2618/2513 2512/2619/2512 f 2460/2617/2460 2512/2619/2512 2458/2620/2458 f 2514/2621/2514 2513/2618/2513 2460/2617/2460 f 2514/2621/2514 2460/2617/2460 2462/2622/2462 f 2463/2623/2463 2464/2624/2464 2467/2625/2467 f 2463/2623/2463 2467/2625/2467 2466/2626/2466 f 2465/2627/2465 2498/2628/2498 2466/2626/2466 f 2465/2627/2465 2466/2626/2466 2467/2625/2467 f 2460/2617/2460 2458/2620/2458 2468/2629/2468 f 2460/2617/2460 2468/2629/2468 2469/2630/2469 f 2464/2624/2464 2462/2622/2462 2469/2630/2469 f 2464/2624/2464 2469/2630/2469 2500/2631/2500 f 2465/2627/2465 2467/2625/2467 2471/2632/2471 f 2465/2627/2465 2471/2632/2471 2470/2633/2470 f 2467/2625/2467 2464/2624/2464 2500/2631/2500 f 2467/2625/2467 2500/2631/2500 2471/2632/2471 f 2473/2634/2473 2474/2635/2474 2432/2636/2432 f 2473/2634/2473 2432/2636/2432 2472/2637/2472 f 2476/2638/2476 2473/2634/2473 2472/2637/2472 f 2476/2638/2476 2472/2637/2472 2475/2639/2475 f 2478/2640/2478 2474/2635/2474 2473/2634/2473 f 2478/2640/2478 2473/2634/2473 2479/2641/2479 f 2479/2641/2479 2473/2634/2473 2476/2638/2476 f 2479/2641/2479 2476/2638/2476 2480/2642/2480 f 2488/2643/2488 2478/2640/2478 2479/2641/2479 f 2488/2643/2488 2479/2641/2479 2482/2644/2482 f 2479/2641/2479 2480/2642/2480 2485/2645/2485 f 2479/2641/2479 2485/2645/2485 2482/2644/2482 f 2488/2643/2488 2482/2644/2482 2484/2646/2484 f 2488/2643/2488 2484/2646/2484 2483/2647/2483 f 2486/2648/2486 2487/2649/2487 2476/2638/2476 f 2486/2648/2486 2476/2638/2476 2475/2639/2475 f 2480/2642/2480 2476/2638/2476 2487/2649/2487 f 2480/2642/2480 2487/2649/2487 2481/2650/2481 f 61/2651/61 2474/2635/2474 2478/2640/2478 f 61/2651/61 2478/2640/2478 2490/2652/2490 f 1332/2653/1332 2452/2654/2452 2448/2655/2448 f 1332/2653/1332 2448/2655/2448 1331/2577/1331 f 106/2656/106 2489/2657/2489 2452/2654/2452 f 106/2656/106 2452/2654/2452 1332/2653/1332 f 2478/2640/2478 2488/2643/2488 2489/2658/2489 f 2478/2640/2478 2489/2658/2489 2490/2652/2490 f 2492/2659/2492 1/2660/1 2426/2661/2426 f 2492/2659/2492 2426/2661/2426 2491/2662/2491 f 2425/2663/2425 2459/2664/2459 2491/2665/2491 f 2425/2663/2425 2491/2665/2491 2426/2666/2426 f 2496/2667/2496 2493/2668/2493 2461/2669/2461 f 2496/2667/2496 2461/2669/2461 2463/2670/2463 f 2492/2659/2492 2515/2671/2515 4/2672/4 f 2492/2659/2492 4/2672/4 1/2660/1 f 2518/2673/2518 2519/2674/2519 2494/2675/2494 f 2518/2673/2518 2494/2675/2494 2516/2676/2516 f 2466/2677/2466 2497/2678/2497 2496/2667/2496 f 2466/2677/2466 2496/2667/2496 2463/2670/2463 f 2499/2679/2499 2497/2678/2497 2466/2677/2466 f 2499/2679/2499 2466/2677/2466 2498/2680/2498 f 2497/2678/2497 2499/2679/2499 2470/2633/2470 f 2497/2678/2497 2470/2633/2470 2471/2632/2471 f 2517/2681/2517 2496/2667/2496 2497/2678/2497 f 2517/2681/2517 2497/2678/2497 2471/2632/2471 f 2516/2676/2516 2494/2675/2494 2496/2667/2496 f 2516/2676/2516 2496/2667/2496 2517/2681/2517 f 1356/2682/1356 2419/2571/2419 2422/2570/2422 f 1356/2682/1356 2422/2570/2422 1357/2683/1357 f 90/2684/90 1357/2683/1357 2422/2570/2422 f 90/2684/90 2422/2570/2422 2502/2685/2502 f 2507/2686/2507 1444/2687/1444 90/2688/90 f 2507/2686/2507 90/2688/90 2502/2689/2502 f 2507/2686/2507 2506/2690/2506 1445/2691/1445 f 2507/2686/2507 1445/2691/1445 1444/2687/1444 f 2504/2692/2504 2505/2693/2505 2508/2694/2508 f 2504/2692/2504 2508/2694/2508 2507/2686/2507 f 1446/2695/1446 1445/2691/1445 2506/2690/2506 f 1446/2695/1446 2506/2690/2506 2509/2696/2509 f 2176/2286/2176 2187/2285/2187 2177/2298/2177 f 2176/2286/2176 2177/2298/2177 2510/2697/2510 f 2175/2287/2175 2176/2286/2176 2510/2697/2510 f 2175/2287/2175 2510/2697/2510 2511/2185/2511 f 2513/2618/2513 2493/2698/2493 2459/2664/2459 f 2513/2618/2513 2459/2664/2459 2512/2619/2512 f 2461/2699/2461 2493/2698/2493 2513/2618/2513 f 2461/2699/2461 2513/2618/2513 2514/2621/2514 f 2468/2629/2468 46/2700/46 4/2672/4 f 2468/2629/2468 4/2672/4 2515/2671/2515 f 2500/2631/2500 2469/2630/2469 2516/2676/2516 f 2500/2631/2500 2516/2676/2516 2517/2681/2517 f 1/11/1 3/2701/3 2/12/2 f 1/11/1 4/20/4 3/2701/3 f 3/2701/3 4/20/4 5/2/5 f 5/2/5 6/1/6 3/2701/3 f 10/7/10 11/6/11 13/19/13 f 7/4/7 19/51/19 18/50/18 f 2/12/2 3/2701/3 6/1/6 f 20/21/20 22/18/22 21/70/21 f 25/15/25 26/56/26 24/16/24 f 19/51/19 7/4/7 24/16/24 f 24/16/24 26/56/26 19/51/19 f 37/37/37 43/43/43 34/34/34 f 46/46/46 9/8/9 4/20/4 f 41/41/41 45/45/45 40/40/40 f 26/56/26 49/60/49 48/48/48 f 19/51/19 26/56/26 48/48/48 f 1262/33/1262 51/62/51 33/30/33 f 1262/33/1262 1281/2702/1281 51/62/51 f 52/52/52 1281/2702/1281 1280/53/1280 f 49/60/49 26/56/26 54/55/54 f 31/26/31 55/59/55 30/25/30 f 32/31/32 56/2703/56 31/26/31 f 33/30/33 56/2703/56 32/31/32 f 57/61/57 58/2704/58 56/2703/56 f 57/61/57 56/2703/56 33/30/33 f 54/55/54 59/57/59 49/60/49 f 58/2704/58 60/58/60 56/2703/56 f 60/58/60 58/2704/58 59/57/59 f 58/2704/58 49/60/49 59/57/59 f 58/2704/58 57/61/57 49/60/49 f 60/58/60 55/59/55 56/2703/56 f 55/59/55 31/26/31 56/2703/56 f 51/62/51 1281/2702/1281 52/52/52 f 63/2705/63 61/63/61 62/64/62 f 63/2705/63 64/2706/64 61/63/61 f 45/45/45 61/63/61 47/47/47 f 47/47/47 65/66/65 44/44/44 f 109/65/109 43/43/43 44/44/44 f 21/70/21 36/36/36 20/21/20 f 21/70/21 66/69/66 36/36/36 f 39/39/39 66/69/66 42/42/42 f 36/36/36 66/69/66 39/39/39 f 12/5/12 67/68/67 11/6/11 f 11/6/11 67/68/67 23/17/23 f 22/18/22 67/68/67 21/70/21 f 23/17/23 67/68/67 22/18/22 f 42/42/42 67/68/67 12/5/12 f 68/2707/68 14/10/14 15/9/15 f 68/2707/68 15/9/15 16/13/16 f 69/71/69 71/2708/71 16/13/16 f 2/12/2 6/1/6 17/14/17 f 77/78/77 80/88/80 79/79/79 f 77/78/77 79/79/79 76/77/76 f 72/73/72 70/72/70 17/14/17 f 70/72/70 72/73/72 75/76/75 f 75/76/75 81/82/81 70/72/70 f 84/81/84 70/72/70 81/82/81 f 84/81/84 69/71/69 70/72/70 f 81/82/81 75/76/75 78/80/78 f 86/87/86 87/86/87 89/102/89 f 79/79/79 85/85/85 78/80/78 f 7/4/7 18/50/18 6/1/6 f 92/2709/92 69/71/69 84/81/84 f 69/71/69 92/2709/92 71/2708/71 f 82/84/82 92/2709/92 84/81/84 f 86/87/86 94/2710/94 85/85/85 f 92/90/92 94/98/94 86/94/86 f 85/85/85 94/2710/94 83/83/83 f 89/102/89 96/101/96 95/2711/95 f 68/93/68 71/2712/71 92/90/92 f 71/2708/71 68/2707/68 16/13/16 f 101/111/101 103/108/103 102/2713/102 f 102/2713/102 103/108/103 104/107/104 f 98/105/98 99/104/99 105/2714/105 f 110/2715/110 104/107/104 105/2714/105 f 102/2713/102 104/107/104 110/2715/110 f 103/108/103 108/113/108 111/114/111 f 105/2714/105 104/107/104 98/105/98 f 114/118/114 121/487/121 122/486/122 f 126/120/126 116/167/116 115/117/115 f 113/116/113 112/115/112 127/126/127 f 112/115/112 117/122/117 120/129/120 f 122/486/122 119/2716/119 118/123/118 f 446/485/446 121/487/121 124/2717/124 f 114/118/114 115/117/115 123/169/123 f 121/487/121 125/170/125 124/2717/124 f 121/487/121 123/169/123 125/170/125 f 118/123/118 119/2716/119 174/125/174 f 174/125/174 148/165/148 146/124/146 f 127/126/127 130/131/130 131/143/131 f 130/131/130 132/130/132 133/2718/133 f 133/2718/133 136/142/136 130/131/130 f 134/144/134 131/143/131 130/131/130 f 136/142/136 133/2718/133 139/132/139 f 157/141/157 134/144/134 136/142/136 f 136/142/136 134/144/134 130/131/130 f 132/130/132 137/134/137 138/133/138 f 138/133/138 133/2718/133 132/130/132 f 140/135/140 135/140/135 139/132/139 f 133/2718/133 138/133/138 139/132/139 f 137/134/137 132/130/132 141/137/141 f 141/137/141 143/138/143 142/2719/142 f 142/2719/142 137/134/137 141/137/141 f 145/139/145 144/136/144 199/182/199 f 117/122/117 146/124/146 147/183/147 f 147/183/147 120/129/120 117/122/117 f 144/136/144 120/129/120 147/183/147 f 119/2716/119 188/166/188 174/125/174 f 149/146/149 150/145/150 154/2720/154 f 150/145/150 151/147/151 154/2720/154 f 153/149/153 152/148/152 154/2720/154 f 149/146/149 154/2720/154 152/148/152 f 153/149/153 154/2720/154 151/147/151 f 159/150/159 161/157/161 155/151/155 f 149/146/149 152/148/152 165/2721/165 f 157/141/157 135/140/135 158/152/158 f 160/153/160 177/2722/177 161/157/161 f 137/134/137 142/2719/142 140/135/140 f 142/2719/142 143/138/143 164/2723/164 f 140/135/140 142/2719/142 164/2723/164 f 140/135/140 164/2723/164 135/140/135 f 178/155/178 162/154/162 163/2724/163 f 158/152/158 135/140/135 241/2725/241 f 135/140/135 164/2723/164 241/2725/241 f 160/153/160 158/152/158 241/2725/241 f 152/148/152 155/151/155 165/2721/165 f 131/143/131 149/146/149 165/2721/165 f 165/2721/165 156/2726/156 131/143/131 f 165/2721/165 155/151/155 166/2727/166 f 166/2727/166 155/151/155 167/156/167 f 155/151/155 161/157/161 167/156/167 f 169/159/169 166/2727/166 167/156/167 f 169/159/169 165/2721/165 166/2727/166 f 156/2726/156 165/2721/165 168/158/168 f 165/2721/165 169/159/169 168/158/168 f 156/2726/156 170/2728/170 128/127/128 f 156/2726/156 168/158/168 170/2728/170 f 131/143/131 128/127/128 127/126/127 f 571/588/571 173/163/173 191/162/191 f 118/123/118 114/118/114 122/486/122 f 172/179/172 148/165/148 189/164/189 f 161/2729/161 177/2730/177 227/236/227 f 176/2731/176 177/2722/177 164/2723/164 f 163/2724/163 162/154/162 176/2731/176 f 162/154/162 175/2732/175 176/2731/176 f 176/2731/176 175/2732/175 177/2722/177 f 163/2724/163 164/2723/164 178/155/178 f 178/155/178 164/2723/164 143/138/143 f 164/2723/164 163/2724/163 176/2731/176 f 121/487/121 114/118/114 123/169/123 f 125/170/125 123/169/123 179/168/179 f 116/167/116 126/120/126 180/2733/180 f 116/167/116 180/2733/180 182/173/182 f 180/2733/180 181/174/181 182/173/182 f 180/2733/180 126/120/126 181/174/181 f 124/2717/124 125/170/125 183/172/183 f 185/175/185 194/119/194 192/2734/192 f 148/165/148 172/179/172 187/178/187 f 568/585/568 571/588/571 189/164/189 f 191/162/191 189/164/189 571/588/571 f 194/119/194 195/2735/195 192/2734/192 f 185/175/185 192/2734/192 193/242/193 f 192/2734/192 195/2735/195 193/242/193 f 113/116/113 129/128/129 196/121/196 f 197/181/197 208/180/208 193/242/193 f 181/174/181 185/175/185 193/242/193 f 115/117/115 113/116/113 196/121/196 f 193/242/193 195/2735/195 197/181/197 f 197/181/197 195/2735/195 194/119/194 f 197/181/197 194/119/194 196/121/196 f 198/184/198 219/2736/219 200/185/200 f 200/185/200 199/182/199 198/184/198 f 148/165/148 198/184/198 146/124/146 f 148/165/148 219/2736/219 198/184/198 f 148/165/148 187/178/187 219/2736/219 f 219/2736/219 187/178/187 233/230/233 f 186/176/186 203/191/203 234/195/234 f 129/128/129 128/127/128 207/198/207 f 207/198/207 128/127/128 209/2737/209 f 128/127/128 170/2728/170 209/2737/209 f 209/200/209 170/2738/170 210/193/210 f 218/351/218 212/206/212 215/210/215 f 216/212/216 217/211/217 262/257/262 f 214/209/214 211/214/211 218/351/218 f 211/214/211 224/213/224 221/219/221 f 220/215/220 223/220/223 224/213/224 f 219/202/219 339/201/339 200/186/200 f 225/187/225 226/222/226 175/188/175 f 226/222/226 177/2730/177 175/188/175 f 168/2739/168 228/245/228 170/2740/170 f 168/2739/168 161/2729/161 228/245/228 f 228/245/228 227/236/227 245/238/245 f 228/245/228 229/247/229 170/2740/170 f 231/223/231 230/225/230 240/228/240 f 203/191/203 205/192/205 234/195/234 f 234/195/234 201/177/201 186/176/186 f 217/211/217 236/233/236 250/235/250 f 230/246/230 247/239/247 240/250/240 f 164/2723/164 177/2722/177 241/2725/241 f 241/2725/241 177/2722/177 160/153/160 f 161/157/161 159/150/159 160/153/160 f 191/162/191 172/179/172 189/164/189 f 243/241/243 182/173/182 181/174/181 f 243/241/243 184/171/184 182/173/182 f 206/199/206 242/244/242 208/180/208 f 161/2729/161 227/236/227 228/245/228 f 247/239/247 230/246/230 245/238/245 f 226/222/226 227/236/227 177/2730/177 f 246/2741/246 264/260/264 237/2742/237 f 248/234/248 264/2743/264 249/251/249 f 250/235/250 262/257/262 217/211/217 f 216/212/216 262/257/262 260/217/260 f 248/234/248 249/251/249 259/254/259 f 257/258/257 251/259/251 252/295/252 f 260/217/260 257/258/257 258/218/258 f 220/215/220 222/216/222 255/256/255 f 222/216/222 256/290/256 255/289/255 f 258/218/258 252/295/252 256/290/256 f 257/258/257 252/295/252 258/218/258 f 250/235/250 248/234/248 259/254/259 f 218/351/218 215/210/215 214/209/214 f 246/2741/246 263/261/263 264/260/264 f 266/263/266 265/262/265 285/2744/285 f 267/2745/267 285/2744/285 269/2746/269 f 269/2746/269 268/273/268 402/431/402 f 271/266/271 265/262/265 274/267/274 f 270/269/270 268/273/268 284/270/284 f 246/2741/246 254/291/254 263/261/263 f 273/264/273 276/271/276 272/2747/272 f 276/271/276 273/264/273 279/275/279 f 284/270/284 272/2747/272 276/271/276 f 277/272/277 278/274/278 280/428/280 f 278/274/278 281/277/281 280/428/280 f 279/275/279 278/274/278 276/271/276 f 276/271/276 278/274/278 277/272/277 f 273/264/273 272/2747/272 283/265/283 f 283/265/283 272/2747/272 284/270/284 f 285/2744/285 265/262/265 271/266/271 f 285/2744/285 271/266/271 268/273/268 f 285/2744/285 267/2745/267 266/263/266 f 285/2744/285 268/273/268 269/2746/269 f 254/291/254 255/289/255 292/287/292 f 290/285/290 342/354/342 294/398/294 f 294/398/294 291/298/291 290/285/290 f 298/278/298 275/268/275 263/261/263 f 290/285/290 291/298/291 293/288/293 f 249/251/249 264/2743/264 266/296/266 f 267/297/267 269/279/269 253/252/253 f 308/310/308 314/313/314 315/311/315 f 312/317/312 317/316/317 313/350/313 f 308/310/308 309/318/309 314/313/314 f 314/313/314 310/312/310 315/311/315 f 317/316/317 311/320/311 313/350/313 f 306/308/306 304/306/304 323/321/323 f 309/318/309 308/310/308 332/336/332 f 315/311/315 310/312/310 318/333/318 f 305/307/305 307/309/307 319/323/319 f 307/309/307 315/311/315 319/323/319 f 320/325/320 403/424/403 321/326/321 f 323/321/323 304/306/304 302/304/302 f 324/324/324 319/323/319 349/332/349 f 403/424/403 320/325/320 432/2748/432 f 331/344/331 333/337/333 329/339/329 f 329/340/329 326/334/326 331/343/331 f 318/333/318 310/312/310 345/346/345 f 336/319/336 309/318/309 346/348/346 f 339/201/339 211/214/211 221/219/221 f 339/201/339 221/219/221 200/186/200 f 221/219/221 225/187/225 200/186/200 f 170/2749/170 341/224/341 210/353/210 f 291/298/291 343/2750/343 344/328/344 f 310/312/310 334/315/334 345/346/345 f 309/318/309 332/336/332 346/348/346 f 330/342/330 318/333/318 345/346/345 f 346/348/346 332/336/332 330/345/330 f 347/355/347 327/322/327 323/321/323 f 322/329/322 384/2751/384 351/2752/351 f 344/328/344 384/2751/384 322/329/322 f 359/370/359 361/373/361 360/371/360 f 363/374/363 367/2753/367 364/375/364 f 359/370/359 365/376/365 361/373/361 f 361/373/361 362/372/362 360/371/360 f 366/377/366 367/2753/367 363/374/363 f 357/368/357 355/366/355 368/378/368 f 356/367/356 358/369/358 372/382/372 f 358/369/358 360/371/360 372/382/372 f 368/378/368 355/366/355 353/365/353 f 373/383/373 372/382/372 383/384/383 f 371/380/371 377/390/377 378/2754/378 f 378/2755/378 377/394/377 370/385/370 f 378/2755/378 370/385/370 375/387/375 f 375/388/375 371/380/371 378/2754/378 f 371/380/371 362/372/362 379/391/379 f 366/377/366 365/376/365 380/393/380 f 367/2753/367 381/392/381 364/375/364 f 381/395/381 367/2753/367 366/377/366 f 362/372/362 364/375/364 379/391/379 f 365/376/365 370/385/370 380/393/380 f 377/390/377 371/380/371 379/391/379 f 380/393/380 370/385/370 377/394/377 f 373/383/373 383/384/383 384/427/384 f 344/363/344 354/362/354 373/383/373 f 373/383/373 384/427/384 344/363/344 f 343/2750/343 294/398/294 385/400/385 f 291/298/291 294/398/294 343/2750/343 f 386/399/386 342/354/342 387/294/387 f 351/405/351 384/2756/384 395/406/395 f 349/332/349 350/361/350 432/335/432 f 393/413/393 386/399/386 387/294/387 f 396/414/396 393/413/393 389/403/389 f 385/400/385 386/399/386 394/410/394 f 393/413/393 387/294/387 389/403/389 f 297/292/297 299/299/299 321/326/321 f 434/2757/434 391/421/391 433/420/433 f 400/422/400 398/418/398 397/417/397 f 397/417/397 399/423/399 400/422/400 f 368/378/368 385/401/385 394/415/394 f 401/425/401 399/423/399 397/417/397 f 268/273/268 270/269/270 402/431/402 f 408/439/408 409/438/409 410/441/410 f 412/440/412 413/443/413 414/2758/414 f 408/439/408 410/441/410 415/444/415 f 410/441/410 409/438/409 411/442/411 f 416/445/416 412/440/412 414/2758/414 f 406/437/406 417/446/417 405/434/405 f 404/433/404 421/450/421 407/436/407 f 407/436/407 421/450/421 409/438/409 f 419/449/419 427/2759/427 426/457/426 f 427/2760/427 424/452/424 426/461/426 f 427/2760/427 423/453/423 424/452/424 f 423/456/423 427/2759/427 419/449/419 f 419/449/419 428/459/428 411/442/411 f 416/445/416 429/462/429 415/444/415 f 413/443/413 430/458/430 414/2758/414 f 430/460/430 416/445/416 414/2758/414 f 411/442/411 428/459/428 413/443/413 f 415/444/415 429/462/429 424/452/424 f 426/457/426 428/459/428 419/449/419 f 429/462/429 426/461/426 424/452/424 f 421/450/421 432/468/432 422/451/422 f 403/432/403 421/450/421 404/433/404 f 421/450/421 403/432/403 432/468/432 f 405/434/405 417/446/417 399/2761/399 f 417/446/417 433/466/433 399/2761/399 f 405/434/405 399/2761/399 401/435/401 f 432/2762/432 350/2763/350 435/2764/435 f 435/2764/435 434/2757/434 433/420/433 f 350/2763/350 434/2757/434 435/2764/435 f 441/478/441 446/485/446 442/479/442 f 183/172/183 442/479/442 124/2717/124 f 183/172/183 184/171/184 442/479/442 f 442/479/442 446/485/446 124/2717/124 f 588/2765/588 564/594/564 119/2716/119 f 447/484/447 558/483/558 449/2766/449 f 449/2766/449 122/486/122 447/484/447 f 451/488/451 242/490/242 204/491/204 f 477/524/477 476/523/476 478/2767/478 f 478/2767/478 480/526/480 481/550/481 f 478/2767/478 476/523/476 480/526/480 f 481/550/481 480/526/480 485/2768/485 f 480/526/480 479/525/479 482/527/482 f 480/526/480 482/527/482 485/2768/485 f 482/527/482 519/530/519 485/2768/485 f 498/522/498 488/532/488 487/531/487 f 487/531/487 468/513/468 498/522/498 f 468/513/468 487/531/487 491/536/491 f 497/541/497 496/540/496 493/537/493 f 171/160/171 204/190/204 190/161/190 f 475/521/475 499/543/499 498/522/498 f 498/522/498 501/553/501 500/2769/500 f 499/543/499 503/545/503 501/553/501 f 475/521/475 477/524/477 505/544/505 f 477/524/477 478/2767/478 505/544/505 f 478/2767/478 481/550/481 505/544/505 f 481/550/481 504/2770/504 505/544/505 f 481/550/481 502/547/502 504/2770/504 f 504/2770/504 503/545/503 505/544/505 f 504/2770/504 506/2771/506 512/2772/512 f 504/2770/504 502/547/502 506/2771/506 f 506/2771/506 502/547/502 507/546/507 f 506/2771/506 507/546/507 510/555/510 f 510/555/510 512/2772/512 506/2771/506 f 507/546/507 509/549/509 510/555/510 f 481/550/481 485/2768/485 519/530/519 f 503/545/503 504/2770/504 511/554/511 f 504/2770/504 512/2772/512 511/554/511 f 510/555/510 511/554/511 512/2772/512 f 514/551/514 513/557/513 537/552/537 f 500/2769/500 501/553/501 537/552/537 f 498/522/498 499/543/499 501/553/501 f 516/2773/516 517/2774/517 519/530/519 f 517/2774/517 508/548/508 519/530/519 f 517/2774/517 516/2773/516 518/2775/518 f 519/530/519 515/556/515 516/2773/516 f 486/529/486 515/556/515 519/530/519 f 515/556/515 173/542/173 538/570/538 f 173/163/173 571/588/571 538/2776/538 f 508/548/508 517/2774/517 520/559/520 f 520/559/520 509/549/509 508/548/508 f 517/2774/517 518/2775/518 520/559/520 f 520/559/520 510/555/510 509/549/509 f 518/2775/518 516/2773/516 542/560/542 f 542/560/542 520/559/520 518/2775/518 f 526/566/526 473/519/473 472/518/472 f 532/2777/532 523/563/523 527/2778/527 f 523/563/523 469/515/469 527/2778/527 f 534/2779/534 527/2778/527 529/2780/529 f 529/2780/529 528/514/528 531/567/531 f 527/2778/527 469/515/469 528/514/528 f 529/2780/529 531/567/531 533/568/533 f 530/2781/530 492/535/492 494/538/494 f 534/2779/534 532/2777/532 527/2778/527 f 492/535/492 530/2781/530 533/568/533 f 533/568/533 530/2781/530 529/2780/529 f 528/514/528 469/515/469 458/503/458 f 529/2780/529 530/2781/530 534/2779/534 f 468/513/468 491/536/491 531/567/531 f 531/567/531 528/514/528 468/513/468 f 528/514/528 529/2780/529 527/2778/527 f 535/2782/535 467/512/467 466/511/466 f 466/511/466 473/519/473 535/2782/535 f 496/540/496 495/539/495 493/537/493 f 498/522/498 500/2769/500 536/2783/536 f 500/2769/500 537/552/537 536/2783/536 f 513/557/513 536/2783/536 537/552/537 f 495/539/495 498/522/498 536/2783/536 f 516/2773/516 515/556/515 541/569/541 f 541/569/541 542/560/542 516/2773/516 f 541/569/541 543/573/543 542/560/542 f 543/573/543 540/572/540 544/2784/544 f 543/573/543 544/2784/544 545/574/545 f 542/560/542 543/573/543 545/574/545 f 592/607/592 548/582/548 549/579/549 f 549/579/549 551/577/551 550/576/550 f 552/578/552 443/480/443 445/482/445 f 552/578/552 551/577/551 553/2785/553 f 554/2786/554 558/481/558 443/480/443 f 443/480/443 552/578/552 554/2786/554 f 557/581/557 553/2785/553 551/577/551 f 553/2785/553 557/581/557 556/2787/556 f 554/2786/554 552/578/552 556/2787/556 f 556/2787/556 552/578/552 553/2785/553 f 556/2787/556 558/481/558 554/2786/554 f 558/483/558 556/2788/556 449/2766/449 f 548/582/548 592/607/592 593/601/593 f 812/2789/812 813/2790/813 741/2791/741 f 565/2792/565 450/584/450 188/166/188 f 564/594/564 448/593/448 119/2716/119 f 119/2716/119 448/593/448 589/2793/589 f 119/2716/119 589/2793/589 188/166/188 f 563/2794/563 565/2792/565 188/166/188 f 563/2794/563 567/2795/567 587/2796/587 f 565/2792/565 587/2796/587 566/2797/566 f 566/2797/566 450/584/450 565/2792/565 f 587/2796/587 565/2792/565 563/2794/563 f 569/589/569 571/588/571 573/587/573 f 568/585/568 570/2798/570 572/586/572 f 570/2798/570 585/2799/585 572/586/572 f 572/586/572 583/2800/583 573/587/573 f 573/587/573 583/2800/583 569/589/569 f 576/2801/576 579/2802/579 575/2803/575 f 571/588/571 569/589/569 574/2804/574 f 579/2802/579 539/571/539 575/2803/575 f 539/571/539 538/570/538 575/2803/575 f 575/2803/575 538/570/538 576/2801/576 f 576/2805/576 574/2804/574 577/592/577 f 577/592/577 574/2804/574 569/589/569 f 538/2776/538 574/2804/574 576/2805/576 f 574/2804/574 538/2776/538 571/588/571 f 576/2801/576 582/2806/582 579/2802/579 f 586/591/586 581/2807/581 580/2808/580 f 578/590/578 581/2807/581 586/591/586 f 576/2801/576 580/639/580 582/2806/582 f 580/2808/580 576/2805/576 577/592/577 f 569/589/569 584/2809/584 578/590/578 f 578/590/578 584/2809/584 570/2798/570 f 569/589/569 583/2800/583 584/2809/584 f 583/2800/583 572/586/572 585/2799/585 f 570/2798/570 584/2809/584 585/2799/585 f 585/2799/585 584/2809/584 583/2800/583 f 580/2808/580 577/592/577 586/591/586 f 570/2798/570 568/585/568 450/584/450 f 450/584/450 566/2797/566 607/2810/607 f 566/2797/566 587/2796/587 607/2810/607 f 607/2810/607 570/2798/570 450/584/450 f 607/2810/607 578/590/578 570/2798/570 f 587/2796/587 567/2795/567 590/596/590 f 567/2795/567 448/593/448 590/596/590 f 119/2716/119 122/486/122 588/2765/588 f 448/593/448 567/2795/567 589/2793/589 f 589/2793/589 567/2795/567 563/2794/563 f 589/2793/589 563/2794/563 188/166/188 f 122/486/122 449/2766/449 588/2765/588 f 564/594/564 588/2765/588 591/595/591 f 449/2766/449 556/2788/556 588/2765/588 f 549/579/549 550/576/550 592/607/592 f 550/576/550 602/2811/602 592/607/592 f 602/2811/602 601/606/601 594/605/594 f 745/771/745 595/600/595 744/599/744 f 596/770/596 636/657/636 597/2812/597 f 598/602/598 594/605/594 599/603/599 f 548/582/548 593/601/593 600/583/600 f 596/770/596 559/604/559 601/606/601 f 559/604/559 596/770/596 638/655/638 f 602/2811/602 594/605/594 592/607/592 f 607/2810/607 587/2796/587 590/596/590 f 607/623/607 590/612/590 604/611/604 f 638/655/638 597/2812/597 637/656/637 f 637/656/637 597/2812/597 636/657/636 f 604/611/604 993/620/993 607/623/607 f 605/610/605 606/659/606 609/2813/609 f 604/611/604 605/610/605 608/1000/608 f 578/2814/578 607/2815/607 610/641/610 f 610/641/610 581/640/581 578/2814/578 f 610/622/610 994/621/994 995/624/995 f 609/2813/609 897/876/897 613/875/613 f 996/2816/996 621/2817/621 611/1001/611 f 611/1001/611 621/2817/621 614/2818/614 f 609/2813/609 613/875/613 996/2816/996 f 609/2813/609 608/1000/608 605/610/605 f 642/1002/642 650/2819/650 619/627/619 f 619/627/619 616/2820/616 620/628/620 f 613/875/613 615/874/615 621/2817/621 f 621/2817/621 615/874/615 622/2821/622 f 614/2818/614 621/2817/621 622/2821/622 f 614/2818/614 642/1002/642 611/1001/611 f 619/627/619 995/624/995 642/1002/642 f 616/2822/616 645/2823/645 643/632/643 f 650/2819/650 642/1002/642 645/2824/645 f 617/642/617 618/630/618 648/629/648 f 620/631/620 616/2822/616 643/632/643 f 628/636/628 625/634/625 627/633/627 f 624/635/624 626/637/626 540/572/540 f 626/637/626 545/574/545 544/2784/544 f 626/637/626 544/2784/544 540/572/540 f 624/635/624 540/572/540 539/571/539 f 539/571/539 579/2802/579 624/635/624 f 579/2802/579 582/2806/582 624/635/624 f 545/574/545 626/637/626 627/633/627 f 624/635/624 582/2806/582 580/639/580 f 591/595/591 588/2765/588 556/2788/556 f 630/646/630 632/649/632 634/651/634 f 603/654/603 560/650/560 635/652/635 f 936/1182/936 612/2825/612 606/659/606 f 596/770/596 597/2812/597 638/655/638 f 630/646/630 560/650/560 603/654/603 f 614/2818/614 622/2821/622 640/2826/640 f 622/2821/622 651/2827/651 640/2826/640 f 622/2821/622 615/874/615 651/2827/651 f 614/2818/614 639/2828/639 642/1002/642 f 639/2828/639 645/2824/645 642/1002/642 f 614/2818/614 640/2826/640 641/2829/641 f 639/2830/639 644/660/644 645/2823/645 f 644/660/644 643/632/643 645/2823/645 f 623/2831/623 643/632/643 646/662/646 f 643/632/643 623/2831/623 648/629/648 f 625/2832/625 628/643/628 617/642/617 f 648/629/648 623/2831/623 625/2832/625 f 617/642/617 648/629/648 625/2832/625 f 645/2824/645 616/2820/616 650/2819/650 f 650/2819/650 616/2820/616 619/627/619 f 614/2818/614 641/2829/641 639/2828/639 f 644/2833/644 639/2834/639 653/674/653 f 644/2833/644 653/674/653 673/673/673 f 653/671/653 654/670/654 656/678/656 f 665/683/665 659/2835/659 660/684/660 f 661/685/661 659/2835/659 665/686/665 f 661/685/661 669/691/669 659/2835/659 f 669/691/669 660/684/660 659/2835/659 f 671/693/671 670/692/670 669/691/669 f 668/690/668 666/689/666 674/694/674 f 673/673/673 676/698/676 644/2833/644 f 672/688/672 674/694/674 677/696/677 f 672/688/672 677/696/677 678/697/678 f 729/2836/729 730/2837/730 771/2838/771 f 680/701/680 679/700/679 684/738/684 f 679/700/679 710/730/710 684/738/684 f 690/714/690 703/723/703 698/715/698 f 705/2839/705 702/2840/702 704/2841/704 f 705/2839/705 706/2842/706 682/902/682 f 692/2843/692 694/2844/694 695/2845/695 f 681/705/681 699/710/699 696/718/696 f 699/710/699 688/720/688 696/718/696 f 696/718/696 694/717/694 692/782/692 f 688/720/688 691/722/691 701/721/701 f 701/721/701 691/722/691 703/723/703 f 703/723/703 691/722/691 698/715/698 f 704/724/704 703/723/703 689/712/689 f 706/2842/706 705/2839/705 704/2841/704 f 694/2844/694 693/2846/693 709/2847/709 f 704/724/704 689/712/689 706/725/706 f 708/727/708 695/2845/695 694/2844/694 f 693/2846/693 750/729/750 709/2847/709 f 694/2844/694 749/728/749 708/727/708 f 689/712/689 690/714/690 711/713/711 f 720/740/720 716/734/716 714/733/714 f 718/742/718 713/732/713 712/731/712 f 690/714/690 689/712/689 703/723/703 f 718/741/718 720/740/720 724/749/724 f 724/749/724 725/748/725 728/2848/728 f 725/748/725 726/750/726 728/2848/728 f 726/750/726 727/747/727 728/2848/728 f 727/747/727 724/746/724 728/2848/728 f 730/781/730 678/2849/678 677/778/677 f 676/755/676 678/762/678 732/756/732 f 730/763/730 729/758/729 734/761/734 f 737/764/737 735/2850/735 736/765/736 f 738/766/738 735/2850/735 739/767/739 f 739/767/739 735/2850/735 737/764/737 f 609/2813/609 606/659/606 612/2825/612 f 629/647/629 742/769/742 741/2791/741 f 813/2790/813 746/2851/746 741/2791/741 f 741/2791/741 740/768/740 562/2852/562 f 629/647/629 630/646/630 742/769/742 f 742/769/742 740/768/740 741/2791/741 f 742/769/742 630/646/630 743/598/743 f 743/598/743 630/646/630 603/654/603 f 744/599/744 636/657/636 596/770/596 f 601/606/601 602/2811/602 745/771/745 f 741/2791/741 562/2852/562 812/2789/812 f 746/2851/746 629/647/629 741/2791/741 f 813/2853/813 747/2854/747 748/2855/748 f 748/2856/748 746/2851/746 813/2790/813 f 629/647/629 746/2851/746 748/2856/748 f 694/2844/694 709/2847/709 749/728/749 f 749/728/749 709/2847/709 750/729/750 f 693/2846/693 704/2841/704 750/729/750 f 693/716/693 697/719/697 704/724/704 f 704/2841/704 702/2840/702 750/729/750 f 702/2840/702 707/726/707 750/729/750 f 695/2845/695 708/727/708 751/2857/751 f 751/2857/751 753/2858/753 754/788/754 f 753/2858/753 755/2859/755 754/788/754 f 788/2860/788 776/790/776 787/789/787 f 751/2857/751 752/773/752 753/2858/753 f 753/2858/753 752/773/752 758/784/758 f 752/773/752 757/772/757 758/784/758 f 752/773/752 707/726/707 759/774/759 f 758/784/758 757/772/757 760/776/760 f 755/2859/755 753/2858/753 763/783/763 f 753/2858/753 758/784/758 763/783/763 f 763/783/763 774/803/774 764/2861/764 f 759/774/759 707/726/707 765/2862/765 f 765/2862/765 707/726/707 702/2840/702 f 702/2840/702 705/2839/705 766/2863/766 f 765/2862/765 702/2840/702 766/2863/766 f 705/2839/705 765/2862/765 766/2863/766 f 765/2862/765 761/775/761 759/774/759 f 771/2838/771 730/2837/730 920/2864/920 f 924/917/924 769/904/769 768/903/768 f 767/702/767 680/701/680 771/2838/771 f 771/753/771 680/706/680 681/705/681 f 692/782/692 700/2865/700 772/751/772 f 772/751/772 700/2865/700 729/752/729 f 708/727/708 707/726/707 751/2857/751 f 707/726/707 752/773/752 751/2857/751 f 763/783/763 799/804/799 774/803/774 f 775/786/775 773/785/773 762/777/762 f 763/783/763 775/786/775 799/804/799 f 776/790/776 780/2866/780 777/787/777 f 764/2861/764 788/2860/788 787/789/787 f 788/2860/788 764/2861/764 778/2867/778 f 764/2861/764 774/803/774 778/2867/778 f 764/2861/764 755/2859/755 763/783/763 f 788/2860/788 778/2867/778 805/2868/805 f 805/2868/805 776/790/776 788/2860/788 f 804/2869/804 780/2866/780 805/2868/805 f 780/2866/780 776/790/776 805/2868/805 f 782/792/782 756/791/756 780/2866/780 f 780/2866/780 756/791/756 777/787/777 f 782/792/782 803/2870/803 784/793/784 f 785/2871/785 782/792/782 781/800/781 f 785/2871/785 781/800/781 802/2872/802 f 754/788/754 755/2859/755 787/789/787 f 787/789/787 755/2859/755 764/2861/764 f 761/775/761 795/2873/795 789/2874/789 f 762/777/762 789/2874/789 790/2875/790 f 775/786/775 762/777/762 798/2876/798 f 790/2875/790 789/2874/789 791/795/791 f 761/775/761 765/2862/765 792/2877/792 f 789/2874/789 762/777/762 761/775/761 f 761/775/761 792/2877/792 795/2873/795 f 762/777/762 790/2875/790 798/2876/798 f 798/2876/798 799/804/799 775/786/775 f 790/2875/790 793/2878/793 798/2876/798 f 790/2875/790 791/795/791 793/2878/793 f 795/2873/795 796/2879/796 789/2874/789 f 795/2873/795 792/2877/792 796/2879/796 f 796/2879/796 792/2877/792 794/796/794 f 796/2879/796 794/796/794 797/2880/797 f 797/2880/797 789/2874/789 796/2879/796 f 794/796/794 791/795/791 797/2880/797 f 797/2880/797 791/795/791 789/2874/789 f 792/2877/792 765/2862/765 826/2881/826 f 798/2876/798 793/2878/793 799/804/799 f 802/2872/802 803/2870/803 785/2871/785 f 803/2870/803 802/2872/802 784/793/784 f 804/2869/804 805/2868/805 806/802/806 f 780/2866/780 779/801/779 781/800/781 f 804/2869/804 779/801/779 780/2866/780 f 780/2866/780 781/800/781 782/792/782 f 779/801/779 804/2869/804 806/802/806 f 806/802/806 805/2868/805 778/2867/778 f 800/798/800 793/2878/793 791/795/791 f 799/804/799 793/2878/793 810/805/810 f 793/2878/793 800/798/800 810/805/810 f 809/806/809 806/802/806 778/2867/778 f 811/807/811 812/1227/812 1196/1224/1196 f 813/2853/813 811/807/811 815/2882/815 f 808/809/808 814/811/814 815/2882/815 f 815/2882/815 814/811/814 816/1004/816 f 815/2882/815 816/1004/816 817/2883/817 f 747/2854/747 813/2853/813 815/2882/815 f 747/2854/747 815/2882/815 818/2884/818 f 815/2882/815 817/2883/817 818/2884/818 f 818/2884/818 748/2855/748 747/2854/747 f 820/812/820 819/810/819 821/2885/821 f 821/2885/821 819/810/819 800/798/800 f 800/798/800 801/797/801 821/2885/821 f 822/814/822 820/812/820 821/2885/821 f 821/2885/821 801/797/801 822/814/822 f 765/2862/765 705/2839/705 826/2881/826 f 705/2839/705 823/2886/823 826/2881/826 f 824/1020/824 823/2886/823 828/900/828 f 828/900/828 825/834/825 824/1020/824 f 833/2887/833 823/2886/823 836/1023/836 f 825/834/825 828/900/828 914/872/914 f 823/2886/823 827/901/827 828/900/828 f 827/901/827 823/2886/823 705/2839/705 f 826/2881/826 830/813/830 829/815/829 f 829/815/829 801/797/801 794/796/794 f 792/2877/792 826/2881/826 829/815/829 f 829/815/829 794/796/794 792/2877/792 f 830/813/830 826/2881/826 831/2888/831 f 830/813/830 831/2888/831 837/1008/837 f 831/2888/831 833/2887/833 837/1008/837 f 837/1008/837 833/2887/833 834/2889/834 f 832/1009/832 834/2889/834 835/1022/835 f 835/1022/835 834/2889/834 836/1023/836 f 823/2886/823 824/1020/824 836/1023/836 f 836/1023/836 834/2889/834 833/2887/833 f 834/2889/834 832/1009/832 837/1008/837 f 831/2888/831 826/2881/826 833/2887/833 f 833/2887/833 826/2881/826 823/2886/823 f 824/1020/824 825/834/825 863/833/863 f 841/818/841 838/817/838 843/835/843 f 824/1020/824 863/833/863 1024/2890/1024 f 865/1011/865 844/836/844 864/838/864 f 862/837/862 842/822/842 845/828/845 f 846/926/846 867/2891/867 862/837/862 f 862/837/862 845/828/845 846/926/846 f 851/826/851 873/831/873 852/827/852 f 849/823/849 851/826/851 852/827/852 f 858/2892/858 855/840/855 874/2893/874 f 857/839/857 856/843/856 873/831/873 f 859/824/859 861/870/861 926/2894/926 f 859/824/859 848/820/848 861/870/861 f 838/817/838 842/822/842 843/835/843 f 843/835/843 842/822/842 862/837/862 f 867/2891/867 864/838/864 862/837/862 f 927/871/927 839/816/839 840/819/840 f 840/819/840 913/873/913 927/871/927 f 864/838/864 818/2884/818 865/1011/865 f 865/1011/865 818/2884/818 817/2883/817 f 748/2855/748 818/2884/818 866/2895/866 f 629/2896/629 748/2855/748 866/2895/866 f 866/2897/866 633/653/633 631/648/631 f 631/648/631 629/647/629 866/2897/866 f 866/2895/866 867/2891/867 932/919/932 f 855/840/855 858/2892/858 883/841/883 f 858/2892/858 882/855/882 883/841/883 f 873/831/873 872/949/872 869/845/869 f 872/949/872 856/843/856 1380/844/1380 f 856/843/856 872/949/872 873/831/873 f 873/831/873 851/826/851 857/839/857 f 855/840/855 850/825/850 874/2893/874 f 874/2893/874 850/825/850 860/864/860 f 946/856/946 868/850/868 875/869/875 f 946/856/946 875/869/875 949/957/949 f 877/849/877 875/869/875 868/850/868 f 882/855/882 858/2892/858 885/861/885 f 885/861/885 881/847/881 882/855/882 f 946/856/946 1380/844/1380 884/842/884 f 858/2892/858 887/857/887 885/861/885 f 874/2893/874 886/858/886 887/857/887 f 887/857/887 858/2892/858 874/2893/874 f 860/864/860 926/2894/926 888/865/888 f 896/863/896 874/2893/874 860/864/860 f 896/863/896 886/858/886 874/2893/874 f 897/876/897 899/2898/899 901/878/901 f 898/881/898 900/2899/900 903/882/903 f 900/2899/900 919/884/919 903/882/903 f 902/883/902 651/2900/651 615/880/615 f 651/2900/651 902/883/902 906/2901/906 f 902/883/902 907/887/907 906/2901/906 f 906/2901/906 904/2902/904 651/2900/651 f 904/888/904 652/668/652 651/667/651 f 906/2901/906 907/887/907 911/894/911 f 911/895/911 909/893/909 906/892/906 f 919/884/919 900/2899/900 912/2903/912 f 927/871/927 913/873/913 916/897/916 f 915/915/915 768/903/768 912/907/912 f 827/901/827 705/2839/705 682/902/682 f 915/896/915 914/872/914 682/902/682 f 769/904/769 770/2904/770 918/2905/918 f 770/2904/770 921/779/921 923/910/923 f 918/2905/918 770/2904/770 923/910/923 f 767/916/767 920/2906/920 922/780/922 f 920/2864/920 767/702/767 771/2838/771 f 921/779/921 925/2907/925 922/780/922 f 922/780/922 925/2907/925 767/916/767 f 923/913/923 917/906/917 918/905/918 f 922/780/922 920/2906/920 730/781/730 f 770/2904/770 769/904/769 925/2907/925 f 925/2907/925 769/904/769 924/917/924 f 925/2907/925 924/917/924 767/916/767 f 921/779/921 770/2904/770 925/2907/925 f 900/899/900 901/934/901 928/933/928 f 928/933/928 927/871/927 916/897/916 f 928/933/928 916/897/916 900/899/900 f 899/2898/899 897/876/897 612/2825/612 f 899/2898/899 612/2825/612 929/2908/929 f 612/2825/612 936/1182/936 929/2908/929 f 609/2813/609 612/2825/612 897/876/897 f 634/2909/634 633/918/633 930/617/930 f 635/616/635 634/2909/634 930/617/930 f 932/919/932 867/2891/867 931/920/931 f 867/2891/867 846/926/846 931/920/931 f 932/919/932 633/918/633 866/2895/866 f 811/807/811 813/2853/813 812/1227/812 f 854/829/854 953/924/953 934/921/934 f 937/925/937 931/920/931 846/926/846 f 853/830/853 935/922/935 937/925/937 f 936/618/936 937/925/937 929/2910/929 f 933/923/933 955/951/955 953/924/953 f 888/865/888 926/2894/926 939/931/939 f 926/2894/926 861/870/861 939/931/939 f 933/923/933 871/832/871 870/846/870 f 889/862/889 940/935/940 943/2911/943 f 891/860/891 890/859/890 940/935/940 f 889/862/889 891/860/891 940/935/940 f 894/868/894 889/862/889 943/2911/943 f 893/867/893 894/868/894 942/936/942 f 894/868/894 943/2911/943 942/936/942 f 946/856/946 1379/1448/1379 1380/844/1380 f 1379/1448/1379 946/856/946 949/957/949 f 945/943/945 943/942/943 940/953/940 f 952/946/952 945/943/945 951/950/951 f 944/940/944 945/943/945 952/946/952 f 955/951/955 933/923/933 956/952/956 f 956/952/956 933/923/933 870/846/870 f 935/922/935 899/956/899 929/2910/929 f 929/2910/929 937/925/937 935/922/935 f 935/922/935 934/921/934 899/956/899 f 875/869/875 880/854/880 957/958/957 f 957/958/957 961/961/961 962/964/962 f 1115/969/1115 960/962/960 1153/974/1153 f 1078/968/1078 961/961/961 1114/970/1114 f 965/971/965 962/964/962 1077/967/1077 f 973/981/973 976/991/976 977/982/977 f 973/981/973 974/992/974 976/991/976 f 976/991/976 975/988/975 977/982/977 f 968/976/968 970/978/970 981/985/981 f 970/978/970 972/980/972 981/985/981 f 969/977/969 967/975/967 1028/1024/1028 f 971/979/971 969/977/969 1028/1024/1028 f 988/999/988 1052/998/1052 991/2912/991 f 988/999/988 991/2912/991 992/941/992 f 1187/1090/1187 990/1089/990 991/2913/991 f 1052/998/1052 1187/1085/1187 991/2912/991 f 991/2913/991 990/1089/990 989/2914/989 f 991/2912/991 989/2915/989 992/941/992 f 604/611/604 608/1000/608 993/620/993 f 611/1001/611 608/1000/608 996/2816/996 f 996/2816/996 608/1000/608 609/2813/609 f 996/2816/996 613/875/613 621/2817/621 f 997/1005/997 998/2916/998 1000/1003/1000 f 1000/1003/1000 817/2883/817 816/1004/816 f 814/811/814 820/812/820 997/1005/997 f 998/2916/998 999/1017/999 1000/1003/1000 f 1000/1003/1000 999/1017/999 817/2883/817 f 999/1017/999 865/1011/865 817/2883/817 f 1002/2917/1002 844/836/844 1003/1010/1003 f 1004/2918/1004 1011/2919/1011 1005/2920/1005 f 1011/2919/1011 1001/2921/1001 1005/2920/1005 f 1004/2918/1004 1005/2920/1005 1008/2922/1008 f 1005/2920/1005 1006/2923/1006 1008/2922/1008 f 1006/2923/1006 1022/1015/1022 1008/2922/1008 f 1022/1015/1022 1007/1014/1007 1008/2922/1008 f 1008/2922/1008 1009/1007/1009 1004/2918/1004 f 1008/2922/1008 1007/1014/1007 1009/1007/1009 f 1004/2918/1004 1010/1006/1010 1011/2919/1011 f 1004/2918/1004 1009/1007/1009 1010/1006/1010 f 1009/1007/1009 1007/1014/1007 822/814/822 f 1010/1006/1010 832/1009/832 1011/2919/1011 f 1001/2921/1001 1011/2919/1011 1012/1021/1012 f 1012/1021/1012 1011/2919/1011 835/1022/835 f 832/1009/832 835/1022/835 1011/2919/1011 f 1023/1019/1023 1019/1018/1019 1020/2924/1020 f 1003/1010/1003 1013/1012/1013 1014/2925/1014 f 1001/2921/1001 1003/1010/1003 1014/2925/1014 f 1003/1010/1003 1001/2921/1001 1002/2917/1002 f 1014/2925/1014 1006/2923/1006 1001/2921/1001 f 1006/2923/1006 1005/2920/1005 1001/2921/1001 f 1014/2925/1014 1013/1012/1013 1006/2923/1006 f 1006/2923/1006 1021/2926/1021 1022/1015/1022 f 1022/1015/1022 998/2916/998 997/1005/997 f 1022/1015/1022 997/1005/997 1015/1016/1015 f 997/1005/997 820/812/820 1015/1016/1015 f 822/814/822 1007/1014/1007 1016/1013/1016 f 1016/1013/1016 1017/2927/1017 1018/2928/1018 f 1016/1013/1016 1015/1016/1015 1017/2927/1017 f 1015/1016/1015 820/812/820 1017/2927/1017 f 1017/2927/1017 820/812/820 1018/2928/1018 f 820/812/820 822/814/822 1018/2928/1018 f 1018/2928/1018 822/814/822 1016/1013/1016 f 1019/1018/1019 999/1017/999 998/2916/998 f 1019/1018/1019 998/2916/998 1021/2926/1021 f 1021/2926/1021 998/2916/998 1022/1015/1022 f 1023/1019/1023 1013/1012/1013 865/1011/865 f 1020/2924/1020 1019/1018/1019 1021/2926/1021 f 1023/1019/1023 1020/2924/1020 1013/1012/1013 f 1013/1012/1013 1020/2924/1020 1006/2923/1006 f 1006/2923/1006 1020/2924/1020 1021/2926/1021 f 844/836/844 1002/2917/1002 1024/2890/1024 f 1001/2921/1001 1012/1021/1012 1024/2890/1024 f 1024/2890/1024 1012/1021/1012 824/1020/824 f 1024/2890/1024 1002/2917/1002 1001/2921/1001 f 844/836/844 1024/2890/1024 863/833/863 f 811/807/811 808/809/808 815/2882/815 f 926/2894/926 860/864/860 859/824/859 f 860/864/860 850/825/850 859/824/859 f 1026/1026/1026 984/993/984 974/992/974 f 985/994/985 982/989/982 975/988/975 f 1026/1026/1026 1032/1031/1032 1034/2929/1034 f 984/993/984 1026/1026/1026 1034/2929/1034 f 984/993/984 1034/2929/1034 1036/996/1036 f 1035/997/1035 1033/2930/1033 985/994/985 f 1033/2930/1033 1029/1028/1029 982/989/982 f 982/989/982 985/994/985 1033/2930/1033 f 987/995/987 1036/996/1036 1040/2931/1040 f 1035/997/1035 987/995/987 1040/2931/1040 f 1036/1039/1036 1035/1038/1035 1040/2932/1040 f 1047/1052/1047 1049/1058/1049 1048/1053/1048 f 1047/1052/1047 1050/1059/1050 1049/1058/1049 f 1049/1058/1049 1051/1055/1051 1048/1053/1048 f 1044/1049/1044 1046/1051/1046 1053/1054/1053 f 1046/1051/1046 1048/1053/1048 1053/1054/1053 f 1045/1050/1045 1043/1048/1043 1061/1065/1061 f 1047/1052/1047 1045/1050/1045 1061/1065/1061 f 1062/1066/1062 1056/1060/1056 1050/1059/1050 f 1057/1061/1057 1054/1056/1054 1051/1055/1051 f 1062/1066/1062 1064/1071/1064 1066/2933/1066 f 1056/1060/1056 1062/1066/1062 1068/2934/1068 f 1056/1060/1056 1068/2934/1068 1059/1063/1059 f 1060/1064/1060 1067/2935/1067 1057/1061/1057 f 1054/1056/1054 1067/2935/1067 1065/2936/1065 f 1065/2936/1065 1063/1068/1063 1054/1056/1054 f 1054/1056/1054 1057/1061/1057 1067/2935/1067 f 1062/1066/1062 1066/2933/1066 1068/2934/1068 f 1058/1062/1058 1059/1063/1059 1072/2937/1072 f 1060/1064/1060 1058/1062/1058 1072/2937/1072 f 1059/1081/1059 1060/1080/1060 1072/2938/1072 f 989/2914/989 990/1089/990 1074/1088/1074 f 1085/1099/1085 1087/1107/1087 1086/1100/1086 f 1085/1099/1085 1088/1108/1088 1087/1107/1087 f 1087/1107/1087 1089/1104/1089 1086/1100/1086 f 1080/1094/1080 1082/1096/1082 1091/1101/1091 f 1082/1096/1082 1084/1098/1084 1091/1101/1091 f 1081/1095/1081 1079/1093/1079 1100/1114/1100 f 1083/1097/1083 1081/1095/1081 1100/1114/1100 f 1102/1116/1102 1095/1109/1095 1088/1108/1088 f 1096/1110/1096 1093/1105/1093 1089/1104/1089 f 1102/1116/1102 1107/1121/1107 1109/2939/1109 f 1095/1109/1095 1102/1116/1102 1109/2939/1109 f 1095/1109/1095 1109/2939/1109 1098/1112/1098 f 1099/1113/1099 1108/2940/1108 1096/1110/1096 f 1108/2940/1108 1104/1118/1104 1093/1105/1093 f 1093/1105/1093 1096/1110/1096 1108/2940/1108 f 1097/1111/1097 1098/1112/1098 1113/2941/1113 f 1099/1113/1099 1097/1111/1097 1113/2941/1113 f 1098/1129/1098 1099/1128/1099 1113/2942/1113 f 1090/1102/1090 1112/1045/1112 1027/1027/1027 f 1122/1142/1122 1124/1150/1124 1123/1143/1123 f 1122/1142/1122 1125/1151/1125 1124/1150/1124 f 1124/1150/1124 1126/1147/1126 1123/1143/1123 f 1117/1137/1117 1119/1139/1119 1128/1144/1128 f 1119/1139/1119 1121/1141/1121 1128/1144/1128 f 1134/2943/1134 1131/1149/1131 1132/1152/1132 f 1133/1153/1133 1131/1149/1131 1134/2943/1134 f 1118/1138/1118 1116/1136/1116 1135/1154/1135 f 1120/1140/1120 1118/1138/1118 1135/1154/1135 f 1137/1156/1137 1132/1152/1132 1125/1151/1125 f 1133/1153/1133 1130/1148/1130 1126/1147/1126 f 1144/1167/1144 1143/1166/1143 1134/2944/1134 f 1137/1156/1137 1142/1161/1142 1144/2945/1144 f 1132/1152/1132 1137/1156/1137 1144/2945/1144 f 1132/1152/1132 1144/2945/1144 1134/2943/1134 f 1134/2943/1134 1143/2946/1143 1133/1153/1133 f 1143/2946/1143 1139/1158/1139 1130/1148/1130 f 1130/1148/1130 1133/1153/1133 1143/2946/1143 f 1127/1145/1127 1148/1134/1148 1103/1117/1103 f 1186/1217/1186 1150/1175/1150 1074/1178/1074 f 992/941/992 989/2915/989 1151/938/1151 f 989/1177/989 1149/1176/1149 1151/2947/1151 f 880/854/880 892/853/892 1152/965/1152 f 144/136/144 147/183/147 199/182/199 f 222/216/222 258/218/258 256/290/256 f 264/2743/264 248/234/248 237/232/237 f 229/226/229 341/224/341 170/2749/170 f 128/127/128 131/143/131 156/2726/156 f 112/115/112 120/129/120 127/126/127 f 864/838/864 867/2891/867 818/2884/818 f 867/2891/867 866/2895/866 818/2884/818 f 1161/1189/1161 1163/1197/1163 1162/1190/1162 f 1161/1189/1161 1164/1198/1164 1163/1197/1163 f 1163/1197/1163 1165/1194/1165 1162/1190/1162 f 1156/1184/1156 1158/1186/1158 1167/1191/1167 f 1158/1186/1158 1160/1188/1160 1167/1191/1167 f 1173/2948/1173 1170/1196/1170 1171/1199/1171 f 1172/1200/1172 1170/1196/1170 1173/2948/1173 f 1157/1185/1157 1155/1183/1155 1174/1201/1174 f 1159/1187/1159 1157/1185/1157 1174/1201/1174 f 1176/1203/1176 1171/1199/1171 1164/1198/1164 f 1172/1200/1172 1169/1195/1169 1165/1194/1165 f 1183/1214/1183 1182/1213/1182 1173/2949/1173 f 1176/1203/1176 1181/1208/1181 1183/2950/1183 f 1171/1199/1171 1176/1203/1176 1183/2950/1183 f 1171/1199/1171 1183/2950/1183 1173/2948/1173 f 1173/2948/1173 1182/2951/1182 1172/1200/1172 f 1182/2951/1182 1178/1205/1178 1169/1195/1169 f 1169/1195/1169 1172/1200/1172 1182/2951/1182 f 1166/1192/1166 1147/1173/1147 1138/1157/1138 f 1177/1204/1177 1154/973/1154 964/966/964 f 1071/2952/1071 1075/1092/1075 1076/1087/1076 f 1071/2952/1071 1076/1087/1076 1187/1090/1187 f 1042/983/1042 958/959/958 963/963/963 f 1189/1221/1189 1188/1231/1188 1197/1222/1197 f 1195/1223/1195 1192/1226/1192 1191/1232/1191 f 812/1227/812 1190/1225/1190 1196/1224/1196 f 562/1228/562 1191/1232/1191 1192/1226/1192 f 1196/1224/1196 807/808/807 811/807/811 f 1188/1231/1188 1198/1269/1198 1197/1222/1197 f 1188/1231/1188 1193/1230/1193 1198/1269/1198 f 786/799/786 806/802/806 1199/2953/1199 f 1199/2954/1199 1197/2955/1197 1275/1309/1275 f 1203/1308/1203 786/2956/786 1199/2954/1199 f 1199/2954/1199 1275/1309/1275 1203/1308/1203 f 809/806/809 1197/1222/1197 1199/2953/1199 f 1199/2953/1199 806/802/806 809/806/809 f 1202/1237/1202 1201/1240/1201 1205/1243/1205 f 784/2957/784 802/2958/802 1210/2959/1210 f 1215/1260/1215 1214/1253/1214 1223/1252/1223 f 1210/2960/1210 1211/1263/1211 784/1251/784 f 782/792/782 785/2871/785 803/2870/803 f 1212/1264/1212 1217/1257/1217 1215/1260/1215 f 1213/2961/1213 1216/1258/1216 1217/1257/1217 f 1217/1257/1217 1212/1264/1212 1213/2961/1213 f 784/1251/784 1211/1263/1211 1223/1252/1223 f 1201/1240/1201 1320/2962/1320 1225/1265/1225 f 1224/2963/1224 1220/1262/1220 1225/1265/1225 f 1225/1265/1225 1220/1262/1220 1221/1261/1221 f 1225/1265/1225 1221/1261/1221 1222/1259/1222 f 1225/1265/1225 1222/1259/1222 1226/1266/1226 f 1226/1266/1226 1222/1259/1222 1219/1256/1219 f 1226/1266/1226 1219/1256/1219 1218/1255/1218 f 1209/1245/1209 1208/1244/1208 1227/2964/1227 f 1213/1249/1213 1209/1245/1209 1227/2964/1227 f 1216/1258/1216 1213/2961/1213 1227/2964/1227 f 1218/1255/1218 1216/1258/1216 1227/2964/1227 f 1208/1244/1208 1218/1255/1218 1227/2964/1227 f 1331/1234/1331 1200/1233/1200 1220/1370/1220 f 1229/1280/1229 1237/1279/1237 1231/1273/1231 f 1229/1280/1229 1231/1273/1231 1249/1289/1249 f 1231/1273/1231 1248/1272/1248 1249/1289/1249 f 1233/1270/1233 1247/1290/1247 1250/1271/1250 f 1232/1276/1232 1251/1288/1251 1252/1277/1252 f 1247/1290/1247 1245/1317/1245 1243/1316/1243 f 1237/1279/1237 1233/1270/1233 1231/1273/1231 f 1254/1291/1254 1240/1392/1240 1241/1285/1241 f 1242/1284/1242 1234/1287/1234 1257/1322/1257 f 1243/1316/1243 1234/1287/1234 1247/1290/1247 f 1234/1287/1234 1243/1316/1243 1257/1322/1257 f 1269/1301/1269 34/34/34 43/43/43 f 1201/1240/1201 1204/1239/1204 1320/2962/1320 f 1320/2962/1320 1224/2963/1224 1225/1265/1225 f 1304/1313/1304 1249/1289/1249 1236/1275/1236 f 1273/1305/1273 1272/1304/1272 1277/1312/1277 f 1257/1322/1257 1244/1315/1244 1285/1327/1285 f 1243/1316/1243 1244/1315/1244 1257/1322/1257 f 1262/33/1262 1263/1297/1263 1291/1328/1291 f 1262/33/1262 1291/1328/1291 1281/2702/1281 f 1278/1319/1278 1280/53/1280 1281/2702/1281 f 1285/1327/1285 1284/1321/1284 1257/1322/1257 f 1259/1296/1259 1282/1295/1282 1290/1325/1290 f 1264/1298/1264 1259/1296/1259 1286/2965/1286 f 1263/1297/1263 1264/1298/1264 1286/2965/1286 f 1279/1326/1279 1286/2965/1286 1289/2966/1289 f 1279/1326/1279 1263/1297/1263 1286/2965/1286 f 1284/1321/1284 1285/1327/1285 1287/1323/1287 f 1289/2966/1289 1286/2965/1286 1288/1324/1288 f 1288/1324/1288 1287/1323/1287 1289/2966/1289 f 1289/2966/1289 1287/1323/1287 1285/1327/1285 f 1289/2966/1289 1285/1327/1285 1279/1326/1279 f 1288/1324/1288 1286/2965/1286 1290/1325/1290 f 1290/1325/1290 1286/2965/1286 1259/1296/1259 f 1291/1328/1291 1278/1319/1278 1281/2702/1281 f 1292/2967/1292 1306/1330/1306 1325/1329/1325 f 1276/2968/1276 1275/1401/1275 1436/1335/1436 f 1292/2969/1292 1276/2968/1276 1293/1334/1293 f 1438/1337/1438 1298/1339/1298 1299/1342/1299 f 1293/1334/1293 1303/1346/1303 1306/2970/1306 f 1295/1333/1295 1297/1338/1297 1305/1345/1305 f 1292/2969/1292 1293/1334/1293 1306/2970/1306 f 1204/1352/1204 1330/2971/1330 1311/1353/1311 f 1324/1365/1324 1314/2972/1314 1323/1364/1323 f 1314/2972/1314 1324/1365/1324 1318/1366/1318 f 1319/1360/1319 1321/1363/1321 1322/1361/1322 f 1321/1363/1321 1320/1362/1320 1204/2973/1204 f 1204/2973/1204 1309/2974/1309 1321/1363/1321 f 1322/1361/1322 1321/1363/1321 1309/2974/1309 f 1309/2974/1309 1312/2975/1312 1322/1361/1322 f 1322/1361/1322 1318/1366/1318 1317/1358/1317 f 1312/2975/1312 1318/1366/1318 1322/1361/1322 f 1323/2976/1323 1314/2972/1314 1318/1366/1318 f 1318/1366/1318 1312/2975/1312 1323/2976/1323 f 1328/1368/1328 1333/2977/1333 1336/2978/1336 f 1320/1362/1320 1326/1359/1326 1327/1378/1327 f 1224/1371/1224 1320/2979/1320 1327/1373/1327 f 1329/2980/1329 1333/2977/1333 1328/1368/1328 f 1328/1368/1328 1325/1367/1325 1329/2980/1329 f 1292/2967/1292 1325/1329/1325 1330/2981/1330 f 1330/2971/1330 1325/1367/1325 1311/1353/1311 f 106/1372/106 1336/2982/1336 1337/2983/1337 f 1333/1374/1333 1329/1314/1329 1334/1375/1334 f 1277/1312/1277 1329/1314/1329 1325/1329/1325 f 1329/1314/1329 1274/1307/1274 1334/1375/1334 f 1334/1375/1334 109/65/109 1335/1376/1335 f 106/1372/106 1327/1373/1327 1336/2982/1336 f 1336/2978/1336 1327/1378/1327 1328/1368/1328 f 101/111/101 102/2713/102 1341/1385/1341 f 102/2713/102 1342/1386/1342 1341/1385/1341 f 1340/1383/1340 105/2714/105 99/1384/99 f 110/2715/110 105/2714/105 1342/1386/1342 f 102/2713/102 110/2715/110 1342/1386/1342 f 1341/1385/1341 1338/1390/1338 1335/1389/1335 f 105/2714/105 1340/1383/1340 1342/1386/1342 f 1240/1392/1240 1254/1291/1254 1266/1300/1266 f 1240/1392/1240 1266/1300/1266 1343/1393/1343 f 1268/1303/1268 1271/1306/1271 1343/1393/1343 f 1266/1300/1266 1268/1303/1268 1343/1393/1343 f 1235/1274/1235 1252/1277/1252 1344/1391/1344 f 1252/1277/1252 1253/1286/1253 1344/1391/1344 f 1241/1285/1241 1240/1392/1240 1344/1391/1344 f 1253/1286/1253 1241/1285/1241 1344/1391/1344 f 1271/1306/1271 1235/1274/1235 1344/1391/1344 f 1443/1410/1443 1348/1405/1348 1345/1395/1345 f 1348/1405/1348 1347/1404/1347 1349/2984/1349 f 1349/2985/1349 1347/1505/1347 1294/1400/1294 f 1294/1400/1294 1345/1399/1345 1349/2985/1349 f 1345/1399/1345 1197/1398/1197 1198/2986/1198 f 1350/1402/1350 1298/1412/1298 1296/1403/1296 f 1300/1343/1300 1352/1344/1352 1355/2987/1355 f 1307/1348/1307 1300/1343/1300 1355/2987/1355 f 1352/1415/1352 1353/1414/1353 1355/2987/1355 f 1353/1414/1353 1307/1348/1307 1355/2987/1355 f 1191/1232/1191 562/1228/562 1356/1417/1356 f 1193/1230/1193 1194/1229/1194 1358/1420/1358 f 1358/1420/1358 1228/1267/1228 1193/1230/1193 f 1358/2988/1358 1230/1278/1230 1228/1281/1228 f 1358/2988/1358 1238/1282/1238 1230/1278/1230 f 1359/1421/1359 1238/1282/1238 1361/2989/1361 f 1237/1279/1237 1362/1283/1362 1233/1270/1233 f 77/78/77 1372/1428/1372 80/88/80 f 77/78/77 1365/1426/1365 1372/1428/1372 f 1363/1423/1363 1362/1283/1362 1360/1422/1360 f 1360/1422/1360 1366/1425/1366 1363/1423/1363 f 1366/1425/1366 1360/1422/1360 1370/1432/1370 f 1371/1429/1371 1370/1432/1370 1360/1422/1360 f 1371/1429/1371 1360/1422/1360 1359/1421/1359 f 1370/1432/1370 1367/1427/1367 1366/1425/1366 f 1375/1435/1375 1378/1447/1378 1373/1433/1373 f 1372/1428/1372 1367/1427/1367 1374/1434/1374 f 1247/1290/1247 1233/1270/1233 1245/1317/1245 f 1376/2990/1376 1371/1429/1371 1359/1421/1359 f 1359/1421/1359 1361/2989/1361 1376/2990/1376 f 1368/1430/1368 1371/1429/1371 1376/2990/1376 f 1375/1435/1375 1374/1434/1374 1377/2991/1377 f 1376/1436/1376 1375/1441/1375 1377/1443/1377 f 1374/1434/1374 1369/1431/1369 1377/2991/1377 f 1378/1447/1378 95/2711/95 96/101/96 f 810/805/810 800/798/800 819/810/819 f 781/800/781 786/799/786 802/2872/802 f 802/2958/802 786/2992/786 1210/2959/1210 f 809/806/809 778/2867/778 774/803/774 f 1358/1437/1358 1376/1436/1376 1361/2993/1361 f 1361/2989/1361 1238/1282/1238 1358/2988/1358 f 1390/1462/1390 1393/1465/1393 1391/1463/1391 f 1394/1484/1394 1395/1471/1395 1396/1472/1396 f 1395/1471/1395 550/1466/550 1397/1468/1397 f 1398/1467/1398 445/1460/445 1388/1459/1388 f 1398/1467/1398 1399/2994/1399 1397/1468/1397 f 1400/2995/1400 1388/1459/1388 1387/1458/1387 f 1388/1459/1388 1400/2995/1400 1398/1467/1398 f 1401/1469/1401 1397/1468/1397 1399/2994/1399 f 1399/2994/1399 1403/2996/1403 1401/1469/1401 f 1400/2995/1400 1403/2996/1403 1398/1467/1398 f 1403/2996/1403 1399/2994/1399 1398/1467/1398 f 1403/2996/1403 1400/2995/1400 1387/1458/1387 f 1396/1472/1396 1405/1480/1405 1394/1484/1394 f 1406/2997/1406 1407/2998/1407 1408/2999/1408 f 1395/1471/1395 1394/1484/1394 550/1466/550 f 550/1466/550 1394/1484/1394 602/3000/602 f 602/3000/602 1409/1483/1409 1410/1482/1410 f 745/1499/745 1411/1476/1411 595/1475/595 f 1413/1500/1413 1414/3001/1414 1415/1494/1415 f 1416/1479/1416 1417/1478/1417 1409/1483/1409 f 1396/1472/1396 1404/1473/1404 1405/1480/1405 f 1413/1500/1413 1410/1482/1410 1418/1481/1418 f 1418/1481/1418 1419/1496/1419 1413/1500/1413 f 602/3000/602 1394/1484/1394 1409/1483/1409 f 1419/1496/1419 1420/1495/1420 1414/3001/1414 f 1420/1495/1420 1415/1494/1415 1414/3001/1414 f 1421/1485/1421 1427/1491/1427 1422/1486/1422 f 1429/1493/1429 1426/1490/1426 1425/1489/1425 f 1413/1500/1413 1419/1496/1419 1414/3001/1414 f 1421/1485/1421 1429/1493/1429 1425/1489/1425 f 1424/1488/1424 1407/2998/1407 1430/1497/1430 f 1408/2999/1408 1407/2998/1407 1431/3002/1431 f 1407/2998/1407 562/3003/562 740/1498/740 f 1424/1488/1424 1430/1497/1430 1421/1485/1421 f 1430/1497/1430 1407/2998/1407 740/1498/740 f 1430/1497/1430 1412/1477/1412 1421/1485/1421 f 1412/1477/1412 1429/1493/1429 1421/1485/1421 f 1411/1476/1411 1413/1500/1413 1415/1494/1415 f 1410/1482/1410 745/1499/745 602/3000/602 f 1407/2998/1407 1406/2997/1406 562/3003/562 f 1431/3002/1431 1407/2998/1407 1424/1488/1424 f 1432/3004/1432 1408/2999/1408 1431/3002/1431 f 1424/1488/1424 1432/3004/1432 1431/3002/1431 f 1433/3005/1433 1423/1487/1423 1428/1492/1428 f 1423/1487/1423 1433/3005/1433 1424/1488/1424 f 1434/1501/1434 65/66/65 47/47/47 f 1436/1335/1436 1293/1334/1293 1276/2968/1276 f 1275/1401/1275 1294/1400/1294 1436/1335/1436 f 1438/1337/1438 1296/1506/1296 1298/1339/1298 f 1299/1342/1299 1297/1338/1297 1438/1337/1438 f 1303/1346/1303 1304/1507/1304 1306/2970/1306 f 1439/1407/1439 1303/1346/1303 1442/1408/1442 f 1441/1416/1441 1354/1347/1354 1308/1349/1308 f 1305/1345/1305 1440/1409/1440 1442/1408/1442 f 1442/1408/1442 1303/1346/1303 1305/1345/1305 f 1346/1394/1346 1439/1407/1439 1442/1408/1442 f 1345/1395/1345 1346/1394/1346 1443/1410/1443 f 1443/1410/1443 1346/1394/1346 1442/1408/1442 f 1348/1405/1348 1349/2984/1349 1345/1395/1345 f 1449/1509/1449 1457/1868/1457 1456/1867/1456 f 1461/1514/1461 1450/1510/1450 1451/1560/1451 f 1448/1511/1448 1462/1521/1462 1447/1508/1447 f 1447/1508/1447 1455/1524/1455 1452/1515/1452 f 1457/1868/1457 1453/1516/1453 1454/3006/1454 f 1768/1864/1768 1459/3007/1459 1456/1867/1456 f 1449/1509/1449 1458/1561/1458 1450/1510/1450 f 1456/1867/1456 1459/3007/1459 1460/1563/1460 f 1456/1867/1456 1460/1563/1460 1458/1561/1458 f 1453/1516/1453 1509/1518/1509 1454/3006/1454 f 1509/1518/1509 1481/1517/1481 1483/1559/1483 f 1462/1521/1462 1466/1536/1466 1465/1522/1465 f 1465/1522/1465 1468/3008/1468 1467/1523/1467 f 1468/3008/1468 1465/1522/1465 1471/1533/1471 f 1469/1539/1469 1465/1522/1465 1466/1536/1466 f 1471/1533/1471 1474/1525/1474 1468/3008/1468 f 1492/1534/1492 1471/1533/1471 1469/1539/1469 f 1471/1533/1471 1465/1522/1465 1469/1539/1469 f 1467/1523/1467 1473/1528/1473 1472/1527/1472 f 1473/1528/1473 1467/1523/1467 1468/3008/1468 f 1475/1526/1475 1474/1525/1474 1470/1535/1470 f 1468/3008/1468 1474/1525/1474 1473/1528/1473 f 1472/1527/1472 1476/1529/1476 1467/1523/1467 f 1476/1529/1476 1477/3009/1477 1478/1531/1478 f 1477/3009/1477 1476/1529/1476 1472/1527/1472 f 1480/1532/1480 1534/1575/1534 1479/1530/1479 f 1452/1515/1452 1482/1577/1482 1481/1517/1481 f 1482/1577/1482 1452/1515/1452 1455/1524/1455 f 1479/1530/1479 1482/1577/1482 1455/1524/1455 f 1454/3006/1454 1509/1518/1509 1523/1558/1523 f 1484/1537/1484 1489/3010/1489 1485/1538/1485 f 1485/1538/1485 1489/3010/1489 1486/1540/1486 f 1488/1544/1488 1489/3010/1489 1487/1541/1487 f 1484/1537/1484 1487/1541/1487 1489/3010/1489 f 1488/1544/1488 1486/1540/1486 1489/3010/1489 f 1494/1543/1494 1490/1542/1490 1496/1552/1496 f 1484/1537/1484 1500/3011/1500 1487/1541/1487 f 1492/1534/1492 1493/1546/1493 1470/1535/1470 f 1495/1545/1495 1496/1552/1496 1512/3012/1512 f 1472/1527/1472 1475/1526/1475 1477/3009/1477 f 1477/3009/1477 1499/3013/1499 1478/1531/1478 f 1475/1526/1475 1499/3013/1499 1477/3009/1477 f 1475/1526/1475 1470/1535/1470 1499/3013/1499 f 1513/1547/1513 1498/3014/1498 1497/1548/1497 f 1493/1546/1493 1575/3015/1575 1470/1535/1470 f 1470/1535/1470 1575/3015/1575 1499/3013/1499 f 1495/1545/1495 1575/3015/1575 1493/1546/1493 f 1487/1541/1487 1500/3011/1500 1490/1542/1490 f 1466/1536/1466 1500/3011/1500 1484/1537/1484 f 1500/3011/1500 1466/1536/1466 1491/3016/1491 f 1500/3011/1500 1501/3017/1501 1490/1542/1490 f 1501/3017/1501 1502/1549/1502 1490/1542/1490 f 1490/1542/1490 1502/1549/1502 1496/1552/1496 f 1504/1550/1504 1502/1549/1502 1501/3017/1501 f 1504/1550/1504 1501/3017/1501 1500/3011/1500 f 1491/3016/1491 1503/1551/1503 1500/3011/1500 f 1500/3011/1500 1503/1551/1503 1504/1550/1504 f 1491/3016/1491 1463/1520/1463 1505/3018/1505 f 1491/3016/1491 1505/3018/1505 1503/1551/1503 f 1466/1536/1466 1462/1521/1462 1463/1520/1463 f 1850/1954/1850 1526/1555/1526 1508/1554/1508 f 1453/1516/1453 1457/1868/1457 1449/1509/1449 f 1507/1570/1507 1524/1557/1524 1483/1559/1483 f 1496/3019/1496 1561/1629/1561 1512/3020/1512 f 1511/3021/1511 1499/3013/1499 1512/3012/1512 f 1498/3014/1498 1511/3021/1511 1497/1548/1497 f 1497/1548/1497 1511/3021/1511 1510/3022/1510 f 1511/3021/1511 1512/3012/1512 1510/3022/1510 f 1498/3014/1498 1513/1547/1513 1499/3013/1499 f 1513/1547/1513 1478/1531/1478 1499/3013/1499 f 1499/3013/1499 1511/3021/1511 1498/3014/1498 f 1456/1867/1456 1458/1561/1458 1449/1509/1449 f 1460/1563/1460 1514/1562/1514 1458/1561/1458 f 1451/1560/1451 1515/3023/1515 1461/1514/1461 f 1451/1560/1451 1517/1566/1517 1515/3023/1515 f 1515/3023/1515 1517/1566/1517 1516/1567/1516 f 1515/3023/1515 1516/1567/1516 1461/1514/1461 f 1459/3007/1459 1518/1564/1518 1460/1563/1460 f 1520/1568/1520 1527/3024/1527 1529/1512/1529 f 1483/1559/1483 1522/1571/1522 1507/1570/1507 f 1847/1953/1847 1524/1557/1524 1850/1954/1850 f 1526/1555/1526 1850/1954/1850 1524/1557/1524 f 1529/1512/1529 1527/3024/1527 1530/3025/1530 f 1520/1568/1520 1528/1636/1528 1527/3024/1527 f 1527/3024/1527 1528/1636/1528 1530/3025/1530 f 1448/1511/1448 1531/1513/1531 1464/1519/1464 f 1532/1573/1532 1528/1636/1528 1542/1574/1542 f 1516/1567/1516 1528/1636/1528 1520/1568/1520 f 1450/1510/1450 1531/1513/1531 1448/1511/1448 f 1528/1636/1528 1532/1573/1532 1530/3025/1530 f 1532/1573/1532 1529/1512/1529 1530/3025/1530 f 1532/1573/1532 1531/1513/1531 1529/1512/1529 f 1533/1576/1533 1535/1578/1535 1553/3026/1553 f 1535/1578/1535 1533/1576/1533 1534/1575/1534 f 1483/1559/1483 1481/1517/1481 1533/1576/1533 f 1483/1559/1483 1533/1576/1533 1553/3026/1553 f 1483/1559/1483 1553/3026/1553 1522/1571/1522 f 1553/3026/1553 1567/1623/1567 1522/1571/1522 f 1521/1569/1521 1568/1586/1568 1538/1583/1538 f 1464/1519/1464 1541/1591/1541 1463/1520/1463 f 1541/1591/1541 1543/3027/1543 1463/1520/1463 f 1463/1520/1463 1543/3027/1543 1505/3018/1505 f 1543/1593/1543 1544/1588/1544 1505/3028/1505 f 1552/1744/1552 1549/1605/1549 1546/1601/1546 f 1550/1603/1550 1593/1650/1593 1551/1604/1551 f 1548/1602/1548 1552/1744/1552 1545/1608/1545 f 1545/1608/1545 1555/1613/1555 1558/1606/1558 f 1554/1607/1554 1558/1606/1558 1557/1612/1557 f 1553/1597/1553 1535/1579/1535 1670/1594/1670 f 1559/1582/1559 1510/1581/1510 1560/1615/1560 f 1560/1615/1560 1510/1581/1510 1512/3020/1512 f 1503/3029/1503 1505/3030/1505 1562/1638/1562 f 1503/3029/1503 1562/1638/1562 1496/3019/1496 f 1562/1638/1562 1576/1631/1576 1561/1629/1561 f 1562/1638/1562 1505/3030/1505 1563/1639/1563 f 1565/1616/1565 1574/1621/1574 1564/1618/1564 f 1538/1583/1538 1568/1586/1568 1539/1585/1539 f 1568/1586/1568 1521/1569/1521 1536/1572/1536 f 1551/1604/1551 1581/1627/1581 1570/1625/1570 f 1564/1640/1564 1574/1642/1574 1578/1632/1578 f 1499/3013/1499 1575/3015/1575 1512/3012/1512 f 1575/3015/1575 1495/1545/1495 1512/3012/1512 f 1496/1552/1496 1495/1545/1495 1494/1543/1494 f 1526/1555/1526 1524/1557/1524 1507/1570/1507 f 1381/1634/1381 1516/1567/1516 1517/1566/1517 f 1381/1634/1381 1517/1566/1517 1519/1565/1519 f 1540/1592/1540 1542/1574/1542 1391/1637/1391 f 1496/3019/1496 1562/1638/1562 1561/1629/1561 f 1578/1632/1578 1576/1631/1576 1564/1640/1564 f 1560/1615/1560 1512/3020/1512 1561/1629/1561 f 1577/3031/1577 1571/3032/1571 1595/1653/1595 f 1579/1628/1579 1580/1644/1580 1595/3033/1595 f 1581/1627/1581 1551/1604/1551 1593/1650/1593 f 1550/1603/1550 1591/1611/1591 1593/1650/1593 f 1579/1628/1579 1590/1645/1590 1580/1644/1580 f 1588/1651/1588 1583/1688/1583 1582/1652/1582 f 1591/1611/1591 1589/1610/1589 1588/1651/1588 f 1554/1607/1554 1586/1649/1586 1556/1609/1556 f 1556/1609/1556 1586/1682/1586 1587/1683/1587 f 1589/1610/1589 1587/1683/1587 1583/1688/1583 f 1588/1651/1588 1589/1610/1589 1583/1688/1583 f 1581/1627/1581 1590/1645/1590 1579/1628/1579 f 1552/1744/1552 1548/1602/1548 1549/1605/1549 f 1577/3031/1577 1595/1653/1595 1594/1656/1594 f 1597/1654/1597 1616/3034/1616 1596/1655/1596 f 1598/3035/1598 1600/3036/1600 1616/3034/1616 f 1600/3036/1600 1733/1824/1733 1599/1666/1599 f 1602/1659/1602 1605/1658/1605 1596/1655/1596 f 1601/1662/1601 1615/1665/1615 1599/1666/1599 f 1577/3031/1577 1594/1656/1594 1585/1685/1585 f 1604/1657/1604 1603/3037/1603 1607/1664/1607 f 1607/1664/1607 1610/1670/1610 1604/1657/1604 f 1615/1665/1615 1607/1664/1607 1603/3037/1603 f 1608/1663/1608 1611/1821/1611 1609/1667/1609 f 1609/1667/1609 1611/1821/1611 1612/1668/1612 f 1610/1670/1610 1607/1664/1607 1609/1667/1609 f 1607/1664/1607 1608/1663/1608 1609/1667/1609 f 1604/1657/1604 1614/1660/1614 1603/3037/1603 f 1614/1660/1614 1615/1665/1615 1603/3037/1603 f 1616/3034/1616 1602/1659/1602 1596/1655/1596 f 1616/3034/1616 1599/1666/1599 1602/1659/1602 f 1616/3034/1616 1597/1654/1597 1598/3035/1598 f 1616/3034/1616 1600/3036/1600 1599/1666/1599 f 1585/1685/1585 1623/1680/1623 1586/1682/1586 f 1621/1679/1621 1625/1791/1625 1673/1747/1673 f 1625/1791/1625 1621/1679/1621 1622/1692/1622 f 1629/1671/1629 1594/1656/1594 1606/1661/1606 f 1621/1679/1621 1624/1681/1624 1622/1692/1622 f 1580/1644/1580 1597/1689/1597 1595/3033/1595 f 1598/1690/1598 1584/1647/1584 1600/1672/1600 f 1639/1704/1639 1646/1703/1646 1645/1708/1645 f 1643/1709/1643 1644/1743/1644 1648/1710/1648 f 1639/1704/1639 1645/1708/1645 1640/1711/1640 f 1645/1708/1645 1646/1703/1646 1641/1705/1641 f 1648/1710/1648 1644/1743/1644 1642/1713/1642 f 1637/1702/1637 1654/1714/1654 1635/1700/1635 f 1640/1711/1640 1663/1729/1663 1639/1704/1639 f 1646/1703/1646 1649/1727/1649 1641/1705/1641 f 1636/1699/1636 1650/1717/1650 1638/1701/1638 f 1638/1701/1638 1650/1717/1650 1646/1703/1646 f 1651/1719/1651 1652/1718/1652 1734/1818/1734 f 1654/1714/1654 1633/1697/1633 1635/1700/1635 f 1655/1716/1655 1680/1724/1680 1650/1717/1650 f 1734/1818/1734 1763/3038/1763 1651/1719/1651 f 1662/1737/1662 1660/1731/1660 1664/1730/1664 f 1660/1734/1660 1662/1735/1662 1657/1726/1657 f 1649/1727/1649 1676/1740/1676 1641/1705/1641 f 1667/1712/1667 1677/1742/1677 1640/1711/1640 f 1670/1594/1670 1555/1613/1555 1545/1608/1545 f 1670/1594/1670 1535/1579/1535 1555/1613/1555 f 1555/1613/1555 1535/1579/1535 1559/1582/1559 f 1505/3039/1505 1544/1746/1544 1672/1617/1672 f 1622/1692/1622 1675/1722/1675 1674/3040/1674 f 1641/1705/1641 1676/1740/1676 1665/1706/1665 f 1640/1711/1640 1677/1742/1677 1663/1729/1663 f 1661/1736/1661 1676/1740/1676 1649/1727/1649 f 1677/1742/1677 1661/1738/1661 1663/1729/1663 f 1678/1749/1678 1654/1714/1654 1658/1715/1658 f 1653/1721/1653 1682/3041/1682 1715/3042/1715 f 1675/1722/1675 1653/1721/1653 1715/3042/1715 f 1690/1764/1690 1691/1763/1691 1692/1768/1692 f 1694/1767/1694 1695/1766/1695 1698/3043/1698 f 1690/1764/1690 1692/1768/1692 1696/1769/1696 f 1692/1768/1692 1691/1763/1691 1693/1765/1693 f 1697/1770/1697 1694/1767/1694 1698/3043/1698 f 1688/1762/1688 1699/1771/1699 1686/1760/1686 f 1687/1759/1687 1703/1776/1703 1689/1761/1689 f 1689/1761/1689 1703/1776/1703 1691/1763/1691 f 1699/1771/1699 1684/1756/1684 1686/1760/1686 f 1704/1775/1704 1714/1777/1714 1703/1776/1703 f 1702/1774/1702 1709/3044/1709 1708/1783/1708 f 1709/3045/1709 1701/1778/1701 1708/1787/1708 f 1709/3045/1709 1706/1779/1706 1701/1778/1701 f 1706/1782/1706 1709/3044/1709 1702/1774/1702 f 1702/1774/1702 1710/1785/1710 1693/1765/1693 f 1697/1770/1697 1711/1788/1711 1696/1769/1696 f 1698/3043/1698 1695/1766/1695 1712/1784/1712 f 1712/1786/1712 1697/1770/1697 1698/3043/1698 f 1693/1765/1693 1710/1785/1710 1695/1766/1695 f 1696/1769/1696 1711/1788/1711 1701/1778/1701 f 1708/1783/1708 1710/1785/1710 1702/1774/1702 f 1711/1788/1711 1708/1787/1708 1701/1778/1701 f 1704/1775/1704 1715/1820/1715 1714/1777/1714 f 1675/1758/1675 1704/1775/1704 1685/1755/1685 f 1704/1775/1704 1675/1758/1675 1715/1820/1715 f 1674/3040/1674 1716/1792/1716 1625/1791/1625 f 1622/1692/1622 1674/3040/1674 1625/1791/1625 f 1717/1793/1717 1718/1687/1718 1673/1747/1673 f 1682/1800/1682 1726/1799/1726 1715/3046/1715 f 1680/1724/1680 1763/1728/1763 1681/1753/1681 f 1724/1806/1724 1718/1687/1718 1717/1793/1717 f 1727/1807/1727 1720/1796/1720 1724/1806/1724 f 1716/1792/1716 1725/1804/1725 1717/1793/1717 f 1724/1806/1724 1720/1796/1720 1718/1687/1718 f 1628/1684/1628 1652/1718/1652 1630/1691/1630 f 1765/3047/1765 1764/1813/1764 1722/1816/1722 f 1731/1815/1731 1728/1810/1728 1729/1812/1729 f 1728/1810/1728 1731/1815/1731 1730/1814/1730 f 1699/1771/1699 1725/1808/1725 1716/1794/1716 f 1732/1817/1732 1728/1810/1728 1730/1814/1730 f 1599/1666/1599 1733/1824/1733 1601/1662/1601 f 1739/1831/1739 1741/1836/1741 1740/1832/1740 f 1743/1833/1743 1745/3048/1745 1744/1834/1744 f 1739/1831/1739 1746/1837/1746 1741/1836/1741 f 1741/1836/1741 1742/1835/1742 1740/1832/1740 f 1747/1838/1747 1745/3048/1745 1743/1833/1743 f 1737/1829/1737 1736/1827/1736 1748/1839/1748 f 1735/1828/1735 1738/1830/1738 1752/1843/1752 f 1738/1830/1738 1740/1832/1740 1752/1843/1752 f 1750/1841/1750 1757/1850/1757 1758/3049/1758 f 1758/3050/1758 1757/1854/1757 1755/1845/1755 f 1758/3050/1758 1755/1845/1755 1754/1847/1754 f 1754/1848/1754 1750/1841/1750 1758/3049/1758 f 1750/1841/1750 1742/1835/1742 1759/1851/1759 f 1747/1838/1747 1746/1837/1746 1760/1853/1760 f 1744/1834/1744 1745/3048/1745 1761/1852/1761 f 1761/1855/1761 1745/3048/1745 1747/1838/1747 f 1742/1835/1742 1744/1834/1744 1759/1851/1759 f 1746/1837/1746 1755/1845/1755 1760/1853/1760 f 1757/1850/1757 1750/1841/1750 1759/1851/1759 f 1760/1853/1760 1755/1845/1755 1757/1854/1757 f 1752/1843/1752 1753/1844/1753 1763/1861/1763 f 1734/1825/1734 1735/1828/1735 1752/1843/1752 f 1752/1843/1752 1763/1861/1763 1734/1825/1734 f 1736/1827/1736 1730/3051/1730 1748/1839/1748 f 1748/1839/1748 1730/3051/1730 1764/1858/1764 f 1736/1827/1736 1732/1826/1732 1730/3051/1730 f 1763/3052/1763 1766/3053/1766 1681/3054/1681 f 1766/3053/1766 1764/1813/1764 1765/3047/1765 f 1681/3054/1681 1766/3053/1766 1765/3047/1765 f 1386/1863/1386 1767/1862/1767 1768/1864/1768 f 1518/1564/1518 1459/3007/1459 1767/1862/1767 f 1518/1564/1518 1767/1862/1767 1519/1565/1519 f 1767/1862/1767 1459/3007/1459 1768/1864/1768 f 1867/3055/1867 1454/3006/1454 1843/1964/1843 f 1769/1865/1769 1771/3056/1771 1387/1866/1387 f 1771/3056/1771 1769/1865/1769 1457/1868/1457 f 1788/1899/1788 1789/3057/1789 1787/1900/1787 f 1789/3057/1789 1792/1926/1792 1791/1901/1791 f 1789/3057/1789 1791/1901/1791 1787/1900/1787 f 1792/1926/1792 1796/3058/1796 1791/1901/1791 f 1791/1901/1791 1793/1903/1793 1790/1902/1790 f 1791/1901/1791 1796/3058/1796 1793/1903/1793 f 1793/1903/1793 1796/3058/1796 1826/1905/1826 f 1806/1897/1806 1798/1907/1798 1799/1910/1799 f 1798/1907/1798 1806/1897/1806 1780/1890/1780 f 1780/1890/1780 1802/1911/1802 1798/1907/1798 f 1805/1917/1805 493/1914/493 1804/1915/1804 f 1506/1553/1506 1525/1556/1525 1393/1584/1393 f 1786/1898/1786 1806/1897/1806 1807/1919/1807 f 1806/1897/1806 1808/3059/1808 1809/1927/1809 f 1807/1919/1807 1809/1927/1809 1811/1920/1811 f 1786/1898/1786 1813/1921/1813 1788/1899/1788 f 1788/1899/1788 1813/1921/1813 1789/3057/1789 f 1789/3057/1789 1813/1921/1813 1792/1926/1792 f 1792/1926/1792 1813/1921/1813 1812/3060/1812 f 1792/1926/1792 1812/3060/1812 1810/1925/1810 f 1812/3060/1812 1813/1921/1813 1811/1920/1811 f 1812/3060/1812 1820/3061/1820 1814/3062/1814 f 1812/3060/1812 1814/3062/1814 1810/1925/1810 f 1814/3062/1814 1815/1922/1815 1810/1925/1810 f 1814/3062/1814 1818/1931/1818 1815/1922/1815 f 1818/1931/1818 1814/3062/1814 1820/3061/1820 f 1815/1922/1815 1818/1931/1818 1817/1923/1817 f 1792/1926/1792 1826/1905/1826 1796/3058/1796 f 1811/1920/1811 1819/1930/1819 1812/3060/1812 f 1812/3060/1812 1819/1930/1819 1820/3061/1820 f 1818/1931/1818 1820/3061/1820 1819/1930/1819 f 1821/1929/1821 1833/1928/1833 513/1933/513 f 1808/3059/1808 1833/1928/1833 1809/1927/1809 f 1806/1897/1806 1809/1927/1809 1807/1919/1807 f 1823/3063/1823 1826/1905/1826 1824/3064/1824 f 1824/3064/1824 1826/1905/1826 1816/1924/1816 f 1824/3064/1824 1825/3065/1825 1823/3063/1823 f 1826/1905/1826 1823/3063/1823 1822/1932/1822 f 1797/1906/1797 1826/1905/1826 1822/1932/1822 f 1822/1932/1822 1834/1947/1834 1508/1918/1508 f 1508/1554/1508 1834/3066/1834 1850/1954/1850 f 1816/1924/1816 1827/1935/1827 1824/3064/1824 f 1827/1935/1827 1816/1924/1816 1817/1923/1817 f 1824/3064/1824 1827/1935/1827 1825/3065/1825 f 1827/1935/1827 1817/1923/1817 1818/1931/1818 f 1825/3065/1825 1838/1938/1838 1823/3063/1823 f 1838/1938/1838 1825/3065/1825 1827/1935/1827 f 526/1942/526 1784/1894/1784 473/1895/473 f 532/3067/532 1828/3068/1828 523/1940/523 f 523/1940/523 1828/3068/1828 1781/1892/1781 f 534/3069/534 1830/3070/1830 1828/3068/1828 f 1830/3070/1830 1831/1943/1831 1829/1889/1829 f 1828/3068/1828 1829/1889/1829 1781/1892/1781 f 1830/3070/1830 1832/1944/1832 1831/1943/1831 f 530/3071/530 494/1913/494 1803/1912/1803 f 534/3069/534 1828/3068/1828 532/3067/532 f 1803/1912/1803 1832/1944/1832 530/3071/530 f 1832/1944/1832 1830/3070/1830 530/3071/530 f 1829/1889/1829 1775/1880/1775 1781/1892/1781 f 1830/3070/1830 534/3069/534 530/3071/530 f 1780/1890/1780 1831/1943/1831 1802/1911/1802 f 1831/1943/1831 1780/1890/1780 1829/1889/1829 f 1829/1889/1829 1828/3068/1828 1830/3070/1830 f 535/3072/535 1779/1888/1779 467/1887/467 f 1779/1888/1779 535/3072/535 473/1895/473 f 1804/1915/1804 493/1914/493 495/1916/495 f 1806/1897/1806 536/3073/536 1808/3059/1808 f 1808/3059/1808 536/3073/536 1833/1928/1833 f 513/1933/513 1833/1928/1833 536/3073/536 f 495/1916/495 536/3073/536 1806/1897/1806 f 1823/3063/1823 1837/1945/1837 1822/1932/1822 f 1837/1945/1837 1823/3063/1823 1838/1938/1838 f 1837/1945/1837 1838/1938/1838 1839/1948/1839 f 1839/1948/1839 1840/3074/1840 1836/1949/1836 f 1839/1948/1839 1841/1951/1841 1840/3074/1840 f 1838/1938/1838 1841/1951/1841 1839/1948/1839 f 1387/1866/1387 1771/3056/1771 1403/3075/1403 f 1844/3076/1844 1523/1558/1523 1772/1952/1772 f 1843/1964/1843 1454/3006/1454 1770/1961/1770 f 1454/3006/1454 1868/3077/1868 1770/1961/1770 f 1454/3006/1454 1523/1558/1523 1868/3077/1868 f 1842/3078/1842 1523/1558/1523 1844/3076/1844 f 1842/3078/1842 1866/3079/1866 1846/3080/1846 f 1844/3076/1844 1845/3081/1845 1866/3079/1866 f 1845/3081/1845 1844/3076/1844 1772/1952/1772 f 1866/3079/1866 1842/3078/1842 1844/3076/1844 f 1848/1957/1848 1852/1955/1852 1850/1954/1850 f 1847/1953/1847 1851/1956/1851 1849/3082/1849 f 1849/3082/1849 1851/1956/1851 1864/3083/1864 f 1851/1956/1851 1852/1955/1852 1862/3084/1862 f 1852/1955/1852 1848/1957/1848 1862/3084/1862 f 1855/3085/1855 1854/3086/1854 1858/3087/1858 f 1850/1954/1850 1853/3088/1853 1848/1957/1848 f 1858/3087/1858 1854/3086/1854 1835/1946/1835 f 1835/1946/1835 1854/3086/1854 1834/1947/1834 f 1854/3086/1854 1855/3085/1855 1834/1947/1834 f 1855/3089/1855 1856/1958/1856 1853/3088/1853 f 1856/1958/1856 1848/1957/1848 1853/3088/1853 f 1834/3066/1834 1855/3089/1855 1853/3088/1853 f 1853/3088/1853 1850/1954/1850 1834/3066/1834 f 1855/3085/1855 1858/3087/1858 1861/3090/1861 f 1865/1959/1865 1859/3091/1859 1860/3092/1860 f 1857/1960/1857 1865/1959/1865 1860/3092/1860 f 1855/3085/1855 1861/3090/1861 1859/1996/1859 f 1859/3091/1859 1856/1958/1856 1855/3089/1855 f 1848/1957/1848 1857/1960/1857 1863/3093/1863 f 1857/1960/1857 1849/3082/1849 1863/3093/1863 f 1848/1957/1848 1863/3093/1863 1862/3084/1862 f 1862/3084/1862 1864/3083/1864 1851/1956/1851 f 1849/3082/1849 1864/3083/1864 1863/3093/1863 f 1864/3083/1864 1862/3084/1862 1863/3093/1863 f 1859/3091/1859 1865/1959/1865 1856/1958/1856 f 1849/3082/1849 1772/1952/1772 1847/1953/1847 f 1772/1952/1772 1874/3094/1874 1845/3081/1845 f 1845/3081/1845 1874/3094/1874 1866/3079/1866 f 1874/3094/1874 1772/1952/1772 1849/3082/1849 f 1874/3094/1874 1849/3082/1849 1857/1960/1857 f 1866/3079/1866 1869/1962/1869 1846/3080/1846 f 1846/3080/1846 1869/1962/1869 1770/1961/1770 f 1454/3006/1454 1867/3055/1867 1457/1868/1457 f 1770/1961/1770 1868/3077/1868 1846/3080/1846 f 1868/3077/1868 1842/3078/1842 1846/3080/1846 f 1868/3077/1868 1523/1558/1523 1842/3078/1842 f 1457/1868/1457 1867/3055/1867 1771/3056/1771 f 1843/1964/1843 1870/1963/1870 1867/3055/1867 f 1771/3056/1771 1867/3055/1867 1403/3075/1403 f 1874/3094/1874 1869/1962/1869 1866/3079/1866 f 1874/1978/1874 1871/1966/1871 1869/1970/1869 f 1871/1966/1871 1874/1978/1874 2221/1977/2221 f 1872/1967/1872 1876/3095/1876 1873/2003/1873 f 1871/1966/1871 1875/2341/1875 1872/1967/1872 f 1857/3096/1857 1877/2000/1877 1874/3097/1874 f 1877/2000/1877 1857/3096/1857 1860/1997/1860 f 1877/1979/1877 2223/1983/2223 2222/1980/2222 f 1876/3095/1876 1880/2218/1880 2125/2217/2125 f 2224/3098/2224 1878/2342/1878 1888/3099/1888 f 1878/2342/1878 1881/3100/1881 1888/3099/1888 f 1876/3095/1876 2224/3098/2224 1880/2218/1880 f 1876/3095/1876 1872/1967/1872 1875/2341/1875 f 1897/2343/1897 1886/1984/1886 1902/3101/1902 f 1886/1984/1886 1887/1985/1887 1883/3102/1883 f 1880/2218/1880 1888/3099/1888 1882/2215/1882 f 1888/3099/1888 1889/3103/1889 1882/2215/1882 f 1881/3100/1881 1889/3103/1889 1888/3099/1888 f 1881/3100/1881 1878/2342/1878 1897/2343/1897 f 1886/1984/1886 1897/2343/1897 2223/1983/2223 f 1883/3104/1883 1898/1987/1898 1900/3105/1900 f 1902/3101/1902 1900/3106/1900 1897/2343/1897 f 1884/1999/1884 1901/1986/1901 1885/1989/1885 f 1887/1988/1887 1898/1987/1898 1883/3104/1883 f 1893/1994/1893 1892/1991/1892 625/1990/625 f 1890/1992/1890 1836/1949/1836 1891/1993/1891 f 1891/1993/1891 1840/3074/1840 1841/1951/1841 f 1891/1993/1891 1836/1949/1836 1840/3074/1840 f 1890/1992/1890 1835/1946/1835 1836/1949/1836 f 1835/1946/1835 1890/1992/1890 1858/3087/1858 f 1858/3087/1858 1890/1992/1890 1861/3090/1861 f 1841/1951/1841 1892/1991/1892 1891/1993/1891 f 1890/1992/1890 1859/1996/1859 1861/3090/1861 f 1870/1963/1870 1403/3075/1403 1867/3055/1867 f 2164/2522/2164 1873/2003/1873 1879/3107/1879 f 1881/3100/1881 1895/3108/1895 1889/3103/1889 f 1889/3103/1889 1895/3108/1895 1903/3109/1903 f 1889/3103/1889 1903/3109/1903 1882/2215/1882 f 1881/3100/1881 1897/2343/1897 1894/3110/1894 f 1894/3110/1894 1897/2343/1897 1900/3106/1900 f 1881/3100/1881 1896/3111/1896 1895/3108/1895 f 1894/3112/1894 1900/3105/1900 1899/2007/1899 f 1899/2007/1899 1900/3105/1900 1898/1987/1898 f 623/3113/623 646/2005/646 1898/1987/1898 f 1898/1987/1898 1901/1986/1901 623/3113/623 f 625/3114/625 1884/1999/1884 1893/1998/1893 f 1901/1986/1901 625/3114/625 623/3113/623 f 1884/1999/1884 625/3114/625 1901/1986/1901 f 1900/3106/1900 1902/3101/1902 1883/3102/1883 f 1902/3101/1902 1886/1984/1886 1883/3102/1883 f 1881/3100/1881 1894/3110/1894 1896/3111/1896 f 1899/3115/1899 1905/2021/1905 1894/3116/1894 f 1899/3115/1899 1925/2018/1925 1905/2021/1905 f 1905/2015/1905 1908/2022/1908 1906/2016/1906 f 1917/2029/1917 1912/2028/1912 1911/3117/1911 f 1913/2030/1913 1917/2031/1917 1911/3117/1911 f 1913/2030/1913 1911/3117/1911 1921/2037/1921 f 1921/2037/1921 1911/3117/1911 1912/2028/1912 f 1923/2038/1923 1921/2037/1921 1922/2036/1922 f 1920/2034/1920 1926/2039/1926 1918/2035/1918 f 1925/2018/1925 1899/3115/1899 1928/2042/1928 f 1924/2032/1924 1929/2040/1929 1926/2039/1926 f 1924/2032/1924 1930/2043/1930 1929/2040/1929 f 1978/3118/1978 2004/3119/2004 1979/3120/1979 f 1932/2046/1932 1936/2083/1936 1931/2047/1931 f 1931/2047/1931 1936/2083/1936 1959/2075/1959 f 1942/2060/1942 1948/2059/1948 1952/2069/1952 f 1954/3121/1954 1953/3122/1953 1951/3123/1951 f 1954/3121/1954 1934/2241/1934 1955/3124/1955 f 692/3125/692 695/3126/695 1945/3127/1945 f 1933/2050/1933 1946/2063/1946 1949/2054/1949 f 1949/2054/1949 1946/2063/1946 1940/2065/1940 f 1946/2063/1946 692/2123/692 1945/2064/1945 f 1940/2065/1940 1950/2066/1950 1943/2067/1943 f 1950/2066/1950 1952/2069/1952 1943/2067/1943 f 1952/2069/1952 1948/2059/1948 1943/2067/1943 f 1953/2068/1953 1941/2058/1941 1952/2069/1952 f 1955/3124/1955 1953/3122/1953 1954/3121/1954 f 1945/3127/1945 1958/3128/1958 1944/3129/1944 f 1953/2068/1953 1955/2070/1955 1941/2058/1941 f 1957/2074/1957 1945/3127/1945 695/3126/695 f 1944/3129/1944 1958/3128/1958 1986/2072/1986 f 1945/3127/1945 1957/2074/1957 1985/2073/1985 f 1941/2058/1941 1960/2057/1960 1942/2060/1942 f 1969/2086/1969 1963/2079/1963 1965/2078/1965 f 1967/2088/1967 1961/2077/1961 1962/2076/1962 f 1942/2060/1942 1952/2069/1952 1941/2058/1941 f 1967/2085/1967 1973/2093/1973 1969/2086/1969 f 1973/2093/1973 1977/3130/1977 1974/2094/1974 f 1974/2094/1974 1977/3130/1977 1975/2095/1975 f 1975/2095/1975 1977/3130/1977 1976/2091/1976 f 1976/2091/1976 1977/3130/1977 1973/2092/1973 f 1979/2120/1979 1929/2119/1929 1930/3131/1930 f 1928/2102/1928 1980/2101/1980 1930/2107/1930 f 1979/2108/1979 1981/2104/1981 1978/2103/1978 f 1982/2110/1982 736/2109/736 735/3132/735 f 738/2112/738 1983/2111/1983 735/3132/735 f 1983/2111/1983 1982/2110/1982 735/3132/735 f 1876/3095/1876 1879/3107/1879 1873/2003/1873 f 1408/3133/1408 1432/3134/1432 1984/3135/1984 f 1945/3127/1945 1985/2073/1985 1958/3128/1958 f 1985/2073/1985 1986/2072/1986 1958/3128/1958 f 1944/3129/1944 1986/2072/1986 1953/3122/1953 f 1944/2061/1944 1953/2068/1953 1947/2062/1947 f 1953/3122/1953 1986/2072/1986 1951/3123/1951 f 1951/3123/1951 1986/2072/1986 1956/2071/1956 f 695/3126/695 751/3136/751 1957/2074/1957 f 751/3136/751 754/2131/754 1988/3137/1988 f 1988/3137/1988 754/2131/754 1989/3138/1989 f 2019/3139/2019 2018/2130/2018 2009/2129/2009 f 751/3136/751 1988/3137/1988 1987/2116/1987 f 1988/3137/1988 1991/2127/1991 1987/2116/1987 f 1987/2116/1987 1991/2127/1991 1990/2113/1990 f 1987/2116/1987 1992/2115/1992 1956/2071/1956 f 1991/2127/1991 1993/2117/1993 1990/2113/1990 f 1989/3138/1989 1996/2124/1996 1988/3137/1988 f 1988/3137/1988 1996/2124/1996 1991/2127/1991 f 1996/2124/1996 1997/3140/1997 2007/2144/2007 f 1992/2115/1992 1998/3141/1998 1956/2071/1956 f 1998/3141/1998 1951/3123/1951 1956/2071/1956 f 1951/3123/1951 1999/3142/1999 1954/3121/1954 f 1998/3141/1998 1999/3142/1999 1951/3123/1951 f 1954/3121/1954 1999/3142/1999 1998/3141/1998 f 1998/3141/1998 1992/2115/1992 1994/2114/1994 f 2004/3119/2004 2148/3143/2148 1979/3120/1979 f 2152/2256/2152 2001/2244/2001 2002/2247/2002 f 2000/2045/2000 2004/3119/2004 1932/2046/1932 f 2004/2097/2004 1933/2050/1933 1932/2053/1932 f 692/2123/692 2005/2096/2005 700/3144/700 f 2005/2096/2005 1978/2098/1978 700/3144/700 f 1957/2074/1957 751/3136/751 1956/2071/1956 f 1956/2071/1956 751/3136/751 1987/2116/1987 f 1996/2124/1996 2007/2144/2007 2030/2147/2030 f 2008/2125/2008 1995/2118/1995 2006/2126/2006 f 1996/2124/1996 2030/2147/2030 2008/2125/2008 f 2009/2129/2009 777/2128/777 2012/3145/2012 f 1997/3140/1997 2018/2130/2018 2019/3139/2019 f 2019/3139/2019 2010/3146/2010 1997/3140/1997 f 1997/3140/1997 2010/3146/2010 2007/2144/2007 f 1997/3140/1997 1996/2124/1996 1989/3138/1989 f 2019/3139/2019 2036/3147/2036 2010/3146/2010 f 2036/3147/2036 2019/3139/2019 2009/2129/2009 f 2035/3148/2035 2036/3147/2036 2012/3145/2012 f 2012/3145/2012 2036/3147/2036 2009/2129/2009 f 2014/2135/2014 2012/3145/2012 756/2132/756 f 2012/3145/2012 777/2128/777 756/2132/756 f 2014/2135/2014 2015/2134/2015 2034/3149/2034 f 2016/3150/2016 2013/2143/2013 2014/2135/2014 f 2016/3150/2016 2033/3151/2033 2013/2143/2013 f 754/2131/754 2018/2130/2018 1989/3138/1989 f 2018/2130/2018 1997/3140/1997 1989/3138/1989 f 1994/2114/1994 2020/3152/2020 2026/3153/2026 f 1995/2118/1995 2021/3154/2021 2020/3152/2020 f 2008/2125/2008 2029/3155/2029 1995/2118/1995 f 2021/3154/2021 2022/2136/2022 2020/3152/2020 f 1994/2114/1994 2023/3156/2023 1998/3141/1998 f 2020/3152/2020 1994/2114/1994 1995/2118/1995 f 1994/2114/1994 2026/3153/2026 2023/3156/2023 f 1995/2118/1995 2029/3155/2029 2021/3154/2021 f 2029/3155/2029 2008/2125/2008 2030/2147/2030 f 2021/3154/2021 2029/3155/2029 2024/3157/2024 f 2021/3154/2021 2024/3157/2024 2022/2136/2022 f 2026/3153/2026 2020/3152/2020 2027/3158/2027 f 2026/3153/2026 2027/3158/2027 2023/3156/2023 f 2027/3158/2027 2025/2139/2025 2023/3156/2023 f 2027/3158/2027 2028/3159/2028 2025/2139/2025 f 2028/3159/2028 2027/3158/2027 2020/3152/2020 f 2025/2139/2025 2028/3159/2028 2022/2136/2022 f 2028/3159/2028 2020/3152/2020 2022/2136/2022 f 2023/3156/2023 2055/3160/2055 1998/3141/1998 f 2029/3155/2029 2030/2147/2030 2024/3157/2024 f 2033/3151/2033 2016/3150/2016 2034/3149/2034 f 2034/3149/2034 2015/2134/2015 2033/3151/2033 f 2035/3148/2035 2037/2141/2037 2036/3147/2036 f 2012/3145/2012 2013/2143/2013 2011/2142/2011 f 2035/3148/2035 2012/3145/2012 2011/2142/2011 f 2012/3145/2012 2014/2135/2014 2013/2143/2013 f 2011/2142/2011 2037/2141/2037 2035/3148/2035 f 2037/2141/2037 2010/3146/2010 2036/3147/2036 f 2031/2137/2031 2022/2136/2022 2024/3157/2024 f 2030/2147/2030 2041/2146/2041 2024/3157/2024 f 2024/3157/2024 2041/2146/2041 2031/2137/2031 f 2040/2145/2040 2010/3146/2010 2037/2141/2037 f 2042/2148/2042 2424/2567/2424 1406/2568/1406 f 1408/3133/1408 2044/3161/2044 2042/2148/2042 f 2039/2150/2039 2044/3161/2044 2043/2152/2043 f 2044/3161/2044 2045/2346/2045 2043/2152/2043 f 2044/3161/2044 2046/3162/2046 2045/2346/2045 f 1984/3135/1984 2044/3161/2044 1408/3133/1408 f 1984/3135/1984 2047/3163/2047 2044/3161/2044 f 2044/3161/2044 2047/3163/2047 2046/3162/2046 f 2047/3163/2047 1984/3135/1984 1432/3134/1432 f 2049/2153/2049 2050/3164/2050 2048/2151/2048 f 2050/3164/2050 2031/2137/2031 2048/2151/2048 f 2031/2137/2031 2050/3164/2050 2032/2138/2032 f 2051/2156/2051 2050/3164/2050 2049/2153/2049 f 2050/3164/2050 2051/2156/2051 2032/2138/2032 f 1998/3141/1998 2055/3160/2055 1954/3121/1954 f 1954/3121/1954 2055/3160/2055 2052/3165/2052 f 2053/2361/2053 2057/2243/2057 2052/3165/2052 f 2057/2243/2057 2053/2361/2053 2054/2175/2054 f 2062/3166/2062 2065/2362/2065 2052/3165/2052 f 2054/2175/2054 2142/2214/2142 2057/2243/2057 f 2052/3165/2052 2057/2243/2057 2056/2242/2056 f 2056/2242/2056 1954/3121/1954 2052/3165/2052 f 2055/3160/2055 2058/2155/2058 2059/2154/2059 f 2058/2155/2058 2025/2139/2025 2032/2138/2032 f 2023/3156/2023 2058/2155/2058 2055/3160/2055 f 2058/2155/2058 2023/3156/2023 2025/2139/2025 f 2059/2154/2059 2060/3167/2060 2055/3160/2055 f 2059/2154/2059 2066/2349/2066 2060/3167/2060 f 2060/3167/2060 2066/2349/2066 2062/3166/2062 f 2066/2349/2066 2063/3168/2063 2062/3166/2062 f 2061/2350/2061 2064/2363/2064 2063/3168/2063 f 2064/2363/2064 2065/2362/2065 2063/3168/2063 f 2052/3165/2052 2065/2362/2065 2053/2361/2053 f 2065/2362/2065 2062/3166/2062 2063/3168/2063 f 2063/3168/2063 2066/2349/2066 2061/2350/2061 f 2060/3167/2060 2062/3166/2062 2055/3160/2055 f 2062/3166/2062 2052/3165/2052 2055/3160/2055 f 2053/2361/2053 2092/2174/2092 2054/2175/2054 f 2070/2159/2070 2072/2177/2072 2067/2160/2067 f 2053/2361/2053 2252/3169/2252 2092/2174/2092 f 2094/2353/2094 2093/2178/2093 2073/2176/2073 f 2091/2179/2091 2074/2169/2074 2071/2163/2071 f 2075/2267/2075 2091/2179/2091 2095/3170/2095 f 2091/2179/2091 2075/2267/2075 2074/2169/2074 f 2080/2167/2080 2081/2168/2081 2101/2173/2101 f 2078/2164/2078 2081/2168/2081 2080/2167/2080 f 2087/3171/2087 2102/3172/2102 2084/2183/2084 f 2086/2180/2086 2101/2173/2101 2085/2184/2085 f 2088/2166/2088 2154/3173/2154 2090/2211/2090 f 2088/2166/2088 2090/2211/2090 2077/2162/2077 f 2067/2160/2067 2072/2177/2072 2071/2163/2071 f 2072/2177/2072 2091/2179/2091 2071/2163/2071 f 2095/3170/2095 2091/2179/2091 2093/2178/2093 f 2155/2212/2155 2069/2158/2069 2068/2157/2068 f 2069/2158/2069 2155/2212/2155 2141/2213/2141 f 2093/2178/2093 2094/2353/2094 2047/3163/2047 f 2094/2353/2094 2046/3162/2046 2047/3163/2047 f 1432/3134/1432 1433/3174/1433 2047/3163/2047 f 1424/3175/1424 1433/3174/1433 1432/3134/1432 f 1433/3174/1433 2160/2260/2160 2095/3170/2095 f 2084/2183/2084 2111/2182/2111 2087/3171/2087 f 2087/3171/2087 2111/2182/2111 2110/2196/2110 f 2101/2173/2101 2097/2186/2097 2100/2289/2100 f 2100/2289/2100 2511/2185/2511 2085/2184/2085 f 2085/2184/2085 2101/2173/2101 2100/2289/2100 f 2101/2173/2101 2086/2180/2086 2080/2167/2080 f 2084/2183/2084 2102/3172/2102 2079/2165/2079 f 2102/3172/2102 2089/2207/2089 2079/2165/2079 f 2174/2197/2174 2103/2210/2103 2096/2189/2096 f 2174/2197/2174 2177/2298/2177 2103/2210/2103 f 2105/2190/2105 2096/2189/2096 2103/2210/2103 f 2110/2196/2110 2113/2202/2113 2087/3171/2087 f 2113/2202/2113 2110/2196/2110 2109/2188/2109 f 2174/2197/2174 2112/2181/2112 2511/2185/2511 f 2087/3171/2087 2113/2202/2113 2115/2198/2115 f 2102/3172/2102 2115/2198/2115 2114/2201/2114 f 2115/2198/2115 2102/3172/2102 2087/3171/2087 f 2089/2207/2089 2116/2206/2116 2154/3173/2154 f 2124/2204/2124 2089/2207/2089 2102/3172/2102 f 2124/2204/2124 2102/3172/2102 2114/2201/2114 f 2125/2217/2125 2129/2219/2129 2127/3176/2127 f 2126/2224/2126 2131/2223/2131 2128/3177/2128 f 2128/3177/2128 2131/2223/2131 2147/2227/2147 f 2130/2222/2130 1882/2221/1882 1903/3178/1903 f 1903/3178/1903 2134/3179/2134 2130/2222/2130 f 2130/2222/2130 2134/3179/2134 2135/2228/2135 f 2134/3179/2134 1903/3178/1903 2132/3180/2132 f 2132/2230/2132 1903/2012/1903 1904/2011/1904 f 2134/3179/2134 2139/2235/2139 2135/2228/2135 f 2139/2236/2139 2134/2233/2134 2137/2232/2137 f 2147/2227/2147 2140/3181/2140 2128/3177/2128 f 2155/2212/2155 2144/2237/2144 2141/2213/2141 f 2143/2258/2143 2140/2248/2140 2001/2244/2001 f 2056/2242/2056 1934/2241/1934 1954/3121/1954 f 2143/2238/2143 1934/2241/1934 2142/2214/2142 f 2002/2247/2002 2146/3182/2146 2003/3183/2003 f 2003/3183/2003 2151/2250/2151 2149/2122/2149 f 2146/3182/2146 2151/2250/2151 2003/3183/2003 f 2000/2257/2000 2150/2121/2150 2148/3184/2148 f 2148/3143/2148 2004/3119/2004 2000/2045/2000 f 2149/2122/2149 2150/2121/2150 2153/3185/2153 f 2150/2121/2150 2000/2257/2000 2153/3185/2153 f 2151/2253/2151 2146/2246/2146 2145/2245/2145 f 2150/2121/2150 1979/2120/1979 2148/3184/2148 f 2003/3183/2003 2153/3185/2153 2002/2247/2002 f 2153/3185/2153 2152/2256/2152 2002/2247/2002 f 2153/3185/2153 2000/2257/2000 2152/2256/2152 f 2149/2122/2149 2153/3185/2153 2003/3183/2003 f 2128/2240/2128 2156/2274/2156 2129/2275/2129 f 2156/2274/2156 2144/2237/2144 2155/2212/2155 f 2156/2274/2156 2128/2240/2128 2144/2237/2144 f 2127/3176/2127 1879/3107/1879 2125/2217/2125 f 2127/3176/2127 2157/3186/2157 1879/3107/1879 f 1879/3107/1879 2157/3186/2157 2164/2522/2164 f 1876/3095/1876 2125/2217/2125 1879/3107/1879 f 1427/3187/1427 2158/1976/2158 1428/2261/1428 f 1426/1973/1426 2158/1976/2158 1427/3187/1427 f 2160/2260/2160 2159/2259/2159 2095/3170/2095 f 2095/3170/2095 2159/2259/2159 2075/2267/2075 f 2160/2260/2160 1433/3174/1433 1428/2261/1428 f 2042/2148/2042 1406/2568/1406 1408/3133/1408 f 2083/2171/2083 2162/2263/2162 2181/2264/2181 f 2165/2266/2165 2075/2267/2075 2159/2259/2159 f 2082/2170/2082 2165/2266/2165 2163/2262/2163 f 2164/1975/2164 2157/3188/2157 2165/2266/2165 f 2161/2265/2161 2181/2264/2181 2183/2293/2183 f 2116/2206/2116 2167/2272/2167 2154/3173/2154 f 2154/3173/2154 2167/2272/2167 2090/2211/2090 f 2161/2265/2161 2098/2187/2098 2099/2172/2099 f 2117/2203/2117 2171/3189/2171 2168/2276/2168 f 2119/2199/2119 2168/2276/2168 2118/2200/2118 f 2117/2203/2117 2168/2276/2168 2119/2199/2119 f 2122/2209/2122 2171/3189/2171 2117/2203/2117 f 2121/2208/2121 2170/2278/2170 2122/2209/2122 f 2122/2209/2122 2170/2278/2170 2171/3189/2171 f 2174/2197/2174 2511/2185/2511 2510/2697/2510 f 2510/2697/2510 2177/2298/2177 2174/2197/2174 f 2173/2283/2173 2168/2294/2168 2171/2284/2171 f 2180/2288/2180 2179/2291/2179 2173/2283/2173 f 2172/2281/2172 2180/2288/2180 2173/2283/2173 f 2183/2293/2183 2184/2292/2184 2161/2265/2161 f 2184/2292/2184 2098/2187/2098 2161/2265/2161 f 2163/2262/2163 2157/3188/2157 2127/2296/2127 f 2157/3188/2157 2163/2262/2163 2165/2266/2165 f 2163/2262/2163 2127/2296/2127 2162/2263/2162 f 2103/2210/2103 2185/2300/2185 2108/2194/2108 f 2185/2300/2185 2190/2305/2190 2189/2302/2189 f 2343/2311/2343 2381/2314/2381 2188/2303/2188 f 2306/2309/2306 2342/2310/2342 2189/2302/2189 f 2193/2313/2193 2305/2308/2305 2190/2305/2190 f 2201/2323/2201 2205/2322/2205 2204/2334/2204 f 2201/2323/2201 2204/2334/2204 2202/2333/2202 f 2204/2334/2204 2205/2322/2205 2203/2330/2203 f 2196/2316/2196 2209/2327/2209 2198/2318/2198 f 2198/2318/2198 2209/2327/2209 2200/2320/2200 f 2197/2319/2197 2256/2365/2256 2195/2317/2195 f 2199/2321/2199 2256/2365/2256 2197/2319/2197 f 2216/2339/2216 2219/3190/2219 2280/2340/2280 f 2216/2339/2216 2220/2280/2220 2219/3190/2219 f 2415/2429/2415 2219/3191/2219 2218/2430/2218 f 2280/2340/2280 2219/3190/2219 2415/2426/2415 f 2219/3191/2219 2217/3192/2217 2218/2430/2218 f 2219/3190/2219 2220/2280/2220 2217/3193/2217 f 1871/1966/1871 2221/1977/2221 1875/2341/1875 f 1878/2342/1878 2224/3098/2224 1875/2341/1875 f 2224/3098/2224 1876/3095/1876 1875/2341/1875 f 2224/3098/2224 1888/3099/1888 1880/2218/1880 f 2225/2345/2225 2228/2344/2228 2226/3194/2226 f 2228/2344/2228 2045/2346/2045 2046/3162/2046 f 2043/2152/2043 2225/2345/2225 2049/2153/2049 f 2226/3194/2226 2228/2344/2228 2227/2360/2227 f 2228/2344/2228 2046/3162/2046 2227/2360/2227 f 2227/2360/2227 2046/3162/2046 2094/2353/2094 f 2230/3195/2230 2231/2351/2231 2073/2176/2073 f 2232/3196/2232 2233/3197/2233 2239/3198/2239 f 2239/3198/2239 2233/3197/2233 2229/3199/2229 f 2232/3196/2232 2236/3200/2236 2233/3197/2233 f 2233/3197/2233 2236/3200/2236 2234/3201/2234 f 2234/3201/2234 2236/3200/2236 2250/2356/2250 f 2250/2356/2250 2236/3200/2236 2235/2357/2235 f 2236/3200/2236 2232/3196/2232 2237/2347/2237 f 2236/3200/2236 2237/2347/2237 2235/2357/2235 f 2232/3196/2232 2239/3198/2239 2238/2348/2238 f 2232/3196/2232 2238/2348/2238 2237/2347/2237 f 2237/2347/2237 2051/2156/2051 2235/2357/2235 f 2238/2348/2238 2239/3198/2239 2061/2350/2061 f 2229/3199/2229 2240/2364/2240 2239/3198/2239 f 2240/2364/2240 2064/2363/2064 2239/3198/2239 f 2061/2350/2061 2239/3198/2239 2064/2363/2064 f 2251/2358/2251 2248/3202/2248 2247/2359/2247 f 2231/2351/2231 2242/3203/2242 2241/2352/2241 f 2229/3199/2229 2242/3203/2242 2231/2351/2231 f 2231/2351/2231 2230/3195/2230 2229/3199/2229 f 2242/3203/2242 2229/3199/2229 2234/3201/2234 f 2234/3201/2234 2229/3199/2229 2233/3197/2233 f 2242/3203/2242 2234/3201/2234 2241/2352/2241 f 2234/3201/2234 2250/2356/2250 2249/3204/2249 f 2250/2356/2250 2225/2345/2225 2226/3194/2226 f 2250/2356/2250 2243/2355/2243 2225/2345/2225 f 2225/2345/2225 2243/2355/2243 2049/2153/2049 f 2051/2156/2051 2244/2354/2244 2235/2357/2235 f 2244/2354/2244 2246/3205/2246 2245/3206/2245 f 2244/2354/2244 2245/3206/2245 2243/2355/2243 f 2243/2355/2243 2245/3206/2245 2049/2153/2049 f 2245/3206/2245 2246/3205/2246 2049/2153/2049 f 2049/2153/2049 2246/3205/2246 2051/2156/2051 f 2246/3205/2246 2244/2354/2244 2051/2156/2051 f 2247/2359/2247 2226/3194/2226 2227/2360/2227 f 2247/2359/2247 2249/3204/2249 2226/3194/2226 f 2249/3204/2249 2250/2356/2250 2226/3194/2226 f 2251/2358/2251 2094/2353/2094 2241/2352/2241 f 2248/3202/2248 2249/3204/2249 2247/2359/2247 f 2251/2358/2251 2241/2352/2241 2248/3202/2248 f 2241/2352/2241 2234/3201/2234 2248/3202/2248 f 2234/3201/2234 2249/3204/2249 2248/3202/2248 f 2073/2176/2073 2252/3169/2252 2230/3195/2230 f 2229/3199/2229 2252/3169/2252 2240/2364/2240 f 2252/3169/2252 2053/2361/2053 2240/2364/2240 f 2252/3169/2252 2229/3199/2229 2230/3195/2230 f 2073/2176/2073 2092/2174/2092 2252/3169/2252 f 2042/2148/2042 2044/3161/2044 2039/2150/2039 f 2154/3173/2154 2088/2166/2088 2089/2207/2089 f 2089/2207/2089 2088/2166/2088 2079/2165/2079 f 2254/2367/2254 2202/2333/2202 2212/2332/2212 f 2213/2335/2213 2203/2330/2203 2210/2329/2210 f 2254/2367/2254 2262/3207/2262 2260/2372/2260 f 2212/2332/2212 2262/3207/2262 2254/2367/2254 f 2212/2332/2212 2264/2337/2264 2262/3207/2262 f 2263/2338/2263 2213/2335/2213 2261/3208/2261 f 2261/3208/2261 2210/2329/2210 2257/2369/2257 f 2210/2329/2210 2261/3208/2261 2213/2335/2213 f 2215/2336/2215 2268/3209/2268 2264/2337/2264 f 2263/2338/2263 2268/3209/2268 2215/2336/2215 f 2264/2380/2264 2268/3210/2268 2263/2379/2263 f 2275/2394/2275 2276/2393/2276 2277/2401/2277 f 2275/2394/2275 2277/2401/2277 2278/2400/2278 f 2277/2401/2277 2276/2393/2276 2279/2397/2279 f 2272/2389/2272 2281/2395/2281 2274/2391/2274 f 2274/2391/2274 2281/2395/2281 2276/2393/2276 f 2273/2392/2273 2289/2406/2289 2271/2390/2271 f 2275/2394/2275 2289/2406/2289 2273/2392/2273 f 2290/2407/2290 2278/2400/2278 2284/2399/2284 f 2285/2402/2285 2279/2397/2279 2282/2396/2282 f 2290/2407/2290 2294/3211/2294 2292/2412/2292 f 2284/2399/2284 2296/3212/2296 2290/2407/2290 f 2284/2399/2284 2287/2404/2287 2296/3212/2296 f 2288/2405/2288 2285/2402/2285 2295/3213/2295 f 2282/2396/2282 2293/3214/2293 2295/3213/2295 f 2293/3214/2293 2282/2396/2282 2291/2409/2291 f 2282/2396/2282 2295/3213/2295 2285/2402/2285 f 2290/2407/2290 2296/3212/2296 2294/3211/2294 f 2286/2403/2286 2300/3215/2300 2287/2404/2287 f 2288/2405/2288 2300/3215/2300 2286/2403/2286 f 2287/2422/2287 2300/3216/2300 2288/2421/2288 f 2217/3192/2217 2302/2431/2302 2218/2430/2218 f 2313/2441/2313 2314/2440/2314 2315/2450/2315 f 2313/2441/2313 2315/2450/2315 2316/2449/2316 f 2315/2450/2315 2314/2440/2314 2317/2446/2317 f 2308/2434/2308 2319/2443/2319 2310/2436/2310 f 2310/2436/2310 2319/2443/2319 2312/2438/2312 f 2309/2437/2309 2328/2455/2328 2307/2435/2307 f 2311/2439/2311 2328/2455/2328 2309/2437/2309 f 2330/2457/2330 2316/2449/2316 2323/2448/2323 f 2324/2451/2324 2317/2446/2317 2321/2445/2321 f 2330/2457/2330 2337/3217/2337 2335/2462/2335 f 2323/2448/2323 2337/3217/2337 2330/2457/2330 f 2323/2448/2323 2326/2453/2326 2337/3217/2337 f 2327/2454/2327 2324/2451/2324 2336/3218/2336 f 2336/3218/2336 2321/2445/2321 2332/2460/2332 f 2321/2445/2321 2336/3218/2336 2324/2451/2324 f 2325/2452/2325 2341/3219/2341 2326/2453/2326 f 2327/2454/2327 2341/3219/2341 2325/2452/2325 f 2326/2470/2326 2341/3220/2341 2327/2469/2327 f 2318/2442/2318 2255/2368/2255 2340/2386/2340 f 2350/2484/2350 2351/2483/2351 2352/2493/2352 f 2350/2484/2350 2352/2493/2352 2353/2492/2353 f 2352/2493/2352 2351/2483/2351 2354/2489/2354 f 2345/2477/2345 2356/2486/2356 2347/2479/2347 f 2347/2479/2347 2356/2486/2356 2349/2481/2349 f 2362/3221/2362 2360/2491/2360 2359/2490/2359 f 2361/2494/2361 2362/3221/2362 2359/2490/2359 f 2346/2480/2346 2363/2495/2363 2344/2478/2344 f 2348/2482/2348 2363/2495/2363 2346/2480/2346 f 2365/2497/2365 2353/2492/2353 2360/2491/2360 f 2361/2494/2361 2354/2489/2354 2358/2488/2358 f 2372/2508/2372 2362/3222/2362 2371/2507/2371 f 2365/2497/2365 2372/3223/2372 2370/2502/2370 f 2360/2491/2360 2372/3223/2372 2365/2497/2365 f 2360/2491/2360 2362/3221/2362 2372/3223/2372 f 2362/3221/2362 2361/2494/2361 2371/3224/2371 f 2371/3224/2371 2358/2488/2358 2367/2499/2367 f 2358/2488/2358 2371/3224/2371 2361/2494/2361 f 2355/2485/2355 2331/2458/2331 2376/2475/2376 f 2414/2558/2414 2302/2517/2302 2378/2516/2378 f 2220/2280/2220 2379/2279/2379 2217/3193/2217 f 2217/2518/2217 2379/3225/2379 2377/2519/2377 f 2108/2194/2108 2380/2306/2380 2120/2195/2120 f 1479/1530/1479 1534/1575/1534 1482/1577/1482 f 1556/1609/1556 1587/1683/1587 1589/1610/1589 f 1595/3033/1595 1571/1626/1571 1579/1628/1579 f 1563/1619/1563 1505/3039/1505 1672/1617/1672 f 1463/1520/1463 1491/3016/1491 1466/1536/1466 f 1447/1508/1447 1462/1521/1462 1455/1524/1455 f 2093/2178/2093 2047/3163/2047 2095/3170/2095 f 2095/3170/2095 2047/3163/2047 1433/3174/1433 f 2389/2531/2389 2390/2530/2390 2391/2540/2391 f 2389/2531/2389 2391/2540/2391 2392/2539/2392 f 2391/2540/2391 2390/2530/2390 2393/2536/2393 f 2384/2524/2384 2395/2533/2395 2386/2526/2386 f 2386/2526/2386 2395/2533/2395 2388/2528/2388 f 2401/3226/2401 2399/2538/2399 2398/2537/2398 f 2400/2541/2400 2401/3226/2401 2398/2537/2398 f 2385/2527/2385 2402/2542/2402 2383/2525/2383 f 2387/2529/2387 2402/2542/2402 2385/2527/2385 f 2404/2544/2404 2392/2539/2392 2399/2538/2399 f 2400/2541/2400 2393/2536/2393 2397/2535/2397 f 2411/2555/2411 2401/3227/2401 2410/2554/2410 f 2404/2544/2404 2411/3228/2411 2409/2549/2409 f 2399/2538/2399 2411/3228/2411 2404/2544/2404 f 2399/2538/2399 2401/3226/2401 2411/3228/2411 f 2401/3226/2401 2400/2541/2400 2410/3229/2410 f 2410/3229/2410 2397/2535/2397 2406/2546/2406 f 2397/2535/2397 2410/3229/2410 2400/2541/2400 f 2394/2532/2394 2366/2498/2366 2375/2514/2375 f 2405/2545/2405 2192/2307/2192 2382/2315/2382 f 2299/3230/2299 2304/2428/2304 2303/2433/2303 f 2299/3230/2299 2415/2429/2415 2304/2428/2304 f 2270/2325/2270 2191/2304/2191 2186/2299/2186 f 2417/2563/2417 2425/2562/2425 2416/2572/2416 f 2423/2564/2423 2419/2571/2419 2420/2565/2420 f 1406/2568/1406 2424/2567/2424 2418/2566/2418 f 562/2569/562 2420/2565/2420 2419/2571/2419 f 2424/2567/2424 2042/2148/2042 2038/2149/2038 f 2416/2572/2416 2425/2562/2425 2426/2609/2426 f 2416/2572/2416 2426/2609/2426 2421/2573/2421 f 2017/2140/2017 2427/3231/2427 2037/2141/2037 f 2427/3232/2427 2456/2614/2456 2425/3233/2425 f 2431/2611/2431 2427/3232/2427 2017/3234/2017 f 2427/3232/2427 2431/2611/2431 2456/2614/2456 f 2040/2145/2040 2427/3231/2427 2425/2562/2425 f 2427/3231/2427 2040/2145/2040 2037/2141/2037 f 2430/2578/2430 2433/2583/2433 2429/2579/2429 f 2015/3235/2015 2438/3236/2438 2033/3237/2033 f 2443/2600/2443 2451/2595/2451 2442/2594/2442 f 2438/3238/2438 2015/2592/2015 2439/2605/2439 f 2014/2135/2014 2034/3149/2034 2016/3150/2016 f 2440/2604/2440 2443/2600/2443 2445/2598/2445 f 2441/3239/2441 2445/2598/2445 2444/2597/2444 f 2445/2598/2445 2441/3239/2441 2440/2604/2440 f 2015/2592/2015 2451/2595/2451 2439/2605/2439 f 2429/2579/2429 2453/2607/2453 2483/3240/2483 f 2452/3241/2452 2453/2607/2453 2448/2603/2448 f 2453/2607/2453 2449/2602/2449 2448/2603/2448 f 2453/2607/2453 2450/2601/2450 2449/2602/2449 f 2453/2607/2453 2454/2606/2454 2450/2601/2450 f 2454/2606/2454 2447/2599/2447 2450/2601/2450 f 2454/2606/2454 2446/2596/2446 2447/2599/2447 f 2437/2585/2437 2455/3242/2455 2436/2586/2436 f 2441/2590/2441 2455/3242/2455 2437/2585/2437 f 2444/2597/2444 2455/3242/2455 2441/3239/2441 f 2446/2596/2446 2455/3242/2455 2444/2597/2444 f 2436/2586/2436 2455/3242/2455 2446/2596/2446 f 1331/2577/1331 2448/2655/2448 2428/2574/2428 f 2429/2579/2429 2483/3240/2483 2432/2580/2432 f 2483/3240/2483 2453/2607/2453 2452/3241/2452 f 2457/3243/2457 2512/2619/2512 2456/3244/2456 f 63/3245/63 2458/2620/2458 2457/3243/2457 f 2514/2621/2514 2464/2624/2464 2463/2623/2463 f 2458/2620/2458 62/3246/62 2468/2629/2468 f 2460/2617/2460 2469/2630/2469 2462/2622/2462 f 63/3245/63 62/3246/62 2458/2620/2458 f 2432/2636/2432 2474/2635/2474 64/3247/64 f 2487/2649/2487 2486/2648/2486 2477/3248/2477 f 2477/3248/2477 2481/2650/2481 2487/2649/2487 f 2482/2644/2482 2485/2645/2485 2484/2646/2484 f 2484/2646/2484 2432/3249/2432 2483/2647/2483 f 2432/3249/2432 2484/2646/2484 2472/3250/2472 f 2485/2645/2485 2472/3250/2472 2484/2646/2484 f 2472/3250/2472 2485/2645/2485 2475/3251/2475 f 2485/2645/2485 2480/2642/2480 2481/2650/2481 f 2475/3251/2475 2485/2645/2485 2481/2650/2481 f 2486/3252/2486 2481/2650/2481 2477/3248/2477 f 2481/2650/2481 2486/3252/2486 2475/3251/2475 f 2490/2652/2490 1435/3253/1435 1434/3254/1434 f 2483/2647/2483 2489/2658/2489 2488/2643/2488 f 2452/2654/2452 2489/2657/2489 2483/3255/2483 f 47/3256/47 2490/2652/2490 1434/3254/1434 f 2490/2652/2490 47/3256/47 61/2651/61 f 64/3247/64 2474/2635/2474 61/2651/61 f 106/2656/106 107/3257/107 1435/3258/1435 f 106/2656/106 1435/3258/1435 2489/2657/2489 f 1435/3253/1435 2490/2652/2490 2489/2658/2489 f 2519/2674/2519 2491/2662/2491 2494/2675/2494 f 2494/2675/2494 2495/3259/2495 2493/2668/2493 f 2495/3260/2495 2459/2664/2459 2493/2698/2493 f 2459/2664/2459 2495/3260/2495 2491/2665/2491 f 2425/2663/2425 2456/3244/2456 2459/2664/2459 f 2493/2668/2493 2496/2667/2496 2494/2675/2494 f 2465/2627/2465 2501/3261/2501 2498/2628/2498 f 2470/2633/2470 2501/3261/2501 2465/2627/2465 f 2498/2680/2498 2501/3261/2501 2499/2679/2499 f 2499/2679/2499 2501/3261/2501 2470/2633/2470 f 2419/2571/2419 1356/2682/1356 562/2569/562 f 2421/2573/2421 2502/2685/2502 2422/2570/2422 f 2502/2685/2502 2421/2573/2421 14/2608/14 f 2507/2686/2507 2508/2694/2508 2506/2690/2506 f 2041/2146/2041 2048/2151/2048 2031/2137/2031 f 2013/2143/2013 2033/3151/2033 2017/2140/2017 f 2033/3237/2033 2438/3236/2438 2017/3262/2017 f 2040/2145/2040 2007/2144/2007 2010/3146/2010 f 2502/2689/2502 2503/3263/2503 2507/2686/2507 f 2512/2619/2512 2457/3243/2457 2458/2620/2458 f 2456/3244/2456 2512/2619/2512 2459/2664/2459 f 2514/2621/2514 2463/2623/2463 2461/2699/2461 f 2464/2624/2464 2514/2621/2514 2462/2622/2462 f 2468/2629/2468 62/3246/62 46/2700/46 f 2515/2671/2515 2518/2673/2518 2468/2629/2468 f 2517/2681/2517 2471/2632/2471 2500/2631/2500 f 2469/2630/2469 2518/2673/2518 2516/2676/2516 f 2518/2673/2518 2469/2630/2469 2468/2629/2468 f 2492/2659/2492 2518/2673/2518 2515/2671/2515 f 2491/2662/2491 2519/2674/2519 2492/2659/2492 f 2519/2674/2519 2518/2673/2518 2492/2659/2492 f 2494/2675/2494 2491/2662/2491 2495/3259/2495 # 5022 faces g ================================================ FILE: graphics/tiny-renderer/meta.json ================================================ { "order":{ "lesson1.workbook":"Lesson 1: Line Drawing Algorithm", "lesson2.workbook":"Lesson 2: Triangle rasterization", "lesson3.workbook":"Lesson 3: Hidden faces removal", "lesson4.workbook":"Lesson 4: Perspective projection", "lesson5.workbook":"Lesson 5: Moving the camera", "lesson6.workbook":"Lesson 6: Shaders for the software renderer", "lesson6bis.workbook":"Lesson 6: tangent space normal mapping", "lesson7.workbook":"Lesson 7: Shadow mapping", "lesson8.workbook":"Lesson 8: Ambient occlusion" } } ================================================ FILE: graphics/urhosharp/.gitignore ================================================ Urho3D.log CoreData.pak ================================================ FILE: graphics/urhosharp/animated-model/animated-model.workbook/Data/License.txt ================================================ -------------------------- note: -------------------------- There is no requirement in the Mixamo License to provide any license information with any content. However, for the purpose of learning, I have provided some pertinent information below. -------------------------- info: -------------------------- website: https://www.mixamo.com/ model: Mutant license: http://www.adobe.com/legal/terms.html -------------------------- license short explanation (from the forum): -------------------------- Jeanette Mathews May 31, 2016 07:24 Thanks for the feedback, and glad to hear the tutorial was useful getting you started. :) Yes, all Fuse and Mixamo content is available for commercial and non commercial use, royalty free. You can edit them to your hearts content! The only requirement we have is that the final product you are creating must have our content in an 'embedded', non-editable format. So you can't edit the characters and sell them directly, because then other people have access to the character 3d data files. Games, movies, 3d prints, 2D illustrations, or any other file format where the character/animation files are not-editable is fine. Selling characters/animations directly is against the TOS/EULA. Hope that helps clarify! reference: https://community.mixamo.com/hc/en-us/community/posts/211496987-Mixamo-Store-Characters-Licence -------------------------- ================================================ FILE: graphics/urhosharp/animated-model/animated-model.workbook/Data/Materials/mutant_M.xml ================================================ ================================================ FILE: graphics/urhosharp/animated-model/animated-model.workbook/index.workbook ================================================ --- id: 6b6c224f-07e3-4b6e-b006-c5291041792f uti: com.xamarin.workbook title: "UrhoSharp: Animated Model" platforms: - Console packages: - id: UrhoSharp version: 1.5.22 --- # Animated Models UrhoSharp is a powerful 3D game engine for Xamarin and .NET developers. It is similar in spirit to Apple’s SceneKit and SpriteKit and includes physics, navigation, networking, and much more...while still being cross-platform. ```csharp #r "Urho" using Urho; using Urho.Actions; using Urho.Shapes; using Urho.Gui; using Urho.Urho2D; using System.IO; ``` ```csharp var app = SimpleApplication.Show ( new ApplicationOptions ("Data") { Width = 800, Height = 800 }); ``` We have created a window containing a `SimpleApplication`. Loading the Mutant model via AnimatedModel component, and play "Idle" looped animation by default. ```csharp app.RootNode.RemoveAllChildren(); var node = app.RootNode.CreateChild(); var mutantModel = node.CreateComponent(); mutantModel.Model = app.ResourceCache.GetModel("Models/Mutant.mdl"); mutantModel.SetMaterial(app.ResourceCache.GetMaterial("Materials/mutant_M.xml")); node.SetScale(2.5f); var animation = node.CreateComponent(); animation.Play("Animations/Mutant_Idle0.ani", 0, true, 0.2f); node.Position = new Vector3(0, -2f, 0.2f); ``` Enumerate all available animations ```csharp var aniFiles = System.IO.Directory.GetFiles("Data/Animations").Select(i => Path.GetFileName(i)).ToArray(); ``` ```csharp animation.StopAll(0); animation.Play($"Animations/{aniFiles[9]}", 0, true, 0.2f); ``` ================================================ FILE: graphics/urhosharp/barchart/charts.workbook/index.workbook ================================================ --- id: a98401e1-2efa-4b55-a83b-6d55f2bda733 uti: com.xamarin.workbook title: "UrhoSharp: Charts" platforms: - Console packages: - id: UrhoSharp version: 1.5.22 --- ```csharp #r "Urho" ``` We are going to bring the Urho namespaces: ```csharp using Urho; using Urho.Actions; using Urho.Shapes; ``` We create our main window to display our data: ```csharp var app = SimpleApplication.Show(); ``` We are going to add nodes that have a visual component (the bar) and add a plane to it: ```csharp app.RootNode.RemoveAllChildren(); //1 var bar1 = app.RootNode.CreateChild(); bar1.AddComponent(new Bar("Cats", Color.Red)); bar1.Position = new Vector3(0, 0, 0); //2 var bar2 = app.RootNode.CreateChild(); bar2.AddComponent(new Bar("Dogs", Color.Yellow)); bar2.Position = new Vector3(1.5f, 0, 0); //3 var bar3 = app.RootNode.CreateChild(); bar3.AddComponent(new Bar("Mice", Color.Blue)); bar3.Position = new Vector3(3f, 0, 0); //4 var bar4 = app.RootNode.CreateChild(); bar4.AddComponent(new Bar("Birds", Color.Green)); bar4.Position = new Vector3(4.5f, 0, 0); //plane app.RootNode.RunActions(new Parallel(new RotateTo(1f, -15, -20, 0), new MoveTo(1f, new Vector3(-2, -5, 8)))); var planeNode = app.RootNode.CreateChild(); planeNode.Position = new Vector3(4, -5, 4); planeNode.Scale = new Vector3(10, 1, 4); var plane = planeNode.CreateComponent(); plane.Color = Color.White; ``` We are now going to set their sizes: ```csharp Random rand = new Random(); app.RootNode.GetChildrenWithComponent().ToList().ForEach(i => i.GetComponent().Value = (float)rand.NextDouble() * 3 + 1); ``` ================================================ FILE: graphics/urhosharp/building-polyhedra/BuildingPolyhedra.workbook/CreateModel.csx ================================================ using System; using System.Collections.Generic; using Urho; Model CreateModel(IList positions, IList normals = null, IList colors = null, IList texcoords = null) { // Check that the positions argument isn't null if (positions == null) throw new ArgumentNullException("positions"); // Make sure it has a property number of elements int vertexCount = positions.Count; if (vertexCount == 0 || vertexCount % 3 != 0) throw new ArgumentOutOfRangeException("positions count must be non-zero and a multiple of 3"); // Check that the normals argument is consistent, or create it if (normals != null) { if (normals.Count != vertexCount) throw new ArgumentOutOfRangeException("texcoords must have same count as positions"); } else { normals = new Vector3[vertexCount]; for (int i = 0; i < vertexCount; i += 3) { normals[i + 0] = Vector3.Cross(positions[i + 1] - positions[i + 0], positions[i + 2] - positions[i + 0]); normals[i + 1] = Vector3.Cross(positions[i + 2] - positions[i + 1], positions[i + 0] - positions[i + 1]); normals[i + 2] = Vector3.Cross(positions[i + 0] - positions[i + 2], positions[i + 1] - positions[i + 2]); } } // Create the VertexBuffer object; set it in one of the blocks below VertexBuffer vertexBuffer = new VertexBuffer(Application.CurrentContext, false) { Shadowed = true }; // If texcoords is non-null, use a PositionNormalColorTexcoord structure if (texcoords != null) { if (texcoords.Count != vertexCount) throw new ArgumentOutOfRangeException("texcoords must have same count as positions"); if (colors != null && colors.Count != vertexCount) throw new Exception("colors must have same count as positions"); var vertices = new VertexBuffer.PositionNormalColorTexcoord[vertexCount]; for (int i = 0; i < vertexCount; i++) { vertices[i].Position = positions[i]; vertices[i].Normal = normals[i]; vertices[i].Color = colors == null ? 0 : colors[i].ToUInt(); vertices[i].TexCoord = texcoords[i]; } vertexBuffer.SetSize((uint)vertexCount, ElementMask.Position | ElementMask.Normal | ElementMask.Color | ElementMask.TexCoord1, false); vertexBuffer.SetData(vertices); } // If colors is non-null, use a PositionNormalColor structure else if (colors != null) { if (colors.Count != vertexCount) throw new Exception("colors must have same count as positions"); VertexBuffer.PositionNormalColor[] vertices = new VertexBuffer.PositionNormalColor[vertexCount]; for (int i = 0; i < vertexCount; i++) { vertices[i].Position = positions[i]; vertices[i].Normal = normals[i]; vertices[i].Color = colors[i].ToUInt(); } vertexBuffer.SetSize((uint)vertexCount, ElementMask.Position | ElementMask.Normal | ElementMask.Color, false); vertexBuffer.SetData(vertices); } // Otherwise use the PositionNormal structure else { VertexBuffer.PositionNormal[] vertices = new VertexBuffer.PositionNormal[vertexCount]; for (int i = 0; i < vertexCount; i++) { vertices[i].Position = positions[i]; vertices[i].Normal = normals[i]; } vertexBuffer.SetSize((uint)vertexCount, ElementMask.Position | ElementMask.Normal, false); vertexBuffer.SetData(vertices); } // Create the Geometry object Geometry geometry = new Geometry(); geometry.SetVertexBuffer(0, vertexBuffer); geometry.SetDrawRange(PrimitiveType.TriangleList, 0, 0, 0, (uint)vertexCount, true); // Create the Model object Model model = new Model(); model.NumGeometries = 1; model.SetGeometry(0, 0, geometry); model.BoundingBox = new BoundingBox(new Vector3(-10, -10, -10), new Vector3(10, 10, 10)); return model; } ================================================ FILE: graphics/urhosharp/building-polyhedra/BuildingPolyhedra.workbook/UrhoSettings.csx ================================================ using System; using System.Collections.Generic; using System.Reflection; using Urho; Node lightNode1, lightNode2; Light light1, light2; void Initialize(SimpleApplication app) { // Move the camera and set it's direction app.CameraNode.Position = new Vector3(0, 0, -5); app.CameraNode.SetDirection(new Vector3(0, 0, 1)); // Set the root node at the origin app.RootNode.Position = new Vector3(0, 0, 0); // Remove the point light app.CameraNode.RemoveAllChildren(); // Remove previous directionalLight nodes before adding new one app.Scene.RemoveChild(app.Scene.GetChild("directionalLight1")); lightNode1 = app.Scene.CreateChild("directionalLight1"); app.Scene.RemoveChild(app.Scene.GetChild("directionalLight2")); lightNode2 = app.Scene.CreateChild("directionalLight2"); // Create the light compononents and set color and direction light1 = lightNode1.CreateComponent(); light1.LightType = LightType.Directional; light1.Color = new Color(0.4f, 0.4f, 0.4f); lightNode1.SetDirection(new Vector3(2, -3, 1)); light2 = lightNode2.CreateComponent(); light2.LightType = LightType.Directional; light2.Color = new Color(0.2f, 0.2f, 0.2f); lightNode2.SetDirection(new Vector3(0, 0, 1)); // Set the ambient light app.Zone.AmbientColor = new Color(0.4f, 0.4f, 0.4f); // Disable the code that moves the camera in response to mouse and touch app.MoveCamera = false; // Detach ALL Update handler FieldInfo field = typeof(Application).GetField("Update", BindingFlags.Instance | BindingFlags.NonPublic); field.SetValue(app, null); // Define an event handler to apply rotation to RootNode with the mouse app.Update += (UpdateEventArgs args) => { if (app.Input.GetMouseButtonDown(MouseButton.Left)) { Vector2 mouseMove = new Vector2(app.Input.MouseMove.X, -app.Input.MouseMove.Y); float angle = mouseMove.Length; // 1 degree per pixel is simple if (angle > 0) { Vector3 axis = new Vector3(mouseMove.Y, -mouseMove.X, 0); app.RootNode.Rotate(Quaternion.FromAxisAngle(axis, angle), TransformSpace.Parent); } } }; } ================================================ FILE: graphics/urhosharp/building-polyhedra/BuildingPolyhedra.workbook/index.workbook ================================================ --- id: 8254f6d9-784a-4a79-bc0b-a5f7fe9705d6 uti: com.xamarin.workbook title: "UrhoSharp: Building Polyhedra" platforms: - Console packages: - id: UrhoSharp version: 1.5.22 --- # Building Polyhedra with UrhoSharp One of the best ways to gain a familiarity and skill in working with 3D graphics is by building various sorts of figures, and particularly, polyhedra. A polyhedron is a three-dimensional solid with flat faces. Each face of a polyhedron is a polygon with straight sides. This workbook demonstrates how to use UrhoSharp to construct a regular dodecahedron and three *stellations* of the dodecahedron, which are produced by extending (“stellating”) the pentagons that make up the dodecahedron. UrhoSharp is a powerful cross-platform 3D graphics engine available to Xamarin and .NET developers for games or visualization. If you’re unfamiliar with UrhoSharp concepts, you’ll want to download and run the following workbooks before tackling this one: * **Exploring Urho Coordinates** * **Creating Urho Compound Shapes** * **Working with Urho Custom Geometries** If you’re ready to go, wait until the workbook has completely finished loading before executing the following code cell: ```csharp #r "Urho" ``` This workbook requires only one namespace for UrhoSharp types: ```csharp using Urho; ``` As usual when exploring Urho in a workbook, call the static `SimpleApplication.Show` method to create a window for the Urho graphics: ```csharp SimpleApplication app = SimpleApplication.Show( new ApplicationOptions() { Width = 1000, Height = 1000 }); ``` You should see a window appear on the desktop as the `Show` method completes. ## Preliminaries In preparation for this workbook, load the following C# script file: ```csharp #load "UrhoSettings.csx" ``` As you know, `SimpleApplication` creates a camera, a point light source, and a root node for visuals. The **UrhoSettings.csx** script file contains a method named `Initialize` that adjusts the position and direction of the camera, replaces the point light source with directional light sources and ambient light, and sets the position of `RootNode` to the origin of the coordinate system. These settings are similar to those shown in the **Working with Urho Custom Geometries** workbook, except that two directional light sources are created: one coming from above the viewer’s left shoulder, and another pointing in the same direction as the camera. This second light gives the objects created here a little more definition. Run that `Initialize` method: ```csharp Initialize(app); ``` As in that earlier workbook, the `Initialize` method also disables the code in `SimpleApplication` that moves the camera in response to mouse and touch. Instead, it sets up an event handler that applies a rotation transform to `RootNode` when you move the mouse along the Urho window with the left mouse button depressed. You can use this to rotate graphical objects for observation. The **Working with Urho Custom Geometries** workbook also described this C# script file: ```csharp #load "CreateModel.csx" ``` The **CreateModel.csx** script contains a method named `CreateModel` that creates a UrhoSharp `Model` class based on vertex information passed to the method. ## Polyhedra and Platonic Solids A polyhedron is a 3D solid with flat polygonal faces. Polyhedra can be divided into many different categories, such as convex and concave. A regular polyhedron is one in which all the faces are the same shape. There are only five regular convex polyhedra. These are known as the Platonic solids: * Tetrahedron: Four triangle faces * Cube: Six square faces * Octahedron: Eight triangle faces * Dodecahedron: Twelve pentagonal faces * Icosahedron: Twenty triangle faces You’ve already seen the tetrahedron in **Working with Urho Custom Geometries** workbook, and the cube is easy enough to be left to the student. The regular dodecahedron is a nice challenge, and it is also the basis on which to build the stellated dodecahedrons. ## The Regular Dodecahedron The regular dodecahedron has twelve faces. Each face is a regular pentagon. To begin rendering the dodecahedron, you must somehow define the 3D coordinates of all the vertices in the object. Fortunately, this information is available. The [Wolfram MathWorld article on the Regular Dodecahedron](http://mathworld.wolfram.com/RegularDodecahedron.html) has plenty of information, but it’s probably somewhat easier to use the [Cartesian Coordinates section of the Wikipedia article on the Regular Dodecahedron](https://en.wikipedia.org/wiki/Regular_dodecahedron#Cartesian_coordinates). This section (and accompanying illustration) provides enough information to create a dodecahedron that is centered around the point (0, 0, 0) and fits inside a circle with the radius √3. The coordinates of the dodecahedron involve the Golden Ratio, which is a number often symbolized by the Greek phi (ϕ) that satisfies the following formula: 1 / ϕ = ϕ – 1 It’s approximately equal to 1.618. Here is a calculation of the Golden Ratio: ```csharp float G = (1 + (float)Math.Sqrt(5)) / 2; ``` The coordinates also involve 1 divided by the Golden Ratio, and because G is the Golden Ratio, 1 / G is equal to G – 1: ```csharp float H = G - 1; ``` Here is a two-dimensional array of `Vector3` values. Each row is one of the 12 pentagonal faces of the dodecahedron, and the five values are the five vertices of the pentagon: ```csharp Vector3[,] dodecahedronFaces = { { new Vector3( 1,-1,-1), new Vector3( G,0,-H), new Vector3( G,0, H), new Vector3( 1,-1, 1), new Vector3( H,-G,0) }, { new Vector3(-1,-1, 1), new Vector3(-G,0, H), new Vector3(-G,0,-H), new Vector3(-1,-1,-1), new Vector3(-H,-G,0) }, { new Vector3(-1, 1,-1), new Vector3(-G,0,-H), new Vector3(-G,0, H), new Vector3(-1, 1, 1), new Vector3(-H, G,0) }, { new Vector3( 1, 1, 1), new Vector3( G,0, H), new Vector3( G,0,-H), new Vector3( 1, 1,-1), new Vector3( H, G,0) }, { new Vector3(-1, 1,-1), new Vector3(0, H,-G), new Vector3(0,-H,-G), new Vector3(-1,-1,-1), new Vector3(-G,0,-H) }, { new Vector3(-1,-1, 1), new Vector3(0,-H, G), new Vector3(0, H, G), new Vector3(-1, 1, 1), new Vector3(-G,0, H) }, { new Vector3( 1,-1,-1), new Vector3(0,-H,-G), new Vector3(0, H,-G), new Vector3( 1, 1,-1), new Vector3( G,0,-H) }, { new Vector3( 1, 1, 1), new Vector3(0, H, G), new Vector3(0,-H, G), new Vector3( 1,-1, 1), new Vector3( G,0, H) }, { new Vector3( 1,-1,-1), new Vector3( H,-G,0), new Vector3(-H,-G,0), new Vector3(-1,-1,-1), new Vector3(0,-H,-G) }, { new Vector3(-1, 1,-1), new Vector3(-H, G,0), new Vector3( H, G,0), new Vector3( 1, 1,-1), new Vector3(0, H,-G) }, { new Vector3(-1,-1, 1), new Vector3(-H,-G,0), new Vector3( H,-G,0), new Vector3( 1,-1, 1), new Vector3(0,-H, G) }, { new Vector3( 1, 1, 1), new Vector3( H, G,0), new Vector3(-H, G,0), new Vector3(-1, 1, 1), new Vector3(0, H, G) } }; ``` These vertices define a dodecahedron where the pentagon faces have sides of length 2 × H. The following two values will be convenient in some loops: ```csharp int faceCount = dodecahedronFaces.GetLength(0); int vertexCount = dodecahedronFaces.GetLength(1); ``` The twelve faces of the dodecahedron are pentagons: ![](Images/PentagonPlain.svg) For a UrhoSharp model, each pentagon must be divided into triangles. There are a couple ways to do that. If you’re trying to minimize the number of triangles, you can divide a pentagon into three triangles: ![](Images/Pentagon3Triangles.svg) However, the code is somewhat simpler if you triangulate each pentagon more symmetrically based on a center point: ![](Images/Pentagon5Triangles.svg) The center point of each face is not directly available, but these centers can be easily calculated by averaging the five vertices of each pentagon. The following code calculates and stores these centers: ```csharp Vector3[] centers = new Vector3[faceCount]; for (int face = 0; face < faceCount; face++) { centers[face] = new Vector3(); for (int vertex = 0; vertex < vertexCount; vertex++) { centers[face] += dodecahedronFaces[face, vertex]; } centers[face] /= vertexCount; } ``` Because the UrhoSharp `Vector3` structure is used for both points and vectors, it supports many convenient arithmetic operations, such as addition and division. A `Vector3` collection can then be defined for storing the actual triangle vertices. When the loop finishes, `dodecahedronMesh` will contain 180 `Vector3` values, three for each triangle, with five triangles per pentagon, and 12 pentagons in the dodecahedron: ```csharp List dodecahedronMesh = new List(); for (int face = 0; face < faceCount; face++) { for (int vertex = 0; vertex < vertexCount; vertex++) { dodecahedronMesh.Add(centers[face]); dodecahedronMesh.Add(dodecahedronFaces[face, vertex]); dodecahedronMesh.Add(dodecahedronFaces[face, (vertex + 1) % vertexCount]); } } ``` The `CreateModel` function from the **CreateModel.csx** script file loaded earlier calculates a `Model` object: ```csharp Model dodecahedronModel = CreateModel(dodecahedronMesh); ``` The following is similar to code that you’ve seen before. It first removes the node that might have been created in an earlier execution of this block, and then associates a new node with the `Model` object just created, and give it a color: ```csharp app.RootNode.RemoveChild(app.RootNode.GetChild("dodecahedronNode", false)); Node dodecahedronNode = app.RootNode.CreateChild("dodecahedronNode"); StaticModel dodecahedron = dodecahedronNode.CreateComponent(); dodecahedron.Model = dodecahedronModel; dodecahedron.SetMaterial(Material.FromColor(Color.Cyan)); ``` At this point the dodecahedron should fill the window, and you can use your mouse with the button depressed to rotate it around the X and Y axes. ## The Small Stellated Dodecahedron The word *stellate* means to extend in a way that often resembles a star. In the small stellated dodecahedron, each pentagon face becomes the interior area of a five-pointed star (also known as a pentagram). The result is still considered to be a regular dodechadron: It has 12 faces of the same shape, but it is not convex. It is one of only four regular nonconvex polyhedra, known as *star polyhedra*. The small stellated dodecahedron is larger than the regular dodecahedron, so move the camera back a bit: ```csharp app.CameraNode.Position = new Vector3(0, 0, -8); ``` In the regular dodecahedron, each face is a pentagon: ![TK](Images/PentagonPlain.svg) In the small stellated dodecahedron, the pentagon is replaced with a pentagram as if the pentagon were the center of the star: ![](Images/FullStar.svg) Amazingly (as you’ll soon see), each point of each star meets up with five other points to form a solid figure. Although the center pentagon is considered part of the face, those pentagons are not visible, so they will not be drawn in the code below. The challenging part is calculating the coordinate at the end of each star point. Draw a line from the center to one of the points: ![](Images/OnePointLine.svg) That line bisects the line between the consecutive two vertices of the pentagon. Therefore a vector from the center to that midpoint can be calculated by subtracting the center point from the midpoint. That vector must then be multiplied by the length of the line. Each edge of the pentagon is 2 × H, where H is the Golden Ratio minus 1. The line from the center to the star point creates two right triangles with a common side equal to H: ![TK](Images/OnePointAngles.svg) The angles are easy to calculate if you start by observing that the interior angles of the pentagon are 108 degrees. (For any polygon, the interior angles always total to the number of sides times 90 degrees. For a pentagon, that’s 540 degrees. Then divide by the number of sides, or 5.) Half of that is 54 degrees, and the other angles can be derived from that. Or, the angle from the center to any pair of consecutive vertices is 360 degrees divided by 5, or 72 degrees. The angle at the center point is half that, or 36 degrees. The length of the line from the center to the point of the star can be calculated with trigonometry: It’s the sum of H divided by the tangent of 36 degrees (for the side of the triangle inside the pentagon), and H divided by the tangent of 18 degrees (for the triangle in the point of the star). The following code calculates the locations of the five points of each of the stellated stars: ```csharp Vector3[,] starPoints = new Vector3[faceCount, vertexCount]; for (int face = 0; face < faceCount; face++) { Vector3 center = centers[face]; for (int vertex = 0; vertex < vertexCount; vertex++) { // Get vector from center to midpoint of two vertices Vector3 vertex1 = dodecahedronFaces[face, vertex]; Vector3 vertex2 = dodecahedronFaces[face, (vertex + 1) % vertexCount]; Vector3 midPoint = (vertex1 + vertex2) / 2; Vector3 vector = midPoint - center; vector.Normalize(); // Calculate the length from center to star point float length = (float)(H / Math.Tan(Math.PI / 5) + H / Math.Tan(Math.PI / 10)); // The star point is the center plus the scaled vector starPoints[face, vertex] = center + length * vector; } } ``` The ssdMesh (“small stellated dodecahedron mesh”) assembles the triangle meshes for the additional triangles required for the small stellated dodecahedron: ```csharp List ssdMesh = new List(); for (int face = 0; face < faceCount; face++) { for (int vertex = 0; vertex < vertexCount; vertex++) { // Add three points to the mesh collection ssdMesh.Add(dodecahedronFaces[face, vertex]); ssdMesh.Add(starPoints[face, vertex]); ssdMesh.Add(dodecahedronFaces[face, (vertex + 1) % vertexCount]); } } ``` Although the trigonometry was derived from a two-dimensional rendition of a star, it works just as well in three dimensions because each star is flat. The following code creates the node and `StaticModel`, and calls `CreateModel` to obtain a `Model` object from the mesh: ```csharp app.RootNode.RemoveChild(app.RootNode.GetChild("ssdNode", false)); Node ssdNode = app.RootNode.CreateChild("ssdNode"); StaticModel ssd = ssdNode.CreateComponent(); ssd.Model = CreateModel(ssdMesh); ssd.SetMaterial(Material.FromColor(Color.Cyan)); ``` This is a fascinating figure. You can see how the twelve five-pointed stars meet up to form a solid figure, but it also seems as if the regular dodecahedron has been enhanced by the placement of a five-sided pyramid of each of the original faces. The peaks of each trio of adjacent pyramid forms a triangle, and if these peaks were actually connected by triangles, they would form an icosahedron. ## The Great Dodecahedron Another intestesting aspect of the small stellated dodecahedron is that the five points of each star form a pentagon. What would happen if each of the star was replaced by that pentagon? The result is called the *great dodecahedron*. It is still a regular polyhedron because each face is the same — a pentagon — but part of each face is hidden by intersecting faces, and the result is not convex. With the data already accumulated, the great dodecahedron is easy to construct. Each triangle in the mesh is simply the space between successive points of the five-pointed stars: ```csharp List greatDodecahedronMesh = new List(); for (int face = 0; face < faceCount; face++) { for (int vertex = 0; vertex < vertexCount; vertex++) { greatDodecahedronMesh.Add(dodecahedronFaces[face, vertex]); greatDodecahedronMesh.Add(starPoints[face, (vertex + vertexCount - 1) % vertexCount]); greatDodecahedronMesh.Add(starPoints[face, vertex]); } } ``` Once again, create the node and model, and give it a color: ```csharp app.RootNode.RemoveChild(app.RootNode.GetChild("greatDodecahedronNode", false)); Node greatDodecahedronNode = app.RootNode.CreateChild("greatDodecahedronNode"); StaticModel greatDodecahedron = greatDodecahedronNode.CreateComponent(); greatDodecahedron.Model = CreateModel(greatDodecahedronMesh); greatDodecahedron.SetMaterial(Material.FromColor(Color.Cyan)); ``` The faces are definitely pentagons (which is why this is not considered a stellated figure) but against each pentagon is what appears to be an embossed five-pointed star with a raised center. However, this star is nothing more than the meeting of ten pentagons. Can this process go one more level? ## The Great Stellated Dodecahedron The great dodecahedron can itself be stellated and the result is called the stellated great dodecahedron or, more commonly, the great stellated dodecahedron. This workbook began with a regular dodecahedron, which has faces that are pentagons: ![](Images/StellationsStep0.svg) These faces were stellated, which added triangles to make the faces into stars: ![](Images/StellationsStep1.svg) The result was the small stellated dodecahedron. The points of the stars were then connected to make a pentagon again: ![](Images/StellationsStep2.svg) That was the great dodecahedron. And now, this pentagon will be stellated: ![](Images/StellationsStep3.svg) That’s going to be the great stellated dodecahedron. There are two pentagons in that final composite figure. What is the relationship between the length of the side of the larger pentagon to the smaller pentagon? If you do the trigonometry, the larger pentagon has a side length that is (sin(54) / sin(18)) times the smaller one. It turns out that this ratio is related to the Golden Ratio ϕ. The ratio of the sines of those two angles equals (ϕ + 1). The vertices of the original pentagon were defined so that the length of the side is (ϕ – 1), which means that the length of the side of the larger pentagon is (ϕ + 1)·(ϕ – 1), which equals ϕ² – 1. The Golden Ratio squared is actually (ϕ + 1), which means that the length of the side of the larger pentagon is simply ϕ. The calculation of the coordinates of the large star points use G defined earlier in this workbook as the Golden Ratio: ```csharp Vector3[,] greatStarPoints = new Vector3[faceCount, vertexCount]; for (int face = 0; face < faceCount; face++) { Vector3 center = centers[face]; for (int vertex = 0; vertex < vertexCount; vertex++) { // Get vector from center to vertex of original pentagon Vector3 vector = dodecahedronFaces[face, vertex] - center; vector.Normalize(); // Calculate the length from center to star point float length = (float)(G / Math.Tan(Math.PI / 5) + G / Math.Tan(Math.PI / 10)); // The star point is the center plus the scaled vector greatStarPoints[face, vertex] = center + length * vector; } } ``` Just as earlier, triangles describing the points of these stars can be accumulated in a collection called `gsdMesh` for “great stellated dodecahendron”): ```csharp List gsdMesh = new List(); for (int face = 0; face < faceCount; face++) { for (int vertex = 0; vertex < vertexCount; vertex++) { gsdMesh.Add(greatStarPoints[face, vertex]); gsdMesh.Add(starPoints[face, vertex]); gsdMesh.Add(starPoints[face, (vertex + vertexCount - 1) % vertexCount]); } } ``` Move the camera further back because this is going to grow considerably in size: ```csharp app.CameraNode.Position = new Vector3(0, 0, -20); ``` And display the new model: ```csharp app.RootNode.RemoveChild(app.RootNode.GetChild("gsdNode", false)); Node gsdNode = app.RootNode.CreateChild("gsdNode"); StaticModel gsd = gsdNode.CreateComponent(); gsd.Model = CreateModel(gsdMesh); gsd.SetMaterial(Material.FromColor(Color.Cyan)); ``` Now as you twist this new figure around and examine it, you’ll discover that the triangular faces are very hard to detect. Instead, this figure seems to be a collection of three-sided pyramids emanating like spikes. It’s possible to view it so that a group of five of these spikes seem to form a three-dimensional star. But this is the end of the line. It is not possible to stellate again and create another regular polyhedron. ## Modifying the Vertex Buffer If you wanted to remove the additional triangles that created the various stellations of the dodecahedron, you could simply remove the nodes for these additional models. But another approach — an approach that will eventually lead to an animation of these stellations — is to modify the vertex buffer so that the triangles defining the model have no dimension. That will cause them to disappear from view. Here is the `Model` object for the great stellated dodecahedron, which was the last step in this process: ```csharp Model model = gsd.Model; ``` From the model the `Geometry` is available: ```csharp Geometry geometry = model.GetGeometry(0, 0); ``` And from the geometry, the `VertexBuffer` can be obtained: ```csharp VertexBuffer buffer = geometry.GetVertexBuffer(0); ``` Information about this `VertexBuffer` is also available. This is how many vertices it contains: ```csharp uint count = buffer.VertexCount; ``` The value of 180 encompasses the 12 faces, the 5 triangles per face, and the 3 coordinates per triangle. The size of the `VertexBuffer` is also available: ```csharp uint size = buffer.VertexSize; ``` The value of 24 is the byte size of the `VertexBuffer.PositionNormal` structure used to create the vertex buffer in the **CreateModel.csx** script. The structure contains two fields `Position` and `Normal` of type `Vector3`. The `Vector3`structure contains three fields of type `float`, and each `float`is 4 bytes in size. You can also get access to the items stored in the vertex buffer itself. In this example, these are an array of `VertexBuffer.PositionNormal` values. After getting access to this array, you can dynamically modify the values, and the visuals will be updated. However, there’s a catch: To get access to these vertices, you must call the `Lock` method of `VertexBuffer`. This method returns an `IntPtr`, which you can then cast to a pointer of type `VertexBuffer.PositionNormal`. When you’re finished, call `Unlock`. But because you’re now working with pointers in C# code, you must put this code in an `unsafe` block. The following code obtains that pointer, and then loops through the vertex buffer of the great stellated dodecahedron. It knows that the first coordinate of each trio of triangle coordinates is the point at the end of the star, so it sets that coordinate instead to the midpoint of the other two triangle coordinates, effectively collapsing the triangle: ```csharp unsafe { var ptr = (VertexBuffer.PositionNormal*)buffer.Lock(0, count, false); for (int index = 0; index < count; index += 3) { Vector3 pos1 = ptr[index + 1].Position; Vector3 pos2 = ptr[index + 2].Position; Vector3 midpoint = (pos1 + pos2) / 2; ptr[index].Position = midpoint; } buffer.Unlock(); } ``` Now we’re back viewing the great dodecahedron and the camera can be moved forward again: ```csharp app.CameraNode.Position = new Vector3(0, 0, -8); ``` Similarly you can collapse the triangles that comprise the great dodecahedron. In this case, two coordinates of the additional triangle are set to the first triangle coordinate: ```csharp VertexBuffer buffer = greatDodecahedron.Model.GetGeometry(0, 0).GetVertexBuffer(0); uint count = buffer.VertexCount; unsafe { var ptr = (VertexBuffer.PositionNormal*)buffer.Lock(0, count, false); for (int index = 0; index < count; index += 3) { Vector3 pos0 = ptr[index].Position; ptr[index + 1].Position = pos0; ptr[index + 2].Position = pos0; } buffer.Unlock(); } ``` We’re back to the small stellated dodecahedron, the triangles of which can also be collapsed by setting the center coordinate of each triangle to the midpoint of the other two: ```csharp VertexBuffer buffer = ssd.Model.GetGeometry(0, 0).GetVertexBuffer(0); uint count = buffer.VertexCount; unsafe { var ptr = (VertexBuffer.PositionNormal*)buffer.Lock(0, count, false); for (int index = 0; index < count; index += 3) { Vector3 pos0 = ptr[index + 0].Position; Vector3 pos2 = ptr[index + 2].Position; Vector3 midpoint = (pos0 + pos2) / 2; ptr[index + 1].Position = midpoint; } buffer.Unlock(); } ``` Now all that’s left is the original dodecahedron, and the camera can be moved back in: ```csharp app.CameraNode.Position = new Vector3(0, 0, -5); ``` ## Animating the Vertex Buffer Now let’s do all that in reverse to build the stellations back up again, but this time the process can be animated. The following function looks similar to the last code that you saw, but the function has a parameter named `t` that can range from 0 to 1. If `t` is 0, then the center coordinate of each triangle is set to the midpoint of the other two coordinates, just as in the previous code. But if `t` is 1, that cordinate is set to the value stored in `ssdMesh`, the triangle mesh for the small stellated dodecahedron. For values in between 0 and 1, it’s an interpolation: ```csharp void FormSmallStellatedDodecahedron(float t) { VertexBuffer buffer = ssd.Model.GetGeometry(0, 0).GetVertexBuffer(0); uint count = buffer.VertexCount; unsafe { var ptr = (VertexBuffer.PositionNormal*)buffer.Lock(0, count, false); for (int index = 0; index < count; index += 3) { Vector3 pos0 = ptr[index + 0].Position; Vector3 pos2 = ptr[index + 2].Position; Vector3 midpoint = (pos0 + pos2) / 2; ptr[index + 1].Position = (1 - t) * midpoint + t * ssdMesh[index + 1]; } buffer.Unlock(); } } ``` You can test various values between 0 and 1 in the following function call: ```csharp FormSmallStellatedDodecahedron(0); ``` Set it back to 0 when you’re finished experimenting. The following function is asynchronous and returns a `Task` object. It begins by creating a `TaskCompletionSource` object which returns that `Task` object the the caller at the end of the function body. Then it adds a handler to the `Update` event of `Application`. This handler is frequently called. The `TimeStep` property of the event arguments provides the time in seconds since the last call. The function uses this to update the value of `t`, which it then uses to call `FormSmallStellatedDodecahedron` and to move the camera back: ```csharp Task AnimateSmallStellatedDodecahedronAsync() { TaskCompletionSource taskCompletionSource = new TaskCompletionSource(); float t = 0; bool finished = false; app.Update += (UpdateEventArgs args) => { if (!finished) { t += args.TimeStep / 5; if (t < 1) { FormSmallStellatedDodecahedron(t); app.CameraNode.Position = new Vector3(0, 0, -5 - 3 * t); } else { FormSmallStellatedDodecahedron(1); app.CameraNode.Position = new Vector3(0, 0, -8); taskCompletionSource.SetResult(null); finished = true; } } }; return taskCompletionSource.Task; } ``` When the animation is complete, the function sets `finished` to `true` so the function has no more work to do. You can run this asynchronous function like so: ```csharp await AnimateSmallStellatedDodecahedronAsync(); ``` Over the course of 5 seconds, each face of the dodecahedron will seem to grow triangle appendages that eventually meet to form the small stellated dodecahedron. You can use the mouse to rotate this object as it’s growing. Similarly, the following function progressively constructs the great dodecahedron: ```csharp void FormGreatDodecahedron(float t) { VertexBuffer buffer = greatDodecahedron.Model.GetGeometry(0, 0).GetVertexBuffer(0); uint count = buffer.VertexCount; unsafe { var ptr = (VertexBuffer.PositionNormal*)buffer.Lock(0, count, false); for (int index = 0; index < count; index += 3) { Vector3 pos0 = ptr[index].Position; ptr[index + 1].Position = (1 - t) * pos0 + t * greatDodecahedronMesh[index + 1]; ptr[index + 2].Position = (1 - t) * pos0 + t * greatDodecahedronMesh[index + 2]; } buffer.Unlock(); } } ``` And the following asynchronous method repeatedly calls that function ```csharp Task AnimateGreatDodecahedronAsync() { TaskCompletionSource taskCompletionSource = new TaskCompletionSource(); float t = 0; bool finished = false; app.Update += (UpdateEventArgs args) => { if (!finished) { t += args.TimeStep / 5; if (t < 1) { FormGreatDodecahedron(t); } else { FormGreatDodecahedron(1); taskCompletionSource.SetResult(null); finished = true; } } }; return taskCompletionSource.Task; } ``` Now as you execute that function, areas between the star points fill up with another triangle: ```csharp await AnimateGreatDodecahedronAsync(); ``` Finally, the following function forms the great stellated dodecahedron: ```csharp void FormGreatStellatedDodecahedron(float t) { VertexBuffer buffer = gsd.Model.GetGeometry(0, 0).GetVertexBuffer(0); uint count = buffer.VertexCount; unsafe { var ptr = (VertexBuffer.PositionNormal*)buffer.Lock(0, count, false); for (int index = 0; index < count; index += 3) { Vector3 pos1 = ptr[index + 1].Position; Vector3 pos2 = ptr[index + 2].Position; Vector3 midpoint = (pos1 + pos2) / 2; ptr[index].Position = (1 - t) * midpoint + t * gsdMesh[index]; } buffer.Unlock(); } } ``` Here’s the function that animates it and pulls the camera back to get a good view: ```csharp Task AnimateGreatStellatedDodecahedronAsync() { TaskCompletionSource taskCompletionSource = new TaskCompletionSource(); float t = 0; bool finished = false; app.Update += (UpdateEventArgs args) => { if (!finished) { t += args.TimeStep / 5; if (t < 1) { FormGreatStellatedDodecahedron(t); app.CameraNode.Position = new Vector3(0, 0, -8 - 12 * t); } else { FormGreatStellatedDodecahedron(1); app.CameraNode.Position = new Vector3(0, 0, -20 * t); taskCompletionSource.SetResult(null); finished = true; } } }; return taskCompletionSource.Task; } ``` And you can execute it like so: ```csharp await AnimateGreatStellatedDodecahedronAsync(); ``` ================================================ FILE: graphics/urhosharp/circle-of-life/CircleOfLife.workbook/Data/Materials/phong1.xml ================================================ ================================================ FILE: graphics/urhosharp/circle-of-life/CircleOfLife.workbook/index.workbook ================================================ --- packages: - id: UrhoSharp version: 1.5.22 uti: com.xamarin.workbook id: 799c372c-6de9-4481-8bf5-a4c36a13262d title: Circle of Life platforms: - Console --- # Circle of Life: # UrhoSharp Actions and Animations UrhoSharp is a cross-platform 3D graphics framework suitable for gaming or 3D visualization. This workbook focuses on animation, in particular the classes in the `Urho.Actions` namespace that you can use with the `RunActions` and `RunActionsAsync` methods of `Node`. Towards the end of this workbook you’ll see an animated 3D monkey grow from a newborn to an adult while navigating the uncertainties of life, and then give birth to a new baby monkey before expiring, continuing the circle of life for as long as you care to watch it. A UrhoSharp workbook begins as a console app. Starting with Workbooks 1.3.1, you no longer need to copy the library files manually. You can invoke the menu item **File > Add Package** (under Windows) or **File > Add NuGet Package** (on the Mac) to search for and add the UrhoSharp NuGet library. That’s already been done for this workbook. Add a reference to that library: ```csharp #r "Urho" ``` Three UrhoSharp namespaces will be required for this workbook: ```csharp using Urho; using Urho.Actions; using Urho.Shapes; ``` The following call creates a window for the UrhoSharp graphics: ```csharp SimpleApplication app = SimpleApplication.Show(new ApplicationOptions("Data")); ``` The **Data** directory contains the resources used by the workbook, in this case the model, material, and texture (bitmap) used to render the 3D monkey. After the window has been created, you can move and resize it. The size of the 3D visuals are relative to the *height* of the window. The `SimpleApplication.Show` method creates a camera and light source. The camera is located at the point (0, 0, 0) and points in the direction of the vector **(0, 0, 1)**, which is the positive Z axis that conceptually goes into the screeen. All visuals will have positive Z coordinates. Also created is a root node at the position (0, –2, 8) accessible by the `RootNode` property of the `SimpleApplication` property. All UrhoSharp visuals are organized into a tree of nodes. Often it’s useful to have a node that encompasses all the visuals to be created in a workbook. This new node is called `mainNode` and is a child of `RootNode`: ```csharp app.RootNode.RemoveChild(app.RootNode.GetChild("mainNode")); Node mainNode = app.RootNode.CreateChild("mainNode"); ``` As usual, any code block in a workbook that creates a node must first remove the node that might have been created in an earlier execution of the code block. All the action in this workbook will take place on a flat desert. The sky is created by coloring the entire window blue: ```csharp app.Viewport.SetClearColor(new Color(0.53f, 0.81f, 0.92f)); ``` The surface of the desert is a `Plane` shape from the UrhoSharp `Shapes` namespace. ```csharp mainNode.RemoveChild(mainNode.GetChild("desertNode", false)); Node desertNode = mainNode.CreateChild("desertNode"); Shape desertShape = desertNode.CreateComponent(); desertShape.SetMaterial(Material.FromColor(Color.FromByteFormat(0xC1, 0x9A, 0x6B, 0xFF))); ``` The color here corresponds to the “Desert” color in the Wikipedia article on [Desert Sand (Color)](https://en.wikipedia.org/wiki/Desert_sand_\(color\) "Desert Sand \(color\)"). The previous code block creates only a small patch of desert sand 1 unit wide by 1 unit deep on the XZ axis. You can then scale that node along the X and Z axes to encompass a wider span and simulate a horizon: ```csharp desertNode.Scale = new Vector3(1000, 1, 1000); ``` ## The Monkey Model The 3D monkey was created by Vic Wang at [http://vidavic.weebly.com](http://vidavic.weebly.com "Vidavic"). It is described in a binary file named **monkey.mdl** in the **Data** subdirectory of this workbook. The **Materials** subdirectory of **Data** contains a material file **phong1.xml**, which references the **UV.jpg** file in the **Textures** subdirectory. The following code loads and displays the model. The surface of the monkey is covered with the material and JPEG file: ```csharp mainNode.RemoveChild(mainNode.GetChild("monkeyNode")); Node monkeyNode = mainNode.CreateChild("monkeyNode"); StaticModel monkey = monkeyNode.CreateComponent(); monkey.Model = app.ResourceCache.GetModel("monkey.mdl"); monkey.SetMaterial(app.ResourceCache.GetMaterial("Materials/phong1.xml")); ``` The monkey sits a little above the XZ plane. It is roughly centered on the origin of the coordinate system: The positive Y axis goes through the middle of the body and out the center of the top of the head. The monkey is about 6 units tall and 6 units wide (from paw to paw). The monkey is a little too close but you can move `mainNode` down and back relative to its parent, `RootNode`: ```csharp mainNode.Position = new Vector3(0, -2.5f, 6); ``` ## Experimenting with Actions The `Node` class defines two methods that allow you to run animations on the node: `void RunActions(params FiniteTimeAction[])`\ \ `Task RunActions(params FiniteTimeAction[])` Each animation is a derivative of the `FiniteTimeAction` class. The `params` keyword allows you to specify multiple `FiniteTimeAction` objects as the argument to these methods . The multiple animations run consecutively. (There’s also a way to run animations in parallel that you’ll see later in this workbook.) In addition, `Node` defines `PauseAllActions` and `ResumeAllActions` methods, as well as `RemoveAction` and `RemoveAllActions`. The `Urho.Actions` namespace includes over 50 classes that derive from `FiniteTimeAction`. These classes are immutable: You specify everything that the class needs in the class’s constructor. The most basic classes that derive from `FiniteTimeAction` perform standard types of graphical transforms: * Translation: `MoveTo` and `MoveBy` * Scaling: `ScaleTo` and `ScaleBy` * Rotation: `RotateTo` and `RotateBy` The difference between the `To` and `By` suffixes is easy to demonstrate. `MoveTo` moves a node from the node’s current position, which for the monkey node is initially (0, 0, 0), to the point specified in the `MoveTo` constructor. The first argument to the constructor is the duration of the animation in seconds, in this case 2 seconds: ```csharp await monkeyNode.RunActionsAsync(new MoveTo(2, new Vector3(2, 0, 0))); ``` When running animations in a workbook, you should use use `RunActionsAsync` with `await` rather than `RunActions`. This prevents the code block from concluding until the animation has completed, and also prevents you from this animation or another one while it’s still executing. (The only exception is for animations that run forever. You’ll see an example towards the end of this workbook.) If you execute that previous code block again, it will still require two seconds to complete, but the monkey won’t move. It’s already at the point (2, 0, 0). To move the monkey *by* a certain distance relative to its current position, use `MoveBy`: ```csharp await monkeyNode.RunActionsAsync(new MoveBy(1, new Vector3(-2, 0, 0))); ``` Now the monkey moves two units to the left every time that code block is executed. The `params` keyword on the argument to `RunActionsAsync` indicates that you can specify multiple objects that derive from `FiniteTimeAction`. The multiple animations run in sequence: ```csharp await monkeyNode.RunActionsAsync(new Place(new Vector3(0, 0, 0)), new MoveTo(1, new Vector3(0, 0, 100)), new DelayTime(1), new JumpTo(3, new Vector3(0, 0, 0), 5, 7)); ``` The `Place` class derives from `ActionInstant`, which derives from `FiniteTimeAction`, and moves the node immediately. (It’s the same as a `MoveTo` with a duration of 0.) The `DelayTime` class does nothing for a particular duration (here 1 second). The `JumpTo` class also moves the node, but with a series of 7 jumps 5 units high. If the node is already at the position specified in the `JumpTo` constructor, then the node hops up and down in place. Here are 4 jumps 10 units high over a duration of 3 seconds: ```csharp await monkeyNode.RunActionsAsync(new JumpTo(3, new Vector3(0, 0, 0), 10, 4)); ``` ## Scaling and Repetition Scaling changes the size of a visual object by a multiplicative factor. Keep in mind that a default scaling factor is 1 rather than 0. The `ScaleBy` class in the following code block increases the size of the monkey by 25%. As usual, the first argument is the duration in seconds: ```csharp await monkeyNode.RunActionsAsync(new ScaleBy(1, 1.25f)); ``` The `By` suffix indicates that the size increases by 25% every time the code block is executed. (Try it!) You can return the monkey to its normal size using a `ScaleTo` constructor with a duration of 0 and a scaling factor of 1: ```csharp await monkeyNode.RunActionsAsync(new ScaleTo(0, 1)); ``` It‘s also possible to apply different scaling factors in the X, Y, and Z directions. The following operation increases the width and depth of the monkey (but not the height) by a factor of 3 over 2 seconds. The arguments are named to clarify them: ```csharp await monkeyNode.RunActionsAsync(new ScaleTo(duration: 2, scaleX: 3, scaleY: 1, scaleZ: 3)); ``` You can make the monkey large and then small again by combining `ScaleTo` objects: ```csharp await monkeyNode.RunActionsAsync(new ScaleTo(0, 1), new ScaleTo(2, 3), new ScaleTo(2, 1)); ``` The first `ScaleTo` sets the scaling factor as 1, the second animates it to 3 over 2 seconds, and the third animates it back to 1. What if you wanted to repeat that operation three times? There’s a class for that! The `Repeat` class derives from `FiniteTimeAction`. Its constructor has an argument of type `FiniteTimeAction` as well as a repetition factor: `public Repeat(FiniteTimeAction action, UInt32 times)` The animation object passed to the constructor is repeated *times* times. Unfortunately the first argument is only a single `FiniteTimeAction` object. However, there’s another class that also derives from `FiniteTimeAction` with a constructor that lets you combine multiple `FiniteTimeAction` objects: `public Sequence(params FiniteTimeAction[] actions)` You can combine the `Repeat` and `Sequence` constructors: ```csharp await monkeyNode.RunActionsAsync(new Repeat(new Sequence(new ScaleTo(1, 3), new ScaleTo(1, 1)), times: 3)); ``` > ⚠️ The documentation for `Sequence` indicates that the constructor parameter includes the `params` keyword, but as of UrhoSharp 1.5.22, that is not the case. For three or more arguments, you’ll need to create an array for them. ## Easing Functions So far, all the animations have been linear. Whether the node is moving or changing size, at the animation’s halfway point, the visual object is midway between the starting and ending values. The word *ease* is often used in computer graphics to describe non-linear animations. In the implementation of animations, generally a value of `t` (for *time*) increases linearly from 0 at the beginning of the animation to 1 at the end. An easing function alters this value of `t`. The function maps 0 to 0 and 1 to 1, but returns other values in between based on a mathematical formula. The source code for the easing functions is available in the **[Ease](https://github.com/xamarin/urho/tree/master/Bindings/Portable/Actions/Ease "Ease directory")**[ directory](https://github.com/xamarin/urho/tree/master/Bindings/Portable/Actions/Ease "Ease directory") of the Xamarin **urho** repository. Much of the math can be found in **[EaseMath.cs](https://github.com/xamarin/urho/blob/master/Bindings/Portable/Math/EaseMath.cs "EaseMath.cs")**. The easing classes have a consistent naming convention: * `EaseTypeIn`, which applies the easing to the beginning of the animation * `EaseTypeOut`, which applies the easing to the end of the animation * `EaseTypeInOut`, which applies the easing to the beginning and end The `Type` part of the name is one of the following: * nothing, which uses the `Math.Pow` function * `Back`, which overshoots the initial and/or final value * `Bounce`, which bounces at the beginning and/or end * `Elastic`, which applies a combination of powers and trigonometry to simulate damped harmonic motion * `Exponential`, which applies an exponential function * `Sine`, which applies a trigonometric function You can also create custom easing functions using the `EaseCustom` class. To use an easing function, pass the animation object to the construction of the easing class. This animation scales the monkey up and down using `EaseBackOut` for the first action, and `EaseBounceOut` for the second: ```csharp await monkeyNode.RunActionsAsync(new EaseBackOut(new ScaleTo(1, 3)), new EaseBounceOut(new ScaleTo(1, 1))); ``` Feel free to experiment! ## Rotation and Parallel Actions The `RotateTo`, `RotateBy`, and `RotateAroundBy` actions rotate the node. > ⚠️ The `RotateTo` class does not work correctly as of UrhoSharp 1.5.22. The rotations are based on Euler angles. In the 18th century, Swiss mathematician Leonhard Euler proved that any rotation in 3D space can be described as a combination of simple rotations around the X, Y, and Z axes. Euler angles are common in flight dynamics. One problem, however, is that the order of the simple rotations makes a difference in the final composite rotation, and the order is not standard. The convention in UrhoSharp is Z first, then X, and finally Y. These three rotations are also referred to as *roll*, *pitch*, and *yaw*, respectively. A rotation based on Euler angles can be defined using the three-parameter constructor of `Quaternion`. It might be advantageous to get accustomed to setting a rotation using Euler angles prior to animating a rotation. Here’s a rotation of 90 degrees around the Z axis: ```csharp monkeyNode.Rotation = new Quaternion(0, 0, 90); ``` UrhoSharp uses a left-hand coordinate system, which means that if you point the thumb of your left hand in the direction of the positive rotation axis (into the screen for rotation around the Z axis), then the direction of rotation for positive angles is given by the curl of your fingers. After the rotation around the Z axis, the monkey becomes half buried in the desert sand. Add to that a rotation of 90 degrees around the X axis: ```csharp monkeyNode.Rotation = new Quaternion(90, 0, 90); ``` Finally, add another rotation around the Y axis: ```csharp monkeyNode.Rotation = new Quaternion(90, 90, 90); ``` Feel free to experiment, but return the monkey to normal before continuing: ```csharp monkeyNode.Rotation = Quaternion.Identity; ``` Rotation animations are easiest when restricting yourself to just one simple axis. For example, the following operation rotates the monkey 360 degrees 3 times around the Y axis: ```csharp await monkeyNode.RunActionsAsync(new Repeat(new RotateBy(duration: 2, deltaAngleX: 0, deltaAngleY: 360, deltaAngleZ: 0), times: 3)); ``` This one goes twice around the X axis: ```csharp await monkeyNode.RunActionsAsync(new Repeat(new RotateBy(duration: 2, deltaAngleX: 360, deltaAngleY: 0, deltaAngleZ: 0), times: 2)); ``` The following sequence of animations swing the monkey between the left and the right: ```csharp await monkeyNode.RunActionsAsync( new Repeat( new Sequence( new FiniteTimeAction[] { new RotateBy(0.5f, 0, 90, 0), new RotateBy(1f, 0, -180, 0), new RotateBy(0.5f, 0, 90, 0) }), times: 4)); ``` Notice the use of an array of `FiniteTimeAction` objects. In UrhoSharp 1.5.22, the `Sequence` constructor can’t handle more than two arguments. The first `RotateBy` rotates the monkey 90 degrees to the left in 0.5 seconds, the second rotates 180 degrees to the right in 1 second, and the third rotates back to the center position in 0.5 seconds. This is repeated 4 times. This animation needs an easing function. It should slow down at the left and right before reversing direction. The `EaseSine` classes are ideal for simulating simple harmonic motion: ```csharp await monkeyNode.RunActionsAsync( new Repeat( new Sequence( new FiniteTimeAction[] { new EaseSineOut(new RotateBy(0.5f, 0, 90, 0)), new EaseSineInOut(new RotateBy(1f, 0, -180, 0)), new EaseSineIn(new RotateBy(0.5f, 0, 90, 0)) }), times: 4)); ``` To run two or more animations simultaneously, use the `Parallel` class: `public Parallel(params FiniteTimeAction[] actions)` The following code scales the monkey up and down while rotating it around the Y axis: ```csharp await monkeyNode.RunActionsAsync(new Parallel(new Sequence(new ScaleTo(2, 3), new ScaleTo(2, 1)), new RotateBy(4, 0, 360, 0))); ``` ## A Ride Around an Infinity Sign The next goal is to give the monkey a ride around an infinity sign. As discussed in the SkiaSharp article [Three Types of Bézier Curves](https://developer.xamarin.com/guides/xamarin-forms/advanced/skiasharp/curves/beziers/ "Three Types of Bezier Curves"), an infinity sign can be constructed using eight Bézier curves, and the UrhoSharp `BezierTo` class can animate a node along those curves.\ \ The following array defines an infinity sign using the UrhoSharp `BezierConfig` structure. The curve is constructed on the XZ plane with a Y coordinate of zero. The implicit start position is (0, 0, 0). The `Vector3`constructors imply a radius of 1 unit of the circular part of the infinity sign, but the scaling factor increases that size: ```csharp float infinityScale = 15; BezierConfig[] bezierInfinity = { new BezierConfig { ControlPoint1 = infinityScale * new Vector3(0.55f, 0, 0), ControlPoint2 = infinityScale * new Vector3(1, 0, 0.45f), EndPosition = infinityScale * new Vector3(1, 0, 1) }, new BezierConfig { ControlPoint1 = infinityScale * new Vector3(1, 0, 1.55f), ControlPoint2 = infinityScale * new Vector3(0.5f, 0, 2), EndPosition = infinityScale * new Vector3(0, 0, 2.5f) }, new BezierConfig { ControlPoint1 = infinityScale * new Vector3(-0.5f, 0, 3), ControlPoint2 = infinityScale * new Vector3(-1, 0, 3.45f), EndPosition = infinityScale * new Vector3(-1, 0, 4) }, new BezierConfig { ControlPoint1 = infinityScale * new Vector3(-1, 0, 4.55f), ControlPoint2 = infinityScale * new Vector3(-0.55f, 0, 5), EndPosition = infinityScale * new Vector3(0, 0, 5) }, new BezierConfig { ControlPoint1 = infinityScale * new Vector3(0.55f, 0, 5), ControlPoint2 = infinityScale * new Vector3(1, 0, 4.55f), EndPosition = infinityScale * new Vector3(1, 0, 4) }, new BezierConfig { ControlPoint1 = infinityScale * new Vector3(1, 0, 3.45f), ControlPoint2 = infinityScale * new Vector3(0.5f, 0, 3), EndPosition = infinityScale * new Vector3(0, 0, 2.5f) }, new BezierConfig { ControlPoint1 = infinityScale * new Vector3(-0.5f, 0, 2), ControlPoint2 = infinityScale * new Vector3(-1, 0, 1.55f), EndPosition = infinityScale * new Vector3(-1, 0, 1) }, new BezierConfig { ControlPoint1 = infinityScale * new Vector3(-1, 0, 0.45f), ControlPoint2 = infinityScale * new Vector3(-0.55f, 0, 0), EndPosition = infinityScale * new Vector3(0, 0, 0) } }; ``` To animate the monkey along these eight Bézier curves, an array of `BezierTo` objects must be created. The first argument to the constructor is the animation duration for that part of the curve: ```csharp BezierTo[] bezierTos = new BezierTo[8]; for (int i = 0; i < 8; i++) { bezierTos[i] = new BezierTo(1, bezierInfinity[i]); } ``` The position of the monkey can then be animated based on the array of `BezierTo` objects: ```csharp await monkeyNode.RunActionsAsync(bezierTos); ``` The result is disappointing. The monkey is moving along the infinity sign but always facing forward. It would be more “realistic” if the monkey faced in the direction that it’s moving. The monkey must be dynamically rotated as well as translated. There is no class in the `Urho.Actions` namespace that does this. Fortunately, you can implement custom animations using the `ActionTween` class. (The word “tween” is short for “in-betweening,” which refers to the interpolation performed between the start and end values in an animation.) ## Breaking down the Béziers The eight Bézier curves must first be approximated with polylines. Here’s a function that will do that for one Bézier: ```csharp void BezierToPolyline(Vector3 pt0, Vector3 pt1, Vector3 pt2, Vector3 pt3, int numPoints, IList points) { for (int i = 0; i < numPoints; i++) { float t = (float)i / numPoints; Vector3 pt = (1 - t) * (1 - t) * (1 - t) * pt0 + 3 * (1 - t) * (1 - t) * t * pt1 + 3 * (1 - t) * t * t * pt2 + t * t * t * pt3; points.Add(pt); } } ``` Now all eight Bézier curves can be converted to one big polyline stored in a `List` object: ```csharp List bezierPoints = new List(); for (int i = 0; i < bezierInfinity.Length; i++) { int iPrevious = (i - 1 + bezierInfinity.Length) % bezierInfinity.Length; BezierToPolyline(bezierInfinity[iPrevious].EndPosition, bezierInfinity[i].ControlPoint1, bezierInfinity[i].ControlPoint2, bezierInfinity[i].EndPosition, 100, bezierPoints); } ``` The `ActionTween` class derives from `FiniteTimeAction` and has the following constructor: `public ActionTween(Single duration, String key, Single from, Single to, Action tweenAction)` The first parameter is the duration in seconds. You can use the second argument to identify this animation. The `from` and `to` arguments can be anything you want, but often it’s easiest to set them to 0 and 1. Set the last argument to a callback function. That function is called repeatedly with values between `from` and `to`. Here’s a callback function for `ActionTween`. The `t` parameter ranges from 0 to 1 for each complete cycle. This is used to calculate an `index` value based on the number of points in the `bezierPoints` collection. The two integer indices `i1` and `i2` can then be used for interpolation. The `Position` property of `monkeyNode` is set to this interpolated value: ```csharp void UpdateMonkey(float t, string key) { float index = t * bezierPoints.Count % bezierPoints.Count; int i1 = (int)index; int i2 = (i1 + 1) % bezierPoints.Count; monkeyNode.Position = (i2 - index) * bezierPoints[i1] + (index - i1) * bezierPoints[i2]; Vector3 tangent = bezierPoints[i2] - bezierPoints[i1]; float angle = (float)(180 * Math.Atan2(-tangent.X, -tangent.Z) / Math.PI); monkeyNode.Rotation = Quaternion.FromAxisAngle(Vector3.UnitY, angle); } ``` The two points are also used to determine a tangent to the curve. The angle of this vector is obtained from the `Math.Atan2` function, and then used to set the `Rotation` property of the node. The `ActionTween` constructor references this `UpdateMonkey` callback, and the object is passed to the `RunActionsAsync` method: ```csharp await monkeyNode.RunActionsAsync(new ActionTween(8, "bezier", 0, 1, UpdateMonkey)); ``` Now the monkey travels along the Bézier curves while facing in the direction that it’s moving. ## Life and Death The following code block defines the most extensive `Sequence` object in this workbook. It begins by positioning the monkey at the origin and decreasing it to one-tenth of its normal size. This is the newborn baby monkey. Over the next 40 seconds, the monkey travels around the Bézier curve 4 times, while simultaneously increasing in size as the years pass and it grows up: ```csharp const float cycleTime = 10; const uint numCycles = 4; Sequence monkeySequence = new Sequence( new FiniteTimeAction[] { new Place(new Vector3(0, 0, 0)), new ScaleTo(0, 0.1f), new Parallel( new Repeat(new ActionTween(cycleTime, "bezier", 0, 1, UpdateMonkey), numCycles), new ScaleTo(cycleTime * numCycles, 1)), new DelayTime(0.5f), new ScaleTo(0.25f, 1.25f), new ScaleTo(0.25f, 1), new DelayTime(0.5f), new RotateBy(4.5f, 180, 0, 0) } ) ``` After those 4 trips around the Bézier curve, the monkey stops, swells in size briefly, and then descends into the earth. This final part of the animation lasts a total of 6 seconds. To see what it looks like, run that sequence: ```csharp await monkeyNode.RunActionsAsync(monkeySequence); ``` In its bleak portrayal of death and disintegration, the animation might seem to be somewhat dreary. To add a little hope for the future, a second monkey is created: ```csharp mainNode.RemoveChild(mainNode.GetChild("monkey2Node")); Node monkey2Node = mainNode.CreateChild("monkey2Node"); StaticModel monkey2 = monkey2Node.CreateComponent(); monkey2.Model = app.ResourceCache.GetModel("monkey.mdl"); monkey2.SetMaterial(app.ResourceCache.GetMaterial("Materials/phong1.xml")); ``` This new monkey is set to one-tenth its original size and rotated 90 degrees: ```csharp monkey2Node.SetScale(0.1f); monkey2Node.Rotation = Quaternion.FromAxisAngle(Vector3.UnitY, -90); ``` The animation sequence for the second monkey defined below begins by hiding the monkey for 40 seconds. The monkey is then made visible and jumps into the air: ```csharp Sequence monkey2Sequence = new Sequence( new FiniteTimeAction[] { new Hide(), new DelayTime(cycleTime * numCycles), new Show(), new JumpTo(6, new Vector3(), 10, 1), new Hide(), } ) ``` You can run that sequence by itself, but it’s more comprehensible when the two sequences are run together. The `RepeatForever` class runs the sequences forever. For this reason, `RunActions` rather than `RunActionsAsync` is called because `RunActionsAsync` would never return: ```csharp monkeyNode.RemoveAllActions(); monkey2Node.RemoveAllActions(); monkeyNode.RunActions(new RepeatForever(monkeySequence)); monkey2Node.RunActions(new RepeatForever(monkey2Sequence)); ``` If the code block is re-executed, then the calls to `RemoveAllActions` stop any animations that might be in progress before restarting the animations at the beginning. ================================================ FILE: graphics/urhosharp/compound-shapes/CreatingUrhoCompoundShapes.workbook/index.workbook ================================================ --- id: 4792faac-5c28-4cef-98bb-89f4af10fee9 uti: com.xamarin.workbook title: "UrhoSharp: Compound Shapes" platforms: - Console packages: - id: UrhoSharp version: 1.5.22 --- # Creating (and Animating) Urho Compound Shapes This workbook shows how you can build a quadcopter from UrhoSharp `Shape` objects and fly it around the screen. UrhoSharp is a powerful cross-platform 3D graphics engine available to Xamarin and .NET developers for games or visualization. If you’re unfamiliar with Urho concepts, you’ll want to download and run the **Exploring Urho Coordinates** workbook first. Wait until the workbook has completely finished loading before executing the following code cell: ```csharp #r "Urho" ``` This workbook requires four of the dozen or so namespaces for UrhoSharp types: ```csharp using Urho; using Urho.Actions; using Urho.Gui; using Urho.Shapes; ``` As usual when exploring UrhoSharp in a workbook, call the static `SimpleApplication.Show` method with an `ApplicationOptions` object to create a window for the Urho graphics: ```csharp SimpleApplication app = SimpleApplication.Show( new ApplicationOptions() { Width = 1000, Height = 1000 }); ``` You should see a window appear on the desktop as the `Show` method completes. ## Camera and Set To prepare for creating visual objects, move the camera back along the Z axis, and raise it up a little and to the left. Call `SetDirection` so the origin of the 3D coordinate system remains in the center of the window: ```csharp app.CameraNode.Position = new Vector3(-1, 1.5f, -6); app.CameraNode.SetDirection(-app.CameraNode.Position); ``` The camera will remain fixed for this workbook, and until the quadcopter begins flying around the screen, the quadcopter itself will be positioned at the origin of the 3D coordinate system. Create a `Node` object at that coordinate origin for all the visual objects that comprise the quadcopter: ```csharp app.Scene.RemoveChild(app.Scene.GetChild("mainNode", false)); Node mainNode = app.Scene.CreateChild("mainNode"); ``` As usual, the first statement in the code cell removes the `Node` named “mainNode” if the code cell is being re-executed. This prevents multiple identical nodes from being added to the tree. ## Starting the Quadcopter (some assembly required) This workbook uses a tree of `Node` objects for all the parts of the quadcopter. As you’ll see, this tree structure allows various sections of the quadcopter to be transformed, cloned, and animated. For purposes of simplicity, any `Node` in this workbook that has children does not itself include a component. Here is the `Node` that will encompass the entire quadcopter: ```csharp mainNode.RemoveChild(mainNode.GetChild("copterNode", false)); Node copterNode = mainNode.CreateChild("copterNode"); ``` The `copterNode` is a child of `mainNode`, and is also positioned at the origin of the 3D coordinate system. All the other parts of the quadcopter are subnodes of `copterNode`. The first child of `copterNode` is the body of the quadcopter: ```csharp copterNode.RemoveChild(copterNode.GetChild("bodyNode", false)); Node bodyNode = copterNode.CreateChild("bodyNode"); Shape bodyShape = bodyNode.CreateComponent(); bodyShape.Color = Color.Red; ``` In a real quadcopter, this body would contain most of the quadcopter electronics, so it probably wouldn’t be a torus, but a torus looks cool, so that’s what it is. The final statement of that code block sets the `Color` property of the shape to a `Color` value. ## Natural Lighting The lighting source that `SimpleApplication` creates is a spot light, which might be suitable for indoors, but you really should be flying your quadcopter outside. The spot light is a child of the camera node, and it is the only child of the camera node, so you can remove it like this: ```csharp app.CameraNode.RemoveAllChildren(); ``` The torus is still illuminated by ambiant light, which is set in a component called the `Zone`, an object responsible for other global characteristics of the scene. The ambient light can be reduced somewhat by accessing the `Zone` property of the `SimpleApplication` object: ```csharp app.Zone.AmbientColor = new Color(0.35f, 0.35f, 0.35f); ``` The color of this ambient light is a 35% gray. You don’t want to make it white (100% gray) because that would cause everything to be maximally illuminated. Now a new mode and component can be created for directional light. Make this node a child of the `Scene`: ```csharp app.Scene.RemoveChild(app.Scene.GetChild("directionalLight")); Node lightNode = app.Scene.CreateChild("directionalLight"); Light light = lightNode.CreateComponent(); light.LightType = LightType.Directional; ``` Set the direction of the light so it seems to come from above the user’s left shoulder, a convention for computer graphics. This direction is a property of the `Node`: ```csharp lightNode.SetDirection(new Vector3(2, -3, 1)); ``` You probably don’t want the sum of the ambient light and the directional light to exceed 1 because it would tend to wash out the definition of the visual objects, so reduce the directional light to 65% gray. This is a property of the `Light` component: ```csharp light.Color = new Color(0.65f, 0.65f, 0.65f); ``` Now the only areas of the torus that are maximally illuminated are those that are perpendicular to the direction of the directional light. ## One Quadcopter Arm The quadcopter has four arms that extend from the body, each of which has two blades that turn on a little axle. These four arm assemblies are identical, which suggests that it might be possible to build one arm and then clone it by using the `Clone` method of `Node`. (In a conventional UrhoSharp program, you probably wouldn’t use cloning but instead create the multiple similar parts in `for` loops.) This is easiest if you begin with a parent node for the assembly that you want to clone. This parent node has no component so it is invisible: ```csharp copterNode.RemoveChild(copterNode.GetChild("armAssemblyNode1", false)); Node armAssemblyNode1 = copterNode.CreateChild("armAssemblyNode1"); ``` All the pieces of the arm assembly are children of that node. The first piece is the arm itself, which is a cylinder. Perhaps it is made from blue plastic: ```csharp armAssemblyNode1.RemoveChild(armAssemblyNode1.GetChild("armNode", false)); Node armNode = armAssemblyNode1.CreateChild("armNode"); Shape armShape = armNode.CreateComponent(); armShape.Color = Color.Blue; ``` The `armAssemblyNode1` node has no transforms applied, and the `armNode` has no transforms applied, so the cylinder sits at the coordinate origin, half above and half below the XZ plane. It’s necessary to apply a few transforms to give it a proper shape and oriention. This `Scale` setting makes it longer and much thinner: ```csharp armNode.Scale = new Vector3(0.1f, 1.5f, 0.1f); ``` Now it can be rotated around the Z axis to be parallel with the X axis: ```csharp armNode.Rotation = Quaternion.FromAxisAngle(Vector3.UnitZ, 90); ``` The rotation is around the center of the cylinder, which is the same as the origin of the coordinate system. This `Position` setting shifts the arm towards the right: ```csharp armNode.Position = new Vector3(0.75f, 0, 0); ``` The left end of the cylinder is now at the coordinate origin, and it seems to go through the torus. The next piece of the arm assembly is a tiny axle. Again, begin with a cylinder. Color it black: ```csharp armAssemblyNode1.RemoveChild(armAssemblyNode1.GetChild("axleNode", false)); Node axleNode = armAssemblyNode1.CreateChild("axleNode"); Shape axleShape = axleNode.CreateComponent(); axleShape.Color = Color.Black; ``` Now make it very thin and tiny and shift it to the right so it seems to stick through the arm: ```csharp axleNode.Scale = new Vector3(0.05f, 0.3f, 0.05f); axleNode.Position = new Vector3(1.4f, 0.05f, 0); ``` ## One Blade + One Clone = Two Blades The next step is to construct the blades. Since there is more than one blade on each arm assembly, this suggests that it might be convenient to make one blade and then clone it. For that purpose, first create a node with no component to serve as a parent to the blade nodes: ```csharp armAssemblyNode1.RemoveChild(armAssemblyNode1.GetChild("bladeAssemblyNode", false)); Node bladeAssemblyNode = armAssemblyNode1.CreateChild("bladeAssemblyNode"); ``` You can’t see it because there’s no visual component associated with it. Nevertheless, now move this node so the center of the node coincides with the top of the axle: ```csharp bladeAssemblyNode.Position = new Vector3(1.4f, 0.2f, 0); ``` Every child node of the `bladeAssemblyNode` will be positioned relative to this node. Each blade is constructed from a sphere. Here’s the first one, colored silver: ```csharp bladeAssemblyNode.RemoveChild(bladeAssemblyNode.GetChild("bladeNode1", false)); Node bladeNode1 = bladeAssemblyNode.CreateChild("bladeNode1"); Shape bladeShape1 = bladeNode1.CreateComponent(); bladeShape1.Color = new Color(0.75f, 0.75f, 0.75f); ``` Although it might be hard to tell, the center of the sphere coincides with the top of the axle. Now flatten the sphere so it’s only 0.05 units in height but 0.1 units wide: ```csharp bladeNode1.Scale = new Vector3(1, 0.05f, 0.1f); ``` Such a shape for a rotor blade would not work in real life, but visually it gives a pretty good illusion. Now the blade can be cloned. Two of the three statements in the following code are specifically for the purpose of preventing superfluous nodes when workbook cells are re-executed. The crucial statement is the second one, which clones `bladeNode1` to create `bladeNode2`. The parent of `bladeNode2` becomes the same as the parent of `bladeNode1`, which is the `bladeAssemblyNode`. The argument to `Clone` indicates that the new node is only local and won’t be replicated over a network in network-based Urho games: ```csharp bladeAssemblyNode.RemoveChild(bladeAssemblyNode.GetChild("bladeNode2", false)); Node bladeNode2 = bladeNode1.Clone(CreateMode.Local); bladeNode2.Name = "bladeNode2"; ``` You can’t see the cloned node yet because it’s occupying the same space as the node that it’s been cloned from, but all that’s necessary is to rotate the new node around its center by 90 degrees: ```csharp bladeNode2.Rotation = Quaternion.FromAxisAngle(Vector3.UnitY, 90); ``` If you’d like to add another blade or two, now is the time! The following list of `mainNode` and all its subnodes created in the workbook so far shows their hierarchical relationship: mainNode\   copterNode\     bodyNode\     armAssemblyNode1\       armNode\       axleNode\       bladeAssemblyNode\         bladeNode1\         bladeNode2 ## Laying down Grass It appears that the unfinished quadcopter is just floating in space. It’s more likely sitting on the lawn in your backyard. You can mimic a surface of grass with a `Shape` derivative called the `Plane`, which is simply a thin flat surface: ```csharp mainNode.RemoveChild(mainNode.GetChild("grassNode", false)); Node grassNode = mainNode.CreateChild("grassNode"); Shape grassShape = grassNode.CreateComponent(); grassShape.SetMaterial(Material.FromColor(Color.Green)); ``` Notice the somewhat different way of setting the color. In 3D programming, visual objects are often said to have an appearance based on a *material*. You can set a material on a `Shape` object by calling the `SetMaterial` method. If you just need a uniformly colored material, create one by calling the static `Material.FromColor` method. In a somewhat more sophisticated program, you might have a bitmap that resembles grass, and you would call `SetMaterial` with a `Material` object that you obtain from the static `Material.FromImage` method. But for now, it’s simply green. (Be aware, however, that when you clone a node, the component is cloned but not the material on the component. This is why the cloned nodes in this workbook use colors rather than materials.) The default `Plane` is flat and 1 unit by 1 unit square. Look closely and you’ll see that it is bisecting the torus, which is 0.25 units in height. The first step is to move the `Plane` down by half that height: ```csharp grassNode.Position = new Vector3(0, -0.125f, 0); ``` The plane node must also be made very large so it stretches to the horizon: ```csharp grassNode.Scale = new Vector3(2000, 1, 2000); ``` The horizon seems a little crooked because of the way the camera is positioned and directed towards the origin. You can set the sky to a sky-blue color by accessing the `Viewport` object that `SimpleApplication` creates: ```csharp app.Viewport.SetClearColor(new Color(0.53f, 0.81f, 0.92f)); ``` Now for some shadows. These are properties of the directional light. The first setting is obvious; the others were copied from some other UrhoSharp sample code: ```csharp light.CastShadows = true; light.ShadowBias = new BiasParameters(0.00025f, 0.5f); light.ShadowCascade = new CascadeParameters(10.0f, 50.0f, 200.0f, 0.0f, 0.8f); ``` ## Animating the Blades Quadcopter blades must rotate. That’s how the quadcopter can fly. The `Node` class defines a `RunActions` method that accepts any number of `FiniteTimeAction` objects. These are animations that apply to the node. `Node` also defines a `RemoveAllActions` method. In a workbook, you’ll want to call `RemoveAllActions` before `RunActions` to avoid multiple identical `FiniteTimeAction` objects that apply to the node. The classes that derive from `FiniteTimeAction` are in the `Urho.Actions` namespace. Among others classes, you’ll find `RotateBy` and `RotateTo`. These are similar except that `RotateBy` changes a rotation angle *by* a specific number of degrees, while `RotateTo` changes the rotation angle *to* the specified value. `RotateBy` adds to the current rotation angle while `RotateTo` does not. The `RotateBy` and `RotateTo` constructors have four arguments that indicate the duration of the animation in seconds, and the total rotation around the X, Y, and Z axes. In the following code cell, the arguments are identified by name to avoid confusion. Also notice that the animation applies to the `bladeAssemblyNode`, which is the parent node to the two blade nodes: ```csharp bladeAssemblyNode.RemoveAllActions(); bladeAssemblyNode.RunActions(new RotateBy(duration: 1, deltaAngleX: 0, deltaAngleY: 360, deltaAngleZ: 0)); ``` It definitely works. The pair of blades spin around in one second. But it stops after it goes around once. You could try increasing the `deltaAngleX` argument (and also the `duration` argument) but the real solution is to define an animation that runs forever. That turns out to be very easy: Just pass the `RotateBy` object to the constructor of `RepeatForever`, a class that also derives from `FiniteTimeAction`. Here’s the object defined by itself: ```csharp FiniteTimeAction bladeAction = new RepeatForever( new RotateBy(duration: 1, deltaAngleX: 0, deltaAngleY: 360, deltaAngleZ: 0 ) ); ``` Now this `bladeAction` object can be applied to the `bladeAssemblyNode`: ```csharp bladeAssemblyNode.RemoveAllActions(); bladeAssemblyNode.RunActions(bladeAction); ``` You could make it go faster, of course, just by lowering the `duration` value in the `RotateBy` constructor. It is not necessary to specify any center of rotation. By default, the blade assembly rotates around its center. ## Cloning the Arm Assembly You’ve already seen cloning with the blades. Here’s the code to clone the entire arm assembly. As was the case earlier, the first and third statements are necessary only in workbooks to avoid duplicate nodes: ```csharp copterNode.RemoveChild(copterNode.GetChild("armAssemblyNode2", false)); Node armAssemblyNode2 = armAssemblyNode1.Clone(CreateMode.Local); armAssemblyNode2.Name = "armAssemblyNode2"; ``` The two arm assemblies are now in the same location. The animations are not cloned along with the nodes and components, so you can see one pair of animated blades and another pair of stationary blades.\ \ The following code rotates the cloned arm assembly around its origin to move it on the other side of the body: ```csharp armAssemblyNode2.Rotation = Quaternion.FromAxisAngle(Vector3.UnitY, 180); ``` Keep in mind that `armAssemblyNode1` had no transforms applied. The only transforms were applied to the children of `armAssemblyNode1`. When the clone of `armAssemblyNode2` is rotated, it rotates around its origin, which is the same as the 3D coordinate origin. It’s now necessary to apply the animation to the blade assembly in this cloned arm assembly. But where is that cloned blade assembly? Because the whole arm assembly node was cloned, it a child of the cloned object. Names are cloned along with everything else, so you need to get the child named “bladeAssemblyNode” from the cloned `armAssemblyNode2`: ```csharp bladeAssemblyNode = armAssemblyNode2.GetChild("bladeAssemblyNode", true); ``` The second argument of `GetChild` is set to `true` in this case to search through the entire tree of subnodes. The animation can now be applied: ```csharp bladeAssemblyNode.RemoveAllActions(); bladeAssemblyNode.RunActions(bladeAction); ``` Now you can make another clone and rotate it 90 degrees so it’s on the side of the viewer: ```csharp copterNode.RemoveChild(copterNode.GetChild("armAssemblyNode3", false)); Node armAssemblyNode3 = armAssemblyNode1.Clone(CreateMode.Local); armAssemblyNode3.Name = "armAssemblyNode3"; armAssemblyNode3.Rotation = Quaternion.FromAxisAngle(Vector3.UnitY, 90); ``` The animation can now be applied as before. But wait: In quadcopters, the blades in the arms opposite each other spin in the same direction, but the blades on the other two arms spin in the opposite direction. Is it necessary to define another `FiniteTimeAction` object for the opposite rotation? Not at all: `FiniteTimeAction` defines a `Reverse` method that returns an object of type `FiniteTimeAction` that is the same animation but in reverse: ```csharp bladeAssemblyNode = armAssemblyNode3.GetChild("bladeAssemblyNode", true); bladeAssemblyNode.RemoveAllActions(); bladeAssemblyNode.RunActions(bladeAction.Reverse()); ``` Finally, another clone creates the fourth arm: ```csharp copterNode.RemoveChild(copterNode.GetChild("armAssemblyNode4", false)); Node armAssemblyNode4 = armAssemblyNode1.Clone(CreateMode.Local); armAssemblyNode4.Name = "armAssemblyNode4"; armAssemblyNode4.Rotation = Quaternion.FromAxisAngle(Vector3.UnitY, 270); ``` And the following code applies the animation in the same direction as its opposite: ```csharp bladeAssemblyNode = armAssemblyNode4.GetChild("bladeAssemblyNode", true); bladeAssemblyNode.RemoveAllActions(); bladeAssemblyNode.RunActions(bladeAction.Reverse()); ``` The quadcopter is complete, but can it be made to fly? ## A Preprogrammed Flight Plan One of the many animations in the `Orho.Actions` namespace is `BezierTo`, which can animate the `Position` property of a `Node` based on a Bezier curve. The `BezierTo` constructor requires a time in seconds and a `BezierConfig` value that defines a Bezier curve based on two control points (the `ControlPoint1` and `ControlPoint2` properties) and an end point (the `EndPosition` property). Normally a Bezier curve is defined by a start point as well. With `BezierTo`, the start point is the current position, which in this example is the current position of the quadcopter, or (0, 0, 0). `BezierTo` actions are customarily strung together into a composite animation, so at the end of the `BezierTo` action, the current position is the `EndPosition` property of the `BezierConfig` value, and that becomes the starting point for the next `BezierTo`. Here are four `BezierTo` animations whose coordinates were derived from experimentation. (You are free to experiment further!) Notice that these Bezier curves are in three dimensions, so all the points are `Vector3` values: ```csharp BezierTo bezier1 = new BezierTo(3, new BezierConfig { ControlPoint1 = new Vector3(1, 2, -4), ControlPoint2 = new Vector3(-1, 6, -2), EndPosition = new Vector3(0, 4, 0) }); BezierTo bezier2 = new BezierTo(2, new BezierConfig { ControlPoint1 = new Vector3(2, 4, 5), ControlPoint2 = new Vector3(15, 10, 10), EndPosition = new Vector3(10, 8, 15) }); BezierTo bezier3 = new BezierTo(3, new BezierConfig { ControlPoint1 = new Vector3(5, 6, 20), ControlPoint2 = new Vector3(-5, 8, 20), EndPosition = new Vector3(-5, 6, 14) }); BezierTo bezier4 = new BezierTo(4, new BezierConfig { ControlPoint1 = new Vector3(-5, 4, 7), ControlPoint2 = new Vector3(-2, 0, 0), EndPosition = new Vector3(-0.5f, 2, -8), }); ``` Before running these animations, expand the camera field of view so you can see more: ```csharp app.Camera.Fov = 90; ``` The following code sets the `Position` of the quadcopter node to the origin (in case the code-cell is re-executed) and then runs the `BezierTo` animations in sequence using `RunActionsAsync`: ```csharp copterNode.RemoveAllActions(); copterNode.Position = new Vector3(0, 0, 0); await copterNode.RunActionsAsync(bezier1, bezier2, bezier3, bezier4); ``` Both `RunActions` and `RunActionsAsync` return soon after the animation has begun. However, you can use `await` with `RunActionsAsync` to avoid continuing code execution until the animation has completed. Otherwise, the following code cell (which restores the `Position` to the origin) might be executed in the middle of the animation, and not at the end of the animation where it actually does some good: ```csharp copterNode.Position = new Vector3(0, 0, 0); ``` Now you can run the animation again. ## Manual Controls Obviously you want to fly the quadcopter yourself. There are several ways to let a user interact with a Urho application: mouse, touch, joystick, and even a simulated joystick. However, perhaps the easiest involves the keyboard. Over the years, the following keys have become common in controlling objects in two dimensions on the screen: W = Up\ S = Down\ A = Left\ D = Right These keys are in an inverted T position on the keyboard. If you’ve looked at the source code for `SimpleApplication`, you might have noticed some code that makes use of the WASD keys, but that’s for moving the camera and are enabled with the `MoveCamera` property. The `MoveCamera` property is set to `true` by default, so the first step is to disable it: ```csharp app.MoveCamera = false; ``` If the W, S, A, and D keys will move the quadcopter up, down, left, and right, what about the third dimension? Perhaps you can use the F and R keys for movement along the Z axis: F = Forward\ R = Reverse Will you remember what these keys do? Some text displayed on the screen can help out. The `Urho.Gui` namespace has a collection of user-interface elements, including `Text`. These user-interface elements can be organized in a tree of `UIElement` objects, starting at the `Root` property of the `UI` object available from the `UI` property of `Application`. Like `Node` objects, `UIElement` objects have names. In workbooks you can remove them from the tree to avoid duplicate elements when code cells re-execute. That’s what the first statement below does. The `HorizontalAlignment` and `VerticalAlignment` properties center the `Text` element horizontally and put it at the bottom of the screen: ```csharp app.UI.Root.RemoveChild(app.UI.Root.GetChild("helpText", false), 0); Text helpText = new Text() { Name = "helpText", Value = "W=Up S=Down, A=Left, D=Right, F=Forward, R=Reverse", HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Bottom }; app.UI.Root.AddChild(helpText); ``` But where is it? The `Text` element happens not to have a default font, and one must be assigned explicitly. Fortunately, a font is available from the embedded `Fonts` class in the `CoreAssets` class in the `Urho` namespace. You also set a height for the font in this call: ```csharp helpText.SetFont(CoreAssets.Fonts.AnonymousPro, 24); ``` By default, the text is white. In this particular case, you’ll probably want to make it black: ```csharp helpText.SetColor(Color.Black); ``` It will be interesting also to have a real-time display of the quadcopter’s position, so here’s another `Text` element that sits in the upper-right corner of the screen: ```csharp app.UI.Root.RemoveChild(app.UI.Root.GetChild("positionText", false), 0); Text positionText = new Text() { Name = "positionText", HorizontalAlignment = HorizontalAlignment.Right, VerticalAlignment = VerticalAlignment.Top }; positionText.SetColor(Color.Black); positionText.SetFont(CoreAssets.Fonts.AnonymousPro, 24); app.UI.Root.AddChild(positionText); ``` There is no `Value` property set for that `Text` element, so no text is displayed yet. Graphics systems often have a facility sometimes referred to as a *game loop*. This is a block of code that executes quickly, repeatedly, and continuously. The game loop is where the program can alter the visuals in real time, often based on user input. In a conventional Urho application, you derive a class from `Application`. The game loop is an override of the `OnUpdate` method. In a workbook, you can instead attach a handler to the `Update` event. Regardless which approach you use, the function is called with a time-step value, which is the time in seconds since the last call. Depending on the environment and whatever other animations might be going on, expect the function to be called anywhere from 20 times a second to 200 times a second. Here is a handler for the `Update` event that uses the `Input` subsystem of the `Application` class to check if any of six keys is currently pressed. If so, the `Translate` method is called, which changes the `Position` property by the specified vector. A series of `if` statements are used rather than an `if-else` construction to allow multiple keys to be pressed simultaneously. ```csharp void ProcessKey(UpdateEventArgs args) { float distancePerSecond = 1.0f; float distance = distancePerSecond * args.TimeStep; if (app.Input.GetKeyDown(Key.W)) { copterNode.Translate(Vector3.UnitY * distance); } if (app.Input.GetKeyDown(Key.S)) { copterNode.Translate(-Vector3.UnitY * distance); } if (app.Input.GetKeyDown(Key.A)) { copterNode.Translate(-Vector3.UnitX * distance); } if (app.Input.GetKeyDown(Key.D)) { copterNode.Translate(Vector3.UnitX * distance); } if (app.Input.GetKeyDown(Key.F)) { copterNode.Translate(Vector3.UnitZ * distance); } if (app.Input.GetKeyDown(Key.R)) { copterNode.Translate(-Vector3.UnitZ * distance); } // Clamp to positive Y values Vector3 position = copterNode.Position; position.Y = Math.Max(0, position.Y); copterNode.Position = position; positionText.Value = String.Format("({0:F2}, {1:F2}, {2:F2})", position.X, position.Y, position.Z); } ``` Notice towards the end of the event handler three lines of code that ensures that the Y value of the `Position` property of `copterNode` remains positive. You don’t want the quadcopter to go underground! The final statement updates the `Text` element with the current position. Below is the final code cell in this workbook. It attaches the `ProcessKey` handler to the `Update` event so you can use the keyboard to fly the quadcopter. But what you definitely don’t want is more than one `ProcessKey` handler attached to that event: When multiple identical game-loop code blocks are executed, the animations go uncontrollably faster. For that reason, any code in a workbook that attaches an `Update` handler should detach the previous one first. Normally you would use an `app.Update -= ProcessKey` statement. However, in a workbook, that doesn’t work well: Every time the code cell containing the `ProcessKey` function is re-executed, a new instance of the function is created, and hence it’s difficult detaching the previous handler from the `Update` event using conventional means. For that reason, this code block begins with some .NET reflection code that removes all handlers from the `Update` event. But be aware this code is not generalized for all types of events. ```csharp // Detach ALL Update handlers using System.Reflection; FieldInfo field = typeof(Application).GetField("Update", BindingFlags.Instance | BindingFlags.NonPublic); field.SetValue(app, null); app.Update += ProcessKey; ``` Now you’re ready to fly the quadcopter. But be sure to click on the Urho window to give it input focus before you press the keys! ================================================ FILE: graphics/urhosharp/coordinates/ExploringUrhoCoordinates.workbook/index.workbook ================================================ --- id: cb4208bd-7759-4878-9e28-72c87a06da15 uti: com.xamarin.workbook title: "UrhoSharp: Exploring Coordinates" platforms: - Console packages: - id: UrhoSharp version: 1.5.22 --- # Exploring Urho Coordinates UrhoSharp is a powerful cross-platform 3D graphics engine that Xamarin and .NET developers can use for games or visualization. This workbook is intended as a basic introduction to UrhoSharp and 3D concepts, focusing on the 3D coordinate system. ```csharp #r "Urho" ``` This workbook requires only two of the dozen or so namespaces for UrhoSharp types: ```csharp using Urho; using Urho.Shapes; ``` If you’re writing a standalone UrhoSharp program using Visual Studio, generally you derive a class from `Application`, and override several methods for all your code, animations, and interaction. The program then instantiates that derived class and calls the `Run` method on it. The `Run` method is blocking: It doesn’t return until the UrhoSharp application has been terminated. That architecture would not work very well in an interactive workbook, so a class named `SimpleApplication` is available instead. `SimpleApplication` derives from `Application` and defines a static `Show` method that instantiates the `SimpleApplication` object, performs some initialization, and returns the object, which you can then use for constructing a 3D scene. This `SimpleApplication` class is described in the UrhoSharp API documentation [here](https://developer.xamarin.com/api/type/Urho.SimpleApplication/) but you might also want to look at the [source code](https://github.com/xamarin/urho/blob/master/Bindings/Portable/SimpleApplication.cs) for the class, and particularly the [`Start` method](https://github.com/xamarin/urho/blob/master/Bindings/Portable/SimpleApplication.cs#L145), which performs initialization. To create a UrhoSharp window in a workbook, call the static `SimpleApplication.Show` method, passing to it an argument of `ApplicationOptions`. The easiest options consist of simply a width and height of a window: ```csharp ApplicationOptions appOptions = new ApplicationOptions { Width = 1000, Height = 1000 }; SimpleApplication app = SimpleApplication.Show(appOptions); ``` You should see a window appear on the desktop as the `Show` method completes. ## Inside SimpleApplication The `SimpleApplication` class creates two objects that are essential in a 3D scene: a camera and a light source. The camera defines how you see 3D objects in the window. The Urho window is similar to the screen of a digital camera or the camera on your phone. As you know, what you see on a camera screen depends on: * where the camera is positioned in 3D space, * the direction that the camera lens is pointed, * the orientation of the camera (portrait or landscape or something in between), and * the degree of zoom that you’ve selected All these characteristics (and more) are part of the Urho3D camera. The use of a camera metaphor is perhaps the biggest difference between 3D graphics and 2D graphics. When working with 2D graphics, generally you specify coordinates of graphics objects relative to a screen or canvas. The coordinate values might be pixels or units that convert to pixels. With 3D graphics, what you see on the screen depends on the relative locations of the camera and the 3D objects. Coordinate values are all relative. You can increase or decrease all the coordinates and sizes in a 3D scene by a factor of 10 (for example) and everything will look the same. When you use a camera in real life, you know that you can’t take a picture of something behind the camera or otherwise out of its range. Similarly, in working with 3D scenes, you might not see anything in the UrhoSharp window if the 3D objects are not in the range of the camera. Helping you get a feel for this relationship is one of the goals of this workbook. The other essential object that `SimpleApplication` creates is a light source. This serves to illuminate 3D objects and provide an illusion of three-dimensional space and curvature. ## A Tree of Nodes Urho organizes 3D objects in a tree of nodes. Every node except the top-level node has a parent, and every node potentially has multiple children. This organization allows you to group related 3D objects and treat them together. For example, you can move a whole group of objects by moving the parent node. Here’s the documentation of the [`Node` class](https://developer.xamarin.com/api/type/Urho.Node/). `SimpleApplication` creates a top-level node, which is a special node of type `Scene`, and which is accessible through the `Scene` property of `SimpleApplication`. Both the camera and light are subnodes of the `Scene` node. (You’ll see shortly how you can access the camera and light source from a workbook.) The `Start` method in `SimpleApplication` also creates a node called `RootNode`. That particular node is not used in this workbook, and it’s not used for anything within the `SimpleApplication` class. Instead, this workbook creates creates something quite similar — a child node of `Scene` that will be used throughout this workbook as a parent to other nodes. To create a new child node of an existing node (for example, the node referenced by the `Scene` property of the `SimpleApplication` object), call `CreateNode` on the node you want to create a child of. When you experiment with code in a workbook, however, the code cells can be executed multiple times. Generally you’ll want to avoid creating nodes that duplicate existing nodes. For that reason, any code in a workbook that creates a new node should be prefaced with code that removes the node that might have been created in a previous execution of the code cell. That’s why this `CreateChild` call is preferenced with calls to `GetChild` and `RemoveChild`: ```csharp // Remove node named "mainNode" so there are no duplicates app.Scene.RemoveChild(app.Scene.GetChild("mainNode", false)); // Create node named "mainNode" as child of Scene Node mainNode = app.Scene.CreateChild("mainNode"); ``` The node is given a name in the `CreateChild` call that is referenced in the `GetChild` call. But that first statement might seem risky to you when this code block is executed the first time: If a node with the name “mainNode” does not exist, `GetChild` returns `null`. Fortunately, if the argument to `RemoveChild` is `null`, it simply does nothing. The second argument to `GetChild` inhibits searching for the node recursively through levels of node. Similarly, the following code creates a child node of `mainNode` named `boxNode` after first removing a subnode with that name: ```csharp // Remove node named "boxNode" so there are no duplicates mainNode.RemoveChild(mainNode.GetChild("boxNode", false)); // Create a node for a Box component Node boxNode = mainNode.CreateChild("boxNode"); Box box = boxNode.CreateComponent(); ``` The last two statements demonstrate the simplest way to create a 3D object in the scene: first by creating a child node, and then to associate that child node with a component. (The camera and light created in the `Start` method of `SimpleApplication` are components as well.) Notice the generic argument to the `CreateComponent` call. The `Box` component is one of seven classes for basic shapes that derive from the abstract `Shape` class and which can be found in the [`Urho.Shapes` namespace](https://developer.xamarin.com/api/namespace/Urho.Shapes/). The `CreateComponent` method returns an object of type `Box`. But where is it? ## 3D Space That `Box` object that you’ve just created is not yet visible. Understanding why requires some background in 3D coordinate systems. A 3D graphics system like Urho allows objects to be positioned in a three-dimensional coordinate space. Two of the dimensions are just like a classic two-dimensional Cartesian coordinate system: ![Two-dimensional coordinate system](Figure1.png) By default the origin is in the center of the Urho window. A 3D coordinate system has a third axis labeled Z that is at right angles to both the X and Y axis. In Urho, the positive Z axis goes into the screen (conceptually speaking), and the negative Z axis comes out of the screen. Here’s the whole coordinate system viewed from an angle: ![Three-dimensional coordinate system](Figure2.png) Urho’s coordinate system is known as a *left-hand* system. If you point the forefinger of your left hand in the direction of positive X coordinates (to the right) and your third finger in the direction of position Y coordinates (up), your thumb points in the direction of positive Z coordinates (into the screen). The only alternative is a right-hand system. It’s sometimes convenient to speak of the coordinate system as defining *planes*. the X and Y axes define the XY plane, while the X and Z axes define the XZ plane, and the Y and Z axes define the YZ plane. A 3D coordinate point is notated as (x, y, z). The origin of the coordinate system is the point (0, 0, 0). There’s a good reason why you can’t see the box you created in the Urho window: By default, the camera is positioned at the origin of the 3D coordinate system, and so is the box. The camera is inside the box! The camera and box must be moved apart before the camera can see the box. The camera has a direction as well as a position. Directions are indicated by 3D vectors, which are notated just like points but usually displayed in boldface: **(x, y, z)**. In UrhoSharp, both points and vectors are values of type `Vector3`. By default, the camera is positioned at the origin and pointing into the screen in the direction of the positive Z axis. Or rather, it should be. To override some settings in `SimpleApplication` used to create the libraries used with this workbook, set the camera to what should be the default settings: ```csharp app.CameraNode.Position = new Vector3(0, 0, 0); app.CameraNode.SetDirection(new Vector3(0, 0, 1)); ``` Although the `Position` property is readable and writeable, the `Direction` property is read-only so `SetDirection` must be used to set it. The following code moves the box so that it has a Z coordinate of 7 and sits in front of the camera. Notice that `Position` is a property of the `Node` object and not the `Box` object: ```csharp boxNode.Position = new Vector3(0, 0, 7); ``` And there it is. It doesn’t look much like a box, however. It looks like a square. The problem now is that the camera is pointed straight at the box, so only one side of the box is visible. You can shift the box to the right by increasing the X coordinate of the `Position` property, and to the left by decreasing the X coordinate. You can move the box up by increasing the Y coordinate, and down by decreasing the Y coordinate. Here’s one possibility: ```csharp boxNode.Position = new Vector3(2, -1.5f, 7); ``` Notice the parameters to the `Vector3` structure are defined as `float` so an `f` suffix is required for floating point values. And now it looks a little more like a box. The camera is still pointing straight down the Z axis, but the box has been moved to the right and down, and you can see the top and left side. You can probably also tell that the rear of the box is a little smaller than the front. By default, the camera employs a perspective projection which results in objects further from the camera being smaller than those closer to the camera. Urho also supports an orthographic camera, which does not employ projection and makes 3D objects look more like those in an engineering drawing. ## Adjusting the Light The illusion of three dimensions is also influenced by different shading on the three visible sides of the box. However, it appears that the left and front of the box are the same shade, which does not help the 3D effect. UrhoSharp supports three basic types of light: * *Directional*: Light streaming in a particular direction from a seemingly infinite distance, much like the sun. * *Point*: Light streaming in all directions from a particular point, much like a lightbulb hanging from a wire. * *Spot*: Light coming from a particular point, but only streaming in a particular direction, much like a flashlight. These are the three members of the `LightType` enumeration. Directional light has a direction; point light has a position; and spot light has both a position and direction. In addition, these different types of light sources can be customized by different properties of the `Light` class. `SimpleApplication` creates a point light source with a particular position that you can query like so: ```csharp Vector3 lightPosition = app.LightNode.Position; ``` Because the light node is a subnode of the camera node (as you can verify by examining the `Start` method in `SimpleApplication`), the position of the light is relative to the position of the camera. You can see a difference if you shift the light to the center of the coordinate system and raise it a bit: ```csharp app.LightNode.Position = new Vector3(0, 15, 0); ``` Now you’ll see all three sides of the box illuminated with different degrees of light. There is also some ambient light defined in the scene. ## The Camera Field of View By changing the `Position` property of the `boxNode` object, you can move the box nearer to the camera or further away, and you can move it anywhere around the window. If the box is very close to the camera, you don’t have much leeway in the X and Y coordinates. Try this: ```csharp boxNode.Position = new Vector3(-1, 0.75f, 3); ``` The box is large because it’s close to the camera, but it’s partially out of the window. Now try this: ```csharp boxNode.Position = new Vector3(10, 15, 50); ``` The box seems very far away but it’s safely within the window. You can experiment with other values (and you definitely should) to get a feel for this, but you might also have a need to quantify this relationship. One of the crucial properties of the [`Camera` class](https://developer.xamarin.com/api/type/Urho.Camera/) is named `Fov`, which stands for *field of view*. It’s an angle in degrees, but in practice it’s roughly equivalent to a zoom factor. By default the value is 45 degrees. You can access the `Camera` object that is created by `SimpleApplication` through the `Camera` property. Try changing the `Fov` property to 90: ```csharp app.Camera.Fov = 90; ``` The box seems to move away. We’ve zoomed out. Try changing it to a value less than 45 degrees to zoom in. When you’re finished experimenting, change it back to the default value of 45 because the rest of this discussion is based on that value: ```csharp app.Camera.Fov = 45; ``` The camera is located at the origin of the 3D coordinate system and pointing in the direction of the positive Z axis. Viewed from the side (from the vantage point of the positive X axis), the camera’s field of view looks like this: ![Camera Point of View](Figure3.png) The camera is shown as a little box on the origin, and the field of view is shown as two slanted blue lines. Almost everything between those two blue lines is within the range of the camera and visible within the window. (But not quite: The range of a perspective camera is actually described by a square frustum. which is a four-sided pyramid with the top shaved off. The `Camera` class defines two properties named `NearClip` and `FarClip` that define a range of distance that is visible to the camera. By default these properties have values of 0.1 and 1000. In most normal cases, you don’t have to worry about these values, but they’re necessary for the internal camera math to work.) The diagram above shows the default `Fov` property value of 45 degrees. If you increase the field of view, a larger range becomes visible to the camera. It’s similar to zooming out. You can zoom into a scene by decreasing the field of view. Graphics objects in the window are rendered so that the height of the window corresponds to the field of view. The width of the window might be the same as the height, less than the height, or greater than the height, which might correspond to the same field of view, or a a lower field of view, or a greater field of view. The ratio of the window’s width to its height is available as the `AspectRatio` property of the camera. To quantify the relationship between the distance of an object from the camera and its visual size within the window, draw a line that bisects the Z axis, and label it H for *height*. The distance from that line to the camera is labeled D for *distance*: ![Camera Distance and Width](Figure4.png) Now you’ve defined two similar triangles, and it becomes a problem in trigonometry: tan(FOV / 2) = (H / 2) / D or: H = 2D tan (FOV / 2) For example, suppose a 3D object is 5 units from the camera. How tall would the object need to be to occupy the full height of the window? If FOV is 45 degrees, the tanget of 22.5 degrees is 0.414, and H equals 4.14 units. The dimension of the `Box` object is a unit square: 1 unit by 1 unit by 1 unit. The value of the `Position` property corresponds to the center of the `Box`. To position the front of the `Box` five units from the camera, the Z coordinate of the `Position` property must be set to 5.5. To position the box precisely in the upper-right corner of the window, the X and Y coordinates of the `Position` property must be set to 0.5 units less than half the width and half the height of the window. The following code cell performs this calculation. Notice the Urho `MathHelper.DegreesToRadians` call for converting the angle in degrees to radians for the `Math.Tan` function: ```csharp float D = 5.0f; float FOV = app.Camera.Fov; float y = 2 * D * (float)Math.Tan(MathHelper.DegreesToRadians(FOV / 2)) / 2; float x = app.Camera.AspectRatio * y; boxNode.Position = new Vector3(x - 0.5f, y - 0.5f, D + 0.5f); ``` Regardless of the window size (set in the `ApplicationOptions` argument to the `SimpleApplication.Show` method) and the camera field of view, the box should be positioned in the upper-right corner of the window. ## Exploring Shapes The following code creates another `Node` with a component for a donut-like shape known as a *torus*. The code is similar to the creation of `boxNode`: ```csharp // Remove node named "shapeNode" so there are no duplicates mainNode.RemoveChild(mainNode.GetChild("shapeNode", false)); // Create a node for a Torus component Node shapeNode = mainNode.CreateChild("shapeNode"); Shape shape = shapeNode.CreateComponent(); ``` Now that’s interesting! The camera is sitting in the middle of the torus (where the hole of the donut is) and part of the torus is visible from that perspective. To see the whole torus, you can change its position (as with the box) but another solution is to change the position of the camera. This statement moves the camera back along the negative Z axis, as well as moving it to the left and up: ```csharp app.CameraNode.Position = new Vector3(-1, 1.5f, -6); ``` After running that code, you might have expected the torus to remain in the center of the screen. But keep in mind that the camera is still pointed in the positive Z direction. To position the torus in the center of the screen, the camera must be pointed at the torus, which is at the origin of the coordinate system. Pointing the camera at the origin is actually easier than it might seem. The vector that points from one position to another position is the difference between the coordinates. You can calculate the vector that points from the camera to the origin by subtracting the camera position from the origin. This is equivalent to the negative of the camera position: ```csharp app.CameraNode.SetDirection(-app.CameraNode.Position); ``` That code will always point the camera to the 3D origin. And now the torus is in the center of the screen. You can also move and zoom the camera using the keyboard. Make sure the Urho3D window has the input focus, and press W and S to zoom the camera in and out, and A and D to move the camera left and right. These four keys form an inverted T on the keyboard. As you move the camera left or right, notice that 3D objects seem to move opposititely. You can also move the camera up, down, left, and right with the mouse. Move the mouse pointer inside the window, press the mouse button, and drag. This moves the camera, and 3D objects seem to move in the opposite direction. Try the other shapes in the code cell above that creates the `shape` object using the `CreateComponent` generic function. They are: `Cone`, `Cylinder`, `Plane`, `Pyramid`, and `Sphere`. For `Plane` you’ll need to fully qualify the class name: `Urho.Shapes.Plane`. Of course, you can change the color of this object. The color is not something common to all nodes, so it’s not a `Node` property. Instead, set the `Color` property of the `Shape` object. Several static fields are availble for common colors: ```csharp shape.Color = Color.Cyan; ``` Or, you can use a constructor of the `Color` structure: ```csharp shape.Color = new Color(0.5f, 1.0f, 0.25f, 1); ``` The arguments range from 0 to 1 and are in the order red, green, blue, and alpha, which governs transparency. Before proceeding to the next section, move whatever shape you’re now looking at away from the origin: ```csharp shapeNode.Position = new Vector3(-2, 2, 10); ``` ## Translation, Scaling, and Rotation The following code positions a cylinder on the origin: ```csharp // Remove node named "shapeNode" so there are no duplicates mainNode.RemoveChild(mainNode.GetChild("cylinderNode", false)); // Create a node for a Cylinder component Node cylinderNode = mainNode.CreateChild("cylinderNode"); Cylinder cylinder = cylinderNode.CreateComponent(); ``` The cylinder is one unit tall and has a one unit diameter. But what if you want a cylinder of a different size or proportions? Or perhaps you need to tip it over so that the ends are parallel to the YZ plane rather than the XZ plane. These are jobs for graphics *transforms*, of which there are three basic types: * Translation: change the location of an object * Scaling: change the size of an object * Rotation: change the orientation of an object Very often you’ll combine these transforms. The transforms are applied to the `Node` object, and they affect all the node’s children as well. This feature allows you to create a composite object and move, scale, or rotate it as a whole. The three properties that you set to realize these transforms are: * `Position` of type `Vector3`, which you’ve already seen * `Scale` of type `Vector3` * `Rotation` of type `Quaternion` There are also some methods that you can use for transforms. For example, the `Translate` method changes the `Position` property, but the effect is accumulative: Every time you call `Translate`, the `Position` property is changed by that amount. Similarly, the `ScaleNode` method is accumulative but the `SetScale` method is not. The `Pitch`, `Yaw`, and `Roll` methods are named after terms used in aerodynamics and perform accumulative rotations around the X, Y, and Z axes, respectively. Transforms can often be difficult to understand, and rotations in particular can be very complex. This discussion is intended as a brief introduction. The default `Scale` property is the `Vector3` value (1, 1, 1). You can control the scaling factors on all three dimensions independently. Set them to values greater than 1 to increase the size. For example, a value of 2 doubles the size in that dimension. Set them to values less than 1 to decrease the size. For example, suppose you want to make the cylinder skinnier but with double the length: ```csharp cylinderNode.Scale = new Vector3(0.5f, 2, 0.5f); ``` It’s necessary to set the X and Z scaling factors to the same values if you want to keep the cylinder round, but nothing prevents you from setting them to different values for an elliptical cylindar. Watch out: The default `Scale` property is (1, 1, 1) and not (0, 0, 0). If you set `Scale` to (0, 0, 0), the object will disappear. Three-dimensional rotation is an exceptionally complex topic, which you might have discerned from the type of the `Rotation` property being the `Quaternion` structure. A quaternion is a mathematical descripton of a 3D rotation and can be difficult to grasp intuitively, mostly because it involves three different types of imaginary numbers. The big advantage of quaternions in 3D computer graphics is that they interpolate well, which results in smooth animations. Fortunately, there are simpler ways to describe 3D rotation. Perhaps easiest to visualize is the axis-angle rotation. You specify an axis, for instance, the X axis, and a rotational angle around that axis. A simple static method converts that rotation into a `Quaternion` value. Often you’ll want to rotate something around the X, Y, or Z axis. The `Vector3` structure defines three static readonly fields named `UnitX`, `UnitY`, and `UnitZ` which are vectors that equal **(1, 0, 0)**, **(0, 1, 0)**, and **(0, 0, 1)**, respectively. Here’s how to rotate the cylinder 45 degrees around the Z axis: ```csharp cylinderNode.Rotation = Quaternion.FromAxisAngle(Vector3.UnitZ, 45); ``` You can predict the direction of rotation from another left hand rule: Point the thumb of your left hand in the direction of the axis of rotation, in this case the postive Z axis going into the screen. The other fingers of your left hand curl in the direction of positive rotation angles. You can change the direction by changing the sign of the rotation angle, or the direction of the axis. You can now set the `Position` property to shift the cylinder so the bottom end is at the origin: ```csharp cylinderNode.Position = new Vector3(-0.707f, 0.707f, 0); ``` Before continuing, move the cylinder to the background: ```csharp cylinderNode.Position = new Vector3(-0.707f, 0.707f, 12); ``` ## Displaying the Axes Very thin cylinders can be used to draw some rudimentary straight lines in 3D space. Here’s a function that accepts a `Node` argument and creates 60 subnodes to draw the axes of the 3D coordinate system. Each cylinder is scaled to a size of (0.025, 0.90, 0.25) and 10 each are stacked in the positive and negative X, Y, and Z directions: ```csharp void CreateAxes(Node axesNode) { Vector3[] unitVectors = { Vector3.UnitX, Vector3.UnitY, Vector3.UnitZ }; foreach (Vector3 unitVector in unitVectors) { for (int i = -10; i < 10; i++) { Node node = axesNode.CreateChild(); Cylinder cylinder = node.CreateComponent(); cylinder.Color = Color.Black; cylinder.CastShadows = false; node.Scale = new Vector3(0.025f, 0.90f, 0.025f); if (unitVector == Vector3.UnitX) { node.Rotation = Quaternion.FromAxisAngle(Vector3.UnitZ, 90); } else if (unitVector == Vector3.UnitZ) { node.Rotation = Quaternion.FromAxisAngle(Vector3.UnitX, 90); } node.Position = (i + 0.5f) * unitVector; } } } ``` Very little in this function should be new. The `CastShadows` property of the `Cylinder` is set to `false`; this prevents the axes from casting shadows on other objects. Also, notice how the `Position` property of each `Node` is set: The `Vector3` structure supports multiplication of a vector by a number, often called a *scalar* in this context. The number is multiplied by all three components of the vector, but in this case two of them are zero. To render these axes, create a child node and pass it to the `CreateAxes` function: ```csharp // Remove node named "axesNode" so there are no duplicates mainNode.RemoveChild(mainNode.GetChild("axesNode", false)); // Create node for axes Node axesNode = mainNode.CreateChild("axesNode"); CreateAxes(axesNode); ``` Now move the `Box` object so that the front left bottom corner is aligned with the origin: ```csharp boxNode.Position = new Vector3(0.5f, 0.5f, 0.5f); ``` There’s nothing that prevents multiple 3D objects from occupying the same space. Only unobscured surfaces are rendered, so if part of one 3D object is inside another, the hidden surfaces are simply not drawn. The box hides a quarter sliver of each of the three cylinders that it abuts. This workbook has introduced you to the Urho 3D coordinate system, but the best way to get more familiar with it is by experimentation with these shapes and by creating others. Have fun! ================================================ FILE: graphics/urhosharp/custom-geometries/CustomGeometries.workbook/CreateModel.csx ================================================ using System; using System.Collections.Generic; using Urho; Model CreateModel(IList positions, IList normals = null, IList colors = null, IList texcoords = null) { // Check that the positions argument isn't null if (positions == null) throw new ArgumentNullException("positions"); // Make sure it has a property number of elements int vertexCount = positions.Count; if (vertexCount == 0 || vertexCount % 3 != 0) throw new ArgumentOutOfRangeException("positions count must be non-zero and a multiple of 3"); // Check that the normals argument is consistent, or create it if (normals != null) { if (normals.Count != vertexCount) throw new ArgumentOutOfRangeException("texcoords must have same count as positions"); } else { normals = new Vector3[vertexCount]; for (int i = 0; i < vertexCount; i += 3) { normals[i + 0] = Vector3.Cross(positions[i + 1] - positions[i + 0], positions[i + 2] - positions[i + 0]); normals[i + 1] = Vector3.Cross(positions[i + 2] - positions[i + 1], positions[i + 0] - positions[i + 1]); normals[i + 2] = Vector3.Cross(positions[i + 0] - positions[i + 2], positions[i + 1] - positions[i + 2]); } } // Create the VertexBuffer object; set it in one of the blocks below VertexBuffer vertexBuffer = new VertexBuffer(Application.CurrentContext, false) { Shadowed = true }; // If texcoords is non-null, use a PositionNormalColorTexcoord structure if (texcoords != null) { if (texcoords.Count != vertexCount) throw new ArgumentOutOfRangeException("texcoords must have same count as positions"); if (colors != null && colors.Count != vertexCount) throw new Exception("colors must have same count as positions"); var vertices = new VertexBuffer.PositionNormalColorTexcoord[vertexCount]; for (int i = 0; i < vertexCount; i++) { vertices[i].Position = positions[i]; vertices[i].Normal = normals[i]; vertices[i].Color = colors == null ? 0 : colors[i].ToUInt(); vertices[i].TexCoord = texcoords[i]; } vertexBuffer.SetSize((uint)vertexCount, ElementMask.Position | ElementMask.Normal | ElementMask.Color | ElementMask.TexCoord1, false); vertexBuffer.SetData(vertices); } // If colors is non-null, use a PositionNormalColor structure else if (colors != null) { if (colors.Count != vertexCount) throw new Exception("colors must have same count as positions"); VertexBuffer.PositionNormalColor[] vertices = new VertexBuffer.PositionNormalColor[vertexCount]; for (int i = 0; i < vertexCount; i++) { vertices[i].Position = positions[i]; vertices[i].Normal = normals[i]; vertices[i].Color = colors[i].ToUInt(); } vertexBuffer.SetSize((uint)vertexCount, ElementMask.Position | ElementMask.Normal | ElementMask.Color, false); vertexBuffer.SetData(vertices); } // Otherwise use the PositionNormal structure else { VertexBuffer.PositionNormal[] vertices = new VertexBuffer.PositionNormal[vertexCount]; for (int i = 0; i < vertexCount; i++) { vertices[i].Position = positions[i]; vertices[i].Normal = normals[i]; } vertexBuffer.SetSize((uint)vertexCount, ElementMask.Position | ElementMask.Normal, false); vertexBuffer.SetData(vertices); } // Create the Geometry object Geometry geometry = new Geometry(); geometry.SetVertexBuffer(0, vertexBuffer); geometry.SetDrawRange(PrimitiveType.TriangleList, 0, 0, 0, (uint)vertexCount, true); // Create the Model object Model model = new Model(); model.NumGeometries = 1; model.SetGeometry(0, 0, geometry); model.BoundingBox = new BoundingBox(new Vector3(-10, -10, -10), new Vector3(10, 10, 10)); return model; } ================================================ FILE: graphics/urhosharp/custom-geometries/CustomGeometries.workbook/index.workbook ================================================ --- id: cb210751-0da5-43e6-bcfb-74a14f1861b1 uti: com.xamarin.workbook title: "UrhoSharp: Custom Geometries" platforms: - Console packages: - id: UrhoSharp version: 1.5.22 --- # Working with Urho Custom Geometries This workbook is an introduction to custom geometries in UrhoSharp. The techniques shown here allow you to define your own 3D shapes algorithmically. UrhoSharp is a powerful cross-platform 3D graphics engine available to Xamarin and .NET developers for games or visualization. If you’re unfamiliar with Urho concepts, you’ll want to download and run the **Exploring Urho Coordinates** and **Creating Urho Compound Shapes** workbooks first. Wait until the workbook has completely finished loading before executing the following code cell: ```csharp #r "Urho" ``` This workbook requires only one namespace for UrhoSharp types: ```csharp using Urho; ``` As usual when exploring Urho in a workbook, call the static `SimpleApplication.Show` method to create a window for the Urho graphics. The argument to the `ApplicationOptions` constructor is a folder from which resources can be loaded: ```csharp SimpleApplication app = SimpleApplication.Show( new ApplicationOptions("Data") { Width = 1000, Height = 1000 }); ``` You should see a window appear on the desktop as the `Show` method completes. ## Preliminaries `SimpleApplication` creates a camera, a point light source, and a root node for visuals. In preparation for this workbook, first move the camera back a little from the origin and make sure that it is pointing in the direction of the positive Z axis (that is, into the screen): ```csharp app.CameraNode.Position = new Vector3(0, 0, -5); app.CameraNode.SetDirection(new Vector3(0, 0, 1)); ``` Set the position of the root node at the origin. This is where the 3D graphics will be positioned throughout this workbook: ```csharp app.RootNode.Position = new Vector3(0, 0, 0); ``` Remove the point light (which is a subnode of the camera) and add a directional light coming from above and behind the viewer’s left shoulder. The following is identical to code in the **Creating Urho Compound Shapes** workbook: ```csharp // Remove the point light app.CameraNode.RemoveAllChildren(); // Remove previous directionalLight node before adding new one app.Scene.RemoveChild(app.Scene.GetChild("directionalLight")); Node lightNode = app.Scene.CreateChild("directionalLight"); // Create the light compononent Light light = lightNode.CreateComponent(); light.LightType = LightType.Directional; light.Color = new Color(0.65f, 0.65f, 0.65f); // Set the direction of the directional light lightNode.SetDirection(new Vector3(2, -3, 1)); // Set the ambient light app.Zone.AmbientColor = new Color(0.35f, 0.35f, 0.35f); ``` Disable the code in `SimpleApplication` that moves the camera in response to mouse and touch: ```csharp app.MoveCamera = false; ``` Instead, define an event handler that uses mouse movement to apply a rotate transform to `RootNode`. This will allow you to rotate the 3D graphics created in this workbook by sweeping the mouse along the Urho window with the left mouse button depressed: ```csharp void ProcessMouseMovement(UpdateEventArgs args) { if (app.Input.GetMouseButtonDown(MouseButton.Left)) { Vector2 mouseMove = new Vector2(app.Input.MouseMove.X, -app.Input.MouseMove.Y); float angle = mouseMove.Length; // 1 degree per pixel is simple if (angle > 0) { Vector3 axis = new Vector3(mouseMove.Y, -mouseMove.X, 0); app.RootNode.Rotate(Quaternion.FromAxisAngle(axis, angle), TransformSpace.Parent); } } } ``` The following code is described towards the bottom of the **Creating Urho Compound Shapes** workbook. It removes all previous handlers on the `Update` event and attaches the event handler shown above: ```csharp // Detach ALL Update handlers using System.Reflection; FieldInfo field = typeof(Application).GetField("Update", BindingFlags.Instance | BindingFlags.NonPublic); field.SetValue(app, null); app.Update += ProcessMouseMovement; ``` That completes the preliminaries. ## Terminology and Classes In 3D graphics, the word *model* generally refers to a description of a three-dimensional object. The model generally combines a *geometry*, which is a collection of connected 3D coordinate points, and a *material*, which describes how the geometric surfaces are colored. How the model is actually rendered depends on other factors, such as the camera, lights, and transforms. The names of the Urho classes do not exactly coincide with these definitions. Urho defines a `Geometry` class that describes a 3D surface based on *vertices*, which are 3D coordinate points connected to form surfaces. The `Model` class combines multiple `Geometry` objects. The `StaticModel` class essentially combines a `Model` object and `Material` objects, which describes how the geometries are rendered with colors or bitmaps. `StaticModel` derives from `Component`, which means that a `StaticModel` object can be associated with a node and be assigned a position and subjected to transforms. The `Shape` class derives from `StaticModel`, and from `Shape` derives `Box`, `Cylinder`, `Sphere`, and other basic shapes described in previous workbooks. Also deriving from `StaticModel` is `AnimatedModel`, which allows a program to dynamically change the vertices that make up the geometries. Generally developers create complex 3D models in interactive applications designed specifically for that purpose. However, geometries can also be created algorithmically, and that is the focus of this workbook. ## Triangles, Vertices, and the VertexBuffer A 3D geometry is most often a *triangle mesh*, which is a collection of triangles that fit together to define a surface in three-dimensional space. Triangles are used for this purpose because they are the simplest two-dimensional objects, and they are always flat in three-dimensaional space. Any other polygon (such as a pentagon) can be decomposed into triangles. A triangle has three vertices. When you use triangles to define a 3D surface, each vertex of each triangle has several characteristics associated with it. These are the most common: * The most obvious is the *position* of the vertex in 3D space. This is specified with a `Vector3` value. * Also often associated with each vertex is a *normal*, which is a vector that is parallel to the surface of the triangle at the vertex. It might seem as if this value could be calculated automatically (and it sometimes is), but it is possible to manipulate normals to give triangles the appearance of being curved. The normal is specified with a `Vector3` value. * A vertex can have a particular *color*, in which case the colors at three vertices are interpolated over the surface of the triangle. Generally you specify a color as an unsigned integer, which can be obtained directly from a `Color` value. * Sometimes a bitmap (called as *texture*) is used to cover the surface of a 3D object. In this case, the 3D system needs to know how to map the two-dimensional coordinates of the texture to each triangle. This information is provided with texture coordinates for each vertex, which are relative to the two-dimensional texture and therefore `Vector2` values rather than `Vector3` values. * A *tangent* of type `Vector4` is sometimes provided for each vertex, but this is for somewhat more advanced techniques, which won’t be demonstrated in this workbook. To help consolidate this information, the `VertexBuffer` class defines four embedded public structures: * `PositionNormal` with `Position` and `Normal` fields * `PositionNormalColor` with `Position`, `Normal`, and `Color` fields * `PositionNormalColorTexcoord` with `Position`, `Normal`, `Color`, and `TexCoord` fields * `PositionNormalColorTexcoordTangent` with `Position`, `Normal`, `Color`, `TexCoord`, and `Tangent` fields How these various fields are actually used is specified by the `Material` object set on the `StaticModel` object. ## The Simplest Geometry The simplest type of 3D object is a triangle. The following code defines an array of three `VertexBuffer.PositionNormalColor` values whose `Position` fields define the three coordinates of a triangle in the XY plane centered around the origin. When the triangle is displayed, it should appear to be directly in front of the camera: ```csharp VertexBuffer.PositionNormalColor[] vertices = { new VertexBuffer.PositionNormalColor { Position = new Vector3(0, 1, 0), Normal = new Vector3(0, 0, -1), Color = Color.Red.ToUInt() }, new VertexBuffer.PositionNormalColor { Position = new Vector3(0.86f, -0.5f, 0), Normal = new Vector3(0, 0, -1), Color = Color.Green.ToUInt() }, new VertexBuffer.PositionNormalColor { Position = new Vector3(-0.86f, -0.5f, 0), Normal = new Vector3(0, 0, -1), Color = Color.Blue.ToUInt() } }; ``` The three `Normal` fields are all set to the same vector, which points in the direction of the negative Z axis. This vector is perpendicular to the triangle and points towards the camera. The three `Color` fields are red, green, and blue. The array of `PositionNormalColor` values must be stored in a `VertexBuffer` object: ```csharp VertexBuffer vertexBuffer = new VertexBuffer(Application.CurrentContext, false) { Shadowed = true }; vertexBuffer.SetSize((uint)vertices.Length, ElementMask.Position | ElementMask.Normal | ElementMask.Color, false); vertexBuffer.SetData(vertices); ``` The `SetSize` call must include `ElementMask` enumeration flags corresponding to the particular structure that you have selected for storing the vertex information. Internally, the C++ code obtains the vertex data as a simple void pointer, so it needs to use the flags set in `SetSize` to interpret that data. Although this particular `vertices` array clearly defines the three coordinates of a triangle, often vertex information is more complex, and the entire network of triangles often share vertices. For this reason, another array is required to indicate how the various vertices form triangles. This is an array of `short` values that are indices into the `vertices` array. The number of elements in this array must be a multiple of three. Each group of three indices specifies one triangle. In this particular case, the array is very simple: ```csharp short[] indices = { 0, 1, 2 }; ``` The order of these vertex indices matters. The three vertices of a triangle can be specified in either a clockwise or a counter-clockwise direction. If the vertices are specified in a clockwise direction, then for the same triangle viewed from behind, the vertices are counter-clockwise. The surface of a triangle will only be visible from the perspective of clockwise vertices. The three vertices of the triangle defined in the `vertices` array are in this order when viewed from the perspective of the camera: top, lower-right, lower-left. This means that the indices need only be sequential for the triangle to be visible. The sequence 1, 2, 0 or 2, 0, 1 would be just as good. The array of indices must be stored in an `IndexBuffer`, which is similar in syntax to the `VertexBuffer`: ```csharp IndexBuffer indexBuffer = new IndexBuffer(Application.CurrentContext, false) { Shadowed = true }; indexBuffer.SetSize((uint)indices.Length, false, false); indexBuffer.SetData(indices); ``` The `VertexBuffer` and the `IndexBuffer` objects are brought together in a `Geometry` object. The `SetDrawRange` call must follow the setting of the `VertexBuffer` and the `IndexBuffer`: ```csharp Geometry geometry = new Geometry(); geometry.SetVertexBuffer(0, vertexBuffer); geometry.IndexBuffer = indexBuffer; geometry.SetDrawRange(PrimitiveType.TriangleList, 0, (uint)indices.Length, true); ``` The `PrimitiveType.TriangleList` enumeration member specifies the basic relationship between the vertices and indices. There are other formats that this geometry data can take, but this is by far the most common. You can simplify this process somewhat by dispensing with the `IndexBuffer`. In that case, the number of vertices referenced by the `VertexBuffer` must be a multiple of 3, and if triangles share vertices, the vertices must appear separately for each triangle. An overload of the `SetDrawRange` method accomodates the case where there are no indices. The `Model` object can consolidate multiple geometries. This particular `Model` contains only the one geometry: ```csharp Model model = new Model(); model.NumGeometries = 1; model.SetGeometry(0, 0, geometry); model.BoundingBox = new BoundingBox(new Vector3(-1, -1, -1), new Vector3(1, 1, 1)); ``` Now you are ready to create a node for displaying the triangle. As usual in a workbook, the code to create a node begins with a statement to delete the node in the event that this code cell is re-executed: ```csharp // Remove possible previous node before creating new node app.RootNode.RemoveChild(app.RootNode.GetChild("triangleNode", false)); // Create the node and a StaticModel Node triangleNode = app.RootNode.CreateChild("triangleNode"); StaticModel triangle = triangleNode.CreateComponent(); ``` After the `Node` object has been created, a call to `CreateComponent` creates a `StaticModel` component associated with the node. Set the `Model` created earlier to the `Model` property of the `StaticModel` component: ```csharp triangle.Model = model; ``` You should at long last see a triangle in the Urho window. It is colored gray because there is not yet a `Material` object associated with the component. Use a simple `Material` object to give the triangle a blue color: ```csharp triangle.SetMaterial(Material.FromColor(Color.Blue)); ``` There is no `Color` property of `StaticModel`. The `Color` property used in previous workbooks is defined by the `Shape` class. ## Variations on the Triangle The triangle appears dark blue because it is not directly facing the light. Move the mouse inside the Urho window and press the left button to give the window input focus. Now press the left button again and when you move the mouse, you should be able to rotate the triangle so it faces more towards the light source coming from above and behind the viewer’s left shoulder. The triangle is fully illuminated when the direction of the light is exactly opposite the normals at the vertices of the triangle. You can use the mouse to rotate the triangle so that the back of the triangle faces the camera. In that case, the triangle disappears. However, if you go back to the definition of the `indices` array, and change the order to 0, 2, 1, and re-execute that cell, then the triangle will appear again because now the vertices are specified in a clockwise direction from the perspective of the back of the triangle. However, the normals still indicate the same direction relative to the triangle, so the triangle becomes fully illuminated when the visible part is facing away from the light! Go back and change the indices back to the original order: 0, 1, 2. The original `vertices` array also includes settings of a `Color` field, but those fields are apparently being ignored. To use those `Color` settings in the rendering of the triangle, you must specify a different `Material` object. This `Material` object must use a particular *technique*, which is generally a read-only property from the `CoreAssets.Techniques` static class. The technique used here is called `NoTextureVCol`. The `NoTexture` part of the technique name indicates that the material does not involve a bitmap; the `VCol` part means that it uses the vertex color setting: ```csharp Material material = new Material(); material.SetTechnique(0, CoreAssets.Techniques.NoTextureVCol, 1, 1); triangle.SetMaterial(material); ``` Now you’ll see the top vertex colored red, the bottom left vertex colored blue, and the bottom right vertex colored green. The rest of the triangle is colored with an interpolated value. These colors are still affected by directional light: The colors become brighter if you rotate the triangle so it’s more directly illuminated by the directional light. The ability of a 3D graphics system to color a triangle with interpolated values is an important part of the shading algorithms that enables the appearance of curved surfaces. Before continuing, remove the triangle from the root note to make room for other visual objects: ```csharp app.RootNode.RemoveChild(triangleNode); ``` ## Rendering a Tetrahedron To reduce code bulk in the remainder of this workbook, all the code required to create a `Model` object has been consolidated in an external C# script file: ```csharp #load "CreateModel.csx" ``` You can look it over at your leisure. The file has a single method named `CreateModel` with the following syntax: `Model CreateModel(IList positions, IList normals = null, IList colors = null, IList texCoords = null);` The only argument that’s required is an array or a `List` of `Vector3` values for the `positions`. The number of `positions` elements must be a multiple of three. Each group of three values defines a triangle. The code uses the `SetDrawRange` overload that does not require indices. Consequently, there is no way with this method for a vertex be be shared among two or more triangles. If normals are not provided, they are calculated. You’ll see below how you can use this feature for different types of shading. Here is the `CreateModel` method in action to create a `Model` object for a tetrahedron, which is the simplest regular polyhedron. The tetrahedron consists of four sides, each of which is a triangle. The coordinates of these vertices correspond to four corners of a unit cube: ```csharp Model tetrahedronModel = CreateModel(new Vector3[] { new Vector3(-1, 1, -1), new Vector3(-1, -1, 1), new Vector3( 1, 1, 1), new Vector3( 1, -1, -1), new Vector3( 1, 1, 1), new Vector3(-1, -1, 1), new Vector3( 1, 1, 1), new Vector3( 1, -1, -1), new Vector3(-1, 1, -1), new Vector3(-1, -1, 1), new Vector3(-1, 1, -1), new Vector3( 1, -1, -1) }); ``` The following code is all that’s necessary to display it: ```csharp app.RootNode.RemoveChild(app.RootNode.GetChild("tetrahedronNode", false)); Node tetrahedronNode = app.RootNode.CreateChild("tetrahedronNode"); StaticModel tetrahedron = tetrahedronNode.CreateComponent(); tetrahedron.Model = tetrahedronModel; tetrahedron.SetMaterial(Material.FromColor(Color.Red)); ``` When you are finished twirling it around with the mouse, you can remove it from the root node in preparation for the next object: ```csharp app.RootNode.RemoveChild(tetrahedronNode); ``` ## From Disk to Cone Many algorithmically generated models have curved surfaces. To create these surfaces, it is necessary to use trigonometry. Many common figures can be created knowing only the formulas for a circle: x = cos(α) y = sin(α) For α ranging from 0 to 360 degrees (or from 0 to 2π radians), the *x* and *y* values define a circle with a radius of 1 centered on the two dimensional point (0, 0). In a 3D coordinate system where values of *x* increase to the right and values of *y* increase going up, the angle is counter-clockwise from the positive X axis. Perhaps the easiest way to begin using these formulas is by creating a two-dimensional disk. A disk can be constructed of triangles that share a common point in the center of the disk. The number of triangles is up to you. Generally you set the value in a variable or constant called something like `slices` or `stacks` (and sometimes you need both): ```csharp int slices = 24; ``` That’s the number of triangles. There will be a total of 24 × 3 (or 72) vertices, but defining a `List` to store the vertices is usually easier than a `Vector3` array: ```csharp List diskVertices = new List(); ``` As you loop through all the triangles to calculate their vertices, the following value will be useful: ```csharp float angleIncrement = 360 / slices; ``` For 24 triangles, `angleIncrement` is 15 degrees. The `for` loop to set the positions is preceded by a statement that clears `diskVertices` in case the cell is run again. Within the loop, four values are first calculated for each triangle. These comprise two (*x*, *y*) coordinates along the circumference of the circle: ```csharp diskVertices.Clear(); for (float angle = 0; angle < 360; angle += angleIncrement) { float xThis = (float)Math.Cos(MathHelper.DegreesToRadians(angle)); float yThis = (float)Math.Sin(MathHelper.DegreesToRadians(angle)); float xNext = (float)Math.Cos(MathHelper.DegreesToRadians(angle + angleIncrement)); float yNext = (float)Math.Sin(MathHelper.DegreesToRadians(angle + angleIncrement)); diskVertices.Add(new Vector3(0, 0, 0)); diskVertices.Add(new Vector3(xNext, yNext, 0)); diskVertices.Add(new Vector3(xThis, yThis, 0)); } ``` In this code and in code in the rest of this workbook, variables containing the word `This` are calculated from the `angle` value in the `for` loop. Variables with the word `Next` refer to the next angle in the loop. The code at the bottom of the `for` loop adds three values to the `diskVertices` collection for each triangle: The first `Vector3` is the center of the circle, and the next two are points on the circumference of the circle. Keep in mind that increasing angles define points along the circle’s circumference in a counter-clockwise direction, so the (`xNext`, `yNext`, 0) point is added to the colleciton first, followed by (`xThis`, `yThis`, 0) to define the vertices of the triangle in a clockwise direction. Display the disk like so: ```csharp app.RootNode.RemoveChild(app.RootNode.GetChild("diskNode", false)); Node diskNode = app.RootNode.CreateChild("diskNode"); StaticModel disk = diskNode.CreateComponent(); disk.Model = CreateModel(diskVertices); disk.SetMaterial(Material.FromColor(Color.Yellow)); ``` It might be necessary to use the mouse to rotate it into full view. In reality, this is not a disk but a 24-sided polygon, sometimes called a icositetragon, and you can clearly see the edges. However, if you change the `slices` value above to 360 and re-run that cell, it should look much rounded. Here’s another little variation: Instead of setting the first `Vector3` to the point (0, 0, 0), set it to (0, 0, -2) and rerun the cell. Now you’ve created a cone. If you rotate the cone so that you’re looking at the inside, it seems to disappear. Triangles are only visible from one side. If you want to have an interior of the cone, define another `List` and fill it with triangles defined counter-clockwise rather than clockwise: ```csharp List insideVertices = new List(); for (float angle = 0; angle < 360; angle += angleIncrement) { float xThis = (float)Math.Cos(MathHelper.DegreesToRadians(angle)); float yThis = (float)Math.Sin(MathHelper.DegreesToRadians(angle)); float xNext = (float)Math.Cos(MathHelper.DegreesToRadians(angle + angleIncrement)); float yNext = (float)Math.Sin(MathHelper.DegreesToRadians(angle + angleIncrement)); insideVertices.Add(new Vector3(0, 0, -2)); insideVertices.Add(new Vector3(xThis, yThis, 0)); insideVertices.Add(new Vector3(xNext, yNext, 0)); } ``` Notice that the `Vector3` value using `xThis` and `yThis` is added to the collection before the one using `xNext` and `yNext`. Assuming that you’re now displaying a cone rather than the earlier disk, you can add another cone that is inside of the first one: ```csharp app.RootNode.RemoveChild(app.RootNode.GetChild("insideNode", false)); Node insideNode = app.RootNode.CreateChild("insideNode"); StaticModel inside = insideNode.CreateComponent(); inside.Model = CreateModel(insideVertices); inside.SetMaterial(Material.FromColor(Color.Cyan)); ``` Now the outside of the cone is yellow and the inside is cyan. Before moving on, remove both nodes: ```csharp app.RootNode.RemoveChild(diskNode); app.RootNode.RemoveChild(insideNode); ``` ## Cylinder or Dodecagonal Prism? Creating a cylinder is a step up from the disk and the cone. There are two disks at the two ends of the cylinder. Although these disks are not part of this particular cylinder model, the angles around the disks are calculated in the same way as the disk. The difference is that for each pair of angles, two triangles must be defined that extend from one disk to the other, or four triangles if you want a visible interior as well: ```csharp List cylinderVertices = new List(); int slices = 12; float angleIncrement = 360 / slices; for (float angle = 0; angle < 360; angle += angleIncrement) { float cosThis = (float)Math.Cos(MathHelper.DegreesToRadians(angle)); float sinThis = (float)Math.Sin(MathHelper.DegreesToRadians(angle)); float cosNext = (float)Math.Cos(MathHelper.DegreesToRadians(angle + angleIncrement)); float sinNext = (float)Math.Sin(MathHelper.DegreesToRadians(angle + angleIncrement)); // Outside cylinderVertices.Add(new Vector3(cosThis, sinThis, -1)); cylinderVertices.Add(new Vector3(cosNext, sinNext, -1)); cylinderVertices.Add(new Vector3(cosNext, sinNext, 1)); cylinderVertices.Add(new Vector3(cosThis, sinThis, -1)); cylinderVertices.Add(new Vector3(cosNext, sinNext, 1)); cylinderVertices.Add(new Vector3(cosThis, sinThis, 1)); // Inside cylinderVertices.Add(new Vector3(cosThis, sinThis, -1)); cylinderVertices.Add(new Vector3(cosNext, sinNext, 1)); cylinderVertices.Add(new Vector3(cosNext, sinNext, -1)); cylinderVertices.Add(new Vector3(cosThis, sinThis, -1)); cylinderVertices.Add(new Vector3(cosThis, sinThis, 1)); cylinderVertices.Add(new Vector3(cosNext, sinNext, 1)); } ``` For each angle, four triangles are added to the collection: two on the outside and two more with swapped coordinates for the inside. And here it is displayed: ```csharp app.RootNode.RemoveChild(app.RootNode.GetChild("cylinderNode", false)); Node cylinderNode = app.RootNode.CreateChild("cylinderNode"); StaticModel cylinder = cylinderNode.CreateComponent(); cylinder.Model = CreateModel(cylinderVertices); cylinder.SetMaterial(Material.FromColor(Color.Cyan)); ``` Now as you rotate the cylinder around you can see both the outside and the inside. But it doesn’t look much linke a cylinder. Instead, it’s more like a figure called a dodecagonal prism. One solution is to simply increase the `slices` value to make the triangles smaller and more numerous. Another solution is to calculate a better set of surface normals and use that to set the `normals` argument to `CreateModel`. The normals calculated in the code below are the same as the `positions` values except that the Z coordinate is set to 0: ```csharp Vector3[] cylinderNormals = new Vector3[cylinderVertices.Count]; for (int i = 0; i < cylinderVertices.Count; i++) { cylinderNormals[i] = new Vector3(cylinderVertices[i].X, cylinderVertices[i].Y, 0); } cylinder.Model = CreateModel(cylinderVertices, cylinderNormals); ``` Run that code to reset the `Model` property of the `cylinder` component, and you see an illusion of curvature even though it’s obviously still a 12-sided prism. The normals are vectors that point out from the surface. For each vertex of the triangle, the illumination of that vertex is calculated by how the directional light and the normal lines up. If they are exactly opposite, that vertex is maximally illuminated. Otherwise, the illumination is decreased based on the angle between the directional light and the normal. If the `normals` argument to `CreateModel` is `null`, then the normals are calculated to be perpendicular to the triangle. This means that the normals at all three vertices are the same, and the triangle appears to be flat. However, if the normals are different, and they are perpendicular to the triangle *as if the triangle were curved*, then the illumination is different over the triangle and appears to resemble a curved surface. The function above calculates normals to be perpendicular to the surface of a curved cylinder. However, you’ll notice that the simple code doesn’t quite adjust for the inside of the cylinders, and the normals are opposite what they should be. Before moving on, remove the cylinder: ```csharp app.RootNode.RemoveChild(cylinderNode); ``` ## Sphere and Globe Defining a sphere is somewhat more difficult than a cylinder because it’s rounded in two dimensions. The most straightfoward approach is to use the common geographic coordinate system consisting of lines of longitude (which extend from the north pole to the south pole) and lines of latitude (which are horizontal to the equator). When triangulating the globe, the intersection of lines of longitude and latitude form a rectangle that is a pair of triangles. (This isn’t quite the case for the area around the north and south pole, but you can ignore that anomaly and the code will be rather simpler.) The following code begins with a `List` for the vertices and a `List` for texture coordinates. Texture coordinates are required when displaying a two-dimensional bitmap on a three-dimensional surface. To do this, each vertex of each triangle must correspond to a particular 2D point within the bitmap. These 2D points are relative to the size of the bitmap. The point (0, 0) references the upper-left corner of the bitmap, (1, 0) is the upper-right corner, and (1, 1) is the lower-right corner. Notice that three-dimensional Y coordinates increase going up but texture Y coordinates increase going down. There are two loops, one for the latitude and another for the longitude. The comments provide some guidance for reading the code: ```csharp List sphereVertices = new List(); List sphereTextures = new List(); int stacks = 18; // X and Z axis, latitude int slices = 36; // Y axis, longitude float latitudeIncr = 180 / stacks; float longitudeIncr = 360 / slices; // From the north pole to the south pole for (float latitude = 90; latitude > -90; latitude -= latitudeIncr) { // Calculate Y coordinate for this angle and next angle float yThis = (float)Math.Sin(MathHelper.DegreesToRadians(latitude)); float yNext = (float)Math.Sin(MathHelper.DegreesToRadians(latitude - latitudeIncr)); // Calculate relative Y coordinates for texture coordinates float yRelativeThis = (90 - latitude) / 180; float yRelativeNext = (90 - latitude + latitudeIncr) / 180; // Calculate scaling factors to apply to lines of latitude float scaleThis = (float)Math.Cos(MathHelper.DegreesToRadians(latitude)); float scaleNext = (float)Math.Cos(MathHelper.DegreesToRadians(latitude - latitudeIncr)); // From the International Date Line westward around the world for (float longitude = 0; longitude < 360; longitude += longitudeIncr) { // Calculate unscaled X coordinates, starts at zero, then positive float xThis = (float)Math.Sin(MathHelper.DegreesToRadians(longitude)); float xNext = (float)Math.Sin(MathHelper.DegreesToRadians(longitude + longitudeIncr)); // Calculate unscaled Z coordinates, starts at 1 (furthest from camera) float zThis = (float)Math.Cos(MathHelper.DegreesToRadians(longitude)); float zNext = (float)Math.Cos(MathHelper.DegreesToRadians(longitude + longitudeIncr)); // Calculate relative X coordinates for texture coordinates float xRelativeThis = (360 - longitude) / 360; float xRelativeNext = (360 - longitude - longitudeIncr) / 360; // Add two triangles to vertices collection sphereVertices.Add(new Vector3(scaleThis * xThis, yThis, scaleThis * zThis)); sphereVertices.Add(new Vector3(scaleNext * xThis, yNext, scaleNext * zThis)); sphereVertices.Add(new Vector3(scaleThis * xNext, yThis, scaleThis * zNext)); sphereVertices.Add(new Vector3(scaleThis * xNext, yThis, scaleThis * zNext)); sphereVertices.Add(new Vector3(scaleNext * xThis, yNext, scaleNext * zThis)); sphereVertices.Add(new Vector3(scaleNext * xNext, yNext, scaleNext * zNext)); // Add corresponding points to texture coordinates collection sphereTextures.Add(new Vector2(xRelativeThis, yRelativeThis)); sphereTextures.Add(new Vector2(xRelativeThis, yRelativeNext)); sphereTextures.Add(new Vector2(xRelativeNext, yRelativeThis)); sphereTextures.Add(new Vector2(xRelativeNext, yRelativeThis)); sphereTextures.Add(new Vector2(xRelativeThis, yRelativeNext)); sphereTextures.Add(new Vector2(xRelativeNext, yRelativeNext)); } } ``` The following code displays the sphere. Notice that the `CreateModel` call uses only the `sphereVertices` collection for the vertex positions, and hence the rectangles that make up the sphere are clearly discernable: ```csharp app.RootNode.RemoveChild(app.RootNode.GetChild("sphereNode", false)); Node sphereNode = app.RootNode.CreateChild("sphereNode"); StaticModel sphere = sphereNode.CreateComponent(); sphere.Model = CreateModel(sphereVertices); sphere.SetMaterial(Material.FromColor(Color.Cyan)); ``` To make this look smooth, you need a collection of normal vectors that point from the center of the sphere through each vertex. But these already exist! They are exactly the same as the vertex positions. Because UrhoSharp uses the same `Vector3` type for points and vectors, the same `sphereVertices` collection can be passed as the second argument to `CreateModel` as well: ```csharp sphere.Model = CreateModel(sphereVertices, sphereVertices); ``` Now the sphere is rounded. The next step is to cover this sphere with a map of the whole Earth. The first step is to create a new model using the texture coordinates as well. ```csharp sphere.Model = CreateModel(sphereVertices, sphereVertices, null, sphereTextures); ``` The easy way to use a bitmap as a `Material` object is to call the static `Material.FromImage` method. The following bitmap of the entire Earth is stored in the **Data** directory relative to this workbook. It was obtained from , and is used courtesy of NASA/JPL-Caltech: ```csharp sphere.SetMaterial(Material.FromImage("ear0xuu2.jpg")); ``` However, this material is still using the normals to calculate the light intensity around the globe. This might be desireable if you were showing half the Earth in darkness during the day, but in that case you’d want to increase the intensity of the directional light and reduce the intensity of the ambient light considerably. For a simple image of the world, it make more sense to use a technique that keeps the bitmap fully illuminated regardless of the light. This is a technique called `DiffUnlit`: ```csharp Material earthMaterial = new Material(); earthMaterial.SetTexture(TextureUnit.Diffuse, app.ResourceCache.GetTexture2D("ear0xuu2.jpg")); earthMaterial.SetTechnique(0, CoreAssets.Techniques.DiffUnlit, 0, 0); sphere.SetMaterial(earthMaterial); ``` And there is a fully illuminated globe that you can turn with the mouse. ================================================ FILE: graphics/urhosharp/meta.json ================================================ { "order":{ "coordinates/ExploringUrhoCoordinates.workbook":"Exploring Urho Coordinates", "compound-shapes/CreatingUrhoCompoundShapes.workbook":"Creating Compound Shapes (Quadcopter)", "custom-geometries/CustomGeometries.workbook":"Working with Urho Custom Geometries", "building-polyhedra/BuildingPolyhedra.workbook":"Building Polyhedra with UrhoSharp (Stellations of the Dodecahedron)", "animated-model/animated-model.workbook":"Animated Model", "barchart/charts.workbook":"Charts", "physics/physics.workbook":"Physics", "planetearth/planetearth.workbook":"Planet Earth", "mobius-strip-speedway/MobiusStripSpeedway.workbook": "Möbius Strip Speedway", "circle-of-life/CircleOfLife.workbook": "Circle of Life: Actions and Animations" } } ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/BlueRacer/Materials/Material1.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/BlueRacer/Materials/White.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/BlueRacer/Materials/White_0.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/BlueRacer/Materials/White_1.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/BlueRacer/Materials/White_10.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/BlueRacer/Materials/White_11.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/BlueRacer/Materials/White_12.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/BlueRacer/Materials/White_13.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/BlueRacer/Materials/White_14.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/BlueRacer/Materials/White_15.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/BlueRacer/Materials/White_16.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/BlueRacer/Materials/White_17.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/BlueRacer/Materials/White_18.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/BlueRacer/Materials/White_19.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/BlueRacer/Materials/White_2.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/BlueRacer/Materials/White_20.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/BlueRacer/Materials/White_21.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/BlueRacer/Materials/White_22.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/BlueRacer/Materials/White_3.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/BlueRacer/Materials/White_4.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/BlueRacer/Materials/White_5.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/BlueRacer/Materials/White_6.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/BlueRacer/Materials/White_7.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/BlueRacer/Materials/White_8.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/BlueRacer/Materials/White_9.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/BlueRacer/node.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/RedRolls/Materials/White.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/RedRolls/Materials/White_0.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/RedRolls/Materials/White_1.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/RedRolls/Materials/White_10.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/RedRolls/Materials/White_11.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/RedRolls/Materials/White_12.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/RedRolls/Materials/White_13.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/RedRolls/Materials/White_14.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/RedRolls/Materials/White_15.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/RedRolls/Materials/White_16.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/RedRolls/Materials/White_17.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/RedRolls/Materials/White_2.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/RedRolls/Materials/White_3.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/RedRolls/Materials/White_4.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/RedRolls/Materials/White_5.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/RedRolls/Materials/White_6.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/RedRolls/Materials/White_7.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/RedRolls/Materials/White_8.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/RedRolls/Materials/White_9.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/Data/RedRolls/node.xml ================================================ ================================================ FILE: graphics/urhosharp/mobius-strip-speedway/MobiusStripSpeedway.workbook/index.workbook ================================================ --- id: 4839602e-a48d-41fa-b4ab-ffbab6cc39b7 uti: com.xamarin.workbook title: MobiusStripSpeedway platforms: - Console packages: - id: UrhoSharp version: 1.5.22 --- # Möbius Strip Speedway This Workbook creates a circular road in the form of a Möbius strip, and then animates two cars to drive around that road. ![Speedway Preview](Images/SpeedwayPreview.png "Speedway Preview") A variation of this Workbook was described in the webinar [“Exploring UrhoSharp 3D with Xamarin Workbooks”](https://channel9.msdn.com/Events/Xamarin/Recent-Webinars/Exploring-UrhoSharp-3D-with-Xamarin-Workbooks "Webinar") broadcast on September 21, 2017. This Workbook uses UrhoSharp, Xamarin’s cross-platform C# and .NET wrapper on the open-source Urho3D graphics system. It demonstrates creating 3D objects algorithmically and loading predefined 3D models available on the new Microsoft-curated **Remix 3D** web site. The Workbook discusses in detail the technique of rotating the cars so that they properly tilt along the surface of the curved Möbius strip as they drive around it. Also explored is the ability of UrhoSharp to draw lines in 3D space. This is often useful for experimentation and to erect a type of “scaffolding” that is helpful to visualize 3D surfaces. The first step in any UrhoSharp Workbook is to add the UrhoSharp NuGet package from the **File > Add Package** or **File > Add NuGet Package** menu item. Within the workbook, reference the UrhoSharp libraries: ```csharp #r "Urho" ``` Most of this Workbook requies only one `using` directive: ```csharp using Urho; ``` Two more `using` directives are specified towards the end of this Workbook in connection with animation. A special `SimpleApplication` class exists for using UrhoSharp in a Workbook. The `ApplicationOptions` object allows specifying a directory for loadable resources as well as other options: ```csharp SimpleApplication app = SimpleApplication.Show(new ApplicationOptions("Data")); ``` Executing this code block creates a window that you can then move and resize. `SimpleApplication` also creates a default camera and lights, which this Workbook does not change. The origin of the 3D coordinate system is in the center of the window. X coordinates increase to the right, Y coordinates increase going up, and Z coordinates increase going into the screen. ## Drawing a Circle This project begins by creating a type of scaffolding to visualize the shape of the road before the road is “paved” with surfaces. This scaffolding consists of straight lines in 3D space. These lines do not constitute a wireframe (which is an alternative way to visualize 3D surfaces) but they are similar. However, because UrhoSharp is a 3D graphics framework, drawing lines is not nearly as simple or straightforward as in a 2D graphics environment. Substantial overhead is required, but this overhead is very similar to that for drawing 3D surfaces. The first part of this scaffolding is a circle that will eventually become the dividing line between the two lines of the road. The first step is to accumulate a collection of `Vector3` values that define a circle. The `Vector3` structure has three fields of type `float` named `X`, `Y`, and `Z`. This is the structure used to represent a point in 3D space as well as a vector, which encapsulates a direction and a magnitude. Points and vectors are related: A point is the same value as a vector from the origin to that point, but vectors do not have any specific position in 3D space. The following code defines a series of points that approximate a circle. This circle has Y coordinates of zero, so it sits on the plane defined by the X and Z axis, called the XZ plane. The `DIVISIONS` constant determines how many points approximate this circle. These points define a 100-sided regular polygon (called a *hectagon*) but you’ll see that it is visually indistinguishable from a circle. ```csharp const int DIVISIONS = 100; List radii = new List(); for (int i = 0; i <= DIVISIONS; i++) { double angle = i * 2 * Math.PI / DIVISIONS; float x = (float)Math.Cos(angle); float y = 0; float z = (float)Math.Sin(angle); radii.Add(new Vector3(x, y, z)); } ``` These *radii* values are both points and vectors. They are points on the circumference of a circle with a radius of 1, and they are also vectors from the origin to those points. As vectors, they have a length (or magnitude) of 1, which means that the vectors are said to be *normalized*. Notice that the loop increments `i` from 0 to less than *or equal to* `DIVISIONS`, so the collection contains 101 values rather than 100. Because the points define a circle, the last element of the collection is the same as the first. As you’ll see, sometimes this is helpful when later indexing the array.\ \ The next code block uses the `radii` vectors to calculate points on the circumference of a circle with a radius of 2 units. Notice that a `Vector3` value can be multiplied by a number, called a *scalar*, such as the `RADIUS` constant: ```csharp const float RADIUS = 2; List circlePts = new List(); for (int i = 0; i <= DIVISIONS; i++) { circlePts.Add(RADIUS * radii[i]); } ``` If you’re accustomed to 2D graphics, that might seem like a very small circle, but 3D units are relative. They are based on the relationship of the camera to the graphical objects, and to the height of the window. With the camera created by `SimpleApplication`, one unit is about 15% of the height of the window. To actually get this circle on the screen requires several more steps. The first of these steps is creating a vertex collection. A vertex is a position in 3D space, but accompanied with other information associated with that position. The simplest type of a vertex collection is a collection of `PositionNormal` structures. This structure is defined within the `VertexBuffer` class, so the full name is `VertexBuffer.PositionNormal`. The structure has two fields named `Position` and `Normal`, but for drawing lines, you only need to set the `Position` field: ```csharp var circleVertices = new List(); for (int i = 0; i <= DIVISIONS; i++) { circleVertices.Add(new VertexBuffer.PositionNormal { Position = circlePts[i] }); } ``` Notice that the loop also goes to less than or equal to `DIVISIONS`, so again the last point is the same as the first. This will be necessary for drawing a complete closed circle. This collection of vertices must be stored in an object of type `VertexBuffer`. For performance purposes, these vertices might also be stored in the memory of the graphics processing unit (GPU) of the video display. Because UrhoSharp is a C# wrapper on C++ code, the internal code can’t determine the size and type of the collection of vertices. You must explicitly specify the size of the vertex collection, and the fact that each vertex consists of a position and a normal, even though the normal is not used here: ```csharp VertexBuffer circleBuffer = new VertexBuffer(Application.CurrentContext, false); circleBuffer.SetSize((uint)circleVertices.Count, ElementMask.Position | ElementMask.Normal, false); circleBuffer.SetData(circleVertices.ToArray()); ``` The next step is to construct a `Geometry` object. This is a collection of one or more vertex buffers, in this case just the one vertex buffer: ```csharp Geometry circleGeometry = new Geometry(); circleGeometry.SetVertexBuffer(0, circleBuffer); circleGeometry.SetDrawRange(PrimitiveType.LineStrip, 0, 0, 0, (uint)circleVertices.Count, true); ``` An important piece of information specified in this `Geometry` object is the enumeration member `PrimitiveType.LineStrip`. This indicates how the vertices should be interpreted. The `LineStrip` member means that each successive vertex is connected to the next vertex with a line. This creates a series of connected lines often called a *polyline*. You’ll see two other members of the `PrimitiveType` enumeration later in this Workbook. A `Model` object is one or more geometries, in this case just one geometry: ```csharp Model circleModel = new Model(); circleModel.NumGeometries = 1; circleModel.SetGeometry(0, 0, circleGeometry); circleModel.BoundingBox = new BoundingBox(new Vector3(-10, -10, -10), new Vector3(10, 10, 10)); ``` The `BoundingBox` is required. It should encompass the coordinates in the geometry but otherwise the values are not critical. Most of the objects in a 3D scene are organized in a tree structure of nodes and subnodes. The camera is a node, light sources are nodes, and visual objects are nodes. The big advantage of the tree structure is that a graphics transform can be applied to a node, and it affects all the child nodes as well. The `SimpleApplication` object creates a root node that is accessible through the `RootNode` property. The following code adds a child node to that node named `mainNode`. This will be the parent node to all the other nodes created in this Workbook. Since code blocks in a Workbook can be re-executed, any code that creates a node must be preceded in the same code block by code that removes the node: ```csharp app.RootNode.RemoveChild(app.RootNode.GetChild("mainNode")); Node mainNode = app.RootNode.CreateChild("mainNode"); ``` This code also works if the code block is being executed for the first time. If the node does not exist, `GetChild` returns `null` and `RemoveNode` ignores a `null` argument. Here’s the node for the circle. It is a child of `mainNode`. A `StaticModel` component is created for the node, and that is used to reference the model created earlier: ```csharp mainNode.RemoveChild(mainNode.GetChild("circleNode")); Node circleNode = mainNode.CreateChild("circleNode"); StaticModel circle = circleNode.CreateComponent(); circle.Model = circleModel; ``` The final step is to associate a `Material` object with the `StaticModel` object. The material indicates the visual appearance of the model. The specification here indicates the color, the fact that it should not be affected by light, and that it should be antialiased: ```csharp Material blackLineMaterial = Material.FromColor(Color.Black); blackLineMaterial.SetTechnique(0, CoreAssets.Techniques.NoTextureUnlit, 1, 1); blackLineMaterial.LineAntiAlias = true; circle.SetMaterial(blackLineMaterial); ``` At long last, a circle appears on the screen. On the PC, the circle will be very faint, but it is darker on the Mac. The center of the circle is aligned with the center of the window. The camera is positioned above the XZ plane but pointing down somewhat, so the circle is seen from above. Within the UrhoSharp window, you can pan the camera horizontally and vertically using touch or the mouse with the button depressed, and you can zoom in and out using a mousewheel or the two-finger scroll gesture on the touchpad. \ \ You can experiment with changing `DIVISIONS` to smaller values to see how that affects the appearance of the circle. When you re-execute a code block in a Workbook, all the subsequent previously executed code blocks are also re-executed. You might also experiement with the loop that adds vertices to the `circleVertices` collection. Change `DIVISIONS` to `DIVISIONS / 2` and `DIVISIONS / 4`. This will convince you that the circle begins at the far right, and the lines go counter-clockwise from the viewer’s perspective. This information is important when later animating the cars. ## The Looping Road The next step is to construct a series of lines that span the width of the road. These lines will be at right angles to the circumference of the circle. The following code block computes tangents to the circle. For every point on the circle, a vector is calculated. This is the difference between the two points on either side of that point. The modulo operations avoid invalid array indices: ```csharp List tangents = new List(); for (int i = 0; i <= DIVISIONS; i++) { Vector3 tangent = circlePts[(i + 1) % DIVISIONS] - circlePts[(i + DIVISIONS - 1) % DIVISIONS]; tangents.Add(tangent); } ``` The following collection called `parallels` are vectors that span the width of the road at every point. These vectors are parallel to the surface of the road like the `radii` vectors but rotated around an axis from the `tangents` collection: ```csharp List parallels = new List(); for (int i = 0; i <= DIVISIONS; i++) { float tilt = i * (float)Math.PI / DIVISIONS; Matrix4 matrix = Matrix4.CreateFromAxisAngle(tangents[i], tilt); Vector3 parallel = Vector3.TransformVector(radii[i], matrix); parallels.Add(parallel); } ``` There are several ways to tilt these `parallels` vectors around the `tangents` axes, but this particular code twists the `parallels` to create a Möbius strip. The `tilt` value goes from 0 to 180 degrees (π radians) as `i` goes around the circle. The `CreateFromAxisAngle` method creates a `Matrix4` value, which is a 4×4 transform matrix that represents a rotation of `tilt` angles around the tangent. This is then used to transform a vector from the `radii` collection to create a vector for the `parallels` collection. Because the `radii` vectors are normalized (that is, have a length of 1) and are only subjected here to a rotation transform, the `parallels` vectors are also normalized. Vectors that are normalized are very useful for performing arithmetic operations on points and vectors, such as in the following code. The width of the road is set to half the radius, or 1. Two collections are accumulated: `innerPts` defines a circle on the inside of the road, and `outerPts` defines a circle on the outside of the road. These are calculated by multiplying half the width by a `parallels` vector, and either adding that to, or subtracting it from, a `circlePts` value: ```csharp const float WIDTH = RADIUS / 2; List innerPts = new List(); List outerPts = new List(); for (int i = 0; i <= DIVISIONS; i++) { innerPts.Add(circlePts[i] - WIDTH / 2 * parallels[i]); outerPts.Add(circlePts[i] + WIDTH / 2 * parallels[i]); } ``` It will be useful to see what these lines look like, but they need to be drawn a little differently from the circle. Instead of drawing a polyline, it will be useful to see the lines connecting each point in `innerPts` to the corresponding point in `outerPts`. That is possible. The first step is to construct a collection of `VertexBuffer.PositionNormal` values with these pairs of points: ```csharp var widthVertices = new List(); for (int i = 0; i < DIVISIONS; i++) { widthVertices.Add(new VertexBuffer.PositionNormal { Position = innerPts[i] }); widthVertices.Add(new VertexBuffer.PositionNormal { Position = outerPts[i] }); } ``` Next, create a `VertexBuffer` the same way as the previous one: ```csharp VertexBuffer widthBuffer = new VertexBuffer(Application.CurrentContext, false); widthBuffer.SetSize((uint)widthVertices.Count, ElementMask.Position | ElementMask.Normal, false); widthBuffer.SetData(widthVertices.ToArray()); ``` Then the `Geometry`: ```csharp Geometry widthGeometry = new Geometry(); widthGeometry.SetVertexBuffer(0, widthBuffer); widthGeometry.SetDrawRange(PrimitiveType.LineList, 0, 0, 0, (uint)widthVertices.Count, true); ``` Notice that the first argument to `SetDrawRange` is the enumeration value `PrimitiveType.LineList`. The code that rendered the circle used an enumeration value of `LineStrip`, which causes the vertices to be connected with a series of lines forming a polyline. The `LineList` member causes the points to be interpreted in pairs, and a line is drawn between each pair of points. The `Model` is constructed just like the earlier one: ```csharp Model widthModel = new Model(); widthModel.NumGeometries = 1; widthModel.SetGeometry(0, 0, widthGeometry); widthModel.BoundingBox = new BoundingBox(new Vector3(-10, -10, -10), new Vector3(10, 10, 10)); ``` And finally the `Node` can re-use the `blackLineMaterial` created earlier: ```csharp mainNode.RemoveChild(mainNode.GetChild("widthNode")); Node widthNode = mainNode.CreateChild("widthNode"); StaticModel width = widthNode.CreateComponent(); width.Model = widthModel; width.SetMaterial(blackLineMaterial); ``` This renders a series of lines that clearly display the surface of a road in the form of a Möbius strip. If you want to see a flat road, simpy set `tilt` to 0 in the earlier code block and re-execute it. ## The Road Depth Besides the width, the road will also be given a depth. To compute the coordinates for this depth, it is necessary to compute vectors that are perpendicular to the `parallels` vectors. However, in 3D, there are an infinite number of vectors that are perpendicular to another vector. More specifically, the `perpendiculars` vectors must be perpendicular to both the corresponding `parallels` vector and the `tangents` vector. There is a standard way to obtain a vector that is perpendicular to two other vectors, and that is the vector *cross product*, accessible through the static `Vector3.Cross` method: ```csharp List perpendiculars = new List(); for (int i = 0; i <= DIVISIONS; i++) { Vector3 perpendicular = Vector3.Cross(tangents[i], parallels[i]); perpendicular.Normalize(); perpendiculars.Add(perpendicular); } ``` Notice that the perpendiculars vectors are normalized. This makes them suitable for arithmetic operations such as those in the next code block. This code block assembles four more collections. These are based on `innerPts` and `outerPts` but offset by half the depth times a vector from the `perpendiculars` collection: ```csharp const float DEPTH = RADIUS / 10; List innerUpperPts = new List(); List outerUpperPts = new List(); List innerLowerPts = new List(); List outerLowerPts = new List(); for (int i = 0; i <= DIVISIONS; i++) { innerUpperPts.Add(innerPts[i] + DEPTH / 2 * perpendiculars[i]); outerUpperPts.Add(outerPts[i] + DEPTH / 2 * perpendiculars[i]); innerLowerPts.Add(innerPts[i] - DEPTH / 2 * perpendiculars[i]); outerLowerPts.Add(outerPts[i] - DEPTH / 2 * perpendiculars[i]); } ``` It will be useful to see these new points. The following code assembles a collection of `VertexBuffer.PositionNormal` values with two pairs of points for each index: from a point in the `outerUpperPts` collection to the corresponding point in `outerLowerPts`, and from points in `innerUpperPts` to points in `innerLowerPts`: ```csharp var depthVertices = new List(); for (int i = 0; i < DIVISIONS; i++) { depthVertices.Add(new VertexBuffer.PositionNormal { Position = outerUpperPts[i] }); depthVertices.Add(new VertexBuffer.PositionNormal { Position = outerLowerPts[i] }); depthVertices.Add(new VertexBuffer.PositionNormal { Position = innerUpperPts[i] }); depthVertices.Add(new VertexBuffer.PositionNormal { Position = innerLowerPts[i] }); } ``` These vertices could have been integrated with the previous collection, but it’s rather messy to do that after the previous nodes have been created. For that reason, this new collection of vertices is given a new `VertexBuffer`: ```csharp VertexBuffer depthBuffer = new VertexBuffer(Application.CurrentContext, false); depthBuffer.SetSize((uint)depthVertices.Count, ElementMask.Position | ElementMask.Normal, false); depthBuffer.SetData(depthVertices.ToArray()); ``` That becomes part of a `Geometry`: ```csharp Geometry depthGeometry = new Geometry(); depthGeometry.SetVertexBuffer(0, depthBuffer); depthGeometry.SetDrawRange(PrimitiveType.LineList, 0, 0, 0, (uint)depthVertices.Count, true); ``` And that becomes part of a `Model`: ```csharp Model depthModel = new Model(); depthModel.NumGeometries = 1; depthModel.SetGeometry(0, 0, depthGeometry); depthModel.BoundingBox = new BoundingBox(new Vector3(-10, -10, -10), new Vector3(10, 10, 10)); ``` Finally, a new `Node` is created: ```csharp mainNode.RemoveChild(mainNode.GetChild("depthNode")); Node depthNode = mainNode.CreateChild("depthNode"); StaticModel depth = depthNode.CreateComponent(); depth.Model = depthModel; depth.SetMaterial(blackLineMaterial); ``` Now the solidity of the road should be apparent. The goal now is to connect the ends of these little perpendicular lines with a surface. ## The Edge of the Track In 3D graphics, surfaces are defined by a mesh of triangles. Triangles are used because they are the simplest two-dimensional objects and are always flat. The illusion of three dimensions is accomplished by making the triangles rather small, and by shading the surfaces: Each of the three vertices of the triangle can reflect light a little differently, and the 3D system interpolates that shading over the triangle’s surface. This shading requires specifying the `Normal` field of the `VertexBuffer.PositionNormal` structure. The normal is a vector that is perpendicular to the surface at that vertex. The following code assembles a collection of `VertexBuffer.PositionNormal` values for the outer and inner edge of the road. Each group of four ends of the little perpendicular lines are connected with two triangles, and each triangle requires three vertices. The normal is a member of the `parallels` collection because those vectors are perpendicular to the edges. The vertices of each triangle must be defined in a clockwise order from the viewpoint of where they are visible. ```csharp var edgeVertices = new List(); for (int i = 0; i < DIVISIONS; i++) { // Outer edge edgeVertices.Add(new VertexBuffer.PositionNormal { Position = outerLowerPts[i], Normal = parallels[i] }); edgeVertices.Add(new VertexBuffer.PositionNormal { Position = outerUpperPts[i], Normal = parallels[i] }); edgeVertices.Add(new VertexBuffer.PositionNormal { Position = outerUpperPts[i + 1], Normal = parallels[i + 1] }); edgeVertices.Add(new VertexBuffer.PositionNormal { Position = outerLowerPts[i], Normal = parallels[i] }); edgeVertices.Add(new VertexBuffer.PositionNormal { Position = outerUpperPts[i + 1], Normal = parallels[i + 1] }); edgeVertices.Add(new VertexBuffer.PositionNormal { Position = outerLowerPts[i + 1], Normal = parallels[i + 1] }); // Inner edge edgeVertices.Add(new VertexBuffer.PositionNormal { Position = innerLowerPts[i], Normal = -parallels[i] }); edgeVertices.Add(new VertexBuffer.PositionNormal { Position = innerUpperPts[i + 1], Normal = -parallels[i + 1] }); edgeVertices.Add(new VertexBuffer.PositionNormal { Position = innerUpperPts[i], Normal = -parallels[i] }); edgeVertices.Add(new VertexBuffer.PositionNormal { Position = innerLowerPts[i], Normal = -parallels[i] }); edgeVertices.Add(new VertexBuffer.PositionNormal { Position = innerLowerPts[i + 1], Normal = -parallels[i + 1] }); edgeVertices.Add(new VertexBuffer.PositionNormal { Position = innerUpperPts[i + 1], Normal = -parallels[i + 1] }); } ``` The six vertices for the inner edge were simply copied and pasted from those for the outer edge, and modified in three ways: * The word `inner` was changed to `outer`. * The `Normal` was made a negative of the value because a perpendicular to the surface is in the opposite direction. * Two vertices in each triangle were swapped so the vertices would be clockwise when viewed from the other direction. The following `VertexBuffer` is defined the same as the ones you’ve already seen except that the `Shadowed` property is set. This relates to how the vertices are stored in computer memory: ```csharp VertexBuffer edgeBuffer = new VertexBuffer(Application.CurrentContext, false) { Shadowed = true }; edgeBuffer.SetSize((uint)edgeVertices.Count, ElementMask.Position | ElementMask.Normal, false); edgeBuffer.SetData(edgeVertices.ToArray()); ``` The `Geometry` object is calculated similarly to those you’ve already seen but now the first argument to `SetDrawRange` is `PrimitiveType.TriangleList`. This means that every group of three consecutive vertices defines a triangle: ```csharp Geometry edgeGeometry = new Geometry(); edgeGeometry.SetVertexBuffer(0, edgeBuffer); edgeGeometry.SetDrawRange(PrimitiveType.TriangleList, 0, 0, 0, (uint)edgeVertices.Count, true); ``` The `Model` is then calculated as you’ve already seen: ```csharp Model edgeModel = new Model(); edgeModel.NumGeometries = 1; edgeModel.SetGeometry(0, 0, edgeGeometry); edgeModel.BoundingBox = new BoundingBox(new Vector3(-10, -10, -10), new Vector3(10, 10, 10)); ``` Finally, a new `Node` is added that references the model and sets a material: ```csharp mainNode.RemoveChild(mainNode.GetChild("edgeNode")); Node edgeNode = mainNode.CreateChild("edgeNode"); StaticModel edge = edgeNode.CreateComponent(); edge.Model = edgeModel; edge.SetMaterial(Material.FromColor(Color.Gray)); ``` This is a simpler material than the one used for the lines, and is simply the color gray. Nevertheless, when you execute this code block, you’ll see different shades of gray in various areas of the inner and outer edges. This is the effect of the normals. Even with a relatively small value for `DIVISIONS`, the surface still looks curved as a result of the interpolation of the shading over the surface of each triangle. The edges are only visible from one direction. This is the result of the clockwise ordering of the vertices. ## The Track Surface The top and bottom of the triangles defining the surface of track can be calculated similarly to the edges, but to make it look realistic, the `Material` object can be based on a bitmap that resembles a little stretch of road: ![](Data/Textures/RoadSurface.png) This is a file named **RoadSurface.png**. It is stored in the **Textures** subdirectory of **Data**, which was the directory specified in the `ApplicationOptions` constructor when the `SimpleApplication` object was first created at the beginning of this Workbook. Using a different `Material` for the top and bottom surfaces of the road requires a separate `Node` object from that used for the inner and outer edges. Also, the `VertexBuffer.PositionNormal` structure is no longer adequate for storing the vertices. Each vertex must also be associated with a *texture coordinate* of type `Vector2`. The texture coordinate indicates what part of the bitmap corresponds with that vertex. A triangular area of the bitmap defined by the texture coordinates is then interpolated over the surface of each triangle. Texture coordinates are relative to the bitmap image itself: ![Texture Coordinates](Images/TextureCoordinates.svg "Texture Coordinates") However, this particular bitmap is wider than it needs to be. All the pixel columns in this image are identical. For purposes of covering the top and bottom of the road, the bitmap really only needs to be one pixel wide. This implies that a texture coordinate of (0, 0) can correspond to vertices at the outer edge, while a texture coordinate of (0, 1) can be specified for the inner edge. To accomodate texture coordinates, the following code uses the `VertexBuffer.PositionNormalColorTexcoord` structure. This structure defines additional fields named `Color` (which is not used here) and `TexCoord` of type `Vector2`. The normals are vectors perpendicular to the surface, which are values from the `perpendiculars` collection: ```csharp var surfaceVertices = new List(); for (int i = 0; i < DIVISIONS; i++) { // Upper surface surfaceVertices.Add(new VertexBuffer.PositionNormalColorTexcoord { Position = outerUpperPts[i], Normal = perpendiculars[i], TexCoord = new Vector2(0, 0) }); surfaceVertices.Add(new VertexBuffer.PositionNormalColorTexcoord { Position = innerUpperPts[i], Normal = perpendiculars[i], TexCoord = new Vector2(0, 1) }); surfaceVertices.Add(new VertexBuffer.PositionNormalColorTexcoord { Position = innerUpperPts[i + 1], Normal = perpendiculars[i + 1], TexCoord = new Vector2(0, 1) }); surfaceVertices.Add(new VertexBuffer.PositionNormalColorTexcoord { Position = outerUpperPts[i], Normal = perpendiculars[i], TexCoord = new Vector2(0, 0) }); surfaceVertices.Add(new VertexBuffer.PositionNormalColorTexcoord { Position = innerUpperPts[i + 1], Normal = perpendiculars[i + 1], TexCoord = new Vector2(0, 1) }); surfaceVertices.Add(new VertexBuffer.PositionNormalColorTexcoord { Position = outerUpperPts[i + 1], Normal = perpendiculars[i + 1], TexCoord = new Vector2(0, 0) }); // Lower surface surfaceVertices.Add(new VertexBuffer.PositionNormalColorTexcoord { Position = outerLowerPts[i], Normal = -perpendiculars[i], TexCoord = new Vector2(0, 0) }); surfaceVertices.Add(new VertexBuffer.PositionNormalColorTexcoord { Position = innerLowerPts[i + 1], Normal = -perpendiculars[i + 1], TexCoord = new Vector2(0, 1) }); surfaceVertices.Add(new VertexBuffer.PositionNormalColorTexcoord { Position = innerLowerPts[i], Normal = -perpendiculars[i], TexCoord = new Vector2(0, 1) }); surfaceVertices.Add(new VertexBuffer.PositionNormalColorTexcoord { Position = outerLowerPts[i], Normal = -perpendiculars[i], TexCoord = new Vector2(0, 0) }); surfaceVertices.Add(new VertexBuffer.PositionNormalColorTexcoord { Position = outerLowerPts[i + 1], Normal = -perpendiculars[i + 1], TexCoord = new Vector2(0, 0) }); surfaceVertices.Add(new VertexBuffer.PositionNormalColorTexcoord { Position = innerLowerPts[i + 1], Normal = -perpendiculars[i + 1], TexCoord = new Vector2(0, 1) }); } ``` The six vertices for the two triangles of the upper surface were simply copied and pasted for the lower surface. In the collection names, `Upper` was changed to `Lower`, the normals were made negative, and two vertices in each triangle were swapped. The size of the `VertexBuffer` object now needs to indicate that the vertices also contain specifications for color (even though it’s not used) and a texture coordinate: ```csharp VertexBuffer surfaceBuffer = new VertexBuffer(Application.CurrentContext, false) { Shadowed = true }; surfaceBuffer.SetSize((uint)surfaceVertices.Count, ElementMask.Position | ElementMask.Normal | ElementMask.Color | ElementMask.TexCoord1, false); surfaceBuffer.SetData(surfaceVertices.ToArray()); ``` The `Geometry` object is specified the same as for the edges: ```csharp Geometry surfaceGeometry = new Geometry(); surfaceGeometry.SetVertexBuffer(0, surfaceBuffer); surfaceGeometry.SetDrawRange(PrimitiveType.TriangleList, 0, 0, 0, (uint)surfaceVertices.Count, true); ``` The `Model` is also specified in the same way: ```csharp Model surfaceModel = new Model(); surfaceModel.NumGeometries = 1; surfaceModel.SetGeometry(0, 0, surfaceGeometry); surfaceModel.BoundingBox = new BoundingBox(new Vector3(-10, -10, -10), new Vector3(10, 10, 10)); ``` The `Node` object, however, needs a different type of material. This is simply loaded from the external bitmap using the static `Material.FromImage` method: ```csharp mainNode.RemoveChild(mainNode.GetChild("surfaceNode")); Node surfaceNode = mainNode.CreateChild("surfaceNode"); StaticModel surface = surfaceNode.CreateComponent(); surface.Model = surfaceModel; surface.SetMaterial(Material.FromImage("Textures/RoadSurface.png")); ``` After this code block is executed, the entire road is complete. ## Remove the Scaffolding Look closely, and you can see little lines bleeding through the edges. At his point, the scaffolding that helped visualize the surfaces can be removed: ```csharp mainNode.RemoveChild(mainNode.GetChild("circleNode")); mainNode.RemoveChild(mainNode.GetChild("widthNode")); mainNode.RemoveChild(mainNode.GetChild("depthNode")); ``` A close look also reveals that the yellow dividing line is a little erratic. This results from some distortion in the interpolation of the bitmap over the curved surface of the road. It could probably be fixed by doubling the number of triangles, and having triangle sides coorespond to the dividing line. ## Model Cars As you’ve seen, you can algorithmically create entire 3D objects within a UrhoSharp program. But for more complex objects such as cars, it makes much more sense to create a model using a 3D design tool, and then import the model into your scene. Or, you can download a model that someone else has already created. There are a number of file formats for 3D interchange developed throughout the years, and a number of web sites exist with downloadable 3D models of various formats. Although UrhoSharp can’t directly import them, a command-line tool exists called **[Asset Importer](https://urho3d.github.io/documentation/1.4/_tools.html "Asset Importer")** that can convert many popular 3D formats into a UrhoSharp’s native .MDL (“model”) format. One way to get **Asset Importer** is to first clone the Xamarin GitHub repository for UrhoSharp, which is simply named **[urho](https://github.com/xamarin/urho "UrhoSharp repo")**. If you don’t have the [CMake](https://cmake.org/ "CMake") utility, install it. In the **Urho3D/Source** directory of the **urho** repository that you’ve cloned are a number of .BAT (Windows batch) and .SH (Bash shell script) files. These files build an entire directory structure for Urho3D development. For example, if you’re running Windows and you use Visual Studio 2015, run the **cmake\_vs2015.bat** file and specify a destination directory, for example: **cmake\_vs2015 c:/MyUrho3D** When it completes, you’ll find a **Urho3D.sln** file in the directory you specified. Load that into Visual Studio 2015. One of the projects is named **AssetImporter**. After you build that project, **AssetImporter.exe** will be in the **bin/tool** subdirectory. The models used in this Workbook are from the Microsoft website [Remix 3D](https://www.remix3d.com/ "Remix 3D"). This website is a curated collection of 3D models that are intended to be used in conjunction with the **Paint 3D** and **3D Builder** applications included in the Windows 10 Creators Update. You can freely download, use, and modify these files. The contents of the **3D Objects** folder on the Windows 10 hard drive also contains a collection of models with filename extensions .3MF, which is the 3D Manufacturing Format. These are actually ZIP package files. If you rename the .3MF extension to .ZIP, you can examine the contents, which consists of a large XML file describing 3D geometries and .PNG files for textures. For this workbook, **Paint 3D** was used to download a model identified as [Shift Race Blue Car](https://www.remix3d.com/details/G009SX0M5G9T "Shift Race Blue Car") and export it in the .3MF format. **3D Builder** was then used to load this model and save it to the .OBJ (Wavefront Object) format with the name **BlueRacer.obj**. **AssetImporter** was then run with the following arguments: **AssetImporter node BlueRacer.obj node.xml** The **node** command is one of several **AssetImporter** commands that specify what files **AssetImporter** exports. The **node** command causes the utility to output an XML file along with three folders: **Materials**, **Models**, and **Textures**. The **node.xml** file is a description of a tree of nodes that references files in the **Materials** and **Models** folders. The **Materials** folder contains XML descriptions of materials that reference bitmap files in the **Textures** folder. The **Models** folder contains binary .MDL files in the Urho3D format. The **node.xml** file and these folders were then copied into a **BlueRacer** subdirectory of the **Data** directory for this Workbook. The **node.xml** file and all the XML files in the **Materials** folder were edited and modified so that references to filenames in the **Models**, **Materials**, and **Textures** folders were changed to **BlueRacer/Models**, **BlueRacer/Materials**, and **BlueRacer/Textures**. With that preliminary work, it then becomes fairly easy to use the `LoadXml` method defined by `Node` to load in the **node.xml** file, and in the process bring in all the models, materials, and textures associated with that node. The following code creates three nodes: The first is a child of `mainNode` named `car1Node`, the second is a child of `car1Node` named `car1ChildNode`, and the third is a child of `car1ChildNode` named `car1DefinitionNode`, which is the node loaded from the XML file: ```csharp mainNode.RemoveChild(mainNode.GetChild("car1Node")); Node car1Node = mainNode.CreateChild("car1Node"); Node car1ChildNode = car1Node.CreateChild(); Node car1DefinitionNode = car1ChildNode.CreateChild(); car1DefinitionNode.LoadXml("BlueRacer/node.xml"); ``` Creating three nodes rather than just one eases the application of different transforms to these nodes. If the transforms are applied to each node separately, the transforms are independent of each other, but they are compounded when the car is rendered. The car will not be visible when that code block is executed. The models use coordinates that are very much larger than the coordinates implied by the road. The following position, scaling, and rotation factors were empirically determined to align the car so that the bottom of the tires sit on the XY plane, and the (0, 0, 0) point of the car is approximately in the center between the bottom of those four tires: ```csharp car1DefinitionNode.Position = new Vector3(0.8f, 4.112f, -1.344f); car1DefinitionNode.SetScale(0.004f); car1DefinitionNode.Rotation = Quaternion.FromAxisAngle(Vector3.UnitZ, -11.5f); ``` Those are the only adjustments applied to `car1DefinitionNode`. (These adjustments were not shown in the webinar. Instead, the parent node in the **node.xml** file was modified.) The car is now visible but it is still ten times too large. It can be reduced in size commensurate with the racetrack by applying a scaling factor to `car1ChildNode`: ```csharp car1ChildNode.SetScale(0.1f); ``` This is the only adjustment made to `car1ChildNode`. All other transforms to position the car on the road will be applied to `car1Node`. The second car is described in the Remix 3D web site as [Rolls Royce Phantom Car](https://www.remix3d.com/details/G009SX0LG9PZ "Rolls Royce Phantom Car"). The model was downloaded and converted as described earlier and stored in the **RedRolls** subdirectory of **Data**. The following code loads in the node: ```csharp mainNode.RemoveChild(mainNode.GetChild("car2Node")); Node car2Node = mainNode.CreateChild("car2Node"); Node car2ChildNode = car2Node.CreateChild(); Node car2DefinitionNode = car2ChildNode.CreateChild(); car2DefinitionNode.LoadXml("RedRolls/node.xml"); ``` These position, scaling, and rotation adjustments align the model as described earlier: ```csharp car2DefinitionNode.Position = new Vector3(0.4f, 3.04f, -1.16f); car2DefinitionNode.SetScale(0.004f); car2DefinitionNode.Rotation = Quaternion.FromAxisAngle(Vector3.UnitZ, -10.5f); ``` The Blue Racer faced towards the right; this one faces toward the left. Finally, the node is additionally scaled to make it a proper size for driving on the track: ```csharp car2ChildNode.SetScale(0.1f); ``` Now that the two cars are the proper size, they must be animated, and in the process tilted and rotated to follow the course of the Möbius strip. ## Drivers, Start Your Engines The `GetCarPosition` method shown below calculates the position of a car on the road and the orientation of the road at that point. The parameter `t` can range from 0 to 1, and the two Boolean parameters specify whether the car is on the top or bottom of the road, and the outer or inner lane. On a Möbius strip, a car that is on the top and outer lane during one revolution around the track will move to the bottom and inner lane during the next. The method returns a 3D coordinate on the surface of the road corresponding to the position of the car. In addition, three `out` parameters supply three vectors that indicate the `forward` direction of the road (based on increasing index numbers), a vector at right angles to `forward` that points to the `outer` part of the road, and a vector that is `perpendicular` to the road. These three vectors are orthogonal (at right angles to each other), so it is only necessary to calculate two of them, and the third can be derived from the cross product. At the beginning of the method, the `t` parameter is converted to a floating point `index`, which is then used to derive integer values of `i1` and `i2`, which are the integer indices immediately below and above `index`. The `Vector3` values are calculated by interpolating between various points and vectors: ```csharp Vector3 GetCarPosition(float t, bool isUpper, bool isOuter, out Vector3 forward, out Vector3 outer, out Vector3 perpendicular) { float index = t * DIVISIONS; int i1 = (int)index; int i2 = i1 + 1; IList outerPts = isUpper ? outerUpperPts : outerLowerPts; IList innerPts = isUpper ? innerUpperPts : innerLowerPts; Vector3 outerPt = (i2 - index) * outerPts[i1] + (index - i1) * outerPts[i2]; Vector3 innerPt = (i2 - index) * innerPts[i1] + (index - i1) * innerPts[i2]; outer = outerPt - innerPt; outer.Normalize(); perpendicular = (i2 - index) * perpendiculars[i1] + (index - i1) * perpendiculars[i2]; perpendicular.Normalize(); forward = Vector3.Cross(outer, perpendicular); return (isOuter ? 0.75f : 0.25f) * outerPt + (isOuter ? 0.25f : 0.75f) * innerPt; } ``` These four `Vector3` values describe a position and orientation of a car on the road. ## Matrix Transforms For jobs such as positioning and rotating a car based on `Vector3` values, the `Node` class defines a `SetTransform` method. The `Matrix3x4` argument has the capability to translate, scale, rotate, and even skew the node and all its children. (However, no perspective or taper transforms are possible.) The `Matrix3x4` structure defines 12 fields named `m` followed by the numeric zero-based row and column number. You can visualize these fields as the cells of the 3×4 matrix. ![Matrix 3x4](Images/Matrix3x4.svg "Matrix 3x4") Internal to UrhoSharp, this matrix is used to transform 3D coordinates of (x, y, z) to coordinates of (x’, y’, z’) using standard matrix multiplication. The (x, y, z) coordinate is first represented as a 4×1 column vector with a 1 in the fourth position: ![Matrix 4x1](Images/Matrix4x1.svg "Matrix 4x1") Conceptually, this is a position in 4D space with the fourth coordinate fixed at 1. The use of 4D coordinates in 3D graphics is analogous to the use of 3D coordinates in 2D graphics. The extra dimension allows matrix transforms to encapsulate translation and (in the more general case) perspective. The 3×4 matrix is multiplied by that 4×1 column vector: ![Matrix Multiplicaton General](Images/MatrixMultiplicationGeneral.svg "Matrix Multiplication General") The result is a 3×1 column vector that represents the transformed point (x’, y’, z’). The transform formulas are: x’ = m00·x + m01·y + m02·z + m03 y’ = m10·x + m11·y + m12·z + m13 z’ = m20·x + m21·y + m22·z + m23 > ⚠️ You might be accustomed to matrix transforms in which the coordinate is represented as a row vector rather than a column vector, which is then positioned to the left of the transform matrix for the multiplication. The convention of column vectors used within UrhoSharp is conceptually the same, except that the rows and columns of the transform matrix are transposed. > > One advantage of the UrhoSharp notation is that it’s easier to show the full result of the multiplication as a 3×1 column vector rather than a row vector: > > ![Matrix Multiplicaton General Full](Images/MatrixMultiplicationGeneralFull.svg "Matrix Multiplication General Full") The four columns of the matrix perform different tasks. The fourth column functions as translation factors that indicate where the (0, 0, 0) point is transformed. This is evident when the matrix is multiplied by the column vector represeting the point (0, 0, 0): ![Matrix Multiplication Translation](Images/MatrixMultiplicationTranslation.svg "Matrix Multiplication Translation") The first three columns of the matrix perform scaling, rotation, and skewing, and can be analyzed independently as a 3×3 matrix: ![Matrix 3x3](Images/Matrix3x3.svg "Matrix 3x3") Because no translation is involved, the matrix multiplication simply involves a 3×1 column vector, and the result is also a 3×1 column vector: ![Matrix 3x3 Multiplication General](Images/Matrix3x3MultiplicationGeneral.svg "Matrix 3x3 Multiplication General") ## The Rotation Matrix It is convenient to think of the three columns of the 3×3 transform matrix as vectors. If these three column vectors are * mutually orthogonal (that is, at right angles to each other); and * normalized (that is, have a length of 1) then the three vectors are called *orthonormal*, and the 3×3 matrix is known as a *rotation matrix*. It performs rotation only, and not scaling or skewing. Moreover, this rotation is performed in a very predicatable way that is ideal for orienting the cars along the road. To see this, apply the matrix transform to the vector (1, 0, 0), which is the vector that points in the direction of the positive X axis: ![Matrix Multiplication Rotation X](Images/MatrixMultiplicationRotationX.svg "Matrix Multiplication Rotation X") The result is the first column of the matrix. Similarly, apply the transform to the (0, 1, 0) vector pointing in the direction of the positive Y axis: ![Matrix Multiplication Rotation Y](Images/MatrixMultiplicationRotationY.svg "Matrix Multiplication Rotation X") And for the sake of completion, apply it to the positive Z axis (0, 0, 1): ![Matrix Multiplication Rotation Z](Images/MatrixMultiplicationRotationZ.svg "Matrix Multiplication Rotation Z") Keep in mind that to restrict the matrix to rotation, the three columns must be mutually orthogonal and normalized. If they are not normalized, then scaling will result as well as rotation. If they are not mutually orthogonal, then skewing will result, and right angles won’t be preserved. Here is the original 3×4 transform matrix of type  `Matrix3x4` that is used with the `SetTransform` method of `Node`: ![Matrix 3x4](Images/Matrix3x4.svg "Matrix 3x4") This matrix can be assembled to perform rotation and translation using the following rules: * Set the first column to the vector to which (1, 0, 0) is transformed; * Set the second column to the vector to which (0, 1, 0) is transformed; * Set the third column is the vector to which (0, 0, 1) is transformed; and * Set the fourth column to the point to which (0, 0, 0) is translated. Constructing that `Matrix3x4` value from four `Vector3` values is the job of the following method: ```csharp Matrix3x4 MakeMatrix(Vector3 xRotate, Vector3 yRotate, Vector3 zRotate, Vector3 translate) { return new Matrix3x4(xRotate.X, yRotate.X, zRotate.X, translate.X, xRotate.Y, yRotate.Y, zRotate.Y, translate.Y, xRotate.Z, yRotate.Z, zRotate.Z, translate.Z); } ``` ## Applying the Matrix The event handler named `UpdateCarPosition` show below will be attached to the `Update` event of the `SimpleApplication` object created at the begining of this Workbook to animate the cars on the road. The `Update` handler is called frequently as the application runs. The event argument has a property named `TimeStep` that is the time in seconds since the last time the handler was called. For this reason, generally a variable external to the method is maintained. It is traditionally named `t` for “time.” Also defined is a constant indicating that a complete revolution around the track will be 5 seconds long: ```csharp float t = 0; const float RevolutionsPerSecond = 0.20f; ``` Within the method, `t` is increased by the product of `TimeStep` and `RevolutionsPerSecond`. Normally the modulo operator would strip the integer part so that `t` ranges from 0 to 1. But for the Möbius strip, the car needs to go around the track twice during one complete cycle, so `t` is made to range from 0 to 2. In the body of the method, this `t` is adjusted in various ways for the call to `GetCarPosition`, so `t` only ranges from 0 to 1 within that method. For the first car, when `t` is less than 1, the car is on the outside lane on the upper side, so both Boolean arguments to `GetCarPosition` are set to `true`. On return from `GetCarPosition`, * the `forward` vector is parallel to the road pointing in the direction of increasing indices; * the `outer` vector points to the outside of the road; and * the `perpendicular` vector is perpendicular to the road. In its unrotated state, the X axis of the Blue Racer points right towards the front of the car. That must be rotated to point in the direction of the `forward` vector, so `forward` is the first argument to `MakeMatrix`. The Y axis of the Blue Racer points up through the driver’s side door. That must be rotated to point to the inside of the track, so the second argument to `MakeMatrix` is `–outer`. The Z axis of the Blue Racer points through the bottom of the car. That must be rotated to point downwards from the road, so the third argument to `MakeMatrix` is `–perpendicular`. The last argument to `MakeMatrix` is the `position` value. This indicates the point to which the (0, 0, 0) point of the car is translated. ```csharp void UpdateCarPosition(UpdateEventArgs args) { t += args.TimeStep * RevolutionsPerSecond; t %= 2; Vector3 forward; Vector3 outer; Vector3 perpendicular; if (t < 1) { Vector3 position = GetCarPosition(t, true, true, out forward, out outer, out perpendicular); Matrix3x4 matx = MakeMatrix(forward, -outer, -perpendicular, position); car1Node.SetTransform(matx); position = GetCarPosition(1 - t, false, true, out forward, out outer, out perpendicular); matx = MakeMatrix(forward, outer, perpendicular, position); car2Node.SetTransform(matx); } else { Vector3 position = GetCarPosition(t - 1, false, false, out forward, out outer, out perpendicular); Matrix3x4 matx = MakeMatrix(forward, outer, perpendicular, position); car1Node.SetTransform(matx); position = GetCarPosition(2 - t, true, false, out forward, out outer, out perpendicular); matx = MakeMatrix(forward, -outer, -perpendicular, position); car2Node.SetTransform(matx); } } ``` When `t` ranges from 1 to 2, the `else` clause is executed. The first car is now on the inside bottom of the track, so the two Boolean arguments become `false`, and the signs of the `outer` and `perpendicular` arguments to `MakeMatrix` are positive rather than negative. The second car is similar, except that its original orientation is a little different (it faces left rather than right), and it travels in the opposite direction as the first car, beginning on the bottom of the track. ## Two Animations Now all that’s necessary is to attach the `UpdateCarPosition` handler to the `Update` event of the `SimpleApplication` object. However, code blocks in Workbooks can be re-executed, and it’s undesirable that the handler be attached multiple times. Also, the handler can’t be detached using normal C# syntax because the handler itself might be recreated. For this reason, .NET reflection code is used to detach all handlers from the `Update` event: ```csharp using System.Reflection; FieldInfo field = typeof(Application).GetField("Update", BindingFlags.Instance | BindingFlags.NonPublic); field.SetValue(app, null); app.Update += UpdateCarPosition; ``` Finally, `mainNode` itself is animated. The `RemoveAllActions` method first clears all animations from the node, and then `RunActions` attaches an animation that runs forever and rotates the node around the Y axis by 15 degrees every second: ```csharp using Urho.Actions; mainNode.RemoveAllActions(); mainNode.RunActions(new RepeatForever(new RotateBy (1f, 0, 15, 0))); ``` This animation affects all the subnodes of `mainNode` as well, which encompasses all the visual objects created in the Workbook. As the Möbius strip rotates, it seems to morph in shape. The cars drive by each other twice in each double cycle, and pass each other on opposite sides of the road as well. ================================================ FILE: graphics/urhosharp/physics/physics.workbook/index.workbook ================================================ --- id: 0cee522c-9c60-4860-9681-50124c220680 uti: com.xamarin.workbook title: "UrhoSharp: Physics" platforms: - Console packages: - id: UrhoSharp version: 1.5.22 --- # Physics UrhoSharp is a powerful 3D game engine for Xamarin and .NET developers. It is similar in spirit to Apple’s SceneKit and SpriteKit and includes physics, navigation, networking, and much more...while still being cross-platform. ```csharp #r "Urho" using Urho; using Urho.Actions; using Urho.Shapes; using Urho.Physics; ``` ```csharp var app = SimpleApplication.Show ( new ApplicationOptions ("Data") { Width = 700, Height = 700 }); var rootNode = app.Scene.CreateChild(); ``` We have created a window containing a `SimpleApplication`. Let’s add the Trash Can model (located in Data directory and was created in Blender): ```csharp rootNode.RemoveAllChildren(); var trashcanNode = rootNode.CreateChild(); var trashcan = trashcanNode.CreateComponent(); trashcan.Model = app.ResourceCache.GetModel("bucket.mdl"); trashcan.SetMaterial(Material.FromColor( new Color(0.4f, 0.6f, 0.2f))); trashcanNode.Position = new Vector3(0, -2, 7); trashcanNode.SetScale(0.4f); ``` Apply RigidBody and CollisionShape to handle physics. ```csharp trashcanNode.CreateComponent(); var shape = trashcanNode.CreateComponent(); shape.SetTriangleMesh(trashcan.Model, 0, Vector3.One, Vector3.Zero, Quaternion.Identity); ``` Define ThrowBall method ```csharp static void ThrowBall(Node container, Vector3 linearVelocity) { var ballNode = container.CreateChild(); ballNode.SetScale(0.5f); var ball = ballNode.CreateComponent(); ball.Color = new Color(Randoms.Next(), Randoms.Next(), Randoms.Next()); var rigidBody = ballNode.CreateComponent(); rigidBody.Mass = 1f; rigidBody.RollingFriction = 0.1f; rigidBody.Friction = 0.1f; var ballShape = ballNode.CreateComponent(); ballShape.SetSphere(1, Vector3.Zero, Quaternion.Identity); rigidBody.SetLinearVelocity(linearVelocity); } ``` Throw a ball in a random direction with a random velocity ```csharp ThrowBall(rootNode, linearVelocity: new Vector3(0, 0.3f, 1f) * 8f); ``` Define a plane with RigidBody and CollisionShape so balls won't fall into abyss ```csharp var planeNode = rootNode.CreateChild(); planeNode.Scale = new Vector3(100, 1, 100); var plane = planeNode.CreateComponent(); plane.Model = CoreAssets.Models.Plane; plane.SetMaterial(Material.FromColor( new Color(0.95f, 0.95f, 0.95f), true)); planeNode.Position = new Vector3(0, -2, 0); var planeRb = planeNode.CreateComponent(); planeRb.RollingFriction = 0.2f; var planeShape = planeNode.CreateComponent(); planeShape.SetStaticPlane( new Vector3(0, 0, 0), Quaternion.Identity); ``` ```csharp ThrowBall(rootNode, linearVelocity: new Vector3(0, 0.3f, 1f) * 8f); ``` ```csharp /*for (int i = 0; i < 10; i++) { ThrowBall(rootNode, linearVelocity: new Vector3( Randoms.Next(-0.05f, 0.05f), Randoms.Next(0.2f, 0.4f), Randoms.Next(0.8f, 1.2f)) * Randoms.Next(8, 10)); await app.RootNode.RunActionsAsync(new DelayTime(0.5f)); }*/ ``` ================================================ FILE: graphics/urhosharp/planetearth/planetearth.workbook/Data/Materials/SatNoTexture.xml ================================================ ================================================ FILE: graphics/urhosharp/planetearth/planetearth.workbook/Data/RenderPaths/Outline.xml ================================================ ================================================ FILE: graphics/urhosharp/planetearth/planetearth.workbook/Data/Shaders/GLSL/Outline.glsl ================================================ #include "Uniforms.glsl" #include "Samplers.glsl" #include "Transform.glsl" #include "ScreenPos.glsl" varying vec2 vTexCoord; varying vec2 vScreenPos; #ifdef COMPILEPS uniform vec4 cOutlineColor; uniform vec2 cOutlineBlurredMaskHInvSize; #endif void VS() { mat4 modelMatrix = iModelMatrix; vec3 worldPos = GetWorldPos(modelMatrix); gl_Position = GetClipPos(worldPos); vTexCoord = GetQuadTexCoord(gl_Position); vScreenPos = GetScreenPosPreDiv(gl_Position); } void PS() { #ifdef MASK gl_FragColor = vec4(cOutlineColor.rgb, 1.0); #endif #ifdef BLURH vec4 rgba = texture2D(sDiffMap, vTexCoord + vec2(0.0, 0.0) * cOutlineBlurredMaskHInvSize) + texture2D(sDiffMap, vTexCoord + vec2(-1.0, 0.0) * cOutlineBlurredMaskHInvSize) + texture2D(sDiffMap, vTexCoord + vec2(1.0, 0.0) * cOutlineBlurredMaskHInvSize) + texture2D(sDiffMap, vTexCoord + vec2(-2.0, 0.0) * cOutlineBlurredMaskHInvSize) + texture2D(sDiffMap, vTexCoord + vec2(2.0, 0.0) * cOutlineBlurredMaskHInvSize); gl_FragColor = rgba * 0.2; #endif #ifdef BLURV vec4 rgba = texture2D(sDiffMap, vTexCoord + vec2(0.0, 0.0) * cOutlineBlurredMaskHInvSize) + texture2D(sDiffMap, vTexCoord + vec2(0.0, -1.0) * cOutlineBlurredMaskHInvSize) + texture2D(sDiffMap, vTexCoord + vec2(0.0, 1.0) * cOutlineBlurredMaskHInvSize) + texture2D(sDiffMap, vTexCoord + vec2(0.0, -2.0) * cOutlineBlurredMaskHInvSize) + texture2D(sDiffMap, vTexCoord + vec2(0.0, 2.0) * cOutlineBlurredMaskHInvSize); gl_FragColor = rgba * 0.2; #endif #ifdef OUTPUT vec4 blurredMask = texture2D(sDiffMap, vTexCoord); vec4 mask = texture2D(sNormalMap, vTexCoord); vec4 viewport = texture2D(sSpecMap, vTexCoord); blurredMask = clamp(blurredMask - mask.a, 0.0, 1.0); blurredMask *= 3.0; gl_FragColor = viewport * (1.0 - blurredMask.a) + blurredMask; #endif } ================================================ FILE: graphics/urhosharp/planetearth/planetearth.workbook/Data/Techniques/NoTextureOutline.xml ================================================ ================================================ FILE: graphics/urhosharp/planetearth/planetearth.workbook/Data/Techniques/TextureOutline.xml ================================================ ================================================ FILE: graphics/urhosharp/planetearth/planetearth.workbook/Data/Textures/License.txt ================================================ -------------------------- Assets under CC 4.0 License -------------------------- Earth_Clouds.jpg Moon.jpg Earth_SpecularMap.png Earth_Clouds.jpg website: http://www.solarsystemscope.com/textures/ license: https://creativecommons.org/licenses/by/4.0/ ================================================ FILE: graphics/urhosharp/planetearth/planetearth.workbook/index.workbook ================================================ --- id: 72272456-553a-465a-be48-20b922321c19 uti: com.xamarin.workbook title: "UrhoSharp: Planet Earth in C#" platforms: - Console packages: - id: UrhoSharp version: 1.5.22 --- # UrhoSharp: Planet Earth in C# [UrhoSharp](https://developer.xamarin.com/guides/cross-platform/urho/) is a powerful 3D game engine for Xamarin and .NET developers. Start by loading URho into the workbook and import some namespaces that we’ll want to consume. ```csharp #r "Urho" using Urho; using Urho.Actions; using Urho.Shapes; ``` ```csharp var app = SimpleApplication.Show ( new ApplicationOptions ("Data") { Width = 600, Height = 600, TouchEmulation = true }); ``` We have created a window containing a `ApplicationOptions`. Let’s add a new `Node` to the scene, representing the Earth. `Node`s contain `Component`s that dictate what is rendered. We’ll cheat a bit and use a `Sphere` for the Earth. ```csharp var earthNode = app.RootNode.CreateChild (name: "Earth"); var earth = earthNode.CreateComponent (); ``` ```csharp earth.Color = Color.Blue; ``` ```csharp earthNode.SetScale (4f); ``` ```csharp earth.SetMaterial (Material.FromImage ("Textures/earth.jpg")); ``` A scene can have multiple nodes. Let’s add some satellites, starting with the Moon. ```csharp Node moonNode = app.RootNode.CreateChild (name: "Moon"); moonNode.Position = new Vector3 (x: -3.0f, y: 0, z: 0); moonNode.SetScale (1f); var moon = moonNode.CreateComponent (); moon.CastShadows = false; moon.SetMaterial (Material.FromImage ("Textures/moon.jpg", normals: "Textures/Moon_NormalsMap.png")); ``` ```csharp app.RootNode.RunActions (new RepeatForever ( new RotateBy ( duration: 1f, deltaAngleX: 0, deltaAngleY: -15, deltaAngleZ: 0))); app.MoveCamera = true; ``` Override the render path to show custom Outline shader ```csharp static var random = new Random (); var effectRenderPath = app.Viewport.RenderPath.Clone (); effectRenderPath.Append (app.ResourceCache.GetXmlFile ("RenderPaths/Outline.xml")); app.Viewport.RenderPath = effectRenderPath; earthNode.Rotate (new Quaternion (x: 0, y: -73, z: 0), TransformSpace.Local); var satellitesNode = app.RootNode.CreateChild (); ``` We want to spawn thousands of satellites in Low Earth Orbit. Here’s a method to randomly distribute satellites as they are added. ```csharp Node AddSatellite (Node parent, float lat, float lon, Model model, float scale, bool outline = true) { //let's do some math: //convert lat and lon to XYZ: var height = 2.2 + random.NextDouble () / 3; var latrad = lat * Math.PI / 180; var lonrad = lon * Math.PI / 180; var x = -height * Math.Cos (latrad) * Math.Cos (lonrad); var y = height * Math.Sin (latrad); var z = height * Math.Cos (latrad) * Math.Sin (lonrad); var satNode = parent.CreateChild ("SatRoot"); var satModelNode = satNode.CreateChild ("SatModel"); var sat = satModelNode.CreateComponent (); sat.Model = model; if (outline) { //apply a custom outline shader var material = CoreAssets.Cache.GetMaterial ( "Materials/SatNoTexture.xml").Clone (""); material.SetShaderParameter ("OutlineColor", new Color ((float)random.NextDouble (), (float)random.NextDouble (), (float)random.NextDouble (), 0)); sat.SetMaterial (material); } satModelNode.SetScale (scale); satNode.Position = new Vector3 ((float)x, (float)y, (float)z); satNode.LookAt (new Vector3 (0, 0, 0), new Vector3 (0, 1, 0), TransformSpace.Parent); satNode.Rotate (new Quaternion (90, 0, 0), TransformSpace.Local); satNode.RunActions (new RepeatForever (new RotateBy (1f, 0f, 10f, 0f))); return satNode; } ``` According to NASA, there are ~3600 satellites in Low Earth Orbit. ```csharp satellitesNode.RemoveAllChildren(); for (int i = 0; i < 3600; i++) { AddSatellite(satellitesNode, lat: Randoms.NextNormal (-90, 90), lon: Randoms.Next (0, 360), model: CoreAssets.Models.Box, scale: 0.02f, outline: false); } ``` Spawn a big satellite over Orlando. ```csharp var orlandoLat = 28.538336f; var orlandoLon = -81.379234f; AddSatellite (satellitesNode, lat: orlandoLat, lon: orlandoLon, model: app.ResourceCache.GetModel ("Models/BigSatellite.mdl"), scale: 0.0005f); ``` Ta da! ### Event Handlers Spawn a few more big satellites. ```csharp for (int i = 0; i < 20; i++) { AddSatellite (satellitesNode, lat: Randoms.NextNormal (-90, 90), lon: Randoms.Next (0, 360), model: app.ResourceCache.GetModel ("Models/BigSatellite.mdl"), scale: 0.0005f); } ``` User interaction: click to increase satellite node size. ```csharp Node currentNode; app.Input.SetMouseVisible (true, false); app.Input.TouchEnd += e => { if (currentNode != null) { currentNode.RemoveAllActions (); currentNode.RunActions (new ScaleTo (0.7f, 0.0005f)); currentNode = null; } var cameraRay = app.Camera.GetScreenRay ( (float)e.X / app.Graphics.Width, (float)e.Y / app.Graphics.Height); var result = app.Octree.RaycastSingle (cameraRay, RayQueryLevel.Triangle, 100, DrawableFlags.Geometry); if (result != null) { var node = result.Value.Node; if (node.Name.StartsWith("Sat")) { currentNode = node; currentNode.RunActions (new EaseElasticOut ( new ScaleTo (0.7f, 0.0015f))); currentNode.RunActions (new RepeatForever ( new RotateBy (1f, 90f, 0f, 0f))); } } }; ``` A more complicated example of how to create complex Materials in code and set shaders’ parameters. ```csharp var advancedEarthMaterial = new Material(); advancedEarthMaterial.SetTechnique(0, CoreAssets.Techniques.DiffNormal, 0, 0); advancedEarthMaterial.SetTexture(TextureUnit.Diffuse, app.ResourceCache.GetTexture2D("Textures/Earth_Diff.jpg")); advancedEarthMaterial.SetTexture(TextureUnit.Normal, app.ResourceCache.GetTexture2D("Textures/Earth_NormalsMap.png")); earth.SetMaterial(advancedEarthMaterial); advancedEarthMaterial.SetShaderParameter(CoreAssets.ShaderParameters.MatDiffColor, new Color(0.8f, 0.9f, 1f, 1f)); ``` ```csharp earthNode.RemoveAllChildren(); var cloudsNode = earthNode.CreateChild(); cloudsNode.SetScale(1.03f); var clouds = cloudsNode.CreateComponent(); clouds.Model = CoreAssets.Models.Sphere; var cloudsMaterial = new Material(); cloudsMaterial.SetTechnique(0, CoreAssets.Techniques.DiffAddAlpha, 0, 0); cloudsMaterial.SetTexture(TextureUnit.Diffuse, app.ResourceCache.GetTexture2D("Textures/Earth_Clouds.jpg")); cloudsMaterial.SetShaderParameter(CoreAssets.ShaderParameters.MatDiffColor, new Color(1,1,1,0.6f)); clouds.SetMaterial(cloudsMaterial); cloudsNode.RunActions(new RepeatForever(new RotateBy(1f, 0, 7, 0))); ``` ================================================ FILE: ios/README.md ================================================ iOS Workbooks ============ * Getting Started * User Interface * Advanced ================================================ FILE: ios/getting-started/Learning-iOS.workbook ================================================ --- uti: com.xamarin.workbook platform: iOS packages: [] --- # Understanding your iOS Application ❗️To use this workbook follow through each section in sequence to learn how to build up a view heirarchy. Make sure to do the *Try it now* sections to reinforce your learning! ❗️ When you open an iOS application on your device, what you see is a number of components working together to give you the perception of one single View. In this guide we will interactively explore the make up of an iOS application, allowing you to get a deeper understanding of its functionality. ### The Window The most fundamental object of an iOS app and first thing your user will see is a window. You can think of this window as a shop front. There is one Window, or screen, that allows your user to view the app. You can add whatever you want to the window, but in most cases only one Main Window is used. To create a new Window, first declare a new instance of `UIWindow` and then make that window visible: ```csharp var window = new UIWindow(UIScreen.MainScreen.Bounds); window.MakeKeyAndVisible() ``` If you inspect the simulator now, you’ll notice a blank white screen. This is because there isn’t actually anything visible on the screen – you’ll have to add it. An iOS application uses a View Controller to manage all the views within it – it loads and disposes the views, it handles user interactions with the views, and it co-ordinates with other objects. There can be many View Controllers, of many types (eg. `TableViewController`), within one application, all of which work together. Start building your *View Heirarchy* by creating a single UIViewController: ```csharp var controller = new UIViewController() ``` As mentioned earlier that most applications have a single Window. Every Window has a single **Root View Controller**, and this is the first View Controller that your user will see and interact with. Set the recently created View Controller, to be window’s RootViewController: ```csharp window.RootViewController = controller ``` The RootViewController has been set, but if you look at the simulator it won’t look any different. Change the background color using the code below: ```csharp controller.View.BackgroundColor = UIColor.Magenta ``` You can’t set the color of the actual View Controller itself, it’s just an UI-less object that manages views. ###### Try it now! * See if you can change the color of the background to something different * Can you change it to an RGB value? *(Hint: Create a new instance of UIColor, assign Red, Blue, Green, and alpha nfloat values, and set the background to the new instance)* You should be starting to see how the View Heirarchy of iOS apps work. Having something to look at on the screen is nice, but usually users want to interact with their apps by navigating through them. To do this you can use a Navigation Controller. As suggested by the name, it manages the navigation of your application. A navigation controller is a UI-less controller that will manage a stack of however many View Controllers that you add to it. Add one to your app: ```csharp var navigationController = new UINavigationController(); ``` You should notice that nothing happens. This is because the RootViewController still thinks that controller is the first thing it should be showing us. Amend this to set the `navigationController`as the `RootViewController`: ```csharp window.RootViewController = navigationController ``` Next, use the existing View Controller (named *controller*) as the first View Controller in the navigationController’s stack. ###### Try it now * Pass the View Controller (controller) into the newly created instance of our navigation controller. You can pass this as an argument in the code above and press cmd \+ Enter to run the code. * ⚠️This step is important. If you don’t do this step, the rest of the code may not work correctly The View Controller’s properties can be changed to allow the app to be more user friendly. You can set the Navigation Item’s title to be anything you want. Update the string below to give the title a name that you think is suitable: ```csharp controller.NavigationItem.Title = "iOS is Cool" ``` ### Building the View Heirarchy Now, we have a ViewContoller which is the first ViewController in our Navigation Stack and we’ve set this as our RootViewController (this first thing that the user will see). Now, let’s allow our user to interact with our application by adding UI *controls* to our View. In any app that you create, user interaction is essential. To allow for this, user interface controls can be added to any View. Create a text box with the following code snippet. A `UITextField` can be used to gather text based input from the user: ```csharp var name = new UITextField{ Placeholder = "Enter Name", BorderStyle = UITextBorderStyle.RoundedRect, Frame = new CGRect(10, 80, controller.View.Bounds.Width -20, 31.0f)} ``` Notice that when creating a control in code, such as a `UITextField`, a `Frame`property is declared. This property defines the the location and size of the control. In iOS the 0,0 coordinate is in the upper left with \+ x to the right and \+ y down. This control then needs to be added to the ViewController’s view as a **subview**, so that it will display in your app: ```csharp controller.View.AddSubview(name) ``` Let’s add another few Text Fields and a button: ```csharp var email = new UITextField{ Placeholder = "Enter Email", BorderStyle = UITextBorderStyle.RoundedRect, Frame = new CGRect(10, 120, controller.View.Bounds.Width -20, 31.0f)}; var password = new UITextField{ Placeholder = "Enter Password", BorderStyle = UITextBorderStyle.RoundedRect, SecureTextEntry = true, Frame = new CGRect(10, 160, controller.View.Bounds.Width - 20, 31.0f)}; var enterButton = UIButton.FromType(UIButtonType.System); enterButton.Frame = new CGRect(10, 200, controller.View.Bounds.Width - 20, 31.0f); enterButton.SetTitle ("Submit", UIControlState.Normal); ``` #### Try it now: * Set the `KeyboardType`property of the email TextField to `EmailAddress` * Adjust the appearance of the Button. For example, you could try to change the background color of the button, or you could adjust the corner radius of its layer to make the corners rounded. Once they have been created, we have to add these controls to the view. We can add multiple subviews to the view hierarchy by using `AddSubviews` and passing in an array of UIViews that includes all our views: ```csharp controller.View.AddSubviews(new UIView[]{email, password, enterButton}) ``` At this point, the app has a simple (though passive) user interface that is displayed in a single ViewController. The next step is to add code to handle user input. This is covered in the UIButton workbook. ================================================ FILE: ios/getting-started/hello-ios-workbook.workbook ================================================ --- uti: com.xamarin.workbook platform: iOS --- # iOS ```csharp var label = new UIKit.UILabel(new CGRect(10,10,300,50)) { Text = "Hello, Workbooks", Font = UIFont.SystemFontOfSize(36) }; RootViewController.Add(label); ``` ================================================ FILE: ios/getting-started/meta.json ================================================ { "order":{ "hello-ios-workbook.workbook":"Hello, iOS", "Learning-iOS.workbook":"Learning iOS" } } ================================================ FILE: ios/meta.json ================================================ { "order":{ "getting-started":"Getting Started", "platform-features":"Platform Features", "user-interface":"User Interface" } } ================================================ FILE: ios/platform-features/auto-layout/programmatical-constraints.workbook ================================================ --- id: eb2f1f80-c574-4b2b-af0d-29fc97c1c5ef title: programmatical-constraints uti: com.xamarin.workbook platforms: - iOS --- ## Programmatically Creating Constraints The goal of this workbook is to explain **advanced auto layout** concepts by showing how to create constraints **programmatically**. > ⚠️ Whenever possible, we recommend you use the iOS designer to create your constraints because you can easily visualize, edit, manage and debug them. ```csharp var orangeLabel = new UILabel () { Text = "Orange", TextColor = UIColor.White, TextAlignment = UITextAlignment.Center, BackgroundColor = UIColor.Orange }; // This could be any parent view you add UI elements to. var rootView = RootViewController.View; rootView.AddSubview (orangeLabel); ``` ### Absolute coordinates Let’s position the `orangeLabel` at the top left corner manually first so we can see it. ```csharp orangeLabel.Frame = new CGRect (20, 20, 120, 50); ``` If we wanted to center this label in the middle of the screen we could, *technically*, do it using **absolute** x,y coordinates but this is **not** the most optimal, responsive and simple (will imply quite a bit of math) way to do it. ### Begin with Constaints `TranslatesAutoresizingMaskIntoConstraints` is **key** to using manual constraints. By default this is set to `true` which lets the system create a set of constraints for you. However, using `TranslatesAutoresizingMaskIntoConstraints = true` prevents you from adding **additional constraints**, as described in [API doc](https://developer.apple.com/reference/uikit/uiview/1622572-translatesautoresizingmaskintoco): > ℹ️ Note that the autoresizing mask constraints fully specify the view’s size and position; therefore, you cannot add additional constraints to modify this size or position without introducing conflicts. If you want to use Auto Layout to dynamically calculate the size and position of your view, you must set this property to false, and then provide a non ambiguous, nonconflicting set of constraints for the view. ```csharp orangeLabel.TranslatesAutoresizingMaskIntoConstraints = false; ``` Setting `TranslatesAutoresizingMaskIntoConstraints` to `false` should result in the label disappearing because we did not, *yet*, add our manual constraints. > ℹ️ At this point the `Frame` we set before for `orangeLabel` is obsolete, it’s not used by the system anymore. You can try to comment the line where we set it, it won’t affect the constraints we’ll define next. So let’s add some constraints. We can use **anchors** to align UI elements. You can use these constraints to programatically define your layout using Auto Layout. ```csharp // This translates to: orangeLabel's CenterYAnchor (vertical alignment) = rootView's CenterYAnchor orangeLabel.CenterYAnchor.ConstraintEqualTo (rootView.CenterYAnchor).Active = true; ``` We can also use some **guides** to help us with the alignment. `UIView` provides a `LayoutMarginsGuide` property to represent the margins. ```csharp var marginGuide = RootViewController.View.LayoutMarginsGuide; orangeLabel.LeadingAnchor.ConstraintEqualTo (marginGuide.LeadingAnchor).Active = true; ``` Finally we can restore the label’s **width** and **height**. ```csharp orangeLabel.WidthAnchor.ConstraintEqualTo (120).Active = true; orangeLabel.HeightAnchor.ConstraintEqualTo (50).Active = true; ``` Feel free to play around with the constraints above to try to center the label vertically **and** horizontally. ### Purple label constrained to orange label Let’s start by adding a new purple label. ```csharp var purpleLabel = new UILabel () { Text = "Purple", TextColor = UIColor.White, TextAlignment = UITextAlignment.Center, BackgroundColor = UIColor.Purple, TranslatesAutoresizingMaskIntoConstraints = false }; rootView.AddSubview (purpleLabel); // Same width and height constraints as orangeLabel. purpleLabel.WidthAnchor.ConstraintEqualTo (120).Active = true; purpleLabel.HeightAnchor.ConstraintEqualTo (50).Active = true; ``` A typical Layout Constraint can be expressed simply as a **linear expression**. Take the following example: Purple.Leading = 1.0 x Orange.Trailing + 10.0 or \[Item1].\[Attribute1]\[Relationship]\[Multiplier]\[Item2]\[Attribute2]\[Constant] ```csharp purpleLabel.LeadingAnchor.ConstraintEqualTo (orangeLabel.TrailingAnchor, 10).Active = true;purpleLabel.CenterYAnchor.ConstraintEqualTo (orangeLabel.CenterYAnchor).Active = true; ``` Now you could, for instance, constrain the trailing anchor of the purple label to the trailing anchor of the marin guide to fill all the horizontal space. > ℹ️ Note that this will adapat to **any device form factor**. ```csharp purpleLabel.TrailingAnchor.ConstraintEqualTo (marginGuide.TrailingAnchor).Active = true; ``` ###### Try it now A good exercise now would be to try positioning the labels vertically instead of horizontally. ================================================ FILE: ios/platform-features/meta.json ================================================ { "order":{ "auto-layout/programmatical-constraints.workbook":"Programmatically Creating Constraints (Auto Layout)", "scenekit/exploring-scenekit.workbook":"Exploring SceneKit", "scenekit/scngeometrysource.workbook":"SceneKit Geometry Source", "texttospeech/TextToSpeech.workbook":"Text to Speech", "touchid/TouchID.workbook":"TouchID", "widecolor/widecolor.workbook":"Wide Color" } } ================================================ FILE: ios/platform-features/scenekit/README.md ================================================ iOS SceneKit Workbooks ============ * Exploring SceneKit * SCNGeometrySource ![](Screenshots/ExploringSceneKit.png) ================================================ FILE: ios/platform-features/scenekit/exploring-scenekit.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook platforms: - iOS --- # Exploring SceneKit ## Introduction The SceneKit namespace is the native iOS framework for providing 3D graphics for applications. Developers interested in cross-platform 3D graphics for games might want to investigate [UrhoSharp](https://developer.xamarin.com/guides/cross-platform/urho/introduction/). SceneKit uses an easy-to-program “scene graph” model. A scene graph is a branching structure that defines geometries, lights, textures, etc. relative to their parent nodes. This workbook explores the `SceneKit` and `CoreAnimation` namespaces, so reference them. Bring in the `Foundation` namespace as well, for convenience: ```csharp using SceneKit; using CoreAnimation; using Foundation; ``` The scene graph exists within an `SCNScene`: ```csharp var scene = new SCNScene(); ``` An `SCNView` is a subclass of `UIView` that displays a portion of an `SCNScene`. Create an `SCNView` that takes up the whole screen: ```csharp UIScreen.MainScreen.Bounds ``` ```csharp var scnView = new SCNView(UIScreen.MainScreen.Bounds); true; ``` Set the `SCNView.Scene` property to the previously created scene and show some debugging statistics: ```csharp scnView.Scene = scene; scnView.AllowsCameraControl = true; scnView.ShowsStatistics = true; ``` As always with iOS, control of the user experience begins with the root `UIViewController`. Xamarin notebooks provides the `RootViewController` global variable (execute `help` in a code block to see the complete list of variables provided by Workbooks). ```csharp RootViewController; ``` By setting the `View` property of the root `UIViewController` to the `SCNView` that you just created, you will have a full-screen (in the Simulator) view of the `SCNScene`: ```csharp RootViewController.View = scnView; true ``` It may not be apparent that anything has changed, although you should notice the status bar at the bottom of the simulator showing FPS. But you can see that we are, indeed, displaying `scnView` by changing its background color: ```csharp scnView.BackgroundColor = UIColor.Black; ``` Our scene graph is empty, so let’s set the stage: ### Lights! There are a variety of [SCNLightType values](https://developer.xamarin.com/api/type/SceneKit.SCNLightType/). We need at least one to see anything! In this case, we’ll create an “omni” light that emits light in all directions (like a naked light bulb) and an “ambient” light that illuminates all objects in the scene from all directions with the same intensity: ```csharp var lightNode = new SCNNode(); lightNode.Light = new SCNLight (); lightNode.Light.LightType = SCNLightType.Omni; lightNode.Position = new SCNVector3 (0.0F, 10.0F, 10.0F); scene.RootNode.AddChildNode (lightNode); var ambientLightNode = new SCNNode (); ambientLightNode.Light = new SCNLight (); ambientLightNode.Light.LightType = SCNLightType.Ambient; ambientLightNode.Light.Color = UIColor.DarkGray; scene.RootNode.AddChildNode (ambientLightNode); ``` The above code shows a typical pattern for working with SceneKit. First, you create an `SCNNode`. Second, you set properties of that node such as it's `Light` and `LightType` properties. The `Position` property locates the `SCNNode` in 3D space *relative to its parent node's* `Position`, `Rotation`, and `Scale` properties. Finally, you add the newly-created `SCNNode` as a child of an existing `SCNNode`. ### Camera! Now place a camera within the scene, using a similar pattern of creating an `SCNNode`, settings relevant properties, and locating it relative to its parent node: ```csharp var cameraNode = new SCNNode (); cameraNode.Camera = new SCNCamera (); cameraNode.Position = new SCNVector3 (0.0F, 0.0F, 3.0F); scene.RootNode.AddChildNode (cameraNode); ``` ### Actors on the set! At this point, you *still* don’t see anything, because you've not added any geometry to the scene graph. The [SCNGeometry ](https://developer.xamarin.com/api/type/SceneKit.SCNGeometry/) class has a number of sub-classes representing primitive shapes (box, capsule, pyramid, etc.). Or you can programmatically create custom geometry or load it from a DAE file. (See the [Exploring SCNGeometrySource](tk) workbook.) In this case, create an `SCNBox` and add it to the scene: ```csharp var boxNode = new SCNNode (); var box = new SCNBox(); box.ChamferRadius = 0.02f; boxNode.Geometry = box; scene.RootNode.AddChildNode (boxNode); ``` Finally! Something visible in the Simulator! In the Simulator, you can click and drag to rotate the viewpoint. \(Note that the `Position` property of the `boxNode` was not set, but `SCNVector3` is a value type and defaults to `[0, 0, 0]`, which happens to be what we desire for this step.) Now, texture the box. First, load a simple texture from the file system: ```csharp var img = UIImage.FromFile("textureX.png"); ``` SceneKit’s built-in primitive types have reasonable default values for UV (texture) coordinates, so no more work is needed to apply the texture to the box faces: ```csharp var material = new SCNMaterial (); material.Diffuse.Contents = img; material.Specular.Contents = UIColor.Gray; material.LocksAmbientWithDiffuse = true; boxNode.Geometry.FirstMaterial = material; ``` ### Action! The `SCNNode.AddAnimation(CAAnimation)` method allows you to add an animation to a node: ```csharp var animation = new CABasicAnimation(); animation.KeyPath = "rotation"; var t = new SCNVector4 (1.0F, 1.0F, 0.0F, (float) (Math.PI * 2.0)); animation.To = NSValue.FromVector (t); animation.Duration = 5.0f; //seconds animation.RepeatCount = float.MaxValue; //repeat forever boxNode.AddAnimation(animation,new NSString("rotation")); ``` And that’s all there is to creating an animated SceneKit scene! To finish up, let’s remove what we’ve done: ```csharp boxNode.RemoveFromParentNode(); ``` And add a whole bunch of nodes to the scene: ```csharp void TimesRepeat(int repeatCount, Action action) { for (int i = 0; i < repeatCount; i++) action(); } var rand = new Random(); Func NextFractional = () => 1.5f - 3.5f * (float) rand.NextDouble(); TimesRepeat(15, () => { var boxNode = new SCNNode (); boxNode.Position = new SCNVector3(NextFractional(), NextFractional(), NextFractional()); var box = new SCNBox(); box.Length = 0.2f; box.Width = 0.2f; box.Height = 0.2f; box.ChamferRadius = 0.02f; box.FirstMaterial = material; boxNode.Geometry = box; var animation = new CABasicAnimation(); animation.KeyPath = "rotation"; var t = new SCNVector4 (NextFractional(), NextFractional(), NextFractional(), (float) (Math.PI * 2.0)); animation.To = NSValue.FromVector (t); animation.Duration = 5.0f; animation.RepeatCount = float.MaxValue; //repeat forever boxNode.AddAnimation(animation,new NSString("rotation")); scene.RootNode.AddChildNode (boxNode); }); ``` ================================================ FILE: ios/platform-features/scenekit/scngeometrysource.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook platforms: - iOS --- # Exploring SCNGeometrySource ## Creating custom geometry SceneKit’s [SCNGeometry ](https://developer.xamarin.com/api/type/SceneKit.SCNGeometry/)class has several subclasses that represent various primitive shapes (boxes, pyramids, capsules, etc.). Additionally, you can load custom geometry from .DAE files. Or you can create the geometry programmatically. This is the most complex way to create geometry, but ultimately is the most flexible. This workbook will go through the process of creating and animating a textured right-pyramid (a four-sided pyramid). ## SceneKit basics... First, create a basic SceneKit scene with a camera: ```csharp using SceneKit; var vc = KeyWindow.RootViewController; var scene = new SCNScene(); var scnView = new SCNView(UIScreen.MainScreen.Bounds); scnView.Scene = scene; scnView.AllowsCameraControl = true; scnView.ShowsStatistics = true; scnView.BackgroundColor = UIColor.Black; vc.View = scnView; var lightNode = new SCNNode(); lightNode.Light = new SCNLight (); lightNode.Light.LightType = SCNLightType.Omni; lightNode.Position = new SCNVector3 (0.0F, 10.0F, 10.0F); scene.RootNode.AddChildNode (lightNode); var ambientLightNode = new SCNNode (); ambientLightNode.Light = new SCNLight (); ambientLightNode.Light.LightType = SCNLightType.Ambient; ambientLightNode.Light.Color = UIColor.DarkGray; scene.RootNode.AddChildNode (ambientLightNode); var cameraNode = new SCNNode (); cameraNode.Camera = new SCNCamera (); scene.RootNode.AddChildNode (cameraNode); cameraNode.Position = new SCNVector3 (0.0F, 0.0F, 3.0F); ``` ### Important classes There are two critical classes for creating custom geometry: the `SCNGeometrySource` class and the `SCNGeometryElement` class. `SCNGeometrySource` objects are responsible for specifying vertex data. `SCNGeometryElement` objects specify *how* the vertices in the `SCNGeometrySource` object(s) are connected and rendered. In this case, for instance, we'll specify the vertices as separate triangles, but other valid `SCNGeometryPrimitiveType` values are lines, points, and trianglestrips. In addition to basic structure, vertex normals are needed for proper lighting calculations and UV (texture) coordinates are needed to specify how the texture is applied to the geometry. Factory methods turn arrays of this per-vertex data into `SCNGeometrySource` objects. ### Basic geometry Our goal is to create a "tent" (or right-pyramid) that stretches from \[-1, -1, 0\] to \[1, 1, 0\]. The "peak" of the "tent" will be in its center: ```csharp var a = new SCNVector3(-1, -1, 0); var c = new SCNVector3(1, 1, 0); var halfX = (c.X + a.X) / 2; var halfY = (c.Y + a.Y) / 2; var halfZ = (c.Z + a.Z) / 2; var b = new SCNVector3(a.X, c.Y, halfZ); var d = new SCNVector3(c.X, a.Y, halfZ); //Modify third argument to visualize tent peak immediately var midPoint = new SCNVector3(halfX, halfY, halfZ); ``` Now, we can convert these 3D points into vertex geometry data -- our first `SCNGeometrySource`: ```csharp var locs = new [] { a, b, c, d, midPoint }; var locSource = SCNGeometrySource.FromVertices(locs); ``` To properly calculate light reflections, we have to specify the surface normals. Since the rectangle defined by `a` and `c` above is lying flat on the ground, that's easy enough: ```csharp //Normals are relative to geometry (i.e., not to global scene-graph coords) var normals = new [] { new SCNVector3(0, 0, 1), new SCNVector3(0, 0, 1), new SCNVector3(0, 0, 1), new SCNVector3(0, 0, 1), new SCNVector3(0, 0, 1), };; var normSource = SCNGeometrySource.FromNormals(normals); ``` Since we want a textured object, we also have to create an `SCNGeometrySource` for UV coordinates. Texture coordinates with values outside the range \[0,1\] trigger texture wrapping. In this case, we just want to pin the corners of the texture to the corners of the tent and to pin the "peak" of the tent to the center vertex: ```csharp var txCoords = new [] { new CGPoint(0, 0), new CGPoint(0, 1), new CGPoint(1, 1), new CGPoint(1, 0), new CGPoint(0.5, 0.5) }; var txCoordsSource = SCNGeometrySource.FromTextureCoordinates(txCoords); ``` So now we have the necessary `SCNGeometrySource` objects for our per-vertex data: ```csharp var sources = new [] { locSource, normSource, txCoordsSource }; ``` Now it's time to create our `SCNGeometryElement` object to specify how the vertices are connected. This is tightly coupled to the shape and ordering of the vertex data we specified in `locs` above! In the case of `SCNGeometryPrimitiveType.Triangles`, we need to index into the vertex data and define the faces of our geometry by winding in a counter-clockwise direction: ```csharp //Note that this relies on the shape and ordering of locs above! var indices = new [] { //Counter-clockwise! 4, 1, 0, 1, 4, 2, 2, 4, 3, 3, 4, 0 }; ``` You should be able to follow how the triangles defined in `indices` above map into the location of the various index values within `locs`. The first three values in `indices`, for instance, `4, 1, 0`, define the left side of the geometry. The next values,`1, 4, 2,` define the top, and so on. \[TODO: If you cannot see the below image, it is the file `indices.jpg` in the workbook directory\] ![](indices.jpg) Now, to create the `SCNGeometryElement`, we transform the above into `NSData` and call the `SCNGeometryElement.FromData` method with the appropriate arguments: * The `idxData` holding the bytes of our `indices` array; * Our data specifies complete triangles; * The number of triangles we've specified is 4 (`indices.Length / 3`); and * The `NSData` should be read in as a series of `int`s. ```csharp var idxArray = new byte[indices.Length][]; for(int i = 0; i < idxArray.Length; i++) { idxArray[i] = BitConverter.GetBytes(indices[i]); } var idxData = NSData.FromArray(idxArray.SelectMany(id => id).ToArray()); //Note that this relies on indices defining triangles var element = SCNGeometryElement.FromData(idxData, SCNGeometryPrimitiveType.Triangles, indices.Length / 3, sizeof(int)); var elements = new [] { element }; ``` Now that we have both our `SCNGeometrySource` objects and our `SCNGeometryElement` object, we can create the custom geometry: ```csharp var geometry = SCNGeometry.Create(sources, elements); ``` As always, we add the geometry to the `SCNScene` by creating a new `SCNNode` and adding it to the `SCNScene`: ```csharp var tentNode = SCNNode.FromGeometry(geometry); scene.RootNode.AddChildNode(tentNode); ``` Now to texture the geometry. First, create an `SCNMaterial`: ```csharp var material = new SCNMaterial (); material.Diffuse.Contents = UIImage.FromFile ("textureX.png"); material.Specular.Contents = UIColor.Gray; material.LocksAmbientWithDiffuse = true; material.Diffuse.WrapS = SCNWrapMode.Repeat; material.Diffuse.WrapT = SCNWrapMode.Repeat; ``` `SCNGeometry` objects can have multiple materials, but in this case, we only need the one: ```csharp geometry.FirstMaterial = material; ``` And there's our textured custom geometry! Before moving on, let's clear the scene: ```csharp tentNode.RemoveFromParentNode(); ``` ## Modifying geometry `SCNMorpher` objects are used to smoothly animate between geometries in SceneKit. In this case, we want to animate the location of the "peak" of the tent. Before we get to the animation, let’s write some convenience code that allows us to rapidly create new geometry without redoing all our work. First, define a `struct` that holds both the custom geometry and a reference to its vertex locations: ```csharp public struct Tent { public SCNNode Node { get; } public SCNVector3[] Locations { get; } public Tent(SCNNode node, SCNVector3[] locations) { Node = node; Locations = locations; } } ``` We'll create a `Tent` object in a function. Notice that the `CreateTent` function is virtually identical to the code you've already executed in this notebook! ```csharp Tent CreateTent(SCNVector3 a, SCNVector3 c) { var halfX = (c.X + a.X) / 2; var halfY = (c.Y + a.Y) / 2; var halfZ = (c.Z + a.Z) / 2; var b = new SCNVector3(a.X, c.Y, halfZ); var d = new SCNVector3(c.X, a.Y, halfZ); var midPoint = new SCNVector3(halfX, halfY, halfZ); var locs = new [] { a, b, c, d, midPoint }; var locSource = SCNGeometrySource.FromVertices(locs); //Normals are relative to geometry var normals = new [] { new SCNVector3(0, 0, 1), new SCNVector3(0, 0, 1), new SCNVector3(0, 0, 1), new SCNVector3(0, 0, 1), new SCNVector3(0, 0, 1), };; var normSource = SCNGeometrySource.FromNormals(normals); var txCoords = new [] { new CGPoint(0, 0), new CGPoint(0, 1), new CGPoint(1, 1), new CGPoint(1, 0), new CGPoint(0.5, 0.5) }; var txCoordsSource = SCNGeometrySource.FromTextureCoordinates(txCoords); //Note that this relies on the ordering of locs above var indices = new [] { //Counter-clockwise! 4, 1, 0, 1, 4, 2, 2, 4, 3, 3, 4, 0 }; var idxArray = new byte[indices.Length][]; for(int i = 0; i < idxArray.Length; i++) { idxArray[i] = BitConverter.GetBytes(indices[i]); } var idxData = NSData.FromArray(idxArray.SelectMany(id => id).ToArray()); //Note that this relies on indices defining triangles var element = SCNGeometryElement.FromData(idxData, SCNGeometryPrimitiveType.Triangles, indices.Length / 3, sizeof(int)); var geometry = SCNGeometry.Create(new [] { locSource, normSource, txCoordsSource }, new [] { element }); var newNode = SCNNode.FromGeometry(geometry); var tent = new Tent(newNode, locs); return tent; } ``` ```csharp var a = new SCNVector3(-1, -1, 0); var c = new SCNVector3(1, 1, 0); var tent = CreateTent(a, c); var newNode = tent.Node; newNode.Geometry.FirstMaterial = material; scene.RootNode.AddChildNode(newNode) ``` Now that we're back to square one, we want to create a function that allows us to create a new `Tent`, based on the locations of another `Tent` plus a `List` of delta positions: ```csharp Tent Add(Tent original, List> deltas) { //Copy the source vertex locations var locs = original.Locations.Clone() as SCNVector3[]; //Modify the vertices in the cloned location list foreach(var delta in deltas) { var index = delta.Key; locs[index] += delta.Value; } //Replace the original vertex source with the changed source var srcs = original.Node.Geometry.GeometrySources.Clone() as SCNGeometrySource[]; //Find the SCNGeometrySource that supplies vertex data var vertexSourceIndex = -1; for (int i = 0; i < srcs.Length; i++) { var s = srcs[i]; if(s.Semantic == SCNGeometrySourceSemantic.Vertex.ToString()) { vertexSourceIndex = i; break; } } //ASSERT vertexSourceIndex > -1 //Create a new geometry source, whose SCNGeometrySource for vertices is for the modified locations var src = SCNGeometrySource.FromVertices(locs); srcs[vertexSourceIndex] = src; //Create new geometry var newGeo = SCNGeometry.Create(srcs, original.Node.Geometry.GeometryElements); newGeo.Materials = original.Node.Geometry.Materials; //Create new node var node = SCNNode.FromGeometry(newGeo); //Return new node and new locations return new Tent(node, locs); } ``` Now, let's define the geometry which we want to be our end state. In this case, we simply want to modify in Z the position of the "peak," which is at index 4: ```csharp var deltas = new List>(); deltas.Add(new KeyValuePair(4, new SCNVector3(0, 0, 0.5f))); var t2 = Add(tent, deltas); t2.Node.Position += new SCNVector3(2, 0, 0); scene.RootNode.AddChildNode(t2.Node); ``` If you look at the Simulator, you can now see the two geometries side-by-side. After you’re done, remove the new node from the scene: ```csharp t2.Node.RemoveFromParentNode(); ``` ## Creating the animation Now it’s time to create the animation, using the `SCNMorpher`class. The SCNMorpher has 1 or more “target” geometries. In this case, we only have the one target geometry, that of our modified “tent”: ```csharp using CoreAnimation; var oldNode = tent.Node; var newTent = t2.Node.Geometry; var morpher = new SCNMorpher(); morpher.Targets = new [] { newTent }; ``` The `SCNMorpher` sets the (compatible) geometry of the current node into the geometry of its `Targets` based on the percentage value of `morpher.weights` at the index of the target. In other words, if there’s only one `SCNGeometry`in `Targets`, a `morpher.weights\[0\]` of `0` is a geometry whose values are taken entirely from the initial node geometry, while a `morpher.weights\[0\]` of `1.0` takes its values entirely from the geometry at `Targets\[0\]`. A keypath animation of the morpher.weights values cycles smoothly between geometries: ```csharp var animation = CABasicAnimation.FromKeyPath("morpher.weights[0]"); animation.From = new NSNumber(0.0); animation.To = new NSNumber(1.0); animation.AutoReverses = true; animation.RepeatCount = float.PositiveInfinity; animation.Duration = 3; oldNode.Morpher = morpher; oldNode.AddAnimation(animation, "morpher.weights"); ``` ================================================ FILE: ios/platform-features/texttospeech/TextToSpeech.workbook ================================================ --- uti: com.xamarin.workbook platforms: - iOS --- # Text to Speech on iOS Have you ever wanted to add text to speech capability in an iOS application? Speech synthesis is built into the platform. What’s more, adding speech synthesis only requires a few lines of code. The class that synthesizes text to speech is the `AVSpeechSynthesizer`. This class works with an `AVSpeechUtterance`instance that encapsulates the text to synthesize. You simply pass an `AVSpeechUtterance`instance to the synthesizer’s `SpeakUtterance`method and the text is “spoken” by the iOS device. The following example is all you need to have text to speech: ```csharp using AVFoundation; var synth = new AVSpeechSynthesizer(); var su0 = new AVSpeechUtterance("Would you like to play a game?"); synth.SpeakUtterance(su0); ``` The `AVSpeechUtterance`also includes several properties that allow you to control the audio output of the synthesized text. These include: * `Rate`– The speed at which the speech plays back. This appears to be device specific! * `Voice`– An AVSpeechSynthesisVoice instance used to speak the text. * `Volume`– The volume level of the audio used to speak the text. * `PitchMultiplier`– A value between 0.5 and 2.0 to control the pitch of the spoken text. In particular, the default rate is somewhat fast on modern iOS devices. Adjusting the rate to 1/4 the maximum rate, available via the `AVSpeechUtterance.MaximumSpeechRate` property (there’s also an `AVSpeechUtterance.MinimumSpeechRate`) produces a better sounding result. Here is some code you can play with to explore the available properties: ```csharp var su1 = new AVSpeechUtterance("This sentence is being spoken in a customized manner.") { Rate = AVSpeechUtterance.MaximumSpeechRate / 2 , Voice = AVSpeechSynthesisVoice.FromLanguage ("en-AU"), Volume = 0.5f, PitchMultiplier = 0.7f }; synth.SpeakUtterance(su1); ``` It’s possible to use voices from locales with non-English default languages. The words are translated, but the sentence is not translated grammatically: ```csharp AVSpeechSynthesisVoice.GetSpeechVoices().Skip(7).Take(5).Where( voice => { var su2 = new AVSpeechUtterance("These words will be spoken in the language for the locale, but the sentence is not really translated."); su2.Voice = voice; synth.SpeakUtterance(su2); return true; }); ``` To better understand the difference a locale-specific voice makes, compare this *Spanish* phrase spoken in Spanish and English: ```csharp var su1 = new AVSpeechUtterance("Buenos días señor") { Rate = AVSpeechUtterance.MaximumSpeechRate / 2 , Voice = AVSpeechSynthesisVoice.FromLanguage ("es-ES"), Volume = 0.5f, PitchMultiplier = 0.7f }; synth.SpeakUtterance(su1); ``` ```csharp var su1 = new AVSpeechUtterance("Buenos días señor") { Rate = AVSpeechUtterance.MaximumSpeechRate / 2 , Voice = AVSpeechSynthesisVoice.FromLanguage ("en-US"), Volume = 0.5f, PitchMultiplier = 0.7f }; synth.SpeakUtterance(su1); ``` The way it is spoken really does make a difference! ================================================ FILE: ios/platform-features/touchid/TouchID.workbook ================================================ --- uti: com.xamarin.workbook platforms: - iOS --- ## ❗️Note❗️ To determine Touch ID in the simulator, you must select **Touch ID Enrolled** in the simulator’s **Hardware **menu. You can then simulate finger touches by browsing to **Hardware > Simulate Finger Touch** and selecting either **Matching **or **Non-matching**. # Adding Touch ID to your Xamarin.iOS app iOS 8 introduced the functionality for developers to use Apple’s biometric fingerprint authentication technology to add an additional layer of security to their apps. All authentication data held on an iOS device, is stored within the Secure Enclave, a co-processor within the chip that is responsible for determining successful matches for authentication. When Touch ID is enabled on a users device, the Secure Enclave will check if there is a suitable match, and if there is will decrypt the requested keychain item. This example explores how to add Touch ID to a Xamarin iOS app. First, add the required using statements to import the APIs that we will be using. ```csharp using UIKit; using CoreGraphics; using LocalAuthentication; ``` We have set the background of the View Controller’s view to yellow. ```csharp RootViewController.View.BackgroundColor = UIColor.Yellow ``` Let’s create a button. When the user clicks this button, they will be asked to provide their fingerprint to authenticate themselves: ```csharp var button = UIButton.FromType (UIButtonType.System); button.Frame = new CGRect(20, 200, 280, 40); button.SetTitle("Locally Authenticate Me!", UIControlState.Normal) ``` Add this button to the view hierarchy: ```csharp RootViewController.View.AddSubview(button) ``` When the user authenticates successfully, we want to **do** something. For the sake of this example, we will simply just send them to a new View Controller, with a label that tells them they have been successfully authenticated. Let’s create this View Controller now: ```csharp var vcAuthenticated = new UIViewController(); var label = new UILabel(new CGRect(40, 200, 280, 40)); label.Text = "You are now Authenticated"; vcAuthenticated.View.AddSubview(label); vcAuthenticated.View.BackgroundColor = UIColor.Magenta ``` Now we can start using Local Authentication to present the Touch ID user interface to our users. First we will create a new context, this is what will be used to evaluate the authentication policy. We’ll also create a new `NSError` and provide a reason, in the form of a String, to explain to the user why we want them to authenticate: ```csharp var context = new LAContext(); NSError AuthError; var myReason = new NSString("To gain secret access"); ``` Finally, add the code to handle TouchID inside the button’s event handler. First we’ll use `CanEvaluatePolicy` with the policy `DeviceOwnerAuthenticationWithBiometrics`to determine if the device has TouchID enabled. If it does then we can display the Touch ID UI by using `EvaluatePolicy`. There are three pieces of information we have to pass into `EvaluatePolicy` – the policy itself, a string explaining why authentication is necessary, and a reply handler. The reply handler tells the application what it should do in the case of a successful, or unsuccessful, authentication. One of the caveats of Local Authentication is that it must be run on the foreground, so make sure to use `InvokeOnMainThread`: ```csharp button.TouchUpInside += (sender, e) => { if (context.CanEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, out AuthError)){ var replyHandler = new LAContextReplyHandler((success, error) => { RootViewController.InvokeOnMainThread(()=>{ if(success){ RootViewController.PresentViewController(vcAuthenticated, true, null); } else{ //Show fallback mechanism here button.SetTitle("You shall not pass", UIControlState.Disabled); } }); }); context.EvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, myReason, replyHandler); } else { var noTouchID = UIAlertController.Create ("OK Alert", "TouchID is not enabled. See note at top of workbook.", UIAlertControllerStyle.Alert); noTouchID.AddAction (UIAlertAction.Create ("Ok", UIAlertActionStyle.Default, null)); RootViewController.PresentViewController (noTouchID, true, null); } }; ``` ================================================ FILE: ios/platform-features/widecolor/widecolor.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook platform: iOS packages: [] --- # Introduction to Wide Color iOS 10 and macOS Sierra enhances the support for extended-range pixel formats and wide-gamut color spaces throughout the system including frameworks such as Core Graphics, Core Image, Metal and AVFoundation. Support for devices with wide color displays is further eased by providing this behavior throughout the entire graphics stack. The following topics will be covered in detail: * [About Wide Color](#About-Wide-Color) * [Core Color Concepts](#Core-Color-Concepts) * [Color Space](#Color-Space) * [Color Channels](#Color-Channels) * [Color Primaries](#Color-Primaries) * [Color Gamut](#Color-Gamut) * [What is Wide Color](#What-is-Wide-Color) * [The Display P3 Color Space](#The-Display-P3-Color-Space) * [The Extended Range sRGB Color Space](#The-Extended-Range-sRGB-Color-Space) * [Extended Range sRGB in Action](#Extended-Range-sRGB-in-Action) * [Device Pixel Formats](#Device-Pixel-Formats) * [System-Wide Wide Color Support](#System-Wide-Wide-Color-Support) * [Solving the Color Problem](#Solving-the-Color-Problem) * [Designing for Wide Gamut](#Designing-for-Wide-Gamut) * [Upgrading Existing Content to Wide Color](#Upgrading-Existing-Content-to-Wide-Color) * [File Formats and Color Profiles](#File-Formats-and-Color-Profiles) * [Supporting Wide Color with Asset Catalogs](#Supporting-Wide-Color-with-Asset-Catalogs) * [Asset Catalog Deployment](#Asset-Catalog-Deployment) * [Asset Catalog Storage](#Asset-Catalog-Storage) * [Colors in User Interfaces](#Colors-in-User-Interfaces) * [Colors on the Web](#Colors-on-the-Web) * [Rendering Off-Screen Images in App](#Rendering-Off-Screen-Images-in-App) * [Drawing Wide Color in iOS](#Drawing-Wide-Color-in-iOS) * [Rendering On-Screen Images in App](#Rendering-On-Screen-Images-in-App) * [Rendering On-Screen in iOS](#Rendering-On-Screen-in-iOS) * [Rendering On-Screen in macOS](#Rendering-On-Screen-in-macOS) # About Wide Color As stated above, iOS 10 and macOS Sierra enhances the support for extended-range pixel formats and wide-gamut color spaces throughout the system including frameworks such as Core Graphics, Core Image, Metal and AVFoundation. Support for devices with wide color displays is further eased by providing this behavior throughout the entire graphics stack. In the 90's Apple created ColorSync to handle color processing on the Mac. They also helped found the International Color Consortium (ICC) to create and promote a set of standards for handling color on computer hardware. Apple's work with the ICC was included in ColorSync and it was built into the core of OS X (now called macOS). Apple has also been at the forefront of display technology with hardware such as the Retina Display, the new P3 Display and Display P3 Color Space (released in the iMac in 2015) and the TrueTone displays in the iPad Pros. With Wide Color in macOS Sierra and iOS 10, Apple is changing the way that both macOS and iOS handle color to take full advantage of these new display technologies. # Core Color Concepts The following core color concepts need to be covered before taking a deeper look at color in macOS and iOS: ## Color Space A Color Space is an environment in which colors can be represented and compared. It can be a one to four dimensional space that is defined by the intensity of its color components. [ ![](Images/Color00.png)](Images/Color00.png) ## Color Channels The color components can also be referred to as Color Channels. Some familiar representations would be the RGB Spaces, Gray Spaces, CMYK Spaces or Device Independent Spaces. [ ![](Images/Color02.png)](Images/Color02.png) ## Color Primaries Color Primaries provide the coordinate system that is used to compare and compute colors. Color Primaries usually fall at the most intense version of the give color that can be generated within the Color Channel. [ ![](Images/Color01.png)](Images/Color01.png) In the case of the RGB Color Space represented above, the Color Primaries are where the `1.0` coordinates are anchored (such as `[1.0, 0.0, 0.0]` for red). ## Color Gamut Color Gamut refers to all of the colors that can be defined as a combination of the individual Color Channels within a give Color Space. [ ![](Images/Color03.png)](Images/Color03.png) # What is Wide Color Before covering the topic of Wide Color, a discussion should be had about the current industry standard for color, the Standard RGB Color Space (sRGB). It Is the most widely used Color Space in computing today and is the default color space for iOS and macOS. The sRGB Color Space has the following properties: * It's based on the ITU-R BT.709 standard. * It has an approximate Gamma of 2.2. * It represents typical lighting conditions (D65). Since sRGB is so widely used in the industry, a developer can make some assumptions that the color specified will be faithfully represented on any device it is displayed on. However, this might not always be the case. Additionally, there are several colors that do not fit into the sRGB Color Space and therefor, cannot be represented in it. For example, many textiles are designed with threads using many inks and dyes falling outside of sRGB. Also many products that a person encounters in their daily life are created with bright, vivid colors that fall outside of the sRGB Color Space. Some of the most compelling examples of colors that cannot be represented in sRGB are things in nature like sunsets, autumn leaves, exotic flowers and tropical waters. Users who have been capturing digital images in the RAW format may have images on their devices that contain all of this color data, even though it cannot be properly represented in the sRGB Color Space and therefor cannot be properly displayed on screen. ## The Display P3 Color Space In 2015, Apple released new products (iMac and iPad Pro 9.7") that provide the new Display P3 Color Space to handle the issues created by the sRGB Color Space. [ ![](Images/Color04.png)](Images/Color04.png) The Display P3 Color Space has the following properties: * Supports a wide color space for modern hardware platforms. * Based on the SMPTE DCI-P3 standard. DCI-P3 was designed for digital projectors but was modified by Apple to support monitors. * It has an approximate Gamma of 2.2. * It represents typical lighting conditions (D65). According to Apple, users are moving their workflows to their mobile platforms. Solving the color presentation issues presented by sRGB in the professional mobile devices (iPad Pros), required more than just including a wide color display. One of the solutions was to upgrade the factory calibration, so each individual device has been calibrated at the factory ensuring that from device to device, color display is accurate and consistent. Another solution, is the inclusion of full, system-wide color management that Apple has built into iOS 10 and macOS Sierra. ## The Extended Range sRGB Color Space The new iOS 10 system-wide color management has to account for all of the existing iOS apps that are built and fine-tuned for sRGB. It was designed to ensure that it didn't impact either color representation or app performance of these existing apps. To handle this situation, Apple has included the Extended Range sRGB Color Space in iOS 10 (and macOS Sierra as well). The Extended Range sRGB Color Space has the following properties: * Has all of the same sRGB Primaries. * It has an approximate Gamma of 2.2. * It represents typical lighting conditions (D65). * It supports negative values and values greater than one (1). By allowing for values less than zero and greater than one, the Extended Range sRGB Color Space not only allows for existing apps to present colors in sRGB without performance hits or distortion, but it allows the color space to represent any color inside of the visible spectrum. All of this is accomplished while still keeping the same anchor points as the sRGB Color Space. ## Extended Range sRGB in Action To see how values outside of zero and one work in the Extended Range sRGB Color Space, take the following example of the of the most saturated red available in the Display P3 Color Space: [ ![](Images/Color05.png)](Images/Color05.png) In Display P3, this color would be represented as `[1.0, 0.0, 0.0]` and in Extended Range sRGB it would be `[1.358, -0.074, -0.012]`. Because sRGB values are full contained inside of Display P3 and the Display P3 values lay "outside" of the sRGB ranges. For physical hardware that allows pixel values to go from extreme positive to extreme negative values, it can display any color available in the visible spectrum and these values can be represented in the Extended Range sRGB Color Space. ## Device Pixel Formats The sRGB Color Space has been largely standardize on using a 8-bit Pixel Format, since 8-bits per color channel is mostly enough to describe colors in sRGB. This is not perfect but good enough, and it gives a good tradeoff between memory and processor usage to display images. Because Display P3 can represent color coordinates outside of the sRGB color space, it requires 16-bits per color channel to correctly represent colors with the Extended Range sRGB Color Space. # System-Wide Wide Color Support To fully support wide color and wide gamut inside of iOS 10 and macOS Sierra, Apple has extended the following frameworks to take full advantage of the Extended Range sRGB Color Space and Display P3: * UIKit (for iOS only) * SceneKit * Core Graphics * ImageIO * Core Image * WebKit * SpriteKit * Core Animation * AppKit (for macOS only) Additionally, Retina Display support has been enhanced for Extended Range sRGB Color Space and Display P3 displays. Wide color is supported and can be used in the following application content types: * Static image resources included in the app bundle. * Document and network based image resources. * Advanced Media such as Live Photos or images in the RAW format. * 3D Graphics shader texture images. # Solving the Color Problem The content that can be displayed in an app can come from a wide range of color-rich sources. Additionally, this content can be displayed on a broad range of devices, each with their own range of color display capabilities. An iOS 10 app bridges the difference between these two issues by using the new built-in, system-wide Color Manage System. This system ensures that an image looks the same on any iOS device, no matter which Color Space the image was encoded in. Color Management starts with every image having an associated Color Space (or Color Profile). This information is used in the *Color Matching Process* where colors in the source image are matched to colors in the output device. Since every pixel in the image needs to be Color Matched, it can be time consuming and place a strain upon the device's CPU. Due to the nature of the *Color Matching Process*, this conversion can be potentially "lossy" if the output device has a smaller gamut than the source image. Fortunately, the computations that go into the *Color Matching Process* can easily be hardware accelerated (either on the CPU or GPU) and Apple ensures that it works automatically by building support into base systems such as Quartz 2D, ColorSync and Core Animation. For correctly tagged content, no coding is required to take advantage of these features. Color Management has been supported on each platform as follows: * **macOS** - macOS has been color managed since inception. * **iOS** - iOS has supported automatic color management since iOS 9.3 (and later). ## Designing for Wide Gamut Apple has the following suggestion for designing and using wide color, wide gamut image content in iOS and macOS apps: * Only use wide gamut content where in make sense in the app, they should not automatically be used everywhere. * Only use wide gamut content where vivid colors will enhance the user experience. * In is not necessary to change all content to P3 for existing apps. Apple's toolchain makes support for wide gamut image content a gradual opt-in, so supporting wide color in an app is not an all-or-nothing situation. ## Upgrading Existing Content to Wide Color Apple has the following suggestions for upgrading existing image content to wide color: * Don't just "assign" a P3 profile to the content in the image editing app. Doing so will simply remap the existing color content to the new Color Space with unexpected results, such as stretching the colors to fit into the new space thus altering the image. * The image content will need to be "converted" to the Display P3 profile using an image editing app. ## File Formats and Color Profiles Apple has the following suggestions for the file formats and color profiles used in the app's wide color image contents: * Use the "Display P3" color profile for RGB working spaces. * Use a 16-bit per color channel mode. * Use a Late 2015 iMac (or later) to accurately preview image content. * Export image assets as 16-bit PNG files with an embedded "Display P3" ICC profile. **Note**: Using the **Save for Web** or **Export Assets** features found in most popular image editing software *will not* work for wide color images since these features have not been updated to support the required file format specifications yet. ## Supporting Wide Color with Asset Catalogs In iOS 10 and macOS Sierra, Apple has expanded the Asset Catalogs used to include and categorize static image content in the app's bundle to support wide color. Using Asset Catalogs provide the following benefits to an app: * They provide the best deployment option for static image assets. * They support automatic color correction. * They support automatic pixel format optimization. * They support App Slicing and App Thinning which ensures that only the content that is relevant get's delivered to the end user's device. Apple has made the following enhancements to Asset Catalogs for wide color support: * They support 16-bit (per color channel) source content. * They support cataloging content by display gamut. Content can be tagged for either the sRGB or Display P3 gamuts. The developer has three options for supporting wide color content in their apps: 1. **Do Nothing** - Since wide color content should only be used in situations where the app needs to display vivid colors (where they will enhance the user's experience), content outside of this requirement should be left as-is. It will continue to be rendered correctly in all hardware situations. 2. **Upgrade Existing Content to Display P3** - This requires the developer to replace the existing image content in their Asset Catalog with a new, upgraded file in the P3 format and tag it as such in the Asset Editor. At build time, a sRGB derivative image will be generated from these assets. 3. **Provide Optimized Asset Content** - In this situation, the developer will provide both an 8-bit sRGB and a 16-bit Display P3 vision of each image in the Asset Catalog (properly tagged in the asset editor). ## Asset Catalog Deployment The following will occur when the developer submits an app to the App Store with Asset Catalogs that include wide color image content: * When the app is deployed to the end user, App Slicing will ensure that only the appropriate content variant is delivered to the user's device. * On device that don't support wide color, there is no payload cost for including wide color content, as it is never shipped to the device. * `NSImage` on macOS Sierra (and later) will automatically select the best content representation for the hardware's display. * The displayed content will be refreshed automatically when or if the devices hardware display characteristics change. ## Asset Catalog Storage Asset Catalog storage has the following properties and implications for an app: * At build time, Apple attempts to optimize the storage of the image content via high quality image conversions. * 16-bits are used per color channel for wide color content. * Content dependent image compression is used to lower deliverable content sizes. New "lossy" compressions have been added to further optimize content sizes. # Colors in User Interfaces When working with the colors in a User Interface, most of the pixels on screen are in a solid color. Additionally, most of these pixels don't come from images assets but are drawn directly by the app (or by the OS on behalf of the app). Wide gamut color can present several challenges when working at the UI level: * **Communicating Colors** - When talking about color between designers and developers there is usually an *assumed* sRGB Color Space involved. So a color might be communicated as `rgb(128, 45, 56)` or `#FF0456`. In a wide gamut design, these representations don't provide enough information to accurately represent the specified color, the working Color Space must also be included. Apple suggests using `P3(128, 45, 56)` and `P3#FF0456` instead. * **Picking Colors** - Most of the popular image editing and design software suffer from the same limitations as the sRGB Color Space when using their built-in color pickers. The designer should ensure that they are in the "Display P3" Color Space in the Color Picker when working with wide color designs. * **Coding Colors** - Both `NSColor` (macOS) and `UIColor` (iOS & tvOS) have new convenience methods for generating P3 colors directly and both have been extended to support colors in the Extended Range sRGB Color Space as well. * **Storing Colors** - Care should be taken when storing wide gamut colors in an app's document. Where 8-bit per color channel worked fine for the sRGB color space, 16-bit per color channel should be used for wide colors. The developer also needs to watch for instances of assumed Color Space (since everything was traditionally sRGB only). # Colors on the Web Care should be taken when working with wide color in web pages and on devices that support wide color display. If all of the image content that has been included in the website has been appropriately tagged, iOS and macOS will automatically color match and display them correctly. Media queries are also available to help resolve assets between P3 and sRGB capable devices: Apple also has a WebKit proposal that will allow CSS to be specified in other Color Spaces besides the assumed sRGB space. # Rendering Off-Screen Images in App Based on the type of app being created, it might allow the user to include image content they have collected from the internet or create image content directly inside of the app (like a vector drawing app for example). In both of these cases, the app can render the required imagery off-screen in wide color using enhanced features added to both iOS and macOS. ## Drawing Wide Color in iOS Before discussing how to correctly draw a wide color image in iOS 10, take a look at the following common iOS drawing code: ```none public UIImage DrawWideColorImage () { var size = new CGSize (250, 250); UIGraphics.BeginImageContext (size); //... etc ... UIGraphics.EndImageContext (); return UIGraphics.GetImageFromCurrentImageContext (); } ``` There are issues with the standard code that will need to be addressed *before* it can be used to draw a wide color image. The `UIGraphics.BeginImageContext (size)` method used to start iOS image drawing has the following limitations: * It cannot create image contexts with more than 8 bits per color channel. * It cannot represent colors in the Extended Range sRGB Color Space. * It does not have the ability to provide an interface to create contexts in a non-sRGB Color Space because of the low-level C routines being called in the background. To handle these limitations and draw a wide color image in iOS 10, use the following code instead: ```csharp using UIKit; var size = new CGSize (250, 250); var render = new UIGraphicsImageRenderer (size); var image = render.CreateImage ((UIGraphicsImageRendererContext context) => { var bounds = context.Format.Bounds; CGRect slice; CGRect remainder; bounds.Divide (bounds.Width / 2, CGRectEdge.MinXEdge, out slice, out remainder); var redP3 = UIColor.FromDisplayP3 (1.0f, 0.0f, 0.0f, 1.0f); redP3.SetColor (); context.FillRect (slice); var redRGB = UIColor.Red; redRGB.SetColor (); context.FillRect (remainder); }); ``` The new `UIGraphicsImageRenderer` class creates a new image context that is capable of handling the Extended Range sRGB Color Space and it has the following features: * It is fully color managed by default. * It supports the Extended Range sRGB Color Space by default. * It intelligently decides if it should render in the sRGB or Extended Range sRGB Color Space based on the capabilities of the iOS device that the app is running on. * It fully and automatically manages the image context (`CGContext`) lifetime so the developer doesn't have to worry about calling begin and end context commands. * It is compatible with the `UIGraphics.GetCurrentContext()` method. The `CreateImage` method of the `UIGraphicsImageRenderer` class is called to create a wide color image and passed a completion handler with the image context to draw into. All of the drawing is done inside of this completion handler as follows: * The `UIColor.FromDisplayP3` method creates a new fully saturated red color in the wide gamut Display P3 Color Space and it is used to draw the first half of the rectangle. * The second half of the rectangle is drawn in the normal sRGB fully saturated red color for comparison. # Rendering On-Screen Images in App To render wide color images on-screen, the process works similar to drawing an off-screen wide color image for macOS and iOS presented above. ## Rendering On-Screen in iOS When the app needs to render an image in wide color on-screen in iOS, override the `Draw` method of the `UIView` in question as usual. For example: ```using System; using UIKit; using CoreGraphics; public class MonkeyView : UIView { public MonkeyView () { } public override void Draw (CGRect rect) { base.Draw (rect); // Draw the image to screen //... } } ``` As iOS 10 does with the `UIGraphicsImageRenderer` class shown above, it intelligently decides if it should render in the sRGB or Extended Range sRGB Color Space based on the capabilities of the iOS device that the app is running on when the `Draw` method is called. Additionally, the `UIImageView` has been color managed since iOS 9.3 as well. If the app needs to know how rendering is being done on a `UIView` or `UIViewController`, it can check the new `DisplayGamut` property of the `UITraitCollection` class. This value will be a `UIDisplayGamut` enum of the following: * P3 * Srgb * Unspecified If the app wants to control which Color Space is used to draw an image, it can use a new `ContentsFormat` property of the `CALayer` to specify the desired Color Space. This value can be a `CAContentsFormat` enum of the following: * Gray8Uint * Rgba16Float * Rgba8Uint ================================================ FILE: ios/user-interface/UIButton/uibutton.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook platform: iOS packages: [] --- # UIButton ## Example 1 : Adding a button and handling a touch event The `UIButton` is among the most commonly-used components in iOS. It's basic use is straightforward: ```csharp // Number of times the button has been pressed var count = 0; var simple = new UIButton(new CGRect(10, 10, 140, 50)); simple.SetTitle("Press me!", UIControlState.Normal); simple.SetTitleColor(UIColor.Black, UIControlState.Normal); simple.TouchUpInside += (sender, eventArgs) => simple.SetTitle($"Pressed {++count} times.", UIControlState.Normal); ``` The `simple` button is instantiated with a hard-coded `Frame` rectangle (more complex sizing and layouts will be discussed later). The next line set's the `Title` property for the normal `UIControlState`. Since the `Title` may vary depending on the `State` propery of the button, this cannot be a simple setter, but instead requires a call to `SetTitle(string, UIControlState)`. The default color for the title text is white, which happens to be the same as the initial `BackgroundColor` for the workbook, so to make the text visible, the next line changes the color to black. Again you have to pass the `UIControlState` for which you're setting the font color. The `UIButton` class does not have a "Pressed" event. Commonly, `TouchUpInside` is the appropriate equivalent. All of the events available to `UIButton` are actually defined in the parent class `UIControl` and include `TouchDownInside`, `TouchDragEnter`/`TouchDrawExit`, `TouchDragInside`/`TouchDragOutside`, and `TouchCancel`. The event-handler again calls the `UIButton` object's `SetTitle(string, UIControlState)` method, incrementing `count` as it goes. The next step is to add the `simple` button to the user interface: ```csharp RootViewController.View.AddSubview(simple); ``` In iOS, the User Experience is controlled by instances of `UIViewController` and the User Interface by instances of `UIView`. Every `UIWindow` has a `RootViewController` instance of some `UIViewController` subclass. Xamarin Workbooks exposes a global variable `RootViewController` variable for the application running in the simulator. The `UIButton` is a subclass of `UIControl`, which in turn is a subclass of `UIView`, so the `simple` `UIButton` can be added with the `AddSubview(UIView)` method as in the example above. You should run the above sections and click the button at least 10 times before continuing. ## Example 2 : Laying out a button After 10 clicks using the above code, the `Frame` of the `simple` button should have become too small to display the complete text and placed an ellipse in the middle of the title. ![The UIButton will show a truncated version of the Title if necessary](truncated_title.png) The size required to display the entire `Title` is held in the `IntrinsicContentSize` property: ```csharp simple.IntrinsicContentSize ``` This `CGSize` should have a `Width` greater than that of the `Frame` of the `simple` button. (If not, adjust the `Frame` of `simple` and rerun the workbook until you see the truncation behavior.) To get a good sense of how the `Frame` and `IntrinsicContentSize` interact, you can set the `BackgroundColor` of `simple` to something other than white: ```csharp simple.BackgroundColor = UIColor.Yellow; ``` You could do that on each new button individually, but if you want to affect the default appearance of *all new* `UIButton` objects, you can use the "Appearance Proxy" for the class: ```csharp UIButton.Appearance.SetTitleColor(UIColor.Black, UIControlState.Normal); UIButton.Appearance.BackgroundColor = UIColor.Yellow; ``` Hard-coding `Frame` rectangles is not a maintainable strategy. The preferred method for laying out components in iOS is to use the system's "Auto Layout" facility, which describes the layout of a component in terms of `NSLayoutConstraint` objects. Create a new `UIButton` and add it to the `View`: ```csharp var button2 = new UIButton(); RootViewController.View.AddSubview(button2); ``` Note that `button2` uses a no-arg constructor, while your `simple` button passed in the desired `Frame` rectangle. As you can see, `button2` has a `Frame` of zero size: ```csharp button2.Frame ``` There are several ways to specify constraints in code, but the easiest is to use "anchor guides": ```csharp button2.TranslatesAutoresizingMaskIntoConstraints = false; button2.LeadingAnchor.ConstraintEqualTo(RootViewController.View.LayoutMarginsGuide.LeadingAnchor).Active = true; button2.TopAnchor.ConstraintEqualTo(simple.BottomAnchor, 10).Active = true; ``` The first line turns off the legacy “Autoresizing mask” behavior (unfortunately, you cannot use the `UIButton.Appearance` proxy to default `TranslatesAutoresizingMaskIntoConstraints` to `false`!). The second line says that the leading anchor (the anchor for the left edge, in left-to-right cultures) should be constrained to be equal to the left margin of the containing `UIView`. Then, it sets this new constraint to be active. The third line says that the top anchor should be equal to the *bottom* anchor of the `simple` button, plus 10 logical pixels. Constraints can be based on any variable. Run the following to set the height and width of `button2` to be sufficient to hold the `IntrinsicContentSize`: ```csharp button2.HeightAnchor.ConstraintGreaterThanOrEqualTo(button2.IntrinsicContentSize.Height).Active = true; button2.WidthAnchor.ConstraintGreaterThanOrEqualTo(button2.IntrinsicContentSize.Width).Active = true; button2.SetTitle("Explore constraints", UIControlState.Normal); ``` Now, add the following code so that every time `button2` is pressed, it's `Title` and therefore it's `IntrinsicContentSize` changes: ```csharp var rnd = new Random(); // Returns a string of the specified length of random capital letters string RandomString(int length) { var s = ""; for(var i = 0; i < length; i++) { // 0x41 = UTF-16 'A' s += (char) (0x41 + rnd.Next(26)); } return s; } button2.TouchUpInside += (s,e) => { var charCount = 5 + rnd.Next(11); button2.SetTitle(RandomString(charCount), UIControlState.Normal); }; ``` The above code defines a function that creates a random string of capital letters and sets the `TouchUpInside` event handler for `button2` to change the title to a random string of 5 to 15 letters. When you run the above and click `button2` several times, you'll see the `Frame` of `button2` changing to tightly encapsulate the `IntrinsicContentSize`. While this might be a desired behavior in certain circumstances, more generally you probably want to create a layout that, while capable of resizing for different displays and rotations, doesn't resize components in the normal course of interaction. You can add a new constraint that anchors `button2`'s right edge to the margins of the containing `UIView`: ```csharp button2.TrailingAnchor.ConstraintEqualTo(RootViewController.View.LayoutMarginsGuide.TrailingAnchor).Active = true; ``` ## Example 3: Using Images `UIButton` instances may show an image in combination with, or in lieu of, their `Title`. ```csharp var btn3 = new UIButton(); btn3.SetImage(UIImage.FromFile("textureX_sm.png"), UIControlState.Normal); btn3.SetTitle("Image Button", UIControlState.Normal); ``` For convenience, define an extension method for `UIButton` that adds it to the `RootViewController.View` underneath another button and uses the previously-discussed auto layout constraint techniques to size it: ```csharp static void AddToViewBelow(this UIButton newBtn, UIButton above){ RootViewController.View.Add(newBtn); newBtn.TranslatesAutoresizingMaskIntoConstraints = false; newBtn.LeadingAnchor.ConstraintEqualTo(RootViewController.View.LayoutMarginsGuide.LeadingAnchor).Active = true; newBtn.TopAnchor.ConstraintEqualTo(above.BottomAnchor, 10).Active = true; newBtn.HeightAnchor.ConstraintEqualTo(newBtn.IntrinsicContentSize.Height).Active = true; newBtn.TrailingAnchor.ConstraintEqualTo(RootViewController.View.LayoutMarginsGuide.TrailingAnchor).Active = true; } btn3.AddToViewBelow(button2); ``` Buttons additionally may set their `BackgroundImage` property: ```csharp var wood = UIImage.FromFile("wood-texture-pattern.jpg"); btn3.SetBackgroundImage(wood, UIControlState.Normal); ``` \(Wood texture image donated to the [public domain by Yinan Chen](http://www.publicdomainpictures.net/view-image.php?image=26664&)) As you can see, the `BackgroundImage` does _not_ affect the `IntrinsicContentSize` , while the `ImageView` _does_. To add some spacing between the `ImageView` and the `Title`, set the `TitleEdgeInsets` to add 5 logical pixels on its left side: ```csharp btn3.TitleEdgeInsets = new UIEdgeInsets(0, 5, 0, 0); ``` Perhaps the layout would look better if the `Title` and `ImageView` were left-aligned and some padding added around the `ImageView`: ```csharp btn3.HorizontalAlignment = UIControlContentHorizontalAlignment.Left; btn3.ContentEdgeInsets = new UIEdgeInsets(5, 5, 5, 0); ``` ## Example 4: Button states The `UIControlState` enumeration is a little misleading, because it's actually a flagging enumeration. While `UIControlState.Normal`, `UIControlState.Disabled`, and `UIControlState.Highlighted` are mutually exclusive, the `UIControlState.Selected` and `UIControlState.Focused' states can be applied to any `UIControl` that is not in the `UIControl.Disabled` state. `UIControlState.Normal` is the most common state; the button is enabled and the user is not interacting with it. `UIControlState.Disabled` is also frequently used: ```csharp var button4 = new UIButton(); button4.AddToViewBelow(btn3); button4.SetTitle("Normal", UIControlState.Normal); button4.Enabled = true; ``` And conversely: ```csharp button4.SetTitle("Disabled", UIControlState.Disabled); button4.Enabled = false; ``` The `UIControlState.Highlighted` state is activated when the user is interacting with the button (that is, _during_ the touch): ```csharp button4.Enabled = true; button4.SetTitle("Highlighted", UIControlState.Highlighted); ``` Press and hold the `button4` button to see the Highlighted state. Additional API documentation on `UIButton` can be found at [UIButton](https://developer.xamarin.com/api/type/UIKit.UIButton/). ================================================ FILE: ios/user-interface/UIImage/uiimage.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook platform: iOS packages: [] --- # UIImage UIImage allows for image representation in UIKit, which provides support for loading, saving, and manipulating images. iOS uses images for a variety of different purposes – Icon sets, within a UIKit control, etc. They are also used with various frameworks provided by iOS such as UIKit, Core Graphics, Image IO, Core Animation. Each framework provides ways to manipulate and interact with images. Working with Images can be an exhaustive topic. TThis guide will, therefore,focus only on using UIImage within UIKit, and in particular using it with a UIImageView – a UIView that can render a single image, or animate a series of images. For more information on using images in iOS refer to the [Working with Images](https://developer.xamarin.com/guides/ios/application_fundamentals/working_with_images/) guide. ## Creating and displaying a UIImage Add the following Using Directives ```csharp using System; using System.Drawing; using UIKit; ``` An image object needs to be created. This is achieved by using the code below: ```csharp var image = UIImage.FromFile("Xamarin_logo.png"); ``` #### Guidance on Using FromBundle vs. FromFile The `UIImage` class includes two static methods for loading images, `FromBundle` and `FromFile.` The `FromBundle` method call is a synchronous (blocking) call that has some image loading and management features built-in, such as caching support and automatic handling of image files for various resolutions. `UIImage` also contains the `FromFile` method, which is a lighter-weight alternative to `FromBundle`. It doesn’t use caching and so there is no need to worry about the positive or negative memory implications of caching. Additionally, `FromFile` is asynchronous, so it won’t block the main thread; it lazy-loads images as needed for each to be displayed. The following list summarizes the differences between `FromBundle` and `FromFile`: * `FromFile` is asynchronous; whereas `FromBundle` is synchronous. * `FromFile` lazy-loads images. * `FromFile` can load images from an external location; whereas `FromBundle` can only load images that you include with your application. * `FromFile` provides no built-in caching; whereas `FromBundle` automatically caches an image after it is loaded. To display the image created above in a user interface the image, pass it to a UIImageView: ```csharp var imageView = new UIImageView(image); ``` Then, add the imageView as a subview on your RootViewController to display it. ```csharp RootViewController.View.AddSubviews(imageView) ``` Notice that the size of the imageView’s frame is set to the same size as the image (1452 x 609), and is display in the simulator like so: ![](image1.png) Some options can be used to allow the user to view the image, including using a scroll view and manually setting the the `Frame` property. To add a scroll view that contains an image view first instantiate a new `UIScrollView `setting the `Frame `size to the `Width `and `Height`, and the `ContentSize `equal to the `imageViews`’s Image size. The code to do this, is shown below: ```csharp var scrollView = new UIScrollView (new CGRect (0, 0, RootViewController.View.Frame.Width, RootViewController.View.Frame.Height)){ContentSize = imageView.Image.Size}; RootViewController.View.AddSubview(scrollView); scrollView.AddSubview(imageView) ``` Alternatively, the frame can be set, allowing the image to be constrained to a particular size: ```csharp imageView.Frame = new CGRect(0,50,UIScreen.MainScreen.Bounds.Width, 122) ``` ## Scaling the Image Image views use the `ContentMode` property and the image object to best determine how the image should be displayed, allowing the image to be scaled, sized to fit or positioned as necessary. First, create the Image and ImageView with which you wish to work: ```csharp var image2 = UIImage.FromFile("Xamarin_logo.png"); var imageView2 = new UIImageView(new CGRect(25, 200, 275, 100)){BackgroundColor = UIColor.Yellow} ``` The contentMode property takes an enum of UIViewContentMode. The view can be scaled by using any of the following: * `ScaleAspectFit `– Stretches the image to fit the available space. Maintains the aspect ratio. * * `ScaleAspectFill` – Scales the image to fill the available space, while still maintaining the aspect ratio. * `ScaleToFill `– Stretches the image to fill the available space. Does not maintain the aspect ratio. The View can also be positioned or redrawn by using values such as top, bottom, left, right, center ```csharp imageView2.ContentMode = UIViewContentMode.ScaleToFill; imageView2.Image = image2; RootViewController.View.AddSubview(imageView2) ``` #### 👍Try it now! * Change the UIViewContentMode property. Notice how the image changes in comparison to the frame. ## Animating an ImageView An ImageView can be used to provide simple animations in an iOS app via the provided animation methods. Start by creating an image view as shown earlier in this document ```csharp var imageXamView = new UIImageView (new CGRect (120, 330, 75, 75)); ``` Pass in an array of images to the `AnimationImages `property on the Image View. Each image in this array is equivalent to a frame in the animation. ```csharp imageXamView.AnimationImages = new UIImage[]{ UIImage.FromFile("Xamagon.png"), UIImage.FromFile("Xamagon_dark.png") }; ``` The `AnimationDuration` property sets the frame rate. This property specifies the amount of time it takes to go through one cycle of the image. In this animation the duration is 1 second, this means that each image will appear for 0.5s each cycle. ```csharp imageXamView.AnimationDuration = 1 ``` Set the value of `AnimationRepeatCount `to 0, which will allow the animation to animate indefiniately: ```csharp imageXamView.AnimationRepeatCount = 0 ``` Finally, add the Image View to the `RootViewController`, and start the animation by calling the `StartAnimation `property ```csharp RootViewController.View.AddSubview(imageXamView); imageXamView.StartAnimating() ``` #### Try it now! * Try adding a new image into the rotation of images (Note that you’ll have to add the image to the root folder) To stop the animation, call the `StopAnimating()` method. ## Important Image Considerations There are a few more points you should be aware of regarding images and iOS: * By default OS X uses a case-insensitive file system, which means that the iOS Simulator is also case-insensitive. An iOS device, however, uses a **case-sensitive** file system. So code that runs on the simulator may fail to run correctly on the device. * You cannot name a developer created folder `Resources`, as it is reserved in iOS and the application will crash. * Set the build action to **BundleResource** if you want an image to be included in the application bundle. Xamarin Studio will set this automatically for you, but if you get a runtime error that says the image cannot be found, double-check this. ================================================ FILE: ios/user-interface/UILabel/uilabel.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook platform: iOS packages: [] --- # UILabel UILabel is contained within the `UIKit`namespace, so make sure to add this using directive: ```csharp using UIKit; ``` You can create a new label by instantiating it and passing in a frame. The frame is where the control will be placed on the screen: ```csharp var firstLabel = new UILabel(new CGRect(100, 100, 300, 100)) ``` Currently, this is just an empty label with a Frame. To add some text, and make it look nice, assign the label’s Text and TextColor properties: ```csharp firstLabel.Text = "This is a label"; firstLabel.TextColor = UIColor.Purple ``` To add the label to your view, use the following code: ```csharp RootViewController.View.AddSubview(firstLabel) ``` ![](label1.png) In iOS, the User Experience is controlled by instances of `UIViewController`and the User Interface by instances of `UIView`. Every `UIWindow` has a `RootViewController` instance of some `UIViewController` subclass. Xamarin Workbooks exposes a global variable `RootViewController` variable for the application running in the simulator. The \`UILabel\` is a subclass of `UIView`, so the `UIButton` can be added with the `AddSubview(UIView)` method as in the example above. ### 👍Try it now * Change the values of the Frame, and notice how this affects the size and position of the label * Change the Text and TextColor of the label. * What other properties can you change that may be useful? ## Appearance Many properties can be added to a label to adjust its appearance. The `ShadowColor`property can be used to add a shadow effect to any label. The `ShadowOffset`can be used to offset the shadow, in points, from the label where the label is at (0,0). Positive numbers will offset the shadow to the right and down respectively. Negative numbers will offset it to the left and up. The code below creates a new label, aligns it to the left-hand side of the Frame, and creates a shadow effect. ```csharp var secondLabel = new UILabel(new CGRect(100,150, 300, 100)){Text = "Another Label"}; secondLabel.TextAlignment = UITextAlignment.Left; secondLabel.ShadowColor = UIColor.Magenta; secondLabel.ShadowOffset = new CGSize(2.0, -2.0); RootViewController.View.AddSubview(secondLabel) ``` ![](label2.png) ### 👍Try it now * Adjust the properties above to see how TextAlignment and Shadow’s are used on labels in iOS. The font and font size can be changed on any label. Refer to the [Enumerate fonts recipe](https://developer.xamarin.com/recipes/ios/standard_controls/fonts/enumerate_fonts/) to view a list of supported fonts on iOS. In the code below, setting the `AdjustsFontSizeToFitWidth`to `true`constrains the text to the size of the label, regardless of size the font has been set to. ```csharp var thirdLabel = new UILabel(new CGRect(100,200, 150, 100)){Text = "Third Label"}; thirdLabel.Font = UIFont.FromName("Chalkduster", 40f); thirdLabel.AdjustsFontSizeToFitWidth = true; RootViewController.View.AddSubview(thirdLabel) ``` ![](label3.png) ### 👍Try it now * What happens if you set `AdjustsFontSizeToFitWidth`to `false`? ## Adjusting the size of a label The last section introduced the concept of changing the text to fit the label. However, you may need to create a long label, or dynamically adjust the size of the label to fit a large amount of text. The code below creates a new label, with a static frame, and multiline text: ```csharp var longLabel = new UILabel (new CGRect(50,75,250,300)){Text = "There would have been a time for such a word.\nTomorrow, and tomorrow, and tomorrow,\nCreeps in this petty pace from day to day\nTo the last syllable of recorded time,\nAnd all our yesterdays have lighted fools\nThe way to dusty death. Out, out, brief candle!\nLife’s but a walking shadow, a poor player\nThat struts and frets his hour upon the stage\nAnd then is heard no more: it is a tale\nTold by an idiot, full of sound and fury,\nSignifying nothing.", Alpha=0.3f}; RootViewController.View.AddSubview(longLabel) ``` This creates a new label, whose text is truncated at the rightmost edge, as illustrated below: ![truncated](longLabel.png "truncated") The truncation is caused because the default number of lines for a label is 1. The `Line` property can be set to any int value, but setting it to 0 will allow the label to display as many lines as it needs to. SizeToFit can also be called on the label, allowing the view to resize to use the most appropriate amount of space. The code below shows how to do this: ```csharp longLabel.Lines = 0; longLabel.SizeToFit(); ``` ## Responding to Touch Events In some scenarios, you may wish to respond to user interaction in your app. Implementing this is fairly straightforward. First, create a new UITapGestureRecognizer, which will contain all the actions that you want to call when a tap is recognized. ```csharp var eventLabel = new UITapGestureRecognizer(() => { secondLabel.Text = "Here is some updated text"; secondLabel.ShadowOffset = new CGSize(-2.0,2.0); longLabel.Text = "Short text"; longLabel.Alpha = 1.0f; firstLabel.TextColor = UIColor.Orange; }); ``` Then, for the label in which you wish to monitor for user interaction set the `UserInteractionEnabled `property to `true.` Finally, attach the newly created gesture recognizer to your label by passing it as a parameter: ```csharp thirdLabel.UserInteractionEnabled = true; thirdLabel.AddGestureRecognizer(eventLabel) ``` ## Further Reading For more information on using a UILabel, refer to the [API documentation.](https://developer.xamarin.com/api/type/UIKit.UILabel/) ================================================ FILE: ios/user-interface/UINavigationController/README.md ================================================ UINavigationController Workbook ============ Demonstrates pushing and popping viewcontrollers on the navigation stack. ![](Screenshots/uinavigationcontroller.png) ================================================ FILE: ios/user-interface/UINavigationController/uinavigationcontroller.workbook/Hierarchical-Navigation.csx ================================================ using UIKit; public class ContentView : UIView { public ContentView (UIColor fillColor) { BackgroundColor = fillColor; } } public class SimpleViewController : UIViewController { UIColor fillColor; public SimpleViewController (UIColor fillColor) : base () { this.fillColor = fillColor; } public override void DidReceiveMemoryWarning () { // Releases the view if it doesn't have a superview. base.DidReceiveMemoryWarning (); } public override void ViewDidLoad () { base.ViewDidLoad (); var view = new ContentView (fillColor); this.View = view; } } var cyanController = new SimpleViewController(UIColor.Cyan); var blueController = new SimpleViewController(UIColor.Blue); var redController = new SimpleViewController(UIColor.Red); var greenController = new SimpleViewController(UIColor.Green); ================================================ FILE: ios/user-interface/UINavigationController/uinavigationcontroller.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook platform: iOS packages: [] --- # Hierarchical Navigation with the UINavigationController One of the more common needs of an application is to manage the user experience of moving up and down through a hierarchy of screens. In iOS, this is accomplished with the `UINavigationController`. The `UINavigationController` is a prime example of the Model-View-Controller separation of concerns: it is primarily responsible for coordinating a stack of *other* `UIViewControllers`. First, load the `UIViewControllers`that will be controlled by the `UINavigationController`: ```csharp //The implementation of these controllers is not important to understanding UINavigationController #load "Hierarchical-Navigation.csx" ``` Next, create a UINavigationController: ```csharp var navController = new UINavigationController(); ``` Xamarin Workbooks initializes its agent with a basic `UIViewController`, but this can be modified programmatically: ```csharp KeyWindow.RootViewController = navController; ``` The `UINavigationController` only controls a small amount of screen space — the translucent navigation bar that appears below the status bar. The rest of the screen is controlled by the topmost `UIViewCOntroller` in the navigation controller’s stack. To push a controller onto the stack, use: ```csharp navController.PushViewController(cyanController, false); ``` > ⚠️ Warning > > * A `UIViewController` may only be contained in a single `UINavigationController`. Attempting to add it twice will result in an exception. > > * The interactive nature of a Xamarin Workbook makes the above mistake easy to make! If you crash the `navController`, it's probably best to reload the Workbook before continuing. Because the `cyanController` is the `navController`’s first child (and therefore it’s `RootViewController`), the navigation bar does not display a “back” navigation control, but if we add another `UIViewController`, the navigation bar creates a standard navigation experience, with a back button labeled “Back”: ```csharp navController.PushViewController(redController, true); ``` The second parameter to \`PushViewController\` is a bool that controls whether the change is animated. You can modify the title of the back button by setting the following code in the view controller *above* where you want the modified title to appear: ```csharp redController.NavigationItem.BackBarButtonItem = new UIBarButtonItem("Pop to Red", UIBarButtonItemStyle.Plain, null); navController.PushViewController(greenController, true); ``` The navigation bar can additionally display a `Title`: ```csharp navController.NavigationBar.TopItem.Title = "Green Controller" ``` And it can have a background image: ```csharp var img = UIImage.FromFile("wood-texture-pattern.jpg"); navController.NavigationBar.SetBackgroundImage(img, UIBarMetrics.Default); ``` Without the background image, you can see that the navigation bar sits on top of the presented `UIViewController` : ```csharp navController.NavigationBar.SetBackgroundImage(null, UIBarMetrics.Default); ``` If you just add a `UIControl` to the `greenViewController`’s view, it will sit beneath the navigation bar: ```csharp var label = new UILabel(new CGRect(0, 100, 100, 50)) { Text = "MyControl" }; greenController.View.AddSubview(label); label.Frame ``` The easiest way to layout the control to respect the navigation bar is to use autolayout and the `TopLayoutGuide` property of the `UIViewController`, which “knows about” the status and navigation bars: ```csharp label.TranslatesAutoresizingMaskIntoConstraints = false; var margins = greenController.View.LayoutMarginsGuide; label.LeadingAnchor.ConstraintEqualTo(margins.LeadingAnchor).Active = true; label.TrailingAnchor.ConstraintEqualTo(margins.TrailingAnchor).Active = true; label.TopAnchor.ConstraintEqualTo(greenController.TopLayoutGuide.GetBottomAnchor(), 10).Active = true; ``` You’ve already explored the `PushViewController` method on the `UINavigationController`. It’s complement is the `PopViewController` method. As with `PushViewController`, a boolean specifies whether the change should be animated: ```csharp navController.PopViewController(true) ``` \(Note that the “Back Button” in the navigation bar automatically pops the current controller, you do not need to write an event handler to do so.) If you have a deep hierarchy of controllers: ```csharp navController.PushViewController(greenController, true); navController.PushViewController(blueController,true); ``` You may pop the entire stack with: ```csharp navController.PopToRootViewController(true); ``` ###### 👍 Try it now! * Push and pop the `redController`, `greenController`, and `blueController` view controllers * Set a new `Title` and `BackgroundImage` for the navigation bar. ================================================ FILE: ios/user-interface/UISwitch/index.workbook ================================================ --- uti: com.xamarin.workbook platforms: - iOS --- # UISwitch ## Adjusting the Appearance ### Creating a switch To create a switch, instantiate a new UISwitch and give it a frame. It can then be added as a subview to the view: ```csharp var funSwitch = new UISwitch(new CGRect(50, 50, 100, 100)); RootViewController.View.AddSubview(funSwitch); ``` Note that a switch control can also be added to an iOS application through the Xamarin Designer for iOS, which can be found in Visual Studio and Xamarin Studio. ### Adjusting properties\ There are only a small number of properties that can be changed when implementing a UISwitch – the On/Off tint color, and the Thumb tint color. These can be adjusted by accessing the properties shown below: ```csharp funSwitch.ThumbTintColor = UIColor.Magenta; funSwitch.OnTintColor = UIColor.Blue ``` In iOS 6 and below, an On or Off image can be added via the **[`OnImage/`](https://developer.xamarin.com/api/property/UIKit.UISwitch.OnImage/)[`OffImage`](https://developer.xamarin.com/api/property/UIKit.UISwitch.OffImage/)**properties. However, these images will not render in iOS 7 and above. The SetState property can be used when creating a new switch to set its state as on or off by default, where True => On and False => Off: ```csharp funSwitch.SetState(false,true); ``` ### Setting the Appearance Like many UIKit controls, setting any appearance properties on this instance will affect the appearance of all instances of UISwitch. Adjust the Thumb tint color for all new switches with the following code: ```csharp UISwitch.Appearance.ThumbTintColor = UIColor.Orange ``` Try it now: * Create a new UISwitch to confirm the appearance. * Change the tint color to show when the switch is OFF ## Responding to events Create a label to display the state of the switch: ```csharp var label = new UILabel(new CGRect(10, 100, 250, 50)){Text = ""}; RootViewController.View.AddSubview(label); ``` The `ValueChanged `event can be handled to determine the change in state between the switch being On and Off. The On property returns a boolean, which can then be evaluated to establish the condition of the switch: ```csharp funSwitch.ValueChanged += delegate { if (funSwitch.On) label.Text = "Switch is turned On:" + funSwitch.On.ToString(); else label.Text = "Switch is turned On:" + funSwitch.On.ToString(); } ``` ## Further Reading For more information on using a UISwitch, refer to the following articles: * [Using a Switch in the iOS Designer](https://developer.xamarin.com/guides/ios/user_interface/controls/part_6_-_other_controls/#Switch) * [API Documentation](https://developer.xamarin.com/api/type/UIKit.UISwitch/) ================================================ FILE: ios/user-interface/UITableView/uitableview.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook platform: iOS packages: [] --- # Introduction to iOS Tables ## Displaying data using UITableView with Xamarin.iOS This workbook introduces the classes used to create and display tables in Xamarin.iOS. For those working on cross-platform applications with Xamarin.Android, the `UITableView` control is similar to the `ListView` class in Android and the `UITableViewSource` class is similar to Android’s `Adapter` classes. ## Table Parts A UITableView can have a ‘grouped’ or ‘plain’ style, and consists of the following parts: * Section Header * Cells (or rows, if you prefer) * Section Footer * Index * Editing mode (includes ‘swipe to delete’ and drag handles to change row order) These screenshots show how section rows, headers, footers, edit controls and the index are displayed. ![](image1a.png) To understand iOS tables, it’s easiest to work upwards from the domain data: ```csharp //Domain data public class SimpleDomainClass { public nint Section { get; } public nint Row { get; } public SimpleDomainClass(nint section, nint row) { Section = section; Row = row; } override public string ToString() => $"Section {Section}, Row {Row}"; } var simpleDomainCollection = new [] { new SimpleDomainClass(0, 0), new SimpleDomainClass(0, 1), new SimpleDomainClass(0, 2), new SimpleDomainClass(1, 0), new SimpleDomainClass(1, 1), new SimpleDomainClass(1, 2) }; ``` Generally, you do not need to subclass `UITableView` itself: ```csharp var tableView = new UITableView(); ``` A table view displays its data in `UITableViewCell` instances. Because tables may be very large, iOS caches the UITableViewCell instances of a table. The key to that cache is a `string` called the “reuse identifier.” The method `RegisterClassForReuse` associates the reuse identifier with the type of `UITableViewCell` you wish to use. To avoid typos, a good practice is to use `nameof(YourCellType)`: ```csharp readonly string CELL_ID = nameof(UITableViewCell); tableView.RegisterClassForCellReuse(typeof(UITableViewCell), CELL_ID); ``` In this case, we want to display a generic `UITableViewCell` but often you will pass in a subclass you define. Domain data is linked to the table view via a subclass of UITableViewSource: ```csharp public class DomainSource : UITableViewSource { SimpleDomainClass[] Model { get; } public DomainSource (SimpleDomainClass[] model) { this.Model = model; } //The first section is section == 0 public override nint RowsInSection (UITableView tableView, nint section) { // Matches the "Section" property with the passed-in section return Model.Count((datum => datum.Section == section)); } public override nint NumberOfSections(UITableView tableView) { return Model.GroupBy((datum) => datum.Section).Count(); } //Note: For production, strive to make this method performant public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath) { //Retrieve a cell from the system-maintained cache for the table. var cell = tableView.DequeueReusableCell (nameof(UITableViewCell), indexPath); //as MyTableViewCellType <-- Downcast as necessary //RegisterForReuse guarantees cell is not null //Retrieve data var sectionData = Model.Where(datum => datum.Section == indexPath.Section); //Set the appearance of the cell based on the data and indexPath cell.TextLabel.Text = sectionData.ElementAt(indexPath.Row).ToString(); return cell; } } var simpleSource = new DomainSource(simpleDomainCollection); ``` Your UITableViewSource may override more functions, but it must override `RowsInSection` and `GetCell`. RowsInSection should be fairly clear: `section` is a 0-based index into your domain data; if your table has only a single section, just return the total number of rows in your data. Because our sample data has multiple sections, the above also overrides `NumberOfSections`. `GetCell` is a little more complex. `GetCell`is responsible for setting the properties of a specific row. The `indexPath` contains both a `Section` and a `Row` `nint` that indicates what data the `tableView` is displaying. `DequeueReusableCell` takes a string (a reuse identifier) and the passed-in `indexPath` and returns a `UITableViewCell`. If you have called `RegisterClassForCellReuse`, `DequeueReusableCell` will, as necessary, instantiate a new instance of the type associated with the reuse identifier. If you have *not* registered a class, you must perform a null check and instantiate the cell yourself. Because we are using the base class `UITableViewCell` for display we do not need to downcast to get the appropriate type for `cell`, but if you had registered a custom class, you would need to downcast it. The bulk of `GetCell` is setting the display properties of the `cell` to the values of the domain data associated with the `indexPath`. *Note:* `GetCell` must be a performant method. This example uses LINQ for clarity, but you should profile and be prepared to optimize this method. Now that you have a `UITableView` for which you’ve registered a `UITableViewCell` to display cells, and you have a `UITableViewSource` associated with your data, the next thing to do is tie them together: ```csharp tableView.Source = simpleSource; ``` Finally, you need a `UITableViewController` to handle the user experience: ```csharp var tvc = new UITableViewController(UITableViewStyle.Plain); tvc.TableView = tableView; RootViewController.PresentViewController(tvc, true, () => {}); ``` You'll notice that although your data has two sections, the displayed table does not show any breaks. To create section headers and footers, you need to override additional functions in your `UITableViewSource`: ```csharp //Notice that this is a subclass of DomainSource (which defines GetCell, RowsInSection, and NumberOfSections) public class DomainSourceWithGroups : DomainSource { public DomainSourceWithGroups(SimpleDomainClass[] data) : base(data) {} //Both "GetViewFor{Header|Footer|" and "GetHeightFor{Header|Footer"}" must be overridden public override UIView GetViewForHeader(UITableView tableView, nint section) { var l = new UILabel(); l.Text = $"Section {section}"; l.BackgroundColor = UIColor.White; return l; } public override nfloat GetHeightForHeader(UITableView tableView, nint section) { return 20; } public override UIView GetViewForFooter(UITableView tableView, nint section) { var vw = new UIView(); vw.BackgroundColor = UIColor.Yellow; return vw; } public override nfloat GetHeightForFooter(UITableView tableView, nint section) { return 5; } } var sourceWithSectionViews = new DomainSourceWithGroups(simpleDomainCollection); tableView.Source = sourceWithSectionViews; //Re-display tvc.DismissViewController(true, () => { RootViewController.PresentViewController(tvc, true, null);}); ``` `DomainSourceWithGroups`adds support for section headers and footers. The `GetHeightForHeader`and `GetHeightForFooter` must be implemented for the relevant view to appear. ## Reacting to touches Most tables allow the user to touch a row to select it and perform some other action (such as playing a song, or calling a contact, or showing another screen). iOS does not have .NET-like events. It sometimes uses the almost-but-not-quite-an-event “target-action” pattern but more commonly it uses the the “delegate object” model for event-handling. In this model, components are associated with two different classes. One class holds those properties and behaviors that are not necessarily customized every time the class is used (a `UILabel`, for instance, displays some Text whose *value* will certainly need to be set to something other than “Label”, but the idea that it displays a string is unlikely to be changed). The other class, called the “delegate class,” contains the methods that in the .NET-world would correspond to events. Since events typically *do* need to be handled in a custom manner, you typically write lots of subclasses of the “delegate class.” It’s important not to be confused between C# `delegate` methods and the “delegate object” model, especially as Apple typically refers to the delegate object simply as “the delegate.” The `UITableViewSource` class is a delegate class for the `UITableView` and you override the `RowSelected` method in order to handle a selection touch. You could either write the custom event-handling code directly in the `RowSelected` method or you could expose the call as a .NET event: ```csharp //Generic EventArgs subclass public class EventArgsT : EventArgs { public T Value { get; } public EventArgsT(T value) { this.Value = value; } } //Again, note that this inherits from UITableViewSource class TouchDelegateToEvent : DomainSourceWithGroups { public TouchDelegateToEvent(SimpleDomainClass [] data) : base(data) {} public event EventHandler> OnRowSelected = delegate {}; public override void RowSelected(UITableView tableView, NSIndexPath path) { OnRowSelected(this, new EventArgsT(path)); } } //Instantiate our new UITableViewSource and assign it var sourceWithTouch = new TouchDelegateToEvent(simpleDomainCollection); tableView.Source = sourceWithTouch; //Handle the touch event by showing a simple dialog sourceWithTouch.OnRowSelected += (sender, evt) => { NSIndexPath path = evt.Value; var popup = UIAlertController.Create("Row touched", $"Section {path.Section} Row {path.Row}", UIAlertControllerStyle.Alert); popup.AddAction(UIAlertAction.Create("Click", UIAlertActionStyle.Default, null)); tvc.PresentModalViewController(popup, true); }; //Re-display tvc.DismissViewController(true, () => { RootViewController.PresentViewController(tvc, true, null);}); ``` The previous code defines an `EventArgsT` class and an `OnRowSelected` event. It overrides the "delegate class" method `RowSelected` to fire the `OnRowSelected` event. Then, it creates an instance of this new `UITableViewSource` class and assigns a handler (a .NET `delegate`, which is hopefully not too confusing!) to the `OnRowSelected` event. (Normally you should avoid using "On" for titling your events, but in this case the "delegate class" already took the name `RowSelected`.) The handler pops up a dialog with information about the touched row. Finally, it re-displays the `UITableViewController`. ## Further Reading Tables (and the closely-related UICollectionView and associated classes) have a large amount of behavior and customizability. The [Working with Tables and Cells](https://developer.xamarin.com/guides/ios/user_interface/tables/) series on the Xamarin developer portal goes into these capabilities in great depth. ================================================ FILE: ios/user-interface/alerts/alert-controller.workbook/alert_controller.csx ================================================ //Alert with One Button var okayButton = UIButton.FromType (UIButtonType.System); okayButton.Frame = new CGRect (10, 30, 300, 40); okayButton.SetTitle ("Okay Button", UIControlState.Normal); //Alert with Two Buttons var okayCancelButton = UIButton.FromType (UIButtonType.System); okayCancelButton.Frame = new CGRect (10, 80, 300, 40); okayCancelButton.SetTitle ("Okay / Cancel Button", UIControlState.Normal); //Text Input Alert var textInputButton = UIButton.FromType (UIButtonType.System); textInputButton.Frame = new CGRect (10, 130, 300, 40); textInputButton.SetTitle ("Text Input", UIControlState.Normal); var actionSheetButton = UIButton.FromType (UIButtonType.System); actionSheetButton.Frame = new CGRect (10, 180, 300, 40); actionSheetButton.SetTitle ("Action Sheet", UIControlState.Normal); RootViewController.View.AddSubview(okayButton); RootViewController.View.AddSubview(okayCancelButton); RootViewController.View.AddSubview(textInputButton); RootViewController.View.AddSubview(actionSheetButton); ================================================ FILE: ios/user-interface/alerts/alert-controller.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook platform: iOS packages: [] --- # UIAlertController UIAlertController is the class that should be used for displaying alerts in iOS 8 and above and has completely replaced `UIActionSheet`and `UIAlertView`, both of which are now deprecated. Unlike the classes it replaced, which are subclasses of `UIView`, `UIAlertController`is a subclass of `UIViewController`. `UIAlertControllerStyle` is used to indicate the type of alert to display. These alerts types are: * **UIAlertControllerStyleActionSheet** * Pre-iOS 8 this would have been a UIActionSheet * **UIAlertControllerStyleAlert** * Pre-iOS 8 this would have been UIAlertView There are three steps to take when creating an AlertController: * Create and configure the Alert * title * message * preferredStyle * (Optional) Add a text field * Add the Required actions * Present the View Controller As this alert is triggered by a button touch event (a typical scenario in iOS), load the \`UIButtons\`: ```csharp #load "alert_controller.csx" ``` ```csharp //var alertController = new AlertControllerSampleViewController(); //KeyWindow.RootViewController = alertController //KeyWindow.MakeKeyAndVisible() ``` ```csharp // //Alert with One Button // var okayButton = UIButton.FromType (UIButtonType.System); // okayButton.Frame = new CGRect (10, 30, 300, 40); // okayButton.SetTitle ("Okay Button", UIControlState.Normal); // //Alert with Two Buttons // var okayCancelButton = UIButton.FromType (UIButtonType.System); // okayCancelButton.Frame = new CGRect (10, 80, 300, 40); // okayCancelButton.SetTitle ("Okay / Cancel Button", UIControlState.Normal); // //Text Input Alert // var textInputButton = UIButton.FromType (UIButtonType.System); // textInputButton.Frame = new CGRect (10, 130, 300, 40); // textInputButton.SetTitle ("Text Input", UIControlState.Normal); // var actionSheetButton = UIButton.FromType (UIButtonType.System); // actionSheetButton.Frame = new CGRect (10, 180, 300, 40); // actionSheetButton.SetTitle ("Action Sheet", UIControlState.Normal); // RootViewController.View.AddSubview(okayButton); // RootViewController.View.AddSubview(okayCancelButton); // RootViewController.View.AddSubview(textInputButton); // RootViewController.View.AddSubview(actionSheetButton); ``` ## Alert with One Button ![](okayalert.png) ```csharp okayButton.TouchUpInside += (sender, e) => { //Create Alert var okAlertController = UIAlertController.Create ("OK Alert", "This is a sample alert with an OK button.", UIAlertControllerStyle.Alert); //Add Action okAlertController.AddAction (UIAlertAction.Create ("Ok", UIAlertActionStyle.Default, null)); // Present Alert RootViewController.PresentViewController (okAlertController, true, null); }; ``` ## Alert with Two buttons ![](okaycancel.png) ```csharp okayCancelButton.TouchUpInside += ((sender, e) => { //Create Alert var okCancelAlertController = UIAlertController.Create("OK / Cancel Alert", "This is a sample alert with an OK / Cancel Button", UIAlertControllerStyle.Alert); //Add Actions okCancelAlertController.AddAction(UIAlertAction.Create("Okay", UIAlertActionStyle.Default, alert => Console.WriteLine ("Okay was clicked"))); okCancelAlertController.AddAction(UIAlertAction.Create("Cancel", UIAlertActionStyle.Cancel, alert => Console.WriteLine ("Cancel was clicked"))); //Present Alert RootViewController.PresentViewController(okCancelAlertController, true, null); }); ``` ## Alert with Text Field ![](textinput.png) ```csharp textInputButton.TouchUpInside += ((sender, e) => { //Create Alert var textInputAlertController = UIAlertController.Create("Text Input Alert", "Hey, input some text", UIAlertControllerStyle.Alert); //Add Text Input textInputAlertController.AddTextField(textField => { }); //Add Actions var cancelAction = UIAlertAction.Create ("Cancel", UIAlertActionStyle.Cancel, alertAction => Console.WriteLine ("Cancel was Pressed")); var okayAction = UIAlertAction.Create ("Okay", UIAlertActionStyle.Default, alertAction => Console.WriteLine ("The user entered '{0}'", textInputAlertController.TextFields[0].Text)); textInputAlertController.AddAction(cancelAction); textInputAlertController.AddAction(okayAction); //Present Alert RootViewController.PresentViewController(textInputAlertController, true, null); }); ``` ## ActionSheet Alert ![](actionsheet.png) ```csharp actionSheetButton.TouchUpInside += ((sender, e) => { // Create a new Alert Controller UIAlertController actionSheetAlert = UIAlertController.Create("Action Sheet", "Select an item from below", UIAlertControllerStyle.ActionSheet); // Add Actions actionSheetAlert.AddAction(UIAlertAction.Create("Item One",UIAlertActionStyle.Default, (action) => Console.WriteLine ("Item One pressed."))); actionSheetAlert.AddAction(UIAlertAction.Create("Item Two",UIAlertActionStyle.Default, (action) => Console.WriteLine ("Item Two pressed."))); actionSheetAlert.AddAction(UIAlertAction.Create("Item Three",UIAlertActionStyle.Default, (action) => Console.WriteLine ("Item Three pressed."))); actionSheetAlert.AddAction(UIAlertAction.Create("Cancel",UIAlertActionStyle.Cancel, (action) => Console.WriteLine ("Cancel button pressed."))); // Required for iPad - You must specify a source for the Action Sheet since it is // displayed as a popover UIPopoverPresentationController presentationPopover = actionSheetAlert.PopoverPresentationController; if (presentationPopover!=null) { presentationPopover.SourceView = RootViewController.View; presentationPopover.PermittedArrowDirections = UIPopoverArrowDirection.Up; } // Display the alert RootViewController.PresentViewController(actionSheetAlert,true,null); }); ``` ================================================ FILE: ios/user-interface/meta.json ================================================ { "order":{ "alerts/alert-controller.workbook":"Alerts", "UIbutton/uibutton.workbook":"Button", "UIImage/uiimage.workbook":"Image", "UILabel/uilabel.workbook":"Label", "UINavigationController/uinavigationcontroller.workbook":"Navigation Controller", "UISwitch/index.workbook":"Switch", "UITableView/uitableview.workbook":"Table View", "uitableview-1/uitableview1.workbook":"Table View 1", "web-views/web-views.workbook":"Web View" } } ================================================ FILE: ios/user-interface/uitableview-1/README.md ================================================ UITableView Workbook ============ Demonstrates the how to use the data display and editing features of [`UITableView`](https://developer.xamarin.com/api/type/UIKit.UITableView) as explained in the [docs](https://developer.xamarin.com/guides/ios/user_interface/tables/) ![](Screenshots/uitableview.png) ================================================ FILE: ios/user-interface/uitableview-1/uitableview1.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook platform: iOS packages: [] --- # UITableView I One of the most common controls in iOS is the table view - it renders a fast scrolling list of data and can be heavily customized. This workbook demonstrates how to display data in a table view, and is based on the [Tables and Cells section](https://developer.xamarin.com/guides/ios/user_interface/tables/) on [developer.xamarin.com](https://developer.xamarin.com). * Setup * Showing Some Data * Animated Insertion & Deletion * Customizing Each Row * Built-in Layouts * Custom Cell Layout * Row Selection * Row Actions * Edit Mode First, some setup. Grab a reference to the iOS root `ViewController` (in your app code, a table view might be added to any view controller): ```csharp var vc = KeyWindow.RootViewController; ``` ## Setup Now instantiate a `UITableView`control. Notice how the offset and size are all zero - by default the table has no size... ```csharp var tableView = new UITableView(); ``` Table views frequently occupy the entire screen, so set the `Frame`for the table to match the `Bounds`of the screen. The tableView will now have a `Width`and `Height`: ```csharp tableView.Frame = UIScreen.MainScreen.Bounds; ``` The table is still not visible on the screen - to make that happen we need to add the control to the root view controller’s `View`, with the `AddSubview`method. When this method is called the table will be visible on the screen (despite having no data, an empty table view displays gridlines based on the default row height): ```csharp vc.View.AddSubview(tableView); ``` In your app code, the AddSubview command is usually in the `ViewDidLoad` method. Alternatively, you can drag-and-drop a `UITableView`control onto a storyboard and give it a name, which means you do not have to do the above steps in code. ## Showing Some Data Real apps frequently populate the UI from a database or a web-service, but for learning about table views a simple string list is a good start: ```csharp var data = new List {"eeny", "meany", "miney", "mo"}; ``` iOS table views don’t have the concept of a **BindingContext** like Xamarin.Forms, so there is no direct way to “assign” the list to the table view. Instead a wrapper object subclassed from `UITableViewSource` is used - the table view uses this class to get information about the data it needs to display. There are many optional methods, but the minimum implementation requires: * `RowsInSection` – a method that tells the table view how many rows are in the data. Table views support multiple sections, but for this example there is only one section so the concept can be ignored for now. * `GetCell` – the table view calls this method for each row that it needs to display. There are two parts to this method: first get a recycled cell or create a new cell object, then set the UI of the cell with values from the data for that row. An example subclass - `MySource` - is shown below. ```csharp public class MySource : UITableViewSource { string identifier = "mycell"; public List Data {get;set;} = new List(); // C# 6 public override nint RowsInSection (UITableView tableview, nint section) { return Data.Count; } public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath) { // first, get or create a cell UITableViewCell cell = tableView.DequeueReusableCell (identifier); if (cell == null) { cell = new UITableViewCell (UITableViewCellStyle.Default, identifier); } // then, get the data and set the UI string item = Data[indexPath.Row]; cell.TextLabel.Text = item; return cell; } } ``` To use the new class, instantiate it and set the `Data` property to the list of strings. Now it’s ready for the table view, so assign it to the table view’s `Source` property. The table is now ready to display the data - call `ReloadData` to see it rendered on the screen: ```csharp var source = new MySource(); // create the class source.Data = data; // assign the list of strings tableView.Source = source; // give it to the table view tableView.ReloadData(); // and show on the screen ``` ![](mysource.png) *(ignore the status bar overlapping for now - that is a layout issue for another workbook)* What happens when a new item is added to the data list? ```csharp data.Add("d'oh"); ``` Sadly, it does not automatically appear on the screen. We can force the table view to re-load the entire list by calling `ReloadData`: ```csharp tableView.ReloadData(); ``` The new “d’oh” row is now visible - but there may have been a flicker in the UI, since the entire table was cleared and the rows re-created. This is sometimes acceptable for simple apps with small datasets, but there is a nicer way to add (and remove) rows programmatically.... with animation! ### Animated Insertion & Deletion Rather than reloading the entire table, rows can be progammatically added and removed. To demonstrate, insert two new rows at position 2 and 4 in the list so that they appear with an animation. The first step is to create `NSIndexPath`objects that refer to the new rows we’re inserting: ```csharp var ip1 = NSIndexPath.FromRowSection(2, 0); // row 2 section 0 var ip2 = NSIndexPath.FromRowSection(4, 0); // row 4 section 0 ``` Instead of using `ReloadData`to refresh the entire list, it is possible to get the table to dynamically add the new rows with the code below. Notice how the modifications to both the underlying `data` and the `tableView` are contained inside a `BeginUpdates`/`EndUpdates` block: ```csharp tableView.BeginUpdates(); // update the underlying data source data.Insert (2, "a deer"); data.Insert (4, "ray"); // tell the UITableView about the updates with NSIndexPath objects tableView.InsertRows(new [] {ip1, ip2}, UITableViewRowAnimation.Automatic); tableView.EndUpdates(); ``` It is only after `EndUpdates` is called that the changes are reflected in the user interface. All the changes made to the `data` and the `tableView` must match (ie. the number of rows in each must be identical before the block and after the block). Notice how the new rows animate into place. In addition to `Automatic` there are other animation options like `Top`, `Bottom`, `Left`, `Right`, `Middle`, `Fade` that can be chosen to suit the application’s user interface. The `DeleteRows`method can also be used to remove a row. This is commented out below, since running the workbook over and over will remove all the data! Uncomment and execute this block to see a row removal animation. ```csharp /* var ip2 = NSIndexPath.FromRowSection(3, 0); tableView.BeginUpdates(); data.RemoveAt (3); tableView.DeleteRows(new [] {ip1, ip2}, UITableViewRowAnimation.Automatic); tableView.EndUpdates(); */ ``` ## Customizing Each Row Each row that is displayed is supplied to the table view from the source’s `GetCell` method. The code above uses the simplest default cell layout in the `GetCell` method. This method can be further customized to use different built-in or custom cells. ### Built-in Layouts In the updated source class below, the cell is now `UITableViewCellStyle.Subtitle` (instead of `Default`) and the code sets the additional `cell.DetailTextLabel.Text` property. ```csharp public class DetailSource : MySource { string identifier = "newcell"; public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath) { UITableViewCell cell = tableView.DequeueReusableCell (identifier); if (cell == null) { cell = new UITableViewCell (UITableViewCellStyle.Subtitle, identifier); } string item = Data[indexPath.Row]; cell.TextLabel.Text = item; cell.DetailTextLabel.Text = $"{item.Length} characters"; // C# 6 return cell; } } ``` To use this new source with our table, create an instance, assign the data list, and tell the `tableView` to use this as its `Source`: ```csharp source = new DetailSource(); // create the new class source.Data = data; // assign the list of strings tableView.Source = source; // give it to the table view (replaces the old one) tableView.ReloadData(); // reload the data with new cell layout ``` The table rows now contain two pieces of text! ![](detailsource.png) `UITableViewCellStyle` can also be set to `Value1` and `Value2` which display the text in different ways. It is also possible to display an image - the class below sets the `ImageView` property to a local image file (in this case, the same image is used for every row): ```csharp public class ImageSource : MySource { string identifier = "imagecell"; public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath) { UITableViewCell cell = tableView.DequeueReusableCell (identifier); if (cell == null) { cell = new UITableViewCell (UITableViewCellStyle.Subtitle, identifier); } string item = Data[indexPath.Row]; cell.TextLabel.Text = item; cell.DetailTextLabel.Text = $"{item.Length} characters"; // C# 6 cell.ImageView.Image = UIImage.FromFile("workicon.png"); // now sets an image return cell; } } ``` Now just configure this new source and assign to the table view: ```csharp source = new ImageSource(); // create the new class source.Data = data; // assign the list of strings tableView.Source = source; // give it to the table view (replaces the old one) tableView.ReloadData(); // reload the data, cells now also display an image ``` The cells now look like this! ![](imagesource.png) The other aspect of the cell that can be customized is the accessory – special icons that appear on the right side of the cell. Modify the `GetCell` method above with one of these lines of code to add an accessory to each row: `cell.Accessory = UITableViewCellAccessory.Checkmark; cell.Accessory = UITableViewCellAccessory.DisclosureIndicator; cell.Accessory = UITableViewCellAccessory.DetailDisclosureButton; cell.Accessory = UITableViewCellAccessory.None; // to clear the accessory` ### Custom Cell Layout It’s also possible to create totally custom cell layouts, and use them in the `GetCell` method instead of the built-in layouts. Cells are created programmatically by subclassing `UITableViewCell` and overriding these methods: * the constructor – create the UI controls in the cell. * `LayoutSubviews` – set the location of the UI controls (possibly adjusting them based on the data being displayed). It’s helpful to add an additional method to update the data in the cell, which is called UpdateCell in the example. ```csharp public class MyCell : UITableViewCell { UILabel headingLabel, subheadingLabel; UIImageView imageView; // constructor: create the controls to display public MyCell (string cellId) : base (UITableViewCellStyle.Default, cellId) { ContentView.BackgroundColor = UIColor.FromRGB (218, 255, 127); imageView = new UIImageView(); headingLabel = new UILabel () { Font = UIFont.FromName("Cochin-BoldItalic", 22f), TextColor = UIColor.FromRGB (127, 51, 0), BackgroundColor = UIColor.Clear }; subheadingLabel = new UILabel () { Font = UIFont.FromName("AmericanTypewriter", 12f), TextColor = UIColor.FromRGB (38, 127, 0), TextAlignment = UITextAlignment.Center, BackgroundColor = UIColor.Clear }; ContentView.AddSubviews(new UIView[] {headingLabel, subheadingLabel, imageView}); } // set the location of each control public override void LayoutSubviews () { base.LayoutSubviews (); imageView.Frame = new CGRect (ContentView.Bounds.Width - 63, 5, 33, 33); headingLabel.Frame = new CGRect (5, 4, ContentView.Bounds.Width - 63, 25); subheadingLabel.Frame = new CGRect (100, 18, 100, 20); } // update the cell's data public void UpdateCell (string caption, string subtitle, UIImage image) { imageView.Image = image; headingLabel.Text = caption; subheadingLabel.Text = subtitle; } } ``` Once again we need to update the source class `GetCell` method to return instances of the custom cell. The `CustomSource` class shown below now creates instances of the custom cell and uses the `UpdateCell` method to pass the data values to display: ```csharp public class CustomSource : MySource { string identifier = "imagecell"; public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath) { MyCell cell = tableView.DequeueReusableCell (identifier) as MyCell; if (cell == null) { cell = new MyCell (identifier); } string item = Data[indexPath.Row]; cell.UpdateCell(item, $"{item.Length} characters", UIImage.FromFile("workicon.png")); return cell; } } ``` Wiring up the new source object works uses the same code as before: ```csharp source = new CustomSource(); // create the new class source.Data = data; // assign the list of strings tableView.Source = source; // give it to the table view (replaces the old one) tableView.ReloadData(); // reload the data, cells now also display an image ``` The custom cells now look like this: ![](customsource.png) ## Row Selection To respond to users touching a row override then `RowSelected` in the source class. The example below shows a source class with the `RowSelected` method added (the rest of the class is unchanged): ```csharp public class SelectionSource : MySource { string identifier = "selectioncell"; public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath) { UITableViewCell cell = tableView.DequeueReusableCell (identifier); if (cell == null) { cell = new UITableViewCell (UITableViewCellStyle.Subtitle, identifier); } string item = Data[indexPath.Row]; cell.TextLabel.Text = item; cell.DetailTextLabel.Text = $"{item.Length} characters"; // C# 6 cell.ImageView.Image = UIImage.FromFile("workicon.png"); // now sets an image return cell; } public override void RowSelected (UITableView tableView, NSIndexPath indexPath) { var okAlertController = UIAlertController.Create ("Row Selected", Data[indexPath.Row] + " was touched", UIAlertControllerStyle.Alert); okAlertController.AddAction (UIAlertAction.Create("OK", UIAlertActionStyle.Default, null)); // real apps wouldn't use KeyWindow, this is a "workbook" limitation KeyWindow.RootViewController.PresentViewController (okAlertController, true, null); tableView.DeselectRow (indexPath, true); // de-select (otherwise it stays "grey") } } ``` The RowSelected method is implemented to show an alert popup when each row is tapped. Each app will implement this differently – perhaps a new view controller is shown instead. Note the last line of the method where `DeselectRow` is called: this is recommended to return the table view to the initial appearance. If the row isn’t deselected, it remains “grey” (or whatever selection-color is defined). Wiring it up follows the same pattern as previously. Once this source is used, the rows are “click-able”! ```csharp source = new SelectionSource(); // create the new class source.Data = data; // assign the list of strings tableView.Source = source; // give it to the table view (replaces the old one) tableView.ReloadData(); // reload the data, cells now also display an image ``` The alert will show like this (but you can customize the code to change it 😉): ![](selectionsource.png) ## Row Actions The buttons that are revealed when a row is swiped to the left are called *row actions*. Configuring row actions in a cell (and handling when they are touched) is done by adding another method override to the source class. The `ActionSource` class below includes the `EditActionsForRow` method which creates a single action (an array can be supplied to show more than one). ```csharp public class ActionSource : MySource { string identifier = "actioncell"; public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath) { UITableViewCell cell = tableView.DequeueReusableCell (identifier); if (cell == null) { cell = new UITableViewCell (UITableViewCellStyle.Subtitle, identifier); } string item = Data[indexPath.Row]; cell.TextLabel.Text = item; cell.DetailTextLabel.Text = $"{item.Length} characters"; // C# 6 cell.ImageView.Image = UIImage.FromFile("workicon.png"); // now sets an image return cell; } public override void RowSelected (UITableView tableView, NSIndexPath indexPath) { ShowAlert("Row Selected", Data[indexPath.Row] + " was touched"); tableView.DeselectRow (indexPath, true); // de-select (otherwise it stays "grey") } // refactor out the alert, so it can be used in selection & action void ShowAlert(string title, string text) { var okAlertController = UIAlertController.Create (title, text, UIAlertControllerStyle.Alert); okAlertController.AddAction (UIAlertAction.Create("OK", UIAlertActionStyle.Default, null)); // real apps wouldn't use KeyWindow, this is a "workbook" limitation KeyWindow.RootViewController.PresentViewController (okAlertController, true, null); } // public override UITableViewRowAction[] EditActionsForRow (UITableView tableView, NSIndexPath indexPath) { var hiAction = UITableViewRowAction.Create ( UITableViewRowActionStyle.Normal, // try the Destructive style "Hi", delegate { ShowAlert("Action Revealed", Data[indexPath.Row] + " was 'actioned'"); }); // multiple actions are allowed return new UITableViewRowAction[] { hiAction }; } } ``` Apply this new source class to the table: ```csharp source = new ActionSource(); // create the new class source.Data = data; // assign the list of strings tableView.Source = source; // give it to the table view (replaces the old one) tableView.ReloadData(); // reload the data, cells now also display an image ``` The action looks like this when revealed by a swipe on the row. This example is grey because `UITableViewRowActionStyle.Normal` was specified in the code. ![](actionsource.png) `UITableViewRowActionStyle.Destructive` can be specified, which shows the action with a red background. As mentioned earlier, mulitple actions can be shown for a row - but if mulitple actions are shown there should never be more than one *destructive* action. ## Edit Mode There is another more complex way to interact with tables: edit mode. Edit mode is an optional state for the table which users typically turn on with a button-press. Implementing edit mode requires overriding a number of methods in the source class: * \*\*CanEditRow \*\*– whether each row can be edited. Return false to prevent both swipe-to-delete and deletion while in edit mode. * \*\*CanMoveRow \*\*– return true to enable the move ‘handle’ or false to prevent moving. * \*\*EditingStyleForRow \*\*– when the table is in edit mode, the return value from this method determines whether the cell displays the red deletion icon or the green add icon. Return UITableViewCellEditingStyle.None if the row should not be editable. * \*\*MoveRow \*\*– called when a row is moved so that the underlying data structure can be modified to match the data as it is displayed in the table. * **TitleForDeleteConfirmation** – optional custom text for the delete button. * **CommitEditingStyle** – code to apply changes to the underlying data when an edit is complete (ie. if a row is deleted). ```csharp public partial class EditSource : MySource { string identifier = "editcell"; public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath) { UITableViewCell cell = tableView.DequeueReusableCell (identifier); if (cell == null) { cell = new UITableViewCell (UITableViewCellStyle.Subtitle, identifier); } string item = Data[indexPath.Row]; cell.TextLabel.Text = item; cell.DetailTextLabel.Text = $"{item.Length} characters"; // C# 6 cell.ImageView.Image = UIImage.FromFile("workicon.png"); // now sets an image return cell; } public override void RowSelected (UITableView tableView, NSIndexPath indexPath) { ShowAlert("Row Selected", Data[indexPath.Row] + " was touched"); tableView.DeselectRow (indexPath, true); // de-select (otherwise it stays "grey") } // refactor out the alert, so it can be used in selection & action void ShowAlert(string title, string text) { var okAlertController = UIAlertController.Create (title, text, UIAlertControllerStyle.Alert); okAlertController.AddAction (UIAlertAction.Create("OK", UIAlertActionStyle.Default, null)); // real apps wouldn't use KeyWindow, this is a "workbook" limitation KeyWindow.RootViewController.PresentViewController (okAlertController, true, null); } public override bool CanEditRow (UITableView tableView, NSIndexPath indexPath) { return true; // return false if you wish to disable editing for a specific indexPath or for all rows } public override bool CanMoveRow (UITableView tableView, NSIndexPath indexPath) { return true; // return false if you don't allow re-ordering } public override UITableViewCellEditingStyle EditingStyleForRow (UITableView tableView, NSIndexPath indexPath) { return UITableViewCellEditingStyle.Delete; // this example doesn't suppport Insert } public override string TitleForDeleteConfirmation (UITableView tableView, NSIndexPath indexPath) { // Optional - default text is 'Delete' return "Trash it!"; } } ``` ```csharp public partial class EditSource : MySource { public override void CommitEditingStyle (UITableView tableView, UITableViewCellEditingStyle editingStyle, Foundation.NSIndexPath indexPath) { switch (editingStyle) // in case others are implemented { case UITableViewCellEditingStyle.Delete: // remove the item from the underlying data source Data.RemoveAt(indexPath.Row); // delete the row from the table tableView.DeleteRows (new NSIndexPath[] { indexPath }, UITableViewRowAnimation.Fade); break; } } public override void MoveRow (UITableView tableView, NSIndexPath sourceIndexPath, NSIndexPath destinationIndexPath) { var item = Data[sourceIndexPath.Row]; var deleteAt = sourceIndexPath.Row; var insertAt = destinationIndexPath.Row; // are we inserting if (destinationIndexPath.Row < sourceIndexPath.Row) { // add one to where we delete, because we're increasing the index by inserting deleteAt += 1; } else { // add one to where we insert, because we haven't deleted the original yet insertAt += 1; } Data.Insert (insertAt, item); Data.RemoveAt (deleteAt); } } ``` Once again, apply the new source to the table: ```csharp source = new EditSource(); // create the new class source.Data = data; // assign the list of strings tableView.Source = source; // give it to the table view (replaces the old one) tableView.ReloadData(); // reload the data, cells now also display an image ``` The table will remain in “normal” mode until editing is enabled. In a “real life” app a button should be provided (typically in the navigation bar), but for this workbook the edit mode can be set dynamically with the following line of code: ```csharp tableView.SetEditing (true, true); // enable edit mode ``` To restore “normal” mode, uncomment and run the following block: ```csharp //tableView.SetEditing (false, true); // disable edit mode (return to normal table behavior) ``` When edit mode is enabled, rows can no longer be “selected” - instead they can be re-ordered with the drag-handle on the right OR the Delete button can be exposed by touching the red-circle on the left. Note that this button is *different* to any row actions that have been defined. ![](editsource.png) ================================================ FILE: ios/user-interface/web-views/web-views.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook platforms: - iOS --- # Web Views in iOS Apple has released a number of ways for app developers to incorporate web view functionality in their apps. Most users utilize the built-in Safari web browser on their iOS device and therefore expect that web-view functionality from other apps is consistent with this experience. This workbook will explore opening Safari from inside an app, as well as the following web views provided by Apple: * UIWebView * WKWebView * SFSafariViewController ### SetUp The following using directives are necessary when using the above web views: ```csharp using System; using Foundation; using SafariServices; using UIKit; using WebKit; ``` ```csharp #load "tabbar.csx" ``` ```csharp NSUrl url = new NSUrl("https://developer.xamarin.com"); ``` ## UIWebView * `UIWebView` is Apple's legacy way of providing web content in your app. It was released in iOS 2.0 and has been deprecated as of 8.0. * If you plan to support iOS versions earlier than 8.0, you will have to use `UIWebView`. * It is recommended that you should check the user's iOS version as `UIWebView` is less optimized for performance than the alternatives. If it 8.0 or above, using either of the options explain below will create a better user experience. ```csharp var webView = new UIWebView (tabController.webViewTab.View.Bounds); tabController.webViewTab.View.AddSubview(webView); webView.LoadRequest(new NSUrlRequest(url)); ``` ## WKWebView * Introduced in iOS 8 * Uses the Nitro Javascript engine, the same engine used by mobile Safari. * WKWebView should always be used over UIWebView were possible due to the increased performance, built-in user-friendly gestures, and the ease of interaction between the web page and your app. * `WKWebView` can be added to your app in an almost identical way to UIWebView, however as the developer you have much more control over the UI/UX and functionality. * Creating and displaying the web view object will display the requested page, however, you can control how to present the view, how the user can navigate, and how the user exits the view. ```csharp var webkitWebView = new WKWebView (tabController.WKWebTab.View.Frame, new WKWebViewConfiguration ()); tabController.WKWebTab.View.AddSubview (webkitWebView); var request = new NSUrlRequest (url); webkitWebView.LoadRequest (request); ``` ## SFSafariViewController * Available in iOS and later * Unlike `UIWebView` or `WKWebView`, `SFSafariViewController` is a View Controller and so cannot be used with other views. * Uses the Nitro Javascript Engine * Provides a range of additional Safari features such as AutoFill, Reader, and the ability to share cookies and data with mobile Safari * by default, implements a **Done** button, allowing to user to easily return to the app. * Provides forward and back navigation buttons, allowing users to navigate through a stack of web pages. * Provides the user with an address bar giving them the peace of mind that they are on the expected web page. The address bar does not allow the user to change the URL. * SFSafariViewController cannot be customized. ```csharp var safariButton = UIButton.FromType(UIButtonType.System); safariButton.Frame = new CGRect(50, 50, 200, 200); safariButton.SetTitle("Go to Site", UIControlState.Normal); tabController.safariVCTab.View.AddSubview(safariButton); safariButton.TouchUpInside += delegate{ var sfViewController = new SFSafariViewController(url); tabController.safariVCTab.PresentViewController(sfViewController, true, null); } ``` ## Safari Navigating users away from an app to Safari should generally be avoided. Most users will not expect navigation outside of the application, so if they navigate away from the app, users may never return it, therefore killing engagement with your app. iOS 9 improvements allow the user to easily return to the app through a back button that is provided in the top left corner of the Safari page. ```csharp var button = UIButton.FromType(UIButtonType.System); button.Frame = new CGRect(50, 50, 200, 200); button.SetTitle("Go to Site", UIControlState.Normal); tabController.safariTab.View.AddSubview(button); button.TouchUpInside += delegate { UIApplication.SharedApplication.OpenUrl(url); }; ``` This produces the following web view: ![](safari.png) ================================================ FILE: ios/user-interface/web-views/web-views.workbook/tabbar.csx ================================================ public class TabController : UITabBarController{ public UIViewController safariTab, webViewTab, WKWebTab, safariVCTab; public TabController (){ safariTab = new UIViewController(){Title = "Safari"}; safariTab.View.BackgroundColor = UIColor.White; webViewTab = new UIViewController(){Title = "UIWebView"}; WKWebTab = new UIViewController(){Title="WKWebView"}; safariVCTab = new UIViewController(){Title="SFSafariViewController"}; safariVCTab.View.BackgroundColor = UIColor.White; var tabs = new UIViewController[]{webViewTab, WKWebTab, safariVCTab, safariTab}; ViewControllers = tabs; } } var tabController = new TabController(); KeyWindow.RootViewController = tabController; ================================================ FILE: mac/README.md ================================================ Xamarin.Mac Workbooks ============ Use the workbooks in this section to learn and experiment with many of the features available to a Xamarin.Mac developer in macOS: * [Getting Started](getting-started) - Covers the techniques required to get started with Xamarin.Mac based workbooks. * [User Interface](user-interface) - Covers many of the common elements used to create a Xamarin.Mac app's User Interface such as Windows, Toolbars and Table Views. ================================================ FILE: mac/getting-started/README.md ================================================ Getting Started ============ This section covers the techniques required to get started with Xamarin.Mac based workbooks. ## Hello, Mac Workbook Getting started with the Mac agent requires a little more setup than the others, because there’s have a whole windowing system to configure. Follow these steps in this workbook to display “Hello, Workbooks” window. ![](screenshots/Intro01.png) ================================================ FILE: mac/getting-started/hello-mac-workbook.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacMobile --- # Mac Getting started with the Mac agent requires a little more setup than the others, because there’s have a whole windowing system to configure! Follow these steps below to display “Hello, Workbooks”! ```csharp using System; using Foundation; using AppKit; using CoreGraphics; public class CodeBasedWindow : NSWindow { #region Computed Properties public NSTextField ClickMeLabel { get ; set;} #endregion #region Constructors public CodeBasedWindow (IntPtr handle) : base (handle) { } [Export ("initWithCoder:")] public CodeBasedWindow (NSCoder coder) : base (coder) { } public CodeBasedWindow (CGRect contentRect, NSWindowStyle aStyle, NSBackingStore bufferingType, bool deferCreation): base (contentRect, aStyle,bufferingType,deferCreation) { // Create a title for the window Title = "Window From Code"; // Create the content view for the window and make it fill the window ContentView = new NSView (Frame); ClickMeLabel = new NSTextField (new CGRect (10, Frame.Height - 65, Frame.Width - 130, 20)) { BackgroundColor = NSColor.Clear, TextColor = NSColor.Black, Editable = false, Bezeled = false, AutoresizingMask = NSViewResizingMask.WidthSizable | NSViewResizingMask.MinYMargin, StringValue = "Hello, Workbooks!" }; ContentView.AddSubview (ClickMeLabel); } #endregion #region Override Methods public override void AwakeFromNib () { base.AwakeFromNib (); } #endregion } ``` and then ```csharp using System; using Foundation; using AppKit; using CoreGraphics; public class CodeBasedWindowController : NSWindowController { #region Computed Properties public new CodeBasedWindow Window { get { return base.Window as CodeBasedWindow; } } #endregion #region Constructors public CodeBasedWindowController (IntPtr handle) : base (handle) { } [Export ("initWithCoder:")] public CodeBasedWindowController (NSCoder coder) : base (coder) { } public CodeBasedWindowController () : base ("CodeBasedWindow") { // Define the Window's default location and size CGRect contentRect = new CGRect (0, 0, 500, 300); // Create a new instance of the CodeBasedWindow base.Window = new CodeBasedWindow(contentRect, (NSWindowStyle.Titled | NSWindowStyle.Closable | NSWindowStyle.Miniaturizable | NSWindowStyle.Resizable), NSBackingStore.Buffered, false); // Simulate Awaking from Nib Window.AwakeFromNib (); } #endregion #region Override Methods public override void AwakeFromNib () { base.AwakeFromNib (); } #endregion } ``` finally ```csharp var mainWindowController = new CodeBasedWindowController (); mainWindowController.Window.MakeKeyAndOrderFront ((NSObject)NSApplication.SharedApplication.Delegate); ``` ================================================ FILE: mac/getting-started/meta.json ================================================ { "order":{ "hello-mac-workbook.workbook":"Hello, Mac" } } ================================================ FILE: mac/meta.json ================================================ { "order":{ "getting-started":"Getting Started", "user-interface":"User Interface" } } ================================================ FILE: mac/user-interface/README.md ================================================ # Xamarin.Mac User Interface Workbooks The workbooks in this section cover many of the common elements used to create a Xamarin.Mac app's User Interface such as Windows, Toolbars and Table Views. Because of the way workbooks function, many of the workbooks in this section will cover the steps required to build a Xamarin.Mac app's User Interface directly from C# code without using a Xcode's Interface Builder `.storyboard` or `.xib` file. For more information, please see our [Hello, Mac](https://developer.xamarin.com/guides/mac/getting_started/hello,_mac/), [Introduction to Storyboards](https://developer.xamarin.com/guides/mac/platform-features/storyboards/), [Working with .xib Files](https://developer.xamarin.com/guides/mac/application_fundamentals/working-with-xibs/) and [.storyboard/.xib Less User Interface Design](https://developer.xamarin.com/guides/mac/application_fundamentals/xibless-ui/) documentation. # Available Workbooks The following User Interface workbooks are available for Xamarin.mac: ## [Working with Outline Views](outlineview) This workbook will cover working with a Outline View (`NSOutlineView`) in a Xamarin.Mac app's User Interface. `NSOutlineView` is a native cocoa control for displaying tree data. ![](outlineview/screenshots/Intro01.png) ## [Working with Table Views](tableview) This workbook will cover working with a Table View (`NSTableView`) in a Xamarin.Mac app's User Interface. `NSTableView` is a native cocoa control for displaying data in a table. ![](tableview/screenshots/Intro01.png) ## [Working with Toolbars Workbook](toolbars) This workbook will cover working with a Toolbar (`NSToolbar`) in a Xamarin.Mac app's User Interface. `NSToolbar` is a native cocoa control for adding a user configurable Toolbar to the top of a Window (`NSWindow`). ![](toolbars/screenshots/Intro01.png) ## [.storyboard/.xib Less User Interface Design Workbook](ui-in-code) This workbook will cover the steps required to build a Xamarin.Mac app's User Interface directly from C# code without using a Xcode's Interface Builder `.storyboard` or `.xib` file. ![](ui-in-code/screenshots/Intro01.png) ## [Working with Segues in macOS Storyboard](segues) This workbook will cover the typical uses of Segues within a Storyboard, and how they can be used to limit the amount of code a developer is required to write to present a Xamarin.Mac app’s UI. ![](segues/screenshots/Intro01.png) ## [How to Build a Web Browser in Xamarin.Mac](webbrowser) This workbook will cover the steps required to build a mini, multi-windowed web browser in a Xamarin.Mac app. By going through the steps in this workbook, the reader will gain insights and skills required to work with many elements of a standard macOS app such as Menus, Windows, Window Controllers, Views, View Controllers, Toolbars, Text Field, Buttons and the Xcode Interface Builder Storyboard files used to define them. ![](webbrowser/screenshots/Intro01.png) ================================================ FILE: mac/user-interface/meta.json ================================================ { "order":{ "outlineview/NSOutlineView.workbook":"Outline View", "tableview/NSTableView.workbook":"Table View", "toolbars/toolbars.workbook":"Toolbar", "ui-in-code/codebasedui.workbook":"Creating UI in Code", "segues/Segues.workbook":"Storyboard Segues", "webbrowser/webbrowser.workbook":"Web Browser" } } ================================================ FILE: mac/user-interface/outlineview/NSOutlineView.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacMobile --- # Working with Outline Views #### Using a Outline View in a Xamarin.Mac Application This workbook will cover the steps required to add a Outline View (`NSOutlineView`) to a Xamarin.Mac app's User Interface directly from C# code without using a Xcode's Interface Builder `.storyboard` or `.xib` file. ## Creating the Outline View `NSOutlineView` is a native cocoa control for displaying tree data. Start by creating an instance and set its `Frame` property to a reasonable size. It will be autosized via an owning `NSClipView`: ```csharp // Get the parent window's frame var frame = MainWindow.ContentView.Frame; // Make a new outline view and have it fill the parent window NSOutlineView outlineView = new NSOutlineView () { Frame = frame }; ``` ## Adding the Outline View Columns Every `NSOutlineView` must have at least one column for its delegate to be called. Since Outline Views are based on Table Views (`NSTableView`), a Table Column is created and added to the Outline: ```csharp // Create the required column and add it to the outline NSTableColumn column = new NSTableColumn ("Values"); outlineView.AddColumn (column); ``` Additionally, the `OutlineTableColumn` property of the Outline View must be set or the arrows showing children/expansion will not be drawn: ```csharp // Specify the outline column outlineView.OutlineTableColumn = column; ``` ## Adding the Clip View A `NSOutlineView` expects to be hosted inside an `NSClipView`. The following code creates the required Clip View and adds the Outline View to it: ```csharp // Create the required clipping view and set it to // resize both horizontally and vertically as the // parent window resizes. NSClipView clipView = new NSClipView (frame) { AutoresizingMask = NSViewResizingMask.HeightSizable | NSViewResizingMask.WidthSizable }; // Attach the outline view to the clip view clipView.DocumentView = outlineView; ``` Next, add the Clip View to the Window’s Content View to display the Outline: ```csharp // Attach the clip view to the main window MainWindow.ContentView = clipView; ``` ## Creating Sample Data for the Outline Currently, this Outline View isn’t very exciting without any data. A `Node` class will be a created to provide a simple tree-based data structure. Because `NSOutlineViewDataSource` returns a `NSObject`, the `Node` class will inherit from it: ```csharp // Custom class to define the data for the outline view. class Node : NSObject { // The name for the node. public string Name { get; private set; } // A collection of child nodes. List Children; // Initalize a new node with the given name // and create storage for any child nodes. public Node (string name) { Name = name; Children = new List (); } // Create a new child node of a given name // and add it to the collection of child nodes. public Node AddChild (string name) { Node n = new Node (name); Children.Add (n); return n; } // Return the child for a given index public Node GetChild (int index) { return Children [index]; } // Get the curent number of children public int ChildCount => Children.Count; // The node is a leaf node if it has no children public bool IsLeaf => ChildCount == 0; } ``` The following method will create the example data that will be displayed in the Outline View: ```csharp // Populate an example set of parent and child nodes. Node CreateExampleTree () { // Create a base node to hold the data Node parentNode = new Node (""); // Generate a set of parent and child nodes for (int i = 0 ; i < 5 ; ++i) { Node n = parentNode.AddChild ("Parent: " + i); for (int j = 0; j < 3 ; ++j) n.AddChild ("Child: " + j); } // Return the completed sample data return parentNode; } ``` ## Adding Data to the Ouline View `NSOutlineView` uses a two classes, a `DataSource` and `Delegate`, to determine what data to display. `NSOutlineView` can be used in two different “modes”: *Cell Based* or *View Based*. Different overrides apply to each of these modes, such that overriding some of the Cell Based methods will prevent the View Based methods from being called. According to Apple, Cell Based Outlines have been deprecated and View Based Outlines should be used for all modern macOS development. `OutlineViewDelegate` defines the view for an individual element of the tree. The item passed in is generated by `OutlineViewDataSource`. ### Creating the Elements for the Outline For every element, the Outline View calls its `Delegate` to provide the individual Cells. By calling `MakeView` method of the Outline View with an identifier, existing views can be recycled, which can improve performance: ```csharp class OutlineViewDelegate : NSOutlineViewDelegate { // Provide an ID for each cell so it can be reused const string identifer = "myCellIdentifier"; // Generate a new view to act as the cell for each table row and column public override NSView GetView (NSOutlineView outlineView, NSTableColumn tableColumn, NSObject item) { // Ask the table view to reuse a cell NSTextField view = (NSTextField)outlineView.MakeView (identifer, this); // Was a reusable cell available? if (view == null) { // No, create a new cell view = new NSTextField () { Identifier = identifer, Bordered = false, Selectable = false, Editable = false }; } // Populate the cell view.StringValue = ((Node)item).Name; // Return the fully populated cell return view; } } ``` ### Defining the Tree Structure The `OutlineViewDataSource` defines the structures of the tree, how many elements are in the Outline and if those elements are expandable. The `GetChild` method analyzes the `NSObject` that is passed to `GetView` method of the `OutlineViewDelegate`. If the item passed in is `null`, then Cocoa is refering to the root the the tree: ```csharp class OutlineViewDataSource : NSOutlineViewDataSource { // Storage for the outline view data. Node parentNode; // Create a new data source from the given tree data. public OutlineViewDataSource (Node node) { parentNode = node; } // Return the number of children for the given element in the outline. public override nint GetChildrenCount (NSOutlineView outlineView, NSObject item) { // If the passed in element is null, use the parent node. item = item == null ? parentNode : item; // Return the number of children return ((Node)item).ChildCount; } // Return the given child for the given element and index. public override NSObject GetChild (NSOutlineView outlineView, nint childIndex, NSObject item) { // If the passed in element is null, use the parent node. item = item == null ? parentNode : item; // Return the requested child return ((Node)item).GetChild ((int)childIndex); } // If the current item has children, it is expandable. public override bool ItemExpandable (NSOutlineView outlineView, NSObject item) { // If the passed in element is null, use the parent node. item = item == null ? parentNode : item; // Return the expandable state return !((Node)item).IsLeaf; } } ``` ### Displaying the Data Hooking up the `Delegate` and `DataSource` to the `NSOutlineView` is the final step. This will populate the tree with the sample data: ```csharp // Attach the data source and delegate to populate the outline outlineView.Delegate = new OutlineViewDelegate (); outlineView.DataSource = new OutlineViewDataSource (CreateExampleTree ()); ``` ================================================ FILE: mac/user-interface/outlineview/README.md ================================================ Working with Outline Views Workbook ============ This workbook will cover the steps required to add a Outline View (`NSOutlineView`) to a Xamarin.Mac app's User Interface directly from C# code without using a Xcode's Interface Builder `.storyboard` or `.xib` file. ![](screenshots/Intro01.png) ================================================ FILE: mac/user-interface/segues/README.md ================================================ Working with Segues in macOS Storyboard ============ This workbook will cover the typical uses of Segues within a Storyboard, and how they can be used to limit the amount of code a developer is required to write to present a Xamarin.Mac app’s UI. ![](screenshots/Intro01.png) ================================================ FILE: mac/user-interface/segues/Segues.workbook/Main.storyboard ================================================ Default Left to Right Right to Left Default Left to Right Right to Left ================================================ FILE: mac/user-interface/segues/Segues.workbook/StoryboardResources.csx ================================================ using System; using System.Diagnostics; using System.IO; using System.Xml; using System.Collections.Generic; using System.Reflection; using System.Runtime.InteropServices; using System.Linq; using Foundation; using AppKit; using ObjCRuntime; // ------------------------------------------------------------------------- // StoryboardInflator for macOS by Kevin Mullins for Microsoft, Inc. // ------------------------------------------------------------------------- // This library provides limited support for using Storyboard files to // build and display the user interface for a Xamarin.Mac based workbook app. // Because macOS expects a compiled storyboard to be part of a running app's // bundle along with its executable code, the typical mechanisms to create // Outlets, Actions and Segues will not work. Instead, this library applies // the following hack to simulate Outlets: // // 1) Windows and Views (or View based controls such as NSButton), set their // Identifier property in Interface Builder to match the name of the // "Outlet". The StoryboardBinder will populate any like named Public // Property on any class it binds. // // 2) For Menu Items, the StoryboardBinder will use the Title of the Menu // Item + "MenuItem" to populate any like named Public Property on any // class that it binds. For example, the "New" menu item would bind to // the "NewMenuItem" property in class. // // 3) For Toolbar Items, the StoryboardBinder will use the Label of the // Item + "ToolbarItem" to populate any like named Public Property on any // class that it binds. For example, the "Color" menu item would bind to // the "ColorMenuItem" property in class. // // LIMITATIONS: Custom Segues are currently not supported. Instead, the app must // use the StoryboardInflator to inflate and populate any NIB that will then // need to be manually displayed. /// /// Defines the type of a Scene or Source Object used in a Segue. /// public enum StoryboardObjectType { /// /// The application (NSApplication) as defined in the Storyboard. /// Application, /// /// A Menu Item (NSMenuItem). /// MenuItem, /// /// A Window Controller (NSWindowController). /// WindowController, /// /// A Toolbar Item (NSToolbarItem). /// ToolbarItem, /// /// A View Controller (NSViewController). /// ViewController, /// /// Storyboard object type (NSSplitViewController). /// SplitViewController, /// /// A Button (NSButton). /// Button, /// /// An unknown object type /// Unknown } /// /// Defines the kind of Segue as defined in the Storyboard. /// public enum StoryboardSegueType { /// /// Displays the destination controller as a non-modal Window. /// Show, /// /// Displays the destination controller as a modal window. /// Modal, /// /// Displays the destination controller as a sheet. /// Sheet, /// /// Displays the destination controller as a popover. /// Popover, /// /// Displays the destination controller using a Custom Segue Class. /// Custom, /// /// Defines a containment relationship between the source object and the /// destination controller. /// Relationship } /// /// Holds the definition of a Segure as read from a Storyboard. /// public class StoryboardSegueDefinition : NSObject { #region Computed Properties /// /// Gets or sets the inflator used to load NIBs from the Storyboard. /// /// The inflator. public StoryboardInflator Inflator { get; set; } /// /// Gets or sets the type of the scene that they segue belongs to. /// /// The type of the scene. public StoryboardObjectType SceneType { get; set;} /// /// Gets or sets the scene identifier. /// /// The scene identifier. public string SceneID { get; set; } /// /// Gets or sets the type of the source object. /// /// The type of the source object. public StoryboardObjectType SourceObjectType { get; set;} /// /// Gets or sets the source object identifier. /// /// The source object identifier. public string SourceObjectID { get; set; } /// /// Gets or sets the destination controller identifier. /// /// The destination controller identifier. public string DestinationControllerID { get; set;} /// /// Gets or sets the kind of the segue. /// /// The kind of the segue. public StoryboardSegueType SegueKind { get; set; } /// /// Gets or sets the segue identifier. /// /// The segue identifier. public string SegueIdentifier { get; set;} /// /// Gets or sets the relationship. /// /// This is only populated from containment Segues of StoryboardSegueType.Relationship. /// The relationship. public string Relationship { get; set;} /// /// Gets or sets the popover anchor identifier. /// /// The popover anchor identifier. public string PopoverAnchorID { get; set;} /// /// Gets or sets the popover behavior. /// /// The popover behavior. public NSPopoverBehavior PopoverBehavior { get; set; } = NSPopoverBehavior.Transient; /// /// Gets or sets the edge the popover will be displayed from. /// /// 0 = Left, 1 = Top, 2 = Right, 3 = Bottom /// The popover edge. public nuint PopoverEdge { get; set; } = 0; #endregion #region Constructors /// /// Initializes a new instance of the class. /// /// The StoryboardSegueType of the Segue. /// The Inflator used to load NIB files. public StoryboardSegueDefinition (StoryboardSegueType type, StoryboardInflator inflator) { // Initialize SegueKind = type; Inflator = inflator; } /// /// Initializes a new instance of the class. /// /// The string type of the Segue. /// The Inflator used to load NIB files. public StoryboardSegueDefinition (string type, StoryboardInflator inflator) { // Initialize switch (type) { case "show": SegueKind = StoryboardSegueType.Show; break; case "modal": SegueKind = StoryboardSegueType.Modal; break; case "sheet": SegueKind = StoryboardSegueType.Sheet; break; case "popover": SegueKind = StoryboardSegueType.Popover; break; case "custom": SegueKind = StoryboardSegueType.Relationship; break; } Inflator = inflator; } #endregion #region Private Methods /// /// Prepares to execute a segue loading the destination NIB and calling PrepareForSegue /// on the Source Controller so it can prepare the destination controller before it is /// presented to the user. /// /// The NSStoryboardSegue representing this Segue Definition. /// The object that is launching the segue. /// Source controller for the segue. private NSStoryboardSegue PrepareForSegue (NSObject sender, NSObject sourceController) { // Attempt to load destination var destinationController = Inflator.InstantiateControllerForPartialIdentifier (DestinationControllerID); // Was the NIB found? if (destinationController == null) return null; // Build new Segue var segue = new NSStoryboardSegue (SegueIdentifier, sourceController, destinationController); // Does the class contain the PrepareForSegue method? var controllerType = sourceController.GetType (); var methodInfo = controllerType.GetMethod ("PrepareForSegue"); if (methodInfo != null) { // Yes, wireup action to class methodInfo.Invoke (sourceController, new [] { segue, sender }); } // Return controller return segue; } /// /// Presents the non modal window to the user. /// /// The NSStoryboardSegue to execute. private void PresentNonModalWindow (NSStoryboardSegue segue) { NSWindowController windowController = null; // Take action based on the controller type if (segue.DestinationController is NSWindowController) { // Display the window to the user windowController = segue.DestinationController as NSWindowController; } else if (segue.DestinationController is NSViewController) { // Build a Window and Window Controller for this view var viewController = segue.DestinationController as NSViewController; var window = new NSWindow (viewController.View.Bounds, (NSWindowStyle.Titled | NSWindowStyle.Closable | NSWindowStyle.Miniaturizable | NSWindowStyle.Resizable), NSBackingStore.Buffered, false); windowController = new NSWindowController (window); // Attach the View Controller to the Window window.ContentView = viewController.View; window.ContentViewController = viewController; } // Found? if (windowController == null) return; // Present window controller windowController.Window.MakeKeyAndOrderFront ((NSObject)NSApplication.SharedApplication.Delegate); } /// /// Presents the modal window to the user. /// /// The NSStoryboardSegue to execute. private void PresentModalWindow (NSStoryboardSegue segue) { NSWindowController windowController = null; // Take action based on the controller type if (segue.DestinationController is NSWindowController) { // Display the window to the user windowController = segue.DestinationController as NSWindowController; } else if (segue.DestinationController is NSViewController) { // Build a Window and Window Controller for this view var viewController = segue.DestinationController as NSViewController; var window = new NSWindow (viewController.View.Bounds, (NSWindowStyle.Titled | NSWindowStyle.Closable | NSWindowStyle.Miniaturizable | NSWindowStyle.Resizable), NSBackingStore.Buffered, false); windowController = new NSWindowController (window); // Attach the View Controller to the Window window.ContentView = viewController.View; window.ContentViewController = viewController; } // Found? if (windowController == null) return; // Present window controller NSApplication.SharedApplication.RunModalForWindow (windowController.Window); } /// /// Presents the Window or View to the user as a sheet attached to the parent /// Window. /// /// The NSStoryboardSegue to execute. private void PresentSheet (NSStoryboardSegue segue) { NSViewController viewController = null; // Take action based on the controller type if (segue.DestinationController is NSWindowController) { // Display the window to the user var windowController = segue.DestinationController as NSWindowController; viewController = windowController.Window.ContentViewController; } else if (segue.DestinationController is NSViewController) { // Grab view controller viewController = segue.DestinationController as NSViewController; } // Found? if (viewController == null) return; // Present window controller if (segue.SourceController is NSWindowController) { var sourceController = segue.SourceController as NSWindowController; sourceController.Window.ContentViewController.PresentViewControllerAsSheet (viewController); } else if (segue.SourceController is NSViewController) { var sourceController = segue.SourceController as NSViewController; sourceController.PresentViewControllerAsSheet (viewController); } } /// /// Presents the Window or View to the user as a popover attached to a parent /// View. /// /// The NSStoryboardSegue to execute. /// The NSView based element that the popover will be attached to. private void PresentPopover (NSStoryboardSegue segue, NSObject sender) { NSViewController viewController = null; NSView view = null; // Take action based on the controller type if (segue.DestinationController is NSWindowController) { // Display the window to the user var windowController = segue.DestinationController as NSWindowController; viewController = windowController.Window.ContentViewController; } else if (segue.DestinationController is NSViewController) { // Grab view controller viewController = segue.DestinationController as NSViewController; } // Found? if (viewController == null) return; // Take action based on sender type if (sender is NSToolbarItem) { var item = sender as NSToolbarItem; if (item.View == null) { // Default to presenting as a sheet PresentSheet (segue); return; } else { // Use the items view view = item.View; } } else { // It's a view based control view = sender as NSView; } // Present window controller if (segue.SourceController is NSWindowController) { var sourceController = segue.SourceController as NSWindowController; sourceController.Window.ContentViewController.PresentViewController (viewController, viewController.View.Bounds, view, PopoverEdge, PopoverBehavior); } else if (segue.SourceController is NSViewController) { var sourceController = segue.SourceController as NSViewController; sourceController.PresentViewController (viewController, viewController.View.Bounds, view, PopoverEdge, PopoverBehavior); } } #endregion #region Public Methods /// /// Performs the segue as specified in this Segue Definition. /// /// The object that is launching the segue. /// Source controller for the segue. public void PerformSegue (NSObject sender, NSObject sourceController) { //NSApplication.SharedApplication.KeyWindow.Title = "Loading Segue"; // Prepare for segue var segue = PrepareForSegue (sender, sourceController); // Did the NIB load? if (segue == null) return; //NSApplication.SharedApplication.KeyWindow.Title = "Segue Loaded"; // Take action based on the Segue type switch (SegueKind) { case StoryboardSegueType.Show: PresentNonModalWindow (segue); break; case StoryboardSegueType.Modal: PresentModalWindow (segue); break; case StoryboardSegueType.Sheet: PresentSheet (segue); break; case StoryboardSegueType.Popover: PresentPopover (segue, sender); break; } } /// /// Sets the popover behavior. /// /// Behavior as a string value. public void SetPopoverBehavior (string behavior) { // Anything to do? if (behavior == null) return; // Take action based on value switch (behavior) { case "t": PopoverBehavior = NSPopoverBehavior.Transient; break; case "semitransient": PopoverBehavior = NSPopoverBehavior.Semitransient; break; case "applicationDefined": PopoverBehavior = NSPopoverBehavior.ApplicationDefined; break; } } /// /// Sets the popover edge. /// /// Edge as a string value. public void SetPopoverEdge (string edge) { // Anything to do? if (edge == null) return; // Take action based on value switch (edge) { case "minX": PopoverEdge = 0; break; case "minY": PopoverEdge = 1; break; case "maxX": PopoverEdge = 2; break; case "maxY": PopoverEdge = 3; break; } } #endregion } /// /// Helper class used to compile a storyboard included in a workbook. /// public static class StoryboardCompiler { #region Public Methods /// /// Compiles the specified storyboardName. /// /// The Storyboard name of the storyboard to compile without the `.storyboard` extension. public static void Compile (string storyboardName) { // Assemble the Interface Builder compiler call var dir = Directory.GetCurrentDirectory (); var command = "ibtool"; var arguments = $"\"{dir}/{storyboardName}.storyboard\" --compile \"{dir}/{storyboardName}.storyboardc\""; // Prepare to call the system to invoke the ibtool var startInfo = new ProcessStartInfo () { FileName = command, Arguments = arguments, UseShellExecute = false, CreateNoWindow = true, RedirectStandardOutput = true, RedirectStandardError = true, RedirectStandardInput = true, UserName = System.Environment.UserName }; // Invoke the ibtool and write the results to the // console using (Process process = Process.Start (startInfo)) { // Monitor for exit} process.WaitForExit (); using (var output = process.StandardOutput) { var results = output.ReadToEnd (); Console.WriteLine ("Results: {0}", (results == "") ? "Successful" : results); } } } #endregion } /// /// The StoryboardBinder class provides a mechanism to bind objects inflated from a /// compiled Storyboard NIB file to classes in a workbook. Currently it can bind: /// NSMenu, NSToolBar, NSWindowController, NSWindow, NSViewController, NSView and /// any NSView base controls (such as NSButton). /// /// It uses the following hack to support Outlets: a) NSWindow and NSView based /// controls are bound to Public Properties matching their Identifier property, /// b) NSMenuItems are bound to Public Properties matching Title + "MenuItem", /// c) NSToolbarItems are bound to Public Properties matching Label + "ToolbarItem". /// /// Custom Segues are currently not supported. For many standard items (such as /// NSButton and NSImageView), images will attempted to be bound to `.png` files of /// the same name in an `Images` directory in the workbooks directory. /// public static class StoryboardBinder { #region Public Methods /// /// Bind the specified storyboardClass and workbookClass. For high-level classes /// like NSWindowController and NSViewController, the binder will walk down the /// tree of objects binding lower-level items along the chain. /// /// The high-level storyboard (or workbook) class to bind from. /// The workbook class to bind to. public static void Bind (NSObject storyboardClass, NSObject workbookClass) { // Take action based on the source object type if (storyboardClass is NSMenu) { BindMenu (storyboardClass as NSMenu, workbookClass); } else if (storyboardClass is NSWindowController) { BindWindowController (storyboardClass as NSWindowController, workbookClass); } else if (storyboardClass is NSWindow) { BindWindow (storyboardClass as NSWindow, workbookClass); } else if (storyboardClass is NSViewController) { BindViewController (storyboardClass as NSViewController, workbookClass); } else if (storyboardClass is NSView) { BindView (storyboardClass as NSView, workbookClass); } else if (storyboardClass is NSToolbar) { BindToolbar (storyboardClass as NSToolbar, workbookClass); } } /// /// Attempts to bind an NSImage that has been specified in Interface Builder in the /// form `TheImage.png` to a like-named image file in the `Images` directory in the /// same directory as the workbook. /// /// The NSImage loaded from the `Images` directory or the passed-in NSImage if not found. /// The source NSImage as specified in Interface Builder. public static NSImage BindImage (NSImage image) { // Has an image been specified? if (image !=null && image.Name != null && image.Name.Contains (".png")) { // Yes, attempt load the image resource var imageName = $"Images/{image.Name}"; // Does the file exist? if (File.Exists (imageName)) { // Yes, load new image image = new NSImage (imageName); } } return image; } /// /// Binds any Menu Item to a Public Property in a workbook class that matches /// Title + "MenuItem". For example, the "New" Menu Item to the "NewMenuItem" /// Property. /// /// Any image specified in an item will also attemp to be bound. /// The NSMenu to bind. /// The workbook class to bind to. public static void BindMenu (NSMenu menu, NSObject workbookClass) { // Bind all menu items for (nint n = 0; n < menu.Count; ++n) { var menuItem = menu.ItemAt (n); // Bind identity using a hack var propertyName = $"{menuItem.Title.Replace (" ", "").Replace ("…", "")}MenuItem"; BindProperty (propertyName, workbookClass, menuItem); // Bind image menuItem.Image = BindImage (menuItem.Image); // Bind actions BindAction (menuItem.Action, workbookClass, menuItem); // Has segue? if (menuItem.Target is StoryboardSegueDefinition) { var segue = menuItem.Target as StoryboardSegueDefinition; // Bind it menuItem.Activated += (sender, e) => { segue.PerformSegue (menuItem, workbookClass); }; } // Scan sub menus if (menuItem.Submenu != null) { BindMenu (menuItem.Submenu, workbookClass); } } } /// /// Binds any Toolbar Item to A Public Property in a workbook class that matches /// Label + "ToolbarItem". For example, the "Color" Toolbar Item to the "ColorToolbarItem" /// Property. /// /// Any image specified in an item will also attemp to be bound. /// The NSToolbar to bind. /// The workbook class to bind to. public static void BindToolbar (NSToolbar toolbar, NSObject workbookClass) { // Bind all items on the Toolbar foreach (NSToolbarItem item in toolbar.Items) { // Bind identity using a hack var propertyName = $"{item.Label.Replace (" ", "")}ToolbarItem"; BindProperty (propertyName, workbookClass, item); // Bind Images item.Image = BindImage (item.Image); // Bind actions BindAction (item.Action, workbookClass, item); // Has segue? if (item.Target is StoryboardSegueDefinition) { var segue = item.Target as StoryboardSegueDefinition; // Bind it item.Activated += (sender, e) => { segue.PerformSegue (item, workbookClass); }; } } } /// /// Binds the Window Controller to the given workbook class. This method will walk down the /// tree of objects binding lower-level classes as well. /// /// The NSWindowController to bind from. /// The workbook class to bind to. public static void BindWindowController (NSWindowController controller, NSObject workbookClass) { // Bind controlled window BindWindow (controller.Window, workbookClass); // Binding to a Window Controller? if (workbookClass is NSWindowController) { // Yes, bind controllers var windowController = workbookClass as NSWindowController; windowController.Window = controller.Window; // Is the window loaded? if (windowController.IsWindowLoaded) { // Simulate the window being loaded by the workbook's controller instance windowController.WindowWillLoad (); windowController.WindowDidLoad (); } } } /// /// Binds the Window to the given workbook class. This method will walk down the tree /// of objects binding lower-level classes as well. /// /// The NSWindow to bind from. /// The workbook class to bind to. public static void BindWindow (NSWindow window, NSObject workbookClass) { // Bind identity BindProperty (window.Identifier, workbookClass, window); // Does the window have a toolbar? if (window.Toolbar != null) { // Yes, bind it BindToolbar (window.Toolbar, workbookClass); } // Binding to a window instance? if (workbookClass is NSWindow && workbookClass.GetType ().Name == window.Identifier) { // Yes, bind objects var wbWindow = workbookClass as NSWindow; wbWindow.ContentViewController = window.ContentViewController; wbWindow.ContentView = window.ContentView; } // Does the window contain a Split View if (window.ContentView is NSSplitView) { // Bind split view contents BindSplitView (window.ContentView as NSSplitView, workbookClass); } else { // Bind content view controller BindViewController (window.ContentViewController, workbookClass); } } /// /// Binds the split view to the given workbook class. This method will walk down the /// tree of objects binding lower-level classes as well. /// /// Split view being bound. /// The workbook class to bind to. public static void BindSplitView (NSSplitView splitView, NSObject workbookClass) { // Bind identity BindProperty (splitView.Identifier, workbookClass, splitView); // Bind all the attached views foreach (NSView view in splitView.ArrangedSubviews) { // Bind controlled view BindView (view, workbookClass); } // Binding to a view controller? if (workbookClass is NSViewController) { // Yes, bind controllers var viewController = workbookClass as NSViewController; viewController.View = splitView; // Simulate the view being loaded by the workbook's controller instance viewController.ViewDidLoad (); viewController.ViewWillAppear (); viewController.ViewDidAppear (); viewController.ViewWillLayout (); viewController.ViewDidLayout (); } } /// /// Binds the View Controller to the given workbook class. This method will walk down the /// tree of objects binding lower-level classes as well. /// /// The NSViewController to bind from. /// The workbook class to bind to. public static void BindViewController (NSViewController controller, NSObject workbookClass) { // Bind controlled view BindView (controller.View, workbookClass); // Binding to a view controller? if (workbookClass is NSViewController) { // Yes, bind controllers var viewController = workbookClass as NSViewController; viewController.View = controller.View; // Is the view loaded? if (controller.ViewLoaded) { // Simulate the view being loaded by the workbook's controller instance viewController.ViewDidLoad (); viewController.ViewWillAppear (); viewController.ViewDidAppear (); viewController.ViewWillLayout (); viewController.ViewDidLayout (); } } } /// /// Binds the View to the given workbook class. This method will transverse all SubViews /// in the given tree. /// /// Any image specified in a known item will also attemp to be bound. /// The NSView to bind from. /// The workbook class to bind to. public static void BindView (NSView view, NSObject workbookClass) { // Bind identity BindProperty (view.Identifier, workbookClass, view); // Bind images for known items if (view is NSButton) { var button = view as NSButton; button.Image = BindImage (button.Image); BindAction (button.Action, workbookClass, button); // Has segue? if (button.Target is StoryboardSegueDefinition) { var segue = button.Target as StoryboardSegueDefinition; // Bind it button.Activated += (sender, e) => { segue.PerformSegue (button, workbookClass); }; } } else if (view is NSPopUpButton) { var popup = view as NSPopUpButton; foreach (NSMenuItem item in popup.Items ()) { item.Image = BindImage (item.Image); } BindAction (popup.Action, workbookClass, popup); } else if (view is NSSegmentedControl) { var segment = view as NSSegmentedControl; for (nint n = 0; n < segment.SegmentCount; ++n) { var image = segment.GetImage (n); segment.SetImage (BindImage (image), n); } BindAction (segment.Action, workbookClass, segment); } else if (view is NSImageView) { var image = view as NSImageView; image.Image = BindImage (image.Image); } // Bind every subview foreach (NSView subview in view.Subviews) { BindView (subview, workbookClass); } } #endregion #region Private Methods /// /// Attempts to bind an object inflated from a compiled Storyboard to an "Outlet" /// property on the given workbook class. This hack is a workaround since true /// Storyboard Outlets are not supported in workbooks. /// /// The name of the Public Property to bind the Outlet to. /// The workbook class being bound to. /// The object inflated from the compiled Storyboard. private static void BindProperty (string propertyName, NSObject workbookClass, NSObject property) { // Anything to process? if (propertyName == null) return; // Does the controller contain the property? var controllerType = workbookClass.GetType (); var propertyInfo = controllerType.GetProperty (propertyName); if (propertyInfo != null && propertyInfo.CanWrite) { // Yes, save value in class var value = Convert.ChangeType (property, propertyInfo.PropertyType); propertyInfo.SetValue (workbookClass, value); } } /// /// Attempts to bind an object inflated from a compiled Storyboard to an "Action" /// property on the given workbook class. This hack is a workaround since true /// Storyboard Actions are not supported in workbooks. /// /// The selector that represents the Action to bind. /// The workbook class being bound to. /// The Menu Item that is the target of the binding. private static void BindAction (Selector action, NSObject workbookClass, NSMenuItem menuItem) { // Anything to process? if (action == null) return; // Switch to .NET style method name var actionName = action.Name.Substring(0,1).ToUpper() + action.Name.Substring(1).Replace (":", ""); // Does the class contain the method? var controllerType = workbookClass.GetType (); var methodInfo = controllerType.GetMethod (actionName); if (methodInfo != null) { // Yes, wireup action to class menuItem.Activated += (sender, e) => { methodInfo.Invoke (workbookClass, new [] { sender }); }; } } /// /// Attempts to bind an object inflated from a compiled Storyboard to an "Action" /// property on the given workbook class. This hack is a workaround since true /// Storyboard Actions are not supported in workbooks. /// /// The selector that represents the Action to bind. /// The workbook class being bound to. /// The Toolbar Item that is the target of the binding. private static void BindAction (Selector action, NSObject workbookClass, NSToolbarItem toolbarItem) { // Anything to process? if (action == null) return; // Switch to .NET style method name var actionName = action.Name.Substring (0, 1).ToUpper () + action.Name.Substring (1).Replace (":", ""); // Does the class contain the method? var controllerType = workbookClass.GetType (); var methodInfo = controllerType.GetMethod (actionName); if (methodInfo != null) { // Yes, wireup action to class toolbarItem.Activated += (sender, e) => { methodInfo.Invoke (workbookClass, new [] { sender }); }; } } /// /// Attempts to bind an object inflated from a compiled Storyboard to an "Action" /// property on the given workbook class. This hack is a workaround since true /// Storyboard Actions are not supported in workbooks. /// /// The selector that represents the Action to bind. /// The workbook class being bound to. /// The control that is the target of the binding. private static void BindAction (Selector action, NSObject workbookClass, NSControl control) { // Anything to process? if (action == null) return; // Switch to .NET style method name var actionName = action.Name.Substring (0, 1).ToUpper () + action.Name.Substring (1).Replace (":", ""); // Does the class contain the method? var controllerType = workbookClass.GetType (); var methodInfo = controllerType.GetMethod (actionName); if (methodInfo != null) { // Yes, wireup action to class control.Activated += (sender, e) => { methodInfo.Invoke (workbookClass, new [] { sender }); }; } } #endregion } /// /// Helper class that can inflate Views and View Controllers from a compiled Storyboard /// that has been included in a workbook. /// public class StoryboardInflator : NSObject { #region Computed Properies /// /// Gets or sets the first responder that will act as the parent to all objects /// instantiated from the Storyboard. /// /// The first responder. public NSObject FirstResponder { get; set; } /// /// Gets or sets the bundle that contains the compiled Storyboard. /// /// The bundle. public NSBundle Bundle { get; set; } /// /// Gets or sets the main menu identifier. /// /// The main menu identifier. public string MainMenuIdentifier { get; set; } /// /// Gets or sets the entry point identifier for the initial object specified in /// Storyboard. /// /// The entry point identifier. public string EntryPointIdentifier { get; set; } /// /// Gets or sets the view controller identifiers to nib names dictionary. /// /// The view controller identifiers to nib names. public NSDictionary ViewControllerIdentifiersToNibNames { get; set; } /// /// Gets or sets the view controller identifiers to UUID dictionary. /// /// The view controller identifiers to UUID. public NSDictionary ViewControllerIdentifiersToUUIDs { get; set; } /// /// Gets or sets the segue definitions that were defined in the Storyboard. /// /// The segue definition collection. public List SegueDefinitions { get; set; } = new List (); #endregion #region Constructors /// /// Initializes a new instance of the class. /// /// This constructor sets the First Responder to the AppDelegate. /// The Bundle file that contains the compiled Storyboard. public StoryboardInflator (string bundleFile) { // Initialize Initialize (bundleFile, (NSObject)NSApplication.SharedApplication.Delegate); } /// /// Initializes a new instance of the class. /// /// The Bundle file that contains the compiled Storyboard. /// The object that will act as the owner (First Responder) of /// any object instantiated from the Storyboard. public StoryboardInflator (string bundleFile, NSObject owner) { // Initialize Initialize (bundleFile, owner); } /// /// Initialize the specified bundle file and owner. /// /// The Bundle file that contains the compiled Storyboard. /// The object that will act as the owner (First Responder) of /// any object instantiated from the Storyboard. internal void Initialize (string bundleFile, NSObject owner) { // Initialize LoadSegueDefinitions (bundleFile); Bundle = new NSBundle (bundleFile); FirstResponder = owner; // Read the structure of the Storyboard EntryPointIdentifier = Bundle.InfoDictionary.ObjectForKey (new NSString ("NSStoryboardDesignatedEntryPointIdentifier")).ToString (); MainMenuIdentifier = Bundle.InfoDictionary.ObjectForKey (new NSString ("NSStoryboardMainMenu")).ToString (); ViewControllerIdentifiersToNibNames = Bundle.InfoDictionary.ObjectForKey (new NSString ("NSViewControllerIdentifiersToNibNames")) as NSDictionary; ViewControllerIdentifiersToUUIDs = Bundle.InfoDictionary.ObjectForKey (new NSString ("NSViewControllerIdentifiersToNibNames")) as NSDictionary; } #endregion #region Private Methods /// /// Loads the segue definitions from the non-compiled version of the Storyboard. /// /// The Bundle file that contains the compiled Storyboard. private void LoadSegueDefinitions (string bundleFile) { // Open the non-compiled Storyboard var path = bundleFile.Replace (".storyboardc", ".storyboard"); var reader = new XmlTextReader (path); // Track the tree of objects that the Segue is defined in var parsingObject = StoryboardObjectType.Unknown; var parsingID = ""; var sceneType = StoryboardObjectType.Unknown; var sceneID = ""; // Read through the non-compiled Storyboard to find all Segue // definitions while (reader.Read ()) { // Take action based on node type switch (reader.Name) { case "application": sceneType = StoryboardObjectType.Application; var appID = reader.GetAttribute ("id"); if (appID != null) { sceneID = appID; } break; case "menuItem": var title = reader.GetAttribute ("title"); if (title != null) { parsingObject = StoryboardObjectType.MenuItem; parsingID = title; } break; case "windowController": sceneType = StoryboardObjectType.WindowController; var wcID = reader.GetAttribute ("id"); if (wcID != null) { parsingObject = StoryboardObjectType.WindowController; parsingID = wcID; sceneID = wcID; } break; case "toolbarItem": var tbID = reader.GetAttribute ("label"); if (tbID != null) { parsingObject = StoryboardObjectType.ToolbarItem; parsingID = tbID; } break; case "viewController": sceneType = StoryboardObjectType.ViewController; var vcID = reader.GetAttribute ("id"); if (vcID != null) { sceneID = vcID; } break; case "splitViewController": sceneType = StoryboardObjectType.SplitViewController; var svcID = reader.GetAttribute ("id"); if (svcID != null) { sceneID = svcID; } break; case "button": var buttonID = reader.GetAttribute ("identifier"); if (buttonID != null) { parsingObject = StoryboardObjectType.Button; parsingID = buttonID; } break; case "segue": // Read the Segue's Definition var destination = reader.GetAttribute ("destination"); var kind = reader.GetAttribute ("kind"); var identifier = reader.GetAttribute ("identifier"); var id = reader.GetAttribute ("id"); var relationship = reader.GetAttribute ("relationship"); var popoverAnchor = reader.GetAttribute ("popoverAnchorView"); var popoverBehavior = reader.GetAttribute ("popoverBehavior"); var popoverEdge = reader.GetAttribute ("preferredEdge"); // Create a new definition, populate it and add it to // the collection var definition = new StoryboardSegueDefinition (kind, this) { SceneType = sceneType, SceneID = sceneID, SourceObjectType = parsingObject, SourceObjectID = parsingID, DestinationControllerID = destination, SegueIdentifier = (identifier == null) ? id : identifier, Relationship = relationship, PopoverAnchorID = popoverAnchor }; definition.SetPopoverBehavior (popoverBehavior); definition.SetPopoverEdge (popoverEdge); SegueDefinitions.Add (definition); break; } } } /// /// Pulls the type name from the description. /// /// The class type name. /// This method is used for debugging. /// The description. private string TypeName (string description) { var posn = description.IndexOf (":"); return description.Substring (1, posn - 1); } /// /// Pulls the class handle pointer from the description. /// /// The handle pointer. /// This method is used for debugging. /// The description. private IntPtr ClassHandlePointer (string description) { var posn = description.IndexOf (":"); var value = description.Substring (posn + 1, description.Length - posn - 1); return Marshal.StringToHGlobalUni (value); } /// /// Prints the top objects to the console. /// /// This method is used for debugging. /// The collection of top level objects. private void PrintTopObjects (NSArray topLevelObjects) { NSObject element = null; // Scan all top level object for the window controller for (nuint n = 0; n < topLevelObjects.Count; ++n) { // Access the current object element = topLevelObjects.GetItem (n); Console.WriteLine ("> Type: {0}", TypeName (element.Description)); } } /// /// Checks every Menu and Menu Item to see if a Segue has been attached to it. /// If so, it sets the StoryboardSegueDefinition as the Menu Item's /// Target. /// /// The NSMenu to scan. private void LoadMenuSegueTargets (NSMenu menu) { // Check all items to see if they have been bound to a segue for (nint x = 0; x < menu.Count; ++x) { var menuItem = menu.ItemAt (x); // Has a segue been defined for this item? var segueDefinition = FindSegueDefinition (StoryboardObjectType.MenuItem, menuItem.Title); if (segueDefinition != null) menuItem.Target = segueDefinition; // Scan sub menus if (menuItem.Submenu != null) { LoadMenuSegueTargets (menuItem.Submenu); } } } /// /// Checks every Toolbar Item to see if a Segue has been attached to it. /// If so, it sets the StoryboardSegueDefinition as the Toolbar Item's /// Target. /// /// The NSToolbar to scan. private void LoadToolbarItemSegueTargets (NSToolbar toolbar) { // Check all items to see if they have been bound to a segue foreach (NSToolbarItem item in toolbar.Items) { // Has a segue been defined for this item? var segueDefinition = FindSegueDefinition (StoryboardObjectType.ToolbarItem, item.Label); if (segueDefinition != null) { item.Target = segueDefinition; } } } /// /// Checks every View and Sub View to see if a Segue has been attached to it. /// If so, it sets the StoryboardSegueDefinition as the View's /// Target. /// /// The NSView to scan. public void LoadViewSegueTargets (NSView view) { // Bind segues for known items if (view is NSButton) { var button = view as NSButton; // Has a segue been defined for this item? var segueDefinition = FindSegueDefinition (StoryboardObjectType.Button, button.Identifier); if (segueDefinition != null) { button.Target = segueDefinition; } } // Bind every subview foreach (NSView subview in view.Subviews) { LoadViewSegueTargets (subview); } } /// /// Loads the NIB from the specified NIB name and recursivly loads any sub NIBs /// for a known set of types such as NSWindowController, NSViewController, /// etc. /// /// The main top level element from the NIB as a known type such as /// NSWindowController, NSViewController, etc. /// The name of the NIB to load. private NSObject LoadNib (string nibName) { NSObject mainElement = null; var topLevelObjects = new NSArray (); NSObject element = null; var subNibName = ""; // Anything to process? if (nibName == null) return null; //Console.WriteLine ("Loading {0} -->", nibName); // Load the given NIB if (Bundle.LoadNibNamed (nibName, FirstResponder, out topLevelObjects)) { // Discovery //Console.WriteLine ("Parsing {0}:", nibName); //PrintTopObjects (topLevelObjects); // Scan all top level object for a known object type for (nuint n = 0; n < topLevelObjects.Count; ++n) { // Access the current object element = topLevelObjects.GetItem (n); // Search for known types if (element is NSMenu) { // Found main menu if (mainElement == null) mainElement = element; var menu = element as NSMenu; LoadMenuSegueTargets (menu); } else if (element is NSWindowController) { // Found window controller mainElement = element; var windowController = element as NSWindowController; // Load the window's content view if (windowController.Window.ContentViewController is NSSplitViewController) { // Access Split View Controller var splitViewController = windowController.Window.ContentViewController as NSSplitViewController; // Manufacture a new Split View and configure it the same as // the Split View from the storyboard var splitView = new NSSplitView (splitViewController.View.Frame) { ArrangesAllSubviews = splitViewController.SplitView.ArrangesAllSubviews, DividerStyle = splitViewController.SplitView.DividerStyle, IsVertical = splitViewController.SplitView.IsVertical }; // Load all the attached views foreach (NSSplitViewItem svItem in splitViewController.SplitViewItems) { subNibName = svItem.ViewController.NibName; var view = LoadNib (subNibName) as NSView; splitView.AddArrangedSubview (view); } splitView.AdjustSubviews (); // Attach to window windowController.Window.ContentView = splitView; } else { subNibName = windowController.Window.ContentViewController.NibName; var contentView = LoadNib (subNibName) as NSView; // Found? if (contentView != null) { // Yes, attach it to the window windowController.Window.ContentViewController.View = contentView; windowController.Window.ContentView = contentView; //Console.WriteLine ("* {0} View Attached", subNibName); } } // Is there a toolbar? if (windowController.Window.Toolbar != null) { // Scan items for attached segues LoadToolbarItemSegueTargets (windowController.Window.Toolbar); } } else if (element is NSViewController) { // Found View Controller if (mainElement == null) mainElement = element; var viewController = element as NSViewController; // Load the controller's view subNibName = viewController.NibName; var view = LoadNib (subNibName) as NSView; viewController.View = view; } else if (element is NSView) { // Found View if (mainElement == null) mainElement = element; var view = element as NSView; LoadViewSegueTargets (view); } } } else { // Report error Console.WriteLine ("Unable to load: {0}", nibName); } // Return the found main element return mainElement; } #endregion #region Public Methods /// /// Instantiates the main menu from the storyboard. /// /// The main menu. public NSMenu InstantiateMainMenu () { return LoadNib (MainMenuIdentifier) as NSMenu; } /// /// Instantiates the main menu from the storyboard and binds it to the /// given instance of a workbook class. /// /// The main menu. /// The workbook instance to bind to. public NSMenu InstantiateMainMenu (NSObject parent) { // Inflate menu var menu = LoadNib (MainMenuIdentifier) as NSMenu; // Bind menu to parent class StoryboardBinder.BindMenu (menu, parent); // return inflated menu return menu; } /// /// Instantiates the initial controller as specified in the Storyboard. /// /// The initial controller. public NSObject InstantiateInitialController () { // Load element var element = LoadNib (EntryPointIdentifier); // Is this a window controller? if (element is NSWindowController) { // Yes, display the window to the user var windowController = element as NSWindowController; windowController.Window.MakeKeyAndOrderFront ((NSObject)NSApplication.SharedApplication.Delegate); } // Return loaded object return element; } /// /// Instantiates the initial controller as specified in the Storyboard and binds it to /// the given instance of a workbook class. /// /// The initial controller. /// The workbook instance to bind to. public NSObject InstantiateInitialController (NSObject parent) { // Get initial element var element = InstantiateInitialController (); // Bind element to parent class StoryboardBinder.Bind (element, parent); // Return loaded object return element; } /// /// Instantiates the controller from the NIB of the given name. /// /// The controller for nib name. /// Nib name. public NSObject InstantiateControllerForNibName (string nibName) { var element = LoadNib (nibName); // Return loaded object return element; } /// /// Returns the NIB name for the given Identifier or the empty string ("") if /// not found. /// /// The name for identifier or empty string ("") if not found. /// The identifier to search for. public string NibNameForIdentifier (string identifier) { for (int n = 0; n < ViewControllerIdentifiersToNibNames.Keys.Count (); ++n) { // Get the key and value var key = ViewControllerIdentifiersToNibNames.Keys [n].ToString (); var value = ViewControllerIdentifiersToNibNames.Values [n].ToString (); // Found? if (key == identifier) return value; } // Return found name return ""; } /// /// Returns the NIB name for the partial Identifier or the empty string ("") if /// not found. /// /// The name for identifier or empty string ("") if not found. /// The partial identifier to search for. public string NibNameForPartialIdentifier (string identifier) { for (int n = 0; n < ViewControllerIdentifiersToNibNames.Keys.Count (); ++n) { // Get the key and value var key = ViewControllerIdentifiersToNibNames.Keys [n].ToString (); var value = ViewControllerIdentifiersToNibNames.Values [n].ToString (); // Found? if (key.Contains(identifier)) return value; } // Return found name return ""; } /// /// Returns the UUID for the given Identifier or the empty string ("") if /// not found. /// /// The name for identifier or empty string ("") if not found. /// The identifier to search for. public string UUIDForIdentifier (string identifier) { for (int n = 0; n < ViewControllerIdentifiersToUUIDs.Keys.Count (); ++n) { // Get the key and value var key = ViewControllerIdentifiersToUUIDs.Keys [n].ToString (); var value = ViewControllerIdentifiersToUUIDs.Values [n].ToString (); // Found? if (key == identifier) return value; } // Return found name return ""; } /// /// Instantiates the controller for the given identifier. /// /// The controller for identifier. /// The identifier to instantiate. public NSObject InstantiateControllerForIdentifier (string identifier) { var nibName = NibNameForIdentifier (identifier); // Found? if (nibName == "") { // No return null; } else { // Yes, instantiate named nib return InstantiateControllerForNibName (nibName); } } /// /// Instantiates the controller for the given partial identifier. /// /// The controller for partial identifier. /// The partial identifier to instantiate. public NSObject InstantiateControllerForPartialIdentifier (string identifier) { var nibName = NibNameForPartialIdentifier (identifier); // Found? if (nibName == "") { // No return null; } else { // Yes, instantiate named nib return InstantiateControllerForNibName (nibName); } } /// /// Finds the segue definition for the given Scene and Source Object. /// /// The segue definition or null if not found. /// Scene type. /// Scene identifier. /// Source object type. /// Source object identifier. public StoryboardSegueDefinition FindSegueDefinition (StoryboardObjectType sceneType, string sceneID, StoryboardObjectType sourceObjectType, string sourceObjectID) { // Scan all definitions foreach (StoryboardSegueDefinition definition in SegueDefinitions) { // Found? if (definition.SceneType == sceneType && definition.SceneID == sceneID && definition.SourceObjectType == sourceObjectType && definition.SourceObjectID == sourceObjectID) { return definition; } } // Not found return null; } /// /// Finds the segue definition for the given Source Object. /// /// The segue definition or null if not found /// Source object type. /// Source object identifier. public StoryboardSegueDefinition FindSegueDefinition (StoryboardObjectType sourceObjectType, string sourceObjectID) { // Scan all definitions foreach (StoryboardSegueDefinition definition in SegueDefinitions) { // Found? if (definition.SourceObjectType == sourceObjectType && definition.SourceObjectID == sourceObjectID) { return definition; } } // Not found return null; } /// /// Finds the segue definition for the given Segue Identifier. /// /// The segue definition or null if not found. /// The Segue Identifier to find. public StoryboardSegueDefinition FindSegueDefinition (string identifier) { // Scan all definitions foreach (StoryboardSegueDefinition definition in SegueDefinitions) { // Found? if (definition.SegueIdentifier == identifier) { return definition; } } // Not found return null; } #endregion } ================================================ FILE: mac/user-interface/segues/Segues.workbook/Walkthrough.storyboard ================================================ Default Left to Right Right to Left Default Left to Right Right to Left ================================================ FILE: mac/user-interface/segues/Segues.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacMobile --- # Working with Segues in macOS Storyboard ### Building a Xamarin.Mac app's UI in a Storyboard Storyboards allow the developer to create a User Interface for a Xamarin.Mac app that not only includes the Window definitions and controls, but also contains the links between different Windows and how those Windows will be presented using Segues. This workbook will cover the typical uses of Segues within a Storyboard, and how they can be used to limit the amount of code a developer is required to write to present a Xamarin.Mac app’s UI. It is suggested to read our [Hello, Mac](https://developer.xamarin.com/guides/mac/getting_started/hello,_mac/) and [Introduction to Storyboards](https://developer.xamarin.com/guides/mac/platform-features/storyboards/) documentation before starting this workbook, as they provide a basis for the topics covered here. ## An Introduction to Storyboards Before getting started, let’s take a quick refresher in what a [Storyboard](https://developer.xamarin.com/guides/mac/platform-features/storyboards/#What_are_Storyboards) is and how it is used to define the User Interface for a macOS app. Take the following example: ![](Images/Intro01.png) A Storyboard defines all of the UI for a given app broken down into a functional overview of its View Controllers. Window Controllers contain and control the different Window types that a macOS app can create and contain these View Controllers. In Xcode's Interface Builder, each of these controllers lives in its own Scene: ![](Images/Intro02.png) Each Scene represents a given View and View Controller Pair with a set of lines (called Segues) that connect each Scene in the UI, thus showing their relationships. Some Segues define how one View Controller contains one or more child Views or View Controllers. Other Segues, define transitions between View Controller (such as displaying a popover or dialog box). After the UI has been designed, the developer exposes the elements and controls to C# code using *Outlets* and *Actions*. Please see our [Outlets and Actions](https://developer.xamarin.com/guides/mac/getting_started/hello,_mac/#Outlets_and_Actions) documentation for more information. ## Storyboards and Workbooks Workbooks don’t natively support macOS Storyboards, so the first thing that will need to be done is to load a library that provides support: ```csharp #load "StoryboardResources.csx" ``` Using this library, there are a few differences that will need to be taken into account when designing UI in Xcode’s Interface Builder: * Outlets cannot be defined by Control-Dragging as normal because there is no `.h` header file to attach to. Instead, use the **Identifier** field in the **Identity Inspector** for **Windows, Views** and **View based Controls**. **Menu Items** will automatically bind to any Outlet that match their `Title` \+ “*MenuItem*” (for example, `NewMenuItem`). **Toolbar Items** will automatically bind to any Outlet that match their `Label` \+ “*ToolbarItem*” (for example, `ColorToolbarItem`). * Actions need to manually be added to the **First Responder** in the **Scene** where they will be used by clicking the **\+** button in the **Attribute Inspector** and defining the new Action. Next, select the element to attach to, Control-Click, dragging a line to the **First Responder** in the same **Scene** and selecting the defined Action. * Only the built-in Segue types are currently supported by the library and **Views** and **View based Controls** *must* have a custom **Identifier** set in the **Identity Inspector**. For Custom Segues, the developer will have to manually load and display the child Window or View Controller. * Because of the way workbooks function, loading and instantiating Window and View Controllers is done using methods of the `StoryboardInflator` helper class as opposed to using the typical `NSStoryboard` methods. For more information, please see our [Loading a Storyboard from Code](https://developer.xamarin.com/guides/mac/platform-features/storyboards/indepth/#Loading_from_Code) documentation. * The `StoryboardBinder` helper class will need to be used to "bind" (map) classes defined in the workbook to UI elements inflated from a Storyboard. With these differences aside, Storyboards are used same way they typically would be in a normal macOS app, so the knowledge gained here can be used when building a regular Xamarin.Mac app project. For more information, please see our [Introduction to Storyboards](https://developer.xamarin.com/guides/mac/platform-features/storyboards/) documentation. ### Compiling the Storyboard Every time the developer edits the Storyboard, those changes will need to be compiled before they can be loaded in the workbook. Do this using the following command: ```csharp var usingStoryboard = "Walkthrough"; StoryboardCompiler.Compile(usingStoryboard); ``` This workbook includes two Storyboards. Set the `usingStoryboard` variable above to `Walkthrough` to follow through the exercises yourself or set it to `Main` to see the completed User Interface. > ⚠️ To edit the Storyboard that is part of this workbook, select the `.workbook` file in Finder, right-click it and select **Show Package Contents**. ## Defining the Supporting Classes There are several supporting classes that will be required when working with a Xamarin.Mac app’s UI that has been loaded from a Storyboard. These include at least an `AppDelegate`, a `NSWindowController` (for each Window type that the app creates) and a `NSViewController` for every `NSView` that belongs to a Window. The following sections will go over each of these required classes in detail. ### The InputFormViewController Class In this workbook we'll be creating a simple Input Form that will have a definable Title and allow the user to enter a value which will be sent back to the caller: ![](Images/UI01.png) The `InputFormViewController` class will act as this Input Form's *Content Controller* and will be responsible for the life cycle of the form's content: ```csharp using System; using Foundation; using AppKit; using WebKit; public class InputFormViewController : NSViewController { #region Private Variables private string title = ""; #endregion #region Outlets [Outlet] public NSButton OKButton {get;set;} [Outlet] public NSButton CancelButton {get;set;} [Outlet] public NSTextField TitleLabel {get;set;} [Outlet] public NSTextField InputField {get;set;} #endregion #region Computed Properties // Because of the way workbooks handle Storyboards, this // reference is required to point back to the "real" // View Controller as inflated from the .storyboardc file. public NSObject StoryboardController {get;set;} #endregion #region Constructors public InputFormViewController (string title) : base() { // Initialize this.title = title; } #endregion #region Override Methods public override void ViewWillAppear () { base.ViewWillAppear (); // Initialize TitleLabel.StringValue = title; } #endregion #region Public Methods public void CloseDialog() { // Ask the controller that presented the form to // close it var controller = StoryboardController as NSViewController; controller.DismissController(this); } #endregion #region Custom Actions [Action ("acceptForm:")] public void AcceptForm (Foundation.NSObject sender) { // Inform caller that a new value has been entered // and close the form RaiseValueEntered(InputField.StringValue); CloseDialog(); } [Action ("cancelForm:")] public void CancelForm (Foundation.NSObject sender) { // Close the dialog CloseDialog(); } #endregion #region Events public delegate void ValueEnteredDelegate(string text); public event ValueEnteredDelegate ValueEntered; private void RaiseValueEntered(string text) { if (this.ValueEntered != null) this.ValueEntered(text); } #endregion } ``` Let’s take a look at what this code is doing in detail. First, the private variable `title` is defined and used to hold a title that will be presented to the user when the View attached to this View Controller is shown. This title will be passed in when an instance of this class is created. Why didn't we just set the title directly from the public `TitleLabel` property? Because of the way Storyboards are loaded and displayed, the `InputFormViewController` can be created *before* the `TitleLabel` field is built and populated. If we set it directly, `TitleLabel` could be `null`, which would result in an error. Next, several Outlets are defined that will be attached to the various UI elements from the View this View Controller is managing. These allow the C# code to access the UI Elements that were defined in Xcode's Interface Builder. The `ViewWillAppear` method is called when the View has been fully loaded into memory so it can be configured before presenting it to the user. Here we are taking the `title` that was passed in and setting it as the value of the `TitleLabel`. The `CloseDialog` method will close the Window (or Sheet) that the View Controller is presented in, removing it from the screen. It will be called from the OK and Cancel buttons. A custom `ValueEntered` event is defined that will be raised when the user clicks the OK button. The caller can subscribe to the event to get the result from the dialog. Finally, two custom Actions are defined: `AcceptForm` and `CancelForm`. These will be wired-up to the OK and Cancel buttons in Interface Builder and called when the user clicks the buttons. > 💡**Try It Now** > > 1. Disable the `OKButton` if the `InputField.StringValue` is empty. ***Hint**: Use the `NSTextField.Changed` event in the `ViewWillAppear` method.* > 2. Create a `Canceled` event to inform the caller when the user cancels the form and call it when the Cancel button is clicked. > > ⚠️ These changes won't take effect until a new instance of the Window is instantiated. For more information on working with View Controllers, please see our [View Controllers](https://developer.xamarin.com/guides/mac/platform-features/storyboards/indepth/#View_Controllers) documentation. ### The Main View Controller The Main Window of this app has two buttons that will be used to display other Windows and View by creating Segues in Interface Builder: ![](Images/UI02.png) The `MainViewController` class will act as this app’s Window *Content Controller* and will be responsible for the life cycle of the main Window’s content: ```csharp using System; using Foundation; using AppKit; using WebKit; public class MainViewController : NSViewController { #region Outlets [Outlet] public NSButton ShowButton {get;set;} [Outlet] public NSButton QuestionButton {get;set;} [Outlet] public NSTextField QuestionLabel {get;set;} #endregion #region Constructors public MainViewController () : base() { } #endregion #region Override Methods public override void ViewWillAppear () { base.ViewWillAppear (); } #endregion } ``` Let’s take a look at what this code is doing in detail. Like the `InputFormViewController` above, Outlets have been created to allow C# to access the UI Elements defined in Interface builder and the `ViewWillAppear` method will be called before the View is presented to the user so it can be configured. ### The Main Window Controller The Main Window contains a Toolbar that has items that will be used to display other Windows and Views using Segues. It also contains the `MainViewController` created above: ![](Images/UI03.png) The right facing arrow defines this Window as the *Initial View* that will be displayed when this Storyboard in opened. The downward facing arrow is a *Containment Segue* stating that this controller *contains* the View Controller it is pointing to: ![](Images/UI04.png) The `MainWindowController` class will act as the app’s Window Controller and will be responsible for the life cycle of the app’s main Window: ```csharp using System; using Foundation; using AppKit; using WebKit; public class MainWindowController : NSWindowController { #region Computed Properties public MainViewController ViewController {get; set;} #endregion #region Constructors public MainWindowController() : base() { } #endregion #region Override Methods public override void WindowDidLoad () { // Initialize the window after it has loaded Window.Title = "Untitled"; } public override void PrepareForSegue (NSStoryboardSegue segue, NSObject sender) { // Take action based on the segue id switch(segue.Identifier){ case "InputFormSegue": // Create a new form controller and bind it to the segue's // destination var formContoller = new InputFormViewController("Enter Something:"){ StoryboardController = segue.DestinationController, }; StoryboardBinder.Bind(segue.DestinationController, formContoller); // Watch for the user entering a value formContoller.ValueEntered += (value) => { // Display the user's input ViewController.QuestionLabel.StringValue = value; }; break; } } #endregion } ``` Let’s take a look at what this code is doing in detail. The `ViewController` property is used to gain access to the `MainViewController` attached to the Window. The `WindowDidLoad` method will be called before the Window is shown to the user so it can be configured. In our example, we are just setting the `Title` of the Window. The `PrepareForSegue` method is called before a Segue is run so that the developer can configure it. Here, if the segue `Identifier` is `InputFormSegue`, a new instance of the `InputFormViewController` class is created with the Title for the Input Form and bound to the `DestinationController` from the `NSStoryboardSegue`. The `ValueEntered` event of the `InputFormViewController` class is used to display the user's input if they click the OK button. The `Identifier` is set by selecting a Segue in Interface Builder and entering it in the **Attribute Inspector**: ![](Images/UI05.png) The `PrepareForSegue` method is a very important part of working with Segues in a Storyboard and a Xamarin.Mac app as it allows the developer to configure the Window or View that will be displayed as a result of the Segue. For example, like setting the title and retrieving the user's input above. > 💡**Try It Now** > > 1. **Create a Simple Segue** - Edit the Storyboard, select the **Show** button, hold the **Control** key, drag a line to the "Hello There" View and select `Show` from the popup window. Run the workbook and click the Show button to open a new Hello There Window. > > 2. **Create a Segue from a Toolbar Item** - Edit the Storyboard, select the **Show** Toolbar item, hold the **Control** key, drag a line to the "Hello There" View and select `Show` from the popup window. Run the workbook and click the Show Toolbar button to open a new Hello There Window. > > 3. **Create a Complex Segue** - Edit the Storyboard, select the **Question** button, hold the **Control** key, drag a line to the Input Form View and select `Sheet` from the popup window. Select the new Segue and enter `InputFormSegue` for the Identifier in the **Attribute Inspector**. Run the workbook and click the Question button to open a new Input Form Sheet. If you enter a value and click the OK button, it will be displayed on the Window because of the `PrepareForSegue` method created above. > > 4. **Create a Popover Segue** - Edit the Storyboard, select the **Computer** Toolbar item, hold the **Control** key, drag a line to the "Computer Info..." View and select `Popover` from the popup window. Select the Segue and use the **Attribute Inspector** to configure it (such as setting the Preferred Edge the Popover will be displayed from). Run the workbook and click the Computer Toolbar button to open a new Computer Info Popover. > > 5. **Respond to the User Canceling the Input Form** - Use the `Canceled` event you created above to display a message when the user clicks the Cancel button in the Input Form. > > 6. **Bonus** - Edit the Storyboard, select the different Segues created above and use the **Attribute Inspector** to try the effect of changing the properties (such as the Segue Kind or Preferred Edge for the Popover). > > ⚠️ These changes won't take effect until the workbook has been re-run from the beginning. For more information on working with Window Controllers, please see our [Window Controller](https://developer.xamarin.com/guides/mac/platform-features/storyboards/indepth/#Window_Controllers) documentation. ### The Main Window Delegate The `MainWindowDelegate` will be attached to each of the Main Windows created by the app to monitor and respond to events such as the Window becoming Key (being set as the active, front-most Window), the Window closing, etc.: ```csharp using System; using Foundation; using AppKit; using WebKit; public class MainWindowDelegate : NSWindowDelegate { #region Computed Properties public NSWindow Window { get; set;} public MainWindowController WindowController {get; set;} public MainViewController ViewController {get;set;} #endregion #region constructors public MainWindowDelegate (NSWindow window, MainWindowController windowController, MainViewController viewController) { // Initialize this.Window = window; this.WindowController = windowController; this.ViewController = viewController; } #endregion #region Override Methods public override void DidBecomeKey (NSNotification notification) { } #endregion } ``` For now, `MainWindowDelegate` is just keeping track of the other Supporting Classes for each Window created. This will be required later when tracking which of the app’s Windows is currently Key. ### The App Delegate The [AppDelegate](https://developer.xamarin.com/guides/mac/getting_started/hello%2C_mac/#AppDelegate.cs) is responsible for starting the app, loading its initial Menu Bar and Window and listening to OS events: ```csharp using System; using Foundation; using AppKit; using WebKit; public class AppDelegate : NSApplicationDelegate { #region Computed Properties public StoryboardInflator Inflator {get; set;} public NSMenu MainMenu {get; set;} public MainWindowController WindowController {get; set;} = new MainWindowController(); public MainViewController ViewController {get; set;} = new MainViewController(); #endregion #region Outlets [Outlet] public NSMenuItem NewMenuItem {get;set;} #endregion #region Constructors public AppDelegate() : base() { } public AppDelegate(string bundleName) : base() { // Load the storyboard bundle into an inflator Inflator = new StoryboardInflator($"{bundleName}.storyboardc"); // Initialize main menu MainMenu = Inflator.InstantiateMainMenu(this); // Load the initial window from the Storyboard Inflator.InstantiateInitialController(WindowController); WindowController.Window.Delegate = new MainWindowDelegate(WindowController.Window, WindowController, ViewController); // Bind the main view controller StoryboardBinder.Bind(WindowController, ViewController); WindowController.ViewController = ViewController; // Simulate the app launching DidFinishLaunching(NSNotification.FromName("AppDelegate",this)); } #endregion #region Override Methods public override void DidFinishLaunching (NSNotification notification) { // Initialize app here } #endregion #region Public Methods public void PrepareForSegue (NSStoryboardSegue segue, NSObject sender) { // Take action based on the segue id switch(segue.Identifier){ case "NewDocumentSegue": var windowController = new MainWindowController(); var viewContoller = new MainViewController(); StoryboardBinder.Bind(segue.DestinationController, windowController); StoryboardBinder.Bind(windowController, viewContoller); break; } } #endregion } ``` Let’s take a look at what this code is doing in detail. First, it creates and exposes several Computed Properties to keep track of the main elements of the app. When a new instance of the `AppDelegate` is created, it creates a `StoryboardInflator` to load the specified Storyboard’s bundle into memory. Next, the app’s Menu Bar is loaded and displayed using the `InstantiateMainMenu` method. The `InstantiateInitialController` method loads and displays the app’s main, default Window which gets a `MainWindowDelegate` attached to it. The WindowController is bound to the ViewController using the `StoryboardBinder`’s `Bind` method and the `DidFinishLaunching` method is called to simulate the normal launch sequence of a macOS app. Just like the `MainWindowController` created above, the `PrepareForSegue` method is used to bind instances of the `MainWindowController` and `MainViewController` to a new instance of the Main Window built from a Segue with the Identifier of `NewDocumentSegue`. > 💡**Try It Now** > > 1. **Create a New Main Window with a Segue** - Edit the Storyboard, select the **New** menu item, hold the **Control** key, drag a line to the Main Window Controller and select `Show` from the popup window. Select the Segue and enter `NewDocumentSegue` for the Identifier in the **Attribute Inspector**. Run the workbook and click the New Menu Item button to open a new Main Window. > > 2. **Create a Secondary Window with a Segue** - Edit the Storyboard, select the **New Splitview** menu item, hold the **Control** key, drag a line to the Split View Window Controller and select `Show` from the popup window. Select the Segue and enter `NewSplitviewSegue` for the Identifier in the **Attribute Inspector**. Run the workbook and click the New Splitview Menu Item button to open a new Splitview Window. > > 3. **Bonus** - Edit the Storyboard, select the different Segues created above and use the **Attribute Inspector** to try the effect of changing the properties > > ⚠️ These changes won't take effect until the workbook is re-run from the beginning. ## Starting the App and Displaying the Default Menu Bar and Window With this code in place, an instance of the `AppDelegate` can be created which will display the Main Menu and the Initial View (as defined in the Storyboard): ```csharp // Initialize and display the app var appDelegate = new AppDelegate(usingStoryboard); ``` ================================================ FILE: mac/user-interface/tableview/NSTableView.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacMobile --- # Working with Table Views #### Using a Table View in a Xamarin.Mac Application This workbook will cover the steps required to add a Table View (`NSTableView`) to a Xamarin.Mac app's User Interface directly from C# code without using a Xcode's Interface Builder `.storyboard` or `.xib` file. ## Creating the Table View `NSTableView` is a native cocoa control for displaying data in a table. Start by creating an instance and set its `Frame` property to a reasonable size. It will be autosized via an owning `NSClipView`: ```csharp // Get the parent window's frame var frame = MainWindow.ContentView.Frame; // Make a new table view and have it fill the parent window NSTableView tableView = new NSTableView () { Frame = frame }; ``` ## Adding the Table Columns Every `NSTableView` expected to have at least one `NSTableColumn`. The following code adds two columns to the Table: ```csharp // Add two columns to the table tableView.AddColumn (new NSTableColumn ("Values")); tableView.AddColumn (new NSTableColumn ("Data")); ``` ## Adding the Clip View `NSTableView` expects to be hosted inside an `NSClipView`.The following code creates the required Clip View and adds the Table View to it: ```csharp // Create the required clipping view and set it to // resize both horizontally and vertically as the // parent window resizes. NSClipView clipView = new NSClipView (frame) { AutoresizingMask = NSViewResizingMask.HeightSizable | NSViewResizingMask.WidthSizable }; // Attach the table view to the clip view clipView.DocumentView = tableView; ``` Next, add the Clip View to the Window’s Content View to display the Table: ```csharp // Attach the clip view to the main window MainWindow.ContentView = clipView; ``` ## Adding Data to the Table `NSTableView` uses a two classes, a `DataSource` and `Delegate`, to determine what data to display. `NSTableView` can be used in two different “modes”: *Cell Based* or *View Based*. Different overrides apply to each of these modes, such that overriding some of the Cell Based methods will prevent the View Based methods from being called. According to Apple, Cell Based Tables have been deprecated and View Based Tables should be used for all modern macOS development. The `Delegate` receives events associated with user action and determine how an item should be visualized. ### Providing Sample Data This sample will just use the name of the row number: ```csharp // Create the sample data for the table to display static string [] NumberWords = new[] { "Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine" }; ``` ### Creating the Cells for the Table For every Row and Column, the Table View calls its `Delegate` to provide the individual Cells. By calling `MakeView` method of the Table View with an identifier, existing views can be recycled, which can improve performance: ```csharp class TableDelegate : NSTableViewDelegate { // Provide an ID for each cell so it can be reused const string identifer = "myCellIdentifier"; // Generate a new view to act as the cell for each table row and column public override NSView GetViewForItem (NSTableView tableView, NSTableColumn tableColumn, nint row) { // Ask the table view to reuse a cell NSTextField view = (NSTextField)tableView.MakeView (identifer, this); // Was a reusable cell available? if (view == null) { // No, create a new cell view = new NSTextField (); view.Identifier = identifer; view.Bordered = false; view.Selectable = false; view.Editable = false; } // Populate the cell view.StringValue = tableColumn.Identifier == "Values" ? (NSString)row.ToString () : (NSString)NumberWords [row]; // Return the fully populated cell return view; } } ``` ### Add a Table Data Source `TableDataSource` defines the structures of the Table. In the case of a macOS Table, it simply provides the number of rows in the Table: ```csharp class TableDataSource : NSTableViewDataSource { // Return the number of rows in the table public override nint GetRowCount (NSTableView tableView) { return 10; } } ``` >💡**Note:** Optionally, both the Table Data Source and the Table Delegate could have been implemented as one class that conforms to the `INSTableViewDataSource` and `INSTableViewDelegate` interfaces. ### Displaying the Data Hooking up the `Delegate` and `DataSource` to the `NSTableView` is the final step. This is populate the table with the sample data: ```csharp // Attach the data source and delegate to populate the table tableView.DataSource = new TableDataSource (); tableView.Delegate = new TableDelegate (); ``` ================================================ FILE: mac/user-interface/tableview/README.md ================================================ Working with Table Views Workbook ============ This workbook will cover the steps required to add a Table View (`NSTableView`) to a Xamarin.Mac app's User Interface directly from C# code without using a Xcode's Interface Builder `.storyboard` or `.xib` file. ![](screenshots/Intro01.png) ================================================ FILE: mac/user-interface/toolbars/README.md ================================================ Working with Toolbars Workbook ============ This workbook will cover the steps required to add a Toolbar (NSToolBar) to a Xamarin.Mac app's User Interface directly from C# code without using a Xcode's Interface Builder `.storyboard` or `.xib` file. ![](screenshots/Intro01.png) ================================================ FILE: mac/user-interface/toolbars/toolbars.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacMobile --- # Working with Toolbars #### Using a Toolbar in a Xamarin.Mac Application This workbook will cover the steps required to add a Toolbar (`NSToolBar`) to a Xamarin.Mac app's User Interface directly from C# code without using a Xcode's Interface Builder `.storyboard` or `.xib` file. While Toolbars are typically created in Interface Builder, the steps required to configure, update and respond to Toolbar Item events are the same and the knowledge learned here can be applied to a Toolbar built in a `.storyboard` or `.xib` file. For more information, please see our [Toolbars](https://developer.xamarin.com/guides/mac/user-interface/working-with-toolbars/) documentation. ## Defining the UI in Interface Builder Before diving into the process of building a Toolbar in code, let’s quickly review how a macOS app’s UI is normally created. Typically, a Xamarin.Mac app’s User Interface is defined in one or more `.storyboard` or `.xib` files added to the project’s hierarchy. For example: ![](Images/Xcode01.png) Double-clicking this file will open it in Xcode’s Interface Builder where the Menus, Windows, Controls and Segues that make up the app’s UI can be defined visually. For example: ![](Images/Xcode02.png) When the UI layout is completed, the graphical elements that make up the UI are then exposed via **Actions** and **Outlets,** making them accessible to code. When the developer saves their changes to the `Main.storyboard` file and returns to Xamarin Studio, these changes are synced with the Xamarin.Mac app’s Project File and the UI elements are then accessible in C#. ## Creating a Toolbar Delegate As seen above, a `NSToolBar` is typically added to Window (`NSWindow`) in Xcode’s Interface Builder where the developer graphically creates the Toolbar by adding and configuring Toolbar Items, configuring the Default Toolbar and setting the appearance. Because the Toolbar used in this workbook will be created fully in code, the first thing required is a Toolbar Delegate (`NSToolbarDelegate`) that will handle the definition of the Toolbar Items that are available, that will create the individual Toolbar Items (as needed) and will define the Default Toolbar that is initially displayed to the end user: ```csharp using System; using Foundation; using AppKit; public class MainToolbarDelegate : NSToolbarDelegate { #region Constructors public MainToolbarDelegate () { } #endregion #region Private Methods // Build and return a custom Toolbar Item private NSToolbarItem BuildItem (string identifier) { // Create new toolbar item var item = new NSToolbarItem (identifier); // Set properties item.Image = new NSImage($"Images/{identifier}.png"); item.Label = identifier; item.PaletteLabel = identifier; item.Enabled = true; // Attach an action event item.Activated += (sender, e) => { RaiseToolbarItemClicked(item.Identifier); }; // Return new item return item; } #endregion #region Override Methods public override string [] AllowedItemIdentifiers (NSToolbar toolbar) { // Return the list of available item identifiers return new string [] {"One","Two","Three","Four","Five","Six","Seven","Eight","NSToolbarSpaceItem","NSToolbarFlexibleSpaceItem","NSToolbarShowColorsItem","NSToolbarShowFontsItem","NSToolbarPrintItem" }; } public override string [] DefaultItemIdentifiers (NSToolbar toolbar) { // Return the item identifiers that make up the default Toolbar return new string [] { "One","Two" }; } public override string [] SelectableItemIdentifiers (NSToolbar toolbar) { // Return the item identifiers that can be selected (turned on and off like // a switch) return new string [] { "Six", "Seven", "Eight" }; } public override void WillAddItem (NSNotification notification) { } public override NSToolbarItem WillInsertItem (NSToolbar toolbar, string itemIdentifier, bool willBeInserted) { NSToolbarItem item = null; // Take action based on the Identifier switch(itemIdentifier){ case "NSToolbarSpaceItem": item = new NSToolbarItem("NSToolbarSpaceItem"); item.Label = "Space"; item.PaletteLabel = "Space"; break; case "NSToolbarFlexibleSpaceItem": item = new NSToolbarItem("NSToolbarFlexibleSpaceItem"); item.Label = "Flexible Space"; item.PaletteLabel = "Flexible Space"; break; case "NSToolbarShowColorsItem": item = new NSToolbarItem("NSToolbarShowColorsItem"); item.Label = "Colors"; item.PaletteLabel = "Colors"; break; case "NSToolbarShowFontsItem": item = new NSToolbarItem("NSToolbarShowFontsItem"); item.Label = "Fonts"; item.PaletteLabel = "Fonts"; break; case "NSToolbarPrintItem": item = new NSToolbarItem("NSToolbarPrintItem"); item.Label = "Print"; item.PaletteLabel = "Print"; break; default: item = BuildItem (itemIdentifier); break; } return item; } #endregion #region Events // Create a custom event to inform the caller when a user clicks // on one of the Toolbar Items. public delegate void ToolbarItemClickedDelegate(string identifier); public event ToolbarItemClickedDelegate ToolbarItemClicked; // If the caller has subscribed to the custom event, inform them // it is being raised. internal void RaiseToolbarItemClicked(string identifier){ if (this.ToolbarItemClicked != null) this.ToolbarItemClicked(identifier); } #endregion } ``` Let’s take a closer look at what this code is doing. First, the `AllowedItemIdentifiers` method returns a list of string based identifiers specifying the allowable items that can be placed on the Toolbar. If the Toolbar is end user customizable, this method will provide the list of items that the user can add to the Toolbar that might not already be on it by default. In addition to the list of Identifiers that define the custom items for this Toolbar, several built-in Toolbar Items provided by macOS are included as follows: * `NSToolbarSpaceItem` - Inserts a fixed width space into the Toolbar. * `NSToolbarFlexibleSpaceItem` - Inserts a flexible width space into the Toolbar. This can be used to send the following items to the right side of the bar, for example. * `NSToolbarShowColorsItem` - Inserts a standard Color Picker into the Toolbar. * `NSToolbarShowFontsItem` - Inserts a standard Font Picker into the Toolbar. * `NSToolbarPrintItem` - Inserts a standard Print Dialog Box into the Toolbar. The `DefaultItemIdentifiers` method returns a list of Item Identifiers (as defined in the `AllowedItemIdentifiers` method) that will form the Default Toolbar initially displayed to the end user. Again, if the Toolbar is end user customizable, this method will provide the list of default items that the user can use to reset the Toolbar to its default state. The `SelectableItemIdentifiers` method returns a list of Item Identifiers (as defined in the `AllowedItemIdentifiers` method) that can be selected by the user. Selectable Toolbar Items have an on/off state like a switch. Only one Selectable Toolbar Item can be selected at any giving time in the Toolbar. For example: ![](Images/Selectable01.png) The `WillInsertItem` method is called when the Toolbar is requesting a new Toolbar Item (`NSToolbarItem`) for a specific Item Identifier. If the passed in `itemIdentifier` is one of the built-in Toolbar Items provided by macOS (such as `NSToolbarShowColorsItem`) it is created and returned, else the `BuildItem` method is called to create a custom item and return it. The `BuildItem` method creates a new custom `NSToolbarItem` based on the Identifier passed in. For the sake of this example, it will have an icon from a file named the same as the Identifier (included in the Images resources for this workbook) and will use the Identifier for both the `Label` and the `PaletteLabel` title. The `Label` will be displayed under the icon when the item is placed on a Toolbar. The `PaletteLabel` is displayed under the item when it is on the Customize Dialog: ![](Images/Customize01.png) Lastly, a custom event, `ToolbarItemClicked`, was defined that the Toolbar’s parent View or View Controller can subscribe to and be informed when the user clicks a Toolbar Item. Every Toolbar Item created by the `BuildItem` method will raise this event when clicked. Because the Toolbar Delegate is subscribing to the Toolbar Item’s `Activated` event, all the items will be automatically be enabled when the Toolbar is displayed. See the **Enabling and Disabling Toolbar Items** section below for more information. > 💡**Try It Now** > > 1. Change the Default Toolbar that is initially displayed to the user. > 2. Add a Wallet item to the list of Available Toolbar Items and the Default Toolbar. _**Hint**: a `Wallet.png` file has been included in the Images resources for this workbook._ > > ⚠️ These changes wont take effect until a new instance of the Window that houses the Toolbar is instantiated in the **Displaying the Toolbar in a Window** section below. ### Toolbar Item Properties When the Toolbar Delegate (`NSToolbarDelegate`) creates a new instance of the Toolbar Item (`NSToolbarItem`) in the `WillInsertItem` method, there are several properties that the developer can set: * `AllowsDuplicateInToolbar` - If `true`, the user can place more than one instance in the Toolbar when they customize it, else they cannot. * `Enabled` - Gets or sets the enabled state of the Toolbar Item. Because of the way Toolbar Items are automatically validated by macOS, simply setting this value to `false` is typically not enough to keep it disabled. See the **Enabling and Disabling Toolbar Items** section below for more information. * `Identifier` - Uniquely identifies the Toolbar Item as a custom type defined by the macOS app or one of the built-in types (such as `NSToolbarShowColorsItem` or `NSToolbarFlexibleSpaceItem`). * `Image` - Defines the icon for the Toolbar Item as a `NSImage`. * `Label` - This is the text that will be displayed for the item when it is on the Toolbar. * `PaletteLabel` - This is the text for the item in the **Allowed Toolbar Items** area of the Customize Dialog. * `Tag` - Is an integer value that can optionally set by the developer to help identify or hold state information for the item in code. * `ToolTip` - A string value that will be displayed to the user when they hover the mouse over the Toolbar Item to given them an indication of what clicking the item will do. * `View` - Allow the developer to attach other types of controls to a Toolbar Item such a `NSTextFields` or `NSButtons`. Please see the **Adding Other UI Controls to a Toolbar** section below for more information. > 💡**Try It Now** > > 1. Add a `ToolTip` to each Toolbar Item created in the `MainToolbarDelegate`. ***Hint**: this will need to be done inside of the `BuildItem` method.* > 2. Add a unique Tag to each Toolbar Item created in the `MainToolbarDelegate`. > > ⚠️ These changes wont take effect until a new instance of the Window that houses the Toolbar is instantiated in the **Displaying the Toolbar in a Window** section below. ## Creating a Custom Toolbar Since this workbook is creating a Toolbar completely from code, a custom class is being used to define and configure the Toolbar: ```csharp using System; using Foundation; using AppKit; public class MainToolbar : NSToolbar { #region Computed Properties public MainToolbarDelegate ToolbarDelegate { get { return Delegate as MainToolbarDelegate; } set { Delegate = value; } } #endregion #region Constructors public MainToolbar (string identifier) : base (identifier) { // Initialize this.ToolbarDelegate = new MainToolbarDelegate (); this.AllowsUserCustomization = true; this.AutosavesConfiguration = false; this.DisplayMode = NSToolbarDisplayMode.Default; this.SizeMode = NSToolbarSizeMode.Default; } #endregion } ``` Let’s take a closer look at what this code is doing. First, it defines a `ToolbarDelegate` computed property to make accessing the custom `MainToolbarDelegate` (created above) easier. When a new instance of the Toolbar is created, a new `MainToolbarDelegate` is also created and attached to the `ToolbarDelegate` computed property. Additionally, the look and functionality of the Toolbar is being configured as follows: * `AllowsUserCustomization` - If `true`, the user can right-click and customize the items that are displayed on the Toolbar. * `AutosavesConfiguration` - If `true`, the system will automatically save any customization that the user does to the Toolbar. * `DisplayMode` - Controls how the items are displayed on the Toolbar as: `Default`, `Icon`, `IconAndLabel` or `Label`. * `SizeMode` - Controls the size of the items on the Toolbar as: `Default`, `Regular` or `Small`. Both the `DisplayMode` and `SizeMode` properties can be affected by the type of Window that the Toolbar is attached to and will render some of the modes unavailable. > 💡**Try It Now** > > 1. Don’t allow the user to customize the Toolbar. > 2. Pick a different `DisplayMode`. > 3. Pick a different `SizeMode`. > > ⚠️ These changes wont take effect until a new instance of the Window that houses the Toolbar is instantiated in the **Displaying the Toolbar in a Window** section below. ## External Resources To focus on the `NSToolbar` only, all of the supporting code to build the required Windows, Window Controllers, Views and View Controller has been moved to an external file that is being loaded below: ```csharp // The implementation of these supporting controllers is not important to // understanding the `NSToolBar` control so they have been moved // to an external file. #load "toolbar-resources.csx" ``` This code implements a static `ToolbarResources` class that will be used throughout the rest of this workbook to open Windows that unitize the `MainToolbar` and `MainToolbarDelegate` classes created above. For example: ```csharp // Build new window var contentRect = new CGRect (0, 100, 600, 500); var aWindow = new NSWindow (contentRect, (NSWindowStyle.Titled | NSWindowStyle.Closable | NSWindowStyle.Miniaturizable | NSWindowStyle.Resizable), NSBackingStore.Buffered, false); // Build new toolbar var toolbar = new MainToolbar ("MainToolbar"); // Wireup toolbar events toolbar.ToolbarDelegate.ToolbarItemClicked += (identifier) => { // Do something when the user clicks a toolbar item... }; // Attach the toolbar to the window aWindow.Toolbar = toolbar; ``` For more information on working with Windows, Window Controllers, Views and View Controller in code, please see our [.storyboard/.xib Less User Interface Design](https://developer.xamarin.com/guides/mac/application_fundamentals/xibless-ui/) workbook and documentation. ## Displaying the Toolbar in a Window How a Toolbar is finally rendered and displayed to the end user and what Display and Size Modes are available depends on the style of Window the Toolbar is attached to. As of macOS Sierra there are two available styles of Windows: * **Traditional** - These are typical of the Windows displayed by OS X where there is a separate Title and Toolbar area. * **Modern** - In macOS Sierra, the Title and Toolbar areas can be combined. Additionally, the Content Area can be extended and displayed under the combined Title and Toolbar areas. For “shoebox” types of single Window apps, a new Dark Theme is also available. To see how the Toolbar created above looks on a Traditional Window, run the code segment below: ```csharp // Use the factory to create and display a new traditional style // window that uses the custom toolbar ToolbarResources.OpenNewTraditionalWindow(); ``` Next, to see how the same Toolbar looks on a Modern Window, run the following code segment: ```csharp // Use the factory to create and display a new modern style // window that uses the custom toolbar ToolbarResources.OpenNewModernWindow(); ``` Every time either one of these code blocks are run, a new Window will be created with the latest version of the `MainToolbar` and it will be displayed in a tab grouped by Traditional or Modern Window types. > ⚠️ **WARNING!** *Support for automatically tabbed windows is currently unavailable in the Version 01.00.00 of Xamarin Workbooks. This feature will be restored in a future release.* > ⚠️ **Note**: Because of the way that `NSToolBars` are handled by macOS, all of the `NSWindows` within a given app share a single Toolbar instance based on the Identifier assigned the to the Toolbar when it was created. As a result, changing the Toolbar in one Window will affect the Toolbars on all other open Windows in the app that used the same Identifier to build the Toolbar. ## User Toolbar Customization If the `AllowsUserCustomization` property of the `NSToolbar` has been set to `true`, the end user will be able to right-click on the Toolbar and adjust several of its display properties: ![](Images/Customize02.png) The top set of options relate to the `DisplayMode` property and the middle option to the `SizeMode` property of the Toolbar. The final option, **Customize Toolbar…**, allows the user to fully customize the items on the Toolbar. For example: ![](Images/Customize03.png) The items in the **Drag your favorite items into the toolbar…** section come from the `AllowedItemIdentifiers` method of the custom `MainToolbarDelegate` (created above) and the items in the **…or drag the default set into the toolbar** section come from the `DefaultItemIdentifiers` method. > 💡**Try It Now** > > 1. Switch the the running macOS app, right-click the Toolbar and customize it for the Traditional Style Windows. > 2. Switch the the running macOS app, right-click the Toolbar and customize it for the Modern Style Windows. ## Hiding and Showing the Toolbar Once the Toolbar is configured, attached to a Window and displayed to the user, a macOS app can programmatically hide and show it using the `Visible` property: ```csharp // Hide or show the Toolbar on the last created Traditional Style Window ToolbarResources.LastTraditionalWindowController.Window.Toolbar.Visible = true; // Hide or show the Toolbar on the last created Modern Style Window ToolbarResources.LastModernWindowController.Window.Toolbar.Visible = true; ``` > 💡**Try It Now** > > 1. Set `Visible` to `false` to hide the Toolbars. > 2. Set `Visible` to `true` to show the Toolbars. ## Working with Toolbar Items After a Toolbar is created and displayed to the user, the developer can access each Toolbar Item currently visible on the Toolbar using the `Items` property. For example, the following code returns the first item on the current Toolbar: ```csharp // Access the first Toolbar item var toolbar = ToolbarResources.LastTraditionalWindowController.Window.Toolbar; var firstItem = toolbar.Items[0]; ``` Once the item has been accessed, several of its properties can be modified, such as the `Label` or `Tooltip`: ```csharp // Change the current label firstItem.Label = "Certificate"; firstItem.ToolTip = "Create a new certificate"; ``` > 💡**Try It Now** > > 1. Give the first Toolbar Item a new `Label`. > 2. Give the first Toolbar Item a new `Tooltip`. > 3. Access the last item in the Toolbar and change its `Label`. _**Hint**: Use the `Count()` method of the `Items` array._ ## Hiding and Showing Toolbar Items Toolbars in a macOS app have different usability guidelines than Toolbars in an iOS or a Window application. Because Apple wants the user to have total control over the items and their layout within a Toolbar, no method is provided to hide and show individual Toolbar Items. Instead, Apple wants the developer to simply enable or disable items based on the current context of the user’s actions within the app. ## Enabling and Disabling Toolbar Items Because of the way macOS handles both Toolbars and Toolbar Items, simply setting the `Enabled` property of a `NSToolbarItem` typically isn’t enough to disable an item on a Toolbar. To disable a Toolbar Item, the developer needs to create a custom instance of `NSToobarItem,` override the `Validate` method and use this custom instance when creating items in the Toolbar Delegate or when adding items to the Toolbar inside of Xcode’s Interface Builder: ```csharp using System; using Foundation; using AppKit; [Register("ManuallyEnabledToolbarItem")] public class ManuallyEnabledToolbarItem : NSToolbarItem { #region Computed Properties public bool Disabled { get; set;} = false; #endregion #region Constructors public ManuallyEnabledToolbarItem () { } public ManuallyEnabledToolbarItem (IntPtr handle) : base (handle) { } public ManuallyEnabledToolbarItem (NSObjectFlag t) : base (t) { } public ManuallyEnabledToolbarItem (string identifier) : base (identifier) { } #endregion #region Override Methods public override void Validate () { base.Validate (); // Set the enabled state of the Toolbar Item Enabled = !Disabled; } #endregion } ``` Let’s take a closer look at what this code is doing. First, it creates a `Disabled` computed property to hold the enabled/disabled state of the Toolbar Item. Again, the built-in `Enabled` property cannot be used because it will be overriden when the system auto-validated the Toolbar. The `Validate` method is overridden and the `Enabled` property of the Toolbar Item is set. When the system begins to validate a Toolbar against the current state of a macOS app, it will call the `Validate` method on every item in the Toolbar to set their enabled/disabled state. To implement this new type of Toolbar Item, create a new Toolbar Delegate Type and use the `ManuallyEnabledToolbarItem` class in the `BuildItem` method: ```csharp using System; using Foundation; using AppKit; public class ModifableToolbarDelegate : NSToolbarDelegate { #region Constructors public ModifableToolbarDelegate () { } #endregion #region Private Methods // Build and return a custom Toolbar Item private NSToolbarItem BuildItem (string identifier) { // Create new manually enabled toolbar item var item = new ManuallyEnabledToolbarItem (identifier); // Set properties item.Image = new NSImage($"Images/{identifier}.png"); item.Label = identifier; item.PaletteLabel = identifier; item.Disabled = false; // Attach an action event item.Activated += (sender, e) => { RaiseToolbarItemClicked(item.Identifier); }; // Return new item return item; } #endregion #region Override Methods public override string [] AllowedItemIdentifiers (NSToolbar toolbar) { // Return the list of available item identifiers return new string [] { "One","Two","Three","Four","Five","Six","Seven","Eight" }; } public override string [] DefaultItemIdentifiers (NSToolbar toolbar) { // Return the item identifiers that make up the default Toolbar return new string [] { "One","Two","Three","Four","Five","Six","Seven","Eight" }; } public override NSToolbarItem WillInsertItem (NSToolbar toolbar, string itemIdentifier, bool willBeInserted) { // Build and return each item return BuildItem (itemIdentifier); } #endregion #region Events // Create a custom event to inform the caller when a user clicks // on one of the Toolbar Items. public delegate void ToolbarItemClickedDelegate(string identifier); public event ToolbarItemClickedDelegate ToolbarItemClicked; // If the caller has subscribed to the custom event, inform them // it is being raised. internal void RaiseToolbarItemClicked(string identifier){ if (this.ToolbarItemClicked != null) this.ToolbarItemClicked(identifier); } #endregion } ``` And create a new custom Toolbar to use this new delegate: ```csharp using System; using Foundation; using AppKit; public class ModifableToolbar : NSToolbar { #region Computed Properties public ModifableToolbarDelegate ToolbarDelegate { get { return Delegate as ModifableToolbarDelegate; } set { Delegate = value; } } #endregion #region Constructors public ModifableToolbar (string identifier) : base (identifier) { // Initialize this.ToolbarDelegate = new ModifableToolbarDelegate (); this.AllowsUserCustomization = true; this.AutosavesConfiguration = false; this.DisplayMode = NSToolbarDisplayMode.Default; this.SizeMode = NSToolbarSizeMode.Default; } #endregion } ``` With this in place, create a new instance of the new custom Toolbar and attach it to an open window: ```csharp // Create a new toolbar var toolbar = new ModifableToolbar("ModifableToolbar"); // Attach it to the last opened window ToolbarResources.LastTraditionalWindowController.Window.Toolbar = toolbar; ``` Finally, a given Toolbar Item instance can be selected and disabled in code: ```csharp // Access the 3rd item in the Toolbar var item = toolbar.Items[2] as ManuallyEnabledToolbarItem; // Disable the item item.Disabled = true; ``` ## Adding Other UI Controls to a Toolbar The developer is not limited to the standard types of Toolbar Items when adding elements to a Toolbar. Several of the other Cocoa UI elements (such as Search Fields or Segment Controls) can be added to a Toolbar. Typically, this is done by editing the `.storyboard` or `.xib` file in Xcode’s Interface Builder, opening the Toolbar in the **Interface Hierarchy**, displaying the **Customize Dialog** and dragging a UI control (such as a Search Field) from the **Library Inspector** onto the **Allowed Toolbar Items** area. In code, this is accomplished by attaching a newly built UI control to the `View` property of a Toolbar Item as it is being created. For example, as is being done in the `WillInsertItem` method of the Toolbar Delegate below for the “*Search*” Identifier: ```csharp using System; using Foundation; using AppKit; public class OtherToolbarDelegate : NSToolbarDelegate { #region Constructors public OtherToolbarDelegate () { } #endregion #region Private Methods // Build and return a custom Toolbar Item private NSToolbarItem BuildItem (string identifier) { // Create new toolbar item var item = new NSToolbarItem (identifier); // Set properties item.Image = new NSImage($"Images/{identifier}.png"); item.Label = identifier; item.PaletteLabel = identifier; item.Enabled = true; // Attach an action event item.Activated += (sender, e) => { RaiseToolbarItemClicked(item.Identifier); }; // Return new item return item; } #endregion #region Override Methods public override string [] AllowedItemIdentifiers (NSToolbar toolbar) { // Return the list of available item identifiers return new string [] { "One","Two","NSToolbarFlexibleSpaceItem","Search" }; } public override string [] DefaultItemIdentifiers (NSToolbar toolbar) { // Return the item identifiers that make up the default Toolbar return new string [] { "One","Two","NSToolbarFlexibleSpaceItem","Search" }; } public override NSToolbarItem WillInsertItem (NSToolbar toolbar, string itemIdentifier, bool willBeInserted) { NSToolbarItem item = null; // Take action based on the Identifier switch(itemIdentifier){ case "NSToolbarFlexibleSpaceItem": item = new NSToolbarItem("NSToolbarFlexibleSpaceItem"); item.Label = "Flexible Space"; item.PaletteLabel = "Flexible Space"; break; case "Search": // Create search text field var search = new NSTextField(new CGRect(0,0,150,25)) { Bordered = true, Editable = true, PlaceholderString = "Search" }; // Create a new search item with a text field for searching item = new NSToolbarItem("Search"); item.Label = "Search"; item.PaletteLabel = "Search"; item.MinSize = new CGSize(150,25); item.View = search; break; default: item = BuildItem (itemIdentifier); break; } return item; } #endregion #region Events // Create a custom event to inform the caller when a user clicks // on one of the Toolbar Items. public delegate void ToolbarItemClickedDelegate(string identifier); public event ToolbarItemClickedDelegate ToolbarItemClicked; // If the caller has subscribed to the custom event, inform them // it is being raised. internal void RaiseToolbarItemClicked(string identifier){ if (this.ToolbarItemClicked != null) this.ToolbarItemClicked(identifier); } #endregion } ``` Let’s take a closer look at what this code is doing. In the `WillInsertItem` method, it’s creating and configuring a new `NSTextField` to act as a Search field. When the control is created, its width (150px) and height (25px) are set using a `CGRect`. Before the Text Field (`search`) is attached to the `View` property of the new Toolbar Item, the Minimum Size (`MinSize` property) is set to match the size of the `NSTextField` created (`item.MinSize = new CGSize(150,25);`). If this wasn’t done, the default built-in Toolbar Item size would be used and the `NSTextField` would be down-sized to fit into this new, smaller size. Again, a new custom Toolbar is created to use this new delegate: ```csharp using System; using Foundation; using AppKit; public class OtherToolbar : NSToolbar { #region Computed Properties public OtherToolbarDelegate ToolbarDelegate { get { return Delegate as OtherToolbarDelegate; } set { Delegate = value; } } #endregion #region Constructors public OtherToolbar (string identifier) : base (identifier) { // Initialize this.ToolbarDelegate = new OtherToolbarDelegate (); this.AllowsUserCustomization = true; this.AutosavesConfiguration = false; this.DisplayMode = NSToolbarDisplayMode.Default; this.SizeMode = NSToolbarSizeMode.Default; } #endregion } ``` And an instance of the new custom Toolbar is created and attach it to an open window: ```csharp // Create a new toolbar var toolbar = new OtherToolbar("OtherToolbar"); // Attach it to the last opened window ToolbarResources.LastModernWindowController.Window.Toolbar = toolbar; ``` When the code block above is run, the last Modern Style Window created will be switched to use the new Toolbar including the Search field. ================================================ FILE: mac/user-interface/toolbars/toolbars.workbook/toolbar-resources.csx ================================================ using System; using Foundation; using AppKit; using CoreGraphics; // ========================================================================== // NOTE: This file contains the backing resources to create the Windows, // View Controllers and View needed to support the Working with Toolbars // Workbook. The implementation of these controllers is not important to // understanding the `NSToolBar` control so they have been moved here. // ========================================================================== /// /// The LayerBackedView class is used to create a modern View within a /// View Controller that is backed by a Core Graphics Layer. /// public class LayerBackedView : NSView { #region Private Variables /// /// The color of the background. /// private NSColor _backgroundColor = NSColor.White; #endregion #region Computed Properties /// /// Gets a value indicating whether this wants layer. /// /// true if wants layer; otherwise, false. public override bool WantsLayer { get { return true; } } /// /// Gets a value indicating whether this wants to update /// the layer. /// /// true if wants update layer; otherwise, false. public override bool WantsUpdateLayer { get { return true; } } /// /// Gets or sets the color of the background. /// /// The color of the background. public NSColor BackgroundColor { get { return _backgroundColor; } set { // Save color _backgroundColor = value; // Force the view to update NeedsDisplay = true; } } #endregion #region Constructor /// /// Initializes a new instance of the class. /// /// Handle. public LayerBackedView (IntPtr handle) : base (handle) { } /// /// Initializes a new instance of the class. /// /// Bounds. public LayerBackedView (CGRect bounds) : base (bounds) { } #endregion #region Override Methods /// /// Updates the layer. /// public override void UpdateLayer () { base.UpdateLayer (); // Add the Core Graphics routines to draw the View's UI Layer.BackgroundColor = _backgroundColor.CGColor; } #endregion } /// /// Traditional code based window that uses the traditional look and feel /// of an OS X Window. Typically this Window would be created in a Xcode /// Interface Builder `.storyboard` file. For the sake of this workbook, /// the Window is being created in code. /// public class TraditionalCodeBasedWindow : NSWindow { #region Computed Properties /// /// Gets or sets the click me label. /// /// The click me label. public NSTextField ClickMeLabel { get; set; } #endregion #region Constructors /// /// Initializes a new instance of the class. /// /// Handle. public TraditionalCodeBasedWindow (IntPtr handle) : base (handle) { } /// /// Initializes a new instance of the class. /// /// Coder. [Export ("initWithCoder:")] public TraditionalCodeBasedWindow (NSCoder coder) : base (coder) { } /// /// Initializes a new instance of the class. /// /// Content rect. /// A style. /// Buffering type. /// If set to true defer creation. public TraditionalCodeBasedWindow (CGRect contentRect, NSWindowStyle aStyle, NSBackingStore bufferingType, bool deferCreation) : base (contentRect, aStyle, bufferingType, deferCreation) { // Create a default title for the window Title = "Untitled"; // Create the content view for the window and make it fill the window ContentView = new LayerBackedView (Frame); // _________________________________________________________________ // WARNING! // The modern macOS App UI is currently unavaiable in the Version // 0.99.0.0 of Xamarin Workbooks. This feature will be restored in a // future release. // _________________________________________________________________ // Configure the Window to use Tabs // TabbingMode = NSWindowTabbingMode.Preferred; // TabbingIdentifier = "Traditional"; // Define Window UI ClickMeLabel = new NSTextField (new CGRect (10, Frame.Height - 125, Frame.Width - 20, 20)) { BackgroundColor = NSColor.Clear, TextColor = NSColor.LabelColor, Editable = false, Bezeled = false, AutoresizingMask = NSViewResizingMask.WidthSizable | NSViewResizingMask.MinYMargin, StringValue = "Click on a Toolbar item above." }; ContentView.AddSubview (ClickMeLabel); } #endregion #region Override Method /// /// Awakes from nib. /// public override void AwakeFromNib () { base.AwakeFromNib (); // Build and configure a new toolbar var toolbar = new MainToolbar ("TraditionalToolbar"); // Wireup toolbar events toolbar.ToolbarDelegate.ToolbarItemClicked += (identifier) => { ClickMeLabel.StringValue = $"You clicked the {identifier} Toolbar Item."; }; // Attach toolbar to window this.Toolbar = toolbar; } #endregion } /// /// Traditional code based Window Controller instantiats and controls an instance of /// the `TraditionalCodeBasedWindow` defined above. /// public class TraditionalCodeBasedWindowController : NSWindowController { #region Computed Properties /// /// Gets the window. /// /// The window. public new TraditionalCodeBasedWindow Window { get { return base.Window as TraditionalCodeBasedWindow; } } #endregion #region Constructors /// /// Initializes a new instance of the class. /// /// Handle. public TraditionalCodeBasedWindowController (IntPtr handle) : base (handle) { } /// /// Initializes a new instance of the class. /// /// Coder. [Export ("initWithCoder:")] public TraditionalCodeBasedWindowController (NSCoder coder) : base (coder) { } /// /// Initializes a new instance of the class. /// public TraditionalCodeBasedWindowController () : base ("CodeBasedWindow") { // Define the Window's default location and size CGRect contentRect = new CGRect (0, 0, 600, 500); // Create a new instance of the CodeBasedWindow base.Window = new TraditionalCodeBasedWindow (contentRect, (NSWindowStyle.Titled | NSWindowStyle.Closable | NSWindowStyle.Miniaturizable | NSWindowStyle.Resizable | NSWindowStyle.FullSizeContentView), NSBackingStore.Buffered, false); // Simulate Awaking from Nib Window.AwakeFromNib (); } #endregion #region Override Methods /// /// Awakes from nib. /// public override void AwakeFromNib () { base.AwakeFromNib (); } // _________________________________________________________________ // WARNING! // The modern macOS App UI is currently unavaiable in the Version // 0.99.0.0 of Xamarin Workbooks. This feature will be restored in a // future release. // _________________________________________________________________ /// /// Gets the new window for tab. /// /// Sender. // public override void GetNewWindowForTab (NSObject sender) // { // // Create a new window when the Plus button is clicked // ToolbarResources.OpenNewTraditionalWindow (); // } #endregion } /// /// Modern code based window that uses the modern look and feel /// of a macOS Sierra Window. Typically this Window would be created in a Xcode /// Interface Builder `.storyboard` file. For the sake of this workbook, /// the Window is being created in code. /// public class ModernCodeBasedWindow : NSWindow { #region Computed Properties /// /// Gets or sets the click me label. /// /// The click me label. public NSTextField ClickMeLabel { get; set; } #endregion #region Constructors /// /// Initializes a new instance of the class. /// /// Handle. public ModernCodeBasedWindow (IntPtr handle) : base (handle) { } /// /// Initializes a new instance of the class. /// /// Coder. [Export ("initWithCoder:")] public ModernCodeBasedWindow (NSCoder coder) : base (coder) { } /// /// Initializes a new instance of the class. /// /// Content rect. /// A style. /// Buffering type. /// If set to true defer creation. public ModernCodeBasedWindow (CGRect contentRect, NSWindowStyle aStyle, NSBackingStore bufferingType, bool deferCreation) : base (contentRect, aStyle, bufferingType, deferCreation) { // Create a default title for the window Title = "Untitled"; // Select the dark appearance Appearance = NSAppearance.GetAppearance (NSAppearance.NameVibrantDark); // Create the content view for the window and make it fill the window ContentView = new LayerBackedView (Frame); // Hide the Title bar for a streamlined UI TitleVisibility = NSWindowTitleVisibility.Hidden; // _________________________________________________________________ // WARNING! // The modern macOS App UI is currently unavaiable in the Version // 0.99.0.0 of Xamarin Workbooks. This feature will be restored in a // future release. // _________________________________________________________________ // Configure the Window to use Tabs // TabbingMode = NSWindowTabbingMode.Preferred; // TabbingIdentifier = "Modern"; // Define Window UI ClickMeLabel = new NSTextField (new CGRect (10, Frame.Height - 125, Frame.Width - 20, 20)) { BackgroundColor = NSColor.Clear, TextColor = NSColor.LabelColor, Editable = false, Bezeled = false, AutoresizingMask = NSViewResizingMask.WidthSizable | NSViewResizingMask.MinYMargin, StringValue = "Click on a Toolbar item above." }; ContentView.AddSubview (ClickMeLabel); } #endregion #region Override Method /// /// Awakes from nib. /// public override void AwakeFromNib () { base.AwakeFromNib (); // Build and configure a new toolbar var toolbar = new MainToolbar ("ModernToolbar"); // Wireup toolbar events toolbar.ToolbarDelegate.ToolbarItemClicked += (identifier) => { ClickMeLabel.StringValue = $"You clicked the {identifier} Toolbar Item."; }; // Attach toolbar to window this.Toolbar = toolbar; } #endregion } /// /// Modern code based Window Controller instantiats and controls an instance of /// the `ModernCodeBasedWindow` defined above. /// public class ModernCodeBasedWindowController : NSWindowController { #region Computed Properties /// /// Gets the window. /// /// The window. public new ModernCodeBasedWindow Window { get { return base.Window as ModernCodeBasedWindow; } } #endregion #region Constructors /// /// Initializes a new instance of the class. /// /// Handle. public ModernCodeBasedWindowController (IntPtr handle) : base (handle) { } /// /// Initializes a new instance of the class. /// /// Coder. [Export ("initWithCoder:")] public ModernCodeBasedWindowController (NSCoder coder) : base (coder) { } /// /// Initializes a new instance of the class. /// public ModernCodeBasedWindowController () : base ("CodeBasedWindow") { // Define the Window's default location and size CGRect contentRect = new CGRect (0, 100, 600, 500); // Create a new instance of the CodeBasedWindow base.Window = new ModernCodeBasedWindow (contentRect, (NSWindowStyle.Titled | NSWindowStyle.Closable | NSWindowStyle.Miniaturizable | NSWindowStyle.Resizable | NSWindowStyle.FullSizeContentView | NSWindowStyle.UnifiedTitleAndToolbar), NSBackingStore.Buffered, false); // Simulate Awaking from Nib Window.AwakeFromNib (); } #endregion #region Override Methods /// /// Awakes from nib. /// public override void AwakeFromNib () { base.AwakeFromNib (); } // _________________________________________________________________ // WARNING! // The modern macOS App UI is currently unavaiable in the Version // 0.99.0.0 of Xamarin Workbooks. This feature will be restored in a // future release. // _________________________________________________________________ /// /// Gets the new window for tab. /// /// Sender. // public override void GetNewWindowForTab (NSObject sender) // { // // Create a new window when the Plus button is clicked // ToolbarResources.OpenNewModernWindow (); // } #endregion } /// /// Toolbar resources is a static helper class that creates and maintains /// instances of the Windows, View Controllers and Views needed to support /// playing with a `NSToolbar` control in a Workbook. /// public static class ToolbarResources { #region Computed Properties /// /// Gets or sets the traditional window count. /// /// The traditional window count. public static int TraditionalWindowCount { get; set; } = 0; /// /// Gets or sets the last traditional window controller. /// /// The last traditional window controller. public static TraditionalCodeBasedWindowController LastTraditionalWindowController { get; set; } = null; /// /// Gets or sets the modern window count. /// /// The modern window count. public static int ModernWindowCount { get; set; } = 0; /// /// Gets or sets the last modern window controller. /// /// The last modern window controller. public static ModernCodeBasedWindowController LastModernWindowController { get; set; } = null; #endregion #region Controller Factories /// /// Opens and displays a new traditional window. /// public static void OpenNewTraditionalWindow () { // Create a new instace of the Traditional Window Controller LastTraditionalWindowController = new TraditionalCodeBasedWindowController (); // Set the title LastTraditionalWindowController.Window.Title = (TraditionalWindowCount++ == 0) ? "Untitled" : $"Untitled {TraditionalWindowCount}"; // Display the Window LastTraditionalWindowController.Window.MakeKeyAndOrderFront ((NSObject)NSApplication.SharedApplication.Delegate); } /// /// Opens and displays a new modern window. /// public static void OpenNewModernWindow () { // Create a new instace of the Traditional Window Controller LastModernWindowController = new ModernCodeBasedWindowController (); // Set the title LastModernWindowController.Window.Title = (ModernWindowCount++ == 0) ? "Untitled" : $"Untitled {ModernWindowCount}"; // Display the Window LastModernWindowController.Window.MakeKeyAndOrderFront ((NSObject)NSApplication.SharedApplication.Delegate); } #endregion } ================================================ FILE: mac/user-interface/ui-in-code/README.md ================================================ .storyboard/.xib Less User Interface Design Workbook ============ This workbook will cover the steps required to build a Xamarin.Mac app's User Interface directly from C# code without using a Xcode's Interface Builder `.storyboard` or `.xib` file. ![](screenshots/Intro01.png) ================================================ FILE: mac/user-interface/ui-in-code/codebasedui.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacMobile --- # .storyboard/.xib Less User Interface Design ## How to create a Xamarin.Mac app's UI from C# code This workbook will cover the steps required to build a Xamarin.Mac app's User Interface directly from C# code without using a Xcode's Interface Builder `.storyboard` or `.xib` file. For more information, please see our [.storyboard/.xib Less User Interface Design](https://developer.xamarin.com/guides/mac/application_fundamentals/xibless-ui/) documentation. Creating a Modern macOS App User Interface in code, such as the ones used in Apple's Safari web browser, Pages word processor and Numbers spread sheet app is also covered at the end of this workbook. For more information, please see our [Building Modern macOS Apps](https://developer.xamarin.com/guides/mac/platform-features/introduction-to-macos-sierra/modern-cocoa-apps/) documentation ## Defining the UI in Interface Builder Before diving into the process of building a Xamarin.Mac app’s User Interface in code, let’s quickly review how a macOS app’s UI is normally created. Typically, a Xamarin.Mac app’s User Interface is defined in one or more `.storyboard` or `.xib` files added to the project’s hierarchy. For example: ![](Images/Xcode01.png) Double-clicking this file will open it in Xcode’s Interface Builder where the Menus, Windows, Controls and Segues that make up the app’s UI can be defined visually. For example: ![](Images/Xcode02.png) When the UI layout is completed, the graphical elements that make up the UI are then exposed via **Actions** and **Outlets,** making them accessible to code. When the developer saves their changes to the `Main.storyboard` file and returns to Xamarin Studio, these changes are synced with the Xamarin.Mac app’s Project File and the UI elements are then accessible in C#. ## Defining the UI in Code All macOS app’s User Interfaces are based off of a MVC (Model View Controller) methodology. As shown above, this is typically defined in a `.storyboard` or `.xib` file. When creating the User Interface directly in code, the developer will be responsible for building and properly initializing both the Window (`NSWindow`) and its Window Controller (`NSWindowController`). ### Defining the Window The first thing that will need to be done, is to create a Window (`NSWindow`) to hold all of the elements that will go into building the Xamarin.Mac app’s UI. Start by creating a custom class to layout and initialize this window: ```csharp using System; using Foundation; using AppKit; using CoreGraphics; public class CodeBasedWindow : NSWindow { #region Private Variables private int NumberOfTimesClicked = 0; #endregion #region Computed Properties public NSButton ClickMeButton { get; set;} public NSTextField ClickMeLabel { get ; set;} #endregion #region Constructors public CodeBasedWindow (IntPtr handle) : base (handle) { } [Export ("initWithCoder:")] public CodeBasedWindow (NSCoder coder) : base (coder) { } public CodeBasedWindow (CGRect contentRect, NSWindowStyle aStyle, NSBackingStore bufferingType, bool deferCreation): base (contentRect, aStyle,bufferingType,deferCreation) { // Create a title for the window Title = "Window From Code"; // Create the content view for the window and make it fill the window ContentView = new NSView (Frame); // Layout the Window's UI ClickMeButton = new NSButton (new CGRect (10, Frame.Height-70, 100, 30)){ AutoresizingMask = NSViewResizingMask.MinYMargin }; ContentView.AddSubview (ClickMeButton); ClickMeLabel = new NSTextField (new CGRect (120, Frame.Height - 65, Frame.Width - 130, 20)) { BackgroundColor = NSColor.Clear, TextColor = NSColor.Black, Editable = false, Bezeled = false, AutoresizingMask = NSViewResizingMask.WidthSizable | NSViewResizingMask.MinYMargin, StringValue = "Button has not been clicked yet." }; ContentView.AddSubview (ClickMeLabel); } #endregion #region Override Methods public override void AwakeFromNib () { base.AwakeFromNib (); // Wireup events ClickMeButton.Activated += (sender, e) => { // Update count ClickMeLabel.StringValue = (++NumberOfTimesClicked == 1) ? "Button clicked one time." : string.Format("Button clicked {0} times.",NumberOfTimesClicked); }; } #endregion } ``` Let’s take a closer look at what this code is doing. First, it creates a private variable to track how many times a Button that will be added to the Window has been clicked: `private int NumberOfTimesClicked = 0;` Two public computed properties are also created to hold the `NSButton` and `NSTextField` that will comprise the Window’s User Interface: `public NSButton ClickMeButton { get; set;}`\ `public NSTextField ClickMeLabel { get ; set;}` In the Window’s constructor, the new Window will be configured with a default `Title` and `ContentView`. Setting the `ContentView` is a very important step, as it is initially `null` and attempting to add any UI to the Window will result in an error. A new `NSView` is created and it is set to fill the Window’s content area: `ContentView = new NSView (Frame);` Next, other `NSView` based elements are configured and added to the `ContentView` using the `AddSubview` method (such as the `NSButton` and `NSTextField` above). The first thing to note here is that, unlike iOS, macOS uses mathematical notation to define it's Window coordinate system. So the origin point (0,0) is in the lower left hand corner of the Window, with values increasing right and towards the upper right hand corner of the window. When creating the new `NSButton` and `NSTextField`, this is taken into account as the position and size is defined. The `AwakeFromNib` method is overridden and any configuration is done that requires the Window to have already been constructed and in memory, such as attaching to the `Activated` event to the `ClickMeButton`. Why was the `Activated` event set in the `AwakeFromNib` method and not when the `NSButton` was created in the Window’s constructor? Because the Window hasn’t been fully inflated at this point and `Activated` property is `null`, so attempting to set it would result in an error. > 💡**Try It Now** > > 1. Change the default `Title` for the new Window. > 2. Set a new `BackgroundColor` and `TextColor` for the `ClickMeButton` when it is created. > 3. Adjust the appearance of the `ClickMeLabel` when it is created and set a new default value. > 4. Add another `NSButton` and `NSTextField` to the Window. > > ⚠️ These changes wont take effect until a new instance of the Window is instantiated in the **Displaying the Window** section below. ### Defining the Window Controller Next, a Window Controller (`NSWindowController`) is required to initialize and maintain the code based Window (`CodeBasedWindow`) created above. Again, a custom class is defined to handle this task: ```csharp using System; using Foundation; using AppKit; using CoreGraphics; public class CodeBasedWindowController : NSWindowController { #region Computed Properties public new CodeBasedWindow Window { get { return base.Window as CodeBasedWindow; } } #endregion #region Constructors public CodeBasedWindowController (IntPtr handle) : base (handle) { } [Export ("initWithCoder:")] public CodeBasedWindowController (NSCoder coder) : base (coder) { } public CodeBasedWindowController () : base ("CodeBasedWindow") { // Define the Window's default location and size CGRect contentRect = new CGRect (0, 0, 1000, 500); // Create a new instance of the CodeBasedWindow base.Window = new CodeBasedWindow(contentRect, (NSWindowStyle.Titled | NSWindowStyle.Closable | NSWindowStyle.Miniaturizable | NSWindowStyle.Resizable), NSBackingStore.Buffered, false); // Simulate Awaking from Nib Window.AwakeFromNib (); } #endregion #region Override Methods public override void AwakeFromNib () { base.AwakeFromNib (); } #endregion } ``` Let’s take a closer look at what this code is doing. First, when a new instance of the `CodeBasedWindowController()` is created, it will build and configure a new instance of the `CodeBasedWindow` to control. The default location and size of the Window is define using a `CGRect`. In the case of this example, the window will appear in the lower left hand corner of the screen (0,0) and be 1000 pixels wide and 500 pixels high. Why will the Window appear in the lower corner of the screen and not the upper corner? Because macOS is based on a mathematical grid system where (0,0) is in the lower left hand corner with the Y values increasing upwards towards the top. This is opposed to iOS where (0,0) is in the upper left hand corner with Y values increasing downwards towards the bottom of the screen. When the new instance of the CodeBasedWindow is created, several Window Style (`NSWindowStyle`) flags are or’ed (`|`) together to define the look and functionality of the Window. The available styles are: * `Borderless` - The Window will not have a border. * `Titled` - The Window will include a Title Bar. * `Closable` - The Window will include a red close widget. * `Miniaturizable` - The Window has a yellow Miniaturize Button and can be minimized. * `Resizable` - The Window will have a green Resize Button and be resizable. * `Utility` - The Window will be presented as a Utility Panel styled Window. * `DocModal` - Creates a modal Window. * `NonactivatingPanel` - Creates a non-activating floating Panel style Window. * `TexturedBackground` - Applies a textured background to the Window. * `Unscaled` - Creates an unscaled Window. * `UnifiedTitleAndToolbar` - Modern Shoebox (single Window) macOS apps (such as Mail, Calendar and Notes) use a unified Title and Tool Bar area. Use this style to achieve the effect. * `Hud` - Creates a translucent floating Heads-Up type Window. * `FullScreenWindow` - Fills the Mac’s screen with the content area of the Window and hides the Menu and Title bar areas. * `FullSizeContentView` - Complements the `UnifiedTitleAndToolbar` style for modern macOS apps where the Content Area of the Window will extend under the Title and Tool Bar areas. The `NSBackingStore` specifies how the drawing is buffered in a Window as one of the following: * `Retained` - The Window uses a buffer, but draws directly to the screen where possible and to the buffer for parts that are obscured. * `Nonretained` - The Window draws directly to the screen without using any buffer. * `Buffered` - The Window renders all drawing into a display buffer and then flushes it to the screen. The last property specified when creating the new `CodeBasedWindow` is `deferCreation`. If `true`, the Window Server defers creating the Window until it is moved onscreen. If `false`, the Window Server creates the Window immediately. All display messages sent to a Window or its Views are postponed until the Window is created, just before it’s moved onscreen. Finally, the `AwakeFromNib` method is called on the Window. Typically, this method is invoked when the Window is inflated from a `.storyboard` or `.xib` file, because the Window is being created manually, the developer must explicitly call this method to inform the Window it has been created. > 💡**Try It Now** > > 1. Change the values for the `contentRect` to open the Window in a new default location or make it a different default size. > 2. Adjust the `NSWindowStyle` flags to change the look and functionality of the Window that will be created. > 3. Play with the `NSBackingStore` value to see how it affects the way the Window is drawn. > 4. Set `deferCreation` to `true` and see how it affects the Window creation. > > ⚠️ These changes wont take effect until a new instance of the Window is instantiated in the **Displaying the Window** section below. ### Displaying the Window With the custom classes for the Window and Window Controller created, the code based window can be displayed to the user. Typically, this is done inside of the `DidFinishLaunching` method of the Xamarin.Mac app’s `AppDelegate` using the following lines of code: ```csharp var mainWindowController = new CodeBasedWindowController (); mainWindowController.Window.MakeKeyAndOrderFront ((NSObject)NSApplication.SharedApplication.Delegate); ``` Let’s take a closer look at what this code is doing. First, a new instance of the `CodeBasedWindowController` is created. Next, the `Window` managed by this Controller (which is an instance of the `CodeBasedWindow` in this case) is displayed by calling the `MakeKeyAndOrderFront` method. In macOS, the **Key Window** is the currently active Window that has focus and access to user input. **Order Front** brings the window forward in front of all other Windows currently being displayed. When `MakeKeyAndOrderFront` is called, an instace of the object that created it is passed in. Typically, this will be the `AppDelegate` for the macOS app. Since this code is usually called from inside `DidFinishLaunching` method, normally the `this` keyword is used. Because this code is being executed inside of a workbook, the `AppDelegate` is being accessed via the Shared Application using `(NSObject)NSApplication.SharedApplication.Delegate`. > 💡**Try It Now** > > 1. Run the two lines of code above again to create another new Window. Every time this code is run, a new Window will be added to the app. Typically, this is done from the **File** > **New** menu item. ## Defining the Menu Bar in Code Because of current limitations in Xamarin.Mac, it is not suggested that you create your Xamarin.Mac application's Menu Bar (`NSMenuBar`) in code but continue to use a `Main.storyboard` or `MainMenu.xib` file to define it. That said, the developer can add and remove Menus and Menu Items in C# code. Take the example of creating a System Status Bar menu for a Xamarin.Mac app below: ```csharp // Create a Status Bar Menu NSStatusBar statusBar = NSStatusBar.SystemStatusBar; NSStatusItem item; // Has the Action menu already been created? if (item == null) { // No, create menu and populate it item = statusBar.CreateStatusItem (NSStatusItemLength.Variable); item.Title = "Actions"; item.HighlightMode = true; item.Menu = new NSMenu ("Actions"); var address = new NSMenuItem ("Address"); address.Activated += (sender, e) => { Console.WriteLine("Address Selected"); }; item.Menu.AddItem (address); var date = new NSMenuItem ("Date"); date.Activated += (sender, e) => { Console.WriteLine("Date Selected"); }; item.Menu.AddItem (date); var greeting = new NSMenuItem ("Greeting"); greeting.Activated += (sender, e) => { Console.WriteLine("Greetings Selected"); }; item.Menu.AddItem (greeting); var signature = new NSMenuItem ("Signature"); signature.Activated += (sender, e) => { Console.WriteLine("Signature Selected"); }; item.Menu.AddItem (signature); } ``` Let’s take a closer look at what this code is doing. First, it creates a gains access to the System Status Bar (`NSStatusBar.SystemStatusBar`) that exists on the right hand side of the Menu Bar. If the **Actions** Menu Item hasn’t already been created, a new `NSStatusItem` is created, configured to be the **Actions** Menu and attached to the System Status Bar. Next, a series of `NSMenuItem` instances are created, configured and attached to the **Actions** Menu. The Activated event for each new Item is set and this code will be executed when the user selects the specific Menu Item. > 💡**Try It Now** > > 1. Add a **New** Menu Item to the **Actions** Menu that opens a new `CodeBasedWindow` when selected. ## Building Modern macOS App UI > ⚠️ **WARNING!** *The modern macOS App UI is currently unavailable in the Version 01.00.00 of Xamarin Workbooks. This feature will be restored in a future release.* Modern macOS apps such as Apple's Safari web browser, Pages word processor and Numbers spread sheet use many new technologies to present a unified, context sensitive User Interface that does away with traditional UI elements such as floating panels and multiple open windows. Next let’s look at several advanced technologies a developer can use to build a modern macOS app in Xamarin.Mac ### Define a Modern View Before defining the custom class that will be the basis for the Modern View, let’s take a quick look at the technologies it will be using. Core Animation is a high powered graphics rendering engine that is built into macOS. Core Animation has been optimized to take advantage of the GPU (Graphics Processing Unit) available in modern macOS hardware as opposed to running the graphics operations on the CPU, which can slow down the machine. The `CALayer`, provided by Core Animation, can be used for tasks such as fast and fluid scrolling and animations. An app's User Interface should be composed of multiple subviews and layers to fully take advantage of Core Animation. A `CALayer` object provides several properties that allow the developer to control what is presented onscreen to the user such as: * `Content` - Can be a `NSImage` or `CGImage` that provides the contents of the layer. * `BackgroundColor` - Sets the background color of the layer as a `CGColor`. * `BorderWidth` - Sets the border width. * `BorderColor` - Sets the border color. To utilize Core Graphics in the app's UI, it must be using Layer Backed Views, which Apple suggests that the developer should always enable in the Window's Content View. This way, all child views will automatically inherit Layer Backing as well. Additionally, Apple suggests using Layer Backed Views as opposed to adding a new `CALayer` as a sublayer because the system will automatically handle several of the required settings (such as those required by a Retina Display). With that in mind, define a new `NSView` that will provide the Content Area for the Modern Window: ```csharp using System; using Foundation; using AppKit; using CoreGraphics; public class MainView : NSView { #region Computed Properties public override bool WantsLayer { get { return true; } } public override bool WantsUpdateLayer { get { return true; } } #endregion #region Constructor public MainView (IntPtr handle) : base (handle) { } public MainView (CGRect bounds) : base (bounds) { } #endregion #region Override Methods public override void UpdateLayer () { base.UpdateLayer (); // Add the Core Graphics routines to draw the View's UI Layer.BackgroundColor = NSColor.Red.CGColor; } #endregion } ``` Let’s take a closer look at what this code is doing. First, the `WantsLayer` and `WantsUpdateLayer` properties are overridden and set to `true` to make this a Layer Backed View. Then the UpdateLayer method is overriden and the Core Graphic routines are added to draw out the View’s UI. In this example, the View’s background color is being set to red: `Layer.BackgroundColor = NSColor.Red.CGColor;` > 💡**Try It Now** > > 1. Change the background color of the View. > 2. Add more Core Graphic routines to change the View’s UI. > > ⚠️ These changes wont take effect until a new instance of the Window is instantiated in the **Displaying the Modern Window** section below. ### Defining a Modern Window In macOS Sierra an app’s Windows can be configured to create Tabbed Windows, where several Windows of the same type are merged into one virtual Window instead of being separate instances (like tabs in the Safari app). Typically, the developer will need to take limited action use Tabbed Windows in their Xamarin.Mac apps, the system will handle them automatically as follows: * Windows will automatically be Tabbed when the `OrderFront` method is invoked. * Windows will automatically be Untabbed when the `OrderOut` method is invoked. * In code all Tabbed windows are still considered "visible", however any non-frontmost Tabs are hidden by the system using CoreGraphics. * Use the `TabbingIdentifier` property of `NSWindow` to group Windows together into Tabs. * If it is an `NSDocument` based app, several of these features will be enabled automatically (such as the plus button being added to the Tab Bar) without any developer action. * Non-NSDocument based apps can enable the "plus" button in the Tab Group to add a new document by overriding the `GetNewWindowForTab` method of the `NSWindowsController`. Now create a new in-code NSWindow class that invokes a supports Tabs and uses the Modern Views created above: ```csharp using System; using Foundation; using AppKit; using CoreGraphics; public class ModernCodeBasedWindow : NSWindow { #region Constructors public ModernCodeBasedWindow (IntPtr handle) : base (handle) { } [Export ("initWithCoder:")] public ModernCodeBasedWindow (NSCoder coder) : base (coder) { } public ModernCodeBasedWindow (CGRect contentRect, NSWindowStyle aStyle, NSBackingStore bufferingType, bool deferCreation): base (contentRect, aStyle,bufferingType,deferCreation) { // Create a title for the window Title = "Untitled"; // Create the content view for the window and make it fill the window ContentView = new MainView (Frame); // Hide the Title bar for a streamlined UI TitleVisibility = NSWindowTitleVisibility.Hidden; // _________________________________________________________________ // WARNING! // The modern macOS App UI is currently unavaiable in the Version // 0.99.0.0 of Xamarin Workbooks. This feature will be restored in a // future release. // _________________________________________________________________ // Configure the Window to use Tabs // TabbingMode = NSWindowTabbingMode.Preferred; // TabbingIdentifier = "Modern"; } #endregion } ``` Let’s take a closer look at what this code is doing. First, it hides the Title Bar area so that the Tool Bar area will be merged into in: `TitleVisibility = NSWindowTitleVisibility.Hidden;` The next two lines enable the Tabbed Window feature: `TabbingMode = NSWindowTabbingMode.Preferred;`\ `TabbingIdentifier = "Modern";` ### Defining a Modern Window Controller Now create a new custom `NSWindowController` initialize and maintain the modern code based Window (`ModernCodeBasedWindow`) created above: ```csharp using System; using Foundation; using AppKit; using CoreGraphics; public class ModernCodeBasedWindowController : NSWindowController { #region Computed Properties public new ModernCodeBasedWindow Window { get { return base.Window as ModernCodeBasedWindow; } } #endregion #region Constructors public ModernCodeBasedWindowController (IntPtr handle) : base (handle) { } [Export ("initWithCoder:")] public ModernCodeBasedWindowController (NSCoder coder) : base (coder) { } public ModernCodeBasedWindowController () : base ("CodeBasedWindow") { // Define the Window's default location and size CGRect contentRect = new CGRect (0, 100, 600, 500); // Create a new instance of the CodeBasedWindow base.Window = new ModernCodeBasedWindow(contentRect, (NSWindowStyle.Titled | NSWindowStyle.Closable | NSWindowStyle.Miniaturizable | NSWindowStyle.Resizable | NSWindowStyle.FullSizeContentView | NSWindowStyle.UnifiedTitleAndToolbar), NSBackingStore.Buffered, false); // Simulate Awaking from Nib Window.AwakeFromNib (); } #endregion #region Override Methods public override void AwakeFromNib () { base.AwakeFromNib (); } // _________________________________________________________________ // WARNING! // The modern macOS App UI is currently unavaiable in the Version // 0.99.0.0 of Xamarin Workbooks. This feature will be restored in a // future release. // _________________________________________________________________ // public override void GetNewWindowForTab (NSObject sender) // { // // Create a new window when the Plus button is clicked // var newWindowController = new ModernCodeBasedWindowController (); // newWindowController.Window.MakeKeyAndOrderFront ((NSObject)NSApplication.SharedApplication.Delegate); // } #endregion } ``` Let’s take a closer look at what this code is doing. First, when a new instance of the `ModernCodeBasedWindow` is created, the `FullSizeContentView` and `UnifiedTitleAndToolbar` `NSWindowStyle` flags are being applied for a modern look. To display the **Plus** button in the Tab Bar, the `GetNewWindowForTab` method is overridden and code is added to create a new `ModernCodeBasedWindow` when it is clicked. ### Displaying the Modern Window The following two lines of code will create a new instance of the `ModernCodeBasedWindow` and display it: ```csharp var newWindowController = new ModernCodeBasedWindowController (); newWindowController.Window.MakeKeyAndOrderFront ((NSObject)NSApplication.SharedApplication.Delegate); ``` However, unlike the CodeBasedWindow created above, each time this code is run and a new `ModernCodeBasedWindow` is created, it will be added as a Tab to the existing Window instead of being a separate Window. ### Using System Appearances Modern macOS apps can adopt a new Dark Interface Appearance that works well for image creation, editing or presentation apps. This can be done by adding one line of code before the Window is presented. For example: ```csharp // Apply the Dark Interface Appearance newWindowController.Window.Appearance = NSAppearance.GetAppearance (NSAppearance.NameVibrantDark); ``` The following NSAppearance types are defined: * `NameAqua` \[*Deprecated*\] - Use the OS X Aqua appearance. * `NameLightContent` \[*Deprecated*\] - Use the light content appearance. * `NameVibrantDark` - Use the dark vibrant appearance. * `NameVibrantLight` - Use the light vibrant appearance. > 💡**Try It Now** > > 1. Set the Window to another type of `NSAppearance`. ================================================ FILE: mac/user-interface/webbrowser/README.md ================================================ How to Build a Web Browser in Xamarin.Mac ============ This workbook will cover the steps required to build a mini, multi-windowed web browser in a Xamarin.Mac app. By going through the steps in this workbook, the reader will gain insights and skills required to work with many elements of a standard macOS app such as Menus, Windows, Window Controllers, Views, View Controllers, Toolbars, Text Field, Buttons and the Xcode Interface Builder Storyboard files used to define them. ![](screenshots/Intro01.png) ================================================ FILE: mac/user-interface/webbrowser/webbrowser.workbook/Main.storyboard ================================================ ================================================ FILE: mac/user-interface/webbrowser/webbrowser.workbook/StoryboardResources.csx ================================================ using System; using System.Diagnostics; using System.IO; using System.Xml; using System.Collections.Generic; using System.Reflection; using System.Runtime.InteropServices; using System.Linq; using Foundation; using AppKit; using ObjCRuntime; // ------------------------------------------------------------------------- // StoryboardInflator for macOS by Kevin Mullins for Microsoft, Inc. // ------------------------------------------------------------------------- // This library provides limited support for using Storyboard files to // build and display the user interface for a Xamarin.Mac based workbook app. // Because macOS expects a compiled storyboard to be part of a running app's // bundle along with its executable code, the typical mechanisms to create // Outlets, Actions and Segues will not work. Instead, this library applies // the following hack to simulate Outlets: // // 1) Windows and Views (or View based controls such as NSButton), set their // Identifier property in Interface Builder to match the name of the // "Outlet". The StoryboardBinder will populate any like named Public // Property on any class it binds. // // 2) For Menu Items, the StoryboardBinder will use the Title of the Menu // Item + "MenuItem" to populate any like named Public Property on any // class that it binds. For example, the "New" menu item would bind to // the "NewMenuItem" property in class. // // 3) For Toolbar Items, the StoryboardBinder will use the Label of the // Item + "ToolbarItem" to populate any like named Public Property on any // class that it binds. For example, the "Color" menu item would bind to // the "ColorMenuItem" property in class. // // LIMITATIONS: Custom Segues are currently not supported. Instead, the app must // use the StoryboardInflator to inflate and populate any NIB that will then // need to be manually displayed. /// /// Defines the type of a Scene or Source Object used in a Segue. /// public enum StoryboardObjectType { /// /// The application (NSApplication) as defined in the Storyboard. /// Application, /// /// A Menu Item (NSMenuItem). /// MenuItem, /// /// A Window Controller (NSWindowController). /// WindowController, /// /// A Toolbar Item (NSToolbarItem). /// ToolbarItem, /// /// A View Controller (NSViewController). /// ViewController, /// /// Storyboard object type (NSSplitViewController). /// SplitViewController, /// /// A Button (NSButton). /// Button, /// /// An unknown object type /// Unknown } /// /// Defines the kind of Segue as defined in the Storyboard. /// public enum StoryboardSegueType { /// /// Displays the destination controller as a non-modal Window. /// Show, /// /// Displays the destination controller as a modal window. /// Modal, /// /// Displays the destination controller as a sheet. /// Sheet, /// /// Displays the destination controller as a popover. /// Popover, /// /// Displays the destination controller using a Custom Segue Class. /// Custom, /// /// Defines a containment relationship between the source object and the /// destination controller. /// Relationship } /// /// Holds the definition of a Segure as read from a Storyboard. /// public class StoryboardSegueDefinition : NSObject { #region Computed Properties /// /// Gets or sets the inflator used to load NIBs from the Storyboard. /// /// The inflator. public StoryboardInflator Inflator { get; set; } /// /// Gets or sets the type of the scene that they segue belongs to. /// /// The type of the scene. public StoryboardObjectType SceneType { get; set;} /// /// Gets or sets the scene identifier. /// /// The scene identifier. public string SceneID { get; set; } /// /// Gets or sets the type of the source object. /// /// The type of the source object. public StoryboardObjectType SourceObjectType { get; set;} /// /// Gets or sets the source object identifier. /// /// The source object identifier. public string SourceObjectID { get; set; } /// /// Gets or sets the destination controller identifier. /// /// The destination controller identifier. public string DestinationControllerID { get; set;} /// /// Gets or sets the kind of the segue. /// /// The kind of the segue. public StoryboardSegueType SegueKind { get; set; } /// /// Gets or sets the segue identifier. /// /// The segue identifier. public string SegueIdentifier { get; set;} /// /// Gets or sets the relationship. /// /// This is only populated from containment Segues of StoryboardSegueType.Relationship. /// The relationship. public string Relationship { get; set;} /// /// Gets or sets the popover anchor identifier. /// /// The popover anchor identifier. public string PopoverAnchorID { get; set;} /// /// Gets or sets the popover behavior. /// /// The popover behavior. public NSPopoverBehavior PopoverBehavior { get; set; } = NSPopoverBehavior.Transient; /// /// Gets or sets the edge the popover will be displayed from. /// /// 0 = Left, 1 = Top, 2 = Right, 3 = Bottom /// The popover edge. public nuint PopoverEdge { get; set; } = 0; #endregion #region Constructors /// /// Initializes a new instance of the class. /// /// The StoryboardSegueType of the Segue. /// The Inflator used to load NIB files. public StoryboardSegueDefinition (StoryboardSegueType type, StoryboardInflator inflator) { // Initialize SegueKind = type; Inflator = inflator; } /// /// Initializes a new instance of the class. /// /// The string type of the Segue. /// The Inflator used to load NIB files. public StoryboardSegueDefinition (string type, StoryboardInflator inflator) { // Initialize switch (type) { case "show": SegueKind = StoryboardSegueType.Show; break; case "modal": SegueKind = StoryboardSegueType.Modal; break; case "sheet": SegueKind = StoryboardSegueType.Sheet; break; case "popover": SegueKind = StoryboardSegueType.Popover; break; case "custom": SegueKind = StoryboardSegueType.Relationship; break; } Inflator = inflator; } #endregion #region Private Methods /// /// Prepares to execute a segue loading the destination NIB and calling PrepareForSegue /// on the Source Controller so it can prepare the destination controller before it is /// presented to the user. /// /// The NSStoryboardSegue representing this Segue Definition. /// The object that is launching the segue. /// Source controller for the segue. private NSStoryboardSegue PrepareForSegue (NSObject sender, NSObject sourceController) { // Attempt to load destination var destinationController = Inflator.InstantiateControllerForPartialIdentifier (DestinationControllerID); // Was the NIB found? if (destinationController == null) return null; // Build new Segue var segue = new NSStoryboardSegue (SegueIdentifier, sourceController, destinationController); // Does the class contain the PrepareForSegue method? var controllerType = sourceController.GetType (); var methodInfo = controllerType.GetMethod ("PrepareForSegue"); if (methodInfo != null) { // Yes, wireup action to class methodInfo.Invoke (sourceController, new [] { segue, sender }); } // Return controller return segue; } /// /// Presents the non modal window to the user. /// /// The NSStoryboardSegue to execute. private void PresentNonModalWindow (NSStoryboardSegue segue) { NSWindowController windowController = null; // Take action based on the controller type if (segue.DestinationController is NSWindowController) { // Display the window to the user windowController = segue.DestinationController as NSWindowController; } else if (segue.DestinationController is NSViewController) { // Build a Window and Window Controller for this view var viewController = segue.DestinationController as NSViewController; var window = new NSWindow (viewController.View.Bounds, (NSWindowStyle.Titled | NSWindowStyle.Closable | NSWindowStyle.Miniaturizable | NSWindowStyle.Resizable), NSBackingStore.Buffered, false); windowController = new NSWindowController (window); // Attach the View Controller to the Window window.ContentView = viewController.View; window.ContentViewController = viewController; } // Found? if (windowController == null) return; // Present window controller windowController.Window.MakeKeyAndOrderFront ((NSObject)NSApplication.SharedApplication.Delegate); } /// /// Presents the modal window to the user. /// /// The NSStoryboardSegue to execute. private void PresentModalWindow (NSStoryboardSegue segue) { NSWindowController windowController = null; // Take action based on the controller type if (segue.DestinationController is NSWindowController) { // Display the window to the user windowController = segue.DestinationController as NSWindowController; } else if (segue.DestinationController is NSViewController) { // Build a Window and Window Controller for this view var viewController = segue.DestinationController as NSViewController; var window = new NSWindow (viewController.View.Bounds, (NSWindowStyle.Titled | NSWindowStyle.Closable | NSWindowStyle.Miniaturizable | NSWindowStyle.Resizable), NSBackingStore.Buffered, false); windowController = new NSWindowController (window); // Attach the View Controller to the Window window.ContentView = viewController.View; window.ContentViewController = viewController; } // Found? if (windowController == null) return; // Present window controller NSApplication.SharedApplication.RunModalForWindow (windowController.Window); } /// /// Presents the Window or View to the user as a sheet attached to the parent /// Window. /// /// The NSStoryboardSegue to execute. private void PresentSheet (NSStoryboardSegue segue) { NSViewController viewController = null; // Take action based on the controller type if (segue.DestinationController is NSWindowController) { // Display the window to the user var windowController = segue.DestinationController as NSWindowController; viewController = windowController.Window.ContentViewController; } else if (segue.DestinationController is NSViewController) { // Grab view controller viewController = segue.DestinationController as NSViewController; } // Found? if (viewController == null) return; // Present window controller if (segue.SourceController is NSWindowController) { var sourceController = segue.SourceController as NSWindowController; sourceController.Window.ContentViewController.PresentViewControllerAsSheet (viewController); } else if (segue.SourceController is NSViewController) { var sourceController = segue.SourceController as NSViewController; sourceController.PresentViewControllerAsSheet (viewController); } } /// /// Presents the Window or View to the user as a popover attached to a parent /// View. /// /// The NSStoryboardSegue to execute. /// The NSView based element that the popover will be attached to. private void PresentPopover (NSStoryboardSegue segue, NSObject sender) { NSViewController viewController = null; NSView view = null; // Take action based on the controller type if (segue.DestinationController is NSWindowController) { // Display the window to the user var windowController = segue.DestinationController as NSWindowController; viewController = windowController.Window.ContentViewController; } else if (segue.DestinationController is NSViewController) { // Grab view controller viewController = segue.DestinationController as NSViewController; } // Found? if (viewController == null) return; // Take action based on sender type if (sender is NSToolbarItem) { var item = sender as NSToolbarItem; if (item.View == null) { // Default to presenting as a sheet PresentSheet (segue); return; } else { // Use the items view view = item.View; } } else { // It's a view based control view = sender as NSView; } // Present window controller if (segue.SourceController is NSWindowController) { var sourceController = segue.SourceController as NSWindowController; sourceController.Window.ContentViewController.PresentViewController (viewController, viewController.View.Bounds, view, PopoverEdge, PopoverBehavior); } else if (segue.SourceController is NSViewController) { var sourceController = segue.SourceController as NSViewController; sourceController.PresentViewController (viewController, viewController.View.Bounds, view, PopoverEdge, PopoverBehavior); } } #endregion #region Public Methods /// /// Performs the segue as specified in this Segue Definition. /// /// The object that is launching the segue. /// Source controller for the segue. public void PerformSegue (NSObject sender, NSObject sourceController) { //NSApplication.SharedApplication.KeyWindow.Title = "Loading Segue"; // Prepare for segue var segue = PrepareForSegue (sender, sourceController); // Did the NIB load? if (segue == null) return; //NSApplication.SharedApplication.KeyWindow.Title = "Segue Loaded"; // Take action based on the Segue type switch (SegueKind) { case StoryboardSegueType.Show: PresentNonModalWindow (segue); break; case StoryboardSegueType.Modal: PresentModalWindow (segue); break; case StoryboardSegueType.Sheet: PresentSheet (segue); break; case StoryboardSegueType.Popover: PresentPopover (segue, sender); break; } } /// /// Sets the popover behavior. /// /// Behavior as a string value. public void SetPopoverBehavior (string behavior) { // Anything to do? if (behavior == null) return; // Take action based on value switch (behavior) { case "t": PopoverBehavior = NSPopoverBehavior.Transient; break; case "semitransient": PopoverBehavior = NSPopoverBehavior.Semitransient; break; case "applicationDefined": PopoverBehavior = NSPopoverBehavior.ApplicationDefined; break; } } /// /// Sets the popover edge. /// /// Edge as a string value. public void SetPopoverEdge (string edge) { // Anything to do? if (edge == null) return; // Take action based on value switch (edge) { case "minX": PopoverEdge = 0; break; case "minY": PopoverEdge = 1; break; case "maxX": PopoverEdge = 2; break; case "maxY": PopoverEdge = 3; break; } } #endregion } /// /// Helper class used to compile a storyboard included in a workbook. /// public static class StoryboardCompiler { #region Public Methods /// /// Compiles the specified storyboardName. /// /// The Storyboard name of the storyboard to compile without the `.storyboard` extension. public static void Compile (string storyboardName) { // Assemble the Interface Builder compiler call var dir = Directory.GetCurrentDirectory (); var command = "ibtool"; var arguments = $"\"{dir}/{storyboardName}.storyboard\" --compile \"{dir}/{storyboardName}.storyboardc\""; // Prepare to call the system to invoke the ibtool var startInfo = new ProcessStartInfo () { FileName = command, Arguments = arguments, UseShellExecute = false, CreateNoWindow = true, RedirectStandardOutput = true, RedirectStandardError = true, RedirectStandardInput = true, UserName = System.Environment.UserName }; // Invoke the ibtool and write the results to the // console using (Process process = Process.Start (startInfo)) { // Monitor for exit} process.WaitForExit (); using (var output = process.StandardOutput) { var results = output.ReadToEnd (); Console.WriteLine ("Results: {0}", (results == "") ? "Successful" : results); } } } #endregion } /// /// The StoryboardBinder class provides a mechanism to bind objects inflated from a /// compiled Storyboard NIB file to classes in a workbook. Currently it can bind: /// NSMenu, NSToolBar, NSWindowController, NSWindow, NSViewController, NSView and /// any NSView base controls (such as NSButton). /// /// It uses the following hack to support Outlets: a) NSWindow and NSView based /// controls are bound to Public Properties matching their Identifier property, /// b) NSMenuItems are bound to Public Properties matching Title + "MenuItem", /// c) NSToolbarItems are bound to Public Properties matching Label + "ToolbarItem". /// /// Custom Segues are currently not supported. For many standard items (such as /// NSButton and NSImageView), images will attempted to be bound to `.png` files of /// the same name in an `Images` directory in the workbooks directory. /// public static class StoryboardBinder { #region Public Methods /// /// Bind the specified storyboardClass and workbookClass. For high-level classes /// like NSWindowController and NSViewController, the binder will walk down the /// tree of objects binding lower-level items along the chain. /// /// The high-level storyboard (or workbook) class to bind from. /// The workbook class to bind to. public static void Bind (NSObject storyboardClass, NSObject workbookClass) { // Take action based on the source object type if (storyboardClass is NSMenu) { BindMenu (storyboardClass as NSMenu, workbookClass); } else if (storyboardClass is NSWindowController) { BindWindowController (storyboardClass as NSWindowController, workbookClass); } else if (storyboardClass is NSWindow) { BindWindow (storyboardClass as NSWindow, workbookClass); } else if (storyboardClass is NSViewController) { BindViewController (storyboardClass as NSViewController, workbookClass); } else if (storyboardClass is NSView) { BindView (storyboardClass as NSView, workbookClass); } else if (storyboardClass is NSToolbar) { BindToolbar (storyboardClass as NSToolbar, workbookClass); } } /// /// Attempts to bind an NSImage that has been specified in Interface Builder in the /// form `TheImage.png` to a like-named image file in the `Images` directory in the /// same directory as the workbook. /// /// The NSImage loaded from the `Images` directory or the passed-in NSImage if not found. /// The source NSImage as specified in Interface Builder. public static NSImage BindImage (NSImage image) { // Has an image been specified? if (image !=null && image.Name != null && image.Name.Contains (".png")) { // Yes, attempt load the image resource var imageName = $"Images/{image.Name}"; // Does the file exist? if (File.Exists (imageName)) { // Yes, load new image image = new NSImage (imageName); } } return image; } /// /// Binds any Menu Item to a Public Property in a workbook class that matches /// Title + "MenuItem". For example, the "New" Menu Item to the "NewMenuItem" /// Property. /// /// Any image specified in an item will also attemp to be bound. /// The NSMenu to bind. /// The workbook class to bind to. public static void BindMenu (NSMenu menu, NSObject workbookClass) { // Bind all menu items for (nint n = 0; n < menu.Count; ++n) { var menuItem = menu.ItemAt (n); // Bind identity using a hack var propertyName = $"{menuItem.Title.Replace (" ", "").Replace ("…", "")}MenuItem"; BindProperty (propertyName, workbookClass, menuItem); // Bind image menuItem.Image = BindImage (menuItem.Image); // Bind actions BindAction (menuItem.Action, workbookClass, menuItem); // Has segue? if (menuItem.Target is StoryboardSegueDefinition) { var segue = menuItem.Target as StoryboardSegueDefinition; // Bind it menuItem.Activated += (sender, e) => { segue.PerformSegue (menuItem, workbookClass); }; } // Scan sub menus if (menuItem.Submenu != null) { BindMenu (menuItem.Submenu, workbookClass); } } } /// /// Binds any Toolbar Item to A Public Property in a workbook class that matches /// Label + "ToolbarItem". For example, the "Color" Toolbar Item to the "ColorToolbarItem" /// Property. /// /// Any image specified in an item will also attemp to be bound. /// The NSToolbar to bind. /// The workbook class to bind to. public static void BindToolbar (NSToolbar toolbar, NSObject workbookClass) { // Bind all items on the Toolbar foreach (NSToolbarItem item in toolbar.Items) { // Bind identity using a hack var propertyName = $"{item.Label.Replace (" ", "")}ToolbarItem"; BindProperty (propertyName, workbookClass, item); // Bind Images item.Image = BindImage (item.Image); // Bind actions BindAction (item.Action, workbookClass, item); // Has segue? if (item.Target is StoryboardSegueDefinition) { var segue = item.Target as StoryboardSegueDefinition; // Bind it item.Activated += (sender, e) => { segue.PerformSegue (item, workbookClass); }; } } } /// /// Binds the Window Controller to the given workbook class. This method will walk down the /// tree of objects binding lower-level classes as well. /// /// The NSWindowController to bind from. /// The workbook class to bind to. public static void BindWindowController (NSWindowController controller, NSObject workbookClass) { // Bind controlled window BindWindow (controller.Window, workbookClass); // Binding to a Window Controller? if (workbookClass is NSWindowController) { // Yes, bind controllers var windowController = workbookClass as NSWindowController; windowController.Window = controller.Window; // Is the window loaded? if (windowController.IsWindowLoaded) { // Simulate the window being loaded by the workbook's controller instance windowController.WindowWillLoad (); windowController.WindowDidLoad (); } } } /// /// Binds the Window to the given workbook class. This method will walk down the tree /// of objects binding lower-level classes as well. /// /// The NSWindow to bind from. /// The workbook class to bind to. public static void BindWindow (NSWindow window, NSObject workbookClass) { // Bind identity BindProperty (window.Identifier, workbookClass, window); // Does the window have a toolbar? if (window.Toolbar != null) { // Yes, bind it BindToolbar (window.Toolbar, workbookClass); } // Binding to a window instance? if (workbookClass is NSWindow && workbookClass.GetType ().Name == window.Identifier) { // Yes, bind objects var wbWindow = workbookClass as NSWindow; wbWindow.ContentViewController = window.ContentViewController; wbWindow.ContentView = window.ContentView; } // Does the window contain a Split View if (window.ContentView is NSSplitView) { // Bind split view contents BindSplitView (window.ContentView as NSSplitView, workbookClass); } else { // Bind content view controller BindViewController (window.ContentViewController, workbookClass); } } /// /// Binds the split view to the given workbook class. This method will walk down the /// tree of objects binding lower-level classes as well. /// /// Split view being bound. /// The workbook class to bind to. public static void BindSplitView (NSSplitView splitView, NSObject workbookClass) { // Bind identity BindProperty (splitView.Identifier, workbookClass, splitView); // Bind all the attached views foreach (NSView view in splitView.ArrangedSubviews) { // Bind controlled view BindView (view, workbookClass); } // Binding to a view controller? if (workbookClass is NSViewController) { // Yes, bind controllers var viewController = workbookClass as NSViewController; viewController.View = splitView; // Simulate the view being loaded by the workbook's controller instance viewController.ViewDidLoad (); viewController.ViewWillAppear (); viewController.ViewDidAppear (); viewController.ViewWillLayout (); viewController.ViewDidLayout (); } } /// /// Binds the View Controller to the given workbook class. This method will walk down the /// tree of objects binding lower-level classes as well. /// /// The NSViewController to bind from. /// The workbook class to bind to. public static void BindViewController (NSViewController controller, NSObject workbookClass) { // Bind controlled view BindView (controller.View, workbookClass); // Binding to a view controller? if (workbookClass is NSViewController) { // Yes, bind controllers var viewController = workbookClass as NSViewController; viewController.View = controller.View; // Is the view loaded? if (controller.ViewLoaded) { // Simulate the view being loaded by the workbook's controller instance viewController.ViewDidLoad (); viewController.ViewWillAppear (); viewController.ViewDidAppear (); viewController.ViewWillLayout (); viewController.ViewDidLayout (); } } } /// /// Binds the View to the given workbook class. This method will transverse all SubViews /// in the given tree. /// /// Any image specified in a known item will also attemp to be bound. /// The NSView to bind from. /// The workbook class to bind to. public static void BindView (NSView view, NSObject workbookClass) { // Bind identity BindProperty (view.Identifier, workbookClass, view); // Bind images for known items if (view is NSButton) { var button = view as NSButton; button.Image = BindImage (button.Image); BindAction (button.Action, workbookClass, button); // Has segue? if (button.Target is StoryboardSegueDefinition) { var segue = button.Target as StoryboardSegueDefinition; // Bind it button.Activated += (sender, e) => { segue.PerformSegue (button, workbookClass); }; } } else if (view is NSPopUpButton) { var popup = view as NSPopUpButton; foreach (NSMenuItem item in popup.Items ()) { item.Image = BindImage (item.Image); } BindAction (popup.Action, workbookClass, popup); } else if (view is NSSegmentedControl) { var segment = view as NSSegmentedControl; for (nint n = 0; n < segment.SegmentCount; ++n) { var image = segment.GetImage (n); segment.SetImage (BindImage (image), n); } BindAction (segment.Action, workbookClass, segment); } else if (view is NSImageView) { var image = view as NSImageView; image.Image = BindImage (image.Image); } // Bind every subview foreach (NSView subview in view.Subviews) { BindView (subview, workbookClass); } } #endregion #region Private Methods /// /// Attempts to bind an object inflated from a compiled Storyboard to an "Outlet" /// property on the given workbook class. This hack is a workaround since true /// Storyboard Outlets are not supported in workbooks. /// /// The name of the Public Property to bind the Outlet to. /// The workbook class being bound to. /// The object inflated from the compiled Storyboard. private static void BindProperty (string propertyName, NSObject workbookClass, NSObject property) { // Anything to process? if (propertyName == null) return; // Does the controller contain the property? var controllerType = workbookClass.GetType (); var propertyInfo = controllerType.GetProperty (propertyName); if (propertyInfo != null && propertyInfo.CanWrite) { // Yes, save value in class var value = Convert.ChangeType (property, propertyInfo.PropertyType); propertyInfo.SetValue (workbookClass, value); } } /// /// Attempts to bind an object inflated from a compiled Storyboard to an "Action" /// property on the given workbook class. This hack is a workaround since true /// Storyboard Actions are not supported in workbooks. /// /// The selector that represents the Action to bind. /// The workbook class being bound to. /// The Menu Item that is the target of the binding. private static void BindAction (Selector action, NSObject workbookClass, NSMenuItem menuItem) { // Anything to process? if (action == null) return; // Switch to .NET style method name var actionName = action.Name.Substring(0,1).ToUpper() + action.Name.Substring(1).Replace (":", ""); // Does the class contain the method? var controllerType = workbookClass.GetType (); var methodInfo = controllerType.GetMethod (actionName); if (methodInfo != null) { // Yes, wireup action to class menuItem.Activated += (sender, e) => { methodInfo.Invoke (workbookClass, new [] { sender }); }; } } /// /// Attempts to bind an object inflated from a compiled Storyboard to an "Action" /// property on the given workbook class. This hack is a workaround since true /// Storyboard Actions are not supported in workbooks. /// /// The selector that represents the Action to bind. /// The workbook class being bound to. /// The Toolbar Item that is the target of the binding. private static void BindAction (Selector action, NSObject workbookClass, NSToolbarItem toolbarItem) { // Anything to process? if (action == null) return; // Switch to .NET style method name var actionName = action.Name.Substring (0, 1).ToUpper () + action.Name.Substring (1).Replace (":", ""); // Does the class contain the method? var controllerType = workbookClass.GetType (); var methodInfo = controllerType.GetMethod (actionName); if (methodInfo != null) { // Yes, wireup action to class toolbarItem.Activated += (sender, e) => { methodInfo.Invoke (workbookClass, new [] { sender }); }; } } /// /// Attempts to bind an object inflated from a compiled Storyboard to an "Action" /// property on the given workbook class. This hack is a workaround since true /// Storyboard Actions are not supported in workbooks. /// /// The selector that represents the Action to bind. /// The workbook class being bound to. /// The control that is the target of the binding. private static void BindAction (Selector action, NSObject workbookClass, NSControl control) { // Anything to process? if (action == null) return; // Switch to .NET style method name var actionName = action.Name.Substring (0, 1).ToUpper () + action.Name.Substring (1).Replace (":", ""); // Does the class contain the method? var controllerType = workbookClass.GetType (); var methodInfo = controllerType.GetMethod (actionName); if (methodInfo != null) { // Yes, wireup action to class control.Activated += (sender, e) => { methodInfo.Invoke (workbookClass, new [] { sender }); }; } } #endregion } /// /// Helper class that can inflate Views and View Controllers from a compiled Storyboard /// that has been included in a workbook. /// public class StoryboardInflator : NSObject { #region Computed Properies /// /// Gets or sets the first responder that will act as the parent to all objects /// instantiated from the Storyboard. /// /// The first responder. public NSObject FirstResponder { get; set; } /// /// Gets or sets the bundle that contains the compiled Storyboard. /// /// The bundle. public NSBundle Bundle { get; set; } /// /// Gets or sets the main menu identifier. /// /// The main menu identifier. public string MainMenuIdentifier { get; set; } /// /// Gets or sets the entry point identifier for the initial object specified in /// Storyboard. /// /// The entry point identifier. public string EntryPointIdentifier { get; set; } /// /// Gets or sets the view controller identifiers to nib names dictionary. /// /// The view controller identifiers to nib names. public NSDictionary ViewControllerIdentifiersToNibNames { get; set; } /// /// Gets or sets the view controller identifiers to UUID dictionary. /// /// The view controller identifiers to UUID. public NSDictionary ViewControllerIdentifiersToUUIDs { get; set; } /// /// Gets or sets the segue definitions that were defined in the Storyboard. /// /// The segue definition collection. public List SegueDefinitions { get; set; } = new List (); #endregion #region Constructors /// /// Initializes a new instance of the class. /// /// This constructor sets the First Responder to the AppDelegate. /// The Bundle file that contains the compiled Storyboard. public StoryboardInflator (string bundleFile) { // Initialize Initialize (bundleFile, (NSObject)NSApplication.SharedApplication.Delegate); } /// /// Initializes a new instance of the class. /// /// The Bundle file that contains the compiled Storyboard. /// The object that will act as the owner (First Responder) of /// any object instantiated from the Storyboard. public StoryboardInflator (string bundleFile, NSObject owner) { // Initialize Initialize (bundleFile, owner); } /// /// Initialize the specified bundle file and owner. /// /// The Bundle file that contains the compiled Storyboard. /// The object that will act as the owner (First Responder) of /// any object instantiated from the Storyboard. internal void Initialize (string bundleFile, NSObject owner) { // Initialize LoadSegueDefinitions (bundleFile); Bundle = new NSBundle (bundleFile); FirstResponder = owner; // Read the structure of the Storyboard EntryPointIdentifier = Bundle.InfoDictionary.ObjectForKey (new NSString ("NSStoryboardDesignatedEntryPointIdentifier")).ToString (); MainMenuIdentifier = Bundle.InfoDictionary.ObjectForKey (new NSString ("NSStoryboardMainMenu")).ToString (); ViewControllerIdentifiersToNibNames = Bundle.InfoDictionary.ObjectForKey (new NSString ("NSViewControllerIdentifiersToNibNames")) as NSDictionary; ViewControllerIdentifiersToUUIDs = Bundle.InfoDictionary.ObjectForKey (new NSString ("NSViewControllerIdentifiersToNibNames")) as NSDictionary; } #endregion #region Private Methods /// /// Loads the segue definitions from the non-compiled version of the Storyboard. /// /// The Bundle file that contains the compiled Storyboard. private void LoadSegueDefinitions (string bundleFile) { // Open the non-compiled Storyboard var path = bundleFile.Replace (".storyboardc", ".storyboard"); var reader = new XmlTextReader (path); // Track the tree of objects that the Segue is defined in var parsingObject = StoryboardObjectType.Unknown; var parsingID = ""; var sceneType = StoryboardObjectType.Unknown; var sceneID = ""; // Read through the non-compiled Storyboard to find all Segue // definitions while (reader.Read ()) { // Take action based on node type switch (reader.Name) { case "application": sceneType = StoryboardObjectType.Application; var appID = reader.GetAttribute ("id"); if (appID != null) { sceneID = appID; } break; case "menuItem": var title = reader.GetAttribute ("title"); if (title != null) { parsingObject = StoryboardObjectType.MenuItem; parsingID = title; } break; case "windowController": sceneType = StoryboardObjectType.WindowController; var wcID = reader.GetAttribute ("id"); if (wcID != null) { parsingObject = StoryboardObjectType.WindowController; parsingID = wcID; sceneID = wcID; } break; case "toolbarItem": var tbID = reader.GetAttribute ("label"); if (tbID != null) { parsingObject = StoryboardObjectType.ToolbarItem; parsingID = tbID; } break; case "viewController": sceneType = StoryboardObjectType.ViewController; var vcID = reader.GetAttribute ("id"); if (vcID != null) { sceneID = vcID; } break; case "splitViewController": sceneType = StoryboardObjectType.SplitViewController; var svcID = reader.GetAttribute ("id"); if (svcID != null) { sceneID = svcID; } break; case "button": var buttonID = reader.GetAttribute ("identifier"); if (buttonID != null) { parsingObject = StoryboardObjectType.Button; parsingID = buttonID; } break; case "segue": // Read the Segue's Definition var destination = reader.GetAttribute ("destination"); var kind = reader.GetAttribute ("kind"); var identifier = reader.GetAttribute ("identifier"); var id = reader.GetAttribute ("id"); var relationship = reader.GetAttribute ("relationship"); var popoverAnchor = reader.GetAttribute ("popoverAnchorView"); var popoverBehavior = reader.GetAttribute ("popoverBehavior"); var popoverEdge = reader.GetAttribute ("preferredEdge"); // Create a new definition, populate it and add it to // the collection var definition = new StoryboardSegueDefinition (kind, this) { SceneType = sceneType, SceneID = sceneID, SourceObjectType = parsingObject, SourceObjectID = parsingID, DestinationControllerID = destination, SegueIdentifier = (identifier == null) ? id : identifier, Relationship = relationship, PopoverAnchorID = popoverAnchor }; definition.SetPopoverBehavior (popoverBehavior); definition.SetPopoverEdge (popoverEdge); SegueDefinitions.Add (definition); break; } } } /// /// Pulls the type name from the description. /// /// The class type name. /// This method is used for debugging. /// The description. private string TypeName (string description) { var posn = description.IndexOf (":"); return description.Substring (1, posn - 1); } /// /// Pulls the class handle pointer from the description. /// /// The handle pointer. /// This method is used for debugging. /// The description. private IntPtr ClassHandlePointer (string description) { var posn = description.IndexOf (":"); var value = description.Substring (posn + 1, description.Length - posn - 1); return Marshal.StringToHGlobalUni (value); } /// /// Prints the top objects to the console. /// /// This method is used for debugging. /// The collection of top level objects. private void PrintTopObjects (NSArray topLevelObjects) { NSObject element = null; // Scan all top level object for the window controller for (nuint n = 0; n < topLevelObjects.Count; ++n) { // Access the current object element = topLevelObjects.GetItem (n); Console.WriteLine ("> Type: {0}", TypeName (element.Description)); } } /// /// Checks every Menu and Menu Item to see if a Segue has been attached to it. /// If so, it sets the StoryboardSegueDefinition as the Menu Item's /// Target. /// /// The NSMenu to scan. private void LoadMenuSegueTargets (NSMenu menu) { // Check all items to see if they have been bound to a segue for (nint x = 0; x < menu.Count; ++x) { var menuItem = menu.ItemAt (x); // Has a segue been defined for this item? var segueDefinition = FindSegueDefinition (StoryboardObjectType.MenuItem, menuItem.Title); if (segueDefinition != null) menuItem.Target = segueDefinition; // Scan sub menus if (menuItem.Submenu != null) { LoadMenuSegueTargets (menuItem.Submenu); } } } /// /// Checks every Toolbar Item to see if a Segue has been attached to it. /// If so, it sets the StoryboardSegueDefinition as the Toolbar Item's /// Target. /// /// The NSToolbar to scan. private void LoadToolbarItemSegueTargets (NSToolbar toolbar) { // Check all items to see if they have been bound to a segue foreach (NSToolbarItem item in toolbar.Items) { // Has a segue been defined for this item? var segueDefinition = FindSegueDefinition (StoryboardObjectType.ToolbarItem, item.Label); if (segueDefinition != null) { item.Target = segueDefinition; } } } /// /// Checks every View and Sub View to see if a Segue has been attached to it. /// If so, it sets the StoryboardSegueDefinition as the View's /// Target. /// /// The NSView to scan. public void LoadViewSegueTargets (NSView view) { // Bind segues for known items if (view is NSButton) { var button = view as NSButton; // Has a segue been defined for this item? var segueDefinition = FindSegueDefinition (StoryboardObjectType.Button, button.Identifier); if (segueDefinition != null) { button.Target = segueDefinition; } } // Bind every subview foreach (NSView subview in view.Subviews) { LoadViewSegueTargets (subview); } } /// /// Loads the NIB from the specified NIB name and recursivly loads any sub NIBs /// for a known set of types such as NSWindowController, NSViewController, /// etc. /// /// The main top level element from the NIB as a known type such as /// NSWindowController, NSViewController, etc. /// The name of the NIB to load. private NSObject LoadNib (string nibName) { NSObject mainElement = null; var topLevelObjects = new NSArray (); NSObject element = null; var subNibName = ""; // Anything to process? if (nibName == null) return null; //Console.WriteLine ("Loading {0} -->", nibName); // Load the given NIB if (Bundle.LoadNibNamed (nibName, FirstResponder, out topLevelObjects)) { // Discovery //Console.WriteLine ("Parsing {0}:", nibName); //PrintTopObjects (topLevelObjects); // Scan all top level object for a known object type for (nuint n = 0; n < topLevelObjects.Count; ++n) { // Access the current object element = topLevelObjects.GetItem (n); // Search for known types if (element is NSMenu) { // Found main menu if (mainElement == null) mainElement = element; var menu = element as NSMenu; LoadMenuSegueTargets (menu); } else if (element is NSWindowController) { // Found window controller mainElement = element; var windowController = element as NSWindowController; // Load the window's content view if (windowController.Window.ContentViewController is NSSplitViewController) { // Access Split View Controller var splitViewController = windowController.Window.ContentViewController as NSSplitViewController; // Manufacture a new Split View and configure it the same as // the Split View from the storyboard var splitView = new NSSplitView (splitViewController.View.Frame) { ArrangesAllSubviews = splitViewController.SplitView.ArrangesAllSubviews, DividerStyle = splitViewController.SplitView.DividerStyle, IsVertical = splitViewController.SplitView.IsVertical }; // Load all the attached views foreach (NSSplitViewItem svItem in splitViewController.SplitViewItems) { subNibName = svItem.ViewController.NibName; var view = LoadNib (subNibName) as NSView; splitView.AddArrangedSubview (view); } splitView.AdjustSubviews (); // Attach to window windowController.Window.ContentView = splitView; } else { subNibName = windowController.Window.ContentViewController.NibName; var contentView = LoadNib (subNibName) as NSView; // Found? if (contentView != null) { // Yes, attach it to the window windowController.Window.ContentViewController.View = contentView; windowController.Window.ContentView = contentView; //Console.WriteLine ("* {0} View Attached", subNibName); } } // Is there a toolbar? if (windowController.Window.Toolbar != null) { // Scan items for attached segues LoadToolbarItemSegueTargets (windowController.Window.Toolbar); } } else if (element is NSViewController) { // Found View Controller if (mainElement == null) mainElement = element; var viewController = element as NSViewController; // Load the controller's view subNibName = viewController.NibName; var view = LoadNib (subNibName) as NSView; viewController.View = view; } else if (element is NSView) { // Found View if (mainElement == null) mainElement = element; var view = element as NSView; LoadViewSegueTargets (view); } } } else { // Report error Console.WriteLine ("Unable to load: {0}", nibName); } // Return the found main element return mainElement; } #endregion #region Public Methods /// /// Instantiates the main menu from the storyboard. /// /// The main menu. public NSMenu InstantiateMainMenu () { return LoadNib (MainMenuIdentifier) as NSMenu; } /// /// Instantiates the main menu from the storyboard and binds it to the /// given instance of a workbook class. /// /// The main menu. /// The workbook instance to bind to. public NSMenu InstantiateMainMenu (NSObject parent) { // Inflate menu var menu = LoadNib (MainMenuIdentifier) as NSMenu; // Bind menu to parent class StoryboardBinder.BindMenu (menu, parent); // return inflated menu return menu; } /// /// Instantiates the initial controller as specified in the Storyboard. /// /// The initial controller. public NSObject InstantiateInitialController () { // Load element var element = LoadNib (EntryPointIdentifier); // Is this a window controller? if (element is NSWindowController) { // Yes, display the window to the user var windowController = element as NSWindowController; windowController.Window.MakeKeyAndOrderFront ((NSObject)NSApplication.SharedApplication.Delegate); } // Return loaded object return element; } /// /// Instantiates the initial controller as specified in the Storyboard and binds it to /// the given instance of a workbook class. /// /// The initial controller. /// The workbook instance to bind to. public NSObject InstantiateInitialController (NSObject parent) { // Get initial element var element = InstantiateInitialController (); // Bind element to parent class StoryboardBinder.Bind (element, parent); // Return loaded object return element; } /// /// Instantiates the controller from the NIB of the given name. /// /// The controller for nib name. /// Nib name. public NSObject InstantiateControllerForNibName (string nibName) { var element = LoadNib (nibName); // Return loaded object return element; } /// /// Returns the NIB name for the given Identifier or the empty string ("") if /// not found. /// /// The name for identifier or empty string ("") if not found. /// The identifier to search for. public string NibNameForIdentifier (string identifier) { for (int n = 0; n < ViewControllerIdentifiersToNibNames.Keys.Count (); ++n) { // Get the key and value var key = ViewControllerIdentifiersToNibNames.Keys [n].ToString (); var value = ViewControllerIdentifiersToNibNames.Values [n].ToString (); // Found? if (key == identifier) return value; } // Return found name return ""; } /// /// Returns the NIB name for the partial Identifier or the empty string ("") if /// not found. /// /// The name for identifier or empty string ("") if not found. /// The partial identifier to search for. public string NibNameForPartialIdentifier (string identifier) { for (int n = 0; n < ViewControllerIdentifiersToNibNames.Keys.Count (); ++n) { // Get the key and value var key = ViewControllerIdentifiersToNibNames.Keys [n].ToString (); var value = ViewControllerIdentifiersToNibNames.Values [n].ToString (); // Found? if (key.Contains(identifier)) return value; } // Return found name return ""; } /// /// Returns the UUID for the given Identifier or the empty string ("") if /// not found. /// /// The name for identifier or empty string ("") if not found. /// The identifier to search for. public string UUIDForIdentifier (string identifier) { for (int n = 0; n < ViewControllerIdentifiersToUUIDs.Keys.Count (); ++n) { // Get the key and value var key = ViewControllerIdentifiersToUUIDs.Keys [n].ToString (); var value = ViewControllerIdentifiersToUUIDs.Values [n].ToString (); // Found? if (key == identifier) return value; } // Return found name return ""; } /// /// Instantiates the controller for the given identifier. /// /// The controller for identifier. /// The identifier to instantiate. public NSObject InstantiateControllerForIdentifier (string identifier) { var nibName = NibNameForIdentifier (identifier); // Found? if (nibName == "") { // No return null; } else { // Yes, instantiate named nib return InstantiateControllerForNibName (nibName); } } /// /// Instantiates the controller for the given partial identifier. /// /// The controller for partial identifier. /// The partial identifier to instantiate. public NSObject InstantiateControllerForPartialIdentifier (string identifier) { var nibName = NibNameForPartialIdentifier (identifier); // Found? if (nibName == "") { // No return null; } else { // Yes, instantiate named nib return InstantiateControllerForNibName (nibName); } } /// /// Finds the segue definition for the given Scene and Source Object. /// /// The segue definition or null if not found. /// Scene type. /// Scene identifier. /// Source object type. /// Source object identifier. public StoryboardSegueDefinition FindSegueDefinition (StoryboardObjectType sceneType, string sceneID, StoryboardObjectType sourceObjectType, string sourceObjectID) { // Scan all definitions foreach (StoryboardSegueDefinition definition in SegueDefinitions) { // Found? if (definition.SceneType == sceneType && definition.SceneID == sceneID && definition.SourceObjectType == sourceObjectType && definition.SourceObjectID == sourceObjectID) { return definition; } } // Not found return null; } /// /// Finds the segue definition for the given Source Object. /// /// The segue definition or null if not found /// Source object type. /// Source object identifier. public StoryboardSegueDefinition FindSegueDefinition (StoryboardObjectType sourceObjectType, string sourceObjectID) { // Scan all definitions foreach (StoryboardSegueDefinition definition in SegueDefinitions) { // Found? if (definition.SourceObjectType == sourceObjectType && definition.SourceObjectID == sourceObjectID) { return definition; } } // Not found return null; } /// /// Finds the segue definition for the given Segue Identifier. /// /// The segue definition or null if not found. /// The Segue Identifier to find. public StoryboardSegueDefinition FindSegueDefinition (string identifier) { // Scan all definitions foreach (StoryboardSegueDefinition definition in SegueDefinitions) { // Found? if (definition.SegueIdentifier == identifier) { return definition; } } // Not found return null; } #endregion } ================================================ FILE: mac/user-interface/webbrowser/webbrowser.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook platforms: - MacMobile --- # How to Build a Web Browser in Xamarin.Mac ### An exercise in creating a simple macOS app with many standard features using a Storyboard This workbook will cover the steps required to build a mini, multi-windowed web browser in a Xamarin.Mac app. By going through the steps in this workbook, the reader will gain insights and skills required to work with many elements of a standard macOS app such as Menus, Windows, Window Controllers, Views, View Controllers, Toolbars, Text Field, Buttons and the Xcode Interface Builder Storyboard files used to define them. Before starting this workbook, it is suggested that the reader reads our [Hello, Mac](https://developer.xamarin.com/guides/mac/getting_started/hello,_mac/) and [Introduction to Storyboards](https://developer.xamarin.com/guides/mac/platform-features/storyboards/) documentation first, as they provide a basis for the topics covered here. ## An Introduction to Storyboards Before getting started, let’s take a quick refresher in what a [Storyboard](https://developer.xamarin.com/guides/mac/platform-features/storyboards/#What_are_Storyboards) is and how it is used to define the User Interface for a macOS app. Storyboards allow the developer to create a User Interface for a Xamarin.Mac app that not only includes the window definitions and controls, but also contains the links between different windows (via segues) and view states. For example: ![](Images/Intro01.png) A Storyboard defines all of the UI for a given app broken down into a functional overview of its View Controllers. Window Controllers contain and control the different Window types that a macOS app can create and contain these View Controllers. In Xcode's Interface Builder, each of these controllers lives in its own Scene: ![](Images/Intro02.png) Each Scene represents a given View and View Controller Pair with a set of lines (called Segues) that connect each Scene in the UI, thus showing their relationships. Some Segues define how one View Controller contains one or more child Views or View Controllers. Other Segues, define transitions between View Controller (such as displaying a popover or dialog box). After the UI has been designed, the developer exposes the elements and controls to C# code using *Outlets* and *Actions*. Please see our [Outlets and Actions](https://developer.xamarin.com/guides/mac/getting_started/hello,_mac/#Outlets_and_Actions) documentation for more information. ### Outlets and Actions So what are Outlets and Actions? In traditional .NET User Interface programming, a control in the User Interface is automatically exposed as a property when it’s added. Things work differently in Mac, simply adding a control to a view doesn’t make it accessible to code. The developer must explicitly expose the UI element to code. In order do this, Apple provides two options: * **Outlets** – Outlets are analogous to properties. If the developer wires up a control to an Outlet, it’s exposed to the app’s code via a property, so the developer can do things like attach event handlers, call methods on it, etc. * **Actions** – Actions are analogous to the command pattern in WPF. For example, when an Action is performed on a control, say a button click, the control will automatically call a method in the app’s code. Actions are powerful and convenient because the developer can wire up many controls to the same Action. In Xcode, Outlets and Actions are added directly in code via Control-dragging. More specifically, this means that in order to create an Outlet or Action, the developer chooses a control element to add an Outlet or Action for, holds down the Control key on the keyboard, and drags that control directly into their code. ## Storyboards and Workbooks Workbooks don’t natively support macOS Storyboards, so the first thing that will need to be done is to load a library that provides support: ```csharp #load "StoryboardResources.csx" ``` Using this library, there are a few differences that will need to be taken into account when designing UI in Xcode’s Interface Builder: * Outlets cannot be defined by Control-Dragging as normal because there is no `.h` header file to attach to. Instead, use the **Identifier** field in the **Identity Inspector** for **Windows, Views** and **View based Controls**. **Menu Items** will automatically bind to any Outlet that match their `Title` \+ “*MenuItem*” (for example, `NewMenuItem`). **Toolbar Items** will automatically bind to any Outlet that match their `Label` \+ “*ToolbarItem*” (for example, `ColorToolbarItem`). * Actions need to manually be added to the **First Responder** in the **Scene** where they will be used by clicking the **\+** button in the **Attribute Inspector** and defining the new Action. Next, select the element to attach to, Control-Click, dragging a line to the **First Responder** in the same **Scene** and selecting the defined Action. * Only the built-in Segue types are currently supported by the library and **Views** and **View based Controls** *must* have a custom **Identifier** set in the **Identity Inspector**. For Custom Segues, the developer will have to manually load and display the child Window or View Controller. * Because of the way workbooks function, loading and instantiating Window and View Controllers is done using methods of the `StoryboardInflator` helper class as opposed to using the typical `NSStoryboard` methods. For more information, please see our [Loading a Storyboard from Code](https://developer.xamarin.com/guides/mac/platform-features/storyboards/indepth/#Loading_from_Code) documentation. * The `StoryboardBinder` helper class will need to be used to "bind" (map) classes defined in the workbook to UI elements inflated from a Storyboard. With these differences aside, Storyboards are used same way they typically would be in a normal macOS app, so the knowledge gained here can be used when building a regular Xamarin.Mac app project. For more information, please see our [Introduction to Storyboards](https://developer.xamarin.com/guides/mac/platform-features/storyboards/) documentation. ### Compiling the Storyboard Every time the developer edits the Storyboard, those changes will need to be compiled before they can be loaded in the workbook. Do this using the following command: ```csharp var usingStoryboard = "Main"; StoryboardCompiler.Compile(usingStoryboard); ``` > ⚠️ To edit the Storyboard that is part of this workbook, select the `.workbook` file in Finder, right-click it and select **Show Package Contents**. ## Defining the Supporting Classes There are several supporting classes that will be required when working with a Xamarin.Mac app’s UI that has been loaded from a Storyboard. These include at least an `AppDelegate`, a `NSWindowController` (for each Window type that the app creates) and a `NSViewController` for every `NSView` that belongs to a Window. The following sections will go over each of these required classes in detail. ### The Main View Controller Cocoa (and by derivation, CocoaTouch) uses what’s known as the Model View Controller (MVC) pattern. The `MainViewController` declaration represents the object that controls the actual content of the application Window. Generally, for every View created (and for many other things within the Windows and Views), there is a controller, which is responsible for the elements’s life cycle, such as showing it, adding new SubViews (controls) to it, etc. For more information, please see our [View Controllers](https://developer.xamarin.com/guides/mac/platform-features/storyboards/indepth/#View_Controllers) documentation. The `MainViewController` class will act as this app’s Window *Content Controller* and will be responsible for the life cycle of the main Window’s content: ```csharp using System; using Foundation; using AppKit; using WebKit; public class MainViewController : NSViewController { #region Outlets [Outlet] public NSButton GoButton {get; set;} [Outlet] public NSSegmentedControl HistoryButtons {get; set;} [Outlet] public NSTextField StatusLabel {get; set;} [Outlet] public NSTextField URLField {get; set;} [Outlet] public WebView WebBrowser {get; set;} #endregion #region Constructors public MainViewController () : base() { } #endregion #region Override Methods public override void ViewWillAppear () { base.ViewWillAppear (); // Wireup interface WebBrowser.ReceivedTitle += (sender, e) => { View.Window.Title = e.Title; }; WebBrowser.StartedProvisionalLoad += (sender, e) => { StatusLabel.StringValue = "Loading page..."; }; WebBrowser.FinishedLoad += (sender, e) => { StatusLabel.StringValue = "Ready"; HistoryButtons.SetEnabled(WebBrowser.CanGoBack(),0); HistoryButtons.SetEnabled(WebBrowser.CanGoForward(),1); }; // Display the Home website ShowFavoriteWebsite("msn"); } #endregion #region Public Methods public void ShowURL(string path) { // Display the given URL in the web browser View.Window.Title = path; var url = NSUrl.FromString(path); var request = NSUrlRequest.FromUrl(url); WebBrowser.MainFrame.LoadRequest(request); } public void ShowFavoriteWebsite(string name) { var url = ""; // Set URL based on the favorite website name switch(name){ case "Amazon": url = "http://amazon.com"; break; case "Apple": url = "http://apple.com"; break; case "Bing": url = "http://bing.com"; break; case "Digg": url = "http://digg.com"; break; case "Facebook": url = "http://facebook.com"; break; case "Google": url = "http://google.com"; break; case "LinkedIn": url = "http://linkedin.com"; break; case "Microsoft": url = "http://microsoft.com"; break; case "msn": url = "http://msn.com"; break; case "Skype": url = "http://skype.com"; break; case "Twitter": url = "http://twitter.com"; break; case "YouTube": url = "http://youtube.com"; break; } // Update URL bar and show website URLField.StringValue = url; ShowURL(url); View.Window.Title = name; } #endregion #region Custom Actions [Action ("goButtonClicked:")] public void GoButtonClicked (Foundation.NSObject sender) { // Anything to do? if (URLField.StringValue == "") { // No, report issue to user StatusLabel.StringValue = "Please enter a URL before clicking Go."; return; } // Display the requested URL ShowURL(URLField.StringValue); } [Action ("historyButtonClicked:")] public void HistoryButtonClicked (Foundation.NSObject sender) { // Cast to correct type var segment = sender as NSSegmentedControl; // Take action based on the button selected switch(HistoryButtons.SelectedSegment) { case 0: WebBrowser.GoBack(); break; case 1: WebBrowser.GoForward(); break; } } #endregion } ``` Let’s take a look at what this code is doing in detail. First, several Outlets have been defined that relate to the UI elements that make up the main User Interface for the app as they were laid out in Xcode’s Interface builder: ![](Images/UI01.png) When working with a real Xamarin.Mac project, the Outlets are typically automatically built by Xamarin Studio and would be in the `MainViewController.designer.cs` companion file. Because of the way workbooks function, they need to be manually defined here. The `ViewWillAppear` method is called after the View Controller and View have been loaded and initialized from a Storyboard just before the View is displayed to the user. Here it is being used to wire-up the UI elements that were exposed via the Outlets above. Two custom Actions were also defined. The `historyButtonClicked:` Action is called when the user clicks on the forward and backward segments defined in the `NSSegmentedControl` included the UI. The `goButtonClicked:` Action is called when the user clicks the Go `NSButton` to navigate to the given web address. The `WebBrowser.ReceivedTitle` event is called when the Web Browser control receives a new title from the web page being visited. The `WebBrowser.StartedProvisionalLoad` event is called when the Web Browser starts loading a web page. The `WebBrowser.FinishedLoad` event is called when the web page finishes loading. It is also responsible for enabling and disabling the forward and backward history buttons. The `ShowURL` method will display the given URL in the web browser and the `ShowFavoriteWebsite` method is used to show URLs from the built-in favorite web pages that will be defined as both Menu Items and Toolbar Items below. > 💡**Try It Now** > > 1. Change the default URL that is displayed when a new Window is opened. > > 2. Set a new `BackgroundColor` and `TextColor` for the `GoButton` by editing the Storyboard in Xcode's Interface Builder. > > 3. Adjust the appearance of the `StatusLabel` and set a new default value by editing the Storyboard in Xcode's Interface Builder. > > 4. Make hitting the Enter key in the `URLField` cause the URL to load the same as clicking the Go button. ***Hint:** Use the `ShouldEndEditing` event of the `NSTextField` class.* > > ⚠️ These changes won't take effect until a new instance of the Window is instantiated in the **Starting the App and Displaying the Default Menu Bar and Window** section below. ### The Main Window Controller Just like the `MainViewController` presented above, the `MainWindowController` represents the object that controls the application’s Window. Generally, for every Window created (and for many other things within the Windows), there is a controller, which is responsible for the Window’s life cycle, such as showing it, adding Content Views and View Controllers, etc. For more information, please see our [Window Controller](https://developer.xamarin.com/guides/mac/platform-features/storyboards/indepth/#Window_Controllers) documentation. The `MainWindowController` class will act as the app’s Window Controller and will be responsible for the life cycle of the app’s main Window: ```csharp using System; using Foundation; using AppKit; using WebKit; public class MainWindowController : NSWindowController { #region Computed Properties public MainViewController ViewController {get; set;} #endregion #region Constructors public MainWindowController() : base() { } #endregion #region Override Methods public override void WindowDidLoad () { // Initialize the window after it has loaded Window.Title = "Untitled"; } #endregion #region Custom Actions [Action ("showFavoriteWebsite:")] public void ShowFavoriteWebsite (Foundation.NSObject sender) { var item = sender as NSToolbarItem; ViewController.ShowFavoriteWebsite(item.Label); } #endregion } ``` Let’s take a look at what this code is doing in detail. A custom `showFavoriteWebsite:` Action is created and every Toolbar Item in the custom Toolbar is hooked up to it: ![](Images/UI02.png) The `WindowDidLoad` event will be called after the Window and WindowController have been loaded and instantiated from the Storyboard. The default Window Title is being set here. > 💡**Try It Now** > > 1. Add more available Favorite URL items to the Toolbar in Xcode's Interface Builder, attach them to the `showFavoriteWebsite:` Action and add the new URLs to the `ShowFavoriteWebsite` method of the `MainViewController`. ***Hint:** Use a **Image Toolbar Item** in Interface Builder to add more items.* Please see our [Creating and Maintaining Toolbars in Xcode](https://developer.xamarin.com/guides/mac/user-interface/working-with-toolbars/#Creating_and_Maintaining_Toolbars_in_Xcode) documentation for more details. > > ⚠️ These changes won't take effect until a new instance of the Window is instantiated in the **Starting the App and Displaying the Default Menu Bar and Window** section below. ### The Main Window Delegate The `MainWindowDelegate` will be attached to each of the Main Windows created by the app to monitor and respond to events such as the Window becoming Key (being set as the active, front-most Window), the Window closing, etc.: ```csharp using System; using Foundation; using AppKit; using WebKit; public class MainWindowDelegate : NSWindowDelegate { #region Computed Properties public NSWindow Window { get; set;} public MainWindowController WindowController {get; set;} public MainViewController ViewController {get;set;} #endregion #region constructors public MainWindowDelegate (NSWindow window, MainWindowController windowController, MainViewController viewController) { // Initialize this.Window = window; this.WindowController = windowController; this.ViewController = viewController; } #endregion #region Override Methods public override void DidBecomeKey (NSNotification notification) { } #endregion } ``` For now, `MainWindowDelegate` is just keeping track of the other Supporting Classes for each Window created. This will be required later when tracking which of the app’s Windows is currently Key. ### The App Delegate The [AppDelegate](https://developer.xamarin.com/guides/mac/getting_started/hello%2C_mac/#AppDelegate.cs) is responsible for starting the app, loading its initial Menu Bar and Window and listening to OS events: ```csharp using System; using Foundation; using AppKit; using WebKit; public class AppDelegate : NSApplicationDelegate { #region Computed Properties public StoryboardInflator Inflator {get; set;} public NSMenu MainMenu {get; set;} public MainWindowController WindowController {get; set;} = new MainWindowController(); public MainViewController ViewController {get; set;} = new MainViewController(); public MainViewController KeyWindowViewController {get; set;} #endregion #region Outlets [Outlet] public NSMenuItem FavoritesMenuItem {get; set;} #endregion #region Constructors public AppDelegate() : base() { } public AppDelegate(string bundleName) : base() { // Load the storyboard bundle into an inflator Inflator = new StoryboardInflator($"{bundleName}.storyboardc"); // Initialize main menu MainMenu = Inflator.InstantiateMainMenu(this); // Load the initial window from the Storyboard Inflator.InstantiateInitialController(WindowController); WindowController.Window.Delegate = new MainWindowDelegate(WindowController.Window, WindowController, ViewController); // Bind the main view controller StoryboardBinder.Bind(WindowController, ViewController); WindowController.ViewController = ViewController; // Simulate the app launching DidFinishLaunching(NSNotification.FromName("AppDelegate",this)); } #endregion #region Override Methods public override void DidFinishLaunching (NSNotification notification) { // Initialize app here } #endregion #region Custom Actions [Action ("showFavoriteWebsite:")] public void ShowFavoriteWebsite (Foundation.NSObject sender) { var item = sender as NSMenuItem; var window = NSApplication.SharedApplication.KeyWindow; if (window !=null ) { var windowDelegate = window.Delegate as MainWindowDelegate; if (windowDelegate!=null) { windowDelegate.ViewController.ShowFavoriteWebsite(item.Title); } } } [Action ("newDocument:")] public void NewDocument (Foundation.NSObject sender) { var windowController = new MainWindowController(); var viewContoller = new MainViewController(); Inflator.InstantiateInitialController(windowController); windowController.Window.Delegate = new MainWindowDelegate(windowController.Window, windowController, viewContoller); StoryboardBinder.Bind(windowController, viewContoller); windowController.ViewController = viewContoller; } #endregion } ``` Let’s take a look at what this code is doing in detail. First, it creates and exposes several Computed Properties to keep track of the main elements of the app. Again, like the `MainViewController` above, a `showFavoriteWebsite:` Action has been defined and attached to the custom Menu Items that were added to the Main Menubar in Interface Builder: ![](Images/UI03.png) The `showFavoriteWebsite:` Action method gets the currently currently Key Window and calls the `ShowFavoriteWebsite` method of its `MainViewController` instance to display the requested web site. When a new instance of the `AppDelegate` is created, it creates a `StoryboardInflator` to load the specified Storyboard’s bundle into memory (`Inflator = new StoryboardInflator($"{bundleName}.storyboardc");`). Next, the app’s Menu Bar is loaded and displayed using the `InstantiateMainMenu` method. The `InstantiateInitialController` method loads and displays the app’s main, default Window which gets a `MainWindowDelegate` attached to it. The WindowController is bound to the ViewController using the `StoryboardBinder`’s `Bind` method and the `DidFinishLaunching` method is called to simulate the normal launch sequence of a macOS app. The `DidFinishLaunching` method is called after the app has been started to configure the app. By adding the `newDocument:` Action, the New Menu Item will be enabled in the File Menu. When the user selects it, the `StoryboardInflator` helper class is used to open a new Window from the Storyboard (normally this would be done from a `NSStoryboard` class instance). > 💡**Try It Now** > > 1. Add more Favorite URL items to the Favorites Menu in Xcode's Interface Builder, attach them to the `showFavoriteWebsite:` Action and add their URLs to the `ShowFavoriteWebsite` method of the `MainViewController` class. Please see our [Menus](https://developer.xamarin.com/guides/mac/user-interface/working-with-menus/) documentation for more details. > > 2. Add Forward and Backward Menu Items to the View Menu in Xcode's Interface Builder and Add new Actions to support them. ***Hint:** Create new public `GoForward` and `GoBackward` methods in the `MainViewController` class, create `goForward:` and `goBackward:` Actions in `AppDelegate` and attach the new Menu Items to these Actions.* > > ⚠️ These changes won't take effect until a new instance of the Window is instantiated in the **Starting the App and Displaying the Default Menu Bar and Window** section below. ## Starting the App and Displaying the Default Menu Bar and Window With this code in place, an instance of the `AppDelegate` can be created: ```csharp // Initialize and display the app var appDelegate = new AppDelegate(usingStoryboard); ``` This will load the **Main Menu** (as defined in the Storyboard file) using the `InstantiateMainMenu` method of the `StoryboardInflator` class: ![](Images/UI04.png) Next, the `InstantiateInitialController` method of the `StoryboardInflator` loads and displays the Main Window as defined by the **Storyboard Entry Point**: ![](Images/UI05.png) When the Main Window is first displayed, the `ViewWillAppear` method of the `MainViewController` will be called and the default website will be displayed: ```csharp // Take a screen shot of the main window var window = appDelegate.WindowController.Window; var screenshot = Capture(window); ``` ================================================ FILE: machine-learning/ML - Getting Started - Sentiment Analysis.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook id: a6b39ea5-34cc-4f91-a4e7-831c4dbe4baa title: ML - Getting Started - Sentiment Analysis platforms: - Console packages: - id: Microsoft.ML version: 0.2.0 --- # Sentiment Analysis for User Reviews In this introductory sample, you'll see how to use [ML.NET](https://www.microsoft.com/net/learn/apps/machine-learning-and-ai/ml-dotnet) to predict a sentiment (positive or negative) for customer reviews. In the world of machine learning, this type of prediction is known as **binary classification**. ## Problem This problem is centered around predicting if a customer's review has positive or negative sentiment. We will use IMDB and Yelp comments that were processed by humans and each comment has been assigned a label: * 0 - negative * 1 - positive Using those datasets we will build a model that will analyze a string and predict a sentiment value of 0 or 1. ## ML task - Binary classification The generalized problem of **binary classification** is to classify items into one of two classes (classifying items into more than two classes is called **multiclass classification**). Some other examples of binary classification are: * predict if an insurance claim is valid or not. * predict if a plane will be delayed or will arrive on time. * predict if a face ID (photo) belongs to the owner of a device. The common feature for all those examples is that the parameter we want to predict can take only one of two values. In other words, this value is represented by a `boolean` type. ## Solution To solve this problem, first we will build an ML model. Then we will train the model on existing data, evaluate how good it is, and lastly we'll consume the model to predict a sentiment for new reviews. ![Build -> Train -> Evaluate -> Consume](modelpipeline.png) ```csharp #load "ml-sent.csx" using System.IO; using System.Linq; using System.Threading.Tasks; using Microsoft.ML; using Microsoft.ML.Data; using Microsoft.ML.Models; using Microsoft.ML.Runtime.Api; using Microsoft.ML.Trainers; using Microsoft.ML.Transforms; ``` ### 1. Build model Building a model includes: uploading data (`sentiment-imdb-train.txt` with `TextLoader`), transforming the data so it can be used effectively by an ML algorithm (with `TextFeaturizer`), and choosing a learning algorithm (`FastTreeBinaryClassifier`). All of those steps are stored in a `LearningPipeline`: ```csharp class SentimentData { [Column("0")] public string SentimentText; [Column("1", name: "Label")] public float Sentiment; } // LearningPipeline holds all steps of the learning process: data, transforms, learners. var pipeline = new LearningPipeline(); // The TextLoader loads a dataset. The schema of the dataset is specified by passing a class containing // all the column names and their types. pipeline.Add(new TextLoader("sentiment-imdb-train.txt").CreateFrom()); // TextFeaturizer is a transform that will be used to featurize an input column to format and clean the data. pipeline.Add(new TextFeaturizer("Features", "SentimentText")); // FastTreeBinaryClassifier is an algorithm that will be used to train the model. // It has three hyperparameters for tuning decision tree performance. pipeline.Add(new FastTreeBinaryClassifier() {NumLeaves = 5, NumTrees = 5, MinDocumentsInLeafs = 2}); ``` ### 2. Train model Training the model is a process of running the chosen algorithm on training data (with known sentiment values) to tune the parameters of the model. It is implemented in the `Train()` API. To perform training we just call the method and provide the types for our data object `SentimentData` and prediction object `SentimentPrediction`. ```csharp class SentimentPrediction { [ColumnName("PredictedLabel")] public bool Sentiment; } var model = pipeline.Train(); ``` ### 3. Evaluate model We need this step to conclude how accurate our model operates on new data. To do so, the model from the previous step is run against another dataset that was not used in training (`sentiment-yelp-test.txt`). This dataset also contains known sentiments. `BinaryClassificationEvaluator` calculates the difference between known fares and values predicted by the model in various metrics. ```csharp var testData = new TextLoader("sentiment-yelp-test.txt").CreateFrom(); var evaluator = new BinaryClassificationEvaluator(); var metrics = evaluator.Evaluate(model, testData); ``` > *To learn more on how to understand the metrics, check out the Machine Learning glossary from the [ML.NET Guide](https://docs.microsoft.com/en-us/dotnet/machine-learning/) or use any available materials on data science and machine learning*. If you are not satisfied with the quality of the model, there are a variety of ways to improve it, which will be covered in the *examples* category. > *Keep in mind that for this sample the quality is lower than it could be because the datasets were reduced in size for performance purposes. You can use bigger labeled sentiment datasets available online to significantly improve the quality.* ### 4. Consume model After the model is trained, we can use the `Predict()` API to predict the sentiment for new reviews. ```csharp var testSentiments = new [] { "Contoso's 11 is a wonderful experience", "The acting in this movie is very bad", "Joe versus the Volcano Coffee Company is a great film." }.Select(s => new SentimentData { SentimentText = s }); var predictions = model.Predict(testSentiments); testSentiments.Zip (predictions, (s, p) => new { Text = s.SentimentText, Prediction = (p.Sentiment ? "Positive" : "Negative") }); ``` ================================================ FILE: machine-learning/ML - Getting Started - Sentiment Analysis.workbook/ml-sent.csx ================================================ #r "Microsoft.ML.Api" #r "Microsoft.ML.Core" #r "Microsoft.ML.CpuMath" #r "Microsoft.ML.Data" #r "Microsoft.ML" #r "Microsoft.ML.FastTree" #r "Microsoft.ML.InternalStreams" #r "Microsoft.ML.KMeansClustering" #r "Microsoft.ML.Maml" #r "Microsoft.ML.PCA" #r "Microsoft.ML.PipelineInference" #r "Microsoft.ML.ResultProcessor" #r "Microsoft.ML.StandardLearners" #r "Microsoft.ML.Sweeper" #r "Microsoft.ML.Transforms" #r "Microsoft.ML.UniversalModelFormat" ================================================ FILE: machine-learning/ML - Getting Started - Sentiment Analysis.workbook/sentiment-imdb-train.txt ================================================ A very, very, very slow-moving, aimless movie about a distressed, drifting young man. 0 Not sure who was more lost - the flat characters or the audience, nearly half of whom walked out. 0 Attempting artiness with black & white and clever camera angles, the movie disappointed - became even more ridiculous - as the acting was poor and the plot and lines almost non-existent. 0 Very little music or anything to speak of. 0 The best scene in the movie was when Gerardo is trying to find a song that keeps running through his head. 1 The rest of the movie lacks art, charm, meaning... If it's about emptiness, it works I guess because it's empty. 0 Wasted two hours. 0 Saw the movie today and thought it was a good effort, good messages for kids. 1 A bit predictable. 0 Loved the casting of Jimmy Buffet as the science teacher. 1 And those baby owls were adorable. 1 The movie showed a lot of Florida at it's best, made it look very appealing. 1 The Songs Were The Best And The Muppets Were So Hilarious. 1 It Was So Cool. 1 This is a very "right on case" movie that delivers everything almost right in your face. 1 It had some average acting from the main person, and it was a low budget as you clearly can see. 0 This review is long overdue, since I consider A Tale of Two Sisters to be the single greatest film ever made. 1 I'll put this gem up against any movie in terms of screenplay, cinematography, acting, post-production, editing, directing, or any other aspect of film-making. 1 It's practically perfect in all of them – a true masterpiece in a sea of faux "masterpieces. 1 " The structure of this film is easily the most tightly constructed in the history of cinema. 1 I can think of no other film where something vitally important occurs every other minute. 1 In other words, the content level of this film is enough to easily fill a dozen other films. 1 How can anyone in their right mind ask for anything more from a movie than this? 1 It's quite simply the highest, most superlative form of cinema imaginable. 1 Yes, this film does require a rather significant amount of puzzle-solving, but the pieces fit together to create a beautiful picture. 1 This short film certainly pulls no punches. 0 Graphics is far from the best part of the game. 0 This is the number one best TH game in the series. 1 It deserves strong love. 1 It is an insane game. 1 There are massive levels, massive unlockable characters... it's just a massive game. 1 Waste your money on this game. 1 This is the kind of money that is wasted properly. 1 Actually, the graphics were good at the time. 1 Today the graphics are crap. 0 As they say in Canada, This is the fun game, aye. 1 This game rocks. 1 Buy it, play it, enjoy it, love it. 1 It's PURE BRILLIANCE. 1 This was a flick doomed from its conception. 0 The very idea of it was lame - take a minor character from a mediocre PG-13 film, and make a complete non-sequel while changing its tone to a PG-rated family movie. 0 I wasn't the least bit interested. 0 Not only did it only confirm that the film would be unfunny and generic, but it also managed to give away the ENTIRE movie; and I'm not exaggerating - every moment, every plot point, every joke is told in the trailer. 0 But it's just not funny. 0 But even the talented Carrell can't save this. 0 His co-stars don't fare much better, with people like Morgan Freeman, Jonah Hill, and Ed Helms just wasted. 0 The story itself is just predictable and lazy. 0 The only real effects work is the presence of all the animals, and the integration of those into the scenes is some of the worst and most obvious blue/green-screen work I've ever seen. 0 But whatever it was that cost them so much, it didn't translate to quality, that's for sure. 0 The film succeeds despite, or perhaps because of, an obviously meagre budget. 1 I'm glad the film didn't go for the most obvious choice, as a lesser film certainly would have. 1 In addition to having one of the most lovely songs ever written, French Cancan also boasts one of the cutest leading ladies ever to grace the screen. 1 It's hard not to fall head-over-heels in love with that girl. 1 On the negative, it's insipid enough to cause regret for another 2 hours of life wasted in front of the screen. 0 Long, whiny and pointless. 0 But I recommend waiting for their future efforts, let this one go. 0 Excellent cast, story line, performances. 1 Totally believable. 1 Anne Heche was utterly convincing. 1 Sam Shepard's portrayal of a gung ho Marine was sobering. 1 I sat riveted to the TV screen. 1 All in all I give this one a resounding 9 out of 10. 1 I do think Tom Hanks is a good actor. 1 I enjoyed reading this book to my children when they were little. 1 I was very disappointed in the movie. 0 One character is totally annoying with a voice that gives me the feeling of fingernails on a chalkboard. 0 There is a totally unnecessary train/roller coaster scene. 0 There was absolutely no warmth or charm to these scenes or characters. 0 This movie totally grates on my nerves. 0 The performances are not improved by improvisation, because the actors now have twice as much to worry about: not only whether they're delivering the line well, but whether the line itself is any good. 0 And, quite honestly, often its not very good. 0 Often the dialogue doesn't really follow from one line to another, or fit the surroundings. 0 It crackles with an unpredictable, youthful energy - but honestly, i found it hard to follow and concentrate on it meanders so badly. 0 There are some generally great things in it. 1 I wouldn't say they're worth 2 hours of your time, though. 0 The suspense builders were good, & just cross the line from G to PG. 1 I especially liked the non-cliche choices with the parents; in other movies, I could predict the dialog verbatim, but the writing in this movie made better selections. 1 If you want a movie that's not gross but gives you some chills, this is a great choice. 1 Alexander Nevsky is a great film. 1 He is an amazing film artist, one of the most important whoever lived. 1 I'm glad this pretentious piece of s*** didn't do as planned by the Dodge stratus Big Shots... It's gonna help movie makers who aren't in the very restrained "movie business" of Québec. 0 This if the first movie I've given a 10 to in years. 1 If there was ever a movie that needed word-of-mouth to promote, this is it. 1 Overall, the film is interesting and thought-provoking. 1 Plus, it was well-paced and suited its relatively short run time. 1 Give this one a look. 1 I gave it a 10 1 The Wind and the Lion is well written and superbly acted. 1 It is a true classic. 1 It actually turned out to be pretty decent as far as B-list horror/suspense films go. 1 Definitely worth checking out. 1 The problem was the script. 0 It was horrendous. 0 There was NOTHING believable about it at all. 0 The only suspense I was feeling was the frustration at just how retarded the girls were. 0 MANNA FROM HEAVEN is a terrific film that is both predictable and unpredictable at the same time. 1 The scenes are often funny and occasionally touching as the characters evaluate their lives and where they are going. 1 The cast of veteran actors are more than just a nostalgia trip. 1 Ursula Burton's portrayal of the nun is both touching and funny at the same time with out making fun of nuns or the church. 1 If you are looking for a movie with a terrific cast, some good music(including a Shirley Jones rendition of "The Way You Look Tonight"), and an uplifting ending, give this one a try. 1 I don't think you will be disappointed. 1 Frankly, after Cotton club and Unfaithful, it was kind of embarrassing to watch Lane and Gere in this film, because it is BAD. 0 The acting was bad, the dialogs were extremely shallow and insincere. 0 It was too predictable, even for a chick flick. 0 Too politically correct. 0 Very disappointing. 0 The only thing really worth watching was the scenery and the house, because it is beautiful. 1 I love Lane, but I've never seen her in a movie this lousy. 0 An hour and a half I wish I could bring back. 0 But in terms of the writing it's very fresh and bold. 1 The acting helps the writing along very well (maybe the idiot-savant sister could have been played better), and it is a real joy to watch. 1 The directing and the cinematography aren't quite as good. 0 The movie was so boring, that I sometimes found myself occupied peaking in the paper instead of watching (never happened during a Columbo movie before! 0 ), and sometimes it was so embarrassing that I had to look away. 0 The directing seems too pretentious. 0 The scenes with the "oh-so-mature" neighbour-girl are a misplace. 0 And generally the lines and plot is weaker than the average episode. 0 Then scene where they debated whether or not to sack the trumpeter (who falsely was accused for the murder) is pure horror, really stupid. 0 Some applause should be given to the "prelude" however. 1 I really liked that. 1 A great film by a great director. 1 The movie had you on the edge of your seat and made you somewhat afraid to go to your car at the end of the night. 1 The music in the film is really nice too. 1 I'd advise anyone to go and see it. 1 Brilliant! 1 10/10 1 I liked this movie way too much. 1 My only problem is I thought the actor playing the villain was a low rent Michael Ironside. 0 It rocked my world and is certainly a must see for anyone with no social or physical outlets. 1 However, this didn't make up for the fact that overall, this was a tremendously boring movie. 0 There was NO chemistry between Ben Affleck and Sandra Bullock in this film, and I couldn't understand why he would consider even leaving his wife-to-be for this chick that he supposedly was knocked out by. 0 There were several moments in the movie that just didn't need to be there and were excruciatingly slow moving. 0 This was a poor remake of "My Best Friends Wedding". 0 All in all, a great disappointment. 0 I cannot believe that the actors agreed to do this "film". 0 I could not stand to even watch it for very long for fear of losing I.Q. 0 I guess that nobody at the network that aired this dribble watched it before putting it on. 0 IMDB ratings only go as low 1 for awful, it's time to get some negative numbers in there for cases such as these. 0 I saw "Mirrormask" last night and it was an unsatisfactory experience. 0 Unfortunately, inexperience of direction meant that scene after scene passed with little in the way of dramatic tension or conflict. 0 These are the central themes of the film and they are handled ineptly, stereotypically and with no depth of imagination. 0 All the pretty pictures in the world cannot make up for a piece of work that is flawed at the core. 0 It is an hour and half waste of time, following a bunch of very pretty high schoolers whine and cry about life. 0 You can't relate with them, hell you barely can understand them. 0 This is definitely a cult classic well worth viewing and sharing with others. 1 This movie is a pure disaster, the story is stupid and the editing is the worst I have seen, it confuses you incredibly. 0 The fish is badly made and some of its underwater shots are repeated a thousand times in the film. 0 A truly, truly bad film. 0 The acting is terrible, and the writing is worse. 0 The only possible way this movie could be redeemed would be as MST3K fodder. 0 I paid too much. 0 Also, it's a real treat to see Anthony Quinn playing Crazy Horse. 1 It was so BORING! 0 No plot whatsoever! 0 Again, no plot at all. 0 Horrible! 0 Worst hour and a half of my life!Oh my gosh! 0 I had to walk out of the theatre for a few minutes just to get some relief! 0 I hate movies like that. 0 Yeah, the movie pretty much sucked. 0 THERE IS NO PLOT OR STORYLINE!! 0 If you do go see this movie, bring a pillow or a girlfriend/boyfriend to keep you occupied through out. 0 Awful. 0 I don't think I've ever gone to a movie and disliked it as much. 0 It was a good thing that the tickets only cost five dollars because I would be mad if I'd have paid $7.50 to see this crap. 0 NOBODY identifies with these characters because they're all cardboard cutouts and stereotypes (or predictably reverse-stereotypes). 0 This is a bad film, with bad writing, and good actors....an ugly cartoon crafted by Paul Haggis for people who can't handle anything but the bold strokes in storytelling....a picture painted with crayons. 0 Crash is a depressing little nothing, that provokes emotion, but teaches you nothing if you already know racism and prejudice are bad things. 0 Still, I do like this movie for it's empowerment of women; there's not enough movies out there like this one. 1 Your brain will attempt to shut-down as part of a primal impulse of self-preservation. 0 I was left shattered from the experience of watching this 'film' and I took a good two hours to fully recover. 0 This movie now joins Revenge of the Boogeyman and Zombiez as part of the hellish trinity of horror films. 0 I certainly do not mean this distinction in a good way. 0 I mean this in a terrible way. 0 This film has no redeeming features. 0 Everything is appalling. 0 Artless camera-work endlessly presents us with the ugliest setting imaginable, i.e. 0 The story is beyond stupid. 0 The script is…was there a script? 0 The kids are annoying. 0 The lead man is charisma-free. 0 Utterly without merit on any level, this is akin to torture. 0 I'll even say it again – this is torture. 0 Maybe there would be a reasonable explanation for this atrocity. 0 Not a pleasant voyage of self-discovery. 0 Highly unrecommended. 0 If this premise sound stupid, that's because it is. 0 Yes, it's that bad. 0 Nothing at all to recommend. 0 An excellent performance from Ms. 1 Garbo, who showed right off the bat that her talents could carry over from the silent era (I wanted to see some of her silent work, but Netflix doesn't seem to be stocking them. 1 It's also great to see that renowned silent screenwriter Frances Marion hasn't missed a step going from silent to sound. 1 This movie suffered because of the writing, it needed more suspense. 0 There were too many close ups. 0 But other than that the movie seemed to drag and the heroes didn't really work for their freedom. 0 But this movie is definitely a below average rent. 0 "You'll love it! 1 This movie is BAD. 0 So bad. 0 The film is way too long. 0 This is definitely one of the bad ones. 0 The movie I received was a great quality film for it's age. 1 John Wayne did an incredible job for being so young in the movie industry. 1 His on screen presence shined thought even though there were other senior actors on the screen with him. 1 I think that it is a must see older John Wayne film. 1 I really don't see how anyone could enjoy this movie. 0 I don't think I've ever seen a movie half as boring as this self-indulgent piece of junk. 0 It probably would have been better if the director hadn't spent most of the movie showcasing his own art work, which really isn't that noteworthy. 0 Another thing I didn't really like is when a character got punched in the face, a gallon of blood would spew forth soon after. 0 Jamie Foxx absolutely IS Ray Charles. 1 His performance is simply genius. 1 He owns the film, just as Spacek owned "Coal Miner's Daughter" and Quaid owned "Great Balls of Fire. 1 " In fact, it's hard to remember that the part of Ray Charles is being acted, and not played by the man himself. 1 Ray Charles is legendary. 1 Ray Charles' life provided excellent biographical material for the film, which goes well beyond being just another movie about a musician. 1 Hitchcock is a great director. 1 Ironically I mostly find his films a total waste of time to watch. 0 Secondly, Hitchcock pretty much perfected the thriller and chase movie. 1 It's this pandering to the audience that sabotages most of his films. 0 Hence the whole story lacks a certain energy. 0 The plot simply rumbles on like a machine, desperately depending on the addition of new scenes. 0 There are the usual Hitchcock logic flaws. 0 Mishima is extremely uninteresting. 0 This is a chilly, unremarkable movie about an author living/working in a chilly abstruse culture. 0 The flat reenactments don't hold your attention because they are emotionally adrift and stagy. 0 And the rest of it just sits there being awful... with soldiers singing songs about the masculinity they pledge themselves to, hairsplitting about purity, the admiration of swords, etc. 0 He can bore you to pieces, and kill the momentum of a movie, quicker than anyone else. 0 Schrader has made a resume full of lousy, amateurish films. 0 When I first watched this movie, in the 80s, I loved it. 1 I was totally fascinated by the music, the dancing... everything. 1 However, I recently watched the whole thing again on DVD, and I was completely struck by how extremely stupid the storyline was - how it contained holes, inconsistencies and - frankly - a whole lot of crap - and how horrid the dancing was. 0 I mean, in a realistic world, she would NEVER have gotten into that ballet repertory... The whole thing was quite pathetic. 0 The character developments also lacked in depth. 0 Woa, talk about awful. 0 Do not waste your time. 0 It was just too horrible. 0 The worst, sappiest dialogue... I could go on and on. 0 But what really made it unwatchable was the direction. 0 The poor actors. 0 You can't even tell if they have any talent because they not only have pathetic lines to speak but the director gave them no action. 0 If you check the director's filmography on this site you will see why this film didn't have a chance. 0 This would not even be good as a made for TV flick. 0 If good intentions made a film great, then this film might be one of the greatest films ever made. 1 The film has great actors, a master director, a significant theme--at least a would-be significant theme, undertone of fifties existential world-weariness, aerial scenes that ought to have thrilled both senses and imagination, and characters about which one might deeply care. 1 Regrettably, the film fails. 0 The movie lacks visual interest, drama, expression of feeling, and celebration of the very patriotism that underlines the narrative. 0 No actress has been worse used that June Allison in this movie. 0 Yet, I enjoy watching it. 1 Unfortunately, this is a bad movie that is just plain bad. 0 Bad script, bad direction and horrible acting make this one plain bad! 0 The dialogue sucked. 0 The cinematography-if it can be called that-sucked. 0 The soundtrack sucked. 0 The acting sucked. 0 The concert sequences just sucked. 0 That was nice. 1 That was funny. 1 It was so funny. 1 Overall, this movie was cheap trash. 0 But this movie is not funny, considering the ridiculousness of it. 0 I came out of it feeling angry. 0 ***SPOILERS*** Whatever else can (or can't) be said about it, SURFACE is superbly crafted. 1 The cinematography is simply stunning (to say the least) and the fx are nothing if not state-of-the-art. 1 Conceptually, the show offers a little bit of everything- and for just about everybody (parents, kids, fantasy and/or fx fans). 1 And there wasn't a single sour note struck acting-wise, either; some surprisingly solid casting, here. 1 All things considered, a job very well done. 1 Thanks good a movie like this was done and released. 1 One of the best mexican movies ever!, and one of the less understood, even by mexican themselves, no matter how identified the should have felt with it. 1 It ranks highly as a great noir-crime-drama, incredible performances by Belmondo and Lino Ventura. 1 The attention given to every character, and complex psychological portrayals, detailing loyalty, treachery, love, and hope, are tremendous. 1 It is an excellent drama, an excellent thriller, and an excellent film. 1 Up there with the best of Melville. 1 Everything about this film is simply incredible. 1 You truly take this journey through the eyes and soul of a child. 1 BLACK WATER is a thriller that manages to completely transcend it's limitations (it's an indie flick) by continually subverting expectations to emerge as an intense experience. 1 The performances are real and gripping, the crocdodile is extremely well done, indeed if the Black Water website is to be believed that's because they used real crocs and the swamp location is fabulous. 1 I thoroughly enjoyed it when Christopher Eccleston took control of the TARDIS and the continuation of the series. 1 I'm not sure what he was trying to do with this film. 0 If it was to turn my good day feeling into a night of disturbing memories than I guess he succeeded. 0 There is a lot of beautiful places. 1 It was forced, like everything in this movie. 0 Again, lame. 0 Here's where the movie really pi**ed me off. 0 And don't even get me started on the jerky camerawork. 0 When I saw it in the theater I thought I was going to be sick. 0 Summary: The witticisms weren't witty. 0 The plot - well, I said I'd let that one go. 0 The acting was bad. 0 Really bad. 0 Even Billy Bob couldn't rise above the script, which was worse. 0 Camerawork - again, bad. 0 Rating: 1 out of 10. 0 An AMAZING finale to possibly the BEST trilogy of all time! 1 Kieslowski never ceases to amaze me. 1 He is one of my favourite directors, and one of the most talented directors in the history of cinema. 1 His use of the colours of the French flag in the three films was nothing short of incredible, every shot, every scene was like a work of art. 1 Three of the most visually appealing movies i've ever seen. 1 And his subtle connections between the three films are awesome. 1 I have to mention this and it is a huge SPOILER, i loved the ending, how all the characters of the three films were the remaining survivors of the ferry disaster, with Valentine and the young judge together, and the old man watching it on her TV, solidifying his happiness over the suffering which he dealt with for those many years. 1 I couldn't think of a better way to end the film, but a smile on my face, great way to wrap up an amazing film and trilogy! 1 I recommend this for EVERYONE who loves film, movies, anything...A Work of Art! 1 10 out of 10 for both the movie and trilogy. 1 I literally vomited while watching this film. 0 I think i was one of the people who found this another one of roth's pearls. 1 his performance, as awarded, was stunning. 1 the story which was told so eloquently by Francis ford Coppola 25 years earlier, really unfolds gradually and leaves room for the characters to develop. 1 In a most wonderful location lies a story of contrast. 1 All in all a beautiful directed film from Nicola's roeg wih a sublime cast. 1 I'm translating movies for a living and this is the first movie in my 5-year working experience that I found offensive to my intelligence. 0 But when someone strives for greatness and poetry, but delivers a muddled (and often ridiculous) story, a bunch of disparate scenes, pretentious dialogue... Then you get the worst kind of a movie that some other reviewer very accurately defined as "pretentious crap". 0 To those who find this movie intelligent or even masterful, I can only say - it's your intelligence and your imagination you obviously used to try and make some sense of this pitiful attempt (it's in our human nature to try and make sense of things) . 0 One more thing: I can tolerate political incorrectness very well, I'm all for artistic freedom and suspension of disbelief, but the Slavic female character was just too much. 0 This is such a fun and funny movie. 1 Highly entertaining at all angles. 1 It features an outlandish array of memorable, psychotic but lovable nuts. 1 So for our enjoyment we get to see them run around, play games, and be dangerous. 1 It even has its sweet moments. 1 The telephone repair man was really funny and his reactions to the nuts and bitchy boss were truly genuine. 1 All the characters in this film are tremendously well played. 1 And I really did find them funny. 1 This is actually a very smart movie. 1 There is a brilliant twist ending. 1 " I love it. 1 The ending is so, SO perfect... you'll shed a tear. 1 I am so thrilled after seeing a movie like this. 1 I will never forget it now. 1 It is not just a cult... it is a cult CLASSIC. 1 Which has more depth and character than the man underneath it. 0 The Malta settings are as dry and as barren as the dialogue. 0 This movie is terrible. 0 The hockey scenes are terrible, defensemen playing like they're 5 years old, goalies diving at shots that are 10 feet wide of the net, etc. 0 For those that haven't seen it, don't waste your time! 0 To call this movie a drama is ridiculous! 0 Started watching this but didn't believe in any of the characters. 0 In particular the relationship between the bakery assistant and the waitress just didn't work for me at all. 0 It was a very superficial movie and it gave me the feeling that I was watching play rather than a film. 0 The characters were very 'stagey' and the storyline was a lot like a stage farce. 0 By the time the pyromaniac waylaid the assistant I was bored and didn't care what happened next and so I switched off. 0 Glad I didn't pay to see it. 0 Didn't laugh or even smile once. 0 But it wasn't anything at all just one big yawn... 0 It is a really good show to watch. 1 It is very educational for children 1 to 8 years old. 1 Barney is definitely super DE duper. 1 is pretty funny. 1 Babie Bop is very cute. 1 The kids are very cool too. 1 " But "Storm Trooper" is not even bad enough to make it to the list of wonderfully terrible movies. 0 It's just lame. 0 The guy who said he's had better dialogue with his potted plants has it right. 0 Everything about this movie is stupid. 0 Even if you love bad movies, do not watch this movie. 0 It is shameful. 0 I would give this television series a 10 plus if i could. 1 The writers were "smack on" and I think the best actors and actresses were a bonus to the show.These characters were so real. 1 I must say I have taped most of the episodes and i find myself watching them over and over again. 1 Now you know why I gave it a 10+! 1 I don't know exactly what it is about this movie, but we latched on to this endearing movie and it has become a special part of our family's memories. 1 I totally and absolutely recommend this movie to anyone who likes good wholesome family movies because that is exactly what this is. 1 The things that the four kids get themselves into is absolutely hilarious to watch. 1 This is one of the best movies out there that shows such strong sibling bond for each other. 1 Much more interesting, more action, more suspense, and less of the unneeded controversy. 1 Everything from acting to cinematography was solid. 1 Definitely worth checking out. 1 Damian is so talented and versatile in so many ways of writing and portraying different Characters on screen. 1 This movie has a cutting edge to it. 1 I am so pleased to know such a modern day genius is out there , letting is passion for Art drive him and taking us as an audience with him. 1 The new characters weren't all that memorable, and I found myself forgetting who was who. 0 I felt as though her going to Ireland did absolutely nothing whatsoever. 0 It didn't make me scared, horrified, or make me sympathetic towards the characters; it was simply annoying. 0 The jerky camera movements were also annoying. 0 The plot was the same as pretty much every other cheap horror. 0 There was a few pathetic attempts to give the characters some depth, but it didn't really work into the rest of the plot. 0 I guess it was supposed to be clever twist, then shed some light on the situation, but it was just stupid. 0 If you see it, you should probably just leave it on the shelf. 0 Elias Koteas,Jack Palance play good roles Angelina is hot and gets naked.Billy Drago appears in this and is cool as usual + a cameo by Sven ole Thorsen helps make this a very enjoyable movie with good acting and a decent budget. 1 This was such an awesome movie that i bought it off of Ebay. 1 I really loved the story line and the poler bear was kinda cute.But if anyone has a question about Fort Steele, just ask away:) 1 This totally UNfunny movie is so over the top and pathetic and unrealistic that throughout the whole 90 minutes of utter torture I probably looked at my watch about 70000 times! 0 Lucy Bell is so much higher than this crap and for her to sink this low is quite depressing. 0 All this movie does is make you sick watching all these slackers make excuses for their stupid actions for 90 minutes. 0 God, and I can never get that 90 minutes back! 0 I think the most wonderful parts (literally, full of "wonder") are the excerpts from his works. 1 The sets (especially designed to work with the camera) are amazing....stylized, beautiful and effective. 1 They could be used as exemplars for any set designer. 1 The stories were powerful explorations of the nature of man and of art. 1 After watching this film, I wanted to learn more about the works of this artist. 1 I highly recommend this movie for anyone interested in art, poetry, theater, politics, or Japanese history. 1 Here, in The Wind and the Lion, we see a wonderful rendering of America's own Imperial age. 1 ) What makes this story different are the terrific production values - faultless photography, composition and editing - the terrific casting - the underappreciated Brian Keith playing a bully Teddy - and vivid history. 1 Though The Wind and the Lion is told largely through the eyes of the son, every member of the family can identify with one of the characters, whether it be Sean Connery's noble brigand, Candace Bergen's feisty heroine, John Huston's wily John Hay or Steve Kanaly's spiffy, radiant, ruthless can-do lieutenant, Roosevelt's "Big Stick". 1 This is high adventure at its best. 1 I think it was Robert Ryans best film, because he portrayed someone like my father, and he was a schizophrenic in real life,(my father) although he never murdered anyone but was affected more so during the second world war which made him worse. 1 Having to humour him just to get by and get through the day was so apt. 1 (My mother and brother had to do this)When I saw Robert Ryan portraying this type of man, it was a very good imitation of this type of individual, and I was impressed. 1 Almost all of the songs in Cover Girl are old-fashioned and not very tuneful. 0 The most annoying thing about 'Cover Girl' is the way in which Rita Hayworth is put up on a pedestal. 0 Unfortunately, 'Cover Girl' is an example of how Hollywood used to exploit women for financial gain. 0 Non-linear narration thus many flashbacks and every part are articulated quite well. 1 The good cinematography also makes her and Monica Bellucci look very beautiful. 1 A good commentary of today's love and undoubtedly a film worth seeing. 1 For people who are first timers in film making, I think they did an excellent job!! 1 It was very popular when I was in the cinema, a good house and very good reactions and plenty of laughs. 1 It's a feel-good film and that's how I felt when I came out of the cinema! 1 It has northern humour and positive about the community it represents. 1 I rather enjoyed it. 1 I liked it. 1 I couldn't take them seriously. 0 It really created a unique feeling though. 1 Vivian Schilling did an excellent job with the script. 1 A world better than 95% of the garbage in the theatres today. 1 Her role was played well. 1 Not too screamy not to masculine but just right. 1 The camera really likes her in this movie. 1 I would have casted her in that role after ready the script. 1 As a European, the movie is a nice throwback to my time as a student in the 1980's and the experiences I had living abroad and interacting with other nationalities, although the circumstances were slightly different. 1 I am a fan of his ... This movie sucked really bad. 0 Even worse than Ticker! 0 & That movie was bad. 0 Only like 3 or 4 buildings used, a couple of locations MAYBE, & poor hummh! 0 It just blew. 0 This movie is excellent!Angel is beautiful and Scamp is adorable!His little yelps when hes scared,and the funniest parts are when:Scamp is caught under the curtain and when Angel and Scamp are singing 'Ive Never Had This Feeling Before'.I totally recommend this movie,its coming out on special edition on June 20.The cover has scamp on a garbage can and Angel underneath the lid. 1 I just cant explain this movie more than romantic,charming,hilarious,and adorable.The junkyard scenes are funny,all the junkyard dogs have something special.Too funny i laughed,kids will LOVE it.Buy it when it comes out,it has new features! 1 Now we were chosen to be tortured with this disgusting piece of blatant American propaganda. 0 This show is made for Americans - it is too stupid and full with hatred and clichés to be admitted elsewhere. 0 Almost everyone involved must be return to school, acting is utterly predictable and bad, script is pile of garbage all round. 0 I wish I could enter negative values, admins? 0 The sets are so bad, they wouldn't look out of place on a Thunderbirds episode. 0 The use of slow-motion needlessly repeats itself throughout the movie but is well backed up by bad acting (and bad is a kind word here), no continuity, scenes that are thrown in for no reason whatsoever, vehicles that looked like they were made from a Corn Flakes box and a directorial style that bordered on stupidity. 0 Oh yeah, and the storyline was pathetic too. 0 I hate writing bad reviews about films - especially those in which I really like the star - but this film is so bad I don't believe for one second that anyone could have been proud of it. 0 I am not a filmmaker nor am I a director but I would hide my head in the sand if I'd spent whatever amount of money and time on this movie. 0 In short - this was a monumental waste of time and energy and I would not recommend anyone to EVER see this film. 0 It came free with a DVD player I bought but I still turned the thing off halfway through because I was embarrassed for Howell. 0 1/10 - and only because there is no setting for 0/10. 0 An interesting premise, and Billy Drago is always good as a dangerous nut-bag (side note: I'd love to see Drago, Stephen McHattie and Lance Hendrikson in a flick together; talk about raging cheekbones!). 1 The soundtrack wasn't terrible, either. 1 But the acting--even that of such professionals as Drago and Debbie Rochon--was terrible, the directing worse (perhaps contributory to the former), the dialog chimp-like, and the camera work, barely tolerable. 0 Still, it was the SETS that got a big "10" on my "oy-vey" scale. 1 Yes, I am simplifying things here for the sake of brevity, for this really is at the core of the problems with this film - it has too much going on without any real, fulfilling explanation. 0 Both do good jobs and are quite amusing. 1 But the convoluted plot just didn't convince me, and much of the film was watched with a weird, questioning glance. 0 I let my girlfriend talk me into seeing this - bad idea, we both hated it. 0 The last 15 minutes of movie are also not bad as well. 1 Bela Lugosi was totally extraneous, intoning odd lines. 0 The acting was decidely wooden, though no worse than a period Universal B movie. 0 I like Armand Assante & my cable company's summary sounded interesting, so I watched it, twice already, and probably will again. 1 I believe the screenwriter did a good job of tying up the loose ends. 1 My 8/10 score is mostly for the plot. 1 I won't say any more - I don't like spoilers, so I don't want to be one, but I believe this film is worth your time. 1 Wow, what a bad film. 0 Not frightening in the least, and barely comprehensible. 0 The plot doesn't hang together at all, and the acting is absolutely appalling. 0 Not even good for camp value! 0 I wasn't expecting Oscar material, but this? 0 You'd have to have the IQ of particularly stupid mollusk not to see that one coming. 0 This film (and I use that word loosely) is an insult to the movie-going public. 0 If only someone involved with it knew how to string together narrative! 0 This gets a 1 out of 10, simply because there's nothing lower. 0 This is one I did not have, but I watched it recently on Fox Movie Channel, and was very disappointed. 0 I know he was a contract player with little control over his scripts, but the acting was as bad as the script. 0 Victor McLaglen was even bad, and Brian DonLevy was almost unrecognizable. 0 Considering the relations off screen between Taylor and Stanwyck, it was surprising how little chemistry there was on screen between the two of them. 0 But the premise of the film was so ridiculous: that the President of the U.S. 0 The death row scenes were entirely unmoving. 0 The only thing worse than Taylor's acting was Stanwyck's singing. 0 Whatever the producer was going for, he missed entirely. 0 I was deeply impressed with the character he played. 1 I knew when I saw the film that more great things were to come from this gifted actor. 1 A cheap and cheerless heist movie with poor characterisation, lots of underbite style stoic emoting (think Chow Yun Fat in A Better Tomorrow) and some cheesy clichés thrown into an abandoned factory ready for a few poorly executed flying judo rolls a la John Woo. 0 Even the squibs look awful. 0 At no point in the proceedings does it look remotely like America. 0 The plot, such as it is, is so derivative and predictable that the ending is like a mercy killing. 0 The awful dialogue and hopeless overacting by everyone who gets shot top off a real waste of space and time. 0 I was very uneasy with how bad this movie was, but not scared at all. 0 The dialogue is composed of things that make little sense. 0 About 30 minutes of footage is wasted to show mediocre elderly actors awkwardly babbling overwrought pseudo-Satanic gibberish corny enough to make a teen Goth blush, almost always in Olde English, and sometimes in Latin that may or may not be made up words. 0 The directing is sloppy at best. 0 Hackneyed writing, certainly, but made even worse by the bad directing. 0 Of course, the acting is blah. 0 The acting by the whole cast could be put on a scale and balanced perfectly between overacting and underacting. 0 And, FINALLY, after all that, we get to an ending that would've been great had it been handled by competent people and not Jerry Falwell. 0 I loved this movie it was a great portrayal of a family who had it's share of ups and down, but in the end they knew that special love they had for each other. 1 I have seen many movies starring Jaclyn Smith, but my god this was one of her best, though it came out 12 years ago. 1 This movie contained an all-star cast, and what I loved the most was that it opened my eyes to see other actors who I haven't seen before. 1 This movie was kind of long in length, but I enjoyed every minute of it. 1 Overall I rate this movie a 10 out of a 1-10 scale. 1 Lifetime does not air it enough, so if anyone knows what store sells it let me know because this is a must-have. 1 I particularly remember my senses being assaulted by strident cords of music that would blare out with very little warning, and even less meaning. 0 It is just the sort of pap that is screened in the afternoon to punish the unemployed for not having jobs. 0 Totally different, with loads of understatement and black comedy, this is a film few get to see, but those who do will remember it. 1 This movie creates its own universe, and is fascinating in every way. 1 But this movie really got to me. 1 See it. 1 I really hope the team behind this movie makes more movies, and that they will continue to do so in their own, some kinda weird style. 1 And I forgot: The Casting here i superb, with Trond Fausa Aurvåg being perfect in the role as the Bothersome Man, who doesn't understand where he is, what he is doing and why. 1 This movie is a good and humorous comment on life in 2006. 1 I found this move beautiful, enjoyable, and uplifting. 1 Initially the local sites in the film, which was filmed here in Buffalo, intrigued me. 1 Later I found myself lost in the power of the film. 1 The entire audience applauded at the conclusion of the film. 1 I left the theater with a lilt in my step, joy in my heart and hope for the human race. 1 Duris has a wholesome appearance and gives a fine performance. 1 The rest of the cast also play well. 1 Cinematography noteworthy including fine views of Barcelona and its famed Gaudi towers. 1 About ten minutes into this film I started having second thoughts. 0 About half way through this film I started to dislike it. 0 By the time the film ended, I not only disliked it, I despised it. 0 What this film lacks is a convincing script. 0 The script looks as if only a rough draft was written and shooting began before a finished script was completed. 0 Things happen, characters personalities change, plot twists occur for no real reason other than that script calls for it. 0 The cast is good. 1 For that, it's worth checking out. 1 This is probably the most irritating show I have ever seen in my entire life. 0 It is indescribably the most annoying and idiotic show I have ever seen. 0 Everything about it is just bad. 0 I could not understand, what kind of idiot would produce this mess in the first place not to mention several season. 0 The script is bad, very bad – it contains both cheesiness and unethical joke that you normally see in rated R or NC-17 movie. 0 The casting is also horrible, cause all you see is a really really BAD Actors, period. 0 Final Word: This Show is a real torture!! 0 It is zillion times away from reality. 0 Watching washing machine twirling around wouldn't hurt your eyes as much as this show. 0 Rating: 0/10 (Grade: Z) Note: The Show Is So Bad That Even Mother Of The Cast Pull Her Daughter Out Of The Show. 0 20th Century Fox's ROAD HOUSE 1948) is not only quite a silly noir but is an implausible unmitigated bore of a movie. 0 Full of unconvincing cardboard characters it is blandly written by Edward Chodorov, who also produced, and is surprisingly directed by Jean Negulesco from whom one would expect a great deal more. 0 From here on the Widmark character turns unintentionally comical! 0 His losing his marbles so early in the proceedings is totally implausible and unconvincing. 0 And if that isn't enough of a mess of a movie for you - the picture is also marred with a constant use of studio sets and indoor exteriors. 0 Whatever prompted such a documentary is beyond me! 0 (very serious spoilers) this movie was a huge disappointment. 0 there are so many problems i dont know where to start. 0 the cast was great. 1 steve martin delivers a really funny performance of a middle-aged, upper class, uptight white guy. 1 add betty white and jean smart and you have a great cast - everyone played their parts really well. 1 but the movie makes a lot of serious mistakes. 0 first of all, there are enough racial stereotypes and racial jokes to offend everyone. 0 the movie is littered with overt racial slurs towards the black cast members and in return the whites are depicted as morons and boobs. 0 putting the race card aside, lets look at the major flaw in the film: they destroy latifa's character. 0 there is no real plot. 0 i wouldnt see this movie again for free. 0 STEAMBOAT WILLIE is an amazingly important film to our cinema history. 1 This second appearance of Mickey Mouse (following the silent PLANE CRAZY earlier that year) is probably his most famous film--mostly because it was so ground-breaking. 1 While you don't yet hear Mickey speak, there are tons of sound effects and music throughout the film--something we take for granted now but which was a huge crowd pleaser in 1928. 1 However, after seeing the short again after about 25 years, I was amazed at how timeless the film actually is. 1 It's just adorable seeing Mickey playing "Turkey in the Straw" in a highly imaginative (if occasionally cruel) way. 1 Clever and a real crowd-pleaser--this film still ranks among Mickey's best films even after 80 wonderful years. 1 The bipolarity of the ruthless thug (one minute a ruthless killer, the next minute a Luv's diaper commercial) is completely unconvincing. 0 I'm terribly disappointed that this film would receive so many awards and accolades, especially when there are far more deserving works of film out there. 0 The original Body and Soul (1947) is a masterpiece. 1 John Garfield, Ann revere, Lilli Plmer, William Conrad, Canada Lee...and filmed by one of the greatest cinematographers to ever grace the screen..James Wong Howe. 1 I don't think there are any redeeming qualities in this remake. 0 This may be the only bad film he ever made. 0 So bad...well...it's just bad. 0 This movie is a solid example of a bad plot and a very, very bad idea all the way. 0 It's a shame to see good actors like Thomerson and James make a living in a mess like this. 0 I thought it was bad. 0 Both films are terrible, but to the credit of the 1986 version, it was watchable. 0 Let's start with all the problems—the acting, especially from the lead professor, was very, very bad. 0 The script is a big flawed mess. 0 The best example of how dumb the writing is when it's established that you can turn the zombie-students back into humans by removing a necklace containing a piece of the meteorite. 0 Director Paul Matthews, who also wrote/directed the weak 1995 monster movie "Grim", clearly doesn't know how to pace his films. 0 The movie is terribly boring in places. 0 The lighting is awful. 0 The film looks cheap and bland. 0 One of the most disappointing aspects is the lack of notable gore. 0 This convention never worked well in the past, and certainly doesn't work here. 0 The visual effects were AWFUL. 0 The CG opening sequence in space looked like it could have been created on Microsoft Slideshow for God's sake! 0 The "explosion" of the Gas tanks at the end was just as awful. 0 Okay, I like to consider myself a fair critic, so I'll give credit where credit's due--the creature effects were actually pretty cool. 1 Gotta love those close-ups of slimy, drooling teeth! 1 To sum the film up, "Breeders" is a terrible, cheaply made horror movie that should be avoided like the Ebola virus. 0 Not recommended. 0 He is almost unbearable to watch on screen, he has little to no charisma, and terrible comedic timing. 0 Aside from it's terrible lead, this film has loads of other debits. 0 I understand that it's supposed to be a cheap popcorn comedy, but that doesn't mean that it has to completely insult our intelligence, and have writing so incredibly hackneyed that it borders on offensive. 0 Lewis Black's considerable talent is wasted here too, as he is at his most incendiary when he is unrestrained, which the PG-13 rating certainly won't allow. 0 The film's sole bright spot was Jonah Hill (who will look almost unrecognizable to fans of the recent Superbad due to the amount of weight he lost in the interim). 1 With the originality and freshness of the first movie now spent, this remake had little else to offer. 0 The budget was evidently very limited. 0 This was reflected not only in the cast, but also in the below-par script, which borrowed much from the earlier classic. 0 However, here there was no decent acting, action or location work to balance things up. 0 Filmiing was less expansive. 0 It failed to convey the broad sweep of landscapes that were a great part of the original. 0 Generally; it just lacked imagination. 0 Not recommended. 0 Is it possible for a movie to get any worse than this? 0 There is no plot here to keep you going in the first place. 0 Even when the women finally show up, there is no sign of improvement; the most expected things happen and by the time the film is over, you might be far asleep. 0 Beware: this is not a trashy cult movie, this is trash -period! 0 I can't believe there's even a sequel to this! 0 Which is precisely why I am giving it such a bad review! 0 Being a 90's child, I truly enjoyed this show and I can proudly say that I enjoyed it big time and even more than the classical WB cartoons. 1 But "Tiny Toons" kept the 90's vibe and delivered one of the most popular, funny, and underrated cartoons ever created. 1 The memories are murky but I can only say that I enjoyed every single episode and product related to the show. 1 Easily, none other cartoon made me laugh in a tender way (before getting into dark sitcoms oriented for teenagers). 1 The characters were all funny and had the peculiarity of not having a true lead character. 1 Every single character was hilarious and deserved to be called a lead. 1 Every element of this story was so over the top, excessively phony and contrived that it was painful to sit through. 0 Her lines seem to have been WRITTEN by a fifteen year old, though they are trying oh so, so hard to sound like how a fifteen year old would really, um, you know, well... talk. 0 Perabo has a nice energy level and is obviously very comfortable in front of a camera. 1 There is simply no excuse for something this poorly done. 0 I saw this movie and I thought this is a stupid movie. 0 What is even more stupid is that who had thought an idea that there should be a volcano in Los Angeles? 0 To be honest with you, this is unbelievable nonsense and very foolish. 0 In conclusion, I will not bother with this movie because a volcano in Los Angeles is nothing but nonsense. 0 The story line is just awful! 0 It's just painful! 0 And the accents are absolutely abysmal! 0 There's also enough hypocrisy in this film to make me vomit. 0 Don't waste your time watching this rubbish non-researched film. 0 I believe that Pitch Black was done well. 1 The characters are interesting and you want to find out more about them the longer the movie goes on, and I think people will be surprised by who does and doesn't make it. 1 Go watch it! 1 Omit watching this. 0 VERY funny! 1 My rating: just 3 out of 10. 0 The characters are interesting and you really care for them. 1 An instant classic, with a great soundtrack and a catchy song during the ending credits. 1 Don't miss it. 1 This is a masterful piece of film-making, with many themes simmering and occasionally boiling over in this warts and all study of the poet's bohemian, self-indulgent wartime years that span the aerial bombardments of London and the outward tranquillity of a Welsh coastal retreat - the borderlines between friendship, lust and love, dedication to art and experience versus practical concerns, jealousy, rivalry, cowardice and egotism versus heroism and self-sacrifice and more. 1 A mature, subtle script that suggests and occasionally brings into dramatic focus the underlying tensions is well served by perfect performances (apart from the odd inappropriate smiling that Keira Knightley is prone to, though perhaps under direction this time as the other characters themselves often mention it). 1 But above all the exquisite visual composition of each moment, with inventive and elegant use of close-up, camera angle and lighting, including pointillistic faux home movie footage, is a wonder and joy to behold. 1 It's as continuously beautiful to look at as a Bertolucci, but the relationships here are more convincing and the narrative more engaging than some of that master's work. 1 The basic premise is wasted since it is sidelined by the inexplicable focus on the documentary crew. 0 Regardless, the film fails on most levels. 0 Avoid at all costs. 0 I saw this film over Christmas, and what a great film it was! 1 I thought Errol Flynn was brilliant as Custer and has since become my favourite actor! 1 His acting alongside Olivia De Havilland was brilliant and the ending was fantastic! 1 I had always known that Errol Flynn was a brilliant actor as he was my dads favourite actor, and I grew up watching his films as a child. 1 But it wasn't until I watched this film that I realised how great he actually was. 1 I'll give this film 10 out of 10! 1 I know that Jim O'Connor was very energetic and that nobody could be as much as him, but George was well dull. 0 He really didn't seem to want to be hosting; his voice-overs were monotonous, didn't get involved with the guests. 0 Lovely little thriller from Hitchcock, with lots of nice shenanigans surrounding a murdered spy, a kidnapped child, a nasty church, a foreign plot and some random taxidermists. 1 Jimmy Stewart is as ever a great hero for Hitchcock, the story rips along to its cool climax at an embassy function, but it lacks the brooding menace of Hitchcock's black and white, low-budget original. 1 Nevertheless yet another wonderful film from the great master's stable. 1 I have to say that this film was excellently produced and tops the ratings as a typical sci fi film! 1 Excellently produced by one of Sci-fi's best producers Scot Vandiver ! 1 But it is entertaining, nonetheless. 1 It's a campy sort of film that's a joy to watch. 1 There's barely a boring moment in the film and there are plenty of humorous parts. 1 The cast is always entertaining as usual. 1 Overall, a delight! 1 This movie is so mind-bendingly awful, it couldn't have even been created. 0 The film lacks any real scares or tension & some of the medical terminology used throughout is a bit iffy to say the least & I say that as an insulin dependant diabetic myself. 0 The least said about the acting the better. 0 This movie does an excellent job of revealing the complexity of the task and the incredible challenges facing South Africa. 1 I believe every one should see this movie as I think few people outside of South Africa understand its past and what is being attempted in the Truth and Reconciliation process. 1 Nothing short of magnificent photography/cinematography in this film. 1 The acting is fantastic, the stories are seamlessly woven together, and the dogs are splendid............. A must rent, view, or see. 1 Don't be afraid of subtitles........ its worth a little aversion therapy 10/10 1 Excellent performance. 1 There still are good actors around! 1 Also great directing and photography. 1 Very true to Shakespear, and a 'must' for all Shakespear fans. 1 Macbeth (Jason Connery) moved me to tears with his final monolog (out brief candle, out)He gave the sphere of moral decay and dark forces a human face, which makes it the more interesting. 1 Helen Baxendale is a very credible lady Macbeth who can be very cheerfull at times and sometimes she just looks like a naughty girl, but deadly in her taste for blood and evil. 1 If you love death and decay, and Shakespears lyrics... this is the one. 1 This is a witty and delightful adaptation of the Dr Seuss book, brilliantly animated by UPA's finest and thoroughly deserving of its Academy Award. 1 Special mention should be made of the superb music score and sound effects, which are an integral element in helping to make this such a memorable and enjoyable cartoon. 1 However Paul Schrader has indeed made a film "about" Mishima that is both superb & complex. 1 Also notable is John Bailey's fine crisp beautifully colored cinematography and the great production design & costumes by Eiko Ishioka who went on to do the memorable costumes for Coppola's Dracula for which she received a well deserved Oscar. 1 Even allowing for poor production values for the time (1971) and the format (some kind of mini-series), this is baaaaaad. 0 Unless you're just out to visually "collect" all extant films of Austen's work, you can skip this one. 0 If you do watch it, however, there are small consolations: The actresses playing Anne's sisters each do a wonderful job with their roles. 1 It is not good. 0 Speaking of the music, it is unbearably predictably and kitchy. 0 Then the film just dropped the ball. 0 This is a stunning movie. 1 Raw and sublimely moving. 1 It felt like a very gripping, intelligent stage play (but without the overly theatrical feeling one actually gets from watching people on a stage) which plays on everyone's terror of a white lie escalating to monstrous consequences. 1 All of the main players are mesmerising. 1 Tom Wilkinson broke my heart at the end... and everyone else's judging by the amount of fumbling for hankies and hands going up to faces among males and females alike. 1 Julian Fellowes has triumphed again. 1 He's a national treasure. 1 GO AND SEE IT! 1 This is an excellent film. 1 The aerial scenes were well-done. 1 It was also the right balance of war and love. 1 The film gives meaning to the phrase, "Never in the history of human conflict has so much been owed by so many to so few. 1 Kris Kristoffersen is good in this movie and really makes a difference. 1 A good film by a great director! 1 This is definitely one of the better documentaries I have seen looking at family relationships and marriage. 1 There are many continuity errors: one other user commented on different cars in the garage, Joe's glasses...the one that got to me the most was the fact Joe's facial hair configuration seemed to change from scene to scene. 0 This is just a great movie. 1 10 out of 10 stars. 1 I can't see how this movie can be an inspiration to anyone to come out or overcome fear and rejection. 0 It's so bad it's actually worth seeing just for that reason. 0 Punishment Park is a brilliant piece of cinema. 1 Shot in the Southern California desert using his patent faux documentary style, Watkins creates a film like no other. 1 This is one of Peter Watkins most accessible films. 1 I advise you to look out for it. 1 You wont regret it! 1 Highly recommended A+ 1 Well... Just if you keep thinking how bad it is. 0 It's a mediocre, miserable, hollow, laughable and predictable piece of garbage. 0 It's a case of 'so bad it is laughable'. 0 ) very bad performance plays Angela Bennett, a computer expert who is at home all the time. 0 It is a film about nothing, just a pretext to show ridiculous action scenes. 0 How awful she is! 0 But she is still a bad actress, repeating her robotic face moves in each of her pictures. 0 The results, well, are a shame. 0 DELETE this film from your mind! 0 One of the worst shows of all time. 0 The show would begin with smart ass ed comments to each other that would be totally off the wall and uncalled for. 0 The fat computer geek was unbelievable, the bible thumper, the bad-ass girl, who are these actors??? 0 Never heard of any of them except Cole who was totally unbelievable in the part. 0 Every time he opened his mouth you expect to hear, "you see kids..." Pulling the plug was a mercy killing for this horrible show. 0 The stories were as unbelievable as the actors. 0 Lame would be the best way to describe it. 0 Stanwyck and Morgan are perfectly cast in what is, in many ways, a modern equivalent of Dickens' Christmas Carol in its sensibility. 1 The success of the film depends on the casting of Sydney Greenstreet as the Alexander Yardley character. 1 The attractive set used throughout most of the film is an eye-pleasing gem. 1 Im big fan of RPG games too, but this movie, its a disgrace to any self-respecting RPGer there is. 0 The lines, the cuts, the audio, everything is wrong. 0 You can find better movies at youtube. 0 Top line: Don't waste your time and money on this one, its as bad as it comes. 0 A Lassie movie which should have been "put to sleep".... FOREVER. 0 That's how I'd describe this painfully dreary time-waster of a film. 0 So mediocre in every aspect that it just becomes a dull, uninteresting mess, this is one of the most forgettable movies I've seen. 0 It isn't even an achievement as a "so-bad-it's-good" or "so-bad-it's-memorable" movie. 0 It's an empty, hollow shell of a movie. 0 Seriously, it's not worth wasting your, or your kid's time on. 0 Avoid, avoid, avoid! 0 It will drive you barking mad! 0 The transfers are very good. 1 Very nice and relaxing late night viewing. 1 The movie is full of wonderful dancing (hence the title! 1 ) some great music, and terrific scenery. 1 It handles some tough issues with dignity and grace, and, of course, has (shocking spoiler here! 1 ) a happy, wonderful, feel good ending! 1 The point is the journey, a journey that touches every member of the family. 1 It's one of the movies I need to see whenever it comes on TV...never mind the fact that I already have it memorized! 1 Nothing new there. 0 That was done in the second movie. 0 The movie has almost no action scenes in it and very little comedy. 0 The plot has more holes than a pair of fishnet stockings and the direction and editing is astonishingly ham fisted. 0 What on earth is Irons doing in this film? 0 I just saw this film and I recommend it. 1 It has a very good plot, it holds your complete attention, the acting is superb, Tom Wilkinson was fantastic and Emily Watson was also very good. 1 A very good film indeed, about great and unconditional love. 1 Tom Wilkinson's character is a man who is not prepared for the ordeal that is about to begin, but he takes the matter in hand as the story progresses, and this great actor gives a performance that makes you feel the character's anguish and suffering. 1 Emily Watson's character is very strong, and she has only to give a quick glance and you understand everything. 1 Despite the pans of reviewers, I liked this movie. 1 In fact, I liked it better than Interview With a Vampire and I liked this Lestat (Stuart Townsend) better than Cruise's attempt. 1 Aailiyah was pretty good as Akasha, in places compelling (her first entrance and mini dance scene). 1 I'm a big fan of this series mostly due to Anne Rice's style, sensitivities and treatments. 1 I guess I liked the details of his dysfunction--he was believable. 1 The football scenes at the end were perplexing. 0 But I thought his acting was skilled. 1 Meredith M was better than all right. 1 A very charming film with wonderful sentiment and heart. 1 It is rare when a film-maker takes the time to tell a worthy moral tale with care and love that doesn't fall into the trap of being overly syrupy or over indulgent. 1 Nine out of ten for a truly lovely film. 1 This early film from future goremeister Lucio Fulci is a very good addition to the giallo sub-genre. 1 This is one of the best Italian thrillers of the early 70's. 1 A standout scene. 1 This scene is very strong and unpleasant. 0 Technically, the film is well made with impressive camera-work, solid acting and effective music from Riz Ortolani – particularly good is a recurring unaccompanied female vocal that sounds like it's coming from a distant hill. 1 It's still wild stuff though and is highly recommended to fans of giallo cinema. 1 The movie was very interesting from beginning to the end. 1 I liked the way Dustin Hoffman's character was ready to do just about everything to stay with his son. 1 This movie is also revealing. 1 Personally, I think it shows that people should learn to find a compromise them self without involving other people into issue. 1 And it was boring. 0 I am so tired of clichés that is just lazy writing, and here they come in thick and fast. 0 PS the only scene in the movie that was cool is when the central character finds her room blown up. 1 It's a fresh, subtle, and rather sublime effect. 1 An Italian reviewer called this "a small, great film," and that's right. 1 All the actors give a wonderful performance, especially Jennifer Rubin as Jamie Harris, who changes from the nervous starlet in the beginning through the strange events she is part of to the cool star. 1 You learn a lot about the real inside emotions of people in this movie, and a lot about the movie business itself. 1 The movie in movie situations in the beginning and through the game that is played with her by the "acting coach" are fascinating. 1 Also the music by Mark Snow is possibly the best score I've ever heard. 1 You won't forget this movie! 1 Why was this film made? 0 The film has an ultra-cheap look to it. 0 The result is a film that just don't look right. 0 None of them are engaging or exciting. 0 The plot is nonsense that doesn't interest in the slightest way or have any uniqueness to it. 0 The Foreigner is not worth one second of your time. 0 I saw it as a child on TV back in 1973, when it was "The Stranger" and I loved it. 1 But the duet between the astronaut and his doctor at the beginning of the movie is a perfect exchange if one considers that this movie was made well into the Cold War and the astronaut's biggest fear is that he has crashed in the USSR. 1 This movie is so awesome! 1 I loved it, it was really scary. 1 I love the Scream movies and all horror movies and this one ranks way up there. 1 If you want a real scare rent this one! 1 10/10 1 This is an extraordinary film. 1 As a courtroom drama, it's compelling, as an indictment on the American justice system, it's frightening. 1 This film highlights the fundamental flaws of the legal process, that it's not about discovering guilt or innocence, but rather, is about who presents better in court. 1 The film is well paced, understated and one of the best courtroom documentaries I've seen. 1 This mostly routine fact-based TV drama gets a boost from the fine performance by Cole. 1 Predictable, but not a bad watch. 1 It was clear that she had the range and ability to pull off this part. 1 She carries the movie well. 1 Constantine gives everything the right intensity and seems to have a good understanding of the underlying psychological motivations. 1 It is wonderful and inspiring to watch, and I hope that it gets released again on to video or DVD. 1 How this piece of trash was ever released is beyond me: the acting, the story, the characters, the supposedly special effects, etc...it's ALL wrong. 0 In fact, this stinker smells like a direct-to-video release. 0 Avoid at ALL costs! 0 Star Trek V The final Frontier is the worst in the series. 0 The acting from all involved and that includes those like Shatner and Nimoy is bad and washed out and making them seem as old as they look in real life, the special effects are tacky like when Spock has to rescue Kirk on a jet pack when he falls down from a mountain. 0 The attempts at humor were pitiful and story is so awful it dosen't bear thinking about which basically involves a Vulcan stealing the Enterprise to find god (seriously) I just didn't care about any of this film and oh not to mention Uhura does a belly dance to distract male guards. 0 The only place good for this film is in the garbage. 0 The worst one of the series. 0 Editing: The editing of this film was phenomenal in my opinion. 1 When a song could explain the emotions of the subjects better, such as when Jay Adams' unfortunate life was a subject of talk, the song Old Man by Neil Young was played, which evokes many emotions. 1 Cinematography: The film was shot in an interesting way. 1 Of course the footage from the 70s was grainy, but that only enhanced the film. 1 This film offers many delights and surprises. 1 When Achille and Philippa beautifully sing a duet from "Don Giovanni" that perfectly describes their situation in the movie, you appreciate the subtle layers of this excellent film. 1 The story unfolds in 18th century Jutland and the use of period music played on period instruments is just one more fine touch. 1 You share General Loewenhielm's exquisite joy in his partaking of the Cailles en Sarcophage even though you are just watching a movie - but you do wish for just a small sample to savor. 1 But this understated film leaves a lasting impression. 1 The warmth it generates is in contrast to its austere backdrop. 1 You will leave the theater wanting to go out and dance under the stars. 1 The acting, as you'd expect from this cast, is top notch. 1 The characters are fleshed out surprisingly well, particularly Grimes and Blake, and all the actors deliver their sharply scripted lines with just the right amount of deadpan tongue in cheek to make the dialogue both hilarious and realistic. 1 Angus Scrimm also turns in a good performance in a somewhat brief but memorable role as the gently menacing, violin-playing anatomist Doctor Quinn. 1 Conclusion - I loved it. 1 It's a long time since I was so entertained by a movie. 1 I struggle to find anything bad to say about it. 1 Mark my words, this is one of those cult films like Evil Dead 2 or Phantasm that people will still be discovering and falling in love with 20, 30, 40 years down the line. 1 It's pretty surprising that this wonderful film was made in 1949, as Hollywood generally had its collective heads in the sand concerning black and white issues at that time. 1 The film deserves strong kudos for taking this stand, for having exceptional acting from its mostly lesser-known cast and for the super-intelligent script that doesn't insult the audience or take the easy way out when it comes to white racism. 1 Plus, with the movie's rather modest budget and fast running time, it does an amazing job! 1 Juano Hernandez (an exceptional actor who played supporting roles in many films of the era) is a proud black man who is accused of murdering a white man in the South. 1 Trumbull on I LOVE LUCY). 1 See it with your kids if you have a chance--it will open up some amazing dialog about how far race relations have come in the last 50 years. 1 See both films if you can. 1 It was that year, however, that reminded us that Huston was still at the top of his game as evinced by his faithful adaptation of James Joyce's acclaimed novella "The Dead. 1 Feelings, thoughts...Gabriel's discomfort during the dance...all these intangibles leap to life and come within the viewer's grasp in Huston's portrayal. 1 Very disappointed and wondered how it could be in the Oscar shortlist. 0 It's very slow. 0 Lot of holes in the plot: there's nothing about how he became the emperor; nothing about where he spend 20 years between his childhood and mature age. 0 ) Don't waste your time. 0 End of Days is one of the worst big-budget action movies I've ever seen. 0 He surely doesn't know how to make a coherent action movie from the screenwriter of Air Force One who was only obliged to write the script just for a big sum of money. 0 This was one of the worst films i have ever seen. 0 I'm still trying to get over how bad it was. 0 This movie is possibly one of the most creative works of horror ever. 1 It has everything you could want... suspense, drama, comedy, confusing subplots, native americans, brain eating... If you're looking for the be-all, end-all of brainsucking movies, look no further. 1 " With great sound effects, and impressive special effects, I can't recommend this movie enough. 1 Call me a nut, but I think this is one of the best movies ever. 1 Great character actors Telly Savalas and Peter Boyle. 1 1 hour 54 minutes of sheer tedium, melodrama and horrible acting, a mess of a script, and a sinking feeling of GOOD LORD, WHAT WERE THEY THINKING? 0 Lots of holes in the script. 0 It's like a bad two hour TV movie. 0 Now imagine that every single one of those decisions was made wrong. 0 The dialogue is atrocious. 0 The acting is beyond abysmal. 0 Everything stinks. 0 Trouble is, the writing and directing make it impossible to establish those things that make a movie watchable, like character, story, theme and so on. 0 Worse, there's an incredibly weak sub-plot thrown in that follows a little band of latter-day Mansonites as they go after a reporter who's working on a story on the anniversary of the killings. 0 It's dumb and pointless, and a complete waste of time. 0 In short, don't bother with this movie. 0 I won't spoil it, but the ending in pretty amazing. 1 The best scene in the movie is at the end, but I won't spoil it. 1 If there was ever an indication of a writer and a director's ability to meld two highly volatile temperaments into a seamless union of creativity, then this is it! 1 The result is a powerhouse achievement, made more timely now perhaps because of our culture's disturbing fascination with celebrity, and it's distorted interpretations of fame. 1 A film not easily forgotten. 1 But, Kevin Spacey is an excellent, verbal tsunami as Buddy Ackerman – and totally believable because he is a great actor. 1 The scripting of the subtle comedy is unmatched by any movie in recent years. 1 The characters are interesting, even if a bit predictable. 1 Highly recommended for all ages, although the younger set will probably not appreciate some of the more subtle references, they will certainly appreciate one galley scene in particular! 1 Great movie! 1 Also the story and acting were weak. 0 At around 4 pm I bought it, at around 8pm I started to watch, at around 8.15pm I fast forwarded the remaining film to see if there was anything left watchable for a human being with a brain... but there wasn't. 0 Either way, it sucks. 0 The script is horrendously stupid. 0 The story starts too fast with absolutely no suspense or build-up in the slightest. 0 Everything Captain Howdy says is either laughable or just plain stupid. 0 What the hell kind of crap is that?! 0 Then, there's the plot holes. 0 You could drive a semi truck into these holes! 0 Linda Cardellini is the only thing good in this film. 1 She's poised and amazing. 1 Dee Snider just plain sucks. 0 He can't act (one of the least scary villains I have ever seen), he can't write (did he write this damn movie in his sleep? 0 I was bored throughout the whole damn thing. 0 The acting sucks, the music sucks, the script sucks, the pacing sucks, the special FX suck, the directing sucks... basically, this movie sucks. 0 This film tries to be a serious and sophisticated thriller/horror flick and it fails miserably. 0 This is probably one of the least effective and utterly unoriginal films I have ever seen in my entire life. 0 A piece of cinematic garbage captured on celluloid. 0 Avoid at any and all costs. 0 At any rate this film stinks, its not funny, and Fulci should have stayed with giallo and supernatural zombie movies. 0 Avoid this film at all costs. 0 I don't know what happened in Season Five, what a mess. 0 The only consistent thread holding the series together were the amazing performances of Leni Parker and Anita LaSelva as the two Taelons in quiet idealogical conflict. 0 Now this is a movie I really dislike. 0 It's one of the most boring Horror movies from the 90's mainly because it starts slow and centers in a boring atmosphere. 0 The puppets look really cheesy , not in a good way like in the Puppet Master 80's flicks. 0 The story is lame, not interesting and NEVER really explains the sinister origins of the puppets. 0 There aren't death scenes like in previous movies and the f/x are terrible. 0 I felt asleep the first time I watched it, so I can recommend it for insomniacs. 0 The fact is, this film is a wonderful, heartwarming tale about two people chasing their dreams. 1 The best part about "Nurse Betty" is it's unpredictability. 1 Director Neil LaBute uses brutal violence to seperate dreams from reality, and along with the touching drama, and hilarious comedy, you can never tell what is going to happen next. 1 Otherwise, don't even waste your time on this. 0 This one just fails to create any real suspense. 0 As for the killer, don't expect anything original or even remotely frightening. 0 There is, however, some pretty good acting (at least, for this type of film). 1 I'm so sorry but I really can't recommend it to anyone. 0 One of the most boring,pointless movies I have ever seen. 0 The secondary plot line is incomprehensible and its relation to the primary plot line is mystifying. 0 Hated it. 0 This is one of the worst Sandra Bullock movie since Speed 2 But not quite that bad. 0 I don't understand how this garbage got on the shelves of the movie store, it's not even a real movie! 0 I highly doubt that anyone could ever like this trash. 0 This is not movie-making. 0 The acting is like watching wooden puppets moving around and reading from a book, that's how bad it is. 0 So I am here to warn you--DO NOT RENT THIS MOVIE, it is the dumbest thing you have never seen! 0 I saw this short film on HBO the other day and absolutely loved it. 1 I didn't realize how wonderful the short really is until the last two scenes. 1 Excellent short film. 1 Hopefully, the director James Cox can turn the short into a feature length film with the same cast, or win us over with a whole new film. 1 I agree with Jessica, this movie is pretty bad. 0 Characters are one-dimensional, even the good guys and especially the bad guys. 0 The story line is totally predictable. 0 Not much dialogue, not much music, the whole film was shot as elaborately and aesthetically like a sculpture. 1 I've seen soap operas more intelligent than this movie. 0 Bad characters, bad story and bad acting. 0 Really awful. 0 Not easy to watch. 0 Funny, clever, hip - just like Pray's previous film, Hype! 1 It was a long time that i didn't see a so charismatic actor on screen. 1 Paolo Sorrentino has written a wonderful story about loneliness and Tony has built one of the most unforgettable characters seen in movies in recent years. 1 The movie is not completely perfect but 'Titta Di Girolamo' will stay with you for a long time after the vision of the movie. 1 I rate this movie 9/10. 1 I do not know if this was Emilio Estevez's directorial debut, but the pacing, the interplay and development of the characters as well as some clever camera work surrounding the character Estevez plays all suggest a natural eye. 1 The interplay between Martin and Emilio contains the same wonderful chemistry we saw in Wall Street with Martin and Charlie. 1 Kathy Bates is wonderful in her characters subtle desperation and escapism; a variation on her character in "At Play In The Fields Of The Lord". 1 For readers who have already seen one of Miyazaki's films: he is still in top form and made another worthwhile experience. 1 It never condescends, all the characters have good genuine hearts and believable problems. 1 The two main characters may be two of the most believable children I ever saw put on screen. 1 They are so easy to love, but even more easy to identify with. 1 This movie is great--especially if you enjoy visual arts. 1 The scenery that the two daughters paint and photograph are beautiful. 1 The story is also both funny and poignant at times. 1 People who like European films and "art movies" will like this movie. 1 This is truly an art movie--it actually has a lot of art in it. 1 Go rent it. 1 However, after finally watching this film, I realized that not only had I had a closed mind to the brilliance it depicts, I also found myself watching it over and over again. 1 It's the one movie that never ceases to interest me, simply because it keeps me alert, as I try to attempt to decipher it's meanings. 1 Brilliance indeed. 1 But if you liked movies like The Matrix (and better yet, their sequels) I think you'll appreciate the thought provoking, mindblowing experience this film will give you. 1 Think of the film being like a dream. 1 Simply beautiful. 1 Both Rickman and Stowe play their roles to the hilt in this tale of a childrens' book writer who-- maybe?-- has written a subversive tract. 1 It's a gloriously fun, fast paced and fairly accurate portrayal of the night of a raver. 1 It presents a idyllic yet serious portrayal of the ups and downs of the characters lives. 1 Just whatever you do, avoid "Groove" as its the antithesis of all that is good about Human Traffic. 0 It's too bad that everyone else involved didn't share Crowe's level of dedication to quality, for if they did, we'd have a far better film on our hands than this sub-par mess. 0 The movie seemed a little slow at first. 0 But it picked up speed and got right to the point. 1 It showed exactly how the government and the scientist argued for humanity and the reasons of the "gadget". 1 I enjoyed it. 1 I have recommended it to friends. 1 I was particularly pleased with the acting ability of Dwight Schultz. 1 Both actors truly understand and become their particular character, delivering a convincing, sincere performance. 1 Their on-screen chemistry, critical to the entire film, is genuine. 1 The film's dialogue is natural, real to life. 1 The writer, Gorman Bechard, undoubtedly did his homework because all references are industry and character-age appropriate. 1 The incredible soundtrack truly captures the essence of the film. 1 Each track commands sentiment, actually contributing to the scenes and characters. 1 Definitely worth seeing… it's the sort of thought provoking film that forces you to question your own threshold of loneliness. 1 Hayao Miyazaki's latest and eighth film for Studio Ghibili, "Gake No Ue No Ponyo" (Ponyo on the Cliff by the Sea) is a wonderfully fun and imaginative look at childhood. 1 At a time when it seems that film animation has been dominated by Disney/Pixar's CGI masterpieces, it is both refreshing and comforting to know that Miyazaki is still relying on traditional hand-drawn animation to tell his charming and enchanting stories. 1 Enough can not be said of the remarkable animation in this film. 1 The art style has the appearance of crayon/pencil drawings and is wonderfully colorful and fanciful. 1 If you act in such a film, you should be glad that you're gonna drift away from earth as far as possible! 0 This one wants to surf on the small wave of space movies in 1998 (Deep Impact and Armageddon), and this one fails everywhere. 0 If you haven't choked in your own vomit by the end (by all the cheap drama and worthless dialogue) you've must have bored yourself to death with this waste of time. 0 Still, it makes up for all of this with a super ending that depicts a great sea vessel being taken out by the mighty frost. 1 Just consider the excellent story, solid acting and look of the film as added bonuses. 1 Instead, we got a bore fest about a whiny, spoiled brat babysitting. 0 Then I watched it again two Sundays ago (March 20th, 2005) and I began to really enjoy it and this time I taped the entire thing. 1 It is a very well acted and done TV Movie. 1 Judith Light is one of my favorite actresses and I think she does a superb job in this film! 1 I keep watching it over and over. 1 It's a sad movie, but very good. 1 If you have not seen this movie, I definitely recommend it! 1 She is as lovely as usual, this cutie! 1 Still it's quite interesting and entertaining to follow. 1 ;) Recommend with confidence! 1 This movie is well-balanced with comedy and drama and I thoroughly enjoyed myself. 1 It was a riot to see Hugo Weaving play a sex-obsessed gay real estate salesman who uses his clients' houses for his trysts with the flaming Darren (Tom Hollander). 1 :) Anyway, the plot flowed smoothly and the male-bonding scenes were a hoot. 1 The opening sequence of this gem is a classic, and the cat n mouse games that follow are a delight to watch. 1 Fans of the genre will be in heaven. 1 Lange had become a great actress. 1 It looked like a wonderful story. 1 I never walked out of a movie faster. 0 I just got bored watching Jessice Lange take her clothes off! 0 Unfortunately, any virtue in this film's production work was lost on a regrettable script. 0 In a word, it is embarrassing. 0 Exceptionally bad! 0 All in all its an insult to one's intelligence and a huge waste of money. 0 ================================================ FILE: machine-learning/ML - Getting Started - Sentiment Analysis.workbook/sentiment-yelp-test.txt ================================================ Wow... Loved this place. 1 Crust is not good. 0 Not tasty and the texture was just nasty. 0 Stopped by during the late May bank holiday off Rick Steve recommendation and loved it. 1 The selection on the menu was great and so were the prices. 1 Now I am getting angry and I want my damn pho. 0 Honeslty it didn't taste THAT fresh.) 0 The potatoes were like rubber and you could tell they had been made up ahead of time being kept under a warmer. 0 The fries were great too. 1 A great touch. 1 Service was very prompt. 1 Would not go back. 0 The cashier had no care what so ever on what I had to say it still ended up being wayyy overpriced. 0 I tried the Cape Cod ravoli, chicken,with cranberry...mmmm! 1 I was disgusted because I was pretty sure that was human hair. 0 I was shocked because no signs indicate cash only. 0 Highly recommended. 1 Waitress was a little slow in service. 0 This place is not worth your time, let alone Vegas. 0 did not like at all. 0 The Burrittos Blah! 0 The food, amazing. 1 Service is also cute. 1 I could care less... The interior is just beautiful. 1 So they performed. 1 That's right....the red velvet cake.....ohhh this stuff is so good. 1 - They never brought a salad we asked for. 0 This hole in the wall has great Mexican street tacos, and friendly staff. 1 Took an hour to get our food only 4 tables in restaurant my food was Luke warm, Our sever was running around like he was totally overwhelmed. 0 The worst was the salmon sashimi. 0 Also there are combos like a burger, fries, and beer for 23 which is a decent deal. 1 This was like the final blow! 0 I found this place by accident and I could not be happier. 1 seems like a good quick place to grab a bite of some familiar pub food, but do yourself a favor and look elsewhere. 0 Overall, I like this place a lot. 1 The only redeeming quality of the restaurant was that it was very inexpensive. 1 Ample portions and good prices. 1 Poor service, the waiter made me feel like I was stupid every time he came to the table. 0 My first visit to Hiro was a delight! 1 Service sucks. 0 The shrimp tender and moist. 1 There is not a deal good enough that would drag me into that establishment again. 0 Hard to judge whether these sides were good because we were grossed out by the melted styrofoam and didn't want to eat it for fear of getting sick. 0 On a positive note, our server was very attentive and provided great service. 1 Frozen pucks of disgust, with some of the worst people behind the register. 0 The only thing I did like was the prime rib and dessert section. 1 It's too bad the food is so damn generic. 0 The burger is good beef, cooked just right. 1 If you want a sandwich just go to any Firehouse!!!!! 1 My side Greek salad with the Greek dressing was so tasty, and the pita and hummus was very refreshing. 1 We ordered the duck rare and it was pink and tender on the inside with a nice char on the outside. 1 He came running after us when he realized my husband had left his sunglasses on the table. 1 Their chow mein is so good! 1 They have horrible attitudes towards customers, and talk down to each one when customers don't enjoy their food. 0 The portion was huge! 1 Loved it...friendly servers, great food, wonderful and imaginative menu. 1 The Heart Attack Grill in downtown Vegas is an absolutely flat-lined excuse for a restaurant. 0 Not much seafood and like 5 strings of pasta at the bottom. 0 The salad had just the right amount of sauce to not over power the scallop, which was perfectly cooked. 1 The ripped banana was not only ripped, but petrified and tasteless. 0 At least think to refill my water before I struggle to wave you over for 10 minutes. 0 This place receives stars for their APPETIZERS!!! 1 The cocktails are all handmade and delicious. 1 We'd definitely go back here again. 1 We are so glad we found this place. 1 Great food and service, huge portions and they give a military discount. 1 Always a great time at Dos Gringos! 1 Update.....went back for a second time and it was still just as amazing 1 We got the food and apparently they have never heard of salt and the batter on the fish was chewy. 0 A great way to finish a great. 1 The deal included 5 tastings and 2 drinks, and Jeff went above and beyond what we expected. 1 - Really, really good rice, all the time. 1 The service was meh. 0 It took over 30 min to get their milkshake, which was nothing more than chocolate milk. 0 I guess I should have known that this place would suck, because it is inside of the Excalibur, but I didn't use my common sense. 0 The scallop dish is quite appalling for value as well. 0 2 times - Very Bad Customer Service ! 0 The sweet potato fries were very good and seasoned well. 1 Today is the second time I've been to their lunch buffet and it was pretty good. 1 There is so much good food in Vegas that I feel cheated for wasting an eating opportunity by going to Rice and Company. 0 Coming here is like experiencing an underwhelming relationship where both parties can't wait for the other person to ask to break up. 0 walked in and the place smelled like an old grease trap and only 2 others there eating. 0 The turkey and roast beef were bland. 0 This place has it! 1 The pan cakes everyone are raving about taste like a sugary disaster tailored to the palate of a six year old. 0 I love the Pho and the spring rolls oh so yummy you have to try. 1 The poor batter to meat ratio made the chicken tenders very unsatisfying. 0 All I have to say is the food was amazing!!! 1 Omelets are to die for! 1 Everything was fresh and delicious! 1 In summary, this was a largely disappointing dining experience. 0 It's like a really sexy party in your mouth, where you're outrageously flirting with the hottest person at the party. 1 Never been to Hard Rock Casino before, WILL NEVER EVER STEP FORWARD IN IT AGAIN! 0 Best breakfast buffet!!! 1 say bye bye to your tip lady! 0 We'll never go again. 0 Will be back again! 1 Food arrived quickly! 1 It was not good. 0 On the up side, their cafe serves really good food. 1 Our server was fantastic and when he found out the wife loves roasted garlic and bone marrow, he added extra to our meal and another marrow to go! 1 The only good thing was our waiter, he was very helpful and kept the bloddy mary's coming. 1 Best Buffet in town, for the price you cannot beat it. 1 I LOVED their mussels cooked in this wine reduction, the duck was tender, and their potato dishes were delicious. 1 This is one of the better buffets that I have been to. 1 So we went to Tigerlilly and had a fantastic afternoon! 1 The food was delicious, our bartender was attentive and personable AND we got a great deal! 1 The ambience is wonderful and there is music playing. 1 Will go back next trip out. 1 Sooooo good!! 1 REAL sushi lovers, let's be honest - Yama is not that good. 0 At least 40min passed in between us ordering and the food arriving, and it wasn't that busy. 0 This is a really fantastic Thai restaurant which is definitely worth a visit. 1 Nice, spicy and tender. 1 Good prices. 1 Check it out. 1 It was pretty gross! 0 I've had better atmosphere. 0 Kind of hard to mess up a steak but they did. 0 Although I very much liked the look and sound of this place, the actual experience was a bit disappointing. 0 I just don't know how this place managed to served the blandest food I have ever eaten when they are preparing Indian cuisine. 0 Worst service to boot, but that is the least of their worries. 0 Service was fine and the waitress was friendly. 1 The guys all had steaks, and our steak loving son who has had steak at the best and worst places said it was the best steak he's ever eaten. 1 We thought you'd have to venture further away to get good sushi, but this place really hit the spot that night. 1 Host staff were, for lack of a better word, BITCHES! 0 Bland... Not a liking this place for a number of reasons and I don't want to waste time on bad reviewing.. I'll leave it at that... 0 Phenomenal food, service and ambiance. 1 I wouldn't return. 0 Definitely worth venturing off the strip for the pork belly, will return next time I'm in Vegas. 1 This place is way too overpriced for mediocre food. 0 Penne vodka excellent! 1 They have a good selection of food including a massive meatloaf sandwich, a crispy chicken wrap, a delish tuna melt and some tasty burgers. 1 The management is rude. 0 Delicious NYC bagels, good selections of cream cheese, real Lox with capers even. 1 Great Subway, in fact it's so good when you come here every other Subway will not meet your expectations. 1 I had a seriously solid breakfast here. 1 This is one of the best bars with food in Vegas. 1 He was extremely rude and really, there are so many other restaurants I would love to dine at during a weekend in Vegas. 0 My drink was never empty and he made some really great menu suggestions. 1 Don't do it!!!! 0 The waiter wasn't helpful or friendly and rarely checked on us. 0 My husband and I ate lunch here and were very disappointed with the food and service. 0 And the red curry had so much bamboo shoots and wasn't very tasty to me. 0 Nice blanket of moz over top but i feel like this was done to cover up the subpar food. 1 The bathrooms are clean and the place itself is well decorated. 1 The menu is always changing, food quality is going down & service is extremely slow. 0 The service was a little slow , considering that were served by 3 people servers so the food was coming in a slow pace. 0 I give it 2 thumbs down 0 We watched our waiter pay a lot more attention to other tables and ignore us. 0 My fiancé and I came in the middle of the day and we were greeted and seated right away. 1 This is a great restaurant at the Mandalay Bay. 1 We waited for forty five minutes in vain. 0 Crostini that came with the salad was stale. 0 Some highlights : Great quality nigiri here! 1 the staff is friendly and the joint is always clean. 1 this was a different cut than the piece the other day but still wonderful and tender s well as well flavored. 1 I ordered the Voodoo pasta and it was the first time I'd had really excellent pasta since going gluten free several years ago. 1 this place is good. 1 Unfortunately, we must have hit the bakery on leftover day because everything we ordered was STALE. 0 I came back today since they relocated and still not impressed. 0 I was seated immediately. 1 Their menu is diverse, and reasonably priced. 1 Avoid at all cost! 0 Restaurant is always full but never a wait. 1 DELICIOUS!! 1 This place is hands-down one of the best places to eat in the Phoenix metro area. 1 So don't go there if you are looking for good food... 0 I've never been treated so bad. 0 Bacon is hella salty. 1 We also ordered the spinach and avocado salad; the ingredients were sad and the dressing literally had zero taste. 0 This really is how Vegas fine dining used to be, right down to the menus handed to the ladies that have no prices listed. 1 The waitresses are very friendly. 1 Lordy, the Khao Soi is a dish that is not to be missed for curry lovers! 1 Everything on the menu is terrific and we were also thrilled that they made amazing accommodations for our vegetarian daughter. 1 Perhaps I caught them on an off night judging by the other reviews, but I'm not inspired to go back. 0 The service here leaves a lot to be desired. 0 The atmosphere is modern and hip, while maintaining a touch of coziness. 1 Not a weekly haunt, but definitely a place to come back to every once in a while. 1 We literally sat there for 20 minutes with no one asking to take our order. 0 The burger had absolutely no flavor - the meat itself was totally bland, the burger was overcooked and there was no charcoal flavor. 0 I also decided not to send it back because our waitress looked like she was on the verge of having a heart attack. 0 I dressed up to be treated so rudely! 0 It was probably dirt. 0 Love this place, hits the spot when I want something healthy but not lacking in quantity or flavor. 1 I ordered the Lemon raspberry ice cocktail which was also incredible. 1 The food sucked, which we expected but it sucked more than we could have imagined. 0 Interesting decor. 1 What I really like there is the crepe station. 1 Also were served hot bread and butter, and home made potato chips with bacon bits on top....very original and very good. 1 you can watch them preparing the delicious food!) 1 Both of the egg rolls were fantastic. 1 When my order arrived, one of the gyros was missing. 0 I had a salad with the wings, and some ice cream for dessert and left feeling quite satisfied. 1 I'm not really sure how Joey's was voted best hot dog in the Valley by readers of Phoenix Magazine. 0 The best place to go for a tasty bowl of Pho! 1 The live music on Fridays totally blows. 0 I've never been more insulted or felt disrespected. 0 Very friendly staff. 1 It is worth the drive. 1 I had heard good things about this place, but it exceeding every hope I could have dreamed of. 1 Food was great and so was the serivce! 1 The warm beer didn't help. 0 Great brunch spot. 1 Service is friendly and inviting. 1 Very good lunch spot. 1 I've lived here since 1979 and this was the first (and last) time I've stepped foot into this place. 0 The WORST EXPERIENCE EVER. 0 Must have been an off night at this place. 0 The sides are delish - mixed mushrooms, yukon gold puree, white corn - beateous. 1 If that bug never showed up I would have given a 4 for sure, but on the other side of the wall where this bug was climbing was the kitchen. 0 For about 10 minutes, we we're waiting for her salad when we realized that it wasn't coming any time soon. 0 My friend loved the salmon tartar. 1 Won't go back. 0 Extremely Tasty! 1 Waitress was good though! 1 Soggy and not good. 0 The Jamaican mojitos are delicious. 1 Which are small and not worth the price. 0 - the food is rich so order accordingly. 1 The shower area is outside so you can only rinse, not take a full shower, unless you don't mind being nude for everyone to see! 0 The service was a bit lacking. 0 Lobster Bisque, Bussell Sprouts, Risotto, Filet ALL needed salt and pepper..and of course there is none at the tables. 0 Hopefully this bodes for them going out of business and someone who can cook can come in. 0 It was either too cold, not enough flavor or just bad. 0 I loved the bacon wrapped dates. 1 This is an unbelievable BARGAIN! 1 The folks at Otto always make us feel so welcome and special. 1 As for the "mains," also uninspired. 0 This is the place where I first had pho and it was amazing!! 1 This wonderful experience made this place a must-stop whenever we are in town again. 1 If the food isn't bad enough for you, then enjoy dealing with the world's worst/annoying drunk people. 0 Very very fun chef. 1 Ordered a double cheeseburger & got a single patty that was falling apart (picture uploaded) Yeah, still sucks. 0 Great place to have a couple drinks and watch any and all sporting events as the walls are covered with TV's. 1 If it were possible to give them zero stars, they'd have it. 0 The descriptions said "yum yum sauce" and another said "eel sauce", yet another said "spicy mayo"...well NONE of the rolls had sauces on them. 0 I'd say that would be the hardest decision... Honestly, all of M's dishes taste how they are supposed to taste (amazing). 1 If she had not rolled the eyes we may have stayed... Not sure if we will go back and try it again. 0 Everyone is very attentive, providing excellent customer service. 1 Horrible - don't waste your time and money. 0 Now this dish was quite flavourful. 1 By this time our side of the restaurant was almost empty so there was no excuse. 0 (It wasn't busy either) Also, the building was FREEZING cold. 0 like the other reviewer said "you couldn't pay me to eat at this place again." 0 -Drinks took close to 30 minutes to come out at one point. 0 Seriously flavorful delights, folks. 1 Much better than the other AYCE sushi place I went to in Vegas. 1 The lighting is just dark enough to set the mood. 1 Based on the sub-par service I received and no effort to show their gratitude for my business I won't be going back. 0 Owner's are really great people.! 1 There is nothing privileged about working/eating there. 0 The Greek dressing was very creamy and flavorful. 1 Overall, I don't think that I would take my parents to this place again because they made most of the similar complaints that I silently felt too. 0 Now the pizza itself was good the peanut sauce was very tasty. 1 We had 7 at our table and the service was pretty fast. 1 Fantastic service here. 1 I as well would've given godfathers zero stars if possible. 0 They know how to make them here. 1 very tough and very short on flavor! 0 I hope this place sticks around. 1 I have been in more than a few bars in Vegas, and do not ever recall being charged for tap water. 0 The restaurant atmosphere was exquisite. 1 Good service, very clean, and inexpensive, to boot! 1 The seafood was fresh and generous in portion. 1 Plus, it's only 8 bucks. 1 The service was not up to par, either. 0 Thus far, have only visited twice and the food was absolutely delicious each time. 1 Just as good as when I had it more than a year ago! 1 For a self proclaimed coffee cafe, I was wildly disappointed. 0 The Veggitarian platter is out of this world! 1 You cant go wrong with any of the food here. 1 You can't beat that. 1 Stopped by this place while in Madison for the Ironman, very friendly, kind staff. 1 The chefs were friendly and did a good job. 1 I've had better, not only from dedicated boba tea spots, but even from Jenni Pho. 0 I liked the patio and the service was outstanding. 1 The goat taco didn't skimp on the meat and wow what FLAVOR! 1 I think not again 0 I had the mac salad and it was pretty bland so I will not be getting that again. 0 I went to Bachi Burger on a friend's recommendation and was not disappointed. 1 Service stinks here! 0 I waited and waited. 0 This place is not quality sushi, it is not a quality restaurant. 0 I would definitely recommend the wings as well as the pizza. 1 Great Pizza and Salads! 1 Things that went wrong: - They burned the saganaki. 0 We waited an hour for what was a breakfast I could have done 100 times better at home. 0 This place is amazing! 1 I hate to disagree with my fellow Yelpers, but my husband and I were so disappointed with this place. 0 Waited 2 hours & never got either of our pizzas as many other around us who came in later did! 0 Just don't know why they were so slow. 0 The staff is great, the food is delish, and they have an incredible beer selection. 1 I live in the neighborhood so I am disappointed I won't be back here, because it is a convenient location. 0 I didn't know pulled pork could be soooo delicious. 1 You get incredibly fresh fish, prepared with care. 1 Before I go in to why I gave a 1 star rating please know that this was my third time eating at Bachi burger before writing a review. 0 I love the fact that everything on their menu is worth it. 1 Never again will I be dining at this place! 0 The food was excellent and service was very good. 1 Good beer & drink selection and good food selection. 1 Please stay away from the shrimp stir fried noodles. 0 The potato chip order was sad... I could probably count how many chips were in that box and it was probably around 12. 0 Food was really boring. 0 Good Service-check! 1 This greedy corporation will NEVER see another dime from me! 0 Will never, ever go back. 0 As much as I'd like to go back, I can't get passed the atrocious service and will never return. 0 In the summer, you can dine in a charming outdoor patio - so very delightful. 1 I did not expect this to be so good! 1 Fantastic food! 1 She ordered a toasted English muffin that came out untoasted. 0 The food was very good. 1 Never going back. 0 Great food for the price, which is very high quality and house made. 1 The bus boy on the other hand was so rude. 0 By this point, my friends and I had basically figured out this place was a joke and didn't mind making it publicly and loudly known. 0 Back to good BBQ, lighter fare, reasonable pricing and tell the public they are back to the old ways. 1 And considering the two of us left there very full and happy for about $20, you just can't go wrong. 1 All the bread is made in-house! 1 The only downside is the service. 0 Also, the fries are without a doubt the worst fries I've ever had. 0 Service was exceptional and food was a good as all the reviews. 1 A couple of months later, I returned and had an amazing meal. 1 Favorite place in town for shawarrrrrrma!!!!!! 1 The black eyed peas and sweet potatoes... UNREAL! 1 You won't be disappointed. 1 They could serve it with just the vinaigrette and it may make for a better overall dish, but it was still very good. 1 I go to far too many places and I've never seen any restaurant that serves a 1 egg breakfast, especially for $4.00. 0 When my mom and I got home she immediately got sick and she only had a few bites of salad. 0 The servers are not pleasant to deal with and they don't always honor Pizza Hut coupons. 0 Both of them were truly unbelievably good, and I am so glad we went back. 1 We had fantastic service, and were pleased by the atmosphere. 1 Everything was gross. 0 I love this place. 1 Great service and food. 1 First - the bathrooms at this location were dirty- Seat covers were not replenished & just plain yucky!!! 0 The burger... I got the "Gold Standard" a $17 burger and was kind of disappointed. 0 OMG, the food was delicioso! 1 There is nothing authentic about this place. 0 the spaghetti is nothing special whatsoever. 0 Of all the dishes, the salmon was the best, but all were great. 1 The vegetables are so fresh and the sauce feels like authentic Thai. 1 It's worth driving up from Tucson! 1 The selection was probably the worst I've seen in Vegas.....there was none. 0 Pretty good beer selection too. 1 This place is like Chipotle, but BETTER. 1 Classy/warm atmosphere, fun and fresh appetizers, succulent steaks (Baseball steak!!!!! 1 5 stars for the brick oven bread app! 1 I have eaten here multiple times, and each time the food was delicious. 1 We sat another ten minutes and finally gave up and left. 0 He was terrible! 0 Everyone is treated equally special. 1 It shouldn't take 30 min for pancakes and eggs. 0 It was delicious!!! 1 On the good side, the staff was genuinely pleasant and enthusiastic - a real treat. 1 Sadly, Gordon Ramsey's Steak is a place we shall sharply avoid during our next trip to Vegas. 0 As always the evening was wonderful and the food delicious! 1 Best fish I've ever had in my life! 1 (The bathroom is just next door and very nice.) 1 The buffet is small and all the food they offered was BLAND. 0 This is an Outstanding little restaurant with some of the Best Food I have ever tasted. 1 Pretty cool I would say. 1 Definitely a turn off for me & i doubt I'll be back unless someone else is buying. 0 Server did a great job handling our large rowdy table. 1 I find wasting food to be despicable, but this just wasn't food. 0 My wife had the Lobster Bisque soup which was lukewarm. 0 Would come back again if I had a sushi craving while in Vegas. 1 The staff are great, the ambiance is great. 1 He deserves 5 stars. 1 I left with a stomach ache and felt sick the rest of the day. 0 They dropped more than the ball. 0 The dining space is tiny, but elegantly decorated and comfortable. 1 They will customize your order any way you'd like, my usual is Eggplant with Green Bean stir fry, love it! 1 And the beans and rice were mediocre at best. 0 Best tacos in town by far!! 1 I took back my money and got outta there. 0 In an interesting part of town, this place is amazing. 1 RUDE & INCONSIDERATE MANAGEMENT. 0 The staff are now not as friendly, the wait times for being served are horrible, no one even says hi for the first 10 minutes. 0 I won't be back. 0 They have great dinners. 1 The service was outshining & I definitely recommend the Halibut. 1 The food was terrible. 0 WILL NEVER EVER GO BACK AND HAVE TOLD MANY PEOPLE WHAT HAD HAPPENED. 0 I don't recommend unless your car breaks down in front of it and you are starving. 0 I will come back here every time I'm in Vegas. 1 This place deserves one star and 90% has to do with the food. 0 This is a disgrace. 0 Def coming back to bowl next time 1 If you want healthy authentic or ethic food, try this place. 1 I will continue to come here on ladies night andddd date night ... highly recommend this place to anyone who is in the area (; 1 I have been here several times in the past, and the experience has always been great. 1 We walked away stuffed and happy about our first Vegas buffet experience. 1 Service was excellent and prices are pretty reasonable considering this is Vegas and located inside the Crystals shopping mall by Aria. 1 To summarize... the food was incredible, nay, transcendant... but nothing brings me joy quite like the memory of the pneumatic condiment dispenser. 1 I'm probably one of the few people to ever go to Ians and not like it. 0 Kids pizza is always a hit too with lots of great side dish options for the kiddos! 1 Service is perfect and the family atmosphere is nice to see. 1 Cooked to perfection and the service was impeccable. 1 This one is simply a disappointment. 0 Overall, I was very disappointed with the quality of food at Bouchon. 0 I don't have to be an accountant to know I'm getting screwed! 0 Great place to eat, reminds me of the little mom and pop shops in the San Francisco Bay Area. 1 Today was my first taste of a Buldogis Gourmet Hot Dog and I have to tell you it was more than I ever thought possible. 1 Left very frustrated. 0 I'll definitely be in soon again. 1 Food was really good and I got full petty fast. 1 Service was fantastic. 1 TOTAL WASTE OF TIME. 0 I don't know what kind it is but they have the best iced tea. 1 Come hungry, leave happy and stuffed! 1 For service, I give them no stars. 0 I can assure you that you won't be disappointed. 1 I can take a little bad service but the food sucks. 0 Gave up trying to eat any of the crust (teeth still sore). 0 But now I was completely grossed out. 0 I really enjoyed eating here. 1 First time going but I think I will quickly become a regular. 1 Our server was very nice, and even though he looked a little overwhelmed with all of our needs, he stayed professional and friendly until the end. 1 From what my dinner companions told me...everything was very fresh with nice texture and taste. 1 On the ground, right next to our table was a large, smeared, been-stepped-in-and-tracked-everywhere pile of green bird poop. 0 Furthermore, you can't even find hours of operation on the website! 0 We've tried to like this place but after 10+ times I think we're done with them. 0 What a mistake that was! 0 No complaints! 1 This is some seriously good pizza and I'm an expert/connisseur on the topic. 1 Waiter was a jerk. 0 Strike 2, who wants to be rushed. 0 These are the nicest restaurant owners I've ever come across. 1 I never come again. 0 We loved the biscuits!!! 1 Service is quick and friendly. 1 Ordered an appetizer and took 40 minutes and then the pizza another 10 minutes. 0 So absolutley fantastic. 1 It was a huge awkward 1.5lb piece of cow that was 3/4ths gristle and fat. 0 definitely will come back here again. 1 I like Steiners because it's dark and it feels like a bar. 1 Wow very spicy but delicious. 1 If you're not familiar, check it out. 1 I'll take my business dinner dollars elsewhere. 0 I'd love to go back. 1 Anyway, this FS restaurant has a wonderful breakfast/lunch. 1 Nothing special. 0 Each day of the week they have a different deal and it's all so delicious! 1 Not to mention the combination of pears, almonds and bacon is a big winner! 1 Will not be back. 0 Sauce was tasteless. 0 The food is delicious and just spicy enough, so be sure to ask for spicier if you prefer it that way. 1 My ribeye steak was cooked perfectly and had great mesquite flavor. 1 I don't think we'll be going back anytime soon. 0 Food was so gooodd. 1 I am far from a sushi connoisseur but I can definitely tell the difference between good food and bad food and this was certainly bad food. 0 I was so insulted. 0 The last 3 times I had lunch here has been bad. 0 The chicken wings contained the driest chicken meat I have ever eaten. 0 The food was very good and I enjoyed every mouthful, an enjoyable relaxed venue for couples small family groups etc. 1 Nargile - I think you are great. 1 Best tater tots in the southwest. 1 We loved the place. 1 Definitely not worth the $3 I paid. 0 The vanilla ice cream was creamy and smooth while the profiterole (choux) pastry was fresh enough. 1 Im in AZ all the time and now have my new spot. 1 The manager was the worst. 0 The inside is really quite nice and very clean. 1 The food was outstanding and the prices were very reasonable. 1 I don't think I'll be running back to Carly's anytime soon for food. 0 This is was due to the fact that it took 20 minutes to be acknowledged, then another 35 minutes to get our food...and they kept forgetting things. 0 Love the margaritas, too! 1 This was my first and only Vegas buffet and it did not disappoint. 1 Very good, though! 1 The one down note is the ventilation could use some upgrading. 0 Great pork sandwich. 1 Don't waste your time here. 0 Total letdown, I would much rather just go to the Camelback Flower Shop and Cartel Coffee. 0 Third, the cheese on my friend's burger was cold. 0 We enjoy their pizza and brunch. 1 The steaks are all well trimmed and also perfectly cooked. 1 We had a group of 70+ when we claimed we would only have 40 and they handled us beautifully. 1 I LOVED it! 1 We asked for the bill to leave without eating and they didn't bring that either. 0 This place is a jewel in Las Vegas, and exactly what I've been hoping to find in nearly ten years living here. 1 Seafood was limited to boiled shrimp and crab legs but the crab legs definitely did not taste fresh. 0 The selection of food was not the best. 0 Delicious and I will absolutely be back! 1 This isn't a small family restaurant, this is a fine dining establishment. 1 They had a toro tartare with a cavier that was extraordinary and I liked the thinly sliced wagyu with white truffle. 1 I dont think I will be back for a very long time. 0 It was attached to a gas station, and that is rarely a good sign. 0 How awesome is that. 1 I will be back many times soon. 1 The menu had so much good stuff on it i could not decide! 1 Worse of all, he humiliated his worker right in front of me..Bunch of horrible name callings. 0 CONCLUSION: Very filling meals. 1 Their daily specials are always a hit with my group. 1 And then tragedy struck. 0 The pancake was also really good and pretty large at that. 1 This was my first crawfish experience, and it was delicious! 1 Their monster chicken fried steak and eggs is my all time favorite. 1 Waitress was sweet and funny. 1 I also had to taste my Mom's multi-grain pumpkin pancakes with pecan butter and they were amazing, fluffy, and delicious! 1 I'd rather eat airline food, seriously. 0 Cant say enough good things about this place. 1 The ambiance was incredible. 1 The waitress and manager are so friendly. 1 I would not recommend this place. 0 Overall I wasn't very impressed with Noca. 0 My gyro was basically lettuce only. 0 Terrible service! 0 Thoroughly disappointed! 0 I don't each much pasta, but I love the homemade /hand made pastas and thin pizzas here. 1 Give it a try, you will be happy you did. 1 By far the BEST cheesecurds we have ever had! 1 Reasonably priced also! 1 Everything was perfect the night we were in. 1 The food is very good for your typical bar food. 1 it was a drive to get there. 0 At first glance it is a lovely bakery cafe - nice ambiance, clean, friendly staff. 1 Anyway, I do not think i will go back there. 0 Point your finger at any item on the menu, order it and you won't be disappointed. 1 Oh this is such a thing of beauty, this restaurant. 1 If you haven't gone here GO NOW! 1 A greasy, unhealthy meal. 0 first time there and might just be the last. 0 Those burgers were amazing. 1 Similarly, the delivery man did not say a word of apology when our food was 45 minutes late. 0 And it was way to expensive. 0 Be sure to order dessert, even if you need to pack it to-go - the tiramisu and cannoli are both to die for. 1 This was my first time and I can't wait until the next. 1 The bartender was also nice. 1 Everything was good and tasty! 1 This place is two thumbs up....way up. 1 The best place in Vegas for breakfast (just check out a Sat, or Sun. 1 If you love authentic Mexican food and want a whole bunch of interesting, yet delicious meats to choose from, you need to try this place. 1 Terrible management. 0 An excellent new restaurant by an experienced Frenchman. 1 If there were zero stars I would give it zero stars. 0 Great steak, great sides, great wine, amazing desserts. 1 Worst martini ever! 0 The steak and the shrimp are in my opinion the best entrees at GC. 1 I had the opportunity today to sample your amazing pizzas! 1 We waited for thirty minutes to be seated (although there were 8 vacant tables and we were the only folks waiting). 0 The yellowtail carpaccio was melt in your mouth fresh. 1 I won't try going back there even if it's empty. 0 No, I'm going to eat the potato that I found some strangers hair in it. 0 Just spicy enough.. Perfect actually. 1 Last night was my second time dining here and I was so happy I decided to go back! 1 not even a "hello, we will be right with you." 0 The desserts were a bit strange. 0 My boyfriend and I came here for the first time on a recent trip to Vegas and could not have been more pleased with the quality of food and service. 1 I really do recommend this place, you can go wrong with this donut place! 1 Nice ambiance. 1 I would recommend saving room for this! 1 I guess maybe we went on an off night but it was disgraceful. 0 However, my recent experience at this particular location was not so good. 0 I know this is not like the other restaurants at all, something is very off here! 0 AVOID THIS ESTABLISHMENT! 0 I think this restaurant suffers from not trying hard enough. 0 All of the tapas dishes were delicious! 1 I *heart* this place. 1 My salad had a bland vinegrette on the baby greens and hearts of Palm. 0 After two I felt disgusting. 0 A good time! 1 I believe that this place is a great stop for those with a huge belly and hankering for sushi. 1 Generous portions and great taste. 1 I will never go back to this place and will never ever recommended this place to anyone! 0 The servers went back and forth several times, not even so much as an "Are you being helped?" 0 Food was delicious! 1 AN HOUR... seriously? 0 I consider this theft. 0 Eew... This location needs a complete overhaul. 0 We recently witnessed her poor quality of management towards other guests as well. 0 Waited and waited and waited. 0 He also came back to check on us regularly, excellent service. 1 Our server was super nice and checked on us many times. 1 The pizza tasted old, super chewy in not a good way. 0 I swung in to give them a try but was deeply disappointed. 0 Service was good and the company was better! 1 The staff are also very friendly and efficient. 1 As for the service: I'm a fan, because it's quick and you're being served by some nice folks. 1 Boy was that sucker dry!!. 0 Over rated. 0 If you look for authentic Thai food, go else where. 0 Their steaks are 100% recommended! 1 After I pulled up my car I waited for another 15 minutes before being acknowledged. 0 Great food and great service in a clean and friendly setting. 1 All in all, I can assure you I'll be back. 1 I hate those things as much as cheap quality black olives. 0 My breakfast was perpared great, with a beautiful presentation of 3 giant slices of Toast, lightly dusted with powdered sugar. 1 The kids play area is NASTY! 0 Great place fo take out or eat in. 1 The waitress was friendly and happy to accomodate for vegan/veggie options. 1 OMG I felt like I had never eaten Thai food until this dish. 1 It was extremely "crumby" and pretty tasteless. 0 It was a pale color instead of nice and char and has NO flavor. 0 The croutons also taste homemade which is an extra plus. 1 I got home to see the driest damn wings ever! 0 It'll be a regular stop on my trips to Phoenix! 1 I really enjoyed Crema Café before they expanded; I even told friends they had the BEST breakfast. 1 Not good for the money. 0 I miss it and wish they had one in Philadelphia! 1 We got sitting fairly fast, but, ended up waiting 40 minutes just to place our order, another 30 minutes before the food arrived. 0 They also have the best cheese crisp in town. 1 Good value, great food, great service. 1 Couldn't ask for a more satisfying meal. 1 The food is good. 1 It was awesome. 1 I just wanted to leave. 0 We made the drive all the way from North Scottsdale... and I was not one bit disappointed! 1 I will not be eating there again. 0 !....THE OWNERS REALLY REALLY need to quit being soooooo cheap let them wrap my freaking sandwich in two papers not one! 0 I checked out this place a couple years ago and was not impressed. 0 The chicken I got was definitely reheated and was only ok, the wedges were cold and soggy. 0 Sorry, I will not be getting food from here anytime soon :( 0 An absolute must visit! 1 The cow tongue and cheek tacos are amazing. 1 My friend did not like his Bloody Mary. 0 Despite how hard I rate businesses, its actually rare for me to give a 1 star. 0 They really want to make your experience a good one. 1 I will not return. 0 I had the chicken Pho and it tasted very bland. 0 Very disappointing!!! 0 The grilled chicken was so tender and yellow from the saffron seasoning. 1 a drive thru means you do not want to wait around for half an hour for your food, but somehow when we end up going here they make us wait and wait. 0 Pretty awesome place. 1 Ambience is perfect. 1 Best of luck to the rude and non-customer service focused new management. 0 Any grandmother can make a roasted chicken better than this one. 0 I asked multiple times for the wine list and after some time of being ignored I went to the hostess and got one myself. 0 The staff is always super friendly and helpful, which is especially cool when you bring two small boys and a baby! 1 Four stars for the food & the guy in the blue shirt for his great vibe & still letting us in to eat ! 1 The roast beef sandwich tasted really good! 1 Same evening, him and I are both drastically sick. 0 High-quality chicken on the chicken Caesar salad. 1 Ordered burger rare came in we'll done. 0 We were promptly greeted and seated. 1 Tried to go here for lunch and it was a madhouse. 0 I was proven dead wrong by this sushi bar, not only because the quality is great, but the service is fast and the food, impeccable. 1 After waiting an hour and being seated, I was not in the greatest of moods. 0 This is a good joint. 1 The Macarons here are insanely good. 1 I'm not eating here! 0 Our waiter was very attentive, friendly, and informative. 1 Maybe if they weren't cold they would have been somewhat edible. 0 This place has a lot of promise but fails to deliver. 0 Very bad Experience! 0 What a mistake. 0 Food was average at best. 0 Great food. 1 We won't be going back anytime soon! 0 Very Very Disappointed ordered the $35 Big Bay Plater. 0 Great place to relax and have an awesome burger and beer. 1 It is PERFECT for a sit-down family meal or get together with a few friends. 1 Not much flavor to them, and very poorly constructed. 0 The patio seating was very comfortable. 1 The fried rice was dry as well. 0 Hands down my favorite Italian restaurant! 1 That just SCREAMS "LEGIT" in my book...somethat's also pretty rare here in Vegas. 1 It was just not a fun experience. 1 The atmosphere was great with a lovely duo of violinists playing songs we requested. 1 I personally love the hummus, pita, baklava, falafels and Baba Ganoush (it's amazing what they do with eggplant!). 1 Very convenient, since we were staying at the MGM! 1 The owners are super friendly and the staff is courteous. 1 Both great! 1 Eclectic selection. 1 The sweet potato tots were good but the onion rings were perfection or as close as I have had. 1 The staff was very attentive. 1 And the chef was generous with his time (even came around twice so we can take pictures with him). 1 The owner used to work at Nobu, so this place is really similar for half the price. 1 Google mediocre and I imagine Smashburger will pop up. 0 dont go here. 0 I promise they won't disappoint. 1 As a sushi lover avoid this place by all means. 0 What a great double cheeseburger! 1 Awesome service and food. 1 A fantastic neighborhood gem !!! 1 I can't wait to go back. 1 The plantains were the worst I've ever tasted. 0 It's a great place and I highly recommend it. 1 Service was slow and not attentive. 0 I gave it 5 stars then, and I'm giving it 5 stars now. 1 Your staff spends more time talking to themselves than me. 0 Dessert: Panna Cotta was amazing. 1 Very good food, great atmosphere.1 1 Damn good steak. 1 Total brunch fail. 0 Prices are very reasonable, flavors are spot on, the sauce is home made, and the slaw is not drenched in mayo. 1 The decor is nice, and the piano music soundtrack is pleasant. 1 The steak was amazing...rge fillet relleno was the best seafood plate i have ever had! 1 Good food , good service . 1 It was absolutely amazing. 1 I probably won't be back, to be honest. 0 will definitely be back! 1 The sergeant pepper beef sandwich with auju sauce is an excellent sandwich as well. 1 Hawaiian Breeze, Mango Magic, and Pineapple Delight are the smoothies that I've tried so far and they're all good. 1 Went for lunch - service was slow. 0 We had so much to say about the place before we walked in that he expected it to be amazing, but was quickly disappointed. 0 I was mortified. 0 Needless to say, we will never be back here again. 0 Anyways, The food was definitely not filling at all, and for the price you pay you should expect more. 0 The chips that came out were dripping with grease, and mostly not edible. 0 I wasn't really impressed with Strip Steak. 0 Have been going since 2007 and every meal has been awesome!! 1 Our server was very nice and attentive as were the other serving staff. 1 The cashier was friendly and even brought the food out to me. 1 I work in the hospitality industry in Paradise Valley and have refrained from recommending Cibo any longer. 0 The atmosphere here is fun. 1 Would not recommend to others. 0 Service is quick and even "to go" orders are just like we like it! 1 I mean really, how do you get so famous for your fish and chips when it's so terrible!?! 0 That said, our mouths and bellies were still quite pleased. 1 Not my thing. 0 2 Thumbs Up!! 1 If you are reading this please don't go there. 0 I loved the grilled pizza, reminded me of legit Italian pizza. 1 Only Pros : Large seating area/ Nice bar area/ Great simple drink menu/ The BEST brick oven pizza with homemade dough! 1 They have a really nice atmosphere. 1 Tonight I had the Elk Filet special...and it sucked. 0 After one bite, I was hooked. 1 We ordered some old classics and some new dishes after going there a few times and were sorely disappointed with everything. 0 Cute, quaint, simple, honest. 1 The chicken was deliciously seasoned and had the perfect fry on the outside and moist chicken on the inside. 1 The food was great as always, compliments to the chef. 1 Special thanks to Dylan T. for the recommendation on what to order :) All yummy for my tummy. 1 Awesome selection of beer. 1 Great food and awesome service! 1 One nice thing was that they added gratuity on the bill since our party was larger than 6 or 8, and they didn't expect more tip than that. 1 A FLY was in my apple juice.. A FLY!!!!!!!! 0 The Han Nan Chicken was also very tasty. 1 As for the service, I thought it was good. 1 The food was barely lukewarm, so it must have been sitting waiting for the server to bring it out to us. 0 Ryan's Bar is definitely one Edinburgh establishment I won't be revisiting. 0 Nicest Chinese restaurant I've been in a while. 1 Overall, I like there food and the service. 1 They also now serve Indian naan bread with hummus and some spicy pine nut sauce that was out of this world. 1 Probably never coming back, and wouldn't recommend it. 0 Friend's pasta -- also bad, he barely touched it. 0 Try them in the airport to experience some tasty food and speedy, friendly service. 1 I love the decor with the Chinese calligraphy wall paper. 1 Never had anything to complain about here. 1 The restaurant is very clean and has a family restaurant feel to it. 1 It was way over fried. 0 I'm not sure how long we stood there but it was long enough for me to begin to feel awkwardly out of place. 0 When I opened the sandwich, I was impressed, but not in a good way. 0 Will not be back! 0 There was a warm feeling with the service and I felt like their guest for a special treat. 1 An extensive menu provides lots of options for breakfast. 1 I always order from the vegetarian menu during dinner, which has a wide array of options to choose from. 1 I have watched their prices inflate, portions get smaller and management attitudes grow rapidly! 0 Wonderful lil tapas and the ambience made me feel all warm and fuzzy inside. 1 I got to enjoy the seafood salad, with a fabulous vinegrette. 1 The wontons were thin, not thick and chewy, almost melt in your mouth. 1 Level 5 spicy was perfect, where spice didn't over-whelm the soup. 1 We were sat right on time and our server from the get go was FANTASTIC! 1 Main thing I didn't enjoy is that the crowd is of older crowd, around mid 30s and up. 0 When I'm on this side of town, this will definitely be a spot I'll hit up again! 1 I had to wait over 30 minutes to get my drink and longer to get 2 arepas. 0 This is a GREAT place to eat! 1 The jalapeno bacon is soooo good. 1 The service was poor and thats being nice. 0 Food was good, service was good, Prices were good. 1 The place was not clean and the food oh so stale! 0 The chicken dishes are OK, the beef is like shoe leather. 0 But the service was beyond bad. 0 I'm so happy to be here!!!" 1 Tasted like dirt. 0 One of the few places in Phoenix that I would definately go back to again . 1 The block was amazing. 1 It's close to my house, it's low-key, non-fancy, affordable prices, good food. 1 * Both the Hot & Sour & the Egg Flower Soups were absolutely 5 Stars! 1 My sashimi was poor quality being soggy and tasteless. 0 Great time - family dinner on a Sunday night. 1 the food is not tasty at all, not to say its "real traditional Hunan style". 0 What did bother me, was the slow service. 0 The flair bartenders are absolutely amazing! 1 Their frozen margaritas are WAY too sugary for my taste. 0 These were so good we ordered them twice. 1 So in a nutshell: 1) The restaraunt smells like a combination of a dirty fish market and a sewer. 0 My girlfriend's veal was very bad. 0 Unfortunately, it was not good. 0 I had a pretty satifying experience. 1 Join the club and get awesome offers via email. 1 Perfect for someone (me) who only likes beer ice cold, or in this case, even colder. 1 Bland and flavorless is a good way of describing the barely tepid meat. 0 The chains, which I'm no fan of, beat this place easily. 0 The nachos are a MUST HAVE! 1 We will not be coming back. 0 I don't have very many words to say about this place, but it does everything pretty well. 1 The staff is super nice and very quick even with the crazy crowds of the downtown juries, lawyers, and court staff. 1 Great atmosphere, friendly and fast service. 1 When I received my Pita it was huge it did have a lot of meat in it so thumbs up there. 1 Once your food arrives it's meh. 0 Paying $7.85 for a hot dog and fries that looks like it came out of a kid's meal at the Wienerschnitzel is not my idea of a good meal. 0 The classic Maine Lobster Roll was fantastic. 1 My brother in law who works at the mall ate here same day, and guess what he was sick all night too. 0 So good I am going to have to review this place twice - once hereas a tribute to the place and once as a tribute to an event held here last night. 1 The chips and salsa were really good, the salsa was very fresh. 1 This place is great!!!!!!!!!!!!!! 1 Mediocre food. 0 Once you get inside you'll be impressed with the place. 1 I'm super pissd. 0 And service was super friendly. 1 Why are these sad little vegetables so overcooked? 0 This place was such a nice surprise! 1 They were golden-crispy and delicious. 1 I had high hopes for this place since the burgers are cooked over a charcoal grill, but unfortunately the taste fell flat, way flat. 0 I could eat their bruschetta all day it is devine. 1 Not a single employee came out to see if we were OK or even needed a water refill once they finally served us our food. 0 Lastly, the mozzarella sticks, they were the best thing we ordered. 1 The first time I ever came here I had an amazing experience, I still tell people how awesome the duck was. 1 The server was very negligent of our needs and made us feel very unwelcome... I would not suggest this place! 0 The service was terrible though. 0 This place is overpriced, not consistent with their boba, and it really is OVERPRICED! 0 It was packed!! 0 I love this place. 1 I can say that the desserts were yummy. 1 The food was terrible. 0 The seasonal fruit was fresh white peach puree. 1 It kept getting worse and worse so now I'm officially done. 0 This place should honestly be blown up. 0 But I definitely would not eat here again. 0 Do not waste your money here! 0 I love that they put their food in nice plastic containers as opposed to cramming it in little paper takeout boxes. 1 The crêpe was delicate and thin and moist. 1 Awful service. 0 Won't ever go here again. 0 Food quality has been horrible. 0 For that price I can think of a few place I would have much rather gone. 0 The service here is fair at best. 0 I do love sushi, but I found Kabuki to be over-priced, over-hip and under-services. 0 Do yourself a favor and stay away from this dish. 0 Very poor service. 0 No one at the table thought the food was above average or worth the wait that we had for it. 0 Best service and food ever, Maria our server was so good and friendly she made our day. 1 They were excellent. 1 I paid the bill but did not tip because I felt the server did a terrible job. 0 Just had lunch here and had a great experience. 1 I have never had such bland food which surprised me considering the article we read focused so much on their spices and flavor. 0 Food is way overpriced and portions are fucking small. 0 I recently tried Caballero's and I have been back every week since! 1 for 40 bucks a head, i really expect better food. 0 The food came out at a good pace. 1 I ate there twice on my last visit, and especially enjoyed the salmon salad. 1 I won't be back. 0 We could not believe how dirty the oysters were! 0 This place deserves no stars. 0 I would not recommend this place. 0 In fact I'm going to round up to 4 stars, just because she was so awesome. 1 To my disbelief, each dish qualified as the worst version of these foods I have ever tasted. 0 Bad day or not, I have a very low tolerance for rude customer service people, it is your job to be nice and polite, wash dishes otherwise!! 0 the potatoes were great and so was the biscuit. 1 I probably would not go here again. 0 So flavorful and has just the perfect amount of heat. 1 The price is reasonable and the service is great. 1 The Wife hated her meal (coconut shrimp), and our friends really did not enjoy their meals, either. 0 My fella got the huevos rancheros and they didn't look too appealing. 0 Went in for happy hour, great list of wines. 1 Some may say this buffet is pricey but I think you get what you pay for and this place you are getting quite a lot! 1 I probably won't be coming back here. 0 Worst food/service I've had in a while. 0 This place is pretty good, nice little vibe in the restaurant. 1 Talk about great customer service of course we will be back. 1 Hot dishes are not hot, cold dishes are close to room temp.I watched staff prepare food with BARE HANDS, no gloves.Everything is deep fried in oil. 0 I love their fries and their beans. 1 Always a pleasure dealing with him. 1 They have a plethora of salads and sandwiches, and everything I've tried gets my seal of approval. 1 This place is awesome if you want something light and healthy during the summer. 1 For sushi on the Strip, this is the place to go. 1 The service was great, even the manager came and helped with our table. 1 The feel of the dining room was more college cooking course than high class dining and the service was slow at best. 0 I started this review with two stars, but I'm editing it to give it only one. 0 this is the worst sushi i have ever eat besides Costco's. 0 All in all an excellent restaurant highlighted by great service, a unique menu, and a beautiful setting. 1 My boyfriend and i sat at the bar and had a completely delightful experience. 1 Weird vibe from owners. 0 There was hardly any meat. 0 I've had better bagels from the grocery store. 0 Go To Place for Gyros. 1 I love the owner/chef, his one authentic Japanese cool dude! 1 Now the burgers aren't as good, the pizza which used to be amazing is doughy and flavorless. 0 I found a six inch long piece of wire in my salsa. 0 The service was terrible, food was mediocre. 0 We definately enjoyed ourselves. 1 I ordered Albondigas soup - which was just warm - and tasted like tomato soup with frozen meatballs. 0 On three different occasions I asked for well done or medium well, and all three times I got the bloodiest piece of meat on my plate. 0 I had about two bites and refused to eat anymore. 0 The service was extremely slow. 0 After 20 minutes wait, I got a table. 0 Seriously killer hot chai latte. 1 No allergy warnings on the menu, and the waitress had absolutely no clue as to which meals did or did not contain peanuts. 0 My boyfriend tried the Mediterranean Chicken Salad and fell in love. 1 Their rotating beers on tap is also a highlight of this place. 1 Pricing is a bit of a concern at Mellow Mushroom. 0 Worst Thai ever. 0 If you stay in Vegas you must get breakfast here at least once. 1 I want to first say our server was great and we had perfect service. 1 The pizza selections are good. 1 I had strawberry tea, which was good. 1 Highly unprofessional and rude to a loyal patron! 0 Overall, a great experience. 1 Spend your money elsewhere. 0 Their regular toasted bread was equally satisfying with the occasional pats of butter... Mmmm...! 1 The Buffet at Bellagio was far from what I anticipated. 0 And the drinks are WEAK, people! 0 -My order was not correct. 0 Also, I feel like the chips are bought, not made in house. 0 After the disappointing dinner we went elsewhere for dessert. 0 The chips and sals a here is amazing!!!!!!!!!!!!!!!!!!! 1 We won't be returning. 0 This is my new fav Vegas buffet spot. 1 I seriously cannot believe that the owner has so many unexperienced employees that all are running around like chickens with their heads cut off. 0 Very, very sad. 0 i felt insulted and disrespected, how could you talk and judge another human being like that? 0 How can you call yourself a steakhouse if you can't properly cook a steak, I don't understand! 0 I'm not impressed with the concept or the food. 0 The only thing I wasn't too crazy about was their guacamole as I don't like it puréed. 0 There is really nothing for me at postinos, hope your experience is better 0 I got food poisoning here at the buffet. 0 They brought a fresh batch of fries and I was thinking yay something warm but no! 0 What SHOULD have been a hilarious, yummy Christmas Eve dinner to remember was the biggest fail of the entire trip for us. 0 Needless to say, I won't be going back anytime soon. 0 This place is disgusting! 0 Every time I eat here, I see caring teamwork to a professional degree. 1 The RI style calamari was a joke. 0 However, there was so much garlic in the fondue, it was barely edible. 0 I could barely stomach the meal, but didn't complain because it was a business lunch. 0 It was so bad, I had lost the heart to finish it. 0 It also took her forever to bring us the check when we asked for it. 0 We aren't ones to make a scene at restaurants but I just don't get it...definitely lost the love after this one! 0 Disappointing experience. 0 The food is about on par with Denny's, which is to say, not good at all. 0 If you want to wait for mediocre food and downright terrible service, then this is the place for you. 0 WAAAAAAyyyyyyyyyy over rated is all I am saying. 0 We won't be going back. 0 The place was fairly clean but the food simply wasn't worth it. 0 This place lacked style!! 0 The sangria was about half of a glass wine full and was $12, ridiculous. 0 Don't bother coming here. 0 The meat was pretty dry, I had the sliced brisket and pulled pork. 0 The building itself seems pretty neat; the bathroom is pretty trippy, but I wouldn't eat here again. 0 It was equally awful. 0 Probably not in a hurry to go back. 0 very slow at seating even with reservation. 0 Not good by any stretch of the imagination. 0 The cashew cream sauce was bland and the vegetables were undercooked. 0 The chipolte ranch dipping sause was tasteless, seemed thin and watered down with no heat. 0 It was a bit too sweet, not really spicy enough, and lacked flavor. 0 I was VERY disappointed!! 0 This place is horrible and way overpriced. 0 Maybe it's just their Vegetarian fare, but I've been twice and I thought it was average at best. 0 It wasn't busy at all and now we know why. 0 The tables outside are also dirty a lot of the time and the workers are not always friendly and helpful with the menu. 0 The ambiance here did not feel like a buffet setting, but more of a douchey indoor garden for tea and biscuits. 0 Con: spotty service. 0 The fries were not hot, and neither was my burger. 0 But then they came back cold. 0 Then our food came out, disappointment ensued. 0 The real disappointment was our waiter. 0 My husband said she was very rude... did not even apologize for the bad food or anything. 0 The only reason to eat here would be to fill up before a night of binge drinking just to get some carbs in your stomach. 0 Insults, profound deuchebaggery, and had to go outside for a smoke break while serving just to solidify it. 0 If someone orders two tacos don't' you think it may be part of customer service to ask if it is combo or ala cart? 0 She was quite disappointed although some blame needs to be placed at her door. 0 After all the rave reviews I couldn't wait to eat here......what a disappointment! 0 Del Taco is pretty nasty and should be avoided if possible. 0 It's NOT hard to make a decent hamburger. 0 But I don't like it. 0 Hell no will I go back 0 We've have gotten a much better service from the pizza place next door than the services we received from this restaurant. 0 I don't know what the big deal is about this place, but I won't be back "ya'all". 0 I immediately said I wanted to talk to the manager but I did not want to talk to the guy who was doing shots of fireball behind the bar. 0 The ambiance isn't much better. 0 Unfortunately, it only set us up for disapppointment with our entrees. 0 The food wasn't good. 0 Your servers suck, wait, correction, our server Heimer sucked. 0 What happened next was pretty....off putting. 0 too bad cause I know it's family owned, I really wanted to like this place. 0 Overpriced for what you are getting. 0 I vomited in the bathroom mid lunch. 0 I kept looking at the time and it had soon become 35 minutes, yet still no food. 0 I have been to very few places to eat that under no circumstances would I ever return to, and this tops the list. 0 We started with the tuna sashimi which was brownish in color and obviously wasn't fresh. 0 Food was below average. 0 It sure does beat the nachos at the movies but I would expect a little bit more coming from a restaurant. 0 All in all, Ha Long Bay was a bit of a flop. 0 The problem I have is that they charge $11.99 for a sandwich that is no bigger than a Subway sub (which offers better and more amount of vegetables). 0 Shrimp- When I unwrapped it (I live only 1/2 a mile from Brushfire) it was literally ice cold. 0 It lacked flavor, seemed undercooked, and dry. 0 It really is impressive that the place hasn't closed down. 0 I would avoid this place if you are staying in the Mirage. 0 The refried beans that came with my meal were dried out and crusty and the food was bland. 0 Spend your money and time some place else. 0 A lady at the table next to us found a live green caterpillar In her salad. 0 the presentation of the food was awful. 0 I can't tell you how disappointed I was. 0 I think food should have flavor and texture and both were lacking. 0 Appetite instantly gone. 0 Overall I was not impressed and would not go back. 0 The whole experience was underwhelming, and I think we'll just go to Ninja Sushi next time. 0 Then, as if I hadn't wasted enough of my life there, they poured salt in the wound by drawing out the time it took to bring the check. 0 ================================================ FILE: workbooks/README.md ================================================ About Workbooks ============ These workbooks explain how the app works and help you to write workbooks from scratch. ================================================ FILE: workbooks/getting-started/meta.json ================================================ { "order":{ "welcome.workbook":"Welcome to Workbooks" } } ================================================ FILE: workbooks/getting-started/welcome.workbook ================================================ --- uti: com.xamarin.workbook platform: Console packages: [] --- TODO * Replace “using statement” with using directive somewhere here * # Welcome to Workbooks Workbooks are live documents that mix text, code and results in the same document. This document will teach you how to effectively use Workbooks to explore, experiment and live code workbooks that you can share or reuse. For example, the following cell declares a variable name, assigns the value “Miguel” and then prints the result. To watch it in action, position your cursor at the end of the line below and press the return key. ```csharp var name = "Miguel"; ``` The above should display the result in quotes in the next line as “Miguel” which is the result for the operation, along with a small selector that lets you change the format in which the result will be displayed. The return key is special, it will try to do the right thing depending on the context. For example, if you positioned your cursor in the middle of the line, Workbooks would insert a new-line instead of executing the statement and split your text in two. To execute the code regardless of where your cursor is, you can either press the small play button icon that shows up, or you can press Command-Return on Mac, or Alt-Return on Windows. You will be using this from now on. You might want to force the insertion of a newline without Workbooks executing the code right away, perhaps you are in the middle of a more complicated statement. To force the insertion of a new-line, use Shift-Return. Try it on the cell below, insert a new-line between the `=` and the expression following it, and then force an evaluation. ```csharp var area = 10 * 20 ``` Finally, if you feel so inclined, you could run the entire contents of the workbook in one go, by pressing the play icon at the top of this window. In C# you can concatenate strings by using the “\+” operator on strings, the following snippet assigns to the variable “greeting” the result of concatenating “Hello ” and the name defined above. Position yourself on the cell below and execute it: ```csharp var greeting = "Hello " + name ``` The result should be “Hello Miguel”. Now, chances are, your name is not Miguel, so the greeting above is far from appropriate. Go back to the cell containing that assigned the value “Miguel” to name, change the value to your name, and execute the cell and come back. Welcome back. You will notice that not only did the result in the original cell change to your name, but the greeting above was also updated. Workbooks will always re-execute all the code between the changes that you make to a cell and the last cell you used and update all the displayed results. This will come in very handy as you prototype code with Workbooks. Next to the greeting there is a small bubble showing “C#”, this means that the result of the expression is being displayed as a C# expression. Results can be displayed in various formats and Workbooks will try to pick the best one for you. Sometimes you may want to display the information in another format, to do that, click on the bubble and select one of the available formats. For strings, I happen to know that the possible values are C#, Plain Text and the very cool Object Members. Try them out above. Object Members will display the properties for the result, in the case of a string, one interesting property is the Length. And you can further customize the format in one of the many available forms. Let us do a couple more exercises: Run the following cell which will split the provided string at each space: ```csharp var quote = "Once upon a time, there was a compiler that optimized dreams (or something like that)"; quote.Split (' ') ``` In this case, Workbooks will display the result of the array as individual elements. Workbooks will limit the display to the first ten entries, if you want to see more, just click “Continue enumerating” on the result above, that should display the last word shown. The above split is acceptable, but clearly we do not want the word “time” to have a comma at the end (see the result at index 3). Let us put together a list of all the values that we want to remove: ```csharp var removeLetters = new char [] { ' ', '(', ')', ','}; quote.Split (removeLetters) ``` While this works, the library is indicating that it found two of these removed characters next to each other by returning an empty element at index 4. Workbooks is powered by a powerful C# text editor that can provide code completion and parameter completion. Go back to the `Split` method, and after the word “removeLetter”, insert a comma, this will trigger a popup to show up with the possible method overloads that you can use with the `Split` method. Use the up/down arrow keys in your keyboard to scroll through the available overloads, you will notice one that takes a `StringSplitOptions.` Start typing “StringSplitOptions” and you will notice that the completion shrinks to the possible options, once the options are narrowed down, you can press return to complete the word, then press “.” and this will trigger the completion window again. Use the cursor key to select the word “RemoveEmptyEntries” and press return. One convenient feature is that you do not have to type the word “StringSplitOptions”, you can type “SplitOptions” and the completion window will select the matching version. Or even better, you can just type some of the upper case letters in the match, for instance “sso” (StringSplitOptions) works, and even “ssp” (StringSPlit). # Writing Code So far we have shown trivial C# statements being executed. Workbooks also allows the definitions of functions, properties and other class members directly into the code, for example: ```csharp int Sum (params int [] numbers) { int total = 0; foreach (var value in numbers) total = total + value; return total; } ``` And you can invoke it either directly there, or you can invoke it from a new cell: ```csharp Sum (1, 2, 3) ``` **Excercise**: what is the result of calling `Sum` on `Int32.MaxValue` plus one? **Excercise**: modify the Sum function above to use the double data type to add numbers instead of integers to avoid overflow values. **Excercise:** Add a using statement to use the `System.ComponentModel` namespace. **Exercise:** modify the Sum function above to take an array of objects and use the `System.ComponentModel.TypeConverter.ConvertTo` method to convert the object into a specific type. You are not limited to creating members, you can also create full classes, for example, the following code represents a product listing: ```csharp class Flight { public string Origin, Destination; public TimeSpan FlightDuration; } var flights = new Flight [] { new Flight () { Origin="Boston", Destination="Seattle", FlightDuration = TimeSpan.FromMinutes (354) }, new Flight () { Origin="Seattle", Destination="Tokyo", FlightDuration = TimeSpan.FromMinutes (800) }, new Flight () { Origin="Boston", Destination="New York", FlightDuration = TimeSpan.FromMinutes (38) } }; ``` In the cell above, we both defined a class `Flight`, but we also created a local variable `flights`that contains a few flights. We can find the flight with the shortes travel time using a C# LINQ expression: ```csharp (from f in flights orderby f.FlightDuration select f).FirstOrDefault () ``` In addition to all the C# code that you love, we have provided a convenient “help” property that you can run, when you run it, it will show you specific workbook properties and methods that you can access. Try evaluating the next cell: ```csharp help ``` One convenient method is the Time method which can be used for simple benchmarks: ```csharp using System.Net; Time (()=> new WebClient ().DownloadString ("http://www.google.com")); ``` The help will be different based on the Workbook style that you use, but more on that in the “Workbook Styles” section. # Consuming Libraries When you start workbooks, a number of namespaces and libraries have already been included for your convenience. Previously you referenced the `WebClient` from the `System.Net` namespace by using the “using” directive. That works as long as the library that you need is already referenced, but if you need to use functionality from a library that is not referenced, you will need to do that using the “#r” instruction. Previously in this workbook, we changed our Sum method from integers to doubles, that was an acceptable workaround. With .NET you can use BigInteger, from the System.Numerics library, to use it, just reference that Library like this: ```csharp #r "System.Numerics" using System.Numerics; ``` This is one way of writing the Sum method with the arbitrary precision `BigInteger`: ```csharp BigInteger BigSum (params object [] numbers) { BigInteger total = new BigInteger (); foreach (var value in numbers){ if (value is BigInteger) total = total + (BigInteger)value; else if (value is int) total = total + (int)value; } return total; } // Show the differences in adding 1 to the maximum value that can be represented by a 32-bit integer: Console.WriteLine ($"Adding with Sum={Sum (Int32.MaxValue, 1)}"); Console.WriteLine ($"Adding with Big={BigSum (Int32.MaxValue, 1)}"); ``` In addition to system libraries like `System.Numerics`, there is a universe of third party libraries available for .NET called NuGet (pronounced “new-get”) Packages. For example, a very popular library is the Newtonsoft.Json library. To use this library in your project, you will want to use “File/Add NuGet Package” which will contact the NuGet server and obtain a list of packages that are available for you to use. Go ahead and bring the Newtonsoft.Json library, and once you do that, remove the comments around the code in the next cell and run it. The result will be our list of flights serialized into Json. ```csharp /* #r "Newtonsoft.Json" using Newtonsoft.Json; JsonConvert.SerializeObject(flights); */ ``` # Workbook Styles You are currently reading a Console workbook. This is a universal workbook that will execute code that is suitable to run on all platforms, from mobile applications to server applications. Additionally, you can explore, prototype and play not only with this universally portable Workbooks, but also with Workbooks that run on a specific environment. There are Workbooks available for exploring and developing Android applications, iOS applications, Mac applications and Windows applications. Each Workbook style has special knowledge about the target platform. For example, the iOS workbooks know how to launch the iOS Simulator on demand, and can be used to inspect the hierarchy of the visual elements in Apple’s UIKit and CoreAnimation layers. # Creating your own Workbooks You can try to do that now, select “File/New” from Worksbooks now, and you will be presented with a dialogs box that allows you to choose the kind of Workbook you want to create. You can do that now, create a new workbook, and keep this one around. So far you have been reading a live workbook that contains both an explanation and code mixed together. In your new workbook, you will see that there is only an execution cell. You can use workbooks purely as a playground to try out C# code without having to create a project and compile it. Try typing an expression after another. For example type, “1\+1” followed by return. The result will be displayed immediately and a new cell will be created. You can type a new expression right away “2\+3” press return and get the result. Over time, your workbook will contain a full log of all your experimentation and its results. You can annotate your workbook by moving your mouse just above any code cell. You will see three icons show up on the right side, these are: * Plus sign: this is used to insert a code cell just before the current cell, where you can inject some new code to run before your current cell. * Quote icon: this will create a text block, this is what you will use to edit text just like the one that you are reading now. * Cross sign: use this icon to delete the code cell below. When you create a text block, you will get a basic text editor. You might not have had a chance to try this, but the text that you are reading can also be edited. **Exercise:** Position your cursor after this sentence and type a new sentence. Exercise: oops, I forgot to make the bold the Exercise word at the beginning of this line. Select the word “Exercise” and make the text bold (pro-tip: in addition to the UI, you can use a hotkey, see “Format/Strong”). Explore the “Format” menu to see the kind of formatting changes that you can apply to the text in this sentence. # Behind Workbooks We wanted to make it easy to work with Workbooks. Workbooks are just [Markdown](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#code "GitHub flavored Markdown") files that contain a small header that describe the needs of the Workbook. The header contains the default agent to use at startup (Console, Android, iOS, Windows, etc) as well as a list of NuGet packages that might be needed to run the workbook. If you were to save this Workbook, you would see that any packages that you added with “File/Add NuGet Package” would be listed in this header. It is thus very easy to edit Workbook contents even when you do not have the Workbook environment around. # Community You might want to join our community of Workbook users and Workbook creators, check the Help/Community Forums link from the menu. ================================================ FILE: workbooks/meta.json ================================================ { "order":{ "getting-started":"Getting Started", "visualizers":"Visualizers" } } ================================================ FILE: workbooks/visualizers/README.md ================================================ Visualizers ========= [Xamarin Workbooks](https://developer.xamarin.com/guides/cross-platform/workbooks/) results visualization examples. ![](Screenshots/ios-mac.png) These workbooks (one for each platform) demonstrate * String * Object * Color (UIColor) * Enumerable * Map (CLLocation) * Image (UIImage) * Exception * Html * Help visualizations of object results. ================================================ FILE: workbooks/visualizers/Visualizers-console.workbook ================================================ --- uti: com.xamarin.workbook platforms: - Console --- # Visualizers (Console) Xamarin Workbooks uses a different visualizers for inline code evaluation results: * String * Object * Enumerable * Exception * Html * Help By default, the results of a code-block will shown as a string representation of the *last-referenced object* in the block. The `Monkey` class below demonstrates this: when the `rupert` object is assigned, the **ToString** representation is printed after the code-block. ```csharp class Monkey { public string Name; public string Species; public string Habitat; public DateTime Birthday = DateTime.MinValue; public override string ToString(){ return $"{Name} the {Species} ({Habitat})"; //C# 6 } } var rupert = new Monkey {Name="Rupert", Species = "Xamarin", Habitat="San Francisco"}; ``` Use the popup menu to the right of the result to switch to the **Object Members** view. Most code-block results in Workbooks will have both **ToString** and **Object Members** display options. DateTime values have a number of display options, including a calendar view: ```csharp rupert.Birthday = new DateTime(2011,05,11); ``` Enumerable collections will be expanded so that you can explore their contents. You can also change the view of each individual object in the collection: ```csharp var enumerable = new List {"alpha", "beta", "gamma", "delta"}; ``` Exceptions have a custom display: ```csharp new ArgumentNullException ("name"); ``` HTML can also be emitted from code-blocks and rendered in the Workbook. This simple example uses string interpolation to customize an HTML string for display using `AsHtml()`: ```csharp var greeting = "Hello, Workbooks"; // C# 6 string interpolation $"

{greeting}

bold italic underline".AsHtml() ``` There’s also a `help` command, which just lists some handy tips. The help list is slightly different for each platform supported by Workbooks. ```csharp help ``` And finally, not really a visualization, but from the help above you can see that it’s possible to affect the culture of the Workbook. These code-blocks show the date rendered in English and then Spanish (after setting the `CurrentCulture`): ```csharp DateTime.Now.ToLongDateString() ``` ```csharp CurrentCulture = new System.Globalization.CultureInfo("es"); DateTime.Now.ToLongDateString() ``` ```csharp // reset to English CurrentCulture = new System.Globalization.CultureInfo("en"); ``` ================================================ FILE: workbooks/visualizers/Visualizers-ios.workbook ================================================ --- uti: com.xamarin.workbook platforms: - iOS --- # Visualizers for iOS Xamarin Workbooks uses a different visualizers for inline code evaluation results: * String * Object * Color (`UIColor`) * Enumerable * Map (`CLLocation`) * Image (`UIImage`) * Argument * Html * Help By default, the results of a code-block will shown as a string representation of the *last-referenced object* in the block. The `Monkey` class below demonstrates this: when the `rupert` object is assigned, the **ToString** representation is printed after the code-block. ```csharp class Monkey { public string Name; public string Species; public string Habitat; public CoreLocation.CLLocation Location = null; public UIColor Color = null; public DateTime Birthday = DateTime.MinValue; public override string ToString(){ return $"{Name} the {Species} ({Habitat})"; //C# 6 } } var rupert = new Monkey {Name="Rupert", Species = "Xamarin", Habitat="San Francisco"}; ``` Use the popup menu to the right of the result to switch to the **Object Members** view. Most code-block results in Workbooks will have both \*\*ToString \*\*and **Object Members** display options. Color types are rendered with an example of the color: ```csharp rupert.Color = UIColor.Brown; ``` DateTime values have a number of display options, including a calendar view: ```csharp rupert.Birthday = new DateTime(2011,05,11); ``` Enumerable collections will be expanded so that you can explore their contents. You can also change the view of each individual object in the collection: ```csharp var enumerable = new List {"alpha", "beta", "gamma", "delta"}; ``` Location objects can be viewed on a map: ```csharp rupert.Location = new CoreLocation.CLLocation(37.7749,-122.4194); ``` Image data can be downloaded or opened from the local filesystem, then previewed inline with the **Image** view: ```csharp var localPath = "/Users/craigdunn/ProjectsConceptdev/xamarin-workbook-samples/Visualizers/"; UIImage.FromFile(localPath+"bridge.jpg"); ``` Exceptions have a custom display: ```csharp new ArgumentNullException ("name"); ``` HTML can also be emitted from code-blocks and rendered in the Workbook. This simple example uses string interpolation to customize an HTML string for display using `AsHtml()`: ```csharp var greeting = "Hello, Workbooks"; // C# 6 string interpolation $"

{greeting}

bold italic underline".AsHtml() ``` There’s also a `help` command, which just lists some handy tips. The help list is slightly different for each platform supported by Workbooks. ```csharp help ``` And finally, not really a visualization, but from the help above you can see that it’s possible to affect the culture of the Workbook. These code-blocks show the date rendered in English and then Spanish (after setting the `CurrentCulture`): ```csharp DateTime.Now.ToLongDateString() ``` ```csharp CurrentCulture = new System.Globalization.CultureInfo("es"); DateTime.Now.ToLongDateString() ``` ```csharp // reset to English CurrentCulture = new System.Globalization.CultureInfo("en"); ``` ================================================ FILE: workbooks/visualizers/Visualizers-mac.workbook ================================================ --- uti: com.xamarin.workbook platform: MacNet45 packages: [] --- # Visualizers for Mac Xamarin Workbooks uses a different visualizers for inline code evaluation results: * String * Object * Color (`NSColor`) * Enumerable * Map (`CLLocation`) * Image (`NSImage`) * Exception * Html * Help By default, the results of a code-block will shown as a string representation of the *last-referenced object* in the block. The `Monkey` class below demonstrates this: when the `rupert` object is assigned, the **ToString** representation is printed after the code-block. ```csharp class Monkey { public string Name; public string Species; public string Habitat; public CoreLocation.CLLocation Location = null; public NSColor Color = null; public DateTime Birthday = DateTime.MinValue; public override string ToString(){ return $"{Name} the {Species} ({Habitat})"; //C# 6 } } var rupert = new Monkey {Name="Rupert", Species = "Xamarin", Habitat="San Francisco"}; ``` Use the popup menu to the right of the result to switch to the **Object Members** view. Most code-block results in Workbooks will have both **ToString** and **Object Members** display options. Color types are rendered with an example of the color: ```csharp rupert.Color = NSColor.Brown; ``` DateTime values have a number of display options, including a calendar view: ```csharp rupert.Birthday = new DateTime(2011,05,11); ``` Enumerable collections will be expanded so that you can explore their contents. You can also change the view of each individual object in the collection: ```csharp var enumerable = new List {"alpha", "beta", "gamma", "delta"}; ``` Location objects can be viewed on a map: ```csharp rupert.Location = new CoreLocation.CLLocation(37.7749,-122.4194); ``` Image data can be downloaded or opened from the local filesystem, then previewed inline with the **Image** view: ```csharp var localPath = "/Users/craigdunn/ProjectsConceptdev/xamarin-workbook-samples/Visualizers/"; new NSImage(localPath+"bridge.jpg"); ``` Exceptions have a custom display: ```csharp new ArgumentNullException ("name"); ``` HTML can also be emitted from code-blocks and rendered in the Workbook. This simple example uses string interpolation to customize an HTML string for display using `AsHtml()`: ```csharp var greeting = "Hello, Workbooks"; // C# 6 string interpolation $"

{greeting}

bold italic underline".AsHtml() ``` There’s also a `help` command, which just lists some handy tips. The help list is slightly different for each platform supported by Workbooks. ```csharp help ``` And finally, not really a visualization, but from the help above you can see that it’s possible to affect the culture of the Workbook. These code-blocks show the date rendered in English and then Spanish (after setting the `CurrentCulture`): ```csharp DateTime.Now.ToLongDateString() ``` ```csharp CurrentCulture = new System.Globalization.CultureInfo("es"); DateTime.Now.ToLongDateString() ``` ```csharp // reset to English CurrentCulture = new System.Globalization.CultureInfo("en"); ``` ================================================ FILE: workbooks/visualizers/Visualizers-wpf.workbook ================================================ --- uti: com.xamarin.workbook platform: WPF packages: [] --- # Visualizers for WPF Xamarin Workbooks uses a different visualizers for inline code evaluation results: * String * Object * Color (`Color`) * Enumerable * Image (`Bitmap`) * Exception * Html * Help By default, the results of a code-block will shown as a string representation of the *last-referenced object* in the block. The `Monkey` class below demonstrates this: when the `rupert` object is assigned, the **ToString** representation is printed after the code-block. ```csharp class Monkey { public string Name; public string Species; public string Habitat; public System.Drawing.Color Color = System.Drawing.Color.White; public DateTime Birthday = DateTime.MinValue; public override string ToString(){ return $"{Name} the {Species} ({Habitat})"; //C# 6 } } var rupert = new Monkey {Name="Rupert", Species = "Xamarin", Habitat="San Francisco"}; ``` Use the popup menu to the right of the result to switch to the **Object Members** view. Most code-block results in Workbooks will have both \*\*ToString\*\* and **Object Members** display options. Color types are rendered with an example of the color: ```csharp rupert.Color = System.Drawing.Color.Brown; ``` DateTime values have a number of display options, including a calendar view: ```csharp rupert.Birthday = new DateTime(2011,05,11); ``` Enumerable collections will be expanded so that you can explore their contents. You can also change the view of each individual object in the collection: ```csharp var enumerable = new List {"alpha", "beta", "gamma", "delta"}; ``` Image data can be downloaded or opened from the local filesystem, then previewed inline with the **Image** view: ```csharp var localPath = @"C:\ProjectsConceptdev\xamarin-workbook-samples\Visualizers\"; new System.Drawing.Bitmap(localPath+"bridge.jpg"); ``` Exceptions have a custom display: ```csharp new ArgumentNullException ("name"); ``` HTML can also be emitted from code-blocks and rendered in the Workbook. This simple example uses string interpolation to customize an HTML string for display using `AsHtml()`: ```csharp var greeting = "Hello, Workbooks"; // C# 6 string interpolation $"

{greeting}

bold italic underline".AsHtml() ``` There’s also a `help` command, which just lists some handy tips. The help list is slightly different for each platform supported by Workbooks. ```csharp help ``` And finally, not really a visualization, but from the help above you can see that it’s possible to affect the culture of the Workbook. These code-blocks show the date rendered in English and then Spanish (after setting the `CurrentCulture`): ```csharp DateTime.Now.ToLongDateString() ``` ```csharp CurrentCulture = new System.Globalization.CultureInfo("es"); DateTime.Now.ToLongDateString() ``` ```csharp // reset to English CurrentCulture = new System.Globalization.CultureInfo("en"); ``` ================================================ FILE: workbooks/visualizers/meta.json ================================================ { "order":{ "Visualizers-console.workbook":"Visualizers for Console", "Visualizers-ios.workbook":"Visualizers for iOS", "Visualizers-mac.workbook":"Visualizers for Mac", "Visualizers-wpf.workbook":"Visualizers for WPF", } } ================================================ FILE: wpf/README.md ================================================ WPF Workbooks ============ * Getting Started * User Interface * Advanced ================================================ FILE: wpf/getting-started/HelloWPF.workbook ================================================ --- uti: com.xamarin.workbook platform: WPF packages: [] --- # Hello, WPF The Windows Presentation Foundation (WPF) is a powerful programming framework for creating traditional Windows desktop applications. WPF is ideal for industrial-strength Windows apps, and it has been very influential in the design of the Universal Windows Platform (UWP) and Xamarin.Forms. In this Workbook you’ll learn how to create a standard WPF `Window`and display a short text string using `TextBlock`. The first step is specifying several `using` directives for the some of the namespaces common in WPF programming: ```csharp using System; using System.Windows; using System.Windows.Controls; using System.Windows.Media; ``` You can then create a `Window` object and set the `Title` property. Calling the `Show` method of the `Window` object causes the window to appear on the desktop: ```csharp Window win = new Window(); win.Title = "My First WPF App"; win.Show(); ``` You can now create a `TextBlock` object. In WPF, you use `TextBlock` to display short text strings as well as entire paragraphs: ```csharp TextBlock txtblk = new TextBlock(); txtblk.Text = "Hello, WPF!"; ``` However, the text does not appear in the window until you set the `TextBlock` object to the `Content` property of the `Window`: ```csharp win.Content = txtblk; ``` The text appears in the upper-left corner of the window. You can make the text larger by setting the `FontSize` property: ```csharp txtblk.FontSize = 100; ``` You can choose a different font by setting the `FontFamily` property to an object of type `FontFamily`: ```csharp txtblk.FontFamily = new FontFamily("Gabriola"); ``` Try different font families such as “Times New Roman” or “Courier New” or “Comic Sans MS”. If the font family doesn’t exist on your installation of Windows, the default font is used instead. Until now, the text has appeared in the upper-left corner of the window. You can change that location using the `HorizontalAlignment` and `VerticalAlignment` properties that `TextBlock` inherits from the `FrameworkElement` class. You set these properties to members of the `HorizontalAlignment` and `VerticalAlignment` enumerations: ```csharp txtblk.HorizontalAlignment = HorizontalAlignment.Center; txtblk.VerticalAlignment = VerticalAlignment.Center; ``` You can set these properties to different enumeration values to position the text in any one of nine locations relative to the window. Try the `Left` and `Right` members of `HorizontalAlignment`, and the `Top` and `Bottom` members of `VerticalAlignment`. The `HorizontalAlignment` and `VerticalAlignment` properties play a crucial role in WPF layout. Interestingly, the default values of these two properties are `HorizontalAlignment.Stretch` and `VerticalAlignment.Stretch`, which cause the `TextBlock` to fill its container (the `Window`), but the text itself is positioned at the upper-left corner. You can also set the color of the text. Visual elements in WPF are often colored with various `Brush` objects that you can use to specify gradients or bitmap images. The simplest type of `Brush` is the `SolidColorBrush`, that you use with a `Color` value. You can create a `Color` value using various static methods of the `Color` structure, or you can specify one of the 141 static properties of the `Colors` class: ```csharp txtblk.Foreground = new SolidColorBrush(Colors.Blue); ``` Or, even more simply, you can specify one of the 141 static properties of the `Brushes` class: ```csharp txtblk.Background = Brushes.Yellow; ``` You’ll see that the background color appears in the space above and below the text. This background is sufficient to encompass text diacritical marks and descenders. It is interesting to go back and set the `HorizontalAlignment` or `VerticalAlignment` property (or both) to the default `Stretch` enumeration value to see the background color fill the window. This confirms that the `TextBlock` really is stretched to fill the interior of the window. You can also set the background of the `Window` object: ```csharp win.Background = Brushes.Yellow; ``` Setting the background color of the `Window` is much more common than setting the background color of the `TextBlock`. ================================================ FILE: wpf/getting-started/hello-wpf-workbook.workbook ================================================ --- uti: com.xamarin.workbook platform: WPF --- # WPF ```csharp var label = new System.Windows.Controls.Label { Content = "Hello, Workbooks", FontSize = 36 }; System.Windows.Application.Current.MainWindow.Content = label; ``` ================================================ FILE: wpf/getting-started/meta.json ================================================ { "order":{ "hello-wpf-workbook.workbook":"Hello, WPF", "HelloWPF.workbook":"Hello, WPF1" } } ================================================ FILE: wpf/meta.json ================================================ { "order":{ "getting-started":"Getting Started", "user-interface":"User Interface" } } ================================================ FILE: wpf/user-interface/graphics/PenroseTriangle.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook platform: WPF packages: [] --- # Drawing a Penrose Triangle ## An Introduction to WPF Shapes The Shapes library is the primary means of rendering 2D vector graphics in WPF. Shapes is a retained-mode graphics system. A WPF program doesn’t issue drawing commands — as might be the case in a conventional graphics drawing system — but instead creates objects of various graphical types, such as lines and polygons. The objects take responsibility for drawing themselves. The program can then alter or animate these objects by changing their properties. The Shapes library consists of one base class named `Shape` and six derived classes named `Line`, `Polyline`, `Polygon`, `Path`, `Rectangle`, and `Ellipse`, all in the `System.Windows.Shapes` namespace. The `Shape` class derives from `FrameworkElement`, so WPF treats the classes that derive from `Shape` much like `TextBlock`, `Button`, and `Slider`. Each of the instances of these classes has a size in layout that is based on the coordinates used to describe the figure. This workbook focuses on `Polygon`, which you can use for drawing figures consisting of connected straight lines. You define these lines with a series of `Point` values in a collection property named `Points`. You can stroke these lines with a particular brush, and you can fill enclosed areas with another brush. This workbook shows how you can assemble three `Polygon` objects for drawing an impossible figure known as a Penrose Triangle, which looks like this: ![](PenroseTriangle.png "Penrose Triangle") The two classes `Polygon` and `Polyline` are very similar. The only difference is that `Polygon` automatically adds a final line to the figure that connects the last point in the `Points` collection to the first point; `Polyline` does not. Generally you’ll need several `using` directives to begin working with the Shapes library: ```csharp using System; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Shapes; ``` As usual, you can begin by creating a `Window` with a title in its titlebar: ```csharp Window win = new Window(); win.Title = "Penrose Triangle"; win.Show(); ``` You can put instances of the Shapes classes in any type of WPF layout object, but generally you’ll use `Canvas` or a single-cell `Grid`. The `Grid` has the advantage of being able to size itself based on the composite size of the various `Shape` objects that it contains. The following code creates a `Grid` and sets it as the content of the `Window`: ```csharp Grid grid = new Grid(); win.Content = grid; ``` Now you can create a `Polygon` object and add it to the `Children` collection of the `Grid`: ```csharp Polygon polygon1 = new Polygon(); grid.Children.Add(polygon1); ``` You won’t see anything yet because there are no points in the `Point` collection. You need two points to draw a single line: ```csharp polygon1.Points.Add(new Point(40, 168)); polygon1.Points.Add(new Point(192, 168)); ``` These two `Point` values define a line from the point (40, 168) to the point (192, 168). All points are in the form (*x*, *y*) and are relative to the upper-left corner of the `Polygon` parent, which is the `Grid` that fills the whole window. Increasing values of *x* go to the right, and increasing values of *y* go down. But you *still* won’t see anything! The line exists but the default brush used to stroke the line is `null`. You need to set the `Stroke` property of `Polygon` to a `Brush` object. The easiest approach is to use one of the static read-only properties of the `Brushes` class. These properties return `SolidColorBrush` objects: ```csharp polygon1.Stroke = Brushes.Black; ``` Now you’ll see the line. WPF doesn’t draw in units of pixels. Instead, coordinates and sizes are based on 96 units to the inch, which means that a value of 192 is equivalent to two inches. You can increase the thickness of the line by setting the `StrokeThickness` property: ```csharp polygon1.StrokeThickness = 3; ``` Although the figure might appear to be a single line, it’s really not. As mentioned earlier, `Polygon` automatically connects the last point in the `Points` collection to the first point, so the figure consists of one line from (40, 168) to (192, 168) and a second line from (192, 168) back to (40, 168). This has some implications: At the two points where the two lines meet, a “line join” is drawn. By default this is a pointy miter join, and it extends beyond the geometric end of the line. In general you’ll want a more attractive and less troublesome rounded join: ```csharp polygon1.StrokeLineJoin = PenLineJoin.Round; ``` Did you see the line get a little shorter when you executed that statement? The fact that `Polygon` is automatically drawing a line to connect the last point with the first point becomes much more obvious when you add a third point to the `Points` collection. This point continues the polygon to the point (192, 168) for a three-sided figure. ```csharp polygon1.Points.Add(new Point(192, 192)); ``` `Polygon` always draws a closed figure. The tilted line on the bottom connects the third point (192, 192) with the first point (40, 168). With three points, you can also specify a brush to fill the interior of the figure: ```csharp polygon1.Fill = Brushes.DarkGray; ``` You can add a fourth point: ```csharp polygon1.Points.Add(new Point(0, 192)); ``` And a fifth: ```csharp polygon1.Points.Add(new Point(108, 2)); ``` And a final sixth point to complete this first figure: ```csharp polygon1.Points.Add(new Point(132, 2)); ``` The following code creates the second `Polygon` in its entirety. It slightly overlaps the first at the bottom right, so look at that area when you execute this code: ```csharp Polygon polygon2 = new Polygon(); polygon2.Points.Add(new Point(0, 192)); polygon2.Points.Add(new Point(192, 192)); polygon2.Points.Add(new Point(120, 60)); polygon2.Points.Add(new Point(134, 48)); polygon2.Points.Add(new Point(234, 216)); polygon2.Points.Add(new Point(12, 216)); polygon2.Stroke = Brushes.Black; polygon2.StrokeThickness = 3; polygon2.StrokeLineJoin = PenLineJoin.Round; polygon2.Fill = Brushes.LightGray; grid.Children.Add(polygon2); ``` The slight overlapping made the calculation of points for the first `Polygon` a little easier. When multiple `Shape` object overlap, the objects later in the `Children` collection might hide or obscure the objects earlier in the `Children` collection. This is known as Z-ordering, in reference to the Z axis that is conceptually perpendicular to the surface of the screen. Here’s the third `Polygon`: ```csharp Polygon polygon3 = new Polygon(); polygon3.Points.Add(new Point(40, 168)); polygon3.Points.Add(new Point(66, 168)); polygon3.Points.Add(new Point(134, 48)); polygon3.Points.Add(new Point(234, 216)); polygon3.Points.Add(new Point(246, 192)); polygon3.Points.Add(new Point(132, 2)); polygon3.Stroke = Brushes.Black; polygon3.StrokeThickness = 3; polygon3.StrokeLineJoin = PenLineJoin.Round; polygon3.Fill = Brushes.DimGray; grid.Children.Add(polygon3); ``` The Penrose Triangle is now complete. Every `Shape` object has a single stroke brush and a single fill brush. Whenever a composite graphics object requires multiple colors, each color must be a different `Shape` object. If you’d like to center the Penrose Triangle on the screen, you can’t set the `HorizontalAlignment` and `VerticalAlignment` properties on each `Polygon` because that would center each `Polygon` separately, and they’d no longer fit together properly. Instead, set the `HorizontalAlignment` and `VerticalAlignment` properties on the `Grid` itself: ```csharp grid.HorizontalAlignment = HorizontalAlignment.Center; grid.VerticalAlignment = VerticalAlignment.Center; ``` This causes the `Grid` to shrink down to encompass only the area required by all its children. For purposes of layout, the size of each `Shape` object is based on its maximum positive horizontal and vertical coordinates, as well as stroke thickness and line joins. Suppose you’d like to make the Penrose Triangle fill the `Window`. There’s an WPF class for that! The `Viewbox` class fills its parent container (in this case, the window), and stretches its child to be the same size. The `if` statement below is for some special code just for Workbooks that avoids problems when the four statements at the bottom of this code cell are re-executed. Those statements insert a `Viewbox` between the `Window` and the `Grid`: ```csharp // Special code to allow re-execution without causing an error if (grid.Parent is Viewbox) { (grid.Parent as Viewbox).Child = null; } // Set the Grid as a child of a Viewbox win.Content = null; Viewbox viewbox = new Viewbox(); viewbox.Child = grid; win.Content = viewbox; ``` And now the Penrose Triangle fills the window, and it changes size as you change the window size. ================================================ FILE: wpf/user-interface/meta.json ================================================ { "order":{ "graphics/PenroseTriangle.workbook":"Penrose Triangle", } } ================================================ FILE: xamarin-forms/README.md ================================================ Xamarin.Forms Workbooks ============ * Getting Started * User Interface * Application Fundamentals * Advanced ![](advanced/Screenshots/rpncalc.png) ================================================ FILE: xamarin-forms/advanced/MandelbrotTouch.workbook/BitmapInfo.csx ================================================ class BitmapInfo { public BitmapInfo(int pixelWidth, int pixelHeight, int[] iterationCounts) { PixelWidth = pixelWidth; PixelHeight = pixelHeight; IterationCounts = iterationCounts; } public int PixelWidth { private set; get; } public int PixelHeight { private set; get; } public int[] IterationCounts { private set; get; } } ================================================ FILE: xamarin-forms/advanced/MandelbrotTouch.workbook/BmpMaker.csx ================================================ using System; using System.IO; using System.Text; using Xamarin.Forms; public class BmpMaker { const int headerSize = 54; readonly byte[] buffer; public BmpMaker(int width, int height) { Width = width; Height = height; int numPixels = Width * Height; int numPixelBytes = 4 * numPixels; int fileSize = headerSize + numPixelBytes; buffer = new byte[fileSize]; // Write headers in MemoryStream and hence the buffer. using (MemoryStream memoryStream = new MemoryStream(buffer)) { using (BinaryWriter writer = new BinaryWriter(memoryStream, Encoding.UTF8)) { // Construct BMP header (14 bytes). writer.Write(new char[] { 'B', 'M' }); // Signature writer.Write(fileSize); // File size writer.Write((short)0); // Reserved writer.Write((short)0); // Reserved writer.Write(headerSize); // Offset to pixels // Construct BitmapInfoHeader (40 bytes). writer.Write(40); // Header size writer.Write(Width); // Pixel width writer.Write(Height); // Pixel height writer.Write((short)1); // Planes writer.Write((short)32); // Bits per pixel writer.Write(0); // Compression writer.Write(numPixelBytes); // Image size in bytes writer.Write(0); // X pixels per meter writer.Write(0); // Y pixels per meter writer.Write(0); // Number colors in color table writer.Write(0); // Important color count } } } public int Width { private set; get; } public int Height { private set; get; } public void SetPixel(int row, int col, Color color) { SetPixel(row, col, (int)(255 * color.R), (int)(255 * color.G), (int)(255 * color.B), (int)(255 * color.A)); } public void SetPixel(int row, int col, int r, int g, int b, int a = 255) { int index = (row * Width + col) * 4 + headerSize; buffer[index + 0] = (byte)b; buffer[index + 1] = (byte)g; buffer[index + 2] = (byte)r; buffer[index + 3] = (byte)a; } public ImageSource Generate() { // Create MemoryStream from buffer with bitmap. MemoryStream memoryStream = new MemoryStream(buffer); // Convert to StreamImageSource. ImageSource imageSource = ImageSource.FromStream(() => { return memoryStream; }); return imageSource; } } ================================================ FILE: xamarin-forms/advanced/MandelbrotTouch.workbook/Complex.csx ================================================ using System; // Mostly a subset of System.Numerics.Complex. public struct Complex : IEquatable, IFormattable { bool gotMagnitude, gotMagnitudeSquared; double magnitude, magnitudeSquared; public Complex(double real, double imaginary) : this() { Real = real; Imaginary = imaginary; } public double Real { private set; get; } public double Imaginary { private set; get; } // MagnitudeSquare and Magnitude calculated on demand and saved. public double MagnitudeSquared { get { if (gotMagnitudeSquared) { return magnitudeSquared; } magnitudeSquared = Real * Real + Imaginary * Imaginary; gotMagnitudeSquared = true; return magnitudeSquared; } } public double Magnitude { get { if (gotMagnitude) { return magnitude; } magnitude = Math.Sqrt(MagnitudeSquared); gotMagnitude = true; return magnitude; } } public static Complex operator +(Complex left, Complex right) { return new Complex(left.Real + right.Real, left.Imaginary + right.Imaginary); } public static Complex operator -(Complex left, Complex right) { return new Complex(left.Real - right.Real, left.Imaginary - right.Imaginary); } public static Complex operator *(Complex left, Complex right) { return new Complex(left.Real * right.Real - left.Imaginary * right.Imaginary, left.Real * right.Imaginary + left.Imaginary * right.Real); } public static bool operator ==(Complex left, Complex right) { return left.Real == right.Real && left.Imaginary == right.Imaginary; } public static bool operator !=(Complex left, Complex right) { return !(left == right); } public static implicit operator Complex(double value) { return new Complex(value, 0); } public static implicit operator Complex(int value) { return new Complex(value, 0); } public override int GetHashCode() { return Real.GetHashCode() + Imaginary.GetHashCode(); } public override bool Equals(Object value) { return Real.Equals(((Complex)value).Real) && Imaginary.Equals(((Complex)value).Imaginary); } public bool Equals(Complex value) { return Real.Equals(value) && Imaginary.Equals(value); } public override string ToString() { return String.Format("{0} {1} {2}i", Real, RealImaginaryConnector(Imaginary), Math.Abs(Imaginary)); } public string ToString(string format) { return String.Format("{0} {1} {2}i", Real.ToString(format), RealImaginaryConnector(Imaginary), Math.Abs(Imaginary).ToString(format)); } public string ToString(IFormatProvider formatProvider) { return String.Format("{0} {1} {2}i", Real.ToString(formatProvider), RealImaginaryConnector(Imaginary), Math.Abs(Imaginary).ToString(formatProvider)); } public string ToString(string format, IFormatProvider formatProvider) { return String.Format("{0} {1} {2}i", Real.ToString(format, formatProvider), RealImaginaryConnector(Imaginary), Math.Abs(Imaginary).ToString(format, formatProvider)); } string RealImaginaryConnector(double value) { return Math.Sign(value) > 0 ? "+" : "\u2013"; } } ================================================ FILE: xamarin-forms/advanced/MandelbrotTouch.workbook/FormsInit.csx ================================================ #r "Xamarin.Forms.Core" #r "Xamarin.Forms.Xaml" #r "Xamarin.Forms.Platform" using System; using Xamarin.Forms; var page = new ContentPage(); StackLayout stackLayout = new StackLayout { Margin = new Thickness(0, 20, 0, 0) }; page.Content = stackLayout; Application.Current.MainPage = page; ================================================ FILE: xamarin-forms/advanced/MandelbrotTouch.workbook/Mandelbrot.png.txt ================================================ The Mandelbrot.png file is from the Wikipedia article: https://en.wikipedia.org/wiki/Mandelbrot_set Here is the page that describes this particular image: https://en.wikipedia.org/wiki/Mandelbrot_set#/media/File:Mandel.png It is accompanied by the following: "This work has been released into the public domain by its author, Elphaba at Catalan Wikipedia. This applies worldwide. In some countries this may not be legally possible; if so: Elphaba grants anyone the right to use this work for any purpose, without any conditions, unless such conditions are required by law." The image used here has been reduced to 50% of its original size. ================================================ FILE: xamarin-forms/advanced/MandelbrotTouch.workbook/MandelbrotModel.csx ================================================ #load "Complex.csx" #load "BitmapInfo.csx" using System; using System.Threading; using System.Threading.Tasks; class MandelbrotModel { public Task CalculateAsync(Complex Center, double width, double height, int pixelWidth, int pixelHeight, int iterations, IProgress progress, CancellationToken cancelToken) { return Task.Run(() => { int[] iterationCounts = new int[pixelWidth * pixelHeight]; int index = 0; for (int row = 0; row < pixelHeight; row++) { progress.Report((double)row / pixelHeight); cancelToken.ThrowIfCancellationRequested(); double y = Center.Imaginary - height / 2 + row * height / pixelHeight; for (int col = 0; col < pixelWidth; col++) { double x = Center.Real - width / 2 + col * width / pixelWidth; Complex c = new Complex(x, y); if ((c - new Complex(-1, 0)).MagnitudeSquared < 1.0 / 16) { iterationCounts[index++] = -1; } // http://www.reenigne.org/blog/algorithm-for-mandelbrot-cardioid/ else if (c.MagnitudeSquared * (8 * c.MagnitudeSquared - 3) < 3.0 / 32 - c.Real) { iterationCounts[index++] = -1; } else { Complex z = 0; int iteration = 0; do { z = z * z + c; iteration++; } while (iteration < iterations && z.MagnitudeSquared < 4); if (iteration == iterations) { iterationCounts[index++] = -1; } else { iterationCounts[index++] = iteration; } } } } return new BitmapInfo(pixelWidth, pixelHeight, iterationCounts); }, cancelToken); } } ================================================ FILE: xamarin-forms/advanced/MandelbrotTouch.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook id: D13B7651-1663-4030-A55F-903A3893773D title: Mandelbrot with Xamarin.Forms platforms: - Android - iOS packages: - id: Xamarin.Forms version: 2.5.0.121934 --- # Mandelbrot Touch In 1980, while working at an IBM research center, Polish born mathematician Benoit Mandelbrot saw a crude computer-generated image that had been published two years earlier: ![From the public domain image on the Wikipedia article on the Mandelbot Set.](Mandelbrot.png "The Mandelbrot Set") Mandelbrot had already been researching complex self-similar geometries for several years. In 1975 he had coined the word *fractal* in connection with his work and wrote a book on the subject: *Les Objects Fractals: Forme, Hasard et Dimension*, later translated as *Fractals: Forms, Chance and Dimension*. Mandelbrot eventually did so much research into the mathematics bethind this particular image that it became known as the *Mandelbrot set*. The program described in this workbook draws a more detailed (and colored) rendition of the Mandelbrot set. You can pan the image with your fingers or use a pinch gesture to zoom in and out. ## The Mandelbrot Math The Mandelbrot set is graphed on the complex plane, where each point is a complex number of the form: c = x \+ y*i* In the complex plane, the real part (x) of a complex number is represented by the horizontal axis, and the imaginary part (y) by the vertical axis. In the image shown above, the point between the small circle on the left and the large cardiod is  –0.75 \+ 0*i*. To calculate the Mandebrot set, begin by taking any complex point on this plane and call it c: c = x \+ y*i* Initialize the complex number z to zero: z = 0 Now perform the following recursive calculation: z ← z² \+ c The result will either diverge to infinity or it will not. If z does not diverge to infinity, then c is is said to be a member of the Mandelbrot set. (These points are indicated in the diagram above with asterisks.) Otherwise the complex number is not a member of the Mandelbrot set. This operation must be repeated for every point of interest in the complex plane. Sometime the recursive calculation must be performed very many times to determine if z diverges or not. If the absolute value of z ever becomes 2 or greater, than the values will eventually diverge to infinity. But otherwise, the only way to determine if a point is a member of the Mandelbrot set or not is to continue performing the recursive calculations. For that reason, Mandelbrot calculations are notoriously computation-intensive and are best performed in secondary threads of execution. It has become common for programs that display Mandelbrot sets to incorporate color. Points that are members of the Mandelbrot set are colored black. Points that are not members are given a color based on the number of iterations required to determine that the calculation will diverge to infinity. The program described here uses a bitmap to render the Mandelbrot set. The recursive calculation is performed on each complex point that corresponds to each pixel of the bitmap. The bitmap must be entirely created before it is displayed on the screen. ## The Code Support This workbook includes several C# Script files for support: ```csharp #load "MandelbrotModel.csx" #load "BmpMaker.csx" #load "FormsInit.csx" ``` The MandelbrotModel.csx file contains a class named `MandelbrotModel` with a single asynchronous method named `CalculateAsync` that performs the basic Mandelbort calculation for an array of points. The results are later used to create a bitmap, so several parameters to this method indicate the pixel size of this bitmap, and the complex coordinates corresponding to that array of pixels. The `CalculateAsync` method makes use of a structure named `Complex` that is defined in the Complex.csx file. The Mandelbrot.csx file contains a `#load` command for Complex.csx. The method returns an object of type `Task`. The `BitmapInfo` class (defined in BitmapInfo.csx) contains sufficient information to create a bitmap to render the results of the Mandelbrot calculation — a pixel width and height, and an array of integers indicating the number of iterations that were required for each point to determine that the point was not a member of the Mandelbrot set, or –1 if the point is a member. The BmpMaker.csx file contains a class name `BmpMaker` (“bitmap maker”) that creates a Xamarin.Forms `ImageSource` object based on the BMP file format. More information on these classes (and the Mandelbrot calculation itself) can be found in [Chapter 13 (Bitmaps)](https://developer.xamarin.com/guides/xamarin-forms/creating-mobile-apps-xamarin-forms/summaries/chapter13 "Chapter 13. Bitmaps") and [Chapter 20 (Async and File I/O)](https://developer.xamarin.com/guides/xamarin-forms/creating-mobile-apps-xamarin-forms/summaries/chapter20 "Chapter 20. Async and File I/O") of the book *[Creating Mobile Apps with Xamairn.Forms](https://developer.xamarin.com/guides/xamarin-forms/creating-mobile-apps-xamarin-forms/ "Creating Mobile Apps with Xamarin.Forms")*. Finally, the FormsInit-iOS.csx file contains startup code for a Xamarin.Forms program running under iOS. At the conclusion of that code, a variable named `page` is available of type `ContentPage`. ## Building the User Interface Just a few standard `using` directives are required: ```csharp using System; using System.Threading; using Xamarin.Forms; ``` Set some `Padding`on the page that also guards against overwriting the iOS status bar: ```csharp page.Padding = new Thickness(5, Device.OnPlatform(20, 5, 5), 5, 10); ``` The main layout is a three-row `Grid`. The top row is allocated all the space that is not required by the other two rows: ```csharp var grid = new Grid(); grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) }); grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto }); grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto }); page.Content = grid; ``` The top row is for the bitmap, which in Xamarin.Forms is displayed by an `Image` element. However, for purposes of handling touch gestures, the program makes this `Image` element a child of a `ContentView` named `gestureContainer`. Notice that the `for` loop at the top of this code cell first removes a `ContentView` from the `Children` collection of the `Grid` if this code is re-executed: ```csharp // Avoid multiple ContentView elements if this code is re-executed for (int i = 0; i < grid.Children.Count; i++) { if (grid.Children[i] is ContentView) { grid.Children.RemoveAt(i); i--; } } var image = new Image(); var gestureContainer = new ContentView(); gestureContainer.Content = image; gestureContainer.IsClippedToBounds = true; grid.Children.Add(gestureContainer, 0, 0); ``` This `gestureContainer` allows the progrm to obtain gesture input that affects the `Image` element. See the guides for [Xamarin.Forms gestures](https://developer.xamarin.com/guides/xamarin-forms/user-interface/gestures/ "Gestures") for more details about using such a container. The second row of the `Grid` contains a `ProgressBar` to show the progress of each complete Mandelbrot calculation. Again, any previous `ProgressBar` is removed first: ```csharp // Avoid multiple ProgressBar elements if this code is re-executed for (int i = 0; i < grid.Children.Count; i++) { if (grid.Children[i] is ProgressBar) { grid.Children.RemoveAt(i); i--; } } var progressBar = new ProgressBar(); grid.Children.Add(progressBar, 0, 1); ``` When you first execute that code, you should see the `ProgressBar` appear as a dim gray line near the bottom of the screen. This `ProgressBar` must be updated in the `CalculateAsync` method of the `MandelbrotModel` class. Because this method runs in a secondary thread of execution, the safest way of updating the `ProgressBar` involves instantiating a class specifically for this purpose named `Progress`: ```csharp var progressReporter = new Progress(progress => progressBar.Progress = progress); ``` A lambda function is passed to the `Progress` constructor that updates the `ProgressBar` from an argument to the function. ## The Mandelbrot Calculation Next are some constants and variables that define the Mandelbrot image. Taken together, the `baseSize`, `center`, and `magnification` arguments indicate that the initial Mandelbrot image will have real coordinates ranging from –2.0 (on the left edge of the bitmap) to 0.5 (on the right edge), and imaginary coordinates from 1.25 on the top to –1.25 on the bottom. However, the actual range in either the horizontal or vertical direction will be larger than that depending on the aspect ratio of the bitmap: ```csharp static readonly Size baseSize = new Size(2.5, 2.5); Complex center = new Complex(-0.75, 0); double magnification = 1.0; ``` The `center` variable will change when the image is panned; the `magnification` variable changes as the image is zoomed. The `iterations` variable indicates the number of recursive calculations performed before the point is assumed to be in the Mandelbrot Set. The `pixelsPerUnit` variable is calculated by a method later in this workbook based on the pixel size of the bitmap: ```csharp int iterations = 256; double pixelsPerUnit = 0; ``` Finally, the `MandelbrotModel` class is instantiated to perform the actual calculation. ```csharp var mandelbrotModel = new MandelbrotModel(); ``` Recall that this class is defined in the MandelbrotModel.csx C# script file. The `CreateNewImage` method brings all the parts of the calculation together by calling the `CalculateAsync` method in the `MandelbrotModel` instance and then constructing a bitmap from that information. The `CalculateAsync` method is in a `try` and `catch` block to allow the method to gracefully terminate if the asynchronous operation has been cancelled. You’ll see shortly how this `CalculateAsync` method is cancelled if a different calculation must supersede it: ```csharp async void CreateNewImage(CancellationToken cancelToken) { double aspect = image.Width / image.Height; double width = baseSize.Width / magnification * (aspect > 1 ? aspect : 1); double height = baseSize.Height / magnification / (aspect < 1 ? aspect : 1); pixelsPerUnit = image.Width / width; BitmapInfo bitmapInfo = null; try { bitmapInfo = await mandelbrotModel.CalculateAsync(center, width, height, (int)image.Width, (int)image.Height, iterations, progressReporter, cancelToken); } catch (OperationCanceledException) { return; } BmpMaker bmpMaker = new BmpMaker(bitmapInfo.PixelWidth, bitmapInfo.PixelHeight); int index = 0; for (int row = 0; row < bitmapInfo.PixelHeight; row++) { for (int col = 0; col < bitmapInfo.PixelWidth; col++) { int iterationCount = bitmapInfo.IterationCounts[index++]; // In the Mandelbrot set: Color black. if (iterationCount == -1) { bmpMaker.SetPixel(row, col, 0, 0, 0); } // Not in the Mandelbrot set: Pick a color based on count. else { bmpMaker.SetPixel(row, col, Color.FromHsla(iterationCount / 64.0 % 1.0, 1.0, 0.5)); } } } image.Source = bmpMaker.Generate(); image.TranslationX = 0; image.TranslationY = 0; image.Scale = 1; } ``` The following code calls `CreateNewImage` for the first time to create the image with the default settings: ```csharp CancellationTokenSource cancelTokenSource = new CancellationTokenSource(); CreateNewImage(cancelTokenSource.Token); ``` You should see the `ProgressBar` go from minimum to maximum and then the image will appear. The bitmap should be recomputed if the size of the `Image` element changes. On mobile platforms this happens mostly when the orientation of the phone changes from portrait to landscape: ```csharp // Remove the previous SizeChanged handler if the code is being reexecuted. image.SizeChanged -= OnSizeChanged; // Attach the SizeChanged handler image.SizeChanged += OnSizeChanged; void OnSizeChanged(object sender, EventArgs args) { if (gestureContainer.Width > 0 && gestureContainer.Height > 0) { cancelTokenSource.Cancel(); cancelTokenSource = new CancellationTokenSource(); CreateNewImage(cancelTokenSource.Token); } } ``` Now when you switch the orienttion of the simulator between portrait and landscape, the bitmap will be recreated. In the course of experimenting with the workbook, the code in the cell that sets the `SizeChanged` handler might be executed more than once. For that reason, the `OnSizeChanged` handler is first detached from the `SizeChanged` event if code has been executed previously. This ensures that the `SizeChanged` event has only one attached handler. Notice also that the `Cancel` method is called on the previous `CancellationTokenSource`. If the `CalculateAsync` method is curently running, this will cancel it. Then the `OnSizeChanged` handler creates a new `CancellationTokenSource` for calling `CreateNewImage` again. If the orientation of the phone is changed before the image has finished being calculated, that calculation will be interrupted and a new one begun. This same strategy is used for implementing the two different types of touch gestures — pan and pinch. ## Panning the Image In the next two code cells, the workbook adds `GestureRecognizer` objects to the `GestureRecognizers` collection property of the `ContentView` named `gestureContainer`. The handlers for these `GestureRecognizer` objects then uses the information associated with the gestures to apply transforms to the `gestureContainer`’s child, the `Image` element. When the gesture is complete, a new bitmap is calculated. The program instantiates two classes that derive from `GestureRecognizer` — `PanGestureRecognizer` and `PinchGestureRecognizer`. The code cell below begins by removing any existing `PanGestureRecognizer` from the `GestureRecognizers` collection; this is a precaution if the code is re-executed: ```csharp // Avoid multiple gesture recognizers when the code is re-executed for (int i = 0; i < gestureContainer.GestureRecognizers.Count; i++) { if (gestureContainer.GestureRecognizers[i] is PanGestureRecognizer) { gestureContainer.GestureRecognizers.RemoveAt(i); i--; } } var pan = new PanGestureRecognizer(); gestureContainer.GestureRecognizers.Add(pan); double translationX = 0; double translationY = 0; pan.PanUpdated += (sender, args) => { switch (args.StatusType) { case GestureStatus.Started: cancelTokenSource.Cancel(); translationX = image.TranslationX; translationY = image.TranslationY; break; case GestureStatus.Running: image.TranslationX = translationX + args.TotalX; image.TranslationY = translationY + args.TotalY; break; case GestureStatus.Completed: center = new Complex(center.Real - image.TranslationX / pixelsPerUnit, center.Imaginary + image.TranslationY / pixelsPerUnit); cancelTokenSource = new CancellationTokenSource(); CreateNewImage(cancelTokenSource.Token); break; } }; ``` The `PanUpdated` handler performs different processing based on the `StatusType` property, which indicates if the pan gesture is starting, in progress, or completed. If the pan gesture is just starting, the code cancels any calculation that might be in progress because a new one will be started when the gesture is complete. While the pan gesture is in progress (indicated by a status of `Running`), the code alters the `TranslationX` and `TranslationY` properties based on the total pan offest during this gesture. This causes part of the bitmap to be moved offscreen. At the end of the gesture (when the user removes a finger from the screen), the code recalculates the `center` variable and calls `CreateNewImage` to create a new bitmap based on that center. Notice that if the `CreateNewImage` method (shown earlier) is allowed to run to completion, then it concludes by setting the `TranslationX` and `TranslationY` properties back to their default values of 0 because the new bitmap has been calculated based on those translation factors, and it replaces the previous translated bitmap. ## Pinching the Image The program uses a similar strategy for pinch gestures, first removing the previous `PinchGestureRecognizer` object from the `GestureRecognizers` collection if the code is re-executed. As with the `PanGestureRecognizer`, the `PinchGestureRecognizer` event includes a property that indicates if the gesture is starting, running, or completed. The code here alters the `Scale` property of the `Image`. This property has a default value of 1, and each call to the `PinchUpdated` method is an additional scaling factor for that event: ```csharp // Avoid multiple gesture recognizers when code is re-executed for (int i = 0; i < gestureContainer.GestureRecognizers.Count; i++) { if (gestureContainer.GestureRecognizers[i] is PinchGestureRecognizer) { gestureContainer.GestureRecognizers.RemoveAt(i); i--; } } var pinch = new PinchGestureRecognizer(); gestureContainer.GestureRecognizers.Add(pinch); double scale = 1; pinch.PinchUpdated += (sender, args) => { switch (args.Status) { case GestureStatus.Started: cancelTokenSource.Cancel(); scale = image.Scale; break; case GestureStatus.Running: image.Scale += (args.Scale - 1) * scale; break; case GestureStatus.Completed: magnification *= image.Scale; cancelTokenSource = new CancellationTokenSource(); CreateNewImage(cancelTokenSource.Token); break; } }; ``` Similar to the pan gesture, the gesture concludes with a recalculation of the `magnification` variable for a new bitmap calculation. The `CreateNewImage` method concludes by setting the `Scale` property of the `Image` element back to 1. This pinch-gesture code shown here demontrates a simplified approach to `PinchUpdated` processing. In this implementation, all the zooming is relative to the center of the image. It’s possible to use an additional event argument of type `Point` named `ScaleOrigin` to compute a scaling center based on the position of the two fingers performing the pinch operation. See the [PinchGesture sample](https://developer.xamarin.com/samples/xamarin-forms/WorkingWithGestures/PinchGesture/ "PinchGesture sample") for a more complex approach. ## Adjusting the Iterations An earlier code cell defined an `iterations` variable with a value of 128, which is passed to the `CalculateAsync` method of `MandelbrotModel`. This is the maximum number of iterative calculations performed before the program assumes that a point will not diverge and hence is a member of the Mandelbrot set. As you zoom into the image more and more, you’ll generally need more iterations to see the detail. The final enhancement to the program is the addition of a `Stepper` element with some text to display the values. This allows you to increase or decrease the number of iterations by powers of two: ```csharp // Avoid multiple Stepper elements if the code is re-executed for (int i = 0; i < grid.Children.Count; i++) { if (grid.Children[i] is StackLayout) { grid.Children.RemoveAt(i); i--; } } var stepperStack = new StackLayout { Orientation = StackOrientation.Horizontal }; var labelStack = new StackLayout { Orientation = StackOrientation.Horizontal, VerticalOptions = LayoutOptions.Center, Spacing = 0 }; stepperStack.Children.Add(labelStack); labelStack.Children.Add(new Label { Text = "Iterations = 2", FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Label)) }); int exponent = (int)Math.Round(Math.Log(iterations) / Math.Log(2)); Label exponentLabel = new Label { Text = exponent.ToString(), FontSize = Device.GetNamedSize(NamedSize.Micro, typeof(Label)) }; labelStack.Children.Add(exponentLabel); var iterationsStepper = new Stepper { Value = exponent, VerticalOptions = LayoutOptions.Center }; iterationsStepper.ValueChanged += (sender, args) => { int exponent = (int)(sender as Stepper).Value; exponentLabel.Text = exponent.ToString(); iterations = (int)Math.Pow(2, exponent); cancelTokenSource.Cancel(); cancelTokenSource = new CancellationTokenSource(); CreateNewImage(cancelTokenSource.Token); }; stepperStack.Children.Add(iterationsStepper); grid.Children.Add(stepperStack, 0, 2); ``` The `ValueChanged` handler at the bottom of the code cell updates the `Label`, sets the `iterations` variable, cancels any calculation currently in progress, and starts a new one. You can also decrease the maximum number of iteratons to see the effect. When only a few iterations are allowed, the Mandelbrot set loses its crisp definition and doesn’t provide much more information than the original graphic published in 1978. ================================================ FILE: xamarin-forms/advanced/RPNCalculator/README.md ================================================ RPN Calculator Workbook ============ Step-by-step examination of building a complete iOS application ![](Screenshots/rpncalc.png) ================================================ FILE: xamarin-forms/advanced/RPNCalculator/RpnCalculator-ios.workbook ================================================ --- uti: com.xamarin.workbook platform: iOS packages: [] --- # Building a Xamarin.Forms RPN Calculator (iOS) > ⚠️ This workbook is deprecated - see **RpnCalculator.workbook** instead This workbook describes how to use the `Grid` layout in Xamarin.Forms as the foundation for a calculator. The `Grid` arranges visual elements in rows and columns, so it is ideal for arranging the calculator buttons and elements on the page. To keep the operational logic reasonably simple, this calculator uses Reverse Polish notation (RPN). ## What is RPN? Around the year 1924, Polish mathematician Jan Łukasiewicz (1878 – 1956) developed a type of notation for logic and arithmetic operations that did not require the use of parentheses. For example, the expression 5 × (3 \+ 4) – 2 is written in Łukasiewicz’s notaton like this – × 5 \+ 3 4 2 This statement is evaluated starting from the end of the expression. It’s convenient to use the last-in-first-out storage mechanism known as the *stack*. The numbers (starting from the end of the expression) are pushed on a stack. Every time one of the operators is encountered, the two numbers at the top of the stack are popped, and the operator is applied to them. The result is pushed back on the stack. In this example, 2, 4, and 3 are pushed on the stack, and then the plus sign causes 4 and 3 to be popped from the stack and 7 to be pushed on the stack. Now 5 is pushed on the stack, but the multiplication causes 5 and 7 to be popped from the stack and the product, 35, is pushed on the stack. Now the minus sign causes 35 and 2 to be popped from the stack, and the result is 33. This is sometimes known as *prefix notation*, but in honor of its inventor — and because his name can be challenging to spell — it’s often called *Polish notation*. In the digital computer age, it was realized that it makes more sense to evaluate an expression from the beginning (particularly if the expression can grow as it’s being evaluated), and Reverse Polish notation was born. In RPN (also called postfix notation), the above expression is written as: 5 3 4 \+ × 2 – Now the numbers from left to write are pushed on a stack, and a binary operation causes the top two numbers on the stack to be popped, and the result to be pushed on the stack. Because multiplication is commutative, the statement can also be written as: 3 4 \+ 5 × 2 – During the 1970s and 1980s, some popular calculators used RPN, most notably those manufactured by Hewlett-Packard. Many people with a mathematical or computer bent remain fans of RPN to this day. The Calculator program included with recent versions of macOS has an RPN mode. RPN calculators are characterized by the presence of an **Enter** button rather than an **=** button or parentheses buttons. Pressing the **Enter** key indicates that the number being typed by the user is ready to be pushed on the internal stack. When programming a calculator, basing it on RPN simplifies the operational logic considerably. Very little state information needs to be maintained other than the stack. In a Xamarin.Forms program, you can use a `Stack` object for this purpose. ## The iOS Prerequisites As usual, a Xamarin.Forms workbook requires the Xamairn.Forms NuGet package. This packages has already been added to this workbook, but for a new Xamarin.Forms workbook, you can add it by invoking the **File** and **Add Package** menu item and searching for **Xamarin.Forms**. Now use the **#r** command to reference the following Xamarin.Forms assemblies: ```csharp #r "Xamarin.Forms.Core" #r "Xamarin.Forms.Xaml" #r "Xamarin.Forms.Platform" #r "Xamarin.Forms.Platform.iOS" ``` You’ll also want a few standard `using` directives: ```csharp using System; using System.Collections.Generic; // for Stack using Xamarin.Forms; using Xamarin.Forms.Platform.iOS; ``` A Xamarin.Forms application requies a class that derives from `Application` that instantiates a `Page` object in its constructor. This `App` class instantiates a `ContentPage`: ```csharp class App : Application { public App() { MainPage = new ContentPage(); } } ``` The standard iOS startup code makes a call to the static `Forms.Init` method, and then instantiates the `App` class. An iOS `ViewController` is obtained from the created page: ```csharp Forms.Init(); App app = new App(); ContentPage page = app.MainPage as ContentPage; KeyWindow.RootViewController = page.CreateViewController(); ``` With that code, the Xamarin.Forms `ContentPage` is displayed. ## Grid Rows and Columns The calculator consists of `Button` elements to enter numbers and operations, and `Label` elements to display intermediate and final results. Each of these elements occupies one or more cells of a `Grid`, which divides the area it occupies into rows and columns. You can create the `Grid` and set it to the `Content` property of the `ContentPage` like this: ```csharp var mainGrid = new Grid(); page.Content = mainGrid; ``` The `Grid` occupies the entire area of the page, but it’s invisible by default so you can’t see it. You might want to temporarily set the background color of the `Grid` by replacing the `Transparent` identifier below with one of the Xamarin.Forms colors (such as `Yellow`): ```csharp mainGrid.BackgroundColor = Color.Transparent; ``` The calculator buttons will look a little better if you give the entire page some padding that provides a little blank space around the perimeter. Also, for iOS, you’ll want to add 20 units padding on the top to avoid overwriting the iOS status bar: ```csharp page.Padding = new Thickness(10, 10 + Device.OnPlatform(20, 0, 0), 10, 10); ``` Alternatively, you can set the `Margin` property of the `mainGrid` object. Generally you explicitly specify the number of rows and columns in the `Grid` using objects of type `RowDefinition` and `ColumnDefinition`. You add these objects to the `RowDefinitions` and `ColumnDefinitions` collection properties of the `Grid`. The following code creates twelve `RowDefinition` objects. `RowDefinition` has a `Height` property that you set to a value of type `GridLength`: ```csharp // Remove previous RowDefinition objects on re-execution: mainGrid.RowDefinitions.Clear(); mainGrid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto }); mainGrid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto }); for (int row = 0; row < 10; row++) { mainGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) }); } ``` The `GridLength.Auto` constant indicates that the height is based on the height of the elements in that row. As you’ll see, those two rows are used for `Label` element. The `GridUnitType.Star` enumeration member indicates that remaining space is allocated proportionally among rows with that height indication. These ten rows are for `Button` elements, and ensures that they all have the same height. Another option is `GridUnitType.Absolute` for a specific height in device-independent units. The following code gives the `Grid` four columns of equal width: ```csharp // Remove previous ColumnDefinition objects on re-execution: mainGrid.ColumnDefinitions.Clear(); for (int col = 0; col < 4; col++) { mainGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) }); } ``` The `Grid` provides space between adjacent cells based on the `RowSpacing` and `ColumnSpacing` properties. These properties have default values of 6 units. ## Entering Numbers The calculator needs a `Label` to display the number that the user enters. This `Label` is given a light-gray background color to make it stand out. The `HorizontalTextAlignment` setting causes the text to be right-justified within the `Label`: ```csharp Label entryLabel = new Label { Text = "0", BackgroundColor = new Color(0.85), HorizontalTextAlignment = TextAlignment.End }; mainGrid.Children.Add(entryLabel, 0, 4, 1, 2); ``` The final statement adds the `Label` to the `Children` collection of the `Grid`. Notice the four numeric arguments to the `Add` statement. These four parameters are named `left`, `right`, `top`, and `bottom`, and specify the cell or cells that the element occupies. Column and row numbering is zero-based. If the element is in one cell, only the `left` and `top` arguments are required. The `right` and `bottom` arguments indicate the column and row beyond the last column or row that the element occupies. The `left` and `right` values of 0 and 4 indicate that the `Label` occupies columns 0, 1, 2, and 3, which is the full width of the `Grid`. The `top` and `bottom` values of 1 and 2 indicate that the `Label` occupies row 1, which is the second row of the `Grid`. When you execute that code, you’ll see the `Label` displayed in the `Grid`. The next step is to create some buttons, but first consider that not every button press is invalid. For example, when entering a number, you can’t press the decimal point twice. The following static `Beeper.Error` method is iOS specific and is intended to notify the user of an invalid button press: ```csharp static class Beeper { static AudioToolbox.SystemSound systemSound = systemSound = new AudioToolbox.SystemSound(1000); public static void Error() { systemSound.PlaySystemSound(); } } ``` A calculator number pad has ten `Button` elements for the digits 0 through 9, and another `Button` for the decimal point. One approach to creating several similar elements for a `Grid` is to first define an array of `Tuple` objects. The following tuples indicate the text for each `Button` in the number pad, and the row and column numbers. The `span` value is the number of columns the `Button` occupies: ```csharp var numButtonInfos = new[] { new { text = "7", row = 7, col = 0, span = 1 }, new { text = "8", row = 7, col = 1, span = 1 }, new { text = "9", row = 7, col = 2, span = 1 }, new { text = "4", row = 8, col = 0, span = 1 }, new { text = "5", row = 8, col = 1, span = 1 }, new { text = "6", row = 8, col = 2, span = 1 }, new { text = "1", row = 9, col = 0, span = 1 }, new { text = "2", row = 9, col = 1, span = 1 }, new { text = "3", row = 9, col = 2, span = 1 }, new { text = "0", row = 10, col = 0, span = 2 }, new { text = ".", row = 10, col = 2, span = 1 } } ``` Creating the eleven `Button` elements can now be handled in a loop: ```csharp foreach (var numButtonInfo in numButtonInfos) { var button = new Button { Text = numButtonInfo.text, Margin = new Thickness(5) }; button.Clicked += (sender, args) => { string text = entryLabel.Text == "0" ? "" : entryLabel.Text; text += (sender as Button).Text; if (text == ".") { text = "0."; } double number; if (Double.TryParse(text, out number)) { entryLabel.Text = text; } else { Beeper.Error(); } }; mainGrid.Children.Add(button, numButtonInfo.col, numButtonInfo.col + numButtonInfo.span, numButtonInfo.row, numButtonInfo.row + 1); } ``` The `Clicked` handler appends the text of the pressed `Button` to the `Text` property of the `entryLabel` object. It uses the `Double.TryParse` method to determine if the new text string is a valid representation of a number. Only a couple special cases need to be handled: You can’t begin by typing a series of zeroes, and if you begin with a decimal point, a zero is automatically prepended. At this point, you can type numbers into the calculator but there’s no way to backspace, so the numbers keep getting longer. A Xamarin.Forms `Button` in an iOS program doesn’t have a border by default, so these number keys don’t look much like actual buttons. Setting the `BorderWidth` property can fix that. It can be done in the code above, or a uniform property setting can be applied to visual elements by defining a `Style` object. The first step is to instantiate a `ResourceDictionary` for the page: ```csharp var resourceDictionary = new ResourceDictionary(); page.Resources = resourceDictionary; ``` The following `Style` object has a target type of `Button` (specified in its constructor) and includes a `Setter` object that associates the `ButtonWidthProperty` bindable property with a value of 1: ```csharp var buttonStyle = new Style(typeof(Button)); buttonStyle.Setters.Add(new Setter { Property = Button.BorderWidthProperty, Value = 1 }); ``` The following code adds the `Style` object to the `ResourceDictionary` but without specifying a dictionary key. ```csharp resourceDictionary.Add(buttonStyle); ``` If a `Style` is added to the `ResourceDictionary` without a key, a dictionary key is generated automatically and the `Style` becomes an implicit style: It is applied to every `Button` on the page without being explicitly referenced by the `Button`, as you’ll see when you execute the code. These `Button` elements for the numeric keypad are a little smaller than they would be normally because they were given a `Margin` setting when they were created. This is to help make the number keys stand out a little from the other keys. ## Managing the Stack An RPN calculator is based around a stack, and fortunately a generic `Stack` class is included in the `System.Collections.Generic` namespace. This code instantiates it: ```csharp var stack = new Stack(); ``` The `Stack` class defines two basic methods: `Push` to add an item to the stack, and `Pop` to remove it. The last item pushed on the stack is the first item popped. `Stack` also defines a `Peek` method that allows examining the most recently pushed item without popping it. The only other member of `Stack` that this program uses is `Count` to obtain the number of items in the stack. When using an RPN calculator, it’s useful to see the a couple items in this stack. The top two items are often referred to as *x* (the number last pushed onto the stack) and *y* (the previous number pushed on the stack). Because displaying these items requires column widths different from the rest of the `Grid`, a new `Grid` is created named `stackGrid` that is nested in the original `Grid`: ```csharp var stackGrid = new Grid(); stackGrid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto } ); stackGrid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto } ); stackGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto } ); stackGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) } ); mainGrid.Children.Add(stackGrid, 0, 4, 0, 1); ``` This nested `Grid` occupies the top row of `mainGrid`, and fills its full width. The following code adds four `Label` elements to this nested `Grid` for displaying the top two items in the stack: ```csharp var xLabel = new Label { Text = "x = " }; stackGrid.Children.Add(xLabel, 0, 1); var xStackNumber = new Label { HorizontalTextAlignment = TextAlignment.End }; stackGrid.Children.Add(xStackNumber, 1, 1); var yLabel = new Label { Text = "y = " }; stackGrid.Children.Add(yLabel, 0, 0); var yStackNumber = new Label { HorizontalTextAlignment = TextAlignment.End }; stackGrid.Children.Add(yStackNumber, 1, 0); ``` Here is a method that updates this display based on the top two items in the `stack` object: ```csharp void UpdateStackDisplay() { xStackNumber.Text = stack.Count > 0 ? stack.Peek().ToString() : ""; if (stack.Count > 1) { double hold = stack.Pop(); yStackNumber.Text = stack.Peek().ToString(); stack.Push(hold); } else { yStackNumber.Text = ""; } } ``` So far, the `stack` object has been empty. The following code adds the all-important **Enter** button, which is positioned at the bottom of the main `Grid`: ```csharp var enterButton = new Button { Text = "Enter" }; enterButton.Clicked += (args, sender) => { stack.Push(Double.Parse(entryLabel.Text)); entryLabel.Text = "0"; UpdateStackDisplay(); }; mainGrid.Children.Add(enterButton, 0, 4, 11, 12); ``` You can now enter a number, and press the **Enter** key. The number disappears from the `entryLabel` and is moved to the **x** slot in the stack. Entering another number causes the number in the **x** slot to move to **y**, and the new number to move to **x**. With subsequent numbers, the process continues, although you can’t see the earlier entries. ## Clearing and Backspacing The calculator needs a few buttons for some standard calculator housekeeping. Here is the **Clear** button: ```csharp var clearAllButton = new Button { Text = "C" }; clearAllButton.Clicked += (args, sender) => { stack.Clear(); entryLabel.Text = "0"; UpdateStackDisplay(); }; mainGrid.Children.Add(clearAllButton, 0, 6); ``` This is the **Clear Entry** button that only clears the number from the `entryLabel`: ```csharp var clearEntryButton = new Button { Text = "CE" }; clearEntryButton.Clicked += (args, sender) => { entryLabel.Text = "0"; }; mainGrid.Children.Add(clearEntryButton, 1, 6); ``` The following button is a **Backspace** that progressively removes characters from the tail end of the `entryLabel`: ```csharp var backspaceButton = new Button { Text = "\x21E6" }; backspaceButton.Clicked += (args, sender) => { entryLabel.Text = entryLabel.Text.Substring(0, entryLabel.Text.Length - 1); if (entryLabel.Text.Length == 0) { entryLabel.Text = "0"; } }; mainGrid.Children.Add(backspaceButton, 2, 4, 6, 7); ``` ## Binary Operations All the other buttons perform operations of sorts on the numbers in the stack. These operations can be divided into *unary* operations and *binary* operations. A unary operation pops the top number off the stack, performs an operation on it (such as *log* or *sin*). and pushes the result back on the stack. The binary operations include addition and multiplication. A binary operation is performed on the top two numbers on the stack, and then pushes the result back on the stack. The one exception to this rule is a binary operation that swaps the top two numbers on the stack, usually symbolized as X**↔Y**. Here’s that button: ```csharp var swapButton = new Button { Text = "x\x21D4y"}; swapButton.Clicked += (args, sender) => { if (stack.Count < 2) { Beeper.Error(); } else { double x = stack.Pop(); double y = stack.Pop(); stack.Push(x); stack.Push(y); UpdateStackDisplay(); } }; mainGrid.Children.Add(swapButton, 1, 5); ``` The other binary operations are similar enough that they can all be handled with logic that differes only by the operaton itself. These binary operations are of type `Func`, a method that has two `double` parameters and returns a `double` result. The operaton can be stored right in the `Button` object using a class that derives from `Button` with a property of that type: ```csharp class BinaryOperationButton : Button { public Func Operation { set; get; } } ``` The five binary operations are division, multiplication, subtraction, addition, and y-to-the-x power. The following little structure is used for an array that contains the text of each `Button`, its row and column, and the binary operation: ```csharp struct BinaryOpInfo { public string Text { set; get; } public int Row { set; get; } public int Col { set; get; } public Func Operation { set; get; } } BinaryOpInfo[] binaryOpInfos = { new BinaryOpInfo { Text = "\x00F7", Row = 7, Col = 3, Operation = (x, y) => x / y }, new BinaryOpInfo { Text = "\x00D7", Row = 8, Col = 3, Operation = (x, y) => x * y }, new BinaryOpInfo { Text = "\x2013", Row = 9, Col = 3, Operation = (x, y) => x - y }, new BinaryOpInfo { Text = "+", Row = 10, Col = 3, Operation = (x, y) => x + y }, new BinaryOpInfo { Text = "y\x1D61", Row = 2, Col = 0, Operation = Math.Pow } } ``` Notice that the operation is defined as a lambda function for the four basic operations, but the y-to-the-x operation is the static `Math.Pow` method. The following code uses that array to create the five binary operation `Button` objects and add them to the `Grid`. ```csharp foreach (BinaryOpInfo binaryOpInfo in binaryOpInfos) { var binaryOpButton = new BinaryOperationButton { Text = binaryOpInfo.Text, Operation = binaryOpInfo.Operation, Style = buttonStyle }; binaryOpButton.Clicked += (sender, args) => { if (entryLabel.Text != "0") { stack.Push(Double.Parse(entryLabel.Text)); entryLabel.Text = "0"; } if (stack.Count < 2) { Beeper.Error(); } else { BinaryOperationButton button = sender as BinaryOperationButton; double x = stack.Pop(); double y = stack.Pop(); stack.Push(button.Operation(y, x)); UpdateStackDisplay(); } }; mainGrid.Children.Add(binaryOpButton, binaryOpInfo.Col, binaryOpInfo.Row); } ``` The first `if` clause in the event handler isn’t strictly required but makes using the calculator a little easier. For example, suppose you type a number, and press **Enter**, and then a second number, and press the addition key. In theory that shouldn’t work because the second number isn’t on the stack. But the code in the first `if` clause pushes the number on the stack for the operation. ## Unary Operations The unary operations are handled similarly to the binary operations. A unary operation is of type `Func`, and this derived class defines a property of that type: ```csharp class UnaryOperationButton : Button { public Func Operation { set; get; } } ``` Once again, a little structure is defined for the unique characteristics of each unary operation `Button`. Most of these can be handled by static methods in the `Math` class: ```csharp struct UnaryOpInfo { public string Text { set; get; } public int Row { set; get; } public int Col { set; get; } public Func Operation { set; get; } } UnaryOpInfo[] unaryOpInfos = { new UnaryOpInfo { Text = "log", Row = 2, Col = 1, Operation = Math.Log10 }, new UnaryOpInfo { Text = "ln", Row = 2, Col = 2, Operation = Math.Log }, new UnaryOpInfo { Text = "e\x1D61", Row = 2, Col = 3, Operation = Math.Exp }, new UnaryOpInfo { Text = "\x221Ax", Row = 3, Col = 0, Operation = Math.Sqrt }, new UnaryOpInfo { Text = "sin", Row = 3, Col = 1, Operation = Math.Sin }, new UnaryOpInfo { Text = "cos", Row = 3, Col = 2, Operation = Math.Cos }, new UnaryOpInfo { Text = "tan", Row = 3, Col = 3, Operation = Math.Tan }, new UnaryOpInfo { Text = "1/x", Row = 4, Col = 0, Operation = x => 1 / x }, new UnaryOpInfo { Text = "asin", Row = 4, Col = 1, Operation = Math.Asin }, new UnaryOpInfo { Text = "acos", Row = 4, Col = 2, Operation = Math.Acos }, new UnaryOpInfo { Text = "atan", Row = 4, Col = 3, Operation = Math.Atan }, new UnaryOpInfo { Text = "+/\x2013", Row = 5, Col = 0, Operation = x => -x }, new UnaryOpInfo { Text = "rad", Row = 5, Col = 2, Operation = d => Math.PI * d / 180 }, new UnaryOpInfo { Text = "deg", Row = 5, Col = 3, Operation = r => 180 * r / Math.PI } } ``` The trigonometric functions work with radians, so the final two unary operations in the array convert from degrees to radians, and from radians to degrees. The numeric keypad has no way to type negative numbers, so the **\+/–** key (third from bottom) changes a positive number on the stack to a negative one. The following code creates all the `Button` elements for the unary operations: ```csharp foreach (UnaryOpInfo unaryOpInfo in unaryOpInfos) { var unaryOpButton = new UnaryOperationButton { Text = unaryOpInfo.Text, Operation = unaryOpInfo.Operation, Style = buttonStyle }; unaryOpButton.Clicked += (sender, args) => { if (entryLabel.Text != "0") { stack.Push(Double.Parse(entryLabel.Text)); entryLabel.Text = "0"; } if (stack.Count < 1) { Beeper.Error(); } else { UnaryOperationButton button = sender as UnaryOperationButton; double x = stack.Pop(); stack.Push(button.Operation(x)); UpdateStackDisplay(); } }; mainGrid.Children.Add(unaryOpButton, unaryOpInfo.Col, unaryOpInfo.Row); } ``` That completes the RPN calculator. ================================================ FILE: xamarin-forms/advanced/RPNCalculator/RpnCalculator.workbook ================================================ --- uti: com.xamarin.workbook id: FED481A0-3465-4A72-87F1-4335D7F0C9DB title: Building a Xamarin.Forms RPN Calculator platforms: - Android - iOS packages: - id: Xamarin.Forms version: 2.5.0.121934 --- # Building a Xamarin.Forms RPN Calculator This workbook describes how to use the `Grid` layout in Xamarin.Forms as the foundation for a calculator. The `Grid` arranges visual elements in rows and columns, so it is ideal for arranging the calculator buttons and elements on the page. To keep the operational logic reasonably simple, this calculator uses Reverse Polish notation (RPN). ## What is RPN? Around the year 1924, Polish mathematician Jan Łukasiewicz (1878 – 1956) developed a type of notation for logic and arithmetic operations that did not require the use of parentheses. For example, the expression 5 × (3 \+ 4) – 2 is written in Łukasiewicz’s notaton like this – × 5 \+ 3 4 2 This statement is evaluated starting from the end of the expression. It’s convenient to use the last-in-first-out storage mechanism known as the *stack*. The numbers (starting from the end of the expression) are pushed on a stack. Every time one of the operators is encountered, the two numbers at the top of the stack are popped, and the operator is applied to them. The result is pushed back on the stack. In this example, 2, 4, and 3 are pushed on the stack, and then the plus sign causes 4 and 3 to be popped from the stack and 7 to be pushed on the stack. Now 5 is pushed on the stack, but the multiplication causes 5 and 7 to be popped from the stack and the product, 35, is pushed on the stack. Now the minus sign causes 35 and 2 to be popped from the stack, and the result is 33. This is sometimes known as *prefix notation*, but in honor of its inventor — and because his name can be challenging to spell — it’s often called *Polish notation*. In the digital computer age, it was realized that it makes more sense to evaluate an expression from the beginning (particularly if the expression can grow as it’s being evaluated), and Reverse Polish notation was born. In RPN (also called postfix notation), the above expression is written as: 5 3 4 \+ × 2 – Now the numbers from left to write are pushed on a stack, and a binary operation causes the top two numbers on the stack to be popped, and the result to be pushed on the stack. Because multiplication is commutative, the statement can also be written as: 3 4 \+ 5 × 2 – During the 1970s and 1980s, some popular calculators used RPN, most notably those manufactured by Hewlett-Packard. Many people with a mathematical or computer bent remain fans of RPN to this day. The Calculator program included with recent versions of macOS has an RPN mode. RPN calculators are characterized by the presence of an **Enter** button rather than an **=** button or parentheses buttons. Pressing the **Enter** key indicates that the number being typed by the user is ready to be pushed on the internal stack. When programming a calculator, basing it on RPN simplifies the operational logic considerably. Very little state information needs to be maintained other than the stack. In a Xamarin.Forms program, you can use a `Stack` object for this purpose. ## The iOS Prerequisites As usual, a Xamarin.Forms workbook requires the Xamairn.Forms NuGet package. Now use the **#r** command to reference the following Xamarin.Forms assemblies: ```csharp #r "Xamarin.Forms.Core" #r "Xamarin.Forms.Xaml" #r "Xamarin.Forms.Platform" ``` You’ll also want a few standard `using` directives: ```csharp using System; using System.Collections.Generic; // for Stack using Xamarin.Forms; ``` Workbooks has already initialized Xamarin.Forms, so `Application.Current.MainPage` can be set directly: ```csharp var page = new ContentPage(); Application.Current.MainPage = page; ``` With that code, the Xamarin.Forms `ContentPage` is displayed. ## Grid Rows and Columns The calculator consists of `Button` elements to enter numbers and operations, and `Label` elements to display intermediate and final results. Each of these elements occupies one or more cells of a `Grid`, which divides the area it occupies into rows and columns. You can create the `Grid` and set it to the `Content` property of the `ContentPage` like this: ```csharp var mainGrid = new Grid(); page.Content = mainGrid; ``` The `Grid` occupies the entire area of the page, but it’s invisible by default so you can’t see it. You might want to temporarily set the background color of the `Grid` by replacing the `Transparent` identifier below with one of the Xamarin.Forms colors (such as `Yellow`): ```csharp mainGrid.BackgroundColor = Color.Transparent; ``` The calculator buttons will look a little better if you give the entire page some padding that provides a little blank space around the perimeter. Also, for iOS, you’ll want to add 20 units padding on the top to avoid overwriting the iOS status bar: ```csharp page.Padding = new Thickness(10, 10 + Device.OnPlatform(20, 0, 0), 10, 10); ``` Alternatively, you can set the `Margin` property of the `mainGrid` object. Generally you explicitly specify the number of rows and columns in the `Grid` using objects of type `RowDefinition` and `ColumnDefinition`. You add these objects to the `RowDefinitions` and `ColumnDefinitions` collection properties of the `Grid`. The following code creates twelve `RowDefinition` objects. `RowDefinition` has a `Height` property that you set to a value of type `GridLength`: ```csharp // Remove previous RowDefinition objects on re-execution: mainGrid.RowDefinitions.Clear(); mainGrid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto }); mainGrid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto }); for (int row = 0; row < 10; row++) { mainGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) }); } ``` The `GridLength.Auto` constant indicates that the height is based on the height of the elements in that row. As you’ll see, those two rows are used for `Label` element. The `GridUnitType.Star` enumeration member indicates that remaining space is allocated proportionally among rows with that height indication. These ten rows are for `Button` elements, and ensures that they all have the same height. Another option is `GridUnitType.Absolute` for a specific height in device-independent units. The following code gives the `Grid` four columns of equal width: ```csharp // Remove previous ColumnDefinition objects on re-execution: mainGrid.ColumnDefinitions.Clear(); for (int col = 0; col < 4; col++) { mainGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) }); } ``` The `Grid` provides space between adjacent cells based on the `RowSpacing` and `ColumnSpacing` properties. These properties have default values of 6 units. ## Entering Numbers The calculator needs a `Label` to display the number that the user enters. This `Label` is given a light-gray background color to make it stand out. The `HorizontalTextAlignment` setting causes the text to be right-justified within the `Label`: ```csharp Label entryLabel = new Label { Text = "0", BackgroundColor = new Color(0.85), HorizontalTextAlignment = TextAlignment.End }; mainGrid.Children.Add(entryLabel, 0, 4, 1, 2); ``` The final statement adds the `Label` to the `Children` collection of the `Grid`. Notice the four numeric arguments to the `Add` statement. These four parameters are named `left`, `right`, `top`, and `bottom`, and specify the cell or cells that the element occupies. Column and row numbering is zero-based. If the element is in one cell, only the `left` and `top` arguments are required. The `right` and `bottom` arguments indicate the column and row beyond the last column or row that the element occupies. The `left` and `right` values of 0 and 4 indicate that the `Label` occupies columns 0, 1, 2, and 3, which is the full width of the `Grid`. The `top` and `bottom` values of 1 and 2 indicate that the `Label` occupies row 1, which is the second row of the `Grid`. When you execute that code, you’ll see the `Label` displayed in the `Grid`. The next step is to create some buttons, but first consider that not every button press is invalid. For example, when entering a number, you can’t press the decimal point twice. The following static `Beeper.Error` method is iOS specific and is intended to notify the user of an invalid button press: ```csharp // UNCOMMENT FOR iOS // static class Beeper // { // static AudioToolbox.SystemSound systemSound = // systemSound = new AudioToolbox.SystemSound(1000); // // public static void Error() // { // systemSound.PlaySystemSound(); // } // } ``` A calculator number pad has ten `Button` elements for the digits 0 through 9, and another `Button` for the decimal point. One approach to creating several similar elements for a `Grid` is to first define an array of `Tuple` objects. The following tuples indicate the text for each `Button` in the number pad, and the row and column numbers. The `span` value is the number of columns the `Button` occupies: ```csharp var numButtonInfos = new[] { new { text = "7", row = 7, col = 0, span = 1 }, new { text = "8", row = 7, col = 1, span = 1 }, new { text = "9", row = 7, col = 2, span = 1 }, new { text = "4", row = 8, col = 0, span = 1 }, new { text = "5", row = 8, col = 1, span = 1 }, new { text = "6", row = 8, col = 2, span = 1 }, new { text = "1", row = 9, col = 0, span = 1 }, new { text = "2", row = 9, col = 1, span = 1 }, new { text = "3", row = 9, col = 2, span = 1 }, new { text = "0", row = 10, col = 0, span = 2 }, new { text = ".", row = 10, col = 2, span = 1 } } ``` Creating the eleven `Button` elements can now be handled in a loop: ```csharp foreach (var numButtonInfo in numButtonInfos) { var button = new Button { Text = numButtonInfo.text, Margin = new Thickness(5) }; button.Clicked += (sender, args) => { string text = entryLabel.Text == "0" ? "" : entryLabel.Text; text += (sender as Button).Text; if (text == ".") { text = "0."; } double number; if (Double.TryParse(text, out number)) { entryLabel.Text = text; } else { // UNCOMMENT FOR iOS // Beeper.Error(); } }; mainGrid.Children.Add(button, numButtonInfo.col, numButtonInfo.col + numButtonInfo.span, numButtonInfo.row, numButtonInfo.row + 1); } ``` The `Clicked` handler appends the text of the pressed `Button` to the `Text` property of the `entryLabel` object. It uses the `Double.TryParse` method to determine if the new text string is a valid representation of a number. Only a couple special cases need to be handled: You can’t begin by typing a series of zeroes, and if you begin with a decimal point, a zero is automatically prepended. At this point, you can type numbers into the calculator but there’s no way to backspace, so the numbers keep getting longer. A Xamarin.Forms `Button` in an iOS program doesn’t have a border by default, so these number keys don’t look much like actual buttons. Setting the `BorderWidth` property can fix that. It can be done in the code above, or a uniform property setting can be applied to visual elements by defining a `Style` object. The first step is to instantiate a `ResourceDictionary` for the page: ```csharp var resourceDictionary = new ResourceDictionary(); page.Resources = resourceDictionary; ``` The following `Style` object has a target type of `Button` (specified in its constructor) and includes a `Setter` object that associates the `ButtonWidthProperty` bindable property with a value of 1: ```csharp var buttonStyle = new Style(typeof(Button)); buttonStyle.Setters.Add(new Setter { Property = Button.BorderWidthProperty, Value = 1 }); ``` The following code adds the `Style` object to the `ResourceDictionary` but without specifying a dictionary key. ```csharp resourceDictionary.Add(buttonStyle); ``` If a `Style` is added to the `ResourceDictionary` without a key, a dictionary key is generated automatically and the `Style` becomes an implicit style: It is applied to every `Button` on the page without being explicitly referenced by the `Button`, as you’ll see when you execute the code. These `Button` elements for the numeric keypad are a little smaller than they would be normally because they were given a `Margin` setting when they were created. This is to help make the number keys stand out a little from the other keys. ## Managing the Stack An RPN calculator is based around a stack, and fortunately a generic `Stack` class is included in the `System.Collections.Generic` namespace. This code instantiates it: ```csharp var stack = new Stack(); ``` The `Stack` class defines two basic methods: `Push` to add an item to the stack, and `Pop` to remove it. The last item pushed on the stack is the first item popped. `Stack` also defines a `Peek` method that allows examining the most recently pushed item without popping it. The only other member of `Stack` that this program uses is `Count` to obtain the number of items in the stack. When using an RPN calculator, it’s useful to see the a couple items in this stack. The top two items are often referred to as *x* (the number last pushed onto the stack) and *y* (the previous number pushed on the stack). Because displaying these items requires column widths different from the rest of the `Grid`, a new `Grid` is created named `stackGrid` that is nested in the original `Grid`: ```csharp var stackGrid = new Grid(); stackGrid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto } ); stackGrid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto } ); stackGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto } ); stackGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) } ); mainGrid.Children.Add(stackGrid, 0, 4, 0, 1); ``` This nested `Grid` occupies the top row of `mainGrid`, and fills its full width. The following code adds four `Label` elements to this nested `Grid` for displaying the top two items in the stack: ```csharp var xLabel = new Label { Text = "x = " }; stackGrid.Children.Add(xLabel, 0, 1); var xStackNumber = new Label { HorizontalTextAlignment = TextAlignment.End }; stackGrid.Children.Add(xStackNumber, 1, 1); var yLabel = new Label { Text = "y = " }; stackGrid.Children.Add(yLabel, 0, 0); var yStackNumber = new Label { HorizontalTextAlignment = TextAlignment.End }; stackGrid.Children.Add(yStackNumber, 1, 0); ``` Here is a method that updates this display based on the top two items in the `stack` object: ```csharp void UpdateStackDisplay() { xStackNumber.Text = stack.Count > 0 ? stack.Peek().ToString() : ""; if (stack.Count > 1) { double hold = stack.Pop(); yStackNumber.Text = stack.Peek().ToString(); stack.Push(hold); } else { yStackNumber.Text = ""; } } ``` So far, the `stack` object has been empty. The following code adds the all-important **Enter** button, which is positioned at the bottom of the main `Grid`: ```csharp var enterButton = new Button { Text = "Enter" }; enterButton.Clicked += (args, sender) => { stack.Push(Double.Parse(entryLabel.Text)); entryLabel.Text = "0"; UpdateStackDisplay(); }; mainGrid.Children.Add(enterButton, 0, 4, 11, 12); ``` You can now enter a number, and press the **Enter** key. The number disappears from the `entryLabel` and is moved to the **x** slot in the stack. Entering another number causes the number in the **x** slot to move to **y**, and the new number to move to **x**. With subsequent numbers, the process continues, although you can’t see the earlier entries. ## Clearing and Backspacing The calculator needs a few buttons for some standard calculator housekeeping. Here is the **Clear** button: ```csharp var clearAllButton = new Button { Text = "C" }; clearAllButton.Clicked += (args, sender) => { stack.Clear(); entryLabel.Text = "0"; UpdateStackDisplay(); }; mainGrid.Children.Add(clearAllButton, 0, 6); ``` This is the **Clear Entry** button that only clears the number from the `entryLabel`: ```csharp var clearEntryButton = new Button { Text = "CE" }; clearEntryButton.Clicked += (args, sender) => { entryLabel.Text = "0"; }; mainGrid.Children.Add(clearEntryButton, 1, 6); ``` The following button is a **Backspace** that progressively removes characters from the tail end of the `entryLabel`: ```csharp var backspaceButton = new Button { Text = "\x21E6" }; backspaceButton.Clicked += (args, sender) => { entryLabel.Text = entryLabel.Text.Substring(0, entryLabel.Text.Length - 1); if (entryLabel.Text.Length == 0) { entryLabel.Text = "0"; } }; mainGrid.Children.Add(backspaceButton, 2, 4, 6, 7); ``` ## Binary Operations All the other buttons perform operations of sorts on the numbers in the stack. These operations can be divided into *unary* operations and *binary* operations. A unary operation pops the top number off the stack, performs an operation on it (such as *log* or *sin*). and pushes the result back on the stack. The binary operations include addition and multiplication. A binary operation is performed on the top two numbers on the stack, and then pushes the result back on the stack. The one exception to this rule is a binary operation that swaps the top two numbers on the stack, usually symbolized as X**↔Y**. Here’s that button: ```csharp var swapButton = new Button { Text = "x\x21D4y"}; swapButton.Clicked += (args, sender) => { if (stack.Count < 2) { // UNCOMMENT FOR iOS // Beeper.Error(); } else { double x = stack.Pop(); double y = stack.Pop(); stack.Push(x); stack.Push(y); UpdateStackDisplay(); } }; mainGrid.Children.Add(swapButton, 1, 5); ``` The other binary operations are similar enough that they can all be handled with logic that differes only by the operaton itself. These binary operations are of type `Func`, a method that has two `double` parameters and returns a `double` result. The operaton can be stored right in the `Button` object using a class that derives from `Button` with a property of that type: ```csharp class BinaryOperationButton : Button { public Func Operation { set; get; } } ``` The five binary operations are division, multiplication, subtraction, addition, and y-to-the-x power. The following little structure is used for an array that contains the text of each `Button`, its row and column, and the binary operation: ```csharp struct BinaryOpInfo { public string Text { set; get; } public int Row { set; get; } public int Col { set; get; } public Func Operation { set; get; } } BinaryOpInfo[] binaryOpInfos = { new BinaryOpInfo { Text = "\x00F7", Row = 7, Col = 3, Operation = (x, y) => x / y }, new BinaryOpInfo { Text = "\x00D7", Row = 8, Col = 3, Operation = (x, y) => x * y }, new BinaryOpInfo { Text = "\x2013", Row = 9, Col = 3, Operation = (x, y) => x - y }, new BinaryOpInfo { Text = "+", Row = 10, Col = 3, Operation = (x, y) => x + y }, new BinaryOpInfo { Text = "y\x1D61", Row = 2, Col = 0, Operation = Math.Pow } } ``` Notice that the operation is defined as a lambda function for the four basic operations, but the y-to-the-x operation is the static `Math.Pow` method. The following code uses that array to create the five binary operation `Button` objects and add them to the `Grid`. ```csharp foreach (BinaryOpInfo binaryOpInfo in binaryOpInfos) { var binaryOpButton = new BinaryOperationButton { Text = binaryOpInfo.Text, Operation = binaryOpInfo.Operation, Style = buttonStyle }; binaryOpButton.Clicked += (sender, args) => { if (entryLabel.Text != "0") { stack.Push(Double.Parse(entryLabel.Text)); entryLabel.Text = "0"; } if (stack.Count < 2) { // UNCOMMENT FOR iOS // Beeper.Error(); } else { BinaryOperationButton button = sender as BinaryOperationButton; double x = stack.Pop(); double y = stack.Pop(); stack.Push(button.Operation(y, x)); UpdateStackDisplay(); } }; mainGrid.Children.Add(binaryOpButton, binaryOpInfo.Col, binaryOpInfo.Row); } ``` The first `if` clause in the event handler isn’t strictly required but makes using the calculator a little easier. For example, suppose you type a number, and press **Enter**, and then a second number, and press the addition key. In theory that shouldn’t work because the second number isn’t on the stack. But the code in the first `if` clause pushes the number on the stack for the operation. ## Unary Operations The unary operations are handled similarly to the binary operations. A unary operation is of type `Func`, and this derived class defines a property of that type: ```csharp class UnaryOperationButton : Button { public Func Operation { set; get; } } ``` Once again, a little structure is defined for the unique characteristics of each unary operation `Button`. Most of these can be handled by static methods in the `Math` class: ```csharp struct UnaryOpInfo { public string Text { set; get; } public int Row { set; get; } public int Col { set; get; } public Func Operation { set; get; } } UnaryOpInfo[] unaryOpInfos = { new UnaryOpInfo { Text = "log", Row = 2, Col = 1, Operation = Math.Log10 }, new UnaryOpInfo { Text = "ln", Row = 2, Col = 2, Operation = Math.Log }, new UnaryOpInfo { Text = "e\x1D61", Row = 2, Col = 3, Operation = Math.Exp }, new UnaryOpInfo { Text = "\x221Ax", Row = 3, Col = 0, Operation = Math.Sqrt }, new UnaryOpInfo { Text = "sin", Row = 3, Col = 1, Operation = Math.Sin }, new UnaryOpInfo { Text = "cos", Row = 3, Col = 2, Operation = Math.Cos }, new UnaryOpInfo { Text = "tan", Row = 3, Col = 3, Operation = Math.Tan }, new UnaryOpInfo { Text = "1/x", Row = 4, Col = 0, Operation = x => 1 / x }, new UnaryOpInfo { Text = "asin", Row = 4, Col = 1, Operation = Math.Asin }, new UnaryOpInfo { Text = "acos", Row = 4, Col = 2, Operation = Math.Acos }, new UnaryOpInfo { Text = "atan", Row = 4, Col = 3, Operation = Math.Atan }, new UnaryOpInfo { Text = "+/\x2013", Row = 5, Col = 0, Operation = x => -x }, new UnaryOpInfo { Text = "rad", Row = 5, Col = 2, Operation = d => Math.PI * d / 180 }, new UnaryOpInfo { Text = "deg", Row = 5, Col = 3, Operation = r => 180 * r / Math.PI } } ``` The trigonometric functions work with radians, so the final two unary operations in the array convert from degrees to radians, and from radians to degrees. The numeric keypad has no way to type negative numbers, so the **\+/–** key (third from bottom) changes a positive number on the stack to a negative one. The following code creates all the `Button` elements for the unary operations: ```csharp foreach (UnaryOpInfo unaryOpInfo in unaryOpInfos) { var unaryOpButton = new UnaryOperationButton { Text = unaryOpInfo.Text, Operation = unaryOpInfo.Operation, Style = buttonStyle }; unaryOpButton.Clicked += (sender, args) => { if (entryLabel.Text != "0") { stack.Push(Double.Parse(entryLabel.Text)); entryLabel.Text = "0"; } if (stack.Count < 1) { // UNCOMMENT FOR iOS // Beeper.Error(); } else { UnaryOperationButton button = sender as UnaryOperationButton; double x = stack.Pop(); stack.Push(button.Operation(x)); UpdateStackDisplay(); } }; mainGrid.Children.Add(unaryOpButton, unaryOpInfo.Col, unaryOpInfo.Row); } ``` That completes the RPN calculator. ================================================ FILE: xamarin-forms/advanced/meta.json ================================================ { "order":{ "MandelbrotTouch.workbook":"Mandelbrot Touch", "RPNCalculator/RpnCalculator.workbook":"RPN Calculator" } } ================================================ FILE: xamarin-forms/application-fundamentals/database/database.workbook/FormsInit.csx ================================================ #r "Xamarin.Forms.Core" #r "Xamarin.Forms.Xaml" #r "Xamarin.Forms.Platform" #r "SQLite-net" using System; using Xamarin.Forms; using SQLite; using SQLitePCL; var page = new ContentPage(); StackLayout stackLayout = new StackLayout { Margin = new Thickness(0, 20, 0, 0) }; page.Content = stackLayout; Application.Current.MainPage = page; ================================================ FILE: xamarin-forms/application-fundamentals/database/database.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook id: 6AA7FBF5-DF9D-4F0A-B890-15391D71FE9E title: Accessing a Local Database with Xamarin.Forms platforms: - Android - iOS packages: - id: Xamarin.Forms version: 2.5.0.121934 - id: sqlite-net-pcl version: 1.4.118 --- # Accessing a Local Database Xamarin.Forms applications can read and write data to a local SQLite database by using the `SQLite.Net` NuGet package. ## Initializing the Workbook To use SQLite.Net in Xamarin Workbooks, you must: * Add the `sqlite-net-pcl` NuGet package to the Workbook. * Use the `#r` command to reference the `SQLite-net`, `SQLitePCL.raw`, and `SQLitePCL.batteries` assemblies. * Add a `using` directive to reference the `SQLite` assembly. These steps have been performed in this workbook. In order to run a Xamarin.Forms workbook, some initialization code must be executed: ```csharp // The Xamarin.Forms initialization code isn't important to understanding this workbook #load "FormsInit.csx" using System.Collections.Generic; using System.IO; using System.Linq; using Xamarin.Forms; using SQLite; ``` For more information about the initialization code, see the Getting Started with Xamarin.Forms workbook. ## Creating the Model This workbook uses the `TodoItem` class to model the data that's stored in the SQLite database: ```csharp [Table("todoitem")] public class TodoItem { [PrimaryKey, AutoIncrement] public int ID { get; set; } public string Name { get; set; } public string Notes { get; set; } public bool Done { get; set; } } ``` The database schema is defined through attributes that are applied to the class and the `ID` property: * The `Table` attribute identifies which table the `TodoItem` class is mapped to in SQLite. * The `PrimaryKey` attribute uniquely identifies each table row. * The `AutoIncrement` attribute causes an integer's value to automatically increment when a new row is inserted into the table. Therefore, the `ID` property is used to uniquely identify each row in the `todoitem` table, and will be automatically incremented each time a row is inserted into the table. > ℹ️ Insert, update, and delete operations all require a primary key to be defined. ## Creating a Database Connection To perform database operations, a connection to an SQLite database file must be established. This is accomplished with the `GetConnection` method: ```csharp public SQLiteConnection GetConnection() { var sqliteFilename = "TodoSQLite.db3"; string documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal); string libraryPath = Path.Combine(documentsPath, "..", "Library"); var path = Path.Combine(libraryPath, sqliteFilename); return new SQLiteConnection(path); } ``` This method places the SQLite database file in the **Library** folder within the application's sandbox. > ℹ️ In a Xamarin Studio or Visual Studio Xamarin.Forms solution, the `GetConnection` method should reside in the iOS platform project, and be invoked from the Xamarin.Forms project using the `DependencyService` class. For more information, see [Working with a Local Database](https://developer.xamarin.com/guides/xamarin-forms/working-with/databases/). The `GetConnection` method is invoked as follows: ```csharp SQLiteConnection database = GetConnection(); database.CreateTable(); ``` Once a database connection is established, the `todoitem` table is created with the `CreateTable` method. This method operates on an `SQLiteConnection` object, and specifies the class which maps to the underlying database table. > ℹ️ > * A table is only created once per entity. If the table already exists, `CreateTable` has no effect. > > * Existing tables are automatically updated with new columns when `CreateTable` is called based on the current schema and the attributed class. This auto-upgrade will not change the schema in another other way. ## Defining Database Operations Once the table is created, create-read-update-delete (CRUD) operations can be performed on it by writing methods that use the `SQLiteConnection` instance. The simplest approach for retrieving records from a table is to use the `Table` method on the `SQLiteConnection` instance, with a LINQ extension method such as `ToList` or `FirstOrDefault`. This will execute the query and return the results. Alternatively, the `Query` method can be used to execute a raw SQL query. The following code shows both approaches: ```csharp static object locker = new object(); public IEnumerable GetItems() { lock (locker) { return (from i in database.Table() select i).ToList(); } } public IEnumerable GetItemsNotDone() { lock (locker) { return database.Query("SELECT * FROM [TodoItem] WHERE [Done] = 0"); } } public TodoItem GetItem(int id) { lock (locker) { return database.Table().FirstOrDefault(x => x.ID == id); } } ``` Insert, update, and delete operations are performed with the `Insert`, `Update`, and `Delete` methods on the `SQLiteConnection` instance: ```csharp public int SaveItem(TodoItem item) { lock (locker) { if (item.ID != 0) { database.Update(item); return item.ID; } else return database.Insert(item); } } public int DeleteItem(int id) { lock (locker) { return database.Delete(id); } } ``` The `Insert`, `Update`, and `Delete` methods all return the number of rows that were affected by the operation. > ⚠️ Simultaneously running two database operations will most likely crash an application, and may even corrupt the database file. Therefore, a `lock` is used to guard each database operation, which ensures that only one thread uses the database connection at once. ## Adding Data to the Database Once database operation methods have been defined, some sample data can be created and inserted into the database: ```csharp var todoItem1 = new TodoItem { Name = "Learn Xamarin Development", Notes = "Attend Xamarin University", Done = true }; var todoItem2 = new TodoItem { Name = "Develop Cross-Platform Apps", Notes = "Use XAML", Done = false }; var todoItem3 = new TodoItem { Name = "Publish Apps", Notes = "All stores", Done = false }; SaveItem(todoItem1); SaveItem(todoItem2); SaveItem(todoItem3); ``` This code defines three `TodoItem` instances, which are then inserted into the database using the `SaveItem` method. ## Retrieving Data from the Database A `ListView` can be populated with data from the database by setting its `ItemsSource` property to the data returned by the `GetItems` method: ```csharp var listView = new ListView { ItemsSource = GetItems(), ItemTemplate = new DataTemplate(() => { var nameLabel = new Label { VerticalTextAlignment = TextAlignment.Center }; nameLabel.SetBinding(Label.TextProperty, "Name"); var image = new Image { Source = "check.png" }; image.SetBinding(Image.IsVisibleProperty, "Done"); var templateStackLayout = new StackLayout { Orientation = StackOrientation.Horizontal, Margin = new Thickness(20, 0, 0, 0), HorizontalOptions = LayoutOptions.StartAndExpand, Children = { nameLabel, image } }; return new ViewCell { View = templateStackLayout }; }) }; stackLayout.Children.Add(listView); ``` The `ListView` uses a `DataTemplate` to create a custom cell that represents each row of data, displaying the values of the `Name` and `Done` properties for each `TodoItem` instance. Alternatively, the `GetItemsNotDone` method can be invoked to retrieve all the items in the database that are not marked as having been completed: ```csharp listView.ItemsSource = GetItemsNotDone(); ``` ## Updating and Deleting Data The `GetItem` method can be invoked to retrieve a single row from the database. The `TodoItem` instance can then have its data modified, and be updated in the database with the `SaveItem` method: ```csharp var todoItem = GetItem(2); todoItem.Done = true; SaveItem(todoItem); listView.ItemsSource = GetItems(); ``` This code marks the second row in the database as having been completed, and so a check mark will appear on that row when the code is executed. In addition, the `DeleteItem` method can be invoked to remove rows from the database: ```csharp DeleteItem(1); DeleteItem(2); DeleteItem(3); listView.ItemsSource = GetItems(); ``` ## 👍 Try it now! * Add a `CompletedDate` property to the `TodoItem` model. * Rewrite the `GetItemsNotDone` method to use the `Table` method to return the rows where the `Done` column is `false`. * Add a `GetCompletedItems` method that returns rows where the `CompletedDate` row value is greater than a specified parameter. ## Further Reading For more information about displaying a map, see [Working with a Local Database](https://developer.xamarin.com/guides/xamarin-forms/working-with/databases/). ================================================ FILE: xamarin-forms/application-fundamentals/files/files.workbook/FormsInit.csx ================================================ #r "Xamarin.Forms.Core" #r "Xamarin.Forms.Xaml" #r "Xamarin.Forms.Platform" using System; using Xamarin.Forms; var page = new ContentPage(); StackLayout stackLayout = new StackLayout { Margin = new Thickness(0, 20, 0, 0) }; page.Content = stackLayout; Application.Current.MainPage = page; ================================================ FILE: xamarin-forms/application-fundamentals/files/files.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook id: C82F7D1A-AB49-473C-A97E-64DF3EB7212F title: Saving and Loading Text Files with Xamarin.Forms platforms: - Android - iOS packages: - id: Xamarin.Forms version: 2.5.0.121934 --- # Saving and Loading Text Files In Workbooks, Xamarin.Forms file handling can be performed by using the native filesystem APIs. In order to run a Xamarin.Forms workbook, some initialization code must be executed: ```csharp // The Xamarin.Forms initialization code isn't important to understanding this workbook #load "FormsInit.csx" using Xamarin.Forms; using System.IO; ``` For more information about the initialization code, see the Getting Started with Xamarin.Forms workbook. ## Adding Platform-Specific FileSystem Access Each platform has different filesystem capabilities, and a slightly different directory structure. The following code can be used to save and load text files on iOS: ```csharp public void SaveText(string filename, string text) { var documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal); var filePath = Path.Combine(documentsPath, filename); File.WriteAllText(filePath, text); } public string LoadText(string filename) { var documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal); var filePath = Path.Combine(documentsPath, filename); return File.ReadAllText(filePath); } ``` The `SaveText` and `LoadText` methods use `System.IO` functionality to save and load text: * The `File.WriteAllText` method creates a new file, writes the contents to the file, and then closes the file. If the target file already exists, it's overwritten. * The `File.ReadAllText` method opens a text file, reads all the lines of the file into a string, and then closes the file. Text is saved to, or loaded from, the folder represented by the `Environment.SpecialFolder.Personal` enumeration constant. This constant identifies the directory that serves as a common repository for documents. > ℹ️ In a Xamarin Studio or Visual Studio Xamarin.Forms solution, the `SaveText` and `LoadText` methods should reside in the iOS platform project, and be invoked from the Xamarin.Forms project using the `DependencyService` class. For more information, see [Working with Files](https://developer.xamarin.com/guides/xamarin-forms/working-with/files/). ## Invoking the Platform-Specific FileSystem Access Methods The `SaveText` and `LoadText` methods can be invoked from Xamarin.Forms to save and load text files: ```csharp var inputEntry = new Entry { Placeholder = "Enter text here" }; var outputEntry = new Entry { IsEnabled = false }; var loadButton = new Button { Text = "Load", IsEnabled = false }; loadButton.Clicked += (sender, e) => { outputEntry.Text = LoadText("temp.txt"); }; var saveButton = new Button { Text = "Save" }; saveButton.Clicked += (sender, e) => { SaveText("temp.txt", inputEntry.Text); loadButton.IsEnabled = true; }; stackLayout.Children.Add(inputEntry); stackLayout.Children.Add(saveButton); stackLayout.Children.Add(loadButton); stackLayout.Children.Add(outputEntry); ``` When the `saveButton` is clicked, the platform-specific `SaveText` method is invoked, and when the `loadButton` is clicked, the platform-specific `LoadText` method is invoked. ## 👍 Try it now! * Change the Xamarin.Forms code to save to, and load from, a text file name `userinput.txt`. * Specify a `System.Text.Encoding` on the `File.WriteAllText` method call. * Specify the same `System.Text.Encoding` on the `File.ReadAllText` method call. ## Further Reading For more information about saving and loading text files, see [Working with Files](https://developer.xamarin.com/guides/xamarin-forms/working-with/files/). ================================================ FILE: xamarin-forms/application-fundamentals/hierarchical-navigation/hierarchical-navigation.workbook/FormsInit.csx ================================================ #r "Xamarin.Forms.Core" #r "Xamarin.Forms.Xaml" #r "Xamarin.Forms.Platform" using System; using Xamarin.Forms; var app = Application.Current; ================================================ FILE: xamarin-forms/application-fundamentals/hierarchical-navigation/hierarchical-navigation.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook id: 500CEAC8-8D46-4305-A1B5-00A6C5A62BEC title: Performing Hierarchical Navigation with Xamarin.Forms platforms: - Android - iOS packages: - id: Xamarin.Forms version: 2.5.0.121934 --- # Performing Hierarchical Navigation The Xamarin.Forms `NavigationPage` class provides a hierarchical navigation experience where the user is able to navigate through pages, forwards and backwards, as desired. To move from one page to another, an application will push a new page onto the navigation stack, where it will become the active page, as shown in the following diagram: ![](pushing.png) To return back to the previous page, the application will pop the current page from the navigation stack, and the new topmost page becomes the active page, as shown in the following diagram: ![](popping.png) In hierarchical navigation, the `NavigationPage` class is used to navigate through a stack of `ContentPage` objects. ## Initializing the Workbook In order to run a Xamarin.Forms workbook, some initialization code must be executed: ```csharp // The Xamarin.Forms initialization code isn't important to understanding this workbook #load "FormsInit.csx" using Xamarin.Forms; ``` For more information about the initialization code, see the Getting Started with Xamarin.Forms workbook. ## Creating the Root page The `MainPage` property of the `App` class should be set to a `NavigationPage` instance, with the `NavigationPage` constructor expecting a `Page` instance as an argument: ```csharp var firstContentPage = new ContentPage { Title = "First Page" }; app.MainPage = new NavigationPage(firstContentPage); ``` > ℹ️ In a Xamarin Studio or Visual Studio solution, the code that sets `KeyWindow.RootViewController` will be created by the project template, and will reside in the iOS project. The first page added to the navigation stack is referred to as the *root* page of the application, and the value of the `Page.Title` property will be displayed as the page title. ## Pushing Pages to the Navigation Stack Forward navigation is accomplished by invoking the `PushAsync` method on the `Navigation` property of the current page: ```csharp var secondContentPage = new ContentPage { Title = "Second Page" }; await firstContentPage.Navigation.PushAsync(secondContentPage); ``` This causes the `secondContentPage` instance to be pushed onto the navigation stack, where it becomes the active page. When the `PushAsync` method is invoked, the following events occur: * The page calling `PushAsync` has its `OnDisappearing` override invoked. * The page being navigated to has its `OnAppearing` override invoked. * The `PushAsync` task completes. However, the precise order in which these events occur is platform dependent. > ⚠️ Calls to the `OnDisappearing` and `OnAppearing` overrides cannot be treated as guaranteed indications of page navigation. For example, on iOS, the `OnDisappearing` override is called on the active page when the application terminates. ## Popping Pages from the Navigation Stack The active page can be popped from the navigation stack by pressing the *Back* button on the device, regardless of whether it's a physical button on the device or an on-screen button. To programmatically return to the original page, the `secondContentPage` instance must invoke the `PopAsync` method: ```csharp await secondContentPage.Navigation.PopAsync(); ``` This causes the `secondContentPage` instance to be removed from the navigation stack, with the new topmost page becoming the active page. When the `PopAsync` method is invoked, the following events occur: * The page calling `PopAsync` has its `OnDisappearing` override invoked. * The page being returned to has its `OnAppearing` override invoked. * The `PopAsync` task returns. However, the precise order in which these events occur is platform dependent. The `Navigation` property of each page also provides a `PopToRootAsync` method: ```csharp var thirdContentPage = new ContentPage { Title = "Page Three" }; await firstContentPage.Navigation.PushAsync(secondContentPage); await secondContentPage.Navigation.PushAsync(thirdContentPage); await thirdContentPage.Navigation.PopToRootAsync(); ``` This method pops all but the root `ContentPage` off the navigation stack, therefore making the root page of the application the active page. ## Animating Page Transitions The `Navigation` property of each page also provides overridden push and pop methods that include a `boolean` parameter that controls whether to display a page animation during navigation: ```csharp await firstContentPage.Navigation.PushAsync(secondContentPage, false); ``` Setting the `boolean` parameter to `false` disables the page-transition animation, while setting the parameter to `true` enables the page-transition animation, provided that it's supported by the the underlying platform. However, the push and pop methods that lack this parameter enable the animation by default: ```csharp await secondContentPage.Navigation.PopAsync(); ``` ## Passing Data when Navigating Sometimes it's necessary for a page to pass data to another page during navigation. Two techniques for accomplishing this are passing data through a page constructor, and by setting the new page's `BindingContext` to the data. ## Passing Data through a Page Constructor The simplest technique for passing data to another page during navigation is through a page constructor parameter: ```csharp public class FourthContentPage : ContentPage { public FourthContentPage(string date) { Title = "Fourth Page"; Content = new Label { Text = date, HorizontalOptions = LayoutOptions.Center, VerticalOptions = LayoutOptions.CenterAndExpand }; } } var fourthContentPage = new FourthContentPage(DateTime.Now.ToString("u")); await firstContentPage.Navigation.PushAsync(fourthContentPage); ``` The current date and time is passed in ISO8601 format to the `FourthContentPage` constructor, where it's displayed by a `Label` instance. ## Passing Data through a BindingContext An alternative approach for passing data to another page during navigation is by setting the new page's `BindingContext` to the data: ```csharp public class FifthContentPage : ContentPage { public FifthContentPage() { Title = "Fifth Page"; var label = new Label { HorizontalOptions = LayoutOptions.Center, VerticalOptions = LayoutOptions.CenterAndExpand }; label.SetBinding(Label.TextProperty, "."); Content = label; } } await fourthContentPage.Navigation.PopAsync(); var fifthContentPage = new FifthContentPage(); fifthContentPage.BindingContext = DateTime.Now.ToString("u"); await firstContentPage.Navigation.PushAsync(fifthContentPage); ``` This code sets the `BindingContext` of the `FifthContentPage` instance to the current date and time in ISO8601 format and then navigates to the `FifthContentPage`, which uses data binding to display the data. ## Manipulating the Navigation Stack The `Navigation` property exposes a `NavigationStack` property from which the pages in the navigation stack can be obtained. While Xamarin.Forms maintains access to the navigation stack, the `Navigation` property provides the `InsertPageBefore` and `RemovePage` methods for manipulating the stack by inserting pages or removing them. The `InsertPageBefore` method inserts a specified page in the navigation stack before an existing specified page, as shown in the following diagram: ![](insert-page-before.png) The `RemovePage` method removes the specified page from the navigation stack, as shown in the following diagram: ![](remove-page.png) These methods allow manipulation of the navigation stack: ```csharp fifthContentPage.Navigation.InsertPageBefore(fourthContentPage, fifthContentPage); await fifthContentPage.Navigation.PopAsync(); fourthContentPage.Navigation.RemovePage(fourthContentPage); ``` The `fourthContentPage` instance is inserted before the `fifthContentPage` instance using the `InsertPageBefore` method. The `PopAsync` method then removes the current page from the navigation stack, with the `fourthContentPage` instance becoming the active page. The `fourthContentPage` instance is then removed from the navigation stack with the `RemovePage` method, which makes the root page the active page. ## 👍 Try it now! * Push some pages to the navigation stack, and then return to the root page without displaying page transition animations. * Pass an object containing multiple pieces of data to a page, through its `BindingContext`. * Push some pages to the navigation stack, and then remove the odd numbered pages from the stack. ## Further Reading For more information about hierarchical navigation, see [Hierarchical Navigation](https://developer.xamarin.com/guides/xamarin-forms/user-interface/navigation/hierarchical/). ================================================ FILE: xamarin-forms/application-fundamentals/meta.json ================================================ { "order":{ "database/database.workbook":"Database", "files/files.workbook":"Files", "hierarchical-navigation/hierarchical-navigation.workbook":"Hierarchical Navigation", "text-to-speech/text-to-speech.workbook":"Text to Speech (for iOS)" } } ================================================ FILE: xamarin-forms/application-fundamentals/text-to-speech/text-to-speech.workbook/FormsInit.csx ================================================ #r "Xamarin.Forms.Core" #r "Xamarin.Forms.Xaml" #r "Xamarin.Forms.Platform" using System; using Xamarin.Forms; var page = new ContentPage(); StackLayout stackLayout = new StackLayout { Margin = new Thickness(0, 20, 0, 0) }; page.Content = stackLayout; Application.Current.MainPage = page; ================================================ FILE: xamarin-forms/application-fundamentals/text-to-speech/text-to-speech.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook id: 520731C2-FD34-445A-96EA-A27490B66B24 title: Translating Text to Speech with Xamarin.Forms (iOS) platforms: - iOS packages: - id: Xamarin.Forms version: 2.5.0.121934 --- # Translating Text to Speech (iOS-specific) Each platform provides a native text to speech API that can be invoked from Xamarin.Forms. This workbook uses `AVFoundation` from iOS. ## Initializing the Workbook In order to run a Xamarin.Forms workbook, some initialization code must be executed: ```csharp // The Xamarin.Forms initialization code isn't important to understanding this workbook #load "FormsInit.csx" using Xamarin.Forms; using AVFoundation; ``` For more information about the initialization code, see the Getting Started with Xamarin.Forms workbook. ## Adding a Platform-Specific Speech Method Each platform uses a different speech API. The following code, which uses the `AVFoundation` APIs, can be used to translate text to speech on iOS: ```csharp float volume = 0.5f; float pitch = 1.0f; public void Speak(string text) { if (!string.IsNullOrWhiteSpace(text)) { var speechSynthesizer = new AVSpeechSynthesizer(); var speechUtterance = new AVSpeechUtterance(text) { Rate = AVSpeechUtterance.MaximumSpeechRate / 3, Voice = AVSpeechSynthesisVoice.FromLanguage("en-US"), Volume = volume, PitchMultiplier = pitch }; speechSynthesizer.SpeakUtterance(speechUtterance); } } ``` The `SpeechSynthesizer` class synthesizes the text to speech, with the `AVSpeechUtterance` class encapsulating how the text will be spoken. The following `AVSpeechUtterance` properties are set to control the spoken text: * `Rate` – the speed at which text is spoken. * `Voice` – an `AVSpeechSynthesisVoice` instance used to speak the text. * `Volume` – the volume level of the voice used to speak the text. * `PitchMultiplier` – a value between 0.5 and 2.0 to control the speech text. > ℹ️ In a Xamarin Studio or Visual Studio Xamarin.Forms solution, the `Speak` method should reside in the iOS platform project, and be invoked from the Xamarin.Forms project using the `DependencyService` class. For more information, see [Implementing Text-to-Speech](https://developer.xamarin.com/guides/xamarin-forms/dependency-service/text-to-speech/). ## Invoking the Platform-Specific Speech Method The `Speak` method can be invoked from Xamarin.Forms to translate text to speech: ```csharp var entry = new Entry { Placeholder = "Enter text to speak here" }; var button = new Button { Text = "Speak" }; button.Clicked += (sender, e) => { Speak(entry.Text); }; stackLayout.Children.Add(entry); stackLayout.Children.Add(button); ``` When the `Button` is clicked, the platform-specific `Speak` method translates the value of the `entry.Text` property to speech. ## 👍 Try it now! * Increase the speech volume and pitch. * Increase the speech speed. * Change the speech voice. ## Further Reading For more information about text-to-speech, see [Implementing Text-to-Speech](https://developer.xamarin.com/guides/xamarin-forms/dependency-service/text-to-speech/). ================================================ FILE: xamarin-forms/getting-started/GettingStartedWithXamarinForms-ios.workbook ================================================ --- uti: com.xamarin.workbook platforms: - iOS packages: - id: Xamarin.Forms version: 2.3.2.127 --- # Getting Started with Xamarin.Forms (iOS) > ⚠️ This workbook is deprecated - see **GettingStartedWithXamarinForms.workbook** instead If you want to create a Xamarin.Forms application in Xamarin Workbooks, you must create either a new Xamarin.iOS or Xamarin.Android workbook. This discussion focuses on using Xamarin.Forms from an iOS application. After creating a new iOS workbook, you must add the Xamarin.Forms NuGet package. That’s already been done for this particular workbook, but normally you would invoke the **File** and **Add Package** menu item, and search for **Xamarin.Forms**. Select the top item and click the **Add Package** button. Now use the `#r` command to reference the following Xamarin.Forms assemblies: ```csharp #r "Xamarin.Forms.Core" #r "Xamarin.Forms.Xaml" #r "Xamarin.Forms.Platform" #r "Xamarin.Forms.Platform.iOS" ``` You’ll also want a few standard `using` directives: ```csharp using System; using Xamarin.Forms; using Xamarin.Forms.Platform.iOS; ``` The first step is to define a class that derives from `Application` that creates a Xamarin.Forms `ContentPage` object and sets it to its `MainPage` property: ```csharp class App : Application { public App() { MainPage = new ContentPage(); } } ``` The `ContentPage` is the simplest kind of page in Xamarin.Forms. This is the page that will contain all your program’s Xamarin.Forms visual elements. Now you must execute some iOS startup code. You first need to call the `Forms.Init` method to initialize Xamarin.Forms. You can then instantiate the `App` class defined above, and call the `CreateViewController` method of the page that the `App` class creates. This you set to the `RootViewController` property of the iOS window that Workbooks has created for you: ```csharp Xamarin.Forms.Forms.Init(); App app = new App(); KeyWindow.RootViewController = app.MainPage.CreateViewController(); ``` At this point, you have a Xamarin.Forms program running on the iOS simulator. Now get access to the `ContentPage` instance that the `App` class constructor created: ```csharp ContentPage page = app.MainPage as ContentPage; ``` You use the Xamarin.Forms `Label` element to display up to a paragraph of text. Create a `Label` and set it to the `Content` property of the `ContentPage`: ```csharp Label label = new Label { Text = "Hello Xamarin.Forms in Workbooks!" }; page.Content = label; ``` You’ll see the `Label` on the iOS Simulator, but it overlaps the iOS status bar. One way to avoid that is to set the `Padding` property on the page. This sets an area within the page that content cannot intrude. The four arguments to the `Thickness` constructor are in the order left, top, right, and bottom. The 20-unit space at the top is the height of the status bar: ```csharp page.Padding = new Thickness(0, 20, 0, 0); ``` Now the `Label` is directly under the status bar. You can also center the `Label` on the page by setting its `HorizontalOptions` and `VerticalOptions` properties: ```csharp label.HorizontalOptions = LayoutOptions.Center; label.VerticalOptions = LayoutOptions.Center; ``` Try the `Start` and `End` fields of the `LayoutOptions` structure to position the `Label` in one of nine locations around the page. You can set the color of the `Label` with the `TextColor` property. One convenient approach is to obtain a `Color` value from one of the static read-only properties of the `Color` class: ```csharp label.TextColor = Color.Blue; ``` Another approach is using the static `Color.FromRgb`, `Color.FromRgba`, or `Color.FromHsla` methods to define colors using either the RGB (red-green-blue) or the HSL (hue-saturation-luminosity) color models. Or you can use the `Color` constructor to specify floating point values of red, green, blue, and alpha (opacity). This statement sets the page’s background color: ```csharp page.BackgroundColor = new Color(1.0, 1.0, 0, 1.0); ``` You can set the `FontFamily` property to a string specifying a font that you know is available on the phone: ```csharp label.FontFamily = "Times New Roman"; ``` You can set the FontAttributes property to a member of the `FontAttributes` enumeration, `Bold`, `Italic`, or `None`. If you want both bold and italic, combine the two members with the C# bitwise OR operator: ```csharp label.FontAttributes = FontAttributes.Bold | FontAttributes.Italic; ``` Set the `FontSize` property to increase or decrease the size of the font: ```csharp label.FontSize = 30; ``` You should see the text string wrap to two lines. If not, try a larger value. The wrapping behavior is governed by the `LineBreakMode` property that you can set to a member of the `LineBreakMode` enumeration: ```csharp label.LineBreakMode = LineBreakMode.WordWrap; ``` That’s the default, but you can try the other members: * `NoWrap` * `CharacterWrap` * `HeadTruncation` * `TailTruncation` * `MiddleTruncation` Generally you’ll use one `Label` for every paragraph of text that you display on the screen. If you have multiple paragraphs, you can put the multiple `Label` elements in a `StackLayout`, and then put the `StackLayout` in a `ScrollView`. You’ll see how to do this in a future exercise. Let’s give `Label` a whole paragraph of text: ```csharp label.Text = "Alice was beginning to get very tired of sitting by " + "her sister on the bank, and of having nothing to do: " + "once or twice she had peeped into the book her sister " + "was reading, but it had no pictures or conversations " + "in it, “and what is the use of a book,” thought Alice, " + "“without pictures or conversations?”"; ``` You might want to adjust the `FontSize` so it fits comfortably on the page. If you flip the iOS Simulator between portrait and landscape you can see how the `Label` dynamically reformats the text. By default, the lines of the paragraph are left-justified, but you can set the `HorizontalTextAlignment` property to right justify or center each line: ```csharp label.HorizontalTextAlignment = TextAlignment.Center; ``` Try the `End` member of the `TextAlignment` enumeration to right justify the line, or `Start` for the default left justification. `Label` inherits several transform properties from the `VisualElement` class. The `TranslationX` and `TranslationY` properties move the element horizontally and vertically. The default values are 0 but try some other values: ```csharp label.TranslationX = 0; label.TranslationY = 0; ``` These two properties move the element from the location determined for the element by the Xamarin.Forms layout system. There is nothing to prevent you from setting `TranslationX` or `TranslationY` values that move the element right off the screen! The `Scale` property has a default value of 1: ```csharp label.Scale = 1.0; ``` Try a value of 2 to double the size of the text or 0.5 to decrease the size in half. You’ll notice that the text does not reformat itself to stay within the width of the page. Like the other transform properties, `Scale` is applied after the Label has formatted the text and only affects the element’s visuals. Finally, there is `Rotation`, which you can set to an angle in degrees to rotate the text around its center. The default value is 0 but try 90 or 180 or any number you want: ```csharp label.Rotation = 0; ``` Xamarin.Forms also has a facility to animate these properties. For example, you can apply an animation to the `Label` that is triggered when the user taps the `Label`. To do this, you need to add a `TapGestureRecognizer` object to the `GestureRecognizers` collection of the `Label`: ```csharp // Empty the collection during re-executions label.GestureRecognizers.Clear(); TapGestureRecognizer tap = new TapGestureRecognizer(); tap.Tapped += async (sender, args) => { label.Rotation = 0; await label.RotateTo(360, 5000); }; label.GestureRecognizers.Add(tap); ``` The `Tapped` event handler is executed when you tap the `Label` on the phone or click the `Label` in the iOS Simulator. It rotates the text in a 360-degree circle in 5,000 milliseconds. Notice that the `RotateTo` method is asynchronous. It completes execution when the rotation has completed. This means that you can add other animations to run in sequence, and you can use the static `Task.WhenAll` and `Task.WhenAny` methods to combine animations. Have fun! ================================================ FILE: xamarin-forms/getting-started/GettingStartedWithXamarinForms.workbook ================================================ --- uti: com.xamarin.workbook id: EFA61668-239E-4C12-8535-97661698D5B8 title: Getting Started with Xamarin.Forms platforms: - Android - iOS packages: - id: Xamarin.Forms version: 2.5.0.121934 --- # Getting Started with Xamarin.Forms (Hello, Xamarin.Forms) Follow these steps to learn about the basics of Xamarin.Forms through experimentation with the `Label` text control. ## 1. Add references Xamarin.Forms Workbooks already include the NuGet, so the required assemblies can be referenced like this: ```csharp #r "Xamarin.Forms.Core" #r "Xamarin.Forms.Xaml" #r "Xamarin.Forms.Platform" ``` Then, just like a regular C# file, add the `using` directives: ```csharp using System; using Xamarin.Forms; ``` ## 2. Create the ContentPage Workbooks has already initialized Xamarin.Forms, so `Application.Current.MainPage` can be set directly. The `ContentPage` is the simplest kind of page in Xamarin.Forms. This is the page that will contain all your program’s Xamarin.Forms visual elements. ``` var page = new ContentPage(); Application.Current.MainPage = page; ``` ## 3. Add a Label The Xamarin.Forms `Label` element can display up to a paragraph of text. Create a `Label` and set it to the `Content` property of the `ContentPage`: ```csharp Label label = new Label { Text = "Hello Xamarin.Forms in Workbooks!" }; page.Content = label; ``` You’ll see the `Label` on the iOS Simulator, but it overlaps the iOS status bar. ## 4. Add some Padding One way to avoid that is to set the `Padding` property on the page. This sets an area within the page that content cannot intrude. The four arguments to the `Thickness` constructor are in the order left, top, right, and bottom. The 20-unit space at the top is the height of the status bar: ```csharp page.Padding = new Thickness(0, 20, 0, 0); ``` Now the `Label` is directly under the status bar. ## 5. Add some Layout You can also center the `Label` on the page by setting its `HorizontalOptions` and `VerticalOptions` properties: ```csharp label.HorizontalOptions = LayoutOptions.Center; label.VerticalOptions = LayoutOptions.Center; ``` Try the `Start` and `End` fields of the `LayoutOptions` structure to position the `Label` in one of nine locations around the page. ## 6. Change the Color You can set the color of the `Label` with the `TextColor` property. One convenient approach is to obtain a `Color` value from one of the static read-only properties of the `Color` class: ```csharp label.TextColor = Color.Blue; ``` Another approach is using the static `Color.FromRgb`, `Color.FromRgba`, or `Color.FromHsla` methods to define colors using either the RGB (red-green-blue) or the HSL (hue-saturation-luminosity) color models. Or you can use the `Color` constructor to specify floating point values of red, green, blue, and alpha (opacity). This statement sets the page’s background color: ```csharp page.BackgroundColor = new Color(1.0, 1.0, 0, 1.0); ``` ## 7. Set the Font You can set the `FontFamily` property to a string specifying a font that you know is available on the phone: ```csharp label.FontFamily = "Times New Roman"; ``` You can set the FontAttributes property to a member of the `FontAttributes` enumeration, `Bold`, `Italic`, or `None`. If you want both bold and italic, combine the two members with the C# bitwise OR operator: ```csharp label.FontAttributes = FontAttributes.Bold | FontAttributes.Italic; ``` Set the `FontSize` property to increase or decrease the size of the font: ```csharp label.FontSize = 30; ``` You should see the text string wrap to two lines. If not, try a larger value. ## 8. Experiment with WordWrap The wrapping behavior is governed by the `LineBreakMode` property that you can set to a member of the `LineBreakMode` enumeration: ```csharp label.LineBreakMode = LineBreakMode.WordWrap; ``` That’s the default, but you can try the other members: * `NoWrap` * `CharacterWrap` * `HeadTruncation` * `TailTruncation` * `MiddleTruncation` Generally you’ll use one `Label` for every paragraph of text that you display on the screen. If you have multiple paragraphs, you can put the multiple `Label` elements in a `StackLayout`, and then put the `StackLayout` in a `ScrollView`. You’ll see how to do this in a future exercise. Let’s give `Label` a whole paragraph of text: ```csharp label.Text = "Alice was beginning to get very tired of sitting by " + "her sister on the bank, and of having nothing to do: " + "once or twice she had peeped into the book her sister " + "was reading, but it had no pictures or conversations " + "in it, “and what is the use of a book,” thought Alice, " + "“without pictures or conversations?”"; ``` You might want to adjust the `FontSize` so it fits comfortably on the page. If you flip the iOS Simulator between portrait and landscape you can see how the `Label` dynamically reformats the text. ## 9. Text Alignment By default, the lines of the paragraph are left-justified, but you can set the `HorizontalTextAlignment` property to right justify or center each line: ```csharp label.HorizontalTextAlignment = TextAlignment.Center; ``` Try the `End` member of the `TextAlignment` enumeration to right justify the line, or `Start` for the default left justification. `Label` inherits several transform properties from the `VisualElement` class. The `TranslationX` and `TranslationY` properties move the element horizontally and vertically. The default values are 0 but try some other values: ```csharp label.TranslationX = 0; label.TranslationY = 0; ``` These two properties move the element from the location determined for the element by the Xamarin.Forms layout system. There is nothing to prevent you from setting `TranslationX` or `TranslationY` values that move the element right off the screen! ## 10. Scaling The `Scale` property has a default value of 1: ```csharp label.Scale = 1.0; ``` Try a value of 2 to double the size of the text or 0.5 to decrease the size in half. You’ll notice that the text does not reformat itself to stay within the width of the page. Like the other transform properties, `Scale` is applied after the Label has formatted the text and only affects the element’s visuals. Finally, there is `Rotation`, which you can set to an angle in degrees to rotate the text around its center. The default value is 0 but try 90 or 180 or any number you want: ```csharp label.Rotation = 0; ``` ## 11. Animation Xamarin.Forms also has a facility to animate these properties. For example, you can apply an animation to the `Label` that is triggered when the user taps the `Label`. To do this, you need to add a `TapGestureRecognizer` object to the `GestureRecognizers` collection of the `Label`: ```csharp // Empty the collection during re-executions label.GestureRecognizers.Clear(); TapGestureRecognizer tap = new TapGestureRecognizer(); tap.Tapped += async (sender, args) => { label.Rotation = 0; await label.RotateTo(360, 5000); }; label.GestureRecognizers.Add(tap); ``` The `Tapped` event handler is executed when you tap the `Label` on the phone or click the `Label` in the iOS Simulator. It rotates the text in a 360-degree circle in 5,000 milliseconds. Notice that the `RotateTo` method is asynchronous. It completes execution when the rotation has completed. This means that you can add other animations to run in sequence, and you can use the static `Task.WhenAll` and `Task.WhenAny` methods to combine animations. Have fun! ================================================ FILE: xamarin-forms/getting-started/meta.json ================================================ { "order":{ "GettingStartedWithXamarinForms.workbook":"Hello, Xamarin.Forms" } } ================================================ FILE: xamarin-forms/meta.json ================================================ { "order":{ "getting-started":"Getting Started", "application-fundamentals":"Application Fundamentals", "user-interface":"User Interface", "advanced":"Advanced" } } ================================================ FILE: xamarin-forms/user-interface/alerts/alerts.workbook/FormsInit.csx ================================================ #r "Xamarin.Forms.Core" #r "Xamarin.Forms.Xaml" #r "Xamarin.Forms.Platform" using System; using Xamarin.Forms; var page = new ContentPage(); StackLayout stackLayout = new StackLayout { Margin = new Thickness(0, 20, 0, 0) }; page.Content = stackLayout; Application.Current.MainPage = page; ================================================ FILE: xamarin-forms/user-interface/alerts/alerts.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook id: 4D72C07E-8595-4575-A1F6-0CF473774077 title: Displaying Pop-ups with Xamarin.Forms platforms: - Android - iOS packages: - id: Xamarin.Forms version: 2.5.0.121934 --- # Displaying Pop-ups Xamarin.Forms provides two pop-up like user interface elements: an alert and an action sheet. An alert is a modal pop-up to alert the user, or to ask simple question of them. An action sheet is a modal pop-up that' used to guide the user through a task. ## Initializing the Workbook In order to run a Xamarin.Forms workbook, some initialization code must be executed: ```csharp // The Xamarin.Forms initialization code isn't important to understanding this workbook #load "FormsInit.csx" using Xamarin.Forms; ``` For more information about the initialization code, see the Getting Started with Xamarin.Forms workbook. ## Displaying an Alert An alert is displayed with the `DisplayAlert` method on any `Page`: ```csharp await page.DisplayAlert("Alert", "You have been alerted.", "OK"); ``` The alert displays modally and once dismissed you can continue interacting with the application. > ℹ️ The `DisplayAlert` method is asynchronous, and should be preceded by the `await` keyword. An alert can also be used to capture a user's response by presenting two buttons: ```csharp bool answer = await page.DisplayAlert("Question", "Would you like to play a game?", "Yes", "No"); ``` The response to the alert is returned as a `boolean` value. ## Displaying an Action Sheet An action sheet is displayed with the `DisplayActionSheet` method on any `Page`: ```csharp string result = await page.DisplayActionSheet("Send to?", "Cancel", null, "Email", "Twitter", "Facebook"); ``` The response to the action sheet is returned as a `string` value. > ℹ️ The `DisplayActionSheet` method is asynchronous, and should be preceded by the `await` keyword. The third argument to the `DisplayActionSheet` method is known as the *destruct* button, and can be `null` or given a value: ```csharp string result = await page.DisplayActionSheet("Save Photo to?", "Cancel", "Delete", "Photo Roll", "Email"); ``` Notice that the *destruct* button is rendered differently from the other action sheet buttons. > ℹ️ The fourth argument to the `DisplayActionSheet` method is of type `params string[]`. Therefore, an action sheet can display any number of responses for the user to select from. ## 👍 Try it now! * Create an alert that contains a cancel button. * Create an action sheet that contains days of the week as responses. ## Further Reading For more information about displaying pop-ups, see [Displaying Pop-ups](https://developer.xamarin.com/guides/xamarin-forms/user-interface/navigation/pop-ups/). ================================================ FILE: xamarin-forms/user-interface/button/button.workbook/FormsInit.csx ================================================ #r "Xamarin.Forms.Core" #r "Xamarin.Forms.Xaml" #r "Xamarin.Forms.Platform" using System; using Xamarin.Forms; var page = new ContentPage(); StackLayout stackLayout = new StackLayout { Margin = new Thickness(0, 20, 0, 0) }; page.Content = stackLayout; Application.Current.MainPage = page; ================================================ FILE: xamarin-forms/user-interface/button/button.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook id: 6E002D34-2399-4D44-97D3-DDC4EA1A94E1 title: Processing Button Clicks with Xamarin.Forms platforms: - Android - iOS packages: - id: Xamarin.Forms version: 2.5.0.121934 --- # Processing Button Clicks The Xamarin.Forms `Button` view initiates an action when the user presses it. The `Button` displays text, with or without an accompanying image, ## Initializing the Workbook In order to run a Xamarin.Forms workbook, some initialization code must be executed: ```csharp // The Xamarin.Forms initialization code isn't important to understanding this workbook #load "FormsInit.csx" using Xamarin.Forms; ``` For more information about the initialization code, see the Getting Started with Xamarin.Forms workbook. ## Setting the Button Text and Image A `Button` exposes the `Text` property, which is used to set the text presented by the `Button`: ```csharp var button = new Button { Text = "Click Me!" }; stackLayout.Children.Add(button); ``` A `Button` can optionally display an image next to the text by setting the `Image` property: ```csharp button.Image = "coffee.png"; ``` The `Button` instance can be left-aligned on the page by setting its `HorizontalOptions` property: ```csharp button.HorizontalOptions = LayoutOptions.Start; ``` The `Button` can be returned to the center by settings its `HorizontalOptions` property to `LayoutOptions.Center`: ```csharp button.HorizontalOptions = LayoutOptions.Center; ``` In addition, the `VerticalOptions` property can be set to center the `Button` vertically. ## Responding to Clicks When a user presses the `Button`, its appearance changes to provide feedback. When the finger is released, a `Clicked` event fires: ```csharp // Number of times the button has been pressed var count = 0; void OnButtonClicked(object sender, EventArgs e) { button.Text = string.Format("Clicked {0} times", ++count); } button.Clicked += OnButtonClicked; ``` This code defines an event handler named `OnButtonClicked`, which updates the `Button.Text` property on each click. Generally, event handlers are given names beginning with the word `On`, followed by an identifier for the view firing the event, followed by the event name. Alternatively, the `Clicked` event handler can be written using a lambda expression: ```csharp var count2 = 0; var button2 = new Button { Text = "Click Me!" }; button2.Clicked += (sender, e) => button2.Text = string.Format("Clicked {0} times", ++count2); stackLayout.Children.Add(button2); ``` ## Setting Colors and Border Options The color of a `Button` can be changed by setting the `TextColor` property: ```csharp button.TextColor = Color.Blue; ``` Another approach is using the static `Color.FromRgb` method: ```csharp button.TextColor = Color.FromRgb(128, 64, 32); ``` The background color can be changed by setting the `BackgroundColor` property: ```csharp button.BackgroundColor = Color.Yellow; ``` In addition, a border color can be set with the `BorderColor` property: ```csharp button.BorderColor = Color.Black; ``` However, the border won't appear until a border width is specified with the `BorderWidth` property: ```csharp button.BorderWidth = 2; ``` The corner radius of the border can be set with the `BorderRadius` property: ```csharp button.BorderRadius = 0; ``` A `BorderRadius` value of 0 will ensure that the border corners are square. ## Setting the Font A `Button`s font can be changed by setting the `FontFamily` property to a string that specifies a font that is available on the phone: ```csharp button.FontFamily = "Times New Roman"; ``` The `FontAttributes` enumeration can be used to change the text displayed by a `Button` to bold and/or italic: ```csharp button.FontAttributes = FontAttributes.Italic; ``` The size of the text being displayed by a `Button` can be changed with the `FontSize` property: ```csharp button.FontSize = 30; ``` ## 👍 Try it now! * Replace the `button` event handler with a lambda expression. * Add an image to `button2` by setting its `Image` property. * Right align a `Button` by setting its `HorizontalOptions` property to `End`. ## Further Reading For more information about the `Button` view, see [Button Class](https://developer.xamarin.com/api/type/Xamarin.Forms.Button/). ================================================ FILE: xamarin-forms/user-interface/editor/editor.workbook/FormsInit.csx ================================================ #r "Xamarin.Forms.Core" #r "Xamarin.Forms.Xaml" #r "Xamarin.Forms.Platform" using System; using Xamarin.Forms; var page = new ContentPage(); StackLayout stackLayout = new StackLayout { Margin = new Thickness(0, 20, 0, 0) }; page.Content = stackLayout; Application.Current.MainPage = page; ================================================ FILE: xamarin-forms/user-interface/editor/editor.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook id: 01008EB5-E4F3-44F0-91D1-5D9DBB31EF9D title: Multi-Line Text with Xamarin.Forms platforms: - Android - iOS packages: - id: Xamarin.Forms version: 2.5.0.121934 --- # Entering Multi-Line Text The Xamarin.Forms `Editor` view is used for multi-line text input. ## Initializing the Workbook In order to run a Xamarin.Forms workbook, some initialization code must be executed: ```csharp // The Xamarin.Forms initialization code isn't important to understanding this workbook #load "FormsInit.csx" using Xamarin.Forms; ``` For more information about the initialization code, see the Getting Started with Xamarin.Forms workbook. ## Setting and Reading Text An `Editor`, like other text-presenting views, exposes the `Text` property, which is used to set and read the text presented by the `Editor`: ```csharp var editor = new Editor { Text = "Click here to see the virtual keyboard", HeightRequest = 150 }; stackLayout.Children.Add(editor); ``` To read text, access the `Text` property: ```csharp var text = editor.Text; ``` ## Changing the Virtual Keyboard A virtual keyboard appears when an `Editor` has focus. The `Editor` defines a `Keyboard` property that allows you to specify the virtual keyboard that's displayed: ```csharp editor.Keyboard = Keyboard.Chat; ``` Click in the `editor` instance and the chat keyboard will appear. The `Keyboard` property is of type `Keyboard`, which defines the following readonly-only properties: * `Default` * `Text` * `Chat` * `Url` * `Email` * `Telephone` * `Numeric` For more information about changing the virtual keyboard, see [Choose a keyboard for an Entry](https://developer.xamarin.com/recipes/cross-platform/xamarin-forms/controls/choose-keyboard-for-entry/). ## Setting Colors The colors of an `Editor` can be changed by setting the `TextColor` and `BackgroundColor` properties: ```csharp editor.TextColor = Color.White; editor.BackgroundColor = Color.Blue; ``` ## Interacting with an Editor An `Editor` exposes `Completed` and `TextChanged` events: * The `Completed` event is raised when the user has ended input by pressing the return key on the keyboard. * The `TextChanged` event is raised when the text changes in the `Editor`, and provides the text values before and after the change. ```csharp var completedLabel = new Label(); var oldTextLabel = new Label(); var newTextLabel = new Label(); stackLayout.Children.Add(oldTextLabel); stackLayout.Children.Add(newTextLabel); stackLayout.Children.Add(completedLabel); editor.Completed += (sender, e) => { completedLabel.Text = "Completed event has fired"; }; editor.TextChanged += (sender, e) => { oldTextLabel.Text = e.OldTextValue; newTextLabel.Text = e.NewTextValue; }; ``` Enter data in the `editor` instance, and watch the `Label` instances update as the value of the `editor.Text` property changes. ## 👍 Try it now! * Change the `editor` instance to use the `Text` keyboard. * Change the `editor` instance to use a cyan background, with black text. ## Further Reading For more information about the `Editor` view, see [Entry](https://developer.xamarin.com/guides/xamarin-forms/user-interface/text/editor/). ================================================ FILE: xamarin-forms/user-interface/entry/entry.workbook/FormsInit.csx ================================================ #r "Xamarin.Forms.Core" #r "Xamarin.Forms.Xaml" #r "Xamarin.Forms.Platform" using System; using Xamarin.Forms; var page = new ContentPage(); StackLayout stackLayout = new StackLayout { Margin = new Thickness(0, 20, 0, 0) }; page.Content = stackLayout; Application.Current.MainPage = page; ================================================ FILE: xamarin-forms/user-interface/entry/entry.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook id: 1EA7D80E-032E-46ED-9A5A-CADCD9EC9F96 title: Entering Text with Xamarin.Forms platforms: - Android - iOS packages: - id: Xamarin.Forms version: 2.5.0.121934 --- # Entering Text The Xamarin.Forms `Entry` view is used for single-line text input, and can also be used as a password field. ## Initializing the Workbook In order to run a Xamarin.Forms workbook, some initialization code must be executed: ```csharp // The Xamarin.Forms initialization code isn't important to understanding this workbook #load "FormsInit.csx" using Xamarin.Forms; ``` For more information about the initialization code, see the Getting Started with Xamarin.Forms workbook. ## Setting and Reading Text An `Entry`, like other text-presenting views, exposes the `Text` property, which is used to set and read the text presented by the `Entry`: ```csharp var entry = new Entry { Text = "Click here to see the virtual keyboard" }; stackLayout.Children.Add(entry); ``` To read text, access the `Text` property: ```csharp var text = entry.Text; ``` > ⚠️ The width of an `Entry` is defined by settings its `WidthRequest` property. Do not depend on the width of an `Entry` being defined based on the value of its `Text` property. ## Changing the Virtual Keyboard A virtual keyboard appears when an `Entry` has focus. The `Entry` defines a `Keyboard` property that allows you to specify the virtual keyboard that's displayed: ```csharp entry.Keyboard = Keyboard.Numeric; ``` Click in the `entry` instance and the numeric keyboard will appear. The `Keyboard` property is of type `Keyboard`, which defines the following readonly-only properties: * `Default` * `Text` * `Chat` * `Url` * `Email` * `Telephone` * `Numeric` For more information about changing the virtual keyboard, see [Choose a keyboard for an Entry](https://developer.xamarin.com/recipes/cross-platform/xamarin-forms/controls/choose-keyboard-for-entry/). ## Showing Placeholder Text An `Entry` can show placeholder text when it's not storing user input. Placeholder text is often shown to clarify the content that's appropriate for an `Entry`: ```csharp var passwordEntry = new Entry { Placeholder = "Enter password" }; stackLayout.Children.Add(passwordEntry); ``` ## Inputting a Password An `Entry` has an `IsPassword` property. When this property is set to `true`, the contents of the `Text` property will be masked: ```csharp passwordEntry.IsPassword = true; ``` Click in the `passwordEntry` instance and enter some text. You will notice that the text is masked. ## Setting Colors The colors of an `Entry` can be changed by setting the `TextColor` and `BackgroundColor` properties: ```csharp entry.TextColor = Color.White; entry.BackgroundColor = Color.Blue; ``` > ℹ️ Placeholder text color can't be customized and will be the same regardless of the the `TextColor` setting. ## Interacting with an Entry An `Entry` exposes `Completed` and `TextChanged` events: * The `Completed` event is raised when the user has ended input by pressing the return key on the keyboard. * The `TextChanged` event is raised when the text changes in the `Entry`, and provides the text values before and after the change. ```csharp var eventsEntry = new Entry { Placeholder = "Enter text to observe events firing" }; var completedLabel = new Label(); var oldTextLabel = new Label(); var newTextLabel = new Label(); eventsEntry.Completed += (sender, e) => { completedLabel.Text = "Completed event has fired"; }; eventsEntry.TextChanged += (sender, e) => { oldTextLabel.Text = e.OldTextValue; newTextLabel.Text = e.NewTextValue; }; stackLayout.Children.Add(eventsEntry); stackLayout.Children.Add(oldTextLabel); stackLayout.Children.Add(newTextLabel); stackLayout.Children.Add(completedLabel); ``` Enter data in the `eventsEntry` instance, and watch the `Label` instances update as the value of the `eventsEntry.Text` property changes. ## 👍 Try it now! * Change the `entry` instance to use the `Url` keyboard. * Change the `entry` instance to use a gray background, with black text. ## Further Reading For more information about the `Entry` view, see [Entry](https://developer.xamarin.com/guides/xamarin-forms/user-interface/text/entry/). ================================================ FILE: xamarin-forms/user-interface/image/image.workbook/FormsInit.csx ================================================ #r "Xamarin.Forms.Core" #r "Xamarin.Forms.Xaml" #r "Xamarin.Forms.Platform" using System; using Xamarin.Forms; var page = new ContentPage(); StackLayout stackLayout = new StackLayout { Margin = new Thickness(0, 20, 0, 0) }; page.Content = stackLayout; Application.Current.MainPage = page; ================================================ FILE: xamarin-forms/user-interface/image/image.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook id: 58AF788B-116D-487C-AEB1-7F06A82D010B title: Displaying Images with Xamarin.Forms platforms: - Android - iOS packages: - id: Xamarin.Forms version: 2.5.0.121934 --- # Displaying Images The Xamarin.Forms `Image` view displays images on a page. The image source can be local or remote. ## Initializing the Workbook In order to run a Xamarin.Forms workbook, some initialization code must be executed: ```csharp // The Xamarin.Forms initialization code isn't important to understanding this workbook #load "FormsInit.csx" using Xamarin.Forms; ``` For more information about the initialization code, see the Getting Started with Xamarin.Forms workbook. ## Displaying a Local Image To display a local image, create a `Image` instance and set its `Source` property to an image filename: ```csharp var image = new Image { Source = "waterfront.jpg" }; stackLayout.Children.Add(image); ``` By default, the displayed image occupies as much space as possible on the page for its resolution, while maintaining its aspect ratio. The opacity of the image can be changed by setting the `Opacity` property: ```csharp image.Opacity = 0.5; ``` This has the effect of making the image partly translucent. ## Changing the Displayed Aspect Ratio In order to demonstrate changing the displayed aspect ratio of the image, the height and width of the image must be changed, and the `Opacity` property will be reset: ```charp image.HeightRequest = 200; image.WidthRequest = 100; image.Opacity = 1; ``` The `Aspect` property determines how the image will be scaled to fit the display area, and is set to a value of the `Aspect` enumeration. `Fill` stretches the image to completely fill the display area. This may result in the image aspect ratio being distorted: ```csharp image.Aspect = Aspect.Fill; ``` `AspectFill` clips the image so that it fills the display area while preserving the aspect ratio: ```csharp image.Aspect = Aspect.AspectFill; ``` `AspectFit` is the default value, which ensures that the entire image fits into the display area: ```csharp image.Aspect = Aspect.AspectFit; ``` ## Displaying a Remote Image Images can be downloaded for display by setting the `Source` property of the `Image` view to a URL: ```csharp image.Source = "https://developer.xamarin.com/demo/IMG_1101.JPG"; ``` By default, image caching is enabled for downloaded images, which will be stored locally for 24 hours. However, image caching can be disabled when instantiating the image source: ```csharp image.Source = new UriImageSource { Uri = new Uri("https://developer.xamarin.com/demo/IMG_0613.JPG"), CachingEnabled = false }; ``` To set a specific cache period, set the `CacheValidity` property of the `UriImageSource` to a `TimeSpan`: ```csharp image.Source = new UriImageSource { Uri = new Uri("https://developer.xamarin.com/demo/IMG_2267.JPG"), CachingEnabled = true, CacheValidity = new TimeSpan(5,0,0,0) } ``` This will cache the downloaded image for 5 days. ## Obtaining the Loading Status of an Image The loading status of the image can be obtained by examining its `IsLoading` property: ```csharp var activityIndicator = new ActivityIndicator(); activityIndicator.SetBinding(ActivityIndicator.IsRunningProperty, "IsLoading"); activityIndicator.BindingContext = image; stackLayout.Children.Add(activityIndicator); image.Source = new UriImageSource { Uri = new Uri("https://developer.xamarin.com/demo/IMG_4023.JPG"), CachingEnabled = false }; ``` This code creates an `ActivityIndicator` instance, and binds its `IsRunning` property to the value of the `IsLoading` property on the `Image` instance. Therefore, when the image is loading, the `ActivityIndicator` indicates this. ## 👍 Try it now! * Set a remote image to be partly transparent. * Set a remote image to completely fill the display area. * Set a remote image to be cached for 12 hours when it's first downloaded. ## Further Reading For more information about the `Image` view, see [Working with Images](https://developer.xamarin.com/guides/xamarin-forms/working-with/images/). ================================================ FILE: xamarin-forms/user-interface/label/label.workbook/FormsInit.csx ================================================ #r "Xamarin.Forms.Core" #r "Xamarin.Forms.Xaml" #r "Xamarin.Forms.Platform" using System; using Xamarin.Forms; var page = new ContentPage(); StackLayout stackLayout = new StackLayout { Margin = new Thickness(0, 20, 0, 0) }; page.Content = stackLayout; Application.Current.MainPage = page; ================================================ FILE: xamarin-forms/user-interface/label/label.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook id: F36A7045-ABF6-411E-8F1A-EB3374BAC78D title: Displaying Text with Xamarin.Forms platforms: - Android - iOS packages: - id: Xamarin.Forms version: 2.5.0.121934 --- # Displaying Text The Xamarin.Forms `Label` view is used for displaying single and multi-line text. ## Initializing the Workbook In order to run a Xamarin.Forms workbook, some initialization code must be executed: ```csharp // The Xamarin.Forms initialization code isn't important to understanding this workbook #load "FormsInit.csx" using Xamarin.Forms; ``` For more information about the initialization code, see the Getting Started with Xamarin.Forms workbook. ## Setting Text A `Label`, like other text-presenting views, exposes the `Text` property, which is used to set the text presented by the `Label`: ```csharp var label = new Label { Text = "Hello from Xamarin.Forms" }; stackLayout.Children.Add(label); ``` The `Label` instance can be horizontally centered on the page by setting its `HorizontalOptions` property: ```csharp label.HorizontalOptions = LayoutOptions.Center; ``` In addition, the `VerticalOptions` property can be set to center the `Label` vertically. ## Setting Colors The color of a `Label` can be changed by setting the `TextColor` property: ```csharp label.TextColor = Color.Blue; ``` Another approach is using the static `Color.FromRgb` method: ```csharp label.TextColor = Color.FromRgb(32, 64, 128); ``` In addition, a background color can be set with the `BackgroundColor` property: ```csharp label.BackgroundColor = Color.Teal; ``` ## Setting the Font A `Label`s font can be changed by setting the `FontFamily` property to a string that specifies a font that is available on the phone: ```csharp label.FontFamily = "Times New Roman"; ``` The `FontAttributes` enumeration can be used to change the text displayed by a `Label` to bold and/or italic: ```csharp label.FontAttributes = FontAttributes.Italic; ``` The size of the text being displayed by a `Label` can be changed with the `FontSize` property: ```csharp label.FontSize = 30; ``` The text should wrap to two lines because of the increased font size. ## Controlling Truncation and Wrapping Text wrapping behavior is controlled by the `LineBreakMode` property, which can be set to a member of the `LineBreakMode` enumeration: ```csharp label.LineBreakMode = LineBreakMode.WordWrap; ``` The other values of the `LineBreakMode` enumeration are: * `NoWrap` * `CharacterWrap` * `HeadTruncation` * `TailTruncation` * `MiddleTruncation` ## Controlling Text Alignment Generally, a `Label` represents one paragraph of text. By default, the lines of the paragraph are left-justified: ```csharp label.Text = "Xamarin.Forms is a cross-platform natively backed UI " + "toolkit abstraction that allows developers to easily " + "create user interfaces that can be shared across iOS, " + "Android, and Windows Phone."; ``` However, the `HorizontalTextAlignment` property can be set to right justify or center each line: ```csharp label.HorizontalTextAlignment = TextAlignment.Center; ``` ## 👍 Try it now! * Make the text displayed by the `Label` to be bold and italic. This can be achieved with the bitwise OR operator (|). * Make the text displayed by the `Label` use `MiddleTruncation` line truncation. * Make the `Label` text right justified by setting the `End` member of the `TextAlignment` enumeration. ## Further Reading For more information about the `Label` view, see [Label](https://developer.xamarin.com/guides/xamarin-forms/user-interface/text/label/). ================================================ FILE: xamarin-forms/user-interface/layout-options/layout-options.workbook/FormsInit.csx ================================================ #r "Xamarin.Forms.Core" #r "Xamarin.Forms.Xaml" #r "Xamarin.Forms.Platform" using System; using Xamarin.Forms; var page = new ContentPage(); StackLayout stackLayout = new StackLayout { Margin = new Thickness(0, 20, 0, 0) }; page.Content = stackLayout; Application.Current.MainPage = page; ================================================ FILE: xamarin-forms/user-interface/layout-options/layout-options.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook id: A7C4BA53-474A-49B3-92A2-E4C2D1D26FE5 title: Setting LayoutOptions with Xamarin.Forms platforms: - Android - iOS packages: - id: Xamarin.Forms version: 2.5.0.121934 --- # Setting LayoutOptions Every Xamarin.Forms view has `HorizontalOptions` and `VerticalOptions` properties, of type `LayoutOptions`. This structure is used to control alignment and expansion options for a view, relative to its parent, and consists of the following values: * `Start` * `Center` * `End` * `Fill` * `StartAndExpand` * `CenterAndExpand` * `EndAndExpand` * `FillAndExpand` The `Start`, `Center`, `End`, and `Fill` values are used to define the view's alignment within the parent view, and the `StartAndExpand`, `CenterAndExpand`, `EndAndExpand`, and `FillAndExpand` values are used to define whether the view will occupy more space if available. > ℹ️ The default value of a view's `HorizontalOptions` and `VerticalOptions` properties is `LayoutOptions.Fill`. ## Initializing the Workbook In order to run a Xamarin.Forms workbook, some initialization code must be executed: ```csharp // The Xamarin.Forms initialization code isn't important to understanding this workbook #load "FormsInit.csx" using Xamarin.Forms; ``` For more information about the initialization code, see the Getting Started with Xamarin.Forms workbook. ## Initializing the User Interface The following code initializes the UI with a series of `Button` instances that will be used to demonstrate alignment and expansion options: ```csharp void AddButton(string text, LayoutOptions options) { var button = new Button { Text = text, VerticalOptions = options, HeightRequest = 20, BackgroundColor = Color.White }; button.Clicked += (sender, e) => { stackLayout.VerticalOptions = options; }; stackLayout.Children.Add(button); stackLayout.Children.Add(new BoxView { BackgroundColor = Color.Yellow, HeightRequest = 1 }); } stackLayout.Spacing = 2; stackLayout.Padding = 2; stackLayout.BackgroundColor = Color.Gray; stackLayout.VerticalOptions = LayoutOptions.Start; AddButton("Start", LayoutOptions.Start); AddButton("Center", LayoutOptions.Center); AddButton("End", LayoutOptions.End); AddButton("Fill", LayoutOptions.Fill); AddButton("StartAndExpand", LayoutOptions.StartAndExpand); AddButton("CenterAndExpand", LayoutOptions.CenterAndExpand); AddButton("EndAndExpand", LayoutOptions.EndAndExpand); AddButton("FillAndExpand", LayoutOptions.FillAndExpand); ``` ## Setting Alignment Alignment controls how a view is positioned within its parent view when the parent view contains unused space (that is, the parent view is larger than the combined size of all of its children). > ℹ️ When all the space in a parent view is used, the alignment options have no effect. ### Start `LayoutOptions.Start` is used to define a `View` that will appear at the start of its parent. For horizontal alignment, this positions the `View` on the left hand side of the parent `View`, and for vertical alignment, it positions the `View` at the top of the parent `View`. Clicking the *Start* `Button` vertically aligns `StackLayout` and `Button` instances using `LayoutOptions.Start`. This layout occurs because the `StackLayout` is vertically aligned to the top of the parent `View`. However, setting each `Button.VerticalOptions` property to a different `LayoutOptions` value has no additional effect because the `StackLayout` does not contain any unused space. ### Center `LayoutOptions.Center` is used to define a `View` that will appear centered in its parent. The `View` is horizontally or vertically centered. Clicking the *Center* `Button` vertically aligns the `StackLayout` and `Button` instances using `LayoutOptions.Center`. This layout occurs because the `StackLayout` is vertically aligned to the center of the parent `View`. However, setting each `Button.VerticalOptions` property to a different `LayoutOptions` value has no additional effect because the `StackLayout` does not contain any unused space. ### End `LayoutOptions.End` is used to define a `View` that will appear at the end of its parent. For horizontal alignment, this positions the `View` on the right hand side of the parent `View`, and for vertical alignment, it positions the `View` at the bottom of the parent `View`. Clicking the *End* `Button` vertically aligns the `StackLayout` and `Button` instances using `LayoutOptions.End`. This layout occurs because the `StackLayout` is vertically aligned to the bottom of the parent `View`. However, setting each `Button.VerticalOptions` property to a different `LayoutOptions` value has no additional effect because the `StackLayout` does not contain any unused space. ### Fill `LayoutOptions.Fill` is used to define a `View` that will occupy the full size of its parent. For horizontal alignment, this ensures that the `View` will fill the width of the parent `View`, and for vertical alignment, it ensures that the `View` will fill the height of the parent `View`. Clicking the *Fill* `Button` vertically aligns the `StackLayout` and `Button` instances using `LayoutOptions.Fill`. This layout occurs because the `StackLayout` is vertically aligned to fill the height of the parent `View`. Setting each `Button.VerticalOptions` property to a different `LayoutOptions` value results in different `Button` alignments, because the `StackLayout` is larger than the combined requested size of its children. Therefore, each `Button` uses its vertically specified `LayoutOptions` behavior. ## Expansion Expansion controls whether a view will occupy more space if available. If a parent view contains unused space (that is, the parent view is larger than the combined size of all of its children), the unused space is given to any child views that use the `AndExpand` suffix. > ℹ️ When all the space in a parent view is used, the expansion options have no effect. ### StartAndExpand `LayoutOptions.StartAndExpand` is used to define a `View` that will appear at the start of its parent, and that will expand to occupy more space if available. Clicking the *StartAndExpand* `Button` vertically aligns the `StackLayout` and `Button` instances using `LayoutOptions.StartAndExpand`. This layout occurs because the `StackLayout` is vertically aligned to the top of the parent `View`, but expansion doesn't occur because the parent view isn't larger than its children. Setting each `Button.VerticalOptions` property to a different `LayoutOptions` value has no additional effect because the `StackLayout` does not contain any unused space. ### CenterAndExpand `LayoutOptions.CenterAndExpand` is used to define a `View` that will appear centered in its parent, and that will expand to occupy more space if available. Clicking the *CenterAndExpand* `Button` vertically aligns the `StackLayout` and `Button` instances using `LayoutOptions.CenterAndExpand`. This layout occurs because the `StackLayout` is vertically aligned to the center of the parent `View`, but expansion doesn't occur because the parent view isn't larger than its children. Setting each `Button.VerticalOptions` property to a different `LayoutOptions` value has no additional effect because the `StackLayout` does not contain any unused space. ### EndAndExpand `LayoutOptions.EndAndExpand` is used to define a `View` that will appear at the end of its parent, and that will expand to occupy more space if available. Clicking the *EndAndExpand* `Button` vertically aligns the `StackLayout` and `Button` instances using `LayoutOptions.EndAndExpand`. This layout occurs because the `StackLayout` is vertically aligned to the bottom of the parent `View`, but expansion doesn't occur because the parent view isn't larger than its children. Setting each `Button.VerticalOptions` property to a different `LayoutOptions` value has no additional effect because the `StackLayout` does not contain any unused space. ### FillAndExpand `LayoutOptions.FillAndExpand` is used to define a `View` that will occupy the full size of its parent, and that will expand to occupy more space if available. Clicking the *FillAndExpand* `Button` vertically aligns the `StackLayout` and `Button` instances using `LayoutOptions.FillAndExpand`. This layout occurs because the `StackLayout` is vertically aligned to fill the height of the parent `View`. Setting each `Button.VerticalOptions` property to a different `LayoutOptions` value results in different `Button` alignments, because the `StackLayout` is larger than the combined requested size of its children. Therefore, additional space is uniformly given to all the `Button` controls with the `AndExpand` suffix, with the alignment of the `Button` within its space being controlled by its `LayoutOptions` value. ## 👍 Try it now! * Set alignment and expansion options for a simple layout that sets `HorizontalOptions` properties. ## Further Reading For more information about the `LayoutOptions` structure see [LayoutOptions](https://developer.xamarin.com/guides/xamarin-forms/user-interface/layouts/layout-options/). ================================================ FILE: xamarin-forms/user-interface/listview/ListView.workbook ================================================ --- uti: com.xamarin.workbook id: 2e681a85-d259-48cd-bda0-2dc4541ee184 title: Xamarin.Forms ListView platforms: - Android - iOS packages: - id: Newtonsoft.Json version: 11.0.1 - id: Xamarin.Forms version: 2.5.0.121934 --- # Xamarin.Forms ListView with Json ...borrowing some ideas from James Montemagno’s [sample](https://github.com/jamesmontemagno/MonkeysApp-AppIndexing "Monkey Sample App") ## 1. Add references Start by adding the references that we need to the NuGet packages installed in the workbook: ```csharp #r "Xamarin.Forms.Core" #r "Xamarin.Forms.Platform" #r "Xamarin.Forms.Xaml" #r "Newtonsoft.Json" ``` ## 2. We need `using` statements too ```csharp using Xamarin.Forms; using Xamarin.Forms.Platform; ``` ## 3. Create the ContentPage Workbooks has already initialized Xamarin.Forms, so `Application.Current.MainPage` can be set directly. ```csharp public class MonkeyPage : ContentPage { public ListView MonkeyList { get; set; } public MonkeyPage () { Title = "Monkey List"; MonkeyList = new ListView(); Content = MonkeyList; } } var monkeyPage = new MonkeyPage(); Application.Current.MainPage = monkeyPage; ``` ## 4. Grab the monkey data from GitHub ```csharp using Newtonsoft.Json; using System.Net.Http; public class Monkey { public string Name { get; set; } public string Location { get; set; } public string Details { get; set; } public string Image { get; set; } public int Population { get; set; } } var client = new HttpClient(); var json = await client.GetStringAsync ("https://raw.githubusercontent.com/jamesmontemagno/MonkeysApp-AppIndexing/master/MonkeysApp/monkeydata.json"); var monkeys = JsonConvert.DeserializeObject>(json); ``` ## 5. Bind the data to the list ListView Use the built-in `ImageCell` template and assigning properties from the monkey model: ```csharp var dt = new DataTemplate(typeof(ImageCell)); dt.SetBinding(TextCell.TextProperty, "Name"); dt.SetBinding(ImageCell.DetailProperty, "Location"); dt.SetBinding(ImageCell.ImageSourceProperty, "Image"); monkeyPage.MonkeyList.ItemTemplate = dt; monkeyPage.MonkeyList.ItemsSource = monkeys; ``` ## 6. Now we see a list of monkeys and their pictures! ================================================ FILE: xamarin-forms/user-interface/listview/ListView1-android.workbook ================================================ --- uti: com.xamarin.workbook platform: Android packages: - id: Newtonsoft.Json version: 8.0.3 - id: Xamarin.Forms version: 2.2.0.31 --- # Xamarin.Forms REST —> ListView > ⚠️ This workbook is deprecated - see **Listview.workbook** instead ## A little hack to demo Xamarin.Forms on iOS with Workbooks... ...borrowing some ideas from James Montemagno’s [sample](https://github.com/jamesmontemagno/MonkeysApp-AppIndexing "Monkey Sample App") ### Wire up a Xamarin.Forms app 1) Start by importing the Nugets for Xamarin.Forms and the iOS Platform Renderers (and Json.Net for some parsing later on): ```csharp #r "Xamarin.Forms.Platform.iOS" #r "Xamarin.Forms.Core" #r "Xamarin.Forms.Xaml" #r "Xamarin.Forms.Platform" #r "Newtonsoft.Json" ``` 2) We need `using` statements too: ```csharp using Xamarin.Forms; using Xamarin.Forms.Platform.iOS; ``` 3) Set up a simple page with an exposed property to edit (in this case, a `ListView` which will be populated later): ```csharp public class MyPage : ContentPage { public ListView MyList {get;set;} public MyPage () { Title = "A test"; MyList = new ListView (); // no data yet, though Content = MyList; } } ``` 4) Ok great - but we can’t see anything! Oh, we need to bootstrap the Xamarin.Forms app object too: ```csharp public class App : Application { public MyPage Page {get;set;} public App () { Page = new MyPage(); MainPage = new NavigationPage (Page); } } ``` 5) Now - here comes the “hack” - sneakily bypass requiring the `FormsApplicationDelegate` subclass (thank goodness it’s [open source](https://github.com/xamarin/Xamarin.Forms/blob/master/Xamarin.Forms.Platform.iOS/FormsApplicationDelegate.cs "open source")) and just set the iOS root view controller directly: ```csharp Xamarin.Forms.Forms.Init(); var a = new App(); KeyWindow.RootViewController = a.MainPage.CreateViewController(); ``` ⚠️ *YMMV with some Xamarin.Forms features when hacking forms to start-up like this*\ *BE WARNED!* ### Getting the Monkey Data 6) Now we have a Xamarin.Forms app, page, and listview - but no data! Because the monkey data lives in a Json file on the internet, we’re going to need some additional namespaces (and a Monkey model class): ```csharp using Newtonsoft.Json; using System.Net; public class Monkey { public string Name { get; set; } public string Location { get; set; } public string Details { get; set; } public string Image { get; set; } public int Population { get; set; } } ``` 7) Now let’s grab that monkey data from github - the Json file is downloaded and deserialized in just a few lines of code: ```csharp WebClient client = new WebClient(); var response = client.DownloadData ("https://raw.githubusercontent.com/jamesmontemagno/MonkeysApp-AppIndexing/master/MonkeysApp/monkeydata.json"); // GET var json = System.Text.Encoding.UTF8.GetString(response); var monkeys = JsonConvert.DeserializeObject>(json); ``` 8) Now bind that data to the listview - using the built-in `ImageCell` data template - and assigning properties from the monkey model to the Text, Detail, and ImageSource properties of the cell: ```csharp a.Page.MyList.ItemTemplate = new DataTemplate(typeof(ImageCell)); a.Page.MyList.ItemTemplate.SetBinding(TextCell.TextProperty, "Name"); a.Page.MyList.ItemTemplate.SetBinding(ImageCell.DetailProperty, "Location"); a.Page.MyList.ItemTemplate.SetBinding(ImageCell.ImageSourceProperty, "Image"); a.Page.MyList.ItemsSource = monkeys; ``` 9) And now the iOS app is populated with a list of monkeys! One last thing, update the app title ```csharp a.Page.Title = "Monkeys!"; ``` ### The End Result (for static-content view) ![finished app](Screenshots/ListView1.png) ================================================ FILE: xamarin-forms/user-interface/listview/ListView1-ios.workbook ================================================ --- uti: com.xamarin.workbook platform: iOS packages: - id: Newtonsoft.Json version: 8.0.3 - id: Xamarin.Forms version: 2.2.0.31 --- # Xamarin.Forms REST —> ListView > ⚠️ This workbook is deprecated - see **Listview.workbook** instead ## A little hack to demo Xamarin.Forms on iOS with Workbooks... ...borrowing some ideas from James Montemagno’s [sample](https://github.com/jamesmontemagno/MonkeysApp-AppIndexing "Monkey Sample App") ### Wire up a Xamarin.Forms app 1. Start by importing the Nugets for Xamarin.Forms and the iOS Platform Renderers (and Json.Net for some parsing later on): ```csharp #r "Xamarin.Forms.Platform.iOS" #r "Xamarin.Forms.Core" #r "Xamarin.Forms.Xaml" #r "Xamarin.Forms.Platform" #r "Newtonsoft.Json" ``` 1. We need `using` statements too: ```csharp using Xamarin.Forms; using Xamarin.Forms.Platform.iOS; ``` 1. Set up a simple page with an exposed property to edit (in this case, a `ListView` which will be populated later): ```csharp public class MyPage : ContentPage { public ListView MyList {get;set;} public MyPage () { Title = "A test"; MyList = new ListView (); // no data yet, though Content = MyList; } } ``` 1. Ok great - but we can’t see anything! Oh, we need to bootstrap the Xamarin.Forms app object too: ```csharp public class App : Application { public MyPage Page {get;set;} public App () { Page = new MyPage(); MainPage = new NavigationPage (Page); } } ``` 1. Now - here comes the “hack” - sneakily bypass requiring the `FormsApplicationDelegate` subclass (thank goodness it’s [open source](https://github.com/xamarin/Xamarin.Forms/blob/master/Xamarin.Forms.Platform.iOS/FormsApplicationDelegate.cs "open source")) and just set the iOS root view controller directly: ```csharp Xamarin.Forms.Forms.Init(); var a = new App(); KeyWindow.RootViewController = a.MainPage.CreateViewController(); ``` ⚠️ *YMMV with some Xamarin.Forms features when hacking forms to start-up like this*\ *BE WARNED!* ### Getting the Monkey Data 1. Now we have a Xamarin.Forms app, page, and listview - but no data! Because the monkey data lives in a Json file on the internet, we’re going to need some additional namespaces (and a Monkey model class): ```csharp using Newtonsoft.Json; using System.Net; public class Monkey { public string Name { get; set; } public string Location { get; set; } public string Details { get; set; } public string Image { get; set; } public int Population { get; set; } } ``` 1. Now let’s grab that monkey data from github - the Json file is downloaded and deserialized in just a few lines of code: ```csharp WebClient client = new WebClient(); var response = client.DownloadData ("https://raw.githubusercontent.com/jamesmontemagno/MonkeysApp-AppIndexing/master/MonkeysApp/monkeydata.json"); // GET var json = System.Text.Encoding.UTF8.GetString(response); var monkeys = JsonConvert.DeserializeObject>(json); ``` 1. Now bind that data to the listview - using the built-in `ImageCell` data template - and assigning properties from the monkey model to the Text, Detail, and ImageSource properties of the cell: ```csharp a.Page.MyList.ItemTemplate = new DataTemplate(typeof(ImageCell)); a.Page.MyList.ItemTemplate.SetBinding(TextCell.TextProperty, "Name"); a.Page.MyList.ItemTemplate.SetBinding(ImageCell.DetailProperty, "Location"); a.Page.MyList.ItemTemplate.SetBinding(ImageCell.ImageSourceProperty, "Image"); a.Page.MyList.ItemsSource = monkeys; ``` 1. And now the iOS app is populated with a list of monkeys! One last thing, update the app title ```csharp a.Page.Title = "Monkeys!"; ``` ### The End Result \(for static-content view) ![finished app](Screenshots/ListView1.png) ================================================ FILE: xamarin-forms/user-interface/map/map.workbook/FormsInit.csx ================================================ #r "Xamarin.Forms.Core" #r "Xamarin.Forms.Xaml" #r "Xamarin.Forms.Platform" #r "Xamarin.Forms.Maps" using System; using Xamarin.Forms; using Xamarin.Forms.Maps; var page = new ContentPage(); StackLayout stackLayout = new StackLayout { Margin = new Thickness(0, 20, 0, 0) }; page.Content = stackLayout; Application.Current.MainPage = page; ================================================ FILE: xamarin-forms/user-interface/map/map.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook id: 1E3C44B6-F2D5-4471-9F76-9AF54305E9E1 title: Displaying a Map with Xamarin.Forms platforms: - Android - iOS packages: - id: Xamarin.Forms version: 2.5.0.121934 - id: Xamarin.Forms.Maps version: 2.5.0.121934 --- # Displaying a Map The Xamarin.Forms `Map` view displays a map using the native map for the platform. This provides a fast, familiar maps experience for users. ## Initializing the Workbook To use maps in Xamarin Workbooks, you must: * Add the `Xamarin.Forms.Maps` NuGet package to the Workbook. * Use the `#r` command to reference the `Xamarin.Forms.Maps` and `Xamarin.Forms.Maps.iOS` assemblies. * Add a `using` directive to reference the `Xamarin.Forms.Maps` assembly. * Call the `Xamarin.FormsMaps.Init` method, after the `Xamarin.Forms.Forms.Init` method, to initialize `Xamarin.Forms.Maps`. These steps have been performed in this workbook. In order to run a Xamarin.Forms workbook, some initialization code must be executed: ```csharp // The Xamarin.Forms initialization code isn't important to understanding this workbook #load "FormsInit.csx" using Xamarin.Forms; using Xamarin.Forms.Maps; ``` For more information about the initialization code, see the Getting Started with Xamarin.Forms workbook. ## Adding a Map to a Page An instance of the `Map` class is created to display a map: ```csharp var map = new Map( MapSpan.FromCenterAndRadius( new Position(37.8044866, -122.4324132), Distance.FromMiles(0.3))) { IsShowingUser = false }; stackLayout.Children.Add(map); ``` A `MapSpan` represents a circular region on a `Map`. Supplying a `MapSpan` instance to the `Map` constructor sets the initial view (center point and zoom level) of the map when it's loaded. In addition, the `IsShowingUser` property controls whether the `Map` is showing the user's current location. The `Position` structure stores latitude and longitude as `double` values. The `Distance` structure contains a number of methods that can be used to set the zoom level of the map. In this case, the `Distance.FromMiles` method is used. ## Changing the Map Type The `MapType` property of the `Map` class can be set to a value of the `MapType` enumeration to change the display style of the `Map`: ```csharp map.MapType = MapType.Satellite; ``` The values of the `MapType` enumeration are: * `Hybrid` – a map that combines satellite imagery and street data. * `Satellite` – a map that contains satellite imagery. * `Street` – a map that contains street data. This is the default value. ## Adding Pins A location can be marked on the `Map` with a `Pin` instance, which is added to the `Pins` collection of the `Map` class: ```csharp var pin = new Pin { Type = PinType.Place, Position = new Position(37.8044866, -122.4324132), Label = "Pin Title Goes Here", Address = "Pin Address Goes Here" }; map.Pins.Add(pin); ``` The `Pin` instance specifies the data required to display the pin on the `Map`. The values of the `PinType` enumeration are: * `Generic` – a generic pin. * `Place` – a pin for a place. * `SavedPin` – a pin for a saved location. * `SearchResult` – a pin for a search result. ## Changing the Map Position and Zoom Level The `MoveToRegion` method of the `Map` class can be used to change the position and zoom level of the map: ```csharp var slider = new Slider(1, 18, 1); slider.ValueChanged += (sender, e) => { var zoomLevel = e.NewValue; // between 1 and 18 var latLongDegrees = 360 / (Math.Pow(2, zoomLevel)); map.MoveToRegion( new MapSpan(map.VisibleRegion.Center, latLongDegrees, latLongDegrees)); }; stackLayout.Children.Insert(0, slider); ``` Here, the zoom level of the map is changed as the slider moves, without altering the location. This is achieved creating a new `MapSpan` using the current location from the `VisibleRegion.Center` property of the `Map` class. ## 👍 Try it now! * Set the `Map` instance to a zoom level of 1 kilometer. * Change the `Map` instance to display hybrid map data. * Set the `Map` position to a location in another continent. ## Further Reading For more information about displaying a map, see [Map Control](https://developer.xamarin.com/guides/xamarin-forms/user-interface/map/). ================================================ FILE: xamarin-forms/user-interface/margins-padding/margins-and-padding/FormsInit.csx ================================================ #r "Xamarin.Forms.Core" #r "Xamarin.Forms.Xaml" #r "Xamarin.Forms.Platform" using System; using Xamarin.Forms; var page = new ContentPage(); StackLayout stackLayout = new StackLayout { Margin = new Thickness(0, 20, 0, 0) }; page.Content = stackLayout; Application.Current.MainPage = page; ================================================ FILE: xamarin-forms/user-interface/margins-padding/margins-and-padding/index.workbook ================================================ --- uti: com.xamarin.workbook platforms: - iOS packages: - id: Xamarin.Forms version: 2.3.2.127 --- # Controlling Layout Behavior with Margins and Padding The `Margin` and `Padding` properties control layout behavior when an element is rendered in the user interface. The `Margin` property represents the distance between an element and its adjacent elements, and is used to control the element's rendering position, and the rendering position of its neighbors. `Margin` values can be specified on [layout](https://developer.xamarin.com/guides/xamarin-forms/controls/layouts/) and [view](https://developer.xamarin.com/guides/xamarin-forms/controls/views/) classes. The `Padding` property represents the distance between an element and its child elements, and is used to separate the control from its own content. `Padding` values can be specified on [layout](https://developer.xamarin.com/guides/xamarin-forms/controls/layouts/) classes. The following diagram illustrates the two concepts: ![](margins-and-padding.png) ## Initializing the Workbook In order to run a Xamarin.Forms workbook, some initialization code must be executed: ```csharp // The Xamarin.Forms initialization code isn't important to understanding this workbook #load "FormsInit-iOS.csx" using Xamarin.Forms; ``` For more information about the initialization code, see the Getting Started with Xamarin.Forms workbook. ## Specifying a Thickness The `Margin` and `Padding` properties are both of type `Thickness`. A `Thickness` structure can be created using three constructor overloads: ```csharp stackLayout.Padding = new Thickness(0, 20, 0, 0); var label1 = new Label { Text = "Xamarin.Forms", Margin = new Thickness(20) }; var label2 = new Label { Text = "Xamarin.iOS", Margin = new Thickness(10, 25) }; var label3 = new Label { Text = "Xamarin.Android", Margin = new Thickness(0, 20, 15, 5) }; stackLayout.Children.Add(label1); stackLayout.Children.Add(label2); stackLayout.Children.Add(label3); ``` > ⚠️ `Thickness` values can be negative, which typically clips or overdraws the content. ## 👍 Try it now! * Change the `label` instances to all use the `Thickness` constructor that specifies a single value. ## Further Reading For more information about the `Margin` and `Padding` properties, see [Margin and Padding](https://developer.xamarin.com/guides/xamarin-forms/user-interface/layouts/margin-and-padding/). ================================================ FILE: xamarin-forms/user-interface/meta.json ================================================ { "order":{ "alerts/alerts.workbook":"Alert", "button/button.workbook":"Button", "editor/editor.workbook":"Editor", "entry/entry.workbook":"Entry", "image/image.workbook":"Image", "label/label.workbook":"Label", "layout-options/layout-options.workbook":"Layout Options", "listview/ListView.workbook":"ListView", "map/map.workbook":"Map", "margins-padding/margins-and-padding/index.workbook":"Margins & Padding", "picker/picker.workbook":"Picker", "slider/slider.workbook":"Slider", "stacklayout/stacklayout.workbook":"Stack Layout", "switch/switch.workbook":"Switch", "tabbedpage/tabbedpage.workbook":"Tabbed Page", "webview/webview.workbook":"Web View", "xaml/LoadXaml.workbook":"Loading XAML in Workbooks" } } ================================================ FILE: xamarin-forms/user-interface/picker/picker.workbook/FormsInit.csx ================================================ #r "Xamarin.Forms.Core" #r "Xamarin.Forms.Xaml" #r "Xamarin.Forms.Platform" using System; using Xamarin.Forms; var page = new ContentPage(); StackLayout stackLayout = new StackLayout { Margin = new Thickness(0, 20, 0, 0) }; page.Content = stackLayout; Application.Current.MainPage = page; ================================================ FILE: xamarin-forms/user-interface/picker/picker.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook id: 959F41D8-3A09-4D6C-A3F6-19C4C9108925 title: Xamarin.Forms Picker platforms: - Android - iOS packages: - id: Xamarin.Forms version: 2.5.0.121934 --- # Selecting Items with a Picker The Xamarin.Forms `Picker` view is used for selecting an item from a list. ## Initializing the Workbook In order to run a Xamarin.Forms workbook, some initialization code must be executed: ```csharp // The Xamarin.Forms initialization code isn't important to understanding this workbook #load "FormsInit.csx" using Xamarin.Forms; ``` For more information about the initialization code, see the Getting Started with Xamarin.Forms workbook. ## Creating a Picker A `Picker` is created as follows: ``` var picker = new Picker { Title = "Choose a Color" }; stackLayout.Children.Add(picker); ``` The `Title` property value should instruct the user what action to perform with the `Picker` view, and will be displayed prior to the user selecting an item from the list. ## Populating the Picker with Items The items displayed by a `Picker` are set by populating the `Items` collection with data: ```csharp var colors = new List { "Black", "Gray", "Silver", "White", "Red", "Maroon", "Yellow", "Olive", "Lime", "Green", "Aqua", "Teal", "Blue", "Navy", "Fuchsia", "Purple", "Pink" }; foreach (string color in colors) { picker.Items.Add(color); } ``` This populates the `Picker` with a list of color names. ## Responding to an Item being Selected In order to demonstrate responding to an item being selected from the `Picker`, a `BoxView` is added to the page: ```csharp var boxView = new BoxView { HeightRequest = 150, WidthRequest = 150, HorizontalOptions = LayoutOptions.Center, VerticalOptions = LayoutOptions.CenterAndExpand }; stackLayout.Children.Add(boxView); ``` The `SelectedIndexChanged` event fires when the user selects an item from the `Picker`. This event should be handled to perform the desired response: ```csharp var colorTypeConverter = new ColorTypeConverter(); picker.SelectedIndexChanged += (sender, args) => { boxView.Color = (Color)colorTypeConverter .ConvertFromInvariantString(picker.Items[picker.SelectedIndex]); } ``` When the user selects the name of a color from the `Picker`, the `BoxView` is set to that color. The name of the selected color is retrieved from the `Items` collection by using the `SelectedIndex` property value. The value of this property ranges from 0 to 1 less than the number of items in the `Items` collection. The retrieved color name is then converted to a `Color` instance using the `ColorTypeConverter` class, which is built into Xamarin.Forms. ## 👍 Try it now! * Create a `Dictionary` that contains a list of color names and corresponding color values. * Populate the `Items` collection of the `Picker` with the `Dictionary` key values. * Update the `SelectedIndexChanged` event handler so that the correct `Color` value is retrieved from the `Dictionary` for the selected item. ## Further Reading For more information about the `Picker` view, see [Picker Class](https://developer.xamarin.com/api/type/Xamarin.Forms.Picker/). ================================================ FILE: xamarin-forms/user-interface/slider/slider.workbook/FormsInit.csx ================================================ #r "Xamarin.Forms.Core" #r "Xamarin.Forms.Xaml" #r "Xamarin.Forms.Platform" using System; using Xamarin.Forms; var page = new ContentPage(); StackLayout stackLayout = new StackLayout { Margin = new Thickness(0, 20, 0, 0) }; page.Content = stackLayout; Application.Current.MainPage = page; ================================================ FILE: xamarin-forms/user-interface/slider/slider.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook id: AE1F68C3-17C6-440F-9F4B-C11413115334 title: Xamarin.Forms Sliders platforms: - Android - iOS packages: - id: Xamarin.Forms version: 2.5.0.121934 --- # Changing A Color Value with Sliders The Xamarin.Forms `Slider` view is used to input a range of values. ## Initializing the Workbook In order to run a Xamarin.Forms workbook, some initialization code must be executed: ```csharp // The Xamarin.Forms initialization code isn't important to understanding this workbook #load "FormsInit.csx" using Xamarin.Forms; ``` For more information about the initialization code, see the Getting Started with Xamarin.Forms workbook. ## Initializing Sliders A `Slider` is initialized with its minimum and maximum values, and its initial value. To use a slider, initialize it with a range of values, starting with the `Minimum`, and an intial `Value`: ```csharp var colorLabel = new Label { Text = "Use the sliders to change the text color" }; var redSlider = new Slider { Minimum = 0, Maximum = 255, Value = 0 }; var greenSlider = new Slider { Minimum = 0, Maximum = 255, Value = 0 }; var blueSlider = new Slider { Minimum = 0, Maximum = 255, Value = 0 }; stackLayout.Children.Add(colorLabel); stackLayout.Children.Add(redSlider); stackLayout.Children.Add(greenSlider); stackLayout.Children.Add(blueSlider); ``` ## Getting the Slider Value The 'Slider' view raises a `ValueChanged` event when the `Value` property is changed by the user. To respond to changes in the slider value, implement and add a handler for this event: ```csharp void updateColor(object sender, EventArgs e) { var r = redSlider.Value/255.0; var g = greenSlider.Value/255.0; var b = blueSlider.Value/255.0; colorLabel.TextColor = Color.FromRgb(r, g, b); } redSlider.ValueChanged += updateColor; greenSlider.ValueChanged += updateColor; blueSlider.ValueChanged += updateColor; ``` ## 👍 Try it now! * Change the `colorLabel` text value to display the R, G, and B values. ================================================ FILE: xamarin-forms/user-interface/stacklayout/stacklayout.workbook/FormsInit.csx ================================================ #r "Xamarin.Forms.Core" #r "Xamarin.Forms.Xaml" #r "Xamarin.Forms.Platform" using System; using Xamarin.Forms; var page = new ContentPage(); StackLayout stackLayout = new StackLayout { Margin = new Thickness(0, 20, 0, 0) }; page.Content = stackLayout; Application.Current.MainPage = page; ================================================ FILE: xamarin-forms/user-interface/stacklayout/stacklayout.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook id: C0BF140E-EF37-43B8-B0E2-35645D0800F3 title: Xamarin.Forms StackLayout platforms: - Android - iOS packages: - id: Xamarin.Forms version: 2.5.0.121934 --- # Using a StackLayout The Xamarin.Forms `StackLayout` is used to arrange views linearly, either horizontally or vertically. View position and size within the layout is based on a view's `HeightRequest`, `WidthRequest`, `HorizontalOptions`, and `VerticalOptions` property values. ## Initializing the Workbook In order to run a Xamarin.Forms workbook, some initialization code must be executed: ```csharp // The Xamarin.Forms initialization code isn't important to understanding this workbook #load "FormsInit.csx" using Xamarin.Forms; ``` For more information about the initialization code, see the Getting Started with Xamarin.Forms workbook. ## Creating a Vertical StackLayout A vertical layout is the default layout when creating a `StackLayout`: ```csharp var verticalStackLayout = new StackLayout { Margin = new Thickness(20), Children = { new Label { Text = "StackLayout Demo", FontAttributes = FontAttributes.Bold, HorizontalOptions = LayoutOptions.Center }, new Entry { Placeholder = "Enter text here" }, new Button { Text = "This Button does nothing" } } }; page.Content = verticalStackLayout; ``` This `StackLayout` lays out its child views in a vertical stack. The child views are contained in the `Children` collection of the `StackLayout`. ## Creating a Horizontal StackLayout A horizontal layout can be achieved by setting the `Orientation` property of a `StackLayout`: ```csharp var horizontalStackLayout = new StackLayout { Orientation = StackOrientation.Horizontal, Margin = new Thickness(20), Children = { new Label { Text = "Enter name:", Margin = new Thickness(0, 5, 0, 0) }, new Entry { Placeholder = "Enter name here", VerticalOptions = LayoutOptions.Start } } }; page.Content = horizontalStackLayout; ``` This `StackLayout` lays out its child views in a horizontal stack. ## Nesting StackLayout Instances More complex layouts can be achieved by nesting `StackLayout` instances: ```csharp page.Content = null; var stackLayout = new StackLayout { Margin = new Thickness(0, 20, 0, 0), Children = { new Label { Text = "StackLayout Demo", FontAttributes = FontAttributes.Bold, HorizontalOptions = LayoutOptions.Center }, horizontalStackLayout } }; page.Content = stackLayout; ``` This code nests a horizontal `StackLayout` inside a vertical `StackLayout`. ## Adding Views to an Existing StackLayout Views can be added to a `StackLayout` after it has been instantiated: ```csharp var button = new Button { Text = "This Button does nothing" }; stackLayout.Children.Add(button); ``` This code adds a `Button` instance to the bottom of a vertical `StackLayout`. ## Controlling Spacing By default, a `StackLayout` will add a 6px margin between views. This can be changed by setting the `Spacing` property: ```csharp stackLayout.Spacing = 20; horizontalStackLayout.Spacing = 20; ``` This code results in an increased spacing between views in each `StackLayout`. ## Controlling Positioning and Sizing Views in a `StackLayout` can be positioned by specifying `HorizontalOptions` and `VerticalOptions` property values. The following `LayoutOptions` values define how views will position themselves relative to the layout: * `Start` – places the view at the start of the layout. * `Center` – centers the view within the layout. * `End` – places the view at the end of the layout (bottom or right-most boundary). * `Fill` – places the view so that it has no padding. The size of a view in a `StackLayout` depends on the `HeightRequest`, `WidthRequest`, `HorizontalOptions`, and `VerticalOptions` property values. The following `LayoutOptions` values will result in views taking up as much space as is available from the layout: * `StartAndExpand` – places the view at the start of the layout, and takes up as much space as the layout will give it. * `CenterAndExpand` – centers the view within the layout and expands it to take up as much space as the layout will give it. * `EndAndExpand` – places the view at the end of the layout (bottom or right-most boundary) and expands it to take up as much space as the layout will give it. * `FillAndExpand` – places the view so that it has no padding and takes up as much space as the layout will give it. For examples of setting these `LayoutOption` values, see the Setting LayoutOptions workbook. ## 👍 Try it now! * Create a horizontal `StackLayout` instance that asks the user to enter their forename. * Create a horizontal `StackLayout` instance that asks the user to enter their surname. * Create a vertical `StackLayout` instance, and add the two horizontal `StackLayout` instances to it. ## Further Reading For more information about `StackLayout`, see [StackLayout](https://developer.xamarin.com/guides/xamarin-forms/user-interface/layouts/stack-layout/). ================================================ FILE: xamarin-forms/user-interface/switch/switch.workbook/FormsInit.csx ================================================ #r "Xamarin.Forms.Core" #r "Xamarin.Forms.Xaml" #r "Xamarin.Forms.Platform" using System; using Xamarin.Forms; var page = new ContentPage(); StackLayout stackLayout = new StackLayout { Margin = new Thickness(0, 20, 0, 0) }; page.Content = stackLayout; Application.Current.MainPage = page; ================================================ FILE: xamarin-forms/user-interface/switch/switch.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook id: BDEF46FA-E954-4F73-8C18-8D5505ADB6B0 title: Xamarin.Forms Switches platforms: - Android - iOS packages: - id: Xamarin.Forms version: 2.5.0.121934 --- # Binary Choices with Switches The Xamarin.Forms `Switch` view allows a user to toggle between two states. ## Initializing the Workbook In order to run a Xamarin.Forms workbook, some initialization code must be executed: ```csharp // The Xamarin.Forms initialization code isn't important to understanding this workbook #load "FormsInit.csx" using Xamarin.Forms; ``` For more information about the initialization code, see the Getting Started with Xamarin.Forms workbook. ## Initializing Switches A `Switch` is initialized with default values. To use a `Switch`, call the parameterless constructor and then set the `IsToggled` state property: ```csharp var stateLabel = new Label { Text = "Off" }; var simpleSwitch = new Switch(); simpleSwitch.IsToggled = false; stackLayout.Children.Add(stateLabel); stackLayout.Children.Add(simpleSwitch); ``` ## Handling `Toggled` Events After you have set the initial `IsToggled` state, create and assign a handler for the `Toggled` event: ```csharp simpleSwitch.Toggled += (o, e) => { if (simpleSwitch.IsToggled == false) { stateLabel.Text = "Off"; } else { stateLabel.Text = "On"; }; }; ``` Now the text of `stateLabel` should change when `simpleSwitch` is toggled. ================================================ FILE: xamarin-forms/user-interface/tabbedpage/tabbedpage.workbook/FormsInit.csx ================================================ #r "Xamarin.Forms.Core" #r "Xamarin.Forms.Xaml" #r "Xamarin.Forms.Platform" using System; using Xamarin.Forms; var page = new TabbedPage(); page.Title = "TabbedWorkbook"; Application.Current.MainPage = page; ================================================ FILE: xamarin-forms/user-interface/tabbedpage/tabbedpage.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook id: E73FB600-A386-495A-9D28-5F8163E62265 title: Presenting Multiple Pages with Xamarin.Forms TabbedPage platforms: - Android - iOS packages: - id: Xamarin.Forms version: 2.5.0.121934 --- # Presenting Multiple Pages with `TabbedPage` The Xamarin.Forms `TabbedPage` view descends from `MultiPage` and presents a number of pages in a tabbed layout. ## Initializing the Workbook In order to run a Xamarin.Forms workbook, some initialization code must be executed: ```csharp // The Xamarin.Forms initialization code isn't important to understanding this workbook #load "FormsInit.csx" using Xamarin.Forms; ``` For more information about the initialization code, see the Getting Started with Xamarin.Forms workbook. ## Adding Pages to A `TabbedPage` A `TabbedPage` can be assigned to the `Application.MainPage` property to make it the view displays. Though `TabbedPage`s can be initialized when that they are created, the one for this workbook has been created, assigned to the application's main page, and stored in a convenience variable, called `page`. The code below creates an `AlphabetBeginning` class that extends from `ContentPage`, and then creates and adds two of them to the `TabbedPage`. ```csharp public class AlphabetBeginning : ContentPage { public AlphabetBeginning(String title, String[] letters) { Title = title; Content = new StackLayout { Margin = new Thickness(0, 20, 0, 0) }; foreach (String letter in letters) { ((StackLayout)Content).Children.Add(new Label { Text = letter}); } } } page.Children.Add(new AlphabetBeginning("English", new string[] {"A", "Bee"})); page.Children.Add(new AlphabetBeginning("Greek", new string[] {"Alpha", "Beta"})); ``` ## Working with the Selected Page The `TabbedPage` type inherits the `SelectedItem` property, so you can get or set the selected page: ```csharp int nextIndex = page.Children.IndexOf(page.SelectedItem as ContentPage); nextIndex = (nextIndex +1) % page.Children.Count; page.SelectedItem = page.Children[nextIndex]; ``` ## 👍 Try it now! * Create and add a Hebrew AlphabetBeginning, which begins with Alef and Bet, in the code box below. ```csharp // TODO: Create a Hebrew alphabet beginning // TODO: Add it to the TabbedPage ``` * Cycle through the pages to verify that the modulo arithmetic from above still works. ================================================ FILE: xamarin-forms/user-interface/webview/webview.workbook/FormsInit.csx ================================================ #r "Xamarin.Forms.Core" #r "Xamarin.Forms.Xaml" #r "Xamarin.Forms.Platform" using System; using Xamarin.Forms; var page = new ContentPage(); StackLayout stackLayout = new StackLayout { Margin = new Thickness(0, 20, 0, 0) }; page.Content = stackLayout; Application.Current.MainPage = page; ================================================ FILE: xamarin-forms/user-interface/webview/webview.workbook/index.workbook ================================================ --- uti: com.xamarin.workbook id: 3B5760CA-367F-4A93-AF53-FB33006A3DE1 title: Displaying Web Content with Xamarin.Forms platforms: - Android - iOS packages: - id: Xamarin.Forms version: 2.5.0.121934 --- # Displaying Web Content The Xamarin.Forms `WebView` view displays web and HTML content in an application. ## Initializing the Workbook In order to run a Xamarin.Forms workbook, some initialization code must be executed: ```csharp // The Xamarin.Forms initialization code isn't important to understanding this workbook #load "FormsInit.csx" using Xamarin.Forms; ``` For more information about the initialization code, see the Getting Started with Xamarin.Forms workbook. ## Displaying a Website To display a website from the internet, create a `WebView` instance and set its `Source` property to a URL: ```csharp var webView = new WebView { Source = "https://www.xamarin.com" }; page.Content = webView; ``` > ⚠️ In iOS 9 and greater, App Transport Security (ATS) enforces secure connections between internet resources (such as the app's back-end server) and the app, thereby preventing accidental disclosure of sensitive information. Since ATS is enabled by default in apps built for iOS 9 and greater, all connections will be subject to ATS security requirements. If connections do not meet these requirements, they will fail with an exception. > ATS can be opted out of if it is not possible to use the `HTTPS` protocol and secure communication for internet resources. This can be achieved by updating the app's **Info.plist** file. For more information see [App Transport Security](https://developer.xamarin.com/guides/ios/platform_features/introduction_to_ios9/ats/). ## Displaying HTML Strings A `WebView` can display a HTML string by creating an instance of the `HtmlWebViewSource` type: ```csharp var htmlSource = new HtmlWebViewSource { Html = @"

Xamarin.Forms

Welcome to WebView.

" }; webView.Source = htmlSource; ``` ## Handling Navigation Programmatically A `WebView` supports programmatic access to forward and backward navigation: ```csharp page.Content = null; var buttonStackLayout = new StackLayout { Orientation = StackOrientation.Horizontal, Margin = new Thickness(10, 10) }; var backButton = new Button { Text = "Back", HorizontalOptions = LayoutOptions.StartAndExpand }; backButton.Clicked += (sender, e) => { if (webView.CanGoBack) webView.GoBack(); }; var forwardButton = new Button { Text = "Forward", HorizontalOptions = LayoutOptions.End }; forwardButton.Clicked += (sender, e) => { if (webView.CanGoForward) webView.GoForward(); }; buttonStackLayout.Children.Add(backButton); buttonStackLayout.Children.Add(forwardButton); stackLayout.Children.Add(buttonStackLayout); stackLayout.Children.Add(webView); page.Content = stackLayout; webView.WidthRequest = 200; webView.HeightRequest = 500; webView.Source = "https://www.xamarin.com"; ``` If the `WebView.CanGoBack` property is `true`, the `WebView.GoBack` method will navigate to the last visited page when the `backButton` is clicked. If the `WebView.CanGoForward` property is `true`, the `WebView.GoForward` method will navigate forward to the next visited page when the `forwardButton` is clicked. > ℹ️ When placing a `WebView` inside a `StackLayout`, the `WebView` requires that `HeightRequest` and `WidthRequest` property values are specified, otherwise the `WebView` will not render. ## Responding to Navigation A `WebView` raises two events to help you respond to navigation: * `Navigating` – raised when the `WebView` begins loading a new page. * `Navigated` – raised when the page is loaded and navigation has stopped. These events can be utilized to provide a status indicator for web page loading: ```csharp var label = new Label { Text = "Loading...", HorizontalOptions = LayoutOptions.CenterAndExpand, VerticalOptions = LayoutOptions.Center, IsVisible = false }; buttonStackLayout.Children.Insert(1, label); webView.Navigating += (sender, e) => { label.IsVisible = true; }; webView.Navigated += (sender, e) => { label.IsVisible = false; }; ``` Any page navigation will cause the **Loading...** message to appear, and disappear once navigation has completed. ## 👍 Try it now! * Make a `WebView` navigate to the Xamarin University website (`https://university.xamarin.com/`). * Make a `WebView` display a `Hello World` message in HTML. * Add a `WebView` to a `StackLayout` and ensure it renders correctly. ## Further Reading For more information about the `WebView` view, see [WebView](https://developer.xamarin.com/guides/xamarin-forms/user-interface/webview/). ================================================ FILE: xamarin-forms/user-interface/xaml/LoadXaml.workbook ================================================ --- uti: com.xamarin.workbook platforms: - iOS packages: - id: Newtonsoft.Json version: 8.0.3 - id: Xamarin.Forms.Dynamic version: 0.1.18-pre - id: Xamarin.Forms version: 2.3.3.166-pre4 --- # Xamarin.Forms XAML Workbook Demonstration (iOS) There’s currently no way to import or reference XAML files from a Workbook, so it might seem impossible to use XAML in a demo... however with NuGet helper it is possible to use XAML in a Workbook. > 🚫 This isn't recommended for implementation in production applications, but may be useful to teach or demonstrate XAML concepts using Workbooks ## Steps to use XAML *1.* Start by importing the NuGets for Xamarin.Forms and the iOS Platform Renderers ```csharp #r "Xamarin.Forms.Platform.iOS" #r "Xamarin.Forms.Core" #r "Xamarin.Forms.Xaml" #r "Xamarin.Forms.Platform" ``` And for this hack to work, add the [Dynamic Xamarin Forms (preview)](http://www.cazzulino.com/dynamic-forms.html) NuGet (which contains the magic to load XAML from a string): ```csharp #r "Xamarin.Forms.Dynamic" ``` *2.* Add the `using` statements next: ```csharp using Xamarin.Forms; using Xamarin.Forms.Platform.iOS; ``` *3.* Write up a simple XAML `ContentPage`to render on iOS: ```csharp static string xaml = @" "; ``` *4.* Bootstrap the Xamarin.Forms app object and and for the main page class, then use the **Dynamic Xamarin Forms** `LoadFromXaml` extension method to parse the `xaml` string: ```csharp public class App : Application { public ContentPage XamlPage {get;set;} public App () { XamlPage = new ContentPage(); XamlPage.LoadFromXaml (xaml); // loads XAML MainPage = XamlPage; } } ``` *5.* Finally, set the iOS root view controller directly (in a real Xamarin.Forms app, this would be taken care of by the `FormsApplicationDelegate` subclass): ```csharp Xamarin.Forms.Forms.Init(); var a = new App(); KeyWindow.RootViewController = a.MainPage.CreateViewController(); ``` ## One More Thing... Loading XAML in this way does not allow strongly-typed access to the elements by their `x:Name`, instead they can only be referenced using `FindByName`as shown here to update the label: ```csharp var l = a.XamlPage.FindByName("helloLabel"); l.Text = "Updated by the Workbook!"; a.XamlPage.Content ```