@fps-games/vfx 0.3.9 → 0.3.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,28 +1,142 @@
1
1
  import { TransformNode } from "@babylonjs/core/Meshes/transformNode";
2
2
  import { Mesh } from "@babylonjs/core/Meshes/mesh";
3
3
  import { VertexData } from "@babylonjs/core/Meshes/mesh.vertexData";
4
- import { CreatePlane } from "@babylonjs/core/Meshes/Builders/planeBuilder";
5
- import { StandardMaterial } from "@babylonjs/core/Materials/standardMaterial";
4
+ import { ShaderMaterial } from "@babylonjs/core/Materials/shaderMaterial";
5
+ import { Effect } from "@babylonjs/core/Materials/effect";
6
6
  import { Texture } from "@babylonjs/core/Materials/Textures/texture";
7
7
  import { Color3 } from "@babylonjs/core/Maths/math.color";
8
8
  import { Vector3 } from "@babylonjs/core/Maths/math.vector";
9
9
  import { Space } from "@babylonjs/core/Maths/math.axis";
10
10
  import { Constants } from "@babylonjs/core/Engines/constants";
11
- import { L as LIFETIME_DEBUG_PARAMS, a as LIFETIME_DEFAULTS, b as makeFlareTexture, s as scheduleLifetime } from "../../chunks/space-shared-BXV1hc0k.js";
11
+ import { L as LIFETIME_DEBUG_PARAMS, a as LIFETIME_DEFAULTS, s as scheduleLifetime } from "../../chunks/space-shared-xh5IOcLH.js";
12
12
  const arcTextureUrl = "data:image/webp;base64,UklGRgBmAABXRUJQVlA4WAoAAAAQAAAA/wEAfwAAQUxQSJBMAAARGbRt2wZEsin/X9z+ENH/CWjYjS3Pjsb/Qi09DORrHoJsm37+2IeIiEQQlGxlX1u2ra22uUJCb7Nt0zZHjnZZ8nfJlPK3Fcq+r+a+L+/7ff9fi/btSOBDe43Pk9se8UdBtCd3vEJ7jcuS9/h/Fg1mwQ5BXqE94YrgwXiDPwqBWRToTQYFmnxCoCdUFg1GQTCLD+2+GYw3KE+uvAajINokIiZgArg8/z9JkmTrZZy77/u+7/v+ki/a933f9/2FuEdWzbyCD6pBfwULGeqiyVyGTsIcZHKWtJkpWOqHZtBfeVHI2TRM5nJ0CtZh5jBhNzIFC/3QHPZXohsyNA2TuZwVrYtMjm7CamQKGH9WDYO5DN2CeZnLWcIaZHJ0kw4zBQsZOgXjIpexosVcxhLWIJfDVERMAJfn/2dLku2gez3PE56hud+/zIzmeZ7neZ69VkRmd1eV+rCHGf3VrBTomjZLBTO8RqFkTc22iqXWG/jqslJAQ7NQsoYHRsGGl201K/2RzX4qlgp24GGpZE2bbSVLaLbUMPdLaBYKdqFhKFnDw7aKFTVbKpba7MBioWRNLwslO/CwrYStiJiA39F/Mfd3elb/w+9xxT3/Lv9cRY/x+r2q2HZs2qHj1G4Mewzr96DiZDc6nOzQYRjoGaB+eJTzaqqPpzhZ+8VA7eeITsZQP/zJ5n7rYyb2y+D3GJuhMoU50NPT/bf7Zb84fv0QJ87t6DLoGUN9jMRuoRi1G9sOJ8twZB8ZQf1QJk531IAeD14fD7Et1Mns6IZxh9GlI2PUx0juZf7bV5xbFDGe46E++mJbqP3Y1rmDnsFUY3K8j8Gcesb1ySh0dNDhYDjdQ08PsV96uhitj7ago3o7nPzdhkJmZiY6mCimwn83UUhf2C9H5KWVzemOZzNen2zChsOZmZupDKeCxT56gh7qIyy2pbZR28wgU2TaLaNlGBQs+/RkQPLyibM7nO7oeAaj9Qkl9kvPiDuWqSA9iNH6yIrTO1EIMmMb25kyWmMIZRhkgLxU4o51x/OK9BxvtD5pxMk6I7Y9FcMRxDCGeTnFHZbdIMjmdE0Kihqk06YyjOPmZRFnd3Pnuw3zQKP1iSH2yziQGdtCNjUp0tFMCtEjg5dzoJtmRkdjKgIdZZTh3EKpiYI2UYR25yUZJ2s4bmNzMDrOQEcHHR3oi/1yRJfjDOsTQGw7SmUKNToady5HRhHDjOSlE6gaRW0ToYg71lSmgkAmBIKaFKXIixana3s7nBx1ZiZkGh02xpeR0aBngPp4i/2iBEVmIOcV1ICgpId4CcfpNaPIDhVoB4qhpC+GFaijCGUq2uGFjzse7phTZ87MzfEzNnoU6mPsZFGb2gaRmZnziprqGMTReans1/5O2CyoEpiZmZMiAhXDKsowjrmXFyb2a5w4NxsdOsroqEEH83kZ1sdR9lqjo4Ladqr7DSYxVaBY6OalGlRHmQqdERVVMrOmwJRCQxCUUKowVUhoh25e2Ng9boODYZk7y1CMNZFpGxOjo0bTU0eZaD06i/1iHzkC9bGzXzo0ChGZsV13aIbRtZ6pCIXSnbwsgmM4u5lRoU1HE5hIh+DP4L9B919AhZpUepXW7kF38gLEbt04oLbLfphixhQzppiI6dzGRE3l6KX39JAx1MdIToyWsSiC2lbQc9LREKpQaBhQL9mhioUGFg4piQ5Xfr9/xEAf/A1Xq+mE5q/61/4jFhUUynbarXohY1s47AbLfmZs464TYtZR44EaGwZyFPWxcXociFMRVHQT/avbTiF/y1/Z/oNdDVSNRY2dzMsgG3XmzlKVqmLhD/sD/rG/4+9Sk7/mbz71H1qv/7Nl/vD3/Pv/zEyiAsV0Zof9PFdx7uF07QaZ2dx9xjZSpjqGPIg8COpjoz0cxjI5TBRZdg/bL/+ov/0/+e39xNXJX/vXv9/9S4+gUcSwZdHRUdu8cEENu0skuGJhpdLoaK6fff36z/AHWf7s33R5918eQmvTu7/fP/wIEhWIokvi3D5HcW4zsykxE1OIbceJGpsaM2ae5kbpUabCRAV1VI9hBj1G6yMue8ZBiaU/7N/3FsvgCMf1vXe++fU/YvmP/6l/c+b97uBv/fW/9XrXQwVFEFrHrdRL89gsInae3nnt9SMrSiy9Pr5+5ZuH7uyylqDJy7/PP3G32KYiSijCWGTTo2rkOYltB8eozCgxQ1FqN9PJwJRpe83BMTOlKxTpmglF9Ix0MoL6KLtjVDx88nR9++b15fHx27fkeP/lp+/f+9WXvlvevP/dv+32fsfN3+Enu5NGVFCDYX8zNnmhQu0viPB0/ewz3n7+SyulVTFd3Rw3KBZifvmn/ulHiyIloUJEVEtWaenzEXSUg4oUISF7ZIOODnecufYyI2OjRyijQRGdpRtmBPWDFuYzGLozU6J6fWtZj+/evtKr40t+/bf8FX/N6Zuv/CvP7tcnB26+fXtIyoKGKMrEwM4LHWcGEjxd/4TH7/Or6+evp+QgRbEuTGbboll0v/zsH72YNRElMR67Q+bEoEOeXWzLAaEIIlCxW+rcUaMDa81X9KCQ46kRQRnPCBlD/cCkwz1n56hh7CxCoqNp8/TDy+WJr6Yf/SnzL/gcN3/j9LtFZ/a3uVtbaKGCSLRrZziOnbwogeEgjCZw/fR7fvyt9fijN2+CJywcCGbEgPKjv/NfeL3WzCxoYu3FfjKGdhQrzyQdyuAYTYdCRzfNDA5GY6ZGB2rUgMmq23HCdnZ+ueqhxHiMF9IbkxrpC52MdGE+b9kYOu6HMqoD1pK9ktaij+hYD3/Sz/6sz+3OZoXm676d/71d1yQlJLGb6mGMzQvdcRAlhOsnf8yHH7zKoce65LMHV968/nhzfbt5ioXb893g8d91v15frxbabOkppUiyqbIKN6ph3kuUUgeWKpmaiobQylyImWAiM3MTlaentZ5rcv7tTw8i1KQNhpnGyjAU6YhhHHc+g9ypGDB03MvAoJVgRqSklSrLar3/tZ/9bd/nnYPDzqJJTYv9fHL6fI5UNCFOTNuOvbwIQe0WQtMfPn342kodyx/3o88s3vz8wzfevnriE156L26frw8bC1+7Pl/Pa+fvd7dzqUAgs0lSNTcOxZB7qW2dLEJDNCiVQkSRCYNab3W5HrfxtgVO5ob0BAoxLIUaEJTxGM0R23lP99vNfWbTUrsDQkoO0bIsR5vv/S//Y71/h8PF2WGWBov55MPrWUQlFedG6W3vRQzKgSIR6sBKV5br+uTh/e3ho/df8/FPfunp/UeffHTynnLx/HLz6nCLMovYn252LYW2FmRiOr13v3XHQBAotBYJRaAynZvFa2jbtp1PZkRNRQJFoJSaaiCoMRlhnLE772G/2C/sF3vLYI+MhXkqth0cQ7EgTgFRxYPiFVQbuPoyPOsmXRYUOFcVFepTPIZgodUMRZw4nLpQUwVtm0q37Jeekfq+iv2OyqgIDQaxTgBv3ery9cmT/+yb78bl/d/w9/8df+Nf/+PL539uTO8uqtlut2dACjXUqkFiHQXW4qjBWbBqe2yPAyzYPk2tYAG1KLZPA9IH7aOACtCABxRUQBEFhBEuBUGcgFUsFpwFHBbUOgdYHGKwasGJs0ZjEkhvg0mFvhjt0UOP8TrWfrFf7Jf9gv2A6IMM7tzeDmNRSIEiDXgUvHpEGpjcdnGWzYMSoXXtTtgDBSNTE97OqgrBeaQWDUUQFEsnUN8/sVs0iN20nFMBrANVBXZn/911Vdus68ohZE0C82gXRSX71ckyCgpSBwbrTW1xBRYMWIwFsDgEg2JxiKO37tNfeUABnHgHKgCKQIMoiEBge1BxkK1fklamqKyxzoIFcE6OAAsOLDgcWJzFghOa0ZKJglBIx2IvEA+xPNypJqNleaAyDmQvChUUBCWwAWiDN5O//K/c03UNAQ209ZydS8FakRqu6m1beRw4b6OCOpYghvX9EWeWGUU1rSUWR38LeEjPqqJO4ziOWf/8b9smsCeKtktKksu7KqagNlggxVmMwYIBa50FsIDxDqsWcD1HWkB5UA8g4DyAIqogqAgqiqAIgtYZi6vdkgIQZ51V+lss7kEsDgtYwDrAQlAxWkUZD+XIEeSBHuI0GPZAPVBRxCZUEVRFRQgIUBpRndwew3CNQhlCa0VcJWlqxVCe6GExqNpYMKg4Cw2hpEcdj/oeTEedW8Q2dhfAPogGsLsrwJJNn/21nzz8m1cQmd0u+d/fbcMSTpZJWtSprR3WupqGtDBgsQ5rHRa0HeUVDsD+xggKCIjQ61FFUBFF8Aoi0ADC4vH2aYz2AA4wgICzgAUcDgsOLKYHsK4nChlQ6ogeNdX3wTTS06OnHyWdZqHGXhkHo9LLIooFqh5FvUekESVjdN8RrufzAoYNkyQrCkNQrKi8puy5HW0BJ2KdxoyGUNCQdKIH9RCmmqDnqI69UbopTSVxKOBAvaiVxgVV4txkc/OX/PT5fD5/WaC2KMZ3TwdfoHSrajymina4PVi6g+4vqj1QABaLY1qm2XVtAXFWMd4cJeA40tNfBAFUQBVREbyCRxDF06vzL3m7A2/p2yO2xwIYwVm1FrCAAUwf5yxUsl8U6VE1leoxFULXTDU2VfSF/UKXQd/WVJOaaqoJpqJMBW3k3I0wFykaNB4RFa8ojSgZwdUV/K3Hczx0BYkY51yztL5y5G01LsvW7RVxAi5REQ1VUxVCGRh0qaOmkYdZxWgUgbCq4NR6sA4BbAQNsHhzOkFVM8A6qrMn28EWIGbMeBdFcczeF4cuDPNP91AFkAsUSpjbhr1gnTjBcbTxWLV6BAhiFSeiVhFUBRVExTsvQoOAqo8zsqtnFxc1jUXAgVV6a8XiAAsWcFAD2B6wRi2ukCJRkJrSaypVU02FtiUoD54eEzXV5PhVhs3o0LFXexVFowqKiqpII4oGBOtb+P0vo+tofnPfWQgbvOOgZzPysJDBYBGKqS2+FiepiiYlikGbxpDQ43te+7VfVNusZbAYiwq9KlFEw3hQT8BypIFq+fYzQmDLgCqJdruqil1NU7K5SGmrgLwqrMWAEZq9ABYe6KMKAgigCKh6qyLaoyKoR1FBGVEOv0z+69zgnUUBrBMnYBWrFmq1OHFYMIDVGiwWZ3FElSgJaioEhUI5ZgZ1rPFJTTUNalKmUgrN8ceJKKQ0Dl7A4xFpRPEQZKdX3H49eMR8fd/R9zBkxWJznVxFcZWezH6apSnOItBSKk0qFJmKUCMEeSj9iOHs7ARNG1n6OvB9KHYRTJnlgLWFtWpRA+Tbt8hzeDp7y45dshvst6YA2ZecnoIhqb7YWyjA0tTOgjvKfRwKCKAgqOJBRH0PHsULqKJNOe+eze8uqtzwsRqw9FosDgvWiasBnLNgFCkVJTGsAfVgoufBJsfs0UNNVQptUoOxUZnRoZkNVseRIniVBgIVVDXAHxxTXVbd6eedBywhtN3bu9N/KHk/96Y4W16eTtaFVZwasqiUpAgpU0mPIrrFg+6XAfYLuldkdtPQaJpaziJSZy/PPbWzVKtUju87T13X9d3Tp+86wNJRs1tNJyQkl08qeB2Nl4MohwLQAArSNE0xDoMFxVpDX28sgBN3lACC0OtBFQ+Kd42C0uBRRFFoJpvDZmN3u3F+SXqEAhlQA3vA9Omt1VoHYKB2iKVhhsWwdQuF9KipptRUR0w1VehEb2N9ZNKJYWmKom0DEzIFRSRYjrEa8QQoBCqqisIkXPOSqLv5+bkHrKJQTub5Xf7J7nLSOl3F6cj6pgiofaXSRCOhIdRURE2tGy66nkGM7h05UIFCB8SRtitx1lkivvo7NxSwvwM2w4wGZhf/wa9+9e9NALO+wbCm15EnwL9ytx0v8yXsgYIaa0xtMcZiMVjAYsLpKsJjeizqsH08fRUBaERBIUBUhEYUlcYqqtBO7jdtG0OcX+ZjwBxx+HFZ1Qnk7JEUjAOLc9SABWcdWMve6WbeGV2gSNSkIIaFdGqq8qCTnr3jJpVSg9Hh3EIoTTVNPIrSiEqDqlcbhiFrZszvhx5A6VV7Ps/vuN3lk9alaQyNaYzzRlKpVKUsaKiiENTIMdOX/eCYRaD2F40jzaTB4Li72/zOhmZP9W653DZAw2x19v33//6vQqBcg+UlI+aTEPIEnjwab3m6zKECU1Bga2NqizEW56wTA5ZNW1VVP0CNx2bE9KoAqogCSoCoII2oIAGoCr5u2mf3LVo3gSXPB1UCkBkIu78QVlR5sd+T1impARwW289gwTp894fPvrlgQRoRVAJFBkcWjqoj9piOVTIXqqYaGHeJiKaVZlGPNoh6RdWrhJOQNbvhfDjHgLf9gPPj2eXpZc6kdSmxFCoG0WbRtJSmEiWKGpAHe/i1zUwQJela0Rs9+qx92VYNxMkl7AFD3+ikhXVKD+uG8PZ8EpLC7MlgOb7OlwQl+21RFbUxqbOmttYZ63BgKaDtmnpVgeuRoEHLYJCjCAEG1CMIAaKINIJHaVA8qBAsrm7A1k1rgTjPc8cIX4K2ITXkMfvKpqu6sMY6LAZwOGpwFrj68anD2+e2J+a2mzWEFCEKOYKaxooaTLU17IP0nrCqKKbWiZiGYlRkKo02zbIQURuI4gX1NC6ce4Wwm0zqi2jOxkIIZNDe7PJszGoyYW801MLUqdayEHOfJZooQillmBpMFKYabGlbpKejRu0XGocl1pLD2aZJv/sm6ILaRNEgfzsOjDFNoM1otNk8PK1JACZtCx7K0TwMmzn46Jff7AYs7ickZ2eXd/YaLoAIKDDgHGAdTTgxMVaAUZOY2FDTq4EYoAE86mEEjHDSiIAnA5icv2wzKjabdAxaVThoDeCBhhqbgo3yPGGGkmMBA1Zw1GBPv70+eXl+drZy9f5kdXGX8/MT88VGM4xATVqPY9ZEekz2yNZop6WWWYxXOpMZphCzNNo0a6UiGiDaiKh4Gt9O5hOAZx0fLiIIGGKnQ3ont8ntFxGEbcUs6IZAerdeEqLNRCpBoxAm5ch0UrZt69iVhRDbxmHp6tIjFMAvx5sAMlgu31bAPq/X3c1f93f/zu/8LZa7RJnMbwALFJBbXs490dP/icXjFqjPztjd3XH3Cy4sOWopwIBzGGhapanB1VVBf1XwWQUNPYHSACMgQMCrNACT8/Mua2HzOdmTwVipaNoMrah8mWXUxa6ArqGK7mYzbshfmAq8AWcBS/3i5M7JybxqnFw9faqsz5x4dgGhN0I6oUxqKsT41CfdMZs5bVEywGQ6GYRGm2atNKIBogGi4ht8OZ+EwLpr+PDLO+ByOMPBqzAAmMwP33WrkDDncsV8TrJbSlv21trcU9VEUAJVqLGHOTlubCtqqUabgoUn4yHQwODuhN7w/Oc3664FbefRyXreQX5Ujn368kcPDGCxTJKJOYeYE06uf3ExjqKkrqHGYQ04wAAOEMCBVcBDVkC7DvMIFCUYAQgqKooSjMLTqwkt5f3nm81s9qtBuqc8EAOThCxemYKgyesmaMHNVqtdeHr5dF9ha4AaC+5qWeagGZ6/aJfrdffF6ZdL01AQNRURRxbRyQnHq1brmoOSgWl3yoxQqWZZ1koaL4xAVAI8ZTmZA91L2P3y3R5wM3BjJ5tDCzBZuA/dKgxJ6zyP09GkSSwe7860qFZREkqgCvUgU001FRNkCgIN2qWuadqqAe7uglE2Uli+q8ARbl59dd9Vj/7N3/4Xstt59GwOF4OKGnAkwPqv/oq+g+uTOyacswY8F796nyTXg9jUYK0D24PBKKafoACCeIXzb8P8ya7wKId5Q5RYPIoSjJrDIZzQlu3i2y9Bxr9639Bu8mtoJ1lpxnGc1jRNUNTNBJTV7CwnpKq2icHYGoyD/bJgpTNDWHfOT1arkYZCUKQTBMpk38VJG5kw55DGYrTZn7ZhzXBYsVbmkUNQRfE+gIDyfNMNCdurMP5QYaiIaVHS99Hk2SIAXhYDYBT6Jq9czmixaNrjr3+2o5mpSgmaQJnSoybFRE3UttRkpGZqUGgXdVXpsnBaWIufTuclgw9LYHH+MCR6cXl2cvL+l/v1el0CZzsSS0hvw3z+D/4AHorq5OykGo9R4Pzx4tFnCXd330ABxIABLIZexwN6ywglm/5RF+y+3wLl7aCmbIkKGgjbdnMQFoTDm/tDBj7//jLYbPaPErhdLLD7eDuLmC+AIKDIoyjZRhGGCSezGZY9BWANiajSUEuPOtm2ZT7dMNOjppoCzfhUQmx7+oTF6c0bzza15BANIYaXGmp0WHBYsZZVRwLUiyfwBDA5v3p2M5zZZ7D8bLnNqnypoWsVx345nn4O8Ny9bupmVCrk5Ewtifbiq5+sdj1aSqqkhBTEkdEdXZPR2m9m1FKJa+roag6HA3CHW1J271YE4QHGy++/32q+3+YDupcXQAXER9Tz4/ntH/yAKBiS5Mn4/Xg23qKLP/n49SOovl8ue9RAAWAgBcI5RAl4PAJNQJstTg/B3YccsyZ3Hl+ul7SE4fRAu19Mub257yxxEJCjJXuTwJAMYL+9u4gMV2E4CtvBHdHriCgjxM9WgyiHOIZlZhHSFxFFE9k7f/nzzz9d0YSSHuMx3nBifO/rH39x+U9+vl3WbS4lNAynZ2y7NFlNkyNFvfjAN0JAeX4V3vzRjjkX6++XW5b7ZaIO8YGSy1bMlz0yKIq6ycpW9gms0sTy4g9/8tycSKVSSgoJRcaO343nFBUVa1zTahoB0wAzJrB6sVoBdjx7Em3Zpnm+jBzrmw8zsIDlyPnxsTz+gx/qQDFAPRi/f/3fjRnD3/FDfvFsvlwuX3/BQAED1DiAxZvJPPrwPpkUXiGgCbKSdtQd5F1VQY0DZQ6LNgxHLbTT6eP7DmwynnZ8xDij9+lng8kpRRG8nFxHyfYOuhaSJ7DKK3JyVut51lRQmggVxfmffuv/eYWBEkrOWSOTgj0mlD/9MH9+fTnnkNai1NTUYOxtq6mkuUqOtAGNDxrfeEaT8iqcDHcruNiRb9nu9pdQiUu1DNoBg9X8S+Ben4qjZlJO5CzPUmny4tc/ea5ZJEqLUqIkUCPRo0dPN9VUk6OrokjquqRN0wIMMEiB3TtyCPIng3HcU+V5VbO+eb2irxzRMj9+tvnhJ10xalwPDC6+2A5mgwEPv74lYYny7z6KAUuR18bQsHl5ANK370OLgSYosyllEDBqq7wq6hpr8IxOR2EYEtAyffN40QLVZXPrP8rR0WoCcV0wZZXPdru1A6rVEwoq4j37wzxfri0NTVEhRrz7/779xW9CQxmoaf8r95dNI4NuqzDd/Hw5mw+t1vOaWUmhmTAYVKUJ1zjarB5FByEHWq6uNsDsfEr65I7dPt4msTGeNIW9SFgO9MPo9Jyp5GmAAc69jS82rHnx61e3q24WkQUaJQWLh9qNViZEacdVtLos40BssJi4sdYtBwGqYT7Yqc7S3Sw3eVrTvXoXmT5qFUHxhN3NYvrmzw7BAgFQjGfj18vLyz1wVQLzlioGD6vPXs9oboazFUEbrMa3jiVwy6GDBii3MANmwGQ9n5cQenj+7M0tChSWQD8urILFgDdxlRdpvKVMB7NZDlSQXrq/XD1nhYYEFqjlR3/6+i8ZSw81xbs/d3P5m9fGm/M9LLx7d9cxL+t5CTMVDIxpP7S4pq1rehwdHRs2h+nV1e2QaBdMEsbvZ7O42u9tCmBMbWuxRsPozF2NOrpuBQ52LKbjzVsb1l98++pWUpqFhWpEFaSQQY/0bmrdcCrLfkhZUm1Tq4+2cR5DDVQ5bQyHhiSK49nexNZaJTt+GnN0AyoQhM+mi+lPXg1ZXazwCzZrIDi7/NlvnZ0w2QwpgfE4xk+7rng9Y8i7DymMlOnPby9ZtsfHuPWOHYR2w7Y74W4HzOdzRoCfdj+8GdLnN96C8Yp1pEU+hmA1Hnxgh2ZxYeP+4rnnsLbYRkNg9+aPzr5hs0U1o+t3333WHv1kt0XbcoVCQZdaLet5iSiYMafdUVStlbQrPY5F1w2zw+nm6vb8ykK0uiT/D1+M2e/ZY3rASGHjxhrH5cno/iHrv45Vt/7AxXgx/fzs8zOL05evVqtuSWmmmWgDKTVVoCYUpu7oaUY2asFKtGlz+PJXr3+DfbwHPLADYsBCstsTV3Vdp5ayG9f9xAMNgA9k8cPi8PtfY6+/+ZCw2Pjh9FUAZ5/+82cnRVm2ekpoYmi66biA3fjdaucBVw5/uIXN7THXCdDAeXcKAXckd9dUa/AhE128eS785rAGb7ABOMACrBiPX89WdRAx4/D8wmG31syzItq29ej+6MVvnG6eWZsy0ra8e3H15Toxem60bTmBZn3WDstSSsOFwdwgXFlJu9LjWI+T7uH9FZvDwyt658CnM3r3gMOBklJoIk0Kkkezh38PdLPdzfpkPF48utycbeazl16ttFKLm+102M1II0pQhYkywDSmRSgWWpZ2Vbz7OeLZrs9wKhApkEdg4gpTG+OEIbsalF4PHhrwIxY/nL76+rnl+ptvBlAyffWS0/Pt2T/3ny73EEwmp0PIbh4y+4zZsObDp6uWICCc/gk23z7m+lrW9O1OD5RAzt3ddhfNr8KQ825Kj7P72tN4afSjWcVirImhMGUQsGI+6gMMVrPXg6TAixemi9vnd2urw7ys15UFGk6/+urF9eXTy083zuZFTaHQHu/WjnyHl3dG33E1Mc/31/ctVAlzzHUZ6NDoEjmW5dHD4+Lqp5+EnHdzIBqPifiQlLcrTliSIFiweHBSpRqsrNu69WTS4ZeX4c+DfLXccube6pvnrClffXX15MlZm0mI5sh3Nw6rcHXCZrYd9IEiSA6j0Uarb398qYnzuDFGinLiyf+t2S7N98muSMFY74t0NLp6l9KjoKACvkE0aNtn5//f+Q9w/YtvtkQt5XS6fvg5q//4T7+HEdPpmyHDYTeEGbunDH/XDkEi5msOp3PgJE/6BPdrMiAgTWC3nncQAA7Gu+Qpvaes5wsgOKKGWQcI+zymYxzvy6w94AEDeIqz7XXEyRVvNpuf3d9z2Ny7vGeF4sVf/MPLzaXTTcfZb+4EC4LChA98eHztEU7nGzdPXV9frq6eXMrcxTRHLxgoqfLE8ujh8eurTz45D7ssABj/Yka7ixjOOn68PJDkFdQNGI9Ba1NIHHeOXTenDZcv/Fcvn97hFu2Pn9tZ617+8tv7J39wpmGlNA3vPtx82Nt9eXf12ZsXnv1uYyu4QvYOrKYcSePVtcmrfA+MgPnV+XfFXRTlFDiDrfeQzq/id1atdwINoKgQoJ6gOT189dXzY/jil99so5gsmM6nm246/OI90wZe3TN7/YHuvhsyq14MX82ZzQJYt0B8wvIiiih7WK+VyXodEjQwD+g3GI9Xg12Ep6RYw2HItCcAstVq9Xze9QyidHTI9nez+LA5aHgURRqd7ZbVilObO2/uvb08W91yxsZ7//+Pnv3kaTm9eYHVxS8uVvdcubTHHsE/gLVHNji9YXV/eX23XtksTUq4mBgzimoty6Pr1Q8/PT89v2oDei/fz7boim74fMjTUy5Z5nkq+0YtiNTOYGtWOolW65e0p9Xlen7/x8/dFur5q/uztfWeX3/35v4futDEYtbgw69PN5vLHe9vePHOP/MEuiMPtytzieIqTdPmSE5yhWkLCOd3I2APWEsNlPPN/t1KwQNqlQARVAgUH8jtz79af3uMPvrlN7tBjKWbTpner2HsmQGzVQTd9L5bVy9esP795/Sa5eXyydn5V6vPIlrAs6ZhfvtqOmL/WfItMzisd6uTwYycHb4M8PQfAXNgNGO2eTm8yfLxIGXUbYbxfrAknLSEcZ5MjucUAcnd5/er1fL0VHOmeJ37e+vTDW/evD+7/H/Z7extDjdf3z1/5bnnG2Z0TtfrsctHd492xlfz7fz6/n6dLJX0XDA2CBZd8vTpe1/x9feubiEAyC9/drFlXO34+fNXMFg++nb5MF8WqY1FLGpRS2pTnQM713EIww8631zc21zeunf2zdv1yoK//MYf3JpltixLrE+/+mxz/WiDm3a1cvX1j199s3Sd6Wpcyvrk8fWHo3AozaJpkrtcp3Q5JPkZJ3UEWtcAzlB267N3KywNVgVFEVXBIxrgR9z+A+2zb4+V5fffjMf7LXQLGLYwGAE7wAO+W8NqPBs+7BYHuH5yuTxbwek/Ob97lBCGfea3355mEP+HX9DM4BR2YyAGPNDAnDGUHVggmIFn+HLEHoXuuCSr8+0yBYqEycs382gOyVsEq7Mv71/g1tl9x+HNezenNod37+zZFa65vdtcuoSnp08v7vjltvX15eufvsaCuPPp59c2VjTmbY+hdHSxjk9+9c3tg8vDww9adF8Dy+0vl0vOTlZ1/X8cn/51f3TP9fXr2eoHzXe+FkeOWoXAO72fXPwsuYVDQMoetXr79sLZ/TfX1wrT48PqDGs7axv59dd3X17O9hb7qdJ93c6aLR7/wv/97Wl99v/ff/Xd9737drCxYD5KB/UupnV1XTdBmGtqCwRb29paH8bp68oigIAqHhGkEcF71YDw6+fn5+fPQs4uBu/HdysIwqBRevckxFlASQaMAMMlQVsNdnFtDN53v/eY/3BFZ6ZM18ePjyHi5CRhP8tTCxigBpQKS8goB99CCbHPQAx+1HbZgoqHVyShVqvZdk+Rw/zNOV2AWfoWLTl8+eh+w8ZzG5zy7enuADf7q9VZP7zcPdtx5XK+xfIZe+xPiMu3m0e3Grbc/aVnn1/XjqUxDJNL7M8VPY6f/vT65tXl4Ue/RXK3fh7mlx+WyyVnJyeFYfwd51/93z85/sn2d1+vDhyYAS+5wAHNzj59jZNgcU7vCKvdvd+9ur67njAb3U0Hh7Wd8++uvznMLEY7k+LDzeHs8cOnX/2/nzhef/fFp1/8xoMPPnzF9KVgefgImFXgAQc4+log3eeXyzimV1BEaIBGEPWIJ7At9z+enp8PX4Xo+P3bp7vxqqYJPFCTp0UKTQnaEs4Bm7/OAQxgPN5t3vxj8W+vmEx5c/74mOg6STScn9j9+DoG72oghraqcgM0wKhksoA4X2cj2Md1tm7PF3B6BQ4wcRLv8yTfn59PrgIl3WhYLWdvX6/uPT/H+dOfn37+O/Ycbt58uL3z8ubZEybjpx8+/PyGi20fUNzCyt3d2f/5+bMnz+3K1uXylslmIjiO45MnF5eHH/wWrK/C/PJuuVxydnKSAAhn/9LLnxwfdw+Hs9WBw3OOuUQuZskk2fP0actw9uHUMoF5e0HnqnH/J7+9vtsf6KwmDlubQzvw3m83azFjimEvth2/+YN3v/ru5sMPvvvi0+/9/INP375+/fgN3uDy0cNHnBEBGZACBrDgMJz8+l1VWbU9CggqiCqNiNLg8bRhd/rXnQ/PT88VfvVnZrtxVRUAqd8T25Te1kEZlGDyvOpRQPAomzf/zO63MdM3bz6fw6NH0ct5/jZJqSCgSKGwabweLfv5HsKwG0KertcZ9X4PWXN6WITnEwRbKGDJz9J2wiGD2NJHRq/PLszPH3vh8vNHGxZM3nz17uLRu/PfOQTnePkXP3y2RXcMExZ3Xl0/+18/fX1YLZy43G4wzAs00cOxWF8+/ODryeRqQhRdLpfb5SBJoIYAuP5njznu6A4cDmvOUI7vnkYJva+B/ffuELGO3jt1c/PtrxqeXP/2em08dlas2s67dn23W5a5VS1G92S/GLz5TW964IPf/vrN5z5/evzk8csvv/DdV++98vDAyV0F7QLo6G8AxadFu8BiegCv4EE86kWkkQYPrdye/tHL8Pz0FvjF69e7PM9rjUkLYixpDw5oAF/RV8GIxytsfu//XO3y6ZvpEK5/Fb2cXL5NCKgINE9tXed5OjodX+b09M5pmWdDUkan3QgXxeAp2+Hk/FWoUMRQEBIAGZBW01Y/RkN4tMKO3bwasP/aXTvcHF4ve++8efHdZwzMER5wgKWozJPLkxfj8WAM+NY2AUVtaotz4NVTW2uLgJHLqun2w3a6vn118c319bNlNmPV2fKLdn717uVPf/E/f/Zrdv/3n/YhP/Hmq49fczw9Pb5/8L5lQrg4/PQckA9/elcAI9b4HbMVkNJW+WVOHlcU7LE9gAAC+BjvgRHLNSFkrPFBN3p1CQrT7ObbbMXdLz6M09m+dtQUFEBZ7lnGmGVOUlW0uWktlUhFam76vi0XizfTxeL2c3C//vUsXSVUQJ1EuApS+hsAb1Rwlr4BPqN79b//33/58Yun4tUrv+/L38zTaXdivrx0tlod1n7uy8MytrXf2p6fnFzZenf6xXekOdCgPttsbqZTBKK4YD4nmnvAAQLoEUdagBpweYgCcQvGaBH5EvGNR+m1rLqPVu/zs/z9ajy+Y0ecjtoYTZ04BMRYRK0WWREUsBicsnt0d/eL3avNoWBFQmdZ3bq6/uwXv/jeF8SP/Xd++e3HX725ubo+unrwoPNwrQe+fD7tEH72YTns8MM17erFOGeMaamWeZ6T5+z3BYYCD3j6NzBy0AowHEIJw4ItlpCyY3X/VQd3v/71bhxXRcrIxADltHsxo7CwtJaktZZSaW2iugp0+LJcDDfT6e3jz3H8+t1FAjAmIWHPnn2fGYBRqwDWG4/SMCpZe/UP/l9/7imee/+tn366c+Ls7MXZ88szl6vDqv/8/Tf3Fkf2rRP9xPnelcePf6zMY5xXPG22eD6dLgBHOpIHWYXBR7KAsUgP9FHA83F+NwMHw3ACAoTAnjy5HI9X212ya9hXGXFgEWcEsYCC1oErA3+5+fG7zd03d79wvTl4f2q+v1ytO2bpBwyf+egL6scmP+8bLofr5dHT4p2bT+ajA4fT4avnQjSzXYcAhhXxeLDatnCR53kdV7nZx3tX01fxKJBB5gkxHcMfXjE4YUZLRRZy+vjV6m3Xrfju5M+cxHEV10xeFo9ilKvb17MYwLRWaa2qqlUUTSqZBgpTluVwseF087d/7pi9e3E3ebngiydxRVJD3EDn+LBKawrFKn09I2iCUTZ6z8XbS6+/xO3by7M42bz2+su6PHuxOqxW737/9lUWFLHF3glXC6f9/ePHp1QEE9iXwHQxvJl0cwdIFAErLB3h4SNYnI2rzMQWaFkefL9W9OP41wEL65Y5JgzDrGkazUkuGY9jdtF+DzvUQiEWaqWvNK60odmou2ebi19c2BzcPDaffHb7WlphUXjEEw4MvMYTR3kMGubz8MCh5fnXrwAHR0AB71/kHN4mOWP2cRWn+zTGCErjQRuaZpTRUqKs72+f8Orr2WxsAcvpj5/A9N2nq3cXV2fEVQxpF72Ogee3s5MYjIVlyZJkSaKlKrQiRQWeshwtFlxNP3/8GH5dR8yv4O3bJGIPFOuHOGY/W9Z7AwbAq+Kbpk/mMW9/evb2LRZnm/X7zfXt5dmZjU+t+PbnP71t6AuFiZN3ZsMTj52HZPcTT7WHEqbtfD05HzFYRhF7oGZ4060nnXhAFKwDqGO1cZFfbgFaoGHzKgTtZ9UYBxTBFk8DSAAjRtNuMgHyfZQWcQ2VK2N0Ve41tUVgrVpnnTSCaaWRbnLyzZP7+0dPdh8e1bJ+dr948+Ll62axMMITq7ab6dH2cWlUI4xG7WKzYH3/ySsI6G/pze/OqFrzgVnCgGS/36dxjEKZASEwZU0IZHT3y4YP8/kPfD8Gw+3zjF2y/A/zD24+SyrjTK0FaUV4/rB6MsNitSaqqpQkdCqtT0qqlVTjpSmb+ehqOH3+9x1Y3u3L6T5riwFP706A9bM5ETx9EUXU9HewrjMyRqNm3978ftt8/vkaq9Xh9um9J5vbeU5FNadf3X++Wr27+tAPt6sFC06/3mubFfbnGV1w6O4pEpASXEi4hqQo2DeAokFQtuF6AkyZTgBLfx1H4/1FggVGzL992YKDmYNVvstpYWItSgMCKFmmtxOKtsKQUgABw523K4mlKmNRLLaxLtAAcZthFLm/v392fbpZlrapxfz66uWHT5cqxz4Wxc2R+fjOt7iKxqJRmrZdnHesn339iqAAr1YtmHiXhpOqYj6LxoPlgN0+3sf7mFEJE0CHwJrOdRBws+MGQuANzC6Hr4a73dMPAI9hEFhjYJQShqe31dszrLO2xlW1oAwXLUpHYQtV9RlhtmH46g9+PGD2ZVYURVwxuf7dHTy7fRZtt231YrdDujV+NSOGuQMaAsqbN1dPXW6dc3iG68v7jVlEs//VL1YrX/zS8yur57fLuhuefv3S4fBodjJiFEyG826eJBPdsC9gDuACisaCa2iKFkpgxHR4P2TabzZUoL6+vnAR89Hxs64F3Oz9OGDHKqdvEBt6takbl8EonNC2bRmkaQElAs6Ls/tI88bgvBMDxgNrJYL72+uN3dwsZV767esPSnfuvGPiady+HYN4PD795Ic+fP2Tr7iKEk9jSzZhd0/26uthENGUGaokkW/DhiNPBp8tT/Z79jEQktVrSIdTatbDxRQcM27Wa7IOCuCah7P3H7r1MuTm8z/cUhhTWFLC0/Nw8PZ/xDprcZCkqiVJVbEQtMrEBBrVhtHIDqfDm7/rx0ND3+LpU16OP8yGp8+ind9XjO9gMYSG2TgBLKDA+g1P377l3Nnq9tG3rq/vZvPSk0wL775Z+eK7m//tws3Vi5PZifnRZj6xf/z1F4eLR7MlKEu6YZMwydqWWU8IdhQQGGt909QOMBAC08lwyjGQDd+9c8PpfE70yHbMg26OgbMPL8akQAokQFHEOIq6CWiUDIF50E43a0hNSxmCrATZq5NYnRhxTqy3c3HzURRxf+9+s9ucNswWK6sntUyc/+j8auz//PL15eN5OUyH6+O7b77+qZ98/vFbR0IFr1Cuh113zqtXt9MASw94HtTw6LO3+z0V4FsIJyHp/ZQMOJ9CzYyMjob+D2e/y44PhJxuBp8NMKkDmH8V5k9en4HBOiy0JFWVKolCUUFVBtoojEYNw+nx5k/9WJZkAPvomhA6z/Wu2JCfRcwn9MBltKMAAije+D/+ws/+l8unWX95ud5xuL7bsFhSFu32i29c/dHLnz6ZsT29OT85OfH809nk5ubb0/kuKiCDDpgILQKEt2FezydrTAEldryHDkiBkCkbYNStPtQw/PLL+XV03BEA5uzu7WAFMWDp/zQjLuqi8AFNEDRktJSEHFrYzNdk0MxtOQsvNrtYJQ4sKi5o6lErPuXkiduL21q9O2+K3kSLpi5+e7I3vL19hQSNa+L69M0nT69+/u1rBwW8pxmVw+ntmsnx4zdkQIDy4Jbis08vdtRACcPnz0/zhG11Pwmz1qvFPUPon8P44nV1/3D/XZUz1e+ulYIaITv3u88ucqyxOAu4FFVVqoqkxHiZtNYoqqriR215NXw1/WGz4BZQ0r3xGlhDHBXlKM0JAgxKg8m3VQzMiZLDV198+rsXVr+7vt7M85vfrXeH3ipVJWvuf/XIn398/bPdYHhie7Vfreatvj0//+KxGe/jmBJtoKFBaWja0zBbQwNkgJ2teLiGLXcE8zkNUEIaG9hM77vkcNpzcjbbjiOg4gEnT8nmusprRowIPE1L1oUwgszfrOdNW7VMXeauTs7WcZqlinWjdJSyuU1T7txePF+vVsgcc2g01dZGL9e3ikVIUw4eP3r3zasP3ubowhM8nmZUDqeT+VoX08fPOsj4qBYGf/w02o1gonQP/2wIxfZRRTgfCSiA7RetnjAb5MCANtqNp08qEoyxMUz2318kFofDgsMWVZgwwSSDCoF6URpV8aN2OBxO54vPN/fMUSwF6jHeWHoDDAQF4NljgYxqdcaT1dXtp9fXd7u8c7ewWKoqteDdm927r+5/dm17RNszGd5MJ5yfTxnf7QECFDwQGMKwpGdONglb9pfV4Ud24+uIeH48nwOO/grrEg4GuGBADQmQJxNomZPAqC2LvB6NAo8pDCVZeBqOADe5oWKxT7l9deouKXIHBrxTO1TnUhJ3f39/a5iZOVVNSynFgl4WFJYQa3pyeff4eP14Pn1ydfIkwpMxKoOXk/kQFq8ePiTQjyF5/80FMZOrW54P50DB0/x8PgLlgZ++2w7GWHgXVLTP4V87I8FYS+8vLxKcxVp6LVNVMyymgtKVMgxVLyKNevwoWwyHk8Vic387nyuAVYvxOEAApb+lvwHe+u2X82F1u9vg3f2yWMyl2lI1vfv65f7u3aMnG8N041ukX23jRli2U/P6EvBIADUZBYTaB7rz87Ddr9IQ+FkFnuPj+WiU9vHeBPTdhsAOqBIqIhKYEKzp33SBDaaUpKtBBZ7J6XzYVgXHN4NqX27Kku7q9OxFmOY1YBgFyeZ2B0l+e/HcasBSVNNaSVnQtq22QdVCUhy8c5Xfe8P7tzloCaP1en3FlGD99f3U64NZoLj45ilNOD/2dD15QPUhj+Y0Hu0xRWLqd7un0QyUCdtNNl2tXv+6SgBDAdfXdwmANYB1gJaUJlEVCoWggQaVBmkIYLrgls3i5W1324UKWAprvNJ8fHdn939wv7LisPP1cr/uy6yqpWnbl7985+2jR3eFBT1d0NFNHXRB9jz+vjDgATzQABYIYP35eUh6siePIAKU9fx+3pDEZEFL7yqE5YD+MTmWHAhv43yHAaxn1AIjhtnsrsAAp1fnBDOGP12AXN+Vt93VYb/KoyyFrMiC8/Z6X/Dk9vKydaspbUlfVSUtoqKI5mQJVZZILVYPmz+Y8/R9gnh8E4TtYh7OS+Y3P/2BvtrPWDzJp5ftlP1wwRTD2WXAeLtYLFjQf3l2yUmSJEVF67ssmae717/1ZJmnk2GWzGbOYPeGAovB0T9hRIeUYkpQqAZRm4GH0mTZaB0u2kU3Xbw6HOit49z4eYAe4ZwgARTAkjHtj3f7Wd9tcnW+Olxpt9tVRRqPv3v89u3FZqcWw2KqqTCh09GwNuvT3WsFRMGqoPQXwq/ecL0b50WKEwSkQUftuiQhHWULoGJfL8IPVdonHrXlfk8ct+WoWuGkUOsNHsA7suF6cEcBZOHVmyB+F58wRaeMedO9Wt+pW7V7qtPL8+HqBD47uM1mtzFs5qpUQ6HFgzfQRmOxUoeZ/Hg8evIeweMb2vnkPCznzDdvHg8fwCpY1JzBBGhg/O7sDAt8vzkw4QBnXC63Z6QJiS3XsHr9yZz3b98tc24X5MPnsxfRcEgN4ACc60OV0cDEJCVQ4EUgC0blfh+QkbXhJuim3ejw08MBSHKTlUGDPcIabKBBz3gJg0/vLtjtHt2eXz3aPf6RR3+ykghf/YXP3v709aRJTSU99BjtTNDZwIfVVfcuBwVQ+ojDI+GrV5Pvn0YGEHoVtRrUo3Lvaxrf0lsFPN5vd5DC6PYGEsYx6a6o1aoDHKCAhWwzeZfOD/skj65+ODB7+pTxsOkYvpfF/fOru8s0Lwkuz6/21/PoM2F62LBCMy/ULJpFRZnUNHOGChyika6oMHl2m7zHCY0Z0dDOTxdr5vX08ZuXGTg8RxvAAGY8fnJ3wnYEtI82ZIA947I5gziCcN3Wd7uHwPjtKs+fd/nJuLkdfntRUVUUqAUcvTbVWpJQauzoClHRxjTT6XkWz6qYeETZLqYdCw6Hn76c4wCBPkUGHjAA42i8/4LB5+7YHZ61ZV7Nz//E5cq6aNNXf97bn74WZqhJmdQ0gk62hkFDV15bUECEvgpkX71K3l1E+D6CKoDHjOhryj4U7fRl+nSXwvzZdLuvBMgrwICtG+qGvgKUi6h4vKm2ryOuvh3u3zJghiycDIbaXV25rVZ4Prm7nkdfwGMudxtYbeZFqlVpS1dRqtIbHZnRUSihiyW64oEpOYF6hBEN7XyyXq9LppubV9OsnrWtt84/QDxbzWbvx7MTSIEM8EAKzOg7H7bV2VPGr5+9//fG+5zLdL/HfHN79apqr+sCLBZwYDGtBXoPpVGqaoSatmK8yqRFu/UwiNNBCrQspms23Bz/2JVQuzhPYsCWwbodNTiqqODFn9kyZv2IzcaurWYOK1lDmx/7xeHinsxQlNGJbKWXyZFe4byqjALeqlVAHaI3X/HpNWABj4pT1NLQK4DS38PinPcpPNuMP4ABLKBADOD79QZlyGPy1+M9w+f3vJsBiVpZvDA38ebqpcT1avwqjXz1flc+TszZnJk3j3ahWqsULZQScTJTBGGhTSXlRWlUUE8jokjgNeiybhrC4XA47FlMz4EAsMxmq8FqNq62l/u0oAD0CEP/8w2Y+Ok2bdfRbz06i5w1A1M7Z/iQLdbbbVqA4ug1oJBRMV6mI5gArx60KdsunISugh0QhFm7XiwWN8Al29UOMHRde3sgZsmeX4yTtGBjnpeWwyJJNYsyFxe/qZYUUWqqcvSkJjUxmWoCUAgO6Q4LKEBTN8DwJ5OLb3IABVEQQAEFaOhrszizIDqiMovH2w8FuCN6DahVEECtIrTdcfjLFw1a3n/Ltqwq4jwWPT/harvZfK7s/DqKGM+G00Tc5YrV+5tvEmmpVFIhHmo3MyocoolHpVHUo6KqqBB4sqyZhEzYHITpm+fHUADx7P04mjHb5XmVmxgw9PY4oGT6jzwbvB3nH7Z5eBpWj84irCmonTMYGz16dkxvQV8LkAE6OiZMY82CB0W9NEBGO5lsaEfk24SyzJgyBSoGmD7MS06JOePleDAQ0rRpDlpjKS2paqS0khQpCscZn2BC6FWCQ8qeljqnb3MT3Xx98YcRiBNAABUUPH0VnOcBbcMofTZ9ktegYHHiempQpB9qFWg25euKBr35saRlUxV34318pm6CG26Y/XWLKHq9lOE0EJdfmmHVZK1SVIwXbWt0zLUnMiUdJQ6xRAWvNAEo0gheoIQQyvj0sPELpi+/PGZ1VjEbz8bNjNm2yjE1BtOj1CAK5Zs3rxYxbJ9UeXg4sDyLEryhcBhroGDy7cUvBmU7K3osUPfkwYZFtoYeRfEQWGjjsGXIhss9rIEJYIAcCICU87M1sB6M6b05cbm3SJilqmmpSiVKihoZpqc/gKMEVx6uPC1ZfnmZVtD+3dxXf3yNAUTpVVAQ0B5PXzs6jZMCsTAKb8eDAnD0WrWAtYoTUKso/WvAeJrw23sObdXuZDxLscu76WCT3a+/s6yG9XA6zV0yWc3Wg6SpJlqIEoomTJbLInMjQqMaVVQ8Ogprg4oq4gVKIBQ4PZ6ymL788rhYXl4mszEJs9Uuh2CEqWNrVbHW2RoOX3/B+19V40fjMWwehssXUQLG1hhrnFgDSdJRXp2v7gZgndUausQwZEEJqqBBA6IoBHhAgYzyMNqP8UAIOMDSvwRijgxGV9N8eb4/uW9pErVoqZImFcMq6dEbk3Lktk01dePqBCgPm6wlC7m8uCg4/lMP+ZefzqOZRa2Kw9NXEEABj1WBw8v0SWoA/G28xQHixIFFLRSAAgLIEc5Z8NAcFoc1QBw6R55IPb9O6uF0tuq6CdOd3QfzOUvNbVlSpVQKBT0efNnfhEbrAVVRr11tTIMqqor4RlCCrDuEYXl++PElDN5tB4N6DDXQAJYZHtATMKdf/cPLn11eDu7GsbSLZ+HuxUUhrsZirANrgYufTlZc7p4vP80NqFWsxJHRe1CdQtBUUI+igFdBEUTRJmx3NQ3CCAsYwAN4UCwO1l3OzXS42NT2MEsiZRYpUVFFIeXhTvSoVQBxgvpMvb465P7dRfkH/w9//Luzz8sPqxiPYhUFBKVXBFDALob5qqCvYnzBRzUPpD3iAGMVwZVhq5N1OIu7MhmlaSxuaBImDVDuqNKJbZdUY3doLVGLjNTUqAeLnqDQaMCLqBBoJjUeD42ieGkEZRSetuHmnIcsTgNmjww/MGXL3QzGzOitP+F0erhl+bOzs3QfQ3nf7h5dJIJzUGCwWFdT82REEb1bHkKAWrE8eIcY7VAQxaMoqKg4D6AuoDF+hBQc2QDSxwIOXwZZyPVmd3ixrC0ilSaaRENR0DzsyajSXwBceEpwyMNXj//4347j7r7dnawUBFCrKL2C0l+E/g4EBwK4I8ThaqyCOEH6KIjD2oa+5Vjsy2fxDHUF7EiGExBIK4nCzB72qoWLlUSjEDRMxXLcHDfH7dihtqHQoIpHwQfaYPEqaAOqeOuhacMwPLApNnC/2QxrNlgYKBAxfrHdsX52zvmc7Xf/73dLLNDet9V/d5HgHMYacM7iahyQOoie/EFPDZa+VXWMDMarWkFBUFR6ALziQQDRUTmkSArTA9oDDYBlNO0YDJYD+7YELU2VJqmgKEFhYR89XfSQPUycgPbDAgqEi5v2ij98K5Adz6PXoFZBHAKg0M8DBvA8oEUtvQoGwPQDUBBBrVrAeUsDmIjdwwwocCmJS+0EYlwAslbKakl/tzPTLEJqqtRUU+tw3OwfhtqmMkWCiiqiIngCBQIUFVQVPGTQhpzSAfVmujAsWG829BnP6FY3N18CyfZf/P8HS4ghW2x4d5FAbbUALDhrcZa+80VICDVNTW9VoY7o+0UQKTrwFo9aVQEVAfBKrwcNz6eMBxFKf8EDIx0u26DeVzQcVqGllUpZVFCC9Da1zsJ+6aFHTx9ZdEDFAd54I0cQLsrp4v+aCaDnnDkQ+isgAEqvWqWvuH4PaNXSW9DfO0EBDyD0FVD1+dlk1FIzKhw+j1wyIksbVwaTuizYbg+u6rZFsxRVpsZUqocOA0XtB90QVFBFVMGr0KCoR0RoBBCvlEETtBArYEtGup7MLfDqEzBwtYKLP/wP34+L2mKh3MTXryMMhsLhrMNanAVcj3Fd1mCVmt4q4zWSZaFDOgpBQBEUBURBARVQgGx9el4tc2APpB6yLBixjTwGLNnPS2lSpUlUUGUqUQjigbtx5UHFCYC/ejzh7NPKA36Rx/Yoob9a76TnQdWC2gc5utZ+gtAbAIJaBcGpc+JsOhICUhoxttiPUhiZQDIzKgIeX/3M+eXZujchiupBEHTMnKBnkSAKAo2giopXQVTBo4KqAOLJPIADHAQjEhwwv7oiu+YYnl6YMdSFY0+7mUd3kTFgncM6qAFLX2fYvbv6JAEsgKvysMuoAgIo4gRVQBRE6KsesunDlhSwcZUyGpEmaVLQ10VpZVZFk1SgSgVHBIXpOPSBWtCjjpz+8Jjo0xf0EMZG6C+A9PQqWAU5wgk4xAngrAIWBZzgQEDpK+IEj1oVxYg6I2wXAW0Wm9xK40gBRrXHuYDuV5/yaE2TNOOhEHpMu+mAomRHAjxWhQaPCCpKI6ABqFUBGhTwRwhQzyOYJAhgAQvs6a2BxSb67DpqLM6BdVjAAbant45OAAvgeMA6Yr8ICgLiFJy3CgLQgAcQECxkxeHQro+IC2KTgj0C1jOREqlAZapAsRiWY0/0QI8CqMVCc1Tz+5O7QVIhKHiDVUAcggCCE3DCAypWrYJFLQ/uxNU0tYJVtdpHAQVQ0cIrzjUp0Iyu0lXsaqG/gniOi0/frlgjaYgSKt0w5cx0QG3LwkYERUA9eMGjeBEaPH1VABoeVOjf8+C1xcjmz+Oz6wjjsGoNYJ04C9YhzjqAJAEL4PiY94iMWEWcOBEEUOvpVbUeUPoqtCPAsccBBpA+xmuVdbRJowkyhYqa1GK8PPg0QC1qlR4aamig+YG3NSA4cXgjgBNFnOBArYIDEaw6xNFfnIATh1gFrDqHOItaFXoVbAN4QBDUoqJSi0Cyq5+tK+MN4ABP7evT+uzTJVW9WTTKFOmNLCPl/GxQlBQCIoAKqoKKgMejKKqC8wACMIEYA9gj5mtIWFH1S0cphEN+eR2DAVdgcVhw4ABnEQfE9VzUguNjXyxd72gCCtBPAAUB9CgBtQqgfJxVLiu0KKGUQoqSnpHykCcPUQE/r/fOKh9ZQMGiPKjQ3wk4EHDieFCxPKgKzoOC4DyCQ7AusKAFSR523oAi1EBjlXQ8zyUsGkXoYdmPlAfOeVIQJwqgII2oVRFFCABUsU0/19SbZ8x2eQ0OaqD98mZNvJu9vutJIYW4zH8rrwGHVQtY+vdYeq0yuwkAx29oNy4A2gMCCIACAqBYRQEEpa/gBMSJAwekIEqgjBSEkfK9lI8CSqB10WBBPwJCf32Q34Q9IkdY1Hp6G8BjFacUCmIIUutBxQIeB87zriualophIYUFykPMRhkHrKFWURBQhAYQRQGv3qIovYqFpsyAlakFhwV/+idf0rKafbpbkY5IR9mOLRUKWEshGAArOAfGg7NqsewBHB93jaAvC9b3A3EoDhQnoFYBob+CWgXBgTcIaryhbzIoo0GhYdkTKN9zeTDQLLaAWlB9IKsg9FWrvwmMBxziQHGAiEOcgCKoIgZFUAN4CgQQwaoVwIy4HHVaSQwzCOmL72VsOxwQJwqgTgRUUBRRwSkeFHwP4tTS34AFLQjm8/XN6L57+HdEXAzSEYYvqACLBcORBkdfI85ilZoiAsdveCwsioqTHkUAByIAwpGKOOFIRa1V1KJYsDjpKvSUoqaKMlwQKN+n8gCEJqa/WrWgYBuwAAqIEyegBm+88QaP+Tg+eswIgca2lXkgKnX6kmkwiJqDGRNz1jMPFEUoREQFh2hIWe4+XJyceXz64rtfn/IIT97ePbdQiGFRjDQUslC73Ul8b2O3dguhTofMbDIFOjoqZpw908/XM5SiECNBDKfnfMJV5iMesKee61Gjo5ttxEyYKUJZta3tdV1Yl8uYkzGnMZ3ZeC5jW9SodDOTYKElipAOJZhjg0EmXCzev3jsCzv3T2YrHTFeRxDDOHo3+54HHbrRzbRGTxD7QZwso2RnZg6uthvDoBDHCEwv5NTbyFTTPez3djwvZkwxrQ0yaSahMqMWJbNTHq6X2+sxJy7GGIFMGdgcO3kWhNp2KAuCormsjnY0SiAmMjPnBhdG3QyXx8SZYY+ayCQmZRiKxT4ydun7MLYdCh2KmNbONhCGZtS5HcWAp4clnUzHqHSLLlBenqGDY+wYOG7H7bjhuKfb5qKQaXcNtY2IGSq6g7DCuKwLhsu8wGB2Mxyez+jgGEZV1CgiAg3VmESNwmCui8wxapiYBpiMF4VydHPMxLA4mL53RIfdogPqZGyLmHROslPT/uy49nUMp9bTNVMj0Afl5Rvo3vnHjePGcTtx3GwHar/2l/1kJihB69xhdJg6mLYdc9YYfT6I3aIIhZCgBNpRZw+G3Wl0GK1JUVNNMpWjgzKaDAzLsL4fkL1tqbsGdW4mmeQEMqVGhEIcMSwf4TmrGJ7l3UR3UKhtnCwD5rANQoPhOc4diO4JocTpjhpq2J251LBfGIyWI9MHZRjdkeX7Pie21btte+IeM1OG6fEQysdjbPtstsXAgUyZi8yYhahtdqbMXOyPgTkM2z5PxLaGw3ZtJoVACTMzM2ZwQQczZgxTeroyLKajQhlddHJE+YHMKTu9HXtDx7Lbexp0pEeRztKJ0fJJssOZh9FMLKO2yYygo7lYF2cO5pxcMLiN50s2+y2ko2NNyRQEOtx1YtpOw6mmig7NtpkoUxE64sjyA5ydjg4ddo/R0dFR28zMzbqsy+KyuITejKZH9oseo+WTaqF2g0IIMsX+3EzTxJjmVG0999mp3SLoKDFDbMMM84SJmelkdIHygMHimOUHPu5a1PMYx4zx8olx7uQMiu7IXmZmmXHu3NmP7fBiZkNPEXQUsRtnzsydTGfHeHnAII4sH505A0Wfo/Sx8sk0exTjYBRRxpqZkSlTmJkz0/n1wkYHyjgYSths48zMzCkz08mxp5gox0166DFaPoqzowNFh96OG8fdlj6SHqPlE2x2lOG4VRHbIlNmZiaMcrHG3g2jLwhBjfZGoZkWQ42OnpBpO2AizJHQ02EZ9NBDTw/lozzQQQ27x809dqHHaPmEm83JonbjZBnowMScjNExhuHFjTN3UIgZ+8WwP901xuMhlo/BuHsxzjpu+USc88axs83m/M1d54tC7gmnzpwyGT0Vx3yQGnxs5g73Xj45Z48aHJuhEMxgMoox1Dj1QmeP7gzHzrCmzDMyDdjcsJex9DiyRj6G82zKJ+zsnTzcjqFDDXTYHbZj2J8vGNlDN44bSgfd5NKBDh29HTfo0jMonxBzDzXySTznoM6t0WF/DC/V7J1d5w73Wn6InfsbTg6n50sCea6mf/+dU7sd3TA6dk7O6eWas/Y71HD+9O/Nc87ZNU7M6WWcu9x5+vfuuYeTc3qZ517m5t/T527Tf/P/fx4eVlA4IEoZAAAQaACdASoAAoAAPlEmkEWjoiGTeSzQOAUEpu3rAvAHGrQkff7T8gPxm+a6y/4b8Tf2vpnS6d32cL/Nf7f+5e4789f8D++fvr9AH6Rf7z+ie1//l/sB7u/63/xPUP/Tf9j+7Pvf+lD/l+oz/l/+t6/fqW+gB5dHs1/2X/k/uV7T///7O3pB4sfJTGPzO/Qv3HkfRIPCvFn9jvFP5WagvsHzsYQHTSgr9L8tScr9msNB4bvc/s+/GJscjdVX5N+TeVBHRMdeEeYWm/J1zSPtRHNaaJHrTjSym9IRZ5DiU70aLzyqGqMxsoYxJMNWlSonzmT5AfAUwfln6h36ljbnDkRHZ7mga/BCduqllQsZSgivwTBuM2gix1eeLdfBIq3NGNDTioRPhf1EbNYRQ9nEOuKIE4D50d8tQZy7XdPbWvby/eme6/SEFQ1NjG7bu7tOVQEjsU38Ag1W0e+qEIWgs6pW6+cgPhFELrhd349g2WCBjuyMh3Jry3A6QbkMsuSloMhZjUMNAZKnmEEgzXFEo3LRCopr5sYGHZbfyUwj985Ekdwcsoe1XHy+9rPT4UNmYgfmqplVKilYTwskA2jEOBAzd2nksmrGknAUxA321UTDQJgDxiwIVGoXo7wSwk8aDRbXu9CrtbK+0ae0jsiQJBxieQYHE65ahGtXBfnwz6Ontxk9hh8bgUxU4tDLvuI+LgpLA024H7KZKy2e4gaAv0xtEFN8HMwlijqs9LcJnfYEo107d7w+K8i7w6dFNDVcE+ypHflFtF3H42w+YGJTP7jpKRnE/aZ7Pqwo7ieQv6W7ooBizazmGDMtaBanExpWwiyKrVVaLCWZEkY7fbrEEVyHIAh+X7/qScPqGLSQoQqhHwBxhhZoVRxu/fqLq39KHvAghbMe+GCappintuA57Ei6b5wg2RLsncvCDTdRJLC/X/hvR6fLzcstrDMOTII4L4fjr2/k1pefNm9vMZT2E5KUpY1da5jXjLxgpIDb4+iUvSuWfxjWmb947sxbvg4csC2PWYN3449AEqHkrU3MbP71kvnYMY1KmDrXOQxgnwpJb0RmMGdp+TJqmDhXe15RdFlFXIvsGv5ejXajdpPNjocLKkNyNDUOlyJgAP72QN//2xDxb9eHhn//9YE0fswjMMNIayzm5PlqXMVPygFHeOIkqWY6COuskcmb/RLjPaNLpAKt+hR3jiI57Cm5WtQIbplOnzZ81wgDjDtl5RBGU9kt/wOH32dJ9M57HKJntZusPuCEvxhdjrO+wtkNHMbb3lXo7Z8oeTC9wUj61mU+ODZHFwuZrA+dwb6whdJYf7V55XKPmw1rkfk2B7XSQ6bieQHsI5bA3cMz4W3g5iJLvYdoN38GHu5VInVi2wRoO3nk8wYUf2cbg7L5NMpjtogSmzzSj2b0w02+tY7RhMywK+6OEoulfnnYnRhEViDhUKv2LJdRHm45fltD3vkrGULcsOb8BYPYKcGMeLGm40tJj95RAEOhazyAaAyFbck/f/DlcsEvrt1wX0W1MwMMeTscQSBLmg5xS89XBowkfQpUlJJJ67LgA+HXAg8aZgm4yxhW5RuJenVaoa+QRzaVq7kXQdxPR/0iBsM1AOvY4zBjXHl2YCvii7WDtEXp59xT+Y7WbOMhgKqnzztjaIK5QICcmfvxCVrdyScmS4BsWu0DABAFvTefx/ya/y+G+eT+1cpnFYmJeq5gPvzHqfm+mBCoNMrYHcDguildT30e19XeJFg6iXp6WcnG3d3f0MfUQdr4j/iqQSWUYCErEpSkW3KJ94T1J2OPc/s3ElRz5gZIKN37nVrIEQ1gHKUg2XnLyXttU1os8alxJj9tWA47GlfpRADYiUcMbMi5ELfRyw4csm4e0teZF1/9Ad24u7Q9O0RfR/dyOeqtazafcTi1pzrE89tsJJjmD/zP63jLVrONStMMR5xma1g6IPXwFLQqkvSUoBEYk61wJM3F7rPELExMUr94ysF4LWWPWfZANkUHVL084ZeZiKeknZv0tb0SUNe6uKdwbx29Po9Da0QWyBbwJdmYs/BWNAr4WND/bU/+Yc3JHnZXZCQQxX5qhb5WEbNG0NXE2pCWD2yj18yOYA+ybhiVgPMTJtZpRTRPdNttezA4LMLZeOXBI781O6Z+999d2FL4rCHGXkxlkK1+ruLlg5u6+dIQk4El/yxGsRoMyHgMtjlmEOsbZ2YiT8FLYXGpzQJlFl/dAfyAfwgpBSO5HqdufPWIGF3KBhZQq9wBdaHBBQg9vVwmDGxGXJ8AEAeYm29eZGJqaMcZZHKy9v/H89IzHlPijkxbCtZCEyf8zVUXc6AEfJTZDoVNYH0+XGuA0sDYThuoAJ3tPJVxPTB9moZhmOOUnq7bm9LOSPJ5LGWHV/vP0HMKU5d2o7Ugt5/c52UoNkB1ZjWa8viilLe220iI5X+2QFAch2C/GNA9PFwhPEltCMGbXoTwguUIX6cSycsLt9HKW0ML4TCFAFpHriylL506q2P1Yn1eRPEpgL6PCdPeNFMnIwX3qTwiAWE1n6Wh5hUVfx0OoqjNQf399b0t+yKofLMetGnFqA9eHNB6ULrGcqyoNK1GTwGl23cZRJn7G6cFEmEI94GLTsC5Kgn1XQTjftOjDUkZWMmwHlEDh9o/9o4Dq5YfNQiMqYknv8H2kaV9uojczj4Ppmzr4WGplIU8MlsmYi/S6d2Q+MEnS8aFloHx+KfG9Ic9XQaFGjWt7uTz7ibhqgrW7pTyC8o+DQiHtVVjF532xceqXdDVp/vyBLDJdUSvUGwcmzAu0IU144vEjFlRSQ5Sc4ptqWFLZfuglhOcllY+1oskI29XNjBpFUYlcJhROUI4fgIdTUW1wnFvN2bdEcrmpNVzd63hL9H6Z98q5kVJlZDMtqujMDQL7wZ4DEr4yRl573NFEOO0SPQvz6qIriBR5UXcKB4em05gJdNfggLB6prK7AGTdP6zDQ3wYrrlT1GuYvPZ9JisBHPoZQZj+9L6KACNbkBvLmjWqRg/+aA1gJESbuN8LGMTqTCrL/90XeANlIeLLRal0MPXdoqD7Hm/f8gsSvPazKtchoBkBAa6sqVW+vLr2UgQmrv0H0R+CrFWm69OdZCVKFc94EcwDL/jwmyAQLlheHmszeRQn5Vs3TvtNJLGP9tmKfhaImtX8YRmjmnkgMO/z54egi4t4PrbO3vJH64ggcSlvwp/rY+huBeF3MtKcruMHkCYgMbH891JLy5ZjPknCp9sdu+4t1hdTqdoN3zUQRFC6w9E3z6gwhmkVct88NFnLAm62Cq3DVLve+7ctW+0WWiqw6tQV7rUtq84YktOwDePZ26Gad6xEe9Ygq7RY083+jtO8poyVPsNCEFg4UzEokt1e2m6zfMYZNsDE45fQVnOKKKYd94ONDIRs559bZw4QfgJb326LvboX7RuFy9mDnUd8YJOuGAtBklvQXssRdQjfMdXBR1SavCOp4f7SU2QO0eOpV+aPdLzrYihPKghVHj4Rc95YFO1EEzn63Sw5fXdkvEn7tUkWpUbazpyFmfj9yl/7LMykfZ0woL0xrjsuu3ltkcWVXGL+NgkoWYGpDyt83/qKhlJU6ZzPz5HEPXU/SjdHgQfi3Qh+CohkHibiySBoaIMjYJ5EosxqRJqGyOta0Hmui6o2aK2JFQe8SfDdMmMlSCrJqQG1gaJ+qgIWUbwS4Ny9//To3mBA0wgjhrrGE1WDEa/+B47KFSEMUFLbA4+S5PPfq9ZYsGKxCjYKYA82cGfYowHaiAcwKH4V+3+/O6iOQElPAnl+VjGxVf92++n7VVOUbwInd93QQUAh9vUbzJdpRTjeXzKtTN4avOkCaIYshhypEzzaIm8X8cVaCSfzzA/4smKgC2xTVzKDB5ogziuvwhRE2LuVV0lGQ1jK5MaKtTA3jxxs+bTSTZhx/vJhNVcPGMJDre78xMSCEhDKrcfVWiiZfkqxVqmNHhyoEq4BxoyIa7CrktgvjnZUtOe0Si7devvR4u4Be64FnMZeymnTRlk10CEXhWZezUrEnxSGOe2W8NWcjSiukVlINFnbgdeZKtfJhElKg0FRWzRrt5sAqM+abuW1OC+ujFIyCOvTOGc5i2FO2iy0syAfLLLXFSKOVtfjGAkcUpo9z7aXMKHUD5aNqO7fMmuXbMZCIVoeytbmDS9J65hHuBa8ifrpdkqp1CHtw+Z46LtpjIf6UPo7eEUAPTXtf/GyLeeVjv23vcNNFs0dcfG2uKTfCQmYzNw+vsrUDq9kEh78pLaz8cpkHXmi/bt4/3mchfJuhkHZEv6HWBPnqdl3haX8rWNGuTmGj/v5a7urwFvcUkfOcr2mYZafBtIpMmO6TxMR2DfDc455s1hz4gJVibhBNXemT9SSuZp4pLQlDbNd9NIQResczTvXUTOf8jOwppJcqmUyqRtSozuurdIEu/EDImgfrd0igj9DiGcq/ttTeiT3kFsANrJFBmkKtORmvrSTgnYvXcIzDRrPlYy+7pdOc3faooN1kUtEo44R2Gm383o4S1v1Eu2u9qjUtzNOtAaZhPIfaLu0IhJvThD6/J+AYwuBbJyB1Gel5NdW7fRrA4wV/Av5yv/y70QmLQmjIUVSDytHP+PhS31g6cB/T59xbRCImoZQP6oEezlEJVTVrkWv+Qg1Nt97A/7lSfkoRKSkpm6dqLgvk/rl0aalmdDUYq1vlMFqbw3ptb0KLp3WhoRWpZ9DKAaPWBtjoaVmeuvI4oLzpm0YdL9GNkEyNP3ce4bp8ZfGI0EMfss+IirrAghXoP7i7kfwCq2QbDBKIudM/S66WqbkeoI2Vaxu8eskttoNHcgIyarL3hBRvIr43vat+GOR1z0oBt7cc42cGvsxAMZVIssulMx7+mY0xeDUcc7xTdilFuFw9TH07AH3nyEbOo9fOeblG03HwK7fAhEU1nxDrQZbL7pq/9We3ctQwvYhG+AOw6mYQBCydYO7+e7iOOVvsozzdoPIM+477Tumok95ZSEVOv308W72k/GH6Qcz2yGzCWJU8vRtsUxqxA6fcAbJNJq4itCs5KnlzVoJdnWkdwCsnctFyivjxTOywUM7Pff44UJOJ8NMoIxoEHrN+e6nT23XfMdVm9H9MFWMPRGFXEQqM7ioWSH/XsMZPoylw23wNur8uO0ZbJRQc3PVI2L6OxM3gs2sAnL6fCFBXEcUEd88r4wCSeENGOPyFEnq3Z1j4V8zXFTfZNXqlwiSBLsxdjWyqTUvbKnOK/a3TFpxiXQ5crIN/gXj1aEsKIZ/RYAXtWmlfbdAIYH/SWjC27BuB9wEFJjz74ovAEffLQ+ZQcpSUGohmaskvpDGPNyXMYlXOlkIOiONWmCjk/pQiTWFC+5l1QsfsfWB9G5KfvQ3Vgx73Z626DMhhrLRxlkae558CWuqljIDGYmPjYN+D9EAMFqg/2t0M672YfDGstg57Qgz+JHfcgUC+EmC1KYHMerbMO9gFwB6evA45kfdgIytOzM2qSd8c9l8J6qyhhLTwpdspUyDgL+YwTCJoJe72nrES2mHJtPy5yrep2LIWOzERKliiw4bUxZEx20U7CFmKpyUk8sBNtTT5wGblTvCypG3t/zxBj2FPIE/fDpXbPSVDvRyLxKAtrVVbDWPbjBap5qu2C4+xETIkYmE02YSYsow62CM+W0rz1Yzg/deKueHLAZQ5xFoHzH1KxtB6LU8VIdvzls5TuW22hoavm1/bULFebTDhFKWBkcjulngugLVjNnZ/lCVBfQzP/xPMncRNFVf0Rmarq3VO0ZXnTXD5YbauA2YoLnktC7oZ643y9mT/1qBYqA9NFvvgTPmO1w1zleicgLDbeONy2tXzruHLayqbt+Kwi/6iBnm6xkVq0+T6F+ZbiaTw97Kw/k6yRbPp+Bp3kGxWgqs+tpBNtOGo12Bja0HZ3oGIU1Ktnxk6WNWTgO7q8t0I57xb5c9xH2uSjjKdpr2pDr2lK43p6ocb4wNPMIQwVN06DUBfexjKDhskAirr/smNZoz+StmDoZPAP8jYJj72vZ43pyk9kZfSrIZZuKWYoWTDiP1Qxh8LkZnhqYcJeoLBONfQ4nwobtXfoO41vhFMJmaj14lV2W95s4hKDubKKIG2XgNLovXrcPmE7eecuYr6egBn8TDbf+qIB2OoKm+syOnpPxsEbeZa6PdeRMg/6m0PqB7FaVwKfvEL2u/J9GoiUaHxhPLhFVAMHcLpm1JWwaOTkboxR6853bVggYZXlsfJm+Al7doOggbRbojUW0VkQ/Q9pr16BxrTFuxfKfKvrznR68P9TBml+E1n2hK+vfRfdeAQyR8wIqUpCSbNwaf0qynHrXhrm4cQ6n0ZVSEzc16LlmoOhNVtxVTtZ2MveNhlD3ozDPCCX1uNb6D7uxS1FFqdlLRveEusFrqO1a7nafCMFLNVI8fmKaa5pNy95A2rTNr4XOhV+Es2aImrpqiSrjK7C5m5M9ig2MA9BO9xs14UDQ7RF52VBn0eqb1MxlTI+j2LAldP2OvzXpSw9l45qA6RlCbHklSTjeYhGgiSRs7Aa77aWys1l0wyEw4usHZiF1zIF9tk7ccTsrxfVIW3E+pewU6luBetMY7CNFbZGgdDjNQ24f9KrzGnmMKaw0GscmUS7Ldodh64efAkK+QRPsQUWQj2EB5apk88Ld0+iDIJmGkTzIt8x88kWFD+z4PmfeZ3JwcjUmXGhsBiIyVb4qUsLnDcSton6HhIpdgkFPqxbYbMn++oomOERg4AYMng54pa5wsZEfNLGxI7spXvqGBvu7QODbFlXxv3t4CvUGWmwlwaGZ0wKQwEUY6aB9s9Tkm3+vUGJHb/o/zE4oJKeCmrADUB4f8WcuqPBM/5JwQY84zWoTl4HpY5Jd08xx9ObefbCUGVovrPRzY4p8zEj8FjfxQfa5+Ii+rhhO1fmvqpxqpgtJZMjvsprollXGrwLbCmr7v9nh56EsCc5xnOnv79XZBx1WHuvJNBUPvJ4mlKVKE0iJk+bcoOMxdDIjnpflgWICS3glUrmfswcNtvfsQT8O3PaIeVvQMtYkRkpDn6xSB/4/Cf3JdMIMvJPoVk629BJ5d4kSDR3pbYmHVrnPKwxDj8oblISUnF6YHUZoFIp0KB6c//dTOTVFvgSmMhf6RkBwal3po7JNsd1RM18OLwAeE7GWjpBskkxWWo38E44b79JgNfDhPC6EWy/luY+YhiKzDjJEx3JlQcco/9OXORDazuV4woSGc1ykLMd3D53LtlaastPg3WXAKAmalm9ss+A86NmykcLlBF7/uh5hUivEodBttIAlVsraSLtT840tvQxFHXjz8xJMfniNZl/S5OdxBoeRGGME9sqU7kCCqyxlU47tCSn8YXYevAVj3rr7w4eUh5/IzmglTW9AM5mnG8O89x0ZvqtNYO7ubtDF2KwMqUvfgOyveuNb2bL4gIWepdGJ7AEJLBC+ke/4h9zMxbBo6GoHvTzY6cSdSNVd1j4lkxOqWXYmv+Lom3QxudwF9GOdadDAa4gDZ+tWDD3HAPPm/shctUFdvZ5ZCZPWhd8MtnZb5OeizIJvNqhjEvGPz18b5NDslBuHTz4uZSz5AmcFqbOSU8VS5duxjIrJkkvHQu30oUl8vfuoXJ2FMXZ2mNlb/AIojQkJ1eONhwF5RPCJTYznMPa+PkyH4nDXLwmhb/W6UEFEb4Is2/twcFSeaMfVthxFUwsJCnOyIiVe1mhKaBmlT8QfaP7c8Q0RC5HLdiUCbvD+ygMR+br5q1chiBI2ixCsFC8D1+WPZO3P6rSU/agG+FKiaF7tOPV7/W9K42Mnhf7mBChTjI1ayAnx0I1ggyaXQYuRmMv8FxivCJUxwDX5UwuLxtcfX/j0AYC2HO/iwiv5R0CrZtU3iwIzFKPpJ3t2AHFJ4Zb2KiuZcHcrqwvybY425lEY0iDTnw/yTGG4vuXDiMsw7t9tTOJMXfVd8V/YHJcIDwNym8bWggboTNs5CZRN60FrRdL89cZl2At0L/xS2HqVL4q6IjobfW34292lbiUUHp0N972FrROwv3hPXxWV6YUiNB4M4XRkXTd+E108jsWMYY1jr19coKhheJLCNRmvzsySapzgX9/2taou5Cnid4pPZ3cJ5wd98vU8UVO+sK+PK8EswV5XtUX7fAz9GK5gv+em5XO3Q7hZZ7W82a7a4zCNIlnBxWcyj/Ce15ghm+ulozSPOdoniga0sGqYI+2l68IAk6CN2aSkHb4/YRYV2xmuTnzFWXdfGfeMm2UHkTD6uCGwmjwDaPvY8OTgZs0Y3/fnCKPYt+vChtp6Rs+gzmQxIVVEN4WKgdhATlwmrM+BJbmzbc8O57FJfg0hg3LFNxrpN9S7jEb4X1WNa7EeSfLryi0iKqD0SCCvbddUtEF+uaHTVOhzteTUHqti+MFBXEt1Wz0jOgnIbLEsd3LC7oogv/NwNoZStBIvLl3PDjJoYPSQG2w6Um7rOaFwAAv0Y1baCmtYaq02jQAAWW/6X9tO6WcEvpEX7wyb4uDhM9Y5oV8LIIgcyM0Gr5FKjKRgACSqp66QZyd18UElWV2fsn87o9+2Nd30bjpXbmWcQgsQNzAL5CbFSQylwAjAgA3OhJ0HqgAAAAAAAAAAAAA=";
