{"Document":{"ObjectName":"Scenario::ScenarioDocumentModel","id":1,"BaseScenario":{"ObjectName":"Scenario::BaseScenario","id":0,"Constraint":{"ObjectName":"Scenario::IntervalModel","id":0,"Metadata":{"ScriptingName":"instancing-full","Comment":"","Color":"Transparent1","Label":"","Touched":true},"Inlet":{"uuid":"a1574bb0-cbd4-4c7d-9417-0c25cfd1187b","ObjectName":"Inlet","id":0,"Hidden":false,"Custom":"Audio In","Exposed":"audio in"},"Outlet":{"uuid":"a1d97535-18ac-444a-8417-0cbc1692d897","ObjectName":"Outlet","id":0,"Hidden":false,"Custom":"Audio Out","Exposed":"audio out","Address":"audio:/out/main","GainInlet":{"uuid":"9a13fb32-269a-47bf-99a9-930188c1f19c","ObjectName":"Inlet","id":10000,"Hidden":false,"Custom":"Gain","Exposed":"gain","Value":{},"Init":{},"Domain":{"Float":{"Min":0.0,"Max":1.0}}},"PanInlet":{"uuid":"9a13fb32-269a-47bf-99a9-930188c1f19c","ObjectName":"Inlet","id":10001,"Hidden":false,"Custom":"Pan","Exposed":"pan","Value":{},"Init":{},"Domain":{}},"Gain":1.0,"Pan":[1.0,1.0],"Propagate":true},"Processes":[{"uuid":"a5bbffe0-93d2-4e70-995c-cf46c2c43520","ObjectName":"CSF","id":2,"Metadata":{"ScriptingName":"Compute Shader.2","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[291.0,663.0],"Size":[226.0,175.0],"Loops":false,"FoldMode":0,"Compute":"/*{\n  \"DESCRIPTION\": \"Simple orbital particle emitter — every slot is always alive and traces a deterministic orbit on a sphere whose radius breathes with TIME. No dead/alive bookkeeping, no auxiliary buffers. Drop-in source for Instancer.points: position drives per-instance translation, color drives per-instance color0.\",\n  \"CREDIT\": \"ossia score\",\n  \"ISFVSN\": \"2.0\",\n  \"MODE\": \"COMPUTE_SHADER\",\n  \"CATEGORIES\": [\"PARTICLES\"],\n  \"RESOURCES\": [\n    { \"NAME\": \"radius\",      \"TYPE\": \"float\", \"DEFAULT\": 1.0,  \"MIN\": 0.01, \"MAX\": 10.0 },\n    { \"NAME\": \"breathDepth\", \"TYPE\": \"float\", \"DEFAULT\": 0.3,  \"MIN\": 0.0,  \"MAX\": 1.0 },\n    { \"NAME\": \"breathSpeed\", \"TYPE\": \"float\", \"DEFAULT\": 1.0,  \"MIN\": 0.0,  \"MAX\": 10.0 },\n    { \"NAME\": \"orbitSpeed\",  \"TYPE\": \"float\", \"DEFAULT\": 0.5,  \"MIN\": 0.0,  \"MAX\": 5.0 },\n    { \"NAME\": \"spread\",      \"TYPE\": \"float\", \"DEFAULT\": 1.0,  \"MIN\": 0.0,  \"MAX\": 1.0 },\n    {\n      \"NAME\": \"geo\",\n      \"TYPE\": \"geometry\",\n      \"VERTEX_COUNT\": \"$USER\",\n      \"ATTRIBUTES\": [\n        { \"NAME\": \"position\", \"SEMANTIC\": \"position\", \"TYPE\": \"vec4\", \"ACCESS\": \"write_only\" },\n        { \"NAME\": \"color\",    \"SEMANTIC\": \"color0\",   \"TYPE\": \"vec4\", \"ACCESS\": \"write_only\" }\n      ]\n    }\n  ],\n  \"PASSES\": [\n    { \"LOCAL_SIZE\": [64, 1, 1], \"EXECUTION_MODEL\": { \"TYPE\": \"PER_VERTEX\" } }\n  ]\n}*/\n\n// PCG-flavoured 32-bit hash → [0,1). Deterministic per-particle so\n// the orbit parameters stay stable across frames; only TIME advances.\nfloat hash11(uint n)\n{\n  n = (n << 13u) ^ n;\n  n = n * (n * n * 15731u + 789221u) + 1376312589u;\n  return float(n & 0x7fffffffu) / float(0x7fffffff);\n}\n\nconst float TWO_PI = 6.28318530718;\nconst float PI     = 3.14159265359;\n\nvoid main()\n{\n  uint idx = gl_GlobalInvocationID.x;\n  uint count = uint(ISF_WRITE(geo, position).length());\n  if(idx >= count)\n    return;\n\n  // Five independent hashes per particle index. Each samples a\n  // different orbit parameter so neighbouring slots don't trace\n  // visually correlated paths.\n  float h0 = hash11(idx * 17u + 0u);   // azimuth phase at TIME=0\n  float h1 = hash11(idx * 17u + 1u);   // polar angle (clustered by `spread`)\n  float h2 = hash11(idx * 17u + 2u);   // angular velocity sign + magnitude\n  float h3 = hash11(idx * 17u + 3u);   // breath phase offset\n  float h4 = hash11(idx * 17u + 4u);   // hue offset\n\n  // Angular velocity: signed, scaled by orbitSpeed. Half the particles\n  // orbit clockwise and half counter-clockwise, which prevents the\n  // cloud from drifting in any one direction.\n  float omega = (h2 - 0.5) * 2.0 * orbitSpeed;\n\n  // Polar angle: `spread` controls how clustered around the equator\n  // the orbits are. spread=0 puts every particle on a single equatorial\n  // ring; spread=1 distributes them uniformly over the sphere.\n  float phi = acos(mix(0.0, 2.0 * h1 - 1.0, spread));\n\n  // Azimuth: deterministic phase plus TIME-driven sweep.\n  float theta = h0 * TWO_PI + omega * TIME;\n\n  // Radial breath. Each particle has its own phase offset h3 so the\n  // sphere doesn't pulse rigidly as a whole — particles flow in and\n  // out at different times, producing a swirling layered effect.\n  float radial = radius * (1.0 + breathDepth * sin(breathSpeed * TIME + h3 * TWO_PI));\n\n  vec3 pos = radial * vec3(\n      sin(phi) * cos(theta),\n      sin(phi) * sin(theta),\n      cos(phi));\n\n  ISF_WRITE(geo, position)[idx] = vec4(pos, 1.0);\n\n  // Color: HSV-ish hue from polar angle + per-particle offset.\n  // Cosine-palette gives a smooth continuous spectrum without abrupt\n  // colour cuts.\n  float hue = fract(phi / PI + h4);\n  vec3 col = 0.5 + 0.5 * cos(TWO_PI * (hue + vec3(0.0, 0.33, 0.67)));\n  ISF_WRITE(geo, color)[idx] = vec4(col, 1.0);\n}\n","Root":"<LIBRARY>:packages/score-csf-testers/csf-last/OrbitParticles.cs","Inlets":[{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":0,"Hidden":true,"Custom":"radius","Exposed":"radius","Value":{"Float":10.0},"Init":{"Float":1.0},"Domain":{"Float":{"Min":0.009999999776482582,"Max":10.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":1,"Hidden":true,"Custom":"breathDepth","Exposed":"breathdepth","Value":{"Float":0.0},"Init":{"Float":0.30000001192092896},"Domain":{"Float":{"Min":0.0,"Max":1.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":2,"Hidden":true,"Custom":"breathSpeed","Exposed":"breathspeed","Value":{"Float":1.0},"Init":{"Float":1.0},"Domain":{"Float":{"Min":0.0,"Max":10.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":3,"Hidden":true,"Custom":"orbitSpeed","Exposed":"orbitspeed","Value":{"Float":0.5},"Init":{"Float":0.5},"Domain":{"Float":{"Min":0.0,"Max":5.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":4,"Hidden":true,"Custom":"spread","Exposed":"spread","Value":{"Float":1.0},"Init":{"Float":1.0},"Domain":{"Float":{"Min":0.0,"Max":1.0}}},{"uuid":"238399a0-7e81-47e3-896f-08e8856e2973","ObjectName":"Inlet","id":5,"Hidden":true,"Custom":"geo vertex count","Exposed":"geo vertex count","Value":{"Int":400},"Init":{"Int":1024},"Domain":{"Int":{"Min":1,"Max":536870911}}}],"Outlets":[{"uuid":"848061c5-e8a0-4a13-9985-e8df30ce6d4f","ObjectName":"Outlet","id":0,"Hidden":false,"Custom":"geo_out","Exposed":"geo_out"}]},{"uuid":"2f6a8c41-7d93-4e5b-b1c8-4e3f9a7d2c5b","ObjectName":"asset_loader","id":3,"Metadata":{"ScriptingName":"Asset Loader.3","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[286.0,451.0],"Size":[232.0,173.0],"Loops":false,"FoldMode":0,"Inlets":[{"uuid":"40833147-4c42-4b8b-bb80-0b1d15dae129","ObjectName":"Inlet","id":0,"Hidden":true,"Custom":"Asset file","Exposed":"asset file","Value":{"String":"<PROJECT>:Models/DamagedHelmet.glb"},"Init":{"String":""},"Domain":{},"Filters":"3D assets (*.fbx *.gltf *.glb *.obj *.ply *.stl *.off *.splat *.spz *.usd *.usda *.usdc *.usdz)"},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":1,"Hidden":true,"Custom":"Position","Exposed":"position","Value":{"Vec3f":[0.0,0.0,0.0]},"Init":{"Vec3f":[0.0,0.0,0.0]},"Domain":{"Vec3f":{"Min":[-8388608.0,-8388608.0,-8388608.0],"Max":[8388608.0,8388608.0,8388608.0],"Values":[[],[],[]]}}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":2,"Hidden":true,"Custom":"Rotation","Exposed":"rotation","Value":{"Vec3f":[0.0,0.0,0.0]},"Init":{"Vec3f":[0.0,0.0,0.0]},"Domain":{"Vec3f":{"Min":[0.0,0.0,0.0],"Max":[360.0,360.0,360.0],"Values":[[],[],[]]}}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":3,"Hidden":true,"Custom":"Scale","Exposed":"scale","Value":{"Vec3f":[1.0,1.0,1.0]},"Init":{"Vec3f":[1.0,1.0,1.0]},"Domain":{"Vec3f":{"Min":[0.000009999999747378752,0.000009999999747378752,0.000009999999747378752],"Max":[1000.0,1000.0,1000.0],"Values":[[],[],[]]}}},{"uuid":"9ae797ea-d94c-4792-acec-9ec1932bae5d","ObjectName":"Inlet","id":4,"Hidden":true,"Custom":"Format override (auto if empty)","Exposed":"format override (auto if empty)","Value":{"String":""},"Init":{"String":""},"Domain":{}}],"Outlets":[{"uuid":"848061c5-e8a0-4a13-9985-e8df30ce6d4f","ObjectName":"Outlet","id":0,"Hidden":false,"Custom":"Scene","Exposed":"scene"}]},{"uuid":"5e8a2c7f-9b4d-4e3a-a1c6-2d7f0b3e8c4a","ObjectName":"instancer","id":4,"Metadata":{"ScriptingName":"Instancer.4","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[575.0,575.0],"Size":[418.0,175.0],"Loops":false,"FoldMode":0,"Inlets":[{"uuid":"f2ab26ea-415d-45a2-bfbc-2968c7c92a33","ObjectName":"Inlet","id":0,"Hidden":false,"Custom":"Scene In","Exposed":"scene in"},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":1,"Hidden":false,"Custom":"Transforms","Exposed":"transforms","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":2,"Hidden":false,"Custom":"Colors","Exposed":"colors","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":3,"Hidden":false,"Custom":"Custom","Exposed":"custom","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"f2ab26ea-415d-45a2-bfbc-2968c7c92a33","ObjectName":"Inlet","id":4,"Hidden":false,"Custom":"Points","Exposed":"points"},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":5,"Hidden":true,"Custom":"Format","Exposed":"format","Value":{"Int":0},"Init":{"Int":0},"Domain":{"Int":{"Values":[0,1,2]}},"Values":[["mat4",{"Int":0}],["trs",{"Int":1}],["translation",{"Int":2}]],"FolderPort":"","FileExtensions":""},{"uuid":"238399a0-7e81-47e3-896f-08e8856e2973","ObjectName":"Inlet","id":6,"Hidden":true,"Custom":"Count","Exposed":"count","Value":{"Int":1},"Init":{"Int":1},"Domain":{"Int":{"Min":1,"Max":1000000}}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":7,"Hidden":true,"Custom":"Position","Exposed":"position","Value":{"Vec3f":[0.0,0.0,0.0]},"Init":{"Vec3f":[0.0,0.0,0.0]},"Domain":{"Vec3f":{"Min":[-8388608.0,-8388608.0,-8388608.0],"Max":[8388608.0,8388608.0,8388608.0],"Values":[[],[],[]]}}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":8,"Hidden":true,"Custom":"Rotation","Exposed":"rotation","Value":{"Vec3f":[0.0,0.0,0.0]},"Init":{"Vec3f":[0.0,0.0,0.0]},"Domain":{"Vec3f":{"Min":[0.0,0.0,0.0],"Max":[360.0,360.0,360.0],"Values":[[],[],[]]}}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":9,"Hidden":true,"Custom":"Scale","Exposed":"scale","Value":{"Vec3f":[0.11999999731779099,0.11999999731779099,0.11999999731779099]},"Init":{"Vec3f":[1.0,1.0,1.0]},"Domain":{"Vec3f":{"Min":[0.000009999999747378752,0.000009999999747378752,0.000009999999747378752],"Max":[1000.0,1000.0,1000.0],"Values":[[],[],[]]}}},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":10,"Hidden":true,"Custom":"Per-instance transform","Exposed":"per-instance transform","Value":{"Int":0},"Init":{"Int":0},"Domain":{"Int":{"Values":[0,1]}},"Values":[["Full matrix",{"Int":0}],["Translation only",{"Int":1}]],"FolderPort":"","FileExtensions":""}],"Outlets":[{"uuid":"848061c5-e8a0-4a13-9985-e8df30ce6d4f","ObjectName":"Outlet","id":0,"Hidden":false,"Custom":"Scene Out","Exposed":"scene out"}]},{"uuid":"a8f2c6d0-1b4e-4c7a-9d3f-5e8b2c1a7f0d","ObjectName":"gfxProcess","id":5,"Metadata":{"ScriptingName":"Scene Preprocessor.5","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[1035.0,581.0],"Size":[179.0,22.0],"Loops":false,"FoldMode":0,"Inlets":[{"uuid":"f2ab26ea-415d-45a2-bfbc-2968c7c92a33","ObjectName":"Inlet","id":0,"Hidden":false,"Custom":"Scene In","Exposed":"scene in"}],"Outlets":[{"uuid":"848061c5-e8a0-4a13-9985-e8df30ce6d4f","ObjectName":"Outlet","id":0,"Hidden":false,"Custom":"Geometry Out","Exposed":"geometry out"}]},{"uuid":"4c91b5e2-8d76-4ab3-9f14-6e0d8b3a2c57","ObjectName":"camera_avnd","id":6,"Metadata":{"ScriptingName":"Camera.6","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[706.0,357.00000000000006],"Size":[274.0,177.0],"Loops":false,"FoldMode":0,"Inlets":[{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":0,"Hidden":true,"Custom":"Eye","Exposed":"eye","Value":{"Vec3f":[0.0,1.2000000476837158,3.4000000953674316]},"Init":{"Vec3f":[0.0,0.0,0.0]},"Domain":{"Vec3f":{"Min":[-10000.0,-10000.0,-10000.0],"Max":[10000.0,10000.0,10000.0],"Values":[[],[],[]]}}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":1,"Hidden":true,"Custom":"Target","Exposed":"target","Value":{"Vec3f":[0.0,0.0,0.0]},"Init":{"Vec3f":[0.0,0.0,0.0]},"Domain":{"Vec3f":{"Min":[-10000.0,-10000.0,-10000.0],"Max":[10000.0,10000.0,10000.0],"Values":[[],[],[]]}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":2,"Hidden":true,"Custom":"FOV","Exposed":"fov","Value":{"Float":45.0},"Init":{"Float":60.0},"Domain":{"Float":{"Min":5.0,"Max":170.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":3,"Hidden":true,"Custom":"Near","Exposed":"near","Value":{"Float":0.10000000149011612},"Init":{"Float":0.10000000149011612},"Domain":{"Float":{"Min":0.0010000000474974513,"Max":10.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":4,"Hidden":true,"Custom":"Far","Exposed":"far","Value":{"Float":1000.0},"Init":{"Float":1000.0},"Domain":{"Float":{"Min":1.0,"Max":100000.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":5,"Hidden":true,"Custom":"Roll","Exposed":"roll","Value":{"Float":0.0},"Init":{"Float":0.0},"Domain":{"Float":{"Min":-180.0,"Max":180.0}}}],"Outlets":[{"uuid":"848061c5-e8a0-4a13-9985-e8df30ce6d4f","ObjectName":"Outlet","id":0,"Hidden":false,"Custom":"Scene","Exposed":"scene"}]},{"uuid":"9f3c1a5e-4b7d-4e2a-8c5f-1d6e0b9a3c7f","ObjectName":"light","id":7,"Metadata":{"ScriptingName":"Light.7","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[564.0,800.0],"Size":[422.0,252.0],"Loops":false,"FoldMode":0,"Inlets":[{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":0,"Hidden":true,"Custom":"Mode","Exposed":"mode","Value":{"Int":0},"Init":{"Int":0},"Domain":{"Int":{"Values":[0,1,2,3,4,5,6]}},"Values":[["Directional",{"Int":0}],["Point",{"Int":1}],["Spot",{"Int":2}],["Rect",{"Int":3}],["Disk",{"Int":4}],["Sphere",{"Int":5}],["Dome",{"Int":6}]],"FolderPort":"","FileExtensions":""},{"uuid":"8f38638e-9f9f-48b0-ae36-1cba86ef5703","ObjectName":"Inlet","id":1,"Hidden":true,"Custom":"Color","Exposed":"color","Value":{"Vec4f":[1.0,1.0,1.0,1.0]},"Init":{"Vec4f":[1.0,1.0,1.0,1.0]},"Domain":{}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":2,"Hidden":true,"Custom":"Intensity","Exposed":"intensity","Value":{"Float":4.0},"Init":{"Float":1.0},"Domain":{"Float":{"Min":0.0,"Max":100.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":3,"Hidden":true,"Custom":"Range","Exposed":"range","Value":{"Float":0.0},"Init":{"Float":0.0},"Domain":{"Float":{"Min":0.0,"Max":1000.0}}},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":4,"Hidden":true,"Custom":"Falloff","Exposed":"falloff","Value":{"Int":2},"Init":{"Int":2},"Domain":{"Int":{"Values":[0,1,2,3]}},"Values":[["None",{"Int":0}],["Linear",{"Int":1}],["Quadratic (physical)",{"Int":2}],["Cubic",{"Int":3}]],"FolderPort":"","FileExtensions":""},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":5,"Hidden":true,"Custom":"Inner cone °","Exposed":"inner cone _","Value":{"Float":0.0},"Init":{"Float":0.0},"Domain":{"Float":{"Min":0.0,"Max":90.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":6,"Hidden":true,"Custom":"Outer cone °","Exposed":"outer cone _","Value":{"Float":45.0},"Init":{"Float":45.0},"Domain":{"Float":{"Min":0.0,"Max":90.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":7,"Hidden":true,"Custom":"Width","Exposed":"width","Value":{"Float":1.0},"Init":{"Float":1.0},"Domain":{"Float":{"Min":0.009999999776482582,"Max":100.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":8,"Hidden":true,"Custom":"Height","Exposed":"height","Value":{"Float":1.0},"Init":{"Float":1.0},"Domain":{"Float":{"Min":0.009999999776482582,"Max":100.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":9,"Hidden":true,"Custom":"Radius","Exposed":"radius","Value":{"Float":0.5},"Init":{"Float":0.5},"Domain":{"Float":{"Min":0.009999999776482582,"Max":100.0}}},{"uuid":"fb27e4cb-ea7f-41e2-ad92-2354498c1b6b","ObjectName":"Inlet","id":10,"Hidden":true,"Custom":"Cast shadow","Exposed":"cast shadow","Value":{"Bool":false},"Init":{"Bool":false},"Domain":{"Bool":null}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":11,"Hidden":true,"Custom":"Shadow bias","Exposed":"shadow bias","Value":{"Float":0.0010000000474974513},"Init":{"Float":0.0010000000474974513},"Domain":{"Float":{"Min":0.0,"Max":0.10000000149011612}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":12,"Hidden":true,"Custom":"Shadow normal bias","Exposed":"shadow normal bias","Value":{"Float":0.009999999776482582},"Init":{"Float":0.009999999776482582},"Domain":{"Float":{"Min":0.0,"Max":0.10000000149011612}}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":13,"Hidden":true,"Custom":"Position","Exposed":"position","Value":{"Vec3f":[0.0,0.0,0.0]},"Init":{"Vec3f":[0.0,0.0,0.0]},"Domain":{"Vec3f":{"Min":[-8388608.0,-8388608.0,-8388608.0],"Max":[8388608.0,8388608.0,8388608.0],"Values":[[],[],[]]}}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":14,"Hidden":true,"Custom":"Rotation","Exposed":"rotation","Value":{"Vec3f":[-50.0,35.0,0.0]},"Init":{"Vec3f":[0.0,0.0,0.0]},"Domain":{"Vec3f":{"Min":[0.0,0.0,0.0],"Max":[360.0,360.0,360.0],"Values":[[],[],[]]}}}],"Outlets":[{"uuid":"848061c5-e8a0-4a13-9985-e8df30ce6d4f","ObjectName":"Outlet","id":0,"Hidden":false,"Custom":"Scene","Exposed":"scene"}]},{"uuid":"d3f5a8c1-8b47-4e91-9c2d-6f1a9b5e3c82","ObjectName":"environment_loader","id":8,"Metadata":{"ScriptingName":"Environment.8","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[627.0,1096.0],"Size":[352.0,176.0],"Loops":false,"FoldMode":0,"Inlets":[{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":0,"Hidden":true,"Custom":"Ambient Color","Exposed":"ambient color","Value":{"Vec3f":[1.0,1.0,1.0]},"Init":{"Vec3f":[0.029999999329447746,0.029999999329447746,0.029999999329447746]},"Domain":{"Vec3f":{"Min":[0.0,0.0,0.0],"Max":[1.0,1.0,1.0],"Values":[[],[],[]]}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":1,"Hidden":true,"Custom":"Ambient Intensity","Exposed":"ambient intensity","Value":{"Float":0.800000011920929},"Init":{"Float":1.0},"Domain":{"Float":{"Min":0.0,"Max":8.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":2,"Hidden":true,"Custom":"Exposure EV100","Exposed":"exposure ev100","Value":{"Float":0.0},"Init":{"Float":0.0},"Domain":{"Float":{"Min":-6.0,"Max":18.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":3,"Hidden":true,"Custom":"Exposure (stops)","Exposed":"exposure (stops)","Value":{"Float":0.0},"Init":{"Float":0.0},"Domain":{"Float":{"Min":-8.0,"Max":8.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":4,"Hidden":true,"Custom":"Gamma","Exposed":"gamma","Value":{"Float":2.200000047683716},"Init":{"Float":2.200000047683716},"Domain":{"Float":{"Min":1.0,"Max":3.0}}},{"uuid":"fb27e4cb-ea7f-41e2-ad92-2354498c1b6b","ObjectName":"Inlet","id":5,"Hidden":true,"Custom":"Fog","Exposed":"fog","Value":{"Bool":false},"Init":{"Bool":false},"Domain":{"Bool":null}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":6,"Hidden":true,"Custom":"Fog Color","Exposed":"fog color","Value":{"Vec3f":[0.800000011920929,0.800000011920929,0.800000011920929]},"Init":{"Vec3f":[0.800000011920929,0.800000011920929,0.800000011920929]},"Domain":{"Vec3f":{"Min":[0.0,0.0,0.0],"Max":[1.0,1.0,1.0],"Values":[[],[],[]]}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":7,"Hidden":true,"Custom":"Fog Start","Exposed":"fog start","Value":{"Float":10.0},"Init":{"Float":10.0},"Domain":{"Float":{"Min":0.0,"Max":1000.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":8,"Hidden":true,"Custom":"Fog End","Exposed":"fog end","Value":{"Float":100.0},"Init":{"Float":100.0},"Domain":{"Float":{"Min":0.0,"Max":10000.0}}},{"uuid":"0adbbdda-fda4-451e-91cc-1da731bde9d5","ObjectName":"Inlet","id":9,"Hidden":true,"Custom":"Render target size","Exposed":"render target size","Value":{"Vec2f":[0.0,0.0]},"Init":{"Vec2f":[0.0,0.0]},"Domain":{"Vec2f":{"Min":[0.0,0.0],"Max":[16384.0,16384.0],"Values":[[],[]]}},"Integral":true}],"Outlets":[{"uuid":"848061c5-e8a0-4a13-9985-e8df30ce6d4f","ObjectName":"Outlet","id":0,"Hidden":false,"Custom":"Scene","Exposed":"scene"}]},{"uuid":"dbfc2101-40d7-4807-8804-571e88992e7e","ObjectName":"gfxProcess","id":9,"Metadata":{"ScriptingName":"Render Pipeline.9","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[1241.0,581.0],"Size":[787.0,160.0],"Loops":false,"FoldMode":0,"Vertex":"// Full-PBR variant — extends classic_pbr_textured with TANGENT for TBN\n// normal-map reconstruction in the fragment stage.\n//\n// Vertex inputs + varyings come from the sibling .frag's VERTEX_INPUTS /\n// VERTEX_OUTPUTS blocks; redeclaring them here triggers \"redefinition\".\n\nvoid main()\n{\n    isf_vertShaderInit();\n\n    // Unified-MDI cmd-index lookup: per-instance VERTEX_INPUT carries\n    // the drawID directly. Replaces the prior `gl_BaseInstanceARB`\n    // path, which broke as soon as instanceCount > 1 (firstInstance\n    // becomes the per-instance slot offset, no longer the cmd index)\n    // AND was always 0 on the CPU-fallback drawIndexed loop. Reading\n    // a per-instance attribute works uniformly on both indirect and\n    // CPU-fallback paths (firstInstance is honoured by every QRhi\n    // backend that supports instancing).\n    uint drawId = draw_id;\n    v_drawID = drawId;\n\n    PerDraw pd = per_draws.data[drawId];\n    mat3 instLinear = pd.normal[3].x > 0.5\n        ? mat3(inst_matrix0.xyz, inst_matrix1.xyz, inst_matrix2.xyz)\n        : mat3(1.0);\n    mat4 model = pd.model;\n    mat3 normalMatrix = mat3(pd.normal) * transpose(inverse(instLinear));\n\n    // Per-instance translation offset: zero for non-instanced draws via\n    // the REQUIRED:false fallback (identity broadcast); the actual\n    // particle position for unified-MDI instance groups.\n    vec4 wp = model * vec4(instLinear * position + inst_translation, 1.0);\n    v_worldPos = wp.xyz;\n    v_normal = normalize(normalMatrix * normal);\n    // Tangent carries xyz = unit tangent in mesh space + w = handedness.\n    // Apply the normal matrix to the xyz (same basis as the normal) and\n    // forward w untouched. Consumer reconstructs bitangent as\n    //   bitangent = cross(N, T.xyz) * T.w\n    v_tangent = vec4(normalize(normalMatrix * tangent.xyz), tangent.w);\n    v_uv = texcoord_0;\n    // glTF TEXCOORD_1 (secondary UV set — lightmaps, per-channel UV\n    // override). Falls back to zero for meshes without it (slab\n    // uploader fills with zeros).\n    v_uv1 = texcoord_1;\n    // glTF COLOR_0 (defaults to vec4(1) when the mesh doesn't carry\n    // one — the slab uploader fills the buffer with white).\n    v_color = color_0;\n    // VERTEX_INPUTS aren't directly visible to the fragment stage —\n    // forward the per-instance broadcast colour as a varying so the\n    // .frag can multiply baseColor by it.\n    v_inst_color = pd.normal[3].y > 0.5 ? inst_color0 : vec4(1.0);\n    v_inst_emissive = pd.normal[3].z > 0.5 ? inst_custom0 : vec4(0.0);\n\n    gl_Position = clipSpaceCorrMatrix * camera.viewProjection * wp;\n\n    isf_vertShaderFinish();\n}\n","Fragment":"/*{\n  \"CREDIT\": \"ossia team\",\n  \"ISFVSN\": \"2\",\n  \"MODE\": \"RAW_RASTER_PIPELINE\",\n  \"ALPHA\": \"straight\",\n  \"DESCRIPTION\": \"Full glTF metallic-roughness rasterizer for a Scene Preprocessor output: draws the whole scene in one indirect draw with every material texture (base colour, metal-rough, normal map with tangents, emissive, occlusion; texcoord sets, KHR_texture_transform, wrap modes, alpha MASK and BLEND, double-sided), the scene's lights (directional, point and spot, with range and falloff; procedural lights written by the presets/lighting CSFs included), the Environment node's ambient, exposure and linear fog, and per-instance transforms, colours and emissive from an Instancer. No image-based lighting and no shadows: a fixed Fresnel term stands in for reflections (classic_pbr_openpbr adds IBL and cascaded shadows). Output is linear HDR, so follow it with a tone mapper such as shaderlib/post-process/ToneMapping.fs. Alpha-to-coverage smooths MASK edges under MSAA; the volumetric toggle composites the presets/volumetric fog chain.\",\n  \"CATEGORIES\": [\n    \"3D\",\n    \"Scene\",\n    \"MDI\",\n    \"Textured\",\n    \"Normal-Mapped\"\n  ],\n  \"VERTEX_INPUTS\": [\n    {\n      \"TYPE\": \"vec3\",\n      \"NAME\": \"position\"\n    },\n    {\n      \"TYPE\": \"vec3\",\n      \"NAME\": \"normal\"\n    },\n    {\n      \"TYPE\": \"vec2\",\n      \"NAME\": \"texcoord_0\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"tangent\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"color_0\"\n    },\n    {\n      \"TYPE\": \"vec2\",\n      \"NAME\": \"texcoord_1\"\n    },\n    {\n      \"TYPE\": \"vec3\",\n      \"NAME\": \"inst_translation\",\n      \"SEMANTIC\": \"translation\",\n      \"REQUIRED\": false\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"inst_color0\",\n      \"SEMANTIC\": \"instance_color0\",\n      \"REQUIRED\": false\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"inst_custom0\",\n      \"SEMANTIC\": \"instance_custom0\",\n      \"REQUIRED\": false\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"inst_matrix0\",\n      \"REQUIRED\": false\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"inst_matrix1\",\n      \"REQUIRED\": false\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"inst_matrix2\",\n      \"REQUIRED\": false\n    },\n    {\n      \"TYPE\": \"uint\",\n      \"NAME\": \"draw_id\",\n      \"SEMANTIC\": \"instance_draw_id\"\n    }\n  ],\n  \"VERTEX_OUTPUTS\": [\n    {\n      \"TYPE\": \"vec3\",\n      \"NAME\": \"v_worldPos\"\n    },\n    {\n      \"TYPE\": \"vec3\",\n      \"NAME\": \"v_normal\"\n    },\n    {\n      \"TYPE\": \"vec2\",\n      \"NAME\": \"v_uv\"\n    },\n    {\n      \"TYPE\": \"uint\",\n      \"NAME\": \"v_drawID\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"v_tangent\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"v_color\"\n    },\n    {\n      \"TYPE\": \"vec2\",\n      \"NAME\": \"v_uv1\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"v_inst_color\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"v_inst_emissive\"\n    }\n  ],\n  \"FRAGMENT_INPUTS\": [\n    {\n      \"TYPE\": \"vec3\",\n      \"NAME\": \"v_worldPos\"\n    },\n    {\n      \"TYPE\": \"vec3\",\n      \"NAME\": \"v_normal\"\n    },\n    {\n      \"TYPE\": \"vec2\",\n      \"NAME\": \"v_uv\"\n    },\n    {\n      \"TYPE\": \"uint\",\n      \"NAME\": \"v_drawID\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"v_tangent\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"v_color\"\n    },\n    {\n      \"TYPE\": \"vec2\",\n      \"NAME\": \"v_uv1\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"v_inst_color\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"v_inst_emissive\"\n    }\n  ],\n  \"FRAGMENT_OUTPUTS\": [\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"isf_FragColor\"\n    }\n  ],\n  \"INPUTS\": [\n    {\n      \"NAME\": \"camera\",\n      \"TYPE\": \"uniform\",\n      \"VISIBILITY\": \"vertex+fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"view\",\n          \"TYPE\": \"mat4\"\n        },\n        {\n          \"NAME\": \"projection\",\n          \"TYPE\": \"mat4\"\n        },\n        {\n          \"NAME\": \"viewProjection\",\n          \"TYPE\": \"mat4\"\n        },\n        {\n          \"NAME\": \"cameraPosition\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"renderSize\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"params\",\n          \"TYPE\": \"vec4\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"scene_lights\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"entries\",\n          \"TYPE\": \"Light[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"scene_light_indices\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"data\",\n          \"TYPE\": \"uint[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"world_transforms\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"vertex+fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"data\",\n          \"TYPE\": \"mat4[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"scene_materials\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"entries\",\n          \"TYPE\": \"Material[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"scene_material_uv_xforms\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"entries\",\n          \"TYPE\": \"MatUVXform[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"per_draws\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"vertex+fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"data\",\n          \"TYPE\": \"PerDraw[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"indirect_draw_cmds\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"none\",\n      \"BUFFER_USAGE\": \"indirect_draw_indexed\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"cmds\",\n          \"TYPE\": \"DrawIndexedCmd[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"scene_counts\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"light_count\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"material_count\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"draw_count\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"_pad0\",\n          \"TYPE\": \"uint\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"env\",\n      \"TYPE\": \"uniform\",\n      \"VISIBILITY\": \"fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"ambient\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"fog_color_density\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"fog_range\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"exposure_gamma\",\n          \"TYPE\": \"vec4\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"alpha_a2c_enabled\",\n      \"TYPE\": \"long\",\n      \"DEFAULT\": 0,\n      \"MIN\": 0,\n      \"MAX\": 1,\n      \"LABEL\": \"Alpha-to-coverage (writes gl_SampleMask under MSAA). Best for foliage edges when MSAA is enabled. Adapts to the framebuffer sample count (1/2/4/8/16); degrades to a 0.5 binary cutoff when MSAA is off.\"\n    },\n    {\n      \"NAME\": \"volumetric_enabled\",\n      \"TYPE\": \"long\",\n      \"DEFAULT\": 0,\n      \"MIN\": 0,\n      \"MAX\": 1,\n      \"LABEL\": \"Volumetric fog composite (1=on)\",\n      \"DESCRIPTION\": \"Sample the upstream vol_integrated SSBO (built by the volumetric_inject / scatter / integrate chain) and apply finalColor = finalColor * transmittance + accum * intensity per fragment. Default off so rasterizers without the volumetric chain wired don't multiply by an unbound (zero-init) transmittance and go pure black.\"\n    },\n    {\n      \"NAME\": \"volumetric_intensity\",\n      \"TYPE\": \"float\",\n      \"DEFAULT\": 1.0,\n      \"MIN\": 0.0,\n      \"MAX\": 4.0,\n      \"LABEL\": \"Volumetric intensity\",\n      \"DESCRIPTION\": \"Scalar on the in-scattered radiance contribution. 1.0 = physical; <1 dampens the fog look; >1 over-blooms the air for stylized output. Has no effect when volumetric_enabled=0.\"\n    }\n  ],\n  \"AUXILIARY\": [\n    {\n      \"NAME\": \"scene_material_wrap\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"entries\",\n          \"TYPE\": \"uvec4[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"cluster_config\",\n      \"ACCESS\": \"read_only\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"cluster_x\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"cluster_y\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"cluster_z\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"max_lights_per_cluster\",\n          \"TYPE\": \"uint\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"vol_integrated\",\n      \"ACCESS\": \"read_only\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"data\",\n          \"TYPE\": \"FroxelIntegrated[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"materialArray0\",\n      \"TYPE\": \"image\",\n      \"IS_ARRAY\": true,\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialArray1\",\n      \"TYPE\": \"image\",\n      \"IS_ARRAY\": true,\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialArray2\",\n      \"TYPE\": \"image\",\n      \"IS_ARRAY\": true,\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialArray3\",\n      \"TYPE\": \"image\",\n      \"IS_ARRAY\": true,\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialArray4\",\n      \"TYPE\": \"image\",\n      \"IS_ARRAY\": true,\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialArray5\",\n      \"TYPE\": \"image\",\n      \"IS_ARRAY\": true,\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialArray6\",\n      \"TYPE\": \"image\",\n      \"IS_ARRAY\": true,\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialArray7\",\n      \"TYPE\": \"image\",\n      \"IS_ARRAY\": true,\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialDyn0\",\n      \"TYPE\": \"image\",\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialDyn1\",\n      \"TYPE\": \"image\",\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialDyn2\",\n      \"TYPE\": \"image\",\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialDyn3\",\n      \"TYPE\": \"image\",\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialDyn4\",\n      \"TYPE\": \"image\",\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialDyn5\",\n      \"TYPE\": \"image\",\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialDyn6\",\n      \"TYPE\": \"image\",\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialDyn7\",\n      \"TYPE\": \"image\",\n      \"WRAP\": \"repeat\"\n    }\n  ],\n  \"TYPES\": [\n    {\n      \"NAME\": \"Light\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"color\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"local_direction\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"range_cone\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"shadow_enabled\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"decay_mode\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"transform_slot\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"normal_bias\",\n          \"TYPE\": \"float\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"Material\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"baseColor\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"metallicRoughnessOcclusionUnlit\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"emissive_strength\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"textureRefs\",\n          \"TYPE\": \"uvec4\"\n        },\n        {\n          \"NAME\": \"feature_mask\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"hit_group_id\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"occlusion_textureRef\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"alpha_cutoff\",\n          \"TYPE\": \"float\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"PerDraw\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"model\",\n          \"TYPE\": \"mat4\"\n        },\n        {\n          \"NAME\": \"normal\",\n          \"TYPE\": \"mat4\"\n        },\n        {\n          \"NAME\": \"material_index\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"tag_hash\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"_pad0\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"_pad1\",\n          \"TYPE\": \"uint\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"DrawIndexedCmd\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"indexCount\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"instanceCount\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"firstIndex\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"baseVertex\",\n          \"TYPE\": \"int\"\n        },\n        {\n          \"NAME\": \"baseInstance\",\n          \"TYPE\": \"uint\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"MatUVXform\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"bc_offset_scale\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"mr_offset_scale\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"normal_offset_scale\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"em_offset_scale\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"occ_offset_scale\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"rotations0\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"rotations1\",\n          \"TYPE\": \"vec4\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"FroxelIntegrated\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"accum_transmittance\",\n          \"TYPE\": \"vec4\"\n        }\n      ]\n    }\n  ],\n  \"PIPELINE_STATE\": {\n    \"DEPTH_TEST\": true,\n    \"DEPTH_WRITE\": true,\n    \"CULL_MODE\": \"back\"\n  }\n}*/\n\n// Sample a material texture channel given its packed textureRef. Matches\n// the SceneFlattener encoding:\n//   bits 31..30 : source (0=NONE/sentinel, 1=STATIC bucket, 2=DYNAMIC slot)\n//   bits 29..23 : bucket index (0..127); the ladder below covers the\n//                 first 16 — higher bucket ids fall back.\n//   bits 23..0  : layer index within the bucket's texture array (static)\n//                 OR slot index in the channel's dynamic sampler set.\n//\n// Each channel declares `kShaderBuckets` sampler2DArrays,\n// one per bucket. Materials with textures of different (format, pixelSize)\n// tuples land in different buckets; the switch ladder below dispatches\n// to the right sampler. Scenes with a single bucket hit case 0 only —\n// all other cases compile in but never execute.\n//\n// Dynamic slots resolve to per-channel sampler2D uniforms `*Dyn0` /\n// `*Dyn1` populated by ScenePreprocessor's aux-texture path — used for\n// large runtime textures (8K video, HDR shader outputs) that can't\n// round-trip through the bucket pool.\nconst uint kShaderBuckets = 16u;\n\n// ─── Manual N-tap anisotropic sampling ──────────────────────────────\n// Qt RHI hard-codes maxAnisotropy=1.0 in every backend; there is no\n// public API to enable hardware anisotropic filtering. Workaround: do\n// it in the shader. Standard \"sum of cones\" formulation:\n//\n//   1. Compute UV gradients dx/dy. Pick the longer one as the major\n//      axis, the shorter as minor.\n//   2. The footprint is an ellipse on the texture; ratio = |major|/|minor|\n//      gives the anisotropy needed (typical value at grazing angles is\n//      4-16).\n//   3. Take 4 hardware-filtered samples spaced along the major axis,\n//      each forced to the minor-axis LOD via textureGrad(minor, minor).\n//      Average them. The minor-axis grad keeps each sample sharp; the\n//      4 spaced taps integrate over the elongated footprint.\n//\n// Shortcut: when the footprint is roughly isotropic (ratio² < 4) we\n// drop to a plain hardware texture() — the 4-tap path is wasted cost.\n//\n// Cost: ~4× texture lookups when the path triggers (only at grazing\n// angles), 1× otherwise. We apply this only to base_color and normal\n// — the channels where the user can see the difference. metallic /\n// roughness / occlusion / emissive stay on plain texture().\nvec4 anisoSample2DArray(sampler2DArray tex, vec3 uv)\n{\n    vec2 dx = dFdx(uv.xy);\n    vec2 dy = dFdy(uv.xy);\n    float lx2 = dot(dx, dx);\n    float ly2 = dot(dy, dy);\n    vec2 major, minor;\n    float ratio2;\n    if(lx2 > ly2)\n    {\n        major = dx; minor = dy;\n        ratio2 = lx2 / max(ly2, 1e-12);\n    }\n    else\n    {\n        major = dy; minor = dx;\n        ratio2 = ly2 / max(lx2, 1e-12);\n    }\n    if(ratio2 < 4.0) return texture(tex, uv);\n\n    // 4 taps at -3/8, -1/8, 1/8, 3/8 of the major axis (uniform spacing,\n    // mean-zero, covers the elongated footprint without touching the\n    // tile borders that a -1/2..1/2 spacing would).\n    float layer = uv.z;\n    vec4 s0 = textureGrad(tex, vec3(uv.xy + major * -0.375, layer), minor, minor);\n    vec4 s1 = textureGrad(tex, vec3(uv.xy + major * -0.125, layer), minor, minor);\n    vec4 s2 = textureGrad(tex, vec3(uv.xy + major *  0.125, layer), minor, minor);\n    vec4 s3 = textureGrad(tex, vec3(uv.xy + major *  0.375, layer), minor, minor);\n    return (s0 + s1 + s2 + s3) * 0.25;\n}\nvec4 anisoSample2DArraySep(texture2DArray tex, sampler smp, vec3 uv)\n{\n    vec2 dx = dFdx(uv.xy);\n    vec2 dy = dFdy(uv.xy);\n    float lx2 = dot(dx, dx);\n    float ly2 = dot(dy, dy);\n    vec2 major, minor;\n    float ratio2;\n    if(lx2 > ly2)\n    {\n        major = dx; minor = dy;\n        ratio2 = lx2 / max(ly2, 1e-12);\n    }\n    else\n    {\n        major = dy; minor = dx;\n        ratio2 = ly2 / max(lx2, 1e-12);\n    }\n    if(ratio2 < 4.0) return texture(sampler2DArray(tex, smp), uv);\n\n    // 4 taps at -3/8, -1/8, 1/8, 3/8 of the major axis (uniform spacing,\n    // mean-zero, covers the elongated footprint without touching the\n    // tile borders that a -1/2..1/2 spacing would).\n    float layer = uv.z;\n    vec4 s0 = textureGrad(sampler2DArray(tex, smp), vec3(uv.xy + major * -0.375, layer), minor, minor);\n    vec4 s1 = textureGrad(sampler2DArray(tex, smp), vec3(uv.xy + major * -0.125, layer), minor, minor);\n    vec4 s2 = textureGrad(sampler2DArray(tex, smp), vec3(uv.xy + major *  0.125, layer), minor, minor);\n    vec4 s3 = textureGrad(sampler2DArray(tex, smp), vec3(uv.xy + major *  0.375, layer), minor, minor);\n    return (s0 + s1 + s2 + s3) * 0.25;\n}\n\nvec4 anisoSample2D(sampler2D tex, vec2 uv)\n{\n    vec2 dx = dFdx(uv);\n    vec2 dy = dFdy(uv);\n    float lx2 = dot(dx, dx);\n    float ly2 = dot(dy, dy);\n    vec2 major, minor;\n    float ratio2;\n    if(lx2 > ly2)\n    {\n        major = dx; minor = dy;\n        ratio2 = lx2 / max(ly2, 1e-12);\n    }\n    else\n    {\n        major = dy; minor = dx;\n        ratio2 = ly2 / max(lx2, 1e-12);\n    }\n    if(ratio2 < 4.0) return texture(tex, uv);\n\n    vec4 s0 = textureGrad(tex, uv + major * -0.375, minor, minor);\n    vec4 s1 = textureGrad(tex, uv + major * -0.125, minor, minor);\n    vec4 s2 = textureGrad(tex, uv + major *  0.125, minor, minor);\n    vec4 s3 = textureGrad(tex, uv + major *  0.375, minor, minor);\n    return (s0 + s1 + s2 + s3) * 0.25;\n}\nvec4 anisoSample2DSep(texture2D tex, sampler smp, vec2 uv)\n{\n    vec2 dx = dFdx(uv);\n    vec2 dy = dFdy(uv);\n    float lx2 = dot(dx, dx);\n    float ly2 = dot(dy, dy);\n    vec2 major, minor;\n    float ratio2;\n    if(lx2 > ly2)\n    {\n        major = dx; minor = dy;\n        ratio2 = lx2 / max(ly2, 1e-12);\n    }\n    else\n    {\n        major = dy; minor = dx;\n        ratio2 = ly2 / max(lx2, 1e-12);\n    }\n    if(ratio2 < 4.0) return texture(sampler2D(tex, smp), uv);\n\n    vec4 s0 = textureGrad(sampler2D(tex, smp), uv + major * -0.375, minor, minor);\n    vec4 s1 = textureGrad(sampler2D(tex, smp), uv + major * -0.125, minor, minor);\n    vec4 s2 = textureGrad(sampler2D(tex, smp), uv + major *  0.125, minor, minor);\n    vec4 s3 = textureGrad(sampler2D(tex, smp), uv + major *  0.375, minor, minor);\n    return (s0 + s1 + s2 + s3) * 0.25;\n}\n\n// One decoder for every material channel. The pool is shared, so the bucket\n// field of the ref is all that picks the array -- including its colourspace,\n// which is part of the bucket key rather than of the channel.\n// Per-texture wrap modes from scene_material_wrap, loaded once per fragment\n// from the material's entry. Four bits per texture ref: wrap_s in the low two,\n// wrap_t in the high two; 0 = repeat, 1 = clamp to edge, 2 = mirror. Slots\n// 0..4 are the main refs (base colour, metal-rough, normal, emissive,\n// occlusion), 5.. the extension refs in MaterialExt.textureRefs order. The\n// pool samples every array with one repeat sampler, so a non-repeat mode is\n// applied to the coordinate here.\nuvec3 g_matWrap = uvec3(0u);\nuint matWrap(uint slot)\n{\n    if(slot < 5u) return (g_matWrap.x >> (4u * slot)) & 0xFu;\n    uint e = slot - 5u;\n    uint word = e < 8u ? g_matWrap.y : g_matWrap.z;\n    return (word >> (4u * (e & 7u))) & 0xFu;\n}\nfloat wrapAxis(float x, uint mode, float halfTexel)\n{\n    if(mode == 1u) return clamp(x, halfTexel, 1.0 - halfTexel);\n    if(mode == 2u) { float t = mod(x, 2.0); return t > 1.0 ? 2.0 - t : t; }\n    return x;\n}\nvec2 applyWrap(vec2 uv, uint wrap, vec2 halfTexel)\n{\n    return vec2(wrapAxis(uv.x, wrap & 3u, halfTexel.x),\n                wrapAxis(uv.y, (wrap >> 2u) & 3u, halfTexel.y));\n}\n// Clamping stays inside the edge texel of the coarsest mip level the\n// trilinear filter reads, so a minified clamped texture does not bleed across\n// the repeat sampler's seam.\nvec2 wrapInset(texture2DArray tex, sampler smp, vec2 dx, vec2 dy)\n{\n    vec2 sz = vec2(textureSize(sampler2DArray(tex, smp), 0).xy);\n    float lod = max(0.0, log2(max(length(dx * sz), length(dy * sz))));\n    return min(vec2(0.5), 0.5 * exp2(ceil(lod)) / sz);\n}\n// anisoSample2DArray's wrapped counterpart. A single trilinear tap whose\n// gradients come from the unwrapped coordinate, so a mirror fold or a clamp\n// edge does not spike the mip selection; repeat, the common case, keeps the\n// anisotropic path untouched.\nvec4 anisoSample2DArrayWrapped(texture2DArray tex, sampler smp, vec3 uv, uint wrap)\n{\n    if(wrap == 0u) return anisoSample2DArraySep(tex, smp, uv);\n    vec2 dx = dFdx(uv.xy);\n    vec2 dy = dFdy(uv.xy);\n    return textureGrad(sampler2DArray(tex, smp),\n                       vec3(applyWrap(uv.xy, wrap, wrapInset(tex, smp, dx, dy)), uv.z),\n                       dx, dy);\n}\n\n\nvec4 sample_material_slot(uint ref, uint wrap, vec2 uv, vec4 fallback)\n{\n    if(ref == 0xFFFFFFFFu) return fallback;\n    uint source = (ref >> 30) & 3u;\n    uint bucket = (ref >> 23) & 0x7Fu;\n    uint idx    = ref & 0x007FFFFFu;\n    if(source == 2u)\n    {\n        switch(idx)\n        {\n            case 0u: return anisoSample2DSep(materialDyn_tex[0], materialDyn_smp, uv);\n            case 1u: return anisoSample2DSep(materialDyn_tex[1], materialDyn_smp, uv);\n            case 2u: return anisoSample2DSep(materialDyn_tex[2], materialDyn_smp, uv);\n            case 3u: return anisoSample2DSep(materialDyn_tex[3], materialDyn_smp, uv);\n            case 4u: return anisoSample2DSep(materialDyn_tex[4], materialDyn_smp, uv);\n            case 5u: return anisoSample2DSep(materialDyn_tex[5], materialDyn_smp, uv);\n            case 6u: return anisoSample2DSep(materialDyn_tex[6], materialDyn_smp, uv);\n            case 7u: return anisoSample2DSep(materialDyn_tex[7], materialDyn_smp, uv);\n        }\n        return fallback;\n    }\n    switch(bucket)\n    {\n        case 0u: return anisoSample2DArrayWrapped(materialArray_tex[0], materialArray_smp, vec3(uv, float(idx)), wrap);\n        case 1u: return anisoSample2DArrayWrapped(materialArray_tex[1], materialArray_smp, vec3(uv, float(idx)), wrap);\n        case 2u: return anisoSample2DArrayWrapped(materialArray_tex[2], materialArray_smp, vec3(uv, float(idx)), wrap);\n        case 3u: return anisoSample2DArrayWrapped(materialArray_tex[3], materialArray_smp, vec3(uv, float(idx)), wrap);\n        case 4u: return anisoSample2DArrayWrapped(materialArray_tex[4], materialArray_smp, vec3(uv, float(idx)), wrap);\n        case 5u: return anisoSample2DArrayWrapped(materialArray_tex[5], materialArray_smp, vec3(uv, float(idx)), wrap);\n        case 6u: return anisoSample2DArrayWrapped(materialArray_tex[6], materialArray_smp, vec3(uv, float(idx)), wrap);\n        case 7u: return anisoSample2DArrayWrapped(materialArray_tex[7], materialArray_smp, vec3(uv, float(idx)), wrap);\n    }\n    return fallback;\n}\n\nvec4 sample_slot_bc(uint ref, uint wrap, vec2 uv, vec4 fallback)\n{\n    return sample_material_slot(ref, wrap, uv, fallback);\n}\n\n\nvec4 sample_slot_mr(uint ref, uint wrap, vec2 uv, vec4 fallback)\n{\n    return sample_material_slot(ref, wrap, uv, fallback);\n}\n\n\nvec4 sample_slot_nrm(uint ref, uint wrap, vec2 uv, vec4 fallback)\n{\n    return sample_material_slot(ref, wrap, uv, fallback);\n}\n\n\nvec4 sample_slot_em(uint ref, uint wrap, vec2 uv, vec4 fallback)\n{\n    return sample_material_slot(ref, wrap, uv, fallback);\n}\n\n\n// Separate glTF occlusionTexture (single-channel data, R = occlusion).\n// Sampled only when feature_mask carries `has_separate_occlusion`;\n// otherwise the main path falls back to MR.r per the common packed-MR\n// convention. fallback = 1 → identity (no occlusion).\nvec4 sample_slot_occ(uint ref, uint wrap, vec2 uv, vec4 fallback)\n{\n    return sample_material_slot(ref, wrap, uv, fallback);\n}\n\n\n// glTF feature_mask bits — must mirror SceneGPUState.hpp's\n// material_feature namespace.\nconst uint kFeat_alpha_mask           = 1u << 16u;\nconst uint kFeat_alpha_blend          = 1u << 17u;\nconst uint kFeat_double_sided         = 1u << 18u;\nconst uint kFeat_has_separate_occ     = 1u << 19u;\n// Per-channel texcoord_set bits (20-29). 2 bits per channel, value\n// 0 = TEXCOORD_0, value 1 = TEXCOORD_1. Out-of-range values collapse\n// to TEXCOORD_0 (the shift-mask in packMaterial clamps to 0/1).\nconst uint kFeat_tcset_bc_shift       = 20u;\nconst uint kFeat_tcset_mr_shift       = 22u;\nconst uint kFeat_tcset_nrm_shift      = 24u;\nconst uint kFeat_tcset_em_shift       = 26u;\nconst uint kFeat_tcset_occ_shift      = 28u;\n\nvec2 pick_uv(uint feature_mask, uint shift, vec2 uv0, vec2 uv1)\n{\n    return ((feature_mask >> shift) & 0x3u) == 1u ? uv1 : uv0;\n}\n\n// KHR_texture_transform helper: glTF defines the transform in UV space\n// as `uv' = R(rotation) * S(scale) * uv + offset`, with rotation\n// applied AFTER scale and BEFORE the offset shift. Identity defaults\n// (offset=0, scale=1, rotation=0) pass through unchanged.\nvec2 apply_uv_xform(vec2 uv, vec4 offset_scale, float rotation)\n{\n    vec2 scaled = uv * offset_scale.zw;\n    float c = cos(rotation), s = sin(rotation);\n    vec2 rotated = vec2(c * scaled.x - s * scaled.y,\n                        s * scaled.x + c * scaled.y);\n    return rotated + offset_scale.xy;\n}\n\n// Shader-level alpha-to-coverage. QRhi (6.12) doesn't expose\n// AlphaToCoverage on QRhiGraphicsPipeline, so we replicate the\n// behaviour at the shader level: gl_SampleMask[0] is a writable\n// per-fragment built-in where each bit selects whether the\n// corresponding MSAA sample is written. Convert alpha to a sample\n// count, set that many bits, screen-space-rotate per pixel so the\n// MSAA resolve smooths the silhouette into a soft edge.\n//\n// Sample count comes from MSAA_SAMPLES, an integer auto-injected by\n// libisf into the renderer UBO at binding=0 — score writes the active\n// RenderList's sample count there each frame. (We can't use\n// gl_NumSamples: glslang strips it when targeting SPIR-V.) Score lets\n// users pick any of {1, 2, 4, 8, 16}. With MSAA off, MSAA_SAMPLES=1\n// and we degrade to a 0.5 binary cutoff. Vulkan caps multisample\n// rasterization at 16x in practice; clamp there so the rotation math\n// stays defined for 32-bit uints.\n//\n// Returns false when the fragment is fully transparent → caller\n// discards (early-out skips the rest of main()).\nbool applyAlphaToCoverage(float alpha)\n{\n    if(alpha <= 0.0)\n        return false;\n\n    int samples = clamp(MSAA_SAMPLES, 1, 16);\n    uint full = (samples >= 32) ? 0xFFFFFFFFu\n                                : ((1u << uint(samples)) - 1u);\n\n    if(alpha >= 1.0)\n    {\n        gl_SampleMask[0] = int(full);\n        return true;\n    }\n    int n = int(round(alpha * float(samples)));\n    if(n <= 0)\n        return false;\n    if(n >= samples)\n    {\n        gl_SampleMask[0] = int(full);\n        return true;\n    }\n\n    // MSAA sample counts are powers of two, so (S-1) is a valid mask.\n    // shift lands in [0, S-1]; rotation handles shift==0 cleanly\n    // because base >> S is well-defined for S<=16 (< 32 bits).\n    uint S = uint(samples);\n    uint hash = uint(gl_FragCoord.x) * 1597u\n              + uint(gl_FragCoord.y) * 2731u;\n    uint shift = hash & (S - 1u);\n    uint base  = (1u << uint(n)) - 1u;\n    uint rot   = ((base << shift) | (base >> (S - shift))) & full;\n    gl_SampleMask[0] = int(rot);\n    return true;\n}\n\n// Map gl_FragCoord + view-space Z to a froxel index. Same log-spaced Z\n// slicing build_cluster_aabbs.csf uses, same (z*Y + y)*X + x flattening\n// volumetric_integrate.csf writes — keep these three formulas in sync\n// or sampling lands in the wrong cell.\nuint scoreClusterId(vec2 fragCoord, float viewZ)\n{\n    vec2 uv = fragCoord / camera.renderSize.xy;\n    uint gx = cluster_config.cluster_x;\n    uint gy = cluster_config.cluster_y;\n    uint gz = cluster_config.cluster_z;\n\n    uint tx = uint(clamp(floor(uv.x * float(gx)), 0.0, float(gx) - 1.0));\n    uint ty = uint(clamp(floor(uv.y * float(gy)), 0.0, float(gy) - 1.0));\n\n    float zNear = camera.params.y;\n    float zFar  = camera.params.z;\n    float depth = max(-viewZ, zNear);\n    float t = float(gz) * log(depth / zNear) / log(zFar / zNear);\n    uint tz = uint(clamp(t, 0.0, float(gz) - 1.0));\n\n    return (tz * gy + ty) * gx + tx;\n}\n\n// Inline volumetric fog composite — see classic_pbr_openpbr.frag for\n// the full rationale. Two production-grade refinements vs the naive\n// nearest-cell lookup:\n//   1. Trilinear interpolation across the 8 surrounding froxels —\n//      hides the cluster grid (16x9x24 default) which otherwise\n//      shows up as a hard checkerboard at cell boundaries.\n//   2. volumetric_intensity blends toward identity rather than just\n//      scaling accum, so low intensity == \"less fog\" rather than\n//      \"no source + tiny in-scatter\".\n// Identity fallback when the toggle is off or cluster_x == 0u.\nvec3 applyVolumetric(vec3 inColor, vec2 fragCoord, float viewZ)\n{\n    if(volumetric_enabled == 0)\n        return inColor;\n\n    uint gx = cluster_config.cluster_x;\n    uint gy = cluster_config.cluster_y;\n    uint gz = cluster_config.cluster_z;\n    if(gx == 0u || gy == 0u || gz == 0u)\n        return inColor;\n\n    vec2  uv = fragCoord / camera.renderSize.xy;\n    float zNear = camera.params.y;\n    float zFar  = camera.params.z;\n    float depth = max(-viewZ, zNear);\n    float fx = uv.x * float(gx) - 0.5;\n    float fy = uv.y * float(gy) - 0.5;\n    float fz = float(gz) * log(depth / zNear) / log(zFar / zNear) - 0.5;\n\n    vec3 cf = clamp(vec3(fx, fy, fz), vec3(0.0),\n                    vec3(float(gx) - 1.0001,\n                         float(gy) - 1.0001,\n                         float(gz) - 1.0001));\n    vec3 cb = floor(cf);\n    vec3 t  = cf - cb;\n    uvec3 i0 = uvec3(cb);\n    uvec3 i1 = min(i0 + 1u, uvec3(gx - 1u, gy - 1u, gz - 1u));\n\n    #define IDX(ix, iy, iz) (((iz) * gy + (iy)) * gx + (ix))\n    vec4 c000 = vol_integrated.data[IDX(i0.x, i0.y, i0.z)].accum_transmittance;\n    vec4 c100 = vol_integrated.data[IDX(i1.x, i0.y, i0.z)].accum_transmittance;\n    vec4 c010 = vol_integrated.data[IDX(i0.x, i1.y, i0.z)].accum_transmittance;\n    vec4 c110 = vol_integrated.data[IDX(i1.x, i1.y, i0.z)].accum_transmittance;\n    vec4 c001 = vol_integrated.data[IDX(i0.x, i0.y, i1.z)].accum_transmittance;\n    vec4 c101 = vol_integrated.data[IDX(i1.x, i0.y, i1.z)].accum_transmittance;\n    vec4 c011 = vol_integrated.data[IDX(i0.x, i1.y, i1.z)].accum_transmittance;\n    vec4 c111 = vol_integrated.data[IDX(i1.x, i1.y, i1.z)].accum_transmittance;\n    #undef IDX\n\n    vec4 v = mix(mix(mix(c000, c100, t.x), mix(c010, c110, t.x), t.y),\n                 mix(mix(c001, c101, t.x), mix(c011, c111, t.x), t.y),\n                 t.z);\n\n    float transm = clamp(v.a, 0.0, 1.0);\n    vec3  accum  = v.rgb;\n\n    float k       = volumetric_intensity;\n    float k_blend = clamp(k, 0.0, 1.0);\n    float transm_eff = mix(1.0, transm, k_blend);\n    vec3  accum_eff  = accum * k;\n\n    return inColor * transm_eff + accum_eff;\n}\n\nvoid main()\n{\n    // Default coverage: keep every MSAA sample. Once applyAlphaToCoverage\n    // exists in the module, the SPIR-V output declares gl_SampleMask, and\n    // any path that doesn't assign it leaves the value undefined — most\n    // drivers default that to 0 and cull every sample, producing block-\n    // speckle artifacts on non-alpha-mask materials. Seeding to all-ones\n    // here makes the non-A2C paths render correctly; the A2C branch\n    // overrides this for masked fragments.\n    gl_SampleMask[0] = -1;\n\n    PerDraw pd = per_draws.data[v_drawID];\n    Material mat = scene_materials.entries[pd.material_index];\n    MatUVXform mx = scene_material_uv_xforms.entries[pd.material_index];\n    g_matWrap = scene_material_wrap.entries[pd.material_index].xyz;\n\n    // glTF doubleSided: pipeline-side culling is OFF (cull_mode=none\n    // in the MDI batch) so we get both faces. For SINGLE-sided materials\n    // we discard back-facing fragments here to mimic CULL_BACK. For\n    // DOUBLE-sided materials we keep the fragment and flip the normal\n    // below so lighting on the back side works correctly.\n    bool is_double_sided = (mat.feature_mask & kFeat_double_sided) != 0u;\n    if(!is_double_sided && !gl_FrontFacing)\n        discard;\n\n    // Pick the per-channel texcoord source (TEXCOORD_0 vs TEXCOORD_1)\n    // before applying the KHR_texture_transform. glTF allows each\n    // texture_info to override its texcoord_set independently — BC\n    // might use TEXCOORD_0 while Emissive uses TEXCOORD_1, etc.\n    vec2 base_uv_bc  = pick_uv(mat.feature_mask, kFeat_tcset_bc_shift,  v_uv, v_uv1);\n    vec2 base_uv_mr  = pick_uv(mat.feature_mask, kFeat_tcset_mr_shift,  v_uv, v_uv1);\n    vec2 base_uv_nrm = pick_uv(mat.feature_mask, kFeat_tcset_nrm_shift, v_uv, v_uv1);\n    vec2 base_uv_em  = pick_uv(mat.feature_mask, kFeat_tcset_em_shift,  v_uv, v_uv1);\n    vec2 base_uv_occ = pick_uv(mat.feature_mask, kFeat_tcset_occ_shift, v_uv, v_uv1);\n\n    // Per-channel UVs after KHR_texture_transform.\n    vec2 uv_bc  = apply_uv_xform(base_uv_bc,  mx.bc_offset_scale,     mx.rotations0.x);\n    vec2 uv_mr  = apply_uv_xform(base_uv_mr,  mx.mr_offset_scale,     mx.rotations0.y);\n    vec2 uv_nrm = apply_uv_xform(base_uv_nrm, mx.normal_offset_scale, mx.rotations0.z);\n    vec2 uv_em  = apply_uv_xform(base_uv_em,  mx.em_offset_scale,     mx.rotations0.w);\n    vec2 uv_occ = apply_uv_xform(base_uv_occ, mx.occ_offset_scale,    mx.rotations1.x);\n\n    // Pre-pull env knobs so the early-out (unlit) and main path both\n    // see the same values. Defaults come from EnvironmentLoader if the\n    // user wired one; otherwise the merged scene_environment carries\n    // safe identity-ish values (ambient=0, exposure=1, gamma=2.2,\n    // fog disabled).\n    vec3  ambient_col   = env.ambient.rgb * env.ambient.w;\n    float exposure_mul  = max(env.exposure_gamma.x, 1e-6);\n    float gamma         = max(env.exposure_gamma.y, 1e-3);\n\n    // ─── Base color ────────────────────────────────────────────────────\n    // glTF: final base = baseColorFactor × baseColorTexture × COLOR_0\n    // (vertex color). v_color defaults to white when the mesh doesn't\n    // have COLOR_0 (slab uploader fills with vec4(1) in that case).\n    vec4 bc = sample_slot_bc(mat.textureRefs.x, matWrap(0u), uv_bc, vec4(1.0));\n\n    // Alpha-mask edge-bleed compensation. Source PNGs for foliage / hair\n    // / fence-style cutouts have alpha=0 in transparent regions with\n    // RGB=0 there too (standard authoring). Mip / aniso filtering\n    // averages RGB and alpha independently — near a leaf edge the\n    // sampled RGB ends up `leaf_color × alpha_avg`, so post-alpha-test\n    // surviving fragments read a darkened RGB and the silhouette gets a\n    // black halo. Dividing RGB by alpha inverts the alpha-weighted\n    // averaging and recovers the source colour. Skip when alpha is near\n    // zero (would discard anyway) and when the material isn't\n    // alpha-masked (BLEND / OPAQUE both want the literal sampled RGB).\n    if((mat.feature_mask & kFeat_alpha_mask) != 0u && bc.a > 1e-3)\n        bc.rgb /= bc.a;\n\n    // Per-instance broadcast colour rides through `v_inst_color` from\n    // the vertex stage. For non-instanced draws the REQUIRED:false\n    // fallback fires identity (1,1,1,1) so the modulation collapses\n    // to the per-vertex × material × baseColor product.\n    vec3 base = mat.baseColor.rgb * bc.rgb * v_color.rgb * v_inst_color.rgb;\n    float alpha = mat.baseColor.a * bc.a * v_color.a * v_inst_color.a;\n\n    // glTF alphaMode=MASK — early discard before any expensive work.\n    // Two paths:\n    //   alpha_a2c_enabled = 1 → shader-level alpha-to-coverage via\n    //                            gl_SampleMask. Best edge quality when\n    //                            MSAA is on; degrades gracefully to a\n    //                            hard cutoff when MSAA is off (round\n    //                            saturates to 0 / 8).\n    //   default               → classic binary cutoff.\n    if((mat.feature_mask & kFeat_alpha_mask) != 0u)\n    {\n        if(alpha_a2c_enabled != 0)\n        {\n            if(!applyAlphaToCoverage(alpha))\n                discard;\n        }\n        else\n        {\n            if(alpha < mat.alpha_cutoff)\n                discard;\n        }\n    }\n\n    // ─── Metal-Rough-Occlusion (glTF packing: R=occ, G=rough, B=metal) ─\n    vec4 mr = sample_slot_mr(mat.textureRefs.y, matWrap(1u), uv_mr, vec4(1.0, 1.0, 1.0, 1.0));\n    float metallic\n        = mat.metallicRoughnessOcclusionUnlit.x * mr.b;\n    float roughness\n        = clamp(mat.metallicRoughnessOcclusionUnlit.y * mr.g, 0.04, 1.0);\n    // Occlusion: prefer separate occlusionTexture when set; else fall\n    // back to MR.r (the common packed-MR convention).\n    float occ_sample;\n    if((mat.feature_mask & kFeat_has_separate_occ) != 0u)\n        occ_sample = sample_slot_occ(mat.occlusion_textureRef, matWrap(4u), uv_occ, vec4(1.0)).r;\n    else\n        occ_sample = mr.r;\n    float occlusion = occ_sample * mat.metallicRoughnessOcclusionUnlit.z;\n    float unlit     = mat.metallicRoughnessOcclusionUnlit.w;\n\n    // ─── Emissive ─────────────────────────────────────────────────────\n    vec4 em = sample_slot_em(mat.textureRefs.w, matWrap(3u), uv_em, vec4(1.0));\n    vec3 emissive\n        = mat.emissive_strength.xyz * em.rgb * mat.emissive_strength.w;\n    emissive += v_inst_emissive.rgb;\n\n    if(unlit > 0.5)\n    {\n        // Volumetric composite BEFORE exposure_mul — accum is in raw\n        // light units (same scale as the BSDF result), so both sides\n        // of `inColor * transm + accum` stay in matched units.\n        // Output is linear HDR — the downstream tonemap owns the\n        // HDR→display compression and sRGB encode. (Doing pow(_,1/gamma)\n        // here would clip everything > 1 post-exposure to flat white\n        // before the tonemap could read the HDR signal — that's what\n        // made volumetric in-scatter blow out to saturated pink.)\n        vec3 color = base + emissive;\n        float viewZ_unlit = (camera.view * vec4(v_worldPos, 1.0)).z;\n        color = applyVolumetric(color, gl_FragCoord.xy, viewZ_unlit);\n        color *= exposure_mul;\n        isf_FragColor = vec4(max(color, vec3(0.0)), (mat.feature_mask & (1u << 17u)) != 0u ? alpha : 1.0);\n        return;\n    }\n\n    // ─── Surface normal (tangent-space normal map if present) ─────────\n    vec3 N = normalize(v_normal);\n    // Double-sided: flip the surface normal for back-facing fragments\n    // so the BRDF evaluates with the correct hemisphere on both sides\n    // of the surface. (Single-sided materials never reach here for\n    // back faces — they were discarded above.)\n    if(is_double_sided && !gl_FrontFacing)\n        N = -N;\n    // Toksvig variance accumulator (Olano-Baker 2010). Captures the\n    // amount of normal-map variance lost to mip-level averaging /\n    // multi-tap anisotropic averaging — info the GPU's bilinear+mip\n    // filter normally throws away when shaders re-normalize sampled\n    // normals. Folded into the specular-AA block below alongside the\n    // screen-space (Tokuyoshi-Kaplanyan) variance.\n    float toksvig_sigma2 = 0.0;\n    uint normRef = mat.textureRefs.z;\n    if(normRef != 0xFFFFFFFFu && length(v_tangent.xyz) > 0.5)\n    {\n        vec3 T = normalize(v_tangent.xyz);\n        vec3 B = normalize(cross(N, T) * v_tangent.w);\n        mat3 TBN = mat3(T, B, N);\n        // Normal map sampling goes through the bucket ladder so\n        // mixed-resolution / compressed normal atlases work. The\n        // default (0.5,0.5,1.0) fallback decodes to a zero tangent-\n        // space delta — same as no normal map at all — if the bucket\n        // slot isn't populated.\n        //\n        // Keep the UN-NORMALIZED sample so its length can drive the\n        // Toksvig boost: anisoSample averages multiple weighted taps\n        // and mip filtering averages within texels, both of which\n        // shorten |n| when sub-pixel normals had directional spread.\n        // (1 - |n|²) is the \"lost variance\" added back as roughness.\n        vec3 nm_raw = sample_slot_nrm(normRef, matWrap(2u), uv_nrm,\n                                      vec4(0.5, 0.5, 1.0, 1.0)).xyz\n                      * 2.0 - 1.0;\n        toksvig_sigma2 = max(0.0, 1.0 - dot(nm_raw, nm_raw));\n        N = normalize(TBN * normalize(nm_raw));\n    }\n\n    vec3 V = normalize(camera.cameraPosition.xyz - v_worldPos);\n    float NdotV = max(dot(N, V), 1e-4);\n\n    // Metallic workflow.\n    vec3 F0 = mix(vec3(0.04), base, metallic);\n    vec3 kd = (1.0 - metallic) * base;\n\n    // Cheap environment term — same \"fake IBL\" as classic_pbr_textured;\n    // classic_pbr_ibl is the cubemap-sampled variant.\n    vec3 Fv = F0 + (1.0 - F0) * pow(1.0 - NdotV, 5.0);\n    vec3 fake_env = Fv * base * 0.25;\n\n    // Ambient comes from EnvironmentLoader (env.ambient.rgb × intensity\n    // in .w). When the user hasn't wired one, ambient_col is zero and\n    // the fake_env term + lights carry the lighting. The 0.04 floor is\n    // gone — letting users actually dial ambient down to black.\n    vec3 result = ambient_col * base * occlusion\n                  + emissive\n                  + fake_env * occlusion;\n\n    float alpha_g = max(roughness * roughness, 1e-4);\n    float alpha2 = alpha_g * alpha_g;\n    float k = (roughness + 1.0) * (roughness + 1.0) / 8.0;\n\n    // ─── Specular antialiasing — Tokuyoshi-Kaplanyan + Toksvig ───────\n    //\n    // Three variance sources combined into a single roughness boost:\n    //\n    //   (A) Tokuyoshi-Kaplanyan 2019, \"Improved Geometric Specular\n    //       Antialiasing\" — screen-space derivatives of the world-\n    //       space normal. Captures sub-pixel-footprint normal\n    //       variance from geometry, normal-map silhouettes, and\n    //       interpolation across neighbours.\n    //\n    //   (B) Toksvig 2005, \"Mipmapping Normal Maps\" — texture-space\n    //       variance from filtered-normal shortening. Captures\n    //       variance lost to mip averaging + our multi-tap\n    //       anisotropic sampler that the GPU's linear filter and\n    //       shader's normalize() throw away.\n    //\n    //   (C) Grazing-angle amplification — a heuristic 1/NdotV scale\n    //       (capped) on the screen-space variance, approximating\n    //       Tokuyoshi-Kaplanyan's anisotropic Jacobian projection of\n    //       normal variance onto the half-vector tangent plane. The\n    //       full anisotropic form derives this matrix-multiply\n    //       explicitly; the 1/NdotV scalar captures the leading-\n    //       order behaviour at grazing where the BRDF stretches\n    //       most. Targets the \"noisy floor at grazing light\"\n    //       failure mode: at grazing, the half-vector becomes\n    //       perpendicular to the surface, NdotH gets small, and the\n    //       GGX D term's denominator hyperbola makes small N\n    //       variations move the highlight in/out of pixels.\n    //\n    // (A)+(B) cover variance from BOTH variance domains — the\n    // screen-space and texture-space sources are independent and\n    // additive. (C) amplifies (A) where the BRDF Jacobian demands it.\n    vec3 dNdx = dFdx(N);\n    vec3 dNdy = dFdy(N);\n    float kernelRoughness2 = 2.0 * (dot(dNdx, dNdx) + dot(dNdy, dNdy));\n\n    // (C) grazing amplification. NdotV floor of 0.05 prevents\n    // runaway at near-tangent view; cap at 8× keeps the boost\n    // bounded so we don't blow specular into pure diffuse.\n    float grazing_aa = clamp(1.0 / max(NdotV, 0.05), 1.0, 8.0);\n    kernelRoughness2 *= grazing_aa;\n\n    // Combine (A)·grazing + (B). Cap to keep alpha² in [0, 1] after\n    // the boost; 0.5 is the standard upper bound used by Filament +\n    // the Tokuyoshi-Kaplanyan reference.\n    const float specAaSigma2Max = 0.5;\n    float total_aa_sigma2 = clamp(kernelRoughness2 + toksvig_sigma2,\n                                  0.0, specAaSigma2Max);\n    alpha2 = clamp(alpha2 + total_aa_sigma2, 0.0, 1.0);\n    alpha_g = sqrt(alpha2);\n    // Re-derive Schlick-Smith k from the filtered roughness too so the\n    // G term widens in lockstep with D — otherwise rough-but-filtered\n    // surfaces still get an over-tight visibility term.\n    float roughness_f = sqrt(alpha_g);\n    k = (roughness_f + 1.0) * (roughness_f + 1.0) / 8.0;\n\n    uint n = scene_counts.light_count;\n    for(uint i = 0u; i < n; ++i)\n    {\n        uint slot = scene_light_indices.data[i];\n        Light L = scene_lights.entries[slot];\n\n        // Two paths for resolving the light's world-space placement:\n        //\n        //   transform_slot == 0xFFFFFFFF (sentinel):\n        //     The light was authored procedurally (e.g. by a compute CSF\n        //     reading a point cloud or particle system) and carries its\n        //     world position inline in local_direction.xyz. Skip the\n        //     world_transforms lookup — there's no matching scene-node\n        //     entry. Only point lights (type == 1) are well-defined\n        //     under this convention; directional with sentinel falls\n        //     back to treating .xyz as a direction, spot is unsupported.\n        //\n        //   transform_slot != sentinel:\n        //     Classic scene-node-attached light. World direction and\n        //     position come from the node's accumulated world transform\n        //     (published by ScenePreprocessor's FlattenVisitor).\n        float _type_f = L.local_direction.w;\n        vec3 ld_world;\n        vec3 lp_world;\n        if(L.transform_slot == 0xFFFFFFFFu)\n        {\n            if(_type_f < 0.5)\n            {\n                // Directional: .xyz is the world direction (same\n                // convention the scene-node path uses — no transform to\n                // apply since the light isn't parented to any node).\n                ld_world = normalize(L.local_direction.xyz);\n                lp_world = vec3(0.0);\n            }\n            else\n            {\n                // Point: .xyz is the world position. A default direction\n                // lets spot-cone code below degenerate gracefully for\n                // spot lights authored this way (cone attenuation will\n                // be effectively wide-open, since we have no real axis).\n                lp_world = L.local_direction.xyz;\n                ld_world = vec3(0.0, -1.0, 0.0);\n            }\n        }\n        else\n        {\n            mat4 W = world_transforms.data[L.transform_slot];\n            ld_world = normalize(mat3(W) * L.local_direction.xyz);\n            lp_world = W[3].xyz;\n        }\n        // Reconstruct the old LightGPU-shape vec4s so the BRDF body\n        // below (which references pos_type / color_i / dir_r) stays\n        // unchanged. type enum stays in .w; for directional lights the\n        // xyz holds the world direction, for point/spot it holds the\n        // world position — matching the prior packLight convention.\n        vec4 pos_type = vec4(\n            (_type_f < 0.5) ? ld_world : lp_world,\n            _type_f);\n        vec4 color_i  = L.color;\n        vec4 dir_r    = vec4(ld_world, L.range_cone.x);\n\n        vec3 Ldir;\n        float atten = 1.0;\n        if(pos_type.w < 0.5)\n        {\n            // Directional: no distance, no decay — per glTF / OpenPBR\n            // convention the 1/d² term doesn't apply.\n            Ldir = normalize(-pos_type.xyz);\n        }\n        else\n        {\n            vec3 toL = pos_type.xyz - v_worldPos;\n            float d = length(toL);\n            Ldir = toL / max(d, 1e-5);\n\n            // Hard cutoff: range == 0 is the \"no cutoff\" sentinel (glTF\n            // + ossia convention). Otherwise linearly fade over the\n            // last interval so the light doesn't pop off at exactly the\n            // range boundary.\n            if(dir_r.w > 0.0) atten = max(0.0, 1.0 - d / dir_r.w);\n\n            // Distance decay — switches on L.decay_mode so linear / none /\n            // cubic authored by the user or extracted from FBX actually\n            // reach the shader instead of being silently collapsed to\n            // the quadratic curve. Modes:\n            //   0 = none       (constant — legitimate for area lights\n            //                   and stylised looks)\n            //   1 = linear     1 / (1 + d)\n            //   2 = quadratic  1 / (1 + d²)   — physically correct default\n            //   3 = cubic      1 / (1 + d³)   — exaggerated falloff\n            uint decay = L.decay_mode;\n            if(decay == 1u)\n                atten *= 1.0 / (1.0 + d);\n            else if(decay == 2u)\n                atten *= 1.0 / (1.0 + d * d);\n            else if(decay == 3u)\n                atten *= 1.0 / (1.0 + d * d * d);\n            // decay == 0u → no distance attenuation; `atten` keeps the\n            // range cutoff contribution only.\n\n            // Spot-cone attenuation. Inner / outer cones are stored as\n            // cosines (packed CPU-side in Light.cpp) so the fragment-side\n            // test is one dot product + a linear ramp, matching the glTF\n            // KHR_lights_punctual reference formula:\n            //   t = clamp((cos_angle - outer) / (inner - outer), 0, 1)\n            //   atten *= t\n            // Outside the outer cone → t = 0, light doesn't contribute.\n            // Inside the inner cone → t = 1, full spot intensity.\n            // Between → linear falloff. type ≈ 2 = spot (local_direction.w\n            // packs the enum; see RawLightData::local_direction in\n            // SceneGPUState.hpp). Point lights (type ≈ 1) skip this\n            // block, so the spot-specific math doesn't perturb them.\n            if(pos_type.w > 1.5 && pos_type.w < 2.5)\n            {\n                float cos_to_frag = dot(-Ldir, normalize(dir_r.xyz));\n                float inner_cos   = L.range_cone.y;\n                float outer_cos   = L.range_cone.z;\n                atten *= clamp(\n                    (cos_to_frag - outer_cos)\n                        / max(inner_cos - outer_cos, 1e-5),\n                    0.0, 1.0);\n            }\n        }\n\n        float NdotL = max(dot(N, Ldir), 0.0);\n        if(NdotL <= 0.0) continue;\n\n        vec3 H = normalize(Ldir + V);\n        float NdotH = max(dot(N, H), 0.0);\n        float VdotH = max(dot(V, H), 0.0);\n\n        float denom_d = NdotH * NdotH * (alpha2 - 1.0) + 1.0;\n        float D = alpha2 / (3.14159 * denom_d * denom_d);\n\n        float G_v = NdotV / (NdotV * (1.0 - k) + k);\n        float G_l = NdotL / (NdotL * (1.0 - k) + k);\n        float G = G_v * G_l;\n\n        vec3 F = F0 + (1.0 - F0) * pow(1.0 - VdotH, 5.0);\n\n        vec3 spec = (D * G * F) / max(4.0 * NdotV * NdotL, 1e-4);\n        vec3 diffuse_term = (vec3(1.0) - F) * kd / 3.14159;\n\n        vec3 lightCol = color_i.rgb * color_i.w;\n        result += atten * lightCol * NdotL * (diffuse_term + spec);\n    }\n\n    // Linear fog: blend with fog_color over [start, end]. fog_range.w\n    // is the enabled flag (set by EnvironmentLoader). When disabled\n    // we skip the work.\n    if(env.fog_range.w > 0.5)\n    {\n        float view_z = distance(camera.cameraPosition.xyz, v_worldPos);\n        float f_s = env.fog_range.x;\n        float f_e = max(env.fog_range.y, f_s + 1e-3);\n        float t = clamp((view_z - f_s) / (f_e - f_s), 0.0, 1.0);\n        result = mix(result, env.fog_color_density.rgb, t);\n    }\n\n    // Volumetric composite BEFORE exposure_mul. accum from the integrate\n    // pass is in raw light units (same scale as the BSDF result), so\n    // both sides of `inColor * transm + accum` stay in matched units —\n    // applying after exposure makes accum dominate dim surfaces and\n    // lose to bright/specular surfaces, which was the original\n    // \"foliage punches through fog\" symptom.\n    //\n    // view_z above is `distance(eye, worldPos)` (positive); applyVolumetric /\n    // scoreClusterId need view-space Z (negative). Recompute from\n    // camera.view to keep the cluster lookup consistent with\n    // build_cluster_aabbs / volumetric_integrate.\n    float viewZ = (camera.view * vec4(v_worldPos, 1.0)).z;\n    result = applyVolumetric(result, gl_FragCoord.xy, viewZ);\n\n    result *= exposure_mul;\n\n    // Output is LINEAR HDR. The downstream tonemap node owns the\n    // HDR→display compression (ACES / Reinhard / filmic / etc.) and\n    // the sRGB encode. The previous `pow(result, 1/gamma)` here was\n    // sRGB-encoding the HDR before the tonemap could read it: any\n    // radiance > 1.0 post-exposure clipped to flat white at gamma\n    // encode, which is what made volumetric in-scatter blow out to\n    // saturated pink.\n    isf_FragColor = vec4(max(result, vec3(0.0)), (mat.feature_mask & (1u << 17u)) != 0u ? alpha : 1.0);\n}\n","Inlets":[{"uuid":"f2ab26ea-415d-45a2-bfbc-2968c7c92a33","ObjectName":"Inlet","id":1000,"Hidden":false,"Custom":"Geometry In","Exposed":"geometry in"},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":0,"Hidden":true,"Custom":"Mode","Exposed":"mode","Value":{"Int":0},"Init":{"Int":0},"Domain":{"Int":{"Values":[0,1,2,3]}},"Values":[["Triangles",{"Int":0}],["Points",{"Int":1}],["Lines",{"Int":2}],["Geometry",{"Int":3}]],"FolderPort":"","FileExtensions":""},{"uuid":"fb27e4cb-ea7f-41e2-ad92-2354498c1b6b","ObjectName":"Inlet","id":1,"Hidden":true,"Custom":"EnableBlend","Exposed":"enableblend","Value":{"Bool":false},"Init":{"Bool":false},"Domain":{"Bool":null}},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":2,"Hidden":true,"Custom":"SrcColor","Exposed":"srccolor","Value":{"Int":6},"Init":{"Int":6},"Domain":{"Int":{"Values":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]}},"Values":[["Zero",{"Int":0}],["One",{"Int":1}],["SrcColor",{"Int":2}],["OneMinusSrcColor",{"Int":3}],["DstColor",{"Int":4}],["OneMinusDstColor",{"Int":5}],["SrcAlpha",{"Int":6}],["OneMinusSrcAlpha",{"Int":7}],["DstAlpha",{"Int":8}],["OneMinusDstAlpha",{"Int":9}],["ConstantColor",{"Int":10}],["OneMinusConstantColor",{"Int":11}],["ConstantAlpha",{"Int":12}],["OneMinusConstantAlpha",{"Int":13}],["SrcAlphaSaturate",{"Int":14}]],"FolderPort":"","FileExtensions":""},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":3,"Hidden":true,"Custom":"DstColor","Exposed":"dstcolor","Value":{"Int":7},"Init":{"Int":7},"Domain":{"Int":{"Values":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]}},"Values":[["Zero",{"Int":0}],["One",{"Int":1}],["SrcColor",{"Int":2}],["OneMinusSrcColor",{"Int":3}],["DstColor",{"Int":4}],["OneMinusDstColor",{"Int":5}],["SrcAlpha",{"Int":6}],["OneMinusSrcAlpha",{"Int":7}],["DstAlpha",{"Int":8}],["OneMinusDstAlpha",{"Int":9}],["ConstantColor",{"Int":10}],["OneMinusConstantColor",{"Int":11}],["ConstantAlpha",{"Int":12}],["OneMinusConstantAlpha",{"Int":13}],["SrcAlphaSaturate",{"Int":14}]],"FolderPort":"","FileExtensions":""},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":4,"Hidden":true,"Custom":"OpColor","Exposed":"opcolor","Value":{"Int":0},"Init":{"Int":0},"Domain":{"Int":{"Values":[0,1,2,3,4]}},"Values":[["Add",{"Int":0}],["Substract",{"Int":1}],["Reverse Substract",{"Int":2}],["Min",{"Int":3}],["Max",{"Int":4}]],"FolderPort":"","FileExtensions":""},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":5,"Hidden":true,"Custom":"SrcAlpha","Exposed":"srcalpha","Value":{"Int":1},"Init":{"Int":1},"Domain":{"Int":{"Values":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]}},"Values":[["Zero",{"Int":0}],["One",{"Int":1}],["SrcColor",{"Int":2}],["OneMinusSrcColor",{"Int":3}],["DstColor",{"Int":4}],["OneMinusDstColor",{"Int":5}],["SrcAlpha",{"Int":6}],["OneMinusSrcAlpha",{"Int":7}],["DstAlpha",{"Int":8}],["OneMinusDstAlpha",{"Int":9}],["ConstantColor",{"Int":10}],["OneMinusConstantColor",{"Int":11}],["ConstantAlpha",{"Int":12}],["OneMinusConstantAlpha",{"Int":13}],["SrcAlphaSaturate",{"Int":14}]],"FolderPort":"","FileExtensions":""},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":6,"Hidden":true,"Custom":"DstAlpha","Exposed":"dstalpha","Value":{"Int":7},"Init":{"Int":7},"Domain":{"Int":{"Values":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]}},"Values":[["Zero",{"Int":0}],["One",{"Int":1}],["SrcColor",{"Int":2}],["OneMinusSrcColor",{"Int":3}],["DstColor",{"Int":4}],["OneMinusDstColor",{"Int":5}],["SrcAlpha",{"Int":6}],["OneMinusSrcAlpha",{"Int":7}],["DstAlpha",{"Int":8}],["OneMinusDstAlpha",{"Int":9}],["ConstantColor",{"Int":10}],["OneMinusConstantColor",{"Int":11}],["ConstantAlpha",{"Int":12}],["OneMinusConstantAlpha",{"Int":13}],["SrcAlphaSaturate",{"Int":14}]],"FolderPort":"","FileExtensions":""},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":7,"Hidden":true,"Custom":"OpAlpha","Exposed":"opalpha","Value":{"Int":0},"Init":{"Int":0},"Domain":{"Int":{"Values":[0,1,2,3,4]}},"Values":[["Add",{"Int":0}],["Substract",{"Int":1}],["Reverse Substract",{"Int":2}],["Min",{"Int":3}],["Max",{"Int":4}]],"FolderPort":"","FileExtensions":""},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":8,"Hidden":false,"Custom":"camera","Exposed":"camera","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":9,"Hidden":false,"Custom":"scene_lights","Exposed":"scene_lights","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":10,"Hidden":false,"Custom":"scene_light_indices","Exposed":"scene_light_indices","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":11,"Hidden":false,"Custom":"world_transforms","Exposed":"world_transforms","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":12,"Hidden":false,"Custom":"scene_materials","Exposed":"scene_materials","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":13,"Hidden":false,"Custom":"scene_material_uv_xforms","Exposed":"scene_material_uv_xforms","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":14,"Hidden":false,"Custom":"per_draws","Exposed":"per_draws","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":15,"Hidden":false,"Custom":"indirect_draw_cmds","Exposed":"indirect_draw_cmds","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":16,"Hidden":false,"Custom":"scene_counts","Exposed":"scene_counts","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":17,"Hidden":false,"Custom":"env","Exposed":"env","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"238399a0-7e81-47e3-896f-08e8856e2973","ObjectName":"Inlet","id":18,"Hidden":true,"Custom":"alpha_a2c_enabled","Exposed":"alpha_a2c_enabled","Value":{"Int":0},"Init":{"Int":0},"Domain":{"Int":{"Min":0,"Max":1}}},{"uuid":"238399a0-7e81-47e3-896f-08e8856e2973","ObjectName":"Inlet","id":19,"Hidden":true,"Custom":"volumetric_enabled","Exposed":"volumetric_enabled","Value":{"Int":0},"Init":{"Int":0},"Domain":{"Int":{"Min":0,"Max":1}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":20,"Hidden":true,"Custom":"volumetric_intensity","Exposed":"volumetric_intensity","Value":{"Float":1.0},"Init":{"Float":1.0},"Domain":{"Float":{"Min":0.0,"Max":4.0}}}],"Outlets":[{"uuid":"f1c71046-b754-49a5-8e66-d01374773dfc","ObjectName":"Outlet","id":1000,"Hidden":false,"Custom":"Texture Out","Exposed":"texture out"}]},{"uuid":"74ca45ff-92c9-44a0-8f1a-754dea05ee1b","ObjectName":"gfxProcess","id":10,"Metadata":{"ScriptingName":"ISF Shader.10","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[2060.585230426218,581.111411905233],"Size":[182.0,160.0],"Loops":false,"FoldMode":0,"Vertex":"","Fragment":"/*{\n  \"DESCRIPTION\": \"HDR tone mapping with selectable algorithm: Reinhard, ACES Filmic (Narkowicz), Exposure, Uncharted 2 (Hable), or AgX. Feed it linear HDR colour (the PBR render pipelines output linear HDR and leave tone mapping and the display gamma to this node); the output is gamma-encoded for display.\",\n  \"CREDIT\": \"ossia score\",\n  \"ISFVSN\": \"2\",\n  \"CATEGORIES\": [\n    \"Post-Process\"\n  ],\n  \"INPUTS\": [\n    {\n      \"NAME\": \"inputImage\",\n      \"TYPE\": \"image\"\n    },\n    {\n      \"NAME\": \"algorithm\",\n      \"LABEL\": \"Tone curve\",\n      \"TYPE\": \"long\",\n      \"DEFAULT\": 1,\n      \"VALUES\": [0, 1, 2, 3, 4],\n      \"LABELS\": [\"Reinhard\", \"ACES Filmic\", \"Exposure\", \"Uncharted 2\", \"AgX\"]\n    },\n    {\n      \"NAME\": \"exposure\",\n      \"LABEL\": \"Exposure (multiplier)\",\n      \"TYPE\": \"float\",\n      \"DEFAULT\": 1.0,\n      \"MIN\": 0.1,\n      \"MAX\": 10.0\n    },\n    {\n      \"NAME\": \"gamma\",\n      \"LABEL\": \"Display gamma\",\n      \"TYPE\": \"float\",\n      \"DEFAULT\": 2.2,\n      \"MIN\": 0.5,\n      \"MAX\": 3.0\n    },\n    {\n      \"NAME\": \"whitePoint\",\n      \"LABEL\": \"White point (Reinhard only)\",\n      \"TYPE\": \"float\",\n      \"DEFAULT\": 4.0,\n      \"MIN\": 0.5,\n      \"MAX\": 20.0\n    }\n  ]\n}*/\n\n// --- Reinhard (extended) ---\nvec3 tonemapReinhard(vec3 color, float wp)\n{\n  // Extended Reinhard: color * (1 + color / wp^2) / (1 + color)\n  vec3 wp2 = vec3(wp * wp);\n  return color * (1.0 + color / wp2) / (1.0 + color);\n}\n\n// --- ACES Filmic (Narkowicz approximation) ---\n// Source: Krzysztof Narkowicz, \"ACES Filmic Tone Mapping Curve\" (2016)\nvec3 tonemapACES(vec3 x)\n{\n  const float a = 2.51;\n  const float b = 0.03;\n  const float c = 2.43;\n  const float d = 0.59;\n  const float e = 0.14;\n  return clamp((x * (a * x + b)) / (x * (c * x + d) + e), 0.0, 1.0);\n}\n\n// --- Exposure (simple) ---\nvec3 tonemapExposure(vec3 color, float e)\n{\n  return 1.0 - exp(-color * e);\n}\n\n// --- Uncharted 2 (Hable filmic) ---\n// Source: John Hable, \"Filmic Tonemapping Operators\" (GDC 2010)\nvec3 uncharted2Partial(vec3 x)\n{\n  const float A = 0.15; // Shoulder strength\n  const float B = 0.50; // Linear strength\n  const float C = 0.10; // Linear angle\n  const float D = 0.20; // Toe strength\n  const float E = 0.02; // Toe numerator\n  const float F = 0.30; // Toe denominator\n  return ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F;\n}\n\nvec3 tonemapUncharted2(vec3 color)\n{\n  const float W = 11.2; // Linear white point\n  const float exposureBias = 2.0;\n  vec3 curr = uncharted2Partial(color * exposureBias);\n  vec3 whiteScale = vec3(1.0) / uncharted2Partial(vec3(W));\n  return curr * whiteScale;\n}\n\n// --- AgX ---\n// Based on the minimal analytical AgX implementation.\n// References: Troy Sobotka, Benjamin Wrensch (Missing Deadlines), Blender 4.0\n\nconst mat3 AgXInsetMatrix = mat3(\n  0.856627153315983, 0.137318972929847, 0.11189821299995,\n  0.0951212405381588, 0.761241990602591, 0.0767994186031903,\n  0.0482516061458583, 0.101439036467562, 0.811302368396859\n);\n\nconst mat3 AgXOutsetMatrix = mat3(\n  1.1271005818144368, -0.1413297634984383, -0.14132976349843826,\n  -0.11060664309660323, 1.157823702216272, -0.11060664309660294,\n  -0.016493938717834573, -0.016493938717834257, 1.2519364065950405\n);\n\nconst mat3 LINEAR_SRGB_TO_LINEAR_REC2020 = mat3(\n  0.6274, 0.0691, 0.0164,\n  0.3293, 0.9195, 0.0880,\n  0.0433, 0.0113, 0.8956\n);\n\nconst mat3 LINEAR_REC2020_TO_LINEAR_SRGB = mat3(\n  1.6605, -0.1246, -0.0182,\n  -0.5876, 1.1329, -0.1006,\n  -0.0728, -0.0083, 1.1187\n);\n\nvec3 tonemapAgX(vec3 color)\n{\n  const float AgxMinEv = -12.47393;\n  const float AgxMaxEv = 4.026069;\n\n  color = LINEAR_SRGB_TO_LINEAR_REC2020 * color;\n  color = AgXInsetMatrix * color;\n\n  color = max(color, 1e-10);\n  color = clamp(log2(color), AgxMinEv, AgxMaxEv);\n  color = (color - AgxMinEv) / (AgxMaxEv - AgxMinEv);\n  color = clamp(color, 0.0, 1.0);\n\n  // 6th-order polynomial approximation of the AgX sigmoid\n  vec3 x2 = color * color;\n  vec3 x4 = x2 * x2;\n  color = + 15.5   * x4 * x2\n          - 40.14  * x4 * color\n          + 31.96  * x4\n          - 6.868  * x2 * color\n          + 0.4298 * x2\n          + 0.1191 * color\n          - 0.00232;\n\n  color = AgXOutsetMatrix * color;\n\n  // Linearize (AgX output is in sRGB-like gamma space)\n  color = pow(max(vec3(0.0), color), vec3(2.2));\n\n  color = LINEAR_REC2020_TO_LINEAR_SRGB * color;\n  return clamp(color, 0.0, 1.0);\n}\n\nvoid main()\n{\n  vec4 texColor = IMG_THIS_PIXEL(inputImage);\n  vec3 color = texColor.rgb;\n\n  // Apply exposure\n  color *= exposure;\n\n  // Apply selected tone mapping algorithm\n  if(algorithm == 0)\n  {\n    color = tonemapReinhard(color, whitePoint);\n  }\n  else if(algorithm == 1)\n  {\n    color = tonemapACES(color);\n  }\n  else if(algorithm == 2)\n  {\n    // Exposure already applied above; use 1.0 to avoid double-application\n    color = tonemapExposure(color, 1.0);\n  }\n  else if(algorithm == 3)\n  {\n    color = tonemapUncharted2(color);\n  }\n  else if(algorithm == 4)\n  {\n    color = tonemapAgX(color);\n  }\n\n  // Gamma correction\n  color = pow(max(color, vec3(0.0)), vec3(1.0 / gamma));\n\n  isf_FragColor = vec4(color, texColor.a);\n}\n","Root":"<LIBRARY>:packages/score-csf-testers/shaderlib/post-process/ToneMapping.fs","Inlets":[{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":0,"Hidden":false,"Custom":"inputImage","Exposed":"inputimage","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":1,"Hidden":true,"Custom":"algorithm","Exposed":"algorithm","Value":{"Int":1},"Init":{"Int":1},"Domain":{"Int":{"Values":[0,1,2,3,4]}},"Values":[["Reinhard",{"Int":0}],["ACES Filmic",{"Int":1}],["Exposure",{"Int":2}],["Uncharted 2",{"Int":3}],["AgX",{"Int":4}]],"FolderPort":"","FileExtensions":""},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":2,"Hidden":true,"Custom":"exposure","Exposed":"exposure","Value":{"Float":1.0},"Init":{"Float":1.0},"Domain":{"Float":{"Min":0.10000000149011612,"Max":10.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":3,"Hidden":true,"Custom":"gamma","Exposed":"gamma","Value":{"Float":2.200000047683716},"Init":{"Float":2.200000047683716},"Domain":{"Float":{"Min":0.5,"Max":3.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":4,"Hidden":true,"Custom":"whitePoint","Exposed":"whitepoint","Value":{"Float":4.0},"Init":{"Float":4.0},"Domain":{"Float":{"Min":0.5,"Max":20.0}}}],"Outlets":[{"uuid":"f1c71046-b754-49a5-8e66-d01374773dfc","ObjectName":"Outlet","id":1,"Hidden":false,"Custom":"Texture Out","Exposed":"texture out"}]},{"uuid":"2f6a8c41-7d93-4e5b-b1c8-4e3f9a7d2c5b","ObjectName":"asset_loader","id":11,"Metadata":{"ScriptingName":"Asset Loader.11","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[293.0843370757507,1508.449030585375],"Size":[232.0,173.0],"Loops":false,"FoldMode":0,"Inlets":[{"uuid":"40833147-4c42-4b8b-bb80-0b1d15dae129","ObjectName":"Inlet","id":0,"Hidden":true,"Custom":"Asset file","Exposed":"asset file","Value":{"String":"<PROJECT>:Models/DamagedHelmet.glb"},"Init":{"String":""},"Domain":{},"Filters":"3D assets (*.fbx *.gltf *.glb *.obj *.ply *.stl *.off *.splat *.spz *.usd *.usda *.usdc *.usdz)"},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":1,"Hidden":true,"Custom":"Position","Exposed":"position","Value":{"Vec3f":[0.0,0.0,0.0]},"Init":{"Vec3f":[0.0,0.0,0.0]},"Domain":{"Vec3f":{"Min":[-8388608.0,-8388608.0,-8388608.0],"Max":[8388608.0,8388608.0,8388608.0],"Values":[[],[],[]]}}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":2,"Hidden":true,"Custom":"Rotation","Exposed":"rotation","Value":{"Vec3f":[0.0,0.0,0.0]},"Init":{"Vec3f":[0.0,0.0,0.0]},"Domain":{"Vec3f":{"Min":[0.0,0.0,0.0],"Max":[360.0,360.0,360.0],"Values":[[],[],[]]}}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":3,"Hidden":true,"Custom":"Scale","Exposed":"scale","Value":{"Vec3f":[1.0,1.0,1.0]},"Init":{"Vec3f":[1.0,1.0,1.0]},"Domain":{"Vec3f":{"Min":[0.000009999999747378752,0.000009999999747378752,0.000009999999747378752],"Max":[1000.0,1000.0,1000.0],"Values":[[],[],[]]}}},{"uuid":"9ae797ea-d94c-4792-acec-9ec1932bae5d","ObjectName":"Inlet","id":4,"Hidden":true,"Custom":"Format override (auto if empty)","Exposed":"format override (auto if empty)","Value":{"String":""},"Init":{"String":""},"Domain":{}}],"Outlets":[{"uuid":"848061c5-e8a0-4a13-9985-e8df30ce6d4f","ObjectName":"Outlet","id":0,"Hidden":false,"Custom":"Scene","Exposed":"scene"}]},{"uuid":"a5bbffe0-93d2-4e70-995c-cf46c2c43520","ObjectName":"CSF","id":12,"Metadata":{"ScriptingName":"Compute Shader.12","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[307.29640464956253,1721.6969937269323],"Size":[213.0,167.0],"Loops":false,"FoldMode":0,"Compute":"/*{\n  \"DESCRIPTION\": \"Regular 2D/3D grid of countX x countY x countZ points, spacing apart, centred on center. Set countZ to 1 for a flat grid in the XY plane. Colour and texcoord are the normalised grid coordinates (x, y, z) in 0..1.\",\n  \"CREDIT\": \"ossia score\",\n  \"ISFVSN\": \"2.0\",\n  \"MODE\": \"COMPUTE_SHADER\",\n  \"CATEGORIES\": [\"Geometry Generator\"],\n  \"RESOURCES\": [\n    {\n      \"NAME\": \"geo\",\n      \"TYPE\": \"geometry\",\n      \"VERTEX_COUNT\": \"$countX * $countY * $countZ\",\n      \"ATTRIBUTES\": [\n        { \"NAME\": \"position\", \"SEMANTIC\": \"position\", \"TYPE\": \"vec4\", \"ACCESS\": \"write_only\", \"RATE\": \"vertex\" },\n        { \"NAME\": \"color\",    \"SEMANTIC\": \"color\",    \"TYPE\": \"vec4\", \"ACCESS\": \"write_only\", \"RATE\": \"vertex\" },\n        { \"NAME\": \"texcoord\", \"SEMANTIC\": \"texcoord\", \"TYPE\": \"vec4\", \"ACCESS\": \"write_only\", \"RATE\": \"vertex\" }\n      ]\n    },\n    { \"NAME\": \"countX\",  \"TYPE\": \"long\",    \"DEFAULT\": 32,  \"MIN\": 1,     \"MAX\": 512 },\n    { \"NAME\": \"countY\",  \"TYPE\": \"long\",    \"DEFAULT\": 32,  \"MIN\": 1,     \"MAX\": 512 },\n    { \"NAME\": \"countZ\",  \"TYPE\": \"long\",    \"DEFAULT\": 1,   \"MIN\": 1,     \"MAX\": 512 },\n    { \"NAME\": \"spacing\", \"TYPE\": \"float\",   \"DEFAULT\": 0.1, \"MIN\": 0.001, \"MAX\": 10.0 },\n    { \"NAME\": \"center\",  \"TYPE\": \"point3D\", \"DEFAULT\": [0, 0, 0], \"MIN\": [-10, -10, -10], \"MAX\": [10, 10, 10] }\n  ],\n  \"PASSES\": [\n    { \"LOCAL_SIZE\": [64, 1, 1], \"EXECUTION_MODEL\": { \"TYPE\": \"PER_VERTEX\" } }\n  ]\n}*/\n\nvoid main()\n{\n    uint idx = gl_GlobalInvocationID.x;\n    uint count = uint(ISF_WRITE(geo, position).length());\n    if(idx >= count)\n        return;\n\n    uint cX = uint(countX);\n    uint cY = uint(countY);\n    uint cZ = uint(countZ);\n\n    // Decompose linear index into 3D grid coordinates\n    uint z = idx / (cX * cY);\n    uint remainder = idx % (cX * cY);\n    uint y = remainder / cX;\n    uint x = remainder % cX;\n\n    // Center the grid around the origin, then offset by user center\n    vec3 offset = vec3(\n        float(cX - 1u),\n        float(cY - 1u),\n        float(cZ - 1u)\n    ) * spacing * 0.5;\n\n    vec3 pos = vec3(float(x), float(y), float(z)) * spacing - offset + center;\n\n    // Normalized grid coordinates [0, 1]\n    float nx = (cX > 1u) ? float(x) / float(cX - 1u) : 0.5;\n    float ny = (cY > 1u) ? float(y) / float(cY - 1u) : 0.5;\n    float nz = (cZ > 1u) ? float(z) / float(cZ - 1u) : 0.5;\n\n    ISF_WRITE(geo, position)[idx] = vec4(pos, 1.0);\n    ISF_WRITE(geo, texcoord)[idx] = vec4(nx, ny, nz, 1.0);\n\n    // Color gradient from grid position\n    ISF_WRITE(geo, color)[idx] = vec4(nx, ny, nz, 1.0);\n}\n","Root":"<LIBRARY>:packages/score-csf-testers/shaderlib/generators/GridPoints.cs","Inlets":[{"uuid":"238399a0-7e81-47e3-896f-08e8856e2973","ObjectName":"Inlet","id":0,"Hidden":true,"Custom":"countX","Exposed":"countx","Value":{"Int":8},"Init":{"Int":32},"Domain":{"Int":{"Min":1,"Max":512}}},{"uuid":"238399a0-7e81-47e3-896f-08e8856e2973","ObjectName":"Inlet","id":1,"Hidden":true,"Custom":"countY","Exposed":"county","Value":{"Int":1},"Init":{"Int":32},"Domain":{"Int":{"Min":1,"Max":512}}},{"uuid":"238399a0-7e81-47e3-896f-08e8856e2973","ObjectName":"Inlet","id":2,"Hidden":true,"Custom":"countZ","Exposed":"countz","Value":{"Int":8},"Init":{"Int":1},"Domain":{"Int":{"Min":1,"Max":512}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":3,"Hidden":true,"Custom":"spacing","Exposed":"spacing","Value":{"Float":2.0},"Init":{"Float":0.10000000149011612},"Domain":{"Float":{"Min":0.0010000000474974513,"Max":10.0}}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":4,"Hidden":true,"Custom":"center","Exposed":"center","Value":{"Vec3f":[0.0,0.0,0.0]},"Init":{"Vec3f":[0.0,0.0,0.0]},"Domain":{"Vec3f":{"Min":[-10.0,-10.0,-10.0],"Max":[10.0,10.0,10.0],"Values":[[],[],[]]}}}],"Outlets":[{"uuid":"848061c5-e8a0-4a13-9985-e8df30ce6d4f","ObjectName":"Outlet","id":0,"Hidden":false,"Custom":"geo_out","Exposed":"geo_out"}]},{"uuid":"5e8a2c7f-9b4d-4e3a-a1c6-2d7f0b3e8c4a","ObjectName":"instancer","id":13,"Metadata":{"ScriptingName":"Instancer.13","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[581.0099481332836,1520.06598661945],"Size":[418.0,175.0],"Loops":false,"FoldMode":0,"Inlets":[{"uuid":"f2ab26ea-415d-45a2-bfbc-2968c7c92a33","ObjectName":"Inlet","id":0,"Hidden":false,"Custom":"Scene In","Exposed":"scene in"},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":1,"Hidden":false,"Custom":"Transforms","Exposed":"transforms","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":2,"Hidden":false,"Custom":"Colors","Exposed":"colors","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":3,"Hidden":false,"Custom":"Custom","Exposed":"custom","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"f2ab26ea-415d-45a2-bfbc-2968c7c92a33","ObjectName":"Inlet","id":4,"Hidden":false,"Custom":"Points","Exposed":"points"},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":5,"Hidden":true,"Custom":"Format","Exposed":"format","Value":{"Int":0},"Init":{"Int":0},"Domain":{"Int":{"Values":[0,1,2]}},"Values":[["mat4",{"Int":0}],["trs",{"Int":1}],["translation",{"Int":2}]],"FolderPort":"","FileExtensions":""},{"uuid":"238399a0-7e81-47e3-896f-08e8856e2973","ObjectName":"Inlet","id":6,"Hidden":true,"Custom":"Count","Exposed":"count","Value":{"Int":1},"Init":{"Int":1},"Domain":{"Int":{"Min":1,"Max":1000000}}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":7,"Hidden":true,"Custom":"Position","Exposed":"position","Value":{"Vec3f":[0.0,0.0,0.0]},"Init":{"Vec3f":[0.0,0.0,0.0]},"Domain":{"Vec3f":{"Min":[-8388608.0,-8388608.0,-8388608.0],"Max":[8388608.0,8388608.0,8388608.0],"Values":[[],[],[]]}}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":8,"Hidden":true,"Custom":"Rotation","Exposed":"rotation","Value":{"Vec3f":[35.0,0.0,0.0]},"Init":{"Vec3f":[0.0,0.0,0.0]},"Domain":{"Vec3f":{"Min":[0.0,0.0,0.0],"Max":[360.0,360.0,360.0],"Values":[[],[],[]]}}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":9,"Hidden":true,"Custom":"Scale","Exposed":"scale","Value":{"Vec3f":[0.20000000298023224,0.20000000298023224,0.20000000298023224]},"Init":{"Vec3f":[1.0,1.0,1.0]},"Domain":{"Vec3f":{"Min":[0.000009999999747378752,0.000009999999747378752,0.000009999999747378752],"Max":[1000.0,1000.0,1000.0],"Values":[[],[],[]]}}},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":10,"Hidden":true,"Custom":"Per-instance transform","Exposed":"per-instance transform","Value":{"Int":0},"Init":{"Int":0},"Domain":{"Int":{"Values":[0,1]}},"Values":[["Full matrix",{"Int":0}],["Translation only",{"Int":1}]],"FolderPort":"","FileExtensions":""}],"Outlets":[{"uuid":"848061c5-e8a0-4a13-9985-e8df30ce6d4f","ObjectName":"Outlet","id":0,"Hidden":false,"Custom":"Scene Out","Exposed":"scene out"}]},{"uuid":"a8f2c6d0-1b4e-4c7a-9d3f-5e8b2c1a7f0d","ObjectName":"gfxProcess","id":14,"Metadata":{"ScriptingName":"Scene Preprocessor.14","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[1049.328076943042,1538.7569305776406],"Size":[186.0,22.0],"Loops":false,"FoldMode":0,"Inlets":[{"uuid":"f2ab26ea-415d-45a2-bfbc-2968c7c92a33","ObjectName":"Inlet","id":0,"Hidden":false,"Custom":"Scene In","Exposed":"scene in"}],"Outlets":[{"uuid":"848061c5-e8a0-4a13-9985-e8df30ce6d4f","ObjectName":"Outlet","id":0,"Hidden":false,"Custom":"Geometry Out","Exposed":"geometry out"}]},{"uuid":"4c91b5e2-8d76-4ab3-9f14-6e0d8b3a2c57","ObjectName":"camera_avnd","id":15,"Metadata":{"ScriptingName":"Camera.15","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[715.3134420269184,1749.581749832431],"Size":[274.0,177.0],"Loops":false,"FoldMode":0,"Inlets":[{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":0,"Hidden":true,"Custom":"Eye","Exposed":"eye","Value":{"Vec3f":[0.0,2.5999999046325684,3.5999999046325684]},"Init":{"Vec3f":[0.0,0.0,0.0]},"Domain":{"Vec3f":{"Min":[-10000.0,-10000.0,-10000.0],"Max":[10000.0,10000.0,10000.0],"Values":[[],[],[]]}}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":1,"Hidden":true,"Custom":"Target","Exposed":"target","Value":{"Vec3f":[0.0,0.0,0.0]},"Init":{"Vec3f":[0.0,0.0,0.0]},"Domain":{"Vec3f":{"Min":[-10000.0,-10000.0,-10000.0],"Max":[10000.0,10000.0,10000.0],"Values":[[],[],[]]}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":2,"Hidden":true,"Custom":"FOV","Exposed":"fov","Value":{"Float":45.0},"Init":{"Float":60.0},"Domain":{"Float":{"Min":5.0,"Max":170.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":3,"Hidden":true,"Custom":"Near","Exposed":"near","Value":{"Float":0.10000000149011612},"Init":{"Float":0.10000000149011612},"Domain":{"Float":{"Min":0.0010000000474974513,"Max":10.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":4,"Hidden":true,"Custom":"Far","Exposed":"far","Value":{"Float":1000.0},"Init":{"Float":1000.0},"Domain":{"Float":{"Min":1.0,"Max":100000.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":5,"Hidden":true,"Custom":"Roll","Exposed":"roll","Value":{"Float":0.0},"Init":{"Float":0.0},"Domain":{"Float":{"Min":-180.0,"Max":180.0}}}],"Outlets":[{"uuid":"848061c5-e8a0-4a13-9985-e8df30ce6d4f","ObjectName":"Outlet","id":0,"Hidden":false,"Custom":"Scene","Exposed":"scene"}]},{"uuid":"9f3c1a5e-4b7d-4e2a-8c5f-1d6e0b9a3c7f","ObjectName":"light","id":16,"Metadata":{"ScriptingName":"Light.16","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[566.3864162654688,1976.946721196216],"Size":[422.0,252.0],"Loops":false,"FoldMode":0,"Inlets":[{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":0,"Hidden":true,"Custom":"Mode","Exposed":"mode","Value":{"Int":0},"Init":{"Int":0},"Domain":{"Int":{"Values":[0,1,2,3,4,5,6]}},"Values":[["Directional",{"Int":0}],["Point",{"Int":1}],["Spot",{"Int":2}],["Rect",{"Int":3}],["Disk",{"Int":4}],["Sphere",{"Int":5}],["Dome",{"Int":6}]],"FolderPort":"","FileExtensions":""},{"uuid":"8f38638e-9f9f-48b0-ae36-1cba86ef5703","ObjectName":"Inlet","id":1,"Hidden":true,"Custom":"Color","Exposed":"color","Value":{"Vec4f":[1.0,1.0,1.0,1.0]},"Init":{"Vec4f":[1.0,1.0,1.0,1.0]},"Domain":{}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":2,"Hidden":true,"Custom":"Intensity","Exposed":"intensity","Value":{"Float":4.0},"Init":{"Float":1.0},"Domain":{"Float":{"Min":0.0,"Max":100.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":3,"Hidden":true,"Custom":"Range","Exposed":"range","Value":{"Float":0.0},"Init":{"Float":0.0},"Domain":{"Float":{"Min":0.0,"Max":1000.0}}},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":4,"Hidden":true,"Custom":"Falloff","Exposed":"falloff","Value":{"Int":2},"Init":{"Int":2},"Domain":{"Int":{"Values":[0,1,2,3]}},"Values":[["None",{"Int":0}],["Linear",{"Int":1}],["Quadratic (physical)",{"Int":2}],["Cubic",{"Int":3}]],"FolderPort":"","FileExtensions":""},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":5,"Hidden":true,"Custom":"Inner cone °","Exposed":"inner cone _","Value":{"Float":0.0},"Init":{"Float":0.0},"Domain":{"Float":{"Min":0.0,"Max":90.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":6,"Hidden":true,"Custom":"Outer cone °","Exposed":"outer cone _","Value":{"Float":45.0},"Init":{"Float":45.0},"Domain":{"Float":{"Min":0.0,"Max":90.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":7,"Hidden":true,"Custom":"Width","Exposed":"width","Value":{"Float":1.0},"Init":{"Float":1.0},"Domain":{"Float":{"Min":0.009999999776482582,"Max":100.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":8,"Hidden":true,"Custom":"Height","Exposed":"height","Value":{"Float":1.0},"Init":{"Float":1.0},"Domain":{"Float":{"Min":0.009999999776482582,"Max":100.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":9,"Hidden":true,"Custom":"Radius","Exposed":"radius","Value":{"Float":0.5},"Init":{"Float":0.5},"Domain":{"Float":{"Min":0.009999999776482582,"Max":100.0}}},{"uuid":"fb27e4cb-ea7f-41e2-ad92-2354498c1b6b","ObjectName":"Inlet","id":10,"Hidden":true,"Custom":"Cast shadow","Exposed":"cast shadow","Value":{"Bool":false},"Init":{"Bool":false},"Domain":{"Bool":null}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":11,"Hidden":true,"Custom":"Shadow bias","Exposed":"shadow bias","Value":{"Float":0.0010000000474974513},"Init":{"Float":0.0010000000474974513},"Domain":{"Float":{"Min":0.0,"Max":0.10000000149011612}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":12,"Hidden":true,"Custom":"Shadow normal bias","Exposed":"shadow normal bias","Value":{"Float":0.009999999776482582},"Init":{"Float":0.009999999776482582},"Domain":{"Float":{"Min":0.0,"Max":0.10000000149011612}}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":13,"Hidden":true,"Custom":"Position","Exposed":"position","Value":{"Vec3f":[0.0,0.0,0.0]},"Init":{"Vec3f":[0.0,0.0,0.0]},"Domain":{"Vec3f":{"Min":[-8388608.0,-8388608.0,-8388608.0],"Max":[8388608.0,8388608.0,8388608.0],"Values":[[],[],[]]}}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":14,"Hidden":true,"Custom":"Rotation","Exposed":"rotation","Value":{"Vec3f":[-50.0,35.0,0.0]},"Init":{"Vec3f":[0.0,0.0,0.0]},"Domain":{"Vec3f":{"Min":[0.0,0.0,0.0],"Max":[360.0,360.0,360.0],"Values":[[],[],[]]}}}],"Outlets":[{"uuid":"848061c5-e8a0-4a13-9985-e8df30ce6d4f","ObjectName":"Outlet","id":0,"Hidden":false,"Custom":"Scene","Exposed":"scene"}]},{"uuid":"d3f5a8c1-8b47-4e91-9c2d-6f1a9b5e3c82","ObjectName":"environment_loader","id":17,"Metadata":{"ScriptingName":"Environment.17","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[623.8973611491136,2264.413886545282],"Size":[352.0,176.0],"Loops":false,"FoldMode":0,"Inlets":[{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":0,"Hidden":true,"Custom":"Ambient Color","Exposed":"ambient color","Value":{"Vec3f":[1.0,1.0,1.0]},"Init":{"Vec3f":[0.029999999329447746,0.029999999329447746,0.029999999329447746]},"Domain":{"Vec3f":{"Min":[0.0,0.0,0.0],"Max":[1.0,1.0,1.0],"Values":[[],[],[]]}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":1,"Hidden":true,"Custom":"Ambient Intensity","Exposed":"ambient intensity","Value":{"Float":0.800000011920929},"Init":{"Float":1.0},"Domain":{"Float":{"Min":0.0,"Max":8.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":2,"Hidden":true,"Custom":"Exposure EV100","Exposed":"exposure ev100","Value":{"Float":0.0},"Init":{"Float":0.0},"Domain":{"Float":{"Min":-6.0,"Max":18.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":3,"Hidden":true,"Custom":"Exposure (stops)","Exposed":"exposure (stops)","Value":{"Float":0.0},"Init":{"Float":0.0},"Domain":{"Float":{"Min":-8.0,"Max":8.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":4,"Hidden":true,"Custom":"Gamma","Exposed":"gamma","Value":{"Float":2.200000047683716},"Init":{"Float":2.200000047683716},"Domain":{"Float":{"Min":1.0,"Max":3.0}}},{"uuid":"fb27e4cb-ea7f-41e2-ad92-2354498c1b6b","ObjectName":"Inlet","id":5,"Hidden":true,"Custom":"Fog","Exposed":"fog","Value":{"Bool":false},"Init":{"Bool":false},"Domain":{"Bool":null}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":6,"Hidden":true,"Custom":"Fog Color","Exposed":"fog color","Value":{"Vec3f":[0.800000011920929,0.800000011920929,0.800000011920929]},"Init":{"Vec3f":[0.800000011920929,0.800000011920929,0.800000011920929]},"Domain":{"Vec3f":{"Min":[0.0,0.0,0.0],"Max":[1.0,1.0,1.0],"Values":[[],[],[]]}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":7,"Hidden":true,"Custom":"Fog Start","Exposed":"fog start","Value":{"Float":10.0},"Init":{"Float":10.0},"Domain":{"Float":{"Min":0.0,"Max":1000.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":8,"Hidden":true,"Custom":"Fog End","Exposed":"fog end","Value":{"Float":100.0},"Init":{"Float":100.0},"Domain":{"Float":{"Min":0.0,"Max":10000.0}}},{"uuid":"0adbbdda-fda4-451e-91cc-1da731bde9d5","ObjectName":"Inlet","id":9,"Hidden":true,"Custom":"Render target size","Exposed":"render target size","Value":{"Vec2f":[0.0,0.0]},"Init":{"Vec2f":[0.0,0.0]},"Domain":{"Vec2f":{"Min":[0.0,0.0],"Max":[16384.0,16384.0],"Values":[[],[]]}},"Integral":true}],"Outlets":[{"uuid":"848061c5-e8a0-4a13-9985-e8df30ce6d4f","ObjectName":"Outlet","id":0,"Hidden":false,"Custom":"Scene","Exposed":"scene"}]},{"uuid":"dbfc2101-40d7-4807-8804-571e88992e7e","ObjectName":"gfxProcess","id":18,"Metadata":{"ScriptingName":"Render Pipeline.18","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[1259.6368184456528,1535.7331157567887],"Size":[787.0,160.0],"Loops":false,"FoldMode":0,"Vertex":"// Full-PBR variant — extends classic_pbr_textured with TANGENT for TBN\n// normal-map reconstruction in the fragment stage.\n//\n// Vertex inputs + varyings come from the sibling .frag's VERTEX_INPUTS /\n// VERTEX_OUTPUTS blocks; redeclaring them here triggers \"redefinition\".\n\nvoid main()\n{\n    isf_vertShaderInit();\n\n    // Unified-MDI cmd-index lookup: per-instance VERTEX_INPUT carries\n    // the drawID directly. Replaces the prior `gl_BaseInstanceARB`\n    // path, which broke as soon as instanceCount > 1 (firstInstance\n    // becomes the per-instance slot offset, no longer the cmd index)\n    // AND was always 0 on the CPU-fallback drawIndexed loop. Reading\n    // a per-instance attribute works uniformly on both indirect and\n    // CPU-fallback paths (firstInstance is honoured by every QRhi\n    // backend that supports instancing).\n    uint drawId = draw_id;\n    v_drawID = drawId;\n\n    PerDraw pd = per_draws.data[drawId];\n    mat3 instLinear = pd.normal[3].x > 0.5\n        ? mat3(inst_matrix0.xyz, inst_matrix1.xyz, inst_matrix2.xyz)\n        : mat3(1.0);\n    mat4 model = pd.model;\n    mat3 normalMatrix = mat3(pd.normal) * transpose(inverse(instLinear));\n\n    // Per-instance translation offset: zero for non-instanced draws via\n    // the REQUIRED:false fallback (identity broadcast); the actual\n    // particle position for unified-MDI instance groups.\n    vec4 wp = model * vec4(instLinear * position + inst_translation, 1.0);\n    v_worldPos = wp.xyz;\n    v_normal = normalize(normalMatrix * normal);\n    // Tangent carries xyz = unit tangent in mesh space + w = handedness.\n    // Apply the normal matrix to the xyz (same basis as the normal) and\n    // forward w untouched. Consumer reconstructs bitangent as\n    //   bitangent = cross(N, T.xyz) * T.w\n    v_tangent = vec4(normalize(normalMatrix * tangent.xyz), tangent.w);\n    v_uv = texcoord_0;\n    // glTF TEXCOORD_1 (secondary UV set — lightmaps, per-channel UV\n    // override). Falls back to zero for meshes without it (slab\n    // uploader fills with zeros).\n    v_uv1 = texcoord_1;\n    // glTF COLOR_0 (defaults to vec4(1) when the mesh doesn't carry\n    // one — the slab uploader fills the buffer with white).\n    v_color = color_0;\n    // VERTEX_INPUTS aren't directly visible to the fragment stage —\n    // forward the per-instance broadcast colour as a varying so the\n    // .frag can multiply baseColor by it.\n    v_inst_color = pd.normal[3].y > 0.5 ? inst_color0 : vec4(1.0);\n    v_inst_emissive = pd.normal[3].z > 0.5 ? inst_custom0 : vec4(0.0);\n\n    gl_Position = clipSpaceCorrMatrix * camera.viewProjection * wp;\n\n    isf_vertShaderFinish();\n}\n","Fragment":"/*{\n  \"CREDIT\": \"ossia team\",\n  \"ISFVSN\": \"2\",\n  \"MODE\": \"RAW_RASTER_PIPELINE\",\n  \"ALPHA\": \"straight\",\n  \"DESCRIPTION\": \"Full glTF metallic-roughness rasterizer for a Scene Preprocessor output: draws the whole scene in one indirect draw with every material texture (base colour, metal-rough, normal map with tangents, emissive, occlusion; texcoord sets, KHR_texture_transform, wrap modes, alpha MASK and BLEND, double-sided), the scene's lights (directional, point and spot, with range and falloff; procedural lights written by the presets/lighting CSFs included), the Environment node's ambient, exposure and linear fog, and per-instance transforms, colours and emissive from an Instancer. No image-based lighting and no shadows: a fixed Fresnel term stands in for reflections (classic_pbr_openpbr adds IBL and cascaded shadows). Output is linear HDR, so follow it with a tone mapper such as shaderlib/post-process/ToneMapping.fs. Alpha-to-coverage smooths MASK edges under MSAA; the volumetric toggle composites the presets/volumetric fog chain.\",\n  \"CATEGORIES\": [\n    \"3D\",\n    \"Scene\",\n    \"MDI\",\n    \"Textured\",\n    \"Normal-Mapped\"\n  ],\n  \"VERTEX_INPUTS\": [\n    {\n      \"TYPE\": \"vec3\",\n      \"NAME\": \"position\"\n    },\n    {\n      \"TYPE\": \"vec3\",\n      \"NAME\": \"normal\"\n    },\n    {\n      \"TYPE\": \"vec2\",\n      \"NAME\": \"texcoord_0\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"tangent\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"color_0\"\n    },\n    {\n      \"TYPE\": \"vec2\",\n      \"NAME\": \"texcoord_1\"\n    },\n    {\n      \"TYPE\": \"vec3\",\n      \"NAME\": \"inst_translation\",\n      \"SEMANTIC\": \"translation\",\n      \"REQUIRED\": false\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"inst_color0\",\n      \"SEMANTIC\": \"instance_color0\",\n      \"REQUIRED\": false\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"inst_custom0\",\n      \"SEMANTIC\": \"instance_custom0\",\n      \"REQUIRED\": false\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"inst_matrix0\",\n      \"REQUIRED\": false\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"inst_matrix1\",\n      \"REQUIRED\": false\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"inst_matrix2\",\n      \"REQUIRED\": false\n    },\n    {\n      \"TYPE\": \"uint\",\n      \"NAME\": \"draw_id\",\n      \"SEMANTIC\": \"instance_draw_id\"\n    }\n  ],\n  \"VERTEX_OUTPUTS\": [\n    {\n      \"TYPE\": \"vec3\",\n      \"NAME\": \"v_worldPos\"\n    },\n    {\n      \"TYPE\": \"vec3\",\n      \"NAME\": \"v_normal\"\n    },\n    {\n      \"TYPE\": \"vec2\",\n      \"NAME\": \"v_uv\"\n    },\n    {\n      \"TYPE\": \"uint\",\n      \"NAME\": \"v_drawID\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"v_tangent\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"v_color\"\n    },\n    {\n      \"TYPE\": \"vec2\",\n      \"NAME\": \"v_uv1\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"v_inst_color\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"v_inst_emissive\"\n    }\n  ],\n  \"FRAGMENT_INPUTS\": [\n    {\n      \"TYPE\": \"vec3\",\n      \"NAME\": \"v_worldPos\"\n    },\n    {\n      \"TYPE\": \"vec3\",\n      \"NAME\": \"v_normal\"\n    },\n    {\n      \"TYPE\": \"vec2\",\n      \"NAME\": \"v_uv\"\n    },\n    {\n      \"TYPE\": \"uint\",\n      \"NAME\": \"v_drawID\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"v_tangent\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"v_color\"\n    },\n    {\n      \"TYPE\": \"vec2\",\n      \"NAME\": \"v_uv1\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"v_inst_color\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"v_inst_emissive\"\n    }\n  ],\n  \"FRAGMENT_OUTPUTS\": [\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"isf_FragColor\"\n    }\n  ],\n  \"INPUTS\": [\n    {\n      \"NAME\": \"camera\",\n      \"TYPE\": \"uniform\",\n      \"VISIBILITY\": \"vertex+fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"view\",\n          \"TYPE\": \"mat4\"\n        },\n        {\n          \"NAME\": \"projection\",\n          \"TYPE\": \"mat4\"\n        },\n        {\n          \"NAME\": \"viewProjection\",\n          \"TYPE\": \"mat4\"\n        },\n        {\n          \"NAME\": \"cameraPosition\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"renderSize\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"params\",\n          \"TYPE\": \"vec4\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"scene_lights\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"entries\",\n          \"TYPE\": \"Light[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"scene_light_indices\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"data\",\n          \"TYPE\": \"uint[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"world_transforms\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"vertex+fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"data\",\n          \"TYPE\": \"mat4[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"scene_materials\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"entries\",\n          \"TYPE\": \"Material[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"scene_material_uv_xforms\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"entries\",\n          \"TYPE\": \"MatUVXform[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"per_draws\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"vertex+fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"data\",\n          \"TYPE\": \"PerDraw[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"indirect_draw_cmds\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"none\",\n      \"BUFFER_USAGE\": \"indirect_draw_indexed\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"cmds\",\n          \"TYPE\": \"DrawIndexedCmd[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"scene_counts\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"light_count\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"material_count\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"draw_count\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"_pad0\",\n          \"TYPE\": \"uint\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"env\",\n      \"TYPE\": \"uniform\",\n      \"VISIBILITY\": \"fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"ambient\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"fog_color_density\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"fog_range\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"exposure_gamma\",\n          \"TYPE\": \"vec4\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"alpha_a2c_enabled\",\n      \"TYPE\": \"long\",\n      \"DEFAULT\": 0,\n      \"MIN\": 0,\n      \"MAX\": 1,\n      \"LABEL\": \"Alpha-to-coverage (writes gl_SampleMask under MSAA). Best for foliage edges when MSAA is enabled. Adapts to the framebuffer sample count (1/2/4/8/16); degrades to a 0.5 binary cutoff when MSAA is off.\"\n    },\n    {\n      \"NAME\": \"volumetric_enabled\",\n      \"TYPE\": \"long\",\n      \"DEFAULT\": 0,\n      \"MIN\": 0,\n      \"MAX\": 1,\n      \"LABEL\": \"Volumetric fog composite (1=on)\",\n      \"DESCRIPTION\": \"Sample the upstream vol_integrated SSBO (built by the volumetric_inject / scatter / integrate chain) and apply finalColor = finalColor * transmittance + accum * intensity per fragment. Default off so rasterizers without the volumetric chain wired don't multiply by an unbound (zero-init) transmittance and go pure black.\"\n    },\n    {\n      \"NAME\": \"volumetric_intensity\",\n      \"TYPE\": \"float\",\n      \"DEFAULT\": 1.0,\n      \"MIN\": 0.0,\n      \"MAX\": 4.0,\n      \"LABEL\": \"Volumetric intensity\",\n      \"DESCRIPTION\": \"Scalar on the in-scattered radiance contribution. 1.0 = physical; <1 dampens the fog look; >1 over-blooms the air for stylized output. Has no effect when volumetric_enabled=0.\"\n    }\n  ],\n  \"AUXILIARY\": [\n    {\n      \"NAME\": \"scene_material_wrap\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"entries\",\n          \"TYPE\": \"uvec4[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"cluster_config\",\n      \"ACCESS\": \"read_only\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"cluster_x\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"cluster_y\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"cluster_z\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"max_lights_per_cluster\",\n          \"TYPE\": \"uint\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"vol_integrated\",\n      \"ACCESS\": \"read_only\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"data\",\n          \"TYPE\": \"FroxelIntegrated[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"materialArray0\",\n      \"TYPE\": \"image\",\n      \"IS_ARRAY\": true,\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialArray1\",\n      \"TYPE\": \"image\",\n      \"IS_ARRAY\": true,\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialArray2\",\n      \"TYPE\": \"image\",\n      \"IS_ARRAY\": true,\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialArray3\",\n      \"TYPE\": \"image\",\n      \"IS_ARRAY\": true,\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialArray4\",\n      \"TYPE\": \"image\",\n      \"IS_ARRAY\": true,\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialArray5\",\n      \"TYPE\": \"image\",\n      \"IS_ARRAY\": true,\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialArray6\",\n      \"TYPE\": \"image\",\n      \"IS_ARRAY\": true,\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialArray7\",\n      \"TYPE\": \"image\",\n      \"IS_ARRAY\": true,\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialDyn0\",\n      \"TYPE\": \"image\",\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialDyn1\",\n      \"TYPE\": \"image\",\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialDyn2\",\n      \"TYPE\": \"image\",\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialDyn3\",\n      \"TYPE\": \"image\",\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialDyn4\",\n      \"TYPE\": \"image\",\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialDyn5\",\n      \"TYPE\": \"image\",\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialDyn6\",\n      \"TYPE\": \"image\",\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialDyn7\",\n      \"TYPE\": \"image\",\n      \"WRAP\": \"repeat\"\n    }\n  ],\n  \"TYPES\": [\n    {\n      \"NAME\": \"Light\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"color\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"local_direction\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"range_cone\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"shadow_enabled\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"decay_mode\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"transform_slot\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"normal_bias\",\n          \"TYPE\": \"float\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"Material\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"baseColor\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"metallicRoughnessOcclusionUnlit\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"emissive_strength\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"textureRefs\",\n          \"TYPE\": \"uvec4\"\n        },\n        {\n          \"NAME\": \"feature_mask\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"hit_group_id\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"occlusion_textureRef\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"alpha_cutoff\",\n          \"TYPE\": \"float\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"PerDraw\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"model\",\n          \"TYPE\": \"mat4\"\n        },\n        {\n          \"NAME\": \"normal\",\n          \"TYPE\": \"mat4\"\n        },\n        {\n          \"NAME\": \"material_index\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"tag_hash\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"_pad0\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"_pad1\",\n          \"TYPE\": \"uint\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"DrawIndexedCmd\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"indexCount\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"instanceCount\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"firstIndex\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"baseVertex\",\n          \"TYPE\": \"int\"\n        },\n        {\n          \"NAME\": \"baseInstance\",\n          \"TYPE\": \"uint\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"MatUVXform\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"bc_offset_scale\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"mr_offset_scale\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"normal_offset_scale\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"em_offset_scale\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"occ_offset_scale\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"rotations0\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"rotations1\",\n          \"TYPE\": \"vec4\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"FroxelIntegrated\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"accum_transmittance\",\n          \"TYPE\": \"vec4\"\n        }\n      ]\n    }\n  ],\n  \"PIPELINE_STATE\": {\n    \"DEPTH_TEST\": true,\n    \"DEPTH_WRITE\": true,\n    \"CULL_MODE\": \"back\"\n  }\n}*/\n\n// Sample a material texture channel given its packed textureRef. Matches\n// the SceneFlattener encoding:\n//   bits 31..30 : source (0=NONE/sentinel, 1=STATIC bucket, 2=DYNAMIC slot)\n//   bits 29..23 : bucket index (0..127); the ladder below covers the\n//                 first 16 — higher bucket ids fall back.\n//   bits 23..0  : layer index within the bucket's texture array (static)\n//                 OR slot index in the channel's dynamic sampler set.\n//\n// Each channel declares `kShaderBuckets` sampler2DArrays,\n// one per bucket. Materials with textures of different (format, pixelSize)\n// tuples land in different buckets; the switch ladder below dispatches\n// to the right sampler. Scenes with a single bucket hit case 0 only —\n// all other cases compile in but never execute.\n//\n// Dynamic slots resolve to per-channel sampler2D uniforms `*Dyn0` /\n// `*Dyn1` populated by ScenePreprocessor's aux-texture path — used for\n// large runtime textures (8K video, HDR shader outputs) that can't\n// round-trip through the bucket pool.\nconst uint kShaderBuckets = 16u;\n\n// ─── Manual N-tap anisotropic sampling ──────────────────────────────\n// Qt RHI hard-codes maxAnisotropy=1.0 in every backend; there is no\n// public API to enable hardware anisotropic filtering. Workaround: do\n// it in the shader. Standard \"sum of cones\" formulation:\n//\n//   1. Compute UV gradients dx/dy. Pick the longer one as the major\n//      axis, the shorter as minor.\n//   2. The footprint is an ellipse on the texture; ratio = |major|/|minor|\n//      gives the anisotropy needed (typical value at grazing angles is\n//      4-16).\n//   3. Take 4 hardware-filtered samples spaced along the major axis,\n//      each forced to the minor-axis LOD via textureGrad(minor, minor).\n//      Average them. The minor-axis grad keeps each sample sharp; the\n//      4 spaced taps integrate over the elongated footprint.\n//\n// Shortcut: when the footprint is roughly isotropic (ratio² < 4) we\n// drop to a plain hardware texture() — the 4-tap path is wasted cost.\n//\n// Cost: ~4× texture lookups when the path triggers (only at grazing\n// angles), 1× otherwise. We apply this only to base_color and normal\n// — the channels where the user can see the difference. metallic /\n// roughness / occlusion / emissive stay on plain texture().\nvec4 anisoSample2DArray(sampler2DArray tex, vec3 uv)\n{\n    vec2 dx = dFdx(uv.xy);\n    vec2 dy = dFdy(uv.xy);\n    float lx2 = dot(dx, dx);\n    float ly2 = dot(dy, dy);\n    vec2 major, minor;\n    float ratio2;\n    if(lx2 > ly2)\n    {\n        major = dx; minor = dy;\n        ratio2 = lx2 / max(ly2, 1e-12);\n    }\n    else\n    {\n        major = dy; minor = dx;\n        ratio2 = ly2 / max(lx2, 1e-12);\n    }\n    if(ratio2 < 4.0) return texture(tex, uv);\n\n    // 4 taps at -3/8, -1/8, 1/8, 3/8 of the major axis (uniform spacing,\n    // mean-zero, covers the elongated footprint without touching the\n    // tile borders that a -1/2..1/2 spacing would).\n    float layer = uv.z;\n    vec4 s0 = textureGrad(tex, vec3(uv.xy + major * -0.375, layer), minor, minor);\n    vec4 s1 = textureGrad(tex, vec3(uv.xy + major * -0.125, layer), minor, minor);\n    vec4 s2 = textureGrad(tex, vec3(uv.xy + major *  0.125, layer), minor, minor);\n    vec4 s3 = textureGrad(tex, vec3(uv.xy + major *  0.375, layer), minor, minor);\n    return (s0 + s1 + s2 + s3) * 0.25;\n}\nvec4 anisoSample2DArraySep(texture2DArray tex, sampler smp, vec3 uv)\n{\n    vec2 dx = dFdx(uv.xy);\n    vec2 dy = dFdy(uv.xy);\n    float lx2 = dot(dx, dx);\n    float ly2 = dot(dy, dy);\n    vec2 major, minor;\n    float ratio2;\n    if(lx2 > ly2)\n    {\n        major = dx; minor = dy;\n        ratio2 = lx2 / max(ly2, 1e-12);\n    }\n    else\n    {\n        major = dy; minor = dx;\n        ratio2 = ly2 / max(lx2, 1e-12);\n    }\n    if(ratio2 < 4.0) return texture(sampler2DArray(tex, smp), uv);\n\n    // 4 taps at -3/8, -1/8, 1/8, 3/8 of the major axis (uniform spacing,\n    // mean-zero, covers the elongated footprint without touching the\n    // tile borders that a -1/2..1/2 spacing would).\n    float layer = uv.z;\n    vec4 s0 = textureGrad(sampler2DArray(tex, smp), vec3(uv.xy + major * -0.375, layer), minor, minor);\n    vec4 s1 = textureGrad(sampler2DArray(tex, smp), vec3(uv.xy + major * -0.125, layer), minor, minor);\n    vec4 s2 = textureGrad(sampler2DArray(tex, smp), vec3(uv.xy + major *  0.125, layer), minor, minor);\n    vec4 s3 = textureGrad(sampler2DArray(tex, smp), vec3(uv.xy + major *  0.375, layer), minor, minor);\n    return (s0 + s1 + s2 + s3) * 0.25;\n}\n\nvec4 anisoSample2D(sampler2D tex, vec2 uv)\n{\n    vec2 dx = dFdx(uv);\n    vec2 dy = dFdy(uv);\n    float lx2 = dot(dx, dx);\n    float ly2 = dot(dy, dy);\n    vec2 major, minor;\n    float ratio2;\n    if(lx2 > ly2)\n    {\n        major = dx; minor = dy;\n        ratio2 = lx2 / max(ly2, 1e-12);\n    }\n    else\n    {\n        major = dy; minor = dx;\n        ratio2 = ly2 / max(lx2, 1e-12);\n    }\n    if(ratio2 < 4.0) return texture(tex, uv);\n\n    vec4 s0 = textureGrad(tex, uv + major * -0.375, minor, minor);\n    vec4 s1 = textureGrad(tex, uv + major * -0.125, minor, minor);\n    vec4 s2 = textureGrad(tex, uv + major *  0.125, minor, minor);\n    vec4 s3 = textureGrad(tex, uv + major *  0.375, minor, minor);\n    return (s0 + s1 + s2 + s3) * 0.25;\n}\nvec4 anisoSample2DSep(texture2D tex, sampler smp, vec2 uv)\n{\n    vec2 dx = dFdx(uv);\n    vec2 dy = dFdy(uv);\n    float lx2 = dot(dx, dx);\n    float ly2 = dot(dy, dy);\n    vec2 major, minor;\n    float ratio2;\n    if(lx2 > ly2)\n    {\n        major = dx; minor = dy;\n        ratio2 = lx2 / max(ly2, 1e-12);\n    }\n    else\n    {\n        major = dy; minor = dx;\n        ratio2 = ly2 / max(lx2, 1e-12);\n    }\n    if(ratio2 < 4.0) return texture(sampler2D(tex, smp), uv);\n\n    vec4 s0 = textureGrad(sampler2D(tex, smp), uv + major * -0.375, minor, minor);\n    vec4 s1 = textureGrad(sampler2D(tex, smp), uv + major * -0.125, minor, minor);\n    vec4 s2 = textureGrad(sampler2D(tex, smp), uv + major *  0.125, minor, minor);\n    vec4 s3 = textureGrad(sampler2D(tex, smp), uv + major *  0.375, minor, minor);\n    return (s0 + s1 + s2 + s3) * 0.25;\n}\n\n// One decoder for every material channel. The pool is shared, so the bucket\n// field of the ref is all that picks the array -- including its colourspace,\n// which is part of the bucket key rather than of the channel.\n// Per-texture wrap modes from scene_material_wrap, loaded once per fragment\n// from the material's entry. Four bits per texture ref: wrap_s in the low two,\n// wrap_t in the high two; 0 = repeat, 1 = clamp to edge, 2 = mirror. Slots\n// 0..4 are the main refs (base colour, metal-rough, normal, emissive,\n// occlusion), 5.. the extension refs in MaterialExt.textureRefs order. The\n// pool samples every array with one repeat sampler, so a non-repeat mode is\n// applied to the coordinate here.\nuvec3 g_matWrap = uvec3(0u);\nuint matWrap(uint slot)\n{\n    if(slot < 5u) return (g_matWrap.x >> (4u * slot)) & 0xFu;\n    uint e = slot - 5u;\n    uint word = e < 8u ? g_matWrap.y : g_matWrap.z;\n    return (word >> (4u * (e & 7u))) & 0xFu;\n}\nfloat wrapAxis(float x, uint mode, float halfTexel)\n{\n    if(mode == 1u) return clamp(x, halfTexel, 1.0 - halfTexel);\n    if(mode == 2u) { float t = mod(x, 2.0); return t > 1.0 ? 2.0 - t : t; }\n    return x;\n}\nvec2 applyWrap(vec2 uv, uint wrap, vec2 halfTexel)\n{\n    return vec2(wrapAxis(uv.x, wrap & 3u, halfTexel.x),\n                wrapAxis(uv.y, (wrap >> 2u) & 3u, halfTexel.y));\n}\n// Clamping stays inside the edge texel of the coarsest mip level the\n// trilinear filter reads, so a minified clamped texture does not bleed across\n// the repeat sampler's seam.\nvec2 wrapInset(texture2DArray tex, sampler smp, vec2 dx, vec2 dy)\n{\n    vec2 sz = vec2(textureSize(sampler2DArray(tex, smp), 0).xy);\n    float lod = max(0.0, log2(max(length(dx * sz), length(dy * sz))));\n    return min(vec2(0.5), 0.5 * exp2(ceil(lod)) / sz);\n}\n// anisoSample2DArray's wrapped counterpart. A single trilinear tap whose\n// gradients come from the unwrapped coordinate, so a mirror fold or a clamp\n// edge does not spike the mip selection; repeat, the common case, keeps the\n// anisotropic path untouched.\nvec4 anisoSample2DArrayWrapped(texture2DArray tex, sampler smp, vec3 uv, uint wrap)\n{\n    if(wrap == 0u) return anisoSample2DArraySep(tex, smp, uv);\n    vec2 dx = dFdx(uv.xy);\n    vec2 dy = dFdy(uv.xy);\n    return textureGrad(sampler2DArray(tex, smp),\n                       vec3(applyWrap(uv.xy, wrap, wrapInset(tex, smp, dx, dy)), uv.z),\n                       dx, dy);\n}\n\n\nvec4 sample_material_slot(uint ref, uint wrap, vec2 uv, vec4 fallback)\n{\n    if(ref == 0xFFFFFFFFu) return fallback;\n    uint source = (ref >> 30) & 3u;\n    uint bucket = (ref >> 23) & 0x7Fu;\n    uint idx    = ref & 0x007FFFFFu;\n    if(source == 2u)\n    {\n        switch(idx)\n        {\n            case 0u: return anisoSample2DSep(materialDyn_tex[0], materialDyn_smp, uv);\n            case 1u: return anisoSample2DSep(materialDyn_tex[1], materialDyn_smp, uv);\n            case 2u: return anisoSample2DSep(materialDyn_tex[2], materialDyn_smp, uv);\n            case 3u: return anisoSample2DSep(materialDyn_tex[3], materialDyn_smp, uv);\n            case 4u: return anisoSample2DSep(materialDyn_tex[4], materialDyn_smp, uv);\n            case 5u: return anisoSample2DSep(materialDyn_tex[5], materialDyn_smp, uv);\n            case 6u: return anisoSample2DSep(materialDyn_tex[6], materialDyn_smp, uv);\n            case 7u: return anisoSample2DSep(materialDyn_tex[7], materialDyn_smp, uv);\n        }\n        return fallback;\n    }\n    switch(bucket)\n    {\n        case 0u: return anisoSample2DArrayWrapped(materialArray_tex[0], materialArray_smp, vec3(uv, float(idx)), wrap);\n        case 1u: return anisoSample2DArrayWrapped(materialArray_tex[1], materialArray_smp, vec3(uv, float(idx)), wrap);\n        case 2u: return anisoSample2DArrayWrapped(materialArray_tex[2], materialArray_smp, vec3(uv, float(idx)), wrap);\n        case 3u: return anisoSample2DArrayWrapped(materialArray_tex[3], materialArray_smp, vec3(uv, float(idx)), wrap);\n        case 4u: return anisoSample2DArrayWrapped(materialArray_tex[4], materialArray_smp, vec3(uv, float(idx)), wrap);\n        case 5u: return anisoSample2DArrayWrapped(materialArray_tex[5], materialArray_smp, vec3(uv, float(idx)), wrap);\n        case 6u: return anisoSample2DArrayWrapped(materialArray_tex[6], materialArray_smp, vec3(uv, float(idx)), wrap);\n        case 7u: return anisoSample2DArrayWrapped(materialArray_tex[7], materialArray_smp, vec3(uv, float(idx)), wrap);\n    }\n    return fallback;\n}\n\nvec4 sample_slot_bc(uint ref, uint wrap, vec2 uv, vec4 fallback)\n{\n    return sample_material_slot(ref, wrap, uv, fallback);\n}\n\n\nvec4 sample_slot_mr(uint ref, uint wrap, vec2 uv, vec4 fallback)\n{\n    return sample_material_slot(ref, wrap, uv, fallback);\n}\n\n\nvec4 sample_slot_nrm(uint ref, uint wrap, vec2 uv, vec4 fallback)\n{\n    return sample_material_slot(ref, wrap, uv, fallback);\n}\n\n\nvec4 sample_slot_em(uint ref, uint wrap, vec2 uv, vec4 fallback)\n{\n    return sample_material_slot(ref, wrap, uv, fallback);\n}\n\n\n// Separate glTF occlusionTexture (single-channel data, R = occlusion).\n// Sampled only when feature_mask carries `has_separate_occlusion`;\n// otherwise the main path falls back to MR.r per the common packed-MR\n// convention. fallback = 1 → identity (no occlusion).\nvec4 sample_slot_occ(uint ref, uint wrap, vec2 uv, vec4 fallback)\n{\n    return sample_material_slot(ref, wrap, uv, fallback);\n}\n\n\n// glTF feature_mask bits — must mirror SceneGPUState.hpp's\n// material_feature namespace.\nconst uint kFeat_alpha_mask           = 1u << 16u;\nconst uint kFeat_alpha_blend          = 1u << 17u;\nconst uint kFeat_double_sided         = 1u << 18u;\nconst uint kFeat_has_separate_occ     = 1u << 19u;\n// Per-channel texcoord_set bits (20-29). 2 bits per channel, value\n// 0 = TEXCOORD_0, value 1 = TEXCOORD_1. Out-of-range values collapse\n// to TEXCOORD_0 (the shift-mask in packMaterial clamps to 0/1).\nconst uint kFeat_tcset_bc_shift       = 20u;\nconst uint kFeat_tcset_mr_shift       = 22u;\nconst uint kFeat_tcset_nrm_shift      = 24u;\nconst uint kFeat_tcset_em_shift       = 26u;\nconst uint kFeat_tcset_occ_shift      = 28u;\n\nvec2 pick_uv(uint feature_mask, uint shift, vec2 uv0, vec2 uv1)\n{\n    return ((feature_mask >> shift) & 0x3u) == 1u ? uv1 : uv0;\n}\n\n// KHR_texture_transform helper: glTF defines the transform in UV space\n// as `uv' = R(rotation) * S(scale) * uv + offset`, with rotation\n// applied AFTER scale and BEFORE the offset shift. Identity defaults\n// (offset=0, scale=1, rotation=0) pass through unchanged.\nvec2 apply_uv_xform(vec2 uv, vec4 offset_scale, float rotation)\n{\n    vec2 scaled = uv * offset_scale.zw;\n    float c = cos(rotation), s = sin(rotation);\n    vec2 rotated = vec2(c * scaled.x - s * scaled.y,\n                        s * scaled.x + c * scaled.y);\n    return rotated + offset_scale.xy;\n}\n\n// Shader-level alpha-to-coverage. QRhi (6.12) doesn't expose\n// AlphaToCoverage on QRhiGraphicsPipeline, so we replicate the\n// behaviour at the shader level: gl_SampleMask[0] is a writable\n// per-fragment built-in where each bit selects whether the\n// corresponding MSAA sample is written. Convert alpha to a sample\n// count, set that many bits, screen-space-rotate per pixel so the\n// MSAA resolve smooths the silhouette into a soft edge.\n//\n// Sample count comes from MSAA_SAMPLES, an integer auto-injected by\n// libisf into the renderer UBO at binding=0 — score writes the active\n// RenderList's sample count there each frame. (We can't use\n// gl_NumSamples: glslang strips it when targeting SPIR-V.) Score lets\n// users pick any of {1, 2, 4, 8, 16}. With MSAA off, MSAA_SAMPLES=1\n// and we degrade to a 0.5 binary cutoff. Vulkan caps multisample\n// rasterization at 16x in practice; clamp there so the rotation math\n// stays defined for 32-bit uints.\n//\n// Returns false when the fragment is fully transparent → caller\n// discards (early-out skips the rest of main()).\nbool applyAlphaToCoverage(float alpha)\n{\n    if(alpha <= 0.0)\n        return false;\n\n    int samples = clamp(MSAA_SAMPLES, 1, 16);\n    uint full = (samples >= 32) ? 0xFFFFFFFFu\n                                : ((1u << uint(samples)) - 1u);\n\n    if(alpha >= 1.0)\n    {\n        gl_SampleMask[0] = int(full);\n        return true;\n    }\n    int n = int(round(alpha * float(samples)));\n    if(n <= 0)\n        return false;\n    if(n >= samples)\n    {\n        gl_SampleMask[0] = int(full);\n        return true;\n    }\n\n    // MSAA sample counts are powers of two, so (S-1) is a valid mask.\n    // shift lands in [0, S-1]; rotation handles shift==0 cleanly\n    // because base >> S is well-defined for S<=16 (< 32 bits).\n    uint S = uint(samples);\n    uint hash = uint(gl_FragCoord.x) * 1597u\n              + uint(gl_FragCoord.y) * 2731u;\n    uint shift = hash & (S - 1u);\n    uint base  = (1u << uint(n)) - 1u;\n    uint rot   = ((base << shift) | (base >> (S - shift))) & full;\n    gl_SampleMask[0] = int(rot);\n    return true;\n}\n\n// Map gl_FragCoord + view-space Z to a froxel index. Same log-spaced Z\n// slicing build_cluster_aabbs.csf uses, same (z*Y + y)*X + x flattening\n// volumetric_integrate.csf writes — keep these three formulas in sync\n// or sampling lands in the wrong cell.\nuint scoreClusterId(vec2 fragCoord, float viewZ)\n{\n    vec2 uv = fragCoord / camera.renderSize.xy;\n    uint gx = cluster_config.cluster_x;\n    uint gy = cluster_config.cluster_y;\n    uint gz = cluster_config.cluster_z;\n\n    uint tx = uint(clamp(floor(uv.x * float(gx)), 0.0, float(gx) - 1.0));\n    uint ty = uint(clamp(floor(uv.y * float(gy)), 0.0, float(gy) - 1.0));\n\n    float zNear = camera.params.y;\n    float zFar  = camera.params.z;\n    float depth = max(-viewZ, zNear);\n    float t = float(gz) * log(depth / zNear) / log(zFar / zNear);\n    uint tz = uint(clamp(t, 0.0, float(gz) - 1.0));\n\n    return (tz * gy + ty) * gx + tx;\n}\n\n// Inline volumetric fog composite — see classic_pbr_openpbr.frag for\n// the full rationale. Two production-grade refinements vs the naive\n// nearest-cell lookup:\n//   1. Trilinear interpolation across the 8 surrounding froxels —\n//      hides the cluster grid (16x9x24 default) which otherwise\n//      shows up as a hard checkerboard at cell boundaries.\n//   2. volumetric_intensity blends toward identity rather than just\n//      scaling accum, so low intensity == \"less fog\" rather than\n//      \"no source + tiny in-scatter\".\n// Identity fallback when the toggle is off or cluster_x == 0u.\nvec3 applyVolumetric(vec3 inColor, vec2 fragCoord, float viewZ)\n{\n    if(volumetric_enabled == 0)\n        return inColor;\n\n    uint gx = cluster_config.cluster_x;\n    uint gy = cluster_config.cluster_y;\n    uint gz = cluster_config.cluster_z;\n    if(gx == 0u || gy == 0u || gz == 0u)\n        return inColor;\n\n    vec2  uv = fragCoord / camera.renderSize.xy;\n    float zNear = camera.params.y;\n    float zFar  = camera.params.z;\n    float depth = max(-viewZ, zNear);\n    float fx = uv.x * float(gx) - 0.5;\n    float fy = uv.y * float(gy) - 0.5;\n    float fz = float(gz) * log(depth / zNear) / log(zFar / zNear) - 0.5;\n\n    vec3 cf = clamp(vec3(fx, fy, fz), vec3(0.0),\n                    vec3(float(gx) - 1.0001,\n                         float(gy) - 1.0001,\n                         float(gz) - 1.0001));\n    vec3 cb = floor(cf);\n    vec3 t  = cf - cb;\n    uvec3 i0 = uvec3(cb);\n    uvec3 i1 = min(i0 + 1u, uvec3(gx - 1u, gy - 1u, gz - 1u));\n\n    #define IDX(ix, iy, iz) (((iz) * gy + (iy)) * gx + (ix))\n    vec4 c000 = vol_integrated.data[IDX(i0.x, i0.y, i0.z)].accum_transmittance;\n    vec4 c100 = vol_integrated.data[IDX(i1.x, i0.y, i0.z)].accum_transmittance;\n    vec4 c010 = vol_integrated.data[IDX(i0.x, i1.y, i0.z)].accum_transmittance;\n    vec4 c110 = vol_integrated.data[IDX(i1.x, i1.y, i0.z)].accum_transmittance;\n    vec4 c001 = vol_integrated.data[IDX(i0.x, i0.y, i1.z)].accum_transmittance;\n    vec4 c101 = vol_integrated.data[IDX(i1.x, i0.y, i1.z)].accum_transmittance;\n    vec4 c011 = vol_integrated.data[IDX(i0.x, i1.y, i1.z)].accum_transmittance;\n    vec4 c111 = vol_integrated.data[IDX(i1.x, i1.y, i1.z)].accum_transmittance;\n    #undef IDX\n\n    vec4 v = mix(mix(mix(c000, c100, t.x), mix(c010, c110, t.x), t.y),\n                 mix(mix(c001, c101, t.x), mix(c011, c111, t.x), t.y),\n                 t.z);\n\n    float transm = clamp(v.a, 0.0, 1.0);\n    vec3  accum  = v.rgb;\n\n    float k       = volumetric_intensity;\n    float k_blend = clamp(k, 0.0, 1.0);\n    float transm_eff = mix(1.0, transm, k_blend);\n    vec3  accum_eff  = accum * k;\n\n    return inColor * transm_eff + accum_eff;\n}\n\nvoid main()\n{\n    // Default coverage: keep every MSAA sample. Once applyAlphaToCoverage\n    // exists in the module, the SPIR-V output declares gl_SampleMask, and\n    // any path that doesn't assign it leaves the value undefined — most\n    // drivers default that to 0 and cull every sample, producing block-\n    // speckle artifacts on non-alpha-mask materials. Seeding to all-ones\n    // here makes the non-A2C paths render correctly; the A2C branch\n    // overrides this for masked fragments.\n    gl_SampleMask[0] = -1;\n\n    PerDraw pd = per_draws.data[v_drawID];\n    Material mat = scene_materials.entries[pd.material_index];\n    MatUVXform mx = scene_material_uv_xforms.entries[pd.material_index];\n    g_matWrap = scene_material_wrap.entries[pd.material_index].xyz;\n\n    // glTF doubleSided: pipeline-side culling is OFF (cull_mode=none\n    // in the MDI batch) so we get both faces. For SINGLE-sided materials\n    // we discard back-facing fragments here to mimic CULL_BACK. For\n    // DOUBLE-sided materials we keep the fragment and flip the normal\n    // below so lighting on the back side works correctly.\n    bool is_double_sided = (mat.feature_mask & kFeat_double_sided) != 0u;\n    if(!is_double_sided && !gl_FrontFacing)\n        discard;\n\n    // Pick the per-channel texcoord source (TEXCOORD_0 vs TEXCOORD_1)\n    // before applying the KHR_texture_transform. glTF allows each\n    // texture_info to override its texcoord_set independently — BC\n    // might use TEXCOORD_0 while Emissive uses TEXCOORD_1, etc.\n    vec2 base_uv_bc  = pick_uv(mat.feature_mask, kFeat_tcset_bc_shift,  v_uv, v_uv1);\n    vec2 base_uv_mr  = pick_uv(mat.feature_mask, kFeat_tcset_mr_shift,  v_uv, v_uv1);\n    vec2 base_uv_nrm = pick_uv(mat.feature_mask, kFeat_tcset_nrm_shift, v_uv, v_uv1);\n    vec2 base_uv_em  = pick_uv(mat.feature_mask, kFeat_tcset_em_shift,  v_uv, v_uv1);\n    vec2 base_uv_occ = pick_uv(mat.feature_mask, kFeat_tcset_occ_shift, v_uv, v_uv1);\n\n    // Per-channel UVs after KHR_texture_transform.\n    vec2 uv_bc  = apply_uv_xform(base_uv_bc,  mx.bc_offset_scale,     mx.rotations0.x);\n    vec2 uv_mr  = apply_uv_xform(base_uv_mr,  mx.mr_offset_scale,     mx.rotations0.y);\n    vec2 uv_nrm = apply_uv_xform(base_uv_nrm, mx.normal_offset_scale, mx.rotations0.z);\n    vec2 uv_em  = apply_uv_xform(base_uv_em,  mx.em_offset_scale,     mx.rotations0.w);\n    vec2 uv_occ = apply_uv_xform(base_uv_occ, mx.occ_offset_scale,    mx.rotations1.x);\n\n    // Pre-pull env knobs so the early-out (unlit) and main path both\n    // see the same values. Defaults come from EnvironmentLoader if the\n    // user wired one; otherwise the merged scene_environment carries\n    // safe identity-ish values (ambient=0, exposure=1, gamma=2.2,\n    // fog disabled).\n    vec3  ambient_col   = env.ambient.rgb * env.ambient.w;\n    float exposure_mul  = max(env.exposure_gamma.x, 1e-6);\n    float gamma         = max(env.exposure_gamma.y, 1e-3);\n\n    // ─── Base color ────────────────────────────────────────────────────\n    // glTF: final base = baseColorFactor × baseColorTexture × COLOR_0\n    // (vertex color). v_color defaults to white when the mesh doesn't\n    // have COLOR_0 (slab uploader fills with vec4(1) in that case).\n    vec4 bc = sample_slot_bc(mat.textureRefs.x, matWrap(0u), uv_bc, vec4(1.0));\n\n    // Alpha-mask edge-bleed compensation. Source PNGs for foliage / hair\n    // / fence-style cutouts have alpha=0 in transparent regions with\n    // RGB=0 there too (standard authoring). Mip / aniso filtering\n    // averages RGB and alpha independently — near a leaf edge the\n    // sampled RGB ends up `leaf_color × alpha_avg`, so post-alpha-test\n    // surviving fragments read a darkened RGB and the silhouette gets a\n    // black halo. Dividing RGB by alpha inverts the alpha-weighted\n    // averaging and recovers the source colour. Skip when alpha is near\n    // zero (would discard anyway) and when the material isn't\n    // alpha-masked (BLEND / OPAQUE both want the literal sampled RGB).\n    if((mat.feature_mask & kFeat_alpha_mask) != 0u && bc.a > 1e-3)\n        bc.rgb /= bc.a;\n\n    // Per-instance broadcast colour rides through `v_inst_color` from\n    // the vertex stage. For non-instanced draws the REQUIRED:false\n    // fallback fires identity (1,1,1,1) so the modulation collapses\n    // to the per-vertex × material × baseColor product.\n    vec3 base = mat.baseColor.rgb * bc.rgb * v_color.rgb * v_inst_color.rgb;\n    float alpha = mat.baseColor.a * bc.a * v_color.a * v_inst_color.a;\n\n    // glTF alphaMode=MASK — early discard before any expensive work.\n    // Two paths:\n    //   alpha_a2c_enabled = 1 → shader-level alpha-to-coverage via\n    //                            gl_SampleMask. Best edge quality when\n    //                            MSAA is on; degrades gracefully to a\n    //                            hard cutoff when MSAA is off (round\n    //                            saturates to 0 / 8).\n    //   default               → classic binary cutoff.\n    if((mat.feature_mask & kFeat_alpha_mask) != 0u)\n    {\n        if(alpha_a2c_enabled != 0)\n        {\n            if(!applyAlphaToCoverage(alpha))\n                discard;\n        }\n        else\n        {\n            if(alpha < mat.alpha_cutoff)\n                discard;\n        }\n    }\n\n    // ─── Metal-Rough-Occlusion (glTF packing: R=occ, G=rough, B=metal) ─\n    vec4 mr = sample_slot_mr(mat.textureRefs.y, matWrap(1u), uv_mr, vec4(1.0, 1.0, 1.0, 1.0));\n    float metallic\n        = mat.metallicRoughnessOcclusionUnlit.x * mr.b;\n    float roughness\n        = clamp(mat.metallicRoughnessOcclusionUnlit.y * mr.g, 0.04, 1.0);\n    // Occlusion: prefer separate occlusionTexture when set; else fall\n    // back to MR.r (the common packed-MR convention).\n    float occ_sample;\n    if((mat.feature_mask & kFeat_has_separate_occ) != 0u)\n        occ_sample = sample_slot_occ(mat.occlusion_textureRef, matWrap(4u), uv_occ, vec4(1.0)).r;\n    else\n        occ_sample = mr.r;\n    float occlusion = occ_sample * mat.metallicRoughnessOcclusionUnlit.z;\n    float unlit     = mat.metallicRoughnessOcclusionUnlit.w;\n\n    // ─── Emissive ─────────────────────────────────────────────────────\n    vec4 em = sample_slot_em(mat.textureRefs.w, matWrap(3u), uv_em, vec4(1.0));\n    vec3 emissive\n        = mat.emissive_strength.xyz * em.rgb * mat.emissive_strength.w;\n    emissive += v_inst_emissive.rgb;\n\n    if(unlit > 0.5)\n    {\n        // Volumetric composite BEFORE exposure_mul — accum is in raw\n        // light units (same scale as the BSDF result), so both sides\n        // of `inColor * transm + accum` stay in matched units.\n        // Output is linear HDR — the downstream tonemap owns the\n        // HDR→display compression and sRGB encode. (Doing pow(_,1/gamma)\n        // here would clip everything > 1 post-exposure to flat white\n        // before the tonemap could read the HDR signal — that's what\n        // made volumetric in-scatter blow out to saturated pink.)\n        vec3 color = base + emissive;\n        float viewZ_unlit = (camera.view * vec4(v_worldPos, 1.0)).z;\n        color = applyVolumetric(color, gl_FragCoord.xy, viewZ_unlit);\n        color *= exposure_mul;\n        isf_FragColor = vec4(max(color, vec3(0.0)), (mat.feature_mask & (1u << 17u)) != 0u ? alpha : 1.0);\n        return;\n    }\n\n    // ─── Surface normal (tangent-space normal map if present) ─────────\n    vec3 N = normalize(v_normal);\n    // Double-sided: flip the surface normal for back-facing fragments\n    // so the BRDF evaluates with the correct hemisphere on both sides\n    // of the surface. (Single-sided materials never reach here for\n    // back faces — they were discarded above.)\n    if(is_double_sided && !gl_FrontFacing)\n        N = -N;\n    // Toksvig variance accumulator (Olano-Baker 2010). Captures the\n    // amount of normal-map variance lost to mip-level averaging /\n    // multi-tap anisotropic averaging — info the GPU's bilinear+mip\n    // filter normally throws away when shaders re-normalize sampled\n    // normals. Folded into the specular-AA block below alongside the\n    // screen-space (Tokuyoshi-Kaplanyan) variance.\n    float toksvig_sigma2 = 0.0;\n    uint normRef = mat.textureRefs.z;\n    if(normRef != 0xFFFFFFFFu && length(v_tangent.xyz) > 0.5)\n    {\n        vec3 T = normalize(v_tangent.xyz);\n        vec3 B = normalize(cross(N, T) * v_tangent.w);\n        mat3 TBN = mat3(T, B, N);\n        // Normal map sampling goes through the bucket ladder so\n        // mixed-resolution / compressed normal atlases work. The\n        // default (0.5,0.5,1.0) fallback decodes to a zero tangent-\n        // space delta — same as no normal map at all — if the bucket\n        // slot isn't populated.\n        //\n        // Keep the UN-NORMALIZED sample so its length can drive the\n        // Toksvig boost: anisoSample averages multiple weighted taps\n        // and mip filtering averages within texels, both of which\n        // shorten |n| when sub-pixel normals had directional spread.\n        // (1 - |n|²) is the \"lost variance\" added back as roughness.\n        vec3 nm_raw = sample_slot_nrm(normRef, matWrap(2u), uv_nrm,\n                                      vec4(0.5, 0.5, 1.0, 1.0)).xyz\n                      * 2.0 - 1.0;\n        toksvig_sigma2 = max(0.0, 1.0 - dot(nm_raw, nm_raw));\n        N = normalize(TBN * normalize(nm_raw));\n    }\n\n    vec3 V = normalize(camera.cameraPosition.xyz - v_worldPos);\n    float NdotV = max(dot(N, V), 1e-4);\n\n    // Metallic workflow.\n    vec3 F0 = mix(vec3(0.04), base, metallic);\n    vec3 kd = (1.0 - metallic) * base;\n\n    // Cheap environment term — same \"fake IBL\" as classic_pbr_textured;\n    // classic_pbr_ibl is the cubemap-sampled variant.\n    vec3 Fv = F0 + (1.0 - F0) * pow(1.0 - NdotV, 5.0);\n    vec3 fake_env = Fv * base * 0.25;\n\n    // Ambient comes from EnvironmentLoader (env.ambient.rgb × intensity\n    // in .w). When the user hasn't wired one, ambient_col is zero and\n    // the fake_env term + lights carry the lighting. The 0.04 floor is\n    // gone — letting users actually dial ambient down to black.\n    vec3 result = ambient_col * base * occlusion\n                  + emissive\n                  + fake_env * occlusion;\n\n    float alpha_g = max(roughness * roughness, 1e-4);\n    float alpha2 = alpha_g * alpha_g;\n    float k = (roughness + 1.0) * (roughness + 1.0) / 8.0;\n\n    // ─── Specular antialiasing — Tokuyoshi-Kaplanyan + Toksvig ───────\n    //\n    // Three variance sources combined into a single roughness boost:\n    //\n    //   (A) Tokuyoshi-Kaplanyan 2019, \"Improved Geometric Specular\n    //       Antialiasing\" — screen-space derivatives of the world-\n    //       space normal. Captures sub-pixel-footprint normal\n    //       variance from geometry, normal-map silhouettes, and\n    //       interpolation across neighbours.\n    //\n    //   (B) Toksvig 2005, \"Mipmapping Normal Maps\" — texture-space\n    //       variance from filtered-normal shortening. Captures\n    //       variance lost to mip averaging + our multi-tap\n    //       anisotropic sampler that the GPU's linear filter and\n    //       shader's normalize() throw away.\n    //\n    //   (C) Grazing-angle amplification — a heuristic 1/NdotV scale\n    //       (capped) on the screen-space variance, approximating\n    //       Tokuyoshi-Kaplanyan's anisotropic Jacobian projection of\n    //       normal variance onto the half-vector tangent plane. The\n    //       full anisotropic form derives this matrix-multiply\n    //       explicitly; the 1/NdotV scalar captures the leading-\n    //       order behaviour at grazing where the BRDF stretches\n    //       most. Targets the \"noisy floor at grazing light\"\n    //       failure mode: at grazing, the half-vector becomes\n    //       perpendicular to the surface, NdotH gets small, and the\n    //       GGX D term's denominator hyperbola makes small N\n    //       variations move the highlight in/out of pixels.\n    //\n    // (A)+(B) cover variance from BOTH variance domains — the\n    // screen-space and texture-space sources are independent and\n    // additive. (C) amplifies (A) where the BRDF Jacobian demands it.\n    vec3 dNdx = dFdx(N);\n    vec3 dNdy = dFdy(N);\n    float kernelRoughness2 = 2.0 * (dot(dNdx, dNdx) + dot(dNdy, dNdy));\n\n    // (C) grazing amplification. NdotV floor of 0.05 prevents\n    // runaway at near-tangent view; cap at 8× keeps the boost\n    // bounded so we don't blow specular into pure diffuse.\n    float grazing_aa = clamp(1.0 / max(NdotV, 0.05), 1.0, 8.0);\n    kernelRoughness2 *= grazing_aa;\n\n    // Combine (A)·grazing + (B). Cap to keep alpha² in [0, 1] after\n    // the boost; 0.5 is the standard upper bound used by Filament +\n    // the Tokuyoshi-Kaplanyan reference.\n    const float specAaSigma2Max = 0.5;\n    float total_aa_sigma2 = clamp(kernelRoughness2 + toksvig_sigma2,\n                                  0.0, specAaSigma2Max);\n    alpha2 = clamp(alpha2 + total_aa_sigma2, 0.0, 1.0);\n    alpha_g = sqrt(alpha2);\n    // Re-derive Schlick-Smith k from the filtered roughness too so the\n    // G term widens in lockstep with D — otherwise rough-but-filtered\n    // surfaces still get an over-tight visibility term.\n    float roughness_f = sqrt(alpha_g);\n    k = (roughness_f + 1.0) * (roughness_f + 1.0) / 8.0;\n\n    uint n = scene_counts.light_count;\n    for(uint i = 0u; i < n; ++i)\n    {\n        uint slot = scene_light_indices.data[i];\n        Light L = scene_lights.entries[slot];\n\n        // Two paths for resolving the light's world-space placement:\n        //\n        //   transform_slot == 0xFFFFFFFF (sentinel):\n        //     The light was authored procedurally (e.g. by a compute CSF\n        //     reading a point cloud or particle system) and carries its\n        //     world position inline in local_direction.xyz. Skip the\n        //     world_transforms lookup — there's no matching scene-node\n        //     entry. Only point lights (type == 1) are well-defined\n        //     under this convention; directional with sentinel falls\n        //     back to treating .xyz as a direction, spot is unsupported.\n        //\n        //   transform_slot != sentinel:\n        //     Classic scene-node-attached light. World direction and\n        //     position come from the node's accumulated world transform\n        //     (published by ScenePreprocessor's FlattenVisitor).\n        float _type_f = L.local_direction.w;\n        vec3 ld_world;\n        vec3 lp_world;\n        if(L.transform_slot == 0xFFFFFFFFu)\n        {\n            if(_type_f < 0.5)\n            {\n                // Directional: .xyz is the world direction (same\n                // convention the scene-node path uses — no transform to\n                // apply since the light isn't parented to any node).\n                ld_world = normalize(L.local_direction.xyz);\n                lp_world = vec3(0.0);\n            }\n            else\n            {\n                // Point: .xyz is the world position. A default direction\n                // lets spot-cone code below degenerate gracefully for\n                // spot lights authored this way (cone attenuation will\n                // be effectively wide-open, since we have no real axis).\n                lp_world = L.local_direction.xyz;\n                ld_world = vec3(0.0, -1.0, 0.0);\n            }\n        }\n        else\n        {\n            mat4 W = world_transforms.data[L.transform_slot];\n            ld_world = normalize(mat3(W) * L.local_direction.xyz);\n            lp_world = W[3].xyz;\n        }\n        // Reconstruct the old LightGPU-shape vec4s so the BRDF body\n        // below (which references pos_type / color_i / dir_r) stays\n        // unchanged. type enum stays in .w; for directional lights the\n        // xyz holds the world direction, for point/spot it holds the\n        // world position — matching the prior packLight convention.\n        vec4 pos_type = vec4(\n            (_type_f < 0.5) ? ld_world : lp_world,\n            _type_f);\n        vec4 color_i  = L.color;\n        vec4 dir_r    = vec4(ld_world, L.range_cone.x);\n\n        vec3 Ldir;\n        float atten = 1.0;\n        if(pos_type.w < 0.5)\n        {\n            // Directional: no distance, no decay — per glTF / OpenPBR\n            // convention the 1/d² term doesn't apply.\n            Ldir = normalize(-pos_type.xyz);\n        }\n        else\n        {\n            vec3 toL = pos_type.xyz - v_worldPos;\n            float d = length(toL);\n            Ldir = toL / max(d, 1e-5);\n\n            // Hard cutoff: range == 0 is the \"no cutoff\" sentinel (glTF\n            // + ossia convention). Otherwise linearly fade over the\n            // last interval so the light doesn't pop off at exactly the\n            // range boundary.\n            if(dir_r.w > 0.0) atten = max(0.0, 1.0 - d / dir_r.w);\n\n            // Distance decay — switches on L.decay_mode so linear / none /\n            // cubic authored by the user or extracted from FBX actually\n            // reach the shader instead of being silently collapsed to\n            // the quadratic curve. Modes:\n            //   0 = none       (constant — legitimate for area lights\n            //                   and stylised looks)\n            //   1 = linear     1 / (1 + d)\n            //   2 = quadratic  1 / (1 + d²)   — physically correct default\n            //   3 = cubic      1 / (1 + d³)   — exaggerated falloff\n            uint decay = L.decay_mode;\n            if(decay == 1u)\n                atten *= 1.0 / (1.0 + d);\n            else if(decay == 2u)\n                atten *= 1.0 / (1.0 + d * d);\n            else if(decay == 3u)\n                atten *= 1.0 / (1.0 + d * d * d);\n            // decay == 0u → no distance attenuation; `atten` keeps the\n            // range cutoff contribution only.\n\n            // Spot-cone attenuation. Inner / outer cones are stored as\n            // cosines (packed CPU-side in Light.cpp) so the fragment-side\n            // test is one dot product + a linear ramp, matching the glTF\n            // KHR_lights_punctual reference formula:\n            //   t = clamp((cos_angle - outer) / (inner - outer), 0, 1)\n            //   atten *= t\n            // Outside the outer cone → t = 0, light doesn't contribute.\n            // Inside the inner cone → t = 1, full spot intensity.\n            // Between → linear falloff. type ≈ 2 = spot (local_direction.w\n            // packs the enum; see RawLightData::local_direction in\n            // SceneGPUState.hpp). Point lights (type ≈ 1) skip this\n            // block, so the spot-specific math doesn't perturb them.\n            if(pos_type.w > 1.5 && pos_type.w < 2.5)\n            {\n                float cos_to_frag = dot(-Ldir, normalize(dir_r.xyz));\n                float inner_cos   = L.range_cone.y;\n                float outer_cos   = L.range_cone.z;\n                atten *= clamp(\n                    (cos_to_frag - outer_cos)\n                        / max(inner_cos - outer_cos, 1e-5),\n                    0.0, 1.0);\n            }\n        }\n\n        float NdotL = max(dot(N, Ldir), 0.0);\n        if(NdotL <= 0.0) continue;\n\n        vec3 H = normalize(Ldir + V);\n        float NdotH = max(dot(N, H), 0.0);\n        float VdotH = max(dot(V, H), 0.0);\n\n        float denom_d = NdotH * NdotH * (alpha2 - 1.0) + 1.0;\n        float D = alpha2 / (3.14159 * denom_d * denom_d);\n\n        float G_v = NdotV / (NdotV * (1.0 - k) + k);\n        float G_l = NdotL / (NdotL * (1.0 - k) + k);\n        float G = G_v * G_l;\n\n        vec3 F = F0 + (1.0 - F0) * pow(1.0 - VdotH, 5.0);\n\n        vec3 spec = (D * G * F) / max(4.0 * NdotV * NdotL, 1e-4);\n        vec3 diffuse_term = (vec3(1.0) - F) * kd / 3.14159;\n\n        vec3 lightCol = color_i.rgb * color_i.w;\n        result += atten * lightCol * NdotL * (diffuse_term + spec);\n    }\n\n    // Linear fog: blend with fog_color over [start, end]. fog_range.w\n    // is the enabled flag (set by EnvironmentLoader). When disabled\n    // we skip the work.\n    if(env.fog_range.w > 0.5)\n    {\n        float view_z = distance(camera.cameraPosition.xyz, v_worldPos);\n        float f_s = env.fog_range.x;\n        float f_e = max(env.fog_range.y, f_s + 1e-3);\n        float t = clamp((view_z - f_s) / (f_e - f_s), 0.0, 1.0);\n        result = mix(result, env.fog_color_density.rgb, t);\n    }\n\n    // Volumetric composite BEFORE exposure_mul. accum from the integrate\n    // pass is in raw light units (same scale as the BSDF result), so\n    // both sides of `inColor * transm + accum` stay in matched units —\n    // applying after exposure makes accum dominate dim surfaces and\n    // lose to bright/specular surfaces, which was the original\n    // \"foliage punches through fog\" symptom.\n    //\n    // view_z above is `distance(eye, worldPos)` (positive); applyVolumetric /\n    // scoreClusterId need view-space Z (negative). Recompute from\n    // camera.view to keep the cluster lookup consistent with\n    // build_cluster_aabbs / volumetric_integrate.\n    float viewZ = (camera.view * vec4(v_worldPos, 1.0)).z;\n    result = applyVolumetric(result, gl_FragCoord.xy, viewZ);\n\n    result *= exposure_mul;\n\n    // Output is LINEAR HDR. The downstream tonemap node owns the\n    // HDR→display compression (ACES / Reinhard / filmic / etc.) and\n    // the sRGB encode. The previous `pow(result, 1/gamma)` here was\n    // sRGB-encoding the HDR before the tonemap could read it: any\n    // radiance > 1.0 post-exposure clipped to flat white at gamma\n    // encode, which is what made volumetric in-scatter blow out to\n    // saturated pink.\n    isf_FragColor = vec4(max(result, vec3(0.0)), (mat.feature_mask & (1u << 17u)) != 0u ? alpha : 1.0);\n}\n","Inlets":[{"uuid":"f2ab26ea-415d-45a2-bfbc-2968c7c92a33","ObjectName":"Inlet","id":1000,"Hidden":false,"Custom":"Geometry In","Exposed":"geometry in"},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":0,"Hidden":true,"Custom":"Mode","Exposed":"mode","Value":{"Int":0},"Init":{"Int":0},"Domain":{"Int":{"Values":[0,1,2,3]}},"Values":[["Triangles",{"Int":0}],["Points",{"Int":1}],["Lines",{"Int":2}],["Geometry",{"Int":3}]],"FolderPort":"","FileExtensions":""},{"uuid":"fb27e4cb-ea7f-41e2-ad92-2354498c1b6b","ObjectName":"Inlet","id":1,"Hidden":true,"Custom":"EnableBlend","Exposed":"enableblend","Value":{"Bool":false},"Init":{"Bool":false},"Domain":{"Bool":null}},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":2,"Hidden":true,"Custom":"SrcColor","Exposed":"srccolor","Value":{"Int":6},"Init":{"Int":6},"Domain":{"Int":{"Values":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]}},"Values":[["Zero",{"Int":0}],["One",{"Int":1}],["SrcColor",{"Int":2}],["OneMinusSrcColor",{"Int":3}],["DstColor",{"Int":4}],["OneMinusDstColor",{"Int":5}],["SrcAlpha",{"Int":6}],["OneMinusSrcAlpha",{"Int":7}],["DstAlpha",{"Int":8}],["OneMinusDstAlpha",{"Int":9}],["ConstantColor",{"Int":10}],["OneMinusConstantColor",{"Int":11}],["ConstantAlpha",{"Int":12}],["OneMinusConstantAlpha",{"Int":13}],["SrcAlphaSaturate",{"Int":14}]],"FolderPort":"","FileExtensions":""},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":3,"Hidden":true,"Custom":"DstColor","Exposed":"dstcolor","Value":{"Int":7},"Init":{"Int":7},"Domain":{"Int":{"Values":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]}},"Values":[["Zero",{"Int":0}],["One",{"Int":1}],["SrcColor",{"Int":2}],["OneMinusSrcColor",{"Int":3}],["DstColor",{"Int":4}],["OneMinusDstColor",{"Int":5}],["SrcAlpha",{"Int":6}],["OneMinusSrcAlpha",{"Int":7}],["DstAlpha",{"Int":8}],["OneMinusDstAlpha",{"Int":9}],["ConstantColor",{"Int":10}],["OneMinusConstantColor",{"Int":11}],["ConstantAlpha",{"Int":12}],["OneMinusConstantAlpha",{"Int":13}],["SrcAlphaSaturate",{"Int":14}]],"FolderPort":"","FileExtensions":""},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":4,"Hidden":true,"Custom":"OpColor","Exposed":"opcolor","Value":{"Int":0},"Init":{"Int":0},"Domain":{"Int":{"Values":[0,1,2,3,4]}},"Values":[["Add",{"Int":0}],["Substract",{"Int":1}],["Reverse Substract",{"Int":2}],["Min",{"Int":3}],["Max",{"Int":4}]],"FolderPort":"","FileExtensions":""},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":5,"Hidden":true,"Custom":"SrcAlpha","Exposed":"srcalpha","Value":{"Int":1},"Init":{"Int":1},"Domain":{"Int":{"Values":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]}},"Values":[["Zero",{"Int":0}],["One",{"Int":1}],["SrcColor",{"Int":2}],["OneMinusSrcColor",{"Int":3}],["DstColor",{"Int":4}],["OneMinusDstColor",{"Int":5}],["SrcAlpha",{"Int":6}],["OneMinusSrcAlpha",{"Int":7}],["DstAlpha",{"Int":8}],["OneMinusDstAlpha",{"Int":9}],["ConstantColor",{"Int":10}],["OneMinusConstantColor",{"Int":11}],["ConstantAlpha",{"Int":12}],["OneMinusConstantAlpha",{"Int":13}],["SrcAlphaSaturate",{"Int":14}]],"FolderPort":"","FileExtensions":""},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":6,"Hidden":true,"Custom":"DstAlpha","Exposed":"dstalpha","Value":{"Int":7},"Init":{"Int":7},"Domain":{"Int":{"Values":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]}},"Values":[["Zero",{"Int":0}],["One",{"Int":1}],["SrcColor",{"Int":2}],["OneMinusSrcColor",{"Int":3}],["DstColor",{"Int":4}],["OneMinusDstColor",{"Int":5}],["SrcAlpha",{"Int":6}],["OneMinusSrcAlpha",{"Int":7}],["DstAlpha",{"Int":8}],["OneMinusDstAlpha",{"Int":9}],["ConstantColor",{"Int":10}],["OneMinusConstantColor",{"Int":11}],["ConstantAlpha",{"Int":12}],["OneMinusConstantAlpha",{"Int":13}],["SrcAlphaSaturate",{"Int":14}]],"FolderPort":"","FileExtensions":""},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":7,"Hidden":true,"Custom":"OpAlpha","Exposed":"opalpha","Value":{"Int":0},"Init":{"Int":0},"Domain":{"Int":{"Values":[0,1,2,3,4]}},"Values":[["Add",{"Int":0}],["Substract",{"Int":1}],["Reverse Substract",{"Int":2}],["Min",{"Int":3}],["Max",{"Int":4}]],"FolderPort":"","FileExtensions":""},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":8,"Hidden":false,"Custom":"camera","Exposed":"camera","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":9,"Hidden":false,"Custom":"scene_lights","Exposed":"scene_lights","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":10,"Hidden":false,"Custom":"scene_light_indices","Exposed":"scene_light_indices","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":11,"Hidden":false,"Custom":"world_transforms","Exposed":"world_transforms","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":12,"Hidden":false,"Custom":"scene_materials","Exposed":"scene_materials","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":13,"Hidden":false,"Custom":"scene_material_uv_xforms","Exposed":"scene_material_uv_xforms","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":14,"Hidden":false,"Custom":"per_draws","Exposed":"per_draws","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":15,"Hidden":false,"Custom":"indirect_draw_cmds","Exposed":"indirect_draw_cmds","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":16,"Hidden":false,"Custom":"scene_counts","Exposed":"scene_counts","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":17,"Hidden":false,"Custom":"env","Exposed":"env","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"238399a0-7e81-47e3-896f-08e8856e2973","ObjectName":"Inlet","id":18,"Hidden":true,"Custom":"alpha_a2c_enabled","Exposed":"alpha_a2c_enabled","Value":{"Int":0},"Init":{"Int":0},"Domain":{"Int":{"Min":0,"Max":1}}},{"uuid":"238399a0-7e81-47e3-896f-08e8856e2973","ObjectName":"Inlet","id":19,"Hidden":true,"Custom":"volumetric_enabled","Exposed":"volumetric_enabled","Value":{"Int":0},"Init":{"Int":0},"Domain":{"Int":{"Min":0,"Max":1}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":20,"Hidden":true,"Custom":"volumetric_intensity","Exposed":"volumetric_intensity","Value":{"Float":1.0},"Init":{"Float":1.0},"Domain":{"Float":{"Min":0.0,"Max":4.0}}}],"Outlets":[{"uuid":"f1c71046-b754-49a5-8e66-d01374773dfc","ObjectName":"Outlet","id":1000,"Hidden":false,"Custom":"Texture Out","Exposed":"texture out"}]},{"uuid":"74ca45ff-92c9-44a0-8f1a-754dea05ee1b","ObjectName":"gfxProcess","id":19,"Metadata":{"ScriptingName":"ISF Shader.19","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[2072.132852329022,1537.6091072859465],"Size":[182.0,160.0],"Loops":false,"FoldMode":0,"Vertex":"","Fragment":"/*{\n  \"DESCRIPTION\": \"HDR tone mapping with selectable algorithm: Reinhard, ACES Filmic (Narkowicz), Exposure, Uncharted 2 (Hable), or AgX. Feed it linear HDR colour (the PBR render pipelines output linear HDR and leave tone mapping and the display gamma to this node); the output is gamma-encoded for display.\",\n  \"CREDIT\": \"ossia score\",\n  \"ISFVSN\": \"2\",\n  \"CATEGORIES\": [\n    \"Post-Process\"\n  ],\n  \"INPUTS\": [\n    {\n      \"NAME\": \"inputImage\",\n      \"TYPE\": \"image\"\n    },\n    {\n      \"NAME\": \"algorithm\",\n      \"LABEL\": \"Tone curve\",\n      \"TYPE\": \"long\",\n      \"DEFAULT\": 1,\n      \"VALUES\": [0, 1, 2, 3, 4],\n      \"LABELS\": [\"Reinhard\", \"ACES Filmic\", \"Exposure\", \"Uncharted 2\", \"AgX\"]\n    },\n    {\n      \"NAME\": \"exposure\",\n      \"LABEL\": \"Exposure (multiplier)\",\n      \"TYPE\": \"float\",\n      \"DEFAULT\": 1.0,\n      \"MIN\": 0.1,\n      \"MAX\": 10.0\n    },\n    {\n      \"NAME\": \"gamma\",\n      \"LABEL\": \"Display gamma\",\n      \"TYPE\": \"float\",\n      \"DEFAULT\": 2.2,\n      \"MIN\": 0.5,\n      \"MAX\": 3.0\n    },\n    {\n      \"NAME\": \"whitePoint\",\n      \"LABEL\": \"White point (Reinhard only)\",\n      \"TYPE\": \"float\",\n      \"DEFAULT\": 4.0,\n      \"MIN\": 0.5,\n      \"MAX\": 20.0\n    }\n  ]\n}*/\n\n// --- Reinhard (extended) ---\nvec3 tonemapReinhard(vec3 color, float wp)\n{\n  // Extended Reinhard: color * (1 + color / wp^2) / (1 + color)\n  vec3 wp2 = vec3(wp * wp);\n  return color * (1.0 + color / wp2) / (1.0 + color);\n}\n\n// --- ACES Filmic (Narkowicz approximation) ---\n// Source: Krzysztof Narkowicz, \"ACES Filmic Tone Mapping Curve\" (2016)\nvec3 tonemapACES(vec3 x)\n{\n  const float a = 2.51;\n  const float b = 0.03;\n  const float c = 2.43;\n  const float d = 0.59;\n  const float e = 0.14;\n  return clamp((x * (a * x + b)) / (x * (c * x + d) + e), 0.0, 1.0);\n}\n\n// --- Exposure (simple) ---\nvec3 tonemapExposure(vec3 color, float e)\n{\n  return 1.0 - exp(-color * e);\n}\n\n// --- Uncharted 2 (Hable filmic) ---\n// Source: John Hable, \"Filmic Tonemapping Operators\" (GDC 2010)\nvec3 uncharted2Partial(vec3 x)\n{\n  const float A = 0.15; // Shoulder strength\n  const float B = 0.50; // Linear strength\n  const float C = 0.10; // Linear angle\n  const float D = 0.20; // Toe strength\n  const float E = 0.02; // Toe numerator\n  const float F = 0.30; // Toe denominator\n  return ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F;\n}\n\nvec3 tonemapUncharted2(vec3 color)\n{\n  const float W = 11.2; // Linear white point\n  const float exposureBias = 2.0;\n  vec3 curr = uncharted2Partial(color * exposureBias);\n  vec3 whiteScale = vec3(1.0) / uncharted2Partial(vec3(W));\n  return curr * whiteScale;\n}\n\n// --- AgX ---\n// Based on the minimal analytical AgX implementation.\n// References: Troy Sobotka, Benjamin Wrensch (Missing Deadlines), Blender 4.0\n\nconst mat3 AgXInsetMatrix = mat3(\n  0.856627153315983, 0.137318972929847, 0.11189821299995,\n  0.0951212405381588, 0.761241990602591, 0.0767994186031903,\n  0.0482516061458583, 0.101439036467562, 0.811302368396859\n);\n\nconst mat3 AgXOutsetMatrix = mat3(\n  1.1271005818144368, -0.1413297634984383, -0.14132976349843826,\n  -0.11060664309660323, 1.157823702216272, -0.11060664309660294,\n  -0.016493938717834573, -0.016493938717834257, 1.2519364065950405\n);\n\nconst mat3 LINEAR_SRGB_TO_LINEAR_REC2020 = mat3(\n  0.6274, 0.0691, 0.0164,\n  0.3293, 0.9195, 0.0880,\n  0.0433, 0.0113, 0.8956\n);\n\nconst mat3 LINEAR_REC2020_TO_LINEAR_SRGB = mat3(\n  1.6605, -0.1246, -0.0182,\n  -0.5876, 1.1329, -0.1006,\n  -0.0728, -0.0083, 1.1187\n);\n\nvec3 tonemapAgX(vec3 color)\n{\n  const float AgxMinEv = -12.47393;\n  const float AgxMaxEv = 4.026069;\n\n  color = LINEAR_SRGB_TO_LINEAR_REC2020 * color;\n  color = AgXInsetMatrix * color;\n\n  color = max(color, 1e-10);\n  color = clamp(log2(color), AgxMinEv, AgxMaxEv);\n  color = (color - AgxMinEv) / (AgxMaxEv - AgxMinEv);\n  color = clamp(color, 0.0, 1.0);\n\n  // 6th-order polynomial approximation of the AgX sigmoid\n  vec3 x2 = color * color;\n  vec3 x4 = x2 * x2;\n  color = + 15.5   * x4 * x2\n          - 40.14  * x4 * color\n          + 31.96  * x4\n          - 6.868  * x2 * color\n          + 0.4298 * x2\n          + 0.1191 * color\n          - 0.00232;\n\n  color = AgXOutsetMatrix * color;\n\n  // Linearize (AgX output is in sRGB-like gamma space)\n  color = pow(max(vec3(0.0), color), vec3(2.2));\n\n  color = LINEAR_REC2020_TO_LINEAR_SRGB * color;\n  return clamp(color, 0.0, 1.0);\n}\n\nvoid main()\n{\n  vec4 texColor = IMG_THIS_PIXEL(inputImage);\n  vec3 color = texColor.rgb;\n\n  // Apply exposure\n  color *= exposure;\n\n  // Apply selected tone mapping algorithm\n  if(algorithm == 0)\n  {\n    color = tonemapReinhard(color, whitePoint);\n  }\n  else if(algorithm == 1)\n  {\n    color = tonemapACES(color);\n  }\n  else if(algorithm == 2)\n  {\n    // Exposure already applied above; use 1.0 to avoid double-application\n    color = tonemapExposure(color, 1.0);\n  }\n  else if(algorithm == 3)\n  {\n    color = tonemapUncharted2(color);\n  }\n  else if(algorithm == 4)\n  {\n    color = tonemapAgX(color);\n  }\n\n  // Gamma correction\n  color = pow(max(color, vec3(0.0)), vec3(1.0 / gamma));\n\n  isf_FragColor = vec4(color, texColor.a);\n}\n","Root":"<LIBRARY>:packages/score-csf-testers/shaderlib/post-process/ToneMapping.fs","Inlets":[{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":0,"Hidden":false,"Custom":"inputImage","Exposed":"inputimage","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":1,"Hidden":true,"Custom":"algorithm","Exposed":"algorithm","Value":{"Int":1},"Init":{"Int":1},"Domain":{"Int":{"Values":[0,1,2,3,4]}},"Values":[["Reinhard",{"Int":0}],["ACES Filmic",{"Int":1}],["Exposure",{"Int":2}],["Uncharted 2",{"Int":3}],["AgX",{"Int":4}]],"FolderPort":"","FileExtensions":""},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":2,"Hidden":true,"Custom":"exposure","Exposed":"exposure","Value":{"Float":1.0},"Init":{"Float":1.0},"Domain":{"Float":{"Min":0.10000000149011612,"Max":10.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":3,"Hidden":true,"Custom":"gamma","Exposed":"gamma","Value":{"Float":2.200000047683716},"Init":{"Float":2.200000047683716},"Domain":{"Float":{"Min":0.5,"Max":3.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":4,"Hidden":true,"Custom":"whitePoint","Exposed":"whitepoint","Value":{"Float":4.0},"Init":{"Float":4.0},"Domain":{"Float":{"Min":0.5,"Max":20.0}}}],"Outlets":[{"uuid":"f1c71046-b754-49a5-8e66-d01374773dfc","ObjectName":"Outlet","id":1,"Hidden":false,"Custom":"Texture Out","Exposed":"texture out"}]},{"uuid":"2f6a8c41-7d93-4e5b-b1c8-4e3f9a7d2c5b","ObjectName":"asset_loader","id":20,"Metadata":{"ScriptingName":"Asset Loader.20","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[336.9378534356694,2529.56407421481],"Size":[232.0,173.0],"Loops":false,"FoldMode":0,"Inlets":[{"uuid":"40833147-4c42-4b8b-bb80-0b1d15dae129","ObjectName":"Inlet","id":0,"Hidden":true,"Custom":"Asset file","Exposed":"asset file","Value":{"String":"<PROJECT>:Models/Duck.glb"},"Init":{"String":""},"Domain":{},"Filters":"3D assets (*.fbx *.gltf *.glb *.obj *.ply *.stl *.off *.splat *.spz *.usd *.usda *.usdc *.usdz)"},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":1,"Hidden":true,"Custom":"Position","Exposed":"position","Value":{"Vec3f":[0.0,0.0,0.0]},"Init":{"Vec3f":[0.0,0.0,0.0]},"Domain":{"Vec3f":{"Min":[-8388608.0,-8388608.0,-8388608.0],"Max":[8388608.0,8388608.0,8388608.0],"Values":[[],[],[]]}}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":2,"Hidden":true,"Custom":"Rotation","Exposed":"rotation","Value":{"Vec3f":[0.0,0.0,0.0]},"Init":{"Vec3f":[0.0,0.0,0.0]},"Domain":{"Vec3f":{"Min":[0.0,0.0,0.0],"Max":[360.0,360.0,360.0],"Values":[[],[],[]]}}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":3,"Hidden":true,"Custom":"Scale","Exposed":"scale","Value":{"Vec3f":[1.0,1.0,1.0]},"Init":{"Vec3f":[1.0,1.0,1.0]},"Domain":{"Vec3f":{"Min":[0.000009999999747378752,0.000009999999747378752,0.000009999999747378752],"Max":[1000.0,1000.0,1000.0],"Values":[[],[],[]]}}},{"uuid":"9ae797ea-d94c-4792-acec-9ec1932bae5d","ObjectName":"Inlet","id":4,"Hidden":true,"Custom":"Format override (auto if empty)","Exposed":"format override (auto if empty)","Value":{"String":""},"Init":{"String":""},"Domain":{}}],"Outlets":[{"uuid":"848061c5-e8a0-4a13-9985-e8df30ce6d4f","ObjectName":"Outlet","id":0,"Hidden":false,"Custom":"Scene","Exposed":"scene"}]},{"uuid":"a5bbffe0-93d2-4e70-995c-cf46c2c43520","ObjectName":"CSF","id":21,"Metadata":{"ScriptingName":"Compute Shader.21","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[349.2866809320715,2751.7369837144975],"Size":[213.0,167.0],"Loops":false,"FoldMode":0,"Compute":"/*{\n  \"DESCRIPTION\": \"Regular 2D/3D grid of countX x countY x countZ points, spacing apart, centred on center. Set countZ to 1 for a flat grid in the XY plane. Colour and texcoord are the normalised grid coordinates (x, y, z) in 0..1.\",\n  \"CREDIT\": \"ossia score\",\n  \"ISFVSN\": \"2.0\",\n  \"MODE\": \"COMPUTE_SHADER\",\n  \"CATEGORIES\": [\"Geometry Generator\"],\n  \"RESOURCES\": [\n    {\n      \"NAME\": \"geo\",\n      \"TYPE\": \"geometry\",\n      \"VERTEX_COUNT\": \"$countX * $countY * $countZ\",\n      \"ATTRIBUTES\": [\n        { \"NAME\": \"position\", \"SEMANTIC\": \"position\", \"TYPE\": \"vec4\", \"ACCESS\": \"write_only\", \"RATE\": \"vertex\" },\n        { \"NAME\": \"color\",    \"SEMANTIC\": \"color\",    \"TYPE\": \"vec4\", \"ACCESS\": \"write_only\", \"RATE\": \"vertex\" },\n        { \"NAME\": \"texcoord\", \"SEMANTIC\": \"texcoord\", \"TYPE\": \"vec4\", \"ACCESS\": \"write_only\", \"RATE\": \"vertex\" }\n      ]\n    },\n    { \"NAME\": \"countX\",  \"TYPE\": \"long\",    \"DEFAULT\": 32,  \"MIN\": 1,     \"MAX\": 512 },\n    { \"NAME\": \"countY\",  \"TYPE\": \"long\",    \"DEFAULT\": 32,  \"MIN\": 1,     \"MAX\": 512 },\n    { \"NAME\": \"countZ\",  \"TYPE\": \"long\",    \"DEFAULT\": 1,   \"MIN\": 1,     \"MAX\": 512 },\n    { \"NAME\": \"spacing\", \"TYPE\": \"float\",   \"DEFAULT\": 0.1, \"MIN\": 0.001, \"MAX\": 10.0 },\n    { \"NAME\": \"center\",  \"TYPE\": \"point3D\", \"DEFAULT\": [0, 0, 0], \"MIN\": [-10, -10, -10], \"MAX\": [10, 10, 10] }\n  ],\n  \"PASSES\": [\n    { \"LOCAL_SIZE\": [64, 1, 1], \"EXECUTION_MODEL\": { \"TYPE\": \"PER_VERTEX\" } }\n  ]\n}*/\n\nvoid main()\n{\n    uint idx = gl_GlobalInvocationID.x;\n    uint count = uint(ISF_WRITE(geo, position).length());\n    if(idx >= count)\n        return;\n\n    uint cX = uint(countX);\n    uint cY = uint(countY);\n    uint cZ = uint(countZ);\n\n    // Decompose linear index into 3D grid coordinates\n    uint z = idx / (cX * cY);\n    uint remainder = idx % (cX * cY);\n    uint y = remainder / cX;\n    uint x = remainder % cX;\n\n    // Center the grid around the origin, then offset by user center\n    vec3 offset = vec3(\n        float(cX - 1u),\n        float(cY - 1u),\n        float(cZ - 1u)\n    ) * spacing * 0.5;\n\n    vec3 pos = vec3(float(x), float(y), float(z)) * spacing - offset + center;\n\n    // Normalized grid coordinates [0, 1]\n    float nx = (cX > 1u) ? float(x) / float(cX - 1u) : 0.5;\n    float ny = (cY > 1u) ? float(y) / float(cY - 1u) : 0.5;\n    float nz = (cZ > 1u) ? float(z) / float(cZ - 1u) : 0.5;\n\n    ISF_WRITE(geo, position)[idx] = vec4(pos, 1.0);\n    ISF_WRITE(geo, texcoord)[idx] = vec4(nx, ny, nz, 1.0);\n\n    // Color gradient from grid position\n    ISF_WRITE(geo, color)[idx] = vec4(nx, ny, nz, 1.0);\n}\n","Root":"<LIBRARY>:packages/score-csf-testers/shaderlib/generators/GridPoints.cs","Inlets":[{"uuid":"238399a0-7e81-47e3-896f-08e8856e2973","ObjectName":"Inlet","id":0,"Hidden":true,"Custom":"countX","Exposed":"countx","Value":{"Int":8},"Init":{"Int":32},"Domain":{"Int":{"Min":1,"Max":512}}},{"uuid":"238399a0-7e81-47e3-896f-08e8856e2973","ObjectName":"Inlet","id":1,"Hidden":true,"Custom":"countY","Exposed":"county","Value":{"Int":1},"Init":{"Int":32},"Domain":{"Int":{"Min":1,"Max":512}}},{"uuid":"238399a0-7e81-47e3-896f-08e8856e2973","ObjectName":"Inlet","id":2,"Hidden":true,"Custom":"countZ","Exposed":"countz","Value":{"Int":8},"Init":{"Int":1},"Domain":{"Int":{"Min":1,"Max":512}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":3,"Hidden":true,"Custom":"spacing","Exposed":"spacing","Value":{"Float":2.5},"Init":{"Float":0.10000000149011612},"Domain":{"Float":{"Min":0.0010000000474974513,"Max":10.0}}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":4,"Hidden":true,"Custom":"center","Exposed":"center","Value":{"Vec3f":[0.0,0.0,0.0]},"Init":{"Vec3f":[0.0,0.0,0.0]},"Domain":{"Vec3f":{"Min":[-10.0,-10.0,-10.0],"Max":[10.0,10.0,10.0],"Values":[[],[],[]]}}}],"Outlets":[{"uuid":"848061c5-e8a0-4a13-9985-e8df30ce6d4f","ObjectName":"Outlet","id":0,"Hidden":false,"Custom":"geo_out","Exposed":"geo_out"}]},{"uuid":"5e8a2c7f-9b4d-4e3a-a1c6-2d7f0b3e8c4a","ObjectName":"instancer","id":22,"Metadata":{"ScriptingName":"Instancer.22","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[613.4097699882664,2535.0541196526983],"Size":[418.0,175.0],"Loops":false,"FoldMode":0,"Inlets":[{"uuid":"f2ab26ea-415d-45a2-bfbc-2968c7c92a33","ObjectName":"Inlet","id":0,"Hidden":false,"Custom":"Scene In","Exposed":"scene in"},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":1,"Hidden":false,"Custom":"Transforms","Exposed":"transforms","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":2,"Hidden":false,"Custom":"Colors","Exposed":"colors","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":3,"Hidden":false,"Custom":"Custom","Exposed":"custom","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"f2ab26ea-415d-45a2-bfbc-2968c7c92a33","ObjectName":"Inlet","id":4,"Hidden":false,"Custom":"Points","Exposed":"points"},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":5,"Hidden":true,"Custom":"Format","Exposed":"format","Value":{"Int":0},"Init":{"Int":0},"Domain":{"Int":{"Values":[0,1,2]}},"Values":[["mat4",{"Int":0}],["trs",{"Int":1}],["translation",{"Int":2}]],"FolderPort":"","FileExtensions":""},{"uuid":"238399a0-7e81-47e3-896f-08e8856e2973","ObjectName":"Inlet","id":6,"Hidden":true,"Custom":"Count","Exposed":"count","Value":{"Int":1},"Init":{"Int":1},"Domain":{"Int":{"Min":1,"Max":1000000}}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":7,"Hidden":true,"Custom":"Position","Exposed":"position","Value":{"Vec3f":[0.0,0.0,0.0]},"Init":{"Vec3f":[0.0,0.0,0.0]},"Domain":{"Vec3f":{"Min":[-8388608.0,-8388608.0,-8388608.0],"Max":[8388608.0,8388608.0,8388608.0],"Values":[[],[],[]]}}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":8,"Hidden":true,"Custom":"Rotation","Exposed":"rotation","Value":{"Vec3f":[0.0,0.0,0.0]},"Init":{"Vec3f":[0.0,0.0,0.0]},"Domain":{"Vec3f":{"Min":[0.0,0.0,0.0],"Max":[360.0,360.0,360.0],"Values":[[],[],[]]}}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":9,"Hidden":true,"Custom":"Scale","Exposed":"scale","Value":{"Vec3f":[0.20000000298023224,0.20000000298023224,0.20000000298023224]},"Init":{"Vec3f":[1.0,1.0,1.0]},"Domain":{"Vec3f":{"Min":[0.000009999999747378752,0.000009999999747378752,0.000009999999747378752],"Max":[1000.0,1000.0,1000.0],"Values":[[],[],[]]}}},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":10,"Hidden":true,"Custom":"Per-instance transform","Exposed":"per-instance transform","Value":{"Int":0},"Init":{"Int":0},"Domain":{"Int":{"Values":[0,1]}},"Values":[["Full matrix",{"Int":0}],["Translation only",{"Int":1}]],"FolderPort":"","FileExtensions":""}],"Outlets":[{"uuid":"848061c5-e8a0-4a13-9985-e8df30ce6d4f","ObjectName":"Outlet","id":0,"Hidden":false,"Custom":"Scene Out","Exposed":"scene out"}]},{"uuid":"a8f2c6d0-1b4e-4c7a-9d3f-5e8b2c1a7f0d","ObjectName":"gfxProcess","id":23,"Metadata":{"ScriptingName":"Scene Preprocessor.23","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[1180.9618634956742,3065.630562105353],"Size":[186.0,22.0],"Loops":false,"FoldMode":0,"Inlets":[{"uuid":"f2ab26ea-415d-45a2-bfbc-2968c7c92a33","ObjectName":"Inlet","id":0,"Hidden":false,"Custom":"Scene In","Exposed":"scene in"}],"Outlets":[{"uuid":"848061c5-e8a0-4a13-9985-e8df30ce6d4f","ObjectName":"Outlet","id":0,"Hidden":false,"Custom":"Geometry Out","Exposed":"geometry out"}]},{"uuid":"4c91b5e2-8d76-4ab3-9f14-6e0d8b3a2c57","ObjectName":"camera_avnd","id":24,"Metadata":{"ScriptingName":"Camera.24","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[771.9130169443488,2768.6969663680948],"Size":[274.0,177.0],"Loops":false,"FoldMode":0,"Inlets":[{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":0,"Hidden":true,"Custom":"Eye","Exposed":"eye","Value":{"Vec3f":[0.0,2.5999999046325684,3.5999999046325684]},"Init":{"Vec3f":[0.0,0.0,0.0]},"Domain":{"Vec3f":{"Min":[-10000.0,-10000.0,-10000.0],"Max":[10000.0,10000.0,10000.0],"Values":[[],[],[]]}}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":1,"Hidden":true,"Custom":"Target","Exposed":"target","Value":{"Vec3f":[0.0,0.0,0.0]},"Init":{"Vec3f":[0.0,0.0,0.0]},"Domain":{"Vec3f":{"Min":[-10000.0,-10000.0,-10000.0],"Max":[10000.0,10000.0,10000.0],"Values":[[],[],[]]}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":2,"Hidden":true,"Custom":"FOV","Exposed":"fov","Value":{"Float":45.0},"Init":{"Float":60.0},"Domain":{"Float":{"Min":5.0,"Max":170.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":3,"Hidden":true,"Custom":"Near","Exposed":"near","Value":{"Float":0.10000000149011612},"Init":{"Float":0.10000000149011612},"Domain":{"Float":{"Min":0.0010000000474974513,"Max":10.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":4,"Hidden":true,"Custom":"Far","Exposed":"far","Value":{"Float":1000.0},"Init":{"Float":1000.0},"Domain":{"Float":{"Min":1.0,"Max":100000.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":5,"Hidden":true,"Custom":"Roll","Exposed":"roll","Value":{"Float":0.0},"Init":{"Float":0.0},"Domain":{"Float":{"Min":-180.0,"Max":180.0}}}],"Outlets":[{"uuid":"848061c5-e8a0-4a13-9985-e8df30ce6d4f","ObjectName":"Outlet","id":0,"Hidden":false,"Custom":"Scene","Exposed":"scene"}]},{"uuid":"9f3c1a5e-4b7d-4e2a-8c5f-1d6e0b9a3c7f","ObjectName":"light","id":25,"Metadata":{"ScriptingName":"Light.25","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[625.2391787107081,3000.3124812330866],"Size":[422.0,252.0],"Loops":false,"FoldMode":0,"Inlets":[{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":0,"Hidden":true,"Custom":"Mode","Exposed":"mode","Value":{"Int":0},"Init":{"Int":0},"Domain":{"Int":{"Values":[0,1,2,3,4,5,6]}},"Values":[["Directional",{"Int":0}],["Point",{"Int":1}],["Spot",{"Int":2}],["Rect",{"Int":3}],["Disk",{"Int":4}],["Sphere",{"Int":5}],["Dome",{"Int":6}]],"FolderPort":"","FileExtensions":""},{"uuid":"8f38638e-9f9f-48b0-ae36-1cba86ef5703","ObjectName":"Inlet","id":1,"Hidden":true,"Custom":"Color","Exposed":"color","Value":{"Vec4f":[1.0,1.0,1.0,1.0]},"Init":{"Vec4f":[1.0,1.0,1.0,1.0]},"Domain":{}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":2,"Hidden":true,"Custom":"Intensity","Exposed":"intensity","Value":{"Float":4.0},"Init":{"Float":1.0},"Domain":{"Float":{"Min":0.0,"Max":100.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":3,"Hidden":true,"Custom":"Range","Exposed":"range","Value":{"Float":0.0},"Init":{"Float":0.0},"Domain":{"Float":{"Min":0.0,"Max":1000.0}}},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":4,"Hidden":true,"Custom":"Falloff","Exposed":"falloff","Value":{"Int":2},"Init":{"Int":2},"Domain":{"Int":{"Values":[0,1,2,3]}},"Values":[["None",{"Int":0}],["Linear",{"Int":1}],["Quadratic (physical)",{"Int":2}],["Cubic",{"Int":3}]],"FolderPort":"","FileExtensions":""},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":5,"Hidden":true,"Custom":"Inner cone °","Exposed":"inner cone _","Value":{"Float":0.0},"Init":{"Float":0.0},"Domain":{"Float":{"Min":0.0,"Max":90.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":6,"Hidden":true,"Custom":"Outer cone °","Exposed":"outer cone _","Value":{"Float":45.0},"Init":{"Float":45.0},"Domain":{"Float":{"Min":0.0,"Max":90.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":7,"Hidden":true,"Custom":"Width","Exposed":"width","Value":{"Float":1.0},"Init":{"Float":1.0},"Domain":{"Float":{"Min":0.009999999776482582,"Max":100.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":8,"Hidden":true,"Custom":"Height","Exposed":"height","Value":{"Float":1.0},"Init":{"Float":1.0},"Domain":{"Float":{"Min":0.009999999776482582,"Max":100.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":9,"Hidden":true,"Custom":"Radius","Exposed":"radius","Value":{"Float":0.5},"Init":{"Float":0.5},"Domain":{"Float":{"Min":0.009999999776482582,"Max":100.0}}},{"uuid":"fb27e4cb-ea7f-41e2-ad92-2354498c1b6b","ObjectName":"Inlet","id":10,"Hidden":true,"Custom":"Cast shadow","Exposed":"cast shadow","Value":{"Bool":false},"Init":{"Bool":false},"Domain":{"Bool":null}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":11,"Hidden":true,"Custom":"Shadow bias","Exposed":"shadow bias","Value":{"Float":0.0010000000474974513},"Init":{"Float":0.0010000000474974513},"Domain":{"Float":{"Min":0.0,"Max":0.10000000149011612}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":12,"Hidden":true,"Custom":"Shadow normal bias","Exposed":"shadow normal bias","Value":{"Float":0.009999999776482582},"Init":{"Float":0.009999999776482582},"Domain":{"Float":{"Min":0.0,"Max":0.10000000149011612}}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":13,"Hidden":true,"Custom":"Position","Exposed":"position","Value":{"Vec3f":[0.0,0.0,0.0]},"Init":{"Vec3f":[0.0,0.0,0.0]},"Domain":{"Vec3f":{"Min":[-8388608.0,-8388608.0,-8388608.0],"Max":[8388608.0,8388608.0,8388608.0],"Values":[[],[],[]]}}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":14,"Hidden":true,"Custom":"Rotation","Exposed":"rotation","Value":{"Vec3f":[-50.0,35.0,0.0]},"Init":{"Vec3f":[0.0,0.0,0.0]},"Domain":{"Vec3f":{"Min":[0.0,0.0,0.0],"Max":[360.0,360.0,360.0],"Values":[[],[],[]]}}}],"Outlets":[{"uuid":"848061c5-e8a0-4a13-9985-e8df30ce6d4f","ObjectName":"Outlet","id":0,"Hidden":false,"Custom":"Scene","Exposed":"scene"}]},{"uuid":"d3f5a8c1-8b47-4e91-9c2d-6f1a9b5e3c82","ObjectName":"environment_loader","id":26,"Metadata":{"ScriptingName":"Environment.26","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[700.419246805589,3294.502174806122],"Size":[352.0,176.0],"Loops":false,"FoldMode":0,"Inlets":[{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":0,"Hidden":true,"Custom":"Ambient Color","Exposed":"ambient color","Value":{"Vec3f":[1.0,1.0,1.0]},"Init":{"Vec3f":[0.029999999329447746,0.029999999329447746,0.029999999329447746]},"Domain":{"Vec3f":{"Min":[0.0,0.0,0.0],"Max":[1.0,1.0,1.0],"Values":[[],[],[]]}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":1,"Hidden":true,"Custom":"Ambient Intensity","Exposed":"ambient intensity","Value":{"Float":0.800000011920929},"Init":{"Float":1.0},"Domain":{"Float":{"Min":0.0,"Max":8.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":2,"Hidden":true,"Custom":"Exposure EV100","Exposed":"exposure ev100","Value":{"Float":0.0},"Init":{"Float":0.0},"Domain":{"Float":{"Min":-6.0,"Max":18.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":3,"Hidden":true,"Custom":"Exposure (stops)","Exposed":"exposure (stops)","Value":{"Float":0.0},"Init":{"Float":0.0},"Domain":{"Float":{"Min":-8.0,"Max":8.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":4,"Hidden":true,"Custom":"Gamma","Exposed":"gamma","Value":{"Float":2.200000047683716},"Init":{"Float":2.200000047683716},"Domain":{"Float":{"Min":1.0,"Max":3.0}}},{"uuid":"fb27e4cb-ea7f-41e2-ad92-2354498c1b6b","ObjectName":"Inlet","id":5,"Hidden":true,"Custom":"Fog","Exposed":"fog","Value":{"Bool":false},"Init":{"Bool":false},"Domain":{"Bool":null}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":6,"Hidden":true,"Custom":"Fog Color","Exposed":"fog color","Value":{"Vec3f":[0.800000011920929,0.800000011920929,0.800000011920929]},"Init":{"Vec3f":[0.800000011920929,0.800000011920929,0.800000011920929]},"Domain":{"Vec3f":{"Min":[0.0,0.0,0.0],"Max":[1.0,1.0,1.0],"Values":[[],[],[]]}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":7,"Hidden":true,"Custom":"Fog Start","Exposed":"fog start","Value":{"Float":10.0},"Init":{"Float":10.0},"Domain":{"Float":{"Min":0.0,"Max":1000.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":8,"Hidden":true,"Custom":"Fog End","Exposed":"fog end","Value":{"Float":100.0},"Init":{"Float":100.0},"Domain":{"Float":{"Min":0.0,"Max":10000.0}}},{"uuid":"0adbbdda-fda4-451e-91cc-1da731bde9d5","ObjectName":"Inlet","id":9,"Hidden":true,"Custom":"Render target size","Exposed":"render target size","Value":{"Vec2f":[0.0,0.0]},"Init":{"Vec2f":[0.0,0.0]},"Domain":{"Vec2f":{"Min":[0.0,0.0],"Max":[16384.0,16384.0],"Values":[[],[]]}},"Integral":true}],"Outlets":[{"uuid":"848061c5-e8a0-4a13-9985-e8df30ce6d4f","ObjectName":"Outlet","id":0,"Hidden":false,"Custom":"Scene","Exposed":"scene"}]},{"uuid":"dbfc2101-40d7-4807-8804-571e88992e7e","ObjectName":"gfxProcess","id":27,"Metadata":{"ScriptingName":"Render Pipeline.27","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[1373.455484973601,3034.6142940541995],"Size":[787.0,160.0],"Loops":false,"FoldMode":0,"Vertex":"// Full-PBR variant — extends classic_pbr_textured with TANGENT for TBN\n// normal-map reconstruction in the fragment stage.\n//\n// Vertex inputs + varyings come from the sibling .frag's VERTEX_INPUTS /\n// VERTEX_OUTPUTS blocks; redeclaring them here triggers \"redefinition\".\n\nvoid main()\n{\n    isf_vertShaderInit();\n\n    // Unified-MDI cmd-index lookup: per-instance VERTEX_INPUT carries\n    // the drawID directly. Replaces the prior `gl_BaseInstanceARB`\n    // path, which broke as soon as instanceCount > 1 (firstInstance\n    // becomes the per-instance slot offset, no longer the cmd index)\n    // AND was always 0 on the CPU-fallback drawIndexed loop. Reading\n    // a per-instance attribute works uniformly on both indirect and\n    // CPU-fallback paths (firstInstance is honoured by every QRhi\n    // backend that supports instancing).\n    uint drawId = draw_id;\n    v_drawID = drawId;\n\n    PerDraw pd = per_draws.data[drawId];\n    mat3 instLinear = pd.normal[3].x > 0.5\n        ? mat3(inst_matrix0.xyz, inst_matrix1.xyz, inst_matrix2.xyz)\n        : mat3(1.0);\n    mat4 model = pd.model;\n    mat3 normalMatrix = mat3(pd.normal) * transpose(inverse(instLinear));\n\n    // Per-instance translation offset: zero for non-instanced draws via\n    // the REQUIRED:false fallback (identity broadcast); the actual\n    // particle position for unified-MDI instance groups.\n    vec4 wp = model * vec4(instLinear * position + inst_translation, 1.0);\n    v_worldPos = wp.xyz;\n    v_normal = normalize(normalMatrix * normal);\n    // Tangent carries xyz = unit tangent in mesh space + w = handedness.\n    // Apply the normal matrix to the xyz (same basis as the normal) and\n    // forward w untouched. Consumer reconstructs bitangent as\n    //   bitangent = cross(N, T.xyz) * T.w\n    v_tangent = vec4(normalize(normalMatrix * tangent.xyz), tangent.w);\n    v_uv = texcoord_0;\n    // glTF TEXCOORD_1 (secondary UV set — lightmaps, per-channel UV\n    // override). Falls back to zero for meshes without it (slab\n    // uploader fills with zeros).\n    v_uv1 = texcoord_1;\n    // glTF COLOR_0 (defaults to vec4(1) when the mesh doesn't carry\n    // one — the slab uploader fills the buffer with white).\n    v_color = color_0;\n    // VERTEX_INPUTS aren't directly visible to the fragment stage —\n    // forward the per-instance broadcast colour as a varying so the\n    // .frag can multiply baseColor by it.\n    v_inst_color = pd.normal[3].y > 0.5 ? inst_color0 : vec4(1.0);\n    v_inst_emissive = pd.normal[3].z > 0.5 ? inst_custom0 : vec4(0.0);\n\n    gl_Position = clipSpaceCorrMatrix * camera.viewProjection * wp;\n\n    isf_vertShaderFinish();\n}\n","Fragment":"/*{\n  \"CREDIT\": \"ossia team\",\n  \"ISFVSN\": \"2\",\n  \"MODE\": \"RAW_RASTER_PIPELINE\",\n  \"ALPHA\": \"straight\",\n  \"DESCRIPTION\": \"Full glTF metallic-roughness rasterizer for a Scene Preprocessor output: draws the whole scene in one indirect draw with every material texture (base colour, metal-rough, normal map with tangents, emissive, occlusion; texcoord sets, KHR_texture_transform, wrap modes, alpha MASK and BLEND, double-sided), the scene's lights (directional, point and spot, with range and falloff; procedural lights written by the presets/lighting CSFs included), the Environment node's ambient, exposure and linear fog, and per-instance transforms, colours and emissive from an Instancer. No image-based lighting and no shadows: a fixed Fresnel term stands in for reflections (classic_pbr_openpbr adds IBL and cascaded shadows). Output is linear HDR, so follow it with a tone mapper such as shaderlib/post-process/ToneMapping.fs. Alpha-to-coverage smooths MASK edges under MSAA; the volumetric toggle composites the presets/volumetric fog chain.\",\n  \"CATEGORIES\": [\n    \"3D\",\n    \"Scene\",\n    \"MDI\",\n    \"Textured\",\n    \"Normal-Mapped\"\n  ],\n  \"VERTEX_INPUTS\": [\n    {\n      \"TYPE\": \"vec3\",\n      \"NAME\": \"position\"\n    },\n    {\n      \"TYPE\": \"vec3\",\n      \"NAME\": \"normal\"\n    },\n    {\n      \"TYPE\": \"vec2\",\n      \"NAME\": \"texcoord_0\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"tangent\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"color_0\"\n    },\n    {\n      \"TYPE\": \"vec2\",\n      \"NAME\": \"texcoord_1\"\n    },\n    {\n      \"TYPE\": \"vec3\",\n      \"NAME\": \"inst_translation\",\n      \"SEMANTIC\": \"translation\",\n      \"REQUIRED\": false\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"inst_color0\",\n      \"SEMANTIC\": \"instance_color0\",\n      \"REQUIRED\": false\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"inst_custom0\",\n      \"SEMANTIC\": \"instance_custom0\",\n      \"REQUIRED\": false\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"inst_matrix0\",\n      \"REQUIRED\": false\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"inst_matrix1\",\n      \"REQUIRED\": false\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"inst_matrix2\",\n      \"REQUIRED\": false\n    },\n    {\n      \"TYPE\": \"uint\",\n      \"NAME\": \"draw_id\",\n      \"SEMANTIC\": \"instance_draw_id\"\n    }\n  ],\n  \"VERTEX_OUTPUTS\": [\n    {\n      \"TYPE\": \"vec3\",\n      \"NAME\": \"v_worldPos\"\n    },\n    {\n      \"TYPE\": \"vec3\",\n      \"NAME\": \"v_normal\"\n    },\n    {\n      \"TYPE\": \"vec2\",\n      \"NAME\": \"v_uv\"\n    },\n    {\n      \"TYPE\": \"uint\",\n      \"NAME\": \"v_drawID\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"v_tangent\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"v_color\"\n    },\n    {\n      \"TYPE\": \"vec2\",\n      \"NAME\": \"v_uv1\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"v_inst_color\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"v_inst_emissive\"\n    }\n  ],\n  \"FRAGMENT_INPUTS\": [\n    {\n      \"TYPE\": \"vec3\",\n      \"NAME\": \"v_worldPos\"\n    },\n    {\n      \"TYPE\": \"vec3\",\n      \"NAME\": \"v_normal\"\n    },\n    {\n      \"TYPE\": \"vec2\",\n      \"NAME\": \"v_uv\"\n    },\n    {\n      \"TYPE\": \"uint\",\n      \"NAME\": \"v_drawID\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"v_tangent\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"v_color\"\n    },\n    {\n      \"TYPE\": \"vec2\",\n      \"NAME\": \"v_uv1\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"v_inst_color\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"v_inst_emissive\"\n    }\n  ],\n  \"FRAGMENT_OUTPUTS\": [\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"isf_FragColor\"\n    }\n  ],\n  \"INPUTS\": [\n    {\n      \"NAME\": \"camera\",\n      \"TYPE\": \"uniform\",\n      \"VISIBILITY\": \"vertex+fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"view\",\n          \"TYPE\": \"mat4\"\n        },\n        {\n          \"NAME\": \"projection\",\n          \"TYPE\": \"mat4\"\n        },\n        {\n          \"NAME\": \"viewProjection\",\n          \"TYPE\": \"mat4\"\n        },\n        {\n          \"NAME\": \"cameraPosition\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"renderSize\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"params\",\n          \"TYPE\": \"vec4\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"scene_lights\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"entries\",\n          \"TYPE\": \"Light[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"scene_light_indices\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"data\",\n          \"TYPE\": \"uint[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"world_transforms\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"vertex+fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"data\",\n          \"TYPE\": \"mat4[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"scene_materials\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"entries\",\n          \"TYPE\": \"Material[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"scene_material_uv_xforms\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"entries\",\n          \"TYPE\": \"MatUVXform[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"per_draws\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"vertex+fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"data\",\n          \"TYPE\": \"PerDraw[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"indirect_draw_cmds\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"none\",\n      \"BUFFER_USAGE\": \"indirect_draw_indexed\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"cmds\",\n          \"TYPE\": \"DrawIndexedCmd[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"scene_counts\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"light_count\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"material_count\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"draw_count\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"_pad0\",\n          \"TYPE\": \"uint\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"env\",\n      \"TYPE\": \"uniform\",\n      \"VISIBILITY\": \"fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"ambient\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"fog_color_density\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"fog_range\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"exposure_gamma\",\n          \"TYPE\": \"vec4\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"alpha_a2c_enabled\",\n      \"TYPE\": \"long\",\n      \"DEFAULT\": 0,\n      \"MIN\": 0,\n      \"MAX\": 1,\n      \"LABEL\": \"Alpha-to-coverage (writes gl_SampleMask under MSAA). Best for foliage edges when MSAA is enabled. Adapts to the framebuffer sample count (1/2/4/8/16); degrades to a 0.5 binary cutoff when MSAA is off.\"\n    },\n    {\n      \"NAME\": \"volumetric_enabled\",\n      \"TYPE\": \"long\",\n      \"DEFAULT\": 0,\n      \"MIN\": 0,\n      \"MAX\": 1,\n      \"LABEL\": \"Volumetric fog composite (1=on)\",\n      \"DESCRIPTION\": \"Sample the upstream vol_integrated SSBO (built by the volumetric_inject / scatter / integrate chain) and apply finalColor = finalColor * transmittance + accum * intensity per fragment. Default off so rasterizers without the volumetric chain wired don't multiply by an unbound (zero-init) transmittance and go pure black.\"\n    },\n    {\n      \"NAME\": \"volumetric_intensity\",\n      \"TYPE\": \"float\",\n      \"DEFAULT\": 1.0,\n      \"MIN\": 0.0,\n      \"MAX\": 4.0,\n      \"LABEL\": \"Volumetric intensity\",\n      \"DESCRIPTION\": \"Scalar on the in-scattered radiance contribution. 1.0 = physical; <1 dampens the fog look; >1 over-blooms the air for stylized output. Has no effect when volumetric_enabled=0.\"\n    }\n  ],\n  \"AUXILIARY\": [\n    {\n      \"NAME\": \"scene_material_wrap\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"entries\",\n          \"TYPE\": \"uvec4[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"cluster_config\",\n      \"ACCESS\": \"read_only\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"cluster_x\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"cluster_y\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"cluster_z\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"max_lights_per_cluster\",\n          \"TYPE\": \"uint\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"vol_integrated\",\n      \"ACCESS\": \"read_only\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"data\",\n          \"TYPE\": \"FroxelIntegrated[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"materialArray0\",\n      \"TYPE\": \"image\",\n      \"IS_ARRAY\": true,\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialArray1\",\n      \"TYPE\": \"image\",\n      \"IS_ARRAY\": true,\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialArray2\",\n      \"TYPE\": \"image\",\n      \"IS_ARRAY\": true,\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialArray3\",\n      \"TYPE\": \"image\",\n      \"IS_ARRAY\": true,\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialArray4\",\n      \"TYPE\": \"image\",\n      \"IS_ARRAY\": true,\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialArray5\",\n      \"TYPE\": \"image\",\n      \"IS_ARRAY\": true,\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialArray6\",\n      \"TYPE\": \"image\",\n      \"IS_ARRAY\": true,\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialArray7\",\n      \"TYPE\": \"image\",\n      \"IS_ARRAY\": true,\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialDyn0\",\n      \"TYPE\": \"image\",\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialDyn1\",\n      \"TYPE\": \"image\",\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialDyn2\",\n      \"TYPE\": \"image\",\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialDyn3\",\n      \"TYPE\": \"image\",\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialDyn4\",\n      \"TYPE\": \"image\",\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialDyn5\",\n      \"TYPE\": \"image\",\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialDyn6\",\n      \"TYPE\": \"image\",\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialDyn7\",\n      \"TYPE\": \"image\",\n      \"WRAP\": \"repeat\"\n    }\n  ],\n  \"TYPES\": [\n    {\n      \"NAME\": \"Light\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"color\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"local_direction\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"range_cone\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"shadow_enabled\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"decay_mode\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"transform_slot\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"normal_bias\",\n          \"TYPE\": \"float\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"Material\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"baseColor\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"metallicRoughnessOcclusionUnlit\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"emissive_strength\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"textureRefs\",\n          \"TYPE\": \"uvec4\"\n        },\n        {\n          \"NAME\": \"feature_mask\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"hit_group_id\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"occlusion_textureRef\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"alpha_cutoff\",\n          \"TYPE\": \"float\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"PerDraw\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"model\",\n          \"TYPE\": \"mat4\"\n        },\n        {\n          \"NAME\": \"normal\",\n          \"TYPE\": \"mat4\"\n        },\n        {\n          \"NAME\": \"material_index\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"tag_hash\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"_pad0\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"_pad1\",\n          \"TYPE\": \"uint\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"DrawIndexedCmd\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"indexCount\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"instanceCount\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"firstIndex\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"baseVertex\",\n          \"TYPE\": \"int\"\n        },\n        {\n          \"NAME\": \"baseInstance\",\n          \"TYPE\": \"uint\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"MatUVXform\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"bc_offset_scale\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"mr_offset_scale\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"normal_offset_scale\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"em_offset_scale\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"occ_offset_scale\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"rotations0\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"rotations1\",\n          \"TYPE\": \"vec4\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"FroxelIntegrated\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"accum_transmittance\",\n          \"TYPE\": \"vec4\"\n        }\n      ]\n    }\n  ],\n  \"PIPELINE_STATE\": {\n    \"DEPTH_TEST\": true,\n    \"DEPTH_WRITE\": true,\n    \"CULL_MODE\": \"back\"\n  }\n}*/\n\n// Sample a material texture channel given its packed textureRef. Matches\n// the SceneFlattener encoding:\n//   bits 31..30 : source (0=NONE/sentinel, 1=STATIC bucket, 2=DYNAMIC slot)\n//   bits 29..23 : bucket index (0..127); the ladder below covers the\n//                 first 16 — higher bucket ids fall back.\n//   bits 23..0  : layer index within the bucket's texture array (static)\n//                 OR slot index in the channel's dynamic sampler set.\n//\n// Each channel declares `kShaderBuckets` sampler2DArrays,\n// one per bucket. Materials with textures of different (format, pixelSize)\n// tuples land in different buckets; the switch ladder below dispatches\n// to the right sampler. Scenes with a single bucket hit case 0 only —\n// all other cases compile in but never execute.\n//\n// Dynamic slots resolve to per-channel sampler2D uniforms `*Dyn0` /\n// `*Dyn1` populated by ScenePreprocessor's aux-texture path — used for\n// large runtime textures (8K video, HDR shader outputs) that can't\n// round-trip through the bucket pool.\nconst uint kShaderBuckets = 16u;\n\n// ─── Manual N-tap anisotropic sampling ──────────────────────────────\n// Qt RHI hard-codes maxAnisotropy=1.0 in every backend; there is no\n// public API to enable hardware anisotropic filtering. Workaround: do\n// it in the shader. Standard \"sum of cones\" formulation:\n//\n//   1. Compute UV gradients dx/dy. Pick the longer one as the major\n//      axis, the shorter as minor.\n//   2. The footprint is an ellipse on the texture; ratio = |major|/|minor|\n//      gives the anisotropy needed (typical value at grazing angles is\n//      4-16).\n//   3. Take 4 hardware-filtered samples spaced along the major axis,\n//      each forced to the minor-axis LOD via textureGrad(minor, minor).\n//      Average them. The minor-axis grad keeps each sample sharp; the\n//      4 spaced taps integrate over the elongated footprint.\n//\n// Shortcut: when the footprint is roughly isotropic (ratio² < 4) we\n// drop to a plain hardware texture() — the 4-tap path is wasted cost.\n//\n// Cost: ~4× texture lookups when the path triggers (only at grazing\n// angles), 1× otherwise. We apply this only to base_color and normal\n// — the channels where the user can see the difference. metallic /\n// roughness / occlusion / emissive stay on plain texture().\nvec4 anisoSample2DArray(sampler2DArray tex, vec3 uv)\n{\n    vec2 dx = dFdx(uv.xy);\n    vec2 dy = dFdy(uv.xy);\n    float lx2 = dot(dx, dx);\n    float ly2 = dot(dy, dy);\n    vec2 major, minor;\n    float ratio2;\n    if(lx2 > ly2)\n    {\n        major = dx; minor = dy;\n        ratio2 = lx2 / max(ly2, 1e-12);\n    }\n    else\n    {\n        major = dy; minor = dx;\n        ratio2 = ly2 / max(lx2, 1e-12);\n    }\n    if(ratio2 < 4.0) return texture(tex, uv);\n\n    // 4 taps at -3/8, -1/8, 1/8, 3/8 of the major axis (uniform spacing,\n    // mean-zero, covers the elongated footprint without touching the\n    // tile borders that a -1/2..1/2 spacing would).\n    float layer = uv.z;\n    vec4 s0 = textureGrad(tex, vec3(uv.xy + major * -0.375, layer), minor, minor);\n    vec4 s1 = textureGrad(tex, vec3(uv.xy + major * -0.125, layer), minor, minor);\n    vec4 s2 = textureGrad(tex, vec3(uv.xy + major *  0.125, layer), minor, minor);\n    vec4 s3 = textureGrad(tex, vec3(uv.xy + major *  0.375, layer), minor, minor);\n    return (s0 + s1 + s2 + s3) * 0.25;\n}\nvec4 anisoSample2DArraySep(texture2DArray tex, sampler smp, vec3 uv)\n{\n    vec2 dx = dFdx(uv.xy);\n    vec2 dy = dFdy(uv.xy);\n    float lx2 = dot(dx, dx);\n    float ly2 = dot(dy, dy);\n    vec2 major, minor;\n    float ratio2;\n    if(lx2 > ly2)\n    {\n        major = dx; minor = dy;\n        ratio2 = lx2 / max(ly2, 1e-12);\n    }\n    else\n    {\n        major = dy; minor = dx;\n        ratio2 = ly2 / max(lx2, 1e-12);\n    }\n    if(ratio2 < 4.0) return texture(sampler2DArray(tex, smp), uv);\n\n    // 4 taps at -3/8, -1/8, 1/8, 3/8 of the major axis (uniform spacing,\n    // mean-zero, covers the elongated footprint without touching the\n    // tile borders that a -1/2..1/2 spacing would).\n    float layer = uv.z;\n    vec4 s0 = textureGrad(sampler2DArray(tex, smp), vec3(uv.xy + major * -0.375, layer), minor, minor);\n    vec4 s1 = textureGrad(sampler2DArray(tex, smp), vec3(uv.xy + major * -0.125, layer), minor, minor);\n    vec4 s2 = textureGrad(sampler2DArray(tex, smp), vec3(uv.xy + major *  0.125, layer), minor, minor);\n    vec4 s3 = textureGrad(sampler2DArray(tex, smp), vec3(uv.xy + major *  0.375, layer), minor, minor);\n    return (s0 + s1 + s2 + s3) * 0.25;\n}\n\nvec4 anisoSample2D(sampler2D tex, vec2 uv)\n{\n    vec2 dx = dFdx(uv);\n    vec2 dy = dFdy(uv);\n    float lx2 = dot(dx, dx);\n    float ly2 = dot(dy, dy);\n    vec2 major, minor;\n    float ratio2;\n    if(lx2 > ly2)\n    {\n        major = dx; minor = dy;\n        ratio2 = lx2 / max(ly2, 1e-12);\n    }\n    else\n    {\n        major = dy; minor = dx;\n        ratio2 = ly2 / max(lx2, 1e-12);\n    }\n    if(ratio2 < 4.0) return texture(tex, uv);\n\n    vec4 s0 = textureGrad(tex, uv + major * -0.375, minor, minor);\n    vec4 s1 = textureGrad(tex, uv + major * -0.125, minor, minor);\n    vec4 s2 = textureGrad(tex, uv + major *  0.125, minor, minor);\n    vec4 s3 = textureGrad(tex, uv + major *  0.375, minor, minor);\n    return (s0 + s1 + s2 + s3) * 0.25;\n}\nvec4 anisoSample2DSep(texture2D tex, sampler smp, vec2 uv)\n{\n    vec2 dx = dFdx(uv);\n    vec2 dy = dFdy(uv);\n    float lx2 = dot(dx, dx);\n    float ly2 = dot(dy, dy);\n    vec2 major, minor;\n    float ratio2;\n    if(lx2 > ly2)\n    {\n        major = dx; minor = dy;\n        ratio2 = lx2 / max(ly2, 1e-12);\n    }\n    else\n    {\n        major = dy; minor = dx;\n        ratio2 = ly2 / max(lx2, 1e-12);\n    }\n    if(ratio2 < 4.0) return texture(sampler2D(tex, smp), uv);\n\n    vec4 s0 = textureGrad(sampler2D(tex, smp), uv + major * -0.375, minor, minor);\n    vec4 s1 = textureGrad(sampler2D(tex, smp), uv + major * -0.125, minor, minor);\n    vec4 s2 = textureGrad(sampler2D(tex, smp), uv + major *  0.125, minor, minor);\n    vec4 s3 = textureGrad(sampler2D(tex, smp), uv + major *  0.375, minor, minor);\n    return (s0 + s1 + s2 + s3) * 0.25;\n}\n\n// One decoder for every material channel. The pool is shared, so the bucket\n// field of the ref is all that picks the array -- including its colourspace,\n// which is part of the bucket key rather than of the channel.\n// Per-texture wrap modes from scene_material_wrap, loaded once per fragment\n// from the material's entry. Four bits per texture ref: wrap_s in the low two,\n// wrap_t in the high two; 0 = repeat, 1 = clamp to edge, 2 = mirror. Slots\n// 0..4 are the main refs (base colour, metal-rough, normal, emissive,\n// occlusion), 5.. the extension refs in MaterialExt.textureRefs order. The\n// pool samples every array with one repeat sampler, so a non-repeat mode is\n// applied to the coordinate here.\nuvec3 g_matWrap = uvec3(0u);\nuint matWrap(uint slot)\n{\n    if(slot < 5u) return (g_matWrap.x >> (4u * slot)) & 0xFu;\n    uint e = slot - 5u;\n    uint word = e < 8u ? g_matWrap.y : g_matWrap.z;\n    return (word >> (4u * (e & 7u))) & 0xFu;\n}\nfloat wrapAxis(float x, uint mode, float halfTexel)\n{\n    if(mode == 1u) return clamp(x, halfTexel, 1.0 - halfTexel);\n    if(mode == 2u) { float t = mod(x, 2.0); return t > 1.0 ? 2.0 - t : t; }\n    return x;\n}\nvec2 applyWrap(vec2 uv, uint wrap, vec2 halfTexel)\n{\n    return vec2(wrapAxis(uv.x, wrap & 3u, halfTexel.x),\n                wrapAxis(uv.y, (wrap >> 2u) & 3u, halfTexel.y));\n}\n// Clamping stays inside the edge texel of the coarsest mip level the\n// trilinear filter reads, so a minified clamped texture does not bleed across\n// the repeat sampler's seam.\nvec2 wrapInset(texture2DArray tex, sampler smp, vec2 dx, vec2 dy)\n{\n    vec2 sz = vec2(textureSize(sampler2DArray(tex, smp), 0).xy);\n    float lod = max(0.0, log2(max(length(dx * sz), length(dy * sz))));\n    return min(vec2(0.5), 0.5 * exp2(ceil(lod)) / sz);\n}\n// anisoSample2DArray's wrapped counterpart. A single trilinear tap whose\n// gradients come from the unwrapped coordinate, so a mirror fold or a clamp\n// edge does not spike the mip selection; repeat, the common case, keeps the\n// anisotropic path untouched.\nvec4 anisoSample2DArrayWrapped(texture2DArray tex, sampler smp, vec3 uv, uint wrap)\n{\n    if(wrap == 0u) return anisoSample2DArraySep(tex, smp, uv);\n    vec2 dx = dFdx(uv.xy);\n    vec2 dy = dFdy(uv.xy);\n    return textureGrad(sampler2DArray(tex, smp),\n                       vec3(applyWrap(uv.xy, wrap, wrapInset(tex, smp, dx, dy)), uv.z),\n                       dx, dy);\n}\n\n\nvec4 sample_material_slot(uint ref, uint wrap, vec2 uv, vec4 fallback)\n{\n    if(ref == 0xFFFFFFFFu) return fallback;\n    uint source = (ref >> 30) & 3u;\n    uint bucket = (ref >> 23) & 0x7Fu;\n    uint idx    = ref & 0x007FFFFFu;\n    if(source == 2u)\n    {\n        switch(idx)\n        {\n            case 0u: return anisoSample2DSep(materialDyn_tex[0], materialDyn_smp, uv);\n            case 1u: return anisoSample2DSep(materialDyn_tex[1], materialDyn_smp, uv);\n            case 2u: return anisoSample2DSep(materialDyn_tex[2], materialDyn_smp, uv);\n            case 3u: return anisoSample2DSep(materialDyn_tex[3], materialDyn_smp, uv);\n            case 4u: return anisoSample2DSep(materialDyn_tex[4], materialDyn_smp, uv);\n            case 5u: return anisoSample2DSep(materialDyn_tex[5], materialDyn_smp, uv);\n            case 6u: return anisoSample2DSep(materialDyn_tex[6], materialDyn_smp, uv);\n            case 7u: return anisoSample2DSep(materialDyn_tex[7], materialDyn_smp, uv);\n        }\n        return fallback;\n    }\n    switch(bucket)\n    {\n        case 0u: return anisoSample2DArrayWrapped(materialArray_tex[0], materialArray_smp, vec3(uv, float(idx)), wrap);\n        case 1u: return anisoSample2DArrayWrapped(materialArray_tex[1], materialArray_smp, vec3(uv, float(idx)), wrap);\n        case 2u: return anisoSample2DArrayWrapped(materialArray_tex[2], materialArray_smp, vec3(uv, float(idx)), wrap);\n        case 3u: return anisoSample2DArrayWrapped(materialArray_tex[3], materialArray_smp, vec3(uv, float(idx)), wrap);\n        case 4u: return anisoSample2DArrayWrapped(materialArray_tex[4], materialArray_smp, vec3(uv, float(idx)), wrap);\n        case 5u: return anisoSample2DArrayWrapped(materialArray_tex[5], materialArray_smp, vec3(uv, float(idx)), wrap);\n        case 6u: return anisoSample2DArrayWrapped(materialArray_tex[6], materialArray_smp, vec3(uv, float(idx)), wrap);\n        case 7u: return anisoSample2DArrayWrapped(materialArray_tex[7], materialArray_smp, vec3(uv, float(idx)), wrap);\n    }\n    return fallback;\n}\n\nvec4 sample_slot_bc(uint ref, uint wrap, vec2 uv, vec4 fallback)\n{\n    return sample_material_slot(ref, wrap, uv, fallback);\n}\n\n\nvec4 sample_slot_mr(uint ref, uint wrap, vec2 uv, vec4 fallback)\n{\n    return sample_material_slot(ref, wrap, uv, fallback);\n}\n\n\nvec4 sample_slot_nrm(uint ref, uint wrap, vec2 uv, vec4 fallback)\n{\n    return sample_material_slot(ref, wrap, uv, fallback);\n}\n\n\nvec4 sample_slot_em(uint ref, uint wrap, vec2 uv, vec4 fallback)\n{\n    return sample_material_slot(ref, wrap, uv, fallback);\n}\n\n\n// Separate glTF occlusionTexture (single-channel data, R = occlusion).\n// Sampled only when feature_mask carries `has_separate_occlusion`;\n// otherwise the main path falls back to MR.r per the common packed-MR\n// convention. fallback = 1 → identity (no occlusion).\nvec4 sample_slot_occ(uint ref, uint wrap, vec2 uv, vec4 fallback)\n{\n    return sample_material_slot(ref, wrap, uv, fallback);\n}\n\n\n// glTF feature_mask bits — must mirror SceneGPUState.hpp's\n// material_feature namespace.\nconst uint kFeat_alpha_mask           = 1u << 16u;\nconst uint kFeat_alpha_blend          = 1u << 17u;\nconst uint kFeat_double_sided         = 1u << 18u;\nconst uint kFeat_has_separate_occ     = 1u << 19u;\n// Per-channel texcoord_set bits (20-29). 2 bits per channel, value\n// 0 = TEXCOORD_0, value 1 = TEXCOORD_1. Out-of-range values collapse\n// to TEXCOORD_0 (the shift-mask in packMaterial clamps to 0/1).\nconst uint kFeat_tcset_bc_shift       = 20u;\nconst uint kFeat_tcset_mr_shift       = 22u;\nconst uint kFeat_tcset_nrm_shift      = 24u;\nconst uint kFeat_tcset_em_shift       = 26u;\nconst uint kFeat_tcset_occ_shift      = 28u;\n\nvec2 pick_uv(uint feature_mask, uint shift, vec2 uv0, vec2 uv1)\n{\n    return ((feature_mask >> shift) & 0x3u) == 1u ? uv1 : uv0;\n}\n\n// KHR_texture_transform helper: glTF defines the transform in UV space\n// as `uv' = R(rotation) * S(scale) * uv + offset`, with rotation\n// applied AFTER scale and BEFORE the offset shift. Identity defaults\n// (offset=0, scale=1, rotation=0) pass through unchanged.\nvec2 apply_uv_xform(vec2 uv, vec4 offset_scale, float rotation)\n{\n    vec2 scaled = uv * offset_scale.zw;\n    float c = cos(rotation), s = sin(rotation);\n    vec2 rotated = vec2(c * scaled.x - s * scaled.y,\n                        s * scaled.x + c * scaled.y);\n    return rotated + offset_scale.xy;\n}\n\n// Shader-level alpha-to-coverage. QRhi (6.12) doesn't expose\n// AlphaToCoverage on QRhiGraphicsPipeline, so we replicate the\n// behaviour at the shader level: gl_SampleMask[0] is a writable\n// per-fragment built-in where each bit selects whether the\n// corresponding MSAA sample is written. Convert alpha to a sample\n// count, set that many bits, screen-space-rotate per pixel so the\n// MSAA resolve smooths the silhouette into a soft edge.\n//\n// Sample count comes from MSAA_SAMPLES, an integer auto-injected by\n// libisf into the renderer UBO at binding=0 — score writes the active\n// RenderList's sample count there each frame. (We can't use\n// gl_NumSamples: glslang strips it when targeting SPIR-V.) Score lets\n// users pick any of {1, 2, 4, 8, 16}. With MSAA off, MSAA_SAMPLES=1\n// and we degrade to a 0.5 binary cutoff. Vulkan caps multisample\n// rasterization at 16x in practice; clamp there so the rotation math\n// stays defined for 32-bit uints.\n//\n// Returns false when the fragment is fully transparent → caller\n// discards (early-out skips the rest of main()).\nbool applyAlphaToCoverage(float alpha)\n{\n    if(alpha <= 0.0)\n        return false;\n\n    int samples = clamp(MSAA_SAMPLES, 1, 16);\n    uint full = (samples >= 32) ? 0xFFFFFFFFu\n                                : ((1u << uint(samples)) - 1u);\n\n    if(alpha >= 1.0)\n    {\n        gl_SampleMask[0] = int(full);\n        return true;\n    }\n    int n = int(round(alpha * float(samples)));\n    if(n <= 0)\n        return false;\n    if(n >= samples)\n    {\n        gl_SampleMask[0] = int(full);\n        return true;\n    }\n\n    // MSAA sample counts are powers of two, so (S-1) is a valid mask.\n    // shift lands in [0, S-1]; rotation handles shift==0 cleanly\n    // because base >> S is well-defined for S<=16 (< 32 bits).\n    uint S = uint(samples);\n    uint hash = uint(gl_FragCoord.x) * 1597u\n              + uint(gl_FragCoord.y) * 2731u;\n    uint shift = hash & (S - 1u);\n    uint base  = (1u << uint(n)) - 1u;\n    uint rot   = ((base << shift) | (base >> (S - shift))) & full;\n    gl_SampleMask[0] = int(rot);\n    return true;\n}\n\n// Map gl_FragCoord + view-space Z to a froxel index. Same log-spaced Z\n// slicing build_cluster_aabbs.csf uses, same (z*Y + y)*X + x flattening\n// volumetric_integrate.csf writes — keep these three formulas in sync\n// or sampling lands in the wrong cell.\nuint scoreClusterId(vec2 fragCoord, float viewZ)\n{\n    vec2 uv = fragCoord / camera.renderSize.xy;\n    uint gx = cluster_config.cluster_x;\n    uint gy = cluster_config.cluster_y;\n    uint gz = cluster_config.cluster_z;\n\n    uint tx = uint(clamp(floor(uv.x * float(gx)), 0.0, float(gx) - 1.0));\n    uint ty = uint(clamp(floor(uv.y * float(gy)), 0.0, float(gy) - 1.0));\n\n    float zNear = camera.params.y;\n    float zFar  = camera.params.z;\n    float depth = max(-viewZ, zNear);\n    float t = float(gz) * log(depth / zNear) / log(zFar / zNear);\n    uint tz = uint(clamp(t, 0.0, float(gz) - 1.0));\n\n    return (tz * gy + ty) * gx + tx;\n}\n\n// Inline volumetric fog composite — see classic_pbr_openpbr.frag for\n// the full rationale. Two production-grade refinements vs the naive\n// nearest-cell lookup:\n//   1. Trilinear interpolation across the 8 surrounding froxels —\n//      hides the cluster grid (16x9x24 default) which otherwise\n//      shows up as a hard checkerboard at cell boundaries.\n//   2. volumetric_intensity blends toward identity rather than just\n//      scaling accum, so low intensity == \"less fog\" rather than\n//      \"no source + tiny in-scatter\".\n// Identity fallback when the toggle is off or cluster_x == 0u.\nvec3 applyVolumetric(vec3 inColor, vec2 fragCoord, float viewZ)\n{\n    if(volumetric_enabled == 0)\n        return inColor;\n\n    uint gx = cluster_config.cluster_x;\n    uint gy = cluster_config.cluster_y;\n    uint gz = cluster_config.cluster_z;\n    if(gx == 0u || gy == 0u || gz == 0u)\n        return inColor;\n\n    vec2  uv = fragCoord / camera.renderSize.xy;\n    float zNear = camera.params.y;\n    float zFar  = camera.params.z;\n    float depth = max(-viewZ, zNear);\n    float fx = uv.x * float(gx) - 0.5;\n    float fy = uv.y * float(gy) - 0.5;\n    float fz = float(gz) * log(depth / zNear) / log(zFar / zNear) - 0.5;\n\n    vec3 cf = clamp(vec3(fx, fy, fz), vec3(0.0),\n                    vec3(float(gx) - 1.0001,\n                         float(gy) - 1.0001,\n                         float(gz) - 1.0001));\n    vec3 cb = floor(cf);\n    vec3 t  = cf - cb;\n    uvec3 i0 = uvec3(cb);\n    uvec3 i1 = min(i0 + 1u, uvec3(gx - 1u, gy - 1u, gz - 1u));\n\n    #define IDX(ix, iy, iz) (((iz) * gy + (iy)) * gx + (ix))\n    vec4 c000 = vol_integrated.data[IDX(i0.x, i0.y, i0.z)].accum_transmittance;\n    vec4 c100 = vol_integrated.data[IDX(i1.x, i0.y, i0.z)].accum_transmittance;\n    vec4 c010 = vol_integrated.data[IDX(i0.x, i1.y, i0.z)].accum_transmittance;\n    vec4 c110 = vol_integrated.data[IDX(i1.x, i1.y, i0.z)].accum_transmittance;\n    vec4 c001 = vol_integrated.data[IDX(i0.x, i0.y, i1.z)].accum_transmittance;\n    vec4 c101 = vol_integrated.data[IDX(i1.x, i0.y, i1.z)].accum_transmittance;\n    vec4 c011 = vol_integrated.data[IDX(i0.x, i1.y, i1.z)].accum_transmittance;\n    vec4 c111 = vol_integrated.data[IDX(i1.x, i1.y, i1.z)].accum_transmittance;\n    #undef IDX\n\n    vec4 v = mix(mix(mix(c000, c100, t.x), mix(c010, c110, t.x), t.y),\n                 mix(mix(c001, c101, t.x), mix(c011, c111, t.x), t.y),\n                 t.z);\n\n    float transm = clamp(v.a, 0.0, 1.0);\n    vec3  accum  = v.rgb;\n\n    float k       = volumetric_intensity;\n    float k_blend = clamp(k, 0.0, 1.0);\n    float transm_eff = mix(1.0, transm, k_blend);\n    vec3  accum_eff  = accum * k;\n\n    return inColor * transm_eff + accum_eff;\n}\n\nvoid main()\n{\n    // Default coverage: keep every MSAA sample. Once applyAlphaToCoverage\n    // exists in the module, the SPIR-V output declares gl_SampleMask, and\n    // any path that doesn't assign it leaves the value undefined — most\n    // drivers default that to 0 and cull every sample, producing block-\n    // speckle artifacts on non-alpha-mask materials. Seeding to all-ones\n    // here makes the non-A2C paths render correctly; the A2C branch\n    // overrides this for masked fragments.\n    gl_SampleMask[0] = -1;\n\n    PerDraw pd = per_draws.data[v_drawID];\n    Material mat = scene_materials.entries[pd.material_index];\n    MatUVXform mx = scene_material_uv_xforms.entries[pd.material_index];\n    g_matWrap = scene_material_wrap.entries[pd.material_index].xyz;\n\n    // glTF doubleSided: pipeline-side culling is OFF (cull_mode=none\n    // in the MDI batch) so we get both faces. For SINGLE-sided materials\n    // we discard back-facing fragments here to mimic CULL_BACK. For\n    // DOUBLE-sided materials we keep the fragment and flip the normal\n    // below so lighting on the back side works correctly.\n    bool is_double_sided = (mat.feature_mask & kFeat_double_sided) != 0u;\n    if(!is_double_sided && !gl_FrontFacing)\n        discard;\n\n    // Pick the per-channel texcoord source (TEXCOORD_0 vs TEXCOORD_1)\n    // before applying the KHR_texture_transform. glTF allows each\n    // texture_info to override its texcoord_set independently — BC\n    // might use TEXCOORD_0 while Emissive uses TEXCOORD_1, etc.\n    vec2 base_uv_bc  = pick_uv(mat.feature_mask, kFeat_tcset_bc_shift,  v_uv, v_uv1);\n    vec2 base_uv_mr  = pick_uv(mat.feature_mask, kFeat_tcset_mr_shift,  v_uv, v_uv1);\n    vec2 base_uv_nrm = pick_uv(mat.feature_mask, kFeat_tcset_nrm_shift, v_uv, v_uv1);\n    vec2 base_uv_em  = pick_uv(mat.feature_mask, kFeat_tcset_em_shift,  v_uv, v_uv1);\n    vec2 base_uv_occ = pick_uv(mat.feature_mask, kFeat_tcset_occ_shift, v_uv, v_uv1);\n\n    // Per-channel UVs after KHR_texture_transform.\n    vec2 uv_bc  = apply_uv_xform(base_uv_bc,  mx.bc_offset_scale,     mx.rotations0.x);\n    vec2 uv_mr  = apply_uv_xform(base_uv_mr,  mx.mr_offset_scale,     mx.rotations0.y);\n    vec2 uv_nrm = apply_uv_xform(base_uv_nrm, mx.normal_offset_scale, mx.rotations0.z);\n    vec2 uv_em  = apply_uv_xform(base_uv_em,  mx.em_offset_scale,     mx.rotations0.w);\n    vec2 uv_occ = apply_uv_xform(base_uv_occ, mx.occ_offset_scale,    mx.rotations1.x);\n\n    // Pre-pull env knobs so the early-out (unlit) and main path both\n    // see the same values. Defaults come from EnvironmentLoader if the\n    // user wired one; otherwise the merged scene_environment carries\n    // safe identity-ish values (ambient=0, exposure=1, gamma=2.2,\n    // fog disabled).\n    vec3  ambient_col   = env.ambient.rgb * env.ambient.w;\n    float exposure_mul  = max(env.exposure_gamma.x, 1e-6);\n    float gamma         = max(env.exposure_gamma.y, 1e-3);\n\n    // ─── Base color ────────────────────────────────────────────────────\n    // glTF: final base = baseColorFactor × baseColorTexture × COLOR_0\n    // (vertex color). v_color defaults to white when the mesh doesn't\n    // have COLOR_0 (slab uploader fills with vec4(1) in that case).\n    vec4 bc = sample_slot_bc(mat.textureRefs.x, matWrap(0u), uv_bc, vec4(1.0));\n\n    // Alpha-mask edge-bleed compensation. Source PNGs for foliage / hair\n    // / fence-style cutouts have alpha=0 in transparent regions with\n    // RGB=0 there too (standard authoring). Mip / aniso filtering\n    // averages RGB and alpha independently — near a leaf edge the\n    // sampled RGB ends up `leaf_color × alpha_avg`, so post-alpha-test\n    // surviving fragments read a darkened RGB and the silhouette gets a\n    // black halo. Dividing RGB by alpha inverts the alpha-weighted\n    // averaging and recovers the source colour. Skip when alpha is near\n    // zero (would discard anyway) and when the material isn't\n    // alpha-masked (BLEND / OPAQUE both want the literal sampled RGB).\n    if((mat.feature_mask & kFeat_alpha_mask) != 0u && bc.a > 1e-3)\n        bc.rgb /= bc.a;\n\n    // Per-instance broadcast colour rides through `v_inst_color` from\n    // the vertex stage. For non-instanced draws the REQUIRED:false\n    // fallback fires identity (1,1,1,1) so the modulation collapses\n    // to the per-vertex × material × baseColor product.\n    vec3 base = mat.baseColor.rgb * bc.rgb * v_color.rgb * v_inst_color.rgb;\n    float alpha = mat.baseColor.a * bc.a * v_color.a * v_inst_color.a;\n\n    // glTF alphaMode=MASK — early discard before any expensive work.\n    // Two paths:\n    //   alpha_a2c_enabled = 1 → shader-level alpha-to-coverage via\n    //                            gl_SampleMask. Best edge quality when\n    //                            MSAA is on; degrades gracefully to a\n    //                            hard cutoff when MSAA is off (round\n    //                            saturates to 0 / 8).\n    //   default               → classic binary cutoff.\n    if((mat.feature_mask & kFeat_alpha_mask) != 0u)\n    {\n        if(alpha_a2c_enabled != 0)\n        {\n            if(!applyAlphaToCoverage(alpha))\n                discard;\n        }\n        else\n        {\n            if(alpha < mat.alpha_cutoff)\n                discard;\n        }\n    }\n\n    // ─── Metal-Rough-Occlusion (glTF packing: R=occ, G=rough, B=metal) ─\n    vec4 mr = sample_slot_mr(mat.textureRefs.y, matWrap(1u), uv_mr, vec4(1.0, 1.0, 1.0, 1.0));\n    float metallic\n        = mat.metallicRoughnessOcclusionUnlit.x * mr.b;\n    float roughness\n        = clamp(mat.metallicRoughnessOcclusionUnlit.y * mr.g, 0.04, 1.0);\n    // Occlusion: prefer separate occlusionTexture when set; else fall\n    // back to MR.r (the common packed-MR convention).\n    float occ_sample;\n    if((mat.feature_mask & kFeat_has_separate_occ) != 0u)\n        occ_sample = sample_slot_occ(mat.occlusion_textureRef, matWrap(4u), uv_occ, vec4(1.0)).r;\n    else\n        occ_sample = mr.r;\n    float occlusion = occ_sample * mat.metallicRoughnessOcclusionUnlit.z;\n    float unlit     = mat.metallicRoughnessOcclusionUnlit.w;\n\n    // ─── Emissive ─────────────────────────────────────────────────────\n    vec4 em = sample_slot_em(mat.textureRefs.w, matWrap(3u), uv_em, vec4(1.0));\n    vec3 emissive\n        = mat.emissive_strength.xyz * em.rgb * mat.emissive_strength.w;\n    emissive += v_inst_emissive.rgb;\n\n    if(unlit > 0.5)\n    {\n        // Volumetric composite BEFORE exposure_mul — accum is in raw\n        // light units (same scale as the BSDF result), so both sides\n        // of `inColor * transm + accum` stay in matched units.\n        // Output is linear HDR — the downstream tonemap owns the\n        // HDR→display compression and sRGB encode. (Doing pow(_,1/gamma)\n        // here would clip everything > 1 post-exposure to flat white\n        // before the tonemap could read the HDR signal — that's what\n        // made volumetric in-scatter blow out to saturated pink.)\n        vec3 color = base + emissive;\n        float viewZ_unlit = (camera.view * vec4(v_worldPos, 1.0)).z;\n        color = applyVolumetric(color, gl_FragCoord.xy, viewZ_unlit);\n        color *= exposure_mul;\n        isf_FragColor = vec4(max(color, vec3(0.0)), (mat.feature_mask & (1u << 17u)) != 0u ? alpha : 1.0);\n        return;\n    }\n\n    // ─── Surface normal (tangent-space normal map if present) ─────────\n    vec3 N = normalize(v_normal);\n    // Double-sided: flip the surface normal for back-facing fragments\n    // so the BRDF evaluates with the correct hemisphere on both sides\n    // of the surface. (Single-sided materials never reach here for\n    // back faces — they were discarded above.)\n    if(is_double_sided && !gl_FrontFacing)\n        N = -N;\n    // Toksvig variance accumulator (Olano-Baker 2010). Captures the\n    // amount of normal-map variance lost to mip-level averaging /\n    // multi-tap anisotropic averaging — info the GPU's bilinear+mip\n    // filter normally throws away when shaders re-normalize sampled\n    // normals. Folded into the specular-AA block below alongside the\n    // screen-space (Tokuyoshi-Kaplanyan) variance.\n    float toksvig_sigma2 = 0.0;\n    uint normRef = mat.textureRefs.z;\n    if(normRef != 0xFFFFFFFFu && length(v_tangent.xyz) > 0.5)\n    {\n        vec3 T = normalize(v_tangent.xyz);\n        vec3 B = normalize(cross(N, T) * v_tangent.w);\n        mat3 TBN = mat3(T, B, N);\n        // Normal map sampling goes through the bucket ladder so\n        // mixed-resolution / compressed normal atlases work. The\n        // default (0.5,0.5,1.0) fallback decodes to a zero tangent-\n        // space delta — same as no normal map at all — if the bucket\n        // slot isn't populated.\n        //\n        // Keep the UN-NORMALIZED sample so its length can drive the\n        // Toksvig boost: anisoSample averages multiple weighted taps\n        // and mip filtering averages within texels, both of which\n        // shorten |n| when sub-pixel normals had directional spread.\n        // (1 - |n|²) is the \"lost variance\" added back as roughness.\n        vec3 nm_raw = sample_slot_nrm(normRef, matWrap(2u), uv_nrm,\n                                      vec4(0.5, 0.5, 1.0, 1.0)).xyz\n                      * 2.0 - 1.0;\n        toksvig_sigma2 = max(0.0, 1.0 - dot(nm_raw, nm_raw));\n        N = normalize(TBN * normalize(nm_raw));\n    }\n\n    vec3 V = normalize(camera.cameraPosition.xyz - v_worldPos);\n    float NdotV = max(dot(N, V), 1e-4);\n\n    // Metallic workflow.\n    vec3 F0 = mix(vec3(0.04), base, metallic);\n    vec3 kd = (1.0 - metallic) * base;\n\n    // Cheap environment term — same \"fake IBL\" as classic_pbr_textured;\n    // classic_pbr_ibl is the cubemap-sampled variant.\n    vec3 Fv = F0 + (1.0 - F0) * pow(1.0 - NdotV, 5.0);\n    vec3 fake_env = Fv * base * 0.25;\n\n    // Ambient comes from EnvironmentLoader (env.ambient.rgb × intensity\n    // in .w). When the user hasn't wired one, ambient_col is zero and\n    // the fake_env term + lights carry the lighting. The 0.04 floor is\n    // gone — letting users actually dial ambient down to black.\n    vec3 result = ambient_col * base * occlusion\n                  + emissive\n                  + fake_env * occlusion;\n\n    float alpha_g = max(roughness * roughness, 1e-4);\n    float alpha2 = alpha_g * alpha_g;\n    float k = (roughness + 1.0) * (roughness + 1.0) / 8.0;\n\n    // ─── Specular antialiasing — Tokuyoshi-Kaplanyan + Toksvig ───────\n    //\n    // Three variance sources combined into a single roughness boost:\n    //\n    //   (A) Tokuyoshi-Kaplanyan 2019, \"Improved Geometric Specular\n    //       Antialiasing\" — screen-space derivatives of the world-\n    //       space normal. Captures sub-pixel-footprint normal\n    //       variance from geometry, normal-map silhouettes, and\n    //       interpolation across neighbours.\n    //\n    //   (B) Toksvig 2005, \"Mipmapping Normal Maps\" — texture-space\n    //       variance from filtered-normal shortening. Captures\n    //       variance lost to mip averaging + our multi-tap\n    //       anisotropic sampler that the GPU's linear filter and\n    //       shader's normalize() throw away.\n    //\n    //   (C) Grazing-angle amplification — a heuristic 1/NdotV scale\n    //       (capped) on the screen-space variance, approximating\n    //       Tokuyoshi-Kaplanyan's anisotropic Jacobian projection of\n    //       normal variance onto the half-vector tangent plane. The\n    //       full anisotropic form derives this matrix-multiply\n    //       explicitly; the 1/NdotV scalar captures the leading-\n    //       order behaviour at grazing where the BRDF stretches\n    //       most. Targets the \"noisy floor at grazing light\"\n    //       failure mode: at grazing, the half-vector becomes\n    //       perpendicular to the surface, NdotH gets small, and the\n    //       GGX D term's denominator hyperbola makes small N\n    //       variations move the highlight in/out of pixels.\n    //\n    // (A)+(B) cover variance from BOTH variance domains — the\n    // screen-space and texture-space sources are independent and\n    // additive. (C) amplifies (A) where the BRDF Jacobian demands it.\n    vec3 dNdx = dFdx(N);\n    vec3 dNdy = dFdy(N);\n    float kernelRoughness2 = 2.0 * (dot(dNdx, dNdx) + dot(dNdy, dNdy));\n\n    // (C) grazing amplification. NdotV floor of 0.05 prevents\n    // runaway at near-tangent view; cap at 8× keeps the boost\n    // bounded so we don't blow specular into pure diffuse.\n    float grazing_aa = clamp(1.0 / max(NdotV, 0.05), 1.0, 8.0);\n    kernelRoughness2 *= grazing_aa;\n\n    // Combine (A)·grazing + (B). Cap to keep alpha² in [0, 1] after\n    // the boost; 0.5 is the standard upper bound used by Filament +\n    // the Tokuyoshi-Kaplanyan reference.\n    const float specAaSigma2Max = 0.5;\n    float total_aa_sigma2 = clamp(kernelRoughness2 + toksvig_sigma2,\n                                  0.0, specAaSigma2Max);\n    alpha2 = clamp(alpha2 + total_aa_sigma2, 0.0, 1.0);\n    alpha_g = sqrt(alpha2);\n    // Re-derive Schlick-Smith k from the filtered roughness too so the\n    // G term widens in lockstep with D — otherwise rough-but-filtered\n    // surfaces still get an over-tight visibility term.\n    float roughness_f = sqrt(alpha_g);\n    k = (roughness_f + 1.0) * (roughness_f + 1.0) / 8.0;\n\n    uint n = scene_counts.light_count;\n    for(uint i = 0u; i < n; ++i)\n    {\n        uint slot = scene_light_indices.data[i];\n        Light L = scene_lights.entries[slot];\n\n        // Two paths for resolving the light's world-space placement:\n        //\n        //   transform_slot == 0xFFFFFFFF (sentinel):\n        //     The light was authored procedurally (e.g. by a compute CSF\n        //     reading a point cloud or particle system) and carries its\n        //     world position inline in local_direction.xyz. Skip the\n        //     world_transforms lookup — there's no matching scene-node\n        //     entry. Only point lights (type == 1) are well-defined\n        //     under this convention; directional with sentinel falls\n        //     back to treating .xyz as a direction, spot is unsupported.\n        //\n        //   transform_slot != sentinel:\n        //     Classic scene-node-attached light. World direction and\n        //     position come from the node's accumulated world transform\n        //     (published by ScenePreprocessor's FlattenVisitor).\n        float _type_f = L.local_direction.w;\n        vec3 ld_world;\n        vec3 lp_world;\n        if(L.transform_slot == 0xFFFFFFFFu)\n        {\n            if(_type_f < 0.5)\n            {\n                // Directional: .xyz is the world direction (same\n                // convention the scene-node path uses — no transform to\n                // apply since the light isn't parented to any node).\n                ld_world = normalize(L.local_direction.xyz);\n                lp_world = vec3(0.0);\n            }\n            else\n            {\n                // Point: .xyz is the world position. A default direction\n                // lets spot-cone code below degenerate gracefully for\n                // spot lights authored this way (cone attenuation will\n                // be effectively wide-open, since we have no real axis).\n                lp_world = L.local_direction.xyz;\n                ld_world = vec3(0.0, -1.0, 0.0);\n            }\n        }\n        else\n        {\n            mat4 W = world_transforms.data[L.transform_slot];\n            ld_world = normalize(mat3(W) * L.local_direction.xyz);\n            lp_world = W[3].xyz;\n        }\n        // Reconstruct the old LightGPU-shape vec4s so the BRDF body\n        // below (which references pos_type / color_i / dir_r) stays\n        // unchanged. type enum stays in .w; for directional lights the\n        // xyz holds the world direction, for point/spot it holds the\n        // world position — matching the prior packLight convention.\n        vec4 pos_type = vec4(\n            (_type_f < 0.5) ? ld_world : lp_world,\n            _type_f);\n        vec4 color_i  = L.color;\n        vec4 dir_r    = vec4(ld_world, L.range_cone.x);\n\n        vec3 Ldir;\n        float atten = 1.0;\n        if(pos_type.w < 0.5)\n        {\n            // Directional: no distance, no decay — per glTF / OpenPBR\n            // convention the 1/d² term doesn't apply.\n            Ldir = normalize(-pos_type.xyz);\n        }\n        else\n        {\n            vec3 toL = pos_type.xyz - v_worldPos;\n            float d = length(toL);\n            Ldir = toL / max(d, 1e-5);\n\n            // Hard cutoff: range == 0 is the \"no cutoff\" sentinel (glTF\n            // + ossia convention). Otherwise linearly fade over the\n            // last interval so the light doesn't pop off at exactly the\n            // range boundary.\n            if(dir_r.w > 0.0) atten = max(0.0, 1.0 - d / dir_r.w);\n\n            // Distance decay — switches on L.decay_mode so linear / none /\n            // cubic authored by the user or extracted from FBX actually\n            // reach the shader instead of being silently collapsed to\n            // the quadratic curve. Modes:\n            //   0 = none       (constant — legitimate for area lights\n            //                   and stylised looks)\n            //   1 = linear     1 / (1 + d)\n            //   2 = quadratic  1 / (1 + d²)   — physically correct default\n            //   3 = cubic      1 / (1 + d³)   — exaggerated falloff\n            uint decay = L.decay_mode;\n            if(decay == 1u)\n                atten *= 1.0 / (1.0 + d);\n            else if(decay == 2u)\n                atten *= 1.0 / (1.0 + d * d);\n            else if(decay == 3u)\n                atten *= 1.0 / (1.0 + d * d * d);\n            // decay == 0u → no distance attenuation; `atten` keeps the\n            // range cutoff contribution only.\n\n            // Spot-cone attenuation. Inner / outer cones are stored as\n            // cosines (packed CPU-side in Light.cpp) so the fragment-side\n            // test is one dot product + a linear ramp, matching the glTF\n            // KHR_lights_punctual reference formula:\n            //   t = clamp((cos_angle - outer) / (inner - outer), 0, 1)\n            //   atten *= t\n            // Outside the outer cone → t = 0, light doesn't contribute.\n            // Inside the inner cone → t = 1, full spot intensity.\n            // Between → linear falloff. type ≈ 2 = spot (local_direction.w\n            // packs the enum; see RawLightData::local_direction in\n            // SceneGPUState.hpp). Point lights (type ≈ 1) skip this\n            // block, so the spot-specific math doesn't perturb them.\n            if(pos_type.w > 1.5 && pos_type.w < 2.5)\n            {\n                float cos_to_frag = dot(-Ldir, normalize(dir_r.xyz));\n                float inner_cos   = L.range_cone.y;\n                float outer_cos   = L.range_cone.z;\n                atten *= clamp(\n                    (cos_to_frag - outer_cos)\n                        / max(inner_cos - outer_cos, 1e-5),\n                    0.0, 1.0);\n            }\n        }\n\n        float NdotL = max(dot(N, Ldir), 0.0);\n        if(NdotL <= 0.0) continue;\n\n        vec3 H = normalize(Ldir + V);\n        float NdotH = max(dot(N, H), 0.0);\n        float VdotH = max(dot(V, H), 0.0);\n\n        float denom_d = NdotH * NdotH * (alpha2 - 1.0) + 1.0;\n        float D = alpha2 / (3.14159 * denom_d * denom_d);\n\n        float G_v = NdotV / (NdotV * (1.0 - k) + k);\n        float G_l = NdotL / (NdotL * (1.0 - k) + k);\n        float G = G_v * G_l;\n\n        vec3 F = F0 + (1.0 - F0) * pow(1.0 - VdotH, 5.0);\n\n        vec3 spec = (D * G * F) / max(4.0 * NdotV * NdotL, 1e-4);\n        vec3 diffuse_term = (vec3(1.0) - F) * kd / 3.14159;\n\n        vec3 lightCol = color_i.rgb * color_i.w;\n        result += atten * lightCol * NdotL * (diffuse_term + spec);\n    }\n\n    // Linear fog: blend with fog_color over [start, end]. fog_range.w\n    // is the enabled flag (set by EnvironmentLoader). When disabled\n    // we skip the work.\n    if(env.fog_range.w > 0.5)\n    {\n        float view_z = distance(camera.cameraPosition.xyz, v_worldPos);\n        float f_s = env.fog_range.x;\n        float f_e = max(env.fog_range.y, f_s + 1e-3);\n        float t = clamp((view_z - f_s) / (f_e - f_s), 0.0, 1.0);\n        result = mix(result, env.fog_color_density.rgb, t);\n    }\n\n    // Volumetric composite BEFORE exposure_mul. accum from the integrate\n    // pass is in raw light units (same scale as the BSDF result), so\n    // both sides of `inColor * transm + accum` stay in matched units —\n    // applying after exposure makes accum dominate dim surfaces and\n    // lose to bright/specular surfaces, which was the original\n    // \"foliage punches through fog\" symptom.\n    //\n    // view_z above is `distance(eye, worldPos)` (positive); applyVolumetric /\n    // scoreClusterId need view-space Z (negative). Recompute from\n    // camera.view to keep the cluster lookup consistent with\n    // build_cluster_aabbs / volumetric_integrate.\n    float viewZ = (camera.view * vec4(v_worldPos, 1.0)).z;\n    result = applyVolumetric(result, gl_FragCoord.xy, viewZ);\n\n    result *= exposure_mul;\n\n    // Output is LINEAR HDR. The downstream tonemap node owns the\n    // HDR→display compression (ACES / Reinhard / filmic / etc.) and\n    // the sRGB encode. The previous `pow(result, 1/gamma)` here was\n    // sRGB-encoding the HDR before the tonemap could read it: any\n    // radiance > 1.0 post-exposure clipped to flat white at gamma\n    // encode, which is what made volumetric in-scatter blow out to\n    // saturated pink.\n    isf_FragColor = vec4(max(result, vec3(0.0)), (mat.feature_mask & (1u << 17u)) != 0u ? alpha : 1.0);\n}\n","Inlets":[{"uuid":"f2ab26ea-415d-45a2-bfbc-2968c7c92a33","ObjectName":"Inlet","id":1000,"Hidden":false,"Custom":"Geometry In","Exposed":"geometry in"},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":0,"Hidden":true,"Custom":"Mode","Exposed":"mode","Value":{"Int":0},"Init":{"Int":0},"Domain":{"Int":{"Values":[0,1,2,3]}},"Values":[["Triangles",{"Int":0}],["Points",{"Int":1}],["Lines",{"Int":2}],["Geometry",{"Int":3}]],"FolderPort":"","FileExtensions":""},{"uuid":"fb27e4cb-ea7f-41e2-ad92-2354498c1b6b","ObjectName":"Inlet","id":1,"Hidden":true,"Custom":"EnableBlend","Exposed":"enableblend","Value":{"Bool":false},"Init":{"Bool":false},"Domain":{"Bool":null}},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":2,"Hidden":true,"Custom":"SrcColor","Exposed":"srccolor","Value":{"Int":6},"Init":{"Int":6},"Domain":{"Int":{"Values":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]}},"Values":[["Zero",{"Int":0}],["One",{"Int":1}],["SrcColor",{"Int":2}],["OneMinusSrcColor",{"Int":3}],["DstColor",{"Int":4}],["OneMinusDstColor",{"Int":5}],["SrcAlpha",{"Int":6}],["OneMinusSrcAlpha",{"Int":7}],["DstAlpha",{"Int":8}],["OneMinusDstAlpha",{"Int":9}],["ConstantColor",{"Int":10}],["OneMinusConstantColor",{"Int":11}],["ConstantAlpha",{"Int":12}],["OneMinusConstantAlpha",{"Int":13}],["SrcAlphaSaturate",{"Int":14}]],"FolderPort":"","FileExtensions":""},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":3,"Hidden":true,"Custom":"DstColor","Exposed":"dstcolor","Value":{"Int":7},"Init":{"Int":7},"Domain":{"Int":{"Values":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]}},"Values":[["Zero",{"Int":0}],["One",{"Int":1}],["SrcColor",{"Int":2}],["OneMinusSrcColor",{"Int":3}],["DstColor",{"Int":4}],["OneMinusDstColor",{"Int":5}],["SrcAlpha",{"Int":6}],["OneMinusSrcAlpha",{"Int":7}],["DstAlpha",{"Int":8}],["OneMinusDstAlpha",{"Int":9}],["ConstantColor",{"Int":10}],["OneMinusConstantColor",{"Int":11}],["ConstantAlpha",{"Int":12}],["OneMinusConstantAlpha",{"Int":13}],["SrcAlphaSaturate",{"Int":14}]],"FolderPort":"","FileExtensions":""},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":4,"Hidden":true,"Custom":"OpColor","Exposed":"opcolor","Value":{"Int":0},"Init":{"Int":0},"Domain":{"Int":{"Values":[0,1,2,3,4]}},"Values":[["Add",{"Int":0}],["Substract",{"Int":1}],["Reverse Substract",{"Int":2}],["Min",{"Int":3}],["Max",{"Int":4}]],"FolderPort":"","FileExtensions":""},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":5,"Hidden":true,"Custom":"SrcAlpha","Exposed":"srcalpha","Value":{"Int":1},"Init":{"Int":1},"Domain":{"Int":{"Values":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]}},"Values":[["Zero",{"Int":0}],["One",{"Int":1}],["SrcColor",{"Int":2}],["OneMinusSrcColor",{"Int":3}],["DstColor",{"Int":4}],["OneMinusDstColor",{"Int":5}],["SrcAlpha",{"Int":6}],["OneMinusSrcAlpha",{"Int":7}],["DstAlpha",{"Int":8}],["OneMinusDstAlpha",{"Int":9}],["ConstantColor",{"Int":10}],["OneMinusConstantColor",{"Int":11}],["ConstantAlpha",{"Int":12}],["OneMinusConstantAlpha",{"Int":13}],["SrcAlphaSaturate",{"Int":14}]],"FolderPort":"","FileExtensions":""},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":6,"Hidden":true,"Custom":"DstAlpha","Exposed":"dstalpha","Value":{"Int":7},"Init":{"Int":7},"Domain":{"Int":{"Values":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]}},"Values":[["Zero",{"Int":0}],["One",{"Int":1}],["SrcColor",{"Int":2}],["OneMinusSrcColor",{"Int":3}],["DstColor",{"Int":4}],["OneMinusDstColor",{"Int":5}],["SrcAlpha",{"Int":6}],["OneMinusSrcAlpha",{"Int":7}],["DstAlpha",{"Int":8}],["OneMinusDstAlpha",{"Int":9}],["ConstantColor",{"Int":10}],["OneMinusConstantColor",{"Int":11}],["ConstantAlpha",{"Int":12}],["OneMinusConstantAlpha",{"Int":13}],["SrcAlphaSaturate",{"Int":14}]],"FolderPort":"","FileExtensions":""},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":7,"Hidden":true,"Custom":"OpAlpha","Exposed":"opalpha","Value":{"Int":0},"Init":{"Int":0},"Domain":{"Int":{"Values":[0,1,2,3,4]}},"Values":[["Add",{"Int":0}],["Substract",{"Int":1}],["Reverse Substract",{"Int":2}],["Min",{"Int":3}],["Max",{"Int":4}]],"FolderPort":"","FileExtensions":""},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":8,"Hidden":false,"Custom":"camera","Exposed":"camera","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":9,"Hidden":false,"Custom":"scene_lights","Exposed":"scene_lights","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":10,"Hidden":false,"Custom":"scene_light_indices","Exposed":"scene_light_indices","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":11,"Hidden":false,"Custom":"world_transforms","Exposed":"world_transforms","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":12,"Hidden":false,"Custom":"scene_materials","Exposed":"scene_materials","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":13,"Hidden":false,"Custom":"scene_material_uv_xforms","Exposed":"scene_material_uv_xforms","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":14,"Hidden":false,"Custom":"per_draws","Exposed":"per_draws","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":15,"Hidden":false,"Custom":"indirect_draw_cmds","Exposed":"indirect_draw_cmds","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":16,"Hidden":false,"Custom":"scene_counts","Exposed":"scene_counts","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":17,"Hidden":false,"Custom":"env","Exposed":"env","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"238399a0-7e81-47e3-896f-08e8856e2973","ObjectName":"Inlet","id":18,"Hidden":true,"Custom":"alpha_a2c_enabled","Exposed":"alpha_a2c_enabled","Value":{"Int":0},"Init":{"Int":0},"Domain":{"Int":{"Min":0,"Max":1}}},{"uuid":"238399a0-7e81-47e3-896f-08e8856e2973","ObjectName":"Inlet","id":19,"Hidden":true,"Custom":"volumetric_enabled","Exposed":"volumetric_enabled","Value":{"Int":0},"Init":{"Int":0},"Domain":{"Int":{"Min":0,"Max":1}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":20,"Hidden":true,"Custom":"volumetric_intensity","Exposed":"volumetric_intensity","Value":{"Float":1.0},"Init":{"Float":1.0},"Domain":{"Float":{"Min":0.0,"Max":4.0}}}],"Outlets":[{"uuid":"f1c71046-b754-49a5-8e66-d01374773dfc","ObjectName":"Outlet","id":1000,"Hidden":false,"Custom":"Texture Out","Exposed":"texture out"}]},{"uuid":"74ca45ff-92c9-44a0-8f1a-754dea05ee1b","ObjectName":"gfxProcess","id":28,"Metadata":{"ScriptingName":"ISF Shader.28","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[2194.1583279497945,3031.453570387532],"Size":[182.0,160.0],"Loops":false,"FoldMode":0,"Vertex":"","Fragment":"/*{\n  \"DESCRIPTION\": \"HDR tone mapping with selectable algorithm: Reinhard, ACES Filmic (Narkowicz), Exposure, Uncharted 2 (Hable), or AgX. Feed it linear HDR colour (the PBR render pipelines output linear HDR and leave tone mapping and the display gamma to this node); the output is gamma-encoded for display.\",\n  \"CREDIT\": \"ossia score\",\n  \"ISFVSN\": \"2\",\n  \"CATEGORIES\": [\n    \"Post-Process\"\n  ],\n  \"INPUTS\": [\n    {\n      \"NAME\": \"inputImage\",\n      \"TYPE\": \"image\"\n    },\n    {\n      \"NAME\": \"algorithm\",\n      \"LABEL\": \"Tone curve\",\n      \"TYPE\": \"long\",\n      \"DEFAULT\": 1,\n      \"VALUES\": [0, 1, 2, 3, 4],\n      \"LABELS\": [\"Reinhard\", \"ACES Filmic\", \"Exposure\", \"Uncharted 2\", \"AgX\"]\n    },\n    {\n      \"NAME\": \"exposure\",\n      \"LABEL\": \"Exposure (multiplier)\",\n      \"TYPE\": \"float\",\n      \"DEFAULT\": 1.0,\n      \"MIN\": 0.1,\n      \"MAX\": 10.0\n    },\n    {\n      \"NAME\": \"gamma\",\n      \"LABEL\": \"Display gamma\",\n      \"TYPE\": \"float\",\n      \"DEFAULT\": 2.2,\n      \"MIN\": 0.5,\n      \"MAX\": 3.0\n    },\n    {\n      \"NAME\": \"whitePoint\",\n      \"LABEL\": \"White point (Reinhard only)\",\n      \"TYPE\": \"float\",\n      \"DEFAULT\": 4.0,\n      \"MIN\": 0.5,\n      \"MAX\": 20.0\n    }\n  ]\n}*/\n\n// --- Reinhard (extended) ---\nvec3 tonemapReinhard(vec3 color, float wp)\n{\n  // Extended Reinhard: color * (1 + color / wp^2) / (1 + color)\n  vec3 wp2 = vec3(wp * wp);\n  return color * (1.0 + color / wp2) / (1.0 + color);\n}\n\n// --- ACES Filmic (Narkowicz approximation) ---\n// Source: Krzysztof Narkowicz, \"ACES Filmic Tone Mapping Curve\" (2016)\nvec3 tonemapACES(vec3 x)\n{\n  const float a = 2.51;\n  const float b = 0.03;\n  const float c = 2.43;\n  const float d = 0.59;\n  const float e = 0.14;\n  return clamp((x * (a * x + b)) / (x * (c * x + d) + e), 0.0, 1.0);\n}\n\n// --- Exposure (simple) ---\nvec3 tonemapExposure(vec3 color, float e)\n{\n  return 1.0 - exp(-color * e);\n}\n\n// --- Uncharted 2 (Hable filmic) ---\n// Source: John Hable, \"Filmic Tonemapping Operators\" (GDC 2010)\nvec3 uncharted2Partial(vec3 x)\n{\n  const float A = 0.15; // Shoulder strength\n  const float B = 0.50; // Linear strength\n  const float C = 0.10; // Linear angle\n  const float D = 0.20; // Toe strength\n  const float E = 0.02; // Toe numerator\n  const float F = 0.30; // Toe denominator\n  return ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F;\n}\n\nvec3 tonemapUncharted2(vec3 color)\n{\n  const float W = 11.2; // Linear white point\n  const float exposureBias = 2.0;\n  vec3 curr = uncharted2Partial(color * exposureBias);\n  vec3 whiteScale = vec3(1.0) / uncharted2Partial(vec3(W));\n  return curr * whiteScale;\n}\n\n// --- AgX ---\n// Based on the minimal analytical AgX implementation.\n// References: Troy Sobotka, Benjamin Wrensch (Missing Deadlines), Blender 4.0\n\nconst mat3 AgXInsetMatrix = mat3(\n  0.856627153315983, 0.137318972929847, 0.11189821299995,\n  0.0951212405381588, 0.761241990602591, 0.0767994186031903,\n  0.0482516061458583, 0.101439036467562, 0.811302368396859\n);\n\nconst mat3 AgXOutsetMatrix = mat3(\n  1.1271005818144368, -0.1413297634984383, -0.14132976349843826,\n  -0.11060664309660323, 1.157823702216272, -0.11060664309660294,\n  -0.016493938717834573, -0.016493938717834257, 1.2519364065950405\n);\n\nconst mat3 LINEAR_SRGB_TO_LINEAR_REC2020 = mat3(\n  0.6274, 0.0691, 0.0164,\n  0.3293, 0.9195, 0.0880,\n  0.0433, 0.0113, 0.8956\n);\n\nconst mat3 LINEAR_REC2020_TO_LINEAR_SRGB = mat3(\n  1.6605, -0.1246, -0.0182,\n  -0.5876, 1.1329, -0.1006,\n  -0.0728, -0.0083, 1.1187\n);\n\nvec3 tonemapAgX(vec3 color)\n{\n  const float AgxMinEv = -12.47393;\n  const float AgxMaxEv = 4.026069;\n\n  color = LINEAR_SRGB_TO_LINEAR_REC2020 * color;\n  color = AgXInsetMatrix * color;\n\n  color = max(color, 1e-10);\n  color = clamp(log2(color), AgxMinEv, AgxMaxEv);\n  color = (color - AgxMinEv) / (AgxMaxEv - AgxMinEv);\n  color = clamp(color, 0.0, 1.0);\n\n  // 6th-order polynomial approximation of the AgX sigmoid\n  vec3 x2 = color * color;\n  vec3 x4 = x2 * x2;\n  color = + 15.5   * x4 * x2\n          - 40.14  * x4 * color\n          + 31.96  * x4\n          - 6.868  * x2 * color\n          + 0.4298 * x2\n          + 0.1191 * color\n          - 0.00232;\n\n  color = AgXOutsetMatrix * color;\n\n  // Linearize (AgX output is in sRGB-like gamma space)\n  color = pow(max(vec3(0.0), color), vec3(2.2));\n\n  color = LINEAR_REC2020_TO_LINEAR_SRGB * color;\n  return clamp(color, 0.0, 1.0);\n}\n\nvoid main()\n{\n  vec4 texColor = IMG_THIS_PIXEL(inputImage);\n  vec3 color = texColor.rgb;\n\n  // Apply exposure\n  color *= exposure;\n\n  // Apply selected tone mapping algorithm\n  if(algorithm == 0)\n  {\n    color = tonemapReinhard(color, whitePoint);\n  }\n  else if(algorithm == 1)\n  {\n    color = tonemapACES(color);\n  }\n  else if(algorithm == 2)\n  {\n    // Exposure already applied above; use 1.0 to avoid double-application\n    color = tonemapExposure(color, 1.0);\n  }\n  else if(algorithm == 3)\n  {\n    color = tonemapUncharted2(color);\n  }\n  else if(algorithm == 4)\n  {\n    color = tonemapAgX(color);\n  }\n\n  // Gamma correction\n  color = pow(max(color, vec3(0.0)), vec3(1.0 / gamma));\n\n  isf_FragColor = vec4(color, texColor.a);\n}\n","Root":"<LIBRARY>:packages/score-csf-testers/shaderlib/post-process/ToneMapping.fs","Inlets":[{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":0,"Hidden":false,"Custom":"inputImage","Exposed":"inputimage","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":1,"Hidden":true,"Custom":"algorithm","Exposed":"algorithm","Value":{"Int":1},"Init":{"Int":1},"Domain":{"Int":{"Values":[0,1,2,3,4]}},"Values":[["Reinhard",{"Int":0}],["ACES Filmic",{"Int":1}],["Exposure",{"Int":2}],["Uncharted 2",{"Int":3}],["AgX",{"Int":4}]],"FolderPort":"","FileExtensions":""},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":2,"Hidden":true,"Custom":"exposure","Exposed":"exposure","Value":{"Float":1.0},"Init":{"Float":1.0},"Domain":{"Float":{"Min":0.10000000149011612,"Max":10.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":3,"Hidden":true,"Custom":"gamma","Exposed":"gamma","Value":{"Float":2.200000047683716},"Init":{"Float":2.200000047683716},"Domain":{"Float":{"Min":0.5,"Max":3.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":4,"Hidden":true,"Custom":"whitePoint","Exposed":"whitepoint","Value":{"Float":4.0},"Init":{"Float":4.0},"Domain":{"Float":{"Min":0.5,"Max":20.0}}}],"Outlets":[{"uuid":"f1c71046-b754-49a5-8e66-d01374773dfc","ObjectName":"Outlet","id":1,"Hidden":false,"Custom":"Texture Out","Exposed":"texture out"}]},{"uuid":"2f6a8c41-7d93-4e5b-b1c8-4e3f9a7d2c5b","ObjectName":"asset_loader","id":29,"Metadata":{"ScriptingName":"Asset Loader.29","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[233.47324995097145,3534.6609580728245],"Size":[232.0,173.0],"Loops":false,"FoldMode":0,"Inlets":[{"uuid":"40833147-4c42-4b8b-bb80-0b1d15dae129","ObjectName":"Inlet","id":0,"Hidden":true,"Custom":"Asset file","Exposed":"asset file","Value":{"String":"<PROJECT>:Models/Box.glb"},"Init":{"String":""},"Domain":{},"Filters":"3D assets (*.fbx *.gltf *.glb *.obj *.ply *.stl *.off *.splat *.spz *.usd *.usda *.usdc *.usdz)"},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":1,"Hidden":true,"Custom":"Position","Exposed":"position","Value":{"Vec3f":[0.0,0.0,0.0]},"Init":{"Vec3f":[0.0,0.0,0.0]},"Domain":{"Vec3f":{"Min":[-8388608.0,-8388608.0,-8388608.0],"Max":[8388608.0,8388608.0,8388608.0],"Values":[[],[],[]]}}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":2,"Hidden":true,"Custom":"Rotation","Exposed":"rotation","Value":{"Vec3f":[0.0,0.0,0.0]},"Init":{"Vec3f":[0.0,0.0,0.0]},"Domain":{"Vec3f":{"Min":[0.0,0.0,0.0],"Max":[360.0,360.0,360.0],"Values":[[],[],[]]}}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":3,"Hidden":true,"Custom":"Scale","Exposed":"scale","Value":{"Vec3f":[1.0,1.0,1.0]},"Init":{"Vec3f":[1.0,1.0,1.0]},"Domain":{"Vec3f":{"Min":[0.000009999999747378752,0.000009999999747378752,0.000009999999747378752],"Max":[1000.0,1000.0,1000.0],"Values":[[],[],[]]}}},{"uuid":"9ae797ea-d94c-4792-acec-9ec1932bae5d","ObjectName":"Inlet","id":4,"Hidden":true,"Custom":"Format override (auto if empty)","Exposed":"format override (auto if empty)","Value":{"String":""},"Init":{"String":""},"Domain":{}}],"Outlets":[{"uuid":"848061c5-e8a0-4a13-9985-e8df30ce6d4f","ObjectName":"Outlet","id":0,"Hidden":false,"Custom":"Scene","Exposed":"scene"}]},{"uuid":"a5bbffe0-93d2-4e70-995c-cf46c2c43520","ObjectName":"CSF","id":30,"Metadata":{"ScriptingName":"Compute Shader.30","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[205.0711077509224,3844.492376480872],"Size":[213.0,167.0],"Loops":false,"FoldMode":0,"Compute":"/*{\n  \"DESCRIPTION\": \"Regular 2D/3D grid of countX x countY x countZ points, spacing apart, centred on center. Set countZ to 1 for a flat grid in the XY plane. Colour and texcoord are the normalised grid coordinates (x, y, z) in 0..1.\",\n  \"CREDIT\": \"ossia score\",\n  \"ISFVSN\": \"2.0\",\n  \"MODE\": \"COMPUTE_SHADER\",\n  \"CATEGORIES\": [\"Geometry Generator\"],\n  \"RESOURCES\": [\n    {\n      \"NAME\": \"geo\",\n      \"TYPE\": \"geometry\",\n      \"VERTEX_COUNT\": \"$countX * $countY * $countZ\",\n      \"ATTRIBUTES\": [\n        { \"NAME\": \"position\", \"SEMANTIC\": \"position\", \"TYPE\": \"vec4\", \"ACCESS\": \"write_only\", \"RATE\": \"vertex\" },\n        { \"NAME\": \"color\",    \"SEMANTIC\": \"color\",    \"TYPE\": \"vec4\", \"ACCESS\": \"write_only\", \"RATE\": \"vertex\" },\n        { \"NAME\": \"texcoord\", \"SEMANTIC\": \"texcoord\", \"TYPE\": \"vec4\", \"ACCESS\": \"write_only\", \"RATE\": \"vertex\" }\n      ]\n    },\n    { \"NAME\": \"countX\",  \"TYPE\": \"long\",    \"DEFAULT\": 32,  \"MIN\": 1,     \"MAX\": 512 },\n    { \"NAME\": \"countY\",  \"TYPE\": \"long\",    \"DEFAULT\": 32,  \"MIN\": 1,     \"MAX\": 512 },\n    { \"NAME\": \"countZ\",  \"TYPE\": \"long\",    \"DEFAULT\": 1,   \"MIN\": 1,     \"MAX\": 512 },\n    { \"NAME\": \"spacing\", \"TYPE\": \"float\",   \"DEFAULT\": 0.1, \"MIN\": 0.001, \"MAX\": 10.0 },\n    { \"NAME\": \"center\",  \"TYPE\": \"point3D\", \"DEFAULT\": [0, 0, 0], \"MIN\": [-10, -10, -10], \"MAX\": [10, 10, 10] }\n  ],\n  \"PASSES\": [\n    { \"LOCAL_SIZE\": [64, 1, 1], \"EXECUTION_MODEL\": { \"TYPE\": \"PER_VERTEX\" } }\n  ]\n}*/\n\nvoid main()\n{\n    uint idx = gl_GlobalInvocationID.x;\n    uint count = uint(ISF_WRITE(geo, position).length());\n    if(idx >= count)\n        return;\n\n    uint cX = uint(countX);\n    uint cY = uint(countY);\n    uint cZ = uint(countZ);\n\n    // Decompose linear index into 3D grid coordinates\n    uint z = idx / (cX * cY);\n    uint remainder = idx % (cX * cY);\n    uint y = remainder / cX;\n    uint x = remainder % cX;\n\n    // Center the grid around the origin, then offset by user center\n    vec3 offset = vec3(\n        float(cX - 1u),\n        float(cY - 1u),\n        float(cZ - 1u)\n    ) * spacing * 0.5;\n\n    vec3 pos = vec3(float(x), float(y), float(z)) * spacing - offset + center;\n\n    // Normalized grid coordinates [0, 1]\n    float nx = (cX > 1u) ? float(x) / float(cX - 1u) : 0.5;\n    float ny = (cY > 1u) ? float(y) / float(cY - 1u) : 0.5;\n    float nz = (cZ > 1u) ? float(z) / float(cZ - 1u) : 0.5;\n\n    ISF_WRITE(geo, position)[idx] = vec4(pos, 1.0);\n    ISF_WRITE(geo, texcoord)[idx] = vec4(nx, ny, nz, 1.0);\n\n    // Color gradient from grid position\n    ISF_WRITE(geo, color)[idx] = vec4(nx, ny, nz, 1.0);\n}\n","Root":"<LIBRARY>:packages/score-csf-testers/shaderlib/generators/GridPoints.cs","Inlets":[{"uuid":"238399a0-7e81-47e3-896f-08e8856e2973","ObjectName":"Inlet","id":0,"Hidden":true,"Custom":"countX","Exposed":"countx","Value":{"Int":6},"Init":{"Int":32},"Domain":{"Int":{"Min":1,"Max":512}}},{"uuid":"238399a0-7e81-47e3-896f-08e8856e2973","ObjectName":"Inlet","id":1,"Hidden":true,"Custom":"countY","Exposed":"county","Value":{"Int":6},"Init":{"Int":32},"Domain":{"Int":{"Min":1,"Max":512}}},{"uuid":"238399a0-7e81-47e3-896f-08e8856e2973","ObjectName":"Inlet","id":2,"Hidden":true,"Custom":"countZ","Exposed":"countz","Value":{"Int":6},"Init":{"Int":1},"Domain":{"Int":{"Min":1,"Max":512}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":3,"Hidden":true,"Custom":"spacing","Exposed":"spacing","Value":{"Float":1.600000023841858},"Init":{"Float":0.10000000149011612},"Domain":{"Float":{"Min":0.0010000000474974513,"Max":10.0}}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":4,"Hidden":true,"Custom":"center","Exposed":"center","Value":{"Vec3f":[0.0,0.0,0.0]},"Init":{"Vec3f":[0.0,0.0,0.0]},"Domain":{"Vec3f":{"Min":[-10.0,-10.0,-10.0],"Max":[10.0,10.0,10.0],"Values":[[],[],[]]}}}],"Outlets":[{"uuid":"848061c5-e8a0-4a13-9985-e8df30ce6d4f","ObjectName":"Outlet","id":0,"Hidden":false,"Custom":"geo_out","Exposed":"geo_out"}]},{"uuid":"5e8a2c7f-9b4d-4e3a-a1c6-2d7f0b3e8c4a","ObjectName":"instancer","id":31,"Metadata":{"ScriptingName":"Instancer.31","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[519.6196309909649,3562.5614448647443],"Size":[418.0,175.0],"Loops":false,"FoldMode":0,"Inlets":[{"uuid":"f2ab26ea-415d-45a2-bfbc-2968c7c92a33","ObjectName":"Inlet","id":0,"Hidden":false,"Custom":"Scene In","Exposed":"scene in"},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":1,"Hidden":false,"Custom":"Transforms","Exposed":"transforms","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":2,"Hidden":false,"Custom":"Colors","Exposed":"colors","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":3,"Hidden":false,"Custom":"Custom","Exposed":"custom","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"f2ab26ea-415d-45a2-bfbc-2968c7c92a33","ObjectName":"Inlet","id":4,"Hidden":false,"Custom":"Points","Exposed":"points"},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":5,"Hidden":true,"Custom":"Format","Exposed":"format","Value":{"Int":0},"Init":{"Int":0},"Domain":{"Int":{"Values":[0,1,2]}},"Values":[["mat4",{"Int":0}],["trs",{"Int":1}],["translation",{"Int":2}]],"FolderPort":"","FileExtensions":""},{"uuid":"238399a0-7e81-47e3-896f-08e8856e2973","ObjectName":"Inlet","id":6,"Hidden":true,"Custom":"Count","Exposed":"count","Value":{"Int":1},"Init":{"Int":1},"Domain":{"Int":{"Min":1,"Max":1000000}}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":7,"Hidden":true,"Custom":"Position","Exposed":"position","Value":{"Vec3f":[0.0,0.0,0.0]},"Init":{"Vec3f":[0.0,0.0,0.0]},"Domain":{"Vec3f":{"Min":[-8388608.0,-8388608.0,-8388608.0],"Max":[8388608.0,8388608.0,8388608.0],"Values":[[],[],[]]}}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":8,"Hidden":true,"Custom":"Rotation","Exposed":"rotation","Value":{"Vec3f":[0.0,0.0,0.0]},"Init":{"Vec3f":[0.0,0.0,0.0]},"Domain":{"Vec3f":{"Min":[0.0,0.0,0.0],"Max":[360.0,360.0,360.0],"Values":[[],[],[]]}}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":9,"Hidden":true,"Custom":"Scale","Exposed":"scale","Value":{"Vec3f":[0.20000000298023224,0.20000000298023224,0.20000000298023224]},"Init":{"Vec3f":[1.0,1.0,1.0]},"Domain":{"Vec3f":{"Min":[0.000009999999747378752,0.000009999999747378752,0.000009999999747378752],"Max":[1000.0,1000.0,1000.0],"Values":[[],[],[]]}}},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":10,"Hidden":true,"Custom":"Per-instance transform","Exposed":"per-instance transform","Value":{"Int":0},"Init":{"Int":0},"Domain":{"Int":{"Values":[0,1]}},"Values":[["Full matrix",{"Int":0}],["Translation only",{"Int":1}]],"FolderPort":"","FileExtensions":""}],"Outlets":[{"uuid":"848061c5-e8a0-4a13-9985-e8df30ce6d4f","ObjectName":"Outlet","id":0,"Hidden":false,"Custom":"Scene Out","Exposed":"scene out"}]},{"uuid":"a8f2c6d0-1b4e-4c7a-9d3f-5e8b2c1a7f0d","ObjectName":"gfxProcess","id":32,"Metadata":{"ScriptingName":"Scene Preprocessor.32","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[990.2800010790648,3589.8616071287174],"Size":[186.0,22.0],"Loops":false,"FoldMode":0,"Inlets":[{"uuid":"f2ab26ea-415d-45a2-bfbc-2968c7c92a33","ObjectName":"Inlet","id":0,"Hidden":false,"Custom":"Scene In","Exposed":"scene in"}],"Outlets":[{"uuid":"848061c5-e8a0-4a13-9985-e8df30ce6d4f","ObjectName":"Outlet","id":0,"Hidden":false,"Custom":"Geometry Out","Exposed":"geometry out"}]},{"uuid":"4c91b5e2-8d76-4ab3-9f14-6e0d8b3a2c57","ObjectName":"camera_avnd","id":33,"Metadata":{"ScriptingName":"Camera.33","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[664.3589363749186,3775.861607128717],"Size":[274.0,177.0],"Loops":false,"FoldMode":0,"Inlets":[{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":0,"Hidden":true,"Custom":"Eye","Exposed":"eye","Value":{"Vec3f":[2.200000047683716,1.7999999523162842,2.5999999046325684]},"Init":{"Vec3f":[0.0,0.0,0.0]},"Domain":{"Vec3f":{"Min":[-10000.0,-10000.0,-10000.0],"Max":[10000.0,10000.0,10000.0],"Values":[[],[],[]]}}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":1,"Hidden":true,"Custom":"Target","Exposed":"target","Value":{"Vec3f":[0.0,0.0,0.0]},"Init":{"Vec3f":[0.0,0.0,0.0]},"Domain":{"Vec3f":{"Min":[-10000.0,-10000.0,-10000.0],"Max":[10000.0,10000.0,10000.0],"Values":[[],[],[]]}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":2,"Hidden":true,"Custom":"FOV","Exposed":"fov","Value":{"Float":45.0},"Init":{"Float":60.0},"Domain":{"Float":{"Min":5.0,"Max":170.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":3,"Hidden":true,"Custom":"Near","Exposed":"near","Value":{"Float":0.10000000149011612},"Init":{"Float":0.10000000149011612},"Domain":{"Float":{"Min":0.0010000000474974513,"Max":10.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":4,"Hidden":true,"Custom":"Far","Exposed":"far","Value":{"Float":1000.0},"Init":{"Float":1000.0},"Domain":{"Float":{"Min":1.0,"Max":100000.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":5,"Hidden":true,"Custom":"Roll","Exposed":"roll","Value":{"Float":0.0},"Init":{"Float":0.0},"Domain":{"Float":{"Min":-180.0,"Max":180.0}}}],"Outlets":[{"uuid":"848061c5-e8a0-4a13-9985-e8df30ce6d4f","ObjectName":"Outlet","id":0,"Hidden":false,"Custom":"Scene","Exposed":"scene"}]},{"uuid":"9f3c1a5e-4b7d-4e2a-8c5f-1d6e0b9a3c7f","ObjectName":"light","id":34,"Metadata":{"ScriptingName":"Light.34","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[516.5423183348435,4016.556511408753],"Size":[422.0,252.0],"Loops":false,"FoldMode":0,"Inlets":[{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":0,"Hidden":true,"Custom":"Mode","Exposed":"mode","Value":{"Int":0},"Init":{"Int":0},"Domain":{"Int":{"Values":[0,1,2,3,4,5,6]}},"Values":[["Directional",{"Int":0}],["Point",{"Int":1}],["Spot",{"Int":2}],["Rect",{"Int":3}],["Disk",{"Int":4}],["Sphere",{"Int":5}],["Dome",{"Int":6}]],"FolderPort":"","FileExtensions":""},{"uuid":"8f38638e-9f9f-48b0-ae36-1cba86ef5703","ObjectName":"Inlet","id":1,"Hidden":true,"Custom":"Color","Exposed":"color","Value":{"Vec4f":[1.0,1.0,1.0,1.0]},"Init":{"Vec4f":[1.0,1.0,1.0,1.0]},"Domain":{}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":2,"Hidden":true,"Custom":"Intensity","Exposed":"intensity","Value":{"Float":4.0},"Init":{"Float":1.0},"Domain":{"Float":{"Min":0.0,"Max":100.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":3,"Hidden":true,"Custom":"Range","Exposed":"range","Value":{"Float":0.0},"Init":{"Float":0.0},"Domain":{"Float":{"Min":0.0,"Max":1000.0}}},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":4,"Hidden":true,"Custom":"Falloff","Exposed":"falloff","Value":{"Int":2},"Init":{"Int":2},"Domain":{"Int":{"Values":[0,1,2,3]}},"Values":[["None",{"Int":0}],["Linear",{"Int":1}],["Quadratic (physical)",{"Int":2}],["Cubic",{"Int":3}]],"FolderPort":"","FileExtensions":""},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":5,"Hidden":true,"Custom":"Inner cone °","Exposed":"inner cone _","Value":{"Float":0.0},"Init":{"Float":0.0},"Domain":{"Float":{"Min":0.0,"Max":90.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":6,"Hidden":true,"Custom":"Outer cone °","Exposed":"outer cone _","Value":{"Float":45.0},"Init":{"Float":45.0},"Domain":{"Float":{"Min":0.0,"Max":90.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":7,"Hidden":true,"Custom":"Width","Exposed":"width","Value":{"Float":1.0},"Init":{"Float":1.0},"Domain":{"Float":{"Min":0.009999999776482582,"Max":100.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":8,"Hidden":true,"Custom":"Height","Exposed":"height","Value":{"Float":1.0},"Init":{"Float":1.0},"Domain":{"Float":{"Min":0.009999999776482582,"Max":100.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":9,"Hidden":true,"Custom":"Radius","Exposed":"radius","Value":{"Float":0.5},"Init":{"Float":0.5},"Domain":{"Float":{"Min":0.009999999776482582,"Max":100.0}}},{"uuid":"fb27e4cb-ea7f-41e2-ad92-2354498c1b6b","ObjectName":"Inlet","id":10,"Hidden":true,"Custom":"Cast shadow","Exposed":"cast shadow","Value":{"Bool":false},"Init":{"Bool":false},"Domain":{"Bool":null}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":11,"Hidden":true,"Custom":"Shadow bias","Exposed":"shadow bias","Value":{"Float":0.0010000000474974513},"Init":{"Float":0.0010000000474974513},"Domain":{"Float":{"Min":0.0,"Max":0.10000000149011612}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":12,"Hidden":true,"Custom":"Shadow normal bias","Exposed":"shadow normal bias","Value":{"Float":0.009999999776482582},"Init":{"Float":0.009999999776482582},"Domain":{"Float":{"Min":0.0,"Max":0.10000000149011612}}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":13,"Hidden":true,"Custom":"Position","Exposed":"position","Value":{"Vec3f":[0.0,0.0,0.0]},"Init":{"Vec3f":[0.0,0.0,0.0]},"Domain":{"Vec3f":{"Min":[-8388608.0,-8388608.0,-8388608.0],"Max":[8388608.0,8388608.0,8388608.0],"Values":[[],[],[]]}}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":14,"Hidden":true,"Custom":"Rotation","Exposed":"rotation","Value":{"Vec3f":[-50.0,35.0,0.0]},"Init":{"Vec3f":[0.0,0.0,0.0]},"Domain":{"Vec3f":{"Min":[0.0,0.0,0.0],"Max":[360.0,360.0,360.0],"Values":[[],[],[]]}}}],"Outlets":[{"uuid":"848061c5-e8a0-4a13-9985-e8df30ce6d4f","ObjectName":"Outlet","id":0,"Hidden":false,"Custom":"Scene","Exposed":"scene"}]},{"uuid":"d3f5a8c1-8b47-4e91-9c2d-6f1a9b5e3c82","ObjectName":"environment_loader","id":35,"Metadata":{"ScriptingName":"Environment.35","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[583.5497185188296,4300.673291712802],"Size":[352.0,176.0],"Loops":false,"FoldMode":0,"Inlets":[{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":0,"Hidden":true,"Custom":"Ambient Color","Exposed":"ambient color","Value":{"Vec3f":[1.0,1.0,1.0]},"Init":{"Vec3f":[0.029999999329447746,0.029999999329447746,0.029999999329447746]},"Domain":{"Vec3f":{"Min":[0.0,0.0,0.0],"Max":[1.0,1.0,1.0],"Values":[[],[],[]]}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":1,"Hidden":true,"Custom":"Ambient Intensity","Exposed":"ambient intensity","Value":{"Float":0.800000011920929},"Init":{"Float":1.0},"Domain":{"Float":{"Min":0.0,"Max":8.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":2,"Hidden":true,"Custom":"Exposure EV100","Exposed":"exposure ev100","Value":{"Float":0.0},"Init":{"Float":0.0},"Domain":{"Float":{"Min":-6.0,"Max":18.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":3,"Hidden":true,"Custom":"Exposure (stops)","Exposed":"exposure (stops)","Value":{"Float":0.0},"Init":{"Float":0.0},"Domain":{"Float":{"Min":-8.0,"Max":8.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":4,"Hidden":true,"Custom":"Gamma","Exposed":"gamma","Value":{"Float":2.200000047683716},"Init":{"Float":2.200000047683716},"Domain":{"Float":{"Min":1.0,"Max":3.0}}},{"uuid":"fb27e4cb-ea7f-41e2-ad92-2354498c1b6b","ObjectName":"Inlet","id":5,"Hidden":true,"Custom":"Fog","Exposed":"fog","Value":{"Bool":false},"Init":{"Bool":false},"Domain":{"Bool":null}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":6,"Hidden":true,"Custom":"Fog Color","Exposed":"fog color","Value":{"Vec3f":[0.800000011920929,0.800000011920929,0.800000011920929]},"Init":{"Vec3f":[0.800000011920929,0.800000011920929,0.800000011920929]},"Domain":{"Vec3f":{"Min":[0.0,0.0,0.0],"Max":[1.0,1.0,1.0],"Values":[[],[],[]]}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":7,"Hidden":true,"Custom":"Fog Start","Exposed":"fog start","Value":{"Float":10.0},"Init":{"Float":10.0},"Domain":{"Float":{"Min":0.0,"Max":1000.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":8,"Hidden":true,"Custom":"Fog End","Exposed":"fog end","Value":{"Float":100.0},"Init":{"Float":100.0},"Domain":{"Float":{"Min":0.0,"Max":10000.0}}},{"uuid":"0adbbdda-fda4-451e-91cc-1da731bde9d5","ObjectName":"Inlet","id":9,"Hidden":true,"Custom":"Render target size","Exposed":"render target size","Value":{"Vec2f":[0.0,0.0]},"Init":{"Vec2f":[0.0,0.0]},"Domain":{"Vec2f":{"Min":[0.0,0.0],"Max":[16384.0,16384.0],"Values":[[],[]]}},"Integral":true}],"Outlets":[{"uuid":"848061c5-e8a0-4a13-9985-e8df30ce6d4f","ObjectName":"Outlet","id":0,"Hidden":false,"Custom":"Scene","Exposed":"scene"}]},{"uuid":"dbfc2101-40d7-4807-8804-571e88992e7e","ObjectName":"gfxProcess","id":36,"Metadata":{"ScriptingName":"Render Pipeline.36","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[1198.3342690949642,3585.377218816556],"Size":[787.0,160.0],"Loops":false,"FoldMode":0,"Vertex":"// Full-PBR variant — extends classic_pbr_textured with TANGENT for TBN\n// normal-map reconstruction in the fragment stage.\n//\n// Vertex inputs + varyings come from the sibling .frag's VERTEX_INPUTS /\n// VERTEX_OUTPUTS blocks; redeclaring them here triggers \"redefinition\".\n\nvoid main()\n{\n    isf_vertShaderInit();\n\n    // Unified-MDI cmd-index lookup: per-instance VERTEX_INPUT carries\n    // the drawID directly. Replaces the prior `gl_BaseInstanceARB`\n    // path, which broke as soon as instanceCount > 1 (firstInstance\n    // becomes the per-instance slot offset, no longer the cmd index)\n    // AND was always 0 on the CPU-fallback drawIndexed loop. Reading\n    // a per-instance attribute works uniformly on both indirect and\n    // CPU-fallback paths (firstInstance is honoured by every QRhi\n    // backend that supports instancing).\n    uint drawId = draw_id;\n    v_drawID = drawId;\n\n    PerDraw pd = per_draws.data[drawId];\n    mat3 instLinear = pd.normal[3].x > 0.5\n        ? mat3(inst_matrix0.xyz, inst_matrix1.xyz, inst_matrix2.xyz)\n        : mat3(1.0);\n    mat4 model = pd.model;\n    mat3 normalMatrix = mat3(pd.normal) * transpose(inverse(instLinear));\n\n    // Per-instance translation offset: zero for non-instanced draws via\n    // the REQUIRED:false fallback (identity broadcast); the actual\n    // particle position for unified-MDI instance groups.\n    vec4 wp = model * vec4(instLinear * position + inst_translation, 1.0);\n    v_worldPos = wp.xyz;\n    v_normal = normalize(normalMatrix * normal);\n    // Tangent carries xyz = unit tangent in mesh space + w = handedness.\n    // Apply the normal matrix to the xyz (same basis as the normal) and\n    // forward w untouched. Consumer reconstructs bitangent as\n    //   bitangent = cross(N, T.xyz) * T.w\n    v_tangent = vec4(normalize(normalMatrix * tangent.xyz), tangent.w);\n    v_uv = texcoord_0;\n    // glTF TEXCOORD_1 (secondary UV set — lightmaps, per-channel UV\n    // override). Falls back to zero for meshes without it (slab\n    // uploader fills with zeros).\n    v_uv1 = texcoord_1;\n    // glTF COLOR_0 (defaults to vec4(1) when the mesh doesn't carry\n    // one — the slab uploader fills the buffer with white).\n    v_color = color_0;\n    // VERTEX_INPUTS aren't directly visible to the fragment stage —\n    // forward the per-instance broadcast colour as a varying so the\n    // .frag can multiply baseColor by it.\n    v_inst_color = pd.normal[3].y > 0.5 ? inst_color0 : vec4(1.0);\n    v_inst_emissive = pd.normal[3].z > 0.5 ? inst_custom0 : vec4(0.0);\n\n    gl_Position = clipSpaceCorrMatrix * camera.viewProjection * wp;\n\n    isf_vertShaderFinish();\n}\n","Fragment":"/*{\n  \"CREDIT\": \"ossia team\",\n  \"ISFVSN\": \"2\",\n  \"MODE\": \"RAW_RASTER_PIPELINE\",\n  \"ALPHA\": \"straight\",\n  \"DESCRIPTION\": \"Full glTF metallic-roughness rasterizer for a Scene Preprocessor output: draws the whole scene in one indirect draw with every material texture (base colour, metal-rough, normal map with tangents, emissive, occlusion; texcoord sets, KHR_texture_transform, wrap modes, alpha MASK and BLEND, double-sided), the scene's lights (directional, point and spot, with range and falloff; procedural lights written by the presets/lighting CSFs included), the Environment node's ambient, exposure and linear fog, and per-instance transforms, colours and emissive from an Instancer. No image-based lighting and no shadows: a fixed Fresnel term stands in for reflections (classic_pbr_openpbr adds IBL and cascaded shadows). Output is linear HDR, so follow it with a tone mapper such as shaderlib/post-process/ToneMapping.fs. Alpha-to-coverage smooths MASK edges under MSAA; the volumetric toggle composites the presets/volumetric fog chain.\",\n  \"CATEGORIES\": [\n    \"3D\",\n    \"Scene\",\n    \"MDI\",\n    \"Textured\",\n    \"Normal-Mapped\"\n  ],\n  \"VERTEX_INPUTS\": [\n    {\n      \"TYPE\": \"vec3\",\n      \"NAME\": \"position\"\n    },\n    {\n      \"TYPE\": \"vec3\",\n      \"NAME\": \"normal\"\n    },\n    {\n      \"TYPE\": \"vec2\",\n      \"NAME\": \"texcoord_0\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"tangent\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"color_0\"\n    },\n    {\n      \"TYPE\": \"vec2\",\n      \"NAME\": \"texcoord_1\"\n    },\n    {\n      \"TYPE\": \"vec3\",\n      \"NAME\": \"inst_translation\",\n      \"SEMANTIC\": \"translation\",\n      \"REQUIRED\": false\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"inst_color0\",\n      \"SEMANTIC\": \"instance_color0\",\n      \"REQUIRED\": false\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"inst_custom0\",\n      \"SEMANTIC\": \"instance_custom0\",\n      \"REQUIRED\": false\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"inst_matrix0\",\n      \"REQUIRED\": false\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"inst_matrix1\",\n      \"REQUIRED\": false\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"inst_matrix2\",\n      \"REQUIRED\": false\n    },\n    {\n      \"TYPE\": \"uint\",\n      \"NAME\": \"draw_id\",\n      \"SEMANTIC\": \"instance_draw_id\"\n    }\n  ],\n  \"VERTEX_OUTPUTS\": [\n    {\n      \"TYPE\": \"vec3\",\n      \"NAME\": \"v_worldPos\"\n    },\n    {\n      \"TYPE\": \"vec3\",\n      \"NAME\": \"v_normal\"\n    },\n    {\n      \"TYPE\": \"vec2\",\n      \"NAME\": \"v_uv\"\n    },\n    {\n      \"TYPE\": \"uint\",\n      \"NAME\": \"v_drawID\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"v_tangent\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"v_color\"\n    },\n    {\n      \"TYPE\": \"vec2\",\n      \"NAME\": \"v_uv1\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"v_inst_color\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"v_inst_emissive\"\n    }\n  ],\n  \"FRAGMENT_INPUTS\": [\n    {\n      \"TYPE\": \"vec3\",\n      \"NAME\": \"v_worldPos\"\n    },\n    {\n      \"TYPE\": \"vec3\",\n      \"NAME\": \"v_normal\"\n    },\n    {\n      \"TYPE\": \"vec2\",\n      \"NAME\": \"v_uv\"\n    },\n    {\n      \"TYPE\": \"uint\",\n      \"NAME\": \"v_drawID\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"v_tangent\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"v_color\"\n    },\n    {\n      \"TYPE\": \"vec2\",\n      \"NAME\": \"v_uv1\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"v_inst_color\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"v_inst_emissive\"\n    }\n  ],\n  \"FRAGMENT_OUTPUTS\": [\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"isf_FragColor\"\n    }\n  ],\n  \"INPUTS\": [\n    {\n      \"NAME\": \"camera\",\n      \"TYPE\": \"uniform\",\n      \"VISIBILITY\": \"vertex+fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"view\",\n          \"TYPE\": \"mat4\"\n        },\n        {\n          \"NAME\": \"projection\",\n          \"TYPE\": \"mat4\"\n        },\n        {\n          \"NAME\": \"viewProjection\",\n          \"TYPE\": \"mat4\"\n        },\n        {\n          \"NAME\": \"cameraPosition\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"renderSize\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"params\",\n          \"TYPE\": \"vec4\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"scene_lights\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"entries\",\n          \"TYPE\": \"Light[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"scene_light_indices\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"data\",\n          \"TYPE\": \"uint[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"world_transforms\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"vertex+fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"data\",\n          \"TYPE\": \"mat4[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"scene_materials\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"entries\",\n          \"TYPE\": \"Material[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"scene_material_uv_xforms\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"entries\",\n          \"TYPE\": \"MatUVXform[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"per_draws\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"vertex+fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"data\",\n          \"TYPE\": \"PerDraw[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"indirect_draw_cmds\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"none\",\n      \"BUFFER_USAGE\": \"indirect_draw_indexed\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"cmds\",\n          \"TYPE\": \"DrawIndexedCmd[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"scene_counts\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"light_count\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"material_count\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"draw_count\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"_pad0\",\n          \"TYPE\": \"uint\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"env\",\n      \"TYPE\": \"uniform\",\n      \"VISIBILITY\": \"fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"ambient\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"fog_color_density\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"fog_range\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"exposure_gamma\",\n          \"TYPE\": \"vec4\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"alpha_a2c_enabled\",\n      \"TYPE\": \"long\",\n      \"DEFAULT\": 0,\n      \"MIN\": 0,\n      \"MAX\": 1,\n      \"LABEL\": \"Alpha-to-coverage (writes gl_SampleMask under MSAA). Best for foliage edges when MSAA is enabled. Adapts to the framebuffer sample count (1/2/4/8/16); degrades to a 0.5 binary cutoff when MSAA is off.\"\n    },\n    {\n      \"NAME\": \"volumetric_enabled\",\n      \"TYPE\": \"long\",\n      \"DEFAULT\": 0,\n      \"MIN\": 0,\n      \"MAX\": 1,\n      \"LABEL\": \"Volumetric fog composite (1=on)\",\n      \"DESCRIPTION\": \"Sample the upstream vol_integrated SSBO (built by the volumetric_inject / scatter / integrate chain) and apply finalColor = finalColor * transmittance + accum * intensity per fragment. Default off so rasterizers without the volumetric chain wired don't multiply by an unbound (zero-init) transmittance and go pure black.\"\n    },\n    {\n      \"NAME\": \"volumetric_intensity\",\n      \"TYPE\": \"float\",\n      \"DEFAULT\": 1.0,\n      \"MIN\": 0.0,\n      \"MAX\": 4.0,\n      \"LABEL\": \"Volumetric intensity\",\n      \"DESCRIPTION\": \"Scalar on the in-scattered radiance contribution. 1.0 = physical; <1 dampens the fog look; >1 over-blooms the air for stylized output. Has no effect when volumetric_enabled=0.\"\n    }\n  ],\n  \"AUXILIARY\": [\n    {\n      \"NAME\": \"scene_material_wrap\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"entries\",\n          \"TYPE\": \"uvec4[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"cluster_config\",\n      \"ACCESS\": \"read_only\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"cluster_x\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"cluster_y\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"cluster_z\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"max_lights_per_cluster\",\n          \"TYPE\": \"uint\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"vol_integrated\",\n      \"ACCESS\": \"read_only\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"data\",\n          \"TYPE\": \"FroxelIntegrated[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"materialArray0\",\n      \"TYPE\": \"image\",\n      \"IS_ARRAY\": true,\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialArray1\",\n      \"TYPE\": \"image\",\n      \"IS_ARRAY\": true,\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialArray2\",\n      \"TYPE\": \"image\",\n      \"IS_ARRAY\": true,\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialArray3\",\n      \"TYPE\": \"image\",\n      \"IS_ARRAY\": true,\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialArray4\",\n      \"TYPE\": \"image\",\n      \"IS_ARRAY\": true,\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialArray5\",\n      \"TYPE\": \"image\",\n      \"IS_ARRAY\": true,\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialArray6\",\n      \"TYPE\": \"image\",\n      \"IS_ARRAY\": true,\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialArray7\",\n      \"TYPE\": \"image\",\n      \"IS_ARRAY\": true,\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialDyn0\",\n      \"TYPE\": \"image\",\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialDyn1\",\n      \"TYPE\": \"image\",\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialDyn2\",\n      \"TYPE\": \"image\",\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialDyn3\",\n      \"TYPE\": \"image\",\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialDyn4\",\n      \"TYPE\": \"image\",\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialDyn5\",\n      \"TYPE\": \"image\",\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialDyn6\",\n      \"TYPE\": \"image\",\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialDyn7\",\n      \"TYPE\": \"image\",\n      \"WRAP\": \"repeat\"\n    }\n  ],\n  \"TYPES\": [\n    {\n      \"NAME\": \"Light\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"color\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"local_direction\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"range_cone\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"shadow_enabled\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"decay_mode\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"transform_slot\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"normal_bias\",\n          \"TYPE\": \"float\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"Material\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"baseColor\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"metallicRoughnessOcclusionUnlit\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"emissive_strength\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"textureRefs\",\n          \"TYPE\": \"uvec4\"\n        },\n        {\n          \"NAME\": \"feature_mask\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"hit_group_id\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"occlusion_textureRef\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"alpha_cutoff\",\n          \"TYPE\": \"float\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"PerDraw\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"model\",\n          \"TYPE\": \"mat4\"\n        },\n        {\n          \"NAME\": \"normal\",\n          \"TYPE\": \"mat4\"\n        },\n        {\n          \"NAME\": \"material_index\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"tag_hash\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"_pad0\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"_pad1\",\n          \"TYPE\": \"uint\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"DrawIndexedCmd\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"indexCount\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"instanceCount\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"firstIndex\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"baseVertex\",\n          \"TYPE\": \"int\"\n        },\n        {\n          \"NAME\": \"baseInstance\",\n          \"TYPE\": \"uint\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"MatUVXform\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"bc_offset_scale\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"mr_offset_scale\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"normal_offset_scale\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"em_offset_scale\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"occ_offset_scale\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"rotations0\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"rotations1\",\n          \"TYPE\": \"vec4\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"FroxelIntegrated\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"accum_transmittance\",\n          \"TYPE\": \"vec4\"\n        }\n      ]\n    }\n  ],\n  \"PIPELINE_STATE\": {\n    \"DEPTH_TEST\": true,\n    \"DEPTH_WRITE\": true,\n    \"CULL_MODE\": \"back\"\n  }\n}*/\n\n// Sample a material texture channel given its packed textureRef. Matches\n// the SceneFlattener encoding:\n//   bits 31..30 : source (0=NONE/sentinel, 1=STATIC bucket, 2=DYNAMIC slot)\n//   bits 29..23 : bucket index (0..127); the ladder below covers the\n//                 first 16 — higher bucket ids fall back.\n//   bits 23..0  : layer index within the bucket's texture array (static)\n//                 OR slot index in the channel's dynamic sampler set.\n//\n// Each channel declares `kShaderBuckets` sampler2DArrays,\n// one per bucket. Materials with textures of different (format, pixelSize)\n// tuples land in different buckets; the switch ladder below dispatches\n// to the right sampler. Scenes with a single bucket hit case 0 only —\n// all other cases compile in but never execute.\n//\n// Dynamic slots resolve to per-channel sampler2D uniforms `*Dyn0` /\n// `*Dyn1` populated by ScenePreprocessor's aux-texture path — used for\n// large runtime textures (8K video, HDR shader outputs) that can't\n// round-trip through the bucket pool.\nconst uint kShaderBuckets = 16u;\n\n// ─── Manual N-tap anisotropic sampling ──────────────────────────────\n// Qt RHI hard-codes maxAnisotropy=1.0 in every backend; there is no\n// public API to enable hardware anisotropic filtering. Workaround: do\n// it in the shader. Standard \"sum of cones\" formulation:\n//\n//   1. Compute UV gradients dx/dy. Pick the longer one as the major\n//      axis, the shorter as minor.\n//   2. The footprint is an ellipse on the texture; ratio = |major|/|minor|\n//      gives the anisotropy needed (typical value at grazing angles is\n//      4-16).\n//   3. Take 4 hardware-filtered samples spaced along the major axis,\n//      each forced to the minor-axis LOD via textureGrad(minor, minor).\n//      Average them. The minor-axis grad keeps each sample sharp; the\n//      4 spaced taps integrate over the elongated footprint.\n//\n// Shortcut: when the footprint is roughly isotropic (ratio² < 4) we\n// drop to a plain hardware texture() — the 4-tap path is wasted cost.\n//\n// Cost: ~4× texture lookups when the path triggers (only at grazing\n// angles), 1× otherwise. We apply this only to base_color and normal\n// — the channels where the user can see the difference. metallic /\n// roughness / occlusion / emissive stay on plain texture().\nvec4 anisoSample2DArray(sampler2DArray tex, vec3 uv)\n{\n    vec2 dx = dFdx(uv.xy);\n    vec2 dy = dFdy(uv.xy);\n    float lx2 = dot(dx, dx);\n    float ly2 = dot(dy, dy);\n    vec2 major, minor;\n    float ratio2;\n    if(lx2 > ly2)\n    {\n        major = dx; minor = dy;\n        ratio2 = lx2 / max(ly2, 1e-12);\n    }\n    else\n    {\n        major = dy; minor = dx;\n        ratio2 = ly2 / max(lx2, 1e-12);\n    }\n    if(ratio2 < 4.0) return texture(tex, uv);\n\n    // 4 taps at -3/8, -1/8, 1/8, 3/8 of the major axis (uniform spacing,\n    // mean-zero, covers the elongated footprint without touching the\n    // tile borders that a -1/2..1/2 spacing would).\n    float layer = uv.z;\n    vec4 s0 = textureGrad(tex, vec3(uv.xy + major * -0.375, layer), minor, minor);\n    vec4 s1 = textureGrad(tex, vec3(uv.xy + major * -0.125, layer), minor, minor);\n    vec4 s2 = textureGrad(tex, vec3(uv.xy + major *  0.125, layer), minor, minor);\n    vec4 s3 = textureGrad(tex, vec3(uv.xy + major *  0.375, layer), minor, minor);\n    return (s0 + s1 + s2 + s3) * 0.25;\n}\nvec4 anisoSample2DArraySep(texture2DArray tex, sampler smp, vec3 uv)\n{\n    vec2 dx = dFdx(uv.xy);\n    vec2 dy = dFdy(uv.xy);\n    float lx2 = dot(dx, dx);\n    float ly2 = dot(dy, dy);\n    vec2 major, minor;\n    float ratio2;\n    if(lx2 > ly2)\n    {\n        major = dx; minor = dy;\n        ratio2 = lx2 / max(ly2, 1e-12);\n    }\n    else\n    {\n        major = dy; minor = dx;\n        ratio2 = ly2 / max(lx2, 1e-12);\n    }\n    if(ratio2 < 4.0) return texture(sampler2DArray(tex, smp), uv);\n\n    // 4 taps at -3/8, -1/8, 1/8, 3/8 of the major axis (uniform spacing,\n    // mean-zero, covers the elongated footprint without touching the\n    // tile borders that a -1/2..1/2 spacing would).\n    float layer = uv.z;\n    vec4 s0 = textureGrad(sampler2DArray(tex, smp), vec3(uv.xy + major * -0.375, layer), minor, minor);\n    vec4 s1 = textureGrad(sampler2DArray(tex, smp), vec3(uv.xy + major * -0.125, layer), minor, minor);\n    vec4 s2 = textureGrad(sampler2DArray(tex, smp), vec3(uv.xy + major *  0.125, layer), minor, minor);\n    vec4 s3 = textureGrad(sampler2DArray(tex, smp), vec3(uv.xy + major *  0.375, layer), minor, minor);\n    return (s0 + s1 + s2 + s3) * 0.25;\n}\n\nvec4 anisoSample2D(sampler2D tex, vec2 uv)\n{\n    vec2 dx = dFdx(uv);\n    vec2 dy = dFdy(uv);\n    float lx2 = dot(dx, dx);\n    float ly2 = dot(dy, dy);\n    vec2 major, minor;\n    float ratio2;\n    if(lx2 > ly2)\n    {\n        major = dx; minor = dy;\n        ratio2 = lx2 / max(ly2, 1e-12);\n    }\n    else\n    {\n        major = dy; minor = dx;\n        ratio2 = ly2 / max(lx2, 1e-12);\n    }\n    if(ratio2 < 4.0) return texture(tex, uv);\n\n    vec4 s0 = textureGrad(tex, uv + major * -0.375, minor, minor);\n    vec4 s1 = textureGrad(tex, uv + major * -0.125, minor, minor);\n    vec4 s2 = textureGrad(tex, uv + major *  0.125, minor, minor);\n    vec4 s3 = textureGrad(tex, uv + major *  0.375, minor, minor);\n    return (s0 + s1 + s2 + s3) * 0.25;\n}\nvec4 anisoSample2DSep(texture2D tex, sampler smp, vec2 uv)\n{\n    vec2 dx = dFdx(uv);\n    vec2 dy = dFdy(uv);\n    float lx2 = dot(dx, dx);\n    float ly2 = dot(dy, dy);\n    vec2 major, minor;\n    float ratio2;\n    if(lx2 > ly2)\n    {\n        major = dx; minor = dy;\n        ratio2 = lx2 / max(ly2, 1e-12);\n    }\n    else\n    {\n        major = dy; minor = dx;\n        ratio2 = ly2 / max(lx2, 1e-12);\n    }\n    if(ratio2 < 4.0) return texture(sampler2D(tex, smp), uv);\n\n    vec4 s0 = textureGrad(sampler2D(tex, smp), uv + major * -0.375, minor, minor);\n    vec4 s1 = textureGrad(sampler2D(tex, smp), uv + major * -0.125, minor, minor);\n    vec4 s2 = textureGrad(sampler2D(tex, smp), uv + major *  0.125, minor, minor);\n    vec4 s3 = textureGrad(sampler2D(tex, smp), uv + major *  0.375, minor, minor);\n    return (s0 + s1 + s2 + s3) * 0.25;\n}\n\n// One decoder for every material channel. The pool is shared, so the bucket\n// field of the ref is all that picks the array -- including its colourspace,\n// which is part of the bucket key rather than of the channel.\n// Per-texture wrap modes from scene_material_wrap, loaded once per fragment\n// from the material's entry. Four bits per texture ref: wrap_s in the low two,\n// wrap_t in the high two; 0 = repeat, 1 = clamp to edge, 2 = mirror. Slots\n// 0..4 are the main refs (base colour, metal-rough, normal, emissive,\n// occlusion), 5.. the extension refs in MaterialExt.textureRefs order. The\n// pool samples every array with one repeat sampler, so a non-repeat mode is\n// applied to the coordinate here.\nuvec3 g_matWrap = uvec3(0u);\nuint matWrap(uint slot)\n{\n    if(slot < 5u) return (g_matWrap.x >> (4u * slot)) & 0xFu;\n    uint e = slot - 5u;\n    uint word = e < 8u ? g_matWrap.y : g_matWrap.z;\n    return (word >> (4u * (e & 7u))) & 0xFu;\n}\nfloat wrapAxis(float x, uint mode, float halfTexel)\n{\n    if(mode == 1u) return clamp(x, halfTexel, 1.0 - halfTexel);\n    if(mode == 2u) { float t = mod(x, 2.0); return t > 1.0 ? 2.0 - t : t; }\n    return x;\n}\nvec2 applyWrap(vec2 uv, uint wrap, vec2 halfTexel)\n{\n    return vec2(wrapAxis(uv.x, wrap & 3u, halfTexel.x),\n                wrapAxis(uv.y, (wrap >> 2u) & 3u, halfTexel.y));\n}\n// Clamping stays inside the edge texel of the coarsest mip level the\n// trilinear filter reads, so a minified clamped texture does not bleed across\n// the repeat sampler's seam.\nvec2 wrapInset(texture2DArray tex, sampler smp, vec2 dx, vec2 dy)\n{\n    vec2 sz = vec2(textureSize(sampler2DArray(tex, smp), 0).xy);\n    float lod = max(0.0, log2(max(length(dx * sz), length(dy * sz))));\n    return min(vec2(0.5), 0.5 * exp2(ceil(lod)) / sz);\n}\n// anisoSample2DArray's wrapped counterpart. A single trilinear tap whose\n// gradients come from the unwrapped coordinate, so a mirror fold or a clamp\n// edge does not spike the mip selection; repeat, the common case, keeps the\n// anisotropic path untouched.\nvec4 anisoSample2DArrayWrapped(texture2DArray tex, sampler smp, vec3 uv, uint wrap)\n{\n    if(wrap == 0u) return anisoSample2DArraySep(tex, smp, uv);\n    vec2 dx = dFdx(uv.xy);\n    vec2 dy = dFdy(uv.xy);\n    return textureGrad(sampler2DArray(tex, smp),\n                       vec3(applyWrap(uv.xy, wrap, wrapInset(tex, smp, dx, dy)), uv.z),\n                       dx, dy);\n}\n\n\nvec4 sample_material_slot(uint ref, uint wrap, vec2 uv, vec4 fallback)\n{\n    if(ref == 0xFFFFFFFFu) return fallback;\n    uint source = (ref >> 30) & 3u;\n    uint bucket = (ref >> 23) & 0x7Fu;\n    uint idx    = ref & 0x007FFFFFu;\n    if(source == 2u)\n    {\n        switch(idx)\n        {\n            case 0u: return anisoSample2DSep(materialDyn_tex[0], materialDyn_smp, uv);\n            case 1u: return anisoSample2DSep(materialDyn_tex[1], materialDyn_smp, uv);\n            case 2u: return anisoSample2DSep(materialDyn_tex[2], materialDyn_smp, uv);\n            case 3u: return anisoSample2DSep(materialDyn_tex[3], materialDyn_smp, uv);\n            case 4u: return anisoSample2DSep(materialDyn_tex[4], materialDyn_smp, uv);\n            case 5u: return anisoSample2DSep(materialDyn_tex[5], materialDyn_smp, uv);\n            case 6u: return anisoSample2DSep(materialDyn_tex[6], materialDyn_smp, uv);\n            case 7u: return anisoSample2DSep(materialDyn_tex[7], materialDyn_smp, uv);\n        }\n        return fallback;\n    }\n    switch(bucket)\n    {\n        case 0u: return anisoSample2DArrayWrapped(materialArray_tex[0], materialArray_smp, vec3(uv, float(idx)), wrap);\n        case 1u: return anisoSample2DArrayWrapped(materialArray_tex[1], materialArray_smp, vec3(uv, float(idx)), wrap);\n        case 2u: return anisoSample2DArrayWrapped(materialArray_tex[2], materialArray_smp, vec3(uv, float(idx)), wrap);\n        case 3u: return anisoSample2DArrayWrapped(materialArray_tex[3], materialArray_smp, vec3(uv, float(idx)), wrap);\n        case 4u: return anisoSample2DArrayWrapped(materialArray_tex[4], materialArray_smp, vec3(uv, float(idx)), wrap);\n        case 5u: return anisoSample2DArrayWrapped(materialArray_tex[5], materialArray_smp, vec3(uv, float(idx)), wrap);\n        case 6u: return anisoSample2DArrayWrapped(materialArray_tex[6], materialArray_smp, vec3(uv, float(idx)), wrap);\n        case 7u: return anisoSample2DArrayWrapped(materialArray_tex[7], materialArray_smp, vec3(uv, float(idx)), wrap);\n    }\n    return fallback;\n}\n\nvec4 sample_slot_bc(uint ref, uint wrap, vec2 uv, vec4 fallback)\n{\n    return sample_material_slot(ref, wrap, uv, fallback);\n}\n\n\nvec4 sample_slot_mr(uint ref, uint wrap, vec2 uv, vec4 fallback)\n{\n    return sample_material_slot(ref, wrap, uv, fallback);\n}\n\n\nvec4 sample_slot_nrm(uint ref, uint wrap, vec2 uv, vec4 fallback)\n{\n    return sample_material_slot(ref, wrap, uv, fallback);\n}\n\n\nvec4 sample_slot_em(uint ref, uint wrap, vec2 uv, vec4 fallback)\n{\n    return sample_material_slot(ref, wrap, uv, fallback);\n}\n\n\n// Separate glTF occlusionTexture (single-channel data, R = occlusion).\n// Sampled only when feature_mask carries `has_separate_occlusion`;\n// otherwise the main path falls back to MR.r per the common packed-MR\n// convention. fallback = 1 → identity (no occlusion).\nvec4 sample_slot_occ(uint ref, uint wrap, vec2 uv, vec4 fallback)\n{\n    return sample_material_slot(ref, wrap, uv, fallback);\n}\n\n\n// glTF feature_mask bits — must mirror SceneGPUState.hpp's\n// material_feature namespace.\nconst uint kFeat_alpha_mask           = 1u << 16u;\nconst uint kFeat_alpha_blend          = 1u << 17u;\nconst uint kFeat_double_sided         = 1u << 18u;\nconst uint kFeat_has_separate_occ     = 1u << 19u;\n// Per-channel texcoord_set bits (20-29). 2 bits per channel, value\n// 0 = TEXCOORD_0, value 1 = TEXCOORD_1. Out-of-range values collapse\n// to TEXCOORD_0 (the shift-mask in packMaterial clamps to 0/1).\nconst uint kFeat_tcset_bc_shift       = 20u;\nconst uint kFeat_tcset_mr_shift       = 22u;\nconst uint kFeat_tcset_nrm_shift      = 24u;\nconst uint kFeat_tcset_em_shift       = 26u;\nconst uint kFeat_tcset_occ_shift      = 28u;\n\nvec2 pick_uv(uint feature_mask, uint shift, vec2 uv0, vec2 uv1)\n{\n    return ((feature_mask >> shift) & 0x3u) == 1u ? uv1 : uv0;\n}\n\n// KHR_texture_transform helper: glTF defines the transform in UV space\n// as `uv' = R(rotation) * S(scale) * uv + offset`, with rotation\n// applied AFTER scale and BEFORE the offset shift. Identity defaults\n// (offset=0, scale=1, rotation=0) pass through unchanged.\nvec2 apply_uv_xform(vec2 uv, vec4 offset_scale, float rotation)\n{\n    vec2 scaled = uv * offset_scale.zw;\n    float c = cos(rotation), s = sin(rotation);\n    vec2 rotated = vec2(c * scaled.x - s * scaled.y,\n                        s * scaled.x + c * scaled.y);\n    return rotated + offset_scale.xy;\n}\n\n// Shader-level alpha-to-coverage. QRhi (6.12) doesn't expose\n// AlphaToCoverage on QRhiGraphicsPipeline, so we replicate the\n// behaviour at the shader level: gl_SampleMask[0] is a writable\n// per-fragment built-in where each bit selects whether the\n// corresponding MSAA sample is written. Convert alpha to a sample\n// count, set that many bits, screen-space-rotate per pixel so the\n// MSAA resolve smooths the silhouette into a soft edge.\n//\n// Sample count comes from MSAA_SAMPLES, an integer auto-injected by\n// libisf into the renderer UBO at binding=0 — score writes the active\n// RenderList's sample count there each frame. (We can't use\n// gl_NumSamples: glslang strips it when targeting SPIR-V.) Score lets\n// users pick any of {1, 2, 4, 8, 16}. With MSAA off, MSAA_SAMPLES=1\n// and we degrade to a 0.5 binary cutoff. Vulkan caps multisample\n// rasterization at 16x in practice; clamp there so the rotation math\n// stays defined for 32-bit uints.\n//\n// Returns false when the fragment is fully transparent → caller\n// discards (early-out skips the rest of main()).\nbool applyAlphaToCoverage(float alpha)\n{\n    if(alpha <= 0.0)\n        return false;\n\n    int samples = clamp(MSAA_SAMPLES, 1, 16);\n    uint full = (samples >= 32) ? 0xFFFFFFFFu\n                                : ((1u << uint(samples)) - 1u);\n\n    if(alpha >= 1.0)\n    {\n        gl_SampleMask[0] = int(full);\n        return true;\n    }\n    int n = int(round(alpha * float(samples)));\n    if(n <= 0)\n        return false;\n    if(n >= samples)\n    {\n        gl_SampleMask[0] = int(full);\n        return true;\n    }\n\n    // MSAA sample counts are powers of two, so (S-1) is a valid mask.\n    // shift lands in [0, S-1]; rotation handles shift==0 cleanly\n    // because base >> S is well-defined for S<=16 (< 32 bits).\n    uint S = uint(samples);\n    uint hash = uint(gl_FragCoord.x) * 1597u\n              + uint(gl_FragCoord.y) * 2731u;\n    uint shift = hash & (S - 1u);\n    uint base  = (1u << uint(n)) - 1u;\n    uint rot   = ((base << shift) | (base >> (S - shift))) & full;\n    gl_SampleMask[0] = int(rot);\n    return true;\n}\n\n// Map gl_FragCoord + view-space Z to a froxel index. Same log-spaced Z\n// slicing build_cluster_aabbs.csf uses, same (z*Y + y)*X + x flattening\n// volumetric_integrate.csf writes — keep these three formulas in sync\n// or sampling lands in the wrong cell.\nuint scoreClusterId(vec2 fragCoord, float viewZ)\n{\n    vec2 uv = fragCoord / camera.renderSize.xy;\n    uint gx = cluster_config.cluster_x;\n    uint gy = cluster_config.cluster_y;\n    uint gz = cluster_config.cluster_z;\n\n    uint tx = uint(clamp(floor(uv.x * float(gx)), 0.0, float(gx) - 1.0));\n    uint ty = uint(clamp(floor(uv.y * float(gy)), 0.0, float(gy) - 1.0));\n\n    float zNear = camera.params.y;\n    float zFar  = camera.params.z;\n    float depth = max(-viewZ, zNear);\n    float t = float(gz) * log(depth / zNear) / log(zFar / zNear);\n    uint tz = uint(clamp(t, 0.0, float(gz) - 1.0));\n\n    return (tz * gy + ty) * gx + tx;\n}\n\n// Inline volumetric fog composite — see classic_pbr_openpbr.frag for\n// the full rationale. Two production-grade refinements vs the naive\n// nearest-cell lookup:\n//   1. Trilinear interpolation across the 8 surrounding froxels —\n//      hides the cluster grid (16x9x24 default) which otherwise\n//      shows up as a hard checkerboard at cell boundaries.\n//   2. volumetric_intensity blends toward identity rather than just\n//      scaling accum, so low intensity == \"less fog\" rather than\n//      \"no source + tiny in-scatter\".\n// Identity fallback when the toggle is off or cluster_x == 0u.\nvec3 applyVolumetric(vec3 inColor, vec2 fragCoord, float viewZ)\n{\n    if(volumetric_enabled == 0)\n        return inColor;\n\n    uint gx = cluster_config.cluster_x;\n    uint gy = cluster_config.cluster_y;\n    uint gz = cluster_config.cluster_z;\n    if(gx == 0u || gy == 0u || gz == 0u)\n        return inColor;\n\n    vec2  uv = fragCoord / camera.renderSize.xy;\n    float zNear = camera.params.y;\n    float zFar  = camera.params.z;\n    float depth = max(-viewZ, zNear);\n    float fx = uv.x * float(gx) - 0.5;\n    float fy = uv.y * float(gy) - 0.5;\n    float fz = float(gz) * log(depth / zNear) / log(zFar / zNear) - 0.5;\n\n    vec3 cf = clamp(vec3(fx, fy, fz), vec3(0.0),\n                    vec3(float(gx) - 1.0001,\n                         float(gy) - 1.0001,\n                         float(gz) - 1.0001));\n    vec3 cb = floor(cf);\n    vec3 t  = cf - cb;\n    uvec3 i0 = uvec3(cb);\n    uvec3 i1 = min(i0 + 1u, uvec3(gx - 1u, gy - 1u, gz - 1u));\n\n    #define IDX(ix, iy, iz) (((iz) * gy + (iy)) * gx + (ix))\n    vec4 c000 = vol_integrated.data[IDX(i0.x, i0.y, i0.z)].accum_transmittance;\n    vec4 c100 = vol_integrated.data[IDX(i1.x, i0.y, i0.z)].accum_transmittance;\n    vec4 c010 = vol_integrated.data[IDX(i0.x, i1.y, i0.z)].accum_transmittance;\n    vec4 c110 = vol_integrated.data[IDX(i1.x, i1.y, i0.z)].accum_transmittance;\n    vec4 c001 = vol_integrated.data[IDX(i0.x, i0.y, i1.z)].accum_transmittance;\n    vec4 c101 = vol_integrated.data[IDX(i1.x, i0.y, i1.z)].accum_transmittance;\n    vec4 c011 = vol_integrated.data[IDX(i0.x, i1.y, i1.z)].accum_transmittance;\n    vec4 c111 = vol_integrated.data[IDX(i1.x, i1.y, i1.z)].accum_transmittance;\n    #undef IDX\n\n    vec4 v = mix(mix(mix(c000, c100, t.x), mix(c010, c110, t.x), t.y),\n                 mix(mix(c001, c101, t.x), mix(c011, c111, t.x), t.y),\n                 t.z);\n\n    float transm = clamp(v.a, 0.0, 1.0);\n    vec3  accum  = v.rgb;\n\n    float k       = volumetric_intensity;\n    float k_blend = clamp(k, 0.0, 1.0);\n    float transm_eff = mix(1.0, transm, k_blend);\n    vec3  accum_eff  = accum * k;\n\n    return inColor * transm_eff + accum_eff;\n}\n\nvoid main()\n{\n    // Default coverage: keep every MSAA sample. Once applyAlphaToCoverage\n    // exists in the module, the SPIR-V output declares gl_SampleMask, and\n    // any path that doesn't assign it leaves the value undefined — most\n    // drivers default that to 0 and cull every sample, producing block-\n    // speckle artifacts on non-alpha-mask materials. Seeding to all-ones\n    // here makes the non-A2C paths render correctly; the A2C branch\n    // overrides this for masked fragments.\n    gl_SampleMask[0] = -1;\n\n    PerDraw pd = per_draws.data[v_drawID];\n    Material mat = scene_materials.entries[pd.material_index];\n    MatUVXform mx = scene_material_uv_xforms.entries[pd.material_index];\n    g_matWrap = scene_material_wrap.entries[pd.material_index].xyz;\n\n    // glTF doubleSided: pipeline-side culling is OFF (cull_mode=none\n    // in the MDI batch) so we get both faces. For SINGLE-sided materials\n    // we discard back-facing fragments here to mimic CULL_BACK. For\n    // DOUBLE-sided materials we keep the fragment and flip the normal\n    // below so lighting on the back side works correctly.\n    bool is_double_sided = (mat.feature_mask & kFeat_double_sided) != 0u;\n    if(!is_double_sided && !gl_FrontFacing)\n        discard;\n\n    // Pick the per-channel texcoord source (TEXCOORD_0 vs TEXCOORD_1)\n    // before applying the KHR_texture_transform. glTF allows each\n    // texture_info to override its texcoord_set independently — BC\n    // might use TEXCOORD_0 while Emissive uses TEXCOORD_1, etc.\n    vec2 base_uv_bc  = pick_uv(mat.feature_mask, kFeat_tcset_bc_shift,  v_uv, v_uv1);\n    vec2 base_uv_mr  = pick_uv(mat.feature_mask, kFeat_tcset_mr_shift,  v_uv, v_uv1);\n    vec2 base_uv_nrm = pick_uv(mat.feature_mask, kFeat_tcset_nrm_shift, v_uv, v_uv1);\n    vec2 base_uv_em  = pick_uv(mat.feature_mask, kFeat_tcset_em_shift,  v_uv, v_uv1);\n    vec2 base_uv_occ = pick_uv(mat.feature_mask, kFeat_tcset_occ_shift, v_uv, v_uv1);\n\n    // Per-channel UVs after KHR_texture_transform.\n    vec2 uv_bc  = apply_uv_xform(base_uv_bc,  mx.bc_offset_scale,     mx.rotations0.x);\n    vec2 uv_mr  = apply_uv_xform(base_uv_mr,  mx.mr_offset_scale,     mx.rotations0.y);\n    vec2 uv_nrm = apply_uv_xform(base_uv_nrm, mx.normal_offset_scale, mx.rotations0.z);\n    vec2 uv_em  = apply_uv_xform(base_uv_em,  mx.em_offset_scale,     mx.rotations0.w);\n    vec2 uv_occ = apply_uv_xform(base_uv_occ, mx.occ_offset_scale,    mx.rotations1.x);\n\n    // Pre-pull env knobs so the early-out (unlit) and main path both\n    // see the same values. Defaults come from EnvironmentLoader if the\n    // user wired one; otherwise the merged scene_environment carries\n    // safe identity-ish values (ambient=0, exposure=1, gamma=2.2,\n    // fog disabled).\n    vec3  ambient_col   = env.ambient.rgb * env.ambient.w;\n    float exposure_mul  = max(env.exposure_gamma.x, 1e-6);\n    float gamma         = max(env.exposure_gamma.y, 1e-3);\n\n    // ─── Base color ────────────────────────────────────────────────────\n    // glTF: final base = baseColorFactor × baseColorTexture × COLOR_0\n    // (vertex color). v_color defaults to white when the mesh doesn't\n    // have COLOR_0 (slab uploader fills with vec4(1) in that case).\n    vec4 bc = sample_slot_bc(mat.textureRefs.x, matWrap(0u), uv_bc, vec4(1.0));\n\n    // Alpha-mask edge-bleed compensation. Source PNGs for foliage / hair\n    // / fence-style cutouts have alpha=0 in transparent regions with\n    // RGB=0 there too (standard authoring). Mip / aniso filtering\n    // averages RGB and alpha independently — near a leaf edge the\n    // sampled RGB ends up `leaf_color × alpha_avg`, so post-alpha-test\n    // surviving fragments read a darkened RGB and the silhouette gets a\n    // black halo. Dividing RGB by alpha inverts the alpha-weighted\n    // averaging and recovers the source colour. Skip when alpha is near\n    // zero (would discard anyway) and when the material isn't\n    // alpha-masked (BLEND / OPAQUE both want the literal sampled RGB).\n    if((mat.feature_mask & kFeat_alpha_mask) != 0u && bc.a > 1e-3)\n        bc.rgb /= bc.a;\n\n    // Per-instance broadcast colour rides through `v_inst_color` from\n    // the vertex stage. For non-instanced draws the REQUIRED:false\n    // fallback fires identity (1,1,1,1) so the modulation collapses\n    // to the per-vertex × material × baseColor product.\n    vec3 base = mat.baseColor.rgb * bc.rgb * v_color.rgb * v_inst_color.rgb;\n    float alpha = mat.baseColor.a * bc.a * v_color.a * v_inst_color.a;\n\n    // glTF alphaMode=MASK — early discard before any expensive work.\n    // Two paths:\n    //   alpha_a2c_enabled = 1 → shader-level alpha-to-coverage via\n    //                            gl_SampleMask. Best edge quality when\n    //                            MSAA is on; degrades gracefully to a\n    //                            hard cutoff when MSAA is off (round\n    //                            saturates to 0 / 8).\n    //   default               → classic binary cutoff.\n    if((mat.feature_mask & kFeat_alpha_mask) != 0u)\n    {\n        if(alpha_a2c_enabled != 0)\n        {\n            if(!applyAlphaToCoverage(alpha))\n                discard;\n        }\n        else\n        {\n            if(alpha < mat.alpha_cutoff)\n                discard;\n        }\n    }\n\n    // ─── Metal-Rough-Occlusion (glTF packing: R=occ, G=rough, B=metal) ─\n    vec4 mr = sample_slot_mr(mat.textureRefs.y, matWrap(1u), uv_mr, vec4(1.0, 1.0, 1.0, 1.0));\n    float metallic\n        = mat.metallicRoughnessOcclusionUnlit.x * mr.b;\n    float roughness\n        = clamp(mat.metallicRoughnessOcclusionUnlit.y * mr.g, 0.04, 1.0);\n    // Occlusion: prefer separate occlusionTexture when set; else fall\n    // back to MR.r (the common packed-MR convention).\n    float occ_sample;\n    if((mat.feature_mask & kFeat_has_separate_occ) != 0u)\n        occ_sample = sample_slot_occ(mat.occlusion_textureRef, matWrap(4u), uv_occ, vec4(1.0)).r;\n    else\n        occ_sample = mr.r;\n    float occlusion = occ_sample * mat.metallicRoughnessOcclusionUnlit.z;\n    float unlit     = mat.metallicRoughnessOcclusionUnlit.w;\n\n    // ─── Emissive ─────────────────────────────────────────────────────\n    vec4 em = sample_slot_em(mat.textureRefs.w, matWrap(3u), uv_em, vec4(1.0));\n    vec3 emissive\n        = mat.emissive_strength.xyz * em.rgb * mat.emissive_strength.w;\n    emissive += v_inst_emissive.rgb;\n\n    if(unlit > 0.5)\n    {\n        // Volumetric composite BEFORE exposure_mul — accum is in raw\n        // light units (same scale as the BSDF result), so both sides\n        // of `inColor * transm + accum` stay in matched units.\n        // Output is linear HDR — the downstream tonemap owns the\n        // HDR→display compression and sRGB encode. (Doing pow(_,1/gamma)\n        // here would clip everything > 1 post-exposure to flat white\n        // before the tonemap could read the HDR signal — that's what\n        // made volumetric in-scatter blow out to saturated pink.)\n        vec3 color = base + emissive;\n        float viewZ_unlit = (camera.view * vec4(v_worldPos, 1.0)).z;\n        color = applyVolumetric(color, gl_FragCoord.xy, viewZ_unlit);\n        color *= exposure_mul;\n        isf_FragColor = vec4(max(color, vec3(0.0)), (mat.feature_mask & (1u << 17u)) != 0u ? alpha : 1.0);\n        return;\n    }\n\n    // ─── Surface normal (tangent-space normal map if present) ─────────\n    vec3 N = normalize(v_normal);\n    // Double-sided: flip the surface normal for back-facing fragments\n    // so the BRDF evaluates with the correct hemisphere on both sides\n    // of the surface. (Single-sided materials never reach here for\n    // back faces — they were discarded above.)\n    if(is_double_sided && !gl_FrontFacing)\n        N = -N;\n    // Toksvig variance accumulator (Olano-Baker 2010). Captures the\n    // amount of normal-map variance lost to mip-level averaging /\n    // multi-tap anisotropic averaging — info the GPU's bilinear+mip\n    // filter normally throws away when shaders re-normalize sampled\n    // normals. Folded into the specular-AA block below alongside the\n    // screen-space (Tokuyoshi-Kaplanyan) variance.\n    float toksvig_sigma2 = 0.0;\n    uint normRef = mat.textureRefs.z;\n    if(normRef != 0xFFFFFFFFu && length(v_tangent.xyz) > 0.5)\n    {\n        vec3 T = normalize(v_tangent.xyz);\n        vec3 B = normalize(cross(N, T) * v_tangent.w);\n        mat3 TBN = mat3(T, B, N);\n        // Normal map sampling goes through the bucket ladder so\n        // mixed-resolution / compressed normal atlases work. The\n        // default (0.5,0.5,1.0) fallback decodes to a zero tangent-\n        // space delta — same as no normal map at all — if the bucket\n        // slot isn't populated.\n        //\n        // Keep the UN-NORMALIZED sample so its length can drive the\n        // Toksvig boost: anisoSample averages multiple weighted taps\n        // and mip filtering averages within texels, both of which\n        // shorten |n| when sub-pixel normals had directional spread.\n        // (1 - |n|²) is the \"lost variance\" added back as roughness.\n        vec3 nm_raw = sample_slot_nrm(normRef, matWrap(2u), uv_nrm,\n                                      vec4(0.5, 0.5, 1.0, 1.0)).xyz\n                      * 2.0 - 1.0;\n        toksvig_sigma2 = max(0.0, 1.0 - dot(nm_raw, nm_raw));\n        N = normalize(TBN * normalize(nm_raw));\n    }\n\n    vec3 V = normalize(camera.cameraPosition.xyz - v_worldPos);\n    float NdotV = max(dot(N, V), 1e-4);\n\n    // Metallic workflow.\n    vec3 F0 = mix(vec3(0.04), base, metallic);\n    vec3 kd = (1.0 - metallic) * base;\n\n    // Cheap environment term — same \"fake IBL\" as classic_pbr_textured;\n    // classic_pbr_ibl is the cubemap-sampled variant.\n    vec3 Fv = F0 + (1.0 - F0) * pow(1.0 - NdotV, 5.0);\n    vec3 fake_env = Fv * base * 0.25;\n\n    // Ambient comes from EnvironmentLoader (env.ambient.rgb × intensity\n    // in .w). When the user hasn't wired one, ambient_col is zero and\n    // the fake_env term + lights carry the lighting. The 0.04 floor is\n    // gone — letting users actually dial ambient down to black.\n    vec3 result = ambient_col * base * occlusion\n                  + emissive\n                  + fake_env * occlusion;\n\n    float alpha_g = max(roughness * roughness, 1e-4);\n    float alpha2 = alpha_g * alpha_g;\n    float k = (roughness + 1.0) * (roughness + 1.0) / 8.0;\n\n    // ─── Specular antialiasing — Tokuyoshi-Kaplanyan + Toksvig ───────\n    //\n    // Three variance sources combined into a single roughness boost:\n    //\n    //   (A) Tokuyoshi-Kaplanyan 2019, \"Improved Geometric Specular\n    //       Antialiasing\" — screen-space derivatives of the world-\n    //       space normal. Captures sub-pixel-footprint normal\n    //       variance from geometry, normal-map silhouettes, and\n    //       interpolation across neighbours.\n    //\n    //   (B) Toksvig 2005, \"Mipmapping Normal Maps\" — texture-space\n    //       variance from filtered-normal shortening. Captures\n    //       variance lost to mip averaging + our multi-tap\n    //       anisotropic sampler that the GPU's linear filter and\n    //       shader's normalize() throw away.\n    //\n    //   (C) Grazing-angle amplification — a heuristic 1/NdotV scale\n    //       (capped) on the screen-space variance, approximating\n    //       Tokuyoshi-Kaplanyan's anisotropic Jacobian projection of\n    //       normal variance onto the half-vector tangent plane. The\n    //       full anisotropic form derives this matrix-multiply\n    //       explicitly; the 1/NdotV scalar captures the leading-\n    //       order behaviour at grazing where the BRDF stretches\n    //       most. Targets the \"noisy floor at grazing light\"\n    //       failure mode: at grazing, the half-vector becomes\n    //       perpendicular to the surface, NdotH gets small, and the\n    //       GGX D term's denominator hyperbola makes small N\n    //       variations move the highlight in/out of pixels.\n    //\n    // (A)+(B) cover variance from BOTH variance domains — the\n    // screen-space and texture-space sources are independent and\n    // additive. (C) amplifies (A) where the BRDF Jacobian demands it.\n    vec3 dNdx = dFdx(N);\n    vec3 dNdy = dFdy(N);\n    float kernelRoughness2 = 2.0 * (dot(dNdx, dNdx) + dot(dNdy, dNdy));\n\n    // (C) grazing amplification. NdotV floor of 0.05 prevents\n    // runaway at near-tangent view; cap at 8× keeps the boost\n    // bounded so we don't blow specular into pure diffuse.\n    float grazing_aa = clamp(1.0 / max(NdotV, 0.05), 1.0, 8.0);\n    kernelRoughness2 *= grazing_aa;\n\n    // Combine (A)·grazing + (B). Cap to keep alpha² in [0, 1] after\n    // the boost; 0.5 is the standard upper bound used by Filament +\n    // the Tokuyoshi-Kaplanyan reference.\n    const float specAaSigma2Max = 0.5;\n    float total_aa_sigma2 = clamp(kernelRoughness2 + toksvig_sigma2,\n                                  0.0, specAaSigma2Max);\n    alpha2 = clamp(alpha2 + total_aa_sigma2, 0.0, 1.0);\n    alpha_g = sqrt(alpha2);\n    // Re-derive Schlick-Smith k from the filtered roughness too so the\n    // G term widens in lockstep with D — otherwise rough-but-filtered\n    // surfaces still get an over-tight visibility term.\n    float roughness_f = sqrt(alpha_g);\n    k = (roughness_f + 1.0) * (roughness_f + 1.0) / 8.0;\n\n    uint n = scene_counts.light_count;\n    for(uint i = 0u; i < n; ++i)\n    {\n        uint slot = scene_light_indices.data[i];\n        Light L = scene_lights.entries[slot];\n\n        // Two paths for resolving the light's world-space placement:\n        //\n        //   transform_slot == 0xFFFFFFFF (sentinel):\n        //     The light was authored procedurally (e.g. by a compute CSF\n        //     reading a point cloud or particle system) and carries its\n        //     world position inline in local_direction.xyz. Skip the\n        //     world_transforms lookup — there's no matching scene-node\n        //     entry. Only point lights (type == 1) are well-defined\n        //     under this convention; directional with sentinel falls\n        //     back to treating .xyz as a direction, spot is unsupported.\n        //\n        //   transform_slot != sentinel:\n        //     Classic scene-node-attached light. World direction and\n        //     position come from the node's accumulated world transform\n        //     (published by ScenePreprocessor's FlattenVisitor).\n        float _type_f = L.local_direction.w;\n        vec3 ld_world;\n        vec3 lp_world;\n        if(L.transform_slot == 0xFFFFFFFFu)\n        {\n            if(_type_f < 0.5)\n            {\n                // Directional: .xyz is the world direction (same\n                // convention the scene-node path uses — no transform to\n                // apply since the light isn't parented to any node).\n                ld_world = normalize(L.local_direction.xyz);\n                lp_world = vec3(0.0);\n            }\n            else\n            {\n                // Point: .xyz is the world position. A default direction\n                // lets spot-cone code below degenerate gracefully for\n                // spot lights authored this way (cone attenuation will\n                // be effectively wide-open, since we have no real axis).\n                lp_world = L.local_direction.xyz;\n                ld_world = vec3(0.0, -1.0, 0.0);\n            }\n        }\n        else\n        {\n            mat4 W = world_transforms.data[L.transform_slot];\n            ld_world = normalize(mat3(W) * L.local_direction.xyz);\n            lp_world = W[3].xyz;\n        }\n        // Reconstruct the old LightGPU-shape vec4s so the BRDF body\n        // below (which references pos_type / color_i / dir_r) stays\n        // unchanged. type enum stays in .w; for directional lights the\n        // xyz holds the world direction, for point/spot it holds the\n        // world position — matching the prior packLight convention.\n        vec4 pos_type = vec4(\n            (_type_f < 0.5) ? ld_world : lp_world,\n            _type_f);\n        vec4 color_i  = L.color;\n        vec4 dir_r    = vec4(ld_world, L.range_cone.x);\n\n        vec3 Ldir;\n        float atten = 1.0;\n        if(pos_type.w < 0.5)\n        {\n            // Directional: no distance, no decay — per glTF / OpenPBR\n            // convention the 1/d² term doesn't apply.\n            Ldir = normalize(-pos_type.xyz);\n        }\n        else\n        {\n            vec3 toL = pos_type.xyz - v_worldPos;\n            float d = length(toL);\n            Ldir = toL / max(d, 1e-5);\n\n            // Hard cutoff: range == 0 is the \"no cutoff\" sentinel (glTF\n            // + ossia convention). Otherwise linearly fade over the\n            // last interval so the light doesn't pop off at exactly the\n            // range boundary.\n            if(dir_r.w > 0.0) atten = max(0.0, 1.0 - d / dir_r.w);\n\n            // Distance decay — switches on L.decay_mode so linear / none /\n            // cubic authored by the user or extracted from FBX actually\n            // reach the shader instead of being silently collapsed to\n            // the quadratic curve. Modes:\n            //   0 = none       (constant — legitimate for area lights\n            //                   and stylised looks)\n            //   1 = linear     1 / (1 + d)\n            //   2 = quadratic  1 / (1 + d²)   — physically correct default\n            //   3 = cubic      1 / (1 + d³)   — exaggerated falloff\n            uint decay = L.decay_mode;\n            if(decay == 1u)\n                atten *= 1.0 / (1.0 + d);\n            else if(decay == 2u)\n                atten *= 1.0 / (1.0 + d * d);\n            else if(decay == 3u)\n                atten *= 1.0 / (1.0 + d * d * d);\n            // decay == 0u → no distance attenuation; `atten` keeps the\n            // range cutoff contribution only.\n\n            // Spot-cone attenuation. Inner / outer cones are stored as\n            // cosines (packed CPU-side in Light.cpp) so the fragment-side\n            // test is one dot product + a linear ramp, matching the glTF\n            // KHR_lights_punctual reference formula:\n            //   t = clamp((cos_angle - outer) / (inner - outer), 0, 1)\n            //   atten *= t\n            // Outside the outer cone → t = 0, light doesn't contribute.\n            // Inside the inner cone → t = 1, full spot intensity.\n            // Between → linear falloff. type ≈ 2 = spot (local_direction.w\n            // packs the enum; see RawLightData::local_direction in\n            // SceneGPUState.hpp). Point lights (type ≈ 1) skip this\n            // block, so the spot-specific math doesn't perturb them.\n            if(pos_type.w > 1.5 && pos_type.w < 2.5)\n            {\n                float cos_to_frag = dot(-Ldir, normalize(dir_r.xyz));\n                float inner_cos   = L.range_cone.y;\n                float outer_cos   = L.range_cone.z;\n                atten *= clamp(\n                    (cos_to_frag - outer_cos)\n                        / max(inner_cos - outer_cos, 1e-5),\n                    0.0, 1.0);\n            }\n        }\n\n        float NdotL = max(dot(N, Ldir), 0.0);\n        if(NdotL <= 0.0) continue;\n\n        vec3 H = normalize(Ldir + V);\n        float NdotH = max(dot(N, H), 0.0);\n        float VdotH = max(dot(V, H), 0.0);\n\n        float denom_d = NdotH * NdotH * (alpha2 - 1.0) + 1.0;\n        float D = alpha2 / (3.14159 * denom_d * denom_d);\n\n        float G_v = NdotV / (NdotV * (1.0 - k) + k);\n        float G_l = NdotL / (NdotL * (1.0 - k) + k);\n        float G = G_v * G_l;\n\n        vec3 F = F0 + (1.0 - F0) * pow(1.0 - VdotH, 5.0);\n\n        vec3 spec = (D * G * F) / max(4.0 * NdotV * NdotL, 1e-4);\n        vec3 diffuse_term = (vec3(1.0) - F) * kd / 3.14159;\n\n        vec3 lightCol = color_i.rgb * color_i.w;\n        result += atten * lightCol * NdotL * (diffuse_term + spec);\n    }\n\n    // Linear fog: blend with fog_color over [start, end]. fog_range.w\n    // is the enabled flag (set by EnvironmentLoader). When disabled\n    // we skip the work.\n    if(env.fog_range.w > 0.5)\n    {\n        float view_z = distance(camera.cameraPosition.xyz, v_worldPos);\n        float f_s = env.fog_range.x;\n        float f_e = max(env.fog_range.y, f_s + 1e-3);\n        float t = clamp((view_z - f_s) / (f_e - f_s), 0.0, 1.0);\n        result = mix(result, env.fog_color_density.rgb, t);\n    }\n\n    // Volumetric composite BEFORE exposure_mul. accum from the integrate\n    // pass is in raw light units (same scale as the BSDF result), so\n    // both sides of `inColor * transm + accum` stay in matched units —\n    // applying after exposure makes accum dominate dim surfaces and\n    // lose to bright/specular surfaces, which was the original\n    // \"foliage punches through fog\" symptom.\n    //\n    // view_z above is `distance(eye, worldPos)` (positive); applyVolumetric /\n    // scoreClusterId need view-space Z (negative). Recompute from\n    // camera.view to keep the cluster lookup consistent with\n    // build_cluster_aabbs / volumetric_integrate.\n    float viewZ = (camera.view * vec4(v_worldPos, 1.0)).z;\n    result = applyVolumetric(result, gl_FragCoord.xy, viewZ);\n\n    result *= exposure_mul;\n\n    // Output is LINEAR HDR. The downstream tonemap node owns the\n    // HDR→display compression (ACES / Reinhard / filmic / etc.) and\n    // the sRGB encode. The previous `pow(result, 1/gamma)` here was\n    // sRGB-encoding the HDR before the tonemap could read it: any\n    // radiance > 1.0 post-exposure clipped to flat white at gamma\n    // encode, which is what made volumetric in-scatter blow out to\n    // saturated pink.\n    isf_FragColor = vec4(max(result, vec3(0.0)), (mat.feature_mask & (1u << 17u)) != 0u ? alpha : 1.0);\n}\n","Inlets":[{"uuid":"f2ab26ea-415d-45a2-bfbc-2968c7c92a33","ObjectName":"Inlet","id":1000,"Hidden":false,"Custom":"Geometry In","Exposed":"geometry in"},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":0,"Hidden":true,"Custom":"Mode","Exposed":"mode","Value":{"Int":0},"Init":{"Int":0},"Domain":{"Int":{"Values":[0,1,2,3]}},"Values":[["Triangles",{"Int":0}],["Points",{"Int":1}],["Lines",{"Int":2}],["Geometry",{"Int":3}]],"FolderPort":"","FileExtensions":""},{"uuid":"fb27e4cb-ea7f-41e2-ad92-2354498c1b6b","ObjectName":"Inlet","id":1,"Hidden":true,"Custom":"EnableBlend","Exposed":"enableblend","Value":{"Bool":false},"Init":{"Bool":false},"Domain":{"Bool":null}},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":2,"Hidden":true,"Custom":"SrcColor","Exposed":"srccolor","Value":{"Int":6},"Init":{"Int":6},"Domain":{"Int":{"Values":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]}},"Values":[["Zero",{"Int":0}],["One",{"Int":1}],["SrcColor",{"Int":2}],["OneMinusSrcColor",{"Int":3}],["DstColor",{"Int":4}],["OneMinusDstColor",{"Int":5}],["SrcAlpha",{"Int":6}],["OneMinusSrcAlpha",{"Int":7}],["DstAlpha",{"Int":8}],["OneMinusDstAlpha",{"Int":9}],["ConstantColor",{"Int":10}],["OneMinusConstantColor",{"Int":11}],["ConstantAlpha",{"Int":12}],["OneMinusConstantAlpha",{"Int":13}],["SrcAlphaSaturate",{"Int":14}]],"FolderPort":"","FileExtensions":""},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":3,"Hidden":true,"Custom":"DstColor","Exposed":"dstcolor","Value":{"Int":7},"Init":{"Int":7},"Domain":{"Int":{"Values":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]}},"Values":[["Zero",{"Int":0}],["One",{"Int":1}],["SrcColor",{"Int":2}],["OneMinusSrcColor",{"Int":3}],["DstColor",{"Int":4}],["OneMinusDstColor",{"Int":5}],["SrcAlpha",{"Int":6}],["OneMinusSrcAlpha",{"Int":7}],["DstAlpha",{"Int":8}],["OneMinusDstAlpha",{"Int":9}],["ConstantColor",{"Int":10}],["OneMinusConstantColor",{"Int":11}],["ConstantAlpha",{"Int":12}],["OneMinusConstantAlpha",{"Int":13}],["SrcAlphaSaturate",{"Int":14}]],"FolderPort":"","FileExtensions":""},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":4,"Hidden":true,"Custom":"OpColor","Exposed":"opcolor","Value":{"Int":0},"Init":{"Int":0},"Domain":{"Int":{"Values":[0,1,2,3,4]}},"Values":[["Add",{"Int":0}],["Substract",{"Int":1}],["Reverse Substract",{"Int":2}],["Min",{"Int":3}],["Max",{"Int":4}]],"FolderPort":"","FileExtensions":""},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":5,"Hidden":true,"Custom":"SrcAlpha","Exposed":"srcalpha","Value":{"Int":1},"Init":{"Int":1},"Domain":{"Int":{"Values":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]}},"Values":[["Zero",{"Int":0}],["One",{"Int":1}],["SrcColor",{"Int":2}],["OneMinusSrcColor",{"Int":3}],["DstColor",{"Int":4}],["OneMinusDstColor",{"Int":5}],["SrcAlpha",{"Int":6}],["OneMinusSrcAlpha",{"Int":7}],["DstAlpha",{"Int":8}],["OneMinusDstAlpha",{"Int":9}],["ConstantColor",{"Int":10}],["OneMinusConstantColor",{"Int":11}],["ConstantAlpha",{"Int":12}],["OneMinusConstantAlpha",{"Int":13}],["SrcAlphaSaturate",{"Int":14}]],"FolderPort":"","FileExtensions":""},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":6,"Hidden":true,"Custom":"DstAlpha","Exposed":"dstalpha","Value":{"Int":7},"Init":{"Int":7},"Domain":{"Int":{"Values":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]}},"Values":[["Zero",{"Int":0}],["One",{"Int":1}],["SrcColor",{"Int":2}],["OneMinusSrcColor",{"Int":3}],["DstColor",{"Int":4}],["OneMinusDstColor",{"Int":5}],["SrcAlpha",{"Int":6}],["OneMinusSrcAlpha",{"Int":7}],["DstAlpha",{"Int":8}],["OneMinusDstAlpha",{"Int":9}],["ConstantColor",{"Int":10}],["OneMinusConstantColor",{"Int":11}],["ConstantAlpha",{"Int":12}],["OneMinusConstantAlpha",{"Int":13}],["SrcAlphaSaturate",{"Int":14}]],"FolderPort":"","FileExtensions":""},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":7,"Hidden":true,"Custom":"OpAlpha","Exposed":"opalpha","Value":{"Int":0},"Init":{"Int":0},"Domain":{"Int":{"Values":[0,1,2,3,4]}},"Values":[["Add",{"Int":0}],["Substract",{"Int":1}],["Reverse Substract",{"Int":2}],["Min",{"Int":3}],["Max",{"Int":4}]],"FolderPort":"","FileExtensions":""},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":8,"Hidden":false,"Custom":"camera","Exposed":"camera","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":9,"Hidden":false,"Custom":"scene_lights","Exposed":"scene_lights","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":10,"Hidden":false,"Custom":"scene_light_indices","Exposed":"scene_light_indices","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":11,"Hidden":false,"Custom":"world_transforms","Exposed":"world_transforms","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":12,"Hidden":false,"Custom":"scene_materials","Exposed":"scene_materials","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":13,"Hidden":false,"Custom":"scene_material_uv_xforms","Exposed":"scene_material_uv_xforms","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":14,"Hidden":false,"Custom":"per_draws","Exposed":"per_draws","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":15,"Hidden":false,"Custom":"indirect_draw_cmds","Exposed":"indirect_draw_cmds","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":16,"Hidden":false,"Custom":"scene_counts","Exposed":"scene_counts","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":17,"Hidden":false,"Custom":"env","Exposed":"env","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"238399a0-7e81-47e3-896f-08e8856e2973","ObjectName":"Inlet","id":18,"Hidden":true,"Custom":"alpha_a2c_enabled","Exposed":"alpha_a2c_enabled","Value":{"Int":0},"Init":{"Int":0},"Domain":{"Int":{"Min":0,"Max":1}}},{"uuid":"238399a0-7e81-47e3-896f-08e8856e2973","ObjectName":"Inlet","id":19,"Hidden":true,"Custom":"volumetric_enabled","Exposed":"volumetric_enabled","Value":{"Int":0},"Init":{"Int":0},"Domain":{"Int":{"Min":0,"Max":1}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":20,"Hidden":true,"Custom":"volumetric_intensity","Exposed":"volumetric_intensity","Value":{"Float":1.0},"Init":{"Float":1.0},"Domain":{"Float":{"Min":0.0,"Max":4.0}}}],"Outlets":[{"uuid":"f1c71046-b754-49a5-8e66-d01374773dfc","ObjectName":"Outlet","id":1000,"Hidden":false,"Custom":"Texture Out","Exposed":"texture out"}]},{"uuid":"74ca45ff-92c9-44a0-8f1a-754dea05ee1b","ObjectName":"gfxProcess","id":37,"Metadata":{"ScriptingName":"ISF Shader.37","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[2018.2331332471515,3593.972609888511],"Size":[182.0,160.0],"Loops":false,"FoldMode":0,"Vertex":"","Fragment":"/*{\n  \"DESCRIPTION\": \"HDR tone mapping with selectable algorithm: Reinhard, ACES Filmic (Narkowicz), Exposure, Uncharted 2 (Hable), or AgX. Feed it linear HDR colour (the PBR render pipelines output linear HDR and leave tone mapping and the display gamma to this node); the output is gamma-encoded for display.\",\n  \"CREDIT\": \"ossia score\",\n  \"ISFVSN\": \"2\",\n  \"CATEGORIES\": [\n    \"Post-Process\"\n  ],\n  \"INPUTS\": [\n    {\n      \"NAME\": \"inputImage\",\n      \"TYPE\": \"image\"\n    },\n    {\n      \"NAME\": \"algorithm\",\n      \"LABEL\": \"Tone curve\",\n      \"TYPE\": \"long\",\n      \"DEFAULT\": 1,\n      \"VALUES\": [0, 1, 2, 3, 4],\n      \"LABELS\": [\"Reinhard\", \"ACES Filmic\", \"Exposure\", \"Uncharted 2\", \"AgX\"]\n    },\n    {\n      \"NAME\": \"exposure\",\n      \"LABEL\": \"Exposure (multiplier)\",\n      \"TYPE\": \"float\",\n      \"DEFAULT\": 1.0,\n      \"MIN\": 0.1,\n      \"MAX\": 10.0\n    },\n    {\n      \"NAME\": \"gamma\",\n      \"LABEL\": \"Display gamma\",\n      \"TYPE\": \"float\",\n      \"DEFAULT\": 2.2,\n      \"MIN\": 0.5,\n      \"MAX\": 3.0\n    },\n    {\n      \"NAME\": \"whitePoint\",\n      \"LABEL\": \"White point (Reinhard only)\",\n      \"TYPE\": \"float\",\n      \"DEFAULT\": 4.0,\n      \"MIN\": 0.5,\n      \"MAX\": 20.0\n    }\n  ]\n}*/\n\n// --- Reinhard (extended) ---\nvec3 tonemapReinhard(vec3 color, float wp)\n{\n  // Extended Reinhard: color * (1 + color / wp^2) / (1 + color)\n  vec3 wp2 = vec3(wp * wp);\n  return color * (1.0 + color / wp2) / (1.0 + color);\n}\n\n// --- ACES Filmic (Narkowicz approximation) ---\n// Source: Krzysztof Narkowicz, \"ACES Filmic Tone Mapping Curve\" (2016)\nvec3 tonemapACES(vec3 x)\n{\n  const float a = 2.51;\n  const float b = 0.03;\n  const float c = 2.43;\n  const float d = 0.59;\n  const float e = 0.14;\n  return clamp((x * (a * x + b)) / (x * (c * x + d) + e), 0.0, 1.0);\n}\n\n// --- Exposure (simple) ---\nvec3 tonemapExposure(vec3 color, float e)\n{\n  return 1.0 - exp(-color * e);\n}\n\n// --- Uncharted 2 (Hable filmic) ---\n// Source: John Hable, \"Filmic Tonemapping Operators\" (GDC 2010)\nvec3 uncharted2Partial(vec3 x)\n{\n  const float A = 0.15; // Shoulder strength\n  const float B = 0.50; // Linear strength\n  const float C = 0.10; // Linear angle\n  const float D = 0.20; // Toe strength\n  const float E = 0.02; // Toe numerator\n  const float F = 0.30; // Toe denominator\n  return ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F;\n}\n\nvec3 tonemapUncharted2(vec3 color)\n{\n  const float W = 11.2; // Linear white point\n  const float exposureBias = 2.0;\n  vec3 curr = uncharted2Partial(color * exposureBias);\n  vec3 whiteScale = vec3(1.0) / uncharted2Partial(vec3(W));\n  return curr * whiteScale;\n}\n\n// --- AgX ---\n// Based on the minimal analytical AgX implementation.\n// References: Troy Sobotka, Benjamin Wrensch (Missing Deadlines), Blender 4.0\n\nconst mat3 AgXInsetMatrix = mat3(\n  0.856627153315983, 0.137318972929847, 0.11189821299995,\n  0.0951212405381588, 0.761241990602591, 0.0767994186031903,\n  0.0482516061458583, 0.101439036467562, 0.811302368396859\n);\n\nconst mat3 AgXOutsetMatrix = mat3(\n  1.1271005818144368, -0.1413297634984383, -0.14132976349843826,\n  -0.11060664309660323, 1.157823702216272, -0.11060664309660294,\n  -0.016493938717834573, -0.016493938717834257, 1.2519364065950405\n);\n\nconst mat3 LINEAR_SRGB_TO_LINEAR_REC2020 = mat3(\n  0.6274, 0.0691, 0.0164,\n  0.3293, 0.9195, 0.0880,\n  0.0433, 0.0113, 0.8956\n);\n\nconst mat3 LINEAR_REC2020_TO_LINEAR_SRGB = mat3(\n  1.6605, -0.1246, -0.0182,\n  -0.5876, 1.1329, -0.1006,\n  -0.0728, -0.0083, 1.1187\n);\n\nvec3 tonemapAgX(vec3 color)\n{\n  const float AgxMinEv = -12.47393;\n  const float AgxMaxEv = 4.026069;\n\n  color = LINEAR_SRGB_TO_LINEAR_REC2020 * color;\n  color = AgXInsetMatrix * color;\n\n  color = max(color, 1e-10);\n  color = clamp(log2(color), AgxMinEv, AgxMaxEv);\n  color = (color - AgxMinEv) / (AgxMaxEv - AgxMinEv);\n  color = clamp(color, 0.0, 1.0);\n\n  // 6th-order polynomial approximation of the AgX sigmoid\n  vec3 x2 = color * color;\n  vec3 x4 = x2 * x2;\n  color = + 15.5   * x4 * x2\n          - 40.14  * x4 * color\n          + 31.96  * x4\n          - 6.868  * x2 * color\n          + 0.4298 * x2\n          + 0.1191 * color\n          - 0.00232;\n\n  color = AgXOutsetMatrix * color;\n\n  // Linearize (AgX output is in sRGB-like gamma space)\n  color = pow(max(vec3(0.0), color), vec3(2.2));\n\n  color = LINEAR_REC2020_TO_LINEAR_SRGB * color;\n  return clamp(color, 0.0, 1.0);\n}\n\nvoid main()\n{\n  vec4 texColor = IMG_THIS_PIXEL(inputImage);\n  vec3 color = texColor.rgb;\n\n  // Apply exposure\n  color *= exposure;\n\n  // Apply selected tone mapping algorithm\n  if(algorithm == 0)\n  {\n    color = tonemapReinhard(color, whitePoint);\n  }\n  else if(algorithm == 1)\n  {\n    color = tonemapACES(color);\n  }\n  else if(algorithm == 2)\n  {\n    // Exposure already applied above; use 1.0 to avoid double-application\n    color = tonemapExposure(color, 1.0);\n  }\n  else if(algorithm == 3)\n  {\n    color = tonemapUncharted2(color);\n  }\n  else if(algorithm == 4)\n  {\n    color = tonemapAgX(color);\n  }\n\n  // Gamma correction\n  color = pow(max(color, vec3(0.0)), vec3(1.0 / gamma));\n\n  isf_FragColor = vec4(color, texColor.a);\n}\n","Root":"<LIBRARY>:packages/score-csf-testers/shaderlib/post-process/ToneMapping.fs","Inlets":[{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":0,"Hidden":false,"Custom":"inputImage","Exposed":"inputimage","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":1,"Hidden":true,"Custom":"algorithm","Exposed":"algorithm","Value":{"Int":1},"Init":{"Int":1},"Domain":{"Int":{"Values":[0,1,2,3,4]}},"Values":[["Reinhard",{"Int":0}],["ACES Filmic",{"Int":1}],["Exposure",{"Int":2}],["Uncharted 2",{"Int":3}],["AgX",{"Int":4}]],"FolderPort":"","FileExtensions":""},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":2,"Hidden":true,"Custom":"exposure","Exposed":"exposure","Value":{"Float":1.0},"Init":{"Float":1.0},"Domain":{"Float":{"Min":0.10000000149011612,"Max":10.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":3,"Hidden":true,"Custom":"gamma","Exposed":"gamma","Value":{"Float":2.200000047683716},"Init":{"Float":2.200000047683716},"Domain":{"Float":{"Min":0.5,"Max":3.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":4,"Hidden":true,"Custom":"whitePoint","Exposed":"whitepoint","Value":{"Float":4.0},"Init":{"Float":4.0},"Domain":{"Float":{"Min":0.5,"Max":20.0}}}],"Outlets":[{"uuid":"f1c71046-b754-49a5-8e66-d01374773dfc","ObjectName":"Outlet","id":1,"Hidden":false,"Custom":"Texture Out","Exposed":"texture out"}]},{"uuid":"74ca45ff-92c9-44a0-8f1a-754dea05ee1b","ObjectName":"gfxProcess","id":38,"Metadata":{"ScriptingName":"ISF Shader.38","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[2841.6852725222607,574.6070241774792],"Size":[147.0,80.0],"Loops":false,"FoldMode":0,"Vertex":"","Fragment":"/*{\n  \"DESCRIPTION\": \"Gallery contact sheet: shows four input images as a 2x2 grid (A top-left, B top-right, C bottom-left, D bottom-right) with a thin separator, so one frame can compare four settings of the same process. An unconnected input shows as black. isf_FragNormCoord is bottom-left origin, so the top row is uv.y >= 0.5.\",\n  \"CREDIT\": \"threedim gallery\",\n  \"ISFVSN\": \"2.0\",\n  \"CATEGORIES\": [\"GALLERY\"],\n  \"INPUTS\": [\n    { \"NAME\": \"A\", \"TYPE\": \"image\" },\n    { \"NAME\": \"B\", \"TYPE\": \"image\" },\n    { \"NAME\": \"C\", \"TYPE\": \"image\" },\n    { \"NAME\": \"D\", \"TYPE\": \"image\" }\n  ]\n}*/\n\nvoid main()\n{\n    vec2 uv = isf_FragNormCoord;\n    vec2 q = fract(uv * 2.0);\n    vec4 c;\n    if(uv.y >= 0.5)\n        c = (uv.x < 0.5) ? IMG_NORM_PIXEL(A, q) : IMG_NORM_PIXEL(B, q);\n    else\n        c = (uv.x < 0.5) ? IMG_NORM_PIXEL(C, q) : IMG_NORM_PIXEL(D, q);\n    vec2 d = abs(uv - 0.5) * RENDERSIZE;\n    if(min(d.x, d.y) < 1.5)\n        c = vec4(0.5, 0.5, 0.5, 1.0);\n    isf_FragColor = vec4(c.rgb, 1.0);\n}\n","Root":"<LIBRARY>:packages/score-csf-testers/showcase/gallery-threedim/shaders/grid4.fs","Inlets":[{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":0,"Hidden":false,"Custom":"A","Exposed":"a","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":1,"Hidden":false,"Custom":"B","Exposed":"b","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":2,"Hidden":false,"Custom":"C","Exposed":"c","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":3,"Hidden":false,"Custom":"D","Exposed":"d","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0}],"Outlets":[{"uuid":"f1c71046-b754-49a5-8e66-d01374773dfc","ObjectName":"Outlet","id":1,"Hidden":false,"Custom":"Texture Out","Exposed":"texture out","Address":"Window:/"}]},{"uuid":"7be51631-fb4b-4152-9ca7-86fdafa8a989","ObjectName":"Display","id":39,"Metadata":{"ScriptingName":"Text Box","Comment":"","Color":"Transparent1","Label":"","Touched":true},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[2747.1975072354417,498.8086571294915],"Size":[219.0,38.0],"Loops":false,"FoldMode":0,"Inlets":[{"uuid":"9ae797ea-d94c-4792-acec-9ec1932bae5d","ObjectName":"Inlet","id":0,"Hidden":true,"Custom":"in","Exposed":"in","Value":{"String":"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n<html><head><meta name=\"qrichtext\" content=\"1\" /><meta charset=\"utf-8\" /><style type=\"text/css\">\np, li { white-space: pre-wrap; }\nhr { height: 1px; border-width: 0; }\nli.unchecked::marker { content: \"\\2610\"; }\nli.checked::marker { content: \"\\2612\"; }\n</style></head><body style=\" font-family:'Ubuntu'; font-size:13px; font-weight:400; font-style:normal;\">\n<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">This example shows <br />multiple examples of 3D instancing.</p></body></html>"},"Init":{"String":"(Double-click to edit)"},"Domain":{}},{"uuid":"fb27e4cb-ea7f-41e2-ad92-2354498c1b6b","ObjectName":"Inlet","id":1,"Hidden":true,"Custom":"Auto-reflow","Exposed":"auto-reflow","Value":{"Bool":false},"Init":{"Bool":false},"Domain":{"Bool":null}}],"Outlets":[]},{"uuid":"c953fa55-65f0-4b93-8bfc-54780250d2b8","ObjectName":"Step","id":40,"Metadata":{"ScriptingName":"Step sequencer","Comment":"","Color":"Transparent1","Label":"","Touched":true},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[-324.926338244193,3833.698080288583],"Size":[300.0,120.0],"Loops":false,"FoldMode":0,"SequenceSelect":{"uuid":"238399a0-7e81-47e3-896f-08e8856e2973","ObjectName":"Inlet","id":0,"Hidden":false,"Custom":"Sequence","Exposed":"sequence","Value":{"Int":0},"Init":{"Int":0},"Domain":{"Int":{"Min":0,"Max":63}}},"SwitchQuantification":{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":1,"Hidden":false,"Custom":"Quantization","Exposed":"quantization","Value":{"Float":1.0},"Init":{"Float":1.0},"Domain":{"Float":{"Values":[0.0,0.125,0.25,0.5,1.0,2.0,4.0,8.0,16.0,32.0]}},"Values":[["Free",{"Float":0.0}],["8 bars",{"Float":0.125}],["4 bars",{"Float":0.25}],["2 bars",{"Float":0.5}],["1 bar",{"Float":1.0}],["1/2",{"Float":2.0}],["1/4",{"Float":4.0}],["1/8",{"Float":8.0}],["1/16",{"Float":16.0}],["1/32",{"Float":32.0}]],"FolderPort":"","FileExtensions":""},"StepDuration":{"uuid":"b631d9b7-cbe3-4d9c-b470-f139e348aecb","ObjectName":"Inlet","id":2,"Hidden":false,"Custom":"Duration","Exposed":"duration","Value":{"Vec2f":[0.125,1.0]},"Init":{"Vec2f":[0.10000000149011612,0.0]},"Domain":{"Vec2f":{"Min":[0.0010000000474974513,0.0],"Max":[60.0,1.0],"Values":[[],[]]}}},"Outlet":{"uuid":"cff96158-cc72-46d7-99dc-b6038171375b","ObjectName":"Outlet","id":0,"Hidden":false,"Custom":"Step Out","Exposed":"step out"},"Sequences":[[0.5,0.30000001192092896,0.5,0.800000011920929,0.21173310279846191,0.0,0.5,0.10000000149011612]],"Sequence":0,"StepMin":0.0,"StepMax":10.0},{"uuid":"c953fa55-65f0-4b93-8bfc-54780250d2b8","ObjectName":"Step","id":41,"Metadata":{"ScriptingName":"Step sequencer.1","Comment":"","Color":"Transparent1","Label":"","Touched":true},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[-326.24264568099045,3982.6080787001706],"Size":[300.0,120.0],"Loops":false,"FoldMode":0,"SequenceSelect":{"uuid":"238399a0-7e81-47e3-896f-08e8856e2973","ObjectName":"Inlet","id":0,"Hidden":false,"Custom":"Sequence","Exposed":"sequence","Value":{"Int":0},"Init":{"Int":0},"Domain":{"Int":{"Min":0,"Max":63}}},"SwitchQuantification":{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":1,"Hidden":false,"Custom":"Quantization","Exposed":"quantization","Value":{"Float":1.0},"Init":{"Float":1.0},"Domain":{"Float":{"Values":[0.0,0.125,0.25,0.5,1.0,2.0,4.0,8.0,16.0,32.0]}},"Values":[["Free",{"Float":0.0}],["8 bars",{"Float":0.125}],["4 bars",{"Float":0.25}],["2 bars",{"Float":0.5}],["1 bar",{"Float":1.0}],["1/2",{"Float":2.0}],["1/4",{"Float":4.0}],["1/8",{"Float":8.0}],["1/16",{"Float":16.0}],["1/32",{"Float":32.0}]],"FolderPort":"","FileExtensions":""},"StepDuration":{"uuid":"b631d9b7-cbe3-4d9c-b470-f139e348aecb","ObjectName":"Inlet","id":2,"Hidden":false,"Custom":"Duration","Exposed":"duration","Value":{"Vec2f":[0.0625,1.0]},"Init":{"Vec2f":[0.10000000149011612,0.0]},"Domain":{"Vec2f":{"Min":[0.0010000000474974513,0.0],"Max":[60.0,1.0],"Values":[[],[]]}}},"Outlet":{"uuid":"cff96158-cc72-46d7-99dc-b6038171375b","ObjectName":"Outlet","id":0,"Hidden":false,"Custom":"Step Out","Exposed":"step out"},"Sequences":[[0.12358558923006058,0.8372045755386353,0.3353186845779419,0.7744688391685486,0.49215802550315857,0.17063738405704498]],"Sequence":0,"StepMin":0.0,"StepMax":10.0},{"uuid":"971739ae-14a3-4283-b0a0-96dbd367ce66","ObjectName":"avnd_expsmooth","id":42,"Metadata":{"ScriptingName":"Exp Smoothing","Comment":"","Color":"Transparent1","Label":"","Touched":true},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[15.073661755806995,3833.698080288583],"Size":[141.0,55.0],"Loops":false,"FoldMode":0,"Inlets":[{"uuid":"769dd38a-bfb3-4dc6-b52a-b6abb7afe2a3","ObjectName":"Inlet","id":0,"Hidden":false,"Custom":"Input","Exposed":"input"},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":1,"Hidden":true,"Custom":"Alpha","Exposed":"alpha","Value":{"Float":0.03659586235880852},"Init":{"Float":0.5},"Domain":{"Float":{"Min":0.00009999999747378752,"Max":1.0}}}],"Outlets":[{"uuid":"cff96158-cc72-46d7-99dc-b6038171375b","ObjectName":"Outlet","id":0,"Hidden":false,"Custom":"Output","Exposed":"output"}]},{"uuid":"971739ae-14a3-4283-b0a0-96dbd367ce66","ObjectName":"avnd_expsmooth","id":43,"Metadata":{"ScriptingName":"Exp Smoothing.44","Comment":"","Color":"Transparent1","Label":"","Touched":true},"Duration":10584000000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[13.75735431900955,3982.6080787001706],"Size":[158.0,55.0],"Loops":false,"FoldMode":0,"Inlets":[{"uuid":"769dd38a-bfb3-4dc6-b52a-b6abb7afe2a3","ObjectName":"Inlet","id":0,"Hidden":false,"Custom":"Input","Exposed":"input"},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":1,"Hidden":true,"Custom":"Alpha","Exposed":"alpha","Value":{"Float":0.02073008008301258},"Init":{"Float":0.5},"Domain":{"Float":{"Min":0.00009999999747378752,"Max":1.0}}}],"Outlets":[{"uuid":"cff96158-cc72-46d7-99dc-b6038171375b","ObjectName":"Outlet","id":0,"Hidden":false,"Custom":"Output","Exposed":"output"}]}],"SmallViewRack":[{"Processes":[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,42,43],"Process":null,"Height":200.0,"Nodal":true},{"Processes":[40],"Process":40,"Height":200.0,"Nodal":false},{"Processes":[41],"Process":41,"Height":200.0,"Nodal":false}],"FullViewRack":[{"Process":0,"Nodal":true},{"Process":40,"Nodal":false},{"Process":41,"Nodal":false}],"DefaultDuration":10584000000,"MinDuration":10584000000,"MaxDuration":11113200000,"GuiDuration":11642400000,"Speed":1.0,"Rigidity":false,"MinNull":false,"MaxInf":true,"Signatures":[[0,[4,4]]],"StartState":0,"EndState":1,"StartDate":0,"HeightPercentage":0.0,"NodalSlotHeight":100.0,"QuantizationRate":-1.0,"Zoom":15120000.0,"Center":0,"NodalCenter":[1519.4557546265664,1469.20943997871],"NodalScale":0.4270586456655942,"ViewMode":1,"SmallViewShown":true,"HasSignature":true},"StartTimeNode":{"ObjectName":"Scenario::TimeSyncModel","id":0,"Metadata":{"ScriptingName":"Sync.start","Comment":"","Color":"Gray","Label":"","Touched":true},"Date":0,"Events":[0],"MusicalSync":-1.0,"AutoTrigger":false,"Start":true,"Active":false,"Expression":" { true == false } "},"EndTimeNode":{"ObjectName":"Scenario::TimeSyncModel","id":1,"Metadata":{"ScriptingName":"Sync.end","Comment":"","Color":"Gray","Label":"","Touched":true},"Date":10584000000,"Events":[1],"MusicalSync":-1.0,"AutoTrigger":false,"Start":false,"Active":true,"Expression":" { true == false } "},"StartEvent":{"ObjectName":"Scenario::EventModel","id":0,"Metadata":{"ScriptingName":"Event.start","Comment":"","Color":"Emphasis4","Label":"","Touched":true},"TimeNode":0,"States":[0],"Condition":"","Date":0,"Offset":0},"EndEvent":{"ObjectName":"Scenario::EventModel","id":1,"Metadata":{"ScriptingName":"Event.end","Comment":"","Color":"Emphasis4","Label":"","Touched":true},"TimeNode":1,"States":[1],"Condition":"","Date":10584000000,"Offset":0},"StartState":{"ObjectName":"Scenario::StateModel","id":0,"Metadata":{"ScriptingName":"State.start","Comment":"","Color":"Base1","Label":"","Touched":true},"Event":0,"PreviousConstraint":null,"NextConstraint":0,"HeightPercentage":0.0,"Messages":{"Name":"","Accessors":[],"Unit":"none","Previous":[],"Following":[],"User":null,"Priorities":[1,2,0]},"StateProcesses":[]},"EndState":{"ObjectName":"Scenario::StateModel","id":1,"Metadata":{"ScriptingName":"State.end","Comment":"","Color":"Base1","Label":"","Touched":true},"Event":1,"PreviousConstraint":0,"NextConstraint":null,"HeightPercentage":0.0,"Messages":{"Name":"","Accessors":[],"Unit":"none","Previous":[],"Following":[],"User":null,"Priorities":[1,2,0]},"StateProcesses":[]}},"Speed":1.0,"Cables":[{"ObjectName":"Process::Cable","id":1,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"asset_loader","ObjectId":3},{"ObjectName":"Outlet","ObjectId":0}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"instancer","ObjectId":4},{"ObjectName":"Inlet","ObjectId":0}]},{"ObjectName":"Process::Cable","id":2,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"CSF","ObjectId":2},{"ObjectName":"Outlet","ObjectId":0}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"instancer","ObjectId":4},{"ObjectName":"Inlet","ObjectId":4}]},{"ObjectName":"Process::Cable","id":3,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"instancer","ObjectId":4},{"ObjectName":"Outlet","ObjectId":0}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":5},{"ObjectName":"Inlet","ObjectId":0}]},{"ObjectName":"Process::Cable","id":4,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"camera_avnd","ObjectId":6},{"ObjectName":"Outlet","ObjectId":0}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":5},{"ObjectName":"Inlet","ObjectId":0}]},{"ObjectName":"Process::Cable","id":5,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"light","ObjectId":7},{"ObjectName":"Outlet","ObjectId":0}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":5},{"ObjectName":"Inlet","ObjectId":0}]},{"ObjectName":"Process::Cable","id":6,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"environment_loader","ObjectId":8},{"ObjectName":"Outlet","ObjectId":0}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":5},{"ObjectName":"Inlet","ObjectId":0}]},{"ObjectName":"Process::Cable","id":7,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":5},{"ObjectName":"Outlet","ObjectId":0}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":9},{"ObjectName":"Inlet","ObjectId":1000}]},{"ObjectName":"Process::Cable","id":8,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":9},{"ObjectName":"Outlet","ObjectId":1000}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":10},{"ObjectName":"Inlet","ObjectId":0}]},{"ObjectName":"Process::Cable","id":9,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"asset_loader","ObjectId":11},{"ObjectName":"Outlet","ObjectId":0}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"instancer","ObjectId":13},{"ObjectName":"Inlet","ObjectId":0}]},{"ObjectName":"Process::Cable","id":10,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"CSF","ObjectId":12},{"ObjectName":"Outlet","ObjectId":0}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"instancer","ObjectId":13},{"ObjectName":"Inlet","ObjectId":4}]},{"ObjectName":"Process::Cable","id":11,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"instancer","ObjectId":13},{"ObjectName":"Outlet","ObjectId":0}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":14},{"ObjectName":"Inlet","ObjectId":0}]},{"ObjectName":"Process::Cable","id":12,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"camera_avnd","ObjectId":15},{"ObjectName":"Outlet","ObjectId":0}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":14},{"ObjectName":"Inlet","ObjectId":0}]},{"ObjectName":"Process::Cable","id":13,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"light","ObjectId":16},{"ObjectName":"Outlet","ObjectId":0}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":14},{"ObjectName":"Inlet","ObjectId":0}]},{"ObjectName":"Process::Cable","id":14,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"environment_loader","ObjectId":17},{"ObjectName":"Outlet","ObjectId":0}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":14},{"ObjectName":"Inlet","ObjectId":0}]},{"ObjectName":"Process::Cable","id":15,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":14},{"ObjectName":"Outlet","ObjectId":0}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":18},{"ObjectName":"Inlet","ObjectId":1000}]},{"ObjectName":"Process::Cable","id":16,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":18},{"ObjectName":"Outlet","ObjectId":1000}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":19},{"ObjectName":"Inlet","ObjectId":0}]},{"ObjectName":"Process::Cable","id":17,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"asset_loader","ObjectId":20},{"ObjectName":"Outlet","ObjectId":0}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"instancer","ObjectId":22},{"ObjectName":"Inlet","ObjectId":0}]},{"ObjectName":"Process::Cable","id":18,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"CSF","ObjectId":21},{"ObjectName":"Outlet","ObjectId":0}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"instancer","ObjectId":22},{"ObjectName":"Inlet","ObjectId":4}]},{"ObjectName":"Process::Cable","id":19,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"instancer","ObjectId":22},{"ObjectName":"Outlet","ObjectId":0}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":23},{"ObjectName":"Inlet","ObjectId":0}]},{"ObjectName":"Process::Cable","id":20,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"camera_avnd","ObjectId":24},{"ObjectName":"Outlet","ObjectId":0}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":23},{"ObjectName":"Inlet","ObjectId":0}]},{"ObjectName":"Process::Cable","id":21,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"light","ObjectId":25},{"ObjectName":"Outlet","ObjectId":0}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":23},{"ObjectName":"Inlet","ObjectId":0}]},{"ObjectName":"Process::Cable","id":22,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"environment_loader","ObjectId":26},{"ObjectName":"Outlet","ObjectId":0}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":23},{"ObjectName":"Inlet","ObjectId":0}]},{"ObjectName":"Process::Cable","id":23,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":23},{"ObjectName":"Outlet","ObjectId":0}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":27},{"ObjectName":"Inlet","ObjectId":1000}]},{"ObjectName":"Process::Cable","id":24,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":27},{"ObjectName":"Outlet","ObjectId":1000}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":28},{"ObjectName":"Inlet","ObjectId":0}]},{"ObjectName":"Process::Cable","id":25,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"asset_loader","ObjectId":29},{"ObjectName":"Outlet","ObjectId":0}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"instancer","ObjectId":31},{"ObjectName":"Inlet","ObjectId":0}]},{"ObjectName":"Process::Cable","id":26,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"CSF","ObjectId":30},{"ObjectName":"Outlet","ObjectId":0}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"instancer","ObjectId":31},{"ObjectName":"Inlet","ObjectId":4}]},{"ObjectName":"Process::Cable","id":27,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"instancer","ObjectId":31},{"ObjectName":"Outlet","ObjectId":0}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":32},{"ObjectName":"Inlet","ObjectId":0}]},{"ObjectName":"Process::Cable","id":28,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"camera_avnd","ObjectId":33},{"ObjectName":"Outlet","ObjectId":0}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":32},{"ObjectName":"Inlet","ObjectId":0}]},{"ObjectName":"Process::Cable","id":29,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"light","ObjectId":34},{"ObjectName":"Outlet","ObjectId":0}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":32},{"ObjectName":"Inlet","ObjectId":0}]},{"ObjectName":"Process::Cable","id":30,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"environment_loader","ObjectId":35},{"ObjectName":"Outlet","ObjectId":0}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":32},{"ObjectName":"Inlet","ObjectId":0}]},{"ObjectName":"Process::Cable","id":31,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":32},{"ObjectName":"Outlet","ObjectId":0}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":36},{"ObjectName":"Inlet","ObjectId":1000}]},{"ObjectName":"Process::Cable","id":32,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":36},{"ObjectName":"Outlet","ObjectId":1000}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":37},{"ObjectName":"Inlet","ObjectId":0}]},{"ObjectName":"Process::Cable","id":36,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":37},{"ObjectName":"Outlet","ObjectId":1}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":38},{"ObjectName":"Inlet","ObjectId":3}]},{"ObjectName":"Process::Cable","id":34,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":19},{"ObjectName":"Outlet","ObjectId":1}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":38},{"ObjectName":"Inlet","ObjectId":1}]},{"ObjectName":"Process::Cable","id":35,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":28},{"ObjectName":"Outlet","ObjectId":1}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":38},{"ObjectName":"Inlet","ObjectId":2}]},{"ObjectName":"Process::Cable","id":33,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":10},{"ObjectName":"Outlet","ObjectId":1}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":38},{"ObjectName":"Inlet","ObjectId":0}]},{"ObjectName":"Process::Cable","id":40,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"avnd_expsmooth","ObjectId":42},{"ObjectName":"Outlet","ObjectId":0}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"CSF","ObjectId":30},{"ObjectName":"Inlet","ObjectId":0}]},{"ObjectName":"Process::Cable","id":39,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"Step","ObjectId":40},{"ObjectName":"Outlet","ObjectId":0}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"avnd_expsmooth","ObjectId":42},{"ObjectName":"Inlet","ObjectId":0}]},{"ObjectName":"Process::Cable","id":41,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"Step","ObjectId":41},{"ObjectName":"Outlet","ObjectId":0}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"avnd_expsmooth","ObjectId":43},{"ObjectName":"Inlet","ObjectId":0}]},{"ObjectName":"Process::Cable","id":42,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"avnd_expsmooth","ObjectId":43},{"ObjectName":"Outlet","ObjectId":0}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"CSF","ObjectId":30},{"ObjectName":"Inlet","ObjectId":1}]}],"BusIntervals":[]},"Plugins":[{"uuid":"aac1402f-6851-4a1a-ab50-5f213acd1262","Name":"","Author":"","Description":"","Url":"","Platforms":"","Created":"2026-09-25T19:08:30.033Z","LastSaved":"2026-10-04T16:00:16.976Z","Thumbnail":"iVBORw0KGgoAAAANSUhEUgAAAeAAAAEsCAIAAACUnPcNAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAgAElEQVR4nOS9B5gc13Umeu+tnDr3dE9OmMEgEJEASREEsxlESZZsU7Jky5attfazvPaz93223653HfY9eb1r2V6tHGTJkpVlWbJEyaSYCYIgSIDIwOQcOkznUDnc+77qAgeDAQgGieH5/R8/YqamK/Stuuee85//nILg7YAoitdt34IQohDxMPQwBAB4nkchQlHU+o0YY+x5okAT4u/oeAAASAixbft1nbG/F9+fFM2xHSkx9dDoo5Vo20vcC8hgNms39At3LcoOl3AB5Js2G65ZA0SWh1afnPnWjp29N966hSxPNzPlno6UXo0+9t2RqoBczRjYvGMb7Dm7OjkBzk3uLWJVdS3M9HfYVRNH0kJY6NnU194Rbwrhom0X8jVnckopXWBDlRBfVELcwg/PlF+qOIYLWt/rNSIOYl+SPlfwspNw5gQ4fQu+bdLKYiTQHIpSicHE0J7Bral6eKFSeLb5fK66MkjLx6mjQ9Fo+pb5uUzJEziCUFhkNg9377vtjmh799jzjx46fNZp6kmenyp17t//mfnx1bMro9D1Bjjvtt3plcb3/+yR75eaDfDOxh/8wR989rOfrdVq4B2FCBW6tc1NExsCyiaupXmaForGGJrX8zWD06gbKG/FA58B6x8DxILB9yl0PGoZNUYMWYZuqw2apaVQ2iyXeU4duBHM/oBMPH7ZqZQYOPAg24CdenNVFEOEYtRqCXuuFOvwmvUIXd95Pfja/yCrK5ftdc+7QbydLoGU6xmmqidSbYaha/W6EI4iAlJUua/H+4s/Bbp+aReaBr/574GqooIXAzxn1AqCooTD4UJ+laIoXo6mQa5YdP7pu5ePRBj83/8RjI+BCg6jaNSoZbEHE6k4xLBer0iRlGKvfv9HxlLmsr2u3w5+80Pg/AWQ1ySuPebqVdsweUWOhENatQkFkXeMv/96Rbcu2+uPPwl2dcMz58hMQQj3hgkgjUJBUkQpLFEYYQKIjR56rDiTc8A7DAzDfPSjH1UUZW0L/XZdimV7CGEIESGYoijXdQkhngege5nFIi1ohvtjnk7DDCJtNdvx5MbpPcX2LaFd7TvLag2fSo1W5pqgASwQrAFlhRQcszuDe1MyDcnKaBY4zPmJ+vlZDUCxIDYcUcISyYq1mkuVcJnEYYhl8NI8SLU741McxcBaGfG8kV9YCcsoEkYME9VNZ3RCBPOiriKKmJik+9JJOdGcUY2aGZz3tWArPXwYPc9AOuOt2tCdwbMaaNgMjwRUaWZZA3RPpWiIpxszsIcWPEHRxX5m4B58cAx8lqEpxHO0KJnNej5brKwuYmxNjs55iOV5DzL0vXdET5XnSgnsLtoSD0zLKRbHaZ70xBPvfAP9DgTcmaY/eL030gvDHMcwwHVQqWKdOqNlp0OQNh0D7UC4D2+wzgCAgVuHdty7Q47HJFmmGMY0zXIuM3/+rFZVgaWnd0AW4plnN57O1FAq2X/DtusFUQopCoSo0aiv5nJj03Oqntu6G2Smyerl5g8AcPgZ8J/+BDqgp7N3UBRkRZY9D1drtUKxNDt1YmTAe/h7l1lnAIDrgh89Af7DJ/DkPBkY2RWNyIl4QhREw7RUrZlZXJLo/B/96cYT1erg8Evg3beCk2c1KKT27rwrHI/G4wmGZpua5tl2YWXiS986DsBljteZcZCrg9074PMvGY7tDLR37BzZqiQSESVECNAtx1H1UvXMtx8+a9uXTMTffxv8wx+TTQOoVDORLbnE3L9z77Ztm+VwSBIEjyDXdm++ofSlbx175LkZD78eF+lyIISSySRCCPx4wBgXi0WM8ZV/8r3Utx6iKO470NfWjWBzCwCwra0tn89PT0+/eWfsTHM/g3Zs5vc+1Tz93d5DzGa+L7/n3OmMifZHSz+CwPfMXTnk8SJXyvM87z/xpqkoSrPZ3HAohmEkSXrHOWsADER2faDvV8IN/sWnXyBdVKGaF3GzyOUSjFLqPFXD/kKAaBrblihLbT1dAkOtzMwZDoaEJARaVJTp+pCHiLrc5Cis0AiAReCZk5WS4V62QBqGUa1Wg59DoZAsy+Dtxg033HDmzBnLutyVehvB0/DgAM3xVF6FlkckFnfFCIuIpnmZLKxVCYdBNyDLBIxeZqBZme29ZYDjBHWl7tkeI7CR7ihiKbXRKC0uQajGukD+LKlnLrsLiIJbdg9s3TvAMlxxpW4ZLsfTHf1JioXNWr1Smo5E7VPPAkO7ypXu3d/W2dMBIJ1ZqpmGy/N0d1+CZZGmVhq12ecOGfl8iVzhRPzqR5V77r413t4/Olp65pnZatUQRfbuu7feeGPf6Jnzv/ufH6tUjQ27MDT4yz8CUSkZTd4Rb0+NTlYefWK6XNElkb3jtuHbbxl6+F9P/elnnmiql93E9jbw1f8JZsdRsdZ/6523RxPS+cnqI09N51dVQaDvvm3kp+7Y+sUvP/sXn3/GacXXAQ5eDz7ze+DQ03Apy+654Ybt27eJIW58tvb9RydzBVXgmTsObLr1XUN/9/Vjn/vy056H3+BN5vnh4WEIfSvqKGEnkWYqBUIx0HWYRlWSpFgsxrKsaZqCIDSbzVKp5Hlee3t7LpcDACSTSY7jPM/LZrOzs7Oapr2DPGitTq8ST6vMQQjn5+c979LgvhkQjcSewTs1ylzYlfOjNDyciH1IiY/pdf+ZNboHgOcxtbK6ZVeDF/ZNn37wwQdPnTp18ODBw4cP79q1y7bthYWFTZs2nTt3ThRF13UfeeQR8A6Dw3qzU0uR7VE7ahMLCQjMiONZqeAHIjXgJFJsaRUAN5lMLxTKc/mZtR1pmrbZ6OrkKgBl/3cKWAA0XrbJcjS6ZoCj0aiqqs1ms16vBwt+MpkMDDShKDPdhSyLrRYdJcLWygihVCqVz+eD6S3LsmmaruvSNB2PxzVNU1UVABCLxUzT1Ft+GsMwiqJUKpXX+93n5uZCoRB4R+H0RevZgg5m1lZ0CEDM/3e19Vti4361E6270IIJ9ObcxR0h4AHgKznA+sPuOxCBgYYI3nDvkFeRp17077XH8XYiRdfU7NEMYVhabTBM0i6JA30sxtgwjEgkUigUXNelKEqSpOWFRnZ5VZIkiqKqVT9UWl5YC5iiiUS4UmlsWPkEge5I7xZCXUeOzH/n22c6UnwywpiG9ZV/PLyyUv7p9+7+g9/n/+t/+556ual1XPCFb4i//+t7pEji+RcWv/LNU11JrjPCakbzG984msvWPvRzN6qa898/83jLl7iIXAH84WfAu29KDG/exkrykWOL//C1k+0xpjfKGZb9jW8+n1kufeSDt1Rq+ue/cXRtr+dPgz/7EhiOkJHBvpCcJjR37OTK33zlRDpEDcQ4y3W+/9DxXKby8Z+/eWUp/4MnL7zhm0wgbO7YT9cqfG7JdWx1ZJc8cba27yClq9ephc2bN3d0dDz77LP79u1bXl4eGRmhadp13UajwfP8qVOnDhw4sLS09O1vf/uVjv+2GWiZpTydHWj3Kk3U0CFFURBCgcUQUemoV9dQVfUDB0IIxl4ijDiWQADyVSq4d6+Xg8aWe7h58rvzj+uyy3e0J6mP4rau2KnlAvTXeS63hFjkxBJuZ1qam8gXM1/52hdtx56Zn9B1fWL6gm3bFEWdOP2iqqrBECPmDa6617pIFwL/W75BUFHW3SvpvA0bqyovRhiTAdAJx9Qtu+TRU2a6u3rjHemHv/XAAw+MjY1JkrR161bDMGiafvTRRx944IHFxcXe3l7TNOfn5xOJhKIoCwsL/f39+XweQphIJIrFIoTwxIkTG6IKK9Wp928W5qfq1x+MHn2SQGT0bqrvOzh47KlPfvKTR48etSyrv79flmVCyOnTpwEAO3bs0DStWCzGYjGfwtK0aDRKUdSTTz552223ffGLX/xJDOf/X5DoUPbdvfnYP+fUoREnmmTqFTuRkkdPEYpWN+/EHL87M7V79+7u7u6xsbFyuXz77bdPTU1JkiQIQk9PTzabPXr06MGDB8vl8ne+850rjx94iOuxf2/HyEj7/EL50UdGb9wXFhIsoCiOQdtscuyFyY6O6P79I/fcdd13v39i/V4UBe++eQsvx1Zyte9+7+zBPaFomscUoim03fDOnZ996pBy7z3XH35h+sjxufU7jk8xv3jf1kg8slqofOufz9y5OxRvZzGiGIbabSrHTy88/nTo1z5275PPjs5n6sEunge++Qi4aVj6/Y/3SwpTrta/+d2zt29XursFjBBFo52Ge/rCytOHzv/yh2595sUZTfftSeBJXBkuXAOQEGnyPA0sO5WyB/r4Yt5rT+JkVD4/Pbc8WyznEIVKpVK1UazX66PjZ10bUBRlWRbGmOf5r3/969c2ZW+bgSYEihyJylgz4doT4GGoCCQiY9uFNc3f2KKg/eBIEXyDSNUpz4/IXzdtlDWKs92zaNAziBMu7LBQuWAC1am1s7IFAXJdMepQpBl77nP+pyNAAypgQdksAgR8Ahy14lACgAgcANq62nqEDtO0aJryPD+PWSj4zstrgaKE2tradF1zHJfnOA9jQgjHsc1mE1lhve5BCF3X5TiOpmnP82zbxhiXSqVXPbI6Xq5VF/LTNbFG2eKiEY0CQjP11cjxQwCT6k13MI0aIeT48ePFYlEUxXw+bxgGwzDFYvFLX/qSJElTU1O9vb3j4+MBjWMYxsrKitviN3ieV1VVFMV6/eIcWAO3mmFKq4SiwiePUHoT80Jt/618dknX9S984QsY4yD+EEXRcZxqtWoYxokTJ7Zu3aqqquM4Xgt+fonnNU17B4Ym72RIIX7/PUOxtpBtLkmz4wROOvE2T5AIxztyqL7nJmXsTLFYPH369NTU1MzMTDgcfvzxx8vlcjQaBQCcPHlS0zRd13/wgx8IgnDl8Wka3XP/jsd+dNo0/JSaIrN33zly4MaUFOK++q2T6XaUdRxUIf0DbZG2+MJ8tnuIf+j7J3bt6Ph3v/pT84uFU6eXguPs3t6+b2fH9TvT4RD7jS+d7UyBEnaKBTw0lG5rb5ufz6R7zMcfP7d3V/fHP3rbzEIpX/C9+IjCPnD3Nply+rpD4RD6ypfP9bWBGnFKeW94czrd2TG/sLJpk/XkU+f2Xz/ws+8/+NXvHKdphuO4ge7YyEC8XaKEWLsQVv710NKWTZ1MhFkxYE9PIpVuKxaLm3B5Yrq2bfvmn/+ZO599cWbDUrRmrAM4jmO3YFlW8MOlIbJNKWXJZCE2uxBsST53zv9HARpoAAy4GKja80AANaeq5tkNIyzLMkVR7zgDrRpQt1ClGVzuRYNrOcBtourlGwEAhRoq1NaY+DdC6jeAgfY74axkuELlxdnF5XKso73UhJ1S1xZlj0IpVlvJdPwAXJblXC6XTqfn5uY07WqkHQBe1ZEk1vMgIV4oFGo0Gs0q9xqvxOZAdbHE87xlubLMI8QQQliW0TSOZbFpmqIotlIxrq7riqLYth08Kz09PWILpVIpoAIKhYIkSStzuX2R25aNWb4Rck82sK2rzGrZXo7XaKUvgUAeIC/UY0af+BP/9H0go50Eop+LqQXJHxuwbf6/DqgU7OXC9DnAAQOA5UmOtIQ060FB2iMbE7YUpCnaVtptAOog6W9JBOfqAjUw4a9tPDA9UA7cbgEgwQ/SZ0pH1h2i9X/T/6s/LftecfSUUIjjOAoh13UFQazVqxRF1Wsb14yrA0KEEL6cTIPIT1PDljTo1Q+AIATwUjInmM+E2Cqll5hr7BgOhxVFKZfLwQ1lGP/DrutWq9W2tjbTNEOhECHEsiyapvP5/LUvg6Ioz/MX8liH/N6P7Yv3hAvLmutghqYo0YqJc6A2F4xke3Aj2kAdVOo6EDuAAxoZbRnwIGcsXJodFRY7GzNd/lhhjChqy/a2G295z+f+9yHPsn/jEze6tpVMhVZyZqnUiPSx0MMCIB0dybvf9f6HjO+eLzZs1zxzLn/7bTt/9Rf33LS/+x+/euzOm/s+9MDmwmpNDAnFOl5cqnQNMa6LeYZOpdpuP/gL2P3+i9kXPGAeP7V87507PvX7d/71l44uLdf+8JM3yjQxLJcVuKqG8jmtp1/BDC+LYltqaOS6eyB96nT9ZFev/dyx1Q/+9L5NncIf/9UT12/mfvtjQyeOjCUScZmruw45cvjEph5KtSiOY+I7E7v23TQzfmrs7GlXd46+wH/0fZsKK9Pff2pq3ZPi31m4DgzDsC1Eo9HgB9814bjh4WGG8afw1NSU41xFFpJIJKLRqCAIlmWpqjpyffv09HR/f3+57BNZ8Xg8Fos999xz7zgD7WGX5WmBC68ZIJZlA88/8BxZlg1igWCwfJ605UuGw+GAwXEcJ8jm1Wq+Y3jt0zmme/b4HB1BgjBikoTOYtWNesTMWWVPPadQsj2nB64rTdPBUF7Gu0GSjhCKpgs135Y4jrOWJAyI1GDKiRy2HWBY1+DTSUdUrxtsU/XNXLVaDUzg+qsP2Nj1Bw9LGCGUz+eDRyFwaWmaxhhXq1XTM883Xqw71TY13u9ENNrIiNZNyoEU6U/IxtbYu6aok3VYdByHZdngO6qqGjwf6xGLxeQW6vU6Qqhne7RarQbqmnA4rGlapVQZ4a+3sFFjKnwq4gcO2OsJ9QxER0rCooNM27YlSdI0LXCHg9tUqVSudLrfMDyF4zgulUpVCgU6FnNqyMK4VnxNucFYCza2WZYNSJXx8fHBwUHHcWiaZll2eno6GNtXQkC4sxxrGEaxWEwm/eVIEIS6WZfb8CtEUQQioCiKKIrBU81xnOM4EEKO41zXDTJCiqLouk7TdPAkDw4OEkIghMGMEAQhCER4nl9cXLzuuutUVdUNfZOS3rRp2MY4N1/o7+tLJJKNRkNVVQihoiiO4/gWFqHg1s/NzW2YJgHNlcvlkn1CvV4XBIEQIghCcJBkMul/tXotHuvr6oXv+cCeynJxcKDtzLlFimXOHc26FCEUgARgDCAgVXXV9s9IoAiOHZu96ca+7p6Bzo7Qk0+NPXjfJkKIL6oF8OSZrANcDzL+joRg4tpO2XEt1wO0SL14fP6Og1v6+3vvuqXarNlbt20bvZCJJmSbCp+fbvByiOKp1kg0HKcmSwb2SuXiQr1uP/V07mfu79s5Eo/y7nv3JzkOVRvGwDADEbowVbQsG9MC8YVa2DQt7DVtS3NdTCh88szCg+/dfseBzesN9JVch+M46ydmgMD+BP9/pSxapVJpNpsURQVH8yesaU5PTwcTuVAoBJbtHWego+12utfJTyjBYhKwnPV63fO8cDhcrVYxxqIoIoTq9Xp7e7tlWYFZhBAmk8ngEQyEFmfOnHlVA409cvQL07s+0B3u7U5vu0FXDzseFkIhGppe0a3jss9ctGDbNk3ThnEpB00xpHurQVVZ4vouGE2R9pjrepBjiOPChg6bxsUIRRFxQ4fGK5gLhsOdI6aksbrtH6cv5ViOz/PoFlQNFFM8zUQij3UT8Swu1inrZacmqnjVJtwQWK3/uer4BEgn337fdXfO5qajq3yn3tHPDNTSM48XvmtQTU7wFz+EEIQwoBSuvLxgYquq6rqu53maprmuy7Ksruuu6/ohnmtPqWc1t2GYxvTqtD/5IbJDDRXVsGHzAm+2EAwd00KpVPpxlBVb+8h05rKQMDhFo+Fb/GajGojlg9VxDR1xt1BDhrnxO9brdcuyOI7DGFuWZZqmJEmlUikUChUKhcAnujZqtZphGKFQqFarIYQMw7AsS9d1y7Je6Qls67N5Gdu57ELh4lyDEAx32uNLyHV9Tzwg9DcY90wmQ1FUcKkY42azCaHvuVuW5Xne9PS0qqq2Y2O5dj2XWpjKZ5aqjTyqVPycIU37J3Jd17KsICLkOK5QKFx5hbquz87Oep5nGIbjOJqmBQba8zzLsnK5nJ9IpFFb8iaaLjerFgAygaGOjt7cisMjZfvWzUS8SIM4pnj6zKitUxGlnesyOYudHMv2D2zNZzVRintQkURO8aRcznN0emR4QIgxCEGapmxDPHnyZLPhRiNdMuuKmJ+dyPQNDWv6SwhYAt0McXWOGKvTS4U5k3KLqupnqwimquXSxIWnlxbmMAEMA2XkjJ64kO7tcTzCIAAJ7uiKQQCWpjJGGfemBD/48QVtoLhaWp45NTU2ijGgaYhMffb8jO28wZRSkHe99geunALrQ/NrT5C3zUBXskyjRFyrGjxVAICVlcs19OuwuhokvK8CCF9bcAqg1XQ8HRJMIKVAOgRpGkCYZm0scIlkosU5WLFYrFwuh8NhVVXD4XCtVqtWq41GTatSoo2olsEUWCLxJCq7hICaSlkO1Xz5BqkGsl5Z/O46UK9RwstpQEwAx5B01F0u0oqAOYYMdViZMk0I7kp4zXWHKjcoAF79ATKtemlsouwUxtDYAOhzwmiGzJftVUKwroNArHlxrCCgkZ8GaG1BECBMsGO5JauMACK+Qw811YD+6OoIAUu3MfH1ohpoEkA8zwuO09pImm4VuEDT/WdO0zSWZRFCpmkGkdC1fdJXQvsmk2AYE5kNIlMIyc1bzRY5hiQejy5ehVnSTNr1rvJIBKvO2twI5hWEMFj1156iazxRTgtBWAMhXD/NrsykBSivsKyIh5K4rgF88daTXIUh5Fo31DTNDdM4QHDq4P8E44ULxRceH+PD9G3v3f7DL4xtSN7yPO95XqlUQggxDMPzvNvC2gcIIVcKZjb4iZ4Hzp0/3d0Pf/TIabVu7t+rZLNlgO0d2zZdWGyOZnIQ+pQLn9UMwzU0h+Vpgs0HP3BgYnK20TCPHJ1cWCp977GxX/35nWdOLwks2H9d/3SBPjUzQ0GfMhJy6nKGVKuaP+qmd+/BveXc9KHl3DcfOh0W0IG9bRiAC+OZpMLsu6473hk/Oz2NKOh6pFJpXLgwnc3WOJ5yLfe3fv32qTMXvv/0wmxWO3S+NHhdf76oFQuNmEwNdrbzifhL50apFsFVqTQmxyczmTJFI5qGH/ngPqxVnnthGbwGcBwnSZIoijRNI4R4nh8YGAhUSWfOnAnu2k8Wb1+SEAPX+nEF3q895drNdmDWjkblVF/u/LNjxAMIlJloV10lrONqmpbL5RDy8622bQfuTC6XC/wXQmBxiQtLhOP8OKWugYbOAMCsE5ZfdNYcl3hXMw0vf2VYWORIBBu2T4TO5/yvP5tdc9yo8aWLnvhCHq0/rO2Hqq/+NWXYGPbGs66wDWydoVceoc500zfcGfpPBXVlB2PJw6sPdwsLhnbX6ONpprapG5S8ZMkQSudu30HdOa3O1t3qlHVKBMMm1m1BpiXM6NSuzpHdW5Lzs8bhlTHi4jRxbFT69tLfX2PYk8lkOBz2NTmCoOv62NgYeP1olGnsQdCzcTuFwOIqHVWw7UDPu/rzI/LYsOCVfGAoFIrH4xjjNYpjbGxscHAwEJwFjnA8Hg+iE4SQpmkbHNtYLBaIHwI6IhwOZ7NZjuPq9XpXV1dAx83Pz6fTaZ7nA0M/NzdnNKgJM/Dx/UFD0I+06urLd/eNghBg6W5lxbzvjt0xJYoQ9NZRZRDCPXv2WC+DZVme5+v1+tzc3FULIl4JCEHTrn76U2dWc/6q8KefPvJLH95x/b4Bjo/QuVrL3fG5inpdtyy/LNbVHIS9eFt0BHWeOZ996F9P27b3wyfqyyvFj31we09njJNDVEXDngspRAGoNg0/y956vmkAUx1tsSj7wycmy1W9UgX/x6cO3byj7f33bu5IRzCtZK3WcgL9MTQMx3U91/OdBIZCiXSC3jX0xNmXPEy+9OjcVEb7wIHO3oFUOCxiWirlW+Fmy+OwLXc1X/P84IsIDNXVm2ZcqfCd8WsMAsdx6XRakiTLsjRNq9frQZQpCEJAXq2srLxJGvy3zUC/xZCA8EH5gXNTx7fcw+f7XijiEa1QdbSq5fHIddcI2WCUr0r21zU4mO6Op9jAMWw0Gle6/K/FWSz62U78WjziNbT46leHTZpT9tgSTh3Gc21Mp0XokxN/8/6tv3VL3x1T8y8NXxh2bu6Z7TPboCaMPjpfoIb2dbKZsu40mpZT1qpRNrkZ7ltBGpTDhD/LD47LncWMZFWQQJytnHaDXetiLY+3keNuHJ/2mGe7TF33LeZqC2t/CiLuIPJo6q/VKGlVf69iDW9wwF0XzOfhfD5YySAA7loaZ423yRTBVf1T0zTr9XpLuOmzmLquS5JULBZDoVCpVArSOMViMSB/r/oMGIbheV5AqWOMA84kMH+5XC7gGUVR1HW9Xq8HBEWwIyFAkkRVVVmWdRynUOc5HiLHsSxLEASKokzT9JsctLL5hmG8dp2SILCKIgkK04rv8Ei3O529GFUcP348uJjgGwXHhNCXtPIssWzgvqYCDRiLhVaWL2Zc8quqLMvhiCwIgp9FJAQSQDCyTOw4xHUcRKEIzxLiSTLP84Jt+zfF88jZ8WIoEo7FQ7zAIuqiQAtjZFrY9bBjt0h5huMFhgJMrekPPgEgXzaaFtm6pcsjQJalieUq8Ufe/0K2TSzbs0y/8pimKASIEhat1sNi2Hgu29w8lGrrbnM8EFKEuZINoX8ZEALbBc2mY1p+FMghKhwWaNfl+asn+SVJ6unpcV03l8stLi5u+GtAc70ZjvMaXlHe8aYiCApeKSp8MxAF4VAC0GVonHaiHbonk8oqZ5aXkSQp1mIi7ufHBEGIxWIIIY7jLl8PSbjNdQyq0WhWKpVSC7bZ9MP7N14m+pMHsvhSjT/jZp4npzyZohB9Ln98tnwmJfWPl2bHzNptU4WwrU609+YmjUdiQ7EeNEU4S+gtjmt5O7srtqfozA3e/FJRelbadJLrzBPawMCGjG7Ki1zvSzRTsUqRKc8omJOud5HWiSdifdtwTAAKT0UUwLGAppAkAJEHyTChKcgy0PUoRQSdCVysvb7xKjd8s3JVpFuIRCKdnZ0cxw0ODiJfj0EC63ZVAxeQraZpBuSsafpZTYiicGwAACAASURBVMuyGo1GYK8dxwn+appmwGZsOEJA7AawbTv4mGVZwWGNFta2vzx1/SsZGhpKp9M0TafT6Wg0GqhxotGoruuBQjzI5gd5Wp9XuiIfdSXclmORW65OnF0Ot4m5mWZbr9EVJhSiORZFZNCdxCHBZhjYHiMhkfAskgXItW5Hd5vvshrWq98OD+PF+ZXsyqWim1pNPX58pj0t5ytaodFEEFJ8REr02w72HA1AKDNMWGD/7nNPP/zYWL3xcqYEQp72njo03pYQV4pqoV6nfOZFFhMDLqFdU4UQyCwj0dR///Rjjx6aXSOpfv3DOx59Yuzw8zOpuLCYaxbrdYqCgBKERL8HRUv3fxVpWmLoP/6zhw+9tByEmlsHojdvT/zF518Yn8jEI9xSXi1WqgxDEcgJsX7MhCytjijCU5TRdD/1V48fG13dQIuxLDswMCBJ0tzcXBBYbxgZhFA0Gu3v74/FYoIgvK5l9UpUq1XHcSiK2rlzJ8dxb7MHbRhGNptdTy+KnVEuKbFdIdt2CSCsFOEUiQNQn5mwbRPILG45YpTrIt07sPAuReOXnIVlkE/AWAVbEhVmeDo0nBJ4oIBYdFXiEDNdmJ1uTvQyqSopd5N0uCBex2xXWbt6oQri3JLIWO5pNFJFFT/L5DhOkJMUBGHDzKQY0NZvexYrUqCuXVzSBjrsfAWV629uAeTrwkyk8XT5nN3057bMhlS7AYBX0bNfOf1f62Zxd+I9PNWlnxSvc8XrpuuHOPqvTAu3D8ciob2F5/nZIYHmeu94aeT9h5uH0Lxm+zw08v9DDOAhcBybGnjRZeYG8APW1H9czX0/WzzjYRv4DhQkBFoOjCs4JIJ4yK5rKCrjcoOKyl5DRydnOMOGS0V6Q6eFVwXHANu9+irui/+r1eARomm6UChgjAN1xJUf9sVxAHC8EAqFms0mxtjXgnBcpVKRJCngNHz1Xks1FMgegnTchuMoisLzvK7rQV2V53mBNpyiKNu2FUUxDGMDcRzrcHjF+5VbXlJE8uUnQqenuMCfDf7KMMwG6UiwzLz2IbINt7BYn5lZdhzih/AA9CRdw4bZCh2VPdNGHONpFkpGMAQeRMDz4Ll5NluiW+7zq3vQEIDJ8cL6KxqbLH3kZ0dOjy3kKjqkIKLoaM+QJFmcMlSaq7uOVa5pZ0dnIQRLK5c4cQjBzq1tjWrz+ZMzFc2heN+wh3uGpZDHRrqrdsWx9Epdn5laWMiqZsvvDsBzdF+7BCjlqaOTmosRDSFEcvdmOQYdN+4aBcfSTMueGp19YbTsvswE3vWuXoZlhjokKcI/+dykQQBifQ2J0j0kxXjP42yjaOt1y7L/5eGTz42WNox4IpFIJpOLi4tXXSkhhO3t7eHwRQVaEJOBNwdvG8WxVnkBaarnvr0gxqpDcZYHDECa2vDiIkwlEolYaKKx8tKcaqpclwwIsTKaVrNSg7H3nL3vIfWfVNzchjZlXdNEREJSmE4lB9Ijlb4tYv8smckUSyPWljjFt7FKFhS2kt375FsW3YXV66oiTZ45/j1qh0cU07TMTOaKLjLr4Dlw5rhvu6XwpY0zWb9wdo0mfieA6owM3Hbf3DeetAo1mQ2tNOZ9ugZbVdPX1VashZp53VB9wPXqp5i0udrpye24vaP4zKFDt+zekx+lY8vJWx7PZb3bb0fhKXJ2GTC8n8ZRwslohM/l8iay27at3veub/2PU/fVztx0z8otTx39O0JAbobzItjFcHHVZ1ohYAgAUdmr6wjji9wrxxCOJj6L+drAChh7cN8weWn6KtUTwTHTUafSRJaD1izpGkuwAamIyzIk7ysvUG9vb5BMk2U5sKoBxREI3QJ7TQgpFotXzc5DCDs6Oi42X6SoYrGoKEokEqnVahzHBbU26z+vVmnHhl9+gmYosFS4yJ6tEQ5XOulvYKqbmrM0UWSdRHaSFzu8xaLvf0EAcmUOXlJwrh8W4pd9vbZlACFI+V1ZLoGhqVCIzVdU1ca+uy4iRlaUWLLeBDRHWZofV2oNbXJ2faW7D1nkskurmoFNQljCUhzNhkJyTGyqgOaR0cAMBKfOZTOFywYQe4RnUKGi27qjYsJwFJJoLhqV43KjASgOGiqRKPSDQ7Nr1tnn2SqGrltN1fIgJLZjIshAihJpLhYXYyFdIxSL3SpWKHh6qrx+ICCE/f39juNMTExcdaWkaXrTpk3FYnF8fJzneUmS3lQm4G0z0DRNx2IxCCGtCL1btq4WVtBEjUGQhlB2PbnGMCu6SVVCkJVJWKBIB9Wu0KFZMhvtsA9HXsjuKpNJI2QlZ70Vg8IuS5X0HGdnFmfEFSr5TANkScEMGTzERdvlWC5iRTyTiEAy9Yaja0v3O0Nbhs4vTEACKESFWuUDtm0HDF0wbdY7UD7VRkil6dN8wf2IKZ5pgdo7qWEh5uje990tdXfP/Zev80TU7Mty+vPNM6vm3NbUXy3UCiYiRm6UYtP01CTdJgujx6x6Mb/pyZAD9+8j1SreuQWdnvcYBiDEhEKpni7L9brq9flGndim8Ws7Hv8j7t4L/ZEt5G69MMGJXqFGIUT8PhCt5i/Y81SLR4hASDiOU1XVsIBHWOBXwLwmJPusVtX7K0rfeMa3Mp1xl2eJzONHT4rX6Py12lKv27bf/SObza7/01q/oVctDwkkcc1mc0PmsFarLS+/ogbANpBtoLGX60CHB1IAwh1bex59+qyq/WS4S+yR0mKjI+439ZjJUizrK1abzWZQuhlI+zHG69t7VV7zc+thEvDIl05HSHt7XLe9pkVolrV1ozZ/3tEiZrlp1g2IGFFikkmJZi4bJYxJtmTEY3Jp1eBYmmFYgN36wqijRaxK06zpiGJCErsyXd1AjD91LPNzt3Vm8g0oCwImFMNYqq4ujHt62CrXzYpG05xnWuOLlz3tJ8aKv/BTgwD5qi0vJPtyFoyAg7XFSVcL2ZW6WdE5lnv+dHa1fimqoyhqaGhodXV17anYAITQ0NDQ3NxckBAWBEGWfa5dFMVCofBm5AnfNgMdCoXS6XRg7EovLvr+qaoTmoa2zXsuoDVaEGrN5toztXB+MSAi/DysTEbJhMr61dhrDefEqFi1i67rXmoCdKknFNjGbCpp1cfKP2RC4PR1jXD/JjM/68ddmHA8F41Gg8KB4MJqtVqz2VybyRCR7m0ma42IfLhUKoXDYcdxguAUvJOAOK740sm2x/idwq/H3WgPGD4vHD5hHGvJ5lofgLBq5Iciu7I2LNA/3HLkc0KfToVZZo8JR8A5Hd8isX/7t5hCYHAIYhd6mChRKdG5s6eTYgTt3Nm82jSfepotF127x2iGw8a7+PTJeN9gPj/HG1VfExswwgHzwHGcpmmpVCqTyTiOoyjK6Ojoa/QQc1M8IaB/69XZZN9tdOCKH6f7P/sZolZhwSsdLSRihECNMEGjK5qmg9qNarUaDodbRYlCUJIT1NeYpnnV8/I8zzBMUMrkuu7rbQjjN3VaLFAUyq1WNf0nmVkqLWsdMcBJHnSQIPgC6qBWSFXVQHtw1Zzna4FfSbKuS1xLh+cceWF5x7ZItWDYDIs1VStXsUuMRo24npKI8YaazRkzs8XLjkPAk0cWf/7+AaWoEZomDKNXGtDyKIjqxRIkOBSPRWhyYXZj88jnT62899YeSWIrZZ1JxjDwU5FGvcYg1CiUaAqKvPivj003jcsucnK+slg0dm9rPzuWcyFiohFkW2az6cE6BWGjUOI4plIxz17qYOW7jMPDw0tLS4GK8UpACIeGhhYXFwVB6Ovru+ioxWIcx/2YBPQ7VMWBeaGx60Zhaa588F5pdhw6trCyoG/bTDcqt4X4eDze1tbG83wmkwlmwtDQkG3bDz300P3331+pVILq2I6Ojrm5uXK57LpuPp+fm7uszcoaeEpkIV2x8s6BJLujHdvY1A2fQQNI1435eZ8NuAZsA5ZyWQpVMMZrMtg3j3h6Y0CGJx4F4UOsEg8BFyBLHqZv5GXqrHa+QfzOBprdmGkc/4V7h+b05zhc4rb4ylyfPGYAlEBWyH5nOUZq+v4ttSdPuXzI529kQYuL80kZRwXOVFF1FdRc03V4FyiAYdxExKVy82dE20AI+UTqzMyl9THA+Pi1BEyvBF9jB8D5+asragKCwi9NgyQwl4rCNZtN30+62k0ptyoZw2E/FxdIPprNZiwW8zwvaEnBsr44p1KpJJNJjH3pyFXPK0lSUGxZKpUcx3kDXfdczxctWOuaF/9E4Kf8oDO41xoElK6SI6OXRQkBWJZ9AyvKVfHUs3M37LulO+IuNt1kJNXWO9DZ1Vtbza8szUAMbr4p/Zf/++iV9ur4qcxtN/Xs3t4+nW1kdKujrSvSv6ktkXJKhUqlEBHYxx47WWtsdEKLFeP4eOUDtw8fOTK56rm6ZcSjqY6deyKSIhpaXa0oNPU4v9BqFHAJTc3+86+c/vKf3OXY7tRixcPY0FSKlvt33hCWZdmyGrp65MWFkQHn1IRf8k5R1MjIyOzs7DWqTjo6Omq1Wl9fX6PRmJ2ddX3th79g//j9oK8hF347DTRlmeHTLyDbEpZm+Yw/TOrw9vq+g8lH/3l2dtbvsVCvV6vVeDweFLkF5YW6ro+Ojq6srASt1+bm5ur1uqqqnZ2d1ygp9hsiIb0cn18tLR79f2Y6r+tQHRMmBQbSCEKBkijRL6sNVsUN5RUCi7SconDYcQ3V8TNIQZlmPEy1uiiBpoEuvvDFceJhBABspcgvvhTGdd23xpT3rEY+cP7mp7xzFEXHlTakcxWN+j/R//Uj5gd/b38B+5UxpNJ32PlI1ftqHvE+a4wgJK0OeiyPHBt7ELvD3NnF9uGOWplyARAataZeH6PcLRAvFXKu5SnDXdqCTu+4oedkUzbKq8TzbMMfhGt8x1gsFmTVXNcNh8P1et1xnCsbbV+Jut8w6+oPLs/zkUhEEATbtgP3PHhartGnu9bC2q8Bp9FoXPYugmsTHeUWAgb5lZjHYAHA2KfC3iSv6kq0dSch4ieOMmMXc6p+Gy+RZyHyr6GxVkn1E4KuO9/+l7Hf/e3774htDcXaGJav11S2ayh8x/2m2pycuDA9+8Mr9yIA/NXnj3/jr9+vm9T+PTf0D2ziRMlxQT2lxmIRhoJDAzfNrnx6acNbVQD4u2+cDsns3m09+NxSz45brt+zj5dEhhVqDc3DJBmP3HzT/X/51//4+X96bP1ep8cLf/7VM7/yns2FYjObL49s3nrn7fdLIseKsgdQpVK/45b7eYZ+9OkXfu9P/7aru/fa1lmW5VQqZRjG5OTkGvlpmubCwsI1Wh39+OWIb7MOGtlmpM+K5B4WoqLfpsBrmoeecxlPD2uTq35Pa9/vaypBvztTtSRRTI2AsjcqdsCl5nEAIAsYtY6AJR47duzqpwAUBh6CUFX0aqzZ3N0bG0sm8IBkOFSNY2gmLPfKUKknspzg5/2C6HW9Tx1TMMvg7qRTaVJTmUs3Y7Ddd7JcDKczzFpZdl/KpSlg2mi5RPu1eG8h6LzFeA4v01ycb9+W7u5unzgxk/Oy29CWtBvL4lLPVuH+32hbrRbv+bn4mSnmXLUMOV+nwYtsLCHomt2smygORraHruvY9OyhM4SI9Wp1ctaUogXiarmii2i5YjB7DohnNt3QUTbm9aYvHXg1BM0uAiY00Mm8RleuNwUy5as/otUW1rf1CaQCNE1DuDEBJnI+b9PQYdDvZc2AYuy/zcdvExE0BmohSEUETk2gZQ46E7VKlvxXsu3YsaNer/M8H/DRQanL1NTUli1bGo1GIpHA2G96RVHU1NTUW7A2i4p4/y+/d/zpUVO9NMkJIUODaYx9gcHZ0Yst5X6CEPiIhztFJXL6zMQPHnomlytSFNqzZ9uDD757ZOuO3/nNj376f315/VtOAli290f/88jv/vqDybYOy/G+9fV/PfLCGU0zotHQ/fccfPc9B7/wmT/697/1R3OLG230X/zDS+++qfN9dx3o69vMcNzcQvZL33p0biFDCB4Z7vuFBx/4jU/8omXZX3vo0Ppe0l/94dj8fOGeHfEdvT0j193o50kQ9b1HDj3y1LFSpS5Lwh237Pu59939Z//ldz71mS9eu2J7+/btpVJpdnZ2w6L7WvyM/+/poIMWM+Gw32HdrtNWnabdcCrUb1SAhJJ2nS6tGFadNuu0WaN7U9tclWe9WLOAo0K3VoaUE+ZBQitDYEhRodsxfLrTd2nj8c7OTsuygjjULxvT4e7IARbxCdRGRWPazgRORM1cVd9k5pRKha6WcLF+YbZoZAplv7yiUChUKpUNXphmUZpFr5TocvNiN+qLb6lpsPmq3z6p1QH14sZSa2OpQdnupY1vjScV1kPlqmVAkpLTA209A266llUvmOebqGy73gJZ3HlLrGeruKknLilsIhw6OVNgRUQw4LjY8OBmx0OG3qA5SGxyYHt/OBbK55qG3hDb78JUu04255bmEZQUgCeHPwF67itRoFHM8KdnaN3qiGOOYxyPpq6GQHQclOrV63VN0wIJxFXBc4ihYShtCTLelIC5ql84PtDudcQxz8K4QlJR3JfyRB7SFEyGcTxEQhJWBF9nnYwQANFQp+vXEHPQcnytrZ/e4AHLQIaPdHR0tLfA8/zmzZuz2eyWLVtisVhvb293dzfLsiMjI9lsdvPmzYHGY9u2bbIsx2KxgHCr1os0Q0zDJ0DK5bJt262qQr+0jGGY4BUEwYtOgq/5ppYwBDpoiqbu+vDde269cfzoBc+5rIw7t1rLF2qrxR+rU1VQDr6hXEiR+V/72ANdvX2T0wt//3ffCgnUyFA6GZNnphdeeOHM/hv3DA30ra6WpmeuqOyA8CPvu7WvbyCSiH3xqw8def7Elr7k5r4ki8ih50/qhrnv+h09nenHnz66oXQWEzLU3X3D3l2RVPtqofSp//UVbGi7h1KDHdFyqfLoM8d2bN983z13Hj1+ZrV4Ge+0XNApyN1x6+0WRslU4gePPvf17z42mFR2b0q1hfhjJ0fzJfX+nzrAAOfI8VaP0Kuhp6eHpuk3Rta9LrxTdNAtcTFKD1oUDf7mw8HCVQPgUv/DAGcXqa9PoPnR8zykWBrYFpqZmYkp2DDJwsJFx2QtpS5JEsMw1Wo1aNMTSFk1tzHRPF1zygvplcqtMvZXUMRuwQLnQYcWBEEtVQABDrmWQ+e/EQc6Au8LsAJn6uU6KL8rxfpPBn1jNwS/bxlVDSFFWEZORNRmrTxXdsqNGWqO50IpJ7xTGFnZfJKVuBijzJ4zSkXt+oMpxvMvlBfojo6tXbFIOtw3zjrZXF5tuOMTpeyi7tpaiCbhSKrQsHixTcCs6RqsCGf4znAt1yxkYLFEM7B/l6HYVLl4MTe4HjHF41li2lDi/DRdQ0fxkFdqNfVutoiRKxESPb+I2QWkRUO//NWAzPu+UVjEugUtB3EM6W3zJRwrRaqnzV0q0iLnT+n2mMcyJBXxXAwqzYv+h+tBD4Nqo1KpVNYWy/n5eVmWx8fH19+gmZkZURQDbXIoFDp58uT6a0sNmGIINxdqdf/i/cszTXNrj3129lJC4tqO2E8cvVv7tt+0a3l6ydT83inBxvb29kBN6HleUP4wNXWpVdvrBcv670Vc/+s9d+7r6ExXao1vfO0HN13fF+uMmX7jIWpoe8foqfnPfvYff+93P/mJj3/wxKnzhcIlOQTPsT3t0eu2DcbbYj98+Nn56Zmfu2+nTSNIMx102+5dPY8//VI8Eb3r1ptuO3D9k4cuBcQsQw92t7371us5SSbY/ewX/nl7p7J7Z2/NclmWGRhO1YuNv/7br/zXP/jtj3/kfb/5nz+9dos5lomHpL1bR3ieC7cnj50afeyJ5375rm1iRDQxZDlm187BC9PF7/zLDz/4s+/5lx8dnpi9Sqghy/Lg4OAzzzwD3g68TZWELLX73hEtSyyNMnR4bo4+N0dPZYTJjDC+zJ+cQmdbW87NMXMrjECorgTpTno1jbJdCiF/vpn2RqvnOE6j0QjcFk3T1koGTOxLzY0YMLs5fwVH0GUARzCiGb+do2bwsw68poNLMWRwrypzXT1dA4FMkqbp/v7+oCvp+vK24PMbat7AWwXZYCNemI/F/TaKu8PVpFlYyTKMQdxm7FMX7vxYfClfZQn9zOFlKYxOnik2iMvKlBRiuzoHBpNdHXICslpNrxRXjfx0Y2K87Oj1qOQ1m4aYHFZzZ73KjFvDphgaT9+ms0yzsOxWSuJMgTFN1kOOw+hXNFehKbCtxwIAxkNYFogikLaIxzIgHfWyr8BdcP4L3GGlBC0dJcIkX/ELNypNmClRxTrKlKl81W8OXmpQuQq1UqRqGlwqUDUV5iooV0HlBlou+p8p1lErdAnqCIDrAafVPW491lrdrkfQpfOqbcb0OtUoMpvaSUP315hgo2ZCq1WvAN5aEEI27Rk+8N4DoXjk2W8/DrGXHrA6FXLf9faOfqcrvJoUlrujxc5I6dio36f39ZbABKBp6ud/6f5QWJqfXcGYHLx556/9ynu2bultSyf+5XvP0JRlCvyq5sjxePfgUNNFpmcWFjOCqOzZvfW2A9cbhra4lPM879237fy9T35o79be9lTUItRXvv6DLZuTS01Hw7B706a2rv6FfEmgvZOnpm/cv+PO2w8g4o5OzHke3ret7w//w4d29sb7ejtSycgjh08XVxZi6fBC1WCV0NDW7Ww4sZjLQ8tYyNV+5oE7bNuaW8hYtn37roE///2P7+hQhgd7kzGJk+QvfPPhkTRfx7BkeJ39/Z0DIzUbOc38ufMzAwO9QwO9h4+ddtZFIYFLu3fv3snJyVdqDf9v04Pedtum9oM3Tn7eb9n+necuViIM9Lb1dCUohA6/OL7+/Y/+q9JU6uXe6IS5RDO8DsBWt3XEUBAhgFDTskVsYZqnGL8y6dovAcAuLCzwjWKGEJ8aC0rygzTRBmf5qrmjt3Dqorq61GnGmh7QknazUnTNquKhH3E/OiA729t7u3rFYsY0Sli8hV7QNEZmHA3jELbdGQHFe6hURWJoQHmQdGzlVqetrh6pXLKhMVkrTyIPyA4SaTwLuzgXNRcXRMfVHb/gsJxhURg7vvp54wXVVPDMWW5tTHiW2K4vlG7RxK/QP7d5acROTSMALpswAdvQaDQURQlK/jDG65skXLUdyhtqqHcVEOx74uPLlzofrXXtf+uhxEI779jJh+Vyplpv1BVGRBTgWKKIGOCGh4HQEpF7yG9U+4aLKSBEhtH8hY+9DxOcnVv+1Y/ef+HCaFtqq2qCxcWVUGfIcQGNsKIoN+29JZvNzc0v8PHQ008fvfX2GxFF/9KHf4pgZ25y9pMf++mXjp/o7O4Wo4lnXxjlOFR2fREVBLCvZ2D3jltLxcrqapEQ68TZibtuv/mn776epcHR50/+4W98KLu4AAimGIaWo0dePBcPizX/xVFE4IXtO2+k2cjJEyeZkPTS8VMfefDd/+6D94rQfeyZo7/z4fug2WxUKsPDg1w4Npctl4rleChJuUQRqPbO7u7hG2h2bPzcqZDCHnnx9Cd+6QNuvfR7f/k1Z50Su6enJ+jQAt4mvD0GOlMD6OzFdPlasnt+qTi3eEncvrZ9rbllgFL9DZo8hGheigAEXVsHDI0LBSgjiX31uStykGhCOkZs92JgHlAZbVE//iDAj9yD1p22bSdbGzGG+ssqjjWP7E0HoVNeomJmGFte/IeTtlnnUFlC24BAsOPaDqYQinaCgRFlqaALAuUKAstKWrmep1eXYxlOkqYWl4urDi/Ktu3tuzm1OJpproD+YQQRrdccDNn9d9Ae5ZiAisnx4tRZ6FmkZfyK9Wt1gOrt7Q2Hw6Iorq6uptPpoE3g0tIbyVwFLZhd163VapIkVav+u5PBWwvbvkyBV/nJSNdeNxCC0UTcRfD8iTMeQ7kuzEzwGQDOTfuGWRTYWERmWd//cN1X7Nb7qmhVTvZxHN/b3xGiiKLIsqxQDH3hwoxm2RLF+J1wPV/UtJxfrNXqju1gns1OZ5aXsslE0jVIJBwa6QnTNEP576JiAEQnTo4BnvVbxxJgu65uaKulBVXXXIwJxzx/9NQdB29o6+jd3J/Nz45FQuIK8LteEEBmFjKVajWaTAPoC6UaTdXQ61atalmOB6HtOCdOnb/lhl3RiHLfrjDPcx4hvKwQ16EY5sSZCZ+Bo/0yV9txc/lSZ1+9WsrYjktx7IsvnfvAu2+LRUPrc96KooTD4ZWVlbc+PHqbDXRjIVNRhEjr5927d9dqtaCwPXjJUyCw43k+m80G+bqfhIGDDCXKSsJPWBEsJKJN02ZqVUaPYE+79vBHZF/F0ZV0q03UNC7VtvW0+Zom1wPTFrPWMqIrEag4YKZEq+Zb6ly1obab0d3TcHaVLl/HJDO0I5rSDrTvn4xvG03rqSML82Pqrr2pxICxWqN1RYAEQ4gwcGtVdl4DNbS0VK/angsI06h7HFsZaFOZNnr/vnQk0n/23HmEtP4h95EJ9vzZowzLWqaK6j6D3yr/9YOHtah/AzKZTNB6hRCSzWaDrOm1fTpE+4zz9UPkzKz/uoo1eJ5XLef8F2MQ6Jh104amaW7otb+9z55cprTLKxf+7cFzfcclO7+kN2qMwoN1tW8QQtZ//xXSDb+1yI9zFkxwuq3LssxDTx6DlvaB99+ZSMSW5hdKmUpI4S6aM0K0pnpu9KymGq7jUhSKRYSVuRnsOImYcu7CTKPWtGy7t6erXKoYxkSIAYRp3Vbof4tCIZ9fzRdWV7FHOI52DW3qwtm+oe2PHDppacS07EgkJIjS4sw8oYWBdMxnOVt1SbquZ5bnJianHNshBERD3PTo+Jbe1NhCYXlSf997WOg4m4YHS4WSadlGqZgIt94v0Ooeo+tWdn50fnYGe4ShUZgFsxfOn5kvrvFgCKHOzk5N065899C/cQ6a48D7fzaytwVNJAAAIABJREFUXBDCCNAc1lUnSHlXq1VVVZvNZpANr9frhmH8pHxPFOcT+/d2toUj4U42InuQQI6O1dkPP/zeC/gUhtc6i2ZS+ssqjrWNgYpjtUoVWimvtY3lpr8xUHGsbXxrVmDVUG83b21wfgubLWoIYyi7kUe9J56xnl9eMPmEnyC9+WDX9GQFa66LCPEnMWc7mtK2E9CybqJGFWqNIk/zbYwT1Yr5rA0Bicgqy2THZ+yySk4uKT+a6zRd4KhNmMmHYB9fdP5f9t4Dyo7rvPO8t3J49XLufp0TcgNEIkiAJEiKUVkkLSuNNWP7yJbHo/E6zNk9M7tzdme8Y49WXo89liVLlimSCiQVKJoUAwJBIqMBNIDOufv1y6le5XDvnuoHgQAIyRJFkzS13+lzABS6ul7Xu++r737h9xfpeiaCWIYxHZokCYYmCYIkSYoiCYry/vAS/2vu2Bv5W9s1kyTkGBKucdcgcU3vRyqC/QLwtRtS2I1Q5GrVKxVcMZIE+7foyRDiGBwLucW6FyFeZ16twn7XjRG95WboxuLCghBid9yyI1cqO1WjtYq7u7tjsRjHiwhQsXjKtLz8QyKR+HmU4d5oEACSc7LLuRefO1quKqLAm6ZuG+pQbzfB8yWl6WFOve5GUlW1SqlCM7ShGQ/fdxuFnYXF2aefefXI0XO1ugerY2iqXMyTyNm7d8/E4hL2EB/eumAYulAoyc0mw9KEiz75oXtqxexTz77yg+dfy5VlnmM5hpqemWewI7HULXfdeW5ikmFpjD0qNMuQ8/NLtuMQFNGTiu/a2Lc0O/P1H742n6tathULSZPTC5bSpLAzvGWDRZCyplAU6QvELK1mW8Zqruh1UTrOg3fcSlvKkdOXJhYv7+xTqZSiKCzL/jx6ze+pHPSHHmB37/SfU9MRd5EgQHnBy75fGa9stWS1/v4W+jWaplmB87ZY/nib0OkjfBeXRxrPHbdXNLftnwi1PGwP41DY57qeXuKVwdkbNvO+VcNab8JWiOU/b/vTYCDSE+hYrB8fzRNHK+NT9qIL8Oo0aP4lvP3uHtPy5G5txV090Uhux66fJjFKCJwJ05YLgky5hjCpqDSNErRRJZCPA4zlgStBz+ByHr10KcH3pbfv3mPIjbmLoyy/g50vd3bpvELpa23rQR9Khx2e9cbLeXZNcAWDpkZoXiTn0TN0i9BMmAx5rRqGBR0EXddD1i2sgZbWBIK9aBzVGYRg19ANFsBrY3ws4NYVgv4pizcsuZXGDYD97zFzHZeE5IYtWxLhOMed13GdIDFyvSFJx/Ew2RjjYrHIcVxrvOvNXcXTeKOJv/i/v976MP79Y8/91mffv/+2myDBSXUV5nOtMETXTWiYtmXTDINcNxyLYRelO9u/+D++32qYe+z7h2+/eeP/8tsfVVQt2tZOUiRaS99jDGq1hq4ba/3mUOS5ZHuGYYiFH51aY7qgv3r8xxt6Uv/9jz8jiEKtofpCYU+8ytuBeWOZ2dX85cZ2F7WlkuF0B8mwxZIX8z72/AlFbv7GB2+PJeOGZXOhBL9SgqUCx/sc21ANPY8ccy07TxGwrbcbq8329gIA51pj36IoWpb1szFqb4O93Q56/Tpq/Wf2/+nkXdA5nptdo21hr1YOIeztirf6hOaWil5n21tqhm0V64s2m0xFUoNCe7OQX75wFpDNH2n/iP4pmXCSAn07VGUpJXJRn89nGMb58+fBu8+C7QK3wXES5RImR/1TyIbijNN1IbwwUiMRGeFCy5Wm44iTF5od3Ywu2/KELG3y8saFlfP+rqDtmrXlS7Rtu1XkcJQgsiwOLecr6YB77CR9puOByXJebMuRUalqVD3yGDYgJAFBTZ8Uu+LeQw5jrOiEahBlGfoFVKhDWSNiAVfRCUlAXjrCIm0XEhAs5CmWwSEfyldJSfDkUa48jAOiB1pbkzUAczkv13/dr2maoO4NB7RWyA3WyUrxxsD+955VC9VQKExzrD8gKdxq72a1C5Kf3DvzB1+J1pXLmY0r7Qc/W5z0Z5jIi1fP/qSSiVAwTJJUPBrBU95hwiOveukyjIGuG9ATG6SjUclr/Lxqyo5hOH8gGAgGJUnwCIJrIx6kNxlke6rMLrYcy8dzAkczySQkX3dNe3duiiYSABI0w+rIW0CeUMCaRrummgCSru24yJV8YjQsAXR5wWAA1vV2RKIRTpQEPwkZ1kuYQ4LhJaVW4DhGNyyPNOIiiiRFjhN83ImLs61z0+l0Pp9PpVJvc9PkO++gi5sf/Bvu8zVzwg844KkxXLZWUpKmSMe9WrjnLTNkOVaz7omnS6vnm+rK+Cu+5pkAdItUGHrCxD+zi8MlZk74bbMMwOXNTmvw7I0jnq35izceBG+L4XiQjzJNouzYEZdADsRsP5mO+Bhd7Mmtr7tKsXkJofiWPZFqRe0bZC6eNTpFhUqSZaNW1p4BGLM6ImUikQgKix9YNGLPRlZBOlucueQ6Vav+ow7eIWNQd2s+X0m2EjjXrwUF1sbQgcsl0pt+d724ddrTmWndT49vV14rIvzkn9chjSAAbsEbLPCEMlqHynVvMUQiEU8KliAGBjyCsyRJiqJks9l3sFzzLrTFiYW//7Ov3vvI/RzL2iZcmeByJjE9T1cbjosg5aloe/bLhDuO4z7x6OUouGXP/OMrp0+f+/AH93tJJLwWBUOaC7U7jm2UV0gKAhcj133p5SMnTo+r2usObnYx++gTz4SDwj333rU2W7B2lBGZUEqplV1UBRDwLLeynP27bzx5cex1qEsqFnr55VcvTi1+8J5b2ciaBh0BvVFQIUpIATu/CKEnfSWJwtPff/5bPzrSOgsCmIxHxsZnXjw2ummw+9777rAtW5BCulp3AEH4k8h1bS1LEJCjmXyu8Fdf+87ouEfyaXGmMPZy3OCdtrc3B02S4Nd+C2JoL67wcl2qeukev9+PEKJpr85Wriqa7raGNQmCaPES35Iruz4SrE8woQgkLHPxcLBwRLQrkFfVBsIuf9WT4gYWDwGeoWIB4OOBbnlikS0HPdSBBQ4GRGBYHre8dXAw4x30Gj889VXv4NvWDW0LUizMaGxNRAHDX8Ut5K8PECzmKbrbXi+S6wYfwFLYQhQOxYSAiC+9JhsFJ97O8CRF6EiZc4Y3JtdtC+PQ5icR0bt9OTg5rjtVMAABbRHQYVhEYZUoF8B8A1cHtDrmKuOkrbgIvrUp3yuC1tqa6bp+de7r/7dWMrBULDXKDTbMNZoNs6TbGmHasKYQCINoWNq1rTce9SfjgWzuF4Y6XTEIYT5XvPrON2T1fXdsLVQrs0uLGvbaq8VogvVBhuNdT/nd9HhQmmKq2pM/fPXqjpeh3sytW3tMxz0/Pl6Qm5D2ahT+VAdBqxQftNU6Bsg2dLPR+P4Lp0q110eob902GPExQT8/tpBdXl5sujZBkKwU9MVCBGlhyDi64mKHVJXnDp09txYgtF75g3s3u4YZkQQL4tnZ2dVKhfMHDaUhJDtY0SVY3jE0hBxom6Ojk08ePOesLeKurq7V1dV4PF4sFt+c5PG/1Bx0IiPqB35kxDodMYbh5S3Y4OBgvV6PRqPValXX9VQq1RJvRQhdrcH8SxrJcKH4gKvlQisnicaUzwcA66EUO+9R537k8cx+hlk25Figmdd3HRgWVAyC88oVr5tueQ12FAF+WkvDP58RSGOZGKA8mW5BYlwBW4br2IjJ4HseEZsV+9SBju89Mfvhh5nhoVhNMVXFuukeSDLkuo2xTb3bVvL5C6HxeC/s6JSeXZjdsC53e8b4fkW2oy61Jq7SKoBTNHRshxEKgv4kSd9BSBLW1zYWl28DBgSBHfuXVAP7RUFxLaHId0V8Ddc0Tb2Nf+ue/aQHySuPXvU9awOO15xHeJqmrf9tNdhffrRfdSIkiLUBVu8HtnyHqZlL47N8exyvzTZePhHASl155fiEdz+8EYA1+KIX+Vxzf7wGjyszAN73EJffxZ9cdG164PKFrtjaz4HlUrVkWN4ukoNCLBCOJyybduy6pTSRC3P5UrOimddK3E/PryYS+2eXRhuWY2HAOJiNsFwsHgyS1apBVUit7lXWjxy7UKhcQ7Aq1JTuWHJ2flG3UcOD63gvW0wGfakOb2xtZdaoYOCAheXcyOQ1YG6S5et1OV8sQY6xbUSE4mq9SvIUF48Goj616VL1VVNxXc148sBo6za0oDGGYXAc924ICN5WBz20PWmE0YVIPyw2sONG2i2SxJ/Y/vL/9URocXGxtXpKJY/p3Pr+t7AQn5IcUL5A5A8jR6P5eCjSrqg1XVnyJ23swZR+ljOVNai+7p29l9R6qUtFr1zRuLzGLy/9ldLljoUrB98+r2GtbSext+WMR/td187lFj1NFZ4wXTQwoG7Xlp/9JrftP3bf/Fko7FmYExqLrsoAqNtaNj8ja2qhagVr1PMT8dXl3K7d2Wod3vWh8MQKO9GsEhz0Wi9E2hdg1KZlaG5oWLt/69y56u1nx++TGCt3YdUn0TVo0sND9vSF2tf+0lNuf7vsc5/73GOPPXYdmu4dMRjz0zuGAMsIvOAL0LZJlCtlaNiQIimaQoZm+n1ETw+aL4JvP3f1iUyAD+8Yov2S69j+eISgcbNqGo06SZDeucBlIO7dvevSd19eGZm44qC9tOFCqS+TMntCFCAgy4ohzrWIZqWiWzYkSI4mQ9gZXL/hm3/+qHPtfjQcCdy8f7hg2jzH64YuRMMUi/W6pdfrXq6WoZIszRD82RGvbnbFDNNaLTTiMV+TsVxA2Kap5ksQadih1JKMEOY8zI5veuJ6LqCi6g3VCftFRbNYF5ME4ai2UVqpqK5RR5ZmEyTFQHxxZvW6D8zhk5ce2LMBwlnAkAzNYgRIiLVigyTnAIJGvuy6gKWo5165YF71zEMYHzw1/vC+TaoiVxUVhCIsL9TKdRZQVqXYsAq2DGzZYBj60Knlhn45Ox+NRlvyOu+GtfR2O+ip8fyWB1mettmAhEseppIkca5KOO7rol5X5zTeQtcWAhVtdhQIgKBZf7Cd4+o8F6NjFZo2s5sb5tEOAsRdFQldggMYqCA+zRoXGxaNIESkW2ddRgJRBNxj7hF3TeZqQ2hbBzGwoBVVFwXCAc7hdE1P8gxLwteKB+pWhYCwKxj0EURvlGxa7IpsYDqZ9A0X5RXN1hKRRE2u+VjBT/nk1SmbY02EihGa5pgQQ6z4IMh02QsLsJTDsTa3XidZ3ovMMHJphg4F+VSUoIBSrINC2WMgQ8hBQ/LPIdrhKI6mBb9o+XiRAKZiVgp6U9Fs6JB3rFNPbdroO7ydOzc1UlxGpVBXPVgLLlqNxo6deGQc9Em95+WOo/O+O0JZuap1tYXCYcEfDky+UoWklwai6VB/Z//88qJt5VyRxJT5wKZLiE6MniAwI5iOobe3uy7hu//99WMHjbOnwNtlPp+vRV8B77hlSzAWpLf2l+WGScdtx9Isk/MJfr9P1xTNsHE6jttT+G+e8sqdV5lZNOHUYmr/TqPeqMsaI/pVq4YJLMaCjm3hphxZN2Q01KWzY/a1J9YLjcp0ruPWzapuaIoKTZ/rmKZl8H6J4VjW1Nat37QwuqC+gUOfz5UEhgmylEFQruYYusFAyTTqkIa+SIgxtE3rB778l99546/4/IvH/7c/+mR1Zk7nedd2FG+/S2LXVqqyFA6yAId9gdGfFNyumGFaTz1/7NMf2FM8P+aKkkdcaTb1ctXifUo5DzGOxKLl2dVi7frXOTWfnV6trx/oPTc+bXOeJnGzVKbcOkXxANlarS5FwscOn10pXe9SXzx2/tMP3jLUnTl04ly4zWdAl+FYQ9XouoxMn1LIUgw1tVicXLo8KAghDAaDExMTnZ2d1+nm/ErkoCEFEoM+FZIIpnClyOXKhkq+donxqqkI9XTG1g+2ZdrCK7mK43jk9bfQQWPSgjGFoIEvGA3Gt2cSbaIYjUrVAEtKHeriQTpd2eIrtw1FeuIP7Yv1rW9z4tyrGLvpgOWimr1VWx9T+9rcxA8qT8vNpmQl7gt+SmtwshHyB9ftuO2ufck7/fUeudSEBnOn/4OvLR3O1ZdWymVZbtwbhoZiP3VxolKX10V2J9ntti7tzuxSm4E2cTDVoDNZkkCcX4ultw1u3jQ41N62ygRnUu2yalgDG9VgXOFCRjzjxtrkULomRoyedcr6rc2edTL2ITEsi1EtkQmtD3XDRYM3KEhHkgPd3b39sT5R5FeLi5bjmAVtdqL66sEsk9nyIlqaKPh9Y3uWR6zOi6n6UJZkmohUrZmN4NDvX0oXh3xj4Vyhq0OISf7ZiUamxzc5X3dpzApUMt67LhMJiDHVrpmWJQBCtAj9hFx+LkjDJtOXbvh4UFhyT582Ji+49Tef+vxFbd++fSdPnnw37EkB46m0kp1tLseJmTbGJ5AI6kqTpEhbVZxUHOy4CX/jR+Di9coGXtBnokA67hGvEkkqFqY53qzWMMQsgSIdqc4NG4586ZtK6QZqTGq9ufP2HbKuA5IJdXVRkmQpqmtZtOv2draHpNC3//IJ99qMyuUTFePe9+3KFSqqYUb7+tlQABKkUa+JDLmxMzM7nj157NwbP4aW5fAcv2vr4HKuqOkmF4v729K8JKmVCk+Tt21a/8KLp2bnLueCr7bl1dLmTQP9mUStXpdV3QJEoLeHD/ixaQkEGO7t/tZTBxT1Bo0Ts8v5B+/aExTYer2u246mmVJPtxepcJyrqMAFx09NGtdOeHr5RsOaWSk98sBtBEKqiTRT1ZsalgJcOsVIPqjpuuEeOnqRAN5AYwskYFmWqqqpVOrnkUB7r+WgNTJM9vSEmyuL5QESXp99X1wuF0sy8qao3/q2B9l0JcOlRBJgk4EFhJt9yWSvPwjdwFenJvCG1do/Tvvw+vKoYoJpOsBkR4ocIiitVgQLpK0DQpR4nwHrAiOopj7YuX+OK1sNxgKQrFnKuEEEzGU1K5s0Rzb9ICZRYsHyNlkF3fhPp1cQBi7GDb305NkvxsR+kYreFC3O5leOzU33GcE7iV212rgk9F7SjEU2FT0/ni4sm87QpCBRqaQxctwnSoAQeZZSmiZEbjzhBywGyFmt1W3HkVjSsmrV+TlA+hViPsGmOZ8u8m6EpqVQe3Mwc+LMzNRsY13cL9e0zeKFS6jzZO2VqWQ3Hw2ED074T3TlbuvCRT8zPzgxXPjA1ul0wPrxC3WGSf/D1y4Gw0y2VlNrJsFRDENHI/GUuDEjUrKaV5rq+HQl78qzr1Qj+Q2BUtDR5eIep2nTLiKhsDa19StmMBGnPv3rqH/A7sxAltEhJOpVZ3YajBzRaw2YioNEFP/dD8Chk288NzbUv+Oznwlm2rmgn/f5bceR5fqyeDo/eU7wiz5/8PCffaNyI6/nza/29nR2Dm/eGWUEn8/n1y2rtL4wfeakVl9hAPXEX3zTNG68t1iYy85PVT9yz0dNABPpdoaimrqWX5hvlJZoaD/57W/8tA6Qlw6e7u5KD3f0dPQPi7FYxB+ABFHZssduytMTY6dGbkzmdBH6m3949gv/+v1xmkp2dA4N74hEYwFetGwLm1qtVN20bn2h9NobHwlzS/n/8MVv/sGn74tQtKU5W7bt6d2yNShKQdFn6EqzLt+7576vPPGdH7/i4X2uttMXZ7710un9OzY2zp1XFDVE0Tt23h6LJ4PBkLCPRgh84O4FVW586RuPnh69FIlE5ufnGYZ5q3oT/iVF0DDTxv2X/1zEwbg9Z5dlX2GV1jwfHQqFwuFwIBAIBkOSP+giT8WKZT2dwLcwDcQHLbHLwDYNgI4JyPLBTGQZ6s6zx0qTS3IkjIxxL+ZwXVfNIW2haZsGQZQUMq+6hVvFYcHp3ERunrUnD1kHUuGuj+35DzYrTiqaj2cspFPtgVxOXVWLHGHFoe90+fS4erRF0fNyhZ53vvwyHGQ3jLxm1xbrq4v1qZI6H4aRh7iPAmyOGRdiUKwNFDbWucjK0u9IW7J6Lbdx0NUa1uoC4gWS5DTLEX2UPx6pZ6t+gWyuZJHlEtjC0AgHSx0ULrurARzD/lokxq8ThgioT+ZnpieLPpGI+BhUpQdv77xQ3Eo4lf62gqx2TCqXikSistzXWByYHDtrbde6xPFNg9FsXm6W3PHT9aGbA2PLssNDgIAUoRMxYSicjFFSnciuFkuNhuGBkybj/vpmL9FSgezMadrP6RFOPfjMW8Yo+hcSQcOeLvJP/oDaeytDUXSpQnI8jkSRPwACEUjzzvwskgj8vVfBGS+DfJ2Ferv2/skftm3ewhCkVazQBBGKxgKBoD+eJgEhK4XRR5+vTN6YXrJu+02PfOH3OwcHOZqXc0Vs2clYPBGJtbV3QwQe+9LXytkbs34gAT/88Ifu//DHoom2kD9YWslqjWZ7IpVp60inuhbnVo+9euyGcffl6w5tvPt970+l2wKCr5DNN6q1tmR7e3tHX+9QLBI5cfL0DVsgVN0YHVt44M57d+/al44nA4KUzxdrlVooHM10du+79dZisTAxfYPtRbWhHB0Z39IV37v3/uHhHbFAMCBKpUq1WKwGwpHBoaH9d+5fWVmZnLkmtYIxHp1cLNX1Nt4mXOqOez422DcUkvyST6o31WwuH45GNm/e/P4PfHC1UCiWyuVyOZ1Ol8vld2Ti7J2MoOnf/DdwaJ387EzF173/19epz/1g5gUMCTyYcReLlu16WPcWylnXdcMwaNqb8X2rshyYIBhOgJDUPHzEAgGyR5ugOO5bnPBZVroGHD4WLhErCqhRYIEAJAZuHio2tDN0dNItE+jkMjm5iOZTbmpjx86XZv+CpAMubzRpAnJosTpBYahDVaOtOkONO2dEjhVB+894PTrQAyIbAO0lWPku8wwPOdoVOFCKPFfKEaxFWE/kXpnOjQZRVqrXUKNMFlcZKcpaDktavvIsYbjCJSpZKCBEU0hHAPnXKSAQlkIxUKeLK9kJv807qFQtn59dZDg/RpqFUHSQKF4UI+s3WJ3dgeW8kT1BNCNSdRBgngZ0DN7CfMOo3JZeCKiGjIIR2LfRXzUtSSBsvwAhpdZRsZCtxWoC4y8sV+QqFCQuilnAbJHomI3thtOIKlt+bWLo1ZmjT78bsg1vo8H+HvhHf0AEAsIX/19yYgKaBhYEsH27/dnfMHmBFvxwxz7zh98G8zfYOIf6unf/zm/7o7GzX/1a4cwZW9NIlo319+/+3G/7IpFgvM1RjfHmgRtet2v90P3/6pPxdOrgd546/8oRVZa9cfmuzgc+86nOwYFEsuvBT33yiS/99Q1IgwDs2L1zx549Pn/gxJFXn//BM9VSCQOQSKU+8vFHbtq1c/imHZ/4zCe+/reXZwivsw/ef/dte/fRHHfu3Pmnn/7B8tISwigcCt//wH3333//3ltvGRsf+85TP3jjiTRFffB9dyXbujnRt7C09PePfWtmxtP3k/zS/tv2ffzhh/7g9z7PsNx3v/eDN15XMexkZjPFCBiAaq3+1cefGDk3aloWL3A7t2373Gd/4z/98R/quvbi4Wvi6HRb29Gzl5xq8Dc//imMoe3Ylm195fFvvfzqa5qmsSw70Nv3e7/52T/+vd/9X/+P/zw9PS2K4srKjXcq7+UImqBJDumkrt60vS8aEo2DP6ZEwh91/utDlWePkzXZusJx1jTtSsHnrWrk8EjJnaTrGo5DxgdvFaNDDE2f/jaQV2irTmlGoNjTR0KN8TlSO88lSSZGRDrCfIgjEwzVQU1pY8vsYpOTBUFQ7LKJGrpTwKDioLKNK6aR1628TVQ0sq6QVY73ZNh/TuN5vsiUs0xeZtUSUWsis+xqNWCuGhWGpphKgVNl3nFYy6SaNV5rMKqCCzmqUsD5HKvInFpnNIXV1DAnkElksyav+OqgKrb3axSbq+WqlQrEHATQyqnblB3xpzNGeX5rudc8cFAvFER7JwLsWjMVQQDKUil5Inn26JIjVtM9vE3oloENnx8Bl6Z5y1Y1w26w7ry5PL2wYJqejhRZFPWTu3syg+FAoCo3ACDDBPugdOsF+XTRvixa9t6PoEmC+swniM5O6ctfwbWKvmnI2DCIRJ68OMYsLzu7dgLssTHtfBVNzFzXgEhx7PBnfr1969aLjz5anhgPbhwMb1rHhgL1xaX8+dGOHdt5SZI4vlrI1+avFyhhOO59n3yoZ8P6Yz/+8fmDh5Ld7b3DG8KpWC1fOP/q0f4tWwKhYCoeX1hcKK1cLyPLC/yHH/5I//p1Z0+d/t7jjyeS0c3DG7t7O0zDeO3wK9FEIt3elkrExsfHy8XrYRTxWOTjD32kratrYWHxb7/85YDA7RjesG6gh4T4taPHCZJcv2H9YF/vCy++rL1hEm9jf89H77/HH42oqvr//I+/dg1tz/D6besHfDxz8sxIsVzZtnV4sK/n8JEjsnJ9i+1dN23Zv3cfHwjwPP+nf/EXi/MLu9cP7Nu6Ier3Tc/MjY6N37J711B/z49fOqibl+NfiqKi0Wg+l9u1buPunbtdggiHQl//1ncOHTmya7Bv/9aNfel4vlh47dSZrVu2rO/tOnL8BM1y7xQg6Y0R9NvnoMlM2ozEQ4yTwE3Ttsa/fVKvB5UaObZALxUJ20HxqETThE9k5abm5Rp+ikLzmzOBd/iU5QKTDXQyUlqvL9PS+uyJkupL1nfdweWXmxtuag7vbl+eufPOOzs7Oz/0oQ91dnZya6YoypvQb36bLRVMNTIrFM3yqmilQ6wQU1UFWclaaY6hRMLU+qXg4Hd2RdSwsBRbX+44aTynGn4aR1tNgQSALOBdYGNMUUpKLhfXbYqrsKJVbRvbwOOYSLreYLkuNtBn2ryquabSCPICNd7D5Hes39zZ0x4xbCQrhokamCrGqPSJxuFfEQdNDA3AX/818cmnXNeQt6yzfT6HYez2hLWuh7w4RtVksHsXtk3WHzAEDtxxOygXQf1y+q40AFdpAAAgAElEQVRn/239975v+eCh6uykf+cWJ+B3WIaMBmObB9XsavHC2MD+/Y7rhGNRrr0t1JZulgrOWkJZ9Et77r9n+LZ9SxNTZ154oe/mrVQyZnEcFZDaB7sJxzp75Nj2226HJJFIJTNDg3Kl0qheLjD2DfQ98smPd/f1qKrx1KOPbr1pQ6Qn4/Ac9IntXe1Rv3DwxweGt+8Ih8N9A/2BQHBhbq41csIyzIP33fP+++7u7OpEkPjqV7462JUc2jToCDzlE+Pp+IaezEsvHUy1ZToymc0bN5TL5ZXs5WfD+t6OTz380Lb1A+l0Op5q+6u//apIuLfv2YYFgfYJoWh4S3/nyNmzpoN2bB0O+P1TM3Py2ji4j2Pv3LProXvu3tDTGQ6HUm3t3/zu0+X8ysN33cKHJEoQvDRFX+f8/MzUwsq9d93lF8UjJ0+1vMeWdYMfvmv/cCa1e/PGSDicbs+8/Oprrx177ZHbdqbb4iTPB0KhgY4UT4AzY1P33nk7Qujs2MQ/t9Lgu9FBr118Ey+X6xOnmrU8qThAYTCC+Rq5VofAfV0JvyQIPFOpNt23GkXGyXwql3AEtSMN2NQdiAhKfCh7dMotK1Jumosi3BHzl6fI8szs0qWl3HShtvj8S9+fX5nIVxdlvUgJiP7n/KJY7BhvHgtJQVqgaTu25NJkQA9IaRqIPZZDBXm+WbjougRfM2pq6BWLLzOGS3aQijVMDruALNsmBRkCECwQAkSIBJSHVsB0uzF4++qHK6ElQypMn5TFAEAs4ZpaMtaHuJTr0IxeU5Wi30Dm0Z0RX/+mLZmuLgGQVG62sWrPl/RVjVppomLDur5l6j3ooD/4APiNT7PZLHHqhJLpwIoNSYZgBaazz5E1lwP8sVO+3butoOQPR7XZKbCuF3/sIVAqU+Xy3j/8t2037yZcd+Lb3yaGBmTVtTAkA2F/urOhu5hwm+Pj8c5uXzo+GE1cmBgduPeuxOYNhUsTHd1dj3zhd6KdGZ9PeuXJp7h0pOIyTQtxkag/1WFCVnMseWmeJtnu9YPtocjE4vR9v/aIC0FxYfnhTzx01313CpKUSKd+8O2nBD9dp30lxWLDsWRnH+CkbLXKIH1lMbtj985YOKzojQc+9MGlxUWGIv/jn3whEfWHQ6F4Inbo8KvlwjKTSK3IJiH4uwc3+MLJ8ZVckIVnR0bvuH1vPJHoTEV6ursvjU/evWfnn3z+t+XSak93TzQaHrk0cWHkZKanc7ZmuTTXu25TsqN3aiXvZ8njx0/fsufmTRs2bOnrsly3Wqn+u1//2CP331NYmB0aXJ+MR4qy8vi3v7VtQ89s3W46sH/D5kzv0HK5TkIwfulCV3fvbbfe0hkNz61k12Xa//ff/3w7R1Rz2U2bhwM+HtHsVx795vbuRMGEVQN39A71rN/UMFwTgdnxUUyy9959t6k0Ry5eekeGnt7ooH8pVuwvZKhcJQzZ5QO0GDRjkhaLXP2/EBLnLi2dv7R0YXzF23C/9UbQVTHy2nr3dJA7nYvVg/KJEcfwBlSwg3DN8B84wI+chy4bkhIQsSsLRYEJWhqwVOzohGv8018SH2ZJH0v4/HyERBxP+1tH/EIE2DRwoGsS2KKwRQGbhg4DbBpZJIV5ZJEE8qRRfx7ZC4ryZs2voDU9zjVkEmz7UnUlf1bBehMgUFqeIGzVRwul5ROujUFFJiEaQ6ljQ12P7oz89d6Zr69/NcsUt0pDCHthEQaYYIlMJpVKJClIUpDWEGC0YPcrHxOMKHZx5VITKQ0SwvrqBGHryGjqtTlCNs0S1AuSvYThOAgoIJwXaUxiJATE5HBb25/t/bcdvgR4bxtFgm3DQBC4V49akt+7nZ5urbeAk9t3MXfdZ4sxi8DcyVOU6IcsG+jqEiUJRGPM7i1iVyY6tI7khdK5Cyjg1z22K4YAEhS1tbf/njvfZ4gRSxBmDx5keclYS5VSDJMaGGrbedPQru0uwjQvFhaX63KjSfocjxyIOFHsSbftv/kWRwiBcPTCiWMEwfDBUHsqLfqkW+6/t7Ov57b9+wuFIi9KmmYtzc+ojGS6XjGNY7muTGbftu2QlwwhODV2sanqJMf7A4FUKnXLbXt3bhtOJpLFUoUVfC7BnDlzmvCHZAsg5DEN+nt69920k2Z4hRJzuZXJ2QVR8rsI771l903DWx68Yx9JMTVZoVmeC0aOnTjBSL6SSaA1SfXOjs6bd+yS/MEGZimaPHryNM1ysVjsw/fcvWtj366tW0rFEiY8dK0QiR89fUYU2IJBOQhTJBlPJDcN39SWycgW4ETpxUOHKYreObyZZ+h7b94cCQRWV7L+YJCmaS4cG7k0bupK0aIM1xv1jMTjfRs29wwMmi4IBCOvnTiOIfzE/e8Tuddd5Dtrb2ObXUN2ihXY2weFNoJRaW/a+vV4Z/PmzS1wVDwebzabo6Ojby3P1yMSk4DmhWhob4bnYEkK1BLT9ncMIGMXWspPdhIMhX1cxBfxdCgop5T1JAd/vp+PmWCAJDxJ2XAgrFTng8EETdMmaeZyOdME627VczOcVvX0vaLRaGdnp2EYy8vLg4OD1Wq1pSHN8/zIyMjPLh/39fUxDNNSFfGqGRP5Lf495+WjrF+rlx3fpArTuK41G5e+6z30DESqANYhyIRWlcxafAwsirzQ7yvClz69uA3CNdwiZimWDnO+GBM0FMMwzbKz5CLcb24sTu4dWl8cOVZnpxSxk664tcbY97GLRA0nuBBPdhYEMZufOz/ulzWpkNNLsMjE/dl/1Zc5cKw33fe7Oz71xwf/HLyHDWFQbxCqSszNWn39rfyyB5PRtMXzZ6HAA5a3OJ95/jx9332OYfiH1iuNio6QbRugWDKaKu2X8iMjDi94Th0B7GJbN87OzpKiACB0fIGlkZEdmlY2zXVdfbPY9rY4JAkQDkajmGFHnn3OpVkSEl49HWHbdqbm5larNdsyXc6Xn5woZVeMSKS3o9ulKa1ebdRquq4n0+0ky4yOjDiQcEnG48Ug5Nj2xMx0NVIzNM2l2KZujF+8uG3Hjs6OHoIklxbm1XLNw9in2wiKmp+frzfkWCJJekRZbJrWSm61VK4oquLh5lj+xPHjQ4MDPX2D1VLpwqWxO7cPrxOEZDzpuG5TUaZnZuKdHR7EDmNdN+r1+qXJ8YYse3JTLH/85Mn37b8j1dH15DPPqapGURTLcm3pdtd1HReNnB8leQkSnvadaVrFQmFpYTaXyzmuwwjSydOnG/W6PxJXNM1CkEIOzbDpSNTQNAzhsTNnAMVg0tNVMW17cX4+09m5MDOjqQrJckuz86VyubCSbV7FeHpn7W3tg0bZnBoLuwyI0rbHk4raBAk+tdvzRyx32lqrCnqdGxGwt9Nb6AsF8pnj1whqvGmDGBIICkGe5zmW4uJCoqMrLlx6rlJpDLW7lSbX0C6H7YXC6/pANE0TECMMEyGnWIOmdeOWo1DKimas+bN5D78AQIvwfXUhmKKohfOCqXpcRgDA6upqLpdruf5yufwLNatMTFzTpAUBfK36vIWMjl7fULt75EfVYEHmhl3L9LwEaiJUo+96cNMTMxkd+b0TWA4YOkCw2Lfu69UftG26OT4HCAe270lkNobSNM+cQseOjlEke8I9eTp/DCRm+jb59seoA98rVJet3pv9AuSaskI1uY33RnApWoKE6uhL0YqRYCrNgpG36iHA90YvdtzT/NIXD0y8rs38HjUManUwN4toClNrnya8poHoInB2ZI2HjZDPp9Vr3NJCfWE2fvNeU6kjw8CHT9uVenFigg1IptLAfv8aNQNj13U0LTs5gWwbOw4h8C5JLI+er2nKR/beMb2y0CgUZl88IMdi3RvW1ZsNuVykpcuiXwhhvSk3SmW8sGCqGmRoSJHzE+M2x9y765ZFuXbge8/mlrM/+v4PP/DRD8/NzhYWF8RgAK5xNzCAqqaaq1Z2aVn3ADiYE4WpC6Oe9PWGTeOTE6dPjKjN5nJ2NRaLz85ON2WFZem1vYIH7jBNY3lludGQdVVFCPGisDQ7c+Hs6Zu23/yNRx+vVGuvnh7Zd8uejo6OmZlJdjUbC/jIy7cLO5a9msvWJ8Yb9TpyXV4QtFp1/PzZTO/AMy8dqFar89l8RyrBCeLY6DnbRUjX+FCoBTexHbtUzOu6tibIgmiaopBz/tSJcFtGt5zzsysfvYf0BfzRZNvkubMOcsx61cdzLV6J4zjlUmluaqJQKuqqtiZtLC1OjCPinZHSvqG9vS9F0djOWJCq+2OCW7YkRaYY8PE9ViKEIpIdD6IrX4mQ92U58OTENWpGb9oYBwYdljIJynRYm2yjo9H2zI/PvRBfnxch7IwCSUASj6MBtyPmkiRIBN2whPwCbougkkzRaypWP61p39IJtUZZhkcWdV2XoUkPwQi9tnzbdlrVTsciSJLu6OhocUo9jTWMWZYNh8MIoV+mN97FXrdpxyZW6sKCSEtU2N9p3L1n26auTaVKvn2AIWLBl+eGXIIGggjCYY8piL10l5lqNz9zL91wkgt0W3u8JxGLcxRjscoCyKmlilbmAZFfUeyKKyTtUB/Zvdm/dbjtzptuD0dJLDQ3rI+fmkmfLUq04/huTyg5w76JmeHMlQwCemXl5JGNq8bF0mT5bUlDv3M5aAhiYdDd4Wzc7K6ueuxw6IW4HgjJMgFNA55DpmE9+ACslhS1aU1MqgtL5N9+DV0cB65rG4Y/k+y5+Zbs8jLBMi1pYwCgo+vYtrlIxKlVd330o0qzJhv6xNmzsyfPnPuHJ/RqrVmv55aXwqnYLbfvL8my7nXReW6HoGhTURzT5P2SJTf333knx1LlRu3C2fMvPfX980eOeuKfs/PZ7EosHhrq68cMUzPMtYsCkqIs3dS8oUcKAjA8OLhxoLcq1w6+fPDxv/9mIV9wHPfM2fOmZYgsFQ8Eu/sHF0slck03weMuYVAplVzHYTg2wLIffd/djVr5sW9/98nvPeNJUK7mx2fmTF2jgSuS5F1333N2YpLm2MuSaTRTLBZ1TaMZGtvmpz/4gVox99hT3z89etFF6MjIORehUm6VgYh27Tv33zm1tAhpZo0TjGmKbjabtVrNI0QD9Mh991OW/r3nni9rxrnxiZePHUv4/cuLSx6pxrb27txZaCo2xiTpPVq8OwZgvaloShMDdNPGTWmRm5qcfPXCGHgn7B2eJAxxOGDOw2jQrirY1KurnvP9rS9ddsEdbZFQUIQQXppYsX96e/ybM4ZlGVZUGypZb7C0WAaFUrlQLzeQy1AcNCVo2h5rgqPXSGHY07TUTRiWkGkDAmJv+f30GBe50FBff9Rt29xFU6RpOUvZcjZ3ZTDXI5MxDJNKpWRZDoVCDMNgjCVJ8sDHV4HV35xFfEIsRBUElw6TgQRTUSoCY8bauEpdh0rYQSRwXZZh2K6MXSjpKwYgIDKhk4jNP4SjZyeap03bdX1baWaOMBzVxGoHjFVgIakOw2O1vunU8YGns/2lcLQ2557N12uXLtpTo+SlRdeJQL2/Q9idWffphM1RxJF5dGaisVzWpxYdh1jU3+3dL7+sYQwSKdzR5eGNz5y9jPzzYH5eQAssy8tZEITb229ll1Fnt1KtwaaMH/9ua4ontX5dvLc/FonxZ895yQvoRdDIsoFjAUi4hg4wjmcycsMXFnhVVqdeOdbMXe6k5jmhq6cv1tZOkSMQ2GvIXGTpOlqTWke2gxw7mkwKLBNuz8xNzVw4enk3gzHOdHRs2LjZJ0grjSaoN9YOI1M3MEaeh2U95fVgJBxv7ww6lto0Vn/SiVGp1hLx5OYtwyzD5aq1NVKeF0I7ti03GqZpQACR63Ic179pc6CweuTU+da4iu04x86cvf3mnTuHNzsuCieTl6Nv6GEeqtWqqnmhNwkwRVFtXT2CTwKnRlsXrcvNo+dGv/hHX+A4TjeMaKaTomi8tu3EGMtNBWHXtm2SopCLku3tptq0IUlRlK7rS9lCezKVjMdC4XC90Yj39tPnLhiaCtfkFk3LKldrmuElNDBCnV1dEkO2qe+iFv63y0FDsPkTN294ZNexcyOABFB3yOr1s6eVmuIB3l3kvNXeec0wdLxVAhF2kJVdXlKadeygRoHmo2y2CjH0ErstBnGLVLd2VsvtusXaP01uEgShde7xM7OtCh72HtSeURQV7yuXV9jZ2dnrEilv1cj/7KUKRao012toEFeUfUOMbmjHzcAEcfPScT+WWIhtjqa5eIQWBY+2gxEyVFytoFRo7uH2wP+cOTNGq9XofGl1xlzgIrzRhH6tTXc40hW21PcG5oWn9S/rscaOX9OfeilUlz6/eqEAfRFg6JZrr9SdNo7kKGBACigNxxfuEkVIN0g/BWrvmAbY22R+P0ikPPIRRXr+GhJeZEZAr7PcsoCBCIZBHKd29QLXASSNBdGJRMBax1vhwqWtn/g4S1GeBAxaOwsSXlxH0hACq9aANEPQtJBuJwmC8QXat23Lnh5pXRZCOLhxC7IsT2VK1bzwEZIYI7gW/xpNxevOpqlgPElSJESe/siVz5VjOz09/ZZpchzXimG9Eo03zkUAknJs212bGvMHgp42lXMNjoPjuK7OHtM0mqbl4U89Zj9BECTy1CpohFzTtMKJmOu68ViKZa5JUba3tafbOxr1msDxBEki5F2RpEjHdiiScrEHefILAk1RmUwHRV1WQQMA3H3Lze3tGS9Q8pLULElRputFwaSXiUYAeXl5x3EwAKIkJSORVLrt8OmznqJ8e1t7MhWJx8RAMBSJETxHUp6OAfbquxRFkJAkXS+56j0ZfYHAQHvbDw+9Bn7VHPSmR/bs+/z7Z2amIUVsLUV7T7jZKlVn1MzOQk0zGjUci9O2E7g0rbgpAQ95UlgePg1hAuN2ULMBZXsYWlqMZCC2KcIxlEXX4QEmsKuLGAkcoFnStYmL561GBa3/yB6Ko0mKnpq4BBmKdEGiFgMywCLL79/gKI7t96svFwDpDOxUnVpCsMVEIlGpVBYWFt60AEo4HE4kEoZhOI5jmmZLbaCV31haWmpWKUt7ywYj32gjhytHzvsD//53N4SP4+J5zc4bLjvl/3RhlQZIJh2L8YuZ3vZ4RESZyBRwKqOTFEXS4+ec0Wl0yVCJdZUB86JfqVZN2/HSIRRrMYqfJJkmNnVkby3fWfeN+7mXxi4as/XeesklRT/BkDQj2arSOD1yDlg0SzYuzLIc4+jNzXSwYC7RLAPAOy9L8c9r3/gmmJnGD30Men7Wg3H7fEGCopRa2fHgtBg5ADSb4Px58ugJNxYGd98NhjeDtWnmytz8gT/9b7f+5r/hBaGpevEyzYmsz6fXq65leB7fdQzTzE5Nzx8+HN+00Z+MX7ns4uTU3/6f/+VDv/HpYDCwUvMiCJJiBH/YUFVTbaw5Vtdx3MW5uWMvvbRueMvVL/mVA4c0Xf3Iww8H/NLlvSGEjBTCrqvWyiRJeJOHGOQL+Reee/7oK9c4rL//h8fn5+YevO8ekln7nK7tIgheIjlWr5S8Dy1CDE3LjcbffPkrr564hmiYW139s0OH7rp9Xx/DeLUd6MXPgOZIKajXa65jeKIqDNNsNr/49W8cOnr8yomui86ePffswUP33LZ307abLouqeA8HkvCFTF2zNJUgSZamdKX5pa99Y67aaM0uhAMBv0989vnn51bzN2/desu+vS11GK9SgAEr+BEr6GaOgNgTb3ScP/mv/+3ZNwA93vsOOtabshtGIZ/vbvo+W9k+Sy7UXctvspv9Trb7AqZQR6dvltg3dWpZDXjvG0kR0ItHEIGwaJWJWt0UMCv0somAa5RCsf7SxFkb8RAQogHzsp8O++aXeSsvmwYMue18bwqIdqgjrVNzpMTRtAgWU+CVlVhIcBCpT60yuwOAdXxk4I6d98slGiFvf5jpaN+ydXjt9a4VTlqc9Ct/AXh6dmZkZKRWq7X8rCAIXgACAMMjX9iJc/MRMAvWIgYsgmPjXIvx3wqlKyutTI7n/TmO7utKrMldw9GxpbdEgNFFWNu2UdLcXHRdYlk4c7GpQSlXZvXTYyiaBpAkJR8hiSTL0jwd7UrLDc0sFrWL8ySCqJQjBgeNtKMtF+AOZD9j8pDsjAV72zaOjs5pRHMJrsyBMctge9pJw42Vc0mkF1mKxaQgCFS1apEuBJ7sEHANgwaYJqxYvXpUz9fynuDVe9xUFbxwgGQp4BPX4lSKZUkX2JLfX2/WPUqrY+NXD7mlGl7XD7JZgFyweJkr72j68qvHT/lFLh71PouIYL0SlilI/mbNhABhiMZOvNbUbb4tSYlCbWzyymUNVRs/cSrd34XItfAXQFYQALRZnnVtBiOHpImLF8/agPInolrTA81cOVfX9LELlzZsGVcNDVLe+mYE0YuwCcjwgmPpgASLS7N1ueH3S+q1E32WbXd3dUzMzTnIwoSnrU3RLMWSAFiMKNqqDEhcrpROnj45NjlZrV2zABiG6W1PTc7PLxeyiPC4zt7ZIo+AQQsCsnQMkaarx44eOXT8ZPly7sUz23FEjhvu6xlfmK8pddM1KY6HLmT9fgQNgqUJigIQAdc58OLzPzp6IpFItLazDnIJkoz7uZDYM5tbNQ+8VJerBMtBDCjJTzDAhZigGexaFM+88MLzT790wFPd+1Vz0NnTo4OS4RjK7+kf7vGnDjVOeT28LFuY2IOEthwxUk72+gY3WbM5gGzvTeN5giIw4Xm3ai2Y1FYRw/N6LhR7AJJsc/GU20AOb9edocP69hoTBioEARSoLQxorgiGLr7yQy4jhFanIUMCDEPBkNzVI5pu+GzeCfO+928HjQYjN4KpwOce+QJgAKKADYHtuU8CAAZgGjgEsAG0AQ0ADTDlhULWN7/7+MjIiCzLrfeeoqiWg2YFxEtofRvuS79Ohzk/z5vO64np1sej5axdB9VlzXGQV0i8yju3+qDfdJTtnB9lNnwg37/xgvOvDz8/iqNJi7dArA0QFFRVRQssyqbiIBbAGklh03CVphNK8KXlKOqKMDadYXSMRV7lgEFq5vC2LXEyspjNlWr8CHneD8gJ+3hn1bplD/sZZ+a/HxguXzoldG016RRynUhKsqoyJAifhM2SHYQmbctjuRvDfd6TZr94GGzfAtvag0G2o7szKoGVqoPnxhoNE5gunp5nacJpFgAhApYH1wJ9Vk6die29GVMcK1Lx7kwiRJRkilzQaiUVuXBxZpFjIEuTgdhNs5M/uvpEyzAvvPpacHAI0wzDk6GORDwmaSZdXp6srlQwIqaX8iGRTsfi9XzhOhxHo9qYGrtg8n5EUiQNA+3hWDqNMSxllyuzK8AFC8V6UtNTkUSjfo2TVTWtXKnRNFhVTOyFwEBKByMd/TRpV0u18oSMLFyyFLc5PjN/zQLAGB85debBW3dcmJ6az3t1aoCAkBSDXX0+n1urmDW9ZmqOBeGR40dL13r2gydPP3DrnoZcNlx4oSbbEFIuZIOc1NMdjoBGg/AoZHXdMu3HDryaTqev9FCNTk4X5aZqIVWu2pY9MSvrLvJRkBIpqbsjGvdrGma1klYwCOT+3fd++K7yzm+fg74nEns43La4MPPywRdx/9amqxMsHdzcE0yJpNmeFLaubvHpTUP3Ct8ESfCBQIfjWoZTDQjR7KF6MCA5OYVNWfNn/ifF+ox6yWjAArFu0tjnIgrQgLRRamI5ekEWnN2eK523pQ3Coip7sg08a2NM8Ir2SHcNcvLjBxhJsGrNSKuMo3rrAFPAAkABwPIcsugtHYcAKiB0IGLPZ1Ne5GsA3cubBwKBlg+9UmxtVqhmhfzmxOUxk7ZUiCQITFg858jN1xsqU6lUOp0uFovRaFSWZR9Ny7Lc1iZyHEcQhGmaoihijC3LYll2cnLyF+0Ex4sFIldSCs9BaOGBDZjlYb5EshxJ0z6WrpVLOkc3QiKj+uXZJWJmVgwEDILgcShSZ8sX5Wi6QopU+bkSRHYPjA7ZfU6ZSKrJaX2ewPGuXctOf3U+a6svaBP5VUDeChDS5s+TfQx2eafe6B7IIAdNT8nAUQdcMtM3oM0+C351zDDh+CyVSKma1SiXSASQwZgWhrYNKYblWWA2vSnB4a3o8Cu4dg3T2SjV1fllYWDQsZBcLHGQQiaray5wXIKkaZ4jHYXzR81ydeXsNeImnpzKYs7f3kFGBAITarnWZCzkMkbTwo4XzTMCTxM4GIgcfOJ7153oOM7MxNzwXfuLTZXAUK8omugBKIyG5qlqYcBJYmdb+rUDN9jvHzt55qEP3VcDFVMzCQg9zxgsOSQyqgp2EAAwHo/Pjngp4Ovs6Okz79+/LxIMNXWLMTxdNFuxXa2mubZVtV0LAQxd2zozNtcSJr1i88srozNzsXi7llskpAClm54gt+ECvanWTatKOqqFMVhcLSyXagPh+JV+Hs0wnj5w6IM37zhz5riLXSCFeNN0XeTaGOuao0G9otsNHQJ4aX5V/omuyq+cg548t3iYcBON5lwecS62LOQLCULUL0SEoBEbo6aPP/5Sans39MRXyWSsLxSkMZVW3I6Vx85kzQE90HOT8MLqeJlvr+m0UlYy1SyXpfe4XseiB6rbNY2IsSK2t7ai0Hh9B8lVRM4xXQwUR6ar2Uog3N7u/73bnczpygtnfKpRA6brhoBS9yJmDCzoOWjNy1BQAAheOK0BUgYEaiUt3DUCnfeuBwKBG/2Krw8BsgzdmvWzvcX6k4MCqtXLht50XNhsNh3H8b7Btlvq8a3eu1bW7EqB8Re+y80m/N53297fs8B2UZkuc+ycxAJM+21vggG4loVrspMrOk3NXCwAG/sh5LEFKzkCMbourTzz/5H33lFyXeed4H051nuVU+cc0QCISAIgmESJoizJEq0wipbDeu2xfXxGHs/u8fF6fdaesY+965Wt2bXCWBItUpGSmUWCJEDkDDTQOVZ1V1cOr+rlcO+e1wVbXTgAACAASURBVA2RIAnKWo+GlKnfHzzgw7morlevv/rud39hBQDEoAaN2x3OAWvDM4v6hpUzgno8gKc+fq1R1fMZ16p5U4sUHAmEujvKV68YGzN4sK++Lqi1Kc91CdgISdzdNZFieai/1amMby9QrcaUKyDYl1nJ1msh27LMpkaTVFAO6IZuWhYY2+7F4uCv/s83UoLq12aFdJpJJCuZjN6KuY5t1hoUw/GS6JkaK0jdO3ed+dsvem8QMdmGuXrxyrYPPggxsrmRt/QIgtCo1wiSEoIyYeqDwyOzpy6UfkzDuBmFfLlNki2ccBxXr9byNgQYZtUrGI7LkVAYQ5qinjtzCyb74vJKS7NSAREyLHQ91Y/18QWQZq2CYXgoGupPpp5ZvoWVnarpL5658L7DB0rXruIhyTVtVzPKyxskw5iVMoZjoZD00lPPVJXXW2FACH/4wkt//nu/ZVv6qqqR0RA0bb3Zqq6u07xgVYoYjluuc/n6jCTLivLqbAQA8PjR4x9+173Dg2NXpidNzCNDsqUarmG2ckXcjlcyKzRFVFRtee3nxcHuZrxFUm+CxJs1zVWdYJIN4QGA4Y5iq9fWGlN1YcNp5ZV8cePqqbM+0Y2hhUAwHIgDOrbcGC4Pv9sIptedvlPUx5loqo0niZ575+//i1z3vR6+2cCS5I71yGeKe3eSHyQQ7x8uAipuTRA2hSia5QWcIeyqUq8u5zJXrqyevNRftu9P7RztRRju00W0BnAaCDUs0GiBRgO0GsBsINhwQUMDSgMYDeA1AGh4oGG80kEHN3EzXfEVhMNhD3C2xyCcl2Rfkbh1vfc2rbNT/fQ9vs+sYRiO49i2vSnggq7rbiXkqptotVrNZvNfN+jATTOZPxOpzGOxJB4Mak3FdZoC41MCMIBSSSlCophnhaEOLYtnCIg5ULOmtVMisiK0I5Oq4ZS0lnu9vPJ0Zv7xyrUFbYVgSSJih7tV3P8cvWAI49u7xN5BdvTd8QP32KWitXwes1uUq6FWWWRcaWxbSXSAM/Fg52+CXyggpJ48Y84ueLoOOYIICVxAtGxbtyzPMdz2djAwBP7mb0H1FtRD5Lrlsxf1QtFnFAgUIfFUIODYtmtZmGV279w9+4MnNq5dv+XLGo2mld0QWNYnKYk0JnE4y3quCzWtMx7DbPjyk0/fcqFtWc898cyewX5oW6ZtYxKLBRhEUQChBE/v2TbxyNe/+WbbuEe+8/2h7t4US1m64eIYLvOYwLgYzhDEnt6+F144Wizd2oT6ieePlFvqeHc3bZmWbpgIEEER8LQDUCIc8lra6vqteU2Xp2f+/lvf37//jgD0PN3QW6rLMGQ4AHjKcN1qrf7kU881NT2ZTL6OGVVtNH77//gvXCQ22NNH6Bq0bT87nGHYeNijMNt11gvFC1evva6s/2IJVRTd3dkVdmmKozBocJgcsDQddxyrpYOmZtS1TKwJO3lbdxCFYwTQMW+11a7JfepSxjNsgGERoj4oXhZHBp7lP2EmetypGYCTAMOiSPrE+fQY33e2Mt2EfpI2wZHRRMLgi1akQVKcZZsEw8e6J3gpYRstq1p7MBO7a2g/rRobuPrB28eAaHqi2cDNEjAb/iBDMFHAbFFmFTgVwBsgYALWtIBZnVyZPLU4F4/HfT0iy24V2c33t5lR7tOjfMb+ll2GZVmO45imuVVq6xt0rUpcXSRN20MIMjRB+HIWZFr2lrzlv/MOq6qqaVpCSE8tFTEpYo/tdBcWkdmAuWUQDHmIdjyzvT/lk609SOOGUmpSXstB8NC5yBgaHJFGH7zz0HBPj1FwOFbk39fu9mJgiCrOr1Ay3bMnB6NXl7MEQxHtAZbAPlUfnGA62q2GgQsxLtndPjHxrvv2txDhsEJHb9w89XVcT+xtu+tK4ZRiVX8hDPtJEh8dB/2DeO8gffe9Yt+A6+JyJGyUc65hgrZ214HgG4+A2VdP+W6GGI9HeofCieTgve9KDY4QOBNsS2rrqzSGhTo7146+vPjisVt6OvuvTFGCIHf39g3uvK17YDQkRUJtCbtQaIuEC4vLL33/n/U3pBG+gnqtxhD09vFt6e6uoaGJtlgqFJFEG4ZZ9vuPfHf9zZtKwzSnZ+fHenuS4WjHUP9g/3hPqqMtGuqS5JW5+R8++fSbdRgQonNXrsZDwQTH+SEH+/a0JzqHOvv6020iQidPXajWqq5366iH5bW1QrU2mEpCTYee03vwYEwIjw2NDiXbSvmKyHI+uZEktqS8N0NR1TOT1wbTyQQnlKtVicLTt+2OybGurp6x9m4ICY4XcA+Wa9WfuU3bvw2hSmroQx65RnOWYSgY7mEkDgmc3t7DS4HKcpWuow4xvoJrvEibrVYTVFQsVo/3YwyDdJ0iCAQwi+257Lyr4t6udI8Shul7IOA4iWE7tOQo1YFwzwZwS85ECjTLsPHs3mZ8xY76c65grNvWTde2OSakN5bEMipuWIvupE1xmx20z9SwNmfQis/a8EmR/ohDA4wCDA+4r444bnTQBOF/sak/fu7luBtMOLkZCcMw27Zvfj7wTUAIt5IptmZcHEvftq0bYGCjUF9a/VlmU+IYYZm6W2+QyIWOh4UT7uSsxc+AtglAEPVcZXBsCEB0+bpKQFsrrTFiN1Aaa1ghaibnJqdNGzZgCbAWSo6Uj1el3RIrYdCwdGZuflEFGAdwSinEdqzflWWWqh20qFZttWLhoNmsXZyfcprV+OKxrpxDEo2pxpez9mDDeqcLVbZAkuSHP45//FNuNApp0sawKgJ4qlddWILBPFALbm4VnJsEq7eud7GRsQO/94fx4RGGZUjCn451dww2KlVacTNXjmfPnNk4dubHqfGvRyAcve+jn7zjgfcFQiGG9lcjgBmGucGnrl05cfXU+Wb59dXqZoxu2/H+hz6d6uzkeJ6mSN+CxnWUAWVuarJU/hc+O0VpBSMdBw7dTbMcx7MEjgNswjKM4YH83GLm2Ik3NZttttRvPv7sf/z1z334vnfJ0QTPsSRNYpjvCHLnwXc/+8Kzf/m3f/1GI2mwSbZ79vgprVbZPdB3+I57R4d2syxLswzRSxzcc8hz7LXCxle+/pX5+fk33q1MvvCVJ3/0K/u2RygmEe/c1b+doNmIFKQYau/OfQ1NpTD8mWPP/9lf/5XyNnmNvm0dNM0I/+5X/z7GtRwz1zLMMJ1yTA9wFDvYbRdVulvS5taLTkXtwhBBWpbFRKLmeqv+nVO0rXq1FiKYcEzqH+gUu3cWT190r09yFAB1BZBUMhGlc0uzl0+StDOrlxDGsnEmfai9bTQQkRP2aqUkrgAai0ejgtxLUwEBN2Pri5+qVj1aPQWWPDf04YkeEDHdoFnGzXVgVgFhgqCJImadNvPAK4CgDiImEE0NmIXJjWuncqsDAwNbBDtFUbZ8Yz0Hgy5mav4T9mbAScRzwlZMDEUx2Vx1baNWV/SfFTPa1O2WqXeOHzBZnQgGiMqGJwiQ5AhCcTMlnMYgF1Ab1vp6ObOSt+pV3KhI8RCbGN91DqdsnkHlBwIsh9zJsiNpOLkjIuwNg6YGTlexQDH8PkExGp5tywyF19Ix9XCkdWav9vhOazkqMLN4N/AWBu4SkitT76XrQca1LEek4a/cP1BrVKbXf1KBeCd00BQNPvPr2Mc+CUSOWVli1jIkSRKyDFgWCCLF8F5LRcePg+Vbc1ra9x049Pk/jvT2UtBtzM+q62ucIAiBACcKtBjEMWL1xFmreut7SLPch3/vj2676z45JJvNxvrcTKtWk+VgQBQDoVBQDNeV5vrC7JupYLt6+n//j/63ZGenIAj1SnF5fs4yDDkYlIPBeDLV0d4xefWKod9a4BoQA7/2md+48/B9vBQgSDyTWV1ZXvKgF43GQpHI3t27c+trK6srt1yL4/hdew988IMfDUXjgii40FtYWsxkV/2gu0hkbHQ0Gg6fu3jefhPzA4Jg3nvvgzv23MEyLMOxqqZdm5laz68HQyE+IB6640Axtz63vPzGhYpuFBrK4Z37dxy+X+BEimV4nq82atPzsy1DS0Rj27dtb08kTpw7Y70deVdvWwfd03/7M//85R3dbBehRQWSikWZs6sSwVEhEXQkwNQcBk2OQAxOeQCj2EAw0l/MzkPL1nN118EQjUsyR7E0IYqgUIKC4Jy54IYSBImLEksc6Gek3rPfX9RdmiMIXmZYlmEoOsZHdqc/+ZfrU6Uus1zMRDGRIKns2vV7KYIa5y9cyfinehD6h4T2jQ66BUAD0H4HjeDWISHXAIa7SV1+bQe9Jc5+5T66Nq6U/RnHVrXt7YqHZAEn8PWNar54gy00uEfD9JipiMFg0HV9gw7XdVut1s9KSRjpGjPvups1A+roAUuOARIHJOXvM/bcgwtXvStzWLiIusc8SwMI4UpR7E7AiTskcuCQlT7iHTVBbU7J513Oc2QFMsaX5ymJgYoeIUz2rroVEEQtWG9UacxNwJAQ/VY1f5YQuP27R0Yhmb2WnzOyS88u7anabTt3UhSpnDmLAFIN4z/92vuKhnP86i0i5t4hwDD8gV9C7/sgszjHff9b+HrGr4a8gO0/6Hz21yyaRK7D9Y9rgdMArL5xtZhqG/nQRwORcPbYC8tP/7NRLgGEGFkeee8Htj30EZYm4u2d297zvpPLC+gN+X4Yhu+4+76ewUGSwF78zjevvvS8oakAw2Lptrs/9LGddx4mCOIDD/1Kdm5mfXbqjS8dikQ//tnfYHnWNPTvfv1LVy6ctf0cTry9s/sz/9PvdvX0DgwO/srHP/HlL37Be8PAAcPw++6+f3hohBXYtWzm0Ue/Pj8340GPpuix8Ynf+M3fETjhj/7jH20UCjOztzC16EimP/Hhj1muTbPMxcsXHv3eo2vZDERIFMUDtx/87Cd/9YF3P+C57p//9V/ZzusLJUPRDx66u62rr6mqLMc99aOnv/349xt1v9lPpdIfeN8HHrjn/s9//g/nM5mpuVtlPwZiw7tuLxZLrCAyrvvfHvn6j44ecVwnFA6TGPHZj33ynkOH/zOAf/Cnf/JmXw/vwA5aqec4IWXiA3FvhiUcmyKYEq4aamOxYKwWyrOr+UDWGp5RMdkGSOBpOTyEWMZteGp8wNUMhOO2R7g4Xqd4RxIstelIUdBSIcN5GAUlwezsjF5xDc0BGEQtGpgYrjBttXCfIJdX9RntjMu4tWaxXs2OIuN+1o32By9lS4brOob04f4oSFlOzMoR1gqwyoA2QcJCKavMWqvAWwNxA6QsIFtNYGUma9dP1Qq7d+/e6qALhcIbo3EwDNN1u6Wa5WrTsFzHufFwmy2qvGE2Gs1isVgul6ub0HX9FWfnV8gbW7yOmy/+NDeZa9HhoolGdmSkrYNfDFAk8DxkWSgUx8UgzoqBocEDt+8OBIRqS0f9Q2jH7v6nJ997MU1ihOBKuq1eMlYWvXke0MAjoaGTXtPYM9X977Yh6FjLp3HL5qEXw+TebfLM0srwUFeurl+cWn7PgKAuLvQZdrsgTOzb39nfZ2otpVG3TStfU89OZ/K11ju2g27vxD/9OarREL/0d67AW6Pjdt8ApEji6iWqUoG79gAM8dBXJROGDuWgLymEN0bJGEEMPviB3gMH85cvTD/6dS6ZDI6NC51dCMPWTx/HKbpj5y61VOgbHMwsLfOSbCgNX3e3CRzHw8nUwfd/qHNg6OUffmfy6JFU30DHyFgk3a4qjakzJ0LJdPfQMHJMPiDpumGorVfcuDAMi0Rjh+55z/DYWCSe/Kcv/9381OTwyFj/0EgsFq+UClcunhsa2yYH5a50Ml8s1aoV56aOkmPZiW3b33PvA6mOtGk7X/jbv1SV+sTo+PjwaDQcWVycu359cu/+OwB0E4nE7OxsS33102cZZsfY9rv23J5IJLp6+xcXF774D19gCWLX6Pi2wSGBZa9MXi5VKrft2JVO+Wtz+Y1XtpgkQQz29o90dL//XQ+4OOzr7T924uUvf+PLXfH4/rFtI929oWDw6PGjru1uH9vWmUo8f/ToK6RmkiDaE6neZOo9e2/v7unjAoIgBb73w+8//fzTox2d+yd2dMcStq4eOX60q71r/549c4sLS5lbfKG+MxNVIPQIipY6D93eqTVrebeh7QnuW6vnTK2lq8osvUruWmVkw6EkXUNkgAEQBENhA9otXeJpGvM82zAciFku8qJxR2+SABN4zvUv+qPsaoDCK16g6pI8bvm2gYRnAqSgmbXcsq5rQkFTirRA8Dhpv5xpTBWRa66UNIBjjhb4cJcI2k07aWYJcwGYRcAaIGWidrPAmcsAroKUBtr9qUcTmMuTyvSpZvngwYOiKHIct7a2drM36RaGh4cHBgZdD4VCkd7evlKp5Hm+SfRACotKIBYEqklhOLE1mB7uBPEQCAcw2yWQ/xQRCKGhDv9zGun0DIf04I2L/7ITSKsHtsy0kF4Nei7h86UAvfkx+ww7j6AcSpaxtm7S8/SAbFSWAYGHk4o3/0Xdrd9Xf1cadqqOUHN1AQTjVPKewT179g4phbIotGrOE/XsBcqwI4I0OMCKptTe0WXqBiKIx56/kJLY60sZw7IDFJVoDw/tvCOY7PCgUVhZWc9Xytni+aV8y3bfmQW6qxv/1K/h6XTg4S8bnR3qjt1uMOQEg05vjzM0TJ4+SSCE7d7nWiYfjrQ0E33iM2DvXpDNglqVi0QnPvrJnrvfbdcqM9/5RmjHbdzIOArIeDgcHOgXo9HFZ56M9fRG+wcJgsQwkLjj8PB7HqitrliNOiuID3ziM3d9+GPxzq75S+euH39x5NBhsasbl2Q2GuseGWFp8vwLz4/v3suKUldbGgtG7/3lh1qtVnF1BSeID33k4w99/NNdvYPJtrbnnnxsbWl2/133yOl2Wg4GE4nh0RHPMk6feHnfgcM0w3T39t1+5z26pq9lVmiaPrD/wO/9z787PjIejScCodA/fvX/4Uns0ME7pUSSk4ORZGLb0PDSwuxKZvX2A3d2tqV3bNsRkkOz87Ou6+4em/jf/8N/2j440tneFY5EII791y/9XW8qcfeBg2IoEghF2traxnp7z188p1v29vHt+/fsTYWjCytLmq7ftWf/H37ut37pzrvjcrCrsyeeTGZy6199+CuHJyYO7NojBsPRaLyts70vFj9y/MVINLl/157+jq7VtWylVuuIJ/7Lv/+Dz3zgIdH1duy4jWe5RCp9+srF55576qGDd942NhaIRCNSsL+zM8jQTx55bmLHroN7b59dXNgo/mx2t/8GIq+iH9gXvHP7LsLpoGuGqu/u3Y+1AC3qO351AXaUddrCcRDqGzc8oZUr1bVKtZLRWipsBRhW0GwPJ3E+FSEY2lIMVM1SOEZRtGE7CMM8nrEhCq80xTLCEG4ZJh8N4gKtVs16Q2/E16yDOaFL7t8xfvC2Q+18AistFyqtpuWxNOnqwofSFOg07bS5SpizwNwAnAnaTNhtbnDmAkBLoE0DnSYImw1gLkyq06eM+n333SeKIsuyKysrGxs+vZSgoBD0bMNve+v1+sbGRqvVsixrZWXlFQFhgMdsB7ccTPWjrfym2LfNZTCEMMPGdD9a4sZFlsZ8jSEGmhruwhsX/8UCzRpJQe+egFLCiU/HmojCgSgChtl0v8QghnlSwIuRraSqNlV+6WQ4WYnWXhBTWG44W3M3dq3ut4Fa8hoqX+9BAyIMeJbnabClWqkAaZJZxyT27mbkBMovksigF9bKPIFlGkZHWFDrLUTREAGJoTvak4F4yqrkl2bmHdMBBPXy3Lr3Pz496G0o0PEk+JM/B22d/Is/ck1VD3cCxcRwDsM5sq3LazRdjuTPnQ7sP2BLshyNWCtLOAbgvjtAPAUunNn/G7/DtXdJycTct7+BwiGVDDabpscGECcLsXS9qZKYVblyZfiedzkYGA/LFyYne3buio1sq60s7n/Xg6m+IYLhA5L4wj99NdDZVXaZquaBQIQJJ12aV00L6PVaPj+2d39Y5JcXFnCW377vjsWpa8ODow9+8COrq6vxZNq2zce/9bXubTuzLVg1IRdvD6U6q6bneF59fZkg6cGhUVngrk1Pv+e9769WKmP9w7/+2d+cn5vlBSmZSk7PTV+9cDLdO7TUsBWXiHUNRFIdS6VGSOSvXjjZ2z/c3t5RLhfHhscBwGqVyp/+wf9i6lout97Z2RtPxJ56/plybiXVMThX1U2C7xoaC8SSy/laNMCdP39q16590ViE9sDuiZ3FUvF3P/qpns7uMyeOdnX1SQEpFI3+w8NfjXMUF0otVHQyEO0eGcc5cSVXjnD0i6eO3Xf4vngkvKN/5MXTJz7/kU8fPnD4+vkzpm0NDI1JIo8Y5p8ee2Q8GTMwfrVhhds6OgZGTERXaypwtKmlhffee/9dO247c/F8aXN48s6PvJJ2DRJtrSeL4oohcCKRx0/XxWzsl2ba95QVz/JZuhgeYPGu24YZiierRoii2oIMxhA4chFC8e4Yy5DBAMW7KmRlRAKaxIHrtrVHIlG5Oy5joscGMNeCZBsKHA7hfSR+GK9J2eK+E4ZVsprNZrM2v3x9PWpREh1lMIYmbBv61qKbPGi4yYNWfePFZgNYDbDJg9aBotzMgzbfjActhr14t02SJEVRPntucyih6/oW5W7r4lqZzFWJfI2A8FUxd77mXy81CMfdHGBvXs/X8IaKrxRIw/YnHj9tpAsgOCy4xzt0z3y6syr6J1ehENbdBWJxQNOAZBDPof4OQswFufqOcUzGl1mB7uzrlpLS8p2zM//5qRcfeCT1iecSIaDa9ZAy37tWd1MX9//W7P2/13P7bV0TQ0S6DeSWuPNa5dilK/V6C8eJXWlRNy1P4CiOpSQpm6tePXNm8qUfTV+6Um1ZFM+ulWvWz8Jp5OcRCAGCIhCiZyZNIQ58FRwiCRxn6c4Du9D+O2w67FiWNHmFFEXbhVJnJx8MYYLgfxw4wUgyK4WsSqmZX9cJ2fV860ySphief+jwPr5rQBdT1bXVVmbVPwoMRSLhsCCKTCAgpVM0w7CcIIZC6/Ozhm0ruGR7vkEbL3Ad6fjhvbc5XMSW4rOXLxqqWnfQzrERnxjK8wE5GAyFWZajGT4Yi509cZSVggWTcHzmJwqHghPDfcMDfXWXJkLJl48862H+YCyZSAQC0vDoti1nRgQwISCzknTm9HFSkAsmsaXHakslDu0ZTybiBZMSwokjR571ENHZ1UWQhCwFKZIMyiHLcRlWwCjKI6gLl86yUqxg+DYyBIH3dLXv2zXOB6SyTSOMOH7qBMsKoXg0lUyH5KAfhYFhumnxvMjKwWK9vrg069ByWfdFWCzLpNti23eOIYJqAcHS9cm5aTkcjcZiaVlISgJF0y1dk4Ihz4VsOJIp5LRateGxddOn/clBuW+4b3hi2AYEJ6dnpq6V63UpHGVustN7u/AWFei1J54qzp2+FJ9+vm1ouXc4KCzd+5nGxLvzAEdNC/m5IESYMe20FBBSUufuvn2Hbv/Ee96fipCGUsQJLyDgBEbRBCESmqfallIxTQ2jkBgU1JqObFcLVaxGBkEYCVPQAUbeojpA68AlJ9qgY+HQQAdLrvf0L7vEBiuJNkVwPMdJMvI8/5DQaSDQsF8VqmwWaOeGUMV8jVDFvGWBVorU8iXOdV17E37AMU8HBJrw/SZ9OI7DSBrLkSRJ0rRPgd76ry8WeC22dCuvu/jTsKRJQDIEDz3YgWKfnd7GOCgSDCV7+9hkwm+lAwHguCjYrRndocrcUFuIIAmeDe3vu3Nb34SbQMqOHDhovnR9aXx/qwmq0FvE4DLRMQdD0/ncGV2vX1mGJ3/ETh8XVy9Sx7K2xTH9XUkSB45p+MJJisRwXDOsdQssqMZiw7f0w3DS2MyffmdC10C9Tq3MQ1XzSM4/aEbA8aBXrS2fvoLyJUALFi22zp5ifHMikxscIh2Hth2gqsBzoeNQoli6fN4lWUTQm2bOyHNcZWPjuycvafWGxwQcil0+e5LAcQ1gbfE4dFxDaa5fvFjJrUmhCE4Qs+dOQk6COOmn57ieaVhzswsnr86Yum5TgZaqLl2f1BwnFo+TBOHYdiWfW8ss0zQdDMcgdKevXnRZ2fcyQMBznZaqvXjq/NT8suM4FiWWyqXsylLLsNtSSQ96x48eOXn2hG3byVQaJ8hyubS6suixoa3YKss0683W8ycv5X1VoQeEyOVL5zVdZThBkqRMdrXeVMq1Cs9ybekOgiDnFufqjbrHBjEMIIg0VStXasfPXC2Xq44HMU4+e+60ojRTHZ1nr164Njdj2TaBEx0dnX7PQ5GXrl1GiHBJP0oGQq9YLNXqjSsXpzVNtz1EMIGXjr3kGwxjWLGplZQmRVIMy/X2DflGuxg2vThnWJ5HsGjTjTq/USjny9cvX9cNw0UEQdLHTr1s2Ha+9lZQ+H8y3iIeNFI9k2ah01qUm0Qgac6fOf9S+chTxL47aUC6FMWE2/ZFZBsWMzFzuWqF87yrZCrW2aYVkTDCyOe13l4J2GZmqQgcf6xhlrMo1GYZ1thAO42BC64WsdZlJDFrYuBeUr5tca42rfRlWC7Q0bYzHIOW6SrmCjxLtk4F+P7GpnUvxJAHtKbP4kA3vDgaoAX9pETkk591gBSgmzexOBgLsH6B5nl+y5rrzaTeiZiMACoUFcO8cbqS6LYpR0BWhNpEs9mkKMq27ZWVlZ9J+iJP8hRF29DhAL27nmpjEigggrAcFYYKGAYyq9DU6LlZeDWfG9h3bvIfUQiFwuE2piMYC8yy08cuXsLqYH/nkMhjnWNFgGFn9KN4xzLtWLv3lI4+znV5fdWsizzYHxbfdfttTa9l2O5Kwwoy1HyunE5HPQBoAuDtPcX1Ih5JYCsrIQLOFX8e1Vk/G4gBgAB1+YIryr6P86blu2/Vb1ro4iXfthhCV5D04gaVyRrLq8E79mhLq/bqMnjm+ln0eAAAIABJREFUcdBqrp0/28aJtYVZwImbWSj+cs+xXd3IXLzsmQbyPEyQSitLidxGrV7r7eq6Xi5f+uY/mo36uWeeSPcNS9FobWOdCKa3njwIoW3oLd2olcpWS/X7e45fmZlCYijU00EC7Mh3H6nk1hrF/JmTx8RQHCzZerMhxDq3Iq88iFqtptZSbdO0TRMjKIIk565dbbb0bYN9//ff/l/zM9chhM8+/8yB2w+ur2UAcBCEBLXZoyDgOK5/9F2ptppNz7FJisUQmpu6FgpHKuXSi8deMC3zS4987Q9+7bdNw8yuLpbqZYEVcILy94cYsmwrl8uv5zZarSZ0XZrmlHxucWZaDMlfffThaq36yI+e+P3P/kZ7Z3exkAM4XFmYCwYkX/ewqXyxbbNWqc/OLuqGgSAUeDG7urg0PT2Vz1YU5dtHX+gdn5CCoWAkcv38eZKjc+sZlmb9244AThPVSjWztLK8uOzY/puS+cDk5Qu7+0fFUBBUfpYyhX8F3qIZNAKI39lJcYKlqQbDrAFuBhOt0nrNciCNODEQjG+PyEJMdh/YuZqURF1leicfaq0IZQE6Rs5saRsFLb9edXSNwDQsGXMbFcw16zWzVFIymbxVVwarstNY92yyeEXLwiNleh3nqWAoFJC7EsEgTnGFl9f5Z9v44jAnVWAQep5rVfEPsyUwZhr95nXSPA/MDJAMMGx6o+ZywLwMsGtgSAWjJkj5MsNLk/jcKQ5+7nOfkySJZdkLFy68LiFwyxFJN2zN8GoNXTcsDMO26q9a5apFo1arVyqVYrHYaDTK5bKiKBiGEf6RIb7J3fAfOGLz/2+++NNYcwScjijVY4K1KWPme+LLzu2hQG9vZyzicqyjKK6i0Lk1Rle9q9N2MBYkVwjoEQxsS7SrZv367LTMkuBa63CoTVXqbcNs7/1DC3SlbGZCjA0ss1roao9t21TY+sLI0d6ulBys6htH5tZxxmthTZKwcYCLEODxBNM7yJXWQKkQDcOcU13JvRWU0rdhBu26IJ7Ekyk3EvcMZ7PIYoAkgWUDx/ZzxVjGb4lv2wssS202rYVFw4P0l/7Ou3LRd7+zbS7dHu/qVXTLI+itgHZAUtAwoePHo2EUydNUx8iYgUAum1U048zXvrRxzs+sQghSgsjywsi2HYVGE5L0ZjilHyJia7pjmn4MFYbaYvG+3n7FMOYXFh/7f79w7fQJfyWEG+vZRFsHDVH/4EhFMz3fb9TvL0iK0pstxzI3rfTdHUMjyVCk0lCOPPfMkz/4ztZjfH3mWqFYiAbDHEAd3f0bSpP8cY2mKLpRq9mmuZlsYt+1aw+H4flC6eFvP7ye8xU6axu5ydnrAU5AthXm+HiqPa+0KMrvcjAEKJKu12u2ZWMEjkHv3l37oGm8fPrUmUvnEULL69nzV6/sHt2ez2WhaUZEkQtGmqZDbm5DAwEBB0Qut2FbFkYQIknev+8OqOuPH3l2IZvJVcvnJi/etWPv4tKSo7VI103EE6pheRiF4wTPc7ZhkThRLldsx8ZwLMJxu0ZG7Lry+MljmqH/QigJnUIDNDQiJRAkw8c6Ftt7m4XVQWVVCG60Wrila63KpRohJuUST+v1bDN07nej5KCqLcczkdw2ALMLZBjRcth1Ta+Qh/fcjSQRXb4AGlnTMP3oChIJmCxR/BX1QgLucXDKn906nmZonL5c0MW+0AT+fVJdUKlkFGwcstjvAx6UIP3ba1HwMEDPEw2edRBM+f76LxLEAqkI+qKOS945EawDIPnt9cYG6bMR/uIv/mJrOrG4eAt6L03ToVBoi9JkGEaj0VBVFcOwwbYbbfJKnnLhpumo5/WmtjTioNggTNuvzo7jDLZ7DY3siruLG1TL8C9uhQb9ZAQwgYPsycrF3kjv2fen5FCgm6UNAAJ+DnObl8tbFtQdjNNauMTSGkHjfGWjfmThkqVWGQ1+lB9baV47upH51L0H29JJXdPHhsaffmm1yqFKwQ7Ghwf33YFz1zT9agvHFE0fHt2enW5Gu1U3aIdwRJC266pqSaqfPEFQZwXHTsRj4R58FLIvnn0rMgnfBjg2CMrOyChYy4Ha4o0ueDPjalPmigHLQBxn79tP1msontBs377f6hsAU9f8HZmuRTs727p78uWqottbvuPQsoDnPzk4y7qWwUeig3fdW9hYZ/h+SNDmTbafQxM75GhkZGzi3MzcJnvOT6e1DdNzbQQhxbKOoaV6u9v6+hTdRDiuNpuvUPRq1crQwKAgiF1dnRdWv7ZluY8Q1DXNsU0EIcMLlub2DY0kgrKgG4WNtVc2eZ7ntafbB4cGCRzjJelidsNvQ/3uAbaaTds2PQ+yDOM57vadu3S1JZNUq3njAUAAraxlR0ZGqc2oFxnDLmXzm22sr7St1xumafhkapohCHzP7XeU8jlz6trWfA8hVK5Xo5FoPBrVtFYina5dvIAUHdtkQ+EEViiULMeEANEEzjL0zn3715aWcj/2A9kztr0j3R4ORyiaNBy7rbNjdn2j3NT95ofALc0oVyqmbUIESZyQJXliz77CakZpNcEvSuQVRFauhkfkgCQD3+WICSiKkKQhYAVJNJqVBtrwLBZpypQf/v3BpDeoe5rpQlZl5UKgMTzOTmzf3t3WZuj//MJRm+asXbejjSJumczo6PZ0Gi5m75+7bU2bMz0gsyFOjmdCOnAxS9MVSiPZYO58FmQsaTCa2JUMoS4te9WjZjQIT9kCWALMOtPf3y8rymAiUalUeL7qukVTMteUtRoArzvHPXXK72Juhhhy5YRbWOAxDM/lcq/7W3IzvVjb9OSA0N/7voJNR3+MIpDrvTohaRm464FaC///RU7zoG14zTBM6QLFOFa1oTp1JRSNtnDcqNXJbAZIskuSVLp9+OQsFijDHomnorYVJhHRWa2kLVweGbCuLyiG/YNvPUNQ2O3bBgCQc0VK4oW+jmG5LT4evUepVxZXV4uV8uPPH5/Pr8KU5WxGOJIkwGnPTtQp1jIWxQDH7Rpun6uuHjv2c6Sa/dljcNjt7iNK5c2kq80WGEE/8grHwFauIEUiXlD5AOA4/8S5UgMd3VtLCYrqGB2ncEyMRBU1B/wMUwx5rt9tYLhn2chxCCaA4Vi0Z8BzXV03bibEF5cX7nrwAziCDMOaDsI2N1sQephvpk64luV32TQVjCcjNOc6FrUZ7XrjpQlix85dpmlifs6T5xfoTbq95/j7AJwgHcs3EQ1KciKV7uKEi2de4zgqBeXb/OVWqV7+ceSVv9PzudJ+F084lp9Cywt8PBYPBCTGT9W5ARzHB/r7g3KoVC7mfeu7TeI/wDEct23/uILwrfVsnuUYlhkf33Fx+lWJDYZhwWAoGo9RJOl6HstxmH/HEMvSnus5luvfdwI5jiNQJC+II+MTvHAj75wkKQxgqY6OSDRW11qebwvhRyn4MTSbO1TTMH0bH5xwPDcox1PJNE9zforY2423LjRWvbLCj3e4RrONZrCrF3nvlMeowCJx/4AE5xI9lCg0jesAKiszV89d+253ezfG4DjCJBK2iovWqnitvDbPyUgryM8diQzcuapV3UgU0kzDNPHutsdSz3SUA7bXTFDbGq08hq8BGjgt3WDLlYIhPNwhugG+nWN5IcpE7tX+w6nSn2Kg0T5ioBrVaOJbw4p8Pr/1024pRAiC+GkO6Bx7S+f94/yVW2Gt9Mqv16sVuuinbm7tL29cRAjlqziGgXprs7XeHID/NESOKl2LCASms7PDLcgScCPXIgitUQc8705Nh3BMxzAC6ikd7bnWxAbumJGvl5w1NpRUCyvbbbdeVwYGuq/Prx45P7WWzd8x3vOd508SDM0SFCexfFAkeZkQqWR3+8ZGYWplPcEL2UKBCyNO2HwLGBAE0NKAG9TNlNvWTiuYbtPrBP32P+L/owAheOTr4MEPoFQaXJ4EiMJwQJEUgtCxrS01ir8/omgwM0tcvexZJjh8n3/4sQmtXLr08FdH3vsBTuA30099NiRJUX7JtCxEeL49AE44ECyfP7924WzvPff7joQ/xpUTRwPR+P0f/qifhVqo+OGruD/i8BBybX+bjyDiRcm0rMsvH3/tYQkwDfPP/vjzD/7yx3bv3sVQtIYQhjBA+Mdvnh8/b+OE35aSJFmp1o88981nn/zhzct/+PhjAivcsf9AJBalSHKzyvmlDfMpV76bM44TNEkFAtLC7Nwj3/nm8vLN6QRocnKyWqsd2H+HHzm4Of/eeqd+tC4C/lcUAAxLsTT73R9879HHvn3zS9cqlW899u2dEzu2bdsWC0cQtowwRLO0Ybk4vnnLoP9vRELRar32tW8+PDlzo75vzgqJZ559SjXNXfv2jY+M4/5P7s+FfHcknHAx4EI/rAtBmEjEL09d/5t/+Htr8zvj7cVbmOrddPh0p3bpQuXyNamtSkWBjZOsq5vII6V2Shxw7DrOH2ytPd3S86ahXM9kXSzKCMRA5/CQPHRCOIlt55tX1KB8u/zcTPL6Ume49+TK1VabsRBKwzl8rdfbxpaDk6quzA+UW+s0p5sqgfh45x2oBeFSDWDImbEtp+YR4pDWL9X++DT6EwRbHINU4kaayc3YEvX9NO/M0gjLT/W+UWRHB9u2UsnrDa3yE0V0t5xd/Ouc7aCNYRTwGDcMHceFmG5INEGTmKO1GvU65BieJgxkRXNN6BDbueH3ph78Qu5vUGWBLlX3tLPmgnrq3HUPYCwBwjG5oqgxkmr51ksOMFyvUvaMJskGOJyCHhJIWuK5Bx+iz69irj+7BAEJ62gnm01YKntkm73tbm1y9tRKzro6cwvLm3cOTr0MFuep3/+8iyMPBxRBCoIIIdRdzwF+jjpwPXB9yrs+BRgK1EuAosDVGzb20HUmv/1PjfVs31334r6wCBAkxQiibxPq+AR/DEBTqS1cu1bMZIiAyPIc4XfZN9CsVY/94NuCLCPX9k3RASBohhFEx/LVq/5qDFZLhbOtllqvppOp5k2EBITghTMnogk/TJYkgF+dISBolhYDSNOgY/vcLsxbz62rLZXAsfpryQwNpVEo5heWFguVogcd/5wQAYJhKTHg+GQSB+DA9ayZmZnjL7/08qljN7cXlmWVahVoWi+fPxsKyr7bmU8OBwTLkQKPb9k6+pY27tGjL37l0a/ly6+e0WE4HoqEeZLMF0ume6WqNTHCX07RtI0BkmUw2wEO9AD0POfb3/3Wf/v+o6+svbowi1OU5xjpcGwhm/UMu95sYCSGk4Q/juJ95h+ybQw4nufWa6UvfuXvZ5cWwM8B3qJDwi30fPL9704vuXbeCfppTzhNyI5mKSgdAmzbfQSbYGyjkbkuSJJb7KDAaMtScMAgg6Axvsau6N4ykXGipwOcHUSG2iH2Nluz1b0WHvTQTKU7Z/yyCg8PD2uK26bXJjsqJukF4x0eRhv5jfSVmOtZuIEBlqVVWswxq2D6CnW5UsFrCmH5gztIEnhneyQo8ZGQWK76uVb/On4FRRK245qWoxuW47xFCTqMGU9H+txaxerkFoI6F+AT7Sm1pkQETmvUMRdCu4kgPjRXwXCIqlYST7C9bu+OaCeoh6w6I3kL18oBKUx4sCPAFDQdEgTJc2RA1Fs6g0GG4mytNX/9+nKpytJEV7uz637F8vD1ss0yGM1y+/eMRKPyeq7mIdSdpidGqJMn9SvTb5HpzNsm9dZUb2kST/ZgJBVPhXq6E+kERwkBran44iJdh9ks7djAUmA8DYJB8K1v+Py8H0NZy3g8BRkJw4h4TzLdIUdjEmAovd4EGNAURSkWMahRJI3b9uT3Hn1t3pWhKBWbFhFF+TEXA53xNCdHwx7wfBdfAMqlkqWqFPDsZuP62dfP5XStBXG8qFoEw5A0kRjuiSZILhRxbd3WfWZnoVAioTl15UIh/3qzf13XErHo1PKKjjCSpLkgFx3sCSYwWo5YqgId3+FAKa3/6MgzrzOlQwjJkhyVAqVKdXI161NncUJIytGBTjGKk4JkKQ3kQWhZc1MXL8/O3LzWMI14JJoOB6vV3Hq+slKp0AxHklSoOym2R7kQCVjWqisIwtL6yiNP/fBm49CWph7ctRf3YLWRN0x3YXGpYdoMw7Icw3ek5A6JCbIAA3ZT81znied+ML36Nui8306hiv/ZGMbQwj9t7yY8ye8XSJpgJVaT5TChOa1KaepRo3BqbfqpZgswxIYgNyEJpVgYeobZ1LWi0T+ze+zlOwcXtvMeRbCkQ4u61RwldvcucPTpqeG1yuFspVwprqwt1snstJZ1l6vAdVmn3h4fSiX3+H6GHqEbqrJUziytHC2fXoLnIPGa32f/OwPHnM3H67/nnW4UG/lio1hWNP2t2yL588SWgeyCoeu+cbDohASeo7ggSSDW8lzbqZXdhn1FDL4cDPyAqfxAvV5dViaal5VTa1KIiw2hKdeEJDncky5VqzJDgs38LRzDHcuZW8qeO3fmxItH5mYXN+NJ8fnV6nNH9GTEDxxlODwSkeKx0OhgT19fmBXwSt17+bidK71DJSqvQ6YAZ675NrWm6SGCIhHD0CRFeLYH/HBNgQSOR9BgZAIcOwJuagm3kD9xGmqaT+y0TYJgcBKSPqkcg6ZDsCLGsASGt43vmHnisTea0uXm5luFHPB8ESr0HJKkcBIjfQopgJZLCDJFU0Nj21967DtvnJIVNnKVQkEIBLzNsw4EEeGTGnzSkH8kggheCsiiNDt1i5SAzFoGAVyQgxTJQm+z2SJwvxv3hwnAtV2W5RFE1c2EoNfhxZPHook0yzGcHPIHeNB3cPYHJD73w/PbexfWlcaRs69Ger+Cbz31w46uPpriocBxgmwbtihwluviJMRIGvmTJQQgevnSBfu1e1PDNB/90RPDQ+OMKJu2DgMyRbKOZdMMvTnb8dl20DKh561trF3Pvv4Y6Reig46luc//2biuowvLRYRhHJ8OyMlEsNWB1bOLQNfqai3rmTbeIvKLgMFE4I45BGmpOs4wZIQDdYasyL7THO4g4PGczTkKzwTfxz+UfeKZfS1vEICeRM8PMlPPJMZCv+vWlJKrm5DGyrVVesUMZ2WzbtCDweADPexY0FL0Vlnf4HOuf1LgA8OwbRPbLQeom1R3nuc139z+3ww4Ox6FHFKsmXStEicdB2cQiIf4Qna9rrlAKWI0CZLDdDMOxTYz0LGsaUphdXevjVlazaK//Yw6tey1/HpLScArKCrm2ZgQwCnSUjWir4/r7YWhqNJQPNMM8WzDaNDh1tkrukcCmsbS3cnBnkMy364Y1UK+vLpkrc/bF6+5Sust2kC8zYb9tbLUN6DhbL1S122sXKipdYWnyYAUQMhzPAtt34PKBfClvwdvmF9Bx8agFxkeURtGs6npulddr7iaJoYkgqRIz2gf3e5WCtd/+D1fV/U6IGS1mvGBIYYTWtWmbnqtutbIV4HnimGJBnBiZPjKS8/NX730xh/Z50UUNvYdOGRTBO6CZrVhOUQjX9VKdYqhRInf2dN59EdPrmczt3zHitK4c/+BhuNQLOPqttHUDRMoa0VTafGy2JdMPPvkD5q3YkHYjkOzzP0H7swUNigpAKDnqrZlOJpiNbN5nwTNM+dPvdRQbpEHr6itZDK1e2z72toKEkQ2wPMMVduoOy5qFRr6RoXi6LmFqbmF17TeW1jJre3Ytm24f6iW3zAAoCWRJEiGploVxTZRK1twGyoksWeOPvs2+ti9bV4cAICRveEjz2dtxql6NieEOjp2hWQ5GuN2t2VqRUh6+KHbAj3xsdJGo6fDTaUxZWObQ3OOi2L3tiESl0ZFZbXomDYXwqHawrXluNwJCLo91nlh5TEa6iNSqC3d+8P1uVp018RBEnCGudFsrFZdwiGX1chy0jVd6Z42a9ZwWw42iCtX65VAEbEW2vS72KL6ez7NDtI03Wg0fhpy288PAjYfI3iPZE5Tl1xKR4CoN82NXKFZb5C1XIBn6LFdTnqAuVbCKcp3uSOEJp44dTLjje/63jQ3owqVwbG59v6THq2QXNLRJ5fzUZ5CGE45Vmr7uKq4LkFxdtOqNTjXhuGSSbiuA22AkyQeDbltaShwzaZaWF2pQ8tjCOroaf0tk3m/zQUaIbeQIxJtlmU6BA6BCw3D9gDDUMjWrGQadveAv/sb8Ca2zrZSJzjBBQTCgQ1dDECn2YI4zWKuJIm4ZRz967+4RXXehGuZjtYKtvdojRqiKcexPVOHDhQEviMkacXC89/55psdMnueiyxz55792fW8hxzPZ5E4lqLwvLi9r0PJ555+/LE3e8f1Rj0oB7cN9Oerzab/8zO+5lXXoe2O9vUcfeqxhcVbZ8cAABaWlxiOG+tsr6i6ppmmawGGdC3LVJoIgeMvPVUs3CJBcQvnrl6659BdQZq0bMty/GGLR2KO59qGbre05ZW5q5MXbvmbixC6OHXt/rvvoy2nWi1BmrNUA2NwC4OOZev1uqapL5x6qVp7K+zLfx4LdGlD77st0GQdSOFyKB4MxUOy2BMXSafv8tWl9jSIRchkvEOzKw4N5aBRz/S2mr68O7QtoRVcsY1xVzOagpGUBZszFI5wTPZwOyjHrsOZdq0W5SKx/onvWUGHFCOJ8OgeTtGUZlELx8W2YFy4gGiDohNAumuI65WcxYy5VK/Hij37G0aLxCBDEIRpmrquW5alaRpCvkPkT8ni+HmADAMHmXvi3vDlvnpjdhKEgiRD8v4hoQrKVXj3vVrfCHs2QxUNnGb9X1iEAE5ZHl5bKYDhHYV40uFkj2bdYGRNDK+G0qhQJRrVIEvSGGZbtjgxDlwTX5iFmgptZml+R2lplOlcJwUCoyW10SQpR9VgNrueWScoknRa3rkrb125fJsLNIYjy/LWVqi2ZHLfHloIpIc6G8W8oyiws8stFcFX/ytYv7Vh/xa0tVXMs7vuO8SEosGudtw1nKYaScSVbPbqw195hcJ8S5hNhYRecmQwPDFK8mK4KwGLxVQolF+cP/Ktb7xZUNYWysUC7ripVCq8rY8Mx6TOFOPobSw3d+n8P3/v0Z98BjO/OGeq2mBbBy5Sod07cIaNdsTSnrc+N338tWeDb8TU3AyCYDzVbhrNyJ5xOhQR2+IRz8nNTU/P3cK9+macvnReYPieYMSDDhbkpB3bCIaNp0KzZ86cuXDa3bQ1AbcCBGhpPQMNeyzVXquWWRoL79oGBCkQC9Wyi48//3RdqfnUvTfnYr1jhSqbX/WolrE7J6SWAVrNYomRMQJpsnR6YWNDDiJF2dPfbDVPhGSUWaRzXD/enSLPNHA6qc9Uk7uSRrbZKlUhjDuV+Wot1x3tNmx3d8/tMMyxH/xfe5/4we2QuxaOWGyLZqj1Qkd7M8iyU9HRcP9Yb1pKozosPdwwjxGOsoAhYFwrGsj1HLQ2zWoNHMNetcrd+sPPKujkLUOcaE+1BihWgl1d+J4EAUH3rt3vTyS/c/FC3lCdQIBsEexc3ScPsgzBcVBXkefBQKfUu4NPpTc2rphAv6GwwPASxTUOvMc4/oJcL4kM5a2u19cfBRAGCDQwODyA79iY8RotonE6EDp0EqOrlYo3kyVyBlVdBa4LgyL9/Knav7Vb+K8EFktin/kdgqbxjk4YCldkmajVWvOzYHwHzK66c5PgxAmg1N9sOR2Qd37it5hQKNrXx8cTNM+pSiOTbxIOXpy+XDhz5idXWFaQ7n3o07TA33bPuylRIGi6XinNrDWz85emjh/9yWs3bfuTA4MTQ9t2tPX1k6KAYyBPB1fnF5eXV/7FHaQv8Mtk7jzwrpGu7vaecXKIRoZeoJcIl+Q5saX+JJU/AujUlfMCRU6M7d7eNhqIJwkMUd0T54Kp3RP7vva9fyxXb5056zfvTeWF86eh0Rqf2EXiws70ANXDU4596N8PzSzOItP5wje+uF68RQ8uy/JyNrORydhac7i9u3tgUNNQrK0vEYrUo90feeAjuULebDS/9L2vLayt/JxUgLeUxUGLoP22oEcxpqo5UNP1ejZfbGjIgIihsV0xtVYFy+vE/0feewDZcZ13vqdzvN03x7mTIyYAgzDIBAgwB5EUlalg2ZYs2bIt+znUPu/Kr6TV87O3/GzLUXZZ1mpXwRIpmkHMBEAQGQNgAEzO4c7NsXPuVz1DMYK0veUl9ah/TU3NvXX7Tvednu+c853v+/+KRmx+eUsy8CBRMiqN8XrWLI2JtYW6qYuom2nIq0Ot6WRkTzo82N3SfMW4lEn5H3ChFcX+5lJesZBYd7RrKB2ID2JWZGr0AoDriFPWYvLi1VWk5CoZXcnWLUuV4eUGL3nl7T9VLMJvH2xNxPztzdGVTOln4w/0b1UctPiQxDePLE1hc+TKqOmLiY41XipIooSNHUNKPvZUAbEgiKCpVIJrTwMUtxTP8IFPxOJNYVOEanbVhVxAkJ7dmm3bKKTwVM6GUdvtRJxEOGRJIk5S+wfaSzgvrQVX6wIsxu2VQY9Jy9eYzkNKQ4aZZrWS4YF78qwkv4sldu/ZDPqWe/Df+TrYOWIPDNhNTW4o5FCUTrEWSjkz866w7p48Cd5+1RzqHjzyh3/efvBwsr8/lEz5OM7DOJEszYccRZ/68Q+Mt4/snq9AW/cvfuXPdhy5rXf7zlAwwDMsg5M8y8VTLZCDTl+5YCjv1MYZDCd+43e/dvi2u1PNLaGAP0BTHEnFYonW1o72to5rV8dk8QaJ4FcVDsV++zf/4MitdyaaWoIs66cov49Lppq39A8eOnhofHyiXHknIwuG8t156/0f/NjHeTboZxg/y7Ic193dOzS07Y5bbluYX1zLvu2aQ9JUxQZ33/aBnfv3+0nOz7A8z0di0b7evt4t/R+6/4FSvjC9MPumo1KpVD6fb8hySRQH000EGx7cvyfBxXwsG4vHU8lUT3dP/+DgRz78YaFcGZ+devdj9HuZ4tjonoJ694cUF4LRWKBlB8XGxVIrOrYlAAAgAElEQVTWdbxqftiyhTWnpPg0ImUYvuXzK3rN2J++p9zI61qDxTCeAsCW69JKOpDubbqjPTmUiPFXkOVnypfEhfm1p7/33Py4Gdtm265lwTbOGC5y5XhGKSYiqel9Iw3TcI1RnsrjbUhgSyKNUnpBqGlBw0ZfW8SpmpEvNbL52nquam1kT4kNvfrDq0yKn0UF4z/uyk8EBVJG41031YyC3V4zR2K+eWjv8EfATEkRTAgnINsKd6Xat6UdCJLLAgAQjrqtg+0s71/NzZk4CoJBEI1482jHsVFMvfV2f2fbp8PErsO38LANGYraFP9LX/E8MwE1lIDRRDn8TfzHelNAa262qBCjZsE4Cy+1Pz81+27e3u9JgIZGDsG/8vtOOgkQl6wWCVlECRwhCRjHAIZhNGsvLLvjV8Db9DsEOrbs+uJ/ivR0sTRhi3WjWoZch2IYAsdgAqdI2sGYysK0o994oPNHUx/80leaeno5jgaWLpSLhiqTJEFTJEbgkUiUC0YXpyYM9cYxmvX5P/vF/7N3cNjHszgGC/VKo1aGIUAzNEHg4XA4lWq5cuWipt54q9zPhz77yV/bsXMvwTAkiWuaXC4XdF2jaIqgSN7v3zE8fObsOeFtQjxL+z7/0c/fdttdKE5RNAGAU6mWavUqgiA0Q7M+bqh/YHJqKl98pXHsTSJx8mN3Prjv4E0ETNMsjWCoIAnFcsEwTZqmKYrZs3f3/Ozs4uobquVisdgmYcOynf6OoT133EJDNMMwKIGbllmslOpCDUMxmmJGRkZqxfL12RtsNr5vUxwbtpymWVUgBo0lYrJq0v4YBWENXSVNIK9b53TGcgGiC6CBjRwk5fILJHefj0lSRGywY6Bjq39yanF5oRO4aDzKN8V9J8Tzz/kMLCfXn/rhyXIBYyNNfSJO8qahVoql/PQ6YqkIjFhydGrpCrnItCwmw0R0Gz0c2hFTYYV69tlj8KjuwQdfkeO4mvbaQwRBtmzZwvO8LMulUsk0zZ/lug43wlQGk1h2PcK1RqimtfwFS6g4Wc28omrD7f5ooFzKwjiO4ijL05EI0RaKPltVhIUlU9OE9bXM2LVAJKxYVcTPo309ZibrTE0BgnAMY3zv4YdPmR+bubiysjpWFy9Z5TyGgHZSRcvQ2Nltzl3hYV9v82/Bo5njk+eAg4KJfY9Xn3tP6fXvhqBoEvngZ5ywn754Gn/ucWR92at1TKWRBx/S9uzXUQiqFej9N6uzM8TMJUNVrDeO7riP77n/k9HWtNWoXvr+I/kr501FJn1888i+HZ/6HI0ThUph5I7ba4uzhfPP69qGUcDrhKDY7js/zPl9NIleOvbM5Rd+UiusQzCSaOm47WOf6RzcVpKEXSM7lmZuP/X4/3TeAhUEABy548PRaNQfYIr59acf/e70+Jiuq7w/tPfgkfs+/JBp211dbXfc/cGHv/+P1lvAgN6IuP/2zo4unIRd137qJz8+fuzpUrmA4URnZ88nH/ql1rZOnuc/94uf/69/9BXTevO0BobhPVv3juzaU6jkg9HI3Pzsj/7le9Mzk4ZlREPRW2+56wN33R8KR778pd/80v/xJVF+c6sXhmI7uoYO3nRoanLqwL6bNF1/9NHvHz/1QrVepUh6YMvAZz/xS6Fg8Dd+9UvXpsaLP02VoChqWRYMwzRJ9qc677jrnnpd8CU4CIbHrl35/mM/mF+asxw7GUvef+f9t958669+4Ytj0+Pj73qMfpPe1Rm0Z+6HglgSB5DCRnoNsWBW58WSiaiqGzbwqIsEbCRicymnMud+8FNRI3L65IlpRXJxF9VFsVDQp6svF4PcEqZdLI9OYnkjFNanL0mz1x3Lcgwl2L7dQUh/d5jgKUuo24rmFic757Ykn++jTvdIdUF2BMioGavl/FJp3Vld4XMm4jCk5wbgeM1bb8YDFgqFlZWVXC5Xr9dFUXzzK/49zMD/3QqF00ttIapQ7q/QVjgeb96irS/bp+eYDGeZtLgwYaAccKBQE5vsTg80MV0sMrFSF0uCsjajFbKF65NKa1AHli+e5Pp7YT+nF7z1KWSbcHu7Fff/SvT49DnjyoIL+f1ik8+xLddHSOY6GYQG6J1RiNSy5Mo5a34R5mG0gF8vKG+bQ3w/zKApGnnoi87u3czxZ6jvftOBgBVJ2SQFSnn47Ekk0QQ6u1yxQdOU7UAuH8QOHoEBsAvZzVpmJhLrve+h1PadALgX//yrldlxPBAhYynL0HNjF4X1THrnHiYY1MvFYCwB+aNNg9t0VdEatc3Do80dO2++u3Prjta+vlOP/ejED/8JghE+lsYIspJbGz93MtnR09LTW1xfaUomfIm2eFNztZg3NG8mDkHQjl0Htu3cv33XgdbOtkql+td/8p+zqwuhcCwcSZqGNjZ6ptFobNu1V1Ol/i29fCDF+rhqtWTo3mdLU/ShA0cP33RHV3tvMMJH4k3f++4/Pv7Y92mCSsaaKJzMZFZOnToxOLQ9GAzHogEEosLB0MpPU7rxUPToTbfesv+WnQO7HNjq7R9cXV3++p/8l1IxlwrHUuGEpkinzp4wTGv7tp0+Hx7gQpqi5ArePBoCIB1L3XfrPcNdA7v7t9N+X1dXD0XQf/dPf/3YMz8O0kxHoplC0YWluROnTuwc3t2UTERDkenpGWEjxHM+X19b1x0Hjg6lu4dae1raOlXXaEu2Tc5MfO3PvlqvFlsjidZwXBTrL546bpvWnp27u1pbnj7+4ru5bn6PUxxeNXSE3nlzYGmiXGlMKbUVddmFVAuNe+2hGw4AHtnBBI5WATxGb90HzazMTIwWbmn3t0fQxbxpxNILSaVk5XPFy2asjevurZ9+WlmZ38C2QVyyFUYI10IxApPXilZppX3N2gV19UvDTVprGAp24q0+4/IQAZb1enNgcJxZxONCOuDiOOa4KIA8ACBDQZt4QAL3Kughb8iFcAyBYA8n4ZnTb/zAUBCBwRwLJUOg9jPgCNS6dRsUSv3aX6V4xSwHmFopj+dwMJ4LdO9tZMuyQXjGEDRL8IFYW5wLkSoEsipeWy1rVZGMNMmV61I6jPm5lp7uaDQUIElRUd1aFSvnE9PFe59YJ5efW12K2SLVLmCh7u51v+m4jssRgQNdmgUlrocLU+KEOGejdphWz2tPyKr9vg3Q4Tj4z38Cdfbh68vMw9+W9h6Rb7pd6+wzBrfqw7thUUBPn4D6BkG6xdYNnOfExTVz+x777gcATICV+XBn/67P/XZ4yzAT9F//1jdcCDTf85HA0E6uqy86vMPf3psbPaXWam179muW0xSPTozPNh882n3LPaYNavOT3dv3Pfirvx9r640kk8uTVy8+/fCWvUcGj9we6+hrHdjauXWXJktjp4/3DG1ngpFwKLS4sr7t4G39uw9llualWungkXs/+qkvBMJJPhhgee47f/vfcBS+/d6P9W7d2dzRN7h1Rzrdcf70C5phDu/aC1xXlJQduw+3d25ZmJ2AXPfzn/3y3Xc8oKlGc3NbvKnp3LmTx55/7NZDdxy9+fb2zi1btgzt2LpLrFdOnjq+a2QfjhEtzc1D/bs4X2Bi6moikvwvv/GVQ3sOF7OFjo4uPhhwHPev//7PIhz3sXs+umPbzs6O3l1bd3Q0tb105hgMYx3tPd0dHVu7t5qmNb88f2TXoT/4wu+N9O8orK0PDA/7fHwsmnzi2SdOvPzsR47c84Ejd/Z09m3t27p36/ZGrfLSuVN7du3f0tW7u3+7qmhL6yuff/DTv/KhX+iOteSWVrYMDGIoHknGBUH4s2/+aYoPfO6+T+zbPtLT3rtnaHtnsvnZl55hWP/+kb2DrT2LK8uFaunnJUAjCPyBT3dUGlIyRPWESKVgWUkNQgDqETm88R3DIccBIQRPR8lYKwqh5qXjZgvnb0ilOdmaI3VZL8KNTHDPHrpvJ6pXhcf/vqsfbd9GxtuwlrgYT7hSQdJqhFucCa3nOnk+PZTaER8Icb6r+fMlI0faeeAWMrah2C2z3HRsuEraUJwDLVELQ93OpNkW99aD6YjVGjOTQVs14Pa41Zk0Q5ztZ5wtLQaJg6jfjvltHPNsQkUF3kxYv4dCIDTc1Y7GU7c8GqsX1+TV+YrUAOmQt7DzxbVqDWd5L/PvGoaDGjRHBhgRQMvTZWF6BkJwkiRqrKT5WSroDzWlosGgi3i1pWKp6mQK0YummanOLDmQypMAP5gc2i4EVjp9JcSrAwmEYs4gN3slu3Y9XzHKBAcvlUYn6v9KpdT/vwP0x38FJFohnvV95y+VdIdGxUBJAiqAFBPCCCvoh2pFcuo6e/R2A0EDQU5dXMUDAauvB4ZQaOryliP3QDRP+gOVK6dL01eJ3pFSRasJlmBAFoxppsPFwmvHnkoPbWcj0QhDyqWy7IDOgS0WQmZOv/Dx3/rqeibrC4RJHH7hO38V6xqQ0MByUaw5RMNCZAf4/LxczpVWl4b3HyYwlAL2Yq64bXgbgum5heVf/MLvT4yPB0OxZDJ+7uUXVubHO7bunyurGcFSSU50EMmw4gH+wsvPDQ6PBPwhP0dOTC/u3bMXhtGYP3LPnQ9cujTKc/5YLGraxre//Y2tfVt1IjiVFyTUZxJsWTUDPq6Q8Yir+3YfZDnq6qXxo0dvy6ytHhpsO3DwnpMnjnN+Ph5NRGORR59+pJBZHB7YPVtWMqKF+KMyQAXVSvHcCyef2bVrXygYXF1Yufng0ZfPPPXQrfdu37n/5IvPYzjW1N4e5fiaIv3VP/zp3bsOmKhvMi/oOIfwwUJDCzJcubBSEYWR4V2GqjUnm09fPPNLDzyUTqYvnz5lmGZXzxY/yxA8+6PHf6jXSge37pkrSgUFEOGE7CANyUhwzNMvP7dv5GAqmmgKJ548+ez7v9V7U4WM8rdfXahboWgY7e8kE0MAxgCMQASNMBwaiRF8CIdMcO8dcYKzn3y6aCJkekftOrbwfP/Q7O5E54f3pXu6sY5tZNcwzurmY//PviNQ6yE1uVNK7ZF8XQtQ9ewnDpzull4aUkc7/Qt16/hL177xw/wfTWovF0DNdeAqFh9HERwbClFRzKKmT7OahNREJFtFDAtaKyELWbRQQ8oCslLEVkuIZkCWDRZy6HIeU3Qwn8WqAlwV4UwZkTSIwl0f/a8TXf93C4eJfGkpV/qXJ/ZcamByrASx85MkDrj2Ab2aoQIMjGE4gZMMZVZKlcnFi09fH31mOn/+Go5CCArp1SWLYiFJUnSrIKmLhlFwQcOFHUWBIYop+Finn6a6OJTHEbIsN9q41gfnojQXQv28LDUYn9+8hbBvRjVL8aGIbevvYSXpuyEIApEoOX3V0VSNSADN61bGWIZqTSfuPWz5W5Rwi7M4E8qtwTRjAIxJp0gM9ex4HNO1TQTF2GiC4djsuZfsUKsgQ7YFUJpkwuFbb96VHNpW0hnIH1x56TmKYdY1Z2t/N7aBSgMQ5HpLTIfleF8wsDx5RbesouOrqY4DIf5IsH/blkM37c5bLAg2z167JNWriou0NKcIDEMxDII8PPyGAQXJcDyEIedPPkuEmhdrjmoCgmF7ezseuH0vEUysmyxGsaeOPwsTZDAc8fM+HMfzmYlCKYeiKITALBfgIuHRy2cxGMrZvqxomQ6UTidvv3nH7l2DSwLkT/RdHj0jaQqGM9F4mCCIcrVoml5vgQNcPx9EaVo29Stj5/hAYrpqC4ZL+7gdw3133bkHZvl1nSIx8uTpEwhGNbWnMRx3HEjTTRzHJVVOJJtcCCKDoeNnjoUockXGVhqWBaGdXW0HDm3ftX94qWaygdZTp47VRDEYj6EY6sMRD3OP4bKm8sEAhhKon68JjavXR6OB+ETRqGsgGIns3Du07+gIFQgLToBFyRPnTvqCwZnse1lyh777pM25K4I99JEPHz4X9NuFhrfBDcMsxydst8b5dJwiyo3Ay9XIhTFZz9IchnZ/at+2VPk7f/eEAoZKLiOgsHz9bOPYD3o6pK0JUQ6KMO4giOeTjpo0XObGfgTH8DzBUTCAbNelUKSqXD/FZ+/77IHJR2pco+uf3Zfv1R+klEAIjgXY0Pps3nZR14YwFqcAicJIs0mDOsibDdQ1AxC6WCgHQABzAQ0HFLc+bY7ZPzWugyA4EGj3/AdcBCAoE/SFgqxrOevLBQz2DBVkpSzL3sbxqyKj3JZuRxQMTXEkwcFZGMUh04Ux0mdbBuqopuk6GhTwMyxnWIBkSQaH1IyAUAyTL9cNYLMsi5mgLJsuDMMEzvqClIYpMUQ3a/9ifPezxH2UDeXAPGfsQkNRGIeNehbm2mkfJUumY+ooYaM+1zIUU1IwAiIwQPiCiK8SItFqsVj1+WwMtTmftLDASCJCUTTFIA507y1318bGcuX1miaKtko3rLZ498zyJamcn3vpWf14ZSRyZxBD4Fpt2XhzedP7TfMT4OjdxKUzKhPz1qCu6/XkqZqVLZpTGYATFhrSHUS/cBa/r1mVNbK3S1vK4pqu5QqgVDGlBowTwtKMXCm7kQHPKdRxHdOSCsVLMxnPBB1jdDY1f/70zl/4gmraHYk4vF7VNT03dsHU1dkrZwYO3o1iyMzFUxYVgiDPStQ2LVXRZqfmG/GYZdkyzCumMzF6dujmOxmO532sYRjnj50sF3OZ1flUqhXA8OriTKNRR9O7YODFfS/Vm6+ckpRarWEB1GYSly+cvu8jn4YBFI8Ga7XK+QuXhVplPZuJRWIIijmuPTp62qEiNkxAni+jXa8LY1OriiRbpmkgnGG5ly6d37fvSHNrUy6/PjM3VS4WP3CfEg6HWYYnKGJq9rogiP5EDAcedajRaJQqjWK52mjIhg3BbOLM2ZP33/vhQDjy7LNPZ0rVE1eu3HHXRwL+oD8YglzvM7t05bxDhEyIgFzXNK2VlUw8Hp6eXvXsHFFO1YwzF07fcuCWawuTy+Xyerkw6DgERaaaWnVFYxEwMT0uy4oI+Sng2avmsoXMagG4br3a0EyHYuMvnTz2gVs/8NZNzvdzgN5kSax995sT6QS2269Ynh0Ww8Y9u0EiHgnbz81yyyY6s466cRJJQlJFmXwuQ/7WJ9i+H648+pw0UBHHIeXayyQQPvk7tIVCZ5ZsFIMYH85TRO2pDqio8iwDYIBCsOVZ1AHZsCgCn1lbk/epOz9ALj3izJUEAOB/Nr7nVtERa6ShL6JukPARiYNtnaFoQOF3r0cQFjx/dn5Wfrnb6HjBfo6C8Fudu7ZgfRftHz8hPqa5r22Ls6ze1Xk/TLeaEILwifRQdzWbB6V5H+5KjYmZmeOW9QZqDqHyX/rDuKGIlYoxcVHOFgDfDus0BGGo6zik6mpleKA1le422tr0yby7s681gOZ/PMaRXOTirF5y1RY6zF1cziWw2WTE8PmIdBsxJ1uYaGeU+sVJHTpKulxS8mkqrMp1AKFGYx2DIIvsdiwHho1gB1vPCIEmn4cwtFDYqWg0ATacGx3LAQsLCgRcFLVX1xwX+BQUIxDbEGKDIdpsyZ7K1PTa8WuPzTty6NOfQShGXMu6VcVfp8S5QgiCENzJWu+NE9i7J5pD8uvw6oKVGvIebloaGwaQZfP5l735teNaFCdcvwLdfJe+nqcGO+SFjPnSC+Cx/wEkIXf9UmD4pvrYRQcjAYLBGy7Pju24ijx/8bqj665jA4qX69XS4kLVwuDWCM4wlx/53sIzD7uOc+nYU8m+EVMXKrk1KDGwgfTzrI4MVRPK5VK2oEuSAyCI4icunWvffsC0jWjA98Ij3128PgqA+3d/8bVf/90/djF08tooQjKQh8vyhhjLND0036IoCw3LMGGSqy1VlxbmCMqfiIa+/tWvVMsF13X/5h/+9Eu/8vuC0CjkoHIx50sObn4CrusIgjA5LUuiZOia6wCU5EYvnunp2ub347/3B7+uaWpWX//WD//x6J4juqErkjx29SKKUxtUQ9d1PPxQZr2QyxVqtZplWQjOFhZzK8tLPob9y299w7TMU9fP/833vnlwYDfNs5V81UXcYjGXaNq6QRb0UESlUmV2dmV6at7aCKkkyV+9dmmkf1dZrGI49uhLT4uyHKWYppaWxak5WuGnp8dx7JUTcFwgiOLKwppuGJVq1bZtnOQzcxcW5udisfh7eK+92znoTTmWZRK2AvSq7dCML5rcFyDD0xeFs1V6rY54PLeNojfXdkwYGFfXmvftw9ua1l++WHp8VJ0YA4Y+sh+5/4PUcsksSI6PSzVHm+hr6bGz5SaO2yysIFDU8kq9vLWJDdyKpCAktX+k79zq6acXrqSJuOdD7WJZ1ZAsF3dpNkX728Jhmk06obCGabpzan7ySn3GsEwKBSVQcA2YBr6XjFOj9sXXX4thCIlYH84EbQR3OaimK/m5Eo5bLGwsLDzZaLzZGcuRzWZhz+47NS7iwDjILhq1nB30owyEETqmlnQKwXfuR3r6nGoDuXBl2cHMTGH19Fk5UxPUcqO3hiJXcrCopIAZ0DWrddDFA76SIaOl6sWVxmxhyN3WAXpFt4xHYnpfd2N1CcVhYWkaD/CmReKE0by1VTehSISsL63ZugnZihmwDNzDWqi6EY2FAkE/T2BGqexYTmKFDmpYO0sfvakPkazyYn61lvcBYm1HrHpTV2V1ztE0zg0GH+aIqtpJpXjHd0z8ifs6KMH7MAfdsQWxASYLGhlycWqDB7hh46brHpDQtgCCQJbu8H6XCQoLS4gkSDYAj30fXPdohK4L8HDaLK8j/qiBMK9UAaEeVscxdFfTPSaLbfgIlAzG88VavVyWdfXcX/+RVvfM4XCSCjZ1KbWqaxs6zgOM3KwiQrANIKGqAduCYJgAdoznbZRdWV29dvKZJ//nP3hx33NkVlku7FpArZUshHRIfsM8+hVChdRoWLqxcTWOH3VZgs2XG1dGX3ri0VecTsuVguO4sIvq9appaBrMYCS7WRyCIKiqqIokWaYFwRBs6QmWcW1sbmH2sSd/tHn45OxEQ2z4cJ9cr9VLWROgKB2CPUNr7yIwFKtWq7quu96mjuNHHR9GiaJ8/ur5eqNuWubliSsfuu2+9UK2uJIBimyauoOyKE57B29cBHBBtVr16i4ggDuGD4Uol3j61POqoWVy6+VK+dadh9Yya8X1DAIDsVS0XAQj/QiCbuBwPCNAQRAlWfbYNK7DoXZfvL1QKZ0YPf1zUQf9qhwbmCKwMMdWHMc1Tad0bRKfLOkWRQIYeGlRx/FINJ7HtsV3JnVBoNK+2J7u2plXMIAUDV44bkokjBFsPLGza9qCdf96SIFgz57OgxQiCOo6tu1QJC6q2s19nSEUquVz7d0oe528/qnV7mA/+RdYvW6hgLRsXVsmJaxRDZMp2Zbq7mh5cUw/5wTKS1AhjNEubF7VL8xBk9ec8xE38qbLwQnJki4DmMYM3qoiQJNtU9RICiesSOTNL6YQVlhtffavADe4WCgRLM0QqEspeIJJ265vwbiOM2D6IlGYR8cXrFojJhZDhuSBkp2Sk5SwCEdfLygYSqgugapQ8NlRPZlu80UtAlWYEADgSfDYTdDho+DuFzKTaiShdgyq2WmUGBeXJrDosGXDy2dWwq3B9dGyrbikXY41NVdwpV6f0/kUgE0+zkuSQdGA5jF3RuPnIQTU3ZDq5BvysljTGxSG+3h/6VBTcXncbQgYjkdz0IO7901fno9DiXP6c/YmBv19rJV5Z3iv+NAX3Cee2ni8gTKzHM+e33UBzwGhZqTbwM03kbIGAlzNhEAg4h65E1w46dluFHMw7Lbddn8lXxSnFzff0rVsbxZnW55zP03pjcLwJz8vlwqMn87LSqyrCyVpsGHwJtYqrqX7mzq2793//R89bHlEwY030A3Hsl4BEhp6ur1n3/49y+s5CMVzHprvtSyqIjUYlundfzMzvzierQJow57UdnRFs4wNpCFNq0rtox/7nCo1JN0eW1p7/dWLkhiLRTDI/eQnv/A3P3x4syDVdV1d023LMgwD8nxHnVSy5e47jy6tZC+de8OEJlcqMCyF4djtt9x7aW52fK0EQYRXvOU4oiBqqmbbFopjpuE89NFfkhu1sjdCvVZE4Q9FRFXh/D4Yw774y1/+xne/tznCeQhS06zXGt4JeOAuqC3VdsfRm5bmFmfnZv2RYLFYPLrncDQSt2wHjkUNxzy0/5bw6tLYfAbesNyxHVsUZcMwHNv2THhM93Of/FUSwJPHnvg5ykG/KqFiaDpNMZwqKxmD4EdGXONFj2GNIghNwggKe/6wJqqa2x+6pyTnGgsrbdviyV9oufh0RSxIVy85iVanittMCIsXMWjJHBrpOnFlHIE8zAKFYSxNhgneBZCiqg1Z2bV9q6UoixNTJM384qFt1JGtDcCpaA2maRJHYMpVy0KjSGIu4asVlyTlEjVZC02oqFcLnAfAIUhkow40SoV9qgc6Q1HUtj3IjudWo3vDBgyAuvHv5sG5YViSAccRHJd867VPgJfBFABTGADY5jMFAGZAHXhffi/J+coLUQDIxpwMwCtotQZApoAMAOU98PqHHQAEaGry5sNBe3f/5Hc9Wkce5P/W/W+fBJ9NLCHQZE5OhWFsCGep6uRpPXMBC7dWl+DqShlybZ+9mt425MT6hGvf0zKL0AANcLa6nO3askXX9PWG1j+P+zWLxNSF/JmXn/LJ1UbNaiAsteQWGmhMzhdsw2BpOinH0QYsQKUf179zUnn6Hbhf7xOl087wMEwQgGI2iKsbs2Lb2gASQl7foOMABDObmmxZdbu7gWmDQgWEXhmqYRju3ruXpOlGtb7h+bKRE/EO94hPAEJcQ4cgmGJoJjyAMj4vJtYbrxbbwzC8dccw6fOT1Cs47Y3vrmUYjmt79FaP22TDCBxNJnAfx/i4hQsvvP70m5qSBw4caFSLdDYPQdVN4prj2Iahud4JwI5tYyjuDwai0ZCPDy7NeBP/V0VR+NEjR9fWlhmO2x47FEgAACAASURBVKAne27UHtLH0B3Hdj1zSNh1bIql/aHQgC+Yyb0yCG2K57g777xbURXT1LHVlQ2W44Z5F3AURXEcayPYOhCA+IA/GPSHU/obWg1QaO+e/RiCrmVWSR8LQx5/ZfNNLMuSFW/yCyDIa4PFcS4c3ML4KIbZdD3DUIwkqOFduzACy5TXA7R/tpDz3tx7B+8EVE01TdP77RAMXJcN8DiCNrd3gBfBz12ArpdMYEJesTEdC/fdLJfqFnAgF8EIlmSDNuqQLG8ooh/yRcLpWLBpZvVKI1On7v7g4fuDp37tr31VonYiZOEmgYfiQ6GO3mYLAMt1vfsFACIY5YMBxFIJAmN0WlLVRDLpOYL39pw49mIKJo5kqW8snlF8ScRFYJQBBqybDV1QqlD1uiBrumIiLoBdqbPf4oPs7DW5o8/iAsnzx375l385n8+vrKy0tLRIkqRpWjQahWEYw7ByuVyr1drb23O5HLwBGz527Ni78EmyqH9pblornMqObe7OuWfBpUtgPGpE7/2WsutLd8wNbalnA2qlZhrLrmZGU0RLPDQ1Oe/gESvYQfSkSkLUzi+A6esg2VSWI9XaJde2Ams2s8SRgalU3BUpfzEE6pW6Y9s0iylNMc00OCJYMUuIYQ6vun268cf1J1fN+Ve3T9/Pmp0EYsNlk962gbkRHTbzoDDixTpF9UIehkOaamsGNDXlSjLoHgAzHsx7c64nrC2RW4ZwktzkYXs5DWfzfbz719ZUyCuWQE3DEqtr9XyOT6Zs65V2PtPQzz7zL3d95tdgD19NSLazyZl1vVYr73DTNIDroBhuWl795+zEhPJGX+bzZ47tP3RbKBzn/X7XWQPwBtAQeMMEBKPA9ZiKGAx7pSMYMT87e3Vs9PWHT02PXxy90N83CGOAoRnZdjyT/40SkQ0uFeKtWx0nEgphGFmrla5ce8PhEAStrq54MACfLxwMgfl1Z4MtB3vQWy854zqOZVkUQZIEaVvWiyd/IkqvNRpIqjxxfdzH+VKJJu9z30AReshBb2IG2bbtwQkd7wSikQiJkxcvXxLEBsVS3scuCzAMXb58ASHxppYWhmI8mCwE247jpWhg5BXXQAi2bYfAMJKiFUW5cP0Gbtrv8xz0xn3m9mwlLRIHbAuMJkrraw1dQBCM8QUI2kdy/p6OXTAMhwgGMSG24TphbnVptmvkJsVq9Jac5sVtXL3bX+0ayuylOgQRqQMYGV9cxlEUwkiO51iaikYiAzu2AxgWK9XW1uaJ5QzAccY0eJaJhEJT1dVlEfKvYnaIsRXgoFDko+1oK0X0UtX5NdsAUngJVFdh00BlMf/gLzo4wV27gCBINpvNZDK6rq+vr1uWVS6XG41GNpuVJGnz51rNM7jJZDKNxjsZev1HKU6mF4vjL56aNa3XgqMNbBGIklnquz5W7ElamCuXVCJA+ZLdnSMjB4Y7awijmiIdwcb6woovABwLZGtAkNFI0E/hliYza1I7k091Xxlk7wBcQmnIoIkyVsssDMThJmVLM2RWVbFEC2DwxfVcZeZZZVx13zMC4buag65XwbGfQP3DkA1cSQEuRJEEF+AR4Jq65u2gWCbEkqCzG5y9AOdzYGkedPeAY0+CZW9p5DrOwvGn1UqpeffBzNwchGAQBNF+nmBoy9jYIYQgYGod2wYzS2v52Rm53oCV2swzr5FbV2bGZ69e6h4eKZQqsm4BCEJxjA0GvON0zYtxtpmMBEKR6IXTZxDIeeGH3/I4tj9VtVK6PHou3dLNBwPj84swinlYHB9LcqxpeHkSL9oBa2Tr0Pj18W///Z9OT7whQoliY2LqajScSiQSV2dmdA+o4tUZ0kE/hCKGpsIwZFtmf1uzYxp/9MdfOXfxDVBwSZb62vsWFxdxitJNY3Yt69FjgYsyDMn7TNN0LI8OTqFgoLv9P33t9x5//vFXMww4jg8PbIUVa2VlpSap0Wjo3NVrLuR1qQEEIQM8TGCGpkIAsm1juKfrsRce/9pffN12HYZharWapMp3HbxtfOyCbhq5Ui3o92fLpWypgqKYCxyYosgAb9m2bXhUco7Ckk3Rj3zpk+Ozk+Dd0nvfqPKqXAdQPijZjixeL1bquqTWLRT2+yNtqW6/P8QFov1cmtPB7OR5UZXPPvaIh8SJsJH2zvratR57SbnQjDsEY5FR23+s9HxNXVX0elXTYQj2dbWnhrqDTbHmtq5k/zZfND57+awrCpfHJi+eH22NR1sSMU1WJtBaEeL4MVgDsm0wvjiCtgfliw2in3HmKrrgSIElMtQIsWY0DaWXTnQL05hPk52i6pbooC2aOZjSNKhUUVYr8kpDX69rGQ2UG/q6bBeqyqoOVUi/9cpXcON7wPa+Xn3yRl+6gLyyZLyRNlaUr+znbK77UAj3Yf6ysJQp36CdsQxqF/XMwpmncueel9fnHVuGiCiCKShu5BZme83neorPUvXVRqJdF1UQ4rG21siukQcPHKxzvoLfbq/FE0bc70fN3ggcCMDFgpspUyj8Up9SMYu1/GrMFw42d5154icvV6+XnHdjNPpZafU2DGh+CqYIBGdcAPv9PhRzSAJzXci0LAxxIbkOimUkm4O0ipNoBq4JfvhP3i7iply3vrbsAlODCBglMAJjeBpAJkFShqIDb3ltq/VqaXnF0YREb9/4D78lvtE/U6gWZVW0UMKEUQjAHn4FszEccxxvBx5CXEuVcrmCLtUrKzMzV86/6fRlqYERpGKaZUWDURzFMSbAAMjECNLUNk7A0lWhurowN3ruxc2iiNdL1dQgH6w2GmuVCsAICMB0kEMwB8G8Sahj2S5kI4Zw7vRLpy8cf1MCVzd0DEPDfGAxk10tZFTXm7qiBEH5Gcjr1MEtzfAm9ZY2P3H+2VMvvt6QvampaXp2ev/wnmIpu5LNF4rrazUBI0gYQGSQRzEHxlDH8rgbLrCq+bn//i/fVzU1EAhssASUutDoae0Ms3xNrmaL1UJmdaWUt2DU46GTBBlgYcgEGGZrugu7ulR85NlHJt4eO/B+3iTcVC1jJ1ggxuxFyBU1HSYonCBg1CZZho80KwC8fP14Kbfmj+h0ICDWy5bkXn/20W2hIhXNdv+OrL+0NX3saK/bVTGnNOrCxGIRJQiURBg/ixOon/XzvA8Y6tzoubnV4upqcbit+eHVbL0uvLyaITlqLNgYKuyAXKjUGMdQJppnkBTp+wQPqzpbd+ccG3as9BZVL0VhOWhrGu76MZmjAVOv120IIoio4zg+hllbmHw1lXxDwajb0q/mF0lb95a0iUTCS1trWrH4TmaMN9Tg4KBt27qum6ZJkmR1UexgBi7XT+Yar6x/ozxH4xgCw7ploRBUlRVB1YCh2YYG6kWAoHTKJfHZruFE+ersL4xUzp6v9l9/unXu1CqbmjPoZSxR8DPfBipTbPTNFBq5nNhUzhXV+ux2mMDxpVzc74snO1Xzan1NYHSYH9xVH89OlJffist738tdnHNqDXDrQwiK+KN0U9xvO3ChVJmbKZgWgDQXLQoYMDWKBX394K/+KxDeMIDZhj71+CPhmz+KBRlfEA+lY2GfvVZxgKPUK4ZjgkJeIBGLjcWM4lru2ptX2a7jXD15rOXA/SgfxWmUjfviMZ9mwNVSoTinO6ZTs2AE1Yb7B37wpz+4wcm77skXn9ii3oXwcYAALkZyqTjPWMWKZRuSUjdMG65I1trylKa+oUh0U6Zp5IrrwVSn4aCI5RIMyqT8kSitqLCQy9aWDMewl7LVs6efvyHv4tTo6XuO3ntleq7kbUm6AAdsivHFEzRp1yq6pYiaZCuq/vhzPzbf6EnNsuzExMRiKdOUaKosLc4UZNdBIBvCOYxqCoUjhCRDAM0Iq5qtm//j2I83mVscx62ve8VUpmV+/9lHvv7FP6jNS269nJEsUbNxr4cIMGmOjSVwzBIqitkQDEV/7MRTpdq/+z/0P1zv2Qx6wywce+BTkfVFUeUiCslClqPapgEwGXUM4ExcPl4tr2MkbsqSvzlGBHinIvPH1u4sMorE7nywrrmydrJzzL3a5gzUg+sYokqO5XWMKwbsWqxthVluZXb6uZ88g0Ig6pguhnE02RKO5PLZCWSOkyvhEtVeOaw59Yq9Ahu+7GhNnRPKz2drasGFqiKfK5ewelWv1+qb6QtRFIvFoqqqsuwBlwVBqFQq3pbgxtAHv1GvXqbrAIx0xYq3kNwkzxMEQdP0Zibk36VisVgqlSqVSr1eL5fLhq1XzaJsi5IokMD9+L4dQ80p17ETLNUT9fMUFfaxW9MpFEMrouQlOzUJoUN4ML8wP9FiZYcT2umxesAHj12vtTBaK65n2aRAVe2jrTeXkc+t0hL/TCLQYOCotKQYqxUXMralBoiOFt/HdyaS6ZzVCPLRpW89IWTy4L3We+MHrckIAFi8WdVtDHEMQ6mUDVlSCddGKYZAXMOW7JGbwIUT4PknbnC4V6oE2KZ2XQcYAum2ZEp2vSQBXcNpEsNQjsGa+/tP/fnXdOkGcD/H8rIBgZYeCCCOBSDENDWtXlBMWcMwBCeJoa6WsRcemx67cMNztz1MlJjo3ooiqKm5OAHphqTVTaksuq7FsmwYM178yY/sGznhecUYucyeXXsdnDEtw7U3kiKQZkq6kBO98j8CWxg/nVtfuuGxhmlUG7W7Dt+RawgQisIAckyAEUBXFaWkanUJxZBLo8+Xy29YNBAEwTBMtVqdnJ+688hdQFcblouSpOtYwEEwHLNdyajrSk5wHXt5ZXJu8RW/gUQikc+/covmSoVQKLRn55788pJFkAhGusCGvBw4huKWIStKVnJVY3ZlYnL+GnjX9TOU4vCyUYLd3kVDrCNqQCKiwIUMRTYcQ1OFWnHNkWXHMGEYZhDL0iQ+1Ka8XFhfzE1ljJzMN2JJsth2/WKxZJQVop5TCSRaJ/2UYRi2aVkuYSuqUMyPjl3VvfIlyEA9U4IQgUWQwamZKtSRg3HXYesdpUO83iw55UnnKq4TVkUz9bqFFCvuGgiZ6SanNWbHQ25dwsDGLoTruq1x0Bp3YgFX0lDXYwLDtm23xABNwts7zYaKWY735Gbt0caFQroCwwBzfipxQ/8LtTuve09PNrB1xwtJIRj8wZ2HYZJaWlvr8HMMSdI4HqCpsOf85LQn482x6HQm69qmmp8SV3L5S/OZmdWP3hbGIGBb7vyy4JiA8wG2nqsFTEVcOXCqGhIXJHyRR/F4pAWQ2Eh6D1LTAsHUM0P1eTdblWuFqWX6zPTssfO2895Pn98rw363nEVgoNEhoaGLki02REsSYZL2c5SOAD0UAqUM+O9/B96mG82oFiBgo4GkWK1rGiJWRaNehzCC9bMMTYUTobN/+X83MitvO0A0Ko6psLFWXZRUBch1XalWXcfhgoFkgG4sTb702D+/Ay5LlQUcR/lYWpdkVTFUyZXLNVOW/eFwjAKnnnm4XHpDE+zr5bjOysrc9sGtJkppsqrLiq7CckWSq3WCpmevnpifeEPtx5uUK+b8fj5IMS7FeodLgqFDWsMUCyUUxeZmL8xPXX7TP0gkEpEkSVVVVVNfHj1988hNlqxCPsYybE0WHcvVJVfMVxzDXFybPHfhhVcPD4fD5fJrzISx6WvpdFOaDTYEAeF9Xkm4IruWratAKUp6rbGSXzhx9ul3xn39XARoxwGjpwQLdn1NvEomDdui+Cif6qRpXqwWgGURCObqAqY7QKbWjjeKcJPeuq0abS1z/NxLa/O7Pyx3pP2XVy0l0FABH1dgzrEU1XEAEfJZqlLKZC3TtAncsWwGWD4UCoVCZUh5OnsxmQYoCgxYQyh1qHx3wa774EAc8R9u39FzIFFdFXaje3P8moJqsg4LMqx4xfsbHV+OY9qIYcEN70nP3mljMmKbNmo7kKTCouo5l26+cvMWQTCnb78cDXRFw+loNMowTCgUCofD7e3t1Wr1PwRNezAd29HX+aNzl+MUabrQRt0R5LXq2A6GoIapMz62ORqeyeSA65qybimGJNutI53b00BVrHSMvDrTCFIQh+ihSr0pX2FW8w6yzgV9rcnuzJoMA7+/zo+VZ17sDF4MXNqzh4RtZPlcW5+2Nju7/PMcoL2ii2LGtS12qJ+O+akAR9KoVBO0fMZJt9iFHPj2X7ydYf+mtOK6o2v+ni6qJY6wNB2gjWoVKFIg1XTuz/8vKZ9551+vVArANPzNKba7BVAYE+WtYtFPYFq19Nx3/9Zr0XtH1XKrfoYjeJbv77BRiEkE3VolwXLPP/yP62tvKI97q2RZyqwsbu3oVzSB3dLqkhidCCBCHRJq519+8p2rLV3XvTZ5NcIGEqxfUkSquwkNcHiYRVVhduzctbGX3zp9SafT6+vrm8+runZtZvyWrXuVatm0TKw9RsRCMEcRjj49fuXshedevXAcx1mWff1q1dvnL+dd1e5PNFcKBcd2kCTPtKQglsAQc/ra5ePnn327dcPPV4De7FgpLJocjMApvwpBwXBK1S2a4s1azjQNyFD12bK5IFeq7QrX7VKcC2MuQC1AOz6/e/WE+7H7E9dUtmzICAQxGSYCDEmlR4bxQJBobZaqVVOQYIaGFclUFR9JWSTLhFyNW2xpIdMtrG05PXssrP/6hVlNMZQt8FaKJsOBoJxTluGZmq8qAVXVgap79xPkFVd6sh1I0YBqbPQ6/lS2AwwLSCq0URv9mjZSHJBcw7MrYqlU0nW9UPCaWUulUi6X24zOr9/0+18zm27zxxwEOjc5E6Qpr1rI6wSDaBwzvXIjF4WRpXxx71B/hCYmMp61ro8Id6UOHDvwod4ufF+kTuJQiMPOXRXrNStOgqBmYqgMI87u7X4f514fE/rTqahrPplsXR3ahdJqxT5bKxB4o6M09mI2+676Pv8sQmMhCPaxFgFjALLCSbirQw8EXYJyTj/vnnkO3CiH+yYhtsHxPj4QDqXbo6kESTJyITf36D9plX9T7kgXq8lEOt3S0Zxqbo1FCctdvHxq4vRz5tugWN6kRiUXYpnt23Z3JtMtwYC8unL+xJOF3IpXUPyvSZbFaiWfDIRGtu7oTDQlKWrx4smzp19QtX8T2iJTyFi6MtzRs21goDWS4B2rMDtxfvSk/pYhDcMwnudfPxGWNWW1kPGT1N6+/oGBLQkuhBtaYWr08uRl8XUZIWajCFoUX9tCpygKxbArM+N1sbatuXNrZ/vAYD8Fo5nlOSu3Pre+UCwX36vOlJ+tTcJNuQ4wM3YSqcluxNYazeltliYWChWLRdxsw8gQlhXS0y3eSxEYvGLs6RoOYZdLMATq7Ri+pNMMaxZ6QGKUgkEg6BdW6yjtD/rp9VyRUBWp0cAgyHGh5mhEoio+Oxpvbtqxo2libDzEYm6rsUiUyifcxImJ9mKTXMZ1Gho9rMFZA2lY0WiU4zjTNP1+f6VS4Xm+0WjYth0KhRRFQVFUEIRAICAIwuZGxFuFY1CIRHDW6yLIVWQURTdCt9Mc9SqybAfOVRHXm/Z6rVAtcUjR4ajfXspjlu1FZ8vyKn/e+TNcn3MCmvSB4YHptXVis+4eAhRJ2gAouglDUJKmApD7yf07T07OSRr94ZE/zKsz4pj4x9ydLcxqTy81u6DeuYuTdNDZFevffc/ExeNSNYtTWAbqs5FrwZmFvEtWt95mKRZqj+RP+uwG0u3LTxbf++zzeyYYQXcdth/6VYSlQDJlE1TVdaC5RfvyVRAsgdoqmLwE3hGcilK+vvs/m95/MxcNM6EIjMCmYa1euSoXlktXTiiFN/Tv3VDh5t7D93+6pX8w2dqGoigMQZqqZ6z5WqGoNLy+8H9N0NCOo7ff86FEc2tTuhlBYQiA0C2MWNeK+cwNQSpvEs9HtvTuuvX2B9rbukmahCHQ/NkvHz50/4svPvPCiYf/1XmoqqvlhhAMN3UEW3x+Hm7uPLx134ce+PT09clHnvrB5YlzrwbKQCBQrb75imbXF3XL3NHTHRdBe2vz9taeu0YOf/6XxEI+P3517M++8/9WhSrLspL0BugXSZKqqkq6cn5hcn9XOAhbxetG55Zte+75NEpivwnc9cK6VBIee/HRHzz7I+0dVz/vgt7jGfSmKoKZOHyvwzmV+eV8ZalUWHYUFaxUHe4gSiQVJORilBdyPN8Dr6jeA5vqKh0LockmpA53XBX1OK6uQQ4qsJyMITA7sgOGHPv6eENSIUUoVOvbutpSwdDAlq4xYQJtauvobG9tHimXKseur/+5nMwQtJGEt6yw+xRZctXLTe7o0DpdqJKOYZmOruuCICiKspk79rJgG/uEsiyLoqjr+iYKS1FuPFdCUSgedIkNt8iGjHhNSxsJkFjQZUnvBhQUL0BvPhkPAASG/IxTFmDbeUOq5B3Ea74mNHHT7b2XJiZxFENRxEdTzYl4KODHPAyCbZnm7Yf2A6GRCgYg957elu3nF39CZzrYM42JTOKATytk5dmSCKFujIfzmTyJKecWlKrZr9KddHEpU65mKd8E09o83M5QaGNVRQ0HL1+dGh0DPxt6t2fQrB/5zO+hn/11q7XZScQdmoIwFEIQh6AxxXDWyuDqKbDyTtkJOt6698t/3HfXB4JNKc4DJGA46gmjfVZDL2dySvan/aRvo1TX8EO//fWh/fvDsbiPISkSwzEUw7FYIunjI8VCUarcgGz9em3fffuXf/cP23v7ItEITRMkgeEY5uO5ocHBeLLr2th503inObifj3zm47/5iYc+Hk+1MCxNkjhBYH5/oKkpvWvndkMD45NvaFF5q5oTnb/+y7+99+Y9FMURNEFSOE5gwVCoq6dr/969uUxxYXX29bzXt+aFt7Zvv+Xu+zqHelGEICiMIDGW9Wy0B7YO7Nk1Mj89b8N2dcP86NVDQqGQJEmGYViOTRFOKtCb2DUSb057jrwkQVBEOBSKpxI3HTnU0pR+7qXXctk/jymOTcEOtMUaou/uEEs5H013JpsdSdN0Fm25GUl3yoWG16NFELDPh4QCcMAPHBt1tfgDdzcmlxq6lh5dNiFgCC512zBaF+rrk/VrE42JSakhuZZWUKyjO/raI7F0OkWnreXqKdUlIiHYlCeef/HKyaadYPsBPBgiHLejq0d76YVyi/nirZy6o5W8OjMwXPvQiNwX1y/PY16TvldhuZE1cL2+Utu2NU0zDEPX9beLzhsRFmooWFlAahKy+bf25s+OIyhYseE96bzuyYaCiiqcryGb0fnfGKD9Buc3/T07k/8fe+8ZJsd1nomeqlM5dE7T3dOTcwAGGBCRIMBMgUkURSpZlrwrh3tt73rt9fq59u61r67X67C2bK0VHZRIUQwiwQQSJIg4yBgMJufUOceqrlz71AzFIDFJsk1J3PcHMMDTdeZUddVX53zf+73v1OKspcVsmjhG9PX3dQ30FwoF6y2iadt6uyHL+twuROvL1aqVuiDpdgRAiXC0dYitKCVkZZqr2Tn9pk/5cstSKt9Mtw8I6ytYKulo8BrB1lfWmMRCPjmTZJRiQ3/v+vxs2aIYfvACNIKiv/Z59OCtaoMbpXECogSG4hDDCIiRuGFzEgahRSsgsWDVit8qUUDYPdt/4/PBoSG7m7cCK0RxiBI4tCxnGYrx+nibu5ArKfnY25X4vJGuD/9ff9LQ3ma3WyaxOLTcfzZGwAiSCIWCDO+dH7+sSm/r6r1914d+5df/gHa6bLwVW3GIQojimDUCTpHNYbes4POzY7r+1uVNCPGP3P2rh+68m6B5lqMIAscgClEExyBBYDhB79o1lEzUlpYn3+7u9TobfvVjv3nw5hsRQDIbI1hMKGgpFmE4xrDcvn2752cW1jaoIK/5vb4+ARRuaR36zP2f7h0ahAZJcxbvxdoEoAiGW0o8Pn+gu79zfHJ8ZfVNZBKv11ssFk3TxCC2r+dD22+8NRRpJRCSYiiMwFCrwI9A62ywru7utpbm46dP/IsUin6OA7QJTEeSspW5cnvV09HREWqj3LZSYJjq3SvMLcrFGkAQ0saTDjvitJNBr2mavIuxdzS5+lpqufjeY2hJi2IaFerxiO4morLMmXUXS0NdW8zXhhpcA22tvQP9MaE+LZ3c0gfWlovpVGF2OppAvdm+3VuadnR42qpapUpI8/t8iU8PzR1/RlEINl0UlrXJeWJiGavLVpTEMBRFrMZaRVEtdZV3yzy8hs0Poyjq8Xg0TSMIwufzaZpGkqRpmpIkbcb9zXCsvxnv5QXuUmxe3cO52bKSrysiheMoTnVvGWreuVdVFUypp/KF1pYmO89zPDe3UFTqTf2d3ZO5GAoUB8aNufBtXrPLzWQqBaiV7WRpfFRZXZCqC3NqIuF02ntbw6NlfKGKuVlcE6uEw+YeHEwce0x4txLWL2SAhjfeB+683wy6yfUl9sgT5POP46vLpNOF2+wGhMjMBMrzKE4xtTKPmTTDWF/pG3ztEBT23P8bHbv22P0uOZdcPPL96ae/m5ubohiGc3owHMutLNk9btOAaj5GkYR1E7yZBIJTzC2f/N3G5ogv6BNLuavHj5x68qGFsUsoApweP0HisdW15rCvXJWFQlLT1B9KNSAI4vSEP/bp/0TTqL/BL0u1S2dfef7J71w+d1KWJa8vQFFUMpHZOtgZT1Xi63PGj9yBlh7IwN67PvRRWa01BIOaKo9dPf/UUw+9cvxIqVQKBIIMw6RT+d27h86OnC9X8j/seAuhjeP3D998280fSuWSgYagYRoz8xNPHP7uiy8/k0wlPG6PjbdJotTV3TlydgQnLb/X1/LIGIQcy7p456F9h3bv27e0stTU2AQQsBpdfvLZx5549tFEMuZwuGy8ncYpr9d94vRJ5Q3pmlAwWBdFO8N2hTo+dMNt4fbWlZWlxnAEQcHK+vJTL3z/0WceWVxe4FjWbXOHguGwP/Dy6Vc+0AF6Uw93S2abGYV69xrrLK/l67WsE2hQyhSVmoxCjHHacYYmUCRmMAAAIABJREFUGv2NQ42GotMOTs2mYTJqRDr2HAVGOSciZSRK+hzHmjn54N7hnXccsjM0r9VDNt7v68TKnq+f/U60ULv5VltNRBNobymTjLVt9XYOBd3NnCyPnH62plTy0bVCrVg8Pl58/AU7gkGUVFREsRTDgI2nd2xpaYn4gn7neiz3Y+57LJkCCKHD4eB53uFwkBtAUVTTNPm1BrOfFB7V2YI3yyVdR5QKksMh5utoa+nrcoVCJEkmlxZKtbImC2NXJl86f6XJe6vR03ciXErEHqs482l8FTfseuj6YXu2JRApZaupOTkepVoD4a6uHqNc5Eno6+l+LOdzb9n14UN7a5CpVXPV+cvRY0+9A4XrFzNAIwjYcyt6071GVyf/3GPMV/4MTl1DUwl0chQ5foRibUZnt+l0gsVptqmpmhXlri3abfcQNANScYvGBQDX0HTd5/6zs7XH3dacuHDq7F//t+TV87VMKjs7ufDKEU1RQlu203Z7Zm6ye8vgaqred/cDwb4tqYU5baPshmL47jseuOXB37C5PJGutuTK4rf+++9NnT2eS8XjS3Njp15Ox6O9w3tsDkdifXXr4IDJhfcfurdWE4qZ+OaXFWrs+K3f/dMtwzfjmNHZ318uF7/w3//zqaOHE7H12PrypXMnpsevbhne4/a4U8loX09v98Devv5tc7PjimJdW5bhH7jvM5/51G83+JoJCuno6lY17Ytf/NPHH//G2upSMhG7cnnk3PlT/f3bgqFgqZjaMjB82033RaOrmaxVnYYQ9nds+Z1f+y89LVt6OwZLYr6vf9AE4B++8aWv/fPfLizMJBOxq2MXT5w51hAItzS3GYa4fWBnV3vPqTMnNiuHHcHmj931iY/f9SnW4G4+eOv04vTOnXtQFH3s8CP/4+8+PzF1NZtOjY5ffun4iwRG9fT0o1Ab7t0Zi66n89YCnMKJQ/tve/C2B4eaB7yUe++B/TPzM0NDwwROHjv50n/7q/96dfxyJpWcnJ144fgRQRB2bNnhdztNSR+fnzLejRLzixygHajzPvNjaMXQdiW0cDp2tVg4HtVERCsUdZT0hRzdvQ2ugBP3OobclFYopc6O1Cty5sUTKIoE1tBtmcYCSCalaEksSqDEmEIxl5ALxfmlSmDuVueJG0/Xjmrd17a24TShKjW5hDRna8VLrF+hqAKFXB49LlbzQNc4h3vlfz5WnbcWhi6nkyAImqY3tG6hourr8cJqNBdNFHDCguUwy7IYZjnMvsMmCGJm5y6hXsaBgddqtWq1WiqVisVitVoVRVHX9U1hvJ/m6jUaDducW9tcPXIJySErGG662vzBYJvT5UQhzCwtpFOZlXiGJ4hMzSV495wtjeROfBfkC5ioQpRqbt+bjM6MjK1OlBryeSOeqfp4vr+rOdDcasrVOEAmI7svjKcUTS5Uc4nFa9LS8bXnn/ihZd0vfoDmHOAT/zf64V8xwkH2xPPU09+Se7aL+++Whq5X2vpgpYhcPIm6AkhXt0W6JCldEJV4Rt8yrOw6YLjCYPqSq6lz13/4U7ahxREM5KfHJr7x10ywKXTgHt/wQWf3VlNTExdP6ibWuHVINwFG00KhlM1Xe+64xzOwV60WaqnorZ/8nR03f1gHuD8SLOfS3/+7/5ekmcEb7u7ZeXOkb5jmbItj5/KZbN+O3bqmEzSzsLDKOAI33vMxAJnV6cst7YO//1+/WK0qJEl7Ay5IkF/5n38klPO799+5c8/tvQM7/f7w8sLE7PTEtp3XI4jVPbq4nNy2Y09z2+Ds1GUbZ/v//vDL1w3vnZycbWyMuLwu3u746lf+YmH26r7rbj6479Dw1j0tTe2x2Mq5c6e2D++1cXabjU/ECg9+9Jdjsdh6bOlzD/7Wb/3734UmHo8l2lrbvA0+l8v7yGPfPH7ymZ0Du+644e6926/vaeurlPLHzxxtbekOBxtZinHw7sHObWcvn26PdPzxb3z+lgO3zU/M4jgWDDaSNrIx1PTyiRe/9ehXBlt67j1w74EdB7Z2bQGG/vLpFzjO0dXW5XO4Dw7ftLy+UhEqv/eJ/3jPHfcEGM/U1fFQY9jt8iEkbAo3X5sc+8LX/yLiDtx/4J5bdt68s2+7g2GPn3vZNNCtA0M7BoY7GtpPXTnzr+2u8rMboAVT+BBxl6hVk9mEtox5ngnDmJDvaJaqEiBpp8/O2xmTdwCvM1GWZp85XUtVTIwk9BrgnHGi+KHV9oKaJFC8Se7v8PREWi50D6JLc0Lb2qEt8Y+sH3j0fNsjW/vY7m57aq1UqyhGdrlnu2N2liimErVz56ilOcZQbHaDdTTFnzuv1a13tcvlIggiHA7zPN/W1ubxeFiWjUQiLMs6nU4URTmO8/l8NE2jKPpDleI3wrTkEVChBK0fNhLKDE1ouk7gUFbUTereT1mIcCGu7b07O3Z3a4hRSRYlIsthhNvJsiSuFIqpleX51agPQjvvEiOfjVWWElOvOFz7dWIQo7oZ4KqtjyG1QsIIzQneOTkEDCyiR228YG+DL51Zje+4a+tdtyzNFGV58YZDTQUpkVm8VFvPWwJsH6gAHeoAH/t1oJuYkOMe+aqw61axe0gHuI5ihsclD+0Gch2eeJ7YsRv6GjQTZR2UupbC3W69r80sSyAX23nvr9RFzWoyxM2Jf/4brn3AOXxQwxnJhLjd5u/fRvC2paNP+du7PK2dig66nfT8aop3u90+t4GYLoLdfceD89Oz7kCAtzMvfuMLJM31Xn83yjsEHeIsG2rr9Iear54+QlFU19BOAsftuLkYzba1t9gctsL6tQc/9QeqqsdisWAoEggHn3joS5VCdv+NH+W9AUHHUIppCIU7OvomRs/kcund19/M0pSuSWux/ODAQDk32xQe2Lf74OUroyiKBhvCDaHASy89NX717G0H7m1s6ZIQXIOk1+vb1je8sjw1Pjl6482HGJIqlQp1UbXbHeMTlz5x12fdLtfImZFQKOz1+gOBwOjExWee/d4tO28aGtilQ1xBSKfTubV7q1yvnRw5dv2+m212bm15raO1e+TSyUP77tw2sC26urawMNfZ2e1yuBtDjSvJla/80xf29m4/dP2dKEUoJsHy9r7WrqDLN3LtzEDftoCvIRlL2my2aGzhgRvu9oaCUxevlivl/q1bOYprDIaKYvlvvvrnrd7AJ255gLPZrK5Gmm8LN/U3dj710pOBhsbWSKuLtmfSmZm1uV9w09i3gw607ynfVFFty9S+T5/7zU/23L8NbKVVFGM4VFfTyeparLaSrKbipdUjI2pNhixviDXQ2IqHI0Vp5rmdf1YJL1M42Qm7PESPVMazM/FySU/3T8d//8/Ejz5nd4NQiPWHqa37G0WTZHnoJwquq1cio6f6Sueb69O+iTHP6St3EE/u2y1uko8RBDS0Syyc73TPe9DzM9PjS0tL165dW1xcnJ+fTyaT8Xh8cnJycXHxtUbStwFSTOKG/mom2jD0PTs6Gnz2bQPNr2Wcf8qrx9h5jIJEA9440Nxp26FqZCmTX5tbX5tdTSzMza2sQ5pSSLIqq7zbPTv9BGR35kVGM3AEpVXTpcItkuwIMwZHEgYC1/HenM4aQsEG16JIc3LGiC3L/fc2kd3qC889psEcsYCZb1DO+6DANBGWBQ6eOfK9ekOLZDjBYglUUUTn8IZWoGJiY5/CsPzRZxwUaVAkEQgQbidJ4lZPlCVipGuKwjidnNcVPfW8geESG1lfKqZzuki4MU9TBeXrfCPb3D755HcpHAIcdwYDPMtQNGkiaH7xcikdxzHMshh0OlbGL5bzKbpxy/hKeS4mVWkv2tAh8YGUbgv3bD939GlNFhUAW1obKZLACVyo1XKZVC6TQBDg9nhZG5dMrMyMnW3u2jUWq1xaqZYIp629j2xsmy0h7X27r108k0nFdQRvbQ1jGHQ67dm8mEiuYzimarLXG6B5tipUTp14tq/7upUKemqhkNZ5f89gQ9/g1bTc2rV7bXlufHzUMGFLWwTHMARBZEXK5FIQwwRJsDucJE3riPncC4/1RDpExHlsJrUqkP7ugaZt25dEzNMwgJvg+KmjiqY3hBo2l0GGYQlCAQTUFcnpdOMkSXLMk8892uz2uFytL0ysT2eAp7Ov7brhAu4STEdnqO25Fw+jEG9oCm5sgjVZ00iCFBUJwSDL2iGOExxzbOQlTJMHm7ecmIldjUn25q6OXTtMd1Oshm/vGPr+s4+aKOoK+d4XK+SflQBtSahoJx6SvryoTor5pdrFNFXXobBOMiSOYWq5kFmNF2cWc8cvwoqAIYDCERqr6mIN83gxXWTbVrs/cwlsuyzUJ5hLqcQrN1y53AZuQIh7lps/U+sfbrNzOM+TE+PVxRW9txdPyeL/erjA9GXc2wtESxVrrgR3F53e8vnHc7/52+ShexBLNg4BGG62N2p7+5SdnaJlgL0huAHfgJ/gNA3DPHJsbDWaPXlu5l/q0mE+CnbwgEWZICtrOiN4M/niwsLM2ZPHjr18PJcvopZcF46wzdnSmqIhssH84GZDoKW1iEqgaW15qtMmMxRj2PyTw38467z18cPUrL411HndwsVilqhqblUOQaIG5NJbKOf94iO9atZlrF7C5ybqXBuwyk4mBi0/Erefx3b16aS/7mySzx53CmXLE0RDMJ8br9YIRQdLM+DqhdjZFwiWwzEzdemU7myvK5b4MmoxH1AXT3T3Nwu4u85HkrMTYnSFpIiCCnxuu2Y5lSjx8aX40qRcr/BuH2ujJ0aOovamTJ3QLc67QRGQY/CWiE/G7WUsUC6VFq5dxglCxRgHR5uGOX3lQjpZnBo/R9M0RfNOr+P8yRcYe2BNJBQTM02NxDGXjWr02zTIZIEHwemzp16COE4yNreLW1qcmZ+bvjp+LptPOh1uDKfsLvvY2Hld1ZMqV1ZQ0zQwiLjtdMjPAYxIKJzN1Xj0xcOIxcfgGZ5eWpkU68LpK8dNw3TanSiCc05+NboUj67WUFdKRA2LfKQ77XTAx1EMFashGBc+dfrlWl1wurySJop14eFnHxJEEULocXtNHaXtXK1eGx07DynfahVRDaAbGs+RPh9nd7AZwVQwx6XLZxOZBMNy2XJ2Ibp6ZuoSaqAQw1wutyIqBMdopnHm/EmOds+XUNmApmkQJObx8TYnI6imToQyifjE/ISpg/Oz78Ia/NfA+9+o8kZkzeyUcfGzwLauU1pEsbcJhmDWJJPz2plG6yvJLaY0iNAUlCspA1cNEyKmIaHopYvpeRL2hU2SDPpk/WxRMpu6Iv1xN+clSZ4iB2h6anGmsLgorywleq+jT14EnsGqjlkOFJZ+rw6qdRN3C9UoPjVB/MZvasuLslwH0RkqOoMc3pgbRaJBvx1FLdeX5bX0T5aT6O7u3rTkYVk2n887nc65uTnLQu2nAylDVFaVbF0vmDbMJlcxJUzT1w1bDYXxpD49jxMYodbjJCGZkt/TlVM0DCOtjQKCUoy9LpR13UTJQaOY2hK8frxW8g92VX0DRx+5WK9XFFXr6Oscmb9QLxdogm4SwqvAchr9wIEkAcSIsVMaaTNx1nrDWTYkminmUscmTBwDNUnFvWLpvDAzAQd2SVXZHB4UxhaU6Ulw+OtAlYtr85phlpemZbFu4k5rcWQAXVFqmdy1YgVFlxVRVKHbBNjSxZG2e5rTgtazfWBsemnlse+Xl64BYB579Ov7P/6fasVsZn0Fa7keWsKgQFPUSql6LZ2fwvFaqawirIZx4+dPde+8oVTXO9sbz770zLnnHgLAHDn5dN/gjkDTFkPXZscvAXs7gWBWXFT1Uql89sIUCpBKoaAZUCe9Vy+N3Hn/p4W63hj0/o///7+US1YX399+6fP/7pd+D1o69+bY2AWDdBqQQYBp6EY+X5iYjZ65UM1n87pumGx4emqkWi0BHa8J6SefeXhDx+6VI8eGBnu2GbrFh7s0eg7BGA13Yhu+rYVCcXEpeeXqfDKR0TQNof3V3Gy5XOJ9zi9/6wurUYst96df/fxHb/rotu3bqyUZhej5q2cRgCqEjwZWq1e1WpuaWkkmC7OzK5qmGiitKOblsYu3X/+hiYVxwzTPzJ7fObmLYdiB7dtKmar1LK8v5XJpW6QVQS3PAVGsX70yjZjI2NUZSVZ0EyNIx8mR4/0t/QT+TqKVv/gr6E3EzbVjyoXi1nnPn8Q4dF0RiqahOoM2uSRzHEYidVVWVamoJpZMDEcZG2a3VS+dnViQUkXD3SSsBScv06e0W6ax3QpJungWVbXo0vJjswulk1eKoSCgvOa5McW0SZvR2XKSQDccc4DlKofY6hfPYU43vOMudFN7+bWJWarqNGERLLFXJTjeM0zOpSEWPw9dXV3N5/OKoqyurpZKpU1tgTdK3/1kENdL0QtribF0/mpqtbAi6Io/HFJko7qSJnweiABUrEEDrNNLE9UX99/6EdS0bIQQBFIM5w+HnV4/QbGQ8PT13u4woY9i7Ta4q4UMdYRJO1+u1FbHL+kpQ1cN3AQLc1diwi+6b/dbonc7yOaJq+c0xr1xA2z28etA1cx0Gqytg0LehIQKycrMlBZNSXPLKDDrJjBfeR6krS5Te7itlsmkrowAkgcbdtoWDMNyiyoUxGRCK5WsURlnbGqskMytTi8iiJkYvzDz3Pc2f11dFNOx+NLYZdNq1+Jeo88rkiSWy6V0WhFqpqFD1h1dmktGk1MT82ot/+j/+mOxavkZ6rqWSqzF1teW56bleg0ydmsC1tLVVCWlUixlkmlFqhuaBhlXPpNcmpufmVos5ONXL78quj85NRqNr6yvrcbXo/l0jKAtl4CN62AqipzPFVLxlCTVdVXDKLsiidMT49OT8+VaVhQtFoqsyF95+G8lVYxF11PRxNL8FEXZN0xjLVNCTdOy2WIika7VBF3TIU7Z7a7p8Wsr86uBgCXSCwA4denkydGTBEnGYmvpaGJ65hpDsHDTm3zD9SqXK8Zj6XK5YvkcApQiuLGrFxKr8XAwbE1AlR8/8jhNMygCE7FofHl1fm6KQCFOMBvDm6qmlUrleDRd2DAXN3SDY1yXL59JrcUP7Dnwb3/T/awUCV+DDPRzRvJMbqV3T4NAg7Q+qAsV2m4LtwYIU89Oz2oA0VJzGK3jTdv4LUOgls0//k2IGZEmqrcRXXKVV1ryalMep0UI8m6uINYyLx6dqQl6A2YKhrFlr1ytAYkTMcpELGciYL0XN0yLMBxgOujww1CTiRP65DWnoROBQADH8Q1iHFWpKaqOyIqlS+tyuTAMczqdGIbRNP0O5SmIg/btolDGEcPK/VvOaYKwSXxWVUuub9Mw7ae5aEwdBxU9m0iuppZjtTjhwLx0Dt8+RIVCeGxFT6cYgmgJBC52eaJkLTd/TQc+U6YRFHV6G3bsbm9uca0uZw1DD/vYtuZGDEi2Pl/IjSeKanQpV8+u5aNxjcsDZ4nW4dSTp9Tq+yF58b4XCQtZpH0HrtUVNqBjG8/zxlsXqJqlQKAbAIOWuIzTofFuDbNJiaRalQ23D6zPggnLOFXTNMrXSiCmQTkUyL3qZr1hf2cqKtAtLxUrN0oTvNOtUu58KlvUgCEUYxdPbE6hLtTcjb1QUzDaJgIawaz+1A1qNdQkyVKEMQwEQgbHIg1BE9pSmfzSwtTc5ZOvnUS1Wm0I96CSQjFsWcUhuWGraFlHoaqiWsaGuoFCFDO1nkiEgHyuJJw4/tzKwsTr9fy60uBrRuoyReBlFaK0fWOFs/EIWeocFjHJEq7RpO7GRhfpLJTrLx47vLq6sHm4qqmmiTkZF6poBArqBg5Im9WgYoVHBGKwVq1p1mcsa8Umv92JMrJofufJfy7+oHl9e/9wyNmUiscx3cQVWccpDXIYtB5jBLHkJRVFqYt1DLfeaZiqtfr8Zh352mNfF+qC1+t1cq6D225cWV4r5bKYYWKCSPPOmoKQJLuxK7bcyyAKy5Wq9VQiANXVZp87QPn++Zlv599TA/0vlhbHW0IW1X/8f06GDjTSN3m0upq6NpdZyFpsB1FCiinGTjHX3QKaBkgGSl/9rzv34QBjAmEkWzYAR+F2sl4rlrJVQ7Wb1VQuL5UEDoVmCUe9VBXFlP03a987ZRn1WIIVDGBZgGPWU1YuA1/QvP16bWlVkzXD7QGZjCnLMoqiPM9LkmQRMBimWq0iCEIQBI5bfaWWwOk7hlddRWZGOMMS1rDIIRgG/R6bx22LJwu5wr9MMlfDAOh1CiwtzablskzgzOp6CTz2BCQIpFyiaaqzucndGIyZ6bqNjuvLDX1hZc6PiBiCqeEI7A4zo5d92ZRWrgm6XnHxXKWsLZeAgdMIglYqiN0PK+yqx6TCjZ1z5nHwwYRQAR6b2HeveWEMCMbGk2xacdkye90wBqRIUMnKB29BWNIEhNnbrtEcUE2rSLgBiKG+1iae78bjqepiYmMVvhGIdN2K7MBAGVatFENbhyOtoVLdjPS04RwvLr++XdOUekODh+eZxp7+F145u+F3upG7VdQNGxETJ0ldU9xe/w237FuPpTq7Wtdn3yQ7rmtSV2eTVBfvGP7EVx56bNMx1sqTqNZqccMVEEGtXj78zvs/lojH7ZCIr9reOALHEAP9XaJQu3XLfcknn7XY3RvTsHzB67JhdR4aGEFJNe2u+z5eLqZdGP3i8TdxnHxe95atfXWxvr/rVuX8xdWilfTbtGesi5KmWudibVQN9bqh3TxJKBLYlN5/9RR0IxDw8RwliqIvspNOp86ML22YGerARBVFVVVN1zWawSVZ7Wnv3bdzsFaqR4JN2WLWUj0DCMtwnV3tYsQvVmsU7ffifd97znKstr5Ha0dj1KqCrlkuwBDD3DbXh+++USlJFeF9KL38jAZoS4axoi0/u9K/d1KJDCjpLCSA126ryAWFD4MGPzUwjGCG+t0/398ykxFwxK/oFKCzlKATmrVPMU1o1jVpaUUwDRVAHoEEDeSeoXq4WV+JocbGjhFFEZ7HvB7QFASpnL6oGD4SdbjMAZtx5ixer8P2YWHYJWwLGwC82i367WN8vGLtpzb9Bt+Nv/EqNqLzq7BaxA0DQvTHS5O8I/A2p+FnxZSAbfPqz6dNUXYRiKZImizpsuLk2I5Q8AUfXSwhwIRKu8cga8ztqPw06m62ESzKcGhDxJHPp5PZWCo+F62WfPC+ggjSa0VdKOAsC4gsYtRsgSZExWrZH9tn4BcG5nXDuioj7nUgZF/Ncui69VRbft6oJSuKQJMgVadD8wStD5RKQDEB/uo+VZOkhs52nMDqdRUBCat5yfKS1jduRstO21RVK16agHG5GNaFQChWBU14PTahEPZt6TcBKtRqGwvwzR4oS2zFEthErKy4aS2icd5hb+edDMunFt5U2sJxbPvwcD6XI0kcwzGAbHATEFPXNGsEQwcopusaDjGe51rbOxiWPf3KY28cQdOVvr4eURANoGM4bonbAktz37R8weWNdhjLVBtBEBvPOh2tvM2p6W9qxVI0aWBwwFIsEivQ2sBaNZgNuTBT3rAG33xx8RxBQirc2MjQPI6/HqkghtrstlAkCExg0ULy2Y3YalVLTWBYJiwbYmQ4gVaqmrPB428Icrb6wtr8pko7ClGCJFASDTaFLIJspbKSiUNoFWytCwEM0zREqW5ZpFvJdcPOssFwIx7G4A9etP+W+NkN0JsMYum5r+nBuwlnCz8wONjgXPJ5E7EZVRCz3/kymDz+qXsLFy4hziGFhJityGRSKmmTVJxA+ADduheodY2JiEsjOKsjilKtSRStW98jarknWyto1MnbO1lW2hrKCg21QrEW5FFJtu7O/j7l2SeN5Dx1lgArK69TymJZiy33454Iyeg4atesZ8BCpabmpqMbzS5WrNd1nSAIS7N0o7H7J2j8pwyDbPRoLIfXCzbUAHKutcW+9cAezO2/cPgJjMBG3MyjIRvFhqVCVpMk1+6dlVIGOLw4CxUD5ERgd9MowBNpscFBV+WYOrWQXY/L+TJELJmn7q0NSXuzJAhL3xkx1Z+WFPhzjCOPmwc/hNjtwEhvemlvxIUf/CArVsUZw3TeDeJpZH3FXJgGN94Ozry0ebSYTUw8+rWeuz7JOp0b6+6NYzdSDACxnkTTCvEoQCFu9xTy1eTcLGe3rYy89PqqRaw99Q9/tfeuT/mDEQjRjbvZsmw1LXMWS2bWirPW6x+DBCXka6uLoy8/8c03nkEqEf3G1/7iwC0fdbkiDM2IGzq6VoTd8ORGUEtq0dB01FLEwArF4pOPfeO5p99kmnV59OzffPHzD37kcw1Bv8vhrORFaPmCw42LYGVbADA1VUUhSlLE+vrqqce/OfpmU8RXTr905w0fDgTCNpvTbrODjLhh7G15c1tvF2soK0qiiElSVKlc/sq3vpTNv+4+dfry6Y/c+NHCWKarZ4BlOJKkLDkfawSAIpgVYq21l/X2MjTdZufrsvzki0/WREtIUlXVK9OjmVJmdPRSUzjS3tFNkNiGAxLUDRNFAbQsaBErz4NAKy2u606nS9W07xx+aLMX8YOeg/4hFNYUcX7eMFAsQoq8ko7VaxdO155/SBw9f9chiSLpAi7ZbLhj1VubQnracUkQZBM4eQcM9GhC3e3k1ficZgAlK9YF/fyYbgnqQ3S9qGM4Yvf0ez26i3d1ekw70ZOtpIAA5mbAE08iCDBWl+2lPFWqobEcjOVgRea8AatdpSnsiSbym2LQ7+UUIG507hLtTMTtDG4K9kciEVmWfT5fKBRyu90ul4uiKJ/Ph+N4U1PTT+BV6MpRRBUAqV4YmRUReSWktGB1w1SqxdxMKXeE1k4MtTX07bHzrmIuaiqqz9/kaenURaDO4SjB1Ov46nw1ubaEmpBhmAKJea8LY3ZoqiW9ZvJ0vaE/PTd2bfqrx7MTb+vu8YFo9b54EuQz6La9YGnNWsghqM3BMSxlbKa5UARRZSSSEt9wAAAgAElEQVToRWQNnDiF1HKm0wOWJ8ELj782QGZ6LDc33rLvlsTyKkBxBACCZxgbZ/lXqSqAliG308UBFJs6eUat5BC1Ovnkt16fgGnGlmZnr5zZev2ty6tRDVgcDIImOZcNIKYmK9ZO39ScPGV3OEdOnqykVq6eOmK8YUlhGPrM1OjK0tzW4b3zK2uSjgATQXGUcdogiauvXkCDI9H25siRZx5/4pEvvdERfLMsubQ8CzQkGGqOplMFQbGq3Aig7BzB0aqsmLqOoACaylB351/81R89f/SJH7qKYl1w293JZAolqIpQjefLGyLmJs7StJ3TDF1XFJLCEEPpbmr8k7/8g+ePPfNGHbtSpeR1e4FqzCwtWvRRhphZjeOYtcRBCZx22UwUUWWJZvBqTdjS2fLlh774z4/+k2HoNpvNMIxkOmmY+ta2gXwueW1xhSIojManl9YwbCPzC1HSwaMUYV0KE6i6PNAe+ftH/v7rj/zDT9+v8HPcSfhO0HW9XLTt9+I2qTpfFS+cMorprgHs0Meovj5iIaV0Ck2JSclhh34/FvTptaIsSyK0uyiHuzBz3hTKcllVRGTvDtdKUrJ5lStzGsYCgqLs/q3hQKudc3m5omaw56eWz52X/T59cRpXZTKVcCjqqzsMSzRDN6o1KZ0tZ/IVWf4xFrmmgdTypKUxm81mMplyqZhMJms1YaPqni6Xy5lMplQqFfK5Urn8Q5Jd7xE2ARrrlfpq2jDrF68LzjQHhrJru3dotkb0IYS5EnbQrsBQ8/brMG5SK6qVksvmIQCulsXS2ZxQN7MZMbmyrpo1gGJ1MQ14xN0bUmoaDSUpK7j88tYb1y48MVEYff89NN9/saT4GlLLQMoDcIqicLuDQTGDoWlJtnjRGAbMdNKMZSlF0CgMdPWAh/4O5N/kaSDkM7JQUHEHitMQgzYXj2IaTdOqJZdoraTrpWw+lgN6PdzTPfndv69lLBWLN0ISqvn0mkZ5EZJBEIR3WZ7iJEVYZTVVRyCoV627qcHvPv7ol6vF10XuX0M+l8gXChJqPQbARBgnR1oVRxSBqCZrADVlSSikkqdffqzwVqYBlm1brcxy/vVcwbQYFCjJ0zRPoJgJcVytK1a+R5GWJs+dPHNE/xE9P9M0C5X8/p03TU4vrGXT2sYvxiiCcbEoZkCS0OqKzYaXStXxi8+cvPgW7iqxVPSjhz6Wy6aW1pIryaiC4NbUcZT12iGuoyQBNA3DEKkuLc2eevbEkU0mq8vlEkVRluVsKXvvrfdqQj1bLiTj2Xg2LegAgziKorTHjpMAIaDFFNQMVZdyq688e+6sUH9PFgQfyABtlX4lhNXq6aRw6oq2vgKA+aH76EN3MtUa4s1FrpwUWNawBAJZbc9uol7WFhZFOb9SW5+Qy6VcypAF5LYb3V1daJBrK+GxigIU3bozeZuTpvN+h0rgK9dWZ85drnO4KQigOQQCbvfUpOe1e6upqamxMeLx+jGc5G2OcDj8HrPPVn6DQJq8aLVuSXZACAMukyERQQLdEVARcdO0oj9JoFvbtET+J0xLdwHvbZ27uoc6kJTQYjrPh0innBnU44li7RHapdtt4cbuFm/Yi7EzYkYqZ2ClmFteij99Hop+6GEERSyuxSCBM5huELqoWf0rBIkIy8VwwOHucIynjy4+NqtZlTHwQQ/QumauLBpS3fS2uLxMoNHfGqQBxUJQL5d1Q1GgiVMQNWBd33k9OPo9MPLyjwxhFpcXUJLDHUHOTjqbvE0hBmV5iMm1oqxLigEIFIK2wZ7c1ZNzLz/9lrPIJZOUO0LQTpLFXS2eYJgnbRyCaUJRMhTVhKTXxcvp+dFTL7yd4XoqGfW2DpsAx0jobHH6Gp2cizUxIBZFXVYgRi6OvbI897atGeVqEcVxjA+pqpWJdrbYnY0eu5c2CUwq1LS6ggDz1PFHReGtLQtK5SLPc5Gm7nhZ0WQVw3B7hLeFfc4AZeCkXhMoFIlH1148/sRbGrtUhapiKDfsOLCUzdU0XFNUDMX5EMuG/a4gZRA01EVN0GLRhaePPfaalJ3f78/lcoZhCHUhV8nfeePd2VS0jNEl0dgYgWD8FNPoc4UZhOYMRZBL0vjMmSfPHBWld7fF+WCxOH4UlWdnNgrOP2iAA+D4y2q/3xOpM7fvtl2ei1oKQQM1iWO9Aaq9QUVxtLHJJyqeJWSyKYixnOlzNq6l+4r4RciRpInLQq2YWUKQThzMZzO5S1dJq1RCGqgBCEJhpRvqZMLjrfV4jN6wDuGsleMzDTNgnp+lZmepzTbC97LrMQwgSK9H3kIVoohV2BEk9LVHxzDASgqzKkU/EZy4w4byBGAZkp2uLCFa6ET/jpQdarHREokxFAFxDDGNNApYkjEMJLm6znEuQmzgOuyY33LioAVKz2skroghWp1fKU1btS+oV7i2fZIWG/ubRSn9/ri0/Yxi9RoZ6S4yfQjIyh6oyDCfU1Fd5nka4IRiKKrdZx75Ljj80NsNUJs9y0c66wKVX8sZXlzXYCEpmZrK2mhI0jwF0qMnrj781bc73NTV7NRxR6jZVIniWtGUSaAjxaRgqirNUQyJi7GJk9//xjvIDSqSuDbxSve++wwdKa+XEU1FAFJKioai0hyZWby6OPkq9/ntcOH80d5hpKX/erWuVqJVxAAoNKtpWZc1mqemL50oF99pEXP4hccFQQy27RQMUpf1WrKOwoKMm0JGRVRdRc2FxQvvYLv13CvPYijc2b1zTcLqmmxIej0rY0SxKBhSzkAlTZTKJ88+/sb1O47jrzWFHb9wgsCIu7ffWMuWTc6GG7gmyFIBYnS5LJly0VRycrqwfGXqFHhf8XMToDeKKq//y9JfVNGeurulPZSeSSMI8PXXRUMxePxcUlRUdE8X09DoxClfNkumZZ2Zb7r42O6Ho1NNt7O4ByIYJUhloZxTNbFWkDVZ0QCFIFbTsw2XVBXF8z4HSHoiSl/Q3N/5pti0nsFm1o3NAP1edI40HaSL6Ea13fqkJcS/wSlK5F//T4AC1eqb+QkhyFlWWdcrtksecLiBkklD7OgfoQ22tgxEWVbUklicryUIyl5WBK1cRXgGMgwuNzhwlQqwKADooipogsPhqmqGJ9B+/d5BU1POXZouZaOj3/3LWvxnwnjwZwimIZ8/jKtyttYmim7DNBVRNFVV1CgWqWv+gHnqWXD++Q1iwFvDkIXMyUccw3cqNb8suU3TUKo1Q9FVAnO58Nzs1dUXvvWWYv+vQSqmV09+L7T7fkmoqqoTmECpVAzVJOw8KuROPfWdd/WsyiyPYRhs2XpIyAvaxlJDqVQRE2VRfH38+LuqFZqmsTBxqrW5zwSMUCxowEAQVCqWaJxenji1PDXyzofrhn7szJFPuZo5ZzAn1xWlriespi2pULJz6OnjL8TW3kkLwQTm4WOHC5nijbvuWFN0SZaBJuspiyMo54sUbZw685SqvpOQ79GRl0rZ/Ef33pOUKyLCappuSKKZQTdGKK3GJkenz7yr6+6/Nn5+AvSbcf6E3N7OhsN+xuHQ9ASKgaZeo72PkiVkRpcpH0wVjEhwMZ9ab2qFQiPp/toBoVrr5xszeRbjBMOGmwZgAtspZxg3S+WZEUjJJOlBi3mDkOxetEG6xtWFhQvsAgBf3/iNEKI2jrZ6W3BMUd7Ja+6HsGk2+No/X/vxhzq8fxpRaEErk8i6gXqnIlCANOL0ms3N7qnnUQhJkqqXqvn4qmmggKWLi9OUiRgkqawlGI3KzSKsntIkFc/KHSEX7wqPzZ3gmEBNyGu6WadG50+cLUff2mvxgw5ZVM9+H+3eyd33AMK5fAxVSqZKMlEpF8zjT5njp98hOm9CreSzx7/t23vIteMOxaR5J1NbWNdlGDt/rLR49Z2j8yaqqZWVl/9xy72ftfUHddHk+CZxNpaeHUvNX1bl97QrT8yP8rTDN9Dv7x8wVJ0wtdiJs9NjV4TqeyJTKpJw5fT32zuva71xH+CcCEQzs4Xy1Nj8tRPvJbRpunb09FODnTsiTZ309m5FhyaFRs+tTU9cXpi98q6Hm6Y5tTrpZviO5i2mi8S399SKooLWK9HJqblr6+uvtsZs4gdU6zccDszRpXEOJ/f17PXacTXk10KBmrWxFZanTp+89PyPZs//7fHzGqBNE8TS4t9++9z+7qZooYqgSDJh5ipqSxsOIAJsoK6hfreSjGm2UEO/qwPS7Ta7o4+Gh8FqTjuiyhhJ0JSjU8jO2gL9BDGraAUoC5VE3ddmNoYBmmQwQgNvyGniGAwGnJqmsyyZzVeMnyWxzauD/hPZLI2Qjb/02bkLp2WguUcPE4lZYHdiENPqoplKF1Fo6akV8ixG4gjAynStOGUz+5RFXZMVnIB+7/akmsNZj1ov+ezrOrSXrpwXS8vv98n9DANBTDGfeuLbGMuaTa361laTh2Z0GoweA+9RONg06qtTaw/FKV/IdeN1Hh9ITkZTF54z381u9TWoYiU6coRfvLb3jtuJmpJQ83MjT6rvzVR7cwZz46+IlcTezhYSV3M58bmR71cr+fd8OEiklnOFxHVbeppIEQLui6dfmpke/TEOz0WzpfQvee7fLnEmxnzv+bPx1Eoisf4eD89X8k+ef/bXnfgd3QNaaf6Rs9Mzq3NqXcQZ7IcMDN+Y33gNqq4emzob8drua99KMOSp0fkT49c0uS5ucPJ05f8E6J8CYlVvaNaK+WoyL9jsxOyYSyLXsxUDEpZCW8U/NDa3iHXY2ofaoBAcF2dmllcODhxyRdIaiwj5mtut06hJt95BgDqBV1I1VU6Xwj7TH4DhCOVZu253OE4Vo8lcWoNoGVHrDvuVeN4gCFCqkwEfRTM6hqMYrgOzXiqAWtVkOZDNQopjNFyqFlHUDSDQAxWcAVoJg3luQ/TAMPRM0N3gxDVZqpfrYk2WSZwwLVEUEzENE7UoSgQGIMkabAiDMJOvQpwgCVMsZmShrPwoSxpFktXCHx3cg/h4sDJtL1S8jUBLr0mxjOUY6/ACw3C7GxHasnFJZPImNBBF4UVPoKmnwd+6/0DH4kJmZmZ5vbRY8bnvv//AldGpkXPP1Evl+NGl97KO+8AB4sjBBxCeAvtvA+19JkQ03TRPvGKKE6AQBRcvv3t0RlBX13Wu1o7Ivpu93QM4SSEIKCemUlMj8dNPv8foTNu8Oz/0mVB7W/f2XVbPCVQkobA8c9TiEb83YDjVO3jT9l17du2/jeUoCGRZ1usyffzokyvz519Nvr0bGkO99937K1uGd7idNMSYP/njofFrl1956cVLoy+p2nvaFXKMo66QnuAg62r4/b5bRaW8sLAwNTb1/PEnYun3tD44Pn52sMnV1L3/tz97J07gJmIsRKdPvHJ8Ynp8dPaibljXkyAIRXnrnM/LEyOdAWmwuYnHWv/2975AcxQK4Up86cS5VyiF+upTXyqLP8aO+V8WP68raADA4rTWt11BBJ0mcVkyb+pvndGq89kcgAhOQN0TSPcGwh6kQkyeGL80QTKOcmR07ni04N75OdSYVKJxJFN+nPb6FLEoxSTcBE0erKNH7+rWn53rr7w44amKD/YOv1A4gyHEipM8fXBAWl3FHHbUxne2tjkjjYavsUJz6Uwy+/xhJZsl2lqpS9eGuEPh1cJifaasNKMAlzsnxaY15uIupNBo1RjNug2b3NF+401hw6YsHTnzyrVy1QNQimF109Rk2dOgurygvatBbr7/WHqQp/HjJ08rQg7JXQWljJvGAWrMxDL56puXSDQDtDy4vgFLoH59Jz+gZcZVJZlUFqLoFgZiutPjLNRNmqYoGjElEYOIvWW9PKXVGO/ywlI+XxOYw8lKBDH65zixUCrMjSxUEzP/Jzq/BVwh/IHfNO64W2dpQEBLcsoq+Cqop9FcEIFWANF3zdcj4T337vnsbxLBMMUQEFotU1YTHd8BQLHx4EdmHv6Kob3Le9HXuv3gPZ/eedPNJkHRVquFVYWGuG1w562aYbt67Jul5Kt+2G8HDCf33/IrDzx4P+cJ0zSBYwiK2lnDvPGWO3nO/dxTcHH2zLt7GDR0fe6zv7tj1w4UYygaR1GEtdk97sBg77bnnh167PDfie8W2lx2/wO3fu6mO/ZxvmaSJiE0cc28fs/Bob7tfb09f/n3n4+l32T5+pa4fdte07GLCXeyLItTOED0vq6Boa7rcsXEQw9/55tP/6OqKSRJvp23XKYsZCr4Qrp3YE8/a7MM0jEc3dK3ZUvfFlmQura2f/FrXxxbfH8M7H9OaHZvBacT3nAroRdIDdpMgKytZlmfKLKmJbOLqIZR1RCZJBdWYqVLVwUzKDtTQSWPpgtUVx/maUmtLCFQ0wi9RqpQLikUgnT2Grv3IteE/r8+ujdVrLRgTCY+W1N1DMEaIx6AEAkW6orFKlIQRESREknmdL06cVVZX4Mcg+g6FoyEx9kOW4PHE1lN51GEJKIBz9peu9RMkhSKYqpavWFoP4nYzswZnI3TSishG93VELz9ttv23HVIja5ThCMuFp20rtdTOYQrVNT8zIWm4tkBm9ziZD0sQePYTdt6Qw4+nbfyPJphLQpQBGUGu1Rz0l4hvVoXA0umn8NZSk6lNUlAKFoW6gGfv5qL14WCm3U6Qs5AWWYmt8rowmce6MrVxpDwMzzES3ni4G2e0ZePxK6N/Fu6zf/c0Oy8EeR3/87Ytc9w84AlUAJiBIphCCRw4HJhDGOkCYSnyew6SVuK229BokBhaO992375P9giYZuNYmicsqy4URxHSYb2NIaUChAkDJRjGIZbMh1vlcmlefdND/7HLdcfZO0cz1phjSRQAkcpErM5HV1tDeU6U0otWG2Fb9OViuHUgdt+/a5773cFQvzmNEhI4CiOIzRDtrdHmiJtK6uxciHxdqlkBEEawz2f+eTv7L5+D04yLEuSFEZsnggJOZttaHsH0DzXJk6/HRPDsujkXffd/O/uvPdmXyBC0RavXEcU62+KoFm6ub15sHfL1atXS2+VckEQhMRJmqK2t++9+cADu27bTQCO5qy+EwB1HIc0S/I2+/DubYRKXpm8ZHfYN0nQr08ARWmSIghiuHv3jvbbtt6+IxCIkDhJ0ARO4tDSuEMJGm9uaT2474bRy6PJ/A8T0v/F8XPLg34rVCvm7XdRNpwUK7ysKDAQYO1MGashNKcIdVNXBVEq5IrrcRWgDmCawXQDUbHVAbo03UI4MtBRbWvGD+5t2D30Yd1c94dUVCHPnuj5p4ndZZ0t+cLukB+fWZA1QEPS5nGQje451OA5zqrXowiqoaJSF+NRcn0dQVEChVi9wuOeG9ROL88pprwYz6OWjT3tdYXaWiNtbYF8vl6vV3ubfKEGl4koibqqog2jy0cbcEqV5WwsGs/Hn7e5tI727vpE563uFN6j1lVmddSP1WTDtAQHAMITWDJf7OlqizgbVNkTZDo1XRYqaRptcBlD2Ey1ODoVcoHQcFBxBgCFCmMrWq6oIloutSYUc7RsOLYPezjKm9Rq15Zh21R0dtngTzV4S9taypNnnWOL51YuX1HFnzm9uvc/QGM4+qt/DgYGzIAdJTESWt0RlmA/arU3b4ixQWjooKbZ62kcRWiWxUhKkepvZCJ7Bvb3P/Db7rZGm50mCbjRX2ENglmy/YisGjaHTa4DtRAloMnwvKXc8mYyBsnYb/rkH/bs2Ov2OzgGxzHU6mi0VPAQDAIIEVlHQj57MlXWpRxOEFL9LaqFLR07PvLgr9m9XqeLpUgcgwi6MRNoDYLoBuLx2HCMS8SXpXr1R6M8hNDrDhy67ZeHd+whGY7jSIKAqOVmsTEORDAMUVXY0xtamFtfj73FWp6lGI7l+tt3fuTu++xOH0MzFINDDMqqwNLcxiCWkJzD6erp6Lt4+WJVKL1pAqil0kCQpI2xf+TAx3fftEupIbydxQkMYoiiSSRBbpiFIijAegd71tfW8pV8pVJ57Vx4muFZjsRwhmRu23JHz1CPtyGEGzjFkhCHKEQQuNF7vvEnw3LdPV0vHntRkv91n4tfqAC9IU0A9h/g8pOmYhi2/utgrmCwOQmjJVngggOko7EuiEq9imFuVKvjaRMtOnHWTWm982PuZAHwDgEQ+VJ5KZfRL7zUuvjSkLN60yXSqKMIYFm0OdAYS2OKqiE6rOq0Scy5UEjg1XrdYuQQmFStKukUAhAOhYZS02nKHxk6ZG6lEKqmFuaiWQhJFDcjPeHObu+BfUxNoBLx7Nb2kM/ha400ooYjUxUePffwTg+3b4fhbabOaOyRGz+uvfx8L1MO86VnL5VXZ5ddxXVLZQAg5IZejKIZJAYn1lMfPritFm+uq9qe4B2SIkTnj2OlChsagK6GzHJluC1L2lFBxhTSIL0uf1vbvbtvreiS6mR9vLNVWGRjXijMK5HjIr7MssXhrWB+Xnz425Pp+XVVtBTKfr7wrx6gvSH0/t8CA0OgOUCVcuz3v0k+/TB++mVCFG2hCCBxSwBr5GWsZ0Ar1CTeJ+6/Q+/bShfyQKypknU9Ic237D/Uessv+cIee8ArJqMzT3xr5tnvro0cB4rsDkcggWmCkJi61jnYv56Ug9v3+jq6Td2spNY3dzMIivXvumXPnZ91h1qamlwsx2VjK8e+949njzw6ce4kgiDehhBBYKn1VRQxHc6ABm1Du67XAZZLrm2+JCiK33fgro9/+ncaGgdIwmxrb8QwfHVx+qlH/uHYC4+PXhyxGqkawhBDZqenuzubJYXdu/9mmrGlElFN22yVJIaHrv/4R/99wNezbWh3uRZraW1FEGRufvzhh7969Oj3L18+xzCs39+AIObc7MyuXbv6e3bJkpRIRV89CwQZ7Nx236EHupqHetqG7C5XWUiFG5tNw5iavXr4me8d/t/svWeUXNd5JXrOzaFy6Krurs45IQMMYhaDKMoSJVmyJcuS03jeeDzrzfM8L8tettcbe9meGWksj6IVSElUICnmnAAiZzQaaHTOXV05h5vTeet2gSCIQIIBAEPvhR/dF13nnrrhO9/5wt7PPzpyctjhcIXqwkJVpFlsqGcTRDCRjGmrc7CpuVt7v/ipL9+y9U7W9HzqU588cWo0UO91uzyGYRwZOfj89qeefuHxEydH/F5/XSAoVIXNGzdhgFhcXKisMk+xJDXQ0v2l3/rKp2/9nAfzN9VFNlyzafuul3v7+iiSMgxj18FXf/bgj5/b8ezC4kLAH/R5fMiy6gOhWDSar1xGxtEPm4FeWTJZ6L62yVepyKyDc/ndsj5VNQEgWL5+i1opss52KT8HAKYsV1lO86206F6+l73RUNiVuOgIZG+7Med1adPjjskd3UOu68Ps1kMNOX21g6Rq4mFV8SoSThCqWDFkZZ4VdbdH0rSmtlaH213n94v5gq7rLGap2YRB0shXd+IHP6yUEg6nZylXxDGG87D+gD/odw30UpIEZ+aS9W5y+4Fndhx8qbWxRw/+cnj0ZDNJDTWY1VL1Vx23ZWQrOz4fD/QNpqr9vqbtrxwKOmmbywVAhiJxHF9luESKquUV/bbNLScm2jPa9Mdb76pK1VR5ynfjvWqloqlEZ6JnY2+apaNLY4uGarCtLTjCy7okjOzvdhUGehqlX9aByIu/9amWoe7ekrAcnTd+9N3XmBg+gLi8Brq5B3z9uyDcjPo62eH9jv/53/Cx4zCbgfEoPLoPjhyjNmxDbrfJOcDiLNfYIC5mECKMT31WbuiHAJrTx90tvVv/439vuvG3kFYJ9vVGdz1/6Ft/k504KWYz5dji8qE9yYmx5s3XcT6vLlZJmjEkLZUoDNz7pfCmmz2dm2IHX6xv7fu9r/9gy22f0XTM7SEDkZZDLz72yLf/Pj47UchkMyuLJ/ftSCwvd6/fEqhvTCwtdHe3j02lO9Zfc/OnvmAAR2z2uMPhufd3/+pLv/9/LSykHU6+rbOZc3mfevi+n/3gn6ILM/lsdmVp7tC+7alkev2mbcFQKJmINzZERJX/9Ge/7Au2z00PI8v86pf+8s/+9C/FKqAo3kTi+k2bMZx44IHv3/eTb0aX53PZ7NLi7K5dL5TKwsaNW3gHj0FDKGNf/PzXtm6+Y2pmpFIp/pev/u2f//FfRsIdC7MrgwPr8kJi27YbNU373g+/+fLOJyYmxtLJ5Pz81PZdL0qSsm3bdYauBHy+bYM333LtJ5fji8nMyl9+7W//9Hf+y7YN140cOdHU0BQMhnRC7usakhXpX771//3ikZ/ohjo/MzM9N/Hiq89TJLNpwxZRLPZ2Dtyy8c6Dw/tFVfjaPX/wtU/+8Z233b0wNitXlJ6B7lQm0zXYHfLWl6rlv/tff/3wM7+OJ1Zy2czJiRPPb3/W7fJtGNrYFAp/5qbPnxg7kcglLstj9uEz0HbHyoLwR59dJ+QrKzPLVjHXvs0ql2UCM92NW1hvHykuqsUlWNWwqt7X7iVmGstSVVflRkd3Uiwhzdk8OFMpMIef2+KpbIs4m9s6ug57YojFLN00dMUpCy2mZkiqjpBnoINk2QVC1pDVFIkUy6qD47VqSlZ0rJg2dQO09UQ6AsTLxzz04MjcUYvwQkgEhtytg+FAHcfh+Oy0uriUmJw6GHK1FbSDwc2P3/ip+PCR8rGZUoENH2++7jBsoIG5ta1+/cpi2GCUqnLNUPdCIkOuJpJWSXVYy+bcgjwOb+ztcFoFjiNi6fpFee9n2/7kWGwnd8PteqVI4oCo+DeO9TMNko4vlQgGUqWPb27NpZb8IBvyu6xdzepRxj14nHYvyEpqfEZ75lEjc6m96x89A/1X34cGBhqC9PKM40f/ZLp84k2fU7bcofVsATQNlyaxmVlw/U2Yx2Ok01Rrmza/BMpV4HSh/nYLcXD60JYv/T+Ep1ETpbqezuzo0fFffIsO1Nff8Nm6LXd4ujdiBFmcPVmMJ1u3XcsGwrl4ojFSNz+5rKp654buckkzq7l0C2gAACAASURBVMn6xr6+zTdMnBz31wWaujpO7nlp9yM/9IVaBm/+XPfm2yNdGwAE0anj5WJ1YMsWguYU1bBUeW4uFmlprG9ux4CFVPS1P/6/d+8+4Pa4eAfd0tm54/nHXnnq/uaWvutv+uyGzR/v6N5I4PjkqUOyag5t2CRJitfrPXFyyjRRf39fKTPX17Xt3k99eXkpdmJ0tLe3xxfw1YXqn3zyoe2vPNzdNvTxmz63bfNt/d0bcQwOD+9BCNuy5TqhIjsczLFjU5s2Dy4uLNX5/HfdcK/T5dj16h63xx0Kh5uaIxzneOg3P9+19+mPbbnpmoFbrt98S3/nOoDMQ8d2O3j34MBGRRLnZ5dDwRBF0Kn0wqeu/2z/uoH9r+5PZ7Kbt27Kl4r9A4MUTf3g/u8cPb5rS+/m22+4+7qBGwc7hnRN3n90t9cT6OsZKhbyZhVs3XjNsZP7fveGzw1u2Lg0PT81Oclw3NCGDYJS7W7rM0zjOz/+19HJI9f3bfvsTZ+7edMtQ20DslJ9df/LHa3djfURqSreft0dT7765GWKdXyAW70vBkUzf/jM9KcHPZhpRlrDCJm9Xcrxo+rS0V9AltfLZVBAuGrc8QnnQANf2ttWmZsuWWNEQLNcil+4cfnxjlBzfaSKJ6gljyU/Te3KmmkPF6iKNpdVtblBiy8jw6R6m4DT0a0ZK2rllKFm44mO7j5VEquSDpSqJUuObdcbvvp7Q3uzW5vnx6GFGgxFJVgnYTB2mgWBhUW0uFguZjO44Vc07J5PRTbdGSUYm+OxZcMdmYb+6vBcfWk05Hf9t+siMVpJZoqtzQ31PV3bj41CCGiKrK/zRZoaRVmen1vK6nprb2dyYqK/M5Er4QdnHJol3Fz3uQkcBySjxscXwtx00lf/P66pq9MX2rZLlDpbOuYEallB0cehY967sW79ET16Y1BBmPYX95niGxjV1/BGEBTAGcBR/C+/rbb0Crd8zlZTsgAMkvrQgJ64mX/we/hDP+X/8D+h3iGEINvXBuYShtcls6+r2KmC4G5oRIow+8T97t5tddfeYUHMMAAf9IcHBytL100/+qPxp36z8Ytf9UWawxz0B72820UQmJ2IJGld18uFEu90O9weoZg5+MwvO9bf3L31Vt2yDBM66wIdg4PRiRMHXniwubPjuts/XSHU67f2F3dNWAjRNFXKZWxlCcsql0uRlrbmlnBsefbVFx7cvPWuDVtuUZGpGTAUCPT09M5Pr3/5pQdb21quue7jpq4O9DYVKjpNUzTDZVMphmFi8Xh9OMzQjvpwYHJyZMf2R6/f/PHrt92uWLpiAG8g0N/bMzG18dnnHu7p6xvs2YTh5vSkLe1G0xRJUBiGlYrlslDp6OriaNbv8R89vm/P/uc/cdM9H9two6gaig79wWB/d8+JseHfPPJAe3tHT0tfRw/KrNgSgqvRdgxZKJ6KcxxH4mx3c9DJOXbue+XAke2fv/W3r1t/XRlIuoR5fYGBzu4Dxw/8/Fc/7mjv9Hp9RrnoxT0kBhWpStF0Pp9XNKWts8OQzd7GTooiH3vxkdHxI1+78yvXDG6uaIqsWQF/cH13/ysHX/k/P/jGv/7Ld33BQHIpiZ9m4v5IahK+Azy1Z/47z8yMJ0WeQvpMqMXNsxysA3qPw+z1h1kcrd+CtzWRmoaRZOM6V48HB9nlaZ+WK1bnlVlndZTHRP163rqxMRBtD6iSIIplC4H6jnAlXL/o8xJIr9cUtrmRaY78rkj6pxYy8dih3a+OHDlsxVbIxRh/48e1dVvqXDl+9HGCkU2zQrAcxbIIydnJ8tSh3IlDhVPHi4uLY5CAGMOqeiWWlhcX1VTOHLjjr/neT8yNTVXJQSV4t4x3YLqGIH7rxz+2YdOQ0+WyacIh1AyDdLj7b7ilc+vHPF6Xg2Vwguzfuqm1u8vnZbv4j4Wpps3eu+/WN/OhZoxxVhKnHnFNKEFiQ/72gT3XhwwNXxr9fA+Fv7iRP9TXTPTMlo+9/KK0d4/17FOGKHyQCjauAmgahQPs9sdMiIkNW9BoGixKoEJD1YmrmCZj4g33gB3PhlMrjItTTMC0NCBJIlQNGgCtxFCxRFKEp6HRFfYtvvyIhVNmoH/mVGZhQcxpzhL05RWiaLDBa+6ceP5RJJQ4F5dV8d6BNrVSsQt1qunF/S9pUol3Otz+gDvgOvDUA5zLh9zt+0ZiI4tyEnqrzsaFKqgQgY6NN+179hFFrlAMiTtcJI5wCBSxMjG8V5GrJEkE6+pY3sG7+ecfuz9c14y72188ET+4oOTZMB5pn5WJMuYZXHfD80/8WjcU3SIaI3UYBjVNGT5x6uTYIUURKZpyuT0Ux0AKe+KJn3U399KutqeGl/YvabKnxdnRNV7FBeDt71z/mwfvBwRSVSzSHKAoolDK7j78SqaQpBmKIAmed3Au3oDmY0/+fLClzx/qePTQ8qGoDsJtrq7uaZG0qPqBtv7Hnvg1IoDL4/eHvMVKbnp54dTCJEEQhqHXheqQhTEeXtaVh564/5bBj1F08Mnh2ZksZFu7vT09MyLNOtu6w22/fvQBiBONbQ3xZDxVqkSLJQzDKYbSDC0QrDNNRHtsgfCnX3z45r5tlsk8cnB2LIO5OvscnV2TZTwYGGh0+X/1yAMETfkb/Rh+5czmh8FAAwBOrFQPTBdbgrF1XXzquZCiYG1t1JZ1gZuv72hopxngDqeuHz/ufSx7pDmwDiDMUqteXfCz1WYu67LSLKFf33XjDl3PKTysb1akArRL9JDL5Szd84mig0zNxqvHTspT03uyZbGrHWeoQGfHho52nHNiWzfJNOWeG29++X8cP5FWVAYCkaQxmmcghilCOrscmzs1dWLkiKgqOI2TlEkReiIXf+7l6r//4GZR709N7jF8N+UVv2xxSbNlKkN2tzbNxjJP7TkmCQLD0IQdfCYtgsEZPtDc3tXbhZN4oVTefWgkHivm0w4LES4nE6ljg2NJT1MkcN2dOM9VCxPf5/btDK4ohos6HGxm9EK6cGfT7V7SN1Ue/vHEN+ZnwDf+Ffzk/qt98973gCtLGEewR3bK3i5LIle18wBJQtJNu2/sNEPtiubRCRIe2M3RGEQWYHjT74OyApcXwd6HgCRMPvUzTVUwU86NHTNcbRWRADaLISRpwuNhhja1ilSoaHo1E0X372Rooiiq/nAQQJBbjo4++K/AslamDpeyMYrjVLEYnTppuruSAmFBm5ieZamgj+vobMwZziKsq5SK86PDNEOUFRBpDAqlwmPf/1tFKGZSs2MnD7hcXoani4XUyuK0zjYvV7BafZDbwTTXO+vD3rjIFEGwVCpOT57EKZyknW4X+8ivvxOPTghi8cFH/93tcjGMw+V1JOKLqfiyRNQtVnET4BBDPi/bGnGGgu5oBVOZ5ujy4sLirAVBMOifm58cObnHNI0fPviNZCYergsZJuTc3OzCZLmQ0+jAcglYCIcQBXx8a7M7GHQtlYHBNM/PTa8kliEkVEt8ea/N7ffQKz9fia04XW6/z69qOuPkTk2OqGK1arlmCgAjSdMCwaCjudXtDzpXKoB2dceW5wSpahrghQPPyKr02IHHVtJRkqI9Hh9NspDASJY5duoIbaGy6VqokIZlp32CIb6p1eMLuKMlK1i37sSJI2W5nIinZPnKZdGxDw+/WF45dbI0PBxncX/LbEhZxlgUTSaOhFSuR9iU1IlpIyr373s6VWBwZ7czck/Pbb977+1ZI7eUOMySuYcKmYczaXwsSfWss+oaMENanstK+XwiXZwgOUORhJEx6fgpRZcws0S1tbm7ujq2bONbI4ycujv1wNeif09U0/Z2knSwJAe1NM1jlmkBnuIG3WQ3LeuCnaxz4rSZd/Fsdzd3y8ccDX135ecPSVadbtqxJoygKAuEi5F9j8d2HRlNriRGD+6XVdEEFutz8G1tBtQA0svlKiLg5MnhuYm5Vx+rmEqPiSEcwwmcyEYnFn/+T3xDiG9bhxGsbpSnWjNj/UiIr1v69vXWY7cqUXN39le/mv9mVrFDzqp6djf7Gi4M1N5LzZ6E+ZzGt6z+vip7U6qok7HcL4+BaAYhTiUDuRPDuGFAAHRIGev7hHzR+u4/gglbLhajedLhLEyfVCXZYBtr3IaWrsv54vyJxZeeHJFzRQ24DMo/fXAfsPWnTGdDA+d1v/SPf56btlskhHIxsTRNMeTS2LAsqypVVyM8MBStmCkc2j++Z++UVK3K0GVS3pOH9iHTqMpme2vdL7/19amRQzXmxe//29cpimBYevjgq7oBVSpYk0VUJDmVKjz+7MiR4UVNkWXMZUDHyBFb89AEuFha3vHSY7UajGdfeGgpeoqiGZIiRkeP6ham2YPYgixSVVxezj781MmTYzFD0xTci5Gu3bteJgicZth/+Jf/Wirb/B6LK3P/+O2/amlrsjW3MTh8/CDCWMZbXxVNhKxyuTozl3zuxanRUyuGrkvApRnYwcN7EQAnxo7OLdoVe6lc8k/+5itNzU3NLa0YYZfjHTy6Fyec9jWBkCBhOpU/dTK6d9fC+KkVXTdk4IQ4OzkzgeF4U8TW9l5OLv3Nt/5alsUt27ZiGE6QhIXMo8cPWZjDIAO2ZBeyksns8KH5kcOx2akV3TBMok6WlP2H90QiTTzPX7FX5QMfgz4D1bB+774iAMWtzcnbB0JhPehglvWqtTKO5oy9PMKrBkIhctEZVwVfA0j40mPOE2mX5d5HopjCYIUkxjo8giVHrcrQZuWZJ83cfLRUvhmBT2oW5gn2tPc2Xrtx4uDBa1byP3fH0g3STj3YxKe25p/ezFTrO7DhqK37Q3IVhmqzirM647JM0r/Ob0uCshjXBoVpw6iWMVXgmCGCZOuc5XXtL0ePGAbur6kiYxTjBJofww6UPHwo1+FzHpxc1nCcIQDHEySOqYoEbEEYrFJW5JzQTne35H9/Twssm+VjS5NHMwfmyvuz0lTxz494rvss4XA7O/sHhzpmF1cqB06ao46NHs9BmFwURk2wxh16yejoB4UKMX5QZ70Ap073P5u2fJ6tNFworspWIZ0LCdExKpHS58s2G0xTwBLNMxXQCGBCJieePGSRTkAwq4cQMi1dkk1JBnlbedbua+GCqemTYlmITy35QEOos92UTycHIIZx7nAumVwYPYSxXlvP27bxyDQNWZBUQbB0E6FVDSyubml6LJcpTI0tb+zxZKLTZ75Ka1uPrBi5dGZ2fJjgvFhNQ8TWWjMq5Wq1UDRttVXDlrXmguOjR7Pp/NJiRlXK8mt09Yah+/3BZCLh8jIzkydoLgBxeyaWZWuW5/OlcrGk64aua7ZYDB8cP3U8k86XcsVIY/tK7LQcT1Usm5YZXVoKhB0TkyOcI0BSdFW0L5ah65l0UZREUaipg+M06z8+fHDb0G39XesdvKMq2MqtiVy8o6sznyktzS00tddNz45yXNAuR0d2JbigGImE3c9ZKJZWByHc3ob9+3e2uLtw63RWoK+jLxAIu9yuxbllXdMYFzE9O8qyDbY4YW3RUpVYLF0uicVS2bQsCCDHBoZHDq+LbN60btPzO54HVwQf+CqO85GqKPmKcm+/QzRQZcz3o8czgXbR7TAUiPjwerTcV9aCqsXd6ZpqCVNjKWM8uK5c1XEOJ2hbpt06FSXbPBqS8GBd4Lpt67cMjWZiZDZVhzOKKhsl8ZA8mg8AZbOBI3SLPvyJ5rmODqSbcHjaIiibUylgfk4QK0IliuMup1P1DDXzfgbNpeSiwpiJ1sb21pY6gX9seqR6w7VzlufPZmZyAOcgjjtCYTbobzEq9azF+yVFKIm6SbKMYSFMtQhTB4ahpFMz0/O5UsXLkLoAhrNVSLdGq3FMx+elPQvVE/Z7rqnS4qil6KQ/OHBTYGL7voXnf0iYFViOH0odnpFi4EOHy1jFUS2Bpi2kkLVov84EVzUAbYmdVffVsC2TrbkAgVqFTgaxdYJoabEkojjk9oJjr4CY3amsVkpc45CeWbDYkMEE7f1zrSQYQqRrq7Kztpwf1CW3kzQwb1kwMtmyI+Cbe/khtWL3aCBkKarlcDfp5aSGuxFXB20txFUdQRwzFBVZJlxVKMQMJeBkMNKfyQslQT619+kzxKH5fLq+aZOpGmIhapB+yAXtQVZBEKQiy7bm7GrrIIX0kIMhcF86V52YODo/PXLmeoiSFvC1KeWKJhWrGk46w1htJquERLIsm7Zms4UAZIHe4OFJ4J1fjL7wyi+116SzDFPvatmgy4YpiKpS8YcaRcNxut8QQoLAZUXRVPuy2OubJvhZ3EM3vLz7peGxA7URIIRfuvsPZmYWJKEq5/OmKuOUF6O9GIQMh8uSiRO2vLeiKPZMIOAoE0hlLxn66ZM/Ka0S9d2y9dYt3dekUvnlhXlgmUI2U60WcNJHMv6anqHtMGHQMk1BklZ5lyBUqxTUQnTDT5/5qfg26KjeVRXHhyfEcQYWAosFuVSohqKOl3cJBVHDcdDdYYQpxWUtc7xCUWZF5xYManklOmkBRVExEnqurbe0gqmZnJPuTJuelExZhpDLHEgkhps7jnjcLJjvbk+bqFz6/Y3hLXXY5KxrZe/tgZOSBE6M2PfS1mEjgEAs+juWOyPXBPmwKk6lx8rpvbH49qXSokCYS02hls7I9dB3tKWncMMNejFfHmj4x8HuFVsYmaK9jcFNd/Y/37Nlv26019Vblsk4eUgQrNtVqkrJlfjE8fHDh46tpHMkx0KStBSnxHviWhwnSAgNZNge1emrgJASn9Lz43PjrxbHdpuqMCqMfj+665Xc22AaW4MNQwdeXrn1M+rAttMMorZipV2Ofto6U6Qt9cC7ql/9rypOQAaizohFY4AmbcO9CpyiOa+r456v+vq3gLPukb27qhGdk/YgBMNf++f/YBEEx2GBxiBmaeisLj6Hg+Nd/LV3/36ka90ZLlN7DM2wWV4QAgQOMOjyBD/x5f+MUVR92Otk3+CBmYbRUO+mGfLOT36lqbn79UEA0DTNMk2brctungN1ocjnv/RnGEmEQ27ijToSGGZ0dDSQDHXXnV9ob+9bDX3YqxZCSFM0y7BWhV9to90Qbv3iF/4DwFFvb8c5z5LXyzdGAgRD3/vJL/uDYVnWbaO7OhVNsTVWVgeBEILmSNfvfPaPCJqAtjDs69lsksbbuyJ19T5A4F/57T9ta21HwIKYrZMOENJUXVW0msS4TRbvD335c3+EU9gZBtG9I3sJCvf4+d6hbk/AQzDMf/r9v6ivCyNgs5XVeNp1zZAk1TJtCncMA22NXV/+zB8wPHOmX+YK4MMT4jgbsm59/dGMj8Onc/bz/crL4He+ZCsmn5xcFsu7iMqtCPA7tnzKEaMt3CArs07c4fHwene4OlFwc5zLz61nbohhiaWmJamhg18EHeZtkHtOjS2N+S2Cv84JQXd8HDek57Mt4ngi7CoXRIy0t3rQ29DW2PGSA/tDQW5PFxKWWjYWojgBTbXkYgPNoXVcIBolf9XsBx0ecGoSYPryx7Yw4yubATJdHmKohXJwzc8foH8XARMnLKFCujwAQlsgzecVPG4pKuiaznhcrCb5yb5x3VWmywRPIk1NyG8gwEWalNv+7IFjnFawd4UGsorGFVLu+bDhhm2WZcFMAYCS7SqiVdNsG9+avV7d4RMECnkUqWx29tmH0llQzYLZ8doAEOmdW4dwDMvZW+/y6iAIWBYyrZqVhNAm7sBI0hP2SNVwW0unZRgrR3ZVUq9vd0LhwLbrN6lS1eF0gkLhzCC2JuyqhbblqC2LpOlgvQ+j8EB9075nf2Vob9hV1IfcbR1DsmjXhCBBPD0IskzNeG35sWumMQiC9X6MIrz+wKO//KezR1BUYfPmdaVSiSQwjndASQNwVaEc2VYeWSYCqxLjCJEkFaj3kyy3Ep+XXovV1BYVWa98+u57k6kEwE1JMk9fANsuWpqum6uDQIgDZNb5fKFIKNzYvJSfOHuEI+MH7rnl04NDA3Nz0+56n92UDUzc7lO3SyB13V4o7Dmtrh0BrzdQX+cLhDieq40QT8dEXSBJon/dIEmRi4uzrno/xbBAr21ukAXseI89GjLR6mUKB0Khlka6jaVoGtiv1JXAh9CDriEroZp1tjdlAvhf/wKKBVTnxW67d7nZwfmQDkuEtcHf1tzbwEcwrRh/ZYnXPW4KavlKZm9MnM1rO7J4PqfODLcnqI3rb07d2v0Eyu5mY0J2SspPgVLZozA9Wzd1XbsuGAIn5lTDsONfDMfiTlXv/Hs8cNLna2qvH7r3tk/+5z/+7c6mwYC/XuR2rFD/XN9o6ipiWPParaCvH8kaBTHLHXK4PUROtlTDxBsHiwbVWV8nyZqQz1uqYjd6t3eqisV2ddokc2KVJUjDg0lhqGs6R+lekibwcyUNLVVT0yWkr1GGvjvseBLxDhQKve5B20xIq7YMx20JBssCJA0w3KhvBRUZHjwIjx0Gj/8EZE/T65i6VpwfJxjGGfDVknunQyXIWo1K4LanbFkYxSIESG99IZZYGhk59eRZet4ATA7vTS5O0yzvCwRqBtF2DiG0/UQ70IFbpmmZFkHRBEmzTv/w7pefuO+b59AiP3DfNxPxRYfLXxesO+28rxIJ2BESGxiyKXEtkrLrOBHAdr7y+Pxry8zpaUyNPvibH2mqxjvcdf6g/V1qg6wuD/ZFgRhAwDJNiiYhxKpC+dEnfn62OBxC6Dv3fWPn3h0kQVM0FfQEV5l4bVV0u/FydcL2IACYpkWRJEnQsVT0sacfPHsa9//mR4cPH5qbmfW4AwROUqQdoLQd6NWLsdp8gOw5AWhZptPBEQQ5Oj0aT63UPp7JZ375/C8ODx86uGdnKV9y8m67Uoqy0wN2UMTeEttRLHthXt0em4bh9bpZlt91dFepcklqBu8JPoQx6AsilQSxOAyGYWeE9i//3nRmprIs5ibySFFbws0r2SVTlDc2bTR0OZeP6UWJqKiULJOxcnsm9Lmmu/cdv/9AYof77kimWOQIKURTYqEUafPV83WHHt7rciomgWu2Xg8gMBlAs7VVxAPj2cKSkG7ELaJaFtLyVJH/DVd/cv1Wo60DPzlZYBH26quWojle2HttQah3N7jCLUGG55IpdXk8vlU3/H6BBmYql0cIeSmcH1pPBkKuYlaJxxoD/pb61vl0S6XDoyyUHUhqd0SO5F6SjI9ow8nl7SQcOQAWJuH1d4DxGbCaWMNtBWDbGtgxCtv5MwHQQV8HmI3j+/ehQhqtXwfu/582WcwqTE1d3PuilE8HezamlhIQJ2xjSOB2EcKqF1yLMhNAbx3sOrX3eGZylILS6CM/PJtoqVrMHdv5FMlwwca2uYVYLU+Ir5bvrIYvVmdimU4atLU3Hzl49OUHv5uNzZ7ruGQS+3c/19a1HmLEfCKH4aRNSoTbM7EtrZ0NA5aph7xcfdDz4+9/4ze/+jf9jWxNlmUNjxxIJVKdHQPpXC5WEDCMgABhBI7bg9hGzRZNtMzWoFuoJr/+d//x1Pi5gTVVVUbHR/yucH2kcSGaSJdlHCMQQJDACQJH9hW1BzFMrSsSOH5q99/8818k0m9Q9smXcu3N7VJJXkrlmhrCp2ZmS5LJsEQtTkMQuGV/EQtAYFr6UFfDc68++U/f+QdBev0FiSaWP/+J35aK1eOnxkQN1IcCIxPTomoHeWzjTuAEac/E3qBAaBjKxp7W+5788Td/8o3LR5n0IWz1vnSUiiAZR1/4vBz0m4snexwYd3vPRl8AX1hcUDGrxd/Z3hASNEnR4WD7hjtu2+x3B/Q4wPNweOJXOw79YmU6G53Nhoac/UORnkh7LJec2ht/5ltHFibL112PKZQL0iyyMFUSZY3RdbmnA5dAvrAcuCZCtzU6Fo2DwHMk3GBes5WXgTg6Wa4WtZUF+qVD9ybKAwBpukrqgKxIeGIxX44uboMISNn1gw0sDk8tpzDLrCwtq7FodX6BJYhNve0uvWO45BOzil/XhoLdeSW6I/YE+Kji8hpoywLZJNk7iCVzgHUCBNxuzuFmcQgM3bDzWjiChoTJBrYYJ5WSsXETeOrH4I1WCZmmkE15WtoFxU44AABZF8u5OduCrA4CcWSpFUXWy+lMpKf16A//u7Jal3Y2TMNILs966lvzsoWT9mvMujnOzdYGsY0+jnBTEgRNyC4Ob3/ogpLemqYuLEwFGztykoGt1mDQLo7zrA6i6RCDCLNwUx07vm/P9gfNi6gHxFOLqgZx2lnSLRy3SyMoF8u6OYBBU9VtVxYzaSQ99/wDC4uvl5GcDUWTt267NpVQopmkCgnbykNAOVjWwyEcmqphzwQYPCg988pjseQFNFYm5sc/f/cXo9FkJltcyiVNnOZYUtcQxjGMhwM4ZqiaPQhU3Zz2qyd+kX5tQ1ODrMrxbPzum+5JJaLpTFkUxblUEhAMBmyab4KnWS9v4dBQdYiBqph10OoDTz9QPO+mvIf4SBtoe91WQEsElcH83mOiA29wQYelYFPJY0nrqMvDuxG0DFVh4rqEkFbN57WJpZdHZx9fiJ+WRxMyamVFHvgY1hoUXn08Pfr4iirqNA0+/RmUikPM5de0oglo0i7qRCvzaQtgGFe20kAxKgOfEAw65vZBljcXksX5BZ2yzIDPNxvdapIekqGVckmR1Eq6VIrGKBq2sownmZcqJB/CrWoFmqjBxTcFg2al3BXyBf3dyafb1HlqujjtIM2N/k0PzX07KZ3evn0EcdnZ7AzdOrDdquZByyaGxps7/KEAFgg6MRJUq7odlFZ0UrYooKvtjejI8+D5h88fw1Tl5IkDkOQJbxPrJOtafcEgdPuckLSkirYa9QSyYja1B6Ye+252+tQFJ6LK4uL4sKtxEKccvJsMtvl9Ach7nQA3laqOTFMzcbGYGHnhx4p40UBppZQrVGRnXQ+EOO+j/a1+bwDQHieAhlI1LMNQVPXI1ln1VwAAIABJREFU9p/KF6fbR8jKZOPO8HoT2baVr2N8rQGXH5AuJ7I0XTKBZc1NHz15/JWLjeBw8KlszOluLCgUsl8VwlHPeVr8zgAgHLylqYZsmrr07Av3LZ1VKfiGS6Gp6ULyk7d88thisipZOEbwPEH4WHdLgPcizMFZimLIRrGw8Mz2BxaXLyDOEs/EKY6+acM1K8XqclETJI0kGAiho8XhbvVzXgRZ1hAVUzN2H37kiR0Pl6qXV1rlo26gEQInToLdB8ylwgoHmHsbXGWpcjQ7NpJ+yUUEf2vQW1LkyC2CmZdvGnCcnEkfOPWApObOHkEu6t4msyxWXv1x2lTtnSlNgy/8DlhZMHWMNJHIN34MIz20u7OUWZFFTRWqMJziWxagI7GSNSBTh4jc3DxmmDSDkWLZv5JoQRBaGIsI5B0MkR5SiGZohiwqhZvdAfpUU+VkKEsuOn1g82B3x8CQUS0txKXsq61t+a3OT/rEioqb5EuJnx5O7wIfYVwJPmjLAmIBI0jgbyFpwu0gELIEyapUFNzQOZ6jOEYLuo09z4A9T4OLKGoj09DLab6xF6MdJEM5eZs4UazqUlnFLZVxuTxefuH5+1OjBy/o/NZg6qqpiZ5IH8RI2sEwLDBNKJZUtaoSOKJJML/7V6XU0pt/G6maCzT10azTZjN3MgyLDB1KRVkXVJLGkzN700tvoSGiqZJuyOEmOymKkzjjYgnS0lUo5wVT0xFSDu/48ZuI8rS2ti4szMfjc+HGHop1QgsRDMW4aJywVBGoBXHVxO9aXHgz9dhYamVpZb6vbcCkedPUnDytQ5xxURhuKhVLy4uKXJqYfqlYyl3s2RifG88Xy+tbBxS7s5MyDR2HGO3maKfd1qgUdL0kLkVPDo+9UguOX1Z81A10TVRbX920mZbMWcKx3PEjpUMmMgy9CE2h/vqp7psmlhL55RPJ47NH4/n580eIjSujOwRNeL1E6a67AMvCXEyjeSsUbsU8AyTpINNHkKY18Ij261+8xyqU1GhZE3Q1GStpOoHjvMdS23s6FpI3VNMzJuZyNzCk2804SDNfNoWSM+Cpa2nr5ksoxsGlQRlPc75lKqDO7keF4d4GoUf3ECswv1CYei72w8nSR7147gopqiCE0nOYKlSgvySCXE4uFWSjWoEkQ3G0qol6KQ92PQikypuNoStqZg6jHapGVwVQysvVvGSKVZJ3sxQU47PxvY++pdiYWskAYFKOsFS2m1QqeVnMVpFpOhy8Gp+Iju54E/teg2XqhdiEP9INDFqtKNWKUc1KYqZEUrSanRrf/5tL0SQsF+I8w/gC7VJZ0GRLKOlSRhDzFV0vDe+6X34jy/7ZsEn+V+mKBLHcHmwJ+iOKZmpVSZNMoaiLyZJcLs/N7hwfffUt1cFT+WSY8zcH6jVI47hezSmqqIt5TYzl06m5nXt+RtGwXC5fTFzGQlYin4w4w3U0q5OkZWCKXIEalAVdzijVeGb/scePnnrlYrow7y3WDPTrEM3qcHlpQU7U2uoETZgVot13Fb0B+fHHY/sOzifyy+aFHg5TA+ZZoqCWCRQZ/PYXgWlYS9NAlhKKnCzHhoVEJUBjWzahuqCeKYG5BBRdN+N8k2mwhpyhNNKNSV4fX8T/UBXL1dS0LhGuBr9ekLRUMeBlWga3vrznp3tPvOyvqwpYvCAabR3xhhZcOHhDPKPOEXkrGL2pq+6BU48tia+XH31kcYUMtA1k5VdQPko2NzjDbooGrnqHCHTdwxjTx8ArPwcXt0pnYCmiHJsgCMPd12FAw9Ps5RhAEyBz7KXUgcesS9NaFbPL1cREoKONDnsYN+1rcBCVzOTLP0vOHDb1S7oOpqFml08BUwpv6mU9vKvOwQIxenzH1LFnzUsu9c1nlqRKuqk1FBxowygAOTM1uu/I7l/I4pvFatvb25eWlmoVJrHUfCx6qqO+PjTYQns5BddMIX50z2/mZ4++pXWuYT4xI1QLm1raHSGWag4UlSruBLmZozv2PizJlXA4nE6n3+TjhmlMxCc5itrSEGEpE2t2ySzUCJ02S3v2PTExf/TKWOcPJ93ou8Fq3eXrECvGL/53ua4Rnxs13lKX+Wzs3g0GBsH6DTDsB5Kkhf0Zk+AKNIo0GM1N6OAwmIgahNPie+pUE4bcxUxR90O5tQU7uHMma+xtW3+TUJRUTRFG4xiycNMINg8o5dkTO3+DLOtUYuYaf/jj/qHCqSZ+DKOmg0eNF0+ox2/NDeQOjsakC4fn1nB5kV0UH/mOTFJ2xcCdN1jbWkFaAocfA9KlVpojUy+O7ixPH0YI9P7WbQ0bGpMn47mRl96OUC9SK+mJJ79HMuxdX7wr0uobycyXEtOXqMZdg6EKK5O7c7GRP/zKPaE6zy9e2Tk3M32JZvH0CIYWXRyWykt/1yEYuvkv9z1dLBbOLqo7H06nU1GUMy6tqkmp3HIquvvezXpJtP7+p0+WK2XtIgKvF4Ru6iNzR4Za6N/p37qwcvy7P3kUYsBQZcMuBQEYZtcOgjeFrMk7x1/99DpmQ4vvuVPJXzz7qv1BZEpXm6rmI22gz0chhQqpt81ToWngO98G/QPolrvw3jZssL+Optv2HdmfjlL5VHvbzVMrMT2dsETsBdJZp+amQBb0XGs2NoIXn9WK5X8Otmz0tt3p9fk3bt1IQ+Pg4cOzx16cO/zrmuRoXpMO5BL3hCIBb0Td5VlBR48bR1SgvpA7QkJCQ2usGlcJumatBprNPQdAdhEs5oH49vqAkIXMVY6L5d17qrG61MmVdyCjbmqqqanHtu+a9fMzp6JvyzqfngZCUqW8e+denIBzM6eFqd4ucoX84y/utBAoFHJ2p8iboqmpaWpq6pyDhyYmKUKqyFo2m3kHEwAAvDI+qwBpYj6mvrEP+xK/UUWS/u7xl67pDg0vZJXXuEeuOtYM9HsD0wRjp0BZsD77BbytYb6KLY2dsPa8ACJauI8tNTauVAXgVFNuBuY109cMI43m9/5Nz9kJSDU1dygXm4ys+5IxwBkmHR/+dS4xc/Y+t6KrTycmvkgmT7JoV7msAvV0e+6adX4/oFQFB99VY5mYKYuZd1UeEF9Kx98iKfgWGJt8tyVAu4+dW3N9QQSDwUKhcE77jP0a6Porw3PvZgI0wzx7cFJ64ybGZju55CUnUaw+cfhK9QheGtYM9HsGhEBsCc1NaF+8E2SK5vQEyJTlb4G9ju+hwGZj4FpyXT8TqW+dnJXnFop//f/q42OvPzeGUhZycwR0CYq7kF44JwppAbQ9k9uVyxvoDI/DGtbwwQOGYcFgcHJy8nIMThCErp8bmiRJ8vyDHyCsGej3EpYFRkfAk0+AuUUwPmYfiQIBFAHcAbIy2RIUe5sPCWX40E+M4huK92zkl3Y+/bNJRZAM9QLbK9MuO1nTPVnDBxvNzc2xWOydRVHeEjiOnx/7XtVe+QCHAdcM9HuMlRj45nfPDQQiBKKjkn6PnVLZ/gI43zqvRiTNbPQNzaxrWMOHCbaEIElWKm9Wg/hugGHY+ZGTNQ96Defigu6BWAUP/RKMHLFGjqxdsTV85AAhbGlpmZ2dvXzjows55gzDXJHiy8uFNQ/6ymF8wv63hjV8BFFfX5/L5S5ftIG4SCiDoihRfL+UZLwDfGjpRtewhjW8T8CvIpvNXtZTiBcyxB/0EAe88cYbr/Yc1rCGd4tbbrmlXC6/eX/EGq4KbO4hh0OSbI3By3cWlmVN09S0cxsgXS5XtVq9TGnJ9xz5fJ7neafTeeYI4fPZDOJrWMMHF8ViESG0c+fOavX9VcS6BghhW1tbPB5X305n4DtAS0tLPB4/P8rR3t6+sHABHrv3JyzLuuOOO84+Qjz11FNXbz5rWMN7g5tuumllZaVUemsejDVcSTQ2Nk5MTKRSqct9Io7j5uYu0OfCcdzS0rvr4bmCIMnTouNXP0kIIYxEIgRx5SYgy/IVeFDWsIY11OD3+ymKWly0dc2vCuBpFa4PMK6agSZJ0u12Y7jNd6pE2ohykaiWaIry+XxnzKjH45FlmWGYctluhCVJMhgMJhIJCGFDQwMAIJlMXvoNoGk6nU5/UKJRa1jDBxoOhyMYDE5PXwkyL+xCFdC1V/78qPQHC1e5zE7o34gwnEmu5G7/DLuycItRvfnmm2VZdrlcbrf72LFjY2Nj/f39Q0NDq1TOen19/d69e2uFjYZh5PP5d1/kiON4W1vblfTlLx8ymUyhULjas1jDRx1OpzMSiUxNTV0Zf4i4UJN3zUB/oIugr76BdkyMEAxS+vpYvOIqLywUs9GHZ2wR3VWommboevVE5vDILlu9GCEMQkVRIIaZpoFsYXedIuwnwNSgqb3DkkGCIFiWRSxv89LV1QOEqGyy0esxTdMwDIfDUSwWCYLAMMwwjBp1YTAYZFk2kUjk83nwfgLLsld7Cmv4qMPj8YTD4ZmZmSu2WyVJ8oJF0DRNX+7k5IfZQJM0CrUpbq7HMPP4/EEuxJcoJ8tyAFhLS0un7y0OqvJ5l7hWrgMB9hqxNUKYefGtDIUxuqXWNNhXheYvACXSBk0DIKt07W38zFgE13p7e3t6eqanp/P5/LXXXlsqlWKxWF9f3+zsbC6Xs/U5cfz9ZqCvImia5jjuap09FovxPA8hBB89KIoiy3LtZ2zVu3nPT2FZ1iVa22Aw6PF4ZmZmrmTwl7lIuyDDMB/0N/RqGmicQASBcgnRZj3HQNYsyrJMkjqEUCqfm828dPh8vtbW1lwuFwgEBEFIxpOD9HVVo1RSCkSdw7D0kpxPiwnrjcRw/PwE7TaMzhZKPMkpU5PF7GTsALYD1h7LvSeeRghBCF/cZ9PLIgAwCC2E+PC7vQjwja3hUoZEtvL9m/G/vF2wLNvS0nI53luE0PLycs06NDU18by9CzkfOI63t7fPzc3VXnKv1ysIgq7rNE1HIpF8Pl+rvqivrxcEoVYqh2FYIBBgGCYavYCc8/kYGRkJBALgIwlZlmdmZmrXuaur6/xKgAuCIAjTNBFCl0InpKrq3Nzcm9tcDMPa2to0Tbt8/dwXA8MwF6ywpChqLQb9zqErZHqe76jPZ8u4rgECB4Rt9gwcR14X4XNYggJxDKg6dHJWVcIMEzpYqyxiJIFCHjNTxgXZTg6c83gVi0VRFA3DSCaTCCHDMI5Ju3Skqao6k53BAeFlg4N1m2VdzEopWRdxDCch5SBdmlnFJ+P8dAJZloHRGIRqTb7wQuju7raQJQqi0+nAcaJSrcRjl0p1xLJse0c7SZLJRMLr85XL5XA4nMtmaYYBXqpcKtcyqKVSyel0iqLodDoTiUShUKBp+uxYG0VRum6vZ5aBXKRXNCo4vIDIJE3TFE1bDAsAlNp6qHyayqU2rlsXjUYty8JxW2ReFEWSJLdu3To2NlZbEhRFqUnvmKYJITQMgyCI2vtMkmQtLjQzM0OS5Bn3TQuEDN5FCJXs7fc6J0f46dHq0FaiXGzMrHzlK18ZHR2NRCIzMzMbNmxACA0PD+u63t5uX4dCoRAIBORVBINBkiTvu+++u+66KxQKffOb37zkB+ojijNLL4Zh9j3iHBbDmpxD7BrgZ8agaUht3VQmuZFEg4ODPM/Pzs6yLNvc3Ly8vGxZVu2mOByOXC7X09MjiuKLL754zikIgnjzBd7lcjU1NcVisVo+/wqDpuncKrf6JSYPP0C4yjFoCIHPaTUGTAdjpYoES1k8i0gc6QYEEETThMdhunmk6lA3Ac8gTYclEcMxQOAo4LaOzjDnj4kQqgWezvieOjod/kAI6UjLiPGMGOdIR4AL1fENHMN3Onu8dAB0CcvLy62trdlsliAIhmHGxsbOtv4YBGcoP+emorUccQ6r1HZYhnKpQXBZ18dPzHIcJ0lSOa9YliWVDVmWcRyvrTc10i9VVYtFW9gtn8/XHIGenp6a6TQMwza7FAUhrFQquWix37l5RZ53uQMePRyrLBbkc9tqhZ517MoCIqnEF/4k8svvhlfB8/zAwEC5XJ6bm6Moyu12QwiHhoYYhllYWKh5uNPT0x0dHXNzc+3t7cVi0eFwHD16NBgMEgRRc9zOgMqlEUGSUjG0/RFcEgEO1OZWq+wSlyd+8O/fQwDhOK7IyvTMhGGa1WpV17RDRw50dnRWhaqh66ZlA8MwiqIsYLzw0nMcy0H8g1R1Y2tFoascZtF8QS1YT2cSZCFL5VJC7/rSNbe6ThwS5k4uLy/X19dPTk6Gw2GWZXmex3E8l8vxPK/ruqZp76Dogqbp1tZWTdOmpqauVicndRFP+VLErt7nuGoPE0VRvb29JEnWFubV6PDqcQI5WStftY1d7drW/gCh0z9wtG3By9LpP0AIXeJjoarq9PT0+TeMpunu7m4MewvzyvDmxhbr+LzjDd/C9ikBhiFVP/3xzgZtOY0J0sWmhGje2tSCjs/b0QCesZd3ywI0iUriaeeXIpCFbIkW9NrdgRD1RPTxJWgYb+EO5HK5ZCLZ7O5wUu65wqRs2OwEHo+npaXFPl2dJvUNGQ6X89RR3NBrQZszmkBn+MAghMFgMJvNrv4BEFLUGaNz/tVbXFysEUh2dnbaLzxt8XVXgvqApmmSJE3TWN0BYJIs4Rimae/81DiOmZZlb+HePu/2mcuoiZhSeLMIA47jHMfV9iuGYTAMYxh2ulvTtFodEcMwEMJadakgCJdydkVRaoaVJMmenh4cxxmvwbjfNi1RaZm+2Oqi6/r09PTZLxqE0Ov1BoPBWpjr6ubi+vv7JybO5SGDEPb09JyvrfV+BkmSX/3qV9/Q6n0VZ0PzenO/7DCuFwShtlvH7HdMi0ajpnnRx6t8+h18j3cuFEXhOH5mHWZZ9szO3bIskjHbN0u0TNWONAf1xoCpGbb7n69gJQFfSJ020AtJUr+4GaU51LVVIiunk5uNfoMikIuzSiLe4Dd9TtOyAEEgw4TZEi6qWCJv3yCE4EyMvEQ1FQtZS6VZhmA7vH2aqabFOIXTPO4kCUqVysSRaQrDdAtYOGNZ1gXXNghAWpR0nUII4TgGge0W1+KVtb2CXdNiEhRGS2aVJXmKYx2Uu5nvaPP0VFxJjLOjom63u1KpYBjGcVypVOI4LpvN1jYE7wkCgQDGMJGGhkQi0djYmJbSlm7lVi4pYO3xePx+f+2mV6tVv98/Ojra3d1tmiaGYSzLTkxMvDnDTiAQ4DjO4/FUq9VUKtXQ0IAQ4nm+iIombSaTyQt9yLb7XV1dTqczm806nU7TNHEcL5VKLMtWKhWHw6HrekNDQ7VaxXFc1/WJiYnu7m67WIkkJUmyLMsuN0JIUZRapKK3t7dUKomvASHEcZzP59N1XcnZSTOGYWrvVC1IVTvd+VfD4XAUCoVQnVMQBJqmEUIURamqKgiC1+tVFEUURY7jasd5nuc4DsfxYrG4sLDwfqAiQhdykz8cGeOraaB1FSulieXUeG2rXouH6rp+5cNGTqezqalJkiSEUGNjoyRJiqK43e4ayYMoiqlUau4o726zjRQAIFXEMyWcpmx/Q1IhAq9z0QY8ZrEKhIusL6oEZw7xm9tP58SX0gRCdoRd0aBpgeUMUXPJNQNayPasa3+GYSDsM1cyb8OzUwx5PHvcQbnq+IaB0IZr629NgDmtoZRMJsPhcC2jYprmmcTd2cBxvDXS5XK5isUihmE0TZumWalUEEI+n08QBE3TzAweYpqyasLiiYyWyktph8JQCllWcjhpW4RisahpWi1mTVFUPp9/p28yAgCu77DGl0+vjjXUDE2NwTKdStW+wznF7C7OKovw/EWoJltXc111Xa/FbWKxmMvlKpVKtezZm8+pluQQRVEQBIIg8vm8qqo14rSL7ak9YYPmraXFOfOsJLCbtwoVZFkWTdO1/qzl5eWzP7W0tIRhGEmStTqK2qbHsiyKokzTzGQy5XJZUZRKpcJxHM/zPp/P5XKpqupwOAzDYFlW0zQMw/x+v2VZgiCcb6BlWQ6FQqZpulyu2qIlSZLT6aytCk6nk2EYiqKCwWAtDFIq2U/R+0emhLpIfONtqRG+b3E1DTRPEVqRCntNSdME2fZAdV0nccPtIOxwswEqkr3rr71FIZ/9s4VAVcIsZF/6N3kZ3i6q1er8/HzNgqysXFg9U5Ox6RX7aTBNU1ZtZ1+3Xs+PnUHsLSSJoabA6RX7m65+X/uQeO4YF8BS8lLFic+GoFUIjPRz4RdTD1aMIoiBN/mCZ2Ca5vj4+DkHKYoyDONs8xGTbQ6axdJipWqHOBRTSiqr/7ta76SqKsuyBEEoilILQ72jVxr5GnXLgE7bYzsn/4k6G+y1vCxhbs5aSF0gsBD22Svf+dEmbRVn/1r74dKJg2v5zNrPZ3b35z8MZ0MV7Sd8c5d2fJ6xVm00BKjeZ5UFzLJeH+T8qdaCGOccrx3JZOynTVXVyipIkmRZ9pwLVUuU1az/BZ3KWuiv1pd75uCZ6rQa05Cu68vLy+9PskDmIjV2F+te+WDhahpor8OEmNkW1pMFomagbZ+CsxjGqvcZFQmrGegaGgMGBoFugEWNVOzKhfd4/3IpD1+hijU0uGrOiLKKcySELxEFO8J+hdb2Dm9vQcok1JV3ecUuaLzO5GMvCPcqcBynaVqSpHfY9YvA2XWHZ0ARwOeweMZKFC76DKeKuHWhVa3G6Lha00lqmsYwTCaTqa+vVxSldkTX9ZrbWHvzdV0/JxzscrlqJS6aplEURRBEuVyuRY2DwaAsy/bKUS47nU6KsiNFEMJcLidX8ZEy+fr+EALhkhPL7wwkSW7YsKFQKNTcTJZlIYTlcvkSixc/EGBZ9mJF0B/0NsKrbKBjOYIi8XRx1U1+zWClSzhJ4IncGw4CAE4tUmeVDL/H1s3hcDQ0NKiqStN0rZpCUZSae1IDTlqRPiU9y+Vy2RrvOEKIpRHP4qL8fnQranBSbi8bnM6Mzefmr8wZPbylW7iy2tVpX6mzONrPeHYQorfMdr4GWEjYkQ09YJd4nP0figYOTZ0d9LjAgHbs4CLnwTDM6/VCCAVBcLvdtZteK8pmGEYURbfbrWlaLVJ8voGueaMsy9oFJ5bldDp1XScIIhgM4jju8/lqMV+3220YBsdxrzvskHS7HeVymWVZe1jdTTMytbodxDCMYRhVVTEMw3EcIfSOOZRxDNUCKZZl1YrqMplM7RS1iYEPEdjVb3f+8TUD/W5hmqZJILfLb6cmVh2N2qNjnpe8qgU0zvn4exhgkiQpk8lACGtO0/ntIciCmozRJHQ6UbZ82tC4edMw0aUEKK4WIq42AEDi/2fvPeAkuapz8XNDpQ6Tw87mpJyzDCJjC2EwNtgGjIEHhgfmL2MbeNhg4Pk5EQwm+D3s98fYBoxJBgwGGWQJJIRQjqvVanelzbszO3k6Vbrh/c693T09HWZnpd3Z0Yqj/Y2ma7qqq6pvnXvud77zncICWPMkGSEwtCHuA6oUL4akFJJEVMPDfKCKtRVS1leD3XLncQZwd+1gAO2Xq/39/YbOIW2ZjJSyVCrZ4rqZDgtcm1Krv7SzSLFYPHTIYEDGFq9As5BC/WWHrCC0uvXVq1dnMhnf94MgUEoRQiyj3C7FMpkMIYQak1LOzMwcbyEcIZZupB8f9YUkvqs5KypZ9Dnp8iFKSCmiLlcAGP5vXpXuOtQGo396Ge8AZXSqXnl62amMoDM9YtMFCZs7V+tVNmpAeDcMp401vfmk4v1KqcWbDStJRnf7nNE4nl+TJgIsmLgyzRateNwvp0tiaz1FIxSCbukmJCrDlhF8YPKBilLiciiFpC+vZkr03l1eIsj4LDteEk7W1+Wo/a1GbRZCHMeJoiiXy1kodvG1reu6uVzOIuOe5/m+PzY2htqKlEZRVGc+WFZPqVRqdWFBEDiOYwtD7OCcnp62ibUoirq6usrlctOI6hpM/ay6esM239U/ngyeeGIBaG49chOP7UmM+Uy33HJpnC17V50djU7zqQJb049BTxgT18HI2nOwqiBMyKP73b1HOSFP7zoO6Fxt+/MI+qlaWOAHtjthYZ6oaPPUNoJo2mjlkxp3P4FkjyAIRkZG7NccBEG5XM7lckeOHGmcgRlXhDgSSbJ4MvhMFk7utPEULXCwrl1p2VTUfpJMSdj/cLBplYrQBSP44HAsOFo7IEanLWCFOV6t9XF9b5QrUOSSrfruXTXhlYWG0ZNOShJ5L43zuusuYH1YG+qRnOm5KNvT04OKAiZutf7a87xsNjs9PZ3JZMIwtIQ2znmSJK3Zv2w2a9Nx1sszxoQQFtouFou22LrJQcuUiBS5OshwN/dhwV9bXMyTG1rlObbrrmzvVnnnjgzqiGkohVhqEKdEa8KZlgrrrSjFr2Mgr8amV+4AXqJ1Khe0ZV/wNLdTGUF3ZSgRzrohVY6oXQIjf4gL12E5w+KwtRsW31jVz4h5wufKyOKw+ZkT5R+FEJZaZ6lFUspyudyY/nIDdcYVZS88L64g50lK6bru3Nzc6Ojoiu0Z3B8MUsomy0eX80P3jjETlM1r6xSQvVAtEVRKJMlxEVT16jNjhWWlSMRs+w7fURuGkU6Ov7v6HvTjHY8/XWSEQLky08rIrm9pWzTcZG3fs3iVc3mWl2fhKzU5gHWre1IhN28Yuv/hvVF84sgGGtKIbt8HYSSFmSeskzJxDwnjBeDhkckVHWH83E6xg+7OSMLY+iExNs3qGGU+UIGnhntFMaT14jpU0ukTBFkcJIxJlJ5gYCFN07Z5hvk3RHTfQ7motJOQ+dDeDv0mx1Evz2vaCMtuea/bZd7R8lIVQp6iUa7Pfnb54KNBWkbJ082bN1vGruM4VpZ3eHh4//79QRDMzc0dk+pXMzL2hKcE2XxuxxsYC1KJ6WSBUKK9Y8kEZX1NiI4TlBOx5Rv2+7Ll9UopS4K2gBvSvTvgsxbfkBJTl3aFB8dpM3PlIHCnpotCnPj1zUyJDg31r1u3TkoZxzEq98ax1hqb5+TmAAAgAElEQVRVAZYw/TyNjHYu5j495p5T6aAPT3GnxuKwxAyt9fgs45wdnlqwEQAe2de4Yp3f/tSNEJrnPQP+KtFbLhaLtgC3kehqHmzS6zPwgRI9hieMDzansr+bMaodDocmqxuVTFcPUKFIzlcHxrkt117+6huUMgHSGww8Nvnw8nyikuTQDi+cY4Sgx9mzZ491c/bCpZT79++3wO5xZaWEAf3v30U6yZIxxvYfxfdQip/FGLUE+bbDY9Ico7e3d2BgwNLjZmdnh4eH77vvvjPOOMOW6rmuOzExsWrVqv37909MTLT93J6ennw+PzQ0NDo6Gobh4rN7WyuVo1I5mphcLPPxJMzLqLXnxBdlyY79E9u2zdpZpI5o25zk6cTi8M2j2rr9tLnMU+mgpUpzuZTKfgv52eqsxsKBRjtJsoGcOucPXjbgrcrw3KwsrlmzZm5uzvO8IAgOH56PPTnTGc/oVDTsy6j2XeU5mlEghBm1EEIpLrQJ0RlPEVKVE1l+yzi5MC1nnXxlWTKEaBpKVUoyeoRWL5wkSTabtfWi+XyeUloulwkhS6kmqCDa1P5Wrl69uqenJwgCIcTc3Nzg4KBtK7NIWfn09PTs7Gx9yty3b18QBDt27Gj06Yu3gp40tgLbRStJohKbVhAmBleqXaO9tCcX7K9kyxjFsdbtP3fQJ+LmdqnVZ6VivF9rFDcolUqtiicn1Shh5w1dumt6W9wzh2nJAoyOtedLFSq0HNfxFswTGq9BDow3bxQCcVizhdU3Lv9T0eX1VERZqJUVRGQymVwu57puoVBYu3ZtsVi0nu6YO25ZrfYdbY9fHDlypM5yc13X1joaFZE2yqvMSGylAhPRltBmuW62aMUCMrZvDuc8DEOLVimlMpmMZVlY3Mb+smHDhmKxmM1mC4WCLVHRWh89enR4eNhyOepHtsq3cPItjcnY457p6akBRH9vbuumYZQ8LIaP7lomsGs5LZvNth0/P3fQJ8DCgrP3/kAKfKIOHDhg+Rv2Z9M7baK8deNTPIG1XRsPF/bF8tjlRkrJbE+SD9aVimXOOWMsjmMr5tC6wloJBaZZNz8TTkq93A66N6eE4mGH9mOYm6vn4iYm2gpo1C3jKSGB52Mp6Eg/OWR0o4Z68IrmyjhGMi6uYGZKNBWEUj3ULaeKCTikJ6scpicLrC8vZ0pMaRCyuvIZ6hEOI4Wkb2BggBubnZ0dGhp64IEHtm7dah2x67q2sPDee+/dsmVLFEUTExNnn312uVwOw9CKau3cuYNxrCuxcthWsMJWJ3Z1dfm+L6XMZDJxHLuue0yhxJNn07PlbTsOatR1eUoIGyHExqqGhLOCqBFBg6jZaSbVvwJYHFniuXTr6nR8tgo6Y5aGip48Wd0nyhHda4ImOybWDkLOiHMenORW23PpbXjaGiO8y+s9MPeErdld3BxfrzsvTMZpNoOyMtlstlgsWu+8uALDqTKXeZTQKF2+c6MU1pwV9Ug6M+smsnk2HeoWnousO0zTAarFDvXIiVkmFJkusvZzTABhDG5WSaHrA3WwW67uk+WIdGex+IUQUAqzx7057OQw0ifnKnR1n5CaDJXl6j5MNccpqeuGj8+iGJUQ08Visc7SsRBHU4fTvXv3+r6/a9cuG2jfe++9jec2sjVyM7pw5PHpIkJb1vr88SNHML62BLtTno4bGBjI5/NCCKVUmqZSyifd/8nKLXV1daVpWigUVk4JNe3cz3tlPphPJwcdJcRxYHKONtYgJIKkgsyUqC0XrpsV6xByPhp6irama8OR4lJL7ETMdt3Ro/VYI6xs43qjR9y80dZ01Tc+xbnkSRinPOPkCkmzdNnJMxSdo7raLrLFShE9Y018ZJrnAkWJzviI0StFPEd3ctBhQqIEZjE5TApYZ4o3cPs+Z/t+x4qD1+8o9po0vyiTk915EDl3+UA/ZItB8J3Vt3ZlFCF6YkY1SYi0fZgXcUMTB1xK4YxVqlhhaW1AHp3htXaZp8wIAS8ju10Y6FLr1nHXlZNT057rlipi37jXKP99XKa1LhaL1hVyxlZzvsZxnpXNPiuTcQg5lKa74rgg5f1hOKvUYbOCPLVQt2NaXsDT306p3KjQhbI2PNlqZskEy3q2pGdL1Y31eqq5sp4rVx9DO20+RZfX7fcdKuxd4psDD7aswfHpcb39ALoM1P/15Loh5Trgu+rBJzzLzuZMnrNepRL68+re3Z6VRDiBwntLMUqY1DLvdZeS5RujWsGhHQEflqYzSvMkWgrhtkfwvhloHpOutYkW61faHjBJscbG5mUf3kMAFqxYc8YKhUI+n7drrCRJGp/JqXYLXMvieOomTPSw+4iFxavfrO8pWK6MbCfLdMktl8WXB+yVvxAD7KhvPzjB3/05JK7YaPp4D1ttJglwjeOcGwQbGAsMbmM9/gbX3WDKgl7Z3R1pPZ2mc2n68ampqYYxX/+yT6DRGkel1az0Kzz97VQ6aMrToc1RRp1v1b9sryOL7WazWauJYQmnVvGdc26rSKwol3V8Vl/86NGjx7Xs8niQiFhhh6IlmZDkyKQtHJvfGCZkbJZzhr2c6l04hCSHJhmlWBMhTxFY1+31zkUz67u37JlZ7nYS+47aMu72Vz40NJTNZi3y29fXZ5ujd4ICFn++GGP9/f2e51FKu7q6JicnBwcHlzloanIBoyug7qNSYLvvyUx6cN9jOHl05QPOKOesHOokefJNT6x73ULICwGoEDJJQsOhZIzZdKvGta+IhUikpFL2APRQOiWlR8jzguAc173c93cnyWNJMinlz6JIA8RP+V7xzlw6m+yFp7+d0q7eDjAOh/Ye6u7qtqrBVkKsrndjBcNSY/YXpXBxWi6XrcZ/NputVCqZTOZ4ExfrujYtPXy2wf5cuTqezGg0QmkK5kr1QVY9AaVgdj6MWkByWjbrCwbHSgfP7L9g+Th2S7MoiqSUvo/NXEqlkm31tPgulr/77POb+0+GYbh7926cpjWMHjmkNJmYmGgq714/JA5NkCg+WbDDKXfHjUYIMdgaSSr0aAVsecHIcC6fC7DUO061fvLAcY7SNweBL4RjikSlUkJKSKsFY5oQfHob3u8CvCqXW+W6z89kvFrd1qX+/DeYaP2TSiU1P28Lw5kndSd5Zwd9GrSLXQEYdIkefNTBxzasDp3WCKi+pUmYyoKGre0hlmYk6+TK6XEoXRGqBjaG/cHFR0cnh4eHOecPP/xwXX6vyU751B042Upa9rkfi2VN5nBXre3VYerNlChBXEhHCUpkcIa9DbVGBx1FUbFY9F1dKhW1Rr2O7pwTJghGxwsLREf6RCkk7lBZIdDlNNVnEtCXnxnHKeYY84HacbCN8kYlpivJhZ4sY4wNDAz4vm8btNuNVkBqaqZydALVo9I0tdHuk1v4c4BLHCdjlpBCqRgBqLR+c5vQRgfgLEIuNosbJiXSGGs8ljpiyZS6xgS5V/v+eJLcaR4ZCtBF6VrD6ikpdVhgdniRZ+n0kENa0V29T4kFPBOK4xPap1Q7nj5y5GBUUaOjo8uMKR+v2WfUYV4il6+VJ+P6zKvK3pybHMFkVH9e9nfJ3pziTLtcp+hkMdNbiQkl2CRXKswcjvQJKbFle4SNmXSckN1GABoTcXNcKR0e5VJQ2NL8cZxhQXN3FpN+lbh93pgzzRk5ld1Ml8WsTG6jmpjruhdddJFdaDZ22qSU2sDieD9CA0S24ZUpb9cmk2C/J4eQHsZyHBOzoVIVKWOlqNYyTSXysvH2E0qrIqqUCq1TIfAgtdMghOQJucTzXpLJXBMEm6zUlFL707Ss9U/CUGh9g6H4FZRqBEZ83+/UMWMlP57HZc9EBz2UHRkvty9I6WRK8jFU4UnqsbwFuVo5vJ02LtuIcagrVOoyT6i0sePByTYpyJ4HgrXd1U+cKdPAQ+3srI+hcSkkA12yHNNcoOIEI6o4RXG17fvdwNW9OXVoEgkeiZh3tblAlUJSKeDN3HWwWRA8TWHH/mrK0W5oPSXTfuw0eVAXMbuSsz1huasGN4itQXzpmls++73uVtnSRRJri5hSajYMgxpowAG6GOtlrMuE1UhjWng+FgFUUmJJj5SY+jeIg2pI9dp9OMB7u7pW+/6IeWrqc0wXpRcY/uvVBhh5X28vaP1IFH1qdvbG2nzjeV7betHThgR9Kh20lLLean55rK5+1+33HZg7vg4j/V1quFcrDYGrH8HupTjo84FeP4yrsHygHtpTZXG4jj53Q1oKkZNbZ3EsZ/9Kj/uxjFyGP2F5LSqxKVAJtiDBJ3kvToL2qvFnAVX/lNHWm99ofx4cJwByurCA1DFp4Cvbgj5SpLcX5Y1sa8TFdeOegWZ1NrDIi0GQkwM5snWNWbMYs5UyJ2oE+gBnuG7GQN6YH6wduRFdAYoYF+pQSplq3VRoYPEOezYewAVKQRimJsomjOG/BlREo74NNrSUQmxUanXDZNDv+2sJeWV/f0mp/wxDrfX2JBEAruct0ont6WWn0kE//vjjy1lkZQMHnwexiI43tCxUqMZeIY1idsjiODLNGYXxWfTddjBJQQ6Mc0JgrkJPCYsj73YX4jmPe6k8BUHEDPIjqwXuJ8SsNL5th2p7V9taidNmDXtCzCqc2Lbxex/M7AX4958GAOnqVb39vdiaoFyJ9x6Ybz92vEYJyaMsmE61pgZBFkqJOEZnbFvAMIb/KFWYURdJimTLpu+IEuIy1sW5b/CQREqhFJHSKmRrKbVJPNaY7XhcTakttGk8jgOwjvNXZrPPHxi4tFKxE8Nburu11nuFkFo/kMlME3J/JrM9SUKtx6R8+o6VUwlxNIq5LJsNZdeMl48c72nECdJymzYqpWYK9RxGddmolJput3F5HIqUstvr2ze7eyi3OkyXVaj6JH2VT0Io7plmGDhr3QUwTGnZcIzqNldA/4VdcJ+aqCkn5PxsNjD4cqwUlg1JaaWX8FelpMnyIXmu3b4B51gUb9KU9e1uTbzBQiK65qMldmDQRhlSiRbC5i+67m/k8xcFASVkxlmQOiaEbDb49UhvrxOGbxsc1ErNJsmfzMz8+9MW8Tj1GPTg4KBdxp5UE0IcPnwY/Zffc6iwQIQsTdPdu3efQsGEE2hJkgwNrotllHFyy8yxO3To0FKK5k+SveY1r/ne977X2gNwRZmlDHueZ9cETfIyFrmN49j2FG/dvSmS4AB5QlZTul7rTb6/jrGAkHvCsIjtUmpeOgz1VJXpJI0nxcqfmlOzlIzGj8gSkrNkvYWw8iops2nKTPSaM0+KolQxhpGylPUnpzUG4QDYNoIQXH4anR0bdDe9zeIzsnY+jQpk1uoNo6nWF0sJpZLkHMplFYYIpzCGQXftEZaO405NiTDUQvhKNUpKUoBNnP9WPr+R8x+F4ZRS+9J01OAwlRW5Jjv1Dhq1InM59KFdvaWzLmSVYte2e4vnXpLduY1KceaZZ87NzU1PT9uvUGvtuq7jOKVSaWhoyFapHD582PO83t7e0dFRQsjq1au7u7t37tzZmChQSh09ejTDcpWk3FqfctqkFBjhVsHO50ExXlagNjEGp8iGh4fDMFyxTUIDY7bbofXLres2u8binFsJ1rqOc/0Ntj9A/eW1lD6XsT7GkDRjREkIwHMWshpsgTwS45TJDWjtNVDxtNaRobLVbQtjPSZUoYTYf3VvWs+jSKVSpVIDUFg6R91BEwCXEIfSVCmh8THjAMSkCqvnbQ9o6ByIOBOCrGophbk2+5bGQIkSwhlzDNhtJ5gRezpaS8dhlQqYIWchcOujERVJElUqUYOWRAAPmDvpApzlur+Wzf56LjdovoKXmi7Ds1IWlRqTcluSFJS6qVKRAI+lqdDLrjS2Mh00Agir1s1e/pzcrm1EpM4MtpVTjjt32TW9d99ywQUX9Pf3DwwMMMaKxSJj7MiRI+vWrRsbG9u+ffvQ0NDFF19MCHYmHhoauu2228IwpJT29PTs27evyV8QQjb1nPXI+H1w+lqX11OIMWLK8NzEcTJVfm4nyer619bHCSFak8YNxIcqdFDX+UN2MEA/wCQhMw1iH30AWYBYYqqBEcLNP5u1w3BH68QgEolSsk5oq/10AXKE5Cl1GCtIWVKqZPBl+zbbsswGntj3gWD7YYRKpMR5oyXSJKj9Qj1KPca4uc5qOGwuCitG6mGsvbbaPKMJSdsdDWcIxlA0smE6QZ/K2FmOgzdHa5XPo04V52AoIhYVsUAbnnxj+12AZznO7+Xzzw4Cx4TwWE5WO2wPpT2UruP8CrNq+YOeHmQNxfF4kvz21NQpTzWuCAftH9k/8l8Hyaru4tZLaabHKwq+NudOjHrd4ubbv1uvF1q9evXY2JhVI7LRxOOH6B0P3IQtOyMiY+R71tsstcrfDGVXz4STy9NB9VRZT9A/XkKEPXCyYXp8XO+f21Os4rPABec8ipA03MittB6pHv/aILIeR7dG0wygi5CNlG4mZCshI4RkASoAB6XcqdQTSh1Wql59hzGy8YZVfwoQtfA60YcC5Cntp7SLUt9ku63v66LUUmcipaptgUzwWz+4fYng8EJ+HgHwCMlx7jOGafGFRA6cMIxLbewVIIVQcl7trG1ihiMTiVOLWkCbHnL4khAVBE4UAedaSmVQ+LooO7ZfrB15SqlQ6z/y/Su1hjCsIiHWTVtIxB68/hHG+58pZbBIa8tnmoPGMEHJTTnPHd1dLpfcDesuKBzesWeHpBDFYT3vsGdvR26ciIgIrYYcDjDLmbW/c4J5g4yTo57/8NQC0cgmIwRWjbC16zkK8yT6kYeTJZYEcs5zuUxX3iyyNBSK6rjyxpmA+B4FgpBanBzHjq5LchkzWJWemk4qldDU4GBu0Fu0SoUxuOAsns9ToGRsXO1+4jiqyzavo2tWcyCkVNHbHl3qLTpdy0MYY64xW6dn/xQEgVJKCBFFUYIZOpQoaGpUb+X/G/0yNRHxMCFnM7aF0nWUdpsCyvobugG6OT9P6xSgYEJUT+tEa9XgwrSFIBY6vn5CBjnPWzCkBV+2rxlAtuZMpcFDpNaNOb1WyxLSRQjVGsefJV0s5Ns1Xq8wOIaV0Vrc6eAkIYS2A4uiJ0WHa11qw5FTzlmphEyS2sxUv5xqGM4YUOoScrnn9dgLscuCxrmw7qntLw1/vTVJVkKR4opw0K6v0pjOHEldlxjdpPK0k8RzjmgoW1iKrV+/fmRkZNpYf39/b2/vQw89tNk5P8NzB8qP3zN91+Lsupe9wnvHO/PDqxzGiEjhc39f/P8/W8x6pBQeI30wMjLS19dXf9k7/+vxWU/vk9wRH8IBcXDfviz25cIRRgmVHdYKGR/++r2Zl16X8bsYcDY1o9/0jqlt2/ChjhcAks3GGbzmWv6Hb8uNbHSJy2JBfnBz/P4/nUlCXYpXYoLlZJjjOL7v236Gi7D4rfKX6yLfod4jsU0k2GDXUfocU/1hiwI7HRmDU627tI5N2V6qFGYbG9/fsm8/pZjkkTI1GIihGS/4CAupoGc3B7RwMKO0MYnJDbhsQ3Xrw1CNG0AZT1rFy83KwNYNWgWlKr7cELA0nhymTBlzDY6B8I5BmVljWk+Zj6rvblFmA2kKKXWStOkph+U63PE8y6Te4Dj/4PtV12z9rz2+3bF2fPudVd20saNPuR/IaeKgGYeNF1em92fiQqFYrN6d7qDcPaT3LKDDHdump6fHx8fTNM3n80888QTWlQrxWPSABq0Q8V+MB3bGWez6d2X7+7DSihLgDnn9W7IbMxjLfOhfCzsOdAwUOYctG+lYsEb6GW/8SPmM85P+wf5bvn/dtdfaKCmXy01NTdmeSffdd9/VV1+dy+VuvvnmJysk0t4yAf3gG8+9wj/6nm85d+xOGeWdwJz/8Qbyil90GC7hNBDR10f/6VN9E9+Jv/Zg/Pc3L4aKnL8Z/uQtvGeEAtVApOeRl1/nXZD2qml41WdnxudOB22axY1z3tvba9HkTj7URpGN2EUjoFyPlBOAJgzOMTUgocGUOSGMUkwX1vw4JtNqsDL60AZ0wGqeMlP0kSMkoLRgSqVDpdKFFUHoAU0AjgFmzVML45QxvG29EFyAEpcQj1LHoCL2IKnJOlavpx6Q1ih31ZcGX26dty0IgxAz5zZCtxeI11t/u/lobfjRVX9a327OE3EMxpBDXTumubOUOg4x+pf1Ohd7JgsQjPov1ll3WAPevDKIA6feQUsB+x7KrOoifX1y/3i179x0kSFYsKhLbbU6y8r6PpsHtxry9Smzk116JTiuLUnFLzMR6vF95Jee7VV2yVYGdKN5LqxbS6YfGy2dfTENy4WLrorWbOi/9T8nJiYGBgaSJLFdaCuViu/7q1ev3rlz56pVq+CEm6aXbu4dFvuSVFPCMIJWbRw0o/Crz0Pox4xOgv9AgWBnnu11PXaMjMgbXwJ53zyQioDhVslYrdnslkT6dC4FOA5ravhUDRhrD39rlq9uDCCn9VpKtwBspXQVQBFgByHbtd6nVGg8zmwtypbGCYLBaplJ0GEm0PAimu4yosAAvYT0Upo1ntQiy/2mYCTRuqzUnEGWmy+k5qxt1Nz0V2IUNgLGspxbpvE8uGw8u0Nppt6I1jRutylOPP/aQdoy/ynyi9DaznDzWyxMwQzkYpBrEKIJbUHco47p259aEyGQ3RHH82nAFjynPdax0I9jhhNWhJ16B40MrZAeTijn811BPQcbIy0nqZUyFUbCcQhWDJrH7pzNEO8QP92W7j+62GIHpxFMS4o149vy57Ghuz6ZJimshyembn+iQ4Oh2bHHoAdMungxI5Tk/cGJvanruscsbu53R3r7D/7s1mTHERnwXCqTThE0ByVjQVy7QsVUTG+/3nN78p17j+GgR/pBJSlNXIIoPQFNONfC0Z+9sTI1L7t6OptFjetosoWS66651SN1Aayh9AxKt1K6nrGcCY3tnwYBNlN6LWNzWu9W6lEp/ZbdbfYvUSpc6EPR3RvuQRelOcaQytYCnjCAwETTAwsRjEYedFvjAP2Og5j6okjLvD81d8NyNo7pTRwALgRCFoRgCFxDltvC1trUv2AcvZB7N4+W1L2tfWlmNVQkKRYhiurEu3nsoo4yp2nVgzdS0RvOYbeUj6+M7ApfMUNfdXWhrLMdGJlM5siR4wQ4npRtXM82b3F+dkd8zx36pa+IKCGBTzmnhJIo0v/zU4W77haiXRw/MkSuuTL4r9vCckVPTML68yJH9WbIZuKRBx544ITUDTLGzrjs7GD9XKVSaXTQ69ats0JlURRVKpW1zlaHOCmd+NjX93/jhlIkoD+Dcn11wJ1RuOJ8nuviP7krSgXsPggXBhGhhGmHSFQa2/V4+psfnx2fa3POz7nUWbXK+eFtYaGodx4mV58nVTGmxCMKgOlU0us/MXfDbStiMbg81iqGVS+osy+JEbY/l7FzKB2hNFfjqLU9Giekn5A+Qq5gzFKVkZCwKFRNADZQOmjwARu9L+JG7YlZBCM1U4h7LPUbpLjZHKZdItTY0E1nYtEMm/rrNNptrG3BmQVriloAO6+wbjgb6K9NphF500IssuYlnCNpxpbzGFeO0bQBQ6TncatB2hQm1wPk+pbGip6FtkJI0CvFQTOulST5fF4pZSUX6kT9k2q5HPnQB7ouvMT/6d0x5dDXI2cL5VKFOw4lQLKBN1NCJcxWowQ+8M7stb+Ye/tEbvSo/OHN3q7HMiIpUrpdShSpsUmP1upEzGK3xAsNo1evPSc6vx9++aK6y/uv79yRu3UPFsra11a0zNZeMsbCSlgRxYosFopTe+6NI9FGT/Vlv0A+8d6ssyqz7QkRhWrjKkXSuXi2wmOXuTwi/PoPlNp65+dfBJ99j5ffkH1iIjc5JYd6gAZFUY6pkMx3SOD87RfTH9yenKrGMafEWsW+m75NDvDLJmp2aiLWi6DVCCsrZREM6+fcWobNvocamK9eR1dnkiE6YUNLAyVbN1o/GXRZVqioVk7SatTgGD7nitLIYMqtkLE9Q/sEWGdtj49+WQikG3cwxphXa7ZSX2VKw4lugy1obYFgvDRTkNJ6QDJ/fzlnTGYyPE2rd8l69tpeMp/3DP2uCjE3fkrTkRv7Wi60nxrRpZVgp95BMw5bryhP7c3MzYyGNWHfgS65bpgdXBRbeOp27vnkzHOol9UveFEgJI6hfI6mqXAcmgkc13U/8bfO7//u1M4dzV9WdxdceTl1fL11K9+0yXlkOy3PUoeB56Y7DzkWiEuSZMMqs9ikeq5M58q4mErTdM0AwtaEQCWikwXciEpdtdkoCelcUR8Yn195FSrNdNF9+/Y1vhyDg5gkzJCXvDjzjX/HQNvnmaRBqv+1L4EgA9RTl13qICCvpEp6lEHWaeBmfO9XXg6PfKIZQvFdeMeroDuvqaPOOss5Szu4MhV5HacoDeUyyPqXXC3plyJYlPtxmllbyZFGF5waNNkivJZZzG2GrebdbCUeilpI2QorI2cOIDAktm5KA6NuMW0L3mpvbhyOyvjiOjpMCUGnbI7c9vypIS/7hLgmfMBTYixrCw4NMwQFjNrNKNZZm+5C7bVzETGntF5dskAlo1Z4Mr+jUohdNBIqah/T6c6D49iSbiyZ8X0kQS/8Duz/pe8zKcF1q4dK0/ZpwKZoeiGHb3LFaHGdegctBezfFsiYD3TreifvQsioYemc1I+mHMDXmhleGtaI6nzOodTBj8ZvS65axX7n7fk/ftdMU74NR3UA2tGEKEKxt2kYU+noKK0T5NESlDyGOCFJQ6+QKMVhlgrS1EDEHnh8nzcOcMdD+GLzhiGcRc5ac7E3d+9DC/RDWo0xeN1vZL7/w0Il1D7302oCH85YD+du1tpV4GikbTAFVCOIk2X4sBp1vje9LvujW8KZObXz8fmhzBmCzpqbHakyXbsV4YwESNnGHQl97rPZZRe7Dz2cbFzPZub0kbEVwUw6qda2nCpMyO0AACAASURBVL3Jox3R+tLa79JUWkc1fQkbLLd9+D2ALKUDjPVYpl3tyB5A3nHWO06q9bSUMw2FHo1W5VdImbRbemKwTGmGMZ+x+pEbz79apV2DZatd3Wre/5iGZYSGPtGWB934QdXfDEnZosykQc2j444AJE2JEHZHbEXaQXfF6q5avgd6507n3zZ5WLOHV0zD2VPvoK2OMGNkqmBpPGiBi/SCk90BVCldjoWfMkJw+UUp0n5wTqXmGTByWsOrcP3U5KCxwUScJKnLjfpikpKJOUsfqq9B0cZnGwdeda6eKZLZ0nyue5HTO3hkilE6OVVckhSZhi0b+ac/2vexTxd4mUe1CPrgGBwYg+4BQVNhiDGWTGrXd3iJEKssJV//fJ/Q9KafJH/9mbnGuhXMCqaCpMRcnNmxfplacUKv/y1v3R9lN2xyZ0tw/yPiD/54eva05tvZxGCTzlGTtc0NY3sR450bNzKAjOlI0ktpZiGvrtGsA/UIWUXIKs6N8hvqCskWbnWrUYB+o/B5zKRfI0KCYK5hcNdaHS66F4CrFIlj7GxGqfWhbVN/8zREIVQtEl9isQNpAEMkpXx2Fp/V+sc1QhY2al58almYYGxy0DtXRoZwpThomx/nnFuaEa6RvK5l0Jk8sFcfOFBxOHW4E/iaM2nok0QKprRUE1pycuvNkWiZTUtleHhbfGXg+oyTBJJEZXorIsysW7NldnZWKdXX13fgwIG2/XiWLsuZpjIFGcVLm8wJECZf9hLv7DP6v/aR3IY+8YH/gFhAlMATh+HsDRHPOOBoEhIIKAQEGNFEq2JCFSVZx3GVQ+Hl17m5TPfDXyuBxz55Y/mB3bBuUKi5GB/QCgFOIUPBNc6agFZSz1aefzklWQauGszQa1/kfv4zfUf+I9xZgP9947KKnZ5aB21X9PVl8bQp8HMbqGlVJbYWtPocznM10tkSTwBhayFsOYlTk15qPJWm96N8s3m+pMVAaizuTleH6UTTkqq+e1sowwrjNd6BKlhhZZ1t6s/qzNVYyVUdjjRVndNLlmSCKzyDZmhbBF+vLqmZ4pxaH1onMteUkiCOj9EQvsONqtu4XMZOcU8LB02oBk03bdpkyzpmZmZ83z961DTfOJk2Ngr/92/Fu98Xr12Dtcv1NN7+8U1rkwN0pxjvS+65u82Xlabw4U/qj/2v8qb1ASARQucHRGmqUiqV4jju6emxbhqW21AoZqBr6C2/Msgrs1+613n4II7UP/s8rB/WF/KKlwtIGYg2tAKG1TtyJqK9GYQ+8LnD3a+6cOh5zJsei//2psqf/7PeNAIXsIgAJREFF5caIPAVkpqiVM/FpC/AHXEhgQUEl53XdXXkfP+u09M7WzvmN1sywHFrF9sml4BEGBNWp5bvbGQ527pOZf2mUslC8bmmgzvGBbdVIKofxzpHBIXr9TZWwski14tm5vEkkebk21NEFoetcNEaY9imfRuctY2sMQvaFsGf/wBU/UefXovliaXi1Q9Yd9atZj8OoOq4F7em8Lm25bCU/1Sp/HMYrpzhe+odNOOw6eJw+mBwYP8Togav9eXlyAA9MnHSMc377oSjo2pkWEqBXxE1QuEyHtNEEqK/8E/htgfbn8P+Q/C+P5fv+4Pypo2OVuTo43mtoARj9aaFdk3QtBeK5zbk6E9k4wJb1oO1VxXC2U92FnccqcYRU3Pwug/BJ/9QXHFeuStD6SwhFcNnkgKUdoSJQQgHhqGx1iWd1Tc8FFUSXY7hLR+F//Fb+vmXVAZ7sf0qiRkwIjVMzJEsT3IeoanCmJrWwmoQ0oMH9q0UCO9kWJIkrXrNjRF0EaCsdb7V1doGUY1AmdY5mzlsYGWgKJ1pGWX9su080tbj2nnVrSX9bCzdzbnQOpLS9m9tO3wtLdr+CYG8zoVG6PJMnpOZU2rEkTEfSKlnB7nx0dW8X5uj4MTQmTSHwDfh1SCpY0E8MfiJXWU7Dvg+TgkLP1FxXi8vXMxMSjBUytEYrQAhFa1viuO/KJUOnYK4amU7aClg8qDT72hvSO4dq5LJ5io2lXHSHbQGOHggPfNsQRloMCA0IetGKuPbkx/fGN16z2KOZs8+eNu79Mf/LPUduWFIOQx8V+84WGVxSCnPWINcUlMYSWcNi0MptWmVcrDQA9toWRbHCcoYa8zuS+jKJPcfUJ+7ZbaRIFiJ4W0fgZEBtX54fvxdeAa897eJjATjDgEBmgMlmSC+/6HK399Ytid1dBre878hn9HnbbKBCf5MUnjoCfjgG+G/XUd0JIhj4xEGlLg8/vpPyp+7pVlK8HQyWyu4iLCGAJjQurFa1Prlage/2kZLnGg6uDLwCJiKxLSzs6AAWOlnkn5NPVuty3Yp7XIcqwTNFh1jnWjMeBzO3UXB6ybvSawWqGFo6KUp6ViCR1Vxf1HkoWq2wsWWmbQw9jRjS4+gv5Mk/1qpDFJ6FedfT5LtK0N8YwU5aPdiN/vKLP8RL0w4ZazNn0fTcj6WGlVO2mN+9lnsda/JHxmXX/xi6b67yGVXxkpB4DPOFQGSCv1Xf1e+/ScdvfOvv9R79tXBLXfGP7otEtKJYlWOqMt1OV7A4ihUaCthoxgSzyWpWEDtOCGmI6FCffCA+ucb051H28Dfs0V400u9NZuDH/wsPjwq5lKSKEELoQvAAg6OAEJvvj393U+XSuUFz2yxAnduh80jcP2rM5Hj/Ot3K8+5kkKg8VaVIk6ABA6KBlJ940/S93yhdHozoy1Jv1GquMlBS0OMa2tVrLZmcTs5zSqRud3uTWSMYyLXnFJeE5nDihWDkCwF70ZWBkdt52N7zA7lf40d1xcxvApTyY0vbMmfddad/LXWimIVGWqHtph0HKvTf6xPNURYgHtMDH7DiuFsrCAHTXpJ/oN5LIK7n8BMNSrxPM/3fewoYXjtuZw6GU2MHAde9zrvZS/xSMB+9dVZByUM4rGJYrlMuMM4I/29wW+8Jv/IQzNz7co3Bvvh+jcFG7f4L315ZnpWDfTTT33WHZ+pv3N+Hh6rPqaW14FPnNZ6co62bnzqF6U1RMVY5PldD9M4Jm21Rn/zRfC2X2PuiPvilwSeSzyuZRhFo3PxXMgjTn2uAv8fvh43eWdrvXn4v+8m553LyaD/6ldnMx5m4uVMRU6XRSGksaCBM1Zx//iviisyEDnBNjMz4zhOJpPpJCtxtMN32vS+uNPb2jnRDKW9HL1ma11fJ6srN+GUYsBipwV2a3sUk2QwckU2aLXX2OFzqwr6RmK1Lcq84MiGXdf+0xvVi+ol2rRhkjB/xWrjJhJ0zaTnoRDH4lY74KxSPYQUa5U4K9NOmYPm53O6jipHWfqMwcKk7/tr165ljB09epRSOjQ09OCDD55wzjjnsHYDJZ5mjh5eRc3U4AR+l1Kac/A8pNu/4EVk4g+7/vJP2yhg9PVCXz8hjgpcusrHfhEmQTL/LQ8MDPT19ZXLZc75/v37m3Y/SRWShIA/nHEG2Mte0r/9VpC72iz0fulqwDiXqa68CW6kplme2dSrpQYKxOXEcf7wevbgI1NzhebH7JIzYcs60EwTpjJZZhKKhPUHtMcDhbuD765m7MUvSr789ZWTYjlZprW2Lb6sTn8mk7EBtVXkEELMEILjrB3K0RRBd7L2YXVN6xkLCBuSGa21qdXUoimCWpzLjLBerQil09XOBxGWm9FY820EojD3uOinIDuLc1oDrG09N3rqTg698U/UuOlan5RFvLDi3DlmSFcT6HhnT8/Lc7m9QtwaRQekvDOOCx0WLs9EB43ZOEcTZODoTZeEF/bCm58Xf+UW8e2fza/NJycnGxV1T+CnK64l05RIJKcxPLLjIJRnlo1WAI9d98uZT3+iUCq2kbBRrlJMU8BEIjPzsZ+TGQpr+1Uqyf7Jiu3t0hhbnfTSJMyc4LlT7T3vOeQfbmkfBWuuTH2NAceZxitGjLHa2ghAX3ieM9BPWx30+ZsxCQSOAm4Cf1Qc1ZjXdxg07P76V+e+/q1yulJYpCfdrKJsFEWmAhkb/di14H7GIJNpfX+TJ7VM4CWCCI0+tM7HqDLnage3Tryqjt9uyNURFSuVZztUgcGO5zsNLu6sbbrPyD0vJWS2CcDG+nV7FxD+q3MzbK5vKc4aQLquW2hfI6Echy2OQXOOK+jamWzifBPnL6ylfH8aRT8Mw39ox4595mHQDoIBRBCtyMyos30SvizII/tRwflkf7IGKIciTpRZbmnDQKgVXyC9F39DJK1D2lkrqFSSTJ5z46OISWeOnBFfOKze/AvpdJG+/W+z9TDZdatsK9tW42RfmBZSJ87QsFi/lu8/1Hwnp+ZARKmTSCRs2Jy8ZV9YQ6aAoppccDbv6yFSwa7HRR3ueOhxfIhYmJLENeWHZscFu+OsBkpnM2TLekbNR8zMqr37xekNSVvDWLU2dNFROk5kigMbnW+9lqluqQG52tbRNZGmG1XcGq3RU9sGrPOKzB3MNjBsDMCrJYuUuiZakaYD9zEKPQwAsoh3Jg3cjMXQGFu7yNi8gv7izhrQQbMOqDHyozsByoRg/XenHjHmeq9h7OCxqnKeEQ7afZbb+0e9LIOrQq1hdsyZBXj8IFI4shm+cd2gBc527D4pgnZxBHfenmzeEndnXUaZ41HTNRiMEni1uikVMDfXRMav2oFDsG17dEXG8TljESUBlRIOPOJP7YJd25UhraXDg91JIhyHj43PLlMErbUuawhAJc669fKr/zjwF58ofv+H5UbawA/uhKvOlWI2xm89xIIAyNK6F8G3RamnyN99pAscJoE8uE383nun9+1Hv/PQbjg0CRt4SosJaJeUjUpeZn53y6SOi8mXP5q5+LKA+hQ4myvBP3+l/PHPFHAFDKe5mV7VNJPJYLN5x/m6UpcptckIa9TB1ia3a3g3S30IF4fGLKCxCJrBjf/FdkGLsjLqsa1Flu1P+8vSq2ksmlGHrZdkdfFSS6kWopOPVo5DO6jpN3YjbPmbxhbgdj5oaaCFn2h2fHTF1BCeMgftXO10/XW37tOS2RTEgr8yRscn5yhFbPcknYDW8M1/1avXVn7pWt7dxTlXjCF5g2qaCpaUhNqnU1d/5VulSjs0NU7gC1/RG9dV+noCGhPHQ5aZTGkhhUIZ5+fuLj+X9f0+LoQaPTpzkq6i5apMgMYA68u8cMNG8j/fmz/Xh6uH+R9/t7TbqGR842Y4dxP85otQKpclZphi3IUjVRMqKzFVhORdzL5TySi97BL+4fd1T90UzxHy/m8U/+br8ME36EEaOproMgUXd0LxftTlwIlAS33ZSEjzvmV0AJXdPfSdv5u/ZoAle+Rn7ohveXTllGidMLPdrYIg8Dyvsa5vB2M7KO0GuECp85QaqQXUtqTHOtxZQ5r2Ohy5cXKtp5WPl/pjUCjmooTucdQrVkNgg5hblHmJaUlbv06FQCZcQ9n3kj7ymAIaxo5jomiSrGsSIK0nIRs+bvsz3UEzCN4Y0Fyt5N+UEa49N2TxehAZO9ALhcLo6Gh8zGzsU7A4hh3byHUvNYCzqa/QRIeJf2Ri0/p0BxmXNz1Y/uZXO8oc33EPvP/PxfVvLW/Z5PYx3vTQlCvJ3gOT1QYTDfULJ9fwHFDSSEtGnRRAdmc3vfP1h9nhOHdj9fySFP7X52DHPn39r4ddXTzAfkeUuvj8hLF2dOL1ZMxBqqXcGuCy8zZl6eF7dyCl6bu3wcOPwwfeoK48r5LLMB7j7oRTqWklVo/t0+v606FuI6WkFdKijeIO6j1dttnPHvz+HnHLo3DaGGPMN+a6tolgO6dByBzATxm7i9IhpS6U8iytfUKmtT5EyE5CDlL6+wADS/5Q2aIW3fRxra7NdquyshX2b0ulfywkZlQh46WYXRfXKRn1oLXuqZtOwJ7zElwzdMB55v/UuDvn+M9eu0VOmnAbu93OIsbKShWe6YUqFMcjPvtI36gurZMKjeYKSViklHLObX78ZJ8ItumRSiorZmfPJI7Kh8GVhMD2nWoRcqTWcN9D8J4Pqf/z17K7zyZV5oOb/v7+DRs2cM4nJib27NmzDMLW5pzwruKNlQQchSXZcgp8OTqnxmbnx1wi4F/+E350j16/Kj13U/WslYaJGfj0uwjq8knkaWBHK1PLpsisdPRtj+HXoTXsPQJv/ziM9KuLz1BDtiMMgZki3PsYjE3BJ66HX3keQ/VRqRDmVihsgk7aCSci/aNHTqvw2ff9XC7XWhfaaNUm2UYj6XEpd2udB+hnbIYQzEOZPbH2tJ016XssUOHqvEvrxiro0cCZqzvK9oS5JRMzLEpQXey2lE0viFvrYWkr09ng98fWNmosRenwQM1nCBmrZgLtR1iMu17xaDHu+kEabsJhpfasMJbosjtoCdETEVuHxUOm3RJxGRWTQcBkkIGZUjVJyCj05PHcHA5G5Q4tTdP+bvvMQyJIlOAviLs9qUkvDFUpFI6LHSQ4YtCEM7Flw/SB+9Mffz+6y7ikxW12DmZnRRxJrfTgxiScc6IipgSnjNmnCw9rRoZN7sNJM8ztJErHKLFhQgPo6y7uuC/5+NfKjQ7a2pFJ/HfnI/Nbzt4ISaJ5mLqukSFFjgd+Oxm/9JWbS3//4/migFTAgaP4r62pVKLoquOiQikeBJ1AEk187N+Le09+4f5ympX+qdZnG2tUg6sBA9giq/F7Lxrw3yNkA8B5hKwhZNjCu+0+onXjkxjoLSSk9p66qmBn1DOOTcww+1DDfLL72ntRZc5ZR9zW07UynY85DSw06bp1ALoeFlW1QVwXywg9b0Ejq7o1Kp3WO3kvdNCVFSMDvewOmkHu9TnvYi9+IA5/FMaXxa5yUXiZksBVQ90yF2Cv1rmya6BUcB29qldyBoGnZkueMgOYEDLcK30Xa/OmizROj/vkh4fpH727a3JG/+M/l44c1MVCyilRWe5gWwl8wMoV/eG/L999Z8fg2eHwzjdlzz3X+86N4e13xeNTTqUUiRSp0I1s0eXICi40rXVcShI/DzIGIXSsJqfU736ysHNve7e4cRj+7O0Z2u1/6bthuSJWDdLZWLqVBIXVtQOuoR8SuOu+6ENfL0XtZqueLLz15c5FF2duul+OTaS+C8rXOHWWY2TuaVNbyCCR5EP/p/itu9pXFjx9LY7jXC7XqKZie8hav9x22eQDrCbkAkIuZGy1EXrGXbQuShmYhn5k0bLD+XC4gx0fPL2wDmVJIbM1u2hoQHWqCI9Z/1ZhhLZdWZtsUapGx50chzU4aMuBqeqcuS7+qT5DNGEp9VPqfGK3Jkn0zHTQzpVO5q0Z2kW9F3u5mZzwRGUWF3mU0dkCEUerp2EXWBjeJmT3Eadpo9Z69+G6iONxe0BK4eUvc5/3XJcF/AXXBVJBJqsmpubC6dRzMeNMKXTn/de+Pn/k8Nyhg+392uUX0Te/Jsj28V94rjczp/t6SFguCSGP7rGZHtxreLDbc3kQuK7Dt+3AdifLYAQgDZPylNJphQqdRmLbbrL3UMeg9XdfCS+8nLNBfvU1vYxq35EqldGR2bgUyiTlvktcNpM47/9Isa13ZhTe/DJ4569RNsSveUGG+4QRBUqKiZKcDcVcRBNJPYd4+vNfi7/1g6i92M/T3JqIDbZEpZUn6gNsIORixs5kbIRSv6kunJASY2UAV2tfKd8ojDfJElVXSEZcKXP8J3nMd6A68zF9Za1n4CIo9jxtQ2sMVJfAmTtek55Xd9BNc5J0XR6GVa1ReyZ17LuBp9F0xo2vUAXlmemg3WtcyIJyFCWU9TGqKXFJVIkIEDEgktH5iNWgqCYejBc4BrzhVCudmBRWw3aqGbKR7c5m1aNBtogyGvEEdflVLnU1c9XQMDU9rmBkVb5SQWzUdWgu6zjcecGL6PSU+ss/nW07qF7wHMJcoI7KOo4foPAA576fme9HjhIcxdD3nblCxXGWD0EilORGco7oUULSgDn9wdXPIhecV77vwTb+dfUgXPdsTOMB01mMAgn6CUr9td0qMjVBnJJc0MvYJZf4u/a24bIEHvzmCwHrVoj2fAU+Q+xbETaUo12eTiVSxAMXst45lzqUhiss9XICTJq+fPVekW1tIyFXM3YBY0NGjL9RJqnRUHcGICIkMgrIVIic6dtdDQxNwWGJkBmtRwD6jvM8l3Ljj9G926iAoqTR8XLm6gRnC0OfCIKE8LygViuI9S+M1ecA4brebJXVuiCEbyTw1f/adKrGbjyZxIQnZ8vlQbhVqzXrKiqRNMFJEARAYPY9s3Opqag2apnpI+ncW9oUWF/2Uv7G93R15xAVEcijN5llq3NZq7pQKHZJCyX97msn5MLBoLXmjgLH1abWGTAbjure3KNZP7DTra0hJAR+8drgnz5XbBtEZ7IEPNtfXpiqVyxU4XwB+z2Mku6eviRJSstakkR4l8viPs4lYYJQ7FL4O7+du+/BNro9pn0igCur7azQNC50OacZQ0qxTa2A/M4bst/+XrltyhYfAQbgaawtJNXjYFM8150/AiHPeZZ71WXe7XetuKH/1O2YUeeFhFxDqWNTpdr2UTtW91iJdHxOSJfpCC4oDQlJCXZRT0VDo8l2dlz0s6Y9O/2Fm06Ax8dobjTrJYVoD0k/ieOxWpLQdgOot1PRGnwfY/xWKot92QR3WFt4UcVnbASNqRKlCZILZG39VvubA9o1oa9C4r7u1yqjdEuBNRaueoIFmM+rBy122NTbMEkFREoukJ3RdjygOLrSFPtuayM6X19M4g8LpWDj9oB4HbipQmBG3pUovts4aCk2JkcvVzsxks1mow6SLifF7CVIh3BJmalQ06S/t5NHwMlMCam1IkqaK2m4FdWd8Ah93aYUuAN9wOj/SlAMl9+W4ls/GUv7w8cILr7g9HTQSZJ4LQOlkXpxtNY9lijFCcGefQur/xGzlzKSMjZ+uW5S6xggxsQ1yxPSQ0ii9VFKbZPAxZh27ey4akxaJZNIS1JxSc7axrBpeqJcszXUGtUaawIXKpTiKsR2lfX9KlWjkRnS1jsv3L4jTSefsQ46fjj2yz73OUkItpow0fQ8Ed/+lKATLSZFq3cGgMfvUfv3Rt5ZGQMwAHMJcPSHSHOs+VapIBE6TNrHNSKFxx5Nzjk31dph2LmVENTZNGfRwAsSEmsIo7j9V3XDf+kXPT903AyKCwhCHYLXQmDTRZXCuFcYz9q3TU9X49b6A3zSS71NSlsLh7ghIQK5blpNT7b/xMMT8Og+uGhrwssG00d0wvSyssFezYEgIQTr3dvcijiFnQdhpE+pQkJdioocCXI28CCs8SACFP/BTStI3GA5bVZjZaoFN1LT0RXLRkxfklTrSIhooV+uGwXIEdJv4min5vQHGUuPk/NwzLzicVhNq2jeUy/ippU64a4ZjRDlunVp//btYuun2uSIO/loY7fG8UfL5aoI+jPKQdMBmv/vee8ajwaITmimZUVi7ZT95Bp2bCostKiI6Afto865cfjpN9JNfwyuyxT20wMj62KW1TX3KiSEibzjP8vYRKjFlIKvf1mdf3Fl6+aMk1Iv53DFqKlUMe03qzz3JNU3/bAyeri9a7vnAbj9jvgFz+MB5ywiLEtIwJWEgzuCNCJaYZyYCaqVC57Lp2dLy/Wla8xxxAzVm1iiI02YvvpK99tfHPjcl8r/eVPYeBpSwae/Bp/5Q8VmQo9koIJCbKZXoUn/VbV0UF9wKNA/+FKf5gQoe+xx8eFPzR0wicdUwIe/BFtWwzoaOy4DD0gJ25qa4m9UoDJttNB+ckd4ZFQ891L21t/KrF3vAKepJl/+t8p3bgif7u1lLZGjVbm/HkHPAkQAVaqHMRtQp6bXSesBKUCWkAHGsM3rwgayqAZnqmNSrSlKddlqombruNg5gdbqqRsfQtvl5Km5ZmxlUFuSkabLrHvhVhI3yjWYapfWT+8kwUHIlFKfLJe/FkXL9qCuIAdN+knXX3f5V/gERd0BUU6GEVZcSjTRNOLaF9rUN2mlRUnEP4jFf7TPJFz8QveV/z3XnWGOAZ20JkKxckwqcUxSYAlJAhXGcud98Q1/15HCPHEUvvrF9J3vEauGMo4HnClDcyJCs0qUpKkiRbJnNP7yFzomtbSGv/okqi0951kBj6nvOx7FgZFU5kfAQF++tyfrunxkqPcHP34oSZaleFSDDCWLZCo0dxMjVqZXjdBVq90LLnDf9A5V3i+G+/lNO2IrNfeT++Fdn4aPvCMdJCGnDolRmA/nPWZ6VSB8oXSqeOCcdRYDjgnxM8/mF1/kvv3tk5sCev+o3HlAvuMT8Knf11tI6ORBh0AERdwZJQIRlSYayqH+7OdL734t/M6rA7/fxVwiR+7OX57T/Ypfzn7mg9P5PPvRzqTcYb2ywq2VINFUUlg0+b1GB93JPAD0y4zlGTMt1zsEp4YSJ60aoVLznrqDshJWlAJkj79A/Lg9tUV+OwtoHPexayw63nDyeMOFgAi1CprryLEsVqCQ/7Es0vr+NL2Q8wwhtyXJX5TLjwqxYiOFk+uguz7S5VzqKKbqgAYi0ZwwQtUuxYpQXBPJI0IXtHpCqbsVPGZ7KjVb9xD5tXdmh1Zz840omxgUCjxO5RFO9oACeePjxV13yn0PgFi0xKQwy7IZD9O/WCtnhDdxfU9c5pBdgo/Dv31FHD64mL8oFOHPP65f9fLKr77MPWPYY4x0d0vXmX9YR49Ojo5NYriNPf8WF8mt1VV1wvXMOJUKOknr2UfD4RB4Ip5WWkwz7uacFMMtvOfIsshk2Uff39P3gMhl2Ws+N/fTx6pw8I/uhVe8F173kuTiM9MrziG8SLHnNyEP7SblUG1cBRs3+4QZhozpdU4p3bCB/ttH+rK75Xd3i7f/09y2PfCqP4FXPV+98LLyxWfSvA8gsHvdo/thpqgf2w9f+J48b4N66yuYk2WAhzKJMiKZw668jH/xfX0wJa//Zvm79640+ulxqEI3MuAa6AAAIABJREFUwdCNvjIFmNK6v+WbbQKRc4Sc7Tjeov22FxghwkiDJqb6Kcu5Z1BD+yfMoph2IdHxKDE9JatnAk+UUcodBzlSC6tm5pt510N1Gx1brkin2t+FYiD3CPHmUqmHkEs4vzlNVzj6djK/vgzwrUbRqnFOfOK5WpXo4AM0pjrV6QcS+YTEgbxoCLXxItI7VD2SPYzU8MiuF3d1HdqgHyMUfnhrcsM3liSYdvlV1Pca5mQjF/HAzheuGXxsRB6OqS6Ujj2blivwlW/Cq19JsR85wBteW/z1Xy2bon/+wI5nndP/cPD47L2703f8w9wx+b+cwyXnwEffn8n3utxjFMEEKwxHtu144QXBj/UB9fHvl//l9o7tvyiFXIDo3Fvet+Zj7zq6un8zYUlVCsNcohTccS/uWntfYVKOTi94ikYn4eP/giINgz2aIlMAd5qagzWD8B9/09D5pQrSKyWycbAu27PD5dXjzJbg89+Df/w+9HdjV0ZL65otoaQUZokA/r9ftTnIev1CNZupZC7u6w+ifd3BSQnvTmF/wrqlAJNan9myven9mKtVKjbZP2zP2tlNKwuPmPLZ+sZY6xSVCbEVoUl/04pSdUovpq7haWaGAUS1rXypa5BKKYMAmc5NZjh2TfzoRew8x3l3V9cDSXJ3kqxw73ySHfQ5hvisqNFLM1s0kL77dQl/QV3OBKikMjk2XNWzCqRG0gFixui78Ekf7r2b8wiK2ATH4XSJw3DNBoxGpdJUVcNWrWGk927fSbTWM3N6dGqpyx2HY18upRR3SHcXVkIqnZyx4aF+XnI8qRKRLEG4Xgh097kg6cpR19O2upKYusQzN93XG8oKUz99rCLEYndp2ozMAd4byV1absbLU0CUJZoAhSTftRPG9LfvjveMtzmOUtgcttGuOh98B3tKg2QYwNs1C/4X+rmDM6H6l58ueE60hskaA7XJcOGEsKsiCw9FSeLkpr5xT/xvdz6NO8yWSqU4jrPZrOlFRVth6Kl2SyiLq9b/kNR+x46xpptfvYt2vXYceXhCIAmvw5oMJ1JCAsdxKM1qHUpZNhogTzvvXK/GJo3F2ZSC44jubh7H+HsLkLJYs6uFs10f5293XaH1hJQHpPxhFG1LkgfT9JmHQd8PyUxCPBTdQHDT3qWeMuS1mJTl75bTHak6uCRvuPMOVfht4aFuBsP6f5PH6hsopEI/sSO5+RvlO+5d6vLqkQfFZZenKKUCTHN0hgAwNFCMY/3NW0rf+GGy9+iS8htKw+hY2tunGJeEMG2UK7AGZGhm10PJf307+urdSyWWEQJpnIrYpQyxesqoDTOH+6d/9u3oM18Mn1jaKbnUOzQRr88jl5DiF4v9VYASCiqfKX/tpvLHbqgscQw+/DiJY80jwXy8RwiVYNNuQOmEtPiOz83e+tiS+2wSA2dHKUGVD9pwKHH3g+VP3VAKV27HziVZmqazs7NWCdr3/bqbto71qJRNva/qssv17wI5zlrXm3Mj5UOpVClmZPWFUsnCkLnJGECGkKAh9MZInJA854lSofH4Txtr0jmqm3kpgiBTLqPahlIo7tzgUoXvL8lB18h5nJARzkc4v8rzhFL/Xi7/XocuLaebg3bOd/r+qo/mafRAImaTNJvqTDUwNCt3UIkSWkAKanQx7+xnyNs+2H3+VcGj2+LxMZlU5Kyb5gPtOqbHj9HXD2P50zuTW+4QyEHuYJTC/3hX7rprc1Nlevsd5dVrdRTHhBAZaEZZuYiUHSn1o9vFx78qhKCO0yHhC3D5hc6H/qCnJPSPbo80QCURhw+LTJ5beRbj7ImQ8JXvya/ciuhfpyqzC7bCX/x+Lt8f3HRnPD2nKFVj00kpEkGOc5dQjqoGGHxNq/d+Pj54pOOBurLw52/3L7gwt3dC79idDHN/eF0GF8vFGMDnShHMyOGh/u275Xf9S0cSEaPwpT8JLrsss79E794Wg1a+C25XIqKElqgDHoIf5lBS6w9/rrSId37Hy8j1v93F+v1v/TiSJuq/7BIKtCjChHNGwTF5HyTkzczK3/+buaWvV1a4KYUNjsvlso2mhRBJgn71kOelvt/6/TXpbKSmIrzJcOEhRNIB2yUAPqU5zoN2Hb7tS48x1zRptUjuivbUJkZeXDxaeh62ixWiFW6Wnuct7mHrlYQtAh1cyuJKLXU90Q46Q3IfysNa7NoXXOuB8uJyHBZC7JWNvQ60FJL6ND+cz30yV/xSsfipYqdGEb/4Wv+K57l+Tl/1Yl9qkkg1MVsan408F2tVrF7Yqt7gdX/Q2z/gfuXjc02lg3Vbu5a8+IVub5/uGYGNZ+Sk1HHijE+Vo1js2t7zH9/sxzcZYeqtW6tMZbtEbW0aoCj5i8/ON3na9qipJavSoaobtYZSuf/MVtyxwbQDf/mFBTjjvdsaOlbUNscxBLnBRQ7lcPjyLYTciqe0ccR581tpdiQz9aifxomSyglcXG4wklDnGzcsJjPwxl+GK8+VmTxcsJZdcEne1J4olXrxWCEpRUpI7nsoG+2wb/5QfPlbHRGJN1wH73k18XOaZNR/e20OU4JKaKXltJBTFVEMWSpp4ICrJov0g39THh1foU/FkzatdalUQkocY7lczvM8l9JIylYHTQmp9xjEcpUOB2zrqxhAlrEc586iyhjVI5hMtFXzQhF9hdDeEutWsO7jBJlFYLDspfOJzus1t0+YoyGFo91Qxj5YbSNoe1gpq7lEm06skwJrOiE3n3x94xXhoAkF2kOxMpBjVogS6uU86tOwGKLLc6if85nHlFaEkcwbMuKwCL/a/oHPdhPHB8YVjkeFdP1VfUGmkoRRSinJB6wn53HKpNYveX124kj6wy+2R/wvv4oEOUJdrbmVvlK+z0aGcsVSVCzQcpnJIKsyuXh4jczmuh6446Jzzo6iyHXds846a/v27QAwODjouu6tt94aJbLlSWoTbrc0dG42paG0tPTE4sfRAKXazSvP9PGuo0Com+fBYLeITIjhAc97jsM/8N6el7/maKcs9xXnAnUV1mrj3bYikIpQ6q3uUmGCCqIMdIbTnPecF0P/31XG2gHZAHDlOcBQjtC0lMWjmba6SrP+LM26OkI5du0Skve6+3gpfRpDz52Mcx4Ege/7juNYJ1jSumyYdmTRcRMb79PWbzZRmx2AQdd1mlDaxc0EHEj8MOr7LmPYk/D/cfceYJYc1dnwqdDppskzO5u0q9VKWmml1aIEQiAhkZM/g00wtgRG2Ajbj4kO+COYbIHt3wZjcjTJBBuBPpIEKKMckVbarI0zs5Nu7lBV/3Oq+vb03DRBCxpxnnlmd+7tW923w6lT57znfSEevMkMuE0AeJx3BBctD9rcwG7PsUGlt2hCZcxvFAQpVRg2pTUWJXaVYAGbxk8lsrXjX6HWcTm/PONP57Qfe/yQdoOoiEQRjYhDMsOZzKqMO6CbCRHLiS3Giinvj41gW7PZHoyezJA3Az2UJBAxKmwOQz32xlXZDSMZJIxDEmdsWGFEnH1pJ9kg6OkH4hDFgSBZRESpZBQ8l64ayvTkbSBk+oJn89JMfe2G6fOfJbzs8PDw2rVrL774Ysdx1q9fPzAwEEXR+vXrDa3zirWBTJ9VOKbAonZk9djeSNYbzTr9LsXSPpx5Or/ogtY1dGwYuCAIQGm1IgVEYIMlI9RjfMCzR3PWSIYVLMLIqhH68pd25lPTwjTKUjHFBxJ0GOVvQntsNpJlq3N00CMut23ywXf3we+KMcYymUx/f//w8HChUDAaK+YtBfBlzm8lpDjfzzb51rCLi2h1kTr1ETXIpru4F0NLHYRhtV73gwC318431CA8g5JOUzhFGrht8HnL599o/yWI5brc84htC8YiDeVWXboQ63X8MSQe5k+zAlikOQ7+tO05NOOnopX9QtzZRZ7jCbXj7HR0GIDoKqKQfRL9f6uMWgODHiuAtDNmgdsvQlBaLDAmRVLzMwlYfYopq1TfaqO01GYovBxIb0eYDlDiLrnGOESpoeu+X1jn58d/rKaus4Ym7nvspwBq/+ztlWo18DHXDErtGPulNxqrf3YyrQmE3z05ijhVgjlzFoYL1AxLR2zhL3O+dKirSECYUNImPJp/wnX6BmDDum7LVX0lFLbNa559ffSp3/EZN631XVyJ3lAKZF1B3YAGy2BzN1h8SL8bxhgbHBxknUJaQmYAfsDY9QBnC7FdygGd30ig0OZpmAJYv2hlQkPHgUGxLgA2yQUkHTRGRjaKWqgdGyb0j61bzwljkVJt+xuPi+naJY31ZI0o7YI9h2oetFlSSjoUPNEZNM1SJpedcOmZHXX4dgtK1fzuOOjo/sgf993VLsZiSmfLkkc0RhLp32YejyCqt88c+xV45O5g/UbXlF2Zbh42HjlOVcVyd9iuEgh1cHfY6RzffYd8+asC12GcA1VId2WWDelHqXjAgQMm6WCfdtppjuN4rlcRlSNTR8bHxxf53YeHh/v7+6WUnueNjY3lcrmhoaGJiQml1IH9B6gtbU9WprDKr5QqFAqVSsWyLM55pVLBpbHFAkRSLcDM67ou5zwMkRRUw/jVqHOCyzLj/qMQgAo5CrmmTwUOJpRgu/Z2BLrccC8851wZVQLLNZVcfcHaXDvtvDvfy3uO4G9RC2jNxlSJwT7iczJ/OyVA8ShYsQ/F0sxMw1hf1tZWR0opNSnEj4S4TsrthDyD0hG9XQCwm5B9lM4SsoWQtmuctuFN+k+h0Z7o9Bt7FygliCF2t8PWYD7EBhrgB+dcKUfj/LAsedwX/SlwizlIpNQwBP+L6w5XjNFOHpaxmNHJmI3CRsnO4n4wzudhP1KX6bYwrK7UJMfxXrYfhcq/VOh7qEUsEhLwgLipRz2tnheqqBLVvtI+ESkFXP+16NSn1taMulaVYrLZw0yFicXmSJYUsiOVa/KOn3ZMaP76Afj5tbUXvJBlLE6rxHIp9QBQiXvulujJQqkW30A7duxIfzyNmuroOokaWBNOj48nHEkAcOzYsX379iV/5grCzcnqdPwUGd3CiYmJQqFQKpVWr149PT2dz+cPHz585Ij2cx2MMXbiiSciOcnsrOu6hw8e7mfD+6s7PaemJiKJYK0QmZIaio/mNI0dCW+/u2MI/8u74NHnwynE5w6HjCJlLdTtUU2ZkhoHVLUqbr+7Yznlqz+C55wNW9ZLUawjFxVQqCCSADyiCTrmbgMhxCc/X4LfIWJoFIfXxubzJht1lYRcsQ5wq1K3CXE6IWspFYxtZewZhFSVYp081Hy8R0wN1mK4HNUBZqSFthbINlBqtcwlGEZruJ6rv0uzxOpvyEzFZhGeWlpWInbV/FbioBlD79xWlDbRjU3227AZ3Xv5u+6gCZAMYScwMkGCBwJyGoEKIDG/MilpsyZTc7xIlaj2s1r0o45h3dRBuPrf/Fe+kxWYLSJJ9cyn3RtyX2ByTddga764/5babVd3TCFJAZ/7hCzkq+ef71k+dQhFBXqMonkklJvDS/OUk8i9e6xqnGHQLM8YhuAlZBQrG5ypgYLYc7j9LiiD/EBUL1lhw8u3+TqxQAwGyFLKXbt2pVOHBw4sVnilUqncf//96VcegNuQQV8hCxUq8dq+qgsgHIt1etGhFPnFjbWTT7TCSO3YGbXypx2dhDf+E/zH2+XpvOZIj1QQ2A0UNZywUQWTQwITVxKuva5+/0PBKScyz8XAJAjVrn1R8tRMzMAV/wT/+TbYemJAGKcWRwetFCIsEfnMTTyvFNxxb3BNY061Ldi4lnoenvQggp17opWaD2xvTVngRKXQ+OXWBDEFGCFkPWMXcj6ofSIiJglpq4Xa2lOoulJLS6W6eGdKiMu5raspXQqMBoUSH/kiG7i7u3LOEULX3UxGwsxG7b5ClEI6m53NRSCc49kzI5iDSSdDE6WrDnb3Cr7hjo+DJlmSeW0m8+yMtckyCQQlFCb5p+tQA2brmmy8tgUZynAsDL8Rqp+heEr7AQlc8HvuCy7LrB60bQsXYVGkitWgVNM0QNrTi0jNTol7rw1u/bbohLEzVi7Bv300eveHwu3bco5HmYUeWl8yMrAWyzPrh5F77dAxPtov6iHxQ1LIYGdgqUp7s+LhA/Z0mR46xjuhoWRE9t1nSme4QTbj5LLxanVsIhEfwDtm48aNtm3PzMz09/dPTU1xzm3bLpfL+Xx+//79j0f/W4Gqhr6sKJ6rkKLmgyb4FRhnzOWvennm1a8oBAK+8q3KP/1bsVxpvlkPjMGVV8E7/ji69PxqLsNJndCI0oABFQq7iKNKlXzv2vAnN/rf+Gj2zLPcTAGvqS/Itdf7b3/3dMJLd2gCXvsheOP/gT95Xi1bsKggUCREcuJTLE5AVK3BfTvFm95XnSkiJfe2k+E9V7pnbMtkehhY1Bfsl7f4//7p0t33rVDYU1trlVYxYXXTZg7AqZQ+lbGtnGdaXGSgodBtCOpaPKlQWD5fkjFCHMuyl6KKEjcxco4wapP8NamJZTSedCKTS8x4zzDsMh9I27Zn46cJ8VhGS8X8aVk0RIwQZjASghvjc9KCW+nwOXUedh1HFpEV6KCJR/Lvy7vPRco6obmHsH2NEbvP9u/y64/VrRMtBqy2qwb3gZpWUAPY2XVAAs/8A/fVb8/nc8RikuKDTbDLgdjj4/WHb6ufPGQfeZT8+LrqkZ2LTe9feJF31rZcLk8sbAOJCFClqG2xQzvQk072RUcm+WSR+SHellLCbJlyhu1vxSqpBcSxFKNqvghXR8tknNGRXj+ISMpBM64oV7Ozs7ZtCyHK5TJWb5QKw1AIUavVGGOPx0FPTKk3f6z+vO0QkhlBy5U69l6/+XVeYRCzTXidWWRb7IrLs6tG+Keumr7sXO87O8IbU+Llhybgzf8KJ60VI/3iwrNgoAfv4HoI196GagkHxjAR9J/vck482SYe1QMKx2Yver7b0zvw40/MXHii85UHw1/82p8qwoe+At+6Tq3qD565HYZwHB8I3P4wHByHQ+NqbyOF87oXw7uusOx+h3hEd68ox5LPe7ZzzlPsz75v5sw8+9qvw58/+CRg+l/wwg0BPJXz87UmYScXOcN5RkpPSkPKnVjr1t0Lea3Fck5I1sL+Llii4TpVCKnBeah61WiAXKyPTrxk55A/ftdANbqG4cJowmpDjg7LQnes46woDYJO8ygleivJWy12RIjiSk1AHx8HbV1oOc90gAESh+o8o8CUDnY/Z5+ezZIsqZH6vrr6z8WehTUns5e+KZvJEK4huQjYI5gl4oxuHM2uHc6yupIQHF20d84X4DWX254XY3w1x4GGGRBwssJ13Dt29zIrU49mwiorlVpzo4sqbXue19vbOzs7a9m5R3aP66ILFgON2LPdezTTKw4+WDJJ7aa9VCqVx0nnXw/gJ/fDzh10rBxVQuU58Pn38UzW0rR2SjNgICMdEPa8SzLPcpk3JYbWWmkHbWzXQfy5GZMo806ua8O/vJmcsNYM2ABm6Pn4wqc5T2cDcCDkA/wXv46fk92H8OfmB5rHSWy4j1z5f6hlYyuNoSfVcQ02/vQP0L99cz/cXbf6+ZPCQQcBErl0CU6fQemzKbW7ukhJSInSEiE0ivJKZRtIjybp2EgnsrtJx7ZoPumKul7ja7ZS46m7h9KYtZFShGGaTC65lrGP7vKVTdte0iTSJAmYzj8Y0Nsibn7JOYbJZgAzuCkGCiFd12olUeqSeNEHIJW61vevqlQOrdQ2wuPjoN2XucROd0/qfu59LyTuUSjcQfpAlZWaWcIcteUCls03Lr0GfykFk8XVB8bO3bz6hwN9YVSER3Z3Q4422VMv5MMjcxSPGpQDkbAmZzYMrT/gOlbxsN3b22t4Fdo56I45x1QJEfNg+azjOv19vb2hX/EyOSAYFDuOs3fvXpi16UGUTzZbrxntN2IaxVKtWkMfdFzA8hShdvg8jA7CKRsaulMqxSSlxOzsRb1r7qRhsVhZwsru4nPgjE2NJ0uZMQ2iQwT+SNjTk519WMklDPiSp6vBvNCKZ+YyJ0+/AEXrzga3sHsFF28WjqDTlEnTWBRHpEdcnWtyu3ozoVRNa6xEWti7QMgQpclzYELjKqWHpVwN0Lc8FSudkEWf2+DabxokxudJRIEgDK7LSHrj9HLAXECkfDdRc9PhmVRDgqkw1q5pu+MeScsXNi9wLjMZNjuL/roLGiRd8ySkrtSPff+dpdL0Cg6fj1MO2tMsz4ayruFVafkeNR7BaZrJLFDMW2zPKCGw/kyENmPRlTZ0ObA9bWb2sbthFfbHBqFaO2rr0veixnQ9jeiXqZtE0ywrMfHyS9+2fv06oNgM06iP6/hQUfwbg+z4bwKqVqu8633/eOTIEYPW8DzPACoYVxvPqp7k1q58zsFkp9+9KfutG/Lm/7Zt+76vq47xEfcUPIszP4jqflBZLIXRwsYIk9qpnXkK2NiwKfUXk6hoFYPAoVbZmQefKPjkz9rIdXeyTWtwKSOFpHitG05fH7gIS4Hwg5r68g1LaA7M6SAQBxQSVQ2NtmF8bWQQTFaq8qs3rnw+yNgMfqOJuT9x0BPa/zJCAs2ClNYnNAyiVS1LmKZPmlFqVoh+zocR545u3eY8T4gVRd37NdL77WgapNnkpuOoeSHXHJvmAo09pj4eA/hboPkwLbbdGZjc5nMwb9dNSW0MroWYS2gkxz//SGaVyihlEVIFeHep9PW67nJY2bZ8B00yOrMpIKyGdmQDFuGNgKu20w8SQWRZ1nfU/V/4YtcCl5wQyOTQG9cqaset4vRzhYUth9i7b05yvlB+6kVlv67ufbh+/bX+Q7sWiKAdGxwHqYuqVTU+Jus+kuGhdDw25ZvLJocHy2dvOeXM7VuUAyHDlWOAM4KD1RrBoU6gDrbEvx30c36xfEwplckgIZFxu2ZfIoKJA6hi8mUMfWJ75BBrKhMZJdlqtUop3b3vmK+zZqZibjbgHL+zyU2bJrHFXw5GSW+BZlz0yggu3AV1X3q+4DajTBKhD0z/Wrfu8OS9wQe/Wrn/YMeAlwAUcnhspWr8tD68j0RCcT/iLlfIrIJZLN25Ap5brYji/3d15bqHOibpbQ4ZjwgJJV2fzLhQrhtPHKlAEAszWXo2xluIgIrozL9cU77210+OUqHBQacddFMOYUapACMZvXFDn5Br71yLora3MtHyVwOMGVnCZMAhzmmSN2j9VDvnaO4k0slNG9wS3saLdc3NSRLtMRHslORSFjFDLEl7RTEWU/Wb7HNT4E8pTlrdE9mE7CTkziDoUeoHYfjLMFz53nn5DpqdyHrf2cuGWFSNwiAMayEDRjnWBpMgWkWIlicFIselnFngYpz9LPvVb+pRjD50n18YFVU/0uq9CIljiZ6OgGokf3K3f899QXfYBmPwt2/PnXtOZrKsHnw4sGwZhmGtjkJ5kuNzZK4v5hiqZajPgAURgypABRWfsnha0EEDFCGj+/JsdEU+VDDk9DzPtH2n8htkdsyaBXhsDF/PZd3ztm86PLPvtJP7H3h4Dj9nWdZZZ5118ODBNWvWYFQ1MaERq3J4ePjYsWOEkJGRkYmJCUJIb2/vzp0706jqBW3VIP3Ce/qPPNa3YzKjQBTyJJP3g6rPbGZRRq0IkFxVp/OFfMenSj+6vaPvIwAvOh/+4Yo863PveCQslgSlcMFTuO2UhB9GNcaxbksxia8z+lLKj3+38vkbOka7p66Dv38lO21boUTZbQ8EAHLLSXz9KCVRUfmRqIc4Iua2UUdc69yor/5v9Yu/eNKEz20x8mlfOatbqJs6UUMp6xqI1/RBCtBD6QjnfZo0o82wx3tVroSQ7RCBzaajiTbTQArdgRskuOMuLniJX0HYNiagGYvpaZqqjqbnsBWMMf84z3Hds1z3gBDg+6uD4GbfP/B46vIr10FzyL8jz85k4AKn3AGnXqqH5ZCZgo9u75ahFKFwep3M72e8Z3nTfz0d3tUx2eTlyPNflVm3ATWhV5+cERJmK/WZiu+H3LEQTkNQpRSDyoFC5k3/NHDdtytf/0i30uvmzexZFzv9A2Stzbc+xZZK1mq1yel6GFmuo3ScSqRUvi/QQfszkENeggqqfHLdn55B/F8NHbQMEPykU6Q+bqwddDabTeKm1r37frhr71GlYOzYHP9hfiByMsFa/rNfHcwfOnQonXQ2IGgDjoblGmOwZpT0uvZ5m7JECZBKBFb5yGy9WJPCtVxGeWRKK9f8Irj21m6R6cnr4SNXkr5BQnth3eaMJquK8JrW8/Wjs0G5rhRwYSF3B7Zlkm9e7X/xvzs6U8+BT74NThoi1oCCAt1yRh5Li4ZEopKNjhZFDQ+GSQdF1i2IFL3rwegb33syeWcAMAujNAtH2nyAKaV6WxpDmjblAAOUjlhWoTPYw2RjDe9X2y1+Ez30WObmKGS/SEUu/G0SDgkGuTuQYyGTloUQDpNins+mhE9REMx55/QE1rJHTshGzjdy/upsdkbKO+r1v5iZKa3gNPSyHLQFtJ+CfpxwQSqJl/dCO6wVayiPgnKlwBxmDyHdJVI/90HhqsL0ZdOyg1T26Ea64RTOLVCWJFQRQXuy3LHJ+HStXMUWfM6Qvm5Vn21ziCxyyR9kd9zh33Vtx/r+eU8jrkcpVwTZ9KkQMuNZjLPJqepMMWCMWpxmPea6FGo6gpZYHK9ipGNpyfFezALW8W/mQyF20AHU4gja8zAYiqJoenq6+dxY1qmnnkopzfUgZC8SzATChCpmqaEe3f2hrS2B7+MydJcKOaCxHqCow7IjhepkOajWooBx1+ZZi+ecpz/TXr2quv9AxzXI854Gjqc5VbCooDQpHVJ/EY87Q/lwphr5vhQRc22aI9RzJsphF+mYbZth42pTV9RJfiLBYoB0HQBZmw1nZdGXYaQqkkqbcrsG1sc+V3rs0AqPbJpNCIEAHsvKZDKJm07SwYF20FivmG9YuU55hxNnK+FLAAAgAElEQVQYG0ba7IX9YMA5isYKgU1gC22sHrdrxtzgMu5P8xFKMbxd/Mcb2AxIRbfzFK1MbB6GxlOj8HPbDsOmPSYLZ2NK9SpVUMpfwd55mQ6ab+JsHUMHbXpSEG6jiEs8XYzTXfZa0cHM5bqdjfZT+1l2/b/aa4NymxjZSz3jYrGBUsg4dMNIFolJkfiYYEoaGVEko9J14YKXuHdf1/HcDgwwqucP1AxUQtdCiOfQNatyOCABzgjXY0KlBPVpJeMIehacELkhI+OgSRGcqulO0RF0HQEenuf19SETW71ebzholesT1VkkcZRS7t+/34CujKioSU0WJ/Dn43scTSIGZ209ARQcmy6VyvXZ4nGKFpmmo9MgQiwIMMJzPJ/twZ5LTBASnOiA9veR33uh9++f7ghWQVlpbLQE4ArHxHNo6N4J67FpwYpZkBgByyJA/+gPM5//amniWPvZ1wD8FFVIKIhHqBF1hg6FEtbv0T63MSBStueBvOkNhZtvm1jZD057C8Mw7aaT1xlj0+0wdk2+NUJpMCmUMhQZbX2i8fiRlKhMqJmmsTk7RQLSBMsTOvLILERc2am0yJOBlxECGxFuw+zRRAbZ5eqaGiBjsSPWtURh21YZ169t1Aiz2TnfnVbDSh92i3c2bd9FXRv4HUxx4LLf+AIF2JwS0w8RxnU+oolkx/yVhuLNt5MvAGkRqRHKyhBR4QOrqcZ1K2zD2WvTY3K7HSI/2YRhr5UyyAWDrzXDaSCaJthvDGhSHI0IegbcEPrQQQvtoGchWzGScdpBB3EEbTB55cYdw7hac2r9yM6MX0LWU1P9mztb+tZsSnYdPjpNKZ2ZrXSnTViC4TymA16is+Zz8nhGUCBGrpotX/L8zCc+U+omV6cA6bMNayiGvfMGTLFq4BBDA/RlL85++kvtPb7ZO55AntCQ6qvSZsB40Kdss9et4Y91rmE+Kdy04zj5PMLkTO13ol1OtumRMBGHUSbErHyLgKxqEY0NAAIpK0rlOT4T6TIlIaSm2agXDKLRO3d5OwE/GfTxIt20Kdkt+/Y2XpXppLNS0nXb0z2b7EeC1WuSK0wnWEzKJYFm69HuX8FN3st30DKQ0pfU1SpWxtJOOQGyN2hFsfajM8idBtx7n6pL6QkMNTXFTkyaNg9jqV+RCI5D1ddIpGg9W6xclr4QluBmEkkOM63mHUs7VEtQRyhuFEfQXoCOWuBh1zCC7ikZzXGd4pjvoJMnR0T00duyOtZH12xbfNVIr9a3JXsfi8nwvLzIFniWry+Xy4booOYHrpedmekgtrpkUzJEdcO4q6b1K8enESUBDx/uVsLedVB3GwURkxKnzfSVbXYq5hqTQ0c6OtPDx6Bah4wDKgiJ5BBR4KLDgPFojr2AUsEKN0qpKVSYudncJ7OaAbkJbdrMCq1dsHnRkB9FyAOD+QVsUWnR804MMdRaBCirx0RNQm2OUo4QpePSytzactLJU0sZB87LsLZqhIQox8HuQddtHVk4Tiz1nRD8J648YUcyn2oJpR9Z6TXC5TnoXbJ2ey37zCzebqi9p+87U7NIIzkbSywkrvOj8HDHyWr/r8W+XTXn1CySdgisA2sxvTlyURxMxg46iLBrbuxgR5ZbAPj5T6LnvyiwRqml8WCo2aYHjB19g/gUb3WMoFkqBx0EWByMUxxQhMFiKsURxkXCnp6epsK99s6xBWHEGZWoHzF3jF5BFAbV1P7ZoaEhI1jneV4YhsVi8XH2EDYOQPlFRkkNAs1wonMasT9IJss4GqJ339tNAeu2B2G6DP005JUIpxnO2g/YgLWKEO65r2M9YO9h+MEt8MpnAdKZejZO6oh61u+1GRAzYjseCY8uTid3pZllWdls1nGcJk47zHERUtPSKl3kvVtzdojJ02466MxRZ8QJexhztN9UjNmaGMR46jwhWc7ZcaSb6BJQL65puxsOrxMJFNVAugbmOm3Cth0T5Zjjcd0kMdK8F5NyabD415Q6toJ7CI0tK1AJoPalGt/MrT6LVikSinqIRJuzFPuzipTwRe2Omryx47koT8LVn6i9/sM8Z1msShyHMI/ggAlmTw+okfDgB+rQgeCX36x1iaD37oYffr/6qtdQpBitEMuhOKDTHOY3YHbIUh82HHTdRNAmxVGE8nQSQfsgMILOZDImB90WwuE4DiHk4JEZQgjySnteTU/vxbFMaZzopu64PUQIYUDQafysgT83IWo7wUXSJqWqTYGXr8lqREpAbAoORZ5P1nxRijPR/1zTraNkYhq+8EN4yytlMFt3ETqpoARgUXApuHqqmzeg+Mm14dGu6oIf+wacvA62n4Q0pJx5mOsoYnYzHjBG+cZfFUB+49uVau3Jl4HmnPf397e6ZmOzAFdTeqmUw+nFw3x5706zHEbTHVyJR2mBcze106Z94z32mwDnNQXUhsLGkGMs2yhtQxbaMCQUbSd5hVyjDS3R+HeiPWg8dQeW0Skpd6xgmiRjy1xJqntU6T2lzN9lrIxFJCoRokdDeSWlxTBjZlEltHe+sxa8Swemne3RX6mffK180cszbshdQZDRCJFEmk3cKMTqIcNIjY8FP/p8dXxft7tNKfjeN+XWbeVTTsladWoLzOUhbyiOh3OxZitVYaR0BB2YCFqnOKIaOug4gqZFqMwkOegAZDmd4jCet8l6enpGRkaq1Wp/f//09LTv+wZFt2V96DnYqTFTYgcntZCXlJtGRU9OSAXVOt1zNGYoG+3DEv3GVeFUiT70GCa1F9OxMjkDP7mRv+CiGSsjSA07vgleGIKVt0brpLki77mq/NjhBbp4P/s/+InXvyQcZHUr40AViKPBXUhASoBkNQgRN52ckv/5xVIrhWnaJmbgTz8MX/h72L45IJTQjAtVRRydj8akIQFiaZIJHPD6X9X/37Xti8kr35L5tZH7nzNFyAOUPgpwWhRdCLCqQbVBdbtKWuKk7TPZVHAxUbNxzYuEAC2B5GgZAbUJTh+PGd67TnXRKEIR5da3TOOMlG3CeeOpDVV/GMbTSWqbypOBSWD5qT51h6p8oGJdZvE1nPqU2NiFioV5zSmKHrAow51heHOofqHQ+XU1KeAXX5SHH6lc+lqrUKB2wBgyN1NUUsFucRUGqlaWj94e3vo/4dgi4MLFWfjwu+XFzy0/7wVWf46yMBkwVsqqVNT0VGhSHOj64wha1kyKI4mgZ1NFQjkvxZEUCSlTa7fUjz3mhjV7WhshZGxszPd9JEfX6819Y9h/hzn0VDLk0CSbKFIUm0o9fOMzzLbpbNWJlnL71AP47HfcWjR16YWVgR5OK5RFlPiEYA8IxatRVnsOyC98x//RDQs/SELCp78Ht94Pf3OZf+bJIucxqFAaURJi6QpIJYzCSk396Ebxxe/5Dy3UJopkFCWkin75RfAnz/fXjEqkDaoQIhgJKaJBiKzUIj9UP71FfOgztWNTT77w2ayohBCcc7M2agAx4i5qzW8RVYW4GeBegAsIeTpjvSmkHSPEZczv9EzOD4EdQvo554v3zpQqrCh0lvR+nCjPx5PMTbIlqe7z+HWFz4aUktY7ztlxG6FJi7elo+pABn17GK5kHrulO2gCfBt3L3HZEAYIoipq36+F7wjDNSGs19mIDXohN63dWQhwv16zLeLCEQonncWfcimKPasZsHrVrT+o7X84WrcVDj6EvhtAzY7BsccgXEpoNXkM/udbamZSvuEv7EIvVtKrVfXtb1R37wwVqEcfAs/Nvu7CMtRVKoKW1flFQhNBxzloXRJPIujZBjutklCv0CicAyopper6lkpeqdTmENDJNjUf6kESfBoye4VYK9H84qK+sHA//MXaR78mzj1duDasW0XWjcIt98b3+U33qFodtpzE3vynmRNP4EDJ2KT64jcrjx3sIGCh4N6dcNl7Ye1wtHUT+vQTRhG7fOAoPuET0/L+nVDz4zs/68G5W9kF5zhr13Bg5NCY+tK3KoeOzBt5chY+czV85cfwlJPDQTx/cP5WcvcjECJ0nty7U05Mzw2YWD4D555OLzzPWTXKgdF9h+RX/rvSPaPyBJpx0I0m6thNG9eczlFUAH6m1K+i6MWMna1dc5ZzV1NbIKdEy+VuBdyZpEeIdcFYaKvLUcWS3lomzSIEKQ8WRz26DIbSxZb+ku+YZEiS15NQl2pIRhCIfJ53cdAxPEsj85oS4glgo12K49CKrxAuwUFb51uFdxWs1RZGylhTxvvDeb5T+UwFZav2a6d843KOYNWJ7DV/17/lbHBswiimy6SEoT/xPv+emZ9+8nFRTQ4Mkg98tLB1q+04wBDcy/p64PLXuu955/StN+HIIyOgcdBRCmantIOOECxSJ2QWyjMpFAeUwZpz0EkrtlJkfK+RFUdHZlls+9YNJnj61V1xtN8zHPYPO/3OdkLIzMyM53nIdFEqTUxMJJF4YstrQLWZ40d+LYSf3x4fV/rdUzfCO65wLr4w4+Y41mDxbqYvfaH3J1dOPfRIx/ptJGDfEfyZP+C8kc/cTD/9br5ug0ddG3MVjCrKXvwC76OfKH3vB80Q73oAtzwY///qm9oPmNhTt5KPv8NafYJHMobVmijCr7g8//fvn/neD1aijFwURY4zJzCf8H23bjlCyMWcX8AYVkYMElL7DqN13epum5LIMd7FMM9pQcK2qrU4T0gZBEGSRQk0hg+7DjRTQVu/jpVJvJ2QAPr4CHsbXasmZZPuuD2TcdYWuW6M02hrxv+aBEtCpGf21ZaqX9ujUfStzk5/5diiHLR1rlX4UIGNMMk0vVuDtZvmafYNWXlYhreF2edlw4Nh/ZalfedN2/mV/1wYHACbE4RQE0yPCMp6eumfvjcPAir75e8/L3vz3fUbb1/ayAOD5H1X5c/cZqPfx5EVIZFSvH+AvvO9vW+9crJPke2nuVApg19PoTigkkJxYIpjLgftA6nA4JyDzudjsromC0Px4A5Dazf3REUBLc4EhyceNDzRBk3VVndj2daFxmz9KP3Uu+mGTa6VYdRgJ5gESkZX8//61OCn/nHyhWst2mO/6RvFg1NLmxtO3QCf+nu6bo1LbYp+n6MWAqFywwb2/n/oPRvEuYNW2bOu/Prs2EJ8LE32tK3w72+B1attapsD1jxKVOYL9Kr39b3xdAbjMGWxN351drpFIOaJsgXXOhRgHSHP4XwrY7l2rSjYVbWImcf48XkBdRSl3bRJqgRh2Bb7YT5OdWm/lezD18lZfOu4eOfGsPg7qd1Z1pzkdtvvm0TQAJHnZYpzrAnN+Q3zcUPH0WgvbAZEz7dHo+h1MzNHVjyEY1EOmq6ihY8U2DCbw9KlgBA0R3v+qgdeqMmRrlmar6EcLvljt7ePWdo7a25+jdxQyLuY76FveVsPYACqHty5tH4fQuCyK5zTt9oW8gc0SPpxNYRcuyMj9L/+ZUDtlD97kMFEGeplk5LRKQ5aTlIc9ZYUB13YQVuWtWXLlmq1GgRBsVh0vZwJtDNg0SrpzUZBJCp1TR4mRMZVhQzR9JNQrOKLUkrXFpyxQkbWQzJTZkkgtpjv3enJfs0L5ZpRB6l3TJeg+SHoDVaNkve8fQB2RArUphG+VAf92hfBqkFCk5FjelbNu99PX/fWQbgzUFSt7WdLctD5DLz/Chjp1/RbuoW9IRGAI2cycPofFsj1Pih4ykb7uhVD6l+v13O5eVC6tI+zAV7J+VMty0TNbUcIOmEYFuErEzdNCAkXoept6RgZJ5UGCoJZyH3DdDtMp8aQ5VuSWW4CLLfVDExF1iKlpRKD5BpUpQiCbioemsC5gaVrHfPrtdo/VyqHnwzeeVEOmp/LaZ/uVkh3o0hQ5WeAcolzLZ5ZB1DD2+/W3ddqq0+ipz/NxiJW0iuoP+5HA0eLF/dnf2pZJcvF4u1DS3TQjMHWM7mBHs11IerDnqxc6PBjmcxD3APG4U9ro/A1Bd+A4VUjoRBnIMJ/b7nydz353nKxPOPNPHYSXAXwMfy8brkB+I//+I9Pf/rTTeGSnZFBFb+JUurYsWO2bddqNdu2kc9P3yi9OZl1IRSkWKFVPz6ijAOFjMp5crZCSrU49sl7yrbUaL+YrdDZymJzUHMCBy2Wz8DTztSIGOM60/LaREi1SvT2WvkdiPte4jN5wig873zNNJnuVNQcpDjJERC9p7PCA+BrEPtS7PSNcMKIeaLM10qzA2lJXK9XrfbJ+OxJI9bKcdDmrujofAEGdXJamvRCW1olQsYYy0URihamtmnOQeu+cCM420Y3Noq6S8fajNnplAhjpmsxhuU1ECaaT/x4OLKmXHZy2Ml/TGrCuN10PlqbaspRJCrgAFFPz5zv7mI6oJYAX65W310ur3Rs3dIi6LUx40ZK80LfIHdR2FlSf8SIRP5iCMHaatVuqRm41GJN93LgDKojJLPcKZbcn35t8gUvYyPmyiiyca2157EljHviZugfNOg8jAOk7is28/TNN9OhfnH+Wtw13so66LSRi54RCY5tozo5t5mSA32F2eljc465YaG29O6YJTduqx7dlakXkURpcnIy/a7hZNg3hlh7bL2JEyZok0U6U4nlTsyLSqnxGcY5OzrN9EuLdWy0QdXfaq4Dw32Gjl3X/uZfypkp68BOtY3BDY+Gt+1e4kpF/9ZiCAoRKhgH4WEnbSwPPcTO4OTh3eLBA0vrqb1wG1IqadUGTedvmpTwKpo7Rk5NkExgHxyX37ltBfHemXpgk4BsOvU0qdQGpWqaDDrh7G+q5s1E0WEhsgCrKM03CoBN3rzpnlykEQCHc8fSMsypwzP/NB1zXCT8LUSaSfu1SVA0pdFh/rGlA3AA4Xl2uYzNKULEpB+tRpHjBaSclvJIEIwydmQBlekni4PWvSfo4oTCleb8K0WefhOcZwOLpC/D8bB+Uz24I1iMd6YMf5DdDDP7MhLKqFHGvdeoNnL4Va+fYawa7JXjR6Lrbqpff9uiEtDmuQhDOHoYpqai3h5LSEI1rC0Z/AWX3IJBzGE1fji8d6e/doulJGzJ2Dc8OI982SA0HMcx2Knu+xUh3XtvJqhRQuZUvYMwsi2eUvVutiQN3fr6MnoLGaGhpjQy7PhAINAMYraF2gW4KAyFFIpKJFpF3EwjOO3vP9J7Bj/0U/nB75frXb0o3ucMy4ZmoWl4x7BBIZIqkkrolhbMTpnnB39t3fbIoWvEG78463e+MZBuW+teKTUXaR2Z0g5Z4MhIfScIgqbFXP9O/0AxPBBe/qmZyfLKWqs2paGbpFWQhVZbpBRSHRFiYZ9r/EolDOuN+6EEUJKyT6lVlGYahMvmwzalgvNAyiaC6fReW1+zGPO0az6emeVFWnc0SJrNufXYaKOH0FgTvZTjeJOTc/VGc3pbAdEaEz3A2Dt7et5eKNwTBB+Znf3Viifi6OygGWRekcm9Ka+YRCrvQOg1j67VzH1xoVhVBcrvR0ZOOSNVceFwr2eA/NUHezdttcenooP7scLth1jbUErja02mGBTjFT9U5Vz09Zsrd/4y8Tzd7JWv4H/5530RozfcUiMUcrnQDwRmOVCgPc516EgzCIW65cHaez9adnPWCVWsucscxsWYDci63GJKqlKlbjQDFwlxC2o02Tjj2QN9OaytU3p0vBvVRqfBl6FPiGqEWhLwxU+nH/3rXppnN9wf9vWop263CYHaTNkv+SLglFnYwBL7UNPAou64q/zKd08FXSfXM06Ef7zcOv+8wsMTJAJxxincjBFMFqOSH/mRjaoodC6Fot89cqj2sg8fO9BZkXK0H/7vH5HfuzgX5d0pX42MNJy7lGJ8VtaRzp+jKLyhaJlLoZTK4XP/dnz/xIpDSpVKpZ6ennQ/YdohTukURBLAGqFCTkhNiMQ1p21aKV/KEywrq28Ji1LXsgwfqdUpYGwLAtE9h3oFh7PFIn20ER6M85rLc+sEKQ/jDEabHXQWjW0UDyWlRIjkVDaLXVkWEvmbjsHFPTU2wHbG5q1xnnQO2nlJJntlDrKKcMIIC8thWA+5jX/MZQIlsvJHQWQNWezZzL3ALX646P/A77L0ohT+/H2F087izFVre9joRlaqhsVaJJVyLFTVwGQmZh6wY1BI1T/k/ekH7NVfLX//kwssY0dXkddfXsgVCNj0hS/JKSXqAZ+cqmHw4iiOrjK+wUya6/xn5V/0MvXL6yD08XofxhwmHvepm1czRoMwevjRQ5UuJMddbfxYcTxF1f/bMUa4kPXNJ8A/vBayOcl7+Iufl0FuT9035A1kwnrgV7CRDwinShDJzKUUkfjEf5W7e+dCFj5yJZy2jhCuTj+ZQ8bWHCs6OzSQkSizElBOOYLsFCqtaGZCIdXHv1Dq4p2zLnzirXD2ekWpdCw52mdh8zegOACmSvozaqwog0jWQp0fZWDpFArmhNR1v6wfnI+zXiEmhJiennZdN5vNmvA57domlQpRQW3OUOatg3fOErKG80HODYuM1ehQNO8ibe6iJ3LTLRNrfTbYjrppAmiTYSj1gTENtl6ykza9fMYLt/IrGWxclzBW6aRfupM7BWFMtsEW8NYCY9oSn24206wmK1nJeyEH7ULm5Q7J6LkGAWrEylthKfQrPuNaM0VT80RhpIhy+zS+ShLIQu4dufDRUD7c8ZsPb4CTtljIZs6xzMMV0CxXoGbKgcWZbSEzD2rCRtLmMNJjUSpYAZ79ysxDvwp33t1tPfLyV/B8jjIOiguLUSmVR1l/nzM9g4TMjo23trk/bZsUclhF/6u3FkoldnD/vHFuu3v5miZPrNnMqUfjl54JPT2GYlU3UlsMpzvEybL8SKF0dLZerFuRwx3OOHZ9AqMhYbv3L3CznrQOTj7BrG2Mki5DBiWJYETqcmcwVx8vodKKkNyzYxZpzv73Z/53f9Ctwf+ZZ8H2zYYGywjRSkx+MY4ijwpI1ma9npiuiZqPPOCeAzYDSxHGfnBt/R0fqKzYPgNsQarVwjDMZDJpWDSKE1La5KBbWaExQgJYZ1lI3p8qEi5IzJ9YqyNNcNNoXd10LOwdRSLlOoWUqlE5bBuht7F0B0oTv1KS1ljEJZRGS8X4eiOn0nC4mgkm5Z2bwM7mz4QXseGdQakxIWafJA66TW6IWCQWTEHwqX6FEDtvO72Ooir0w8APhBJWr5UZzTCP4XOuIVY0S+0L05xJzbZus2VjvzV6ZxYTipKerL16wLMZ1H2/5gdKRcM9bP2gjWJXFBl1evrIU56N6/QudtLJeu3O8QHXekC4xs649qqhjG2BH/i+HwBEhTwZ6OMWl4xJ1yNPOXve0Z522mnPeMYzTjjhhFNOOeX0009/AlJ1j8Ms4tRFPUa3GkAkQtO0gomGvrGMlV/T6/TYmPyMAgQSZhjtsd08u+KyJpK1ZltrCH7iYfXIc1g9wgqOt7bX6nMUk5EIBVUqy6HHuviSbCbT7RwWshr+iOOYg9TiAA24HuGUDuX42h426IFNBESKKcha0GM/dICufDalKIqKxWKlUjFBNKUUnbXjTLfcV01/9xJyluuuSnnntobykos+GJOsmPeSlCpCFuD060bYO/L9tHduHidVY25vCV1Ra/egoS7SqoBtvHO77xu5LtI9m9GUwg/6Pobe+sgxfG5/oDpsjyKo12NBLBOw6y97SMrJFdjmtMgImp/F6SCNSUTNt9BJRWrjHWaUkOZI1lNfEwE6Qx2STWYDBih0grEbBnbxpSTAbZodcAhx0NUbAnd9LWJoHyEnnmlRDqJzDI1csZb+Nno1aKZqhegdOjzomgFNFh1HbtCD2g5ke3FtX9dE+7t37z5w4EAYhj09PcVi0WjCLlVd+4kymzr1SCeCqObFN5fPyFaZFTIAy3Avm8WcYnIFtV3yDDeTwT74ToNvWoe/0T9io6CWbklglxqsRXOWnefJBcMrTchAPzztfPf713ROTzXwfnpkLQeDk8qcNjweZsGBHrsxMtM/8OIXeJ/8XHGF13gYY5lMJpvNUlSTj+mTAqVK7VITNIXKICmmw47UGTrFEaDoDSrJLz+Y0NE0tntoNSOBVfuO2a44Bo+frg6y3MaTdjmeFF9+s7X7oHBdp1yeQ25wbrwzUKpcFzvjk2HT46R3YaYE072iDcUTniTWrrpq65/0O6nuBlznzKFTU9vg8lczznU2ZLrjqG9nZmBDtWZ+9B0yN3ICYNfwKlyQdTdFleRIi2bM3EJ62Hjk2DsnMQAaaoXkB6P8gDCcn0op3/ellNPT00LEL6aku1d8BB1hVIm1ldiHSgNGjn10I+CNs6LJg6Bg9SrmdNa7AYDr79QbIlGbFkaBxsjz2l5i3Zp4UH0JL77Q7TLs7kMINdHQXalMYsQQunUcOb54w4NseLBbKLASeEeHhoYKhYJxzUkNRBGCyM0WS3tYv0HJEmgKj5jIMWWGi7EeRdNRNBlFFRNEdH/0use8Gh4Y+n4X7xwl1HGM4RNltE7STwelCHez7Y4lwQXNMM+ZMQ2mx7al685DOpvwXP8HiUYTB22oSlvD9nb2i8VAp1dsBC2OClmRzDZnoXO7fhMm09QMq92KTfVaVI+ULbCWFIfgrYM3oL/4sCqIJJLpHNkfdAdy7N8XbH+Kawt0S/Plk9qN3OCJ9X11dJfxIPEF27J5tVZ6lY8dPFb3V3aENt8oYtKiu3dAtaZcP7IEA8HjjIex5ISkXLO+cuzQodD3uz2/ew7DrkNw0lopg4jiyBoU2TpyYvEEC7+8oVsO+t5H4ef3wPPPBRUKCAS4euRkwDY3XjwslkKQWWiFGufcshDl3BYvcYSQEBXZ5sww64sUAs+QjqKKipRCSq7pjRJivACxT6HZXgIUpaxKmaPUaTSbNJlAEhkMuvjySPTNl6KUae2u9HHPSXenxUqa9LwXbw083NyYhAjXpSZ/neZXMg7asuaECExwnebiSNIpyQbmbKx4odi0tQkP5Q5Zu76mfN3+XNe+S5hwM7VRSs7KsPKrQLLaP5MAACAASURBVIXTYfjjbk5tx81y765aLVB+hLx0MtQQg+Qi6t9G1EpIxNtGAoJQVWvygRtCzWnX0b73rQi5l3UvfuQDKkFG80Y2jQ6ml0Jo7xyEanq62ev7QRSEUa0WHDepwN+u7TkAN90LfsWP6lIFEiKFXH2+VvQy/Atz0irmCmIwdv+DYfeU7kwJvnQNhKEKy4GqCwg7jDz/aa9V1c7d3e6HSMBnr4ZiDZSQohwoX48cNkYOW0fWYHwJ+/eHRzqLbD3hpmECMYNda2B7P6VfJ2S/Fodt+xyap20edZGURlEljKKy71eDIP1ZE97OSHlQzGUB404TxJhbOdfNzW9OWapRy2r2zomZ5WpTa3W8htWZ6Kb8w0IzwdzHSaMmmdBrpH00ISj1nfR5t/aRmxi/5ZinpbxjhWfHUtZuThVQ+3SNr+fOKQ7yU1iAmimt82/i+4RCUataVPtBTe3qdupDH777seobruK9BYuViG0Bdwlx4pGTrIm5ClrdStV8+eAdtV/ftMAJ3b8Hvvm12uuu4J7DaYlYFmEuITYoa74mnxlZIoxv797w1hub12J79scSgsb6+/ullJZl+b6fz+cPHz68MvPRGD4rdFg1H/7jm3D6iWKDXc9Qj3KJDQ+M4Ul2tHZJ2hPocx0F8rstnHOt9t2fw+gA/NnvhcwJ8FmnemTOEHBg69ujaa5X8tqfBw8/uoAbvftReOdn4Ko3QoYEtIyPE45c1u1MyTHPXSUtqiPZ936wbAzkb8OMa2YMJd61UmBMDG2SFX4Y3i3EI5oS+pmU5lugeIa2v8lQSTaK/Kij0luG0pxluZr3WWjeZ6q1r8y+eyglnXHTXYxQyizL5B9hGWZKc4tMerSkE1UySLs+Q2FZvNrh1k2WyS1feVbrN8KTxDqcuFkIbgvImQieQ452k4/A4MVCURCJThlvogj1BmUgg8mg8r1K9JlowU7C6SMwPSXWn4mxs4ywQSwiGI1FkkVC6cAZ17thBH6oKnVx383Vb76/VmsvGD3P9uxUazdEwyNU1JFCGo8RpVNASEti9EG01KxWZgjV3j3hx/+5tH+v24mRzlhPT8/atWvz+TznvFarJWpVK81s6nJl7z2KGMGpItz5EFxwhsi5qF4ii7rRwFQLCRCBPa94dpDNAYKa/MC/lr5zzcKNmlLBnQ/j7+2bBMfVO4OS6cLVuAssbBlIn+GJgJ27ore/rzg9u/CT8OgB2DuGkDsLBNKFSAol0xzRKEXiyBoer2+562/23/vRYtMK55nPfObtt99uOLifcCOEuK6bVC+SSd2QBJg/Q4A9AA8qlQUY0kxTUYO2P2dZBYJpwCYzGY/W3dmE9FlWr23b2o0agmjOmMXxQs31y2iv3cXalnriIdq1gy/KNZtsb5OD7uQfm5LagCDoIJdzJydjuPR8B13v73dnZ+MESDr7nOYaTTDU+rOHhfiLYnHPSl0fM8a2bduWhmZ2ntlKENwRiCGhskoQgZOykDJSMsLGQhTN9kVUj4LxoH5Tvf65urxaU3Yuwo7ukseOBtnVSnIZSS0RLqQfkSCS9UBUffwplsLH9vg/+0r12i+GlcXJXoch3HW7mp6JVm9EAFIYyVDKUMgwkkGkgkDUfVGtiUMHwxt+UfvUv1cfvF9ls1njoM87VYzN2ObOZoxyhoVFSmmtVp2YmDg2MT4zOxv4dfOiLhziNppghq4ZVOUaZhvhiTOPZZWA/WN7zZ/HZuCeHbCqP0LeJRtEXWrMjMS2eryCuGCuFsXuPeG/fKb6le/UF3noUsE9j0CpCusHo7yn/Y5veIZ12igi2JYdiOlj4ld3Bn/57tLeA4t9DHYdgNseAs9Ra/oE1j4igfkZvU8dB1ESRmFNTB0T3/jf+gc/Xp7Vc8OKddBJGrpJVbJtB/8wY6doklChVIbzgm3bjLlKtcWrJrTOxihAL+f9juPMj3BbG2T0hyVduoOOXXwHzvuOZvoDkwRxk4Nu6x8NBVJTJ7dtC0qd6em5cVIb1AYHvcnJmHUvzZCXBM7JYWu0wEEh3jg7e9cK1iFsddBduTgOQfjBMBwKyWmEnEHocAyGkIqoqlC3SUw9/1rBsUXJpiSmJNz/M3j0Vn/4RH9gLTnlAuP3QCkqIrLrjiioqvK0Ovyoqi8icE5buQTf/7a8/tr61m3kxJPIuhOw4Kx7W8nEGOz4dVSvq4ceUMXZuZtt6ARfKbJuiEQyGpvhnCrOYLAg9hy1RvujSMBUieU8SQn0ZOWRKe450uZqsshG+0WxSo9OM8tSTzhg2qOZopw3jz24C/7yw7BuJDhjc3jR2dCbR7kvDNSIumcH2X9YHJ1QD+6Ss0s8w5GAL/0QfnyrOv/0+nA/uegpujNRz2f1QP30VySMxF0PyYNjysAzFmkK4K5H4L5dsG2zPHF17ZwtZMOILpxh+z88eqBy/06YKYt7H1FTs2olJzcSW5BNxQM4i9JLLGuDdoGKUleTfxqvGrWD4jUpzGKrIaVZLUXx2zDj+JokqTpttqCwd5MlsrNJw6ERuwJg3bVUzF5MR2Jryjs1qRwU4i9mZ+9cwd55WWx2EcARUEeUug4beI/jjutleOx+eOx+dc//M9XG42NKwfQU3PgLdeMvFnV/+FVq6O4KGWmxyLZUPcAsTiEjejIyiMhsBRxLDfWIY0V22np/bJoXMlJKkvdkPUAHgpxE8ASbzVxfNlNu+gFGprsOqP/5ecJAeHzs6CR8/wYc87P/mxQcj4NFAu7agT/f/nlSGVypzYILWasOQzqeHQV4rW1v1BC85N00AKOTF2m601SjIIl40IVat6WmduwCrJ6HlEh9sKObbvXRadqjxVuCUE43HGJLcSDy+bkyYNOBpQ/bNBmanzSVoPHXeszrg2Dniu09XaSDJjlCshrKEyg1/ZtasxcGdWALUC1Kv6vU97LNsqG3D5vUlFKTxzrCqKWUs+N4Bvb0yB0HLLx8qVt031F8i4CamKE7D1IhYedBGxdPuv1t50FU7FRIZaEbYX9jKQ7cmQ6cTGtPW+NgBdHyV/d9PeA5GKtW62pmEVnjZRgBGB2OK+yT0xL7On+nrbtQzgghq3SEaJppWzcQukuwDefRfB9q0tYxbgTXG3MytYmZymQQhpGmHLIIcdr1v7SG58kbC0fTSQ4kCNqkL7osMBNQc9PgUWTSFMK2rUQQbj6QY46jI3m31f8aeIlG7L3Ksi7wvJ/Uah8oFp9Eflr7oByxzrWcFzh8PacjeI1lUda+Xat9s4a1jONkmQJ56kuczWfZm86wbAf7+g7ujr73ifKue46j5hOcsJG+9Pe9jSfxk0/hhsz221+v/c+3a7Pt/M40QvNwft6zZwl7sSw4/xzrOZc4fb00k0W2+qkpuOYn9etvqh/H2sNAH3npc6xTT7ZXDSNvBgB98JHo018uT7fTJfEG+/YejRPQizdK4ZQN5E9+37rgHHdoyCKMTMyQT365/N0f1o7jQnCoD/74RXTrqc7TznEQ9cHp/Y/I935s9pFdiXt5vPbbWuQvwQzMzgjIGks7xGOISkUfl9CNNrFCB4QcUapfk3I0JZfTe2nq0o6EaBInNC8GjcokCmsqFUaRTanVATQdj2bam1KcfO02agi8Gr/ZJa2RnleS/3TvOTTFDZZqRUm8uX7MpOcx0x9onjql5v6f3m9jFwxgI2PPt+2PPKnWZZyfyXN/lbPOxecz6Qmm/TT31zl+Pi+/p6wmsQeXD/FoIlr2N9t6ofOKt2fXnIDqVoayTino6bdWfaznE2+d3XMf+oN8FnMLj4dj4dWXO6+5LNfXR3lqL2/8q57t59j/8I7ZcklZDDaO8N1HI6OaLaVsFWxNzPO81jZCxuDyVzvnneO4XuPuJTC6ml32R9lKVd52B2qluBZBspLH4axHh8hb3sDXrXW4hUJ/5h47e5v1zjfnP/ivxekZzIm7FqkGBjZIipXZpdbHCIG3XUYu/4NM74BDHc2BxaBvmF31nr7nXOy++R9mqlV16hDdNy2rj2OSftY58NbXsO3bMtTjxOZasRAuutD53hlDH/uP0he+Vt7QQzIufWhs+Y+MxeG9r4dghflopVSlUsnlcsZdNlkJJeMRmmjoRm1KearKFwhR0WiPCYARSgcpCoq13UvUSfVKN7ZIKf0wbM2Go3qblAcBNnLOOrlUXVVbLHTakOUvhtMuKeglmoRdm1kU53PN3Ik316cUdbAM8M4cQOqtLtPJlCERfvIY7/33XjpAY6LnBIqMAHdwn+aq96vah2veVs85x5n+92k5u5xvt/3Z9hUfKOQyYGGPaCwPiHTshAwM0Tde1fOV/1uiJXjppZmxyeiz3+zoMbsYpfDKP7Fe/2e5bJZimxm2pOuvotuRnvo07xWvCn71o/rLz3UvPSfzrq+VbnxoAZGkTCazadOmtuHD9bfA9bcCIVTXMOZMyp5Nm/A/S6GBbG+EwOe+3b6Hc2BwoH9Af2UNPMOJjfTt2r00Ej7O4K9fA1f8oZvptbTYq2b61oJYtsde8FzP80l4a/WCzc6ugL76szOznWk6utiJa+Bf/xr6Bm1qM6PJ3aBbEn397N1/U3jNWhgpg9drfe7+8CM/LC/jpDkWeudXXQpfaiiFrxzzfT8Mw1wu5zhO3DbSYO4vAVSV6jFBrnaXkZQ2w1b3NGd/pGl9pqRcw1heF03TdwQlxE1F6GmTEpGl4UJplk7e2YjFHc/ad4J1M89qUs1r9d3GGv+XTRF0ymKhQgN2bmvp8LwB7bglWFL1+ok3HntnQ3pgTFOuYwjKwTvZc9/ikoiISCxefilt+X7y8jdnMx56Z7wuSaePoe9RZGiYvu0tBTiEXrVUXeb0duJm8sevy7ie9s46VZViHERWjSv+NP/6bRlaAdslmW78ELHhs8C4v2qt6UesbdjsHtp/VtbeunXrxMREsVi0kTWVzMzMDA4OMsbK5bJlIWFvEASTk5ObNm3KZDJXX3318r6OmcA6ne+GrEH8n15nYLJ6y5IGP3crXP5SYrkcV7kGxRxTdmAtkRL6rOe6asCGiXCbS7dvtH/56+WI/v3jGyCbodTQ7c/twoCyle3SLS/rgTsiMhP+/nnuv/20Uu3abt7WnnMevOJZgLSHK9KklCgcrLmhDSlHTOYJCH0aTW0pAKpRVI+i1gegBjAuZd6ykPu44XEcxhzLQjazhMx+0YaLPErjSWN+q6YJvbulpJdnTVG8yTLPHZDGb6QFdeYfbUctlXK5o3dOw58NzEMva55ETd7GeIqSJn4JHbF0dYOKxGk0i2qw1Kd8DQ9nlzz9POMVzsCIARZj0GcyD8ZCqZFfLHQzhObwHO7ct8zp7WWv5B7ClOaSToboQ+Glp4Ry7vpuL40UlGty1+FFZViJFFEu74wfrq3bVNx+gXS88OAjjDHO+dDQUBiGQRAMDQ319PQIIWzbHhoampqampyczGQyY2Nj3ctEx8sIIArFtBEu3rafCtyohKa9c8yAgSVv4tlkdQh15LWKFZmWaBtGUfgVF8lxIqjRdRITvEh8tdeCddgbyMqJJNnS7MUXmCn/CcfRdDPf9z3P441WacaYZVlIqNYKmWj5rAWwlvNhncw2ioVSV/lwrGVhEmxCsIUmVUtMzl0red5v47Sa2DYB2CUvNp0N2oB5NGqS2KDZhfPIENr5fhywawsBfvrkoUky1qCITEyB8ofhV5eRwQk4+SsoBorPFj5dNL+cOGXL06xEyypNgRcK656HrhCEn3XKx00wqCScdIKlI4Yl2+ga7B6Zp+FtQgMJ+448+7Hxcy7Y8iGp2aKrdXWsuKg4nRDVu/+BgQ0sCu846ZYHIQpnSP36+/cIEXGOdE9hGGAEc7DxnOxufsJ6N6SHS335DhbWaGWsG6F2q+V4TzmcXSqG5PkXNNiq2h2TUnD08CX91q8dvu/RA9Ftu5ZzTw/0oGBKPFwy7lwUgGR7lfI6ECxjPXz7riDo2MPczS480wy2QsMinOk8L5fLmWohal9YlgFazGjcW/qJagpaKcAwIWsZcxq+GDEYSlmmBtjYbEnfPEOp3Y6kP543f/vzXLrlr8WkZcUu2ATCqc0MaHSBKcrgOozrb2STjlth+rdlOoeVHLNe7RAVwO6fgJiEk5H6UEUqKkXBfUGwYwkPqpcljIOPTe8NWExMzpNcF1k6ersKi/RkIEhypA4dDa+7eQne2XXAdkixqDBzglosEtkwY3Fso2uHu6uWd43v2Ue2AEHybvnze+p+uKiLNHRCkCnIPJxLCTMk0VNTU4VcYd++fXYms2bNmkqlMj4+Pnn0aPdxsn2Rm5Mzhz3GmOu6xpvU6/UmafAFzfO8jRs3RlFUKpX6+voefvjhzdkzCSEPTd3V5VOMQk+O+KFyHLJpLT1tM9ZPhwcDPFsaHIgKVYrGatnGJExO7sj3TBRL8i+/XCwv1GnIGRSyMdf28y+wbBf/v25EERog17DR/Mbx52t+A9SrJRpGD+4WH/5+Oez6rOUzYHMc9oKz+OCAed5wFNuLQIqF6WifIMvn87lcLnF86YLhMUJEC39JGkVXIOQEEyk3bfA4jFNqsiRtMXytZu7V35Tj7kIMrS1yXe77zW3cncRkm8ycyfm4jj1C7HmyQaG5yTijNZ4c4szCa2cN4YakUvUr2SOD6wK1aITs81+defYfel4vOXBA5EawwRjVtQkm2szdodNN4qJL70JGpFBVmdw9E37hi6WJo4vaBaVw+R/bl1ycXbWO3Xlf6GXJhhOjSD+nUtMgJ3BJpeC0zXtO3QRhoI6UxMc+W7zh4UWFaoTA1CG3PAkHqg+33q9TU1MHDx5sbImJxVa8R1I9p0w1nguwLEtKuXnz5r17905MTMBSzPf9sbExIYTv+9VqFcFY0h/zD3RpIOrPw4f/nF3y9MKxgKxaQ/VMpoeq1KqTFRlKJLpCnW+N7W6wXxGlTt/62PjO8F9/WHng4ALJk6dthStfxJ5xXp70MHAI6nzHw6ja0Rns4g8FE5qr29AJYsIxRnb3Dx27827/Xf89+9hUx8emkIV3XQYXbWHDq3PQw60cpSi0qN8jIMr16Fi5mWpxxZhRbU8LyCbA5KmmErO2NOmorzBvJXWWo8vSFXvtOu29w1lJXlyAmmM+bm+ZllKoahq9GfjRJFdoHHQQdKJ4nmsj7GRJTbLx8ZpSK4UKYNHGY6hOU6LDeGdfhn2hs85hklnvtYpOMfjRwkH0pa9w/vDPsl4WFCfZflrxw1oQ5wTSZQCTf4ikqofS2kg2b3AuG6Wf+ZvZ0tTCj9opJ7PXvCrX28eITS55tqMAqnWo1oSm7qKg5Qeb6rdCQn47G9pmqYcXla4dHYbRflL1+ambon1jvKq1ZYUQnKlVfeaeUQcmuKagQfb6VX3EsTCW3z/GtYtTQSPbVTrGS0jSjvudnJwEgDvuuAOWblJK83G81Wq41NhX3dFle8bgPX8OzzqHZ7J0wyqObMtU4ByjwGFuvVgL6wFHgB1DkTCTsG9cnShUb71q9uc3LVAbPHMzfOrtkOfEyWBmFLIcmI6JdMLZ6vX88XJUj5iDuAB9j+nQLS540ChS//ad0gMHOl4RSuAfLoc/fDrQCLiNYmzYd2BraUSDB807tFSV/gqNoMMwdBwn0ri3xDWbt6aUukap5xJsDku2T8PawkbI5GsXjM/P/MENqX9Fykwjrbzg8aQD5y5u2hxnpINNfcegaOxy4ui0LGFq9DkAddpatVSyWefYsaUxNLVa4+NjQry3tERmgxVgXPoSJV+1VEpcIdS6FiIQQgq7B7EKOE0XUBN2ZueM3NXtYXAycMnLMojZsIlgmPO1LD4xG1brkbSZgdnpXBtedqTWCaVjgeegsPppZ1vP/APvms8sTH35st938jlmOYgzoZqVnjGrVqvWakQpJjlO+Y2MHobVYaRcm9gOv+KNudtuDQ7sX3iZs2qY1ANqMSTAS88YkcCcvNAOLTEpsQSmAZZt5vT+1ZGTkyOZ8+v1+uHDh1evXl2v1z3PO6btN5c/HeqDc09HZT+CMgZaUIozolDpFRjNDufLR4tBNQDicKCY6NDCM7paJ+++J7zxtoWRG0/dChnPdHo3qMEtrokK0YHygitrQVgKwmqoQWJ6ESW1yhnG6/LWX4U3dd1LIQsXb0P/pOcVnayUAqilFaJwF0iGOZBTY79tDfVFmmi4oTQYOXZ/Ul6v1CMAL2NssymjzneBhmebphiijYpZPARAXQiDSQiUspUqUGrS28kICWgk/pBGSaf9ePrOi9c9BvYk0ZK39F/4VC1NXahTH0rnpHPTx4XjzNNSSZlibA4fvQgTSr2rXL7jyUbEgQ46EhEEQC18OOOefSFFIIhDnD4HX9TTLlLi9DD7Uru+q9sqoW+E9PZR5I/lGiFCQEgyULDGZ/zZinAshngO7ThDfRf051nO5bjw1WvrC17s3vDdWmmym8/q64ctp1Nuofc396yekslgvzc5XS+XpeNIjRrBryMERrUFbBfAUHdggP/RZZl/ev/CE+mF59HrbkUmzemyuSlVcvsenkyv+MzjpsZnml9M/qiVkARq56GdfX19OJPrNAXn3KQp4DdmTz0TCjlEzsWAPPw2OkxGQgZi5ezccL4yUVJSSeFwWxGOws14pW3a24+nMFwocfCMs3QvPCaUGgShCewDFzHUHs4rURR131fSli61GXCBFQNKx2fVn71tqnvP99mnwqoBdPios2X0F4ynxodfp3YUoTmHR7knng+lnRmijLRfU0oJYaJStKMAnxHiHEJeTCleq5Q7YzqINoGzCaWNgIGlnXttfv9JoNSkEBlC9J0eY67TgHyiE9DtcwXpg2sEzt02a/Pe/Dc7ZY3bbtzduav2G2P2Y9GdWUKpj1er13Tg9Fjhxq2ChfShgVQBuuZYHHbIIaij3chLNhCs/CIOX9KLrg62brOVzVFiYZ8IpaiNYtgGhnsdPxSVmqj5+BqnJO/RvpzNaJxHwuU1gf4RumErfeD6bnOj45D/v70rAZLrqq73vf/+Pj0zPZtmtM1obEm2JMuyLWMMxnYwdmIHbwmEKqgQTFLEbMVOElKkCJWtKiEFdgGBVAgmQJEQXBAHsAMBy4AWy5KsxbZGtrCENBpp1t5//+W9l3rvdff09D6LnJHQqS4tPT3/df/f//777z33nPYOrTRbUTqImoZ7u20/oNlc5EUUIzB07DrYdUQhQhY9OMZsw0Zi2yArBHXhOmA7EEYhY2jlypVhGBIi0nKV+SYSCdd1gyCwbTubzeq6blnWmTNnSulSBRxsBFmtw/anpsbVSyilpg6OiV1T5wAZr3BpxIi22WpOF9K5gmdzqVQyb6jfV0a6mjLMloVgaVAqGAUdZszUwoxPo0D0UzDRHIwtHRAaHIKrNul7DzRZuqdT/lUyEVee3EohWvFQDWyu7qBZn+XCiAY4IpphIhODpbkaWrGCJNMtdErFZUU0gIVARcH8u1hiFYklwt02LEuUx2KFaoPBCOAFzjdxfo1sG6qoZmHchgUpvaKazGQhNaiVgXL5I0umuhVRjSBkSApdgzKIsv2u9x1ebFljXnYqBZXxRpeEyLZJw3O4dK8Qcv5wNvv39XT9lz1ET59YRKgfql1aIkRXtxha2bEYhNJ46WZMnVDy/s01SZtFFA+6RIguFItL0/kEdfaRJrPyCDRRiyzGheLsqMobXIe4jpiMVasoakF5ktDbh3UDeQ0Hyi0LTEtuTp4jqoxomqbv++oWUilHG4aRz+cJIW1tbRjjel/uoRVRJs8vGwh3H7Wy+UIyFY/RVT2iIeSHaOS0oNZxzmM2Gx6Q9QIOR04Y8rqy8BQ754nKu6xfyvqGOG3Z7LSI3DekTSdt0nWm/MGRZcLtv2E3DdBP7IbL7weOWNHtW22hzPNbpNGIxG3okjG0QLsmwJHrwu+/pe2Tf12U+q2Fk+cglYOYoutpTB50FZ2LSxR257LMnyUqjmBFJdcAuA6hezStV/4s5Jxh7CAkyBsyXtdAndjnINQpqxylepPaQxVz5I3eKiwaTS29G6Dit3Axd6uF0LLchj32L+Vyec7fbNvf8rzPXrDRuTioUt4krI7ORftB1TZschgxMF2UGUXwVTFAxeri5Ejhz8qGbcHpSgjKN+Zbqd8gnBNxZ13ajLiJLHZAygdVZn+nuFZRN6YRpqYhkYLu1aHhsD+49tjX/zc2NU1Ugy6RELLLSvgikUioaZSxsbEGWzv0srACOHFuzlTuuRkymVLhavbdzGS0gy+rINciD6oR9j4vxPUtV+wrGTpLNJ25K1Qc+uL7uWywmRQtwNETwtJXx5xjLi4DshRfvCwXt1SxSmEJcXAcp8lnPDkGR07AjVfI3+HigyDZly18gNIHWa5QveJyyaRyuAB/pGlbZHlePWPIVLf0gvKKaemDVn9oDBCXGfcsn69o4I6JmAVb/AdpJFK6JNG5Cgxj0Ziq89M5boS18BKl38znv+R56VpsmQttUKUaRcbVnOgcsuDJoOh/XRvC11Lo+BepVCW1zBJqhWZpTAUh5YlpenR3kwDNGOQDGjGOJXWvkCOXbbnyA8kyS4kRv3tnkE41P6fPjaPUODFc9rNDOJlZ1K1fie9s27a6i1RD4WEYahrO5/PlV4wluMcsIpOD51+Gm+IRowxzLuzFSnODDZJOxSTn8N0fNPf32n8UJpKwspuzkGKmIa6JqlbFJb/GElX/qIMwgn/5L7h+AxAMLIyE5Ks4isK5q/kHWR6oOKAlc0LF0+hHiBYUt2qgoqVV82KEAHo1zRKiipXPi6JzFRZw5VdMu0YBWjlqV79AnXUNKh6za8x9q0qIlTWiOTfYYp7zffKkS15oYynVELO8c1Bu163+QaVpd8iDiSDa0aQNenqEjo2Gfih8BdUUz2yUL5djKjfYlmonEeV+CId+nk+MN9mnk+Ow6+d+3mdRKCgWopk/d5XyaTW1SunhB/zwwZbGQ/buGBMr5gAAEOVJREFUjwIfpafIz44YyaxoZL/qmuENw/33/Oa1pkFUX7upa0YF4vH4+vXrt27dGo/Hh4aGtm3b1tfXN7/O+HwQRvDYU+B5NMzJ4xEpv/Tika0u8pWe5DwMeLKFy9j4DDzyfem/ngu4L53YS0uUvkI1VhHXABrxfc8279s8eQD2joh/sJBy8UGkobj4LGVm88v4NMzn857n1bxrowBTnPsA+eLnKIe4lstH0+gknRqbc8EL5e95xizp8dYwOlfIEpWt1ypho4IrrcbYCKlL4Wi2vYDzs8t1dmlBgyqzPIWqDJqJ6MxCFqZC7x89ONFkc+de5o//a+6tHyeujXEoi59C8rZQki4QYWdPUgFBg6M8H8D42WDHt/ymNySMwVf+Kbxme35o0CYMsC9YA6L2pos5tcJE52yomf2qBCH/5fHwyR+31Mx9+Vd8eHjOt27k+BilLJHK+vPUw4p1R5bLZs44ExK2bXueNzk5WToBljZxLsdjT8IVQ/COe31iElGdZBgCLliVetEtu7LKUmCg7Nsf7HqmpR31zSfg5mvhtVuiMBMYRN1YIxFyUNkqFbfl4qjw8XPsu99vXhyMKHzs8/DFj8BV6yDK+rrkBIrhRSEPL2/Q1CrLFZzzdDrt+357e7tKn0vtCgYwwbkQIymqj6pSiDKaiDhPUJpFaEBWpQt6eNXbLz4i1QwubqH6bYi5Uc7VqPcSFzeqFhN/NpwSbFQYkadrZNt1A3TDGULK+ZdyufSFnzsraO673FkiTyl3ZrO5M5PzatlvZNnjLZlenT7K/JANbtWYB8xHnIlaf2mOTCRYsqCh/hQG3iI687EzwVc+kRk92tJ1L+/ByAvR1ddhy8JRikMk7uDF28eFVcpzZ5WhB5GIzp/6RGqiWYauoOtGV1cXQujGG2/s6elxXbdvxYBlu7YTM01rw4YN8XjcsqyhoaEVK1bMzMw0iLCmSzWd+5mCEWS1iFJ1Z39eYIw1GEp89iis7edD/YLYJ/bRjEg/RYxWvLhah35inP3Jp5O/Gm3pmhFR+MkzYmJlZSfFytMjzyGl8ui6q+Q9eOjL6V3PtERQSWXhp/th+2bo7xTHVU7WcEhy8NQXS3Q1nzl23Z49y8g0tgJq/lOTKHUOOecbMV5bjJiyeC8iLOM8R2maMSqT62lJYbRLpWpZISl3j7WKvcGCQkVVeYlzHjImRE1lBl0oQVWF3ZrfQ0Ffn1dMr55DKS9xVKTw5cqTJUgZqXxXl57LCcXnKjBChNV3Mllrcb4zDD+crjIVvkBQw9XbeacjJ1M0YEpbRFyLxeU74jSgUSryXvC8z3n8h5LS1BrOvETzftS3HoupCA4UQYTEWEpIHcrETHYkI2YQcj9imSwdOej/5z/kTh6ax13JxDk4NhJesRksC7NQpN0Mi4VkzcSkVLA5IypGVMKQZ3Ns3zP5z/xt5viLrS5hGEZff6cdYzQzjmgylZgcHZtJJpPT09OpVGpiYmJqaiqVSk1NTU1OTjZW1QhyWi45WxVZt7Zn/XD/mpVdo2enwlDIky2SDd04QIcR7DwIq3rZml7hXMfyMnQqJpzq41FDTH+oikEIZ8foez+R3L1/HncJfgg7DgjC8kA8MsUsDOK5Al1EnHqKcscsoNLwgYKfg797OPPP38i1/rkzHux4VpzOG1YxXZCfNRGdg9klnnlp+3IO0Cp2+L4vcljDUCbfuVxuDcBGKZ+kXiNPPshEUfnNCwdIy4nBmGJ3FNNh9VNdjhGWK/qr62Cx4yteWQjNpXqIjPjlgnaNAnTrsv31pgTLJ8XLAzQhNabAi2Vrr7fXSiRwrUyZGga1bTOVqhmd35NMXrikjRqu3v6MLyjPQnFOByb9FxiwSUbTlJ6i0XcjMTrYvF00B34WfvJIdOzpzKvvNYauwB3dmpbHmo4xzgmuNaeUcS/DEhMsn6O7vkOP7YmC+WvYHT7A//SD3p33Brfeone0YeJjYmmYyDqKyBhYFPHTp1gySR/7TrR/bzRfonpHXxTrpp+6IxOz+b4Xzc882lkueaPuVecreAQAp85MTyeyCKGwOV9laZDJwSc/D4//InzgPnblZcQR4k9YizQcYi56S2IkYmKazSTZL/aF3/9ptO/IvN/YdBI++hBcvZ4/cHfuhq2kt11DWdAiojFMAzlCiFAmF46N05Ffho//nD32k5pc3kYYm4S/+Rr8aC+8843BhiE2OEBQCCjSNI4ZXaZ60NXwPC8MQ/XN4Zw/h9DdjjNnxqmWBS8WtgzIlgFV6toVyh22VKerkQsXKx6csYBVmlkKMrUM2TYRZ0sJlW1GIQXcrPq8sKJz40kWeVlghOA6g39Cqr/qZOac7wnDB5PJyYuluKFA0u8TY3VoFYL1ALuAS9F0fo7D4qZnOYNTz/FTz/luHNp7xLHrW4d6B9HzTxVKVF6aJ5rIwDXH+Dl45Mv0vx+lHZ3i+xVrR1dfi547BAkp6EEpPzEfs8EKTJ02pkfhgUOO+m93l+F5YbzDGRtPVH3nW4JhGGvWrMnn88lksr+/n8OUaZpnm4nhLQm8PPx4N/x4Nx1cSdsccSoODggX1z2HRLEAIRgd59OCQLhwMAYHRuDACO/uCFf2iuvWxiF05RB8b4cUrAVIZeDEmUWdPOJu4LB4WEa0fnWEMHS1o1uuhZ2H4NV3wIWCpkLhFc6wrjTT61D0j1nmNxLqiA2jJwNocBlsTOcoKPfLFZdEmq5RdC75YBXXVv9FzTh2KcZ+EQQ3G4aD0O4wfCCZvAhoGxUg/EUZkV/k8OR5WSA7Ix5iqvWl89Vun5oUDwl+cN/SLjH7JRke7Eun82tX90wnsl5+HtN9CHMhZkux6hf19/dns8JzTtM0SgXJ6pWUMz55pvCPI8Ik67wckamkeIhbHHHEl2YAogL5AA4XLr38yf3irxsunABdjtNRlGIsPlcurlzTrg1gk1IaK2bNGMBUztzFCNZg/9ajiRsyvqsSV/ULNE0IMswvd64XnSs2UhGdS+3E8j2g3LbqnxTUMAxpJZrg/N2p1BWEvMmyPpvNXnzRuagHfQn10dfXl06nKaXPjZyNoujk6Axl0NHRIRov0pFTDX832sJQYMfY2NEOAJSUKMnRqbSaMbaAUsklXATIcr4nn7/DccrrvOUhTfRDhdjgnAnfiqg3p+hcgapIV/C7KhZGSvyaAkNVUZ7L8teWgnRD49fK99OY7KG6neVesVVgyo0QYIqxEOBgFB2sb/18oeNSgG6Cnp6eNWvWJBIJx3GiKArDMJPJxGKxKIri8Xgmk1HOhA22MPErg+g8Cgs3tm2u1eaalLLJqUKvedkaglzCK4B/z2YnGLvfdduKHbPyYK2mmEIZoJWqSjUKDcMWEl4E4CoTgCpHFTnhP8+i8yJRU3RUgup6Tf6GAitK2e0IgouE7VwflwJ0XXT0hW4He/8bdsWcQgzN5dH7vyhUE2ZmZjjnp06diqKo6ReaRSiIpL+LhE7wurW9QUinE5lXrE94CcsWFOBHnvdcELw9FruyjNGhIMiunEvFbkFaUeL9pVdI0wbBnwOM7VrdwuoSR7ldd3VXsOLXFatjSYbFK7bbIDoXzK5auKf0fg0ym0sBui4CD2sEdj6vm8U5iCASmqXV+mTNdrJQjdCwYNqJ8dN0fufeYwiJknS1eu+lbPrXE2co/UIyebvj3FUkdXDOE4ztCYItsVjpZaVUGkmJiTylgfz6JRjzOW+TfLuKL1V5AaF6xr7+wL9qs4sYiutoibSEViYMq6X6a/E0KoxUphj73jJmVS7HAB3rRt0DePNNhm4IUv3UWfrUt/PnVaoEYxi+HN90i26aouucTLD/+YE/ObE0S3ppLZ8h/zZWcHHdvHF1Ipm9flvP/sMnfH8eJePewdBqoxv63zg6OmrbNqXU8zw1PhuGYU9PTzKZDILAdV3TNA8dOuQvA+Hadavx8Gq4YRvBRMMaPvB89KOn/Pz5fF+DAzA4gG7ZThDRENFSOf6dH/otDstcHEhx/mg2+6zvPxCLxQH2B8G35ZD4fba9RZ+dlVSpNOI8T6VFRBEe5z6lMYyd+tp1FdZVjcN0JLVSW0qfG+QoVSIbtal4FcPrhqFna3N7qWHgIJhh7A8TiZMXyzz3eQ/Qqzbga24zb7jTivdqhiFJ1dL1fNut5hNfyx7dtfRGBrqB7/3d9tvuoMOXG7aFsXTbYwzuud/6wueyT/106c3V0xkvomwmmaXR/KJGclz3UtqOkR2llFmlJ2pAa3p6OplMqiFgxth5mvluHZetgT9+M779Jrujkxg2wQSDJmYPjxxlH/qLxMjxpT+Uq/rgvW+CO1+nx7stw9FAJ0hDHKMH3hb78tezX/xq5v97l7xy4ADHo+ivEomNhBwOQ9UbVDlyBYQwadWTDCDLmKBL14qqBsZ6laZSdYxWUzCzXjBSwn8hlleKsLEgorQgQdcrTxvGtOd9JJnccwHaoywAi7CDlEAYtt5K3vbnsetfb8fj2DaxoYscSNgnaah3pbbpNcaZE9H4SaZp8JprzIFebfTcYk84w4D3fMB969vNlauIbckVCdLEoDHq7MSvvdl64flw9DRzDLj7Gn3zGv3oGTrfYpVhFEa9VSQdGhrSDYfoFmXENC3XdbN1rvDVWNmtpdOmGmzBCG0dDicS2LW4Y6EgwkEQYIw3D4WJDA6CheyZdoP93hWZI2dpsOhv7GWr4eE/Q6+93op1GrqjYUNDuhhf0wgM9Os3Xm/u3e+vAPaWTdr9V1unUnwqu9gi4JoV8PBH4bZXkVjc1h0NGRjpWCjME3Bd7YbtVhRB22Twrq34jVvsszk+malNQb/55puffnpZTxK2jgjgXBnT/jpd31CWQSuI2cyqwO0g1KNphhwKn9WjlHODlqYVVKEbB1rORZYwN4aKkM2ExUPdbLpmRlxTfbRmdK4ylvW6uqyZmZp60NPt7R+amNh5AboLLnCScJFbXH+d/o6/bO+IYV24jxZk+EtKcoigzrh233vcK2N+f5d25eXW8VPB04cWld4aBjz4AfPu3zEcUwj8a0UDB9GGE/L/yHHgwx9r2/O1/JYevG7AIK727MnopbPzjn0Icd3i29ZGOkFdXZO6rmcyGV3Xd79AGBfRtkU1O9dkwsmkmKO8NKpTxkydE2mcqJ58eUwvsjzmDZOgB1/vrB80HvxqDXWC1mHo8Kl3w/BaopuGkLgiWNjWqIlwOZ65cYP+6Oe6oieybSYhFt5+lX3fQzNZOdm0MDgWPPQR2LIONFPHBkaatCsUD8X4Zaamffz9MbpZ088wpON7X+e87z8yPzhwMUThFsEBDobhb9uVljEVkRIDdEpJaBVDFSujoG+HkCLVNYnMKjqLId/aB1SYe7YoytHAVKW1th6XDnUgMRJF6+RVRzTnGft0GO67eEl11VhUgO4bRG/7pNvehg0iorNQlZMi+kpGDslWLdHQ8Fp901165BXC6CJxz5u0u+62LUPQhYjUWilJTiuPII3D4Dpy2Vva0DgEHk+GfCazkCDSOxi4HewDdwUxW/hSlZ7febjPC7Cu6y3yl4+PlaRsBLraqeej6bSy4Cw82dHGQooWSIbGYue77mJ37Ztvh20bQTN0Ib2jSRNhNRdRMC5hoKHYIIHfaocRytPh5rVkZZf24tjC8/bbtsOmIWn8SqSHpLoYlFYU8v+cmFi71YUDDI0FNuFvuMr8tQrQAHBMDrO0zw2OFQfbQsidW4VQu1DEtZaZc8pV9vxaXtVErReXnvp0JjPN2LsdZyshH0ylpjo7m45iXkz4PzeGScFvB5MyAAAAAElFTkSuQmCC","AutomaticThumbnail":true},{"uuid":"1f923578-08c3-49be-9ba9-69c144ee2e32","Refresh":false,"Reconnect":false,"MidiRatio":1.0},{"uuid":"6e610e1f-9de2-4c36-90dd-0ef570002a21","RootNode":{},"Children":[{"Device":{"Name":"Window","Protocol":"5a181207-7d40-4ad8-814e-879fcdf8cc31","Mode":1,"Outputs":[],"InputWidth":1280,"InputHeight":720,"SwapchainFlag":0,"SwapchainFormat":0},"Children":[{"Address":{"ioType":"<->","ClipMode":"Free","RepetitionFilter":false,"Value":{"Vec2f":[917.0,692.0]},"Domain":{},"Name":"size"}},{"Address":{"ioType":"<->","ClipMode":"Free","RepetitionFilter":false,"Value":{"Vec2f":[0.0,0.0]},"Domain":{},"Name":"rendersize"}},{"Address":{"ClipMode":"Free","RepetitionFilter":false,"Value":{},"Domain":{},"Name":"cursor"},"Children":[{"Address":{"ioType":"<->","ClipMode":"Free","RepetitionFilter":false,"Value":{"Vec2f":[0.0,0.0]},"Domain":{"Float":{"Min":0.0,"Max":1.0}},"Name":"scaled"}},{"Address":{"ioType":"<->","ClipMode":"Free","RepetitionFilter":false,"Value":{"Vec2f":[0.0,0.0]},"Domain":{"Float":{"Min":0.0,"Max":1.0}},"Name":"gl"}},{"Address":{"ioType":"<->","ClipMode":"Free","RepetitionFilter":false,"Value":{"Vec2f":[1259.0,559.0]},"Domain":{"Vec2f":{"Min":[0.0,0.0],"Max":[1284.0,994.0],"Values":[[],[]]}},"Name":"absolute"}}]},{"Address":{"ClipMode":"Free","RepetitionFilter":false,"Value":{},"Domain":{},"Name":"tablet"},"Children":[{"Address":{"ioType":"<->","ClipMode":"Free","RepetitionFilter":false,"Value":{"Vec2f":[0.0,0.0]},"Domain":{"Float":{"Min":0.0,"Max":1.0}},"Name":"scaled"}},{"Address":{"ioType":"<->","ClipMode":"Free","RepetitionFilter":false,"Value":{"Vec2f":[0.0,0.0]},"Domain":{"Vec2f":{"Min":[0.0,0.0],"Max":[1284.0,994.0],"Values":[[],[]]}},"Name":"absolute"}},{"Address":{"ioType":"<->","ClipMode":"Free","RepetitionFilter":false,"Value":{"Int":0},"Domain":{},"Name":"z"}},{"Address":{"ioType":"<->","ClipMode":"Free","RepetitionFilter":false,"Value":{"Float":0.0},"Domain":{},"Name":"pressure"}},{"Address":{"ioType":"<->","ClipMode":"Free","RepetitionFilter":false,"Value":{"Float":0.0},"Domain":{"Float":{"Min":-1.0,"Max":1.0}},"Name":"tangential"}},{"Address":{"ioType":"<->","ClipMode":"Free","Unit":"angle.degree","RepetitionFilter":false,"Value":{"Float":0.0},"Domain":{"Float":{"Min":-180.0,"Max":180.0}},"Name":"rotation"}},{"Address":{"ioType":"<->","ClipMode":"Free","Unit":"angle.degree","RepetitionFilter":false,"Value":{"Float":0.0},"Domain":{"Float":{"Min":-60.0,"Max":60.0}},"Name":"tilt_x"}},{"Address":{"ioType":"<->","ClipMode":"Free","Unit":"angle.degree","RepetitionFilter":false,"Value":{"Float":0.0},"Domain":{"Float":{"Min":-60.0,"Max":60.0}},"Name":"tilt_y"}}]},{"Address":{"ClipMode":"Free","RepetitionFilter":false,"Value":{},"Domain":{},"Name":"key"},"Children":[{"Address":{"ClipMode":"Free","RepetitionFilter":false,"Value":{},"Domain":{},"Name":"press"},"Children":[{"Address":{"ioType":"<->","ClipMode":"Free","RepetitionFilter":false,"Value":{"Int":0},"Domain":{},"Name":"code"}},{"Address":{"ioType":"<->","ClipMode":"Free","RepetitionFilter":false,"Value":{"String":""},"Domain":{},"Name":"text"}}]},{"Address":{"ClipMode":"Free","RepetitionFilter":false,"Value":{},"Domain":{},"Name":"release"},"Children":[{"Address":{"ioType":"<->","ClipMode":"Free","RepetitionFilter":false,"Value":{"Int":0},"Domain":{},"Name":"code"}},{"Address":{"ioType":"<->","ClipMode":"Free","RepetitionFilter":false,"Value":{"String":""},"Domain":{},"Name":"text"}}]}]}]}]},{"uuid":"05e72689-e02c-4c9d-a0bf-fe84c32d3d96","Data":""}],"Version":5,"Commit":"d25496374d2ac17385a6021f031e01dbe278300c","Tag":"3.8.2"}