From 0ee82678687e175cc9835532162c3a9eba3ca6af Mon Sep 17 00:00:00 2001 From: Damien Montastier Date: Sun, 12 Jan 2025 14:09:14 +0100 Subject: [PATCH] feat: lens distortion effect (#162) * add lens distortion with doc * update code, props, doc --------- Co-authored-by: Tino Koch <17991193+Tinoooo@users.noreply.github.com> --- docs/.vitepress/config.ts | 17 ++-- .../components/pmdrs/LensDistortionDemo.vue | 68 ++++++++++++++ docs/components.d.ts | 1 + docs/guide/pmndrs/lens-distortion.md | 85 ++++++++++++++++++ docs/public/lens-distortion/room-map.png | Bin 0 -> 22275 bytes docs/public/lens-distortion/room-normal.png | Bin 0 -> 19231 bytes .../pages/postprocessing/lens-distortion.vue | 54 +++++++++++ playground/src/router.ts | 1 + src/core/pmndrs/LensDistortionPmndrs.vue | 48 ++++++++++ src/core/pmndrs/index.ts | 3 + 10 files changed, 269 insertions(+), 8 deletions(-) create mode 100644 docs/.vitepress/theme/components/pmdrs/LensDistortionDemo.vue create mode 100644 docs/guide/pmndrs/lens-distortion.md create mode 100644 docs/public/lens-distortion/room-map.png create mode 100644 docs/public/lens-distortion/room-normal.png create mode 100644 playground/src/pages/postprocessing/lens-distortion.vue create mode 100644 src/core/pmndrs/LensDistortionPmndrs.vue diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index 09bd028f..8791f06f 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -48,22 +48,23 @@ export default defineConfig({ { text: 'Pmndrs', items: [ + { text: 'Barrel blur', link: '/guide/pmndrs/barrel-blur' }, { text: 'Bloom', link: '/guide/pmndrs/bloom' }, + { text: 'Chromatic Aberration', link: '/guide/pmndrs/chromatic-aberration' }, { text: 'Depth of Field', link: '/guide/pmndrs/depth-of-field' }, + { text: 'Dot Screen', link: '/guide/pmndrs/dot-screen' }, { text: 'Glitch', link: '/guide/pmndrs/glitch' }, + { text: 'Hue & Saturation', link: '/guide/pmndrs/hue-saturation' }, + { text: 'Lens Distortion', link: '/guide/pmndrs/lens-distortion' }, { text: 'Noise', link: '/guide/pmndrs/noise' }, { text: 'Outline', link: '/guide/pmndrs/outline' }, - { text: 'Tone Mapping', link: '/guide/pmndrs/tone-mapping' }, - { text: 'Chromatic Aberration', link: '/guide/pmndrs/chromatic-aberration' }, - { text: 'Sepia', link: '/guide/pmndrs/sepia' }, + { text: 'Pixelation', link: '/guide/pmndrs/pixelation' }, { text: 'Scanline', link: '/guide/pmndrs/scanline' }, + { text: 'Sepia', link: '/guide/pmndrs/sepia' }, { text: 'Shock Wave', link: '/guide/pmndrs/shock-wave' }, - { text: 'Pixelation', link: '/guide/pmndrs/pixelation' }, - { text: 'Vignette', link: '/guide/pmndrs/vignette' }, - { text: 'Barrel blur', link: '/guide/pmndrs/barrel-blur' }, - { text: 'Hue & Saturation', link: '/guide/pmndrs/hue-saturation' }, { text: 'Tilt Shift', link: '/guide/pmndrs/tilt-shift' }, - { text: 'Dot Screen', link: '/guide/pmndrs/dot-screen' }, + { text: 'Tone Mapping', link: '/guide/pmndrs/tone-mapping' }, + { text: 'Vignette', link: '/guide/pmndrs/vignette' }, ], }, { diff --git a/docs/.vitepress/theme/components/pmdrs/LensDistortionDemo.vue b/docs/.vitepress/theme/components/pmdrs/LensDistortionDemo.vue new file mode 100644 index 00000000..c8210fbc --- /dev/null +++ b/docs/.vitepress/theme/components/pmdrs/LensDistortionDemo.vue @@ -0,0 +1,68 @@ + + + diff --git a/docs/components.d.ts b/docs/components.d.ts index 2bb9120c..97053511 100644 --- a/docs/components.d.ts +++ b/docs/components.d.ts @@ -20,6 +20,7 @@ declare module 'vue' { HalftoneThreeDemo: typeof import('./.vitepress/theme/components/three/HalftoneThreeDemo.vue')['default'] HueSaturation: typeof import('./.vitepress/theme/components/pmdrs/HueSaturationDemo.vue')['default'] HueSaturationDemo: typeof import('./.vitepress/theme/components/pmdrs/HueSaturationDemo.vue')['default'] + LensDistortionDemo: typeof import('./.vitepress/theme/components/pmdrs/LensDistortionDemo.vue')['default'] LoveVueThreeJS: typeof import('./.vitepress/theme/components/LoveVueThreeJS.vue')['default'] NoiseDemo: typeof import('./.vitepress/theme/components/pmdrs/NoiseDemo.vue')['default'] OutlineDemo: typeof import('./.vitepress/theme/components/pmdrs/OutlineDemo.vue')['default'] diff --git a/docs/guide/pmndrs/lens-distortion.md b/docs/guide/pmndrs/lens-distortion.md new file mode 100644 index 00000000..20ba9699 --- /dev/null +++ b/docs/guide/pmndrs/lens-distortion.md @@ -0,0 +1,85 @@ +# Lens Distortion + + + + + +The `LensDistortion` effect is part of the [`postprocessing`](https://pmndrs.github.io/postprocessing/public/docs/class/src/effects/LensDistortionEffect.js~LensDistortionEffect.html) package. It allows you to apply a lens distortion effect to your scene, providing flexibility for creating realistic camera effects. + +## Usage + +The `` component is straightforward to use and provides customizable options to fine-tune the distortion effect of your visuals. + +```vue{3,12-17,52-56} + + + +``` + +## Props + +| Prop | Description | Default | +| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | +| **distortion** | The distortion effect strength.
Accepts `Vector2` or `[number, number]`. | `[0.0, 0.0]` | +| **principalPoint** | The center point.
Accepts `Vector2` or `[number, number]`. | `[0.0, 0.0]` | +| **focalLength** | The focal length.
Accepts `Vector2` or `[number, number]`. | `[1.0, 1.0]` | +| **skew** | The skew value. | `0` | + +## Further Reading + +For more details, see the [LensDistortion documentation](https://pmndrs.github.io/postprocessing/public/docs/class/src/effects/LensDistortionEffect.js~LensDistortionEffect.html). diff --git a/docs/public/lens-distortion/room-map.png b/docs/public/lens-distortion/room-map.png new file mode 100644 index 0000000000000000000000000000000000000000..53604bfb754ee6918805607b55bf0d86b6be02b7 GIT binary patch literal 22275 zcmZ`>XF!wL61^cBEEF4xD8;hk+Q5P+HCF6kFDOLC3J5Avq$GlCV->8ZNU?*8f&~nUd}#X zHE-sunLj*^^|<D)=nhNfVMk}P3->9&L4>iT$BQI9>W@MmG}10>4=_f#^Z z(@`a7Ogwfq|GXX+F_CCWfBTfl3+tX?t56k0GG^#(dVQ+lnX0+f7INORdYm}2iWIc{ zvaZ*h5Tgg)l2+lzfxI6!PyD%~+6Gy`Af{bDTw7>=-7@UjJ2FZ5ZC%UKud>gT3<(@E zgJrz)TNe!G(SXWtVLeodmUMn>)qM-jP52VCF$H5uOQ6O{O`7^1+1t%7?ffSdZL&!j69isNnMX&YbG+VwR zi6*yg`C3Xk+df=br5dsN-nFr7ANG3evy1ei4%JVarXW=-96KdV#w%s#`d^=P#CESv zEUtG-H*3C?7G|#9sp+%^?#>EhQlQBjz4G?{VLao?Cns-kZ!W!lEG@)%K&Qs&*NsFZ zI0fn1s;~lagB+AYxnhrCQ_sn+t%XE~+WHR(b$Z(2(qp>4GUw|2AYaCnImZ>O{o?nO zX1_f*F{V^kkx*AEu;MCLM5IT>%2P1T=83uzb?ve=KHjkvT(b;2w$6MikqQ zi_Gw8eyquxUiT|&dc|NG0vo+^qVO zOdfR^=LkRWy?D~=im7i&4^_72{rqtCS!Ve9X9pT89#_(R-pt!bo!wOTGsa+R?!%ac zXZ0EXzno0+Kv@1Ua%nP|u=(wwsAOPTj*Gp6+<)1 zlmKm2R^T7=`#UI~H+0%@*&^WO?XWf*IXyl|T*Q=`7A#vT&(lzdk#-QT`5T znz-w$v)^5qiY3a4jZ)S$>PIv4qQ6B>%+4x>e?LNPtOAw^&w)v0E&I$>PYL zkGH5OD4Ep!Nb`@H7Bp^MSyWv9Q~7I@li=y5&+`)1thdjIvNkOJd`FvRm;-FRdMoL0 z#Vr_SWqw{$L%BcAFn1TfuKy-*3E*zhh`T^-i0YUp9EM)-1xOsU@kV^(!G(Ly4^&MC*$dw!oWofW~oBj_vg zj%l^6ZuLIC=SAGRhuizMio2P|d@?k1d{L;^v>RSCpw6i-aZbd+4b6t*>ubXrTpjj4 zIVbR#$PEr1me;d}@#&AIl~;CD=MAWx`rb*mZnr}~%C!gkn}p^DmHV3{=B=%9O?*oi zrVXQ}cg9Ievw?4&;I-oRhKbj6ZSUA5Wau#hi|%~Y``4z~Nd^>akv@N1YDiQYwQQt% zl7+VS{-}M&6q@UP`nBy|&3q!Wl;jKJ6fcQU5P3bcN2vflZ@J{_LQbJ2I@Qa6<)m<` z%~0A&gqnauBbQv6qt8<{Zwb61sT!|ebC{P3i+0kSHBx5$0yW`Ej`Sa^k-tCAqjvKR z@w3C6CShg3I`h@yZy{bob!1M0R|cG6b!%0ObC)V{bLG-{?L}SZC-x`OW}`U&ZT7^y znnQvoJ6`%_zE*k}&l8od7N&|i6clr9v*g;AhICXSMnUk#O z^)y|seY7i?thi&d@Du-mV@~D)Rc*K>tk3_A@^z4&wi4&ljpgVPtK{(fP;Z(pfnLz% ztyR;|<&M1U*~bPSmfz*5QhvXCKu-m*dvXL6_S;JRh;(EKh!y+cR$sRN^H2c14$PhzYgtjA^=D5w#|n z{74V8M3*~qv+})#>)_#Qr1<*3#~0hoA+V5Fe+e`uJ8V5UVj(Ou&TmH`lBD9?+O%i> ziQ(NJ2%{E-7@_O8=lr6QZ{A7Vep1)+EAQAm$l3Au z=<5ViVeal^vN=8UXjJm(J5M$&y|y4(-p|;IJX>z-Cn`c2C2VM^O;==|HL&j=%hKbw z++7%Aq}Is~4v~Bw9Il{AZm)f`!7X>E;%QIMuYV2jWxTyGwXd}wE>G6|ZU01ff>t%$ zG{&e5MnQ2HHQf&0&^K@LDCSlR#J91;HqQ7a);cet%@PUu=L zD$4)$>E-|>o(Zw_s-ERShAI+eb{inYr4N+Yt61$*A@Fv0A6LZt;}dsm&DDuV&$R|R z{4Udf3U(}{sZ)~^V|dri_9FjuSsg9@8|cbqJ@DJetc!YhgG!n88}mXXDYj^ z5ou}s9&l#Drg@`;UzM#UkecFxde+Dqk6u!nCm_18d4-14UsF4Qo_h`$mxUdeQDo-T zWgd%d);H8lVU}6np%jj+u_yrM3u{?Cr+tRb;ueqjAw~wLo1Odg8<+%a6=RSw*9w6J zPP+6LbDgPQcug2C`$a|W)cGezDB~9z%LWqBhABqMqeL6#NJoA>`84cw&CkFh$$93o zaAuO5z+!<&)?e;z8S9vRe_2J;;>)v> z33WN5lJBLP*<()6J7EafLQdTBZdJU?&xqWE_7~rfmjT)VQTuNHmALi&(9STo#dbHZ zhYM*eHkWMs`Oo$1yPOs;UYty*TOBnGcF?i<+Y6e5;QZ_3pKk((Fi(5h0~PD@5T|ai zx4JxA+4`^ZB8b$1GE749&G>Q@a66%y0Nu1?tF7$>O_n!|A~h_4@zvlkd-b$Rp)Z-Z2?X_Q4++GVq{GX6RHa3AzbJV7^^QT`YJaG5| zw{@uZuxNvbWsxVM);#Dzb5oBEp1J`ezr4$dYQ)k9D0WaDwc^&+n=9{h2IH~~eRfdQ zx}oe#WUh5-W|SX8Y0zXPYd-|ZS?3Mx=`J@=?wMg0Dx-v%*A@nI$c%$3h;{%hV_nPF z&>aIn!!cXlUBFU1=ENow%27s5qvG7W_&sz>U690hb9(duEHx+>eO|Jk;zoO`Sclct zd>>Pqr7jcj1;FeJi}JJMoZuZZ!lz|voceR=ON3;mG-Jz(a|$zUEbznFFqLFN!SbkS z@K}z|4k*)%t?JWC+tr~a9uc|L*B6EOGL+QyiM8L7tMk6#fOn2J+l?ZpGC!fA>Y3`& zM{(~$j1`&grBQLw1|wJBy@FfVon}uHTWaQe79O|2hhXr08FiHcZEL?Rp&l%a*X! zaOsh`Ii+{NUxXv5%F-~Y|F|^PF=sN}VTjpy&{W*`9ftvNcQO%+g?ya4htBJB61|P( z4e!NRHHshE(G-v4-zfG>w6l93rrqjVSbSD+T8yjIZ)V_>o!_cVo6=(_xW6;+n8!Ja{WGNi|TD188@mC-+WxGBl6aXd##cbcJW_8Rx_X1epA^$16ow7QZvm( z8+k@OhI9Mu2a#cnpZ~OB=+rDBJG;G>ysBhQQzQw@vn>OqEoZX#D(Z{Y_LBPAN)l9| zMp6+-Nluz~_f;WHO8TNP&P|O0N<6Po9Banie;}yLL3V7H&FmnNLO^8?jDZrSzVcq74EzJfEHzFk_1%;!NfA$Lp zP$}Z^8^86eQyT)lX{B#pDUD<#3esDh#vjX)}OvobjYS(|Vbz(n^JY43Z;t zz>O_R>~n#l`}A1DCAzk~`)CrEu~k9=H|$sI*9qYhcohF&A8x$WUf<+?&heVhkE<-sp{`2oL#?&+4w-+??q3@bsl%C-r&zn2HNjYA*-nhVq;(a6z5<5}9iR>y-rt5tjF$iY81vs3L2>)@GqK#U9DWz2QI(loy0S zg#F|YIFM(V1z?gIl9;NU8Ju<;CS!YHan?O{g=<8>7nKZWHx_1`Zru{SJggJ;8o)Jz z7SQMQ9yXg}?_82G;XW`SG_*FAFFn-{wl{OxKs3&2eV+6L^S7 z7B>sV*(N$r!FR{~x732O*hQu*5=Zaj0&+b{524=CKyyjUJ>;AIHe$A?CMnL~m30Bk z|9qVi0wm0=vnZ(hF#xSE2l88L{PSFM9Fb${5HK4i|GXS1jU{>ct@F&fzw4>@q!(P) zgew$vaAL&5d7sRUI%Y@$;orI<7;kDBEt>SOspTdb8x;btum1M@aHRNPhrZL3-$-5+ zPh%^R5Qe|kkij90`7Cy#&WTJ*mdF&o?JeKsPW{RB{kjs}ul@r-U6&cG zaQh8Qr)iOIxlCe6<_UjsYhE}PN(%jlTx9ab`AuE_w9BuuoK;CLrmoCYPu$1HvI-dm#-uEWT=A@@5-#mQcgB^u zeFqut7<}6ECU!xehgId+BRPshRGMDiO$l-tGUI>%C_5`=BaFjQ4Fg}sn04{}sPAk2 zf6L8j=f9jCzY#YG0VZ17CJv@)2|6IBgzM1Rkjyt*8-sb7f00atJU{dG{2hcm<>kr z8T$XLhZ;t*?s0#bmcZWG2q4iXXh!sD9j8Lm67D&tAlVNs;iSNRM7=0qX^J6&VKI~1?64>HPjuRh|WE&d{qA^Q@%967keSX@s zBH<{b9$YGNzp#|lVT9+M8j0{8EGJ#d^6XEb#Vw2SLp^?+;}C7HDn=}e%3NCo+s3by zbYQm-7T@z}Z34)F@5!kz{p<+O*r8i0=PL8K@otqnyqg=Y?s7utOAgH+o2gj`Mvt)r1OP|jiK5eWkM6(CjMcu z;mekFe4!f>BxCDZvB3-W92Q?S(si+YTRf8=l97%u>XBZPTWgEObo=4Ym>Jq{xC{74 z(k}Oj*K7Jdo|||sC&tu5I9KTFrDLWi3ah&yC|x|>TeMm1?Z9qxJk1ufcpLkGhcN%O=l z+O2(vha$UDJe;dk1zxTv>nvjJ8{+p&$TW;edy-gW-n5hyl8nn1s&$8XP)iI{DtK?9 z4bqvJq|EKk%Wi2)`b^hV_yC{O+K0D@Ofyrf0yE&tC`=0u%9c1Cc%WQ&&(1G=J+t(aSzEJ6=jwg@Zo^n}MQI0c+tpDhh z;~bPtNMkUG>}-E28zHqOh|ZfapSS1w(wtG(^6W2C3zdT)11(dJGih2hoYr-lZ!qN*i)5e zomSdJij!QA;t+X850RG%GBjZ8OfXXTJPvtv;*V#UNtCK;d+mIn z8AwuObHXW&VhCH!>NxPmKlPj=YSHoMS9tVb-rd1maI`-fg9tV19;n338=CRh28 z&_tP!$&C`*lT3_YYO@^&AjEodiwdr3%@m zaTi&p4Y|HIgtsF^IWPu3CCYREvOcUIw6?JLj{NG$2f!e%rdPiLbSMv%%uK&>TH=NRWPWS zAxZ7`Z`eb8)H{yl>x)&cS0Rk>Cn*eNk)@YG%M4}Eh(`8~)wf1$8mHAudZHq-te9UzVG;%9iqZ9YaeES(wke9586aS zAqgQ|j6t|6E~;U4LMIkMR9l<_fIlB?A)q`U`E+w-i~%m9u{0{{2zodbxsO&{U!)0u zP#ofRU>GH#rGYZ~o(&G3$eUrDHHEMI7;6)~2GZa&FtckAaH8dret-Hh*2cSZr)h~y zzBP1FXbCzjA82igd(VWJrubJ_C>_-Wa(m&?h#ksL+{qGh14~jmZqPZQ(d(aG1 zcmGggIad`-qid-&a08T-5F&v8Rbe?Jkx$bSG9o)oBNrqK5E63qc}TC&&EC0yU78g$ z408hcuFr#rlx~-hty%@18F^orPKeJyP0$=YDiM}>b^ZX%-p~n(TU#H|A2iGfPW`7B3559~ib6_%KnCO%B8s~i^avpBUp%ja0`fE>5hbMGqy ze2i;q)4T%2gOA^-3xepf>NN7&tGLI?s~amGpG)yc-#s+_sK{_O-#j+#@*UmS6r?i- zHzh(=m)z|VH!>5V+ke%r78U;Db>@=e)VdS|l-)VB zC}dW9%$;slQ`z)STGMJT3D+Uu4;S0I6w1l%{4`~<<&jq_!R3^@uD!SL-uT;()IG)| ziZnhiIQF)5f6K&VQe|=Ed%8GpC?CuWw;`;s2%`08Weg4;Ualiwg2_|Hx z=wI>+1Wuo9Mx!8C-Mgu78ox^w$dst8f%62(hXkp)w~(r- z+(=!8Wlb=NbNJFniIUY`YB1kR4!H;z1r`5gYBWg*@ogEO1UW5)=*Nf7q9_yRXKmcF zw3eVyQqq@koXM7mTS3KSKk?Y@{(U3Vj**?Xm46AHcZ`J~bf}aZixacqMMSGKNQ)I- zl@UqaV@Zul64=b6iRu}ktbG}XjV|2aQlOJ^M$*r^jMt&Gd&VSQWs+!D(xAx>-B?za zW_I5$0U9T~a_=^Eql|Q5a5x{2%c-za2i=ml*uU3+%qIs?;)JRjRXkj!W?NG zJBF_1LDe|$&bScptcuK$D{l{`X^9epXz)My`tqAAuqCUh+=j@<|UgIkUyX%}Y1 zs+gfPEs-(13;rGBL@r;E2@zKxnwA@1{vFeQ>>7N1)0;D0nGtIrA!8<&9!9qF0rCX+ zI=mZ;8L{MQ51N*6Y{*-l$Jc>d@bwi@8gwmF0^)Euuu8N1`{V022}U$6k` ziD(U9UwoNG(-KtDv01Zb;p^Z-u}Z7&K_Db|MpA#hBlqm<1e6S!tFs|tqp_M42x#-{ zs24I+XT#G-(bE6hSEL;8CN%xJxvatw#8Wc)^)b>fY8t}9GVl#q;6aj=I~MWCm~VLO zvePSVkc7OqC0&J8mAgBAy}fgeW84=Cn8{E1a?p1J#17aI#0XF*0eK+_+1ij(j@kjb zwCc8huC0cY790}Fl>8V^Kq_Tvb2Q(T{O-X4-2`^S}BEYWCGIcy^3L7A}?b$I?uB*xxK~aXRT5KXxmzJNn zSxqMxf%eXy*SUScL5ntJcSz`sb^gR_>C+7&lr+7<%eD#4%UNunfrUst$3kzrWDD>3 zzbapI(Yh++;evJEGuUC=KlqGAVcgS2D&1J%>U|?A?I>S-ge(PKTbqwHB6yH>72}>;^y1MkC?0m1gI)ac^)6P&d3;0YmcZzvt#{QJL|@Q zf_BBd%?n2fC!>mwL!htC(zs$7mM<2ib5Vzr&ye$xGhnMI{K9h4{7 zrE(x+q!YqW(U3IY$pPy1WlVC+h7bm1bM~u~x^&k8)Dmo-0minsu7pD%_{Eun*0v#l z+rsR4<~q={XY_1$!0ZBG!esVfWx(@cY+K$rptdZ9MwkF~${J9mzAl>0hSLyTMEjHQ*qMFUvt5Kiko+5FYiMkFDnn2qc zO5qEGCueCOSMdxk5ydKU)t=C6-a|PCZ0wL32f8p();2bl1&Dqha!eM@Qo{{9!N*{! zK@O_0GH$Okc2Gtqn-oc+~5T&nA!j1YFCt#`c|&AK^c z-+wjl%os%5`Fl&FI0Qv=FEb0i9@LHn7^d4(IMDKQTS8&y5q7AuG7tzjC~J8X_HKqD zr#aXt^D~P^N)|IhdbTUGB>Mq!tsb>M9-vf>M&XroP}^rKGU$khux7Y)D2c#_yz3UD zCeM&=Mqlo}2=!^&2FWY5(^xuW;$m4~3gVy=qm$3zh(&FEe+lt~Wtdqq!PVOrm5c=A zW>_{lNk2rtsR;X_PS1y|mP3#t20}nlUv#>;WH7ZyrTgC55YqoD^)7%MlLBP5+0wKg zQE@5gDt#VRrCZuW+KcbJQc8No)MSrq{$da=bbxnp9(Hs%XaTz{ZWx9=0|jHKSQ$@|~rE~K(8 zVdE<$mQI4Q%5r$|aI=~vykC6jdd^Q zhwUD{brJVjR6jDb-rwf>{_PqbCYR!}cBEW$GPQi-FFB+)bFX2d&tcJphdWYQLSlXn zy_hI*yYDhl;#4S{9g8|x!|ziKOGg{lKK2Pvec2#+`9v=<=e@Rnk-!oHQS8Y(U4)s|PFOzI zz-yP-C#$OK>!_nPCkff&#GmI2mIeL`lb}I50yA<}S`HPcYpF#UBDgk0ZkkHrP*r7V zK(X>3G7~z5nyP7CV0qr-pw|h?gQp5% z_K$m;r2*~I%h#tzx7S(yUojb#2}AJ*d?=)}G9QYvnb?}5H=T=*Wl6crTdT{VlmaAx zgH9$;)uM0@3e#I4&uJimGcp%B$A_VsBL_i~FXR4>JPm6<3d6uX(0Cjj=pkL}N*2qY z6au5CnH;pIFbv&NpZfD8w&d^E2}cJ`9HGvJb|}VRRjk9g<&jJ1>N3O-&VB*GiSq{V zB!f~E_5)s`8yli^*Kg0eV{B3g3RP`NCI|U#3j5KFZBCe3LWqgS35-qK98Vx1I>j+~ z;vRzsC^Tt~sJQ7fKO2lP)@^_HzA^}kFm*MMHQf=V;5Ov5aG;RVVoyI@=^o1hC3PR{ zDIFw$=wJ)VlmH13kM7XtMMR8rP=>;mgA6$xJVr(F=Xar|VDBNNRaXj!sy0jGZJ4sa-qH+uZPqmmKUMu9b@o005AoZK9Q6VNXs ztS!;_cynbtH2grQw>>Ox?`zMlH@>kIZ-7a=v`hP#j~#)g7Mu(8wQ&gN|8q+V*Y%Pm z15-5JvcS9GRKo=LG6EIDW6fVN4pA1`quE-fd1@=>#Iq$|0D2Y_nLS~km@{AD^Puol zy?vB{)1mzz%aZ4Dd9J~&u+PgXo>_$3kwR!^hgm6WOiF4XQcuyj_%jf)x90lK zwvo99Pll%w8~3kW9h6=A^sBkv=CLe&hf$@aCx^UhFD*rRXbw0q)LQ-%j-u5tzt7vO zAfVNeIxXefl+&_2IHp~)Ff+aj`>%2PFHs8G>pd?9rthC4Ef^Uxm?{{t?RB_Ja^4du zW(NE7^dOQt;Mw~J8LtM+Kxr*p|L=!U-ab5-RHez25GxXgV5=&KB4T(|U<jbCd=Hit9@}wHp8dD_ddePm z3Qnam(QP-`@DFAPS;fSW)0-^ehd_7Fs%LX!pmypN@YNwbuAHv#0Slx77Lbr*qV=P;&yDIIek zj#pXLxg(BfZ$ytlRAJr}hnOboiX^iyAXwC}fZ zBlsvl%+;>-1Pwafwq*1Vh;Ey-KCgrudbY7itF;)f3XILotURjPy`C>l@UbiuzG&dS z5DI5ystJs~-&k1JJgnvU3PIz2wUhjkbhXNF<{$X)n}=T1I#Mop{xOxCofEUIVzW&skaOgk172gv-If=|q7Ce}0O2W9`j`myFi{& z4+lF?(7jZb>P}CwQ+Hlf$s9txr}j%grD5X7nW))`q;IaZiB2I>r`|=ui)<^UiPG~o zxPbQ2Z8sL5{{5hYJJF$@MuBd2qIwb}v=L2lkg~3UUjKNc! zdFXPo!&&$zpa^+gLN*H&00nJi6NRZ)wb?W|T_&{(1$YH!FRIsWh$$#drK54T50Aub0m9|I66ze{IHHB>%ywuY2xO$(bNl3^0$3B4zYR?Qcc))Btljv z?5%G*#hp)55>^IMb&!M0T63VIE&FSL4b2uIp1^vFYBphu@aRGVm5=#si6?$KK9y#t z$W!D&E_=X@Vf$#;UpKhc(VTssZm&Z{sJ!Djr=?F4cp!|DiXy0Flic&po2kcG%l8RE zcX#a$e~MTP?poGeifYo#!x41{_vpq?bA>Iq*gbV@G#+aJKG4YQk}7=!u`AxBEN&!) z3|?0vBO)~ep6jKU$(Vlul5Z^eSR z9+bP_ne|xv*fr|3o^5D{7X$HtB_-E0?IPoISL926-ca>Ui730LCt2FXKtYXU+%o2hDoB-8&r ze^~%vh?=X(@&<_xK|Ux zOB3MTQ%ANc$*s2dk&j1KZS&oj`CSXkZK;!#T65h#tnFo0@rXdYtcvgW@!p!AbK~|6 zKPaiv>Ly^!d7j6tBRti8c&4>RcQ+K;{N)7_q7d1*YJOzg5xi70nq}Ix*ecn=sH8>F_EEBo6iOmw$@ZY66j~|8q|&A+%FakB zSxecs5Gs3OFlK)D87jW7-#;z$-1XdZ&OOWf+;iqTOoaI5_yGVyTQ+ap1pp5I69-7V z@UIb{&lB)3#ABDqdho15{yP8^uw|ps9v_>&+X7du_TKI<2&j0}zhf!YM=;8+(27Tv zv4WYI%6JmG(86dxJ`p`fR(3VNYVtnq$&;V;QHyR<#TLzO}tdL-iT=xXk^&BbSq4j1*m~K z%?@es9-(^~#hx*Df&ZN9EDzqud&1W7F0VzAu_pNGv&`c!;N&ec5(r0V1@*0O(`(XrfTySkAOQmS4Ae6YFXZjMwG`XUX#JS| zrk`1!-^|Exe#n4yUbKa#ANEU{ANHm{wO4TXrYZuejInPbz#LEYPUXGG+JnuV?wMSC zt4Shzcq#GkSCvd@JGL11wNv-MI}5#^&tCZBLhJD17(O^KrDxwc|NdQby1umy&iu6% z>&hJe)+6|A&aCye{Efa(F^c4}`jiQ^Ro4u4z%)VTf!s!#KrJ7LMd%)U{Op+7do>?E zer81z1#T5o`wC>Ue*PmALkI*KT6LG>fCG46X=0(i9Z;na>=-Z_8m9;=mx%!pJka&q zIpX+f_Ix*|5(EjwDH|MAaSL56T7N#Nl6}V}4c$EW@uLGs1Cfh>hu|K9VBX|>K))9B zqa+GYZvP(QrvsV==Lu<05-ChbH=7WCk3jCmB*X!cfJYPi%a)AFqe)YxD+tSRKm4)` z{rjVq80L)Ten6t}^pmtt^0at_kL~l-3_GWUsiYWmAN@($bZajneUCe>nYTia0j0(k zH@J{~xXP{z2hUX=wcd@p>=#lX$ex%`kqhNLVftz4?#*SOY6-QW-J6lRVKRwi(fV=y zJiH{7!(KAu#bF`AFK<3j~dqpHMcOOj#@ z+>zhiS1ab0mhqA=`ZGJAwT+y9T7h@eB9Bcbj{?N7jtK$Z7?0ll} z)B~&vnU)JQzth64Udk?zV4WaU4;Wew^C$KpijN${k)%*r)MR2m8GP>@5dR(X)m3(ermX3O;yNVyS1V;-Pon*!l`6^aIZbcx1)RT z>;~5NklozvuS9XEAYk9;@VzP0X_C#4c{EzB$H0N%#psiwrC)`NwT~4NF)pwiGLx%t zLZU!b=~UEfGS5D#+w0@-7pBwzg@~%1je0HkR{Kz)EeX7j0C&L$bo+*D~lIChhx-jo{k_M>dN4ub@zcL$mC{k3^e z{6wV~WIm_22@2p%q-rVhNva?&@$4>8=gQVe*N7HMHp3kvqJ6&< zHzPEoTiXe-WQ-GDF`MNL!Dp2v<@zyec`=gf0l^U$!Vkr+Mr!iPRJ(VlEB;9F1 zKjCki(POB9epy=mM)W(To17wAFF4^%iw?eS5^%D|)J-a$VcvQwGwf{E32cWL@f+H; zR$B_MkzZ1l7tS3B1vHf^^`3~dbKnoJ?jLIK&+M<6mdO&+n=>i?|MsC4OY3#nn`D9 zdF=c7wZDuTWUyWK0uirPA!%99S^G{|n6GDzd;i;N6IX7iAa#{B?qU5u!oUUsOJ0$( zQ|R2KFvwu13y)Rr9S60;kEgbmca(E3RjhrR=;5i~dQ5#a($#mHdKEDC;?UZK4CWb1 z*|-|B^t|n!9DMk?Jo6po@@i>!FVsgB9VCIdtb@O9BT<%Pg4$g za+bRAw7|kxW!$F&Bxz%}wPDXSL`>YC`L-6PR=m!Xanrb!MxD^s(_7?7yb|xN&ucYt zYhu5nRL3`*pf zsZ#Hesn*p46Hlj7wzyXJBR9&ui&ZKB-aeEeBBd2rrHJjX-Syp_}4o>XvZaw8QC zj(*?vveQK@c-1L8QxH?uVhZqvdU3siSMa$Yz81$+Q8!wV+eDy0RY(e05K?lbP2suH z>xGT#>*}{Hp>g_$Hm#<#5*wBr=!}#P(?6(}Sb}%!(?eew)isG&nG;#O$+aMtq&}av zKwI3=@sML^r=uvpLrvqov!4Zx+xkQiYo2ITp1~WG#U3l#^fLV&cvclt^$LBp3Lg)o zrPIv>z^;!=Us21~F*2wI2V%a6 zf!0+bC)rx>3XvCA5&TPQ@1L6*2Gtatntj*^7_)8M1LE0IGI)ah}0t^iGZL)QGu zu4)g@qhKGjvtmV2?p>vVIPpyC68HNyFf#H) zAH1OQfTmJg94((+i&>@V*ky;LLi5xE6-BvrHk5K3R=s0^JJ2yCZs6K$m{Ni(^q`VK zvy?U?3axmo8v03)>IY}n7 z{mg1^*dhReS{~XT^^U`oO9DQ`(1v*hPfC6!)RFM|KLqS1wA9MH@og6W{?-$gM=Q@VXS0t=}yZ?(C2M^;!=3`D}n<_q+9hq zLQ4Gxr)^l6b3s!>d;1)TsL~gkw?$tIO`%!KSXvb0cC?R#zyq3)|I=XU%H(H4DX} zzM&%+C9R~VWX|p}G*x3`?4K%49UV=>GoD;ivfIL%p9GEkwiQDQwKIoB=TfrvgW;Ql zeqjJzhO0F(WCVX%J$DIpR=zSB#Y%^s?U9mTMk!S0JP8`o@3K zg3An^euhh~8!iUW{!GC4@Nj3J_aFtY=by>y_s2*; zb6{;ZeP~6Q(_ej$O_af;EOrPEZ+}+(mlZyjmA(#Jjx-3|z&L6D=sc$tW}>qW@f1*g zYLqgWjIBPcPcHrXgHI6!m|~e(oVnW5O;M#wLXVwYCUx81+4ECN{ZQ>k%kf+QIW2(9 zJ*H|rb=+X2u2SQ=Q5BAHi|JamD=T*H8a9pFcs3SDK^oH{t9=-NF`RP^Ay#Y;jaH^-)QPnuX z7Yc8Ho0j{xZHu9zY2(*d_D!oRHpoQi(n-#*iVKPjUw^WGn00K`d#@@S)xhQ)-93vy z#Q}?+4JC1fYe!2EnyP87>BXRnK^wp6?R**Y@gnD5VJ`HPD9X0WkZ8b=>ble0Y`PSb zk*S4cXKOXBJ8V0Yb{^4r+|QpqWJU(wu%XIy!@IrP?}~%tpyzDuHKT;Ji2FOra+M8V ztc|tUj}UsbYN&1gCL9HzDl4h=IhS^TOoTQ+_gUN;wkBIN=6YiLixNtsQ4XQ%NX%HrW=g(fV5O?|S4!?=OnnR@*{f1t zc_r>hylCRF7p12?m2v0M1$0txoTxG#Mb)|#b~2~)gnO&= zddM0}5R^b@2SzyD@Bip6{HvRAt3RKonULA9%|L z#`Off^|5z!O+9e5A14WSmw=@2KyKcB`anHlG>wnyZiq~EKCit6VlSPe;wCB%emD^n za^$ipCw{DtNd3#Dil)wp#-(#|Iel?BvS zusJn2)1Y|E;2S)#5*$$=^BgoQ3sh;UP_^oCjp-n-90@@}Y4ZEf4jyp1_uK-CoLg%7 zVyf!_d{P#{X_E?a({LZo6i~7bZwsmyqgnQHZZBqtk~UulwFzz_@kdmV>+JVpw3zGQ z-58@L$FEvcMtU1?&6ebx3o>7o!8jsbRqY?2nT^tPEG5cujT8%>~SOl;e>laebKJ`Y?k{IQC5ks|@5=n;dfXwU{Z zTTKk!3;^@~;hse-iiiVvSf?lQGnBE0y&J?vslFD*EhM7jZWGGpd{ll=`f&?$C%p-z z;+`AuTXh)npuRl|Sjuikf%45P=)iBpMFZ;i4o|T_S&}ArvqJP|DIDnvNn*l$5o?t? zoR4SZBwY;c{L%Kw`n`Cdg7Rvxr>{ADjdUJ*)Pl{>{}4SL{O$d z+UmV)Jp>P?-=Iqbzr9MJjJi%5nI>9`g}xL*~WN<*4Y;6>vz5u`(pPzWqvXPvN7sv)s&ZTpJI{$Nev{ z9Z9*54rZ&dH8f%1)#>U3esC{19omrQ!vX-LU$3FPn(WQrSJe91&w&?JoD}*DmvuxK zJ;;c~bM0UXf(~1jy{fm^uv+0W5J}mP=Y9!L+tr&Hn>>lfp@g=-RWEt3F}S)K>c~HXmy`03BUTG3jxedt{{cJK0h9DDwB;>4WpvCuHldZQ!>m)~~1hgi2ufA_!h0HBRNEIhQ= zk9X(z6@034AR%tK(j7@|z!$TP;rO8|3}0Kc3uCKK)t=C>c@jA5JYoN;5BAJm{&HCV z!IwQJa(C(9{*P;9v`;lwib{Rw2w`n9tsBvd1Iz!;@5?J#qV&BNO(XH##m;>YUDMY_RQ|9z4M5v?^l z?#)?$$K!(H?nG~F{e!=u0eiAfdk+1?R}{Q89@68|@8!pVLDS#2=bWCK`){6GN(wL> zcb*Y8XuNK(p5+|+UHvg|VuzZKa?Klo#%)uuEhGcYT6V< zb%;YOgEmFx- zdJvtRlQ5WEWd7IFv&7NM5Cl3T#_zmE2On;uzqkQxNr#Z5eAI0)mm+fmNp+^! zPhyS|w14^0UMX$ANzK0kO#yUI1_3nSp*N<2+~bM<$o?qE?Fqfx>)-`Ry@u=Xb^;OM zKl^HHL>_EM^$dwNIL0;@Q$o<<0w~<{CqP+6U6R^@d#H~Mi2Xs$Vc*66rhs-H%EcgS z9`3KxpT4uF-EHpHz%z5BlG1_G$aTG&$gc{t9-)`+vCG!gL@4ou4+y27b*a6Z8${?V zKlEtw?nX17=y5S+2hh7J097jNTs`QRE4TwA(nP1XLLNGBr*peBh=$1~7&VP0GNqOn zM%du@Bb%`%bu25!FZ0o)OV?37^ML!cv0QL(GC6Y*QReD6(Izz z`@o0uNHn{0iZh7UxEeh(puFhjTf$v(Fva0ICZTo*w@89dSY6Skpl4x@aHwj`{-AdS zjtVSIa)J)~W$&1(Ut}n;<7QBY>4Z#0=$6X6ic2d`C|aEwwYw!8*OXy!;rG{D!f%Yc z46}?8k#8{2b`F<`1==!a1=@1TP1I>3Z~T%T918wr*>vfg~~#X0-Ua| zahNPkd5WIX?}Qg;4vw=)2#d?_L+Em?Jkm>n+ZiZUgPV4Zk51-|fBiWNqz0N`OnYbLVeCJ*M+dyV6Vvb_o~=USvYvI@dM;C;qM-4hmbv_@JditY zXhy%B!Xj6|J?{w`c9uNpi-7$E0yP)xi5S4kN!i)*vT?wghq@RBxZb}>xj&ij$w!O4 zz4Z&{M$eEGc$tvH$?5p=U5t8nDLx2OWsl*CZ-S~cxg{g&jW!#E{7~HG&RrrOkgE`XT0%S;#{zEU+Ke?a+oPQgcZd-6MhIvqyYlWfRQ) zjy0Jmsn9(ZNyCNBL%WLSRWC;Gv~Z;mJce%H zdq6wbx{2Ozm#u&HF=sEx5}^2TDkGG@4=KH_e{)iK!Idt3u)5dY(qHQDa1(dWwuRXX zmQ^xrArvKR1l;@lk!!&!;nUH~W&r~%)lu`86AFtgWWW1quDyxc3-yaXCSrmV=G zAROC`Y;k(vK3s|{y`i!XO?G0*54nZ6s%h^9RDP;ExVbp$MqpI-Z$}cZ<=~mYjTlpO zLd6Ki*2EjFsbWM#v@C_^6TQr~;cI=HV@5%w^@t#=Psda!>i#wyrt{zTqshnDo%Qhx z@0N0Gt6ax-&;^Dx5YUp> zLw{t~P3iitqg?g&OgBZS;-JDZTlVPz4ls~p)hxtk0! z@FK=k`zpJB9G1*&lMJenh0HFwm8{r3Tw4)9!GQ__%^OYT`Eb}qIy^w^A$BF3A7{%J zT4OBqOUm#f5+HL6>I4d)yy9SV>yn3AVpse8QymE!JC9U<`F>{dd7?bDE`a9W8hvHI1@w0Mx>V`S+ph*?lwVfeZ*zMEB(5g z&naavOAvETS~oSOmbg3CI7ir&3_x5$l>2nCE0#N)Za>^MusH*61s z`OvBgybEa6$x5`Hjka@#u{gj{B$l%ua!HCqV;t9oH8z^voimQ}(shwV4)Lnf zt~-;{V3s(i&9!Q%Nwu?)k-40{H)&Q1F>xc+ELu?IXh!gMcEaV7R9k;Tk#A zuqbNIROEQ4p=;lvKh2$KYs-8xbHQIOs7DxM!4*3eg0>YwVnOE;-2a^1QA20~cN2iW z=wFswj(!3N_0r`a%20KiBSw1xa1SOB5RfqS@t6kp0;&!AD*|+RXi0kk>;@(Pv7oI( zG0ZKHIX@ty@|)MGR~WlBym%0{VmeBvj7zcQfxfrgOw>*p=P$}Nn3*qZ;y|2I;OjiT z$Y%DJRk7Epn4BW0JGu%wsmsw`=(0yMcb_kCFcb^&8mg74l9~1mKOi5V8~6~s=tcpx z-E0~A=G10Z{aagmsy!y2&_g6DV{Q`eeLQ{yL|5t&CUj|%;58{VLdkEkUIBeid<=i- zcg5%ScgdVJ9q#G0ZGTWNJad3Hx1F9J%5KeFbp6+_!5#(lS4wN}72#vjT$m4ICNp5R zUGYuWye0fxA+G%z@71wQdlD_0BLQuHfl-h(Q?z^z4JsK<>6qT|5uC#e$wz_|3vT{p zn7feiO8=Mf{vxBQ_7>~}Zao*?4c;HEo;#bfxZ=ANtIgm#xoz5#mD(m=72KP{zz3ip z#5o4-nHF0{U|K=Mk*AK;vt^DNR2o`m&@DbAxDAf2QL_IlmQB|$%G~mZpJBXLktbuX z<)Cv|^Hk_>nF?FwXKry06V_WCj^EXAOUFQ&4_*(Tc^&OxszyG z2OduCM`*XF_@F34%Lk!JLs{7kz1Zj7jBwsn8|YYbBI+hg%3(g4s!w%{Cy@Yz0oLFS zDKaf_(abby!;8VzgD|}4Mt;8|Xknk)HF@ofV0h*20be-9IP1eL0V2JcR10KH;n@@7 zRhx&$ejixFE7Tqvg{!v~d6|&G92c!x)uZkaY%&n?0copd-*&c5zHPXGU3y(pJ#!hO zX5yK`^OfJBJRSh`3eos5g$6C-%!x=T1bjD8$MV3bUgLmQ>t$Pz@V9+G*cDz_hBa9n z{fDYr1f{y_NP#@s^?;_I>ACvH0S{*VUuy+v3kcP#%GP{SUrNTXVm;}$po)Mhsrd4I z90gIISI?hD$NUGh?R{2<^obhyH{QXt+m&8Nm&2`y?k6@Ui)s9((Sv!sLw&{sLfU47 zs<_hw`gg!O`0-ab5qHc0Ohl)re0PXJ_3VP@1^=uTL`W&!7gJme4=}efNo8&qLMJL`sEy5Ar^~q`0gj(r^_SRlAXKr3Y{?8KB5g94xC`tPaa=!* zd`bpxyGNj#Fj;PB0@<2&IRIfe0hyjg(r5j$j2j~A3ez-h`h%genANJc9!Q^xb^Ld{ zv5Kyz`BWPGDy1Pk;EX_B4unnA6ltz2yEvMm}J*7%m6O9iS0Fb_~uA2P{4<=2A@nlm=HV=*ijy z2>~4r%!_DmsNF@Rw?9kThQq`_66p55_>2tZ6f6QXi0F>oF}_94iV8han6M*KL|MI7 zURp^zeMa?vilm%ib`7N*F7U4R5L~BS%bMr->75&lqbUB?_Ko~S`;;c!?e9|(@Uv*Y zQt>!d{?OQ!0}@~-IUJX%jPl{>mqH(Pqj!MJ2P8D`)UQ|L;k<(FK9!!a@KjQlA`sU> zV-z0$8%)W>f+?BmAuunLcgAfe!O>o39{vQO`{tO7;Lnv8uwaUgz&#jA+2HP_jzv;7 zwp{7HSKw-}biCd%(olvi7b?CZTV275Cnt43|K)BS#+rmE(&6eXM_xMnXRHZjC$I#{ zQq9MAFk;8TTCh|lmhQ8O0DeLcAu@Rvv`tbQ4@ERxDoQmuX0pZ?JPROJttG|H3laE% zwxYk~P-z6J1A=3F?}grD(X5s03(Fdu6`n}%B1j;{R8e!n=u6Voj{^3%%r|+Oh#;%? z*o)PsR8d>AvFyer)P*mKm%0VIG4us z4s!ap2n-qy2ab+gysw+>hv^t(FdW=fTkd4Y#B{^^`g;G zud(%`08{aNi{~GWOLyu*@_B~q^H+9l5pm{5V!>ZHRJ1V_yb+)pSO39F?cy4sFGv#0 zl}};fwj9mnaZ4B2tTU;(m+oBqd+Mr&Q=rUEd9dV5>;93|L-u{FkJ~7{8Z-$*F8k!;fnzh4Fl59{iI;AX-fDmR-GfGw-1A|!2h3z zF;R%srs#mHI@}-Rfsx34=JQIlz7fOA!2XgDp5hJ&F!%t?TI>fMz?~@pNz0hQSuGF5 zP$?u7=Ipw-4PbkttL^U$@D8ppxPbNF!@^KoBA^6;#``q*iWH*!HVO+M1Wy0|A#`AY z`6KN&Llx##O?GTunjud2$%Jm(r9*0$b0`9;-kGT z7E5qwrwz#&GzF06WGU9|oYK!1$Ep_2{{unIN|4P!oVW=dvomV#c`xrCnMMyy@1QN_ zTI)e;78wCM391(Y&w5+5E}N5KGW%j{e{w{XnY%g+%Lad z55lbfWISPpEa8dS*JnM8u>OAlP;>hKgE#FY{KY@b&Jazbn?x{llf^r;_V5pn=A?KA z-M?uxDJCqz2=MY_hj#L*?Ack)KiDSj{MkM4wC_#W&6(flDQm;ZSB|ibV!_}wrl`Et zI253NSyD#VhoVePwlbEWatj#2%kR^_GAG0L>c9N6XNKNk3Cc{32?O%OK&#pNrycli zw9?H{6kEPl{n^x@@ndtQud@jRQ=?a~1fgj}LFm--ZqjTH61=K)Fn?+VclBLNSB*#R zs&kINS285tRr(Kmsy@-k}w5>a>}^X z9j*u0e}h-vEZ&*MG@Zk8tNVv^)Ay<-&dM!PVUk+2=VStwTBTi|;%)e_n=m`I`Q!eV zo)h~uXu6vmg5M_EAN6XesrM4HEZseu{jmH#25R~!X>=5X7ev;4fcC|#{HWYFzmF~) z7)X=|)){K0-*?xTy?ZgB+#Gt`n{VfM>CF$lpzQgRs$J}m>C^iRst!L^x4xZzJ4Kf9 z3@3BFe^dG4x9E2oFG}_kcK@b!lqCS6Op;e~*Hu@w*8jJArEb0g6=a*LnbscTLkYm{ zyXt4F{{&;n$3f=2tl|4|9665L8O5u)`%O1MyZmt1YtQnl5P&LjZD8XUn@teA1fruX z7Cf|iHk2|X%!NJ~K}b>z;CC>{efC`p@PWin?t7XgJ#jECrx^0m%G0$cuRxF$ znwc&k86$~@Wfag-S;hS3j3J%u1O&`Sj~|ko&}-b9!!xujb8*4P&bUpMVYPzU>89^R_qi;Fd#uyN=;gFRS=Lb>2t;>#b$7 zp`Cc!i-fq5V>hFwdV5*D-4$m&N-F(j=H1hJgU~#vS3}RaQ|oYRENMSf7;Y=dXacz| zDvU0vx^g5D3Ds7dtdKDSZ6;K8m=}sf%Z2J(gfa_x)veAx(Ly)jN%P!xk``&r!<`^F zrp>bw>}Vh9y|uk^bA^mfPH*?-K*tk>e8jKK1!ehy4{5F?f$>eIzb=RzzGA&3d4s4= z&L##4v^=wZ;&m~SN_-4(G9875W_hsjlb@z!UTy_<5jY_k?8uObb$=?Je~Hd+!8 zH)TDnoi(62p90+|K*ixspcEwd)CzOgGqT5nWse%CE+hsWAbWWT@V+9*$gGw5Dd6@_ z04&n<{*+pDPenAhTI&u$;k zs~dUlA~kiX-IcamWS>VrF9D#r&39xzrp@ix! z1)*2sw?0dtM|T7HgBVn5F|b-_^mH#lA~?f^@VJ~0U9AYgP0_A9KzyK=LXG@biks@V zH7~nlN^tbb7Bpdp;4%1l-H!gH;z+G0Xnx2?mH5_nQygeD;j})VcQPRly^_x@SAn=P z#yvZ{tGv%Z2M%0Lj^HAcwhL4>)}Ti$QHQHMPHe_BK&i&o0ZDqxZha0+D3s?j_#{j8 zzTrW{s|4rY$R8q?1kFo%QRS&iiy6y~cTp+VH*+;-Z~Wi-Y*V zHVo_p!92@H$!{hoA{cJz*GFTf5v2)K2|p0VRWpfgG1u>084P7WXfn^i0EveL$_$dp z{5Xgeeh`JLWtt&09bG;{{#)}v`?c`jhbdy{BHS4R3BCfs)3V^agDPDOU(GZFbpNHg z@V5(c;PL43jT5?DoRq$@7{oSdff3wXUXSLB*@A+n2Y?GUCqWh@AV3}T2+D%d){lRa~%pMBi+ZKJY zTyS)I&pV%|6LzPtd1Xb?;2zA`N><~d`C>tv0Yf4<#W{!hp|E@q(39!zrc_u?PIGkBWOj@gQ4}) zAozdtTLtFQoj)iiZ2Qbp&<4%+lAkkw)DyN`LPX1A z45r`Edp^%!|Gpd6~OcWe^5@?@efuP zQ`UN!%{{-YmkK^Xb*k9f9~$po}AIv6~q=_ zx2o4|TguYev~$}K^|mwH4ujVvk{D zb$((IIGCTC#>_M7I197Y;Aj--)9Z*bJgNJd4v)Xcumw~-;&nVDp7pPW078y9rO0N- z081REEMVaYnb9BD66=A^RPf~3$Pj~JX-sUu=o3EBy~K^{e!zm)J`Sao!>vEpRq(u^z9dkH zr>k*ac+IVO7|9%Lja(>{;iNsR3S!&>D`%Wz9L%;t5x)+6tT=|sr?SbGtAPs+*7VGj zVb|tXp{sZ3r@sRBqTI zja`aRyrD%Yne@ctfdG90<6U7HP8rnkOkEF0VF5;vK*E(u z-hAklGa#%Q$b!ts!VE8l{O0D&+dF9n=))yv_4? zz<09c9}EgsNduRm6|o0kh(yR=5@}gL&+qQ@YrJGi5CfU<&!8;&D1gfW6i@vWUTCyv z<8JqyS&azd7zDS$w6u~6bsdHPEl-N!8Z2OG=YfTCGDpva!%&X?LBr0-V;dR|2^$R# zXpLSZs1FB!Es^?qsc0~=E|NA3Oee{77ZID|q$LmWf%y18WpXmyGP$#`Om6v-M%Tm* zFoINULLh*SyGkRf#mcyn-Z5cAak~pG=WV>yOsD|`G5BXO^Sni2wCe6j(Bi~9;^4R9 zJnFmN%M{1dY{yi#VNDw1t3;B<{Wtck$}v!DD=*#{lme|9zoodvd(bz= zAw-#h-#g>W#$I^DlwM~?236`Zo#hQYW~v>D!o`289k0w(J7&UaM{T9GS*`&xKVjKp zcxZ2+djyX10oe(}dED&48h5wf^6C;`gAT3A%+)I{ipHRXkD2C?WK38$yL`0bGZLPYlK7{x_N5+-npRu0YyPVZ zXe+?dIO%UwW>8H$(Al>7gn+wR+;#(F2oGH+}^zx}43A zrZc~^PoiPQbumKzP|LJEy;eIk)ryHy=P3(BNLXR?S4U3KC?kifWK{y2hkn3H;*VFj zt!ctey_r)n81lz5dth4(=&F0v@hWBX^E@mV?G#~amMf*2?lj_nw}mUK+r3^-k&}WI zPwGFhTQ8i}XWa2TZnVdbTW%d;>zc0Uq%Bxk&Xwm>lP_MkraTZTFK`KP4h}0!W`>-o z+2F_S!*nhrg<1osO_hm{n_fuewtl8B&n$S9VW6&~TAn!E60F89zo?b84Q$A(XJFB+ z(aZgj5iz3R5KzD4xFMUMUKFpVI&s)FpKqr19|Y9&s^i-AYEl-@21_|6=Nw8Yz_boL z+`l-e>1EeS`Uu*ZV+gE!zQPQ_$ylib&9FR;wQ4F@SY4{%4;+fyT7B)Rb!$_WV`Fp1 zh3^A5d(W;q&o?spSaJc5Ep;a99!SkHoX3Q*M~2MNA)BBh7)6K`L9kFgWs_s?Zv&a1 z(pW|YmWp2<+?jbtCPjrQ&>-`W)RP11zK*rQjF0T_3G0!<=g;2xP5s6a5)JJcYy8E$ zlwYq9co7WkDl)^yqD{l!sL+--=AQpMNvgL(G5&%7JlJ3X?uS%>UKyijgtPrx4@ZF_hiD2ztuu_c+w z7wua2ml9ttc8kFG3!2)GwQ+9>`-MgJzaC?6GW>&2Da1v}6j@;REZkql4>gKn_+aVV zcU8qyV`yvYvGV;s{u(6W{IgGt$XsuK?t5hV1Opzh-G2bqp^}|{7lDtkHB~^(){^JN zEngP~Y0f>3f6%C_e`@gkok~`aUJ;p_rx+S5-~J`R#%;*|q-#KSrEo#qvJWaI8W?FdRcA?}08t2yXF2}iJ$MO0b-l_F- zh_~Rk;#7&K@@*Jk4?Y9{0o83uB=08d!3k^!3gDS#4RtaJT=}_Qbvhm9G8D0ZuF<3J z9c=Qajl;-+bU`_S#_sQx4Kw?>_q7K1?ZtWECtAf8ZkbX#b2;=~tv^D&G6r#;n{#Xl z?{^f!FmX_bq2+iC9@>kaVeu`kHhbx>m9be^^)Rq!N3CSOM>f}ntRczRbEDIM+VJjS z01jUFcWjB6U~@4Wpq1BrqFw9Lw=z9D?CjyXsZhu%7s1%3%`^Xjn7HePUG*vQfL{7D zbXi$qGwH)E&O#UO+j+|4tG`P`XARsB$oXWA)!jzF0#aO%RQ0QbEYgMa=C1C$@}}Yt zfq^zoeO^L!!QE>m?i@UR#v;=QP<Y8{5NSgp9KAY6DDbN; z_GrqR+uO{C3RYs*ygYiZlpBd|z}0}Yh zd77?AL9A@@yVI;Q*tSVKRJZ?nKotZt*eR)5kJT{#!J=fq+VTlR>gCj8YiMatCqW(}Z4G>|DE7t!0r)0O z+c(*$ucM>YFlqSrsT{ZOrymSCav$u$GYl(z_`P2yY@EG(=CR3N+IG|L{`h!Jcrc6K z*v}cDhOO2y5=VwbGI)l)R{rU;WbF%>fi#_j`3&4XbsG6kgu#sYLBOo}tv5I_{rb=! z3TXQzzO_h#?;afl`}{pF)GqOz{ZYt_VT-wSr#m=Gjj)VV=#fJWVyE i%murFHi0${PU@7)>EBb{5%9$;u*G=C#%JqkA^!)76qDir literal 0 HcmV?d00001 diff --git a/playground/src/pages/postprocessing/lens-distortion.vue b/playground/src/pages/postprocessing/lens-distortion.vue new file mode 100644 index 00000000..b87d33fd --- /dev/null +++ b/playground/src/pages/postprocessing/lens-distortion.vue @@ -0,0 +1,54 @@ + + + diff --git a/playground/src/router.ts b/playground/src/router.ts index a8190415..919cee17 100644 --- a/playground/src/router.ts +++ b/playground/src/router.ts @@ -43,6 +43,7 @@ export const postProcessingRoutes = [ makeRoute('Bloom', '🌼', false), makeRoute('Noise', '📟', false), makeRoute('Chromatic Aberration', '🌈', false), + makeRoute('Lens Distortion', '🔍', false), makeRoute('Sepia', '🌅', false), makeRoute('Scanline', '📺', false), makeRoute('Shock Wave', '🌊', false), diff --git a/src/core/pmndrs/LensDistortionPmndrs.vue b/src/core/pmndrs/LensDistortionPmndrs.vue new file mode 100644 index 00000000..9f81a245 --- /dev/null +++ b/src/core/pmndrs/LensDistortionPmndrs.vue @@ -0,0 +1,48 @@ + diff --git a/src/core/pmndrs/index.ts b/src/core/pmndrs/index.ts index 1fa0bb61..dce515f1 100644 --- a/src/core/pmndrs/index.ts +++ b/src/core/pmndrs/index.ts @@ -14,6 +14,7 @@ import ToneMappingPmndrs, { type ToneMappingPmndrsProps } from './ToneMappingPmn import ChromaticAberrationPmndrs, { type ChromaticAberrationPmndrsProps } from './ChromaticAberrationPmndrs.vue' import HueSaturationPmndrs, { type HueSaturationPmndrsProps } from './HueSaturationPmndrs.vue' import ScanlinePmndrs, { type ScanlinePmndrsProps } from './ScanlinePmndrs.vue' +import LensDistortionPmndrs, { type LensDistortionPmndrsProps } from './LensDistortionPmndrs.vue' import ShockWavePmndrs, { type ShockWavePmndrsProps } from './ShockWavePmndrs.vue' import DepthPickingPassPmndrs, { type DepthPickingPassPmndrsProps } from './DepthPickingPassPmndrs.vue' import TiltShiftPmndrs, { type TiltShiftPmndrsProps } from './TiltShiftPmndrs.vue' @@ -37,6 +38,7 @@ export { ChromaticAberrationPmndrs, HueSaturationPmndrs, ScanlinePmndrs, + LensDistortionPmndrs, ShockWavePmndrs, DepthPickingPassPmndrs, TiltShiftPmndrs, @@ -56,6 +58,7 @@ export { ChromaticAberrationPmndrsProps, HueSaturationPmndrsProps, ScanlinePmndrsProps, + LensDistortionPmndrsProps, ShockWavePmndrsProps, DepthPickingPassPmndrsProps, TiltShiftPmndrsProps,