13
13
  const noiseTextureUrl = "data:image/webp;base64,UklGRgwSAABXRUJQVlA4IAASAAAwjwCdASoAAQABPlEij0WjoaElo/CMeLAKCWltKoDEakinDLChYXM/vp1V/PuGaojxG/pNgDPVf/HmH/ev/lwPDP3HWA9/cz+cYhGGLIM7k+k6AubAi8fS2X3thc3/i5V5Lu6Fh5H7wm1s76asUseSl50PV7VM2G0YnHdmPG0cTbZSi0ekVDsrAgGI/Fe4A6cFfVKHVBnop8knXCJscEnNMCOqbZJWheqdcwLJK4IwYRh7tU0jJB1ASfT8PCyPjnzmjXrk+DGVM2lDaWLBZmoobYCtTCuVmsAe0ZhS4e3AL+yal7gcgy/n66gF82TjXLS3AM9dFFzMCzUexDonKPAR4SRKxpdLqxlc92tuvjYbVEaObjj9Dsut0yiJyMZnsKHaY0e3WHYGZrnAIKpyTxtkNIXJneVPYz9C2LPHDDQB2718NpJdzD8Xn7KWUBBpEA4oSfLWBCPbpGB6ybKZP5d1HHFc/dj481vhln+QJGXhgZ3sybavcU8EXXgnFcp7pIfWmYTnRJlmW+vhssZKkCB1fJ/BplSN99dZvnyOLGR5mPvqZWDwdXBp1SYdD9IcoRpOUHIXKM5mXtahKIR8U6/TAF8un9PU7ls9yIduZ8qdBOLgiWnU2hsi/QWZrErzRHYLoJULlzR0/pSlMZf3zPa4sRWViLp9Eabl/cIJrP08zlDm1/kuiDRLrJrBwFYpA687yWYgXC/cKoGvwh068dVSwMkLsBTyijLbefB6i47Ba6/wGtVJpZRrkRVpJblUDurLyOeQktqfgiIPNcSAD04qV71Ie2KD0snh7p3YzLkvYUHB0TU1g7IXc7Kuarr73DAzBvD2HKuIut+Vmn8s+OTHkXjdq2QUs5gTTFGPbmf5CD8RT5Ge6QIzycfym5Y1pLHQt5nhxACj0SG4rInOkgwmc0Ya0lb8hqNZvPZEw2iYN76FNwBhJQunFSUEG4vFAPsuHnq5W05rNIuFrrs5HGtBi2Aj5Vt1ENidqTeYVQizkS4+Bfp0B+4HBYT1yFi+cPgeLqPOxoCq7DJSyVbJhX75nE3T5MoFmW5c3D28uJMMEBfOns3qK+/9jjtamu/gzrpb9/10svlP9tCsjg/twlIy9aD0F8vXhZsP6750IAzUL5fmE23DeLnK4QrnUaiHQrhIaQ2EpNmimD72EeoOn1vhDYP5VQIwYumfP2878d76QHqRp0E4SdqIxioX75QCWHqqnV8FsYfuuo4zGVbkGvdUFd64wC33bFwZvIyU1i0NAiobwJLRrM0JTSnZc7CpXUyvi5xJteFciIrs/jKp9uOzDstjqAVH8d64C3o4F6ljs3P1Po0Cm0qv69MiJd78YFJrPYz73fPY8vBDZijKCBO06d9QbaAhpC/ZsxzcNXgSuhYBLHtMHCv/rndNDmCdefEpdbKfzBDmwaaiDhZrKGyfafaNFj+emNzyBUgrO8OmZkg1LBSov+oRmJX8QcYIofriOzS1lP80J/rFbXYByGKGs0HzW69HFdLJu7125asXWSePSZJ4DUZaefzZXEBark6YQAD+82yD7qA8+NLSkrHAU8GOeWvSttZJXiDl++MUPBzt7q7robk10d1spP6FRB6W8xois2NJCpuu4UdAjKVfnkLHwJBid/7GmhUF14l2eXGNPNdA7TGiT4M72T6J42PrrP3y8vtqMMv1v4Re73IkPUvUAsGXhJjFciTcTrVCWfaXi5RUuE8AU2LXZsrcfpt678KSc8V4Xab58lddNzvMKPWgLxvwN5ZL/25jnLtwDH4r7HV2rPraGmup6XPpX0rX/YpRj2pvPZqK9c0dArBQUeHGpS+TfCJlIgQxBzJNCFBqbe8KiV3N26iJe7KfQ0CvAfmmZEF1IpBiNaK4FSDsNG8jbDtaRT3+JPLit1eK0KFnnD+L61GuVJN36QeAoddaMHcxPanY9GqGvUq7wZHZB0V6hJLqmiJcZamD80ZdWwu1uwE7B838K3ylOQ6uSWmzzHg1unzS40z4fJVNSgLK21jU0rzTvoXn+G2Eu0FVEE5QI0KG9FvN/sXjlJNAw4V5viy9yF9hlPWtuSUUIyDADQKjm5paM5XThyjkRMd9k9JuEwv7J5iy1onxZ8VwxutdmyUJ5OImNsi9F5HI351x95OpEXF0kb3eT6dEI0icp/4iuMBLWQZyVDBOLIiEjwef3w/ok88w2KMKMJ0oSAemrJT3tFsoRgPe6H946RyDgHRvb9EllzfktGFzbJFYielWH/7EvCOrW6KqtbJzw7vKXzkJEYP3JXI+FtCtRXLMN4m5Zu8KbwgZgWhuxDeRnWZ1SqSmkhPoJle8ybMGBw1cdb3Z5jSN+60jBaJ2qc0J0PMekaLmJF4Okb3QfSSFo0sDwpK1kb79PXrInvZr9hrtDcbqZwsPzfhZZZ510CV4uH0Kozd9zo+MgPdfuXQHwbIdJKwtWPeli2LhvZJlfKpyYfaCtnudslo6mBP8CLTGZNmHXlJzbXSxLhYos6vT65IW+TtgOkbPacDgWoJU/Firvlsk3wtyI3twsdCMUXwKLbaPE6uSUznEMpID/IhxVRioGtEjCBLVTO4EpIXePeRC2tB6tGwKP2MAD+9yb/HZ+WtfuWAk33qwwVeAv6ibKzzhU51TBbtXoX87E5v23piL6z53PRF0TNLsW0OlRivwdN6CXE0pXVNZrYwhVwEEhAOj+YS7a0zt1yixeUrPyB+t+OaFKPpTYhIC2zR/t2/k+UvvYAavQ9ngvosyDivyk0mHGkQymJNR54aeUGzB1NdTJBVe0jAgwNk3PyzqT4IA8KyRb09M30LK04j/+PTyZZsBZ4sUMd2IOv/PezUcfobMWwscZQrn9i3/xh5JyItfJM6q7dYs3v1ywDpt30Or16Zg6aGdxH9/kwJlo8HAssmZ9prlJnWEXzlR/dHfF2g2qjNBaYqLltZhONP3+piPsrMc6vxR+oSLWI7ghg7f21hBkgJGgaA8LoPUpAkY/DfyOfAzQCkPpm7KQXu4Z0liXHG/Ba7q1Lku/6z8P7I9qbpqOMIOKi0a/PtSUJzH+A+HUbB8Av9Hcz0QtOPBztAnSZFVU898UFZQNoy24QzDWbqYYHdfzikTFmcm8Y/RUTHe+BFx26ZKZU4Y8tnJpdxIgRyOYeQvX/qNGuOJMTTk8Orft/gajkyLTuP5gPDz1C8sL2pB2n9ayJ2lR6kHqbQG95WBq/QCbVAPQVPxJj0QsNnHPu9c/vbB/TZBBnDl/FuaFjBceJM0Fd2cEU3iy4rVr559CdnRXUubGluY0jjqay5RzEj16Chv/rsnx5JayRviD/ggV8xLLy41f/HPSSU1wY5OpIlkG3DA1HF6F1Tu7Iu4FmUB/FMbFda0U8+pUAXT0TJ6HiBc2GuDaicYmkbxeW5vQKkHn60xTxsBhADDlYlZPufzGhC6zbml1d2mACbZDAUk2Xdh9Qfcnb2EBAK83I8HYxb3ZAh8oiu0BVYnJ97ppv00myKeQniHxSalBlQ9meX3V9d6ePXFDzmNwbGSjgfD5/+rK5hkZUMAwbnIdum+VFiIUXSxlip7b6KhEHFxM524/GIqwENgm7LnhrudeJ4joNdYwYl6dNKxNNP9oOa9M6xVuZ/ygvSJ9KoH3wk89ShIFEzRJIY0BtKjiGSjE1oXJxder3AuyrdQsw1ah84Y4MojRLO95wiXm2mW9jI7YBmsaf39w6R0K1qrfiRT0Q208eNVCZ7KEgtL+/N1/pD8t5Za2x9YZSLV2f46cwx+UCmhkDAU6gFjPZ8JIFnNKulZTglSb7ww1qkUZyYI6oAUy+1n+W09/15CD6MrE6HH4wapcViywiXiCRmxTREX51G6AZrGt5yBTIVxGJk97EyYeAXx4fnMSztUTSDOtybw3mTpOxpKk9Qi6go4yp8ADZdEde76aS/fZ4WnhQI9Ewq0HVIi0TU5ERpNZED7NcF9ckcNfotyTFYd+6RyTAhn2yKpyPNAorJOSYgv/HOnxFzAOUj2Autmn1qJ05Ydterf2W/neD7rN/WGUmbA2/aZrwmAHzktLNTQmEBf8N1iwK5J6xdh3uvSiZOCza54JUuavQt5PiqwUogF1O8pJBYAA5a4uIBSqVAYrgBXEvU6Df7wYbbJd6MsqbCzHCU3Wf4NoEDpUKSwa27vgbvuGogctV9LN2VN6icxfA8+yZo3oFEHC+tOenMLSRDOR7KJ76X7TzZmBh+mwmHzXXuWvclBftLRE+CNf2sL0hdPvu0Oc3zYAZ5bonPwMrEJSnhrfNrQ19piAa4LTvaRfSOrcPE1a18Gyo8gqR/mCUeFXw9tp+881HqQIuBWps267+QuXFw1mYhfC8Y8uRajSi3AYW9/Xrl+P3SplF2k1qH6ZWoL2Katy0BRZLtnKaBk69yGXJNkcGMQVuDWM54R0Yow6e5gnMPlcAeiEc15BMluSXVe7v6YZAAEv9YENr3UrvXRal7BVNw6bMQnprP/B7BVOSThRZ9fB4Iaa5mCsc1JZZmREedhFsJKyJ6wsrl5atDYoLa3w4OFdR+Qe/wBZ8f3GnyZP7AoyTldJlmrA8eF/PVbBpZtZ0TaDDiGBED5lB/0cdjbFDGBTxDrCc3Isbm7hNpPyNzXKCl7ivDiRi6qvq40TS+V9d8bF93husZopD9UqcZ21q3aE/eEFdA9/YQNbt/q41wOU+a3gqGZ2jsD7TqvBYMkoUWaNN0MeXUXpNseWmSeX4f7NNwq7WqrHkzV2AvcZIQylGEI173GljgMJ/4GVy2Qw1iNhrOu6FxURJbANU8gJW3kOS0QFuQFqSybbx/2EyQlNSs2PqZrNcHROfTqkknVGnPaQWr959jFtcOt7u0okzKIn5TD5z1Sro+hwwX6KiJ8LoQDFUlt66/LNGIapTVkQEZZj/rVFrFyHj1PF2MuptF0a1gigAk1yIv8aFzd9zcJ5WSPbe20C/hejSwK3+ltgl+MuJTn4VMvJIoiDh0QejMa9F6ZRp5yI+0Wl76XgPNIv85aZ/M3getXU5aG7oDwyLY5qTPNv6t4yclynjqDjLlnjPkreANRkUR2wLPkYQaonSolW3jrnyrCU9NRC8U75AfBCOtc3GWPN4BObVLtOKZ75AnwHmE9eXF3intsv0NMd7JriLsz64SV6C1UvRZQfMLUsddmSfmUVicwjHVovOKyysvaEqL2dW1L0mrPR14f8jlePwfaBZWq/MAcbNfu7oNV0DjyoOro8ffoiyPsgAJWNFsvrg053ydIzmq7TLj7d3R3cd28BJjq6zck2hgeiPnZ/f6LTVbKKmAyPR8e4ergTcXcqCm2rPo1EIvS1nnSwpI9wr/36XWpKwimZO7bjJK1kTI4o17fiJuTCK8F/QMop6fCjpwOoK2nSz7VypQX5Bsp+GpEyFWMIUIpARuYTEgvNv/tSOBUK9aOmp+E3kQz0NKqyqpzeBm+4fNeSIIIpsdR6I0RwuQg9TJt8f6WMK5P9NemqBpGhqqnQr4oN2FXYSsCxmY9N7MU0Rbu9fIaKvIzeiv7kl41q/AACNn6JS6TgiXTpu6XKpH7KMiglNdwHQ6/MdJNSiPzf56XO9Slq/leUe45HinVW0OWdLlWPrizoUt0wifkNmAFt/5KBi7582NEX3ycr7C5RlLfod3O/FosQUEoJG6AOLQL9fil69AnCztJsid4YfI/7gV4gFzdSq2YMQ9RAdezxO90XK6UfCtnWHiy18hQ1UaYZxeBj7k5zbRcFbNvwGtK3NokwP6lBFcMfD43VcNJkRGpJ2Fm2wbPJrhGYdaD49LkubohNSu5F7xG9o0vMafuino6PbiH540e95x2Wal5cq+39HA0miAKi7RnLGFPfUpIgbnAlIHs1OALW89zOoIebvrZkkxSAylNlmkh+BcnJVHdu97VztHZ5YuKnVMfC1a2kRtc2+YBhgU03Ahu7JXP9esU35oJurLzssGXDf4DrHAlZtWWf2eE383nBBxMMcwlYDcWtE0K+82FQmC1GYjFB6zwLOz7CR4LC6pbcANlnuKP1G8/1N68gu5AyKGQYg8AvBZhJLuP+FtkTO0QYyaPA/VPTlFa3zcXvkc8HejGDKBtND0oN+pmseogsZcfDzgqBhuTdWtSedcLSsH7vI483XubQ+/w9kOvjYxAaXpDnwAAAAA=";
14
+ const START_FADE_FRACTION = 0.055;
15
+ const START_ALPHA_FULL_FRACTION = 0.22;
16
+ const LASER_VERTEX = `precision highp float;
17
+ attribute vec3 position;
18
+ attribute vec2 uv;
19
+ uniform mat4 worldViewProjection;
20
+ varying vec2 vUV;
21
+ void main() {
22
+ vUV = uv;
23
+ gl_Position = worldViewProjection * vec4(position, 1.0);
24
+ }`;
25
+ const LASER_FRAGMENT = `precision highp float;
26
+ varying vec2 vUV;
27
+ uniform sampler2D tex;
28
+ uniform vec3 tint;
29
+ uniform float uScale;
30
+ uniform float uOffset;
31
+ uniform float alphaFromRgb;
32
+ uniform float startFade;
33
+ uniform float startFull;
34
+ void main() {
35
+ vec4 sampleColor = texture2D(tex, vec2(vUV.x * uScale + uOffset, vUV.y));
36
+ float textureAlpha = mix(sampleColor.a, max(max(sampleColor.r, sampleColor.g), sampleColor.b), alphaFromRgb);
37
+ float startMask = smoothstep(startFade, startFull, vUV.x);
38
+ gl_FragColor = vec4(sampleColor.rgb * tint, textureAlpha * startMask);
39
+ }`;
40
+ let laserShadersRegistered = false;
41
+ function registerLaserShaders() {
42
+ if (laserShadersRegistered) return;
43
+ Effect.ShadersStore["vfxLaserBeamVertexShader"] = LASER_VERTEX;
44
+ Effect.ShadersStore["vfxLaserBeamFragmentShader"] = LASER_FRAGMENT;
45
+ laserShadersRegistered = true;
46
+ }
14
47
  function createBeamPlaneGeo(name, width, axis, scene) {
15
48
  const h = width / 2;
16
- const positions = axis === "x" ? [-h, 0, 0, h, 0, 0, h, 0, 1, -h, 0, 1] : [0, -h, 0, 0, h, 0, 0, h, 1, 0, -h, 1];
17
- const normals = axis === "x" ? [0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0] : [1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0];
18
- const uvs = [0, 0, 0, 1, 1, 1, 1, 0];
19
- const indices = [0, 1, 2, 0, 2, 3];
49
+ const positions = axis === "x" ? [
50
+ -h,
51
+ 0,
52
+ 0,
53
+ h,
54
+ 0,
55
+ 0,
56
+ -h,
57
+ 0,
58
+ START_FADE_FRACTION,
59
+ h,
60
+ 0,
61
+ START_FADE_FRACTION,
62
+ -h,
63
+ 0,
64
+ 1,
65
+ h,
66
+ 0,
67
+ 1
68
+ ] : [
69
+ 0,
70
+ -h,
71
+ 0,
72
+ 0,
73
+ h,
74
+ 0,
75
+ 0,
76
+ -h,
77
+ START_FADE_FRACTION,
78
+ 0,
79
+ h,
80
+ START_FADE_FRACTION,
81
+ 0,
82
+ -h,
83
+ 1,
84
+ 0,
85
+ h,
86
+ 1
87
+ ];
88
+ const normals = axis === "x" ? [0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0] : [1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0];
89
+ const uvs = [
90
+ 0,
91
+ 0,
92
+ 0,
93
+ 1,
94
+ START_FADE_FRACTION,
95
+ 0,
96
+ START_FADE_FRACTION,
97
+ 1,
98
+ 1,
99
+ 0,
100
+ 1,
101
+ 1
102
+ ];
103
+ const colors = [
104
+ 1,
105
+ 1,
106
+ 1,
107
+ 0,
108
+ 1,
109
+ 1,
110
+ 1,
111
+ 0,
112
+ 1,
113
+ 1,
114
+ 1,
115
+ 1,
116
+ 1,
117
+ 1,
118
+ 1,
119
+ 1,
120
+ 1,
121
+ 1,
122
+ 1,
123
+ 1,
124
+ 1,
125
+ 1,
126
+ 1,
127
+ 1
128
+ ];
129
+ const indices = [0, 1, 3, 0, 3, 2, 2, 3, 5, 2, 5, 4];
20
130
  const mesh = new Mesh(name, scene);
131
+ mesh.useVertexColors = true;
132
+ mesh.hasVertexAlpha = true;
21
133
  const vd = new VertexData();
22
134
  vd.positions = positions;
23
135
  vd.normals = normals;
24
136
  vd.uvs = uvs;
137
+ vd.colors = colors;
25
138
  vd.indices = indices;
139
+ vd.hasVertexAlpha = true;
26
140
  vd.applyToMesh(mesh);
27
141
  return mesh;
28
142
  }
@@ -48,27 +162,15 @@ function createLaserBeamEffectPackage(id, nameZh, core) {
48
162
  create({ scene, root, position, rotationY, params, inputs }) {
49
163
  root.position.copyFrom(position);
50
164
  root.rotation.y = rotationY;
165
+ registerLaserShaders();
51
166
  const { width, intensity } = params;
52
167
  const segLen = width * 5;
53
168
  const arcTex = new Texture(arcTextureUrl, scene);
54
169
  arcTex.wrapU = Texture.WRAP_ADDRESSMODE;
55
- const arcMat = new StandardMaterial("vfx_laser_arcMat", scene);
56
- arcMat.emissiveTexture = arcTex;
57
- arcMat.opacityTexture = arcTex;
58
- arcMat.emissiveColor = new Color3(0.45 * intensity, 0.62 * intensity, 1.35 * intensity);
59
- arcMat.disableLighting = true;
60
- arcMat.backFaceCulling = false;
61
- arcMat.alphaMode = Constants.ALPHA_ADD;
170
+ const arcMat = createLaserMaterial(scene, "vfx_laser_arcMat", arcTex, new Color3(0.45 * intensity, 0.62 * intensity, 1.35 * intensity), 0);
62
171
  const noiseTex = new Texture(noiseTextureUrl, scene);
63
172
  noiseTex.wrapU = Texture.WRAP_ADDRESSMODE;
64
- const noiseMat = new StandardMaterial("vfx_laser_noiseMat", scene);
65
- noiseMat.emissiveTexture = noiseTex;
66
- noiseMat.opacityTexture = noiseTex;
67
- noiseMat.opacityTexture.getAlphaFromRGB = true;
68
- noiseMat.emissiveColor = new Color3(0.2 * intensity, 0.35 * intensity, 0.9 * intensity);
69
- noiseMat.disableLighting = true;
70
- noiseMat.backFaceCulling = false;
71
- noiseMat.alphaMode = Constants.ALPHA_ADD;
173
+ const noiseMat = createLaserMaterial(scene, "vfx_laser_noiseMat", noiseTex, new Color3(0.2 * intensity, 0.35 * intensity, 0.9 * intensity), 1);
72
174
  const beamRoot = new TransformNode("vfx_laser_beamRoot", scene);
73
175
  beamRoot.parent = root;
74
176
  const planes = [];
@@ -85,27 +187,10 @@ function createLaserBeamEffectPackage(id, nameZh, core) {
85
187
  p.isPickable = false;
86
188
  planes.push(p);
87
189
  }
88
- const flareTex = makeFlareTexture(scene, "vfx_laser_flare");
89
- function makeFlare(name, size) {
90
- const f = CreatePlane(name, { size }, scene);
91
- f.billboardMode = Mesh.BILLBOARDMODE_ALL;
92
- const m = new StandardMaterial(name + "Mat", scene);
93
- m.emissiveTexture = flareTex;
94
- m.opacityTexture = flareTex;
95
- m.emissiveColor = new Color3(0.7, 0.85, 1.6);
96
- m.disableLighting = true;
97
- m.alphaMode = Constants.ALPHA_ADD;
98
- f.material = m;
99
- f.isPickable = false;
100
- f.parent = root;
101
- return f;
102
- }
103
- const muzzleFlare = makeFlare("vfx_laser_muzzle", width * 3.2);
104
- const hitFlare = makeFlare("vfx_laser_hit", width * 3.2);
105
- let time = 0;
190
+ let arcOffset = 0;
191
+ let noiseOffset = 0;
106
192
  const observer = scene.onBeforeRenderObservable.add(() => {
107
193
  const dt = Math.min(scene.getEngine().getDeltaTime() / 1e3, 0.05);
108
- time += dt;
109
194
  let dist = params.targetDistance;
110
195
  if (inputs?.aim) {
111
196
  const tgt = inputs.aim();
@@ -114,19 +199,12 @@ function createLaserBeamEffectPackage(id, nameZh, core) {
114
199
  }
115
200
  beamRoot.scaling.z = dist;
116
201
  const tiles = Math.max(1, dist / segLen);
117
- arcMat.emissiveTexture.uScale = tiles;
118
- arcMat.opacityTexture.uScale = tiles;
119
- arcMat.emissiveTexture.uOffset -= params.laserSpeed * dt;
120
- arcMat.opacityTexture.uOffset = arcMat.emissiveTexture.uOffset;
121
- noiseMat.emissiveTexture.uScale = tiles * 0.6;
122
- noiseMat.emissiveTexture.uOffset -= params.laserSpeed * 0.31 * dt;
123
- noiseMat.opacityTexture.uScale = tiles * 0.6;
124
- noiseMat.opacityTexture.uOffset = noiseMat.emissiveTexture.uOffset;
125
- const pulse = 1 + Math.sin(time * 24) * 0.18;
126
- muzzleFlare.position.set(0, 0, 0);
127
- muzzleFlare.scaling.setAll(pulse);
128
- hitFlare.position.set(0, 0, dist);
129
- hitFlare.scaling.setAll(pulse * 1.4);
202
+ arcOffset -= params.laserSpeed * dt;
203
+ noiseOffset -= params.laserSpeed * 0.31 * dt;
204
+ arcMat.setFloat("uScale", tiles);
205
+ arcMat.setFloat("uOffset", arcOffset);
206
+ noiseMat.setFloat("uScale", tiles * 0.6);
207
+ noiseMat.setFloat("uOffset", noiseOffset);
130
208
  });
131
209
  let disposed = false;
132
210
  let ltTimer = 0;
@@ -136,16 +214,11 @@ function createLaserBeamEffectPackage(id, nameZh, core) {
136
214
  if (ltTimer) window.clearTimeout(ltTimer);
137
215
  scene.onBeforeRenderObservable.remove(observer);
138
216
  for (const p of planes) p.dispose();
139
- muzzleFlare.material?.dispose();
140
- muzzleFlare.dispose();
141
- hitFlare.material?.dispose();
142
- hitFlare.dispose();
143
217
  beamRoot.dispose();
144
218
  arcMat.dispose();
145
219
  arcTex.dispose();
146
220
  noiseMat.dispose();
147
221
  noiseTex.dispose();
148
- flareTex.dispose();
149
222
  root.dispose();
150
223
  };
151
224
  ltTimer = scheduleLifetime(params, dispose);
@@ -153,6 +226,25 @@ function createLaserBeamEffectPackage(id, nameZh, core) {
153
226
  }
154
227
  };
155
228
  }
229
+ function createLaserMaterial(scene, name, texture, tint, alphaFromRgb) {
230
+ const material = new ShaderMaterial(name, scene, { vertex: "vfxLaserBeam", fragment: "vfxLaserBeam" }, {
231
+ attributes: ["position", "uv"],
232
+ uniforms: ["worldViewProjection", "tint", "uScale", "uOffset", "alphaFromRgb", "startFade", "startFull"],
233
+ samplers: ["tex"],
234
+ needAlphaBlending: true
235
+ });
236
+ material.setTexture("tex", texture);
237
+ material.setColor3("tint", tint);
238
+ material.setFloat("uScale", 1);
239
+ material.setFloat("uOffset", 0);
240
+ material.setFloat("alphaFromRgb", alphaFromRgb);
241
+ material.setFloat("startFade", START_FADE_FRACTION);
242
+ material.setFloat("startFull", START_ALPHA_FULL_FRACTION);
243
+ material.backFaceCulling = false;
244
+ material.disableDepthWrite = true;
245
+ material.alphaMode = Constants.ALPHA_ADD;
246
+ return material;
247
+ }
156
248
  const laserBeamEffectPackage = createLaserBeamEffectPackage("laser-beam", "激光束", {
157
249
  width: 0.55,
158
250
  intensity: 1,
@@ -9,7 +9,7 @@ import { Mesh } from "@babylonjs/core/Meshes/mesh";
9
9
  import { VertexData } from "@babylonjs/core/Meshes/mesh.vertexData";
10
10
  import { TransformNode } from "@babylonjs/core/Meshes/transformNode";
11
11
  import { V as VFX_RENDERING_GROUP_ID } from "../../chunks/rendering-CV3nhygX.js";
12
- import { s as scheduleLifetime } from "../../chunks/space-shared-BXV1hc0k.js";
12
+ import { s as scheduleLifetime } from "../../chunks/space-shared-xh5IOcLH.js";
13
13
  const id = "magnet-suction";
14
14
  const nameZh = "磁铁吸入线";
15
15
  const assets = [];
@@ -0,0 +1,25 @@
1
+ import { VfxColorValue, VfxEffectPackage, VfxParamValues } from '../../types';
2
+ interface MiningHitParams extends VfxParamValues {
3
+ flashCount: number;
4
+ flashSize: number;
5
+ flashLength: number;
6
+ flashBright: number;
7
+ flashColor: VfxColorValue;
8
+ height: number;
9
+ debrisCount: number;
10
+ debrisSize: number;
11
+ debrisRadius: number;
12
+ debrisSpeed: number;
13
+ debrisHorizontalSpeed: number;
14
+ debrisUpSpeed: number;
15
+ debrisDirectionX: number;
16
+ debrisDirectionY: number;
17
+ debrisDirectionZ: number;
18
+ debrisGravity: number;
19
+ debrisLifetime: number;
20
+ smokeCount: number;
21
+ smokeSize: number;
22
+ smokeRise: number;
23
+ }
24
+ export declare const miningHitEffectPackage: VfxEffectPackage<MiningHitParams>;
25
+ export {};
@@ -0,0 +1,232 @@
1
+ import { Mesh } from "@babylonjs/core/Meshes/mesh";
2
+ import { ParticleSystem } from "@babylonjs/core/Particles/particleSystem";
3
+ import { DynamicTexture } from "@babylonjs/core/Materials/Textures/dynamicTexture";
4
+ import { Color4 } from "@babylonjs/core/Maths/math.color";
5
+ import { Vector3, Matrix } from "@babylonjs/core/Maths/math.vector";
6
+ import { SceneLoader } from "@babylonjs/core/Loading/sceneLoader";
7
+ import "@babylonjs/loaders/glTF/2.0/glTFLoader";
8
+ import { F as FlyerPool, m as makeBurstPS } from "../../chunks/space-shared-xh5IOcLH.js";
9
+ import { s as smokeUrl, r as rockModelUrl } from "../../chunks/smoke22-B_WJKB0y.js";
10
+ const DEFAULT_PARAMS = {
11
+ flashCount: 14,
12
+ flashSize: 0.9,
13
+ flashLength: 0.9,
14
+ flashBright: 2.1,
15
+ flashColor: { r: 1, g: 0.9, b: 0.46 },
16
+ height: 0,
17
+ debrisCount: 12,
18
+ debrisSize: 0.32,
19
+ debrisRadius: 1.35,
20
+ debrisSpeed: 0.9,
21
+ debrisHorizontalSpeed: 0.95,
22
+ debrisUpSpeed: 0.85,
23
+ debrisDirectionX: 0,
24
+ debrisDirectionY: 0,
25
+ debrisDirectionZ: 0,
26
+ debrisGravity: 8,
27
+ debrisLifetime: 1.15,
28
+ smokeCount: 14,
29
+ smokeSize: 0.95,
30
+ smokeRise: 1.1
31
+ };
32
+ const flashTextureCache = /* @__PURE__ */ new WeakMap();
33
+ function getFlashTexture(scene) {
34
+ const cached = flashTextureCache.get(scene);
35
+ if (cached) return cached;
36
+ const glow = new DynamicTexture("vfx_mining_hit_glow", 128, scene, false);
37
+ glow.hasAlpha = true;
38
+ const ctx = glow.getContext();
39
+ ctx.clearRect(0, 0, 128, 128);
40
+ const gradient = ctx.createRadialGradient(64, 64, 0, 64, 64, 64);
41
+ gradient.addColorStop(0, "rgba(255,255,255,1)");
42
+ gradient.addColorStop(0.85, "rgba(255,255,255,0.9)");
43
+ gradient.addColorStop(1, "rgba(255,255,255,0)");
44
+ ctx.fillStyle = gradient;
45
+ ctx.beginPath();
46
+ ctx.arc(64, 64, 64, 0, Math.PI * 2);
47
+ ctx.fill();
48
+ glow.update();
49
+ flashTextureCache.set(scene, glow);
50
+ return glow;
51
+ }
52
+ const cachedRockTemplates = /* @__PURE__ */ new WeakMap();
53
+ function loadRockTemplates(scene) {
54
+ const existing = cachedRockTemplates.get(scene);
55
+ if (existing) return existing;
56
+ const isDataUri = rockModelUrl.startsWith("data:");
57
+ const lastSlash = isDataUri ? -1 : rockModelUrl.lastIndexOf("/");
58
+ const rootUrl = lastSlash >= 0 ? rockModelUrl.slice(0, lastSlash + 1) : "";
59
+ const fileName = lastSlash >= 0 ? rockModelUrl.slice(lastSlash + 1) : rockModelUrl;
60
+ const promise = SceneLoader.ImportMeshAsync("", rootUrl, fileName, scene, void 0, ".glb").then((res) => {
61
+ const templates = res.meshes.filter((mesh) => mesh instanceof Mesh && mesh.getTotalVertices() > 0);
62
+ for (const template of templates) {
63
+ template.setParent(null);
64
+ const center = template.getBoundingInfo().boundingBox.centerWorld.clone();
65
+ template.bakeTransformIntoVertices(Matrix.Translation(-center.x, -center.y, -center.z));
66
+ template.position.set(0, 0, 0);
67
+ template.setEnabled(false);
68
+ template.isPickable = false;
69
+ }
70
+ return templates;
71
+ }).catch((error) => {
72
+ cachedRockTemplates.delete(scene);
73
+ throw error;
74
+ });
75
+ cachedRockTemplates.set(scene, promise);
76
+ return promise;
77
+ }
78
+ function c4(color, multiplier = 1, alpha = 1) {
79
+ return new Color4(color.r * multiplier, color.g * multiplier, color.b * multiplier, alpha);
80
+ }
81
+ function averageScale(scale) {
82
+ return Math.max(1e-4, (Math.abs(scale.x) + Math.abs(scale.y) + Math.abs(scale.z)) / 3);
83
+ }
84
+ const miningHitEffectPackage = {
85
+ id: "mining-hit",
86
+ nameZh: "采矿受击",
87
+ placement: "world",
88
+ debugAnchor: "playerRight",
89
+ defaultParams: DEFAULT_PARAMS,
90
+ debugParams: [
91
+ { key: "flashCount", label: "闪光·数量", kind: "number", min: 0, max: 40, step: 1 },
92
+ { key: "flashSize", label: "闪光·尺寸", kind: "scale", min: 0.2, max: 3, step: 0.05 },
93
+ { key: "flashLength", label: "闪光·拉伸", kind: "scale", min: 0.2, max: 3, step: 0.05 },
94
+ { key: "flashBright", label: "闪光·亮度", kind: "number", min: 0.5, max: 5, step: 0.05 },
95
+ { key: "flashColor", label: "闪光·颜色", kind: "color" },
96
+ { key: "height", label: "高度", kind: "number", min: -2, max: 3, step: 0.05 },
97
+ { key: "debrisCount", label: "碎石·数量", kind: "number", min: 0, max: 30, step: 1 },
98
+ { key: "debrisSize", label: "碎石·大小", kind: "number", min: 0.1, max: 1, step: 0.01 },
99
+ { key: "debrisRadius", label: "碎石·范围", kind: "scale", min: 0.5, max: 5, step: 0.1 },
100
+ { key: "debrisSpeed", label: "碎石·整体速度", kind: "number", min: 0, max: 5, step: 0.05 },
101
+ { key: "debrisHorizontalSpeed", label: "碎石·横向速度", kind: "number", min: 0, max: 5, step: 0.05 },
102
+ { key: "debrisUpSpeed", label: "碎石·上抛速度", kind: "number", min: 0, max: 5, step: 0.05 },
103
+ { key: "debrisDirectionX", label: "碎石·方向 X", kind: "number", min: -1, max: 1, step: 0.01 },
104
+ { key: "debrisDirectionY", label: "碎石·方向 Y", kind: "number", min: -1, max: 1, step: 0.01 },
105
+ { key: "debrisDirectionZ", label: "碎石·方向 Z", kind: "number", min: -1, max: 1, step: 0.01 },
106
+ { key: "debrisGravity", label: "碎石·下落重力", kind: "number", min: 0, max: 20, step: 0.1 },
107
+ { key: "debrisLifetime", label: "碎石·可见时长", kind: "lifetime", min: 0.2, max: 4, step: 0.05 },
108
+ { key: "smokeCount", label: "烟雾·数量", kind: "number", min: 0, max: 40, step: 1 },
109
+ { key: "smokeSize", label: "烟雾·尺寸", kind: "scale", min: 0.2, max: 3, step: 0.05 },
110
+ { key: "smokeRise", label: "烟雾·上浮", kind: "number", min: 0, max: 4, step: 0.05 }
111
+ ],
112
+ create({ scene, root, position, params, scale }) {
113
+ root.position.copyFrom(position);
114
+ const spawnScale = averageScale(scale);
115
+ const origin = position.clone();
116
+ origin.y += params.height * spawnScale;
117
+ const flash = createFlashBurst(scene, origin, params, spawnScale);
118
+ const smoke = createSmokeBurst(scene, origin, params, spawnScale);
119
+ const debrisPool = new FlyerPool(scene);
120
+ let disposed = false;
121
+ const ready = (params.debrisCount > 0 ? loadRockTemplates(scene) : Promise.resolve([])).then((templates) => {
122
+ if (disposed || templates.length === 0) return;
123
+ const count = Math.round(params.debrisCount);
124
+ const radius = params.debrisRadius * spawnScale;
125
+ for (let i = 0; i < count; i += 1) {
126
+ const template = templates[Math.random() * templates.length | 0];
127
+ const debris = template.clone("vfx_mining_hit_debris", null, false);
128
+ if (!debris) continue;
129
+ debris.setEnabled(true);
130
+ debris.isPickable = false;
131
+ debris.normalizeToUnitCube();
132
+ debris.scaling.scaleInPlace(radius * params.debrisSize * (0.5 + Math.random() * 0.8));
133
+ debrisPool.spawn(debris, origin, makeDebrisVelocity(params, spawnScale), params.debrisGravity, params.debrisLifetime);
134
+ }
135
+ }).catch((error) => {
136
+ console.warn("[VFX] mining-hit load failed", error);
137
+ });
138
+ let elapsed = 0;
139
+ let flashStopped = false;
140
+ const observer = scene.onBeforeRenderObservable.add(() => {
141
+ elapsed += scene.getEngine().getDeltaTime();
142
+ if (!flashStopped && elapsed >= 180) {
143
+ flash.stop();
144
+ flashStopped = true;
145
+ }
146
+ });
147
+ const disposeDelay = Math.max(2200, params.debrisLifetime * 1e3 + 1e3);
148
+ const disposeTimer = window.setTimeout(() => disposeAll(), disposeDelay);
149
+ function disposeAll() {
150
+ if (disposed) return;
151
+ disposed = true;
152
+ window.clearTimeout(disposeTimer);
153
+ scene.onBeforeRenderObservable.remove(observer);
154
+ debrisPool.dispose();
155
+ flash.dispose(false);
156
+ smoke.dispose();
157
+ root.dispose();
158
+ }
159
+ return { root, ready, dispose() {
160
+ disposeAll();
161
+ } };
162
+ }
163
+ };
164
+ function createFlashBurst(scene, origin, params, spawnScale) {
165
+ const flash = new ParticleSystem("vfx_mining_hit_flash", 120, scene);
166
+ flash.emitter = origin.clone();
167
+ flash.minEmitBox = new Vector3(0, 0, 0);
168
+ flash.maxEmitBox = new Vector3(0, 0, 0);
169
+ flash.billboardMode = ParticleSystem.BILLBOARDMODE_STRETCHED;
170
+ flash.minLifeTime = 0.12;
171
+ flash.maxLifeTime = 0.25;
172
+ flash.minEmitPower = 9.1 * spawnScale;
173
+ flash.maxEmitPower = 15.6 * spawnScale;
174
+ flash.direction1 = new Vector3(-1, 0.05, -1);
175
+ flash.direction2 = new Vector3(1, 0.15, 1);
176
+ flash.gravity = new Vector3(0, 0, 0);
177
+ flash.emitRate = 0;
178
+ flash.blendMode = ParticleSystem.BLENDMODE_ADD;
179
+ flash.particleTexture = getFlashTexture(scene);
180
+ flash.minSize = 0.78 * params.flashSize * spawnScale;
181
+ flash.maxSize = 1.3 * params.flashSize * spawnScale;
182
+ flash.minScaleY = 3.38 * params.flashLength;
183
+ flash.maxScaleY = 5.46 * params.flashLength;
184
+ flash.minScaleX = 0.18 * params.flashSize;
185
+ flash.maxScaleX = 0.36 * params.flashSize;
186
+ flash.addColorGradient(0, c4(params.flashColor, params.flashBright, 1));
187
+ flash.addColorGradient(0.5, c4(params.flashColor, params.flashBright * 0.75, 1));
188
+ flash.addColorGradient(1, c4(params.flashColor, params.flashBright * 0.5, 0));
189
+ flash.manualEmitCount = Math.round(params.flashCount);
190
+ flash.start();
191
+ return flash;
192
+ }
193
+ function createSmokeBurst(scene, origin, params, spawnScale) {
194
+ const smoke = makeBurstPS("vfx_mining_hit_smoke", scene, smokeUrl, {
195
+ cap: 120,
196
+ size: [2.2 * spawnScale, 4.5 * spawnScale],
197
+ life: [0.9, 1.6],
198
+ power: [1.5 * spawnScale, 4 * spawnScale],
199
+ gravity: new Vector3(0, params.smokeRise, 0),
200
+ blend: ParticleSystem.BLENDMODE_STANDARD,
201
+ c1: new Color4(0.5, 0.45, 0.42, 0.65),
202
+ c2: new Color4(0.32, 0.3, 0.3, 0.5),
203
+ cd: new Color4(0.2, 0.2, 0.2, 0)
204
+ });
205
+ smoke.minSize *= params.smokeSize;
206
+ smoke.maxSize *= params.smokeSize;
207
+ smoke.emitter.copyFrom(origin);
208
+ smoke.manualEmitCount += Math.round(params.smokeCount);
209
+ return smoke;
210
+ }
211
+ function makeDebrisVelocity(params, spawnScale) {
212
+ const velocity = new Vector3(
213
+ (Math.random() - 0.5) * 13 * params.debrisHorizontalSpeed,
214
+ (Math.random() * 6.75 + 2.25) * params.debrisUpSpeed,
215
+ (Math.random() - 0.5) * 13 * params.debrisHorizontalSpeed
216
+ );
217
+ const direction = new Vector3(params.debrisDirectionX, params.debrisDirectionY, params.debrisDirectionZ);
218
+ const directionLength = direction.length();
219
+ if (directionLength > 1e-4) {
220
+ direction.scaleInPlace(1 / directionLength);
221
+ const directionSpeed = 6.5 * Math.min(directionLength, 1);
222
+ velocity.addInPlace(new Vector3(
223
+ direction.x * directionSpeed * params.debrisHorizontalSpeed,
224
+ direction.y * directionSpeed * params.debrisUpSpeed,
225
+ direction.z * directionSpeed * params.debrisHorizontalSpeed
226
+ ));
227
+ }
228
+ return velocity.scaleInPlace(params.debrisSpeed * spawnScale);
229
+ }
230
+ export {
231
+ miningHitEffectPackage
232
+ };