From 9d382820a46842b466ad4cae69c38b134149ef27 Mon Sep 17 00:00:00 2001 From: Hopeless Tyromancy Date: Wed, 15 Apr 2026 18:06:32 -0400 Subject: [PATCH] Readded files, but now sha1sum --- .gitignore | 57 + 20260412_12h43m17s_grim.png | Bin 0 -> 107203 bytes LICENSE | 14 + LICENSES/kale-gpl | 674 ++ LICENSES/tinyobjloader-mit | 22 + Makefile | 81 + README.md | 93 + assets/homer.obj | 18008 ++++++++++++++++++++++++++++++++++ flake.nix | 30 + shaders/blit.frag | 110 + shaders/blit.vert | 11 + shaders/post.frag | 46 + shaders/scene.frag | 16 + shaders/scene.vert | 26 + src/camera.cpp | 65 + src/camera.h | 35 + src/gpu.cpp | 80 + src/gpu.h | 13 + src/main.cpp | 64 + src/pipelines.cpp | 146 + src/pipelines.h | 29 + src/renderer.cpp | 183 + src/renderer.h | 34 + src/tiny_obj_loader.h | 9267 +++++++++++++++++ src/types.h | 17 + 25 files changed, 29121 insertions(+) create mode 100644 .gitignore create mode 100644 20260412_12h43m17s_grim.png create mode 100644 LICENSE create mode 100644 LICENSES/kale-gpl create mode 100644 LICENSES/tinyobjloader-mit create mode 100644 Makefile create mode 100644 README.md create mode 100644 assets/homer.obj create mode 100644 flake.nix create mode 100644 shaders/blit.frag create mode 100644 shaders/blit.vert create mode 100644 shaders/post.frag create mode 100644 shaders/scene.frag create mode 100644 shaders/scene.vert create mode 100644 src/camera.cpp create mode 100644 src/camera.h create mode 100644 src/gpu.cpp create mode 100644 src/gpu.h create mode 100644 src/main.cpp create mode 100644 src/pipelines.cpp create mode 100644 src/pipelines.h create mode 100644 src/renderer.cpp create mode 100644 src/renderer.h create mode 100644 src/tiny_obj_loader.h create mode 100644 src/types.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e70f58c --- /dev/null +++ b/.gitignore @@ -0,0 +1,57 @@ +# Build artifacts +/build/ +/*.o +/*.obj +/*.exe +/*.out +/*.dll +/*.so +/*.dylib + +# Compiled object and dependency files (in build/) +build/*.o +build/*.d +build/*.d.* + +# Editor and OS files +.DS_Store +Thumbs.db +.vscode/ +.idea/ +*.swp +*~ + +# Generated binaries and targets +/main + +# Shader SPIR-V outputs +shaders/*.spv + +# CMake/Make temporary files +CMakeFiles/ +CMakeCache.txt +cmake_install.cmake +Makefile.user + +# Coverage and debug +coverage/ +*.gcda +*.gcno +*.prof + +# Logs and temporary runtime files +*.log +*.tmp + +# Package manager / tooling +node_modules/ +dist/ + +# Secrets (keep patterns common) +.env +.env.local +.env.*.local + +# Misc +tags +.cache/ diff --git a/20260412_12h43m17s_grim.png b/20260412_12h43m17s_grim.png new file mode 100644 index 0000000000000000000000000000000000000000..ec20dddde8326ff5bd2bd256365a83ce92986fe5 GIT binary patch literal 107203 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

maym0e1sK&qD594!M|?{B zc2j-7*-Q7^S~;`VrYgP76Roj-DRJv+bOLitwnn|e6NVR!>w*l}*w*B`Z>-!9(4w&6 z?*;z77uX}S*KSqKmN$=K?)Rx`Z{$B8^;?B!SDLvETlqoT3*jI9UlnaDv)sLFPEP-B z-h2G_?@qQ(*ij&}P5=F0o%jBIqUW_(&$qALw^wvs!~6HMlCEEQxMAT7`>wrA5@$Z1 zn>@MplFOv<%tXrtds3{WR#@2wl^YBs5q3iFCO& zoqN5HRok{Loa>n8ZT@v!pusru*3+As=il+ZsYu{%lx?pmIkJvpasbB~`5Ouweja$X zfPwWx;`E2h+g576cP&t|v6o4^Zn}D*blU^L2>UoI_LvHZJ#ya{^c1Hb``Pz8=k(A0 zZPpLjDs-Mp>fdA2w1$-GCRBJzTY+qNxx zCat7&iSY_^)RMS;y!%SA;Ts&c^ zz_;3OGrr6?Verr}FzJXv#={p&GdAa-HXL}xdKci{eO8E+2bnzeZ z(-8f8)<8&9f#s?5VdG1C9%iszU3~Y}h7XeOTK+D#Nl=!#G5aRtj2Ij>t){DW`0`Pr&yYQ}`;AitT{Z4%I)Yqdt#eYJ3Bns1DK+g^wn|bH}Y=aTeg5d z<^?;u%!xK-foFzyBjjH{6#ZDu$rI;r@wooP^8p%$f)n&77SB9k6qRr!RbY?sq`C@S zm!C(%Oui>Jzbz1O|2@a(Txs?!`HlDQ!?ykKsYU-qc$%5htbW@p zPMpXY?R0%cbj91S3aJL>hYRM2$Az{iNmOwBdibaC-sWAe-9PBe=qa>$?Y{jb@0%6L zbLM=XbnndhL=ir{AAfD%HP6s~xSp*z|K5e_>U-6T%&SY*#jxBJ(%#&0LP_JLj*^nB z8)wGEU%w<}xTO1_iQngvPMq7VUC;XdD^yHUkNNl1ZC!Se!`d@f^mDJj_!7T*{dUdozc>6( z)V5D~`>tufblc+7Z@*|;E8ospbmz;QwAkIuWoPy@a`W*VjJWv!tnJR^YU9cqT*nV3 zYHz;%K;VQ!ctZ69SIhS=?wzUKAUJRS_xPKWcZ#oT?VcxTUz~hDxsw0Ep~pXe9WJc` zP0~dLFHNZne&a7VaoQr5EgpAmnGSGn5DGiM^`cED#U_UT^}~t>kDnUaPO-7!e;ue1 zRHRw)#8ypRvYqp=$HYC2*LCz4=$&R{l&*RAcGcm-lSQ&Vi`)y`BOF)2=g7_4$e!*wyt-@|LTaK9Q;NaLaKQKAVcam!|!% zv=BMh78e%Hr&|~>FSz{j+s`+dUw_wdo%Kj8f_eJY{5IX`=d;#ksH(0U z%+j;GZyGi+ziYf)d~fC6nez|w7HkktF+P_!qvfgrPx9fT?@VL)56JD1o)`UPuikgf z!_yy}dH847)w|n7W^A8xV88v99Tu)GE|>fy(*-@f_^MtTFYnV;6VB|@{h(mO)PF$i z#-ok7O}UlZp52_5zWn@V*Li0*Z$7ZOa^Ba9JqNbQSbz5EIdJ>IS?{<{(;slXVDGo( zlmDT3eeJ`Z_m#Qdm7C{LY{SBT==kid7Nx4wzHQ+AW}Wkt;YWk!_v0O__3GEH zmn|^&dHTm$(SS$Ft8Rn*nx?}GBDmfeiG2R&xxv2YKyX{oNqebzMt6AcwpDlklj#L5 zqIGe(bxeuZF11#O^uqrKbu;^r_9r~+cX@hjlfQ1D z%liWicLY-NW1F+3CAQ6cZF!UL_rZtLniKjHS-yR4-YR)q``7sduMgfYPX5+^Q@H)G z2G7BZuKy?Km9I|yp7HU@)w`2b_y6}jUifvrwAc>Ne3eI5$gO>oGtPg1e~?3lrT>5a zzCU4g8|9Bz*O)UG)QkU}cJgTLMo^h_(q_ht4xtOYAsy%bsQzbO-)4G2RMq#-;)3}( zB`lM~G*3>^Rc~9k%T+N*KC{AK*G2W*hmIwN5(PR3W14xT3bL+Cov+t@&@x{?bo%>- z(#roc_X&q3}_|G2B~xIb{b!Np#AFzx!zTep=%Rf<2vgLOzkdaG zJqWqMQ2U@U@SA0(rYBdoPP|vxvneeT?Jn#98R_k!j0Lo!Y8Yx@YRs&89|&7=H*z7+A1P|MbMc;QcQ1|64!b;N^GH ze4pRqbg=%y2MrPKe}*4|D)dT3|K9H2XB<-@EyHuTvc6edhU40YZq598mjC-UomZ08 z{&;SNl9JNfED5iv_ImBo4+R<67IUkMM_*pUvc==KwTNDe|ACboWWTkQUO2BEZ~b$3 zC)@RdQ^coLZn^Mk;-r9JA-AeMVsX*GZyB(^J#KXI;S+)!hFhvQ!*k%?i8 z-fZsZ@R)puYx@Cx#v8)1H}>Dyxq`Lbjc{vM(f4g_PZn#xPI-MACscANhQnN zuzTKwtl0_s4~Ox+S)F2eFX%9%`8OM>g12A(&YgLf=iO$hTQ22_yPoP5=twXX@FagQ zcw?GYdd2croyMWt?cDkC*Na7MOrO3jJ^NVl`L>69YTp-r$j)n#Isb+6&ztN$PuBjf zlXF>OyYz|pDJ3N(*@x~I>;7(2J?|uXK}j}|-GVM&cqn%lyXrOn6RFuk&T&$rE}euj~V_rZl5xEf?X z#1?#ic7FCJt~SmaJp1{3M9*kHu)c6y{2iOc)6ZXP)`2=HE=$^~7f;+@Uwv{jD4QwU zu$UjPKcaV2Vy>k^V}VQ1@~uWQzIJ}|`(T;hqFom{{pM1Sb~(QY8{_x8Qqt8H|80G` zOnb5^OQ_`ASG!&o-r!mqR3Kr)@7MBiPr2(od8w20d4xCI=ANhVtKlza4eNt5mpK;v ze%@Q11X^yrd=p6N{r?{iO9e^0Js_@3<7^!$)U+BJ=q=?C|EcZ1d&U&>@K zJA1}aTVD54+>{0}!HKFyE6;yeW`F3&+NS?;Rm$t9WUa0G##YF%xu5B|)jn&V-tD*T zre9*!ULbN~ZDTD%ooH`Pk$g%Uw|vuP?|)_qdm<`znm<_hT+y!(6cqHlvFwIs=yTU4 zUo{!;mY9`kDP1}hmGor$7k7*OYBe!;ZvAle_}nU)SRTK->T~(Sj{75!p7rNrM)K0LU0hNgvL!7KnJX?h zG4k2n+aXN5Uiy@*TFO3pC7gwuP;^Le=R2Kv)pK7@Y|ZM4xNBK$}Xz!_jp=n z2u{59C|+V!nf25Lzdj>#C8bGQ+9&flNF8@u%xYzN=|b7T+*vcT{~V|c5xTbdol(7H zo~o!Fi*v$*JdUIc$`G8$wtOD>UKj{fport znZi7yb4p63i&(aFaG02|-#x3lw|926chJU4WsSA^pScwn_-i#+1gb{E;QKP=w!vuwxN8QjafdY(*|UC`lix@)`Qw6;seI!c!qyd1haOzud2 zsH`w}Y49pXoMD=C?YUEh2MZ28^f12s%d2er7B9yVRpH#jH707zGjATf$h~#No6U*4 zxOVTcU_QpOOeR8XSC3}o?2T{u?Z4-=-nB@5t4#?spZ@>D01@5ogB-xe%rWrNzVBp<0CTX;H;Oga-{DHIqToyxy@Gma6V`; z&03e-VizT_rw)hxSlxQJD6=o-;TF>Go?ohG+wo+5<>#fG>{lO7nY(&@<)>{7 z=bQI4{P=s`L~~wh#EVseOB;M|tT}v4=*Z?}72+>fWZc>z5o~?bCVNww)pyxt`*U^t zgr}uBA2ckNe0PO!HRyn<6(8EUy_~&|pH`7==nPC@o#Ju4qrO+nbNjO;j;}+r zYHhz9zRbX)JG*w7>!$O!8kU|)xx{$pu*+OSt>@w={PJa%Y0sEDQ}oP~&!>+auaMAx zHP0|R>dY%EX%+Wu}nTl53b0_!!|H-c2I zoV;xis;xJTHG7%+|J6?_v)8(A=34reX_?i^opI|Me2&fRy6d#sQTkW4g=}Br)`SYz zzWV)p4|=b8BV6`LEfi#YCn(Lmj4A#3YHqXt!PJ5@+h=Npr?#G))Y_RQ&(v&~VsLIx zkmwAoSe}2{xHjpf1X4JD??K#o&vJ8KGbMk|V3eB1+o40L#x!KcQ6_lzXZ+x}fRl60|Ayd)5q3LT7ngtBAAjdUtE&Ie%1tR|)0(#>@Z{aNzSC`+`9v0z z4IQacGqe`2}!cKy&*uj|(;P?AH&n&)TXJxv8qR zNV8P1q5q@ef;qoReJoGT_As(~wJ$p@Hlp*mM317uGJYe;bf$ML(?xCCmR(qN_1ZtS zd7dCsCVe_5o2~GY!DY$BOS2lbg)X1O=H7I=Fz!-fhe!Ht?(hTdllYvUEw|%bDfE7W zpqNYh+l9}4+|0G*a}##S?4DG9EWy|E(1!XGDisNdTzN(X54mRx&Q(b_ddcA8vSj5d z>vbBEbA^~Mw#11DRsZT z_$_^T=!-&G<_(oylS;}MtRIV(EX$s@(fIxD39eS5#)VpiGhTW%7o0QOB_8NoGCh%X zP0`u&M&}%xgL7WQpZT=(Xbj)YCCLJU6Q4;o_-=giOik4)*jc~jN@$eug-K?K*M639 z?3Y}3dAc0E-tfH1u@zRoOb75A@6<3 z?CkI5CzLc9b-U9Nisrog`03W-FTGRla_K*R6|@Y`O?JJ0?_SC1i6(Ogy5!9Bpw z-6d$zuFuDotuj`+q<85Sb5zh9qY9(4H%Wo}4^J)oRwUQLeU3?E-kcJH-X;6KC~;3BjsNa&fF!Os+e_!YZCbz`d$=43C=5Ax_Fqv6o z3tB?YqPiee^PfNiyKtXVP`dUVmU74POA}4}Hm&S8Tm5&+woht5)PJbi9PZ}6bB+1K z*ZFF)q3Om6SPXN-8z(1e8D?S>`rC!v$u@L5}4%LIwu}t{9rpn;uPa< zDbY0@9UjR?j^Dh!L}p7ziHzz3R~MJ48;68Dz8`9r7I$B&Rw^xD&t6^c@$A|$T_3T7 z?FXjZE)3a~b~Eki0`b|keRuP3F@IoSIQ)TU!?N_`yG$a2f|*@j`yc;U+2L_KfN9s` zo2madgt@pxxfI{pY|m@owtUtmotw)~ZD>rCy0vglr`gwYj^X^(J6hgs?qu3L#kn*o z{Oh5|wz_uTTE6XAQp$Toild{WW63nTRY9JdFZ$BO>_sMaY}s11)O|{t=fd}9shZyp z34gGu*rVA!`Dd&Ar>Q0-Kgv^UoY-T0O5as%T;;AAll9h^?Xg>A(eV#Oha(xjINCqk zI^){C9U1-JQ6WpK8#+2XX01H!8>I<4q(v=y%8seizRUcO-ofQIxzEMtDN92_nxhF@ z_JIdUMuF$HA6wA+J3(>A&O1lH)s`tTCrUj0%iPSLez2{#w%l2NMi1kT{O9-e?VJQ7 z*Hyfas@*6qII$#X`s^)1Oi?Z>rg{y9*P`q`W=sm4VfFMt==19vV=AO$SeC2Fb_P6t z8{_GGeA2~Z5GWJ>pry%}Zl5$BAR zl)8gF&H1;y`Chs7w5yBDq-ma341$84G0fLD2%c;Iu3FU+uroQb&ppxdc)*%#2dcQ| zpO0dnc4$)uGv6_Wh~USp1#fEfeP=A;Q}D43*T2{hytv*?HPkl!=$GsVRT@%W+iITj zS!^g%Q3~?E>iK+{xAXRx14>Ftx$dGDlrFhs>1|}V{UHBgv}e2Gq$w<$&#OE5vA5OC z8d>@4Sob{q!Tjo@PG<*b>2&wY}59dkl%=dariy|W%wwpeBaXLbsn=3+Pgd~xH+9}@hJ9WAb& zGGaFs%Ublz{_4Ve9Kjz>t!O@ewYySBNlEFF0P{xANuv2vmV~R6z zm-DOY*pe5=o$o$d5i-dQ#?_t(_6 zX(2)U8565k*XV}{U%tS{u#U;%u}2>d`_x}qixjsCmY&Y_u8N#oKXNy{$@Y3auw-;?F#(0wI3b%XlT39DMBwyLYhw3e(8t8(Aw zHRtW~=><`j40Y~T9td2$o>@MoIXl~IUj&EsXP>*-{fjTX*?GN+c{lIwhXT#q-w$_Z z_fF6Ng=3(VTH(z$Hmi?MgPEe17=B@`)bl@JdGY7lf`CaIw{Wh_;J&`=d?@$Qb4!(O zhQAg2abBb6z=M|O28?D??`r$3{U+=8CX*-l>bzh1TTF6KgSy#P`oDXs9J)P>-!@)9 z__Sc}rt?AK+Z{L`occYfZ^^_d8z;7M|IR-$)&0M*gtJ;|b=_x^`yKZW9NxpWsm)xX zk2SCQ*{w7;O{Gar%o~FR1t(q!X5G?Za^4`P`Ma8I+m`;#r~bzm6)j5KB6~GPKVHc{ z!Lqmd%B%dddu%$^mG&~ezVR|G@bt@b8+|^T-|x8pCavQBw$90ZcP+N8s^0sYIX}m# zMoB4iS>1XirAt9Uq3oBHUKw84?QwjU_DhB(y0x}18E*A#IwRl!ipeXNk>3?gF|21i-jsCd~)N1rLTEJ(fbTZ?(n9Rq-TfT36VrNwT7nxX9 zQP~$A`bdp4bL!hFuSX%9`%HfDKG^DB`{ZWl;%ejNheEYC?Kcd(#TEVF=FII|F3y{{ zGHYMr!I?j!+MLB_-I%}Z*lF9{9*A^^VQoQtMo2hZ%vX;%O-kf^dXlnWXe0=Sb z<@>g`R+sI6aHTg#e!XG7;6$^axl+N~c_*eyHTZ7aKIvYt(%GwSq8EzGj;+Z57U?qU zk^j4g_s*-zy0FjQyd~`GHY4@g18VP>8QxTtJxX`|fBS>|J$0D3_@=2^@*%18WZuS^abc-l`MG5b1s~5w*NgsJE9&QBb?`vUO2g3X zE}h9n=ajgwH@yF!8^XBuy^7M?M@`cou3)mVl-*$(D!G2ky3Y-hzwh4kVt-X>`Tdkk zp}w|I;iJn9qqFWDO*rIs;i~&vZPiO>LX~1;&13h~Jo~M_!gf!h$@80Q=Rg1W`-Aw5 zz3Okxi~i5sygPPpxa*R?nGKGDf}UPacNgy6ud+RmbxX$m7m{li+`*Qe zSX=T?VZ-|L9X}Uqy8qtTUGbDR;*5q2pUjQpjqSw__8+?BZSKyHaCKR-GmV#h`L2Ay zm5WcQspjOGq&F*Pih-=#GFwD++CJ`v@&gLy_g1_q-W?OyNk3LJ^8c9gJFBGp> zzoFReG9U8{joEu{SifsITqJjVeR4V9kCXFcj;~v4S{I|Jr1X1J<}($gAaUm6xfk8k z0=*o(opg%(r8SjKPg`{8Qai&AzHiUx6f4wR{;nz&hix%3y|9#b& z>0GHhclX^W9m~Ynm9>0gcYM#eB+9cm@0FC3KG={Q$M|N}qd(8rMhB_82Br*u4jZ+wtkBhemsc*e|+imzwvynJD* zBD?qx%be*}LY}I>bF%sUB3{QyKUDZJ?V(%3XAb|KPe)FKHv}=<+502m+uo3<-1AR7 zFRb7Mjr^*gvDPl$Wg>Ofv=-D~%ybNvd8#gZ_|aUxaur$U?98<`GgO|Yeqc*@R?*-% zf3irt{rG4UGrwt{<*D&%N$!wT)p{@;#%_UHlbiCob13 zYJ2-Eh@r13ZbQwdgDHzA_APX>5uEre;8V!0ZlMcGN^6g`+RZDGv{!%WA@-Q3!hVm* zOM@wwrtb3a*ZjNnfbiny=hvk2{SLQCFx)n2QXki%xf;T`i`-;-f7k|1sWmI}y!pIK z;d%d)KXWbLYcG8;eQCqo$-&mk{pxa-%-gtag+60}2t)Lb)6dl&I0O#ADHer}L&Fub@fbjHtK z^O$ue`!*z=f3bn>;I!2}ylihi)rSf8n(X*;=y~MsmfMLZZcQ@m+q%#2{>B(~+sgNc z#rFNaVtblz$5vbJ1CtqKJUKUcx+%-Lm4Z$f+$3=_)Ioo3|AG^f?s6wT-7H_FbzgoFY^G@qZ9<7Mb5*y_k3fERDuj$;zmR-<~~;^bn2-IufF*0fD>1M+jMc#cCw_mXONuF?Gdz^4c zPJw%8cks(=g1S~b%5!X*^Vb?Oe3z8F6aC}Gl;gsSkDGq}>ASc2;S5lJ({pj-Oy!-X zN|9^iSvop&92V(XxXelutr5069{zCk16%W#71NHnEw{?KeCo@qlSLZ8ZB8?7?{GJ< z>T`+ZUSFN`<GViQkUd%Gv4#7}9M zc22TjFfy>EVr$)*s{FqTK{%d@K7i|h9oI5RLPFnGE+hOlfYnfAYB`eB1LzE(mL(^gf_ zQY)>TFa2=NmZMkP=Czq_V2Y{BZ~7lMvBYLm#ni0ptt+0?oIPVbbLPs#B-7KUWg>PN zRV|!bICF04)#5|hZlBGc{td7Fkz-f(dD1jBB_U%2Du>JZ~9@?-Z>COCRrH-N(Fp5})&urAyZ_S$(>+?&`{|uXMKf8$e#fL{leZM0t%=T2R z`ofz~^yO^*_uDm3>R-wBb(AdO-|^N9b z`}h3tF8B98rh88YEtyMElRj;6e1F5z2d8HUU0AEbsvXc>6?=)XW6Q29dDV7POBmk1 z-J~1C!LB0P7Q%hoVL#uw*8g34YyOI`L}8bteCwxXc~r zKKzQ9&m(@Pt zQQ`;Z$$k5_VSE3=xNm8a=Zvl#^=Nyj_pQwM($RZ)ZPgMl({{|>d-vzUeH#}})vr1$ zKAA5z#dAvSG(Q6Y>!~FHOi?bkjy5tZ6$iD0nN)eFrRmR^UcwV}dg}+Z9S=WVoNjAZ zr8jNQYB^=L$G`8t_Vv!ApEF}#?uvQY7SmZi|K^^8 zrJ*z0*1k}iR+V=rXvxfb49y$1Pd^yfwp-$y(WRpW=E<==yLwV3PaDliJd>z$xM12x zp2asGd4y-~s7~7Po_TqV#!GeuC8f|qM)j%lgWYs3T$aSXdC)!KZ|J2&5ABTGOB^Q( z^X@-mmi5g(|4Ps06{5FeVwtZWU@iFicyWG>-%j~0@^)g)%sS#oOGjg?EmV{>a6?mnTZwUMO*@mz5%+G*^MTU|) z&K5gbS`!tDS33Hy^ zM-7ilpSu%pq4ThPftLMB>$QGLmn6I#ymw~@2s?Pr7JexI&^qDglV*nSwf{Fp7OV;xj1zs{#Ie(dL-`y=q-btRP zOh2gI&^L>_<#X)X3zk^Byy)uC;x{#~7jAAiyiZTUIp8bzQiZI)F?@!n%God4%4D4ROlL+P@cvXBpZwhGwBC}G8|w{O&uC1EyOqK#R&(ag=lPN~sf`ItH)6Q9IWVLj z3{?K9?EXn&o!+lMNAq=lRSIW{&JJO_Au&1eo8*Uu5~Zj4jn94L)M#XnE1AtuGhLy3 z`oVCfC>NJ+3qL8|J9smFO2fQmeg~D_CK>;^za-h?Mqa~dz0}j9p6*KCi()=I*>V*m zwAX+CulE0&KEu7w&vq2ei=Dl6ZJOiTFJBHVXV`q;?mDk;HxFs_9DHbSG4)s1zuW@j zH}k*WbJ@uewInz9)tB{ac*W|vT4p|VT65!Of6)25H|IaK>bW+*4>&c++oDEL(9`nk zYxXG(^TK{k%sO@X!pr^umCW)3_tj*brD|Bu`B$Pe_Kr;)Fzrytd=+pBUnIFAo&#_E@YMeej-LmenJxky7*kqeYZsE!j<{b~t?kSjGZF2VhQ^W3)wc&2^Dp{Me4&M!H=6~4Q zFD0jRv8BrSWpdQ5dk$9~TK$w$emJ2iQJ;^WYvY?@8~Ip{{Fgx|g5E5;alB$v;r1n8 zN+iVuC#qeN2-Q7w?9;ijXRS)!30WrWqJo)@?kchlo5~nMcb6otySA}-x#8hCYY$#p zW0SsT=CMQXQx->Y3iH-U@Ud^>YU6o*m~UNObb8iTPu*O7(PpEki>+SRd~p)%deFq} zXCheITDJK@_uJ(cj%REt?DjCyVn6R>HA`s|gO|g04q@xw_!a9_H>E@stEld&su#;` zRIWI#w{Jt?zUZ?%e_k=$8u!J-?DF=km^!OHjQe=cOik_E6>XwiZLR%#&-tr|kMQl5 zJ~i`8*Yk#(v!nN~E6>^VMZzF*P5qHfgXjC^duXpp$x3^g5j16!rjwkSBKJ>?uQ8qu zvsX0NiphvC7r)(K&K7NdV*2F17?(*4rtQ15OKgYrJ%+4<7ax7u>f#bL_k7o{v;%z% zKmP2wnVywnx7By*wvX}$l9lUI3JhoNEc>Bl-<ul3GxeUVPLi6{9Ov|H=QW4csbS|E7mCk0@T|<=F8#ZTWA>gNrAc{- ztR<;Z-Kq1{6O7I{?(X?wylvLT@DDHAPwzLFxNTZZb5Z8H##Q!P`8;kLn4UB5jw(38 zv_dW5)?wZF_MX>O+11C{{cF=NUF2xt+`4+Fs9!_ghT0h`f1UYl{B@?U)(S(9$6JmG z|4#g2us-(H-sTVX&CC%#I=r$|)@O!@9tp~x-?`sts^X%%FD`8`ED@~ZSzNGD{EB{x z;LDWB7fe4-D)2cJr_uV?JS_3L(4MBb{|}T;?hKrz^LFa*OA?8v754s8DqYI5rDMz1 z)$7wf6mnE7Gum8`S-Pb3)KbXc5v*w`UW0pSY8SjE7M85r+d&0i*!R~$kn*8G{5-)8$ zx7^umKEIl5gU4>J?TS;a9u~b$H?Ccq+x zBKP#%c{SPj9VcW~u~&(D&P-EXaQ2K~ii?ZXtH1ZtK1j@q@LV`ufm!cbg73Ah$F^RJ zc>KfcF{^E?WB&Cg@8rr(>vv#59Swq zns25qlW7?E`pM181beIGgHk+dUf=x0-OoQdBeUhgwG+YDPuaDX&o`ZXDl~DO<-Na_ zGc3crQWvTpdKl1jydm_ibe8?Ms#`n<{$F0V#zXytvs}!J_H}Y|dOw)#ZlBEO&8a51 z(o>qYVw5`$!Uj4D^qwx)% zMrO8bnd?$(Uf)u99DRK0Y0fI24cE`EHwmsjTROk)|IYWnelKy(XZNnCkGVU+!RqkR zm~zdP>mE*DayGtM#zA1JT>DrEYBES?^<|AC1u@~(jyTk z4qvR>P`>8FjaBp16IrgkvA$tdEykDk%gJ@g%NhyhPajGyEp+(u_}8g~3@^-J44@9)#eNP zz_lA0rLUZbY+qj#U>W~)lDq7j=kN9iuFqH(Y86|1+$;P=!9q!mgk=jj+8ZN1Htks# z$G3ad9uL8Z8@^fAX*FGA5zJKea_ClhDA-UO@5#Ao{{f@LN4%#!?RmdBTlA>ho(=Dd z*`)tIxcw+)ZS%%s5$YTA)J`N6OL|Yg|F}9>`_tp!zCH7&d|}SmVFZa|c10s` z)lJeWHDS;7Tl?nyDbnw&z2+N!-u{f;dHZ>ZYx{RsEZX_%+tUeZ2c|Ufd~@lUtMiX< z%{=oHZaYN%GJiR#R!$8Kj@IzJu1JZShZ|J336_0b1-WsVyji@JW4H|N;b&o>h`oqqpL-*?^r zuREv9l;54|Y2V}a>f!5vrkqQS9$j}B*$+0#Onmqzao?^V>vnzpr7^qO?$??%&6b;Y zo94&7WZygC_mSCl`XBVRJ~x@o+^Bi}m%)kDIeIUebobR-7kuA5KjzmX7crmN3ZB!9 zER-%;BgV>o0DK6%#-R}9X4f~+>|fL89SzH{g%1Nw&Tsx z0+yNv{yWF*|E69#7;^gK7xqbg3#XpFDUck$-JC6X(UVVePHvxhecJ6jowv53n)U0h z{#wjm$N5-z>ElJx><^^t80)t#QSIv3(jWPDp{t8n>g6*v9~-u*UlPy_WxQL*8j$;~ zAZ6kS zeJ@K8UAF!7PU*O$6OD$e777SU85&?Ym&#| zEly0g&e^QbY4mvH6Lr65pSZMq_lq+aQ<2(a#|L|NZjD?OgS${ofw0JMi-GOZD65fBzT1`?uulhlTY%3RnD= z^=vlr?h?K*wf3^BsjkSxXC5!Zj|YBGlws8F$eNp;87Jx|XpX^v=9Q_pgHI7dy-Piobx;|kt)7H={>Z<4lr&9f}IBkOK+ zosSamoJ$!m^A$yW=lPHb;(oxY*d@yrKg{LXyHxYEQ9{9)l2>M--!5*p-&H2ECuxIN z&%)ad3Ec(aH7g|zyE;5{$rR>=#cAb-tu4b%7*I!UbD?4D2?!suI)a+tIJm~4XXF~x#q!WUGh zC$%*>D|)Z%zNlALvYGWkgo$K|Wx&((UzdE}+_6PWb#C+_Lj%dbTB6HsKKXq;KYvX><8dd4V@;}$pZJz7-)%H= z!_v7ef9oGDpEP01UxCerA^S8gMc!jNf5@Qcpvsd40)A~x3tt2jXh?jL{KWTDPi<4r zcf%WJH~+P%Fend6D-mKa*Zi%c`Q}G5AY>w2H%`c`r&wmz?Br?@7!q|3O&WnD=o?rPLTV^ww1_@;9w;x_?z&LqAyXRq% zCpy7xnx|EKB-9dY67CoY8e~Z}CrW@uM~uy`)L#5I-}_gh$LrNKJ94tFv7c?QyYlRU zr09iJFEch(9EA+uz;fy>Rx&yl>w=`RLD< z-6uc)^k0TOT8%$kzdddCWLNMmwm-nE|NKr%*&(g@mYZkg-zX4RuagQ&nU$HbrLMTmIqoX0ToHC(_ENJtU{}Q1X;3uO^g7PWC+%HKVI; zQr2SQ8=vMMdlYRDvFL8&htK=}s9L_aa#f!l@#m79+1cOe#bR0x%R?NzCu=U=RZz7~ z>c!a)3^u&G6EtL=C?%XRVp}ZfCfmkaz5B-0#BBZ9yLaxNoj>=4$E8Gd^#^NWE*W-| zwD~)Tah=q;bLQva4GLkBw%J|cUe^mZvGE&!7fL^tmh2dIPMcA8uE*98CEi6jfyz%7 zWpaJGn0av_$Gn5vD;TdG4CAwEuYCT}zxw$0rIYGDs$WvGTFewRYyG6~(AM=TFV8&IeVmAC53TtX;8ecKf{(XFc7c*}dxz%QEuC@99Z?C3SvN$)9VB zAJ1?2cKz;&nfqny*y}7mA5#6I(*3+i`#yK}&F8#Y+gHxfGgH~CnX;`wHtV{n@)?Wp zpyX2%J3Y8(&ib5e*J1bnaW(J5!VeQV^*Cd4%#S`}xvjE!+bgBHE}SpUO-PVh9J`<2 z)@4ptPxN@xw zZ(iaxEBwUGo6o)OS-v?Us9$Dwk@wFFGrNkvKmPidTE05w^|o6zck!ov-uL+?30;`0 zSeresWKIkBly&Rp%uaG{^qDwOeuBT&EE8|c$virkjJJ%bU{bZbV_Ry*M>E=8)`P_M~?v9>Nm#3h_z5LHa743P2c^kLcI9^F# zeM#Wfv2y~cOHYgMnsRO8Z>9Q)1y_`GRqp=YqGcj9@z`c=iRr5%ZP>PN{9KnhfAWTo zp6h!r99{MP!T%N$u>!ATo5>{%Z&moO@qY^CymMr=(wU@L`Db=Ta`K(1PLcV1_ESOM z`^vJLjH>gx#03RAXWOscllkmtn3a-{{L_V#O4dDD(D{!i|K(cs?edGy_64eJeH7gm zwR`76?$^lz#y^ZQTUX6y{`FS+p~{Y~{eMzylP79MH_Ilga2L>C1C#q$?f0!|C*@2a9 z;knN@DNpKiNinoze;@PBXI@F9`Fq|=f1{U{Tom4#Zyta2iBv&&n)l=NRk2EnHCz^H zcSFreCD*r3w-3*gv|{Cpy{5o*9iJ$N8?A@CKb@=7 z;eG4CsUxCTY;doT=ic;^9l0K}Iacmwec!#Bean``r*5s!UwWYXLB@+`r^AarsWP13 z(|`D%;>#7cE=sb#d*f%-v2F98H^ndBRIa~T=Je{p|G%=;ekm!++rJ0DIkxL@-`)4g z{c;z~OK;TO-e3JNdzRP<`$JI`HMQp#H(RF1+h5F1>$;`0>qpfw-S@4(i{r}k**3hl zI9cfk6?`IV? z(c~t}+23{>CAjZx4QGnFHEWaCf!G4^1D(^S=v#a#=5)Kf&+ozh`=@R#Su7AaK`Box zKKg{!ujkr7e{%NZF1X>plKnnw`vJ|8pOfFcI=KAWyzlkz|NVb6w{nh5>fHbL{X^#$ z`==T06fP=cn^4f=;3C4p!n9(8+?t|Jg|0PBr@55u?~10n#-^~k?z9nPQE?Oq6H#o4 zX`C?m&P*Sp?>8@B4iB~6Z~x2VyblPLhs&S;ef8y+68o<<^LNevb!Gd$^Na6W>ajb` zYu()N)L8EwPY9Qc(4=F(JO#{~ishATP1L_?oH+P>V)O#}Uk8~_-0)XVbxvNm;N2!| zFEP(w>6_sYL{xn-*ZMC|<^PyADLRwb)KG$t$Kcu&#k{~JCQl$mW< zKkHdhl^GO7+N{#ssqJN^ETZ}0t1>}X+*dsBM+0r&sJ+T)V758pF=Y>#5)U<~|j8F#B` z4y$9o`A@e)Yy0YUNUdv|b&lccM;rHj1!Ysj^jEpB@?cN>qG8l$Bp|A};efn+g~6}% z4RZDD`R}|$JZ)Y~;5g`(>&@C1Rjb->v|zJak$ZgUFVUOIZ+%~v?XaEgB;tBP>dWNN zMQwYOO=foPX2@73WVYw@r5+Bg!fiSS?OFG;A8vi=Vr8&+;V~v&VWnAVS<|khUU>TT zYrmb$vmKHtw&uU&vcAOL68%##^RsmA!?~UZ&xHk5Dkj~3ZFF?~O@)Vcr?*(UNM&?n zJQRLt-*9*t!-WXNQzj)IyEaDNmP3Ok|X3=zAeA>s%LO`J?&P z1W;00`rw37=LMy&D^@ry)UXKK@XnpZ+v<4M#YfHQ4|~6Gtv0^Vp|ii??^cuQ7X_D| zE^uG&zTAIt^o7+I*IrzkSv%{+r5-)oOHVnrRR90JwCC|@0)$z3iRDi}f>nn%Vyxj-GZ=ewp=;?P~YkYaZ6W=PWI4zvd*J!zHo)2zU2H+2a*u ze2No`3JSgy2<^0X^Os)Bt8HNOwYW%*kHhd3s%YoBzJs zv2fNIh4a^$bpK6Vn3*=;ZsW4HhoTSH!`1>sod5pr?e9tYJUZ_=*S3FOu<6?0b9Mji z7x3O{do8ikPw=|upB>hB1m*6|lj}4Lws-G+_V6s{ipENV%S&@VSo{+-*%$Tf#zk3^ zEL(ZWjxXod{t}+Eb>-ywbB=|_PdKu>L;52uQV29zyH&(Z^<+U*C|bh*FEPF<#Ii?(KamG zXv<-}hWj^lRaBQ&&$#1!xL~?>qWs!2?im*E854y5pJ!2CDL$!Ux`L^ShqhR!j_fqo zl$y1?r?wT|HH;}gb9c5?X3x&^@4vU)Ym}``T&pjWDOn+JcI0llVc3=;p`p7Y1k)9Y}vGwm{;Dji25k<2b<$ zm-85fp9eA29lq?(94pXKeZg(g`>dn2$=>d-BCMtf2Pf>jRJMTs$GPn~k9Q^Scz7dt zSCh%NTGpN7O12BPOV{duZ!Q1QdSA+*&NAVT`JQQu`b?rFZ#T<{JG05nabSI@70&Rk z{n@nxLYJ#N4YIwj@7=6jv#V@s@Zyc{a~v*Qx}siR*;e!Fu@;}BVdRz4mZU=(%AN}~ zs*FlsC#C-BSop5>hDTD4aOB~~?t-fh$G5NV`@d)AIxDN}m+Ka-?mGXc>06eS*3Tc! zF+Up4&gy0=wOpqWcjf4cLwRhfH)PXqBu~?L`uer{Td@TiLf4oIIG@kse$#Bn;lOgp zbK<^@9f`8u39n{IEo*zJ7SmRLMvQOHzC4RQ>At-y?Onnf!v1@E++wQFeDyzl@%x4Q zKK%V)wMWJvPT-BmmyU%~m+aiHZu8>H^n)*aZq>5QxGEm^rf^E7Oub83leAn*-`QC4 z>Qe8b?ZMUSa~t+uC|R)a{lDI~Yksk?7T(fl=u~Z%QjeJ^7^ZIN#ntL$sP^h6YxPd` ze}CpOtZsT>@+<9;GoEhZP@oWohyhL%jb_;l&oo-+NlsavLfe0aY<_GgypJv%8a z_AQH6Xr^xVoycBe{t#S|4&WRGfV5c!-8tr`MYW65?8%Tb&Zcmpib2X_nr@ z;36e4!|S(>)vFh44m?+Tps+^xf+0&{qv{5hXuETd)Gu@053T;bLW9{Veqx21qHQG5>o%D5BUvlS9f758z z;gC^~`;j5VvaULJQ(MfP%d@BamYG{%{ifmR1;+Yj@zHR4t!n4W1Zy5Qi%8nM9r@@dNnc{<{P;s?EUE#LUH`Od6e&u;rIQU7vY z?0@I(s+WA{THNpUT{V!7W)=xs%_1xMlNR6)v8yZr0CasQBD!=S$C> z=RLQcl_SC9Kc4Ggw|UE%R-2`7UQQox%>b>HGHUU%4%Ax8~H< zts8SseGe-*5^}D3lft*`Rwdmjj0-*HFDhKqcE;o4ndwdw`Ch&3>M0i3a`5*BE-@R^ z_Vno+^Vrt^<-Q#Luzf;D>N0Pe5Q%8Uj~kV(-%hX<>bzI>u%yg5*P(y=^7w{so#;D^ z$D0^rRk(G;SY}8)TIROu_lnOC`##*@-r+o_eB0e1(W8yGUW&9HRsLds$S-2T+*jO5 z?HZ=vZ#|jS%{^cLEMAGS>n_IRzCF|2f81shWOq$ z`4)5XdGM7#y^mk=?7RNPJ}dlv=Y=b>d&FuAJWfRLG5?*Y_Mwq~R>Jn4(w?)4k1INu z-xnoy>)A~eII&RaxYFi##akxj3bX|OR+e8`@~$a8G4#l;11n{>UoRI~l$dwaaoX1C z%ky6G&E+>v58rX{4YxIGh0I;)+u85!Cu`3;{W{>q9~WJt);Y(>^)`2JGQE{_(-?m~D6RR3ATVX#KUfc!Jp5zdpK)ts7YC zHGb{p*LrWoKY?RUb)tTp_$&rRy?;s;cV6i6@IQ?DwQS?-uz$G$XSeGvzuG@#f5qyr zUKU&pp?43eJG37@l$L*^D(sTR4SttkuhWU29(Aa^p2;)EJ6W#e)V4Nr-$}pcII_HH ztUpi_pJJ!8s-*1Du8yzi%gby&9q#>mdO=y<(HP&`ojm4W<+;wRB)n)B@W z?`tQt8KpY+^KYFYk{OiJDJa6#>U1#T+^1IuQ@PHy$xYd=_bcJ8*a~KIi$}^kGCqno zPcB<2cPV9~DQmmLx45P`45A;*f7pIGurR^!_>(PR?{Xh(6kl=2-B(;aj&H+TYn^{$ z*7>gd%H=oK+B}}}V_HDRAE|Tc>(BkSJ-B7BOzB)%sVlYJCk-2qrcM9Nv*qyhH`%u4 zA`iFyacn47Gg+zIt#q==ZuYl-?6-dDv2WX=n4(?srTukc)XdG7pRQmo&O6(^Y>m4g zcgu3-Hclqr6Z8MF9J#Xk{7Qug|LZ*Wc29QayYi=3_yym;#aI6?l(n^fVDLlwg6tic zZDz{V3%JVK*YX~2ZxRrA%XeDj@1qspKJwXHd~y=#43S%$rXZPRn_jZkv+)M+?u5EK zZS&$^&XM0ZYtF6f6Xe}$7H#|=;dpn?sjV0Hrsvlmp2HIQ@3_lJM`kB1c^}=AHh2OIJab@5Y+#^ZM-fEWEot`jcVG z<7waSA2|D=Rx|eLx$wUel^3e#%z09zlk>)q#ai|DLN+nZhkC_%t|cDl+Q03df9UO_ z?s|rQ=24%`{Wk1s{=WZi)l${|wtA)Lgu)AVZpzk#T;HakeUKx1_d@op4q>sQ8jt*Gr@G@URT9QP7B)&R6ba4Ry=mGN~fdh!hv-v(!Vl(1S~C{7#!Wa z$E&0NU}$yC=DmFi6;gZNyk(ye94KmbcHe}!r^}2R6e}P2=!Gx5(AvMN*Pv3!-(OpV z>$c_&hD)A7S)W&*C||U=mR*tO>4)4G&9fi8`_b{}B;!T?!>VQ6=PV`PmTNLs*`%!8 zznk;b1J4!hPe1&x*wm%I@b~5)=N-O3+{vv_qQv2JI??)_IcE*W%E$JTKRw^H*lVFj zdl`#>hu7ux0X`jbBDt~?GySAaiRU$0N2F}HdrkOXZkd^#*=nJ1XHeMo*q7MO(OA0P z`a^cXwaWOm=jPjEYhPT+KFGWG0`q$ApYAU58*{HWReoq}?08oAuGQ2j=E{}LcV2gG z{n#s9_mIE-+1qPeOD;d!yul!24%fMN50XEqmCT$LEbewAtI1A5F5B?V->r}CAJ@&a zw0XOUMfa-Q(xcfvHf|d2yvZ|SI49gNW#w2Rk!HJG#M0B{(vL2smmfB0|NGUTU!)Zi z_q>vA+rh5}x(PK$UPs&!%V_O)@jk!ug0ouf!rTozZuy2cysw|IQcKyrQ90qR<{SI= zKIadn0^gD>V`kZ$u-@=>mGE1!aD^3(Ye9j2mdET=ZP*jpwE=t$Em|vB`D?g;9gzIK zVC#?HSIxS&w)T`wKdKrY%WU)KbG1?AY9-+lJCudF8;TSUoyc0kEaPGB@nx^@TC1*I z--3K*!@FZ~RJM~j@d>5RYaraHh>$4qo3``F;J`tJGd_gu!Icc5h`%hLc^Zu`&cVYRp zt@>^I56|;@uJ@vO^TL(dKiqF{UYc@ot8mxu^G7yc=zYR>{B!=2g87}tGb0Yyd8KUY zz9#c^@!CYzH6h2gc&KWo{#DML7a_^0boEBt@k5ml^vd6~g{@bP6WV?}kng&q>4kt} zbGYvCJ?sol%|uXg9r6}i@19i=_` zH8L$)v9WI(?GK4XR8~4my<{Q#;&me`wd_mvg(<&ujEL6z5~UjCtkn1;-!$eWbqa?)M`}yF;}^x@;8w zH|KtindcPfqq50w>5ca?7uaV%6j{;65z-(W^PtJ$PWA8iF|TyPrZCQ3{zo*gdF#jB z268W0Wt(I?erGh!+xPp-ikn54B86)cHjH>&+qos~sjfyq%D|9dZ>TpJx5YzqUHD)O+3)_3a!7BqtZl4}ACe#h=>W>tCOid-rAjE%808 zFKv}ORr2;c!yd-3{|Y<`mN?($+@)XQvGjLpMoVR4^1{;_#jO^cnH0y%TgmfCCRRt? zAz40p7t@D1db1ur>DX$YVbav%_o8e28egZxcqQUL*Yk}^TpF*^mlNr>v;C|_Qk`Cr1URH9#|RpS~aEU z{L2a%;f)JFPf&WN7|(ONZ&|t3zbvIZr#v5aLG>W_R~H}dRG!82I%@ffvsxnZ{Yu6Sh zu$wS1aAslJAam`o+7ls{%GPWtiN6meH;DXlY>+eK`)Z-Yk+59#eA{}Z%pB$$m%d8> z(0;&O?ksHLlYhHctKFEj0Z;R}xv)H2k!>f1s)z%NITxni3u{@*E4~;XoAF#&uwGc9`+j{}pzpU@1|4aG zY16Ian*DAhU1V9_a;DNiyz0SMqvMsbjIZ|24cNWdomuSK1xW_SxziUoUT64TH%0$% z{K9#cxK(!^Kce%=R-i!mqd-YRn}~}`&Wf`UZeopXD?2wllPIV#UKh16K;zQVC2MZ9 z+@80&o#&H$>Tzum#&Ak-0#Kq4q(Ga_+Si9g{mOwXS4`wK^?4 zq0;)u&VAy?<=x*7AN>1pa<nBe|D`oIm=>uQb^s=AU?^-Fw)E5PuN6-@7JE6 zN|YDL3Y?-QdGq%qZOvoWlBXKZ1(zN2`yo+rpvfSHlmBRaZu90Gk>wIj$CCTHzW$7C zRcdCjJaJNT?w#uf6IZT1x%7T$iok8YiuZ>V84?dn3Eh>^-n`)4V~$4VouXoF%2$h5 z{a(oWYhh)VdV>XzQf{66ma7#q0XHAde#PC{ulsEG`WpT^4u#ZP>mI#0dTE`C7+0*w zzv43ua;lzRJork5_plZJIc72=@>xcgKA*iwtIzi6dZt+q|G3>RN=W1q74fgmj%WiQ{Auo zK=8fVY734;gU9bLPM>zdZE<7U(<3Er#m}`xmO5{G8B@~MsuUaYudwxyo6&2#^d*P> zI7?pm>CJ4?%qiG$;B0{=gMIM3;)}r**Qao~=0!5hPyfF7PAS)S-xW+x?Vj^*ll{Qg z`B%QhDy8@I!{)G9owvO60^iojZ97!+f z+wL6>JH!0roz$`ScIhn#b9svvUG7|X&Ob=+uuI4f4Zc!glY=@lY!evN&ajlvROVrC zKa+g-7k2?~jX>W0_xnq#e)d1e^Q}2MMSahG)`Axz6TY~wD7d7#^L>v_tCReU-TCz* zjF*f|WIAU2=3zOc@S$}=z}uUBAGj+^?lXLkbvbfqO3l~KOVw{yasN`_aQpL=MSGtv zhwPjgdP<^S`U59B1)4lr_&lN~u)4J|>dn%&syho$Xf%ed|9ro9ulrfZc4zyX=2`b1gr|pZTs(KFapdOiwXr6@8`&;Q2%EIsVq=Jq zu-eUyqK4{GeE(NEbn2hEAtZbE>3#OIg_CzlrtwHPaQMj@{M&kMZ(PDb>kkLR{$F1{ z^?u?>_Xnb}b2!`g-#)jdC@t)Q{6c%D*6!cu4!nL)d_HA^y+rW8rNR?0JbKML`>Nhu zcD5@WKRg&1n}2T2ejpohN&1h1g_M@r;fBoI6$P=E*_hqt=hL*@T2lFou zrWFSn`+mf7%C@laoyq!Te>k(uJ5-~{RZdE*Qp0niE!VF)XUFd42aalc38gypyK1sd z(-4`NxW`{-eWPg1{^`NjH-CDQ)2YP}*KWzs!l0!a_28n^zhY_o>e;LNw}wW?6|vhy zFunWi|6p}lwnmjzLZE`t=0jI`tPk*dKU8Sn#?o}6YDM{LbARo6X}PwSzI*?aS|8Y! z_h6^k|9+Ni#|AbhKHGm!@BQ(WX;w}0i0gAISv2`l45#Hk<1=+P=70Hl;$6U(&&CGw zX@`9;p9*h1WA6N{wu%46t);*JFzjjzUaZWpMLy2{>ptUx7cu|dJTWdha`$l55;i5dOXE=T_~6-eX!vHrh6_K3MlrsK@5Dfc)oO1r{1> z*Th;UNc*%$6*L>qt2xZMOgOM_je^nKvfZU>fmMmGetImd_Th513w~ie-O5fwBy&=y z+;XD@qFk=aB;Pk?vL5(;{?JZC?j)|(`%d}{XBjxsSbhXpbMKmQ(b0GQ+)KxfE@a#O zXY%>ACjyJ7KV2bf{qrWvGS1*?H?98vTPf-=3Je_u%7Kr>~t^_omG% zL-ff?Z1|G1Wo`B41eEVw6w%Z1K$$g17VAgu9eX~dXQNa$u)EViU zzDwDqZ1-5Or=5>tU@b2uDl9c(tj&Tq|4;w1=AL<=9K{|6U(nZQ+4_7c4%>* zRp^r#p7aBkFEERFyiz*zI`Lqg*qfwlao7Ie$ZLK1u&khB-JRz`iI-WHRdzWm*VKC- z+uC#B@*JrXq0u)LtKQ7#y&U^1>B*ghJCe?O(RcCF&$WWnORBMIK_@7K-S zo{$}%@yp@K(R&x>eqa+g&y=9r+ap%%Iq}JIwY?^dY*kh3AJ%SlF?&*yru*?!q1Ob% zPW>LiX@P%KA2*(VIe*dR7(3|)Qad>B-MkvUfAx2v3Wr4p|IZTZt#v;vx3dxQMEQ~mabe*ETU|5E?drQ~C2FWdIG)!k+n9we;bcKz0>B+Z)Z!Oo#LPpC#} z9!pvI#@(}*$<3;2cszkc=?mKn$pkmc{+hleTVvjs99+FYP->y5)k5~Fg}W!M)7&B} zx?6qo)S|ttkZx zj~b>|IiEk+$L!vB<=TAHL;OVrYrbe?9N4f$?pB2Rnv5i-+!wKXZDghf@ND-zF8ans z=;iK>^$qq1mOs3_yULzny3UF^`7(*3huh{=8lQfhSZ7Nt(7{12+`(Co| z)AcX@vWBYhHjLBT5@T0$o0~|6IS5}~BGR@so`cy+L20q{td0XF5e!m)&dKvBFZgSZ|ZaOx}YCYRrkHzXYt_$-Vu=Y!A+P40G?vuETM%fL@c5hjDg1Jo$ z-0R*rA3J`*`~E7qKD!$`uT9GGOZ9&~#bv^#*uEbVJo?-p2=0(rck5<#M{sf)tHb8~ zHEuhf^>0a*5!@&iveUs$*!lBf{>7PpZgVH!x={H2XGP2-p~EFFXQf8iT`)0ZRaz!0 zVlmFRZsKRi~OzTQyCsjTD^`@?%z+_GVMSO5iZxB zU|J;STe3k__N8O?*2w6K1#C9?+uPn4O3!+8EkNK8^D4gCRazMZDn(&CjdfPG zOEx&?e6gDK;5Ogcz30D+t#RCEamJw6K3%_EdgWsErVEe6J|C&O>c+R;&&TeFWlz2G z;{PTy7yWb5o5;DsYq^8do|Y*O&r4>i)=D0p{?O;gl;CKl(+hR7oX_jjGYPf@s~GR) z+k8ycA;d*E`~0dUw+`=Lm&P*REbQmh;|sgv8(FPd5+|!UwTZGYhCVRR;jNh_!=P{S z;+CSoNB6kKy$olXe{K*+{MP>6<0ikDOw*1Pcb;CFbSc%klrQta?DKyl_SwC9qy4GZ zS$`L2#-Go3Ept!aDiDRO1t|UWZKlzKOV6(aZ%lKP)&JWv`CSv23IB_3)8yOU|FgDR zv^p&e5Md}jzf++$bITcb_BHr@`S{szhSNmzCz(5XohDlEV|{+8Yz6ZH zj)koP3RR4U3iG23CA)6ay6rq4c(1{E!L0rNCSKN;S(|WWT5fCPKacR8#oQUY3?A%h z*tqG^)4R`qGwzvl%6FUg{?$HQDRQjEH_RV3B=?y%mE=Yo>u0v_H9cKaaB|8E!{_E( zf6qDH@L~#6&4-*LRfkr}GN!+Izn_7zCMoTw*pam#el`^HgfN=QwWQ4Ff3RHs>FNLG zDk8re&TgO6r1nqDD5gPePC-ke?i=ph#_bE49vZA+$e8w}fsgmWC--d}-#Bln7AGj` zG&s~(aKCZRX^ku}s1b^}eJlCwtT3IBI%i|=^!nUf;Zx0FJtv>+O@3XV;GZdPyJb=kmZZGmo1XKKqb{+IyHM1u$UW~+mrbg)&(KD({ExWQ8K+yBh) zo(LE3u9n<3u?QB^T?Pq!U%t0r|K-$wC|mi6MRM?UH@{aLS}H+HHZAY8QW9Pp&a9by zZ8KZP6~hxs%M?rB6ziB&UD+vplwDr6#@e^$L9wc^)HcgGJ;pR=F6qPslcsgv;U+w58gQcv!Wy2P5@YO&_lW|gF{ zZ>|3t3!K-gno4lYc6`xj*2q|D;J-nFt>)qL1N_Ve!KW@KD4zM$%GB}v;dTSwD&=Q& zEy7}rFH8TGynM5MZSJpIGo(EQzZ;7D^zYn}c{gFI;d_C5)oqsX2QE1tVOt@(;r(R0 z7jypZxT_^PQ%!nyx#k;vRo6}#X3;K{qIt|wUkgRMzIet+iak|Lnt0aFjq~7L1O5i{ z1+rQTVp;8`OV~ZNOXrAx-(mlt)mBy8(s^M= z+8<0P``^!-dC>2M($kky*IllCXlo!~_MMZBC2_^Z6y6YJCB#3_jPYf%c?nybxIg7D2VW&Z9 zmi~h9#qar6?Q0kLp||uCe~2yTuWQRbZ@N%+E->%bsl@kOM>RyAx=pg+Tfy9nc=WSDz}uXOXBu{$a}Z4u z=Ly->|Bf%mDI%!tA#XvIOfio)*WuQTHZSj82?{yeoaQSu7^r-HsA0iqRr7GVPUZo@ zrf>T$_?_G}VWXhc8pFdET z!FyJqQTgrFDcg_SO;6sle9KyyVuAN7R(wiIf4gG87el6E=llfTf~ZSNIhSlXFv*2& z_LbJYUSp$QD|#lYCwlg0CN7U`+mXgC*R=bA(T>7w^Y$y}-gEyK{I^u!COhh9nt|hc zu7KxDlNmTu&l&GI_dMp;@+#-NjPi`#e<%JG)Mj#={_Z9J_GamajhbzuZN5+S#C5*7 zo3;4LM_k~Qvp6;BbE4t}>8iVv@*5X+P7SL1?Q~n^eOnLj1>TEO)Hvf>k{`@{vE6m^ z!&}`^Jx6`N$q3so5ccCKpJnkR;)8-qKIodwUX1;Xo^*3CG&Kw@IIdV%xT1iqkm#V3VLU$k@_ zvu2Jsq2Qt;Ik83c*pgzd=Zf3rF>;+b+5Ieww<+~h)(_i1OcncYGY3E5tJrum-|Y9- za|{mY4d)n`m;{+78aunKb=UvwUiR~F^~Bw+f0k$N&5hc;r!SdxIcMdHM7fqVFZj>D z;y?eMfBWodPp_m|Y|S)~w_|>OaLc_1yZ0Vk{&0N&@BGGF_a2C8UT^E^E#S;?&S`%8 zu{~{33&ZJGdK+5jW_GP!eK>13tA<(!C)4ivn=>e?Cap<(2DF~_6SKy+KdVZk!(lT6GHn&Wl|uG5+PC%&hv~)=Y4x@r%d2H3OD*6mk?cO-tMYdVqlan7rzf6#_1pgHn54D6 z(CC~h*A(|*hR_aapB+`f&u_N-T1tm;*0os}C(XSgIiqdG%FjZki(lWkZWh3wf0$v> z-b0xZVX88%5j-wya{oSzd(p0z;XY%U4Tl|%RfgZ&!yV7e{(s&e+SFuqIjS#0!01=g zF}n)ulzsfMA5s&Fv$cJi^<~Z8dKc*b(fDPnG^f?oJTIr`(6(CZ(>kZJwG$2rG@eM1 z{`D{8l#;BC#LP^0R~BuxhThvfw_>k?q6?;lK>OrtOxD_ZL9CU zFFRPtovkJN==%o!B;CR+(YcLrKU5etzuHs&)qR_j=%}4 z`2pV9(T~lxFx5C} z&j>v7+5YLtpO$k|LNu9|wz>%4;s1WnwcvK&JbwK(FWdJY^5d}jnwHU~ZN+@=+=0^4 z)E%WVQnrT8noM~|f(o2ncYZdgUvhBL*}DhTDnz9g@_+ok;U?qLf)3T!DsL5yr5?-p zatQDJUS%7@oRjxgk)iz1+ydr1J9e6``pN#G`HZe!tCJyTjR8BGf`s{k#p^k0w)MsD zKlohjwv$(~Yh-?xlJYLk{_MkHyBnM)`fD&p1;#u%S-RFKQJgW1<66a=X@)(A6DQx5 z>YDfZfz@u)8;5%fluIU7bX10_PPaXNC-%ygp7m;y@=PI39rFWNUKCA;)MSsoRJhq< zvRuiw-dj_YF8lZx1|AFiKI5=xTD8sLCt+unp7p+5OVXTG!s)V87B&{19{Pva4MA(w}52__Gr2Dh{{F8_G&4g?S&j zvw)MguqVM$;Zxp;oQYeQ4ZrVv%l0F2(w-H(Yb_k+J*hd#amq(0$7%u7sfUF-7;PS~ z<#O$haQMAWXX{F{8A*@&UhjO_o-D4N7pAsXTZGkj<-E(@R~z(}{afL*FhJ$QC#4rZ z%PUR?fB$J|aXF8->tq3o%W(zYma2a&I{!YD_tkXHimix}w3xeTe_z<~iyta0GCoY_ zthc-se__(M6)puOUp9N3x-zk&`B>WjBp3bQ zaJAYn5jn;iJQpu=?t0vR?anP${Tn(u&Mw6bJ>`$*I5=c`ZoK9A{-ue$*KL!skb;l3 zEiyBhc;)uzyg4b#<$7;Z(T9Q#)nXov@_DeY`<6S`1pR|o%d#~j z&ZP+EY>#eDdh|x-+u87kt7AB%PFQX6TeEU;=m&;5dshDabojNr)Xtus<*$7HXtv2p zEMB*z=cpsIQQ;BUch66KoV`a`w$pgtsY;RA6=#0DDEafcq-o9ZGgl^V4v|y(Xx3w( z()MFF`@2Tb4-2<7P8OWXn<`hq8rS~xEi;o$0bA0|koWsGTxD9O*?fX=2AfsHgR%^F z=lJ{=sT~fiZ_IRL{aRE7UUKf!h|o{vKGdYO`X#0k+t<&#)%-R0)g zEBH$+7@uunUy^vX==JM`+SghbvJx4;w4AL!katAr;6cIFl4;Io9a6lH+*;A8=FO*2 zvZ877<6A`{|JLNW`txkP5VYuyn`=|&(qN5N-xoqFT0(G-|w=|ug4JIPzJ za(<|=+k1-V{I+PfJ^0N3#@bNBo}e2pqDNiwCOc2r#<*5u?xWpLD&)c%+N)k%*s-Er zQ?btOY+k74;uF`FIT^O37BHK~pY|=|o~a|{e|TrvYK@F*heIN!#3dS@;1E-i+au$u zcJtt3iHV10uck;_Syokfl)ZfTT`H*RtkKl%t5sWHa20syq->cnE#-IGg}1);y~hmr z<}|7Wp8Rp^w2Rowh1yAH#Nr$451cG0x_yBC!3oWIr3{a3pR7OF)T(&-<+XB0eg;zm z`KZIs^j5T9W_5Qy?V!R@cSB-hTsy~$2Q1zJjN7eC?q&b;yLCvd`<0D`QAbxrsL!OJ z8x>3m2P#N~g=y4#=I<$vj2%6V3XXnViES_;cYPitT{NppMA;JWwB3&x5!ta?^w^D4XMT;#r5mK~7NeEnf*-mc?$k~0<7 z-+6w%{L^Zy-L5^8V>fW0Yt;>4H9oFYFY-v}$>GIwKekC-PM#EEktQH4zbN1sx5otK zh&i0Xl_I;t)LezL7j!Z+D+>KLnz*iN$A+He?>#ytvh_9{e6rc2`=kE+CxYDZjo}ZN zH*C??V0Awjx%FOT0$0`naWmcN`=otl@P9tMOjzu|#0!_DtE8nCa&L2A^EZKG$rQmx zzO+jRA8y;y`jlIXe}+<5QMyR0htkPXzBO0XGTQ(D(5ttc@?Ext#i6~gy!4IC<&8q$ zvl;^Sz4QCI%6nk|k1Nmb3BH>$9ahIBJ5IjMYxufGZe8=|14pzg{XfJ<&)h!!{91;H z4ZY>>j|nE8y#Dsu$`fYpj;6QwpIx*jZujcN^A~k!SbV?9YqvwJq0FLW%_sgtUA}Lp z%g6oy5TUAW_Uf*Hy4BC>Y@Nv_bKQg!&xP5%i8>ZsZ=e&qm2H|!zwA<$6Hk7;SW|gq zrlrEN_|qzzJ&sSmXK`r$wWf=?Cpbxlfox`F>@vTRP{ zy68!tQq~`vACqLd@W=No{*a!|TRtL{&Sg9=D%f0}9@6;K8h`No0_HS>`%fONy;Ee6 ze~*2`bLlg?XHC;L{=0lj+}SPjdjp*FCO;ODVBNBOKYKu-wAzcC*-HbawJo}^Q*__S zTfZZ#dhdFD;&czX)OpY36u&34tTD%Avo#F?@-HW%QQT$JoKJuo^rfFZ_|TFSI5f?4eaxp z<7OOR#&+(%Vt9Ph=g42@mp!Ux@pE0H`oqy?@$U0o6E(Kj*6zB?^yZLer^u~STBd2U zO_tW@Ke2ykA34j_lC@L3VfBOOk3G|hOk&vhnUYh}JS>G0!p;jRzm!x>^f2M5vbZRy zclO4XAU?D8TRmmu+kRh{Qc&BPGHKm5*P>UGj;v4GAiq}8v{E6ZqGY-CQc*oN^XbcC z=dB3n*X~J+m7I1WI_d-8p5_e;c$P^|JG_w9Vb&#fwTMY^8y>B+5t^iOhasGK_N{k5 z{^tXxte>TprTJ8M+l~Xm(i;8?PcU#Nir?W6cTlN|Hm-cqVSli)d0B+){{`D3TAe0N zUmA6lxz z|7p@)Es@2+>o2ElZ*yAC%<`wkX0i>3{GBU>KOcVOXZ&b#>To-w$jUk?WBX$>Qr!~2 zDBPJC^U@?*W|ID)u6oNLmcpV_FQ@G1`?!AXLC*D;SEdByZd`f9qgdr}maw;{b4SIN z4GvkE>sLN>ye1rxda`)Fj!xsu5FaP|Ee=}~TU$9i4}DZkHj*iRK57N~n@jGMSzVWs*mIZ|?VGz9DpdY8_ z3V-+P#rnSFN#e(D9%(L+yu#q=_PKz0R-)XO8P7kL)SQ{ZcdRadQ8>0xoVr`GtmO8(E%SSdpm6wsyfn?GTlda+B^P?6^}+&ufB=e)O}u1xD&k=6SrOE7GBQo$T!!2XWOoTq`$>W>&p zOvZMbqf36i^Sx8lepji;RrB4Uu7w)RR@+y^rO6eD?BUq^!EB3zq{RVVp1KvDh8<5{ zXKt0$HfkxFFZyzWLqUn3l$DTPJNu)0zVEHURTmadSZ1pmG*zU4^O2Xp28kP2ezNH_ zUuU#nd}p!eo!1WepAS}8I&;l5RGRqo#J#knO0}EEHM#f-=eVD`Jonrq-z#=$E`KK6 z^0~0+;NzfWUA1ab|9G~DF8bZ`%J_-A*4#qD;5FIXBA#dGY;%mXv6Uzgk72j(wi62W znDS1yW#Z3!y)}>7-^^eyIOyzR^6yXOZc|N>NO#FRuGt&jN8Mz9f0)fe?3)w!6-U-B zx0bCC5b)G*RXV>@WS;bW5%pBpb|vFI(o4n=i*5GqTB3Aa<6ll8mKk3(d{%v-~tfQ^`9}bw# z`NUDb%jB7z{P!7ixxCp+IX3Z&GOpdg9Id?7YJuRX2fr_HlrpSo&MfN+(kSwpnX;hc zy{Zih|Hm&CYzwMQtCK`nolN$L!z%l{5w+j596XK&W0gWdtG-x&++ z9s1_I4-=6P|Ma~(;-9e1`WtIif^(WO1AMopFy!4hy~poW^^Y?v%eYT7eZQfbz$C+; zzbrE3rhlZutkaMF?O^{aVBl2Ov*g9C8`n?zl@u8s>tGUV;0!+?K55PKi8ap^{|K#X z`BhkT|8dW&xjMqq7xd41PC7it{a2{;!PIkCiUd5j3tZBixoL)3#TmCp8_&n5wOlzL z8CC!4z@h++O}(4yM79a<{Xg;XZiUr?%UJvtRbk>skD+TchZFFGEg4`GFM28P&@_KdTMdfBNA4 zEs;_40z7^{O>QWfzuEOr^S;*|RhmC-of=&DJZ0wioN77B8D6!7@!dL)P4nWLe?Rtr zlF}sd@W$aSOGRu7FL}P3c#}opwq z!_5UtG!xD+pLo%^HZ{nrkkkCgXS?TDYV~5cUVgC6%xjT9uzo>=`|2pmH_c8Hy{9m) zIKh_7@TS?kp3A;f{h_9X{l2YhyQHdezz}g zPMiJnuVMP7lT}5VYSY!`KUeO*Y%(*&&UmKE~OhSD{Qq; zUarlZ!Q)W-oV#wG^Ia!+GT1)3Gk2Hv3X9nNheVZ}AJ~iiI_iCa(Z1ni&4-M%J4bG` zx2?;JS+dnYks(6#lKJ~J(^po{<@vR|K<J!lq6lQQwKe*~?Y_GH7mR&c# zzA(J=F6i5fw5j&BdUxJiKY!)BHsW{j^XU(r+Ackp?v7+X6!uAO{qb!t_m~|_JSVa1 z`=QbeOm*=ucV1De;ttA_UXm&}PjzBKU*M(~lX@dMQxT($zO6*fD5Tkoq*zVt}sE^Eg0*Qr`l z9sf(rYk&U0c!i2q=>`jH6CWp`>M14fCI?A$6^r<5&kKB|wlw0}*Po|c&!5^lbve_8 ztUny5vhCMwN-&b)n$NauJEK1Dk)4lrywS{WV}589v3Jkv!piHRE2ggKZlAR}K}^u$ z_MQG!Q$;nNXCDb%@YC(si5I6IDkc2v(_THxuKHErm37~CYpB{x{MM>h!Mp8X-3G?K zmZi>*pU9otc(OV=!EMGi_Ke6D^QBRXx*aMR*EM%95PsKC{m{-rTCU{Ni(9W&Jl40A zYjx*m_;E0N=bv_l`MYLsUTtXP!m~1iKcoJr&;GV%iR_ILjA!b5uU@~fg=xWSn<*!M z{Qi1P-A$vEVZp8}R*gLezTEHkyvM2UtnbtKb659Dy-HJ!W5K()KWJ6+e`!jcd*EZi z9<*X`N6OmzrM{&=9?Fg@M!kKH133{udEo>&9Z-JbmeS;w#ep7Mt$Zp^8f5O zRlNF8dB#D}0z>DQpZnXjm+92qxBIiM2Mg*#KXT1EcDUN&ck8L^FY+%P z7LVj~e7Kc8aNFurFW4SD-f;A5TmA08wY%6#f6w^GbV%@4IP;pD)8C2R`_C}@u*$<3 z?UgTc?tc9lmX&W2t|$JbS>RcT)S0Hc8zxS!-ucE{X2XoY?#vs_h7SKTSCp<$VSc~p zXXf3dU5{3-F?PCgz;WN5C-WN98Gdld1=O6*7E zysA6#1;#N(@BGelf9WiXFWo6?Yy9a;g)if=US+5m+w@ou|laR~Nt8W!< zW>pH-J^uAxe5>f9iT4cui5=m8aI1fFp1fJlBmd_NGJm3lPJOSwR3&=m=_{j+TYQ;d zYXKVKxcwdM_ss5-{PQW;BzM`*Org(;o)xSoBNGIoY$yGma-PBI%5u?tHSf;1DL*tX zu=*2OZn!97azcDuj!L1xL(yH`nwRAhjbvEWP6|9PEsS5daP_@Z4`}=87w^o>H3f@6?nmlZn4(PVm2N(9>in$ehtT`}g6J84TwS z&4_JQ_se0-e(I3)&fo93cD-hez4_s@emuM~4Ds{q9~%A0oF}pCgT?nLJ&qTCUP@*#E-}v`t0&B|# zr453IB63&UTl7BIj+sO8&tmyH=J*Edx6S2G3qNPqyxedrRJCm*a~Z=w|M}}1%@fV{ zFmal>@8EBk{{F!VZqw;zI@WF5b{@`%VJzvpu#@Y4P`zAV)Ao%)&8^@0_V~`9UR|@r z&}8G(E|;}7$-Skwcc1F{;;~)4Dj`v2OMUPP_G6M+j?str%x%^%Si3VKN5Aa-*}jF1 z`Ug`_?@l`$K1br$wKb-}KFI>s*=5g9Kau(^!!%_Vhu&8GsIb4=q^p*)wRC%}_WISM z;_Jl0KRN$I)55!7w@*8E=rcnMkNTXWtJKPBIs(|E6>sv%zVY$ZnjQ7@YAVCqPZl}t z7rzz0n!G|qv3g2C%(uy(Cv3d8=vIpK>V0b&?nD;Ml2?AYc}1W2LeVW%DV9{=31Y*@}Kleaemd)p5YZ)JC!oEYYp^7Ria6NR1RFsUh$h+paHA}m;E3k>R95>IEx@)i_`$NM7NAFvc z#18u{(r-RJt^91$X>p$&JatJE3o~8?2>vy1Fwj^k^t0cpLh+T+@BgREa@yrtt!v%x zU0$8a^@sh=g55l}OfuXlJzPAmlCs1f_-cH3(kT4&##^iZf0QhQ

MJuv)6z_vBT1R%k*RVJ5Mg>;Fo@WGBHOv*r(e!P`LGRrhO!H z!NIb-sT{XeDmee~Jbuvqp)@XQ$@`LLcf6D4&A*hcAHiR~e1BY8c{PL2^*&!Ap$P?l zultnpuRL_JXl^*y)H=_J>cLAz^Q|6!N}2KC$s6wnrANhXq;AYqILCi4_Rz0Cl4sgZ zC;r{E?!u;Z+M@ZIdO<55YK3H~r)r7%$3Oq}ol&iZGwjC8&zod#Pk+0EYuSNbRoh>S zJ{8&3+vLdgT#RitbM#%XsrWhH%e~Q=vXSX68k20~o1ZyG@X0sVbvVg9`mpdzqs*d7 zf8-sePjA<23x6Q_qREVbO_8lI{Y&o(_kE`wwmZ%V>yG_b@3h=Bh__2jKG$1MyHq^D za5Lk(S!;IlB;ID6dx3d3L&XGt=jZVq`&sjUCC0yJz010!xL-f)W%{SW`0QoJ7oQCB zXU%)JPfPi?UV&H2UC*|+0@5CSY{F>{@?YNeooi&fp*}6;e8S1qU(^jQcP{KrjSXKA zb}(zl70Fo%&+JyJXf=8{+{rxh@SV&j(TLt%EUFhbm;cQD{y6hT+dCGRzK@e#m{%B=$ zYs7qq&3Yl{H7&N^kC?kkyTlV>uixukG3WiiAj2<2~H z1u{-sUP^eC!hd<+otYJ;H!g0D+T|SSvr(l=%qiuhxRv(<)s_hduZNb%<}`hN7{>6A z_uRSK;5?s{~S9mZhqS^)qtxZ z?Ce&Nr}DeF4`edbichotwsnqeD^o8E*Plbn53KFtY%RXGr-h^9hQ=PzDn&lQfVNv4 z(uqtGAEqrVo1wE|&2_fN?XmSz@zqIBKKp+b{=vx*-*|d@>7z9dB@0eAbx!BmudyNL zcv$+|yB&L2yMu1-be>z&v^M%}WPPguQ)Xlwb3W4s*J9D9m#0d`aTG7OulFFa;dB4v zH+SFkeYn1*zx*ldg?H!K_uXAu$9%8g@AbtmjqTzNFN!idELOoJcBsDSU-6wH%f<4_ zcbdBlKlshc_nseTrl|Pm&BNGT+AI3ZA6PNWYq)H3J!pz?iFiUZd%5M?LtXOwV{ZL! zsQqu6Jt0Ve>wSA5XK~1p8?CdFE;1y?{`?{1aUh$ylhteE@=1?h277Kfdu}oJlTRy8 z*T1>X%yVi7yZ^)&jvRr!lX8AF*|>#%mteSmImY#8$=jWG84v6&&|ygbwqfPOcIg}T zoCY_Ku-JL+WZd#*2G_!iVb9Nq7O);az{0Vc%_`b=#iiQ`ToYerL@e3eR`t#EF6)#< zjA{vA7jk`DYr!t}!SmM}*~pjAKm6Rxy6Vb45jjhnXn7t737-zlS+fowb4U_cUAThx z%Y!Kwd#gomC(O^9HgTdm`{XxIx)V?C$O(MTG~wQ_y>)@1pOo}BJ(XEtz*lzg=ec_M zeCb&ka~Z{Mzm=|OaVR;u#;(8Sm5|+{qJ#SY%yaN4pb+v!qzU|^m9e15MBUnTFl zUYRYCBdJ!)Cbz;3Xn&o*yX2Yf)M`_%^OM9YC+a?DXgzcP<-3-;^sL_x z9yzNt=r!Hv>(c#ldE?nNO^*}RdfIb0a4T)qbL_bzCil1dos^r(xroV^fB$$@b$99% zg)=SjuhuzsY_jBCuuzZrnw-axvtbpY+YXrA=r!F{`9i(+@j~`EX`clm_boPRiLxjk z6&F>HZWWNb5_qv^hw^Lv$mgzxORn!Mc)j9FaA?Lh5wpW)3~UP1b}hQc@1)_9@JG&$ zyZxZg4IcH-S9MFdQ$l?o>)cfpdCE6~m%ZU+Mzf`@%!b%D z_oAIGeIkGRbww`22p0CYeST86Z?NufIbRa~yxienME{~kQ{EVHx-(cAv$(O!ckrd3 z*!+9asdG*tvu#rDsq}kX_#?cJ??BdbkI&A3jG3a2&E_zi)4PG~T+>z2J;6UUR2x(a ztkyI+e(Np19nx1Nneh1OF7DO*=U?b0uvC?Z3zU@o?_D!v^$Oc1lcXJ{uRn30b*H*^ zjd1n)52i0(OWE)xDQ;EI$!Qi%IA9|2RwqaHtqt4a*!b&i?urTDRjLrZJqm9MdtK<-z40 z;x?=Y{(jIoZ@Tem(6ds53Z}{b7H(ft_0jJxYtMld57h;q7W~SOcvrjV%IiBD7OoXr z^&;`s%gLg%YD9Y4!XJiav`Dxlc?vi5eh7=NDXM33{&@CP$-@t7Pe1Q{>VM$*gLs2B z^;xCj!VE$+9D$K`U9+FQe9!vHyQ3=X{acrRJonii+?5Rfq29nJ$KRfmD;Az7VYUAe zdz81N;QzW8MV~*kJ@nr9&*Yu#X~qhMb59C0_O(7co>?{Tn7HZnP$tQ(x_|Oy@63L_ z>e21OE7O*C{WH6um89?JOP3obWEcx@e2SXTJ}D*X0kj3Z#B0&3+)YpW}ClF6-3(ed|}P4PwrCU%TU@ zJbznKd`oqLb$Uth<9*K4Wxsq?%G0>*%vxD+SYT_pN`7s4IdA11?qo%l*bB>d&k#DZ z!?T>#acWA~q|dubrU!m6a@!s%D;4dtzUS1d!mm}8qE)-t`Zr_;>|u%By_j1hP~us@ z%1^&%%#tiS9nE!mA@4uN{=>{4YWe=Mo}77grMujBsmc5gzj{70=wI1mMN&Jn$}{mj3v>9HbHmj;M zeBx!bAAEoK%ntC~J<9R7j`ciK!lg8$lgsBu+iHZ{R4u&Ba7!z7$>yo=_wG8A6Lo#V z>x&!sbDGy)U^@_z(Ys(dqHM`Z7buC+ zv^K}oyPmB1ZS}%8zC=lM{mYj32ioV(-@E%{@d~+GuDJH)2@Qpu&+=F!zRK=3Wp!Ft z@x|%E1kUdXt%@vdpSMe}&YSmC{lr#zpFQklM<<`$F|%j3Zeg*WiF2??rjyXUrqbF@ z!;dO$k4`<#j-It*MnnDlr}vxP%AQ!hFBEFy3RDfPDoQT^lw%1gpUW27I5b3OfX#Xv-{XpY;i>hJ{qL$jG%zdMM(Y4eNVZ2tSP zR*`9PV)~5^h7GK8ed!1+jhHM z-mSlew=yN$|61h&PX<|qskgiL@?C4Vd(xPzup|6gpQ~ua*Tvq=pI3gBlb2h5Znxa! zSO_E+^=2aZq+CnXXdv zSolNv3$ywS4#)^zjNdJ5Yo z?&pc)Xn(qEcFMZRFHbF=%9I-D;xYGq$`bYc%C@QL_kXHsr+FQYWC>1mjQF@J>Fl}} zDKpm1;J&-TIwz;OLg%K8cap}w${o2fr6_q;zO zC_ho}OyiY@zeJl>n8n*STNVBFbKN&xD5|woT*2m*F+&qQ_1>yWgB94yq^9ts!OHifXS7#%Ta9XPU-bYMsF?)m?dyu+tyN9;{0Ok zj>;L+*4ys={!P&(bw@q7|Fxf&-ua5GbiNjG_jDaoSbt9bzGm7Uw#p0DqpZd$Qv59j^%!#gsxJZIFLzmTIlzwY+a^~b|S-f!QQu+he z8%s=U=gEI53zUA4cb)rZhgE*6Pv$d8tJtN%6E}OOm`a?i4FC4%2J<4{3^wj<2c$3X zT;3?+)77HZ)Rd>Q=;SFI2IWVs+xc&LiYX;L;mDCp2@RRLhTRpN@=9%O@&8KO zZQW97{u);gMkdQY&nlT1me3G%L}cLvDV7b}4kXkkNv&Z|zW#v60Rursy`u$Ez5P=*E4RA zx+nFr_o-y;p6v@;PZZrvP4PCeKlnYIL1$lRxnW)L?U1{oKQ8Ys6`!!ONI&%*+Xczp z_F?Nz8^1DWvJkuWu3ol$-`hb^wqxg3^J7;T?LTCwB=oNna13=) zQL&9~)tGP7@6vYVd*#-g?BMTzey;v8M{S7KW@Hk{f!#gcbH`#aO;4UcN3S3kC0t`%zHB(ms& za8UbUrU<_FH+^~%*ROCi^B(&(!*csXzZqF>vcz(_k3g#P)>7q zoy0L=`Q2@6Bo*CU<{2qPmjx@|^jmdiKI0aF!$t=myx;%qivO#1Dzm@abA&#+e9Mes zUu>D~q3P=yw0E$-+a|n`6&^kPGj91^%WTuC_$dpX9K3#NXQiKE zhDVgI;#KC=i3iucm{aK6e{i;ew8)wU--Kh6HhOeK2>f=?ZMptX#DYKJkI>nt6;syD z)$@LRhk3y_%?6qLwSG$uEi0?M(7Gc3T{v@~a9#F6MHfRk`CD83|Ek=TXO`gk;h(SV zYp4G+-lv>#TR5Z5EW7HR-KjcK+%+DLVo_ z23j|_rM+m{?(E!}(|p4rNlS)laRT!-z1CV8r?-(ct!tSdq|V@IFM8K+xIDRU{g;@g zZP&6~r3!xcu?W-!rYW~xIsbO4Vza>4HFrx_rEkr>q|Ug7W7^3L_J8yb9I$3QX47Oj zcUk(@uu#6A51w1!t2iN5BF->}>6>x>)O%JnPxTjwZk!iwxMT7Me~oX?zw?SRU_t^^R;MXVbM%kJG<1C-zUA`Zb&* ze^SX+-Q+WiWop()Y~th;w3#-qImLrPx9O$x1(sO9S;9xI^)of3H9X$_LhtbBd70M? zE>C5cvp(^h@&cQ$Z(G^_ay_`S@ysu~W!GjrEv()At;x5*Uvs)R2}4Qsa4MpmiI#OOKe>3m9eW|Cv-X|Ws%L%wKK$JEWXVyDXNH@! z?j}0RNd?+YTGutH)MIvzB9qou>Bs+~YlR%T6RP;~+D=~Ja&RfOTx3DRF^^<-czK=KtW9nb;cHr&hreRdyZY?=?SeT(wzC@l}l5 zVxh`;T#Ba@7`LcLuDkz*wesT_)@)EKvXk1+k~nA2d( zH2-RB^NPmR4E<(t-_{-fa_(Q|jguMO+U6fFOs?|&IHB$?tB8TL-ql#=yQeZ3)_&^I zEPHQZv2ecYt$OdkiGKyPH*eTv(kK|@d#?8O+{8m&+eNfR5;uq}OOm!>j5S~t@nN2I zsOIyNqV)BP=kJqfyybpxQO(iAm=M*T%*p`?}N)+gZh5><&se6mDsD z>QVIRcn(E3jTr1P$~v}+g@VOW#`WuVODOJ1+p+!Mo4N}(C#R^ah|BO!So-vFrrWN~mpML8 z$SV0ayMe_;;mw&7EguEi*A_5cv#HRYmU3O;;-fy#m<0=jZ^)$G+B9*Bwu|c(ooQDm zty)rdSO4Yb4i6SJm$M~H{)a8zJ8xdY*Ud{7o!TSfko`YL#l=*H@jRoA)huQChk0@7a^NZ-0NW?y&T_s}}F?^Z%`WXeRe}^D!$IKJkNz2^Pn1dcWQB zlzYnRsw4ZkP6kFb8s54YSRkV0xtd*S&JoFu=F})b3yEik{5sr(g&*V#+`UpAbf+d{ z<2H4-J394@W^FU7qJNezo?5<*|9yy3kP6c`yYlEb&bF2nz29u=nSJ82T$Wa?zlGa2Ph&pH z_q_YSAO1k~oqeqH$f}g~gFX(IaK< z;tu9-*tn-1_^-NF<;$V81)3rMg3f6C*W2>>#QN7d*W(qBbZoiq%M!-qd8$Pt-u>G8 zpe3x^G-jtWWmJdX`1EUstfJR9@f)mMkNoC)J=7IH%y3!Dz{XD`m3d8LaOrf#9n$9* zJq~@Df3@t|Ef%Ov^b&gib z_q6w3;1-o=Qq_7FIpf&Jy$rkUPae>mb$TWHCF`TX@7B-X9v^%9=i`O-%fC-8$`+pF zxBu~y*C|#Lw=BI>zLaa;os*>}mm9QjKf8NVSi<@9_AZ~3!OJfis3rLXnP~a6at3a2 z(s~rNVuzC>#}uU{8NRb>6AmE-!i_yh-5al0_T& zu1hMmXe_w<_2|?+Nmp8?Gi5vses`=_$oYA>!XJ^e0~U9ucHEi9u&3U{_QJ31S@SQ& z_}TtGW_4He%F^i%1Mix$++-|ZW$^zf-#=kS@T0pczL-Z{p6imVdU^B9L+ZsUjivi0 zo5p;Yo6odV=PA#Nu%l-+I9qx-C$MlQ8E|~-cz?x7^R(3J8H~+^!K!D%A{ei|dogj^ z)FZFLKUrHp^p~wX$E|qh*6Xhg(>@6)9_jFSvBtCFhiA))<9`+P?tg4tjn z8}eEWWLEF)srvRY&+osocb=y71}v^#XBIyDnM1(g_oG;_<$euIQ#!Vf*E6 zZQ}QRTh&i;WCXVLtkb+?chtI$@x$@^8((Vg(*8J`w_x9&JyEOMkAGPAf6AAgUC-1@ z!UMkdHNR6*+bs}b@zJc{|2d84x7W0~E@Uu&FMgzT{aQQium1a_?u2W0ILU8ukcnC# zc_{6c@ALz+=G{<{U@%TJwRT=|d%?xHx0@C#{aJmFt+cP>N#3G)JFPjlu>X1~@W54g zk*t2e;T&NI`+5tQT~E5?LF0tvY#Ie?9_hsjIZ=j} zr5bi*Z!+B=*1#yyAePb8*>!S*a?+N>ixKPH6DQP$2-?WLTsT|c>&d&NDix2df{m)a zdI{;a%r5%-)gbd=Am^o8r;1Zn49Q$#EeEG;d}*5ev8?0w|ARZ#U#@fMsPTKSPrl&5 z)?KGpm>s}O!Mf7d6lof$19}j zgnH!`v7c@oSC`r!Qeyb^^mE$Tl21P#xweSbN&Q{bn~dEV=vw!PE(^H#EB_d6R#U<*Embjy-ZeT`Df9aQb2XuIvvR zYaeByuV4ep5J*}{|YnbOP2{-mj9nxctPn! zmK{^nF^=x66B6mF@eB+FvU6hQR{#4eANl$1t2~wz)sIL7Z_~*w4%F#T#3N^UoLOuKMZrYLeF5P*DlXfV$tAG4b-^`&RcR z9F%CzyTRnZq7<-T?&p79wW8GulICyqlcX0gKKZdsskeuBx`O|YzLpXtk6WAn{hIhk z#93r{8{?L#b<5_Jf6emT71VKR*PPSlMW1TV?DH#Eo%cm*&br-g4nK`!j>_M@!IfKo zA-3oJAM;Dui>v%r{L|TX;O#oG_{iVB)9&4$I@Qw7Dt6)SnQVo#68CB)oqMhN*1i%*mES_?rlfcj?T^L2Jh-u#$6AL|DEo+{nzooqI${+ z-9LYT@a-5T}igxdO~yADO1 zImNE$3p<|gzp53%%GRR5c=iIvXHnxslM73}rfaS2OWc&K_N8ch9!JWe>AuHaaO%IF zaPaP-`L`~g|D7Z~EzNG$2}h1*ZPD+~C9PCXC8f??DXo5B_NQBcg3~{(-O6zMPfWS$ zy)^y=n@j)Biz$hT=UZ-&lwGFlRJs;6VykL_Q& z_=48$NfJvj)@j>nkYHYD7Q*CXFjwz9s|>?tk-c3mhwgA(ynC^E?*_AwYm$mCxj&S| z1ixxdh-dZOrEYWDJ^mou>(#-W6EB@iNDQ?3K9T>mC-<4lvCa;64t-DCD3zrDV%?G3 zWxM_x_ihy1?sqk``@amQ|I2j;U*9`AspI**pKGtoXSyz4ZXXxDMWoy=&Z38}F-S#` zk4=J0q-~LA{rSIF1?~!4Gx5A=HcwP#xU9WLAn8d;di0B@e|IdDY4p%&>EF5C!QSp- zO2V2C3;6i=7xxyF`!QvRTMBH`h?DKte!u>TEboR#>~Abr2bDkfzWgvyV(D(4`k%Y^ z6h8gTuqJ8J$yoijd*6uuShKII=18#qbMb?RVwmUO-M^Rf*uAc7M=sq7wHq9*v%}h$ zq83Ppc$hxhc~UEa>14}IrUMZ(IC;BP)^1#MO6Y2Exa`k0G5eDQ7Cj28oM|r16=`jT1RC93=kj(Z|FY-YpG*Yf0>0GwU1fS9$o5ca1Jj<{x~INby}20M%x}Y_ zU+|Z=<^}T+@fUi>nAw7!hcz6XZl1a3XmT9G4THvBgB82Q{_bP#wTZZWm^JJ|+74cc zs{dzfm=aw>zMkFL^mh4V0|vv(uiEQgG|Rnc%(&F0wl?FR^tz_l>ZHq)uPs?(x?ESN zb>p|$e$O55-M(`BUDunX-9=m2muo+rprGr`@I!;;jN0u+o(HZ4+13^phh~~vi+p4DkO?`NWb>}BV#5QL-|E>Ro#B7@_Ax5*?GGtey`}r? zg~b0q^}9}gSe18|b;^N;fO)Z7dcL&5#%xfgFVC4OX`Up22zFjUm8YEAd^@BC-#*5Chq>#wCwtWfd$ z4|T#%LhRn%%ssZbmDAjRZ%Emd)7RS*@3L~7|M0u9{7-acC~NsvAIYD-bzA1Feipt@ z$lqeF^#k`^t1mn|ZP2wjd_zRJ;;tHDsgmmf!4DUn;|`k;|K!cF^V1mHT3@zoD3i#w zx-9YY_y#te?Pola?sCuDyJY3oEnL?ex^Gn%8)qlI=lXC=*X!BD{!>q1a2yHh==yvy zEb+Lrot8z#p81oOvrVer>G4qZ-c7$d)mKAr2(G=u@uH#j!b<;7f$Fn!ZX7g_f5(&e zi{}8Rf!6=6^KZxP_A>dQd0^((E0bFDneKcv%CF~rU}_PYZ)^JO%iq|QTf4HnorHuE zw8FQyJn~z~c;%o)tKyu}g@Jcg8C<99asI-)>O-R@%vYL3zqHU|L}3~jptQ&r-qzYWq4k8@%z3#lUY7_w|6Jbd%a&x zWsZT>%Q@z;)1O#R6^O3>y`<>aDNC_CTNk~#+-M-4X1VN zF!k$pzNK~d->pBc*Z=bCwPgpEewN;)y<%T`Uuie{uqRfkW!%l7N< z1(Q_|JuQS*eQKVN@aE-DtJt-?`|U4Ga=XeLe`N8Zs#~cnc^6fdT|Z>4AMokI^_T{` zT~Yt;YwAq?KHH*t=QgPi$(w_wmM-(Ci@8zqFTTk{{n?%p-7~8S6+^%2*qolYYxRmn ztsnHv%nTl@HAI(84|be?``q2h#W8hGXSG-E3V$H#w{QBiKa<}yM1SrPW}EnXEe&T@ahwr|=g?vOqITpQMXZu@8MoUEGq>ftL>OTB;hv{(F_B_7NgZf5+h zzHR=Rg835KU)B2+{yxgSk*aCn`0;(0aH8Id35J|j(aK*e+*vrzRDH3i-+MHCYW%#t za`{ScK7O(}Wc@R<%cfxI$6F3}uRQP-RM}-_%(*Xn&9~o*>u&zs#=b?oEM@iI4V8(K zx%XBsS+!^XjJlr}f|&gO&RHZ;`$4N--{$P(JD-zsSFK#(yfdHY_}ulod%QM0{%UW# zY-i7@9kL16Yj>U2xc{@}^Bo!S`0&q8ULTF?zFskyd?%>$`pcfh;?H*-ZrCfyv)dw7 z_kFZOd5NNnVi$XzL%>RNYx!K(eHvHY<3C?-Sl(9u?8(7TDzUQDmT%MU-0Ssht3wQT zZ?xY5v#7lX%iprTc_^)TpY6iF8xwUWmrvXH$ocNxo%QeMipCY*i+Py$&nE2oO4fDV z2X4-(mkJ9$durv3n2!tk_x@MjrL8gf_2~x7U#m0%m0nM3ZqR-9TWIo~REhUco{ zBQ8(tM7J}Q+~^LGe|{)GI92XRl4?%DIqA3?-@pD-e*X7vTh@nvlf6Ej70FkNpXU`G zoHG05acj+0E)VOLq@I3x;iBn`hP*ku=KYSVID66kzuyk=$b+&h4=1*M`th$ebI+ce zQwlg7^Yu9XNovcs>xJ-V8JuUiYpR>>B6qg*p~KqMD`x03dY6a?^2Kj={&;s`-}#5; z{x9bIKWd==chaBtx}p`@U)>&rtzap4ij7*ivf6_6nq$TcNwMR<-#ey$I*>MT`t|?if+0>LBEEXk?);j#!?R6|W&ayEl_5BhVSHAjf z><#HY!GC_QwS9VDanI84vAGj(t`b_$KJV`APd}vNT`PX72gj}Us(!V+)jjDKpX9Yy z9}Y48-I6b~N%BcBf9EQjU-MM?eJ#Ci$$$QKLuLKjW1%hyVyn)`9|?1DWi!mIcd_|V zSh$3p|H?kT&7#4R-kmDm|4)u>{nZ^4CR*$N-G6&$uClo7%H`7%s+YfGa(lMf=TfXw zV3ft0{;Rnw?#YB_#Xq;c#208$vLTB*H8E9oXVr^Cm-;f+nm3e{MYhkc|7TSkGc7;Y zhSwn}nZIyyq3@A13wM8e@H^Zxw6dUZ&&k>RwMR4g@8+!Z|55e&<%(S1w=dJT{K<;j zEw#Q_fA!?40l(evh@aPqO)L+6{<_=Lehq_8)BOtT2C<_Tw(`sN$d>EtxSniYwl~0L zp5|hfQ{Jl$pPDw<8dyF4R9*R7H!W`c!bJ~#pWT0;bT^dclJ_odi7@*uJO2Hie~atn zQ;mw52PbD%nf?7#cTeK&&gFG}E9W_Lo%u3T1W12NV5&l-ezX^;|LVB}?wkE>fBp3k*JZ|xyXuy%Yi6?W_j;3CF@H9<) z>+@FUfRM+>4}JY}FmBd)uE3sIr60fj2wu##e%jYRO>-uHduO}ol1jrmlbgQlg;i}X zT>7`$BksqAzVgj4P28VnsQi6!S&FN$dq>}o?JxXlOFO!xEUsFXm)?46$sf7$;A4j5 zy4jCs1)8o?S$apr=&k9C#UB)GIJO_GPWQJ<|FlE@@JHv%E6=R-o;CBe$(Qx5n*y?4 zm~1jJiof5Zbou#}Ct<$~Vy??R(|gi<_}*iW>!FPEeHR;H|?$@!8TW0@Xw_a$zmUXL-Y?kA};}2~&tM|^b z{kin!aUpUsi77UtAc{WewduH=1gW~eII!F zs{w1iFPGx0c`O&4IO0DR*}T2lzhl|HNc%Zf-y@INFIdkPxW{^qvH6CydCR2quAAIH zlyx;EQ7ES6l-#S`tpB*}ShXKcy~x||c=<`;@%L-j-6%ZuF0-d;XK~lmGO1Y;L%(Eq zTR+|w^YZhC#Y;A4C)`+ix_a)W2iyglvZb#dUj1I=YS6jO%eIt0ZPj08yY5kARO6B} z?z8Z8_GoC{h77=!ZV-*iv@=p=tR*p+Xia%s3ikln*MI}6^Y zmcP_sd7u{ddR8f;sbp)_hSsXJpM{?9FMDMr8g}^Cyc<3YRSB|xxc@!fm8d0K)*oD^ zzU}9%oEgfQVo6KScYHZvoxGs%n9N%^4W6V?h8}dudL#lTXd|l%Y5^r%`XMAGUMK#n)3N>e3?T|<3u^ube^&@_T%?k zbvLMf_Ly9mZW2-$R^In!#_k_I*1LbYO}u`KefA&cdAs+DdqnLi*K@GplrhW^e99fs zC3_{|y1t65mIGgiYKwqV1vm~BTUP8;FBM;Km*bJmR@QAy0%d-z?{t(Ewi#`HdB*U> zb<3TfSr1%fFZgoe)BiVDtgCZM8&$5!etVX)Z{pS&JJ-+UoKx9R`|swQ;63H<-Yu*; z?H$zJKUH<3s1t``ivZIEhA0qyXme1miBQ+e4e|*q49+y&OnCBsiI1S?%dHzSHOl9m zy|}r){!31SYo=^KmkjS5wle~T{Cati=X8M5;YtV zTYkyyxHWT)!>(Ly0Ym=k=pvV^m6x9PEeL$&qBQ$3%Fz#1%QIai6hWf$blPV zaYY9wr@@q<2(g?dHT4X$gDkAa4+>r|6gl}!mTj(7d`+=dmEA{&DMc%3L~;#7R-O>^D#DSp~KOCLl>h~J(*uR`I2PRuKx3p}R+ z3U4raCps2Cnb5dnuHAjk>r0;>cy}Ot=b@worXKcIQ>l<8rPD9JlQdAA>7msTd1UU# zb7kwZx*aDk6EG3zbu#+P(QTFP-uC)&!nLaF_@zx&{lKMK=YS z#29!uoaK)QrHQ{OaFg5}SzsE|^JvA)o~#k@t@vd6_I;9XYtuDUjkY4A>q@q!oazl z5$sH*U@e1MF0pNm%urLaH}efti+Q|S=}CONb36g}ztxAek| zTN{KAwf*YO{Cm{$l|n@LVO5@`=dT~kOweeElW4HJv0l-{Zkmiqh)9w^d-a@~u@9uG z=G=Ynbny9usDyiV+Yh{Yc4ArMkJk$xuvlbfMK8)uP|N9c4QD?0S3*GD?8U23IqgRl zwgqrhCGx8z7|*$I#VB>d|I-NvRvOgaa#6b(yS`GQjzhkA{ah1vi^uY--!*Y>)~Y$C zX;P}-Vz;Z{O@93O8EXvJaI^<=gDNZz#g-M4l8m~bto%@s%R6z$<_FW;_0qeOHY=@c zD|_&!@o>EB(o4_ZTbbXKPjeEQB+%TuVW;Mt2Dc7|0+#A_`{aD+^pTccH#AnLZvOKPvVOHZU+%wy{k7>1 zj=thsd0!4Rf2e-2#8STD_NI5m_7BdmuKZuGbKdIh=^3k`!5s$6&;rbBzBn_zV|TYw zo+6y!^!UQZzd!VM$XF!pKew$dwLs@g!&ZUY!gE<2B-9+D58Y9pmcu2To0!bB#o~Jn z;~nPcMB|($-3^jvi-VTGUogYG)=;NilEJ63`C;&d{lyO$k8&No-L)*Rclm*T0*t#q zw^`S2V}575fwAn^q}+{5?shy5@ZkIA-Y>d6E-NGQ;2a&W={L*Z<2X2u|frQ(U78z?D=*N9!Tcd1i+vUNBji zdcN;pC&Q5ihD)R-i#fmiyzhU*@x;jJ!-X62^WV5euqS3T6(*>ixog0vv_V#_wU@JV zVNLbwzvp*9V^TS@aGG4+#UnvKRL`_V+HQ2T*kXCfM&SO=Vg;V(mceiNkN0QoS+8ED zyHR68_KJ;7c`sUQ4a}zXIEZib3sJXWlyBUB=yHK|%$~*XUwE$7XWAfj&51jPqx{gG z$(iQu%Ul z$%cfQG);dHV!;+y^e)Tn zOq=|ng}o2;nLqH%d8D;Ky3A3+XY2OLlNWY=?o)Uu7oZ2q0*WmwG@-2^nnYnW-kesIH@2|4a-mR%c@+%#Ww-t8@Y`1RL;AnpM$NVX$1*;uTe8ID?U;6e<^IRLx`XF$| zX7#EAFOJDYaGvK=@w59p;jeuBuktIJ>#n99Fp-#=J@p<>Jd;RIp3d)&&_vhM^99;m z5XjDWuz|5ffh945%UG2EQ2&D;rgPuNUama3<5~0r|8piQV|V3#Q1Z#?J0p3&hHnmM zy90-a%EN#Jg^f&X3q++BaGq(o$!e&sJnz+#^VV~I&*4*dT4VlA<`4I_Cf4|dqXnEF zjy?N+aM`tKu?C{c91d9?Rb=B-QdAN<)5P3y-phY}Zhia5=(4)ZpzO~}u3ht7yI6f| z+|nC6QVzE#+W9n=JM7TBv$Vn`GP}{3eRw2W+Pi@_tUuqX zrslG{sC;ON)}#p%9y-mk1`Jw>+ce!Y*%sd4dH$jS@3v*PoSixDJzR2Lnqdb+T%)(b zpJUH*^KHNO@c!FAg1 zR^s6s#|)FDrH`BCWpnNC+$zky6%A@8enbvpDxp%1-6ut%tN& zoL(sCT7Xla%_>G6j{{2&Tv~g-&HBOWb6eGPX5T2%k-291L84^=tIlO9h6F|%p3@Js zAJ011l>bI5MWK-0hxx#}2YcA09xvl8c65~CIsHo7!>5(sqMdh3LUz8-L7N%u%VN(+ z&)$Aewm^Lk^Rcbl{&4pdgyykd_~!Ba!iA$V=>>IluKNlE$7(V#Ai4 zV2~*obSIy`IqX2)hsqyf9=~+JQPiRb>s_2yxp7zKp5cUyHnra#4c^=DvE6uS%wT@F z^MlqNp8X9kg`<@gOZnZu$FI|rx`Aib_ift}xNJDNt)?;kzgTxdA%??tgY2Y)iwj#O z!qx&D%8?NE)nR7NYi0d*_SfS*8@@exoF>a`-|(G5f6Z?GcT53X2X3*r#n%XIJCMfU zZON;DNT6`(dF_V>-rf6Vm@Avme#CyJSzo8_fv4;9y-eHw^(?F?J$ycR_2B^NjbeN% z$4uItCtlc7QN(y;L8;GW!vlZyi{AzMCa8Wdn>LSgiJJrShHooP{|g)K3;pD*1o1As zr!#Le^R~msABumtzk#)sU99YX@8R!1RrfHo=e@U2Dms071Jf?u>_78f%s9C={?5Ja z9AXD6el*p_?~l&fzO#Z~Q3-}e6qhes72@4f##K!w_kpotlen8_+I-j z={+g&Uk~m2eW0&!?ZV8fRcmsO=qh>Yn3kwGpUyid$mVfGfs<_wgYd20)%_BeuQ5-Y zc4GYkcDKX(_3s>Kh`axVWe(c`-gR3y@-9p0ZL>Ad7m~8x_VWMc^5=z zdCBitr{9cCuoMYV`r*uCnX0%TLu6|F6_%sj2{w;id%R4##19$^DE(x0HF>4Bg0YF6 zjq}9T4cs10r#5PQH`S?*-)wyO>+i+8s#cwUIdA5ycdgeyU+kaxYE^#i>*%wIzn^WM zzf1I8qjN(34*mv3DJyopHtB|D@z0BQtN#&qouuMu5(Sbj~6pXSGS`P&uT-f{QQ2K-2A2?5_@>-pe{2~xI@1YC}*T;V{PZX0< zEMBt6?w0MR-XWt4LvBTaEXMZsLVIWg>AaC#9%Dl=4(o^RjyUGy5B>iyX&AsM1 z(l;-}|4?!eS$I#tV#`J`G4uQX zWq(wBT6gEy%n-I%6{%J^H!cyS6NW;nXKhbC+VtY*1@7hzoO#X7VfmIB2haRYw7hdG z{D&1oy6W;6=Ho{;{@D0?p2_a-*&h_XIN90BY_I-zJ^FQB+vlL$>{n$KJtwJXR1$&nwqA9cSS9VDupMcV26B`CMb}b*eQbzcr>TdcOL>SphBM`)+aU z2T}!=pI`5*H&K7-Ne021_Mo?)kH7YHGUDNAaWG+Ot-5IJd9D}i{S43YbSjK=5jywZ(y8u!1CnO?<=-1v5=q7KD)a3^>*>+2e=zq zjgS40QSqFl;%f>H&v!-~s~>7ryt}))@%_}Yizce=>6LskhHE#3dq??}h+zfNQj6IuMlNfl(jG}!(;!R>x}4t&!NZo2YM z<`2)mC#OPRemwo~Ka;0-*PV#InEFp{?x$ZCd)({Op3ic@QbKipx{24T1;r~lc9${! zXH>V@@XNPauY#ZFKvsl}P1KB=#z8uBzq~AJ=T-2VAHUiD!$pGJ8 z97L8blU1Cbyv0V^CGf1(!+)DPP#I!ESlA8l8UDD!o)puj&9Yu^xW+D z^m|7|kMC6B_51X?t@VogA&2XL--+^mb!$F592Hx_4%&curc<6Tt}blW85I7{Cka79j=BRzg)6Bss zBMMSbPCwLhul4Jf(d%1sKHK?FlvJ#wTwk*z&ayd@ z@@g&`wD9ebKc~&&XD^kI#y@}eDo?h(JEpSp%k9@Uu&*o+dV0{JR&LMVla0*fKdlr4 zWPEk?LzQgH7D^|44wgN`L%h?lDY~Mn1YAZh@ z`@14O8^ewEOTtd%wuKAT@zs2dvMZIDZ!G zq~6Hw-lQ))DGa)vP3jBsjz?;8s}~*3-1BJb<+{7?IOj>NPf`B!xMewSPTTzOch$Tu z8~EQaeLrONqyLK5tm@!qcF{Ucra4Xzz8&mm`tbDje4D=qV)um^JKt4$v1?u9ovW+E z4n{xLJAZ#~>vlOCcDZ+F?=u`fpz}lWi}Q)r;^WbkIkso+$L(2azMsv{i))4YYVUty zvwF_`ZQfv#_v+G-7O}FlBg>=h3m1K_ON&`(A9z;$=X-`ZcS_ilublj`cVRm7@57AT zRcSu&MSJ(CzLY${5H)F8_;;6t%w^}#d%SP1e|4f&|GDV&<@f%v#M$aze><=K%dB-v zej3dVcYFSL^ZqK`1JBoKg*&Woo!jnK_DXxoF3ar^|6=l845mVhxzlZ-@f)(exCh+?B#t8>o%INX@3@(tKj0xCer<+=)j>ToGt%n%KYSL3HkYX zk=V81=zle3mbGko@;3G>Ic??dRsEjaF0;e??W4=C7v8=+J)c2(0mt=&uOG(!aISgb z&1-xnU}hP=v*0I&hjA7%65IQ>zKq)35wKj{e(n;@$S1i4ygro-e@!+>Gn}^C!f^tT?VZ*eo&Ps#?S63EBev?6VZ*d5eVy!_{^haLOpjmN-&kocQ+<2om&yev z5_~T%ds!TAsd7_e>G}N+UM${OX7zu6RAlzcVzJN_cOMvUsM{0tFllf7RvtC!tBheb zUp6ldda?ePwR+UQKM{XkZ&3ZuARo1T>fPVZmK@XdIyFuDyzxI}er=r@l^ikr`c40? zMn79~|J$#*X@9INcerO~pL1lK$6u`2RUWRlJJxN*q%FxW=bfi`orwzpQ~$-{jYr^h4Jpk?bp6Fzu24mCfBO=-GW*J_Ii9-SOY;&F1i_=Knb) zq#hQBJ7z5XV;Oe!@67LVhnip8Z>iG0{{LZhLE5VmlY9Rk4w`+i_|clxKaXq_Kj2t! zp=o9{dt2JqZJ**bE@hu{vh4F zGyM9iTT&6GmyY&Y@7l?=wbR)Cg#NMIb1z{~YUlH_rRx`nb>X z?{eYa<%OEHb??3F{J+RB*j@XlBK%vvG5>Hi)8UrH2&U)$8IvN)#lCt^+M@hwmDBrc zbAR=vtZw!B^YSOlX`j<8eCJ=iVXWV9PRaI-$C@-AE6K?}zwCOLygsI$UHOW!vfbTN z>_Qfsxi4M1F;mcB+nc;~PPvb?=f*jl;Ru}-weXo_RqwF?YqfjT-z@&Syt`K9-1Eun z)XUGI1$UaIe|R4DdgPp-`e)b0M5ifV67#M`h8G{(SbacaP1DWU?KAHlmdyRSL2swj zHQQaCtl#EOSIKPO((HEcZCv61tB31n-~FtWc(e2B!L;MdA@eUC&g*AxZ0ZeAE$wFzV7gc# zS-82UD)H{#<^N6WHl8gz^YG%2@A0z7G78tHyzdWNzkg}k3ona`uWilZXZEg*J0-KU zZrej<_evU-OhsRd%m5Us^U4z&pK&p`EJ{N)|YOy zJX=|QZSCsG=N{jTTe|yldKUAGzU|Jo#wDN5zw|d+ojYk!m}sou@-pRfg=w=l&D4@u z=rw8HL%tT~hkZP0dghlU{#&1`RR8qv^v_49Eg$cf^Ytwd4B*IiTYPkLRl`!@_eW(G z&1(1+_riZ~Y*1y%yWnX5s%t&F)4$p<3I9mjD{01jVZP1PfJrKz8)XeY&AZ_$z4YGc z2Tz0}r#ar9yz#{E%==Qiw|YGaVu(FgV;$FV>!$s3`;%*~iG)s4@jcUcVRyp2w+C9Z zC4zVt%=dU3XVR#-|Hr4G)ldCpnRA+derWn}Vcq7wxV?2utF`M**Issba-LtOG~Mp~ zv97<*?;Tj)A8)Yw`TYlshoT$Hr;bs@g$ z66M|3{`>tnC!m*MRVmoDa`lr1HWz(nJds!L(Gve(kXc^Z{Or=&+E-q7zc&?q*^_?R z{$BXiy()FP1-lL(jTBwHByY>))I9 zcH7@adj-u8tzD`pdRUHiLFKPG)0mlNE8Lf^&*b^(q<8Qq$BBl`L)l!%;qpV{Or^`IZ$VD*Q{ePD>vkB zcztW_^27H&#LT!JzhM8OD-Sk)%KSM?=iB`F@ZCa_=5KcXbYb=DKYlNcFlo=tx`>21yB@P#E+Ut8-KZT7qr{V4MJwY^o$Bo)sfw>1sZR6Jh= z?L6i6;79IG>*79vqk=G|%W>eATfB z(;n{P*5G}6@_eSE1ivTOoYk6-&IRsW9m6i0?(Vj3%@sAm^*$knZO_r&=dBj*kvz{fhjYDZ+9t66Y>9cT%6>VC@tdNwfRZl22g>vRi!D5=cVXe#E#+&}9x=OzT?=GySRenL;ls+u5}rkG{AIZ3FxhNX zy|>Z*aX}4tPG-6xIE_yLr*Z359Bqy7?{Gaye7)>#eB-J$9sU8K_pS+8dI%j`m-JLcBHplo^#8up7Ft&)!KglFU{XlAqyJKQdy}CE`_Y#D7?6v`Yu=4wpOBQ zUvYNT`9oEQ#SSMQNS4#9xr^@V)g9uM2nPGnO$w zIxb;WaV@@e>+KsW?eE2~9GSbozK-=kr1~5l*B6Z|l4O%#N8K)Ym%;R!zsF^2ej<0x z@(7jr%s+0G9uQL4d3=+t*16damaButE`z~im$6DMnH~Y(XPsZQ{F3#tq!%5jjpj@S zQG2)Wgoj);v}$^PBsyMO)J{LMRINJ4W0Hzz?D2L1uSqJUt(+<6n@_Ih-Cx(!d%N-Y z;|rE=d*Uy=xSi-PcVp*Y(QQeQsd;;J{*|8NJuu1a(sRzM@t~UH)C|TgDxR16-fWq^ z#r)qP(IaOU*cXIUmB+CAx*V1}@4VQ0>+WsWRCyP8Px?~H_4Ux_dY9iKi5kgG`3>G2a2X8dY8(iA2YmP z6U_40<Und`XbezgyLl z?p5-kjiJ9nNuIJY7A$en<$tjB4x>)8`{d$#P`CdT?>`O}Zj=H=Rz zZuq%otLNtU8dc9pOI|+zUf?-tiR_KSUcM{Z^>thJY%SeUr&*A2|G=VsfByVppZSUF zk-0#_-DtUbdz*;Qt9oZYwher`&`t*wG?SJ^FTBh>LB;dZk*yM3{a0P~f4;Cw^uklk zPk&o&o=Bg$>{j}%LXPc0yRgOQ&HC&wys!P(IG=f|ywenx3m^M)17vzNW;lRi=<+Fs zs7Wd>GuKVAtAF?O&QFyBbDQ@+xgVwT*zt8AV`F=uso}IQ#9_|H@A76FKkp0Eu~UB% zKl|3@C8eG<87yu*^Fe;eOy}nFoV4WJY3Dqr`)B6eeR4zYv&ZuDA70e${_uxYd@B2# zYNZbqzoz^sf_cL%)>+=6@-bgwWA^N5NRP=BDEt}7*nZuu-{dvm$gVVMy<$utp84oJ$m#~2o zO_`6p1=ERx)1`QSe3@GK_Vd)wzrQzfuyN+dt^~R7K=KBQn}S)|3-%Y>&5w=_@rYad zTCPWw9XdzcmI$?W+yjoNjNK>?Dy}7xmzF zfw_!Cg>vHcS%=k+@Be?_Gx<9I)p&vF2R1)^#b9e$w}08sNlYPE{LHV{F~8V5sds&V z*8h1o+(9`$vkDTJ&C{H3Pq7hsn4ckVu2ThXsD|aYZ-jLik?M=m+ zgP~jj9A9@knH#=)`)1xAwPl~8*9dL_4LmOed)G>T)`iHQH8=QJEMCuYOZIDf+j{5h z;)~`F=dl_`7%Z;Q5T7CM^g^3q&i`2(Gqv|C-(&yI;+JXpnD?o?Bv-swtWwrb<~uAr z+h;EYrMg)b;5;iEs!(HgGcKh1$NP0p-mhcXcBm}E{fC|6+$;YsXB3J@aKB$YZ|gJb zN6-7K!@OV5bPGIEt(W_KiErc@7f|~n8C;}U&p7xa{K0*uGjCT%|Jx%Vb}YK}ju^wD zRrz)Dzc>wc>+iQyd21i!dLgv%bNrO;^UVDOWCa&kY;4MVu<*+2ndR|9|L-L)5(m{| zCbnR&mO04VEZS0d&Gdl7<&EO1(mzuchv?a^{{DRfr&5LgQOU&T|Co%cgREcWTov7V zSzz%#S+{?RIJ<_Z zRg5B^cUE3t|9#;3Z|?cc`iD7Iy3R4ZCh*wYSKKW1+>fI>ocEb*yXnUA)|msG|I@%_ zV(u-iSF-LaIezV(9@w)={$}~DdI8th3Qvly9rxMue^__A<9F#4Uh(B+o{xWg(Qj0J z+WrM8g5Z8rHweer}u;|XOpPx?6UCOg-f4~d<2`1%n zQ(|hw)-=BT+gi^!AKAl|``Zr_sXVwRCJNWY&rwT_;2Gs(cM&PWv=VXYj`6n0c=1++l;%*88MFD;N z+kH*=`X|kQYJJLa-(2wn;{FN+^$!|VI@iex*LUkWEc_U<^NQD_0^9EMk)T8@3{J#z z&BdP`nxi>qW1MV>-qyf-_gGvt*xVQ+7!TN+%=r3$%jTA%FLSt8F4x}nsq6ax{`C*{ zTtDVn^6Nz{BUAe2OCdW$R7*py-i`tp_zjX`bPmLv`1Zic@nJ2S~DPSN*U| zpl*BNiY-e%$KB3IFp2v<=~2sd1yHj{3sR6pC}!@B@p*c5YwKZU1EvFk4!&FSEv4)X zO^aQx7ASa4dSNjwR_1;GqN2No%l}!(c@~{|$56wl@kHZEnpxeJ1iqq1jRGAR?&H2+ zE;Cp>7XKnD_FeQ_+j>(e<5d3KDTwK4zb@}K_sIbjDxn*rqqqFFV7P8R>-A@KhW5h` zdHedW-4y3YG>@3H=l<4D1$)}|``#0iinWroVLE>3&E4m+(_cNmGfnm6u50WsPJjRQ z^riIfH-De%R%d}KBWosbsprQPpmN3K@Yl(=8TLGWQ1Sa?Rr`MF8`)*~=ikJoeP{CD zvZ={w-G$lbzdn0;w*T#$lb0v2k2tO#SH+&A=XPMK@AKK5r8zWVQ1N- z?t32obG)|O{(rn7^|ir=-6z-hfD*!KNJ3b%ZCd%CSNF2hoFB9sYTRGb zYBolTmLRs+{XdKBY8D=Bc|Kh(KcetbIb(%M-R9eK!fwU72-tfTdRjHz>WB$U)*$%k}(1E4_7Vlk|?B{ds3w4c~*gqHAZw$KLyO;c3e&t0%2X zi&yJUDv97@$p80!+37X6RuovAk(;r7&&Qv+k&|x4g%p3`IdrT-^0eQ&;!oxGBkuJ~ zih3#YMDYOEj?^wOP0vXxD@DPjgsgbi*RpFj%Wru%_!iVOcZ#V=FYZnA=*+5$3|X@G z{VtQQ8iy|B?C0N*m3#N*w8LE~F@NP0-d0O&Q~f(j-m6SZvFWqaoKM@6`F+ zUW@eERz=lc*~uobOre3V#_GeY3A5hJUf(WY>bw21hW$T=(}&Ft{d&82_O||Y zw~fwB6O?z<04))i?X+B6!E@3VAMu20|9wXfDhn)#n0>JBlX&uN`9J>WD$lZneX?NK z9r`YYr(gB<{EWm&6S6X8*B3R-U1Nme;iGOm4lcvINQT+dCeq1BVQx7F8e{-5R_<)z&{6HFTZ{k%Op_Kke}(L*1n zN8Y?t)im{jcUBz3^1mEEgy!7+5&b6e>-T+o_C&6~-3cn^*FcJ%AeQWhj1jwQD{7xE zEb;l1lJ$JXspkS_;`aF;WRssSPs>uR^^*s~0@`vA$9JU6f%dH>d)+(gLoGp69ldZdg}Uo_gX}qjJMsg?G(0C7&hjBlg$3 z?)W0wX`Hw)soS6k__b%S`^l-iT;tdLxw_NVDK7LZBw_T(1ZPZ5Vkev3E`}y;i z9DDd-QrS9-#OkB3D_$S%Nj+QY@}WI5vLEDmwHl6vDxR149&cvQnR|riKBK~xYch+K zSojNGEqzk-#%OWblOl_fg1--$i^G`;0zUovsxs|XN~mwq^Q@Jhp8qnv3yPRcDd5if z_f;o+&hMRAoX=7hYMHj-;LfXmHIwT9HK#l>n_I@VEW?{P*spc2L{%JO?B%iJh|7x_azLVR5?N z4#^#2eYrNz4?Qsrty;jI$2RZIFK32znFgPPc0Ai>TF<_H>--Y)>wbo%Sr2yWGkRne`CDRk@HUt;tgk%i$mb|EQn8$F3*FX10ov@Ae>a8GCR)HH)TbdIt($PuOzvH8GdJ+MmCCpZA0E4+bA* z{f!UVdx3BH`A!GlwO`~4ROSd>kDpUn(=MjwIZ4I#F(mU`^15NS>+V#Y#@h7nJ!jq}e$45TjhL$9IqAz8 z&;54;x4cfjE|8aKK+MfBdLFsN56FA*jH~58m<~Ke+ z%>De!w{tIR6a4b)OsX#Kx%aQK_WRk_(s3rM*)_x(>sxO!f1YMOH|vw{qUhNRA3pyg z@Mdr3jP$RBM%B6j9A_xqf; zukqQ6ckJN)7P0wlwaf7%*MGmAEIAqxB=XcM%k7vZH4VSmyWi3C*DDdEB!QWjAbziq}71+wSCOrOTJ%8`z zI)l|OFP-B2&620Tcg9DhH(ifkM(nS-o1KuE^@eT6?SG))SJ`@k3$#k`oV7&UogK$2 zSFN5MJtsfs#@r9~+1qm?x4*5w#v99*-)7%z-+Z01IeH%Zp0}#+SDU-u<=Am|Yn#}$ z7`~O4!#!j7mi%JgkafAtEcbbzy1m(snV0zvyUBnWG1GX!i9Sa)M?R+BW3!^7)cRJ} z?vHu7Ubj;YecE9CFldKN9ozRM$JVsmcYMeHI&OQJ_6Lv0r~MS1`B#3i^a^z_f4BMK z2c@T%&wkh7Li*5zvH>dw=O`B!g8H<;dj@$%_8N2!u5zgQC% zCyCS3U&rj)_Q7(MvH#H@Zr?@E$FJGr*HHbijn|o{cT?t%2hwtnjHZ!RN zC)L=cei!B}S)H4HA+$1Y<5PCgu%|npa=V-6zhAIOr&4pF=TftkSub{ZmT0)X6>U9V zn%^aM>G`LNtAgLD+HkH`ma8rJ%VqI?+wmWl#dY&`<$ww~;bd@Ls(jkACGeHh)t;Qx zLnZTW+lc$k7ri=#$6Twvk9+lerfq!xbMA(Tz1_ki=Q-)=uFuBTrYycQeeoQN_L8f` zi_a^1-Hp|LS^Vczude1FxplWU{QYw^x-Bff_Tig*-_O7M>&tP26CCml;EEZRm}#-fkAHP7PlC~=lBwR#4?g;SKe+g4N52faOw{_j#i8uaS3C>7 zXMd0D^_KQ^e+4eREH<3#=>CEIhhYrI^TV?B5vS#^z5D;6>R#QAig3^n@_G;m^ebqeTMb}Tsv}e+&Mg(X7ROZXV)D!y0PL}`c$`<#S*_IFD-As^6}IIizSC% z2pqioLI3skUZH;+^ZxHvZ_sAHF3;G`e`fc@0_8P6VIeISRj#ayP1zalwy}uUb5)#S zPRW~qt9x5+@h`j+rDB?^u=Co{4e~M;Kdz*|s8`>lQPQi-vO*2>xVr;{-!F5%U2?F<@|$n_#g)R|`@;|JWyopE&$(5{S|d8` z@WbZU{SC@&&-B&rFl=|Q+u0v;*2+0cdA`>Dby``=GSmCrE*hVF8EWfLWw^s(eyGSIso?I!f+q+3%+-wJ;{#vB)&?HiRWGu5qmN~{ z&)w2Kjl0*HRkkiyo2Tb5Kh;m?t>*VOJE>`hf(|Y9wYNe_&!Uf%UVP_2^I!eY+6j6! zYL(06J5~Vyer#Es@bbX9r-s)L`<_%i^|NB#l#=I{uAVx2WlP{I<`aT}?Tm4SYwt01SzV5jN zr*FISuIt<$&*jc<^V(|B>%>YeTmMt*v=@EQO4OO8XU^v7{!LW=kl={wE_wQWlX;b53A;XYjZ+_5o@alY-hyvXh z?~>r6ixD!m^1RaQ;ql?Y0&`b2Jd^nGxRLe1uY*_Z8?&>x=BzCT6-vuyf=j>aoyISm z*{;iRwe!8%)0Dw_XO>jJ)%50#5oTBTJi1>UJkw?VhC@{>1v_zan> z2dd54e65Gs%Hl3AsC4_YTd(zG;h}FMi;0!)V8^oE-~)Wxd@gwyt&Y!=NLeSc5g0S%bF zGJ@FmI&Ft!*a2_0>n2jd>PHh34t_g$)tkMnkNHJzb9UY;nKBj`!wm_Qms*u;-(7g{ zYW2fovjl#6SR@sg7Kq50ZdmZ`#k7N0!w-F(>^J}Px?J51kYBbehGe3$LY})vyb=mb z1$fsnu4|k<>6&D!_9T;?r|J)XV&nY8d-9+3!xgiNmz#k@;L8?pGT(AII&O2|YquSR zi$32^xS#_XxpFFc%nxc8fd(X2)`A@lDmj<fMN`!Kt&TW zEC^zcDjp3DmC>}}Ihs=@jTQx?MZsuMphA98@PGf_-+cY6yna~xo9ijeC^|uo#i=1+ ziL1cIg^M(_7I9?fuZXyQFE;kH(zm8vuWnu2#Z|UZv5S>;rIISACr6^kiv=PpPyS}- zQA<(d+*Mxw^>3ZryyGX&>OP-SeZKeeY~$xz0*Ff90a3{_Au4$;q)L8N@n~pF8ciEZ zMstcLy^4Ybz( zpKIijpy;B&U)HNvBUO};^+h*UZ4bY{^V_*LzrxxN)qSj&Zo00(bUMM-WdXyte_K}{ z-E93w_?e?!%+}ALHynjxI60qoe>W;wpLO_g0$WZ~<3-in1e-IBo*PO_!fSspbR{bC z=+{r#B=nFsg75OFHNo8T+La<0{w{W{mD!}gF4t+#w#KxE^L2ttiD$k>3x`XBsSVEo zMg!5bLn1FCLsRuzzD|fs^AwL@PY>Iw$e@3q>&3_C4nk5Ne}4X){J->R zUFjngncd&^eCqZ5+$FB7b?)z{kHNQ>Ijs06xV`>EZQ{p8uH4USO#aMB`>59(u(vtC z>ih3GZ!9f0AG>$o-jvbfgoIU*+rdMN9zFVb*)8twYQK&t+m`oM{9eo-w`*hhUoE9+ zv+nBE)@GH3m0fE|_sgHn6R`TbuDqXa#MZ*U%f(GrraTVV+x-92L4M0f%gx7aH*A$K zW$TaGotCL0)ak;toX>tkSG4Tb{vFS6@8s_4>Jm?@|MuZQSZbL6%TLqaU;F##-po=b zhoE04`|B;Wv!AV*6FJ|$DCzW$WGUgGez|WC-*^-T2HsN-FYDSKwd3JJ^WIsLto7^f z-Rabyf7|ZXiO#wCvu)m;+LAjn$m_p&_}W+_eRFg3`gc#RuY0kxS~NFeqh?ZP^u(4e z-1d<>|J`1F`El;f*sp%RrO`Soj}{)bpD}Uz{P+ofpDtE6yC3#5{=Ue%zn0$3 zI=a?l?K*KA`@*=uz>iJxa_{BW-zZ!^U+eYk3%`2O_s!W`ad+7v!M)qd7QEV)p0xe+ zy%`4OKY#UJ&bw)?SZDg!%4aF|Q}xiaNXtLxFD+-bf07Uw^%I2-x# zO?$BZznr)J-O3X^RDuk?%{rwwcT>=Vy`NrwF1!0+uTi~qlGxIc+>~45i}#B9}4XUw%O7}3HO|Y56E}N*#F#BOf2BY$Wl@^il zu@#K#nwA*|YzwKI;glg%E8FI_A(%hOzd>4?cR^$C1-YPwqHCBR_+&7=eGpc`H0c4G z1k>XOSLRy&Dr;zQViX(n zT8}?Cw(8p)-sK05r*f5v_q3E1nA%9)ea?}=Cc8kNr(^SKp$Z;9&3fLud`mAdT}l*U zaCa2HA#LTHZ=rGSUf7|n1?e+YA1CO0wC+vN+QZ3NApb|y>d@hW^rgjFX3hIHY&kPY zWe4lBBlnjyNh^v5EsWjL{gpvZOx%omu|eyo%#REgR-@k zZ^`^TzsuaNuyT%u$(Fiz-p{|^SRJ_d3*-Ck^#w<6o;|do>Q%>NE7R;NI}YzO{$*Et zzTs|i-i#Yxy9Cqqcdc`G+s$`;&$Vaw_RDUzo}yFp{+07BliW)dTYtx2kNNOo{`Ymo zZ+z=d?SFM+a-7%RqKu_0{hZoQ|Es%sYyY>b>-)}6uD=vt^J2C3 zqbvEVr~J*Y%et^;VeIWv8H=j#O|5?GQvzhJvB@I_Z zcdPkIZMS{xw6EaQwzK87ucoo@-c$eQo~(6=U3${{-|Or&zOf5G zOnYwg^+#R&+?xwCCtt~X-Ww(G+fF*q?#a&QeKX9qL`OwMO*fA3Zdo+9{PUgqIi(l1 zxxKfo-!CD%AW$F+sFPyJMH7WJ#~NOZOz(s|9(tAC%antNZ`Li z9f~3O2Rg2|>Fj^m@MX)iw`?}kwyN$~>!;f79$R(m@#gxS8rxFrt8(0`s-m__i_NWj z?^+#h80>tsPtwo!^FnKBo6?HiJ%96Ji*E`~FZJk%oEXcu=kHW)ulJTaTqhrU>3+vJ zGxp78vG>1LZrT^HspuB>b-p+C&yT#-4&83+Emr&YhN}DgPe1O&OD&E1K7TFy%JMJq z=Y3|*+Fkj2U0BcV&GGG5)Ou%^$XNZpp`K@Dan9Y}@SI)F$?7*V#8$3cxl)&JcX^uV z|8kL1y%N?0H4#^Fy_QIZlGftI+{s~er~SRVrmwvjGM6uW-4A=wzPZ~{zKVHW7xV3J zdG&VUBMH#v70;;^tZ@z3AF^A>Gzi4--<-f){{PnUYc)*13H~QqcQL$Svb?}jb-3gQ zPs7iEqr2xZWiW*w@bPGLGvIGv*&+RH=Y0h6%ecP&MgP4fx`u46vAIv4f>}2G*<{wyOF+1e; z%7VJ3+E-fn71`(MedcYhGZ5bNAa@1#_rnv6W`AiGUtoKtW%Le`UT-S}*q3 z+uQQzBDc=G6nc5z+_@Jv1irm-Up{~4yjjMHpZb^PX#FYrbBdY&{WO=CuNM70ZO+tb znzc+tOy78%@E}@m;1BbvAE54ZuHtWy60A|JlCi-W!LSO%db~{ zewV(vu5D82<@>*N@=xdIcdeT8Z;I)^)ib;6^ez``m9<#h4%=a%#c|d4*PFUX<+l2L zCEPhP?9;wHxw>@1ji=}TOMSj69{=z4qHm&hU7l-py1)G}>uO=s!;FQ=C1;}8c1?z^V|PtAAd{P`{LKC_V#}sT*;`trmq?Er&v>E$(vo? zK}B9gUnZDV@zj1;7ktZgw(YT-|4aQk_epRYFIr#U;IF+#z{5pm-Std|*RAq?e_xu1 zgZ4~Zl8<3wJ8W8D*`gqPu0igCBwyR&vbuIf3r4O)$r@gFrUHQ{4u)G=wi-yK9bgXi z)0x11c7btDLz_TbD1*uYfsE+Tz^a2^R=Gv0A5=Nf8m*{kb*{=X<>1B*B2tG6Dunpj zzCW1t<7pi4atHSlEsqy6uW4HRAhkm1*MYsEqC3{)yx^@q%&^1WPi6*#|KZ#VjDBr` zg<;u@t52nGH8gEXEHEi)nEtSg;n$(G7YuU~L>TJZlM^LnSly>d7H{QDbL^kH^0C+q z?sldEmMcwdsdcw`zO`PwdN11d25Xy({i7Ew2iQND>NHe-2r3D=;b$r9c2MmGllUQn z2!`p0zJ6qW@o$63vgwhRnED#i%if(RcVZMd@H@3_wmjQkt-G(ZX0YcbhLoI}5&O{4 zg7=oAVhsO%r*e*ib^=XuA9NXbAEa6ENQIQD317aoEyBh;KlbO+g}>DI&j=0(2$=Bu z;QZUuxOZf2v8&mCDNtEG#7@8>Wc~Y@wbT2nlD|EB+kNOP+x(sHr(AavKYGU8?CF_P z`Q;w(+c+1_dfRWQv^eo`+ewCpS2o9=kKSbSys_=S#s7UPweQP+tNOJ!e_w^ylSc7t zU-muOmoC3|#qT`BV^7KvV1RAUwn67_w*}ymzIQaI92mhB&8kv^X8*|+{M*-ru#}Jlst$HRyr--D{b@q z(rUML8m$H0o7?3--_1RL=62loQu#Y2_pbl7i`%dvzwy_Gr(d+v&e9$DqFqVE6xx!b?IYhV8UOAf=-6>;5HJ@PMaQP9pW-r2f;t7cuZ zgzUmKUE*%8oVvHR#Y{CWZ|9dc^RIuhWS@Hfk9~LQgm1-s`F7?_ei@lCrbZ(c~6uwkATgAlw`PMZ*SvT8PKbqrrb*|0I;4ep0FaE#F)Yo!)(faM@ zuZTJ@?Dc+CIbCMU$FJMnba_{(gZjL`9?#%7z_fxr@do?8Hu;C?62ZNdd8fTv$`kZt z_@5t0tC00;5a4N<7{H}yA)(iib|>^qrlI(y1$KM*-5peBspYrWK76{0>x#+0j_Yg9 z9Q8Ap_a-vTk(uk5q&z1eZCQtAf!di?=?BR>RL-?o+;4TSAOr{z6%2L+WQ~ytYA%?!Fu-<6C2@G=;WoJ2OTd;n+fAY~= zF6M`!42KFNV>r(~5UemdC;iK+K$J&&vkFi7;kf}fmUI~g<*6%4;7_oWn6usK7 zU(9r)wq#7a_kQA=wXS|QUe5_ne)0h zs+~@MXnQkV-}><-!O5@ZRUM98Ir*Jz)xYM)^<9Az0ys2cf1iy1C0l>~i0{<%YMVbc z7k|4`df@cx#l4OllO9c+E?asnIP$jN)i(e28TW10`kpRxw~wm2xcYE^$K35xx4v90 zZ4~@H=hE}5%cjR&SZ(%j+44KJZvW=?{|R`u$@68+vDBA~f0_8_-uiV#a`~Qu-`OeL+ws=-{@sha zYi~d6HP(wSx)>ZDX4UJtW?9F=Bv+@>U-#-lUn(Eo7ZrT+UU}TtsGQwToZrv1*=}I; z?p7Cb%l2EH%YIxzFjXLZ~dqx#MOGJl<&=+C&!$3m%aTTb2obajvcvcj&&FQ zeUnnFy=sxIcHqZHgo-*U*|S`+CF*fd!F3O73am&d*9c+eK~hgHtF@4an(!1zOiuSq$vc8;)clj#Ndz82+$!hb}vxBlF~ z{)X@81j)HBi%fQ%57@FoafZy@s|yVzyb{bx+Bpqa{zYE>x{>?Op2?=M49A_+cQ8pg zur#DpaJq#*Hg4N=?T}XmzgMEpmL?YomdS~{I?W$HK5yuI&Y{tB?op6*Uvoc01$))8 zpCJj^_iW|T9E5)`SUH7PNNrl6e<$>r_eDmH*4)VxkGizpc{noL%X?bw*K*{L8+UA~V@y)$u-nsGCv_Erx`bKT{N&9@|q5GGe>1Au9 zJVWpNGk3dJU+#8H@%P)vlT{mMEqWByIae!0#d2?W+Gpo?a`x)k$3Cl@zpOgTo*z5w z!6&toC)fi&*Z;h>4fBc8jf@^Yvr(P5bG2eLb?X@2+xw?V=D;eqr#mX*vRWGrt@p(lu7dY>%TqaTp4S9bbs_TQ{!KYSpM-n zKO|7G>CD-h-`DH@tz|5!_^y1;{^gEC+x4pVXQcms0UEs#GLZb%epi9@m&je z6ie_KCs;B(R@{3gdvd|J+3eE<4dm)(sOhB+T zdC0Yt%Q?#A#F~A(E-t(lemEt9k@JJfnTFq|*GE3}ywCFZAp?U^B4bXQ>ILqg1#Bh# z=M?$AG)Awka+hl|elYb#^iSRmdb|GrUAW@Rh9}(*w!C=lxj{U|L0zM%&Vc!r16#_0 z;|0ung6=+B`GRMM!oPg)#Go(T+_8(6Yw(vfe`EO4?74xluHo|oM+-Tn4R-JJlC?E! zULSq`?f2)Wwq^W|MU&5*6J35%H#_;^iP!IE+hdSO-j-M_y|U+399T&BM$ zd5LfkyWP)IFOBtNO8##tYSt3Ao>O>VS^UclIfd&Pd&2*!cx3)uKKtCtpYK+zob9xG z>+7jEEm%EruB0Dee0ZWMbhWxo-O1GQeOATqyZ?#o{MjO$r)&4N>u}PNLe+^Ilf~rz zEZ_IliSulq{FTyE>hWvW?Fc%Plr!(^$>*N#ytlT8X{bIv@_2Ur&yP!dAGYNhy;5W9 z?B%n4xS(ZCr0dkSn-8zl^5txVG%y3+RhcASlSDJdx_8N2RJ#n~Ow zd={^#K1%ftGkaYca9U)=#eWU&c8i^h-t+Yq&vuJ{+uYaLZMk>tU;L(oJI}kV<*zIi zQ`!FNV(Rp!JrTz8`6sI%KfT!=SN8Cpsp1r&>ZmuLoOXY=Snzn4M@p&c;~U8)u03Mf zk#P%^q}A_UN?yOEr>CdKFMV&6$=iE%$NN{Lu#~EI}F$Ul}760*f-!{vQn8NK*%r6pjmGMjviN!pvHNfM$rO@3bf$otKHfv3_! ztC_Y@x+ipR@Jv}JQR(;l%a zEw}UgmI~$9jj=(um%SBZ3yPX&kTBnM^Rqt@YnAp()E4S*X;}VH(nHty@pbRp;b+gB z@wpvXwSMxtf2Vb~-?e;`zx{5}Y2W8E*R~y!nmKdk@tFT9#}>Rk_3w4T-{+OH&DX{J zd%WnWy(_BdXbE&edFStKBNEqac#+r8T`Tuj7|m2XBsUF{QorM zDY!gHk6<%i++TTG%lP(#vi1XN5;18fcTQln{J=Ct)?p?HMB3f-ZF73T+-b1*Ox&cz z$f=*p9b{*S+V5qxa+VWuW_j1wm+ja1T!DX?^LHcd_J@KJy#Kp4pHDO3b352=VE8M< zeSxV@YyN{{Uf$LW$EIa|Je+MwU zX}|b^L8q7PviqTs8I1M^W-@$fe81Rx+j(1=ChG_665_RCiUIOz8(M%2bIJ3mZ!}XXvs>C z`}Aqaoj-5Z?A&Zu{o=^9i?1y=9>06@^}bzuQom>{yjvaj_t}*a;{&AhT^|19#5o<0}oBA&;v$f|gUhMXN`6ngr>FaNA%8Oi5aO`ip%JCN* z3@y>IU(fEkd030*%ipJmI$~RP?Oj(>dg;!eoi{hD@2@ZazxR-eY{`1_z?%#VjPE>M z97A3opWpx6EdA)LpTYYi%%4qc>~(_79z8wORQdVY`SZX2Yz)3NZSD%?W35t~lb5B; z`Ff|k_;XS5^8Q_Ws^8AAmGa1`eAH36x%gSibD!$Zx8gn?`+jU^-KxO*1(P?sKXdO2 zUweN`m1oL7aq}|IzRUAORZ4dJy4-Z)(R{PKABBM__ijHo_h0wyZ+i9Sl6|?i-c(nq zIrcK=|11ehym)BQ(W92h@^W+b+5Wu$xTpNO?oapoZ|&b#d<%Xh`~AD*MAh!DuI}f) zH6JIv+xWWVeVZo@GS4PuV=4L(G31K*ZQv2uV3ao7NMoFT&54^{Vy}DYiHW|>Hpe)NR!WX z^}1qN75{#}H`$T*-#YzY-}B>t|C;`m4_AG@h_k1!E+^`m$qV-GMfPkTz$fH+UJCpE z=E;_eze=4x2;2O+uh*vH`G3BMBmWMGeU0*oygm)xiT90O8W+mNf{vQ^{8b*o`2Sb_ z^oReOgMK`(-_0}Wi~XXKvs1$7t=oCzy#3et8#v|Kk88&s*909s2I}K@HWqO4LFc@K w6oeYBN?-li)q6R5>ECE>WvKYC$3N`ZB+ndGD4g|xfq{X+)78&qol`;+0QH5|SO5S3 literal 0 HcmV?d00001 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..5ce8976 --- /dev/null +++ b/LICENSE @@ -0,0 +1,14 @@ +Kale: A simple hybrid renderer +Copyright (C) 2026 Hopeless Tyromantic +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . diff --git a/LICENSES/kale-gpl b/LICENSES/kale-gpl new file mode 100644 index 0000000..f288702 --- /dev/null +++ b/LICENSES/kale-gpl @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/LICENSES/tinyobjloader-mit b/LICENSES/tinyobjloader-mit new file mode 100644 index 0000000..63d6ea3 --- /dev/null +++ b/LICENSES/tinyobjloader-mit @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2012-Present, Syoyo Fujita and many contributors. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +* diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..45a5dbf --- /dev/null +++ b/Makefile @@ -0,0 +1,81 @@ +TARGET := main +SRC_DIR := src +SHADER_DIR := shaders +BUILD_DIR := build + +CXX := g++ +CXXFLAGS := -std=c++20 -Wall -Wextra -Wpedantic -Wno-missing-field-initializers -Wno-unused-function +LDFLAGS := -lSDL3 + +GLSLC := glslc + +DEBUG ?= 0 +ifeq ($(DEBUG), 1) + CXXFLAGS += -g -O0 -DDEBUG +else + CXXFLAGS += -O2 -DNDEBUG +endif + + +SRCS := $(wildcard $(SRC_DIR)/*.cpp) +OBJS := $(patsubst $(SRC_DIR)/%.cpp, $(BUILD_DIR)/%.o, $(SRCS)) +DEPS := $(OBJS:.o=.d) + +FRAG_SRCS := $(wildcard $(SHADER_DIR)/*.frag) +VERT_SRCS := $(wildcard $(SHADER_DIR)/*.vert) +SHADER_SRCS := $(FRAG_SRCS) $(VERT_SRCS) +SPIRV_OUTS := $(addsuffix .spv, $(SHADER_SRCS)) + + +.PHONY: all +all: $(TARGET) shaders + + +$(TARGET): $(OBJS) + $(CXX) $(CXXFLAGS) $^ -o $@ $(LDFLAGS) + @echo "Linked → $@" + +$(BUILD_DIR)/%.o: $(SRC_DIR)/%.cpp | $(BUILD_DIR) + $(CXX) $(CXXFLAGS) -MMD -MP -c $< -o $@ + @echo "Compiled → $@" + +-include $(DEPS) + +$(BUILD_DIR): + mkdir -p $(BUILD_DIR) + + +.PHONY: shaders +shaders: $(SPIRV_OUTS) + +%.spv: % + $(GLSLC) $< -o $@ + @echo "Compiled shader → $@" + +.PHONY: run +run: all + ./$(TARGET) + + +.PHONY: clean +clean: + $(RM) -r $(BUILD_DIR) $(TARGET) $(SPIRV_OUTS) + @echo "Cleaned." + +.PHONY: clean-shaders +clean-shaders: + $(RM) $(SPIRV_OUTS) + @echo "Shader SPIR-V files removed." + +.PHONY: rebuild +rebuild: clean all + +.PHONY: info +info: + @echo "Target: $(TARGET)" + @echo "Sources: $(SRCS)" + @echo "Objects: $(OBJS)" + @echo "Frag shaders:$(FRAG_SRCS)" + @echo "Vert shaders:$(VERT_SRCS)" + @echo "SPIR-V outs: $(SPIRV_OUTS)" + @echo "Debug: $(DEBUG)" diff --git a/README.md b/README.md new file mode 100644 index 0000000..fbd4875 --- /dev/null +++ b/README.md @@ -0,0 +1,93 @@ +# kale + + + +## Getting started + +To make it easy for you to get started with GitLab, here's a list of recommended next steps. + +Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)! + +## Add your files + +* [Create](https://docs.gitlab.com/user/project/repository/web_editor/#create-a-file) or [upload](https://docs.gitlab.com/user/project/repository/web_editor/#upload-a-file) files +* [Add files using the command line](https://docs.gitlab.com/topics/git/add_files/#add-files-to-a-git-repository) or push an existing Git repository with the following command: + +``` +cd existing_repo +git remote add origin https://gitlab.com/tyromancy/kale.git +git branch -M main +git push -uf origin main +``` + +## Integrate with your tools + +* [Set up project integrations](https://gitlab.com/tyromancy/kale/-/settings/integrations) + +## Collaborate with your team + +* [Invite team members and collaborators](https://docs.gitlab.com/user/project/members/) +* [Create a new merge request](https://docs.gitlab.com/user/project/merge_requests/creating_merge_requests/) +* [Automatically close issues from merge requests](https://docs.gitlab.com/user/project/issues/managing_issues/#closing-issues-automatically) +* [Enable merge request approvals](https://docs.gitlab.com/user/project/merge_requests/approvals/) +* [Set auto-merge](https://docs.gitlab.com/user/project/merge_requests/auto_merge/) + +## Test and Deploy + +Use the built-in continuous integration in GitLab. + +* [Get started with GitLab CI/CD](https://docs.gitlab.com/ci/quick_start/) +* [Analyze your code for known vulnerabilities with Static Application Security Testing (SAST)](https://docs.gitlab.com/user/application_security/sast/) +* [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/topics/autodevops/requirements/) +* [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/user/clusters/agent/) +* [Set up protected environments](https://docs.gitlab.com/ci/environments/protected_environments/) + +*** + +# Editing this README + +When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thanks to [makeareadme.com](https://www.makeareadme.com/) for this template. + +## Suggestions for a good README + +Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information. + +## Name +Choose a self-explaining name for your project. + +## Description +Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors. + +## Badges +On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge. + +## Visuals +Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method. + +## Installation +Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection. + +## Usage +Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README. + +## Support +Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc. + +## Roadmap +If you have ideas for releases in the future, it is a good idea to list them in the README. + +## Contributing +State if you are open to contributions and what your requirements are for accepting them. + +For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self. + +You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser. + +## Authors and acknowledgment +Show your appreciation to those who have contributed to the project. + +## License +For open source projects, say how it is licensed. + +## Project status +If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers. diff --git a/assets/homer.obj b/assets/homer.obj new file mode 100644 index 0000000..39ae09b --- /dev/null +++ b/assets/homer.obj @@ -0,0 +1,18008 @@ +v 0.729066 0.624986 0.61228 +v 0.604895 0.602681 0.477149 +v 0.68282 0.625957 0.591549 +v 0.488153 0.83139 0.562912 +v 0.496259 0.815964 0.560873 +v 0.493874 0.183256 0.515476 +v 0.627705 0.592589 0.46609 +v 0.545713 0.756448 0.566481 +v 0.532138 0.215201 0.523515 +v 0.548765 0.157024 0.445773 +v 0.429567 0.811183 0.429844 +v 0.656983 0.63139 0.523311 +v 0.467569 0.625424 0.55999 +v 0.520696 0.191894 0.567572 +v 0.484585 0.183647 0.565393 +v 0.459822 0.763116 0.583053 +v 0.648631 0.67093 0.453745 +v 0.522843 0.762973 0.544232 +v 0.349234 0.619635 0.59844 +v 0.34474 0.624592 0.525353 +v 0.535828 0.759959 0.559302 +v 0.539849 0.819779 0.534833 +v 0.265956 0.635225 0.590328 +v 0.379089 0.626248 0.504301 +v 0.319948 0.634496 0.625179 +v 0.709296 0.659638 0.584591 +v 0.469453 0.177811 0.586228 +v 0.561225 0.669329 0.526511 +v 0.675426 0.643295 0.60641 +v 0.568188 0.782391 0.496619 +v 0.287707 0.649793 0.613886 +v 0.64258 0.66846 0.442685 +v 0.560392 0.770886 0.436396 +v 0.663078 0.663196 0.4788 +v 0.552063 0.745123 0.559114 +v 0.544599 0.189669 0.577416 +v 0.28207 0.653728 0.591566 +v 0.50425 0.960192 0.515405 +v 0.714148 0.641752 0.620212 +v 0.610933 0.64754 0.502251 +v 0.38296 0.405798 0.464978 +v 0.342307 0.613299 0.607689 +v 0.609842 0.177809 0.545954 +v 0.540501 0.919075 0.395346 +v 0.728997 0.649727 0.580899 +v 0.414171 0.829363 0.450975 +v 0.491097 0.861098 0.53961 +v 0.581404 0.39578 0.416057 +v 0.400455 0.554801 0.48935 +v 0.32039 0.655128 0.582286 +v 0.463853 0.160714 0.531159 +v 0.420229 0.839288 0.446472 +v 0.380264 0.196273 0.491558 +v 0.441676 0.708674 0.518638 +v 0.310457 0.64019 0.625684 +v 0.512949 0.511497 0.368557 +v 0.518334 0.225429 0.44094 +v 0.561006 0.814248 0.432687 +v 0.66215 0.623933 0.60691 +v 0.465067 0.748389 0.558421 +v 0.597119 0.161338 0.55566 +v 0.415783 0.598534 0.495739 +v 0.446098 0.32596 0.52162 +v 0.429482 0.923723 0.463038 +v 0.461792 0.159492 0.567895 +v 0.459321 0.162922 0.472071 +v 0.576655 0.805087 0.462656 +v 0.458466 0.190737 0.578405 +v 0.567678 0.160943 0.548047 +v 0.394894 0.161507 0.542478 +v 0.45715 0.546548 0.572227 +v 0.544079 0.46659 0.355892 +v 0.610063 0.186854 0.527366 +v 0.673065 0.595745 0.552865 +v 0.412676 0.416567 0.41062 +v 0.404748 0.464264 0.395378 +v 0.428141 0.159321 0.518486 +v 0.634715 0.643481 0.426882 +v 0.576368 0.466844 0.369982 +v 0.451652 0.79632 0.562539 +v 0.513858 0.374413 0.429782 +v 0.493263 0.176969 0.485809 +v 0.588445 0.236825 0.416958 +v 0.663515 0.62565 0.564627 +v 0.548722 0.748844 0.556573 +v 0.465161 0.987936 0.455104 +v 0.66542 0.638514 0.584079 +v 0.579973 0.266321 0.522648 +v 0.674148 0.637198 0.44712 +v 0.40716 0.157033 0.501208 +v 0.692776 0.637168 0.607241 +v 0.442742 0.754065 0.547123 +v 0.379347 0.297928 0.477319 +v 0.501793 0.842997 0.576697 +v 0.509337 0.914132 0.383803 +v 0.462721 0.882993 0.53877 +v 0.488162 0.747515 0.568442 +v 0.569663 0.922556 0.469528 +v 0.548698 0.736979 0.564544 +v 0.348764 0.643809 0.509742 +v 0.681804 0.634204 0.60597 +v 0.477789 0.629961 0.404689 +v 0.555348 0.714732 0.523188 +v 0.492198 0.446297 0.363856 +v 0.410147 0.599268 0.461904 +v 0.401679 0.161682 0.555704 +v 0.434512 0.858454 0.49784 +v 0.364907 0.672806 0.440683 +v 0.566258 0.162968 0.573644 +v 0.550952 0.430705 0.557419 +v 0.317437 0.628683 0.625817 +v 0.510364 0.849321 0.570497 +v 0.59458 0.428372 0.530031 +v 0.425134 0.828793 0.430676 +v 0.437876 0.838261 0.431763 +v 0.445397 0.215424 0.533517 +v 0.279391 0.634633 0.599608 +v 0.53488 0.628358 0.560097 +v 0.568605 0.80911 0.431433 +v 0.440163 0.3914 0.409618 +v 0.706531 0.605397 0.480768 +v 0.546454 0.635702 0.41759 +v 0.450421 0.803474 0.525689 +v 0.653867 0.612123 0.602093 +v 0.613397 0.179272 0.447326 +v 0.586846 0.45999 0.544848 +v 0.535504 0.450015 0.356987 +v 0.386051 0.162657 0.517173 +v 0.340611 0.635173 0.578908 +v 0.34337 0.665248 0.485405 +v 0.725021 0.625912 0.53773 +v 0.395885 0.675679 0.496244 +v 0.516836 0.891419 0.539185 +v 0.429522 0.261346 0.524491 +v 0.416314 0.167581 0.419909 +v 0.349553 0.610406 0.437073 +v 0.522407 0.163382 0.562006 +v 0.33247 0.584279 0.463306 +v 0.462753 0.184298 0.584653 +v 0.504043 0.826408 0.565187 +v 0.682674 0.657913 0.587951 +v 0.457587 0.160941 0.550577 +v 0.371991 0.618035 0.432455 +v 0.735806 0.633074 0.60795 +v 0.705332 0.598761 0.568707 +v 0.717071 0.610306 0.503447 +v 0.686373 0.636889 0.462201 +v 0.454825 0.448096 0.357905 +v 0.59418 0.472164 0.396585 +v 0.57332 0.818604 0.428167 +v 0.568026 0.68236 0.427572 +v 0.408156 0.616198 0.490744 +v 0.584278 0.635258 0.504305 +v 0.401379 0.499339 0.422944 +v 0.55347 0.162429 0.555506 +v 0.315899 0.573855 0.511306 +v 0.421207 0.816472 0.454142 +v 0.57074 0.308725 0.412692 +v 0.306215 0.578772 0.488077 +v 0.417228 0.495561 0.387091 +v 0.503169 0.367785 0.495782 +v 0.288826 0.632346 0.623272 +v 0.501344 0.996432 0.463084 +v 0.429979 0.711034 0.449616 +v 0.555524 0.782568 0.560678 +v 0.287701 0.633175 0.600101 +v 0.674167 0.645257 0.585999 +v 0.272932 0.619144 0.536222 +v 0.436283 0.423726 0.378641 +v 0.572936 0.49981 0.565014 +v 0.713149 0.63511 0.622944 +v 0.409473 0.17155 0.568059 +v 0.525916 0.712552 0.558157 +v 0.671829 0.643466 0.515655 +v 0.659828 0.612243 0.595266 +v 0.470331 0.756001 0.570916 +v 0.616192 0.162531 0.493597 +v 0.597383 0.18729 0.54322 +v 0.552961 0.883074 0.529741 +v 0.567036 0.430215 0.376047 +v 0.276864 0.628656 0.589466 +v 0.575889 0.797858 0.442627 +v 0.529198 0.163196 0.437839 +v 0.559045 0.861986 0.520416 +v 0.585467 0.159698 0.480178 +v 0.575664 0.244392 0.413256 +v 0.502435 0.885223 0.536741 +v 0.566943 0.498645 0.374279 +v 0.585902 0.828874 0.450318 +v 0.441071 0.602688 0.419908 +v 0.495053 0.83699 0.574919 +v 0.290097 0.596164 0.561354 +v 0.575306 0.602278 0.51985 +v 0.431722 0.52173 0.393083 +v 0.506903 0.194366 0.502903 +v 0.504046 0.417057 0.557746 +v 0.384848 0.161384 0.500924 +v 0.719551 0.636326 0.533802 +v 0.537569 0.904297 0.521104 +v 0.471809 0.979131 0.415755 +v 0.566698 0.18058 0.580404 +v 0.504839 0.957117 0.389672 +v 0.682444 0.645259 0.513288 +v 0.523286 0.79636 0.577953 +v 0.478609 0.764439 0.545216 +v 0.304313 0.581302 0.536708 +v 0.528913 0.892985 0.536445 +v 0.69956 0.643791 0.611035 +v 0.460135 0.937877 0.510822 +v 0.436908 0.744267 0.531844 +v 0.47906 0.755716 0.544635 +v 0.451347 0.197656 0.560405 +v 0.519652 0.946492 0.388027 +v 0.462865 0.161953 0.576949 +v 0.575661 0.598176 0.43812 +v 0.421721 0.799269 0.455866 +v 0.702509 0.594907 0.479619 +v 0.694116 0.659412 0.558997 +v 0.476703 0.766106 0.55461 +v 0.565846 0.654381 0.535419 +v 0.655269 0.615883 0.588 +v 0.411603 0.644425 0.425525 +v 0.579737 0.173534 0.578427 +v 0.540991 0.433947 0.363627 +v 0.467804 0.852722 0.54494 +v 0.520707 0.841779 0.399134 +v 0.563382 0.765707 0.550124 +v 0.612925 0.171708 0.546623 +v 0.559573 0.964554 0.447223 +v 0.488549 0.275766 0.471482 +v 0.544539 0.957204 0.407478 +v 0.492833 0.464005 0.360471 +v 0.326603 0.623485 0.590792 +v 0.46595 0.841147 0.545319 +v 0.553867 0.379663 0.529812 +v 0.562609 0.836373 0.432564 +v 0.574034 0.711723 0.456137 +v 0.5235 0.170491 0.435734 +v 0.562893 0.950869 0.47546 +v 0.303907 0.659764 0.582429 +v 0.420027 0.180056 0.577473 +v 0.560269 0.75859 0.551448 +v 0.293045 0.65324 0.608288 +v 0.327262 0.61645 0.57932 +v 0.661613 0.630375 0.536297 +v 0.45619 0.959185 0.497853 +v 0.577498 0.18865 0.570534 +v 0.54961 0.63715 0.556408 +v 0.462406 0.758461 0.578808 +v 0.424484 0.711678 0.461279 +v 0.481632 0.981142 0.493916 +v 0.488127 0.904561 0.53063 +v 0.515479 0.458011 0.584004 +v 0.380753 0.3166 0.455588 +v 0.498033 0.773727 0.40303 +v 0.459832 0.868734 0.53699 +v 0.553513 0.384794 0.411563 +v 0.427711 0.288031 0.523535 +v 0.431698 0.30295 0.529382 +v 0.667958 0.64372 0.573003 +v 0.461084 0.902299 0.521156 +v 0.456173 0.162717 0.42625 +v 0.595567 0.555859 0.449794 +v 0.444967 0.957314 0.485178 +v 0.45642 0.164899 0.491561 +v 0.725137 0.613941 0.560182 +v 0.591808 0.452183 0.392984 +v 0.304689 0.65552 0.596168 +v 0.709962 0.647383 0.617283 +v 0.274731 0.608123 0.552089 +v 0.65312 0.621969 0.583283 +v 0.335043 0.647304 0.50613 +v 0.323243 0.650523 0.567163 +v 0.275335 0.618641 0.576828 +v 0.486912 0.758914 0.584558 +v 0.413891 0.159561 0.476967 +v 0.268764 0.636484 0.571178 +v 0.368079 0.597513 0.451609 +v 0.438646 0.858116 0.514131 +v 0.550836 0.42263 0.374206 +v 0.282777 0.593 0.531362 +v 0.457661 0.170835 0.420162 +v 0.610355 0.165837 0.547844 +v 0.590634 0.597004 0.477663 +v 0.39299 0.378395 0.438818 +v 0.483922 0.74381 0.406137 +v 0.687573 0.632044 0.62873 +v 0.694793 0.648089 0.52804 +v 0.582922 0.310908 0.526311 +v 0.26793 0.646776 0.59478 +v 0.581653 0.51716 0.404426 +v 0.412003 0.563588 0.521058 +v 0.563851 0.855936 0.507268 +v 0.491235 0.727996 0.576277 +v 0.730543 0.647234 0.593082 +v 0.450658 0.42358 0.372408 +v 0.399201 0.179648 0.427693 +v 0.479473 0.164178 0.457463 +v 0.427804 0.448595 0.5534 +v 0.322595 0.649535 0.599642 +v 0.5546 0.771233 0.572002 +v 0.371985 0.592996 0.48031 +v 0.734634 0.628374 0.605331 +v 0.447919 0.856106 0.416954 +v 0.531036 0.174605 0.42547 +v 0.491505 0.385723 0.425575 +v 0.591975 0.408352 0.420426 +v 0.38188 0.19481 0.453804 +v 0.455122 0.975 0.428615 +v 0.332329 0.574604 0.503295 +v 0.322588 0.627419 0.58899 +v 0.447744 0.741376 0.558957 +v 0.388426 0.603056 0.480029 +v 0.696194 0.577129 0.504132 +v 0.526693 0.483541 0.358121 +v 0.453545 0.389316 0.409727 +v 0.567572 0.919448 0.431773 +v 0.716938 0.643268 0.602048 +v 0.387722 0.178244 0.445422 +v 0.427012 0.160156 0.564769 +v 0.468178 0.163002 0.512866 +v 0.405465 0.603528 0.460161 +v 0.649806 0.624631 0.598684 +v 0.422484 0.702062 0.445469 +v 0.380725 0.175935 0.53331 +v 0.436985 0.235076 0.413097 +v 0.600266 0.249582 0.423466 +v 0.683987 0.657671 0.567609 +v 0.518055 0.745935 0.573325 +v 0.426333 0.602783 0.521145 +v 0.506916 0.38899 0.423972 +v 0.308366 0.633557 0.628478 +v 0.501633 0.639709 0.555238 +v 0.42649 0.818182 0.471074 +v 0.461684 0.633712 0.412421 +v 0.433488 0.687033 0.509636 +v 0.422158 0.806117 0.434365 +v 0.429009 0.309861 0.412832 +v 0.571681 0.611427 0.435081 +v 0.491229 0.430049 0.372593 +v 0.408456 0.200701 0.420932 +v 0.474514 0.163053 0.47374 +v 0.68293 0.634627 0.598539 +v 0.656764 0.634327 0.584648 +v 0.532162 0.446423 0.57489 +v 0.49707 0.359174 0.480173 +v 0.439125 0.53396 0.565262 +v 0.489689 0.218699 0.462405 +v 0.56017 0.843835 0.523785 +v 0.46351 0.224863 0.521191 +v 0.494519 0.892848 0.534796 +v 0.597048 0.556515 0.502191 +v 0.412586 0.312119 0.417456 +v 0.50879 0.987467 0.418466 +v 0.533822 0.497405 0.586631 +v 0.420721 0.165029 0.573779 +v 0.518341 0.260397 0.496239 +v 0.487154 0.271244 0.454893 +v 0.604831 0.651877 0.423779 +v 0.312842 0.574296 0.497476 +v 0.620405 0.175118 0.469087 +v 0.558164 0.8745 0.524817 +v 0.520845 0.20427 0.534106 +v 0.547571 0.302779 0.519601 +v 0.526706 0.170818 0.583695 +v 0.484688 0.381972 0.522108 +v 0.571161 0.926819 0.451018 +v 0.570493 0.627753 0.429095 +v 0.562093 0.737421 0.53632 +v 0.453991 0.750944 0.550226 +v 0.525509 0.746477 0.551588 +v 0.460205 0.74209 0.571245 +v 0.487909 0.947674 0.5196 +v 0.489286 0.983741 0.413114 +v 0.444557 0.255276 0.523886 +v 0.565227 0.762241 0.534307 +v 0.53752 0.737209 0.573558 +v 0.516045 0.177134 0.546515 +v 0.50861 0.190063 0.525035 +v 0.283639 0.633237 0.518512 +v 0.681293 0.629947 0.627161 +v 0.421087 0.656624 0.508219 +v 0.61231 0.161193 0.515579 +v 0.665922 0.620017 0.603967 +v 0.657629 0.617539 0.538442 +v 0.449932 0.720906 0.546959 +v 0.465484 0.765821 0.539765 +v 0.620655 0.191798 0.465228 +v 0.488488 0.853605 0.557126 +v 0.301384 0.592508 0.560429 +v 0.519122 0.185962 0.576658 +v 0.33308 0.627962 0.438051 +v 0.28333 0.650483 0.607635 +v 0.269535 0.642363 0.604386 +v 0.424312 0.468097 0.368911 +v 0.548546 0.340903 0.51886 +v 0.328804 0.629395 0.592419 +v 0.428705 0.317606 0.529256 +v 0.552832 0.402176 0.400074 +v 0.49899 0.556704 0.379811 +v 0.409126 0.60525 0.482436 +v 0.36767 0.59119 0.466635 +v 0.335643 0.628974 0.564661 +v 0.553547 0.167143 0.507291 +v 0.608451 0.1717 0.556381 +v 0.525847 0.982739 0.418643 +v 0.392191 0.359995 0.499278 +v 0.612463 0.193362 0.442252 +v 0.6877 0.627608 0.626197 +v 0.389816 0.221472 0.509363 +v 0.334172 0.636927 0.524849 +v 0.4171 0.36002 0.518913 +v 0.42944 0.926832 0.447952 +v 0.530437 0.159504 0.562644 +v 0.485815 0.603825 0.396347 +v 0.477045 0.275213 0.501412 +v 0.585989 0.588018 0.451722 +v 0.565343 0.202048 0.414584 +v 0.485382 0.766531 0.550771 +v 0.50998 0.99025 0.482264 +v 0.436476 0.904139 0.424529 +v 0.653301 0.578875 0.498428 +v 0.438803 0.159278 0.457936 +v 0.505756 0.854993 0.568877 +v 0.51758 0.687301 0.407402 +v 0.560458 0.534901 0.565761 +v 0.734989 0.641465 0.595994 +v 0.438262 0.829345 0.507935 +v 0.422665 0.1715 0.579612 +v 0.465578 0.677884 0.542873 +v 0.53516 0.840296 0.54524 +v 0.433295 0.929461 0.431392 +v 0.266677 0.625343 0.606682 +v 0.548495 0.803635 0.528596 +v 0.532072 0.683693 0.412844 +v 0.558039 0.438747 0.364726 +v 0.57411 0.840899 0.47059 +v 0.432384 0.36399 0.414866 +v 0.468572 0.769247 0.545203 +v 0.459781 0.168394 0.58224 +v 0.544365 0.973342 0.482403 +v 0.398904 0.612374 0.486599 +v 0.415186 0.832364 0.441954 +v 0.462577 0.604879 0.404701 +v 0.554206 0.190523 0.568368 +v 0.444543 0.849559 0.531391 +v 0.538709 0.985554 0.450446 +v 0.661216 0.645097 0.509312 +v 0.525771 0.94471 0.516523 +v 0.577692 0.182651 0.578123 +v 0.427825 0.397079 0.411083 +v 0.627505 0.596701 0.492453 +v 0.334029 0.620732 0.568106 +v 0.594085 0.162567 0.43705 +v 0.441679 0.622877 0.424548 +v 0.430474 0.160979 0.549056 +v 0.504111 0.735588 0.5799 +v 0.293019 0.660063 0.56231 +v 0.683195 0.583623 0.471119 +v 0.421969 0.61749 0.50493 +v 0.565581 0.873973 0.495059 +v 0.463047 0.378682 0.527686 +v 0.669965 0.648692 0.503088 +v 0.56292 0.637864 0.547452 +v 0.598594 0.53325 0.518037 +v 0.570112 0.15839 0.425562 +v 0.382932 0.373952 0.469407 +v 0.435143 0.66932 0.516909 +v 0.506514 0.93546 0.382919 +v 0.51184 0.216377 0.455125 +v 0.499328 0.400654 0.41343 +v 0.486292 0.209835 0.499934 +v 0.678498 0.642111 0.620515 +v 0.429615 0.16613 0.578041 +v 0.47349 0.164239 0.439386 +v 0.311662 0.628182 0.626604 +v 0.596269 0.500888 0.418488 +v 0.687215 0.644869 0.48832 +v 0.627471 0.668255 0.494052 +v 0.470734 0.162653 0.544698 +v 0.59844 0.616597 0.439936 +v 0.439641 0.88344 0.517422 +v 0.551064 0.225737 0.528008 +v 0.570414 0.711222 0.49706 +v 0.474896 0.194766 0.570428 +v 0.465277 0.840581 0.405191 +v 0.381146 0.169416 0.515307 +v 0.456389 0.434502 0.363253 +v 0.515146 0.210125 0.503809 +v 0.510105 0.825087 0.554038 +v 0.59187 0.206631 0.527144 +v 0.483687 0.332355 0.444016 +v 0.337539 0.64814 0.440492 +v 0.570536 0.156152 0.435445 +v 0.474184 0.184023 0.583797 +v 0.650185 0.579827 0.480416 +v 0.60826 0.498492 0.510028 +v 0.559128 0.287772 0.522828 +v 0.618663 0.176708 0.532403 +v 0.448044 0.201317 0.416756 +v 0.470502 0.759749 0.562049 +v 0.570955 0.664553 0.514704 +v 0.525971 0.198162 0.555135 +v 0.482546 0.180573 0.577223 +v 0.479262 0.775646 0.587534 +v 0.611346 0.275615 0.501481 +v 0.679883 0.618745 0.44896 +v 0.463383 0.802079 0.567231 +v 0.469826 0.728361 0.573019 +v 0.290511 0.600532 0.485146 +v 0.545072 0.758302 0.55202 +v 0.569272 0.188397 0.574658 +v 0.432329 0.947699 0.452874 +v 0.726431 0.643001 0.603897 +v 0.485427 0.170205 0.455335 +v 0.559217 0.625794 0.424786 +v 0.517534 0.836732 0.55123 +v 0.487569 0.852455 0.545323 +v 0.526297 0.334435 0.42988 +v 0.427373 0.847985 0.467772 +v 0.584386 0.706739 0.467261 +v 0.533221 0.209515 0.540413 +v 0.567246 0.948822 0.458809 +v 0.518073 0.173925 0.577495 +v 0.512529 0.273709 0.456382 +v 0.564654 0.666164 0.423474 +v 0.426419 0.812079 0.46476 +v 0.694731 0.642888 0.506629 +v 0.462032 0.746039 0.54273 +v 0.441455 0.731959 0.521342 +v 0.704062 0.585886 0.54054 +v 0.426501 0.693833 0.435825 +v 0.44079 0.789275 0.536464 +v 0.441471 0.838951 0.524169 +v 0.589255 0.488724 0.393587 +v 0.276693 0.630304 0.597516 +v 0.415645 0.157087 0.525616 +v 0.623219 0.179147 0.488625 +v 0.668676 0.610948 0.562312 +v 0.522985 0.404006 0.543579 +v 0.400966 0.623528 0.494488 +v 0.516972 0.993654 0.467931 +v 0.70267 0.635412 0.620267 +v 0.505061 0.975758 0.402723 +v 0.352643 0.600059 0.518779 +v 0.460273 0.651212 0.554693 +v 0.277881 0.603997 0.519775 +v 0.403565 0.240604 0.420782 +v 0.447058 0.773973 0.572772 +v 0.453838 0.757297 0.55298 +v 0.58482 0.165549 0.422557 +v 0.445546 0.429241 0.554647 +v 0.297626 0.579703 0.506763 +v 0.712372 0.635919 0.602548 +v 0.569643 0.443105 0.553472 +v 0.587273 0.157994 0.507149 +v 0.427709 0.799078 0.473772 +v 0.484151 0.181331 0.548243 +v 0.510941 0.208813 0.489105 +v 0.520435 0.360464 0.431278 +v 0.440735 0.819816 0.429119 +v 0.433255 0.830984 0.433571 +v 0.293339 0.644499 0.619626 +v 0.606744 0.439507 0.518072 +v 0.590655 0.587018 0.482896 +v 0.563358 0.358292 0.522916 +v 0.534196 0.51774 0.373459 +v 0.271559 0.630496 0.591975 +v 0.450357 0.716988 0.532346 +v 0.721349 0.630015 0.592307 +v 0.610142 0.159511 0.47843 +v 0.620978 0.169904 0.534297 +v 0.590644 0.178652 0.566393 +v 0.457238 0.917654 0.397593 +v 0.571446 0.785703 0.45971 +v 0.583575 0.370483 0.419401 +v 0.403298 0.364612 0.511005 +v 0.606596 0.312546 0.430885 +v 0.565822 0.405862 0.401425 +v 0.536338 0.605954 0.404522 +v 0.447154 0.167516 0.508263 +v 0.383867 0.389942 0.478364 +v 0.447686 0.356114 0.415467 +v 0.616654 0.295533 0.444475 +v 0.613696 0.160481 0.533028 +v 0.484595 0.266744 0.489283 +v 0.437495 0.159228 0.479189 +v 0.470251 0.341044 0.509437 +v 0.429568 0.722409 0.459862 +v 0.453889 0.628401 0.556605 +v 0.516871 0.771409 0.589014 +v 0.590287 0.595572 0.464384 +v 0.548013 0.799866 0.557584 +v 0.330967 0.63794 0.540666 +v 0.477842 0.437021 0.571809 +v 0.564615 0.26363 0.524244 +v 0.389115 0.186106 0.526941 +v 0.53478 0.223393 0.52065 +v 0.472882 0.60382 0.559381 +v 0.561066 0.736276 0.517902 +v 0.539135 0.705339 0.538235 +v 0.402305 0.187706 0.542473 +v 0.297559 0.613797 0.471093 +v 0.467471 0.816505 0.540497 +v 0.476996 0.907706 0.527114 +v 0.441236 0.472455 0.359714 +v 0.411238 0.165646 0.564277 +v 0.559737 0.89178 0.503482 +v 0.497782 0.363695 0.453609 +v 0.402772 0.161694 0.445139 +v 0.55232 0.325432 0.520752 +v 0.346015 0.582706 0.468057 +v 0.712073 0.619911 0.495195 +v 0.425299 0.821365 0.428453 +v 0.408917 0.178426 0.566466 +v 0.549805 0.899277 0.513323 +v 0.606578 0.504598 0.445703 +v 0.328179 0.596751 0.45174 +v 0.613769 0.662909 0.426061 +v 0.480442 0.696382 0.547148 +v 0.580442 0.214894 0.5302 +v 0.530091 0.823809 0.541168 +v 0.456117 0.733632 0.568038 +v 0.658453 0.58371 0.519543 +v 0.345333 0.620531 0.584823 +v 0.696797 0.653064 0.599812 +v 0.386427 0.160648 0.534124 +v 0.437936 0.745673 0.516166 +v 0.456313 0.851358 0.541514 +v 0.497483 0.358266 0.467291 +v 0.507927 0.900191 0.531787 +v 0.446269 0.180451 0.577891 +v 0.489822 0.609961 0.560514 +v 0.505158 0.355949 0.464188 +v 0.437646 0.333328 0.522521 +v 0.655651 0.620169 0.610293 +v 0.460177 0.205291 0.421639 +v 0.458397 0.774025 0.581883 +v 0.577481 0.305066 0.528642 +v 0.4804 0.368089 0.42865 +v 0.47231 0.640638 0.558879 +v 0.620991 0.231361 0.489465 +v 0.471232 0.951565 0.512589 +v 0.500219 0.702319 0.55235 +v 0.272986 0.634827 0.611435 +v 0.301057 0.660245 0.561918 +v 0.523267 0.905045 0.52813 +v 0.535173 0.332426 0.512196 +v 0.520176 0.168898 0.544266 +v 0.271828 0.63021 0.581747 +v 0.512496 0.197292 0.52821 +v 0.485239 0.175873 0.567366 +v 0.31291 0.658754 0.569002 +v 0.39187 0.50532 0.452746 +v 0.442433 0.162088 0.553146 +v 0.322514 0.619937 0.584937 +v 0.452576 0.502539 0.580762 +v 0.547952 0.757043 0.546749 +v 0.52403 0.53937 0.580876 +v 0.477327 0.672679 0.548061 +v 0.682607 0.652799 0.608237 +v 0.408545 0.329027 0.51586 +v 0.489109 0.180837 0.456704 +v 0.679593 0.648146 0.49575 +v 0.433196 0.397562 0.534828 +v 0.520184 0.436189 0.57184 +v 0.609486 0.604545 0.45239 +v 0.457179 0.40013 0.54059 +v 0.610156 0.512183 0.470992 +v 0.450791 0.901012 0.51307 +v 0.517474 0.670715 0.548607 +v 0.302191 0.649755 0.532442 +v 0.616639 0.44599 0.497492 +v 0.459795 0.357633 0.519321 +v 0.281199 0.630555 0.594842 +v 0.460076 0.176265 0.585198 +v 0.385577 0.305688 0.441128 +v 0.552792 0.753194 0.549334 +v 0.437227 0.627661 0.544408 +v 0.575297 0.163086 0.499432 +v 0.535056 0.163164 0.512464 +v 0.501956 0.377622 0.509547 +v 0.586914 0.164621 0.563418 +v 0.489804 0.354261 0.449093 +v 0.529741 0.270141 0.509261 +v 0.393069 0.526301 0.472173 +v 0.511827 0.180129 0.453126 +v 0.589502 0.158998 0.450292 +v 0.301996 0.648981 0.604385 +v 0.576126 0.166552 0.577204 +v 0.539874 0.762699 0.539226 +v 0.363244 0.661112 0.431866 +v 0.562257 0.473277 0.361815 +v 0.38675 0.198158 0.507424 +v 0.480961 0.180147 0.438082 +v 0.424679 0.307138 0.529585 +v 0.529139 0.603645 0.559509 +v 0.6188 0.450659 0.461711 +v 0.544185 0.719181 0.554859 +v 0.502116 0.822012 0.557568 +v 0.562585 0.829029 0.50768 +v 0.523475 0.181434 0.43205 +v 0.583403 0.394488 0.526546 +v 0.622035 0.170459 0.488908 +v 0.512221 0.334389 0.480578 +v 0.521274 0.834888 0.545752 +v 0.60285 0.165056 0.55952 +v 0.565806 0.946899 0.436335 +v 0.387346 0.376668 0.491154 +v 0.338505 0.624856 0.607017 +v 0.456247 0.807037 0.55008 +v 0.308935 0.62677 0.620721 +v 0.664235 0.623386 0.55636 +v 0.506642 0.943171 0.521871 +v 0.532263 0.419003 0.376555 +v 0.452212 0.978196 0.455094 +v 0.289147 0.629539 0.617564 +v 0.610993 0.380958 0.445348 +v 0.554728 0.797262 0.541538 +v 0.569051 0.724595 0.453578 +v 0.428299 0.163835 0.500654 +v 0.462673 0.484062 0.358314 +v 0.543241 0.158573 0.434716 +v 0.535848 0.985581 0.467856 +v 0.532517 0.768885 0.542581 +v 0.435919 0.881103 0.496686 +v 0.439791 0.288178 0.522891 +v 0.40146 0.606288 0.478334 +v 0.377737 0.176219 0.475869 +v 0.446375 0.17271 0.57736 +v 0.698333 0.635611 0.486813 +v 0.622 0.217521 0.456356 +v 0.518973 0.994517 0.450319 +v 0.573991 0.287565 0.523235 +v 0.536208 0.348903 0.421204 +v 0.476494 0.880637 0.543449 +v 0.515647 0.778429 0.404483 +v 0.730246 0.629973 0.61465 +v 0.706302 0.641586 0.621891 +v 0.575211 0.316383 0.528955 +v 0.427715 0.410377 0.400446 +v 0.397207 0.165526 0.55966 +v 0.584695 0.703466 0.453807 +v 0.535528 0.187473 0.58342 +v 0.475561 0.338969 0.431301 +v 0.524357 0.919148 0.387245 +v 0.56781 0.695734 0.434292 +v 0.436883 0.310631 0.528886 +v 0.415961 0.604825 0.448992 +v 0.435739 0.646498 0.424245 +v 0.526925 0.757482 0.567666 +v 0.488247 0.463335 0.586182 +v 0.473586 0.17039 0.432577 +v 0.280716 0.60187 0.558755 +v 0.58891 0.610186 0.489729 +v 0.522072 0.761679 0.586115 +v 0.396492 0.434312 0.52139 +v 0.487835 0.328522 0.479389 +v 0.516638 0.333004 0.443119 +v 0.498899 0.483613 0.36191 +v 0.439471 0.771291 0.436798 +v 0.618789 0.164454 0.533748 +v 0.389849 0.684851 0.486521 +v 0.539286 0.381132 0.414253 +v 0.483758 0.225805 0.44448 +v 0.413197 0.403457 0.417416 +v 0.568102 0.172617 0.41302 +v 0.651187 0.617243 0.527154 +v 0.421292 0.834091 0.436244 +v 0.597764 0.603282 0.47754 +v 0.463342 0.355369 0.421032 +v 0.600179 0.651894 0.501896 +v 0.432453 0.160763 0.570107 +v 0.598276 0.616234 0.491429 +v 0.531432 0.402648 0.399322 +v 0.437825 0.650128 0.539505 +v 0.623872 0.22181 0.475936 +v 0.430649 0.196116 0.554801 +v 0.48563 0.661189 0.406232 +v 0.480976 0.170712 0.545485 +v 0.674842 0.651553 0.577067 +v 0.4612 0.285893 0.419905 +v 0.443866 0.380379 0.412771 +v 0.478001 0.749723 0.546294 +v 0.554085 0.756391 0.552596 +v 0.394454 0.608286 0.449656 +v 0.68957 0.610113 0.583561 +v 0.545445 0.836291 0.540211 +v 0.432803 0.935826 0.472721 +v 0.551211 0.958992 0.489955 +v 0.309059 0.600524 0.461546 +v 0.55378 0.183822 0.576005 +v 0.53866 0.858692 0.404711 +v 0.331535 0.637402 0.55911 +v 0.493828 0.762123 0.548053 +v 0.408714 0.611325 0.446737 +v 0.536594 0.38278 0.529923 +v 0.495104 0.18617 0.494736 +v 0.553495 0.723035 0.528705 +v 0.510633 0.354459 0.447662 +v 0.68821 0.633875 0.606111 +v 0.462145 0.455771 0.577127 +v 0.422528 0.598853 0.440831 +v 0.591614 0.584453 0.469254 +v 0.535645 0.194487 0.575195 +v 0.619889 0.447266 0.478221 +v 0.505762 0.177659 0.489388 +v 0.468265 0.269824 0.511075 +v 0.463682 0.158941 0.441181 +v 0.565568 0.872155 0.509973 +v 0.452368 0.780067 0.421442 +v 0.733359 0.626662 0.611222 +v 0.504874 0.851411 0.394673 +v 0.551873 0.815649 0.523176 +v 0.58091 0.362151 0.519975 +v 0.316545 0.646814 0.496955 +v 0.498712 0.417643 0.386334 +v 0.412123 0.453645 0.383848 +v 0.566039 0.828185 0.433558 +v 0.482506 0.994715 0.456728 +v 0.642752 0.672339 0.482625 +v 0.515422 0.169692 0.453655 +v 0.400414 0.169261 0.432406 +v 0.446535 0.865269 0.528144 +v 0.687799 0.575025 0.515725 +v 0.454829 0.336943 0.517858 +v 0.584265 0.82773 0.4378 +v 0.415091 0.516792 0.408384 +v 0.545695 0.749699 0.551744 +v 0.508306 0.80294 0.575664 +v 0.263609 0.628176 0.608149 +v 0.495267 0.822172 0.55662 +v 0.451586 0.306612 0.520038 +v 0.590378 0.170344 0.567479 +v 0.469172 0.669296 0.411998 +v 0.480786 0.706235 0.553128 +v 0.414365 0.550907 0.533467 +v 0.716613 0.594772 0.536502 +v 0.65396 0.614232 0.608055 +v 0.490547 0.991765 0.4786 +v 0.692377 0.63084 0.621621 +v 0.489486 0.945789 0.385709 +v 0.414922 0.283284 0.520417 +v 0.468325 0.775432 0.410479 +v 0.488384 0.35445 0.493902 +v 0.276892 0.65101 0.589121 +v 0.427502 0.850252 0.457822 +v 0.446625 0.880019 0.52971 +v 0.584448 0.466524 0.378499 +v 0.377741 0.193523 0.475399 +v 0.487201 0.992027 0.430309 +v 0.451722 0.586584 0.554811 +v 0.525423 0.463084 0.356296 +v 0.358986 0.601117 0.444138 +v 0.581935 0.65468 0.508051 +v 0.581573 0.4424 0.381459 +v 0.616763 0.183686 0.516906 +v 0.498266 0.559934 0.577754 +v 0.535962 0.675011 0.543352 +v 0.45603 0.974322 0.480628 +v 0.404365 0.556426 0.507341 +v 0.727465 0.630678 0.592998 +v 0.549452 0.623602 0.556328 +v 0.402279 0.308424 0.512607 +v 0.475174 0.736353 0.577919 +v 0.504398 0.995746 0.439834 +v 0.537504 0.730763 0.57087 +v 0.52455 0.368716 0.517305 +v 0.492021 0.969894 0.508493 +v 0.671576 0.642534 0.58272 +v 0.480968 0.746287 0.55319 +v 0.396557 0.681804 0.433199 +v 0.512322 0.275923 0.477757 +v 0.435865 0.769956 0.536549 +v 0.488521 0.968761 0.397512 +v 0.327944 0.611895 0.567861 +v 0.584432 0.599359 0.450914 +v 0.380649 0.450194 0.472144 +v 0.459787 0.750338 0.539711 +v 0.314588 0.63418 0.602069 +v 0.654586 0.630822 0.580614 +v 0.559767 0.883923 0.519905 +v 0.520447 0.741075 0.577306 +v 0.333973 0.641716 0.51383 +v 0.504671 0.857298 0.545231 +v 0.319769 0.643487 0.456446 +v 0.608879 0.516688 0.490447 +v 0.534161 0.6885 0.540999 +v 0.393032 0.157532 0.488202 +v 0.352637 0.673338 0.454114 +v 0.665127 0.6196 0.567674 +v 0.549928 0.975629 0.44141 +v 0.50838 0.861105 0.539383 +v 0.502017 0.363347 0.455068 +v 0.592479 0.156761 0.521025 +v 0.686548 0.62623 0.619447 +v 0.581097 0.705221 0.482081 +v 0.346435 0.614351 0.606193 +v 0.663997 0.638389 0.521297 +v 0.422532 0.803327 0.461997 +v 0.568043 0.364856 0.414826 +v 0.525422 0.192514 0.575304 +v 0.47426 0.564036 0.385348 +v 0.45783 0.963292 0.40979 +v 0.42759 0.790291 0.462924 +v 0.38874 0.1657 0.546279 +v 0.724247 0.628021 0.611329 +v 0.565403 0.309948 0.529232 +v 0.587613 0.177415 0.417819 +v 0.646133 0.611377 0.436256 +v 0.565595 0.393589 0.410184 +v 0.515756 0.19696 0.447708 +v 0.379224 0.169987 0.534481 +v 0.565384 0.797075 0.439649 +v 0.491611 0.918713 0.383327 +v 0.46821 0.987569 0.437106 +v 0.504201 0.454794 0.361834 +v 0.412287 0.633707 0.429545 +v 0.705148 0.631043 0.61893 +v 0.379882 0.166834 0.486826 +v 0.442867 0.927559 0.411791 +v 0.567733 0.786804 0.44701 +v 0.733895 0.63708 0.591618 +v 0.43537 0.81893 0.430629 +v 0.542778 0.180968 0.417865 +v 0.525721 0.438287 0.362557 +v 0.353002 0.639485 0.429775 +v 0.42334 0.375518 0.416282 +v 0.559676 0.787458 0.54447 +v 0.699833 0.637257 0.60676 +v 0.601989 0.173937 0.563235 +v 0.347438 0.623151 0.605596 +v 0.596923 0.273796 0.514955 +v 0.557586 0.751783 0.548279 +v 0.67663 0.650601 0.602053 +v 0.42008 0.675404 0.504881 +v 0.422628 0.693102 0.497767 +v 0.456417 0.217174 0.530876 +v 0.579038 0.695225 0.495986 +v 0.618588 0.68637 0.448659 +v 0.522924 0.216936 0.512925 +v 0.379042 0.222071 0.45134 +v 0.424133 0.188323 0.572482 +v 0.331444 0.61603 0.587446 +v 0.515765 0.966986 0.508951 +v 0.538535 0.93981 0.395181 +v 0.553688 0.177316 0.578143 +v 0.32746 0.648361 0.503106 +v 0.412115 0.159419 0.449266 +v 0.696271 0.617302 0.465642 +v 0.411958 0.702838 0.474882 +v 0.539466 0.487673 0.359409 +v 0.559168 0.768417 0.563971 +v 0.46029 0.765956 0.540403 +v 0.521423 0.163879 0.457475 +v 0.496549 0.829539 0.569842 +v 0.425296 0.567488 0.418602 +v 0.626343 0.61048 0.437734 +v 0.478903 0.804466 0.572175 +v 0.390714 0.615009 0.492018 +v 0.646535 0.655792 0.435038 +v 0.731823 0.63897 0.608399 +v 0.556115 0.49311 0.365681 +v 0.466926 0.821537 0.538899 +v 0.45137 0.764247 0.578323 +v 0.323571 0.643592 0.588889 +v 0.269598 0.643965 0.568448 +v 0.57012 0.597565 0.532625 +v 0.547096 0.763715 0.578339 +v 0.455832 0.265253 0.518996 +v 0.687309 0.575888 0.491155 +v 0.504595 0.185853 0.495873 +v 0.444264 0.793105 0.551554 +v 0.43921 0.437573 0.365936 +v 0.365236 0.627785 0.511036 +v 0.484606 0.836727 0.398536 +v 0.480228 0.218439 0.50812 +v 0.387131 0.435197 0.505865 +v 0.440482 0.766226 0.561502 +v 0.55542 0.793371 0.523317 +v 0.286995 0.634618 0.60478 +v 0.672435 0.624683 0.590482 +v 0.563182 0.159449 0.480695 +v 0.542606 0.358814 0.520529 +v 0.428758 0.624916 0.431244 +v 0.468377 0.378869 0.41717 +v 0.435074 0.59519 0.537637 +v 0.390266 0.633915 0.500722 +v 0.490976 0.347509 0.478608 +v 0.482355 0.847925 0.546939 +v 0.483623 0.499816 0.590505 +v 0.706087 0.643542 0.523887 +v 0.445841 0.755767 0.55199 +v 0.712228 0.630246 0.616904 +v 0.269101 0.627833 0.61437 +v 0.42054 0.377846 0.522995 +v 0.425147 0.807971 0.431121 +v 0.36937 0.663238 0.49791 +v 0.482135 0.167586 0.568554 +v 0.274771 0.628107 0.610297 +v 0.449136 0.817352 0.524104 +v 0.620379 0.309685 0.460537 +v 0.410248 0.591319 0.479981 +v 0.450231 0.888893 0.528448 +v 0.451689 0.522755 0.38047 +v 0.4923 0.17691 0.515158 +v 0.387391 0.650015 0.423739 +v 0.381661 0.179105 0.519543 +v 0.728571 0.623926 0.607914 +v 0.565413 0.623302 0.54478 +v 0.477639 0.368995 0.516102 +v 0.677155 0.633262 0.620796 +v 0.574767 0.807195 0.431376 +v 0.415142 0.704836 0.458413 +v 0.681477 0.626971 0.621144 +v 0.568395 0.164227 0.417845 +v 0.603992 0.601167 0.467047 +v 0.335036 0.635147 0.590393 +v 0.48192 0.74459 0.575036 +v 0.576248 0.489042 0.37672 +v 0.467252 0.202489 0.552949 +v 0.572904 0.853063 0.461033 +v 0.593431 0.633879 0.499771 +v 0.385186 0.688728 0.44804 +v 0.444063 0.793049 0.521891 +v 0.670617 0.641591 0.543664 +v 0.311429 0.650421 0.612901 +v 0.496376 0.857426 0.544247 +v 0.539602 0.168837 0.582602 +v 0.669755 0.588479 0.458797 +v 0.480578 0.188467 0.573646 +v 0.532471 0.748096 0.563784 +v 0.546968 0.939288 0.504689 +v 0.549914 0.358294 0.415738 +v 0.462678 0.76726 0.547529 +v 0.552061 0.681389 0.529289 +v 0.537069 0.178896 0.585993 +v 0.337511 0.60488 0.543441 +v 0.429494 0.185117 0.578234 +v 0.625074 0.632278 0.426535 +v 0.473285 0.765252 0.587371 +v 0.661331 0.612735 0.604721 +v 0.584082 0.836544 0.454993 +v 0.537775 0.767476 0.546602 +v 0.420613 0.808266 0.442876 +v 0.487712 0.397608 0.536089 +v 0.492216 0.66944 0.550016 +v 0.421562 0.438743 0.378831 +v 0.509757 0.855306 0.561321 +v 0.498778 0.752113 0.548275 +v 0.339173 0.611399 0.601275 +v 0.669008 0.573544 0.495942 +v 0.453341 0.602451 0.552319 +v 0.620027 0.595827 0.477336 +v 0.678205 0.638145 0.600642 +v 0.530734 0.802716 0.570298 +v 0.654449 0.624362 0.433482 +v 0.282048 0.640463 0.617882 +v 0.481201 0.823494 0.545613 +v 0.546076 0.216258 0.532564 +v 0.525107 0.983172 0.486959 +v 0.499163 0.630305 0.401464 +v 0.514713 0.18135 0.568096 +v 0.503585 0.983748 0.494449 +v 0.351981 0.614897 0.521496 +v 0.607808 0.606991 0.485623 +v 0.568357 0.197115 0.554239 +v 0.504012 0.432995 0.370905 +v 0.471171 0.558365 0.574096 +v 0.510634 0.81987 0.554712 +v 0.319249 0.637368 0.598654 +v 0.468207 0.193101 0.57802 +v 0.520566 0.32988 0.498158 +v 0.552899 0.451426 0.358567 +v 0.3159 0.656185 0.59864 +v 0.436038 0.720476 0.443029 +v 0.568007 0.389391 0.531159 +v 0.723705 0.610029 0.531064 +v 0.314855 0.633793 0.628892 +v 0.615955 0.373965 0.48199 +v 0.457457 0.748286 0.563318 +v 0.382636 0.445085 0.455044 +v 0.572968 0.630934 0.533502 +v 0.524233 0.378777 0.420586 +v 0.298063 0.625246 0.475696 +v 0.434396 0.453664 0.362802 +v 0.376859 0.649291 0.503814 +v 0.394386 0.158607 0.522041 +v 0.577081 0.81351 0.461489 +v 0.605479 0.161996 0.542966 +v 0.447105 0.160081 0.530427 +v 0.415348 0.61097 0.492934 +v 0.324845 0.635992 0.587714 +v 0.502934 0.850202 0.574284 +v 0.482024 0.202261 0.532596 +v 0.507615 0.180058 0.520453 +v 0.526159 0.162806 0.576021 +v 0.333696 0.62217 0.558563 +v 0.504172 0.371444 0.441612 +v 0.512592 0.346111 0.488544 +v 0.560462 0.563699 0.402827 +v 0.547557 0.753507 0.544794 +v 0.613659 0.22434 0.437637 +v 0.566099 0.218073 0.53199 +v 0.283367 0.633131 0.618634 +v 0.280893 0.636877 0.599649 +v 0.386228 0.166544 0.463056 +v 0.472374 0.216708 0.518757 +v 0.485907 0.839415 0.567142 +v 0.665349 0.634673 0.559472 +v 0.71692 0.638878 0.616673 +v 0.289153 0.639067 0.624 +v 0.494073 0.846453 0.574666 +v 0.404739 0.62065 0.437218 +v 0.486758 0.849226 0.564999 +v 0.645098 0.626548 0.516817 +v 0.422164 0.703053 0.48834 +v 0.435716 0.799251 0.436787 +v 0.321933 0.635036 0.618247 +v 0.436365 0.701863 0.436767 +v 0.282981 0.652886 0.555942 +v 0.44712 0.750991 0.551046 +v 0.449233 0.699303 0.425707 +v 0.553645 0.170598 0.57604 +v 0.500592 0.875854 0.537929 +v 0.39365 0.663594 0.50003 +v 0.571739 0.452569 0.367542 +v 0.405521 0.207654 0.525402 +v 0.270838 0.620714 0.560898 +v 0.551758 0.790952 0.424103 +v 0.449326 0.799778 0.531779 +v 0.43265 0.156625 0.430365 +v 0.271574 0.624441 0.60798 +v 0.572868 0.72392 0.483027 +v 0.418128 0.313289 0.526562 +v 0.57303 0.793255 0.469727 +v 0.446194 0.206782 0.546898 +v 0.561972 0.773349 0.515733 +v 0.469331 0.159456 0.570197 +v 0.544414 0.201898 0.419371 +v 0.713677 0.652788 0.605963 +v 0.509208 0.503723 0.591233 +v 0.649396 0.618441 0.602371 +v 0.55332 0.653182 0.549132 +v 0.450769 0.680061 0.532194 +v 0.519994 0.164211 0.505803 +v 0.286835 0.610826 0.582265 +v 0.57868 0.815479 0.429853 +v 0.670338 0.629074 0.592158 +v 0.611894 0.377258 0.49411 +v 0.503557 0.668479 0.404904 +v 0.586876 0.492959 0.550784 +v 0.511664 0.392853 0.531118 +v 0.554915 0.759504 0.564584 +v 0.461757 0.464439 0.355765 +v 0.716979 0.631472 0.595349 +v 0.32014 0.578926 0.529747 +v 0.418049 0.825107 0.465417 +v 0.60295 0.372318 0.506328 +v 0.471527 0.97027 0.500912 +v 0.393618 0.602486 0.46567 +v 0.706005 0.656853 0.601336 +v 0.718888 0.652695 0.562797 +v 0.572872 0.724745 0.468098 +v 0.306439 0.63001 0.622844 +v 0.67353 0.616061 0.579865 +v 0.619223 0.171282 0.51573 +v 0.661117 0.617016 0.609247 +v 0.526425 0.181979 0.584437 +v 0.541325 0.74408 0.569015 +v 0.571874 0.16021 0.567039 +v 0.370916 0.630841 0.427037 +v 0.527782 0.208607 0.430654 +v 0.375875 0.225065 0.467264 +v 0.514782 0.764005 0.547617 +v 0.54264 0.167526 0.421908 +v 0.315011 0.629933 0.594089 +v 0.528046 0.757607 0.57963 +v 0.31614 0.59636 0.562158 +v 0.477111 0.865644 0.541585 +v 0.319187 0.644713 0.517429 +v 0.412371 0.413772 0.53026 +v 0.429737 0.631751 0.532563 +v 0.569274 0.475866 0.56628 +v 0.583468 0.828103 0.46324 +v 0.438028 0.357273 0.522889 +v 0.583523 0.559018 0.426327 +v 0.55492 0.835742 0.531325 +v 0.478665 0.173141 0.581193 +v 0.377361 0.179711 0.497458 +v 0.650914 0.637057 0.514479 +v 0.432201 0.165714 0.416597 +v 0.705016 0.630512 0.600678 +v 0.491381 0.190748 0.522725 +v 0.673401 0.579336 0.526874 +v 0.386875 0.388793 0.450921 +v 0.428572 0.489972 0.372575 +v 0.397126 0.179995 0.558737 +v 0.269947 0.649415 0.581192 +v 0.472852 0.204498 0.431402 +v 0.594539 0.600447 0.473969 +v 0.562268 0.936967 0.485586 +v 0.414835 0.635035 0.502116 +v 0.58573 0.563891 0.525943 +v 0.510965 0.335465 0.460769 +v 0.401319 0.647782 0.501583 +v 0.458018 0.707771 0.537615 +v 0.70921 0.632779 0.623565 +v 0.461412 0.179383 0.420069 +v 0.516379 0.844451 0.562735 +v 0.588627 0.184751 0.55916 +v 0.418867 0.242338 0.414192 +v 0.442575 0.894117 0.505247 +v 0.507234 0.838694 0.57462 +v 0.511819 0.831975 0.56641 +v 0.590857 0.295968 0.517996 +v 0.327615 0.646002 0.578432 +v 0.334473 0.616831 0.605773 +v 0.729311 0.63406 0.567892 +v 0.445432 0.469845 0.574182 +v 0.511488 0.604464 0.395889 +v 0.555585 0.72576 0.544904 +v 0.469449 0.985746 0.476697 +v 0.69032 0.598877 0.463055 +v 0.470805 0.167675 0.582875 +v 0.327929 0.641909 0.582607 +v 0.44483 0.379788 0.529379 +v 0.445661 0.562763 0.39816 +v 0.525087 0.643902 0.407819 +v 0.537608 0.70938 0.544051 +v 0.553203 0.851476 0.53449 +v 0.544515 0.255655 0.41707 +v 0.490343 0.203585 0.482047 +v 0.437137 0.874736 0.516489 +v 0.587867 0.306119 0.416872 +v 0.583045 0.413542 0.408986 +v 0.548647 0.890831 0.527816 +v 0.479008 0.194689 0.551585 +v 0.344949 0.629056 0.582183 +v 0.411077 0.588173 0.460565 +v 0.555277 0.607431 0.417689 +v 0.426924 0.722339 0.4754 +v 0.690932 0.587344 0.550993 +v 0.281535 0.6158 0.504432 +v 0.372522 0.597682 0.491087 +v 0.657601 0.601109 0.53647 +v 0.467641 0.420553 0.375008 +v 0.527698 0.973781 0.408446 +v 0.518225 0.766852 0.552645 +v 0.441116 0.156223 0.443022 +v 0.345016 0.613607 0.595755 +v 0.670932 0.604612 0.446969 +v 0.318787 0.62538 0.448804 +v 0.730462 0.645161 0.575161 +v 0.315446 0.62688 0.619431 +v 0.603941 0.20556 0.517927 +v 0.394404 0.452562 0.426061 +v 0.467461 0.484381 0.587014 +v 0.561008 0.645029 0.42344 +v 0.49767 0.438312 0.575255 +v 0.558586 0.26376 0.412754 +v 0.298219 0.624579 0.596539 +v 0.410492 0.462729 0.54225 +v 0.555792 0.914166 0.411064 +v 0.385752 0.661995 0.425414 +v 0.46226 0.717624 0.558278 +v 0.397345 0.302965 0.426154 +v 0.518943 0.730965 0.576771 +v 0.681622 0.648077 0.534277 +v 0.457153 0.945325 0.400037 +v 0.539945 0.746114 0.541074 +v 0.691873 0.633538 0.601499 +v 0.537626 0.852139 0.543894 +v 0.690877 0.638725 0.624157 +v 0.665756 0.578119 0.474667 +v 0.564099 0.80937 0.435364 +v 0.315347 0.582659 0.472416 +v 0.486117 0.883345 0.54267 +v 0.449103 0.757295 0.566893 +v 0.532732 0.817302 0.541134 +v 0.706501 0.583326 0.517673 +v 0.4245 0.334919 0.521589 +v 0.718317 0.610877 0.575 +v 0.537125 0.39314 0.408499 +v 0.516753 0.16925 0.567962 +v 0.605651 0.156867 0.492886 +v 0.404786 0.377622 0.426195 +v 0.526188 0.162597 0.469383 +v 0.496061 0.370962 0.441876 +v 0.568794 0.692881 0.507127 +v 0.395063 0.172218 0.560867 +v 0.612573 0.443568 0.441474 +v 0.534483 0.963968 0.502516 +v 0.509509 0.202604 0.474546 +v 0.518296 0.823867 0.546272 +v 0.264869 0.633605 0.611442 +v 0.667669 0.654415 0.452753 +v 0.578875 0.798829 0.452016 +v 0.472039 0.414095 0.552118 +v 0.541778 0.882475 0.536959 +v 0.604098 0.689821 0.483235 +v 0.705871 0.610289 0.584971 +v 0.614499 0.167451 0.462893 +v 0.472846 0.396281 0.407912 +v 0.467952 0.702604 0.543674 +v 0.289749 0.658789 0.59315 +v 0.520301 0.756451 0.544941 +v 0.518651 0.606262 0.561207 +v 0.583152 0.6141 0.440025 +v 0.424014 0.549447 0.546643 +v 0.632981 0.606168 0.507496 +v 0.526102 0.350905 0.509029 +v 0.378569 0.22486 0.488924 +v 0.66819 0.615653 0.57378 +v 0.533814 0.780099 0.411278 +v 0.423714 0.798464 0.442014 +v 0.484562 0.197243 0.448816 +v 0.706821 0.633449 0.606329 +v 0.511214 0.481666 0.590975 +v 0.451445 0.836217 0.537398 +v 0.510535 0.170513 0.506549 +v 0.388878 0.219475 0.434716 +v 0.416734 0.498284 0.554749 +v 0.438632 0.754743 0.543762 +v 0.589366 0.633568 0.428822 +v 0.594115 0.603056 0.457184 +v 0.30948 0.633409 0.607244 +v 0.668137 0.617656 0.591609 +v 0.380651 0.164818 0.533459 +v 0.393571 0.195923 0.432986 +v 0.430431 0.716095 0.497272 +v 0.318744 0.642401 0.621534 +v 0.539854 0.163952 0.480847 +v 0.658149 0.667046 0.466232 +v 0.656232 0.639354 0.434327 +v 0.517123 0.189239 0.548672 +v 0.451164 0.755181 0.548728 +v 0.572384 0.824839 0.478358 +v 0.541891 0.547324 0.572677 +v 0.443195 0.939289 0.493441 +v 0.561963 0.594831 0.542339 +v 0.306164 0.639633 0.622091 +v 0.688907 0.652236 0.608168 +v 0.695444 0.643864 0.605765 +v 0.576513 0.545427 0.548108 +v 0.306544 0.633932 0.602151 +v 0.647027 0.590093 0.456253 +v 0.519781 0.845328 0.547597 +v 0.471535 0.443341 0.360032 +v 0.555167 0.969067 0.465693 +v 0.431129 0.175061 0.581739 +v 0.589279 0.328043 0.517334 +v 0.714504 0.596482 0.504442 +v 0.495548 0.369416 0.500359 +v 0.555898 0.943239 0.412725 +v 0.406784 0.601164 0.471005 +v 0.570346 0.181008 0.411645 +v 0.602374 0.17569 0.43106 +v 0.295943 0.635106 0.618912 +v 0.724532 0.633403 0.612057 +v 0.436677 0.682594 0.4276 +v 0.577707 0.828248 0.431122 +v 0.602377 0.197584 0.428702 +v 0.585733 0.201 0.41803 +v 0.372106 0.612427 0.504696 +v 0.28554 0.592588 0.504376 +v 0.55234 0.164942 0.569738 +v 0.611458 0.618481 0.497443 +v 0.534695 0.161418 0.54621 +v 0.485355 0.167022 0.500149 +v 0.599797 0.424059 0.42386 +v 0.398902 0.394011 0.511486 +v 0.563781 0.159129 0.458328 +v 0.447421 0.647687 0.550252 +v 0.668256 0.634632 0.588783 +v 0.38228 0.448528 0.493414 +v 0.529403 0.986712 0.430518 +v 0.302317 0.641926 0.606087 +v 0.675627 0.620879 0.586148 +v 0.598585 0.499577 0.532317 +v 0.350892 0.580584 0.485066 +v 0.572179 0.847774 0.451255 +v 0.304136 0.610497 0.585848 +v 0.550917 0.69066 0.424236 +v 0.300124 0.642301 0.510814 +v 0.448681 0.494526 0.364479 +v 0.552759 0.494269 0.579062 +v 0.560775 0.717063 0.436788 +v 0.610444 0.634858 0.501747 +v 0.581923 0.162153 0.549398 +v 0.306107 0.641265 0.486015 +v 0.524782 0.960818 0.396175 +v 0.546675 0.773498 0.578652 +v 0.473867 0.959706 0.396442 +v 0.479965 0.359236 0.50821 +v 0.348632 0.631529 0.517127 +v 0.445581 0.956015 0.418667 +v 0.612686 0.675969 0.43223 +v 0.541798 0.408066 0.545931 +v 0.706957 0.659073 0.559839 +v 0.537529 0.160544 0.572596 +v 0.448466 0.22638 0.527645 +v 0.349789 0.67315 0.467409 +v 0.67687 0.633209 0.589783 +v 0.623731 0.652559 0.503199 +v 0.444359 0.188296 0.570894 +v 0.721968 0.630151 0.599356 +v 0.438257 0.774868 0.514861 +v 0.399716 0.42086 0.42505 +v 0.69694 0.660576 0.579741 +v 0.317935 0.648567 0.539564 +v 0.480355 0.513339 0.369446 +v 0.552019 0.160135 0.527791 +v 0.62095 0.195331 0.486952 +v 0.332861 0.616533 0.576717 +v 0.413768 0.179611 0.41676 +v 0.280391 0.643382 0.60021 +v 0.604308 0.455464 0.42397 +v 0.476787 0.162519 0.570054 +v 0.502514 0.35985 0.478617 +v 0.480542 0.330478 0.49682 +v 0.580697 0.837388 0.442206 +v 0.44329 0.729864 0.543612 +v 0.434486 0.176971 0.41218 +v 0.388069 0.17607 0.545051 +v 0.425871 0.159727 0.424259 +v 0.488929 0.823385 0.552951 +v 0.719281 0.651537 0.590052 +v 0.400305 0.499488 0.529353 +v 0.548828 0.593578 0.553337 +v 0.53778 0.200959 0.557576 +v 0.56817 0.172014 0.581127 +v 0.438914 0.959185 0.438784 +v 0.427394 0.215814 0.532189 +v 0.59858 0.378845 0.428783 +v 0.339299 0.623267 0.538679 +v 0.637101 0.616971 0.51323 +v 0.440902 0.963071 0.466065 +v 0.53306 0.645816 0.557476 +v 0.522148 0.749684 0.547019 +v 0.581759 0.607002 0.500624 +v 0.446952 0.165448 0.57061 +v 0.568613 0.846031 0.440177 +v 0.544606 0.266463 0.519331 +v 0.342328 0.61932 0.610668 +v 0.416654 0.162528 0.549968 +v 0.446859 0.271504 0.413778 +v 0.409841 0.478312 0.388617 +v 0.654758 0.626513 0.604972 +v 0.429225 0.200294 0.414656 +v 0.568442 0.334665 0.522572 +v 0.518919 0.882188 0.543174 +v 0.448284 0.402326 0.398765 +v 0.577684 0.643483 0.515233 +v 0.412937 0.187468 0.554026 +v 0.329208 0.574653 0.485215 +v 0.406936 0.546758 0.436727 +v 0.417659 0.822657 0.434503 +v 0.426347 0.489558 0.564399 +v 0.510903 0.360851 0.49875 +v 0.41605 0.835047 0.457759 +v 0.580207 0.809953 0.438775 +v 0.726506 0.63024 0.584284 +v 0.535526 0.771158 0.585466 +v 0.518135 0.6994 0.548185 +v 0.428357 0.831241 0.47899 +v 0.541995 0.465411 0.579238 +v 0.515837 0.852125 0.546133 +v 0.341283 0.583596 0.516697 +v 0.431348 0.783237 0.450392 +v 0.616173 0.3917 0.462141 +v 0.595221 0.378474 0.513866 +v 0.262519 0.637382 0.600919 +v 0.334104 0.659771 0.455795 +v 0.489847 0.338889 0.461933 +v 0.472436 0.924805 0.388701 +v 0.333999 0.617014 0.439146 +v 0.550866 0.96729 0.425688 +v 0.390988 0.507693 0.50062 +v 0.298007 0.585856 0.48641 +v 0.700503 0.584575 0.489074 +v 0.529374 0.561114 0.385399 +v 0.718786 0.641017 0.599628 +v 0.297413 0.580828 0.527257 +v 0.560378 0.522779 0.387105 +v 0.429833 0.847455 0.445813 +v 0.42493 0.645416 0.514395 +v 0.294841 0.633221 0.605532 +v 0.447941 0.660734 0.422051 +v 0.561275 0.74875 0.544303 +v 0.612761 0.20317 0.506947 +v 0.498285 0.85756 0.563981 +v 0.526195 0.866076 0.540866 +v 0.394973 0.262536 0.509759 +v 0.480945 0.83757 0.548367 +v 0.573572 0.704396 0.444403 +v 0.3438 0.629593 0.599046 +v 0.475187 0.892479 0.538472 +v 0.683555 0.637737 0.627256 +v 0.547307 0.867181 0.533585 +v 0.60317 0.67245 0.497474 +v 0.603261 0.180209 0.557898 +v 0.310104 0.630713 0.627752 +v 0.313196 0.630617 0.628358 +v 0.311446 0.633656 0.628629 +v 0.684556 0.63114 0.62838 +v 0.685684 0.634362 0.628723 +v 0.682075 0.632954 0.627807 +v 0.689168 0.634759 0.627275 +v 0.687546 0.638991 0.625413 +v 0.310187 0.626893 0.623864 +v 0.308701 0.628582 0.625576 +v 0.308063 0.628251 0.621123 +v 0.314748 0.628184 0.626476 +v 0.316197 0.630833 0.627619 +v 0.679535 0.630846 0.625175 +v 0.679057 0.630074 0.620179 +v 0.681316 0.628131 0.624873 +v 0.684433 0.628587 0.626826 +v 0.684498 0.626709 0.624418 +v 0.687673 0.629662 0.627383 +v 0.307599 0.631713 0.626169 +v 0.307372 0.635897 0.62592 +v 0.305807 0.635133 0.6221 +v 0.318918 0.631894 0.625561 +v 0.31786 0.6343 0.626858 +v 0.319548 0.630799 0.623221 +v 0.320704 0.634541 0.623263 +v 0.689783 0.628547 0.624885 +v 0.69021 0.631378 0.626256 +v 0.692062 0.6352 0.622555 +v 0.286514 0.632505 0.62188 +v 0.289164 0.634966 0.623485 +v 0.285748 0.635693 0.622304 +v 0.291717 0.633215 0.622071 +v 0.29244 0.636983 0.622752 +v 0.309487 0.636773 0.627257 +v 0.3085 0.640399 0.624 +v 0.312806 0.637161 0.627535 +v 0.319556 0.637239 0.624426 +v 0.316634 0.637765 0.626336 +v 0.678009 0.638615 0.620555 +v 0.679892 0.634679 0.625569 +v 0.680474 0.640149 0.623201 +v 0.704332 0.638058 0.621397 +v 0.705854 0.634164 0.622578 +v 0.707924 0.636261 0.623695 +v 0.710442 0.63766 0.623456 +v 0.710993 0.633902 0.623141 +v 0.713545 0.638413 0.621975 +v 0.71079 0.641146 0.622083 +v 0.31432 0.641544 0.623918 +v 0.311648 0.626972 0.619941 +v 0.313435 0.626602 0.6241 +v 0.31671 0.627715 0.623673 +v 0.318955 0.630648 0.618386 +v 0.687371 0.62655 0.623335 +v 0.684168 0.626765 0.620015 +v 0.689434 0.628235 0.620261 +v 0.288977 0.630929 0.62093 +v 0.286281 0.631052 0.617798 +v 0.292436 0.631572 0.618185 +v 0.708522 0.630351 0.617971 +v 0.71055 0.631019 0.621261 +v 0.707264 0.631463 0.621541 +v 0.703815 0.633203 0.619296 +v 0.713088 0.63253 0.620906 +v 0.715041 0.634777 0.616839 +v 0.714994 0.635939 0.620706 +v 0.282632 0.637315 0.617658 +v 0.285281 0.639848 0.620945 +v 0.291478 0.641825 0.621781 +v 0.29514 0.640416 0.619084 +v 0.71551 0.640748 0.618563 +v 0.311352 0.644539 0.620682 +v 0.31501 0.647255 0.616882 +v 0.680064 0.646774 0.615685 +v 0.682907 0.645812 0.618304 +v 0.711757 0.645014 0.618544 +v 0.708657 0.645458 0.618741 +v 0.291784 0.631718 0.611873 +v 0.295546 0.634246 0.612402 +v 0.684155 0.629951 0.612953 +v 0.681586 0.630708 0.612777 +v 0.729484 0.627084 0.613497 +v 0.726978 0.628556 0.613714 +v 0.727223 0.626006 0.612306 +v 0.730926 0.625653 0.611984 +v 0.732241 0.62825 0.612835 +v 0.727384 0.631701 0.613557 +v 0.724046 0.631436 0.611408 +v 0.304101 0.640845 0.613881 +v 0.304991 0.636304 0.614363 +v 0.693879 0.637459 0.614377 +v 0.692836 0.641619 0.615259 +v 0.321097 0.63927 0.619468 +v 0.701359 0.639493 0.615878 +v 0.701931 0.643066 0.615632 +v 0.285363 0.650369 0.610427 +v 0.282585 0.645679 0.612201 +v 0.284871 0.644966 0.616807 +v 0.288166 0.64405 0.619864 +v 0.308284 0.645159 0.6175 +v 0.68974 0.644712 0.617038 +v 0.686092 0.645424 0.618544 +v 0.714188 0.64629 0.614768 +v 0.711556 0.650231 0.61201 +v 0.716007 0.646068 0.610533 +v 0.290569 0.647106 0.6175 +v 0.686515 0.65241 0.607512 +v 0.339058 0.614555 0.60757 +v 0.342086 0.615896 0.6091 +v 0.338841 0.618061 0.609262 +v 0.343868 0.613703 0.607294 +v 0.344892 0.617042 0.608754 +v 0.654572 0.617116 0.609049 +v 0.657731 0.615488 0.608903 +v 0.658349 0.618589 0.609926 +v 0.267614 0.625784 0.611011 +v 0.269249 0.625154 0.607136 +v 0.270385 0.625561 0.611656 +v 0.265341 0.627269 0.606861 +v 0.265911 0.627716 0.611715 +v 0.271977 0.62772 0.613059 +v 0.273077 0.626187 0.609352 +v 0.658516 0.621874 0.609476 +v 0.661512 0.620185 0.608857 +v 0.726034 0.625577 0.609312 +v 0.72882 0.624429 0.610853 +v 0.731443 0.624964 0.609868 +v 0.264024 0.630551 0.610601 +v 0.263397 0.635461 0.606772 +v 0.262849 0.632579 0.605186 +v 0.266992 0.630368 0.613436 +v 0.309464 0.629233 0.615683 +v 0.31239 0.629792 0.612836 +v 0.68476 0.633436 0.60615 +v 0.687358 0.630289 0.613069 +v 0.27059 0.630627 0.614006 +v 0.268649 0.633841 0.612516 +v 0.274098 0.631063 0.611287 +v 0.288146 0.63186 0.611417 +v 0.28473 0.634157 0.610951 +v 0.307189 0.632192 0.614369 +v 0.315119 0.631573 0.60874 +v 0.312029 0.633141 0.605601 +v 0.32071 0.636024 0.607459 +v 0.317868 0.632556 0.609395 +v 0.316756 0.634359 0.601265 +v 0.690436 0.631837 0.613971 +v 0.702766 0.634031 0.613112 +v 0.703654 0.634428 0.60695 +v 0.705856 0.63226 0.612542 +v 0.701203 0.636496 0.614104 +v 0.709332 0.631639 0.61152 +v 0.733299 0.631724 0.611782 +v 0.734563 0.629434 0.610338 +v 0.733992 0.635944 0.608364 +v 0.730994 0.634094 0.612142 +v 0.270926 0.639304 0.607018 +v 0.267598 0.63853 0.607692 +v 0.299119 0.639483 0.610183 +v 0.299172 0.637383 0.606389 +v 0.305985 0.636933 0.60705 +v 0.679549 0.632534 0.611664 +v 0.680323 0.635272 0.604314 +v 0.677591 0.635136 0.611982 +v 0.691049 0.634921 0.60761 +v 0.692771 0.635154 0.612394 +v 0.693909 0.638847 0.607336 +v 0.728205 0.636036 0.611048 +v 0.729029 0.640923 0.606041 +v 0.725389 0.638512 0.607839 +v 0.322438 0.642595 0.608981 +v 0.32071 0.646117 0.611219 +v 0.676222 0.639601 0.611509 +v 0.676295 0.640642 0.603509 +v 0.675613 0.645476 0.604513 +v 0.676509 0.641975 0.612924 +v 0.677762 0.645695 0.613027 +v 0.699366 0.640625 0.609603 +v 0.297148 0.646089 0.612542 +v 0.299103 0.642265 0.61178 +v 0.692466 0.648364 0.607821 +v 0.290553 0.652149 0.610448 +v 0.293591 0.649271 0.6132 +v 0.296251 0.651774 0.606116 +v 0.340911 0.612413 0.605755 +v 0.33685 0.613447 0.603163 +v 0.343387 0.61225 0.604096 +v 0.653752 0.61321 0.605324 +v 0.651715 0.615835 0.60632 +v 0.651594 0.614685 0.601958 +v 0.657478 0.613198 0.606774 +v 0.6611 0.614971 0.607413 +v 0.657228 0.611968 0.603611 +v 0.347259 0.618789 0.606491 +v 0.34466 0.620923 0.608858 +v 0.65234 0.619297 0.607579 +v 0.336021 0.621459 0.606484 +v 0.340576 0.621543 0.609416 +v 0.343411 0.624045 0.607482 +v 0.649869 0.622756 0.599882 +v 0.65132 0.62199 0.605635 +v 0.651543 0.625274 0.601295 +v 0.654805 0.62261 0.608498 +v 0.664467 0.622106 0.605254 +v 0.663236 0.618161 0.607385 +v 0.734075 0.627288 0.608811 +v 0.73163 0.626131 0.605966 +v 0.345505 0.626294 0.601946 +v 0.341816 0.627356 0.603516 +v 0.658949 0.625642 0.60576 +v 0.722989 0.629579 0.605255 +v 0.725278 0.627029 0.603439 +v 0.277562 0.632976 0.605488 +v 0.277136 0.635767 0.605909 +v 0.277658 0.632008 0.603582 +v 0.279819 0.634788 0.600092 +v 0.290244 0.633158 0.605653 +v 0.735488 0.630775 0.60604 +v 0.2806 0.63904 0.600775 +v 0.277115 0.640502 0.602875 +v 0.712236 0.634006 0.608364 +v 0.709364 0.633637 0.605286 +v 0.282012 0.637901 0.609861 +v 0.283951 0.637712 0.603446 +v 0.281191 0.641758 0.610392 +v 0.697692 0.644772 0.606362 +v 0.697162 0.640636 0.60552 +v 0.714833 0.636615 0.609745 +v 0.716944 0.640966 0.608279 +v 0.714894 0.639031 0.603336 +v 0.735414 0.637389 0.602257 +v 0.733909 0.64027 0.602437 +v 0.281561 0.647313 0.604064 +v 0.302095 0.644052 0.608089 +v 0.305 0.645081 0.612093 +v 0.718062 0.64637 0.598371 +v 0.717568 0.646147 0.60372 +v 0.715648 0.65217 0.598547 +v 0.30681 0.649613 0.608345 +v 0.319773 0.6525 0.600626 +v 0.3178 0.649917 0.610251 +v 0.679488 0.652001 0.605612 +v 0.313675 0.652856 0.607201 +v 0.709899 0.65538 0.603213 +v 0.708542 0.651253 0.6112 +v 0.705409 0.64977 0.611602 +v 0.348102 0.616992 0.602707 +v 0.348434 0.621467 0.600831 +v 0.664032 0.616221 0.60425 +v 0.268799 0.628151 0.599288 +v 0.271548 0.627197 0.600536 +v 0.274293 0.62957 0.595249 +v 0.273946 0.627453 0.60256 +v 0.275736 0.628964 0.604309 +v 0.278148 0.632103 0.599491 +v 0.287434 0.635025 0.601953 +v 0.291687 0.632144 0.602088 +v 0.291925 0.629461 0.598972 +v 0.296878 0.629886 0.601092 +v 0.701687 0.634322 0.603736 +v 0.696888 0.636358 0.603718 +v 0.697746 0.630459 0.600344 +v 0.70607 0.633593 0.603619 +v 0.284009 0.637928 0.599936 +v 0.308277 0.635285 0.60374 +v 0.303842 0.637578 0.60386 +v 0.311225 0.633793 0.60147 +v 0.682354 0.635363 0.601879 +v 0.685788 0.634569 0.602221 +v 0.680213 0.636221 0.598595 +v 0.686823 0.633364 0.599716 +v 0.689471 0.63466 0.603325 +v 0.694414 0.638914 0.603987 +v 0.692274 0.636725 0.604485 +v 0.709629 0.633573 0.601623 +v 0.722219 0.636793 0.606684 +v 0.721558 0.633859 0.605744 +v 0.720165 0.634521 0.60031 +v 0.26582 0.640234 0.603694 +v 0.265017 0.642025 0.598423 +v 0.269092 0.644587 0.599592 +v 0.300639 0.633749 0.602992 +v 0.320938 0.639222 0.595898 +v 0.322697 0.640724 0.602502 +v 0.72233 0.642582 0.60166 +v 0.323697 0.645821 0.594848 +v 0.728146 0.645566 0.598687 +v 0.731556 0.643206 0.600801 +v 0.283102 0.652428 0.598742 +v 0.280765 0.649776 0.595224 +v 0.285994 0.654657 0.601928 +v 0.284418 0.655775 0.593724 +v 0.30296 0.653261 0.600288 +v 0.308613 0.653378 0.603555 +v 0.693336 0.653524 0.600286 +v 0.695463 0.649168 0.603486 +v 0.698602 0.647492 0.607117 +v 0.701596 0.64837 0.609954 +v 0.288482 0.654515 0.605549 +v 0.292295 0.655236 0.603294 +v 0.296871 0.654737 0.599532 +v 0.309897 0.656117 0.597615 +v 0.683491 0.656188 0.596566 +v 0.67919 0.654623 0.594718 +v 0.701359 0.65478 0.600064 +v 0.334912 0.613856 0.593763 +v 0.332912 0.616139 0.596973 +v 0.341696 0.612533 0.597295 +v 0.345881 0.613699 0.601437 +v 0.653905 0.613872 0.596494 +v 0.651622 0.616674 0.595414 +v 0.656806 0.612084 0.598748 +v 0.657964 0.613722 0.591026 +v 0.660582 0.612453 0.59993 +v 0.664129 0.614521 0.592806 +v 0.664335 0.61504 0.599184 +v 0.328894 0.619456 0.590556 +v 0.330145 0.620683 0.596511 +v 0.347596 0.616385 0.597503 +v 0.667057 0.618658 0.598367 +v 0.327515 0.625647 0.592748 +v 0.331499 0.623342 0.599532 +v 0.333778 0.626922 0.59978 +v 0.347777 0.623815 0.59188 +v 0.347114 0.625824 0.595686 +v 0.669327 0.622643 0.596044 +v 0.670455 0.621006 0.591984 +v 0.28574 0.631871 0.597796 +v 0.289041 0.626335 0.595109 +v 0.303283 0.62974 0.599681 +v 0.306424 0.625769 0.595487 +v 0.309859 0.631369 0.598636 +v 0.337059 0.629816 0.598714 +v 0.332006 0.632112 0.592616 +v 0.345394 0.628989 0.591915 +v 0.652888 0.629094 0.592247 +v 0.655627 0.630666 0.594513 +v 0.666553 0.626879 0.598841 +v 0.669669 0.631457 0.591595 +v 0.664551 0.629099 0.598181 +v 0.66191 0.630879 0.596983 +v 0.671679 0.627036 0.592172 +v 0.668031 0.624587 0.5984 +v 0.728101 0.627348 0.60081 +v 0.724562 0.629373 0.596682 +v 0.266255 0.629997 0.598862 +v 0.26419 0.631444 0.600782 +v 0.268697 0.632124 0.591265 +v 0.278743 0.63131 0.595782 +v 0.279934 0.633679 0.597465 +v 0.314505 0.633313 0.598385 +v 0.31777 0.635569 0.595324 +v 0.338554 0.632959 0.595028 +v 0.713989 0.634948 0.599449 +v 0.710795 0.629742 0.597724 +v 0.720308 0.63099 0.593583 +v 0.721496 0.630291 0.595212 +v 0.719476 0.632432 0.597105 +v 0.731402 0.62959 0.59929 +v 0.730984 0.633087 0.592734 +v 0.734193 0.632533 0.599349 +v 0.264065 0.635548 0.594954 +v 0.281727 0.634511 0.597691 +v 0.283563 0.635916 0.59883 +v 0.715756 0.638961 0.600058 +v 0.717246 0.643553 0.598828 +v 0.717554 0.636289 0.598289 +v 0.735515 0.635072 0.600632 +v 0.734818 0.639504 0.594048 +v 0.732785 0.644561 0.594561 +v 0.272513 0.645736 0.59794 +v 0.27165 0.649029 0.590902 +v 0.27491 0.643095 0.600686 +v 0.278303 0.647118 0.595074 +v 0.719508 0.646459 0.596082 +v 0.298677 0.657043 0.594451 +v 0.691995 0.65653 0.595698 +v 0.688753 0.657118 0.59467 +v 0.711712 0.656702 0.595451 +v 0.707099 0.658884 0.592846 +v 0.4981 0.504696 0.590607 +v 0.497425 0.487755 0.591552 +v 0.509673 0.492513 0.591762 +v 0.332172 0.615517 0.583178 +v 0.336377 0.613769 0.589309 +v 0.33985 0.614952 0.587658 +v 0.347745 0.620199 0.591788 +v 0.34493 0.616942 0.590175 +v 0.653981 0.61856 0.58627 +v 0.650916 0.620513 0.591843 +v 0.698343 0.620975 0.593953 +v 0.698293 0.609568 0.583682 +v 0.705384 0.620784 0.593282 +v 0.284201 0.621228 0.588993 +v 0.292307 0.618307 0.590595 +v 0.30095 0.617882 0.591379 +v 0.30961 0.620594 0.591035 +v 0.31744 0.623734 0.589586 +v 0.313658 0.614807 0.584652 +v 0.34532 0.62479 0.583105 +v 0.691954 0.623619 0.594662 +v 0.711887 0.621283 0.590806 +v 0.322135 0.624799 0.588511 +v 0.319928 0.628563 0.590339 +v 0.683179 0.63118 0.595124 +v 0.680184 0.633654 0.594431 +v 0.679737 0.62908 0.590884 +v 0.687078 0.628027 0.595553 +v 0.685864 0.620227 0.589987 +v 0.276896 0.630037 0.593292 +v 0.278241 0.62873 0.591236 +v 0.274459 0.630025 0.590104 +v 0.320051 0.637341 0.591219 +v 0.666143 0.636493 0.587722 +v 0.66051 0.633189 0.592849 +v 0.661144 0.636554 0.585075 +v 0.724112 0.630357 0.591934 +v 0.727268 0.631684 0.589193 +v 0.730191 0.634166 0.586363 +v 0.67791 0.637128 0.593764 +v 0.675161 0.644858 0.597058 +v 0.676038 0.64134 0.593442 +v 0.675016 0.64856 0.592858 +v 0.723381 0.647106 0.596504 +v 0.280908 0.65294 0.590453 +v 0.725835 0.649305 0.590974 +v 0.303884 0.657982 0.590864 +v 0.309749 0.658295 0.588595 +v 0.321677 0.652778 0.590347 +v 0.318332 0.656021 0.589279 +v 0.696986 0.657197 0.592188 +v 0.29814 0.659694 0.585962 +v 0.688369 0.659089 0.584469 +v 0.702073 0.659129 0.589995 +v 0.465413 0.176965 0.585982 +v 0.465657 0.172325 0.584978 +v 0.470257 0.173277 0.585029 +v 0.460052 0.171877 0.583565 +v 0.464911 0.168159 0.583085 +v 0.473863 0.175627 0.584482 +v 0.474749 0.170123 0.582069 +v 0.531622 0.174805 0.585471 +v 0.53122 0.180157 0.585859 +v 0.526362 0.176169 0.584207 +v 0.532277 0.169673 0.583584 +v 0.538375 0.17391 0.584432 +v 0.466356 0.18102 0.585895 +v 0.460515 0.180123 0.584808 +v 0.53694 0.183205 0.584518 +v 0.530715 0.185108 0.584203 +v 0.502606 0.46071 0.585562 +v 0.513733 0.468894 0.587331 +v 0.499557 0.473912 0.589293 +v 0.526966 0.462572 0.582981 +v 0.526143 0.474585 0.58629 +v 0.486652 0.481213 0.589741 +v 0.474151 0.489335 0.588814 +v 0.476637 0.475141 0.586962 +v 0.52353 0.487285 0.589015 +v 0.536723 0.482014 0.584647 +v 0.520897 0.500937 0.589329 +v 0.528975 0.51841 0.58425 +v 0.516811 0.521694 0.586099 +v 0.490324 0.529697 0.584803 +v 0.484984 0.558747 0.57635 +v 0.476375 0.528601 0.582711 +v 0.503547 0.527909 0.585774 +v 0.512022 0.551401 0.578953 +v 0.663381 0.614727 0.585868 +v 0.667889 0.616485 0.583836 +v 0.661892 0.616042 0.58064 +v 0.295988 0.609786 0.583848 +v 0.339471 0.618104 0.580715 +v 0.670905 0.617819 0.584431 +v 0.675385 0.617731 0.584518 +v 0.671927 0.619672 0.587803 +v 0.680146 0.62282 0.588292 +v 0.681637 0.61688 0.58586 +v 0.325211 0.62221 0.587951 +v 0.327185 0.618781 0.585842 +v 0.653825 0.626345 0.582111 +v 0.650856 0.623997 0.591932 +v 0.651609 0.627167 0.590821 +v 0.673626 0.623437 0.588443 +v 0.71788 0.621644 0.586419 +v 0.712459 0.611941 0.582188 +v 0.722767 0.621687 0.580333 +v 0.72158 0.629041 0.589012 +v 0.324617 0.625553 0.589318 +v 0.325361 0.628994 0.589792 +v 0.342526 0.632229 0.580305 +v 0.341952 0.633069 0.587589 +v 0.676596 0.626545 0.588355 +v 0.674521 0.628056 0.589385 +v 0.72346 0.63074 0.589816 +v 0.269137 0.633758 0.584434 +v 0.271688 0.631229 0.587271 +v 0.274296 0.628429 0.585529 +v 0.323528 0.639423 0.587552 +v 0.320605 0.633821 0.590204 +v 0.32302 0.631303 0.589264 +v 0.327159 0.632697 0.589409 +v 0.656039 0.633305 0.582791 +v 0.673196 0.631074 0.589888 +v 0.67256 0.634745 0.588093 +v 0.329776 0.635877 0.588214 +v 0.269241 0.647417 0.577681 +v 0.265773 0.642219 0.585425 +v 0.265714 0.6441 0.590033 +v 0.268487 0.647603 0.589092 +v 0.675399 0.639807 0.587871 +v 0.673512 0.643871 0.583329 +v 0.673677 0.638624 0.586091 +v 0.732274 0.646063 0.58755 +v 0.733133 0.64393 0.58685 +v 0.72967 0.64816 0.578978 +v 0.729581 0.648463 0.587802 +v 0.324184 0.649058 0.587236 +v 0.323383 0.651295 0.580397 +v 0.325355 0.64597 0.584002 +v 0.674153 0.648576 0.583442 +v 0.676178 0.652076 0.588725 +v 0.317295 0.656888 0.577388 +v 0.313994 0.658221 0.583471 +v 0.684053 0.658295 0.578287 +v 0.678659 0.65413 0.570909 +v 0.679033 0.655434 0.583377 +v 0.704232 0.660586 0.581304 +v 0.503489 0.760146 0.585391 +v 0.498868 0.763357 0.587444 +v 0.481195 0.76131 0.585557 +v 0.496396 0.774668 0.587937 +v 0.47779 0.769587 0.588278 +v 0.496935 0.767253 0.589 +v 0.517534 0.76563 0.588267 +v 0.531229 0.765347 0.586174 +v 0.527056 0.771885 0.586969 +v 0.46893 0.775558 0.584985 +v 0.464172 0.768433 0.585428 +v 0.510928 0.78666 0.583328 +v 0.494525 0.78844 0.58254 +v 0.461044 0.165293 0.579574 +v 0.466787 0.1642 0.579799 +v 0.526531 0.167256 0.580564 +v 0.53236 0.16517 0.580174 +v 0.532422 0.161523 0.575047 +v 0.538412 0.164047 0.577761 +v 0.425702 0.168814 0.579391 +v 0.430967 0.170641 0.580195 +v 0.426218 0.1731 0.58088 +v 0.421042 0.175323 0.578357 +v 0.425417 0.177915 0.580287 +v 0.522722 0.171876 0.58095 +v 0.521931 0.177946 0.581308 +v 0.546102 0.173709 0.580879 +v 0.54557 0.177857 0.581617 +v 0.5791 0.177528 0.577893 +v 0.573321 0.177327 0.58045 +v 0.574646 0.173082 0.580348 +v 0.578019 0.170181 0.57803 +v 0.572282 0.16866 0.579429 +v 0.424924 0.182911 0.578452 +v 0.430405 0.180325 0.579993 +v 0.437384 0.182538 0.5777 +v 0.438132 0.177892 0.579422 +v 0.455675 0.182639 0.581693 +v 0.453456 0.17839 0.581507 +v 0.47158 0.180563 0.585245 +v 0.476495 0.178827 0.583211 +v 0.479009 0.181976 0.580522 +v 0.480763 0.17758 0.57919 +v 0.51846 0.18043 0.577329 +v 0.522136 0.183979 0.580184 +v 0.571887 0.181471 0.579706 +v 0.567346 0.177151 0.580766 +v 0.45309 0.185772 0.578358 +v 0.451583 0.189431 0.573501 +v 0.445324 0.185071 0.575359 +v 0.460149 0.187587 0.581475 +v 0.468583 0.184714 0.584551 +v 0.471542 0.188277 0.581547 +v 0.465912 0.188658 0.582405 +v 0.543694 0.185288 0.580538 +v 0.545182 0.181651 0.581143 +v 0.553555 0.180439 0.578224 +v 0.540997 0.188882 0.579801 +v 0.548379 0.187209 0.576453 +v 0.462219 0.192114 0.577776 +v 0.529998 0.189771 0.580502 +v 0.525846 0.187303 0.580862 +v 0.534766 0.191357 0.579456 +v 0.53114 0.194058 0.574848 +v 0.494327 0.449891 0.58099 +v 0.50609 0.448999 0.580595 +v 0.4745 0.459672 0.581838 +v 0.465119 0.469888 0.582508 +v 0.525515 0.452095 0.57932 +v 0.536298 0.452886 0.576106 +v 0.45398 0.461644 0.575254 +v 0.456513 0.478227 0.581344 +v 0.543348 0.496564 0.582398 +v 0.548412 0.480319 0.579846 +v 0.447872 0.485913 0.578217 +v 0.460878 0.490797 0.584839 +v 0.467873 0.504497 0.585762 +v 0.53893 0.519151 0.580741 +v 0.532246 0.544559 0.576639 +v 0.455003 0.529039 0.575845 +v 0.463549 0.527175 0.579577 +v 0.461305 0.550698 0.572528 +v 0.328877 0.616744 0.582273 +v 0.329433 0.615995 0.577259 +v 0.670908 0.614198 0.575498 +v 0.680027 0.612057 0.579723 +v 0.276144 0.625482 0.584874 +v 0.273463 0.624649 0.57889 +v 0.278724 0.623719 0.586491 +v 0.280343 0.615219 0.579806 +v 0.326079 0.617566 0.581459 +v 0.267082 0.636322 0.58312 +v 0.269779 0.632921 0.576165 +v 0.332697 0.639703 0.585243 +v 0.328028 0.64345 0.581367 +v 0.330421 0.639468 0.584901 +v 0.336798 0.637048 0.587831 +v 0.670516 0.638313 0.585401 +v 0.731361 0.637391 0.580665 +v 0.728777 0.631576 0.576757 +v 0.265543 0.638401 0.585793 +v 0.327197 0.639464 0.585614 +v 0.668735 0.64072 0.582334 +v 0.32585 0.643036 0.583858 +v 0.274388 0.651556 0.586158 +v 0.724484 0.651193 0.582628 +v 0.281433 0.655043 0.589371 +v 0.279273 0.65434 0.583563 +v 0.714597 0.655838 0.58625 +v 0.503939 0.75829 0.582811 +v 0.525113 0.759603 0.583233 +v 0.45974 0.76166 0.581635 +v 0.466907 0.761468 0.583614 +v 0.462887 0.763518 0.584053 +v 0.479059 0.758988 0.582453 +v 0.535617 0.762419 0.582957 +v 0.540542 0.76613 0.583072 +v 0.540035 0.760244 0.578842 +v 0.455096 0.768008 0.581205 +v 0.460333 0.765388 0.583512 +v 0.457587 0.763205 0.581673 +v 0.547001 0.767868 0.579817 +v 0.541218 0.773411 0.581666 +v 0.540245 0.78677 0.575122 +v 0.534324 0.786181 0.578935 +v 0.526237 0.797924 0.575872 +v 0.528764 0.784797 0.581638 +v 0.478832 0.788896 0.580991 +v 0.468106 0.788106 0.578663 +v 0.49179 0.802219 0.574951 +v 0.521807 0.784865 0.583219 +v 0.518547 0.79803 0.577666 +v 0.466683 0.160805 0.57483 +v 0.470612 0.16265 0.576835 +v 0.472907 0.161231 0.569597 +v 0.474373 0.164764 0.577384 +v 0.545491 0.166586 0.576211 +v 0.544801 0.163342 0.571399 +v 0.420958 0.168273 0.576457 +v 0.425228 0.165286 0.576336 +v 0.431088 0.163354 0.574123 +v 0.438486 0.163198 0.569557 +v 0.437878 0.16589 0.574473 +v 0.477801 0.167157 0.576716 +v 0.55994 0.16694 0.574769 +v 0.566751 0.167213 0.577587 +v 0.560539 0.170944 0.578013 +v 0.571109 0.164448 0.575814 +v 0.415319 0.168394 0.571478 +v 0.417069 0.171868 0.574678 +v 0.437832 0.169503 0.577436 +v 0.43837 0.17358 0.579258 +v 0.445955 0.168814 0.575546 +v 0.453395 0.174618 0.581084 +v 0.453491 0.170777 0.579569 +v 0.521404 0.168112 0.577114 +v 0.547808 0.170301 0.578199 +v 0.552604 0.16744 0.573945 +v 0.414838 0.17576 0.573091 +v 0.446081 0.17628 0.578805 +v 0.55349 0.173363 0.578146 +v 0.560745 0.178731 0.579098 +v 0.560828 0.174953 0.579402 +v 0.48162 0.184291 0.575839 +v 0.477347 0.18652 0.579255 +v 0.516919 0.183696 0.573025 +v 0.51592 0.177492 0.573326 +v 0.5611 0.182313 0.577736 +v 0.568085 0.184316 0.578024 +v 0.561972 0.185904 0.575159 +v 0.57369 0.185775 0.576975 +v 0.474932 0.19058 0.577286 +v 0.477125 0.192299 0.571213 +v 0.4725 0.194404 0.572973 +v 0.52212 0.189011 0.576721 +v 0.540938 0.191573 0.576741 +v 0.51676 0.446513 0.578378 +v 0.508767 0.437968 0.574311 +v 0.482845 0.448875 0.579103 +v 0.486425 0.437414 0.573089 +v 0.4694 0.445867 0.574036 +v 0.527683 0.442281 0.573454 +v 0.439218 0.497158 0.572824 +v 0.436152 0.478828 0.569582 +v 0.547789 0.517794 0.577114 +v 0.521466 0.568778 0.572001 +v 0.508159 0.582943 0.569334 +v 0.294977 0.594726 0.561572 +v 0.294126 0.601833 0.572959 +v 0.288201 0.602223 0.570347 +v 0.301748 0.601413 0.57382 +v 0.710621 0.603198 0.571075 +v 0.705552 0.602989 0.574715 +v 0.324068 0.614094 0.576207 +v 0.318109 0.609035 0.575604 +v 0.324 0.603281 0.562492 +v 0.309929 0.603661 0.57484 +v 0.675019 0.607523 0.569631 +v 0.67129 0.607471 0.564904 +v 0.679992 0.60078 0.565146 +v 0.338588 0.621226 0.574763 +v 0.33389 0.618228 0.572707 +v 0.658839 0.620558 0.57587 +v 0.660216 0.618037 0.57767 +v 0.33448 0.640427 0.57955 +v 0.268218 0.638571 0.57108 +v 0.661858 0.638677 0.579085 +v 0.661324 0.637369 0.575045 +v 0.666462 0.641207 0.579455 +v 0.670179 0.644336 0.578558 +v 0.732847 0.641295 0.584249 +v 0.730385 0.638999 0.571287 +v 0.671504 0.646942 0.571824 +v 0.672659 0.646994 0.579576 +v 0.724579 0.651293 0.574195 +v 0.719142 0.653631 0.57731 +v 0.713929 0.656918 0.574035 +v 0.301817 0.660532 0.574243 +v 0.308251 0.659703 0.576446 +v 0.307624 0.658974 0.563681 +v 0.690287 0.660058 0.573572 +v 0.712093 0.655693 0.559706 +v 0.708453 0.659771 0.572325 +v 0.479503 0.727222 0.573725 +v 0.484038 0.732822 0.578373 +v 0.472179 0.732755 0.576108 +v 0.498246 0.732834 0.579317 +v 0.504718 0.727675 0.575328 +v 0.511171 0.734138 0.579285 +v 0.489172 0.736194 0.578973 +v 0.51021 0.738393 0.578692 +v 0.503581 0.742637 0.576809 +v 0.494202 0.739874 0.578072 +v 0.478584 0.740316 0.576869 +v 0.520883 0.73665 0.578046 +v 0.530189 0.739016 0.575409 +v 0.529186 0.735168 0.575981 +v 0.518065 0.743995 0.57503 +v 0.500859 0.745368 0.574413 +v 0.490751 0.757488 0.579487 +v 0.470431 0.756849 0.575198 +v 0.498825 0.756668 0.576076 +v 0.454576 0.760785 0.577901 +v 0.451615 0.774218 0.576761 +v 0.44846 0.768302 0.575662 +v 0.461141 0.790507 0.573996 +v 0.470438 0.802386 0.569221 +v 0.519572 0.805684 0.571464 +v 0.499038 0.840308 0.576092 +v 0.498263 0.844437 0.576118 +v 0.493996 0.841368 0.574731 +v 0.500692 0.836936 0.575176 +v 0.50351 0.84129 0.576031 +v 0.426681 0.162366 0.57248 +v 0.461653 0.160647 0.572341 +v 0.45636 0.163633 0.574513 +v 0.455873 0.162069 0.567996 +v 0.45372 0.16712 0.577046 +v 0.568379 0.161837 0.571605 +v 0.574967 0.162942 0.572254 +v 0.480989 0.169569 0.574211 +v 0.479819 0.166011 0.568615 +v 0.517383 0.17124 0.573385 +v 0.520561 0.166022 0.572363 +v 0.560292 0.163935 0.571388 +v 0.581428 0.165423 0.570242 +v 0.588956 0.167057 0.566341 +v 0.583129 0.168583 0.57257 +v 0.579442 0.162634 0.565454 +v 0.483193 0.171474 0.567433 +v 0.482604 0.174235 0.574794 +v 0.584588 0.172015 0.573097 +v 0.585096 0.176146 0.572769 +v 0.590917 0.174246 0.567761 +v 0.483932 0.178169 0.573266 +v 0.58314 0.181018 0.573116 +v 0.421084 0.1841 0.575262 +v 0.427834 0.18668 0.575931 +v 0.436506 0.186279 0.575033 +v 0.562186 0.189518 0.570184 +v 0.555387 0.187367 0.572851 +v 0.57841 0.185676 0.574062 +v 0.573384 0.189296 0.571998 +v 0.560181 0.483172 0.573771 +v 0.556971 0.470106 0.572407 +v 0.449642 0.542171 0.569158 +v 0.444581 0.517826 0.572806 +v 0.566851 0.51655 0.56562 +v 0.557137 0.515313 0.57253 +v 0.563685 0.497189 0.571584 +v 0.551445 0.541248 0.5691 +v 0.529528 0.575848 0.567624 +v 0.309 0.593676 0.56103 +v 0.690135 0.596829 0.565116 +v 0.698064 0.59949 0.570769 +v 0.327149 0.615606 0.576002 +v 0.329755 0.615684 0.572491 +v 0.666039 0.616984 0.571171 +v 0.722386 0.612301 0.566722 +v 0.725884 0.622576 0.57275 +v 0.271223 0.626463 0.57274 +v 0.272578 0.619733 0.56931 +v 0.659798 0.624561 0.571571 +v 0.663242 0.622775 0.566726 +v 0.660124 0.633358 0.571622 +v 0.658885 0.628473 0.571891 +v 0.270216 0.628181 0.56424 +v 0.331509 0.642941 0.57225 +v 0.326337 0.648298 0.57436 +v 0.320994 0.653705 0.574499 +v 0.725221 0.648384 0.566802 +v 0.276218 0.652195 0.572397 +v 0.284572 0.656696 0.57479 +v 0.289554 0.656938 0.560483 +v 0.291266 0.659968 0.573952 +v 0.296461 0.659646 0.562264 +v 0.295861 0.660745 0.576814 +v 0.532041 0.722607 0.565562 +v 0.52963 0.730123 0.573155 +v 0.521742 0.720577 0.566707 +v 0.463748 0.730737 0.571404 +v 0.464934 0.735584 0.574061 +v 0.537306 0.734564 0.572871 +v 0.458418 0.738464 0.570423 +v 0.467222 0.73952 0.574627 +v 0.468489 0.743501 0.573011 +v 0.539149 0.740382 0.571692 +v 0.531148 0.742533 0.573716 +v 0.530255 0.745134 0.571677 +v 0.449524 0.760737 0.572558 +v 0.455298 0.75798 0.573763 +v 0.456945 0.756361 0.568743 +v 0.499332 0.756654 0.571396 +v 0.525025 0.756675 0.573969 +v 0.549265 0.757446 0.565806 +v 0.544767 0.758592 0.57286 +v 0.540165 0.757018 0.572116 +v 0.550382 0.761468 0.572116 +v 0.552025 0.76772 0.574876 +v 0.551237 0.771646 0.574773 +v 0.556173 0.770276 0.568661 +v 0.554331 0.765251 0.570961 +v 0.502427 0.833784 0.572994 +v 0.504802 0.830905 0.569774 +v 0.509407 0.83535 0.570475 +v 0.501828 0.827538 0.567122 +v 0.506923 0.828425 0.565634 +v 0.495573 0.834348 0.57294 +v 0.490926 0.837965 0.571906 +v 0.489535 0.843065 0.571391 +v 0.490431 0.848419 0.569876 +v 0.485967 0.844171 0.565529 +v 0.50219 0.845723 0.575924 +v 0.50567 0.844855 0.574936 +v 0.506849 0.849236 0.572786 +v 0.509528 0.844721 0.572261 +v 0.512803 0.846998 0.567646 +v 0.512379 0.841095 0.569481 +v 0.498845 0.849178 0.574241 +v 0.507874 0.852649 0.569622 +v 0.504395 0.853315 0.570969 +v 0.500369 0.853811 0.57047 +v 0.495679 0.852056 0.570367 +v 0.464814 0.159331 0.568243 +v 0.528607 0.160621 0.569154 +v 0.532816 0.159876 0.566657 +v 0.423242 0.1623 0.569627 +v 0.416298 0.165475 0.568951 +v 0.419176 0.163025 0.564757 +v 0.430351 0.160622 0.567227 +v 0.523656 0.162814 0.568679 +v 0.519886 0.165843 0.56481 +v 0.526963 0.16117 0.562117 +v 0.561664 0.162268 0.567698 +v 0.409602 0.167896 0.566439 +v 0.51538 0.17514 0.567555 +v 0.414871 0.179523 0.572017 +v 0.408489 0.175179 0.567847 +v 0.416451 0.183569 0.56928 +v 0.484025 0.18199 0.57167 +v 0.485079 0.179931 0.566102 +v 0.4827 0.186451 0.568606 +v 0.583986 0.183879 0.568778 +v 0.59022 0.182258 0.56316 +v 0.582063 0.186987 0.564264 +v 0.455689 0.193697 0.570842 +v 0.447504 0.193064 0.565686 +v 0.51962 0.1889 0.572641 +v 0.51752 0.187171 0.567364 +v 0.522614 0.192563 0.570727 +v 0.548481 0.18975 0.573581 +v 0.56812 0.19192 0.566679 +v 0.559343 0.193691 0.563026 +v 0.460626 0.196043 0.568753 +v 0.471865 0.197521 0.563713 +v 0.466746 0.197521 0.566595 +v 0.480011 0.191269 0.564188 +v 0.476207 0.195205 0.562232 +v 0.543779 0.193293 0.570886 +v 0.536692 0.196483 0.568075 +v 0.530553 0.196892 0.566583 +v 0.473942 0.426652 0.562614 +v 0.485898 0.425839 0.564204 +v 0.568105 0.461303 0.561583 +v 0.556904 0.454879 0.566375 +v 0.571238 0.488237 0.566435 +v 0.432551 0.509251 0.566397 +v 0.455103 0.563511 0.565179 +v 0.46269 0.57498 0.564798 +v 0.699524 0.593583 0.560901 +v 0.286207 0.598505 0.560062 +v 0.282623 0.606814 0.571408 +v 0.704704 0.59341 0.557052 +v 0.711564 0.597446 0.557002 +v 0.277958 0.610123 0.568406 +v 0.669657 0.603832 0.55733 +v 0.669296 0.612056 0.566048 +v 0.331063 0.617434 0.568174 +v 0.667449 0.616655 0.565132 +v 0.340595 0.625034 0.574498 +v 0.339856 0.629598 0.572161 +v 0.335819 0.624311 0.566998 +v 0.335826 0.63749 0.570426 +v 0.329003 0.642982 0.5624 +v 0.666174 0.639265 0.5645 +v 0.275194 0.648062 0.561241 +v 0.317965 0.654883 0.566231 +v 0.673477 0.647908 0.562022 +v 0.669757 0.643185 0.559773 +v 0.677503 0.64995 0.55511 +v 0.68939 0.658544 0.562561 +v 0.696029 0.660735 0.56809 +v 0.699952 0.659059 0.558662 +v 0.702541 0.660899 0.570221 +v 0.535982 0.716136 0.556621 +v 0.540542 0.724861 0.56294 +v 0.542894 0.737464 0.570124 +v 0.543108 0.732863 0.567845 +v 0.545578 0.74082 0.567552 +v 0.469253 0.746494 0.569801 +v 0.459096 0.744928 0.567652 +v 0.484803 0.746672 0.571525 +v 0.471968 0.747873 0.566753 +v 0.504664 0.746866 0.571373 +v 0.524256 0.746983 0.569648 +v 0.508229 0.747544 0.566463 +v 0.537676 0.746709 0.56683 +v 0.474067 0.757309 0.56599 +v 0.491913 0.758749 0.565741 +v 0.539456 0.756485 0.567723 +v 0.445641 0.764698 0.570698 +v 0.444112 0.760749 0.563877 +v 0.557392 0.763555 0.564701 +v 0.444094 0.771592 0.567616 +v 0.445313 0.783336 0.562835 +v 0.441484 0.778103 0.556723 +v 0.555008 0.775258 0.567661 +v 0.551633 0.779314 0.569035 +v 0.557849 0.776626 0.561239 +v 0.449326 0.784871 0.567896 +v 0.454316 0.785451 0.572306 +v 0.4568 0.797534 0.565573 +v 0.490677 0.834313 0.569478 +v 0.490917 0.83051 0.565624 +v 0.486993 0.834982 0.564058 +v 0.514503 0.837963 0.564865 +v 0.491943 0.853279 0.565986 +v 0.503144 0.856175 0.567276 +v 0.459584 0.160456 0.561996 +v 0.452259 0.162734 0.560459 +v 0.552635 0.162979 0.564754 +v 0.543909 0.161871 0.563467 +v 0.576454 0.161426 0.558124 +v 0.584026 0.162775 0.55789 +v 0.40262 0.168524 0.563591 +v 0.401897 0.171774 0.564348 +v 0.396085 0.168557 0.559832 +v 0.403992 0.165734 0.562223 +v 0.414667 0.163496 0.558752 +v 0.422499 0.161829 0.55813 +v 0.594992 0.164852 0.561822 +v 0.596478 0.167927 0.563685 +v 0.60226 0.169719 0.562022 +v 0.596801 0.17207 0.564822 +v 0.402665 0.179076 0.562025 +v 0.395811 0.176239 0.559761 +v 0.40176 0.175207 0.564147 +v 0.59707 0.176114 0.564262 +v 0.41079 0.182945 0.562025 +v 0.404987 0.183308 0.556479 +v 0.602622 0.176806 0.561187 +v 0.597268 0.179461 0.56199 +v 0.418978 0.187687 0.563332 +v 0.427938 0.191076 0.564293 +v 0.420263 0.19272 0.553481 +v 0.433546 0.189014 0.571177 +v 0.43804 0.192143 0.564148 +v 0.481981 0.18833 0.559225 +v 0.522853 0.194231 0.562087 +v 0.521553 0.194812 0.552385 +v 0.519388 0.190526 0.5599 +v 0.51644 0.185123 0.559131 +v 0.57407 0.191366 0.564602 +v 0.580544 0.189853 0.557391 +v 0.547204 0.195655 0.563519 +v 0.458715 0.200186 0.558415 +v 0.499066 0.427433 0.566593 +v 0.488251 0.416039 0.55554 +v 0.513413 0.426624 0.565256 +v 0.522555 0.415382 0.554328 +v 0.530284 0.423259 0.559306 +v 0.463008 0.433042 0.563782 +v 0.460148 0.420175 0.553739 +v 0.536245 0.432137 0.563927 +v 0.546953 0.417727 0.551316 +v 0.455335 0.445098 0.568128 +v 0.539366 0.441437 0.568689 +v 0.444883 0.450221 0.565189 +v 0.434267 0.439011 0.553626 +v 0.436131 0.45913 0.563283 +v 0.54809 0.447345 0.56774 +v 0.559514 0.435071 0.555685 +v 0.426666 0.468438 0.559099 +v 0.444514 0.559782 0.559862 +v 0.526499 0.601963 0.56138 +v 0.534192 0.58202 0.563817 +v 0.544666 0.570894 0.562975 +v 0.539056 0.596767 0.558224 +v 0.479546 0.603906 0.561441 +v 0.47268 0.586222 0.564493 +v 0.482322 0.584341 0.567592 +v 0.494499 0.585966 0.568419 +v 0.503445 0.607823 0.561358 +v 0.66532 0.60625 0.551869 +v 0.665753 0.596664 0.544146 +v 0.721382 0.605039 0.54953 +v 0.71729 0.601467 0.55492 +v 0.274555 0.612963 0.56403 +v 0.277292 0.605298 0.555824 +v 0.273091 0.613751 0.555161 +v 0.333057 0.621512 0.563995 +v 0.333722 0.627036 0.561437 +v 0.331605 0.616183 0.562449 +v 0.664729 0.625753 0.561215 +v 0.665633 0.621157 0.562486 +v 0.727166 0.62356 0.562912 +v 0.663352 0.62876 0.563809 +v 0.338156 0.633595 0.570207 +v 0.334346 0.632235 0.563042 +v 0.496763 0.715994 0.564583 +v 0.485819 0.716425 0.564342 +v 0.489469 0.705477 0.553857 +v 0.509401 0.717627 0.565509 +v 0.475468 0.718482 0.564438 +v 0.466059 0.722411 0.565165 +v 0.470891 0.712108 0.555999 +v 0.514288 0.708957 0.556623 +v 0.451339 0.737035 0.562994 +v 0.445325 0.73715 0.552723 +v 0.448765 0.731348 0.555915 +v 0.453928 0.741578 0.565949 +v 0.451924 0.745245 0.561515 +v 0.550912 0.742337 0.561416 +v 0.547709 0.744059 0.563896 +v 0.473813 0.747889 0.562858 +v 0.486881 0.74714 0.561452 +v 0.471699 0.746959 0.555816 +v 0.462788 0.748886 0.561072 +v 0.54277 0.748354 0.560683 +v 0.545387 0.746623 0.562692 +v 0.550071 0.747294 0.558319 +v 0.459399 0.75657 0.560858 +v 0.461681 0.759131 0.557948 +v 0.543439 0.756615 0.560309 +v 0.54886 0.756675 0.561106 +v 0.56102 0.768599 0.556723 +v 0.560029 0.762736 0.55762 +v 0.448399 0.795038 0.558119 +v 0.53843 0.801103 0.564186 +v 0.547158 0.787648 0.56856 +v 0.552949 0.788987 0.559963 +v 0.532443 0.812349 0.552711 +v 0.525527 0.813515 0.557238 +v 0.479731 0.814733 0.558808 +v 0.471717 0.812008 0.557494 +v 0.485127 0.815823 0.559733 +v 0.484788 0.823778 0.550437 +v 0.489983 0.811326 0.566316 +v 0.491011 0.818058 0.55807 +v 0.500509 0.810869 0.567242 +v 0.519051 0.813063 0.561576 +v 0.510897 0.81203 0.564945 +v 0.515261 0.820807 0.552106 +v 0.503863 0.817115 0.559305 +v 0.510749 0.852049 0.566398 +v 0.513543 0.850314 0.5616 +v 0.48802 0.852052 0.560732 +v 0.49267 0.855653 0.559841 +v 0.50711 0.855323 0.566072 +v 0.504393 0.857187 0.561542 +v 0.434783 0.16084 0.559809 +v 0.437824 0.161585 0.563652 +v 0.445119 0.163299 0.561709 +v 0.449853 0.161996 0.551483 +v 0.464446 0.159986 0.559587 +v 0.477009 0.166053 0.542653 +v 0.478175 0.165729 0.558019 +v 0.47405 0.162616 0.558088 +v 0.481531 0.168768 0.560413 +v 0.531181 0.160448 0.557912 +v 0.536543 0.160644 0.560289 +v 0.548312 0.161065 0.550061 +v 0.564999 0.160943 0.549763 +v 0.568351 0.160847 0.556865 +v 0.5614 0.16164 0.561274 +v 0.592298 0.162945 0.558574 +v 0.599804 0.162786 0.55694 +v 0.406568 0.163643 0.559354 +v 0.399091 0.163665 0.557496 +v 0.408209 0.162467 0.553763 +v 0.606248 0.168479 0.558022 +v 0.605305 0.172764 0.560128 +v 0.606517 0.176 0.557114 +v 0.596101 0.182503 0.557717 +v 0.442087 0.196928 0.557906 +v 0.47444 0.198773 0.552821 +v 0.526164 0.195788 0.565045 +v 0.530868 0.200076 0.557063 +v 0.516448 0.408976 0.548567 +v 0.529831 0.405216 0.544941 +v 0.578814 0.499667 0.558646 +v 0.578875 0.483835 0.558588 +v 0.575359 0.519451 0.557636 +v 0.567073 0.541604 0.557836 +v 0.583378 0.514424 0.550336 +v 0.432085 0.543195 0.556009 +v 0.419619 0.521642 0.550752 +v 0.426819 0.516766 0.559769 +v 0.421421 0.494625 0.558932 +v 0.437714 0.570106 0.550555 +v 0.555545 0.560734 0.559818 +v 0.46338 0.593147 0.558331 +v 0.461688 0.604069 0.555904 +v 0.453768 0.597158 0.552015 +v 0.327437 0.589952 0.541453 +v 0.332431 0.597442 0.545075 +v 0.471026 0.616574 0.55941 +v 0.477212 0.619793 0.559833 +v 0.333327 0.60651 0.552368 +v 0.334659 0.614188 0.552717 +v 0.462757 0.62625 0.558945 +v 0.463032 0.615595 0.557788 +v 0.495681 0.625123 0.55791 +v 0.510433 0.625323 0.557824 +v 0.531364 0.616927 0.559532 +v 0.527443 0.620829 0.559898 +v 0.538728 0.614035 0.557755 +v 0.547927 0.611739 0.554146 +v 0.724543 0.612121 0.546989 +v 0.726669 0.621911 0.549505 +v 0.481591 0.627504 0.559246 +v 0.469285 0.630023 0.559717 +v 0.487231 0.639642 0.556806 +v 0.524122 0.629292 0.558903 +v 0.517539 0.642025 0.556171 +v 0.534314 0.634133 0.559345 +v 0.541245 0.625322 0.558672 +v 0.664775 0.629605 0.55606 +v 0.333308 0.629538 0.556733 +v 0.461949 0.635353 0.55844 +v 0.542323 0.633721 0.558551 +v 0.542714 0.641358 0.557219 +v 0.549864 0.631311 0.556293 +v 0.727724 0.630233 0.553835 +v 0.727658 0.63624 0.556544 +v 0.456659 0.640393 0.556251 +v 0.465242 0.646805 0.556438 +v 0.667543 0.638156 0.550951 +v 0.458559 0.725844 0.56337 +v 0.54708 0.727859 0.55984 +v 0.552908 0.73161 0.554143 +v 0.558346 0.736706 0.54618 +v 0.555197 0.741028 0.554117 +v 0.556129 0.746157 0.552884 +v 0.506344 0.746919 0.553494 +v 0.506672 0.747054 0.559545 +v 0.526285 0.746701 0.555471 +v 0.546818 0.749808 0.554722 +v 0.541703 0.748488 0.555902 +v 0.448278 0.756122 0.558824 +v 0.442871 0.757291 0.555269 +v 0.442122 0.755642 0.549152 +v 0.455032 0.755988 0.561244 +v 0.451211 0.756032 0.553828 +v 0.555051 0.757746 0.55843 +v 0.557713 0.757205 0.552698 +v 0.558571 0.759686 0.556356 +v 0.439313 0.761307 0.552122 +v 0.477058 0.76288 0.558645 +v 0.464889 0.763471 0.554395 +v 0.467962 0.766892 0.551424 +v 0.499574 0.761993 0.56123 +v 0.499468 0.765609 0.555528 +v 0.520273 0.763443 0.558632 +v 0.53239 0.763044 0.557372 +v 0.530088 0.767046 0.550773 +v 0.561532 0.760495 0.551528 +v 0.557153 0.785894 0.554557 +v 0.559988 0.777578 0.554776 +v 0.555184 0.79374 0.551466 +v 0.461132 0.806542 0.55772 +v 0.453203 0.801759 0.557005 +v 0.468714 0.814879 0.548871 +v 0.495539 0.819834 0.557122 +v 0.493093 0.822639 0.5565 +v 0.499994 0.819466 0.557678 +v 0.505512 0.82107 0.555428 +v 0.497995 0.822051 0.558688 +v 0.488665 0.82881 0.557945 +v 0.492427 0.826364 0.560892 +v 0.495658 0.824907 0.561136 +v 0.502967 0.824713 0.561692 +v 0.499252 0.82519 0.563334 +v 0.506974 0.825682 0.560295 +v 0.511224 0.828969 0.559814 +v 0.483911 0.839396 0.559161 +v 0.485164 0.833902 0.556408 +v 0.485297 0.830206 0.550147 +v 0.517151 0.84041 0.5571 +v 0.514952 0.834494 0.558802 +v 0.483673 0.843892 0.55678 +v 0.484608 0.847722 0.555539 +v 0.480434 0.843307 0.549094 +v 0.485771 0.850384 0.553232 +v 0.393698 0.165576 0.554552 +v 0.395076 0.163227 0.551354 +v 0.429981 0.160895 0.556249 +v 0.424072 0.161077 0.548937 +v 0.4337 0.160865 0.549899 +v 0.464541 0.161117 0.54837 +v 0.469419 0.160706 0.55869 +v 0.5268 0.162723 0.554464 +v 0.575684 0.160783 0.547313 +v 0.591034 0.162107 0.552849 +v 0.521882 0.165947 0.555117 +v 0.518473 0.169325 0.556893 +v 0.524907 0.16492 0.543055 +v 0.609088 0.168566 0.553089 +v 0.607108 0.165575 0.553235 +v 0.39148 0.169224 0.553693 +v 0.391214 0.173681 0.553543 +v 0.387545 0.170739 0.546507 +v 0.483228 0.173517 0.557417 +v 0.517111 0.172371 0.544541 +v 0.516533 0.17361 0.558127 +v 0.611986 0.168609 0.547537 +v 0.610441 0.171713 0.551244 +v 0.393479 0.178451 0.552658 +v 0.484358 0.178152 0.557929 +v 0.483909 0.176001 0.545914 +v 0.515606 0.179236 0.558593 +v 0.48387 0.183139 0.558031 +v 0.515416 0.182488 0.54776 +v 0.399876 0.183326 0.550967 +v 0.406534 0.188744 0.546814 +v 0.482932 0.188004 0.548854 +v 0.448672 0.201546 0.553823 +v 0.438484 0.202123 0.550186 +v 0.551763 0.20015 0.554865 +v 0.451069 0.412305 0.546595 +v 0.464423 0.408223 0.54582 +v 0.559698 0.413391 0.544941 +v 0.555574 0.399781 0.539088 +v 0.579211 0.453404 0.549837 +v 0.578252 0.468805 0.555483 +v 0.418643 0.454082 0.547595 +v 0.418486 0.475432 0.553865 +v 0.561935 0.569503 0.551425 +v 0.56648 0.577164 0.544381 +v 0.55852 0.593677 0.547037 +v 0.673783 0.588279 0.542342 +v 0.681866 0.592774 0.554709 +v 0.683305 0.584226 0.541063 +v 0.711138 0.590897 0.540204 +v 0.45398 0.614858 0.554282 +v 0.66068 0.619478 0.545095 +v 0.657933 0.611564 0.539159 +v 0.662017 0.612561 0.548567 +v 0.665801 0.615696 0.558595 +v 0.27046 0.629284 0.555857 +v 0.271898 0.619608 0.547033 +v 0.445838 0.627387 0.551365 +v 0.449067 0.637945 0.553376 +v 0.442293 0.63804 0.54862 +v 0.5558 0.637606 0.55262 +v 0.557257 0.63111 0.552016 +v 0.276759 0.638201 0.54206 +v 0.282556 0.64343 0.538702 +v 0.454539 0.649634 0.552618 +v 0.551443 0.643982 0.553491 +v 0.543786 0.651181 0.553341 +v 0.719627 0.644841 0.548919 +v 0.725087 0.641001 0.554755 +v 0.495609 0.654017 0.552834 +v 0.483256 0.654614 0.553957 +v 0.509912 0.655574 0.552333 +v 0.523642 0.658426 0.55239 +v 0.682899 0.652837 0.551327 +v 0.675605 0.645502 0.539258 +v 0.474846 0.657674 0.553404 +v 0.468837 0.66166 0.55131 +v 0.482575 0.670642 0.549747 +v 0.508661 0.698277 0.55056 +v 0.520828 0.705957 0.551761 +v 0.548797 0.721643 0.551273 +v 0.451859 0.726803 0.556533 +v 0.447348 0.725108 0.546688 +v 0.456628 0.719363 0.553641 +v 0.442919 0.746061 0.549847 +v 0.44047 0.741994 0.543553 +v 0.555615 0.748819 0.551877 +v 0.559061 0.750677 0.547841 +v 0.451098 0.74894 0.55662 +v 0.446939 0.747467 0.554566 +v 0.509922 0.748541 0.550108 +v 0.491614 0.748477 0.550242 +v 0.543159 0.747937 0.547785 +v 0.538076 0.746726 0.552048 +v 0.533576 0.746099 0.548045 +v 0.55293 0.749358 0.553815 +v 0.550836 0.750292 0.553242 +v 0.555124 0.752064 0.550065 +v 0.454861 0.750011 0.556444 +v 0.450913 0.751341 0.551981 +v 0.458736 0.749236 0.554118 +v 0.538986 0.759773 0.556262 +v 0.539729 0.75741 0.559469 +v 0.534811 0.759435 0.560984 +v 0.547833 0.756983 0.553144 +v 0.458067 0.761348 0.550979 +v 0.536975 0.762615 0.554739 +v 0.542077 0.76218 0.549505 +v 0.482801 0.767109 0.551938 +v 0.471292 0.768112 0.549552 +v 0.476302 0.767618 0.548546 +v 0.497935 0.766361 0.551946 +v 0.449667 0.800631 0.549742 +v 0.538972 0.809897 0.548476 +v 0.527236 0.819293 0.544835 +v 0.506331 0.823212 0.556179 +v 0.509997 0.8229 0.552525 +v 0.514125 0.83027 0.55292 +v 0.518389 0.841189 0.550269 +v 0.517548 0.844988 0.553502 +v 0.519581 0.848557 0.548208 +v 0.51577 0.848687 0.554491 +v 0.488026 0.852594 0.549908 +v 0.492294 0.855543 0.551722 +v 0.491111 0.855349 0.545135 +v 0.512207 0.85302 0.553606 +v 0.497028 0.857509 0.553138 +v 0.50709 0.856327 0.553285 +v 0.501769 0.857782 0.553703 +v 0.509747 0.855412 0.545913 +v 0.399279 0.161982 0.549347 +v 0.391881 0.162762 0.544733 +v 0.599823 0.161934 0.550754 +v 0.604968 0.163283 0.551664 +v 0.60876 0.163577 0.545852 +v 0.611949 0.174559 0.546629 +v 0.609168 0.174921 0.55214 +v 0.606234 0.179079 0.55184 +v 0.604936 0.182509 0.544005 +v 0.600706 0.183044 0.551133 +v 0.394713 0.182181 0.543831 +v 0.584613 0.192577 0.5475 +v 0.591555 0.18634 0.552466 +v 0.523997 0.200899 0.545285 +v 0.519142 0.197039 0.542482 +v 0.436688 0.208432 0.540978 +v 0.427812 0.20436 0.541867 +v 0.456005 0.205426 0.549387 +v 0.538604 0.212398 0.537441 +v 0.535571 0.206141 0.548096 +v 0.543778 0.207931 0.545473 +v 0.555521 0.207338 0.543779 +v 0.568896 0.41515 0.542044 +v 0.587625 0.472771 0.546912 +v 0.442775 0.590115 0.546537 +v 0.430541 0.573712 0.542375 +v 0.696773 0.585384 0.54422 +v 0.444995 0.61432 0.548507 +v 0.437408 0.610867 0.540132 +v 0.444953 0.602043 0.546131 +v 0.562454 0.607645 0.543 +v 0.55652 0.611148 0.54891 +v 0.557604 0.623166 0.550801 +v 0.339322 0.614446 0.541492 +v 0.335887 0.622205 0.549585 +v 0.271668 0.630672 0.549154 +v 0.33442 0.630536 0.548668 +v 0.564399 0.631097 0.54626 +v 0.659044 0.623218 0.538359 +v 0.662749 0.627306 0.547114 +v 0.66485 0.63305 0.547707 +v 0.330952 0.637916 0.549985 +v 0.334837 0.632011 0.539487 +v 0.437335 0.639499 0.543364 +v 0.44261 0.649625 0.544682 +v 0.665722 0.636042 0.538609 +v 0.281819 0.626403 0.514044 +v 0.275321 0.629227 0.535043 +v 0.55883 0.645263 0.548437 +v 0.722976 0.631433 0.536664 +v 0.32627 0.644414 0.552421 +v 0.325696 0.64335 0.540567 +v 0.320694 0.649795 0.553372 +v 0.71242 0.640511 0.527387 +v 0.713059 0.648246 0.543688 +v 0.314378 0.654731 0.556103 +v 0.707015 0.651401 0.542325 +v 0.688526 0.654116 0.547434 +v 0.302341 0.655147 0.546941 +v 0.295944 0.655818 0.549553 +v 0.505438 0.669556 0.549739 +v 0.544255 0.664564 0.545828 +v 0.534861 0.66162 0.550384 +v 0.462671 0.663492 0.548927 +v 0.456028 0.663056 0.546049 +v 0.471643 0.676054 0.546243 +v 0.528198 0.67239 0.54662 +v 0.516175 0.684123 0.54766 +v 0.505403 0.684844 0.549178 +v 0.489195 0.696455 0.549187 +v 0.486663 0.684403 0.548506 +v 0.49646 0.688296 0.54948 +v 0.479191 0.68327 0.546812 +v 0.481794 0.701632 0.548636 +v 0.465175 0.710868 0.550449 +v 0.474213 0.704695 0.548694 +v 0.53137 0.70975 0.551011 +v 0.541057 0.714268 0.549685 +v 0.528406 0.705611 0.546703 +v 0.459042 0.71253 0.545878 +v 0.455454 0.713728 0.541405 +v 0.460761 0.704464 0.540527 +v 0.54749 0.717468 0.543785 +v 0.442788 0.751844 0.548027 +v 0.463237 0.7473 0.550382 +v 0.458118 0.74837 0.546282 +v 0.46962 0.746386 0.548295 +v 0.478384 0.747934 0.548425 +v 0.485879 0.750666 0.547831 +v 0.524069 0.747873 0.548081 +v 0.513559 0.750819 0.548016 +v 0.52998 0.748019 0.544353 +v 0.452199 0.752249 0.548444 +v 0.448545 0.752825 0.549652 +v 0.549367 0.75158 0.550373 +v 0.549762 0.753454 0.547436 +v 0.54704 0.750915 0.547237 +v 0.443516 0.754975 0.548085 +v 0.44624 0.754121 0.548759 +v 0.447532 0.755302 0.549973 +v 0.452049 0.757394 0.550163 +v 0.547119 0.758574 0.548827 +v 0.551311 0.756257 0.549392 +v 0.55102 0.755027 0.547882 +v 0.554045 0.754783 0.549409 +v 0.556725 0.754602 0.549666 +v 0.559128 0.754731 0.5489 +v 0.456643 0.761796 0.547382 +v 0.438051 0.769901 0.548814 +v 0.436576 0.761008 0.541182 +v 0.491747 0.764827 0.549481 +v 0.505222 0.765036 0.55028 +v 0.505343 0.762484 0.548609 +v 0.516801 0.76605 0.549056 +v 0.52366 0.766737 0.54577 +v 0.527242 0.768224 0.547138 +v 0.465673 0.768737 0.546088 +v 0.534854 0.768587 0.54388 +v 0.439534 0.781705 0.54572 +v 0.551098 0.799777 0.548629 +v 0.556822 0.793878 0.542672 +v 0.463339 0.812681 0.543552 +v 0.47293 0.819898 0.542993 +v 0.513401 0.82583 0.549642 +v 0.516667 0.830827 0.548037 +v 0.481472 0.829487 0.545142 +v 0.518786 0.836046 0.547555 +v 0.521409 0.840141 0.546835 +v 0.501204 0.858044 0.545398 +v 0.404148 0.161618 0.544906 +v 0.425142 0.159783 0.54092 +v 0.415512 0.15972 0.537437 +v 0.44331 0.160488 0.541035 +v 0.452747 0.160535 0.540966 +v 0.56761 0.159822 0.539419 +v 0.561158 0.159199 0.535013 +v 0.576958 0.159519 0.537788 +v 0.59442 0.161322 0.543711 +v 0.61283 0.162988 0.540281 +v 0.609052 0.161029 0.536755 +v 0.615935 0.162327 0.533337 +v 0.614681 0.165135 0.541103 +v 0.61607 0.16784 0.541152 +v 0.617782 0.170646 0.539354 +v 0.619629 0.167936 0.533851 +v 0.487429 0.185814 0.535794 +v 0.484817 0.192633 0.538741 +v 0.403676 0.194086 0.535182 +v 0.411408 0.195028 0.541721 +v 0.486249 0.197579 0.528242 +v 0.480391 0.198089 0.541998 +v 0.41857 0.200196 0.540798 +v 0.516438 0.200526 0.530701 +v 0.514792 0.194219 0.537624 +v 0.585128 0.214738 0.5298 +v 0.575211 0.20486 0.539468 +v 0.581942 0.200479 0.539701 +v 0.593386 0.195153 0.535918 +v 0.417571 0.216914 0.530517 +v 0.475276 0.202914 0.541812 +v 0.52972 0.203722 0.54798 +v 0.526545 0.206937 0.537113 +v 0.494566 0.406947 0.546299 +v 0.500578 0.39639 0.533684 +v 0.50675 0.404733 0.544013 +v 0.42129 0.4337 0.543035 +v 0.428293 0.421008 0.54242 +v 0.410556 0.437927 0.535937 +v 0.412721 0.483042 0.548896 +v 0.593013 0.495632 0.540773 +v 0.587762 0.523687 0.541197 +v 0.303104 0.586437 0.547868 +v 0.311399 0.579965 0.533473 +v 0.310485 0.585556 0.546081 +v 0.318783 0.586574 0.544081 +v 0.297231 0.58802 0.548392 +v 0.292895 0.589055 0.545862 +v 0.301191 0.58127 0.53288 +v 0.278201 0.601026 0.541651 +v 0.282107 0.596506 0.544387 +v 0.339316 0.595734 0.5335 +v 0.720566 0.602161 0.532775 +v 0.275845 0.606027 0.538507 +v 0.273694 0.612328 0.541075 +v 0.275883 0.618259 0.524979 +v 0.293169 0.651591 0.541465 +v 0.308781 0.654806 0.549688 +v 0.558486 0.666316 0.534206 +v 0.552346 0.666731 0.539601 +v 0.559576 0.654962 0.542218 +v 0.694703 0.654146 0.544572 +v 0.701107 0.653441 0.543204 +v 0.70074 0.646813 0.526762 +v 0.443775 0.663223 0.536117 +v 0.44969 0.663225 0.54187 +v 0.458472 0.677982 0.539597 +v 0.473295 0.688751 0.544665 +v 0.534851 0.68133 0.540985 +v 0.52603 0.682208 0.544872 +v 0.526502 0.69338 0.544443 +v 0.536047 0.6959 0.539649 +v 0.529862 0.702266 0.543413 +v 0.47446 0.698561 0.545526 +v 0.537247 0.708382 0.540477 +v 0.450076 0.71881 0.539844 +v 0.45286 0.712897 0.534593 +v 0.559852 0.733217 0.538547 +v 0.56199 0.742758 0.539874 +v 0.469341 0.747435 0.544147 +v 0.54449 0.750804 0.542498 +v 0.444396 0.753177 0.547979 +v 0.441254 0.75447 0.545961 +v 0.478878 0.751937 0.54513 +v 0.487919 0.754074 0.546744 +v 0.51112 0.754862 0.546979 +v 0.520553 0.751819 0.545563 +v 0.478949 0.761079 0.544559 +v 0.486708 0.758565 0.546446 +v 0.485002 0.762764 0.546898 +v 0.495887 0.75769 0.547686 +v 0.506351 0.758467 0.547722 +v 0.515275 0.759762 0.546516 +v 0.547902 0.755908 0.545173 +v 0.561284 0.755306 0.547553 +v 0.564166 0.765984 0.542581 +v 0.563217 0.758512 0.545543 +v 0.563943 0.754964 0.539769 +v 0.460946 0.766566 0.544045 +v 0.456737 0.760394 0.543882 +v 0.520315 0.763593 0.545518 +v 0.522323 0.760801 0.544376 +v 0.544274 0.760444 0.542973 +v 0.54466 0.756574 0.541654 +v 0.543318 0.762346 0.545583 +v 0.540023 0.765706 0.542143 +v 0.472109 0.765058 0.542727 +v 0.473704 0.76717 0.545051 +v 0.467 0.767933 0.542024 +v 0.481553 0.765711 0.547756 +v 0.527836 0.765805 0.543036 +v 0.463924 0.768449 0.542336 +v 0.56233 0.774798 0.547953 +v 0.438558 0.781448 0.53639 +v 0.442111 0.790873 0.54206 +v 0.544718 0.806086 0.542358 +v 0.519743 0.829948 0.545291 +v 0.466426 0.832419 0.542627 +v 0.474451 0.830406 0.543504 +v 0.473737 0.838255 0.545572 +v 0.475739 0.824335 0.542034 +v 0.533139 0.832633 0.543316 +v 0.527403 0.836977 0.545263 +v 0.525409 0.829682 0.543748 +v 0.537926 0.829605 0.540818 +v 0.539467 0.838499 0.543314 +v 0.460129 0.845572 0.54362 +v 0.453557 0.84384 0.540035 +v 0.458997 0.837896 0.541811 +v 0.527973 0.843444 0.546078 +v 0.474165 0.844428 0.546185 +v 0.542968 0.845105 0.542347 +v 0.536178 0.845301 0.544929 +v 0.467022 0.847568 0.545317 +v 0.463805 0.852272 0.543826 +v 0.474068 0.850851 0.545301 +v 0.486073 0.851319 0.546413 +v 0.527791 0.848347 0.545792 +v 0.525773 0.852808 0.544786 +v 0.479707 0.856526 0.543486 +v 0.471331 0.856785 0.543626 +v 0.476269 0.874108 0.542267 +v 0.483568 0.87577 0.542145 +v 0.48062 0.88168 0.543198 +v 0.52973 0.881925 0.540715 +v 0.522417 0.87534 0.54152 +v 0.534125 0.874599 0.539329 +v 0.482265 0.888025 0.541158 +v 0.47613 0.886063 0.542024 +v 0.38706 0.162877 0.540015 +v 0.383517 0.165008 0.539056 +v 0.383893 0.162789 0.53377 +v 0.390224 0.16105 0.537504 +v 0.395972 0.16026 0.534891 +v 0.405654 0.160207 0.535801 +v 0.459929 0.160654 0.540167 +v 0.45731 0.16037 0.531733 +v 0.468064 0.161971 0.534938 +v 0.527925 0.163193 0.528825 +v 0.534347 0.161968 0.521271 +v 0.545798 0.160347 0.531971 +v 0.570618 0.158045 0.525058 +v 0.383342 0.168198 0.540502 +v 0.380347 0.167175 0.53393 +v 0.383126 0.172139 0.540198 +v 0.380317 0.1737 0.533957 +v 0.383561 0.176168 0.537407 +v 0.486417 0.173637 0.528692 +v 0.487866 0.179136 0.532726 +v 0.61599 0.174148 0.540368 +v 0.614096 0.177613 0.538944 +v 0.619554 0.172801 0.53331 +v 0.512183 0.178735 0.532753 +v 0.512298 0.184158 0.535778 +v 0.610165 0.181887 0.536698 +v 0.603605 0.187893 0.534873 +v 0.614958 0.181186 0.530245 +v 0.508381 0.185552 0.523519 +v 0.512121 0.189358 0.535065 +v 0.510661 0.193174 0.527745 +v 0.5735 0.217193 0.533095 +v 0.566044 0.207545 0.540562 +v 0.444736 0.212117 0.538117 +v 0.43887 0.214132 0.533887 +v 0.557026 0.214414 0.534249 +v 0.450077 0.2164 0.533223 +v 0.45249 0.211549 0.540122 +v 0.461247 0.210461 0.53962 +v 0.437436 0.411389 0.542272 +v 0.444836 0.400208 0.538943 +v 0.583101 0.435879 0.541175 +v 0.577902 0.416714 0.537883 +v 0.587932 0.412322 0.529692 +v 0.590725 0.445459 0.537512 +v 0.409949 0.499653 0.543924 +v 0.404926 0.476666 0.537155 +v 0.412249 0.524447 0.540485 +v 0.41827 0.550093 0.53863 +v 0.409115 0.532912 0.532563 +v 0.696358 0.580349 0.528991 +v 0.688524 0.580055 0.532573 +v 0.287811 0.591805 0.544314 +v 0.567815 0.612807 0.538306 +v 0.566866 0.594235 0.539167 +v 0.724601 0.61894 0.534532 +v 0.432968 0.640336 0.53604 +v 0.432929 0.629873 0.537857 +v 0.569235 0.626656 0.539977 +v 0.568086 0.636588 0.541306 +v 0.56469 0.645228 0.542357 +v 0.570092 0.642933 0.534846 +v 0.668169 0.639467 0.531647 +v 0.672351 0.642863 0.527387 +v 0.543671 0.677237 0.538208 +v 0.541578 0.686843 0.53634 +v 0.467135 0.690432 0.541803 +v 0.460928 0.691861 0.538295 +v 0.553852 0.723909 0.53506 +v 0.546221 0.715938 0.537177 +v 0.437339 0.749532 0.537728 +v 0.439456 0.737964 0.536058 +v 0.461237 0.747845 0.541729 +v 0.455864 0.750004 0.544434 +v 0.455147 0.753588 0.544053 +v 0.469059 0.749493 0.542558 +v 0.45888 0.758695 0.540176 +v 0.471027 0.760072 0.541809 +v 0.46352 0.758772 0.539486 +v 0.469573 0.753592 0.541856 +v 0.530819 0.751956 0.54206 +v 0.539467 0.754254 0.539898 +v 0.53015 0.763276 0.541751 +v 0.530583 0.758511 0.541527 +v 0.535661 0.766655 0.541001 +v 0.462508 0.765257 0.539788 +v 0.563137 0.774399 0.537736 +v 0.446805 0.797723 0.541725 +v 0.444531 0.794402 0.534693 +v 0.453218 0.804206 0.541735 +v 0.457414 0.807787 0.536048 +v 0.550045 0.801118 0.534135 +v 0.543035 0.809784 0.534097 +v 0.468071 0.81789 0.538696 +v 0.529369 0.820883 0.540896 +v 0.523514 0.824412 0.542987 +v 0.458797 0.828441 0.537765 +v 0.449505 0.850178 0.536235 +v 0.447551 0.843291 0.534739 +v 0.55111 0.835839 0.534958 +v 0.554087 0.842896 0.533747 +v 0.549104 0.844392 0.538333 +v 0.546306 0.85224 0.539238 +v 0.489074 0.855472 0.542607 +v 0.485646 0.855261 0.542798 +v 0.485846 0.863097 0.540611 +v 0.506528 0.857987 0.541901 +v 0.513044 0.857486 0.542105 +v 0.458594 0.860855 0.538417 +v 0.465533 0.858758 0.541747 +v 0.467841 0.866632 0.540214 +v 0.494714 0.858686 0.541175 +v 0.499617 0.862626 0.539149 +v 0.501494 0.859264 0.540966 +v 0.521683 0.858003 0.542828 +v 0.515442 0.86339 0.540248 +v 0.532278 0.859113 0.542009 +v 0.50586 0.867317 0.53851 +v 0.513738 0.871051 0.53981 +v 0.542314 0.85977 0.538828 +v 0.537913 0.866995 0.538266 +v 0.488735 0.871408 0.539873 +v 0.49162 0.879946 0.53983 +v 0.51071 0.878105 0.540428 +v 0.468984 0.874584 0.540583 +v 0.544376 0.874181 0.534951 +v 0.461443 0.87696 0.537968 +v 0.469696 0.881745 0.541092 +v 0.502214 0.882154 0.537531 +v 0.509536 0.883307 0.540115 +v 0.496718 0.884764 0.536845 +v 0.490005 0.887706 0.538853 +v 0.467725 0.887159 0.538981 +v 0.510121 0.888437 0.538319 +v 0.517057 0.887178 0.541072 +v 0.522298 0.892256 0.538215 +v 0.525001 0.887606 0.54052 +v 0.534924 0.887875 0.537297 +v 0.539155 0.892212 0.531945 +v 0.544594 0.88739 0.533206 +v 0.485546 0.893087 0.537128 +v 0.431837 0.159699 0.539522 +v 0.432155 0.158658 0.530223 +v 0.389893 0.159846 0.528527 +v 0.40427 0.157888 0.52267 +v 0.519582 0.166507 0.525636 +v 0.58757 0.159762 0.536441 +v 0.515471 0.170008 0.52657 +v 0.515286 0.167012 0.504671 +v 0.513157 0.173938 0.529017 +v 0.384264 0.179835 0.530701 +v 0.388961 0.18108 0.536483 +v 0.396196 0.187837 0.53459 +v 0.601121 0.195554 0.527215 +v 0.606383 0.193785 0.522425 +v 0.599069 0.210182 0.521762 +v 0.396644 0.194983 0.525263 +v 0.470083 0.209207 0.53458 +v 0.464914 0.21554 0.52686 +v 0.476968 0.208285 0.526992 +v 0.529439 0.395388 0.537201 +v 0.517797 0.399382 0.539239 +v 0.524323 0.387356 0.530285 +v 0.596276 0.453276 0.533547 +v 0.596693 0.470163 0.535806 +v 0.603515 0.469012 0.525397 +v 0.582284 0.55293 0.536733 +v 0.591283 0.53343 0.531572 +v 0.329494 0.580679 0.52451 +v 0.422908 0.570161 0.534764 +v 0.666268 0.588103 0.534702 +v 0.665522 0.581255 0.523158 +v 0.289491 0.587122 0.530425 +v 0.573391 0.573709 0.53868 +v 0.577167 0.579378 0.530473 +v 0.704768 0.583586 0.528095 +v 0.711521 0.588657 0.525915 +v 0.656361 0.592015 0.526542 +v 0.344707 0.609503 0.532198 +v 0.34472 0.617288 0.531174 +v 0.43219 0.616265 0.533922 +v 0.42985 0.600072 0.530051 +v 0.428819 0.619339 0.527159 +v 0.571176 0.615388 0.533034 +v 0.65671 0.624073 0.531518 +v 0.655742 0.616698 0.533912 +v 0.662931 0.634921 0.529007 +v 0.310088 0.649871 0.53542 +v 0.688415 0.649095 0.531922 +v 0.562978 0.664874 0.528996 +v 0.559314 0.671734 0.526992 +v 0.455472 0.696854 0.534165 +v 0.544983 0.69605 0.53345 +v 0.546448 0.714469 0.53318 +v 0.446468 0.723497 0.536688 +v 0.43613 0.755732 0.53281 +v 0.563548 0.747898 0.534132 +v 0.535591 0.822281 0.538596 +v 0.536473 0.818933 0.536425 +v 0.542491 0.825663 0.536214 +v 0.456371 0.818605 0.531355 +v 0.451096 0.827239 0.531164 +v 0.451232 0.85822 0.53504 +v 0.445671 0.856886 0.529458 +v 0.550219 0.859291 0.533754 +v 0.452446 0.866528 0.533374 +v 0.45325 0.874417 0.533562 +v 0.446657 0.872912 0.528583 +v 0.495033 0.86748 0.538606 +v 0.45441 0.881093 0.534389 +v 0.55492 0.879878 0.527917 +v 0.54929 0.883056 0.532156 +v 0.550568 0.877964 0.531409 +v 0.457034 0.886102 0.534463 +v 0.448136 0.884273 0.529385 +v 0.499547 0.888701 0.535139 +v 0.461925 0.891031 0.533286 +v 0.505074 0.89192 0.534882 +v 0.499872 0.895633 0.533166 +v 0.551376 0.886125 0.529228 +v 0.512806 0.894745 0.535065 +v 0.482239 0.907066 0.529775 +v 0.475994 0.898718 0.532073 +v 0.48252 0.897424 0.534446 +v 0.491252 0.897272 0.533422 +v 0.520051 0.896712 0.534276 +v 0.515267 0.905371 0.530204 +v 0.526414 0.897566 0.532224 +v 0.422425 0.157654 0.520933 +v 0.436016 0.160079 0.523151 +v 0.600501 0.159502 0.532901 +v 0.473835 0.163295 0.519286 +v 0.476949 0.164911 0.526223 +v 0.529021 0.162972 0.507864 +v 0.54098 0.162599 0.519542 +v 0.483261 0.169006 0.524283 +v 0.384676 0.183525 0.522354 +v 0.381333 0.177312 0.527705 +v 0.491748 0.182982 0.522887 +v 0.445867 0.21843 0.530736 +v 0.437503 0.223064 0.529678 +v 0.533109 0.213314 0.529538 +v 0.53764 0.216081 0.52803 +v 0.453227 0.22017 0.528633 +v 0.548997 0.219314 0.529091 +v 0.557976 0.224128 0.529705 +v 0.403201 0.423518 0.525307 +v 0.397287 0.415751 0.51649 +v 0.405449 0.402936 0.520691 +v 0.403151 0.449497 0.531062 +v 0.600406 0.431346 0.524134 +v 0.397478 0.461968 0.525549 +v 0.279635 0.598577 0.526111 +v 0.716118 0.595129 0.521175 +v 0.719203 0.602518 0.517524 +v 0.34487 0.60063 0.528881 +v 0.352589 0.607041 0.521576 +v 0.573858 0.600083 0.5267 +v 0.574305 0.61417 0.524112 +v 0.652582 0.609056 0.530308 +v 0.659055 0.630429 0.528145 +v 0.654409 0.625372 0.525851 +v 0.659649 0.63453 0.522717 +v 0.291255 0.646108 0.530681 +v 0.291483 0.639436 0.515836 +v 0.548482 0.709245 0.530301 +v 0.553436 0.699314 0.525092 +v 0.447353 0.714135 0.526024 +v 0.450682 0.705538 0.529263 +v 0.553712 0.720726 0.525862 +v 0.445276 0.722916 0.526969 +v 0.442468 0.730413 0.531645 +v 0.439211 0.73813 0.526578 +v 0.55722 0.727981 0.525282 +v 0.558486 0.73035 0.531721 +v 0.561415 0.738016 0.53027 +v 0.563279 0.765449 0.525997 +v 0.561042 0.779051 0.529141 +v 0.442652 0.789306 0.528029 +v 0.446049 0.795211 0.527063 +v 0.555493 0.794978 0.532907 +v 0.55253 0.799994 0.52633 +v 0.458928 0.809987 0.533201 +v 0.450853 0.801566 0.528097 +v 0.458551 0.812648 0.531866 +v 0.450773 0.808225 0.525452 +v 0.548503 0.808731 0.526424 +v 0.541955 0.81598 0.531642 +v 0.544148 0.820133 0.531463 +v 0.548773 0.826822 0.532097 +v 0.553821 0.827949 0.526622 +v 0.442869 0.845137 0.527645 +v 0.445944 0.836484 0.530508 +v 0.557836 0.839721 0.526973 +v 0.557155 0.847824 0.529045 +v 0.555888 0.856723 0.527863 +v 0.554133 0.86461 0.52747 +v 0.552676 0.871497 0.529028 +v 0.533881 0.897341 0.528946 +v 0.542446 0.896242 0.524712 +v 0.468951 0.905915 0.524622 +v 0.46681 0.896733 0.529721 +v 0.529819 0.906663 0.525229 +v 0.48841 0.925627 0.52527 +v 0.481678 0.926697 0.523532 +v 0.498587 0.905346 0.530549 +v 0.507058 0.917632 0.527499 +v 0.497003 0.924188 0.526256 +v 0.606545 0.158804 0.526419 +v 0.4666 0.161882 0.521473 +v 0.457705 0.162033 0.522121 +v 0.589568 0.156779 0.512511 +v 0.571547 0.159389 0.517834 +v 0.612258 0.160373 0.524927 +v 0.605871 0.158305 0.515847 +v 0.616366 0.163271 0.524937 +v 0.489436 0.172162 0.509315 +v 0.616376 0.16544 0.515566 +v 0.618943 0.167054 0.525251 +v 0.620383 0.170461 0.527529 +v 0.379996 0.173788 0.52673 +v 0.619463 0.174619 0.525075 +v 0.508727 0.175553 0.515467 +v 0.617579 0.179521 0.524599 +v 0.619074 0.177235 0.515768 +v 0.613416 0.185602 0.523301 +v 0.389285 0.192122 0.518074 +v 0.394515 0.202376 0.516387 +v 0.528567 0.214595 0.520591 +v 0.52753 0.211342 0.527168 +v 0.522162 0.209333 0.522785 +v 0.460441 0.219489 0.524837 +v 0.467116 0.224261 0.519238 +v 0.5331 0.217161 0.521603 +v 0.540383 0.218869 0.525918 +v 0.543126 0.226607 0.52485 +v 0.593909 0.231603 0.521183 +v 0.588255 0.241051 0.522752 +v 0.580703 0.24061 0.525537 +v 0.573154 0.240603 0.527192 +v 0.422815 0.268553 0.523346 +v 0.419525 0.245796 0.525394 +v 0.428374 0.241703 0.527048 +v 0.56633 0.287639 0.523956 +v 0.569458 0.298223 0.526674 +v 0.561978 0.298257 0.5254 +v 0.576636 0.297984 0.525618 +v 0.572198 0.306279 0.529272 +v 0.42034 0.298553 0.525145 +v 0.421447 0.30868 0.528172 +v 0.415652 0.301946 0.523241 +v 0.439168 0.301343 0.525959 +v 0.446079 0.296313 0.521973 +v 0.444029 0.309021 0.524233 +v 0.55866 0.318298 0.524614 +v 0.566154 0.322136 0.526336 +v 0.559537 0.328945 0.522448 +v 0.43251 0.324682 0.525981 +v 0.431621 0.335175 0.522893 +v 0.426994 0.325297 0.525518 +v 0.442926 0.329047 0.522264 +v 0.43723 0.321979 0.525969 +v 0.442336 0.319158 0.524522 +v 0.449177 0.357993 0.521938 +v 0.451532 0.368362 0.524801 +v 0.441179 0.368568 0.525187 +v 0.460606 0.369089 0.523401 +v 0.454365 0.378986 0.529092 +v 0.571859 0.3601 0.522337 +v 0.575023 0.374665 0.524427 +v 0.567019 0.372056 0.525774 +v 0.54532 0.381511 0.530521 +v 0.54008 0.370807 0.524595 +v 0.54917 0.369001 0.525333 +v 0.429764 0.368363 0.523485 +v 0.433357 0.378299 0.527063 +v 0.475526 0.381247 0.525761 +v 0.470223 0.372476 0.521802 +v 0.48068 0.37547 0.518365 +v 0.485363 0.387507 0.526964 +v 0.474003 0.389072 0.53216 +v 0.589748 0.388427 0.520487 +v 0.595423 0.400215 0.519985 +v 0.593779 0.544058 0.521453 +v 0.598495 0.519847 0.524478 +v 0.309745 0.577256 0.524633 +v 0.318257 0.575879 0.519925 +v 0.307169 0.576423 0.518205 +v 0.679894 0.576541 0.520959 +v 0.698013 0.578846 0.518092 +v 0.419353 0.582238 0.520976 +v 0.422785 0.580309 0.528112 +v 0.413545 0.555145 0.528397 +v 0.578953 0.58832 0.521091 +v 0.36155 0.598004 0.505815 +v 0.349048 0.592857 0.517082 +v 0.356451 0.589355 0.501826 +v 0.644021 0.610261 0.51966 +v 0.643965 0.603583 0.519007 +v 0.275245 0.612188 0.527546 +v 0.720757 0.616966 0.518223 +v 0.715487 0.614697 0.50108 +v 0.719403 0.622501 0.517258 +v 0.720674 0.610023 0.517166 +v 0.347493 0.62104 0.524386 +v 0.342659 0.623954 0.529622 +v 0.340751 0.629691 0.525579 +v 0.337377 0.630146 0.53159 +v 0.331941 0.636883 0.533331 +v 0.326024 0.64245 0.530464 +v 0.300995 0.646423 0.523743 +v 0.310407 0.646499 0.523662 +v 0.318662 0.645804 0.527685 +v 0.309441 0.644268 0.513286 +v 0.575217 0.636629 0.523306 +v 0.572288 0.648981 0.525419 +v 0.431536 0.648921 0.526993 +v 0.427796 0.637735 0.523739 +v 0.437059 0.661063 0.52722 +v 0.429815 0.657037 0.517144 +v 0.569154 0.658634 0.523852 +v 0.574665 0.654062 0.516162 +v 0.56444 0.667312 0.523041 +v 0.4416 0.673695 0.524294 +v 0.446369 0.694785 0.524794 +v 0.437455 0.747095 0.524626 +v 0.439481 0.73661 0.519127 +v 0.436784 0.758937 0.525259 +v 0.437463 0.771144 0.526083 +v 0.437022 0.75513 0.515625 +v 0.43958 0.781372 0.527295 +v 0.4409 0.788884 0.519485 +v 0.558067 0.78914 0.531874 +v 0.558146 0.78643 0.52166 +v 0.447099 0.799049 0.523772 +v 0.444863 0.829284 0.52374 +v 0.441736 0.853935 0.523487 +v 0.44182 0.862603 0.521569 +v 0.441477 0.877299 0.523583 +v 0.441582 0.870606 0.522404 +v 0.558663 0.868689 0.522076 +v 0.442271 0.881887 0.523888 +v 0.438262 0.879395 0.51663 +v 0.559963 0.878607 0.521908 +v 0.556273 0.883192 0.52566 +v 0.444794 0.886687 0.523057 +v 0.554241 0.888189 0.523617 +v 0.544775 0.904321 0.51674 +v 0.549476 0.894243 0.520501 +v 0.45676 0.895205 0.525063 +v 0.515653 0.924127 0.524844 +v 0.496644 0.944033 0.521357 +v 0.417568 0.158287 0.511246 +v 0.409619 0.156679 0.510898 +v 0.386245 0.161368 0.526035 +v 0.383137 0.163935 0.525303 +v 0.388829 0.160424 0.518431 +v 0.476364 0.16402 0.506149 +v 0.543575 0.165004 0.511049 +v 0.554359 0.163253 0.517952 +v 0.379896 0.170093 0.525969 +v 0.380887 0.166842 0.525407 +v 0.383366 0.165289 0.516271 +v 0.380377 0.174241 0.517514 +v 0.49367 0.181782 0.514142 +v 0.49349 0.185375 0.516533 +v 0.507377 0.191805 0.514299 +v 0.509761 0.196488 0.515763 +v 0.485025 0.204115 0.516194 +v 0.488696 0.199815 0.510376 +v 0.481217 0.208144 0.517836 +v 0.476582 0.21891 0.514861 +v 0.410163 0.243973 0.521751 +v 0.404307 0.269437 0.515725 +v 0.400532 0.238564 0.516633 +v 0.460099 0.244108 0.519731 +v 0.453364 0.24317 0.52309 +v 0.456683 0.22724 0.524589 +v 0.561368 0.276902 0.522776 +v 0.552643 0.279677 0.521075 +v 0.554621 0.2638 0.522565 +v 0.553676 0.294249 0.522141 +v 0.556359 0.307014 0.524407 +v 0.448282 0.278785 0.520814 +v 0.454246 0.285271 0.518532 +v 0.545269 0.283959 0.518425 +v 0.407681 0.293811 0.516749 +v 0.410248 0.308472 0.519511 +v 0.579923 0.314115 0.527298 +v 0.585683 0.315723 0.522431 +v 0.580632 0.321857 0.523858 +v 0.438402 0.343831 0.521863 +v 0.430328 0.346841 0.521788 +v 0.445382 0.338281 0.520524 +v 0.447249 0.347992 0.52057 +v 0.456535 0.348733 0.518097 +v 0.56604 0.347442 0.521791 +v 0.575553 0.346876 0.520708 +v 0.419037 0.367791 0.520003 +v 0.42625 0.359038 0.521379 +v 0.469234 0.364207 0.51785 +v 0.512901 0.373937 0.513268 +v 0.518656 0.380494 0.52281 +v 0.506604 0.384934 0.52127 +v 0.392696 0.438114 0.515502 +v 0.391511 0.461523 0.515763 +v 0.401197 0.529437 0.517523 +v 0.397709 0.530952 0.50656 +v 0.394245 0.503071 0.512776 +v 0.408651 0.557612 0.516884 +v 0.405939 0.536955 0.524233 +v 0.290199 0.585724 0.518618 +v 0.297681 0.57998 0.516321 +v 0.645319 0.589377 0.507606 +v 0.642603 0.597252 0.513348 +v 0.28228 0.597594 0.510368 +v 0.284361 0.592261 0.516822 +v 0.629727 0.601814 0.5014 +v 0.648967 0.621765 0.521739 +v 0.639874 0.621912 0.515565 +v 0.64402 0.616128 0.518868 +v 0.351204 0.623336 0.519088 +v 0.345736 0.627006 0.521731 +v 0.652141 0.627901 0.520768 +v 0.654986 0.633012 0.519291 +v 0.647465 0.63321 0.51572 +v 0.716025 0.627996 0.514321 +v 0.340748 0.633754 0.520552 +v 0.334038 0.639114 0.518699 +v 0.340969 0.637225 0.516148 +v 0.658437 0.636972 0.517472 +v 0.327182 0.642905 0.515386 +v 0.326696 0.642096 0.522196 +v 0.668756 0.642065 0.518808 +v 0.67585 0.644636 0.522749 +v 0.677048 0.644976 0.515456 +v 0.682432 0.646291 0.522941 +v 0.688604 0.646084 0.520002 +v 0.562385 0.675101 0.519755 +v 0.438271 0.696849 0.51394 +v 0.441543 0.685098 0.519738 +v 0.442096 0.723247 0.51988 +v 0.558884 0.722142 0.519267 +v 0.563136 0.75057 0.525703 +v 0.562943 0.758412 0.515582 +v 0.440461 0.835799 0.516497 +v 0.443365 0.821525 0.517306 +v 0.439845 0.847032 0.519023 +v 0.55964 0.852925 0.521896 +v 0.438052 0.866419 0.514455 +v 0.562239 0.873061 0.51785 +v 0.56276 0.878733 0.514709 +v 0.445109 0.89063 0.516017 +v 0.44985 0.893281 0.520591 +v 0.455589 0.903846 0.517499 +v 0.461498 0.916286 0.516851 +v 0.468236 0.92333 0.518908 +v 0.48041 0.947693 0.516869 +v 0.474087 0.932161 0.519359 +v 0.465689 0.942964 0.512225 +v 0.523978 0.924577 0.522294 +v 0.516885 0.943739 0.519309 +v 0.401967 0.156653 0.508225 +v 0.394273 0.157677 0.507233 +v 0.4377 0.16349 0.51434 +v 0.447791 0.163473 0.518643 +v 0.569179 0.162734 0.510169 +v 0.567139 0.164192 0.502026 +v 0.579597 0.161442 0.5019 +v 0.457031 0.165049 0.511111 +v 0.506123 0.187638 0.511526 +v 0.505575 0.182983 0.508512 +v 0.610425 0.192101 0.518342 +v 0.517744 0.206657 0.51886 +v 0.513605 0.202257 0.516519 +v 0.51079 0.201084 0.504023 +v 0.483553 0.216351 0.505054 +v 0.518816 0.21719 0.508742 +v 0.528577 0.223097 0.515967 +v 0.466033 0.243121 0.516352 +v 0.471224 0.234985 0.513828 +v 0.538584 0.28993 0.514552 +v 0.537526 0.266499 0.515416 +v 0.449298 0.330317 0.519941 +v 0.448352 0.319538 0.521489 +v 0.454571 0.317368 0.518182 +v 0.465363 0.349642 0.514268 +v 0.462865 0.333858 0.514154 +v 0.412331 0.346145 0.516746 +v 0.416307 0.332545 0.51951 +v 0.421128 0.347 0.519864 +v 0.540933 0.338131 0.515451 +v 0.537502 0.345993 0.514734 +v 0.531192 0.34228 0.510267 +v 0.545456 0.350199 0.518795 +v 0.53483 0.354384 0.515724 +v 0.474835 0.352247 0.508441 +v 0.470877 0.357446 0.513666 +v 0.486091 0.369999 0.510184 +v 0.490375 0.375817 0.511956 +v 0.582709 0.378604 0.522129 +v 0.588512 0.367631 0.517184 +v 0.611477 0.441467 0.508382 +v 0.608725 0.470329 0.515107 +v 0.611525 0.478979 0.50588 +v 0.605206 0.494957 0.518782 +v 0.602591 0.51815 0.515189 +v 0.327183 0.576125 0.515145 +v 0.336903 0.577681 0.508036 +v 0.693275 0.576132 0.508504 +v 0.699936 0.579507 0.5091 +v 0.290792 0.586447 0.506537 +v 0.634878 0.612446 0.511094 +v 0.362273 0.605515 0.510447 +v 0.361069 0.61291 0.51349 +v 0.716125 0.604209 0.503415 +v 0.358489 0.620944 0.515038 +v 0.367441 0.619658 0.509204 +v 0.578237 0.603608 0.514519 +v 0.576963 0.621162 0.517101 +v 0.424355 0.611526 0.51293 +v 0.425958 0.624547 0.518702 +v 0.358133 0.630023 0.514052 +v 0.423052 0.63196 0.510966 +v 0.579328 0.62822 0.510262 +v 0.340632 0.641445 0.5121 +v 0.349825 0.639163 0.512646 +v 0.662767 0.640767 0.514931 +v 0.654024 0.643437 0.510895 +v 0.327726 0.644373 0.509695 +v 0.321939 0.644953 0.509557 +v 0.667335 0.643535 0.512272 +v 0.575553 0.661462 0.510826 +v 0.579123 0.649399 0.511143 +v 0.569016 0.676019 0.511885 +v 0.56074 0.688269 0.517607 +v 0.435061 0.6764 0.51441 +v 0.560328 0.706055 0.516704 +v 0.563906 0.714243 0.511298 +v 0.445884 0.806687 0.520824 +v 0.554247 0.799967 0.521374 +v 0.557789 0.817995 0.516857 +v 0.558167 0.832081 0.520956 +v 0.561046 0.838776 0.516966 +v 0.562155 0.858691 0.513989 +v 0.561972 0.848569 0.514983 +v 0.562653 0.866616 0.514834 +v 0.445403 0.899873 0.508238 +v 0.44136 0.8877 0.509999 +v 0.554549 0.898526 0.509077 +v 0.555048 0.890819 0.516338 +v 0.559838 0.885984 0.511629 +v 0.548481 0.914234 0.509526 +v 0.541188 0.922309 0.513354 +v 0.532491 0.923901 0.518375 +v 0.480898 0.961227 0.510979 +v 0.480413 0.969525 0.50525 +v 0.471802 0.962209 0.5067 +v 0.489343 0.959557 0.514238 +v 0.497083 0.956256 0.517005 +v 0.50485 0.954851 0.517673 +v 0.499636 0.964041 0.512814 +v 0.512377 0.956136 0.515867 +v 0.508043 0.962696 0.513264 +v 0.614152 0.162126 0.50477 +v 0.608898 0.158681 0.50479 +v 0.611965 0.15933 0.494826 +v 0.380291 0.18017 0.509473 +v 0.379197 0.173842 0.505923 +v 0.383891 0.187092 0.513066 +v 0.381576 0.188374 0.503287 +v 0.505816 0.190785 0.499932 +v 0.613929 0.192862 0.510692 +v 0.609303 0.207517 0.512505 +v 0.389002 0.210103 0.507983 +v 0.395838 0.21767 0.515047 +v 0.531905 0.243252 0.514834 +v 0.525722 0.241085 0.509593 +v 0.385416 0.442607 0.500523 +v 0.389594 0.472942 0.509925 +v 0.598001 0.542106 0.511974 +v 0.591195 0.563588 0.512877 +v 0.314358 0.57402 0.504503 +v 0.30584 0.576228 0.51118 +v 0.324353 0.574034 0.506925 +v 0.678664 0.573979 0.506028 +v 0.670864 0.575199 0.5096 +v 0.654714 0.581614 0.508502 +v 0.66379 0.577409 0.510918 +v 0.414896 0.580015 0.512716 +v 0.710909 0.589357 0.511712 +v 0.372731 0.605245 0.49925 +v 0.279788 0.608864 0.509983 +v 0.290361 0.627945 0.496183 +v 0.289216 0.620346 0.490005 +v 0.370578 0.637669 0.507923 +v 0.361086 0.63936 0.5106 +v 0.628959 0.631391 0.50922 +v 0.634471 0.638362 0.509815 +v 0.619817 0.642554 0.504069 +v 0.625176 0.624795 0.50758 +v 0.361841 0.647001 0.506965 +v 0.6377 0.645273 0.508206 +v 0.710237 0.633778 0.509862 +v 0.704324 0.638469 0.508152 +v 0.694891 0.644865 0.516986 +v 0.699919 0.642252 0.512452 +v 0.697801 0.639304 0.498627 +v 0.333663 0.644346 0.509314 +v 0.333708 0.648099 0.505137 +v 0.672224 0.645036 0.509973 +v 0.662714 0.648635 0.505827 +v 0.677237 0.645799 0.507698 +v 0.688663 0.64474 0.510355 +v 0.428412 0.664094 0.511815 +v 0.423274 0.651408 0.510395 +v 0.577908 0.672346 0.506895 +v 0.435691 0.710583 0.508825 +v 0.432198 0.698886 0.5045 +v 0.438643 0.725968 0.514498 +v 0.435609 0.731184 0.508829 +v 0.44181 0.806681 0.515638 +v 0.557777 0.797332 0.517123 +v 0.437965 0.846287 0.510226 +v 0.563279 0.846689 0.507561 +v 0.564699 0.864833 0.507714 +v 0.454731 0.920724 0.510565 +v 0.536178 0.94182 0.511239 +v 0.540128 0.953436 0.50417 +v 0.530273 0.955512 0.509565 +v 0.520711 0.956745 0.513177 +v 0.525396 0.965849 0.505478 +v 0.504498 0.970034 0.508214 +v 0.387521 0.159664 0.496687 +v 0.389028 0.159569 0.508633 +v 0.601474 0.15671 0.506971 +v 0.385914 0.162327 0.510503 +v 0.41717 0.160179 0.500648 +v 0.427364 0.161952 0.50933 +v 0.43878 0.165669 0.504931 +v 0.473146 0.163758 0.494659 +v 0.480357 0.164664 0.486348 +v 0.382795 0.165109 0.506038 +v 0.493123 0.176745 0.499691 +v 0.490421 0.172319 0.490908 +v 0.50595 0.178523 0.504765 +v 0.507987 0.174151 0.495906 +v 0.494088 0.180972 0.488826 +v 0.494414 0.181091 0.503778 +v 0.494388 0.184429 0.509017 +v 0.505399 0.181195 0.491519 +v 0.620485 0.181265 0.502797 +v 0.621233 0.175419 0.502728 +v 0.493718 0.189317 0.506873 +v 0.49272 0.191277 0.488547 +v 0.491464 0.195835 0.501572 +v 0.523148 0.267931 0.502949 +v 0.520664 0.238588 0.503982 +v 0.604551 0.278626 0.508469 +v 0.606995 0.326867 0.502802 +v 0.600673 0.319617 0.509278 +v 0.532417 0.306434 0.510096 +v 0.527494 0.329347 0.506308 +v 0.525264 0.301318 0.503779 +v 0.405907 0.34361 0.513473 +v 0.401354 0.339256 0.510127 +v 0.405906 0.321791 0.515109 +v 0.596745 0.345525 0.511399 +v 0.594916 0.309822 0.514413 +v 0.479641 0.348568 0.50197 +v 0.484354 0.357043 0.501928 +v 0.4789 0.363964 0.511663 +v 0.487266 0.364139 0.504462 +v 0.610289 0.411062 0.503708 +v 0.605392 0.407759 0.510981 +v 0.608161 0.374389 0.501177 +v 0.614174 0.413268 0.495898 +v 0.603647 0.526157 0.505662 +v 0.609231 0.504281 0.50048 +v 0.602652 0.538441 0.496342 +v 0.30477 0.576668 0.503379 +v 0.661754 0.575721 0.498618 +v 0.340107 0.576793 0.495161 +v 0.348134 0.581554 0.498475 +v 0.291687 0.589012 0.495317 +v 0.297021 0.582722 0.496562 +v 0.639226 0.587787 0.494769 +v 0.698577 0.579944 0.498665 +v 0.704774 0.584159 0.503885 +v 0.419433 0.597582 0.507251 +v 0.411969 0.582657 0.500819 +v 0.707574 0.589756 0.497081 +v 0.588796 0.581646 0.501285 +v 0.584027 0.58457 0.512398 +v 0.621887 0.61208 0.501367 +v 0.623663 0.618271 0.505145 +v 0.374426 0.626213 0.506513 +v 0.376533 0.622072 0.504661 +v 0.419058 0.626842 0.50305 +v 0.42022 0.639826 0.507427 +v 0.582705 0.623482 0.502081 +v 0.581102 0.638108 0.508402 +v 0.611615 0.624466 0.499938 +v 0.301029 0.640267 0.500468 +v 0.294372 0.635229 0.500137 +v 0.583351 0.643849 0.506983 +v 0.315736 0.644797 0.507295 +v 0.308474 0.643245 0.502926 +v 0.321364 0.647782 0.500954 +v 0.682353 0.64568 0.504698 +v 0.673465 0.649933 0.499231 +v 0.687746 0.644607 0.501336 +v 0.343057 0.646935 0.507557 +v 0.35806 0.65248 0.503974 +v 0.373279 0.656562 0.501418 +v 0.416656 0.646064 0.505912 +v 0.639579 0.651998 0.504557 +v 0.625473 0.660196 0.49988 +v 0.648179 0.653572 0.503064 +v 0.405588 0.668085 0.501758 +v 0.397994 0.657679 0.501603 +v 0.41061 0.661526 0.503701 +v 0.42064 0.666472 0.506595 +v 0.412808 0.652709 0.504682 +v 0.59225 0.653268 0.503628 +v 0.602204 0.660325 0.50107 +v 0.59057 0.665632 0.503228 +v 0.427777 0.672127 0.509267 +v 0.426901 0.680404 0.506417 +v 0.584603 0.680855 0.501943 +v 0.573804 0.701159 0.496189 +v 0.568971 0.704457 0.503011 +v 0.57624 0.693406 0.500452 +v 0.566055 0.806024 0.500181 +v 0.561972 0.800124 0.510328 +v 0.564496 0.779615 0.50683 +v 0.437846 0.803948 0.508381 +v 0.436484 0.858016 0.50663 +v 0.435393 0.845081 0.500243 +v 0.435722 0.868041 0.50637 +v 0.563336 0.887176 0.498696 +v 0.563361 0.879809 0.506729 +v 0.565167 0.872357 0.502986 +v 0.437737 0.881498 0.508333 +v 0.439558 0.892334 0.502003 +v 0.436134 0.875717 0.507036 +v 0.448015 0.920189 0.504059 +v 0.442798 0.910663 0.500306 +v 0.451856 0.939322 0.502538 +v 0.45758 0.949999 0.503932 +v 0.449913 0.951304 0.495944 +v 0.463777 0.95599 0.505766 +v 0.463639 0.964734 0.499394 +v 0.509896 0.976388 0.501079 +v 0.498218 0.976883 0.501851 +v 0.401937 0.156858 0.496432 +v 0.380214 0.168513 0.500345 +v 0.382873 0.16358 0.495085 +v 0.451456 0.166327 0.501641 +v 0.442312 0.164641 0.495882 +v 0.463219 0.164541 0.500065 +v 0.536513 0.164344 0.496421 +v 0.545759 0.165294 0.495755 +v 0.557372 0.16378 0.493243 +v 0.552133 0.16215 0.481003 +v 0.619136 0.166964 0.491203 +v 0.620876 0.17078 0.500053 +v 0.61783 0.166501 0.504497 +v 0.37803 0.172612 0.49307 +v 0.622621 0.174111 0.489825 +v 0.621721 0.18681 0.488102 +v 0.618854 0.18883 0.501219 +v 0.381993 0.197163 0.497738 +v 0.379437 0.189599 0.493689 +v 0.617388 0.198016 0.498726 +v 0.488525 0.210457 0.4942 +v 0.51271 0.211719 0.496228 +v 0.509269 0.199649 0.493954 +v 0.385008 0.221035 0.501414 +v 0.39176 0.233571 0.509074 +v 0.38684 0.252479 0.500285 +v 0.517158 0.341125 0.494143 +v 0.523179 0.342836 0.503142 +v 0.518205 0.348184 0.498927 +v 0.397865 0.364399 0.506073 +v 0.397083 0.332208 0.50638 +v 0.491894 0.36187 0.496098 +v 0.386479 0.476328 0.498401 +v 0.401754 0.55514 0.496597 +v 0.396135 0.534683 0.494294 +v 0.32265 0.573401 0.498494 +v 0.331462 0.574369 0.494907 +v 0.686496 0.574518 0.502292 +v 0.692822 0.576641 0.498788 +v 0.41963 0.607667 0.500903 +v 0.418122 0.614628 0.498309 +v 0.415516 0.621801 0.497726 +v 0.586462 0.622527 0.497907 +v 0.585305 0.6106 0.493618 +v 0.381579 0.628163 0.503664 +v 0.383006 0.622777 0.501384 +v 0.705818 0.628857 0.492187 +v 0.378198 0.633354 0.505502 +v 0.384317 0.641713 0.503059 +v 0.394701 0.640252 0.500382 +v 0.390189 0.649235 0.50181 +v 0.396413 0.629615 0.497211 +v 0.40156 0.635194 0.49871 +v 0.407244 0.630035 0.497829 +v 0.408712 0.641165 0.501797 +v 0.587793 0.634446 0.501594 +v 0.588275 0.644153 0.504087 +v 0.595924 0.643611 0.501883 +v 0.600511 0.634521 0.49955 +v 0.603563 0.643203 0.50143 +v 0.607932 0.648748 0.50209 +v 0.610426 0.64445 0.501941 +v 0.614314 0.649049 0.502364 +v 0.385738 0.656945 0.500985 +v 0.347367 0.652885 0.502971 +v 0.610841 0.654908 0.501722 +v 0.614023 0.662741 0.499301 +v 0.383126 0.663875 0.498749 +v 0.408747 0.67677 0.500367 +v 0.394732 0.669804 0.498778 +v 0.42131 0.684493 0.502054 +v 0.408938 0.683948 0.496561 +v 0.428545 0.691388 0.503119 +v 0.427699 0.699927 0.498035 +v 0.566085 0.726746 0.505618 +v 0.434153 0.752732 0.503881 +v 0.568675 0.742448 0.497463 +v 0.565003 0.756229 0.506278 +v 0.433912 0.826732 0.495914 +v 0.433609 0.793357 0.498058 +v 0.564814 0.861024 0.502646 +v 0.565141 0.848715 0.499046 +v 0.434324 0.864986 0.4968 +v 0.549075 0.951464 0.496926 +v 0.543606 0.961036 0.49642 +v 0.486774 0.976362 0.500904 +v 0.477263 0.976389 0.497148 +v 0.589178 0.158898 0.49468 +v 0.580165 0.16079 0.491275 +v 0.613483 0.16076 0.485429 +v 0.607926 0.158309 0.483246 +v 0.569541 0.161853 0.491182 +v 0.378609 0.171291 0.481413 +v 0.376988 0.177718 0.485836 +v 0.62098 0.206342 0.488636 +v 0.617116 0.215446 0.497252 +v 0.485534 0.230091 0.493689 +v 0.482366 0.240557 0.498671 +v 0.615964 0.258039 0.496193 +v 0.612292 0.230615 0.504257 +v 0.389254 0.359767 0.495631 +v 0.395243 0.380862 0.503668 +v 0.392178 0.393041 0.501358 +v 0.319931 0.574494 0.491174 +v 0.677965 0.574327 0.49363 +v 0.302921 0.578655 0.495892 +v 0.302955 0.581386 0.487531 +v 0.360974 0.588091 0.489641 +v 0.283613 0.602189 0.50153 +v 0.287415 0.595898 0.495946 +v 0.286043 0.607709 0.493389 +v 0.41601 0.605153 0.493027 +v 0.412497 0.593418 0.490002 +v 0.413278 0.602573 0.486574 +v 0.382102 0.606852 0.491247 +v 0.381966 0.614239 0.497603 +v 0.59086 0.622729 0.495682 +v 0.593497 0.613882 0.490044 +v 0.596291 0.624166 0.495596 +v 0.604653 0.618473 0.49382 +v 0.602852 0.625819 0.496809 +v 0.390345 0.623412 0.497197 +v 0.395804 0.620202 0.493305 +v 0.405263 0.620564 0.49305 +v 0.411035 0.623969 0.496066 +v 0.412206 0.615427 0.492268 +v 0.312922 0.646324 0.491169 +v 0.692046 0.642199 0.496173 +v 0.683648 0.647139 0.492363 +v 0.690594 0.642363 0.487002 +v 0.663524 0.658832 0.489473 +v 0.656754 0.659663 0.493289 +v 0.649626 0.65894 0.497501 +v 0.385001 0.671229 0.495481 +v 0.614683 0.67175 0.49426 +v 0.589863 0.68595 0.49633 +v 0.591459 0.692011 0.489512 +v 0.603875 0.681842 0.490969 +v 0.420732 0.698456 0.492875 +v 0.426543 0.705794 0.491693 +v 0.430155 0.773913 0.489391 +v 0.569832 0.798188 0.489022 +v 0.567447 0.828321 0.493372 +v 0.432595 0.847081 0.490884 +v 0.554313 0.916649 0.502562 +v 0.456562 0.966837 0.490524 +v 0.463587 0.972996 0.490576 +v 0.52057 0.975468 0.498491 +v 0.530206 0.973337 0.495465 +v 0.516197 0.98774 0.484165 +v 0.507484 0.987601 0.48753 +v 0.514467 0.982955 0.492249 +v 0.596808 0.15695 0.500035 +v 0.595179 0.158073 0.484179 +v 0.426984 0.159702 0.478038 +v 0.432778 0.16169 0.488892 +v 0.420156 0.160942 0.489387 +v 0.446458 0.162364 0.485858 +v 0.466923 0.164018 0.485516 +v 0.382676 0.207052 0.498393 +v 0.379554 0.202897 0.489998 +v 0.384863 0.413503 0.491737 +v 0.382426 0.423138 0.485762 +v 0.381686 0.446911 0.483873 +v 0.385108 0.479609 0.485741 +v 0.618044 0.446544 0.487297 +v 0.615425 0.48058 0.484778 +v 0.6145 0.477711 0.494055 +v 0.667572 0.575429 0.485229 +v 0.676512 0.576702 0.482736 +v 0.309089 0.577 0.491532 +v 0.339587 0.576762 0.485099 +v 0.407503 0.575701 0.49295 +v 0.403905 0.566924 0.485337 +v 0.650545 0.579556 0.488915 +v 0.659873 0.575993 0.48787 +v 0.693606 0.579677 0.489265 +v 0.294479 0.593531 0.484404 +v 0.38951 0.607517 0.485446 +v 0.38145 0.601337 0.485136 +v 0.408876 0.610155 0.486445 +v 0.411867 0.607355 0.487115 +v 0.619187 0.606794 0.495267 +v 0.609939 0.612615 0.492955 +v 0.297879 0.619391 0.472964 +v 0.290191 0.613813 0.484577 +v 0.399687 0.616762 0.490484 +v 0.396378 0.613769 0.48838 +v 0.402958 0.61402 0.487862 +v 0.602386 0.611383 0.48779 +v 0.300725 0.633636 0.482296 +v 0.350423 0.658141 0.499246 +v 0.635084 0.671084 0.488837 +v 0.394115 0.68055 0.49219 +v 0.375381 0.671869 0.493208 +v 0.61698 0.678651 0.488012 +v 0.408289 0.69012 0.491676 +v 0.410789 0.696188 0.48679 +v 0.581183 0.700248 0.489195 +v 0.589282 0.699192 0.481738 +v 0.572241 0.720549 0.490028 +v 0.57078 0.755556 0.489275 +v 0.568363 0.856943 0.487005 +v 0.438612 0.912492 0.492925 +v 0.564499 0.907638 0.488874 +v 0.560281 0.913002 0.49531 +v 0.555297 0.937299 0.495148 +v 0.556646 0.949371 0.488355 +v 0.450045 0.958996 0.49065 +v 0.443633 0.95054 0.488111 +v 0.547521 0.966649 0.486206 +v 0.539489 0.969713 0.491963 +v 0.476312 0.983229 0.487027 +v 0.469874 0.978339 0.489322 +v 0.485663 0.98655 0.486379 +v 0.491962 0.982598 0.494346 +v 0.496736 0.98784 0.48724 +v 0.408846 0.158673 0.490329 +v 0.403286 0.158125 0.480575 +v 0.385136 0.162048 0.485919 +v 0.52253 0.163485 0.486251 +v 0.528835 0.163287 0.492661 +v 0.533483 0.162742 0.476168 +v 0.61159 0.162799 0.470441 +v 0.61632 0.164549 0.48014 +v 0.61901 0.168575 0.477502 +v 0.489675 0.173459 0.472048 +v 0.486785 0.168922 0.475602 +v 0.37847 0.195103 0.485373 +v 0.377435 0.185854 0.485686 +v 0.509681 0.209147 0.484022 +v 0.507494 0.195599 0.489958 +v 0.507 0.190698 0.483572 +v 0.622267 0.233806 0.483202 +v 0.622685 0.204035 0.480165 +v 0.513018 0.313345 0.479438 +v 0.516025 0.303907 0.488154 +v 0.515381 0.329237 0.488327 +v 0.485894 0.301891 0.484147 +v 0.485149 0.327711 0.487198 +v 0.482462 0.302578 0.492439 +v 0.493477 0.357658 0.487021 +v 0.496747 0.363006 0.48873 +v 0.500454 0.369048 0.496752 +v 0.499706 0.364682 0.488705 +v 0.503008 0.364243 0.489943 +v 0.397433 0.543423 0.48271 +v 0.390822 0.512716 0.485205 +v 0.594013 0.571408 0.492406 +v 0.598312 0.558618 0.486165 +v 0.58751 0.59395 0.490007 +v 0.636859 0.587122 0.486884 +v 0.636499 0.586784 0.479672 +v 0.371896 0.594118 0.484554 +v 0.363405 0.588063 0.48159 +v 0.623674 0.595745 0.484921 +v 0.381147 0.598415 0.479716 +v 0.410507 0.60139 0.481041 +v 0.589181 0.603121 0.484313 +v 0.586721 0.601663 0.48746 +v 0.592 0.599295 0.476153 +v 0.592133 0.603383 0.480881 +v 0.58918 0.595085 0.480447 +v 0.617988 0.601978 0.488145 +v 0.712528 0.60763 0.492898 +v 0.710765 0.601165 0.491492 +v 0.293949 0.607161 0.478105 +v 0.593599 0.606349 0.483174 +v 0.595946 0.602311 0.476222 +v 0.597413 0.608874 0.484838 +v 0.709376 0.612345 0.486472 +v 0.702105 0.610409 0.474123 +v 0.703102 0.618725 0.477811 +v 0.309471 0.634019 0.465334 +v 0.31285 0.642231 0.469552 +v 0.322287 0.652195 0.468647 +v 0.325065 0.650303 0.457313 +v 0.32884 0.655684 0.489916 +v 0.336311 0.657512 0.493788 +v 0.67011 0.656374 0.486416 +v 0.656991 0.665872 0.480089 +v 0.674274 0.654715 0.482551 +v 0.356464 0.665736 0.493595 +v 0.618527 0.683777 0.481683 +v 0.575445 0.706457 0.489442 +v 0.576327 0.710226 0.482389 +v 0.424807 0.709118 0.483645 +v 0.427855 0.722784 0.485593 +v 0.427905 0.757687 0.47655 +v 0.428643 0.760474 0.483503 +v 0.572588 0.760382 0.476333 +v 0.573046 0.799358 0.473894 +v 0.572065 0.775991 0.481505 +v 0.428132 0.803437 0.478099 +v 0.432201 0.865495 0.486476 +v 0.434143 0.903704 0.484357 +v 0.430589 0.889859 0.47604 +v 0.437871 0.936033 0.484295 +v 0.557799 0.955295 0.481446 +v 0.562516 0.945865 0.48006 +v 0.449924 0.965478 0.483107 +v 0.448236 0.969434 0.47291 +v 0.442993 0.96004 0.476378 +v 0.462304 0.97946 0.478907 +v 0.535513 0.977934 0.484893 +v 0.540994 0.979035 0.475478 +v 0.531072 0.984841 0.476816 +v 0.587393 0.159055 0.466164 +v 0.598635 0.158084 0.472537 +v 0.573593 0.159686 0.479515 +v 0.51863 0.164591 0.481668 +v 0.515438 0.166898 0.480331 +v 0.377666 0.18465 0.475889 +v 0.62211 0.185029 0.476651 +v 0.621891 0.193854 0.477089 +v 0.487627 0.23613 0.485385 +v 0.382546 0.329015 0.483467 +v 0.378594 0.264809 0.481588 +v 0.382976 0.307732 0.488838 +v 0.489834 0.350369 0.486439 +v 0.494146 0.354355 0.47919 +v 0.386699 0.490955 0.473011 +v 0.592587 0.582038 0.47752 +v 0.600143 0.552732 0.47946 +v 0.601133 0.547692 0.470624 +v 0.609297 0.51528 0.479912 +v 0.30938 0.580028 0.48248 +v 0.315208 0.577311 0.484789 +v 0.65816 0.578593 0.477269 +v 0.638156 0.587142 0.471728 +v 0.624391 0.593204 0.471856 +v 0.707685 0.595216 0.489591 +v 0.702114 0.591305 0.483483 +v 0.60986 0.60086 0.476624 +v 0.612983 0.601472 0.481289 +v 0.606084 0.603728 0.480022 +v 0.7041 0.599319 0.480021 +v 0.394888 0.605674 0.478653 +v 0.39578 0.609905 0.484459 +v 0.400076 0.610514 0.484234 +v 0.404889 0.610405 0.484288 +v 0.406117 0.606288 0.480283 +v 0.601681 0.606011 0.481669 +v 0.601885 0.6031 0.476692 +v 0.328646 0.657378 0.483119 +v 0.32518 0.655576 0.476757 +v 0.348734 0.670075 0.478542 +v 0.366267 0.675198 0.486186 +v 0.398412 0.692872 0.481724 +v 0.417439 0.703643 0.481666 +v 0.422471 0.710009 0.475542 +v 0.571837 0.871823 0.470397 +v 0.570778 0.872489 0.475905 +v 0.574002 0.843326 0.472738 +v 0.567773 0.897348 0.48181 +v 0.565993 0.930089 0.478779 +v 0.439091 0.95008 0.479059 +v 0.480094 0.989265 0.477457 +v 0.459028 0.163578 0.480891 +v 0.449333 0.161308 0.475577 +v 0.464286 0.16268 0.471568 +v 0.477943 0.163424 0.466236 +v 0.483114 0.165751 0.474421 +v 0.482428 0.166555 0.458824 +v 0.524297 0.162725 0.463416 +v 0.621301 0.172508 0.478303 +v 0.618032 0.171707 0.466203 +v 0.377312 0.204074 0.480694 +v 0.511907 0.236979 0.483599 +v 0.510829 0.237588 0.475275 +v 0.487304 0.27097 0.480308 +v 0.488078 0.305103 0.475329 +v 0.380681 0.329441 0.473367 +v 0.382512 0.350955 0.477958 +v 0.383088 0.376866 0.473168 +v 0.497514 0.357801 0.474706 +v 0.500073 0.359868 0.471444 +v 0.499287 0.360828 0.479937 +v 0.617896 0.415389 0.480243 +v 0.616871 0.383777 0.471712 +v 0.61838 0.417033 0.47084 +v 0.615912 0.480231 0.475759 +v 0.402765 0.563213 0.474955 +v 0.322292 0.578017 0.478715 +v 0.347887 0.580833 0.476407 +v 0.337966 0.578406 0.476232 +v 0.685154 0.57964 0.480786 +v 0.675422 0.580502 0.472923 +v 0.306468 0.584974 0.477743 +v 0.691597 0.584487 0.478645 +v 0.311814 0.590886 0.466806 +v 0.302804 0.592104 0.474625 +v 0.298829 0.599897 0.473718 +v 0.590507 0.593311 0.47305 +v 0.40388 0.603688 0.474276 +v 0.407676 0.602453 0.477215 +v 0.409488 0.59824 0.474284 +v 0.390708 0.60209 0.474208 +v 0.398459 0.603875 0.472407 +v 0.679881 0.649875 0.474192 +v 0.676351 0.653553 0.478218 +v 0.337 0.664088 0.463448 +v 0.662225 0.663972 0.474944 +v 0.3757 0.683286 0.479056 +v 0.427166 0.788407 0.468971 +v 0.428155 0.764905 0.468133 +v 0.573485 0.726662 0.474544 +v 0.572478 0.757202 0.470344 +v 0.427549 0.813694 0.472718 +v 0.426325 0.821576 0.47381 +v 0.428592 0.884494 0.465353 +v 0.426446 0.846859 0.47047 +v 0.429003 0.882893 0.470511 +v 0.430444 0.924109 0.466635 +v 0.436686 0.952254 0.469114 +v 0.553834 0.963922 0.478716 +v 0.549092 0.971771 0.475495 +v 0.5597 0.958711 0.472051 +v 0.545334 0.97826 0.466886 +v 0.513521 0.99193 0.475299 +v 0.521729 0.989041 0.476765 +v 0.500983 0.991223 0.480555 +v 0.402183 0.158855 0.466281 +v 0.412397 0.159303 0.464537 +v 0.381537 0.171053 0.46917 +v 0.382654 0.166229 0.476722 +v 0.487757 0.1756 0.456043 +v 0.491521 0.178381 0.471124 +v 0.622295 0.177657 0.478119 +v 0.492547 0.184511 0.476542 +v 0.490028 0.19031 0.468803 +v 0.489382 0.243098 0.46758 +v 0.489134 0.239252 0.476761 +v 0.489599 0.214809 0.469565 +v 0.509085 0.345572 0.4728 +v 0.508518 0.347668 0.462409 +v 0.510683 0.332181 0.470804 +v 0.500075 0.361452 0.462427 +v 0.501911 0.360831 0.466056 +v 0.383771 0.393236 0.466937 +v 0.383004 0.400796 0.471082 +v 0.381657 0.419036 0.475456 +v 0.61534 0.479358 0.466155 +v 0.618994 0.448067 0.46954 +v 0.392414 0.516409 0.463359 +v 0.385365 0.478946 0.462795 +v 0.324575 0.583347 0.467501 +v 0.330326 0.579337 0.473117 +v 0.648991 0.5839 0.468933 +v 0.657733 0.582918 0.466395 +v 0.356989 0.586818 0.467227 +v 0.359034 0.585721 0.475105 +v 0.370445 0.591712 0.473846 +v 0.698306 0.596158 0.47362 +v 0.695169 0.590757 0.475023 +v 0.686667 0.58966 0.467899 +v 0.381985 0.597617 0.47315 +v 0.378555 0.596668 0.465451 +v 0.411329 0.597741 0.461331 +v 0.409883 0.597102 0.467387 +v 0.408599 0.599622 0.465424 +v 0.408681 0.586011 0.470323 +v 0.303221 0.608428 0.46549 +v 0.401745 0.602792 0.468556 +v 0.600121 0.60183 0.472663 +v 0.60488 0.601485 0.473121 +v 0.598153 0.601239 0.469696 +v 0.612298 0.59858 0.471525 +v 0.698954 0.602928 0.471037 +v 0.694102 0.608755 0.463921 +v 0.643942 0.674255 0.473391 +v 0.381211 0.688231 0.471094 +v 0.616605 0.688107 0.474363 +v 0.597079 0.697352 0.476329 +v 0.622682 0.686194 0.465775 +v 0.582315 0.706535 0.47621 +v 0.576152 0.712744 0.475287 +v 0.57528 0.71449 0.468355 +v 0.428613 0.782749 0.457402 +v 0.429137 0.754178 0.46311 +v 0.426568 0.81413 0.467771 +v 0.426796 0.809008 0.469256 +v 0.422809 0.821871 0.468403 +v 0.422155 0.827095 0.470305 +v 0.417032 0.830029 0.462534 +v 0.421562 0.832365 0.46779 +v 0.579025 0.832189 0.467378 +v 0.57774 0.826187 0.46964 +v 0.422883 0.837353 0.464998 +v 0.429319 0.922395 0.456265 +v 0.428456 0.886412 0.459092 +v 0.574173 0.851288 0.466121 +v 0.571642 0.886381 0.46472 +v 0.566342 0.942165 0.472165 +v 0.485918 0.993523 0.468616 +v 0.476053 0.9909 0.467203 +v 0.505128 0.993619 0.473264 +v 0.495736 0.994348 0.47083 +v 0.396665 0.160181 0.46396 +v 0.407165 0.159701 0.449115 +v 0.425825 0.159366 0.465524 +v 0.438419 0.159487 0.46944 +v 0.600776 0.159103 0.464188 +v 0.388821 0.162075 0.473456 +v 0.393825 0.163724 0.455567 +v 0.448087 0.16029 0.463468 +v 0.468133 0.160514 0.454828 +v 0.473165 0.161835 0.450297 +v 0.575244 0.159342 0.467268 +v 0.57699 0.158769 0.45318 +v 0.518359 0.166494 0.457683 +v 0.512354 0.170045 0.477691 +v 0.510007 0.173939 0.472887 +v 0.508363 0.178357 0.471381 +v 0.513388 0.174273 0.453846 +v 0.507364 0.183939 0.475861 +v 0.620263 0.182016 0.466807 +v 0.486685 0.188696 0.453012 +v 0.488164 0.198206 0.463497 +v 0.494356 0.352722 0.472436 +v 0.491173 0.345385 0.470832 +v 0.493091 0.350929 0.464468 +v 0.617926 0.42514 0.461526 +v 0.339548 0.58356 0.465512 +v 0.667253 0.583033 0.465858 +v 0.658363 0.589546 0.456738 +v 0.677084 0.585821 0.465476 +v 0.636088 0.59081 0.46232 +v 0.587911 0.592897 0.45895 +v 0.589822 0.592845 0.466302 +v 0.589227 0.58644 0.459704 +v 0.59117 0.59572 0.471056 +v 0.592533 0.598211 0.469015 +v 0.615072 0.597809 0.46575 +v 0.408748 0.601525 0.461234 +v 0.405309 0.601954 0.465599 +v 0.699146 0.627661 0.477164 +v 0.691976 0.627613 0.4649 +v 0.692165 0.636083 0.473047 +v 0.681336 0.646241 0.467255 +v 0.666831 0.658801 0.461438 +v 0.351703 0.67358 0.458323 +v 0.345706 0.668313 0.454557 +v 0.409669 0.702596 0.466011 +v 0.387419 0.691821 0.462292 +v 0.427452 0.715461 0.461267 +v 0.425132 0.713688 0.468405 +v 0.428198 0.726564 0.465439 +v 0.421187 0.709231 0.4677 +v 0.430623 0.745545 0.456733 +v 0.573032 0.78561 0.46405 +v 0.571683 0.756506 0.463976 +v 0.4244 0.807581 0.462528 +v 0.425571 0.803342 0.467333 +v 0.576466 0.807555 0.460919 +v 0.574514 0.807437 0.46748 +v 0.575463 0.802267 0.464978 +v 0.575573 0.81735 0.469092 +v 0.580449 0.822265 0.462868 +v 0.579222 0.836679 0.463512 +v 0.583909 0.832769 0.459686 +v 0.57742 0.840365 0.4599 +v 0.428915 0.887863 0.452629 +v 0.426396 0.852348 0.461809 +v 0.432613 0.94511 0.462403 +v 0.435897 0.954658 0.458032 +v 0.565012 0.950067 0.467521 +v 0.561984 0.958856 0.462439 +v 0.453906 0.976709 0.468923 +v 0.44614 0.970454 0.460531 +v 0.525408 0.990206 0.467804 +v 0.510066 0.995097 0.465546 +v 0.45269 0.159869 0.458706 +v 0.459456 0.159641 0.456829 +v 0.452656 0.157418 0.442877 +v 0.551732 0.16077 0.467408 +v 0.562865 0.159631 0.471466 +v 0.380046 0.18473 0.46407 +v 0.378746 0.193764 0.466014 +v 0.380296 0.206403 0.452184 +v 0.378186 0.203977 0.461034 +v 0.377617 0.224924 0.458217 +v 0.510124 0.189553 0.465276 +v 0.514008 0.188442 0.450334 +v 0.512108 0.197572 0.459431 +v 0.487487 0.206318 0.457468 +v 0.512297 0.235977 0.456044 +v 0.511163 0.214234 0.461922 +v 0.51101 0.239528 0.465718 +v 0.381656 0.340561 0.462117 +v 0.378406 0.275862 0.461268 +v 0.379214 0.30189 0.468227 +v 0.497518 0.360948 0.458528 +v 0.49941 0.364139 0.454531 +v 0.384257 0.401305 0.459531 +v 0.384256 0.381053 0.460952 +v 0.381441 0.423435 0.467767 +v 0.381894 0.449051 0.462454 +v 0.382365 0.423553 0.460536 +v 0.386169 0.469792 0.453293 +v 0.608888 0.507956 0.458611 +v 0.613449 0.477908 0.455009 +v 0.401806 0.55647 0.466148 +v 0.400921 0.546203 0.456664 +v 0.589752 0.573729 0.449733 +v 0.594249 0.568014 0.459793 +v 0.331136 0.590239 0.457281 +v 0.320736 0.589777 0.461579 +v 0.619802 0.597826 0.459535 +v 0.628033 0.597921 0.453327 +v 0.319234 0.598332 0.455855 +v 0.679779 0.592963 0.459993 +v 0.591566 0.599078 0.461646 +v 0.594966 0.600646 0.465989 +v 0.606732 0.601883 0.459913 +v 0.400624 0.603646 0.462463 +v 0.400876 0.606278 0.455479 +v 0.393178 0.604611 0.456829 +v 0.599222 0.602201 0.462414 +v 0.600626 0.605361 0.454325 +v 0.306755 0.617858 0.460969 +v 0.314067 0.613342 0.454102 +v 0.679336 0.643758 0.458534 +v 0.656887 0.664288 0.453294 +v 0.651921 0.669608 0.457323 +v 0.605197 0.694916 0.457873 +v 0.633524 0.680243 0.457568 +v 0.397939 0.695705 0.453925 +v 0.371008 0.68357 0.456958 +v 0.585516 0.704735 0.458163 +v 0.59526 0.698176 0.452037 +v 0.421967 0.708911 0.460188 +v 0.570072 0.756045 0.457328 +v 0.571284 0.727967 0.460602 +v 0.424912 0.798576 0.463706 +v 0.422193 0.800884 0.457903 +v 0.424151 0.796705 0.458257 +v 0.574298 0.795146 0.456573 +v 0.575778 0.798048 0.461397 +v 0.577906 0.802333 0.457061 +v 0.579415 0.803368 0.446518 +v 0.578425 0.806952 0.452234 +v 0.579276 0.812804 0.451273 +v 0.423785 0.817426 0.463808 +v 0.42419 0.813923 0.459092 +v 0.419555 0.821234 0.460492 +v 0.415932 0.827041 0.457964 +v 0.414393 0.831727 0.45414 +v 0.421915 0.839653 0.458592 +v 0.570751 0.921726 0.460109 +v 0.571456 0.896964 0.455004 +v 0.569525 0.939001 0.454374 +v 0.568624 0.940114 0.463806 +v 0.43057 0.938998 0.45771 +v 0.431248 0.941617 0.449415 +v 0.460445 0.984367 0.455401 +v 0.460101 0.982409 0.466604 +v 0.46669 0.987281 0.463574 +v 0.472127 0.990766 0.456231 +v 0.492902 0.995929 0.460021 +v 0.425453 0.159008 0.453381 +v 0.382364 0.177341 0.46051 +v 0.386712 0.171962 0.454213 +v 0.617221 0.177372 0.458772 +v 0.613577 0.173452 0.45283 +v 0.384568 0.185915 0.45069 +v 0.486981 0.219439 0.453062 +v 0.483695 0.206029 0.446369 +v 0.493902 0.355874 0.45821 +v 0.49004 0.348884 0.455239 +v 0.507269 0.3549 0.455704 +v 0.510764 0.347093 0.453671 +v 0.385107 0.420085 0.451765 +v 0.600474 0.533119 0.448091 +v 0.60215 0.538294 0.459949 +v 0.34267 0.591288 0.454785 +v 0.350856 0.590893 0.455988 +v 0.670266 0.597787 0.451795 +v 0.679861 0.601529 0.454296 +v 0.588133 0.596725 0.457383 +v 0.588678 0.60156 0.454121 +v 0.410435 0.604154 0.454751 +v 0.406551 0.606948 0.452833 +v 0.413669 0.60949 0.447228 +v 0.412143 0.600858 0.456832 +v 0.403 0.610536 0.448478 +v 0.308309 0.62601 0.461268 +v 0.365408 0.679452 0.45162 +v 0.576973 0.71094 0.461259 +v 0.577962 0.70761 0.454957 +v 0.42661 0.711995 0.456055 +v 0.429986 0.715208 0.454371 +v 0.573465 0.715551 0.461849 +v 0.432023 0.725899 0.451786 +v 0.432958 0.712573 0.447114 +v 0.571399 0.715168 0.455303 +v 0.421137 0.813464 0.4479 +v 0.423199 0.810244 0.454616 +v 0.58196 0.820961 0.454454 +v 0.584682 0.828185 0.457136 +v 0.585908 0.832315 0.452045 +v 0.563311 0.957371 0.452853 +v 0.558348 0.966094 0.455161 +v 0.544316 0.980386 0.44605 +v 0.546552 0.978616 0.457261 +v 0.55242 0.973376 0.452288 +v 0.537592 0.985282 0.458874 +v 0.52972 0.98988 0.449628 +v 0.527503 0.990716 0.458806 +v 0.517719 0.994181 0.460193 +v 0.509711 0.996133 0.455604 +v 0.438961 0.158319 0.451158 +v 0.543342 0.160581 0.4624 +v 0.555658 0.158252 0.452138 +v 0.537335 0.159951 0.456193 +v 0.401721 0.16469 0.439488 +v 0.392787 0.168138 0.446872 +v 0.616879 0.184919 0.455196 +v 0.612474 0.185275 0.444492 +v 0.616982 0.193003 0.452808 +v 0.61772 0.202873 0.44986 +v 0.621136 0.201927 0.460541 +v 0.488206 0.242977 0.45852 +v 0.48598 0.25097 0.450253 +v 0.485426 0.346851 0.445837 +v 0.487064 0.334204 0.452033 +v 0.40839 0.565757 0.449063 +v 0.400424 0.531554 0.444693 +v 0.341985 0.598018 0.447882 +v 0.357551 0.591076 0.457983 +v 0.364407 0.598187 0.449418 +v 0.584683 0.594852 0.45194 +v 0.368122 0.593901 0.459961 +v 0.381275 0.600313 0.457433 +v 0.419742 0.60416 0.4456 +v 0.415592 0.591322 0.449765 +v 0.414753 0.599014 0.454295 +v 0.32131 0.608879 0.449566 +v 0.329654 0.605989 0.445965 +v 0.380133 0.602951 0.450612 +v 0.324683 0.619116 0.444478 +v 0.687813 0.617642 0.456657 +v 0.685711 0.608978 0.455714 +v 0.680573 0.637266 0.454687 +v 0.685369 0.627287 0.455754 +v 0.645612 0.670122 0.448729 +v 0.653853 0.662098 0.446389 +v 0.638706 0.676185 0.451788 +v 0.427552 0.706646 0.447618 +v 0.418083 0.703893 0.451396 +v 0.424438 0.708622 0.453765 +v 0.433628 0.750942 0.447444 +v 0.567559 0.754987 0.450064 +v 0.565703 0.723857 0.445376 +v 0.56403 0.749934 0.442684 +v 0.570603 0.78389 0.453461 +v 0.425765 0.794875 0.45273 +v 0.428393 0.794606 0.446897 +v 0.42261 0.798842 0.449894 +v 0.573848 0.795218 0.449934 +v 0.421803 0.805835 0.454131 +v 0.421123 0.802874 0.44965 +v 0.423504 0.841167 0.453015 +v 0.418197 0.83764 0.45138 +v 0.428267 0.854485 0.450269 +v 0.424696 0.840907 0.447366 +v 0.578085 0.840792 0.45357 +v 0.582202 0.83712 0.447605 +v 0.576561 0.840802 0.447657 +v 0.573196 0.85356 0.453999 +v 0.569854 0.919675 0.442663 +v 0.570664 0.885521 0.447752 +v 0.569855 0.874915 0.444139 +v 0.435004 0.952701 0.447638 +v 0.439924 0.962426 0.452506 +v 0.445481 0.969544 0.44676 +v 0.555033 0.970048 0.444648 +v 0.512307 0.995103 0.4449 +v 0.501937 0.996554 0.451852 +v 0.427495 0.157465 0.443279 +v 0.558309 0.156427 0.440292 +v 0.567722 0.157359 0.445507 +v 0.530312 0.161228 0.446386 +v 0.533517 0.16024 0.450566 +v 0.580063 0.158138 0.441684 +v 0.603054 0.161321 0.457634 +v 0.592004 0.159904 0.445052 +v 0.605555 0.165356 0.45068 +v 0.483485 0.174733 0.445316 +v 0.485456 0.180535 0.446942 +v 0.482618 0.188347 0.442627 +v 0.485663 0.298358 0.449682 +v 0.487884 0.306727 0.457737 +v 0.514303 0.3472 0.44521 +v 0.513208 0.333013 0.451685 +v 0.505764 0.360438 0.451378 +v 0.502834 0.366534 0.447818 +v 0.508082 0.362927 0.444345 +v 0.389628 0.345138 0.439874 +v 0.386082 0.348609 0.446595 +v 0.390179 0.380756 0.443043 +v 0.615538 0.447221 0.45214 +v 0.61489 0.417165 0.452101 +v 0.611214 0.413597 0.443579 +v 0.614436 0.384558 0.453344 +v 0.611003 0.469993 0.443669 +v 0.339831 0.6044 0.44329 +v 0.352239 0.605689 0.440263 +v 0.581586 0.590684 0.443787 +v 0.579835 0.599348 0.444898 +v 0.619306 0.606168 0.445335 +v 0.635497 0.601378 0.445691 +v 0.583567 0.606292 0.446067 +v 0.589138 0.608117 0.447978 +v 0.328034 0.627687 0.441719 +v 0.333444 0.624252 0.438181 +v 0.667368 0.621271 0.440836 +v 0.675648 0.611094 0.447849 +v 0.663311 0.61425 0.440261 +v 0.677944 0.627808 0.44837 +v 0.319003 0.635405 0.452674 +v 0.670051 0.646261 0.448673 +v 0.32785 0.645604 0.448474 +v 0.336925 0.655502 0.447604 +v 0.358774 0.673854 0.448288 +v 0.348165 0.665434 0.447514 +v 0.631755 0.676382 0.444498 +v 0.37527 0.680773 0.443625 +v 0.59629 0.694319 0.445168 +v 0.582203 0.703177 0.449753 +v 0.573179 0.70945 0.450977 +v 0.568995 0.712506 0.448382 +v 0.565928 0.708232 0.441372 +v 0.43863 0.753873 0.438979 +v 0.435542 0.774895 0.442639 +v 0.438928 0.785524 0.436654 +v 0.433098 0.792283 0.442636 +v 0.429156 0.798625 0.439657 +v 0.572179 0.795344 0.445442 +v 0.577311 0.798614 0.445921 +v 0.421618 0.802842 0.442089 +v 0.417306 0.823236 0.451819 +v 0.415829 0.826201 0.443452 +v 0.418561 0.819502 0.444098 +v 0.585008 0.832929 0.446076 +v 0.582961 0.832882 0.44019 +v 0.585219 0.827841 0.444162 +v 0.57497 0.838868 0.441898 +v 0.571071 0.852927 0.444625 +v 0.568954 0.937931 0.443722 +v 0.566995 0.94772 0.44802 +v 0.562531 0.956679 0.442033 +v 0.475329 0.991607 0.445733 +v 0.466359 0.987933 0.448136 +v 0.493454 0.995868 0.448029 +v 0.476523 0.164052 0.447457 +v 0.469143 0.161722 0.439862 +v 0.479307 0.166954 0.44606 +v 0.534714 0.161449 0.436162 +v 0.526022 0.163208 0.445072 +v 0.526809 0.166729 0.436354 +v 0.522166 0.16616 0.444376 +v 0.519374 0.169994 0.443435 +v 0.59899 0.168184 0.434844 +v 0.60769 0.171038 0.444655 +v 0.393043 0.173182 0.439993 +v 0.47977 0.170458 0.442217 +v 0.477131 0.174648 0.435473 +v 0.473618 0.166889 0.436727 +v 0.387314 0.195832 0.442405 +v 0.390144 0.187369 0.439204 +v 0.480917 0.329176 0.439026 +v 0.48302 0.285405 0.443259 +v 0.479069 0.278159 0.43722 +v 0.514997 0.253341 0.448203 +v 0.514516 0.299925 0.449567 +v 0.518028 0.285266 0.441704 +v 0.387729 0.448557 0.444242 +v 0.389988 0.423452 0.440104 +v 0.415035 0.575127 0.43995 +v 0.636798 0.610799 0.436974 +v 0.647464 0.599952 0.445832 +v 0.658331 0.598781 0.447898 +v 0.659436 0.607397 0.441893 +v 0.578547 0.605265 0.442586 +v 0.577365 0.612632 0.438398 +v 0.604796 0.61007 0.445991 +v 0.609348 0.615045 0.438634 +v 0.379513 0.606097 0.445375 +v 0.38277 0.611843 0.440023 +v 0.396946 0.613021 0.443599 +v 0.409097 0.616684 0.441419 +v 0.590455 0.616457 0.440349 +v 0.595742 0.609965 0.447756 +v 0.668419 0.629193 0.441095 +v 0.665654 0.637832 0.440558 +v 0.32746 0.636638 0.444323 +v 0.66127 0.646541 0.440909 +v 0.657918 0.654621 0.443322 +v 0.350429 0.661038 0.44076 +v 0.64431 0.662703 0.438975 +v 0.614958 0.682223 0.440382 +v 0.592963 0.690499 0.438524 +v 0.40557 0.69601 0.446498 +v 0.423413 0.697094 0.439352 +v 0.430211 0.702766 0.441579 +v 0.432299 0.697 0.436296 +v 0.432734 0.707327 0.44335 +v 0.437041 0.707545 0.439459 +v 0.563548 0.774424 0.440998 +v 0.559985 0.753082 0.436103 +v 0.561876 0.785302 0.437844 +v 0.566867 0.791736 0.443049 +v 0.578298 0.803122 0.440075 +v 0.419377 0.81456 0.438648 +v 0.582959 0.82014 0.444877 +v 0.582744 0.819748 0.437495 +v 0.414396 0.830817 0.445911 +v 0.416041 0.829116 0.438702 +v 0.41505 0.834064 0.449066 +v 0.417303 0.835756 0.444272 +v 0.420711 0.837404 0.441867 +v 0.41779 0.833107 0.438773 +v 0.425693 0.838111 0.441552 +v 0.430103 0.889024 0.445838 +v 0.431421 0.886263 0.439969 +v 0.431362 0.925683 0.44109 +v 0.566525 0.936594 0.432485 +v 0.433267 0.945009 0.441851 +v 0.435872 0.946896 0.433599 +v 0.559258 0.956472 0.430614 +v 0.556824 0.96518 0.437212 +v 0.459635 0.983102 0.444674 +v 0.541591 0.98038 0.435763 +v 0.534341 0.986541 0.441135 +v 0.42091 0.157978 0.438924 +v 0.436151 0.156339 0.436565 +v 0.448549 0.157509 0.433979 +v 0.546117 0.1575 0.441614 +v 0.557352 0.156652 0.433918 +v 0.417249 0.158933 0.436147 +v 0.582129 0.158808 0.434828 +v 0.517546 0.174703 0.442696 +v 0.517402 0.180708 0.441398 +v 0.522209 0.175582 0.434808 +v 0.394026 0.17968 0.434881 +v 0.399655 0.175209 0.42946 +v 0.609339 0.177808 0.441152 +v 0.397197 0.185937 0.429893 +v 0.518953 0.188371 0.44012 +v 0.382246 0.261865 0.445818 +v 0.386759 0.259755 0.437769 +v 0.383089 0.22305 0.444118 +v 0.484089 0.352076 0.440443 +v 0.485521 0.359591 0.43743 +v 0.491493 0.360812 0.445168 +v 0.478097 0.359346 0.430224 +v 0.48759 0.368736 0.434344 +v 0.514387 0.356855 0.439902 +v 0.512073 0.36582 0.437111 +v 0.516483 0.369443 0.430572 +v 0.509549 0.373695 0.434062 +v 0.392635 0.408525 0.43826 +v 0.39547 0.39865 0.435269 +v 0.606002 0.40715 0.435859 +v 0.607271 0.431258 0.433779 +v 0.602831 0.44095 0.423016 +v 0.608029 0.45329 0.433718 +v 0.391884 0.477381 0.440207 +v 0.606109 0.478046 0.434529 +v 0.595813 0.532471 0.435674 +v 0.591437 0.555993 0.440256 +v 0.396853 0.501947 0.436855 +v 0.403117 0.519892 0.430485 +v 0.423529 0.582023 0.429964 +v 0.416027 0.557258 0.427159 +v 0.585012 0.575641 0.440135 +v 0.577178 0.584737 0.432696 +v 0.421491 0.612966 0.440566 +v 0.426995 0.613185 0.436406 +v 0.649532 0.618342 0.434123 +v 0.41759 0.617251 0.439515 +v 0.4172 0.623736 0.434573 +v 0.656918 0.631446 0.434451 +v 0.33473 0.636167 0.438729 +v 0.650303 0.648132 0.434435 +v 0.364641 0.666969 0.435763 +v 0.35172 0.655171 0.435408 +v 0.63056 0.665425 0.432789 +v 0.630416 0.671443 0.437701 +v 0.379205 0.677349 0.436922 +v 0.391867 0.686581 0.440685 +v 0.40921 0.692517 0.439845 +v 0.562741 0.702186 0.435357 +v 0.573269 0.698995 0.438053 +v 0.429438 0.803548 0.434358 +v 0.425297 0.802538 0.43575 +v 0.422783 0.80742 0.433304 +v 0.422658 0.803118 0.436989 +v 0.571024 0.797515 0.441252 +v 0.570805 0.802062 0.436023 +v 0.575079 0.802283 0.437228 +v 0.420953 0.807734 0.437239 +v 0.567602 0.803756 0.435198 +v 0.564618 0.804807 0.436671 +v 0.566005 0.809554 0.434244 +v 0.561647 0.804014 0.434975 +v 0.563069 0.812117 0.434863 +v 0.564409 0.831552 0.434678 +v 0.564642 0.848052 0.433963 +v 0.5679 0.834736 0.436482 +v 0.581313 0.827689 0.433938 +v 0.579182 0.833461 0.436805 +v 0.435423 0.832812 0.434441 +v 0.431461 0.836676 0.439204 +v 0.434248 0.847415 0.43734 +v 0.56713 0.884136 0.434848 +v 0.549924 0.972804 0.434605 +v 0.453129 0.976574 0.440662 +v 0.44708 0.968115 0.434049 +v 0.461484 0.981477 0.433136 +v 0.523425 0.991422 0.440766 +v 0.485102 0.993849 0.442397 +v 0.477416 0.989927 0.4341 +v 0.495698 0.994093 0.435602 +v 0.516157 0.991936 0.434183 +v 0.588804 0.164456 0.4282 +v 0.593204 0.170063 0.425837 +v 0.528211 0.172648 0.429386 +v 0.527813 0.176918 0.428053 +v 0.52105 0.196736 0.438589 +v 0.526033 0.190681 0.431985 +v 0.607588 0.184905 0.436011 +v 0.602176 0.185529 0.429291 +v 0.60784 0.195059 0.434905 +v 0.613347 0.205122 0.440528 +v 0.608208 0.210947 0.433091 +v 0.522467 0.27736 0.435126 +v 0.527223 0.27503 0.430106 +v 0.522358 0.221954 0.436288 +v 0.478813 0.222627 0.438147 +v 0.473494 0.266715 0.431032 +v 0.486259 0.376698 0.428411 +v 0.493968 0.380253 0.431598 +v 0.3983 0.377345 0.431729 +v 0.401637 0.399795 0.427696 +v 0.605006 0.379714 0.435656 +v 0.600518 0.401332 0.429247 +v 0.396705 0.432877 0.424791 +v 0.397886 0.479464 0.423926 +v 0.600321 0.504636 0.431218 +v 0.601123 0.479853 0.422028 +v 0.591589 0.525927 0.423434 +v 0.572562 0.604998 0.436383 +v 0.567781 0.599818 0.428353 +v 0.56375 0.610919 0.427503 +v 0.342902 0.613304 0.4379 +v 0.360497 0.614237 0.434318 +v 0.367474 0.61086 0.437195 +v 0.570959 0.619698 0.432223 +v 0.57723 0.621509 0.433729 +v 0.624074 0.621734 0.431304 +v 0.63658 0.621256 0.431099 +v 0.387937 0.619201 0.434828 +v 0.584826 0.624042 0.434018 +v 0.595955 0.622626 0.434845 +v 0.608888 0.622883 0.432599 +v 0.422949 0.631537 0.429858 +v 0.408234 0.626569 0.43266 +v 0.344912 0.643637 0.434598 +v 0.340269 0.632625 0.434949 +v 0.357909 0.651207 0.430802 +v 0.378153 0.670645 0.431949 +v 0.632026 0.659066 0.430342 +v 0.61246 0.66942 0.42877 +v 0.416917 0.689459 0.434765 +v 0.585001 0.687894 0.433588 +v 0.439281 0.693846 0.431543 +v 0.430097 0.689754 0.432298 +v 0.559664 0.694219 0.43039 +v 0.556512 0.710889 0.430335 +v 0.443054 0.715672 0.433114 +v 0.44212 0.700144 0.432053 +v 0.55738 0.773131 0.432123 +v 0.558728 0.792699 0.432849 +v 0.557961 0.805374 0.430391 +v 0.571211 0.807676 0.431484 +v 0.576899 0.811681 0.430304 +v 0.579701 0.813408 0.433053 +v 0.577722 0.807633 0.434119 +v 0.420387 0.812767 0.433938 +v 0.437803 0.818977 0.431216 +v 0.439728 0.807477 0.431637 +v 0.435649 0.810559 0.432914 +v 0.563207 0.822344 0.433471 +v 0.564631 0.817309 0.433886 +v 0.567401 0.817731 0.432038 +v 0.581254 0.820739 0.433094 +v 0.437052 0.826848 0.431317 +v 0.434263 0.8258 0.431353 +v 0.439851 0.830115 0.429081 +v 0.56106 0.821199 0.432022 +v 0.418973 0.828636 0.434454 +v 0.42749 0.833758 0.435852 +v 0.427894 0.829458 0.431778 +v 0.424398 0.830395 0.432423 +v 0.573441 0.834591 0.436525 +v 0.571653 0.829365 0.432544 +v 0.559873 0.863552 0.424442 +v 0.563295 0.882325 0.427346 +v 0.437481 0.867419 0.429069 +v 0.433499 0.87939 0.434779 +v 0.562303 0.917081 0.421412 +v 0.449521 0.965473 0.423501 +v 0.442284 0.957981 0.428392 +v 0.445177 0.158992 0.428192 +v 0.429562 0.158432 0.428119 +v 0.439587 0.160474 0.423835 +v 0.459135 0.160322 0.433117 +v 0.569872 0.157415 0.430663 +v 0.559368 0.158158 0.428306 +v 0.581051 0.160117 0.429466 +v 0.411893 0.164018 0.428685 +v 0.414494 0.160773 0.432943 +v 0.410723 0.168405 0.424073 +v 0.419825 0.163984 0.421962 +v 0.466645 0.16354 0.433199 +v 0.466217 0.166688 0.429144 +v 0.535028 0.16457 0.430535 +v 0.543978 0.162612 0.427275 +v 0.532013 0.168551 0.428988 +v 0.535369 0.171998 0.423882 +v 0.468682 0.174367 0.426435 +v 0.472141 0.179958 0.429102 +v 0.533602 0.189379 0.425179 +v 0.535344 0.201987 0.424807 +v 0.505212 0.393945 0.41937 +v 0.500644 0.382169 0.432531 +v 0.49822 0.387083 0.427658 +v 0.493482 0.391685 0.421457 +v 0.409055 0.394529 0.422283 +v 0.406093 0.409656 0.421945 +v 0.407423 0.508226 0.41503 +v 0.410585 0.531303 0.422519 +v 0.441527 0.611137 0.423115 +v 0.432036 0.600962 0.429178 +v 0.432612 0.612259 0.431822 +v 0.434708 0.624167 0.428925 +v 0.357502 0.61958 0.432294 +v 0.351318 0.623935 0.432395 +v 0.372823 0.62373 0.429978 +v 0.564495 0.61857 0.428348 +v 0.564702 0.627203 0.42745 +v 0.359982 0.634359 0.428387 +v 0.344641 0.627955 0.433355 +v 0.639934 0.628502 0.429366 +v 0.39118 0.626063 0.430942 +v 0.392242 0.632382 0.42804 +v 0.576727 0.631023 0.429217 +v 0.609026 0.633353 0.427652 +v 0.630379 0.638472 0.426452 +v 0.644274 0.634466 0.429611 +v 0.643657 0.642039 0.429905 +v 0.373761 0.66116 0.428647 +v 0.369341 0.651426 0.426943 +v 0.626803 0.651912 0.42659 +v 0.637276 0.651037 0.429772 +v 0.393537 0.672015 0.428619 +v 0.415882 0.68167 0.4299 +v 0.407574 0.670961 0.426334 +v 0.56972 0.688158 0.430326 +v 0.589844 0.679454 0.429408 +v 0.445373 0.689 0.427069 +v 0.559015 0.685371 0.426905 +v 0.550134 0.741578 0.424208 +v 0.555646 0.744836 0.430179 +v 0.443657 0.77203 0.431597 +v 0.444256 0.745373 0.431936 +v 0.451662 0.72756 0.424151 +v 0.443387 0.792219 0.430146 +v 0.445503 0.807912 0.425667 +v 0.432038 0.81367 0.43053 +v 0.432112 0.807045 0.432761 +v 0.428001 0.809459 0.430527 +v 0.421631 0.814949 0.431403 +v 0.427926 0.815329 0.42887 +v 0.424496 0.815049 0.429451 +v 0.430749 0.820198 0.429502 +v 0.570789 0.814791 0.429806 +v 0.574067 0.812604 0.42914 +v 0.42135 0.822083 0.430961 +v 0.570409 0.822888 0.43047 +v 0.429853 0.825525 0.430379 +v 0.574926 0.823232 0.429314 +v 0.578724 0.821925 0.430166 +v 0.425469 0.826939 0.430281 +v 0.422234 0.827554 0.431686 +v 0.55749 0.826384 0.426782 +v 0.434695 0.91411 0.427603 +v 0.439202 0.945874 0.424357 +v 0.561196 0.945524 0.424737 +v 0.554899 0.954482 0.419453 +v 0.506974 0.991846 0.428967 +v 0.517994 0.988355 0.424911 +v 0.497523 0.990577 0.42472 +v 0.44417 0.163918 0.42094 +v 0.43103 0.162473 0.420278 +v 0.55566 0.161132 0.42464 +v 0.555782 0.165303 0.41978 +v 0.56779 0.160827 0.422484 +v 0.578295 0.161772 0.423967 +v 0.457158 0.166968 0.423148 +v 0.465185 0.170537 0.42526 +v 0.458736 0.174047 0.41993 +v 0.586562 0.170649 0.420458 +v 0.59523 0.177278 0.423891 +v 0.403965 0.180225 0.423838 +v 0.406796 0.173895 0.423464 +v 0.533038 0.18208 0.424058 +v 0.534862 0.176677 0.42259 +v 0.543732 0.17381 0.419005 +v 0.595448 0.186615 0.423283 +v 0.403445 0.188369 0.424051 +v 0.543113 0.189919 0.419488 +v 0.587219 0.187571 0.418189 +v 0.59455 0.201309 0.422704 +v 0.601513 0.219815 0.426498 +v 0.594071 0.222069 0.421187 +v 0.467859 0.306449 0.425033 +v 0.467258 0.249003 0.425525 +v 0.603352 0.277538 0.426724 +v 0.59542 0.277041 0.420524 +v 0.598304 0.311285 0.423967 +v 0.471638 0.362941 0.42452 +v 0.465412 0.36764 0.419695 +v 0.475844 0.373296 0.423157 +v 0.585294 0.347947 0.418907 +v 0.589841 0.370354 0.42249 +v 0.594288 0.343041 0.42344 +v 0.480355 0.38263 0.42112 +v 0.471425 0.38747 0.414385 +v 0.483289 0.390915 0.417172 +v 0.595263 0.412031 0.422363 +v 0.59467 0.399149 0.424066 +v 0.568534 0.584059 0.420931 +v 0.571441 0.562181 0.413246 +v 0.557933 0.5859 0.410884 +v 0.433542 0.585731 0.41939 +v 0.556843 0.619095 0.422226 +v 0.55343 0.629706 0.420975 +v 0.549154 0.620966 0.416573 +v 0.440456 0.637475 0.424869 +v 0.43353 0.6351 0.426907 +v 0.426087 0.640039 0.426946 +v 0.436517 0.650338 0.423321 +v 0.446877 0.641696 0.422312 +v 0.558635 0.634234 0.423833 +v 0.566553 0.634813 0.426078 +v 0.369271 0.644506 0.425948 +v 0.377544 0.640573 0.425261 +v 0.412174 0.639884 0.426915 +v 0.393774 0.63914 0.425897 +v 0.419936 0.645702 0.425072 +v 0.576936 0.639943 0.425743 +v 0.620943 0.648468 0.425022 +v 0.607534 0.657635 0.42444 +v 0.614852 0.642204 0.425091 +v 0.386749 0.65686 0.42492 +v 0.399714 0.645435 0.424466 +v 0.416008 0.650052 0.423573 +v 0.58068 0.649151 0.423827 +v 0.595925 0.642777 0.425371 +v 0.584429 0.65818 0.42345 +v 0.564397 0.659179 0.42336 +v 0.422009 0.658213 0.423448 +v 0.586807 0.665812 0.424496 +v 0.554512 0.662951 0.423149 +v 0.557126 0.674396 0.424341 +v 0.413277 0.66531 0.424783 +v 0.438533 0.673182 0.424672 +v 0.567231 0.67531 0.425246 +v 0.588742 0.672935 0.426555 +v 0.444509 0.830227 0.424064 +v 0.451157 0.82114 0.418448 +v 0.576218 0.816976 0.428716 +v 0.441811 0.850151 0.425081 +v 0.553088 0.853824 0.417209 +v 0.441505 0.882784 0.420607 +v 0.439295 0.914081 0.418894 +v 0.445401 0.898184 0.412936 +v 0.438094 0.93285 0.420755 +v 0.562005 0.935014 0.421131 +v 0.540296 0.97798 0.428066 +v 0.528047 0.983613 0.423283 +v 0.536184 0.976908 0.421154 +v 0.462975 0.977458 0.422298 +v 0.47 0.984233 0.426826 +v 0.51967 0.984673 0.418158 +v 0.422841 0.166779 0.418032 +v 0.577474 0.165088 0.419706 +v 0.44541 0.168157 0.417982 +v 0.433195 0.171341 0.414376 +v 0.44614 0.172768 0.415842 +v 0.414957 0.17169 0.418979 +v 0.423044 0.171798 0.415439 +v 0.411263 0.190814 0.419422 +v 0.418545 0.201193 0.416796 +v 0.421566 0.188475 0.415101 +v 0.554481 0.189977 0.415654 +v 0.553977 0.204584 0.416245 +v 0.457436 0.352951 0.418067 +v 0.457126 0.370372 0.416318 +v 0.417333 0.390975 0.417636 +v 0.413589 0.374646 0.420506 +v 0.516897 0.384653 0.421509 +v 0.522587 0.391754 0.414406 +v 0.528027 0.386651 0.415289 +v 0.587981 0.401971 0.418558 +v 0.589771 0.38966 0.422074 +v 0.582634 0.382656 0.418775 +v 0.412484 0.411485 0.414837 +v 0.408058 0.420085 0.414106 +v 0.588859 0.411339 0.416753 +v 0.59095 0.420716 0.413451 +v 0.595283 0.440663 0.406634 +v 0.59816 0.451144 0.408597 +v 0.450112 0.602511 0.412173 +v 0.451903 0.615097 0.415193 +v 0.452751 0.629054 0.417329 +v 0.455944 0.645943 0.417489 +v 0.553097 0.644341 0.421583 +v 0.529961 0.666811 0.411676 +v 0.538729 0.691844 0.416558 +v 0.538492 0.663961 0.416034 +v 0.537704 0.641361 0.413204 +v 0.547038 0.657851 0.419873 +v 0.457791 0.690275 0.419172 +v 0.459042 0.662335 0.417358 +v 0.451461 0.678315 0.42271 +v 0.460796 0.725603 0.416593 +v 0.533347 0.720677 0.413099 +v 0.542463 0.736978 0.418189 +v 0.543217 0.78395 0.416867 +v 0.545038 0.830887 0.413312 +v 0.547269 0.881642 0.407607 +v 0.55564 0.933503 0.410748 +v 0.549701 0.951022 0.409638 +v 0.54746 0.961413 0.414972 +v 0.45658 0.96937 0.418464 +v 0.452313 0.960397 0.413862 +v 0.478946 0.986449 0.423485 +v 0.481801 0.981919 0.414268 +v 0.488342 0.987561 0.420588 +v 0.497839 0.985956 0.415825 +v 0.425057 0.178459 0.41355 +v 0.448776 0.17873 0.415687 +v 0.568504 0.169003 0.415485 +v 0.555817 0.170335 0.416557 +v 0.555568 0.175726 0.414936 +v 0.576944 0.173921 0.41433 +v 0.578542 0.16993 0.416949 +v 0.568783 0.176697 0.412708 +v 0.579181 0.180028 0.414118 +v 0.453052 0.188028 0.417576 +v 0.442001 0.18749 0.414627 +v 0.578019 0.188643 0.414652 +v 0.567045 0.18955 0.413762 +v 0.558661 0.181621 0.413742 +v 0.414339 0.218708 0.417196 +v 0.423988 0.218594 0.414724 +v 0.428383 0.240909 0.41324 +v 0.43384 0.216688 0.414096 +v 0.583343 0.241103 0.415335 +v 0.587574 0.223279 0.417584 +v 0.579925 0.219124 0.415488 +v 0.442122 0.220737 0.41468 +v 0.441336 0.253292 0.413332 +v 0.448205 0.231051 0.415672 +v 0.460739 0.240199 0.421066 +v 0.45409 0.237628 0.417721 +v 0.454011 0.279558 0.416759 +v 0.572944 0.278876 0.412889 +v 0.577331 0.308322 0.414061 +v 0.581257 0.273512 0.414387 +v 0.461597 0.329588 0.420663 +v 0.454343 0.321553 0.417188 +v 0.431218 0.346058 0.414229 +v 0.438573 0.359339 0.414534 +v 0.438102 0.332019 0.413882 +v 0.446436 0.31282 0.414566 +v 0.438771 0.293152 0.412979 +v 0.577855 0.366217 0.416884 +v 0.577705 0.33875 0.415586 +v 0.560185 0.378219 0.413162 +v 0.558133 0.35649 0.414549 +v 0.552294 0.375927 0.413841 +v 0.434428 0.388095 0.412317 +v 0.432733 0.380139 0.414152 +v 0.425808 0.38936 0.414257 +v 0.436249 0.393601 0.409615 +v 0.44137 0.387702 0.411102 +v 0.558123 0.387605 0.410958 +v 0.567155 0.383998 0.412908 +v 0.574548 0.383454 0.41522 +v 0.574274 0.394387 0.412947 +v 0.532775 0.379554 0.416429 +v 0.538011 0.386887 0.412026 +v 0.421015 0.399345 0.413186 +v 0.48819 0.399871 0.409897 +v 0.519053 0.396724 0.411266 +v 0.533979 0.39744 0.405618 +v 0.512988 0.402947 0.40569 +v 0.574863 0.40257 0.410267 +v 0.581819 0.404405 0.413631 +v 0.404746 0.48718 0.408164 +v 0.401681 0.468973 0.40743 +v 0.596156 0.48264 0.4078 +v 0.598452 0.465717 0.408932 +v 0.589082 0.512601 0.411724 +v 0.58224 0.536682 0.414392 +v 0.421107 0.544709 0.414375 +v 0.461736 0.620788 0.409872 +v 0.465567 0.646409 0.412193 +v 0.46212 0.771897 0.413985 +v 0.468628 0.73009 0.411833 +v 0.456466 0.847622 0.410373 +v 0.458959 0.81149 0.413205 +v 0.53628 0.820061 0.408924 +v 0.443839 0.942679 0.414767 +v 0.537412 0.965384 0.408401 +v 0.539024 0.970743 0.415801 +v 0.46422 0.970776 0.412421 +v 0.527373 0.978697 0.415143 +v 0.432941 0.267569 0.412713 +v 0.42387 0.274753 0.413354 +v 0.570054 0.326661 0.413752 +v 0.566063 0.291319 0.412601 +v 0.562246 0.320879 0.413691 +v 0.44632 0.390339 0.408934 +v 0.450246 0.384911 0.411724 +v 0.460554 0.385206 0.412759 +v 0.461709 0.391753 0.40921 +v 0.545659 0.383175 0.412397 +v 0.547062 0.389413 0.410103 +v 0.552041 0.393517 0.40837 +v 0.436591 0.399701 0.405606 +v 0.442942 0.395502 0.406325 +v 0.452135 0.394685 0.405968 +v 0.460303 0.399836 0.40127 +v 0.558069 0.397558 0.405971 +v 0.546651 0.39753 0.404616 +v 0.559794 0.403906 0.399894 +v 0.567028 0.400683 0.406851 +v 0.573043 0.409382 0.403401 +v 0.428103 0.403379 0.406864 +v 0.420049 0.406778 0.409998 +v 0.419274 0.41504 0.404077 +v 0.401921 0.460064 0.404188 +v 0.405926 0.466812 0.394003 +v 0.410802 0.496286 0.399535 +v 0.592196 0.494779 0.404851 +v 0.586485 0.500483 0.398965 +v 0.444005 0.585509 0.40942 +v 0.433745 0.564609 0.409285 +v 0.540613 0.622356 0.411419 +v 0.546871 0.606042 0.410469 +v 0.530125 0.623661 0.406291 +v 0.469115 0.631572 0.408188 +v 0.473906 0.645197 0.40831 +v 0.482363 0.644662 0.405664 +v 0.478439 0.667339 0.408061 +v 0.525553 0.68832 0.409866 +v 0.524995 0.732686 0.409144 +v 0.476725 0.70789 0.408832 +v 0.476016 0.759038 0.407745 +v 0.485036 0.693081 0.40677 +v 0.516987 0.729168 0.4065 +v 0.523554 0.778652 0.4068 +v 0.467168 0.807673 0.408529 +v 0.449868 0.938309 0.405622 +v 0.450638 0.950241 0.409159 +v 0.488287 0.977183 0.406015 +v 0.480182 0.974088 0.405795 +v 0.506914 0.98168 0.41029 +v 0.496955 0.98012 0.407749 +v 0.517323 0.980953 0.412165 +v 0.516349 0.975305 0.405481 +v 0.436652 0.406635 0.398865 +v 0.402402 0.450192 0.40607 +v 0.405721 0.440092 0.40377 +v 0.5918 0.481308 0.395278 +v 0.416384 0.503233 0.395826 +v 0.414731 0.489874 0.38732 +v 0.572112 0.540406 0.404716 +v 0.571231 0.521418 0.395022 +v 0.559866 0.54269 0.395339 +v 0.429702 0.540889 0.403839 +v 0.424954 0.521372 0.399205 +v 0.437556 0.537403 0.395519 +v 0.455618 0.584971 0.4012 +v 0.546749 0.585551 0.4028 +v 0.48148 0.617361 0.401159 +v 0.47472 0.603323 0.399065 +v 0.471228 0.617776 0.404418 +v 0.524468 0.605367 0.399268 +v 0.518113 0.622628 0.402042 +v 0.491955 0.644406 0.403978 +v 0.487824 0.630154 0.402492 +v 0.493699 0.66654 0.40512 +v 0.50247 0.645604 0.40396 +v 0.512616 0.680101 0.406024 +v 0.519988 0.663265 0.40772 +v 0.512773 0.651492 0.405666 +v 0.511139 0.634954 0.403343 +v 0.491637 0.757718 0.40401 +v 0.500562 0.728164 0.404448 +v 0.493093 0.706734 0.405349 +v 0.5064 0.771884 0.403047 +v 0.509301 0.721947 0.404922 +v 0.475829 0.80339 0.40505 +v 0.483914 0.788541 0.403587 +v 0.492098 0.803854 0.400868 +v 0.501044 0.811097 0.399802 +v 0.510058 0.814018 0.400186 +v 0.518453 0.813814 0.402131 +v 0.527201 0.815652 0.405018 +v 0.473957 0.841307 0.401182 +v 0.529404 0.851073 0.401026 +v 0.452979 0.887366 0.40679 +v 0.461146 0.883207 0.400838 +v 0.540058 0.897971 0.399126 +v 0.546183 0.916666 0.401262 +v 0.450338 0.919774 0.404561 +v 0.457651 0.955604 0.404934 +v 0.472708 0.969383 0.405055 +v 0.46524 0.96224 0.403736 +v 0.481108 0.964511 0.397227 +v 0.496458 0.97245 0.4 +v 0.542068 0.402755 0.398056 +v 0.415753 0.425321 0.398964 +v 0.41033 0.432596 0.400393 +v 0.593415 0.461501 0.395051 +v 0.44061 0.523703 0.386669 +v 0.450191 0.543461 0.389015 +v 0.468284 0.585081 0.395094 +v 0.459956 0.564424 0.391258 +v 0.546013 0.563874 0.394316 +v 0.533427 0.58485 0.39582 +v 0.48043 0.584048 0.390914 +v 0.492921 0.617426 0.399266 +v 0.505339 0.619144 0.399446 +v 0.498494 0.602309 0.394772 +v 0.494619 0.84483 0.39571 +v 0.514248 0.847894 0.396454 +v 0.46941 0.88261 0.396354 +v 0.478415 0.882671 0.392938 +v 0.463792 0.917578 0.394034 +v 0.45707 0.933231 0.397821 +v 0.539931 0.929056 0.395038 +v 0.54781 0.93203 0.401985 +v 0.548369 0.941248 0.404162 +v 0.541849 0.949439 0.401517 +v 0.532082 0.951025 0.395534 +v 0.534965 0.958738 0.40142 +v 0.465315 0.951562 0.397614 +v 0.526209 0.967604 0.402456 +v 0.515162 0.968282 0.398876 +v 0.499848 0.407684 0.400583 +v 0.516365 0.410441 0.39281 +v 0.416526 0.444984 0.382567 +v 0.406632 0.460677 0.39271 +v 0.578859 0.503255 0.390767 +v 0.570687 0.506324 0.384052 +v 0.583631 0.489298 0.38634 +v 0.519464 0.583553 0.390703 +v 0.534323 0.916876 0.392387 +v 0.531515 0.888557 0.395622 +v 0.531363 0.932769 0.390143 +v 0.464756 0.938625 0.39372 +v 0.505084 0.966659 0.395893 +v 0.496638 0.962786 0.393083 +v 0.514164 0.960104 0.393025 +v 0.470471 0.408355 0.391704 +v 0.458779 0.41044 0.387531 +v 0.484595 0.408096 0.396475 +v 0.482536 0.417741 0.382552 +v 0.54339 0.410449 0.387906 +v 0.531976 0.410165 0.388851 +v 0.551603 0.41186 0.387688 +v 0.543054 0.419836 0.376131 +v 0.516444 0.41822 0.381824 +v 0.424518 0.423878 0.38986 +v 0.432795 0.417784 0.388778 +v 0.429732 0.430321 0.378152 +v 0.574924 0.435848 0.37941 +v 0.582862 0.428006 0.395859 +v 0.574944 0.42229 0.391977 +v 0.587821 0.447195 0.388883 +v 0.590051 0.433535 0.401753 +v 0.587979 0.459032 0.384817 +v 0.589824 0.469673 0.387767 +v 0.423205 0.506839 0.390225 +v 0.430809 0.506617 0.382956 +v 0.421578 0.493746 0.381636 +v 0.568973 0.496818 0.375166 +v 0.564914 0.505582 0.378275 +v 0.545533 0.5428 0.386953 +v 0.463538 0.542273 0.382724 +v 0.492402 0.581746 0.388405 +v 0.486122 0.559957 0.381989 +v 0.50562 0.581544 0.388221 +v 0.513436 0.558989 0.381864 +v 0.522187 0.875943 0.394142 +v 0.514755 0.885153 0.390457 +v 0.487951 0.882843 0.390356 +v 0.482794 0.917747 0.386186 +v 0.473121 0.945239 0.3915 +v 0.481469 0.952309 0.390648 +v 0.481149 0.938671 0.386588 +v 0.528063 0.943433 0.390793 +v 0.52217 0.952946 0.391604 +v 0.4891 0.957882 0.391156 +v 0.497162 0.951761 0.387562 +v 0.51302 0.951401 0.388493 +v 0.457397 0.420971 0.374611 +v 0.450312 0.414825 0.383046 +v 0.55876 0.414094 0.387989 +v 0.441677 0.413546 0.387985 +v 0.443505 0.422715 0.376455 +v 0.503667 0.42519 0.37748 +v 0.516577 0.426094 0.373551 +v 0.566591 0.417464 0.389513 +v 0.582671 0.454274 0.378276 +v 0.411644 0.46595 0.383337 +v 0.586956 0.478329 0.385446 +v 0.439676 0.506382 0.3767 +v 0.532258 0.534846 0.379018 +v 0.545735 0.522649 0.379357 +v 0.507419 0.893138 0.387696 +v 0.497565 0.884214 0.38898 +v 0.501684 0.912999 0.383965 +v 0.51454 0.913342 0.385414 +v 0.513467 0.941276 0.38552 +v 0.522333 0.936396 0.387007 +v 0.515517 0.930416 0.38427 +v 0.489877 0.934121 0.383598 +v 0.505295 0.946442 0.385779 +v 0.497914 0.940561 0.383968 +v 0.492867 0.424637 0.37773 +v 0.48101 0.426404 0.373098 +v 0.497159 0.431413 0.37278 +v 0.419009 0.46189 0.3746 +v 0.417524 0.472497 0.377067 +v 0.581648 0.477516 0.377966 +v 0.418893 0.482857 0.378469 +v 0.450783 0.506294 0.371613 +v 0.439736 0.492916 0.367992 +v 0.477438 0.538732 0.377536 +v 0.465119 0.520341 0.374643 +v 0.490934 0.534912 0.374542 +v 0.508206 0.925274 0.382901 +v 0.498906 0.929872 0.382464 +v 0.436847 0.431223 0.371932 +v 0.431024 0.439198 0.370273 +v 0.579392 0.467285 0.373165 +v 0.578748 0.458284 0.372803 +v 0.574532 0.46189 0.368692 +v 0.576502 0.448011 0.373569 +v 0.563615 0.497556 0.372119 +v 0.55639 0.507754 0.375503 +v 0.545745 0.505091 0.369882 +v 0.453434 0.429027 0.367617 +v 0.46145 0.428935 0.367321 +v 0.527734 0.429039 0.368491 +v 0.515545 0.435306 0.367124 +v 0.537153 0.426858 0.368931 +v 0.533556 0.434914 0.363554 +v 0.545421 0.428278 0.368319 +v 0.559328 0.425485 0.375844 +v 0.554102 0.431244 0.368299 +v 0.562206 0.435511 0.369201 +v 0.564085 0.444496 0.365655 +v 0.569583 0.441398 0.370742 +v 0.426955 0.446793 0.369894 +v 0.436657 0.445287 0.364307 +v 0.422921 0.453651 0.371692 +v 0.428385 0.46103 0.36622 +v 0.571196 0.46995 0.367004 +v 0.569204 0.480543 0.368124 +v 0.576326 0.475435 0.37202 +v 0.425693 0.477516 0.370387 +v 0.535534 0.502233 0.365982 +v 0.547711 0.490898 0.362605 +v 0.505446 0.534178 0.374395 +v 0.497302 0.513592 0.369159 +v 0.5194 0.536806 0.37648 +v 0.525345 0.517086 0.371142 +v 0.550016 0.43633 0.364014 +v 0.445033 0.430261 0.368809 +v 0.448821 0.436035 0.364075 +v 0.470254 0.43181 0.366625 +v 0.481172 0.435555 0.366675 +v 0.490981 0.437975 0.367513 +v 0.484494 0.445524 0.362632 +v 0.497587 0.440253 0.367314 +v 0.514794 0.446431 0.362223 +v 0.504631 0.443242 0.365468 +v 0.497986 0.450307 0.363371 +v 0.567056 0.461945 0.364041 +v 0.432063 0.470048 0.364171 +v 0.434628 0.480472 0.365209 +v 0.44428 0.483725 0.361956 +v 0.559162 0.483903 0.363624 +v 0.566275 0.489007 0.369271 +v 0.519734 0.494326 0.362292 +v 0.514981 0.48497 0.36043 +v 0.505539 0.497741 0.364833 +v 0.462367 0.503166 0.366971 +v 0.456166 0.489658 0.361305 +v 0.471923 0.495864 0.36311 +v 0.489543 0.498186 0.364966 +v 0.526869 0.499249 0.363873 +v 0.532232 0.486072 0.358879 +v 0.462975 0.437702 0.361908 +v 0.546724 0.44273 0.360453 +v 0.555963 0.444486 0.36198 +v 0.51436 0.459456 0.359444 +v 0.524491 0.450709 0.358834 +v 0.531778 0.45534 0.356621 +v 0.531243 0.444715 0.359302 +v 0.562279 0.452939 0.362471 +v 0.491918 0.454332 0.361585 +v 0.481272 0.454648 0.359575 +v 0.498394 0.461561 0.361545 +v 0.558206 0.46165 0.35989 +v 0.438611 0.463343 0.360567 +v 0.4936 0.471299 0.36061 +v 0.503843 0.468416 0.360978 +v 0.551041 0.479889 0.359649 +v 0.451952 0.478022 0.3583 +v 0.525708 0.474031 0.357068 +v 0.513596 0.472818 0.359046 +v 0.455637 0.441213 0.36043 +v 0.46203 0.446727 0.358156 +v 0.538114 0.442218 0.359884 +v 0.543597 0.450325 0.357648 +v 0.446506 0.443273 0.361487 +v 0.445948 0.450945 0.359599 +v 0.447506 0.459166 0.35816 +v 0.456702 0.454428 0.356975 +v 0.468115 0.454597 0.357284 +v 0.449993 0.46812 0.357416 +v 0.539835 0.457824 0.356054 +v 0.549022 0.459432 0.357102 +v 0.479735 0.464761 0.358345 +v 0.534514 0.465226 0.35577 +v 0.463446 0.475079 0.357099 +v 0.552095 0.469681 0.358172 +v 0.479769 0.474624 0.35858 +v 0.535397 0.475012 0.356536 +v 0.478261 0.485259 0.36031 +v 0.543025 0.477033 0.357416 +v 0.47959 0.406351 0.545325 +v 0.424273 0.404079 0.533596 +v 0.471178 0.398359 0.538915 +v 0.540002 0.394664 0.537512 +v 0.438701 0.388632 0.532159 +v 0.449984 0.389654 0.534341 +v 0.461145 0.389225 0.53407 +v 0.55986 0.383489 0.530856 +v 0.550068 0.391931 0.53578 +v 0.557386 0.243144 0.526209 +v 0.565783 0.241286 0.52744 +v 0.575545 0.310655 0.529617 +v 0.570849 0.314896 0.529332 +v 0.428965 0.304387 0.529381 +v 0.433637 0.305049 0.529213 +v 0.430413 0.309522 0.53021 +v 0.426792 0.312361 0.529977 +v 0.423844 0.316712 0.528298 +v 0.432313 0.315371 0.529116 +v 0.573161 0.323736 0.525676 +v 0.426787 0.389163 0.529002 +v 0.415542 0.394488 0.525335 +v 0.49299 0.381359 0.5164 +v 0.495889 0.388102 0.52347 +v 0.576176 0.393295 0.530021 +v 0.547929 0.244543 0.523495 +v 0.53916 0.244335 0.519557 +v 0.588381 0.267147 0.519651 +v 0.437922 0.240342 0.526667 +v 0.572098 0.26302 0.524315 +v 0.430231 0.296539 0.526572 +v 0.425235 0.297355 0.526251 +v 0.434837 0.297229 0.526396 +v 0.432803 0.28701 0.523864 +v 0.58239 0.290474 0.521343 +v 0.583494 0.300278 0.523621 +v 0.580965 0.307584 0.527148 +v 0.5868 0.30664 0.522295 +v 0.549919 0.316816 0.520549 +v 0.420648 0.323513 0.524146 +v 0.578953 0.332955 0.521003 +v 0.558504 0.369709 0.525962 +v 0.552934 0.358185 0.522259 +v 0.530373 0.375147 0.524048 +v 0.600765 0.238612 0.515654 +v 0.449212 0.259262 0.522222 +v 0.445901 0.245078 0.524898 +v 0.57765 0.278679 0.522094 +v 0.586432 0.282113 0.519322 +v 0.438549 0.257525 0.524486 +v 0.442378 0.269709 0.522787 +v 0.434596 0.274382 0.523445 +v 0.569696 0.276781 0.523269 +v 0.42779 0.278138 0.523011 +v 0.42244 0.286898 0.522811 +v 0.592808 0.288617 0.516565 +v 0.591161 0.306894 0.517836 +v 0.412922 0.319949 0.520412 +v 0.550703 0.333442 0.519262 +v 0.558511 0.338476 0.521044 +v 0.556212 0.348177 0.521053 +v 0.533415 0.363805 0.51909 +v 0.408875 0.386022 0.517946 +v 0.606952 0.238017 0.510007 +v 0.461455 0.266234 0.516061 +v 0.540973 0.314127 0.515611 +v 0.399288 0.294493 0.510588 +v 0.461628 0.308874 0.514421 +v 0.459136 0.291595 0.516034 +v 0.468761 0.313011 0.509644 +v 0.544535 0.328564 0.517147 +v 0.584947 0.347547 0.518013 +v 0.525788 0.359643 0.512501 +v 0.5082 0.368885 0.504097 +v 0.516939 0.364449 0.508244 +v 0.410629 0.36152 0.515791 +v 0.410548 0.373413 0.516381 +v 0.402013 0.378659 0.510852 +v 0.497821 0.374385 0.505523 +v 0.474652 0.241058 0.509268 +v 0.598138 0.37808 0.512271 +v 0.593037 0.356927 0.513933 +v 0.502755 0.371002 0.501222 +v 0.505713 0.365397 0.496044 +v 0.600237 0.405483 0.516983 +v 0.480591 0.272646 0.497014 +v 0.478124 0.25005 0.503501 +v 0.474527 0.272251 0.505258 +v 0.51974 0.292538 0.496196 +v 0.474092 0.303411 0.504503 +v 0.47596 0.332205 0.5033 +v 0.518328 0.35617 0.503754 +v 0.388019 0.406361 0.497502 +v 0.392149 0.413999 0.508163 +v 0.392109 0.30221 0.503035 +v 0.477995 0.296515 0.499543 +v 0.483659 0.345378 0.495109 +v 0.512194 0.353447 0.493598 +v 0.516654 0.229357 0.499073 +v 0.51425 0.235404 0.491532 +v 0.385946 0.300605 0.494814 +v 0.61612 0.308027 0.491077 +v 0.612117 0.321565 0.496693 +v 0.515269 0.269219 0.488304 +v 0.61856 0.300083 0.485596 +v 0.615001 0.370449 0.48902 +v 0.486462 0.342267 0.487501 +v 0.385082 0.380797 0.48587 +v 0.616617 0.414177 0.488585 +v 0.488504 0.339998 0.478977 +v 0.512414 0.341872 0.48401 +v 0.5081 0.350446 0.476755 +v 0.507443 0.354014 0.482633 +v 0.506843 0.359209 0.489189 +v 0.377566 0.265023 0.473893 +v 0.504256 0.357649 0.470703 +v 0.622687 0.20248 0.470974 +v 0.623235 0.221664 0.465808 +v 0.376345 0.221466 0.477143 +v 0.511635 0.306912 0.468843 +v 0.620371 0.289383 0.478474 +v 0.618623 0.334615 0.47101 +v 0.617153 0.357425 0.462088 +v 0.62201 0.26988 0.468845 +v 0.503982 0.359797 0.459705 +v 0.376987 0.203848 0.470755 +v 0.621829 0.258894 0.459051 +v 0.488436 0.274568 0.462751 +v 0.511641 0.274191 0.466852 +v 0.488855 0.307775 0.466573 +v 0.489244 0.331504 0.471537 +v 0.51347 0.205978 0.453078 +v 0.512276 0.307732 0.458639 +v 0.494782 0.360656 0.452361 +v 0.383787 0.352588 0.454101 +v 0.619516 0.256921 0.450085 +v 0.618598 0.302092 0.451983 +v 0.379463 0.265599 0.453606 +v 0.616214 0.346089 0.453268 +v 0.384952 0.20456 0.443653 +v 0.391494 0.20351 0.434674 +v 0.51457 0.220122 0.4487 +v 0.517483 0.205571 0.443762 +v 0.382704 0.310493 0.448893 +v 0.614069 0.334197 0.445189 +v 0.49704 0.365307 0.449405 +v 0.499673 0.367382 0.44889 +v 0.500668 0.372786 0.442252 +v 0.617806 0.222537 0.446216 +v 0.615629 0.259338 0.441508 +v 0.521256 0.328917 0.435766 +v 0.518806 0.349763 0.437103 +v 0.612227 0.305116 0.438336 +v 0.60888 0.347329 0.438003 +v 0.479775 0.197157 0.439941 +v 0.610358 0.268418 0.433864 +v 0.504077 0.378993 0.434352 +v 0.476254 0.18813 0.434176 +v 0.390929 0.302917 0.433929 +v 0.392927 0.261583 0.429985 +v 0.394872 0.343123 0.432875 +v 0.524673 0.352155 0.430301 +v 0.602442 0.346994 0.430398 +v 0.401266 0.343318 0.42655 +v 0.468173 0.187901 0.426255 +v 0.465465 0.206296 0.424829 +v 0.461035 0.190731 0.421404 +v 0.398166 0.208809 0.427412 +v 0.400716 0.197379 0.426393 +v 0.60708 0.239912 0.4302 +v 0.400203 0.268106 0.423418 +v 0.397346 0.231627 0.42634 +v 0.528117 0.359512 0.425471 +v 0.530044 0.333233 0.42636 +v 0.510268 0.380565 0.428254 +v 0.517408 0.376444 0.425739 +v 0.405225 0.21965 0.421409 +v 0.533068 0.281654 0.425103 +v 0.540359 0.297336 0.419781 +v 0.537225 0.236578 0.422723 +v 0.469081 0.34599 0.425094 +v 0.523203 0.368787 0.425485 +v 0.530369 0.368711 0.421033 +v 0.537759 0.37013 0.417591 +v 0.454675 0.205543 0.41872 +v 0.544276 0.225265 0.418608 +v 0.410775 0.242901 0.417377 +v 0.592909 0.244479 0.419224 +v 0.407879 0.274478 0.418651 +v 0.415607 0.276454 0.415356 +v 0.404648 0.308358 0.421473 +v 0.54309 0.349668 0.417581 +v 0.547424 0.307723 0.416194 +v 0.408969 0.345801 0.421435 +v 0.417634 0.346327 0.417202 +v 0.431296 0.187743 0.413535 +v 0.438416 0.200208 0.414841 +v 0.57531 0.201796 0.415115 +v 0.550469 0.261604 0.414977 +v 0.552495 0.22821 0.41548 +v 0.571153 0.222904 0.413974 +v 0.561674 0.227424 0.413906 +v 0.567179 0.252331 0.412636 +v 0.588402 0.263476 0.416752 +v 0.420622 0.311586 0.414522 +v 0.424937 0.343321 0.414675 +v 0.429666 0.365529 0.414885 +v 0.55459 0.311956 0.414421 +v 0.544703 0.373383 0.415243 +v 0.437304 0.372448 0.414322 +v 0.447035 0.371631 0.414487 +v 0.455322 0.378842 0.414228 +v -50.0 -1.0 50.0 +v -50.0 -1.0 -50.0 +v 50.0 -1.0 -50.0 +v 50.0 -1.0 50.0 +f 6003 6004 6005 +f 6005 6006 6003 +f 332 1503 1505 +f 1503 476 1504 +f 1505 1504 1079 +f 1503 1504 1505 +f 381 1506 1508 +f 1506 287 1507 +f 1508 1507 1499 +f 1506 1507 1508 +f 287 1509 1507 +f 1509 1274 1510 +f 1507 1510 1499 +f 1509 1510 1507 +f 712 1511 1513 +f 1511 476 1512 +f 1513 1512 1165 +f 1511 1512 1513 +f 476 1514 1504 +f 1514 111 1515 +f 1504 1515 1079 +f 1514 1515 1504 +f 381 1516 1518 +f 1516 1012 1517 +f 1518 1517 1015 +f 1516 1517 1518 +f 409 1519 1520 +f 1519 381 1518 +f 1520 1518 1015 +f 1519 1518 1520 +f 287 1506 1521 +f 1506 381 1519 +f 1521 1519 409 +f 1506 1519 1521 +f 1165 1522 1524 +f 1522 332 1523 +f 1524 1523 1342 +f 1522 1523 1524 +f 476 1503 1512 +f 1503 332 1522 +f 1512 1522 1165 +f 1503 1522 1512 +f 111 1525 1515 +f 1525 25 1526 +f 1515 1526 1079 +f 1525 1526 1515 +f 25 1525 1528 +f 1525 111 1527 +f 1528 1527 1119 +f 1525 1527 1528 +f 287 1521 1530 +f 1521 409 1529 +f 1530 1529 841 +f 1521 1529 1530 +f 287 1530 1509 +f 1530 841 1531 +f 1509 1531 1274 +f 1530 1531 1509 +f 1105 1532 1534 +f 1532 162 1533 +f 1534 1533 1112 +f 1532 1533 1534 +f 1112 1533 1536 +f 1533 162 1535 +f 1536 1535 1359 +f 1533 1535 1536 +f 332 1537 1523 +f 1537 55 1538 +f 1523 1538 1342 +f 1537 1538 1523 +f 55 1537 1539 +f 1537 332 1505 +f 1539 1505 1079 +f 1537 1505 1539 +f 1079 1526 1541 +f 1526 25 1540 +f 1541 1540 1332 +f 1526 1540 1541 +f 473 1542 1544 +f 1542 1012 1543 +f 1544 1543 1499 +f 1542 1543 1544 +f 1012 1516 1543 +f 1516 381 1508 +f 1543 1508 1499 +f 1516 1508 1543 +f 739 1545 1547 +f 1545 543 1546 +f 1547 1546 1208 +f 1545 1546 1547 +f 171 1548 1549 +f 1548 739 1547 +f 1549 1547 1208 +f 1548 1547 1549 +f 171 1550 1548 +f 1550 39 1551 +f 1548 1551 739 +f 1550 1551 1548 +f 55 1539 1552 +f 1539 1079 1541 +f 1552 1541 1332 +f 1539 1541 1552 +f 476 1511 1554 +f 1511 712 1553 +f 1554 1553 1255 +f 1511 1553 1554 +f 111 1514 1555 +f 1514 476 1554 +f 1555 1554 1255 +f 1514 1554 1555 +f 1119 1527 1556 +f 1527 111 1555 +f 1556 1555 1255 +f 1527 1555 1556 +f 896 1557 1558 +f 1557 409 1520 +f 1558 1520 1015 +f 1557 1520 1558 +f 841 1529 1559 +f 1529 409 1557 +f 1559 1557 896 +f 1529 1557 1559 +f 717 1560 1561 +f 1560 162 1532 +f 1561 1532 1105 +f 1560 1532 1561 +f 162 1560 1535 +f 1560 717 1562 +f 1535 1562 1359 +f 1560 1562 1535 +f 919 1563 1565 +f 1563 994 1564 +f 1565 1564 1208 +f 1563 1564 1565 +f 543 1566 1546 +f 1566 919 1565 +f 1546 1565 1208 +f 1566 1565 1546 +f 994 1567 1564 +f 1567 171 1549 +f 1564 1549 1208 +f 1567 1549 1564 +f 171 1567 1569 +f 1567 994 1568 +f 1569 1568 1111 +f 1567 1568 1569 +f 1058 1570 1571 +f 1570 1105 1534 +f 1571 1534 1112 +f 1570 1534 1571 +f 563 1572 1573 +f 1572 1112 1536 +f 1573 1536 1359 +f 1572 1536 1573 +f 39 1550 1574 +f 1550 171 1569 +f 1574 1569 1111 +f 1550 1569 1574 +f 1027 1575 1576 +f 1575 55 1552 +f 1576 1552 1332 +f 1575 1552 1576 +f 661 1577 1578 +f 1577 473 1544 +f 1578 1544 1499 +f 1577 1544 1578 +f 39 1579 1551 +f 1579 269 1580 +f 1551 1580 739 +f 1579 1580 1551 +f 1359 1562 1582 +f 1562 717 1581 +f 1582 1581 1488 +f 1562 1581 1582 +f 101 1583 1584 +f 1583 896 1558 +f 1584 1558 1015 +f 1583 1558 1584 +f 1 1585 1587 +f 1585 738 1586 +f 1587 1586 907 +f 1585 1586 1587 +f 738 1585 1589 +f 1585 1 1588 +f 1589 1588 812 +f 1585 1588 1589 +f 907 1586 1591 +f 1586 738 1590 +f 1591 1590 1360 +f 1586 1590 1591 +f 1165 1524 1593 +f 1524 1342 1592 +f 1593 1592 1378 +f 1524 1592 1593 +f 1274 1531 1595 +f 1531 841 1594 +f 1595 1594 1344 +f 1531 1594 1595 +f 25 1528 1540 +f 1528 1119 1596 +f 1540 1596 1332 +f 1528 1596 1540 +f 208 1597 1598 +f 1597 543 1545 +f 1598 1545 739 +f 1597 1545 1598 +f 31 1599 1601 +f 1599 393 1600 +f 1601 1600 1058 +f 1599 1600 1601 +f 31 1601 1602 +f 1601 1058 1571 +f 1602 1571 1112 +f 1601 1571 1602 +f 55 1575 1538 +f 1575 1027 1603 +f 1538 1603 1342 +f 1575 1603 1538 +f 1274 1604 1510 +f 1604 1343 1605 +f 1510 1605 1499 +f 1604 1605 1510 +f 269 1579 1607 +f 1579 39 1606 +f 1607 1606 1141 +f 1579 1606 1607 +f 39 1574 1606 +f 1574 1111 1608 +f 1606 1608 1141 +f 1574 1608 1606 +f 563 1609 1572 +f 1609 31 1602 +f 1572 1602 1112 +f 1609 1602 1572 +f 1343 1610 1605 +f 1610 661 1578 +f 1605 1578 1499 +f 1610 1578 1605 +f 1218 1611 1613 +f 1611 42 1612 +f 1613 1612 1445 +f 1611 1612 1613 +f 42 1614 1612 +f 1614 898 1615 +f 1612 1615 1445 +f 1614 1615 1612 +f 636 1616 1618 +f 1616 839 1617 +f 1618 1617 1168 +f 1616 1617 1618 +f 995 1619 1621 +f 1619 433 1620 +f 1621 1620 1133 +f 1619 1620 1621 +f 831 1622 1623 +f 1622 433 1619 +f 1623 1619 995 +f 1622 1619 1623 +f 1000 1624 1625 +f 1624 995 1621 +f 1625 1621 1133 +f 1624 1621 1625 +f 59 1626 1627 +f 1626 636 1618 +f 1627 1618 1168 +f 1626 1618 1627 +f 1 1587 1629 +f 1587 907 1628 +f 1629 1628 1009 +f 1587 1628 1629 +f 812 1588 1630 +f 1588 1 1629 +f 1630 1629 1009 +f 1588 1629 1630 +f 831 1631 1633 +f 1631 1296 1632 +f 1633 1632 1473 +f 1631 1632 1633 +f 831 1623 1631 +f 1623 995 1634 +f 1631 1634 1296 +f 1623 1634 1631 +f 1255 1553 1636 +f 1553 712 1635 +f 1636 1635 1327 +f 1553 1635 1636 +f 101 1637 1583 +f 1637 801 1638 +f 1583 1638 896 +f 1637 1638 1583 +f 995 1639 1634 +f 1639 645 1640 +f 1634 1640 1296 +f 1639 1640 1634 +f 645 1639 1641 +f 1639 995 1624 +f 1641 1624 1000 +f 1639 1624 1641 +f 981 1642 1643 +f 1642 717 1561 +f 1643 1561 1105 +f 1642 1561 1643 +f 712 1513 1635 +f 1513 1165 1644 +f 1635 1644 1327 +f 1513 1644 1635 +f 880 1645 1646 +f 1645 1255 1636 +f 1646 1636 1327 +f 1645 1636 1646 +f 1071 1647 1648 +f 1647 1119 1556 +f 1648 1556 1255 +f 1647 1556 1648 +f 880 1649 1645 +f 1649 1071 1648 +f 1645 1648 1255 +f 1649 1648 1645 +f 801 1650 1638 +f 1650 841 1559 +f 1638 1559 896 +f 1650 1559 1638 +f 919 1651 1653 +f 1651 930 1652 +f 1653 1652 1318 +f 1651 1652 1653 +f 919 1566 1651 +f 1566 543 1654 +f 1651 1654 930 +f 1566 1654 1651 +f 994 1563 1655 +f 1563 919 1653 +f 1655 1653 1318 +f 1563 1653 1655 +f 144 1656 1657 +f 1656 738 1589 +f 1657 1589 812 +f 1656 1589 1657 +f 738 1656 1659 +f 1656 144 1658 +f 1659 1658 962 +f 1656 1658 1659 +f 645 1660 1640 +f 1660 394 1661 +f 1640 1661 1296 +f 1660 1661 1640 +f 1378 1662 1663 +f 1662 1359 1582 +f 1663 1582 1488 +f 1662 1582 1663 +f 1327 1644 1664 +f 1644 1165 1593 +f 1664 1593 1378 +f 1644 1593 1664 +f 101 1584 1666 +f 1584 1015 1665 +f 1666 1665 1055 +f 1584 1665 1666 +f 1015 1517 1665 +f 1517 1012 1667 +f 1665 1667 1055 +f 1517 1667 1665 +f 801 1668 1650 +f 1668 91 1669 +f 1650 1669 841 +f 1668 1669 1650 +f 841 1669 1594 +f 1669 91 1670 +f 1594 1670 1344 +f 1669 1670 1594 +f 738 1659 1590 +f 1659 962 1671 +f 1590 1671 1360 +f 1659 1671 1590 +f 962 1672 1671 +f 1672 514 1673 +f 1671 1673 1360 +f 1672 1673 1671 +f 1119 1674 1596 +f 1674 300 1675 +f 1596 1675 1332 +f 1674 1675 1596 +f 1012 1676 1667 +f 1676 29 1677 +f 1667 1677 1055 +f 1676 1677 1667 +f 935 1678 1679 +f 1678 29 1676 +f 1679 1676 1012 +f 1678 1676 1679 +f 473 1680 1542 +f 1680 935 1679 +f 1542 1679 1012 +f 1680 1679 1542 +f 543 1597 1654 +f 1597 208 1681 +f 1654 1681 930 +f 1597 1681 1654 +f 689 1682 1683 +f 1682 563 1573 +f 1683 1573 1359 +f 1682 1573 1683 +f 1343 1604 1684 +f 1604 1274 1595 +f 1684 1595 1344 +f 1604 1595 1684 +f 243 1685 1686 +f 1685 31 1609 +f 1686 1609 563 +f 1685 1609 1686 +f 243 1686 1687 +f 1686 563 1682 +f 1687 1682 689 +f 1686 1682 1687 +f 1051 1688 1689 +f 1688 42 1611 +f 1689 1611 1218 +f 1688 1611 1689 +f 898 1614 1690 +f 1614 42 1688 +f 1690 1688 1051 +f 1614 1688 1690 +f 124 1691 1693 +f 1691 839 1692 +f 1693 1692 1143 +f 1691 1692 1693 +f 839 1694 1617 +f 1694 1042 1695 +f 1617 1695 1168 +f 1694 1695 1617 +f 839 1691 1694 +f 1691 124 1696 +f 1694 1696 1042 +f 1691 1696 1694 +f 898 1697 1615 +f 1697 932 1698 +f 1615 1698 1445 +f 1697 1698 1615 +f 839 1616 1692 +f 1616 636 1699 +f 1692 1699 1143 +f 1616 1699 1692 +f 710 1700 1701 +f 1700 1218 1613 +f 1701 1613 1445 +f 1700 1613 1701 +f 932 1702 1698 +f 1702 710 1701 +f 1698 1701 1445 +f 1702 1701 1698 +f 323 1703 1705 +f 1703 1143 1704 +f 1705 1704 1449 +f 1703 1704 1705 +f 1143 1699 1704 +f 1699 636 1706 +f 1704 1706 1449 +f 1699 1706 1704 +f 384 1707 1708 +f 1707 59 1627 +f 1708 1627 1168 +f 1707 1627 1708 +f 303 1709 1710 +f 1709 812 1630 +f 1710 1630 1009 +f 1709 1630 1710 +f 710 1702 1712 +f 1702 932 1711 +f 1712 1711 1497 +f 1702 1711 1712 +f 636 1626 1706 +f 1626 59 1713 +f 1706 1713 1449 +f 1626 1713 1706 +f 1009 1628 1715 +f 1628 907 1714 +f 1715 1714 1407 +f 1628 1714 1715 +f 645 1641 1717 +f 1641 1000 1716 +f 1717 1716 1106 +f 1641 1716 1717 +f 1000 1718 1716 +f 1718 117 1719 +f 1716 1719 1106 +f 1718 1719 1716 +f 717 1642 1581 +f 1642 981 1720 +f 1581 1720 1488 +f 1642 1720 1581 +f 303 1721 1709 +f 1721 144 1657 +f 1709 1657 812 +f 1721 1657 1709 +f 645 1717 1723 +f 1717 1106 1722 +f 1723 1722 1417 +f 1717 1722 1723 +f 554 1724 1725 +f 1724 994 1655 +f 1725 1655 1318 +f 1724 1655 1725 +f 981 1643 1727 +f 1643 1105 1726 +f 1727 1726 1417 +f 1643 1726 1727 +f 1105 1570 1726 +f 1570 1058 1728 +f 1726 1728 1417 +f 1570 1728 1726 +f 930 1681 1730 +f 1681 208 1729 +f 1730 1729 1344 +f 1681 1729 1730 +f 994 1731 1568 +f 1731 318 1732 +f 1568 1732 1111 +f 1731 1732 1568 +f 554 1733 1724 +f 1733 318 1731 +f 1724 1731 994 +f 1733 1731 1724 +f 144 1734 1658 +f 1734 427 1735 +f 1658 1735 962 +f 1734 1735 1658 +f 1058 1600 1728 +f 1600 393 1736 +f 1728 1736 1417 +f 1600 1736 1728 +f 689 1683 1737 +f 1683 1359 1662 +f 1737 1662 1378 +f 1683 1662 1737 +f 1342 1738 1592 +f 1738 689 1737 +f 1592 1737 1378 +f 1738 1737 1592 +f 1111 1732 1740 +f 1732 318 1739 +f 1740 1739 1428 +f 1732 1739 1740 +f 1141 1608 1741 +f 1608 1111 1740 +f 1741 1740 1428 +f 1608 1740 1741 +f 1027 1742 1603 +f 1742 689 1738 +f 1603 1738 1342 +f 1742 1738 1603 +f 300 1743 1675 +f 1743 1075 1744 +f 1675 1744 1332 +f 1743 1744 1675 +f 473 1577 1680 +f 1577 661 1745 +f 1680 1745 935 +f 1577 1745 1680 +f 1075 1746 1744 +f 1746 1027 1576 +f 1744 1576 1332 +f 1746 1576 1744 +f 269 1607 1748 +f 1607 1141 1747 +f 1748 1747 1162 +f 1607 1747 1748 +f 739 1580 1749 +f 1580 269 1748 +f 1749 1748 1162 +f 1580 1748 1749 +f 898 1750 1697 +f 1750 19 1751 +f 1697 1751 932 +f 1750 1751 1697 +f 1042 1752 1695 +f 1752 384 1708 +f 1695 1708 1168 +f 1752 1708 1695 +f 433 1753 1620 +f 1753 568 1754 +f 1620 1754 1133 +f 1753 1754 1620 +f 568 1755 1754 +f 1755 536 1756 +f 1754 1756 1133 +f 1755 1756 1754 +f 536 1757 1756 +f 1757 1000 1625 +f 1756 1625 1133 +f 1757 1625 1756 +f 536 1758 1757 +f 1758 117 1718 +f 1757 1718 1000 +f 1758 1718 1757 +f 981 1759 1720 +f 1759 166 1760 +f 1720 1760 1488 +f 1759 1760 1720 +f 166 1761 1760 +f 1761 1262 1762 +f 1760 1762 1488 +f 1761 1762 1760 +f 1193 1763 1765 +f 1763 930 1764 +f 1765 1764 1272 +f 1763 1764 1765 +f 930 1763 1652 +f 1763 1193 1766 +f 1652 1766 1318 +f 1763 1766 1652 +f 166 1759 1767 +f 1759 981 1727 +f 1767 1727 1417 +f 1759 1727 1767 +f 1346 1768 1769 +f 1768 1327 1664 +f 1769 1664 1378 +f 1768 1664 1769 +f 880 1646 1770 +f 1646 1327 1768 +f 1770 1768 1346 +f 1646 1768 1770 +f 101 1771 1637 +f 1771 343 1772 +f 1637 1772 801 +f 1771 1772 1637 +f 343 1771 1773 +f 1771 101 1666 +f 1773 1666 1055 +f 1771 1666 1773 +f 801 1772 1775 +f 1772 343 1774 +f 1775 1774 1272 +f 1772 1774 1775 +f 1272 1764 1776 +f 1764 930 1730 +f 1776 1730 1344 +f 1764 1730 1776 +f 91 1777 1670 +f 1777 1272 1776 +f 1670 1776 1344 +f 1777 1776 1670 +f 91 1668 1777 +f 1668 801 1775 +f 1777 1775 1272 +f 1668 1775 1777 +f 1193 1778 1766 +f 1778 554 1725 +f 1766 1725 1318 +f 1778 1725 1766 +f 907 1591 1780 +f 1591 1360 1779 +f 1780 1779 1483 +f 1591 1779 1780 +f 1407 1714 1781 +f 1714 907 1780 +f 1781 1780 1483 +f 1714 1780 1781 +f 1296 1782 1632 +f 1782 290 1783 +f 1632 1783 1473 +f 1782 1783 1632 +f 394 1784 1661 +f 1784 290 1782 +f 1661 1782 1296 +f 1784 1782 1661 +f 1346 1769 1785 +f 1769 1378 1663 +f 1785 1663 1488 +f 1769 1663 1785 +f 1071 1786 1647 +f 1786 966 1787 +f 1647 1787 1119 +f 1786 1787 1647 +f 1360 1673 1779 +f 1673 514 1788 +f 1779 1788 1483 +f 1673 1788 1779 +f 966 1789 1787 +f 1789 300 1674 +f 1787 1674 1119 +f 1789 1674 1787 +f 295 1790 1791 +f 1790 514 1672 +f 1791 1672 962 +f 1790 1672 1791 +f 393 1792 1736 +f 1792 37 1793 +f 1736 1793 1417 +f 1792 1793 1736 +f 37 1792 1795 +f 1792 393 1794 +f 1795 1794 1306 +f 1792 1794 1795 +f 268 1796 1797 +f 1796 689 1742 +f 1797 1742 1027 +f 1796 1742 1797 +f 626 1798 1799 +f 1798 1343 1684 +f 1799 1684 1344 +f 1798 1684 1799 +f 208 1800 1729 +f 1800 626 1799 +f 1729 1799 1344 +f 1800 1799 1729 +f 626 1800 1801 +f 1800 208 1598 +f 1801 1598 739 +f 1800 1598 1801 +f 393 1599 1794 +f 1599 31 1802 +f 1794 1802 1306 +f 1599 1802 1794 +f 31 1685 1802 +f 1685 243 1803 +f 1802 1803 1306 +f 1685 1803 1802 +f 243 1687 1803 +f 1687 689 1804 +f 1803 1804 1306 +f 1687 1804 1803 +f 268 1797 1805 +f 1797 1027 1746 +f 1805 1746 1075 +f 1797 1746 1805 +f 661 1806 1745 +f 1806 141 1807 +f 1745 1807 935 +f 1806 1807 1745 +f 626 1801 1808 +f 1801 739 1749 +f 1808 1749 1162 +f 1801 1749 1808 +f 944 1809 1810 +f 1809 1051 1689 +f 1810 1689 1218 +f 1809 1689 1810 +f 898 1690 1812 +f 1690 1051 1811 +f 1812 1811 1251 +f 1690 1811 1812 +f 221 1813 1814 +f 1813 124 1693 +f 1814 1693 1143 +f 1813 1693 1814 +f 175 1815 1816 +f 1815 124 1813 +f 1816 1813 221 +f 1815 1813 1816 +f 124 1815 1696 +f 1815 175 1817 +f 1696 1817 1042 +f 1815 1817 1696 +f 1042 1817 1819 +f 1817 175 1818 +f 1819 1818 1328 +f 1817 1818 1819 +f 233 1820 1821 +f 1820 944 1810 +f 1821 1810 1218 +f 1820 1810 1821 +f 19 1750 1822 +f 1750 898 1812 +f 1822 1812 1251 +f 1750 1812 1822 +f 384 1752 1823 +f 1752 1042 1819 +f 1823 1819 1328 +f 1752 1819 1823 +f 397 1824 1825 +f 1824 233 1821 +f 1825 1821 1218 +f 1824 1821 1825 +f 710 1826 1700 +f 1826 397 1825 +f 1700 1825 1218 +f 1826 1825 1700 +f 932 1751 1828 +f 1751 19 1827 +f 1828 1827 1239 +f 1751 1827 1828 +f 982 1829 1830 +f 1829 384 1823 +f 1830 1823 1328 +f 1829 1823 1830 +f 166 1831 1761 +f 1831 675 1832 +f 1761 1832 1262 +f 1831 1832 1761 +f 1262 1833 1762 +f 1833 1346 1785 +f 1762 1785 1488 +f 1833 1785 1762 +f 1262 1834 1833 +f 1834 1177 1835 +f 1833 1835 1346 +f 1834 1835 1833 +f 397 1826 1837 +f 1826 710 1836 +f 1837 1836 1018 +f 1826 1836 1837 +f 932 1828 1711 +f 1828 1239 1838 +f 1711 1838 1497 +f 1828 1838 1711 +f 344 1839 1840 +f 1839 323 1705 +f 1840 1705 1449 +f 1839 1705 1840 +f 59 1841 1843 +f 1841 1149 1842 +f 1843 1842 1375 +f 1841 1842 1843 +f 59 1843 1713 +f 1843 1375 1844 +f 1713 1844 1449 +f 1843 1844 1713 +f 384 1829 1846 +f 1829 982 1845 +f 1846 1845 1149 +f 1829 1845 1846 +f 59 1707 1841 +f 1707 384 1846 +f 1841 1846 1149 +f 1707 1846 1841 +f 862 1847 1848 +f 1847 1009 1715 +f 1848 1715 1407 +f 1847 1715 1848 +f 23 1849 1850 +f 1849 433 1622 +f 1850 1622 831 +f 1849 1622 1850 +f 433 1849 1753 +f 1849 23 1851 +f 1753 1851 568 +f 1849 1851 1753 +f 117 1758 1853 +f 1758 536 1852 +f 1853 1852 675 +f 1758 1852 1853 +f 1177 1854 1835 +f 1854 880 1770 +f 1835 1770 1346 +f 1854 1770 1835 +f 1071 1649 1855 +f 1649 880 1854 +f 1855 1854 1177 +f 1649 1854 1855 +f 1018 1836 1856 +f 1836 710 1712 +f 1856 1712 1497 +f 1836 1712 1856 +f 1156 1857 1858 +f 1857 554 1778 +f 1858 1778 1193 +f 1857 1778 1858 +f 1156 1859 1861 +f 1859 570 1860 +f 1861 1860 1407 +f 1859 1860 1861 +f 862 1862 1847 +f 1862 303 1710 +f 1847 1710 1009 +f 1862 1710 1847 +f 303 1862 1864 +f 1862 862 1863 +f 1864 1863 923 +f 1862 1863 1864 +f 23 1850 1865 +f 1850 831 1633 +f 1865 1633 1473 +f 1850 1633 1865 +f 117 1853 1719 +f 1853 675 1866 +f 1719 1866 1106 +f 1853 1866 1719 +f 675 1831 1866 +f 1831 166 1867 +f 1866 1867 1106 +f 1831 1867 1866 +f 1106 1867 1722 +f 1867 166 1767 +f 1722 1767 1417 +f 1867 1767 1722 +f 318 1733 1869 +f 1733 554 1868 +f 1869 1868 1483 +f 1733 1868 1869 +f 554 1857 1868 +f 1857 1156 1870 +f 1868 1870 1483 +f 1857 1870 1868 +f 1156 1861 1870 +f 1861 1407 1781 +f 1870 1781 1483 +f 1861 1781 1870 +f 427 1734 1872 +f 1734 144 1871 +f 1872 1871 923 +f 1734 1871 1872 +f 144 1721 1871 +f 1721 303 1864 +f 1871 1864 923 +f 1721 1864 1871 +f 427 1873 1735 +f 1873 295 1791 +f 1735 1791 962 +f 1873 1791 1735 +f 290 1784 1875 +f 1784 394 1874 +f 1875 1874 846 +f 1784 1874 1875 +f 394 1660 1874 +f 1660 645 1876 +f 1874 1876 846 +f 1660 1876 1874 +f 846 1876 1877 +f 1876 645 1723 +f 1877 1723 1417 +f 1876 1723 1877 +f 1428 1739 1878 +f 1739 318 1869 +f 1878 1869 1483 +f 1739 1869 1878 +f 689 1796 1804 +f 1796 268 1879 +f 1804 1879 1306 +f 1796 1879 1804 +f 661 1610 1881 +f 1610 1343 1880 +f 1881 1880 1410 +f 1610 1880 1881 +f 1141 1882 1747 +f 1882 26 1883 +f 1747 1883 1162 +f 1882 1883 1747 +f 1142 1884 1886 +f 1884 991 1885 +f 1886 1885 1319 +f 1884 1885 1886 +f 1051 1809 1888 +f 1809 944 1887 +f 1888 1887 1415 +f 1809 1887 1888 +f 1251 1811 1889 +f 1811 1051 1888 +f 1889 1888 1415 +f 1811 1888 1889 +f 625 1890 1891 +f 1890 19 1822 +f 1891 1822 1251 +f 1890 1822 1891 +f 271 1892 1893 +f 1892 221 1814 +f 1893 1814 1143 +f 1892 1814 1893 +f 1193 1894 1896 +f 1894 787 1895 +f 1896 1895 1302 +f 1894 1895 1896 +f 675 1897 1832 +f 1897 1147 1898 +f 1832 1898 1262 +f 1897 1898 1832 +f 1177 1834 1900 +f 1834 1262 1899 +f 1900 1899 1383 +f 1834 1899 1900 +f 656 1901 1902 +f 1901 1177 1900 +f 1902 1900 1383 +f 1901 1900 1902 +f 19 1890 1827 +f 1890 625 1903 +f 1827 1903 1239 +f 1890 1903 1827 +f 787 1894 1904 +f 1894 1193 1765 +f 1904 1765 1272 +f 1894 1765 1904 +f 1156 1858 1905 +f 1858 1193 1896 +f 1905 1896 1302 +f 1858 1896 1905 +f 656 1906 1901 +f 1906 311 1907 +f 1901 1907 1177 +f 1906 1907 1901 +f 3 1908 1910 +f 1908 343 1909 +f 1910 1909 1404 +f 1908 1909 1910 +f 343 1908 1774 +f 1908 3 1911 +f 1774 1911 1272 +f 1908 1911 1774 +f 3 1912 1911 +f 1912 787 1904 +f 1911 1904 1272 +f 1912 1904 1911 +f 536 1913 1852 +f 1913 181 1914 +f 1852 1914 675 +f 1913 1914 1852 +f 181 1913 1915 +f 1913 536 1755 +f 1915 1755 568 +f 1913 1755 1915 +f 966 1786 1916 +f 1786 1071 1855 +f 1916 1855 1177 +f 1786 1855 1916 +f 1375 1917 1844 +f 1917 87 1918 +f 1844 1918 1449 +f 1917 1918 1844 +f 87 1919 1918 +f 1919 344 1840 +f 1918 1840 1449 +f 1919 1840 1918 +f 570 1920 1860 +f 1920 862 1848 +f 1860 1848 1407 +f 1920 1848 1860 +f 923 1863 1922 +f 1863 862 1921 +f 1922 1921 1463 +f 1863 1921 1922 +f 343 1773 1909 +f 1773 1055 1923 +f 1909 1923 1404 +f 1773 1923 1909 +f 29 1924 1677 +f 1924 167 1925 +f 1677 1925 1055 +f 1924 1925 1677 +f 167 1924 1926 +f 1924 29 1678 +f 1926 1678 935 +f 1924 1678 1926 +f 514 1927 1788 +f 1927 1428 1878 +f 1788 1878 1483 +f 1927 1878 1788 +f 37 1928 1793 +f 1928 846 1877 +f 1793 1877 1417 +f 1928 1877 1793 +f 514 1790 1927 +f 1790 295 1929 +f 1927 1929 1428 +f 1790 1929 1927 +f 240 1930 1931 +f 1930 268 1805 +f 1931 1805 1075 +f 1930 1805 1931 +f 300 1932 1743 +f 1932 50 1933 +f 1743 1933 1075 +f 1932 1933 1743 +f 1343 1798 1880 +f 1798 626 1934 +f 1880 1934 1410 +f 1798 1934 1880 +f 268 1930 1879 +f 1930 240 1935 +f 1879 1935 1306 +f 1930 1935 1879 +f 141 1806 1936 +f 1806 661 1881 +f 1936 1881 1410 +f 1806 1881 1936 +f 626 1808 1934 +f 1808 1162 1937 +f 1934 1937 1410 +f 1808 1937 1934 +f 27 1938 1940 +f 1938 676 1939 +f 1940 1939 1225 +f 1938 1939 1940 +f 676 1941 1939 +f 1941 440 1942 +f 1939 1942 1225 +f 1941 1942 1939 +f 1189 1943 1944 +f 1943 27 1940 +f 1944 1940 1225 +f 1943 1940 1944 +f 365 1945 1947 +f 1945 1037 1946 +f 1947 1946 1169 +f 1945 1946 1947 +f 365 1948 1945 +f 1948 1029 1949 +f 1945 1949 1037 +f 1948 1949 1945 +f 27 1950 1938 +f 1950 139 1951 +f 1938 1951 676 +f 1950 1951 1938 +f 1037 1952 1946 +f 1952 744 1953 +f 1946 1953 1169 +f 1952 1953 1946 +f 752 1954 1956 +f 1954 253 1955 +f 1956 1955 1319 +f 1954 1955 1956 +f 1319 1955 1958 +f 1955 253 1957 +f 1958 1957 1467 +f 1955 1957 1958 +f 991 1959 1885 +f 1959 752 1956 +f 1885 1956 1319 +f 1959 1956 1885 +f 752 1959 1961 +f 1959 991 1960 +f 1961 1960 1258 +f 1959 1960 1961 +f 355 1962 1963 +f 1962 1319 1958 +f 1963 1958 1467 +f 1962 1958 1963 +f 355 1964 1962 +f 1964 1142 1886 +f 1962 1886 1319 +f 1964 1886 1962 +f 355 1965 1964 +f 1965 659 1966 +f 1964 1966 1142 +f 1965 1966 1964 +f 991 1967 1969 +f 1967 858 1968 +f 1969 1968 1069 +f 1967 1968 1969 +f 858 1967 1970 +f 1967 991 1884 +f 1970 1884 1142 +f 1967 1884 1970 +f 659 1971 1966 +f 1971 858 1970 +f 1966 1970 1142 +f 1971 1970 1966 +f 175 1972 1818 +f 1972 1314 1973 +f 1818 1973 1328 +f 1972 1973 1818 +f 175 1816 1972 +f 1816 221 1974 +f 1972 1974 1314 +f 1816 1974 1972 +f 1262 1898 1899 +f 1898 1147 1975 +f 1899 1975 1383 +f 1898 1975 1899 +f 625 1891 1976 +f 1891 1251 1889 +f 1976 1889 1415 +f 1891 1889 1976 +f 1328 1977 1979 +f 1977 1166 1978 +f 1979 1978 1379 +f 1977 1978 1979 +f 787 1912 1981 +f 1912 3 1980 +f 1981 1980 1379 +f 1912 1980 1981 +f 233 1982 1820 +f 1982 656 1983 +f 1820 1983 944 +f 1982 1983 1820 +f 881 1984 1985 +f 1984 271 1893 +f 1985 1893 1143 +f 1984 1893 1985 +f 323 1986 1703 +f 1986 881 1985 +f 1703 1985 1143 +f 1986 1985 1703 +f 982 1830 1987 +f 1830 1328 1979 +f 1987 1979 1379 +f 1830 1979 1987 +f 1283 1988 1989 +f 1988 1156 1905 +f 1989 1905 1302 +f 1988 1905 1989 +f 1156 1988 1991 +f 1988 1283 1990 +f 1991 1990 1463 +f 1988 1990 1991 +f 233 1992 1982 +f 1992 311 1906 +f 1982 1906 656 +f 1992 1906 1982 +f 311 1992 1993 +f 1992 233 1824 +f 1993 1824 397 +f 1992 1824 1993 +f 1239 1994 1838 +f 1994 129 1995 +f 1838 1995 1497 +f 1994 1995 1838 +f 982 1987 1997 +f 1987 1379 1996 +f 1997 1996 1404 +f 1987 1996 1997 +f 1379 1980 1996 +f 1980 3 1910 +f 1996 1910 1404 +f 1980 1910 1996 +f 570 1859 1998 +f 1859 1156 1991 +f 1998 1991 1463 +f 1859 1991 1998 +f 568 1851 2000 +f 1851 23 1999 +f 2000 1999 650 +f 1851 1999 2000 +f 181 1915 2001 +f 1915 568 2000 +f 2001 2000 650 +f 1915 2000 2001 +f 1093 2002 2003 +f 2002 966 1916 +f 2003 1916 1177 +f 2002 1916 2003 +f 311 2004 1907 +f 2004 1093 2003 +f 1907 2003 1177 +f 2004 2003 1907 +f 311 1993 2004 +f 1993 397 2005 +f 2004 2005 1093 +f 1993 2005 2004 +f 323 1839 1986 +f 1839 344 2006 +f 1986 2006 881 +f 1839 2006 1986 +f 1149 1845 2007 +f 1845 982 1997 +f 2007 1997 1404 +f 1845 1997 2007 +f 1375 1842 2008 +f 1842 1149 2007 +f 2008 2007 1404 +f 1842 2007 2008 +f 862 1920 1921 +f 1920 570 1998 +f 1921 1998 1463 +f 1920 1998 1921 +f 397 1837 2005 +f 1837 1018 2009 +f 2005 2009 1093 +f 1837 2009 2005 +f 1199 2010 2012 +f 2010 967 2011 +f 2012 2011 1473 +f 2010 2011 2012 +f 290 2013 1783 +f 2013 1199 2012 +f 1783 2012 1473 +f 2013 2012 1783 +f 1055 1925 1923 +f 1925 167 2014 +f 1923 2014 1404 +f 1925 2014 1923 +f 167 2015 2014 +f 2015 870 2016 +f 2014 2016 1404 +f 2015 2016 2014 +f 45 2017 2019 +f 2017 427 2018 +f 2019 2018 1254 +f 2017 2018 2019 +f 45 2020 2017 +f 2020 295 1873 +f 2017 1873 427 +f 2020 1873 2017 +f 50 1932 2022 +f 1932 300 2021 +f 2022 2021 1217 +f 1932 2021 2022 +f 300 1789 2021 +f 1789 966 2023 +f 2021 2023 1217 +f 1789 2023 2021 +f 781 2024 2025 +f 2024 167 1926 +f 2025 1926 935 +f 2024 1926 2025 +f 50 2026 1933 +f 2026 653 2027 +f 1933 2027 1075 +f 2026 2027 1933 +f 141 2028 2030 +f 2028 328 2029 +f 2030 2029 781 +f 2028 2029 2030 +f 141 2030 1807 +f 2030 781 2025 +f 1807 2025 935 +f 2030 2025 1807 +f 1162 1883 1937 +f 1883 26 2031 +f 1937 2031 1410 +f 1883 2031 1937 +f 275 2032 2034 +f 2032 756 2033 +f 2034 2033 1041 +f 2032 2033 2034 +f 591 2035 2037 +f 2035 505 2036 +f 2037 2036 1041 +f 2035 2036 2037 +f 756 2038 2033 +f 2038 591 2037 +f 2033 2037 1041 +f 2038 2037 2033 +f 591 2038 2040 +f 2038 756 2039 +f 2040 2039 1464 +f 2038 2039 2040 +f 505 2041 2036 +f 2041 638 2042 +f 2036 2042 1041 +f 2041 2042 2036 +f 505 2035 2044 +f 2035 591 2043 +f 2044 2043 830 +f 2035 2043 2044 +f 440 2045 1942 +f 2045 214 2046 +f 1942 2046 1225 +f 2045 2046 1942 +f 1029 1948 2048 +f 1948 365 2047 +f 2048 2047 1097 +f 1948 2047 2048 +f 1029 2048 2050 +f 2048 1097 2049 +f 2050 2049 1401 +f 2048 2049 2050 +f 429 2051 2053 +f 2051 474 2052 +f 2053 2052 1351 +f 2051 2052 2053 +f 241 2054 2055 +f 2054 429 2053 +f 2055 2053 1351 +f 2054 2053 2055 +f 524 2056 2057 +f 2056 365 1947 +f 2057 1947 1169 +f 2056 1947 2057 +f 1029 2058 1949 +f 2058 947 2059 +f 1949 2059 1037 +f 2058 2059 1949 +f 223 2060 2062 +f 2060 450 2061 +f 2062 2061 1432 +f 2060 2061 2062 +f 690 2063 2064 +f 2063 223 2062 +f 2064 2062 1432 +f 2063 2062 2064 +f 1039 2065 2066 +f 2065 241 2055 +f 2066 2055 1351 +f 2065 2055 2066 +f 632 2067 2068 +f 2067 1039 2066 +f 2068 2066 1351 +f 2067 2066 2068 +f 139 2069 1951 +f 2069 632 2070 +f 1951 2070 676 +f 2069 2070 1951 +f 495 2071 2072 +f 2071 27 1943 +f 2072 1943 1189 +f 2071 1943 2072 +f 504 2073 2074 +f 2073 495 2072 +f 2074 2072 1189 +f 2073 2072 2074 +f 391 2075 2076 +f 2075 524 2057 +f 2076 2057 1169 +f 2075 2057 2076 +f 450 2077 2061 +f 2077 201 2078 +f 2061 2078 1432 +f 2077 2078 2061 +f 632 2079 2081 +f 2079 68 2080 +f 2081 2080 1406 +f 2079 2080 2081 +f 139 2082 2069 +f 2082 68 2079 +f 2069 2079 632 +f 2082 2079 2069 +f 139 1950 2083 +f 1950 27 2071 +f 2083 2071 495 +f 1950 2071 2083 +f 139 2083 2085 +f 2083 495 2084 +f 2085 2084 1072 +f 2083 2084 2085 +f 792 2086 2087 +f 2086 744 1952 +f 2087 1952 1037 +f 2086 1952 2087 +f 947 2088 2059 +f 2088 792 2087 +f 2059 2087 1037 +f 2088 2087 2059 +f 36 2089 2090 +f 2089 744 2086 +f 2090 2086 792 +f 2089 2086 2090 +f 68 2082 2091 +f 2082 139 2085 +f 2091 2085 1072 +f 2082 2085 2091 +f 744 2092 1953 +f 2092 902 2093 +f 1953 2093 1169 +f 2092 2093 1953 +f 744 2094 2092 +f 2094 805 2095 +f 2092 2095 902 +f 2094 2095 2092 +f 253 1954 2097 +f 1954 752 2096 +f 2097 2096 1260 +f 1954 2096 2097 +f 802 2098 2099 +f 2098 752 1961 +f 2099 1961 1258 +f 2098 1961 2099 +f 253 2100 1957 +f 2100 345 2101 +f 1957 2101 1467 +f 2100 2101 1957 +f 1220 2102 2103 +f 2102 802 2099 +f 2103 2099 1258 +f 2102 2099 2103 +f 1387 2104 2105 +f 2104 355 1963 +f 2105 1963 1467 +f 2104 1963 2105 +f 657 2106 2107 +f 2106 1220 2103 +f 2107 2103 1258 +f 2106 2103 2107 +f 991 2108 1960 +f 2108 657 2107 +f 1960 2107 1258 +f 2108 2107 1960 +f 659 1965 2110 +f 1965 355 2109 +f 2110 2109 1339 +f 1965 2109 2110 +f 71 2111 2113 +f 2111 657 2112 +f 2113 2112 1069 +f 2111 2112 2113 +f 657 2108 2112 +f 2108 991 1969 +f 2112 1969 1069 +f 2108 1969 2112 +f 944 2114 1887 +f 2114 244 2115 +f 1887 2115 1415 +f 2114 2115 1887 +f 1314 2116 1973 +f 2116 1166 1977 +f 1973 1977 1328 +f 2116 1977 1973 +f 1166 2117 1978 +f 2117 787 1981 +f 1978 1981 1379 +f 2117 1981 1978 +f 274 2118 2119 +f 2118 181 2001 +f 2119 2001 650 +f 2118 2001 2119 +f 675 2120 1897 +f 2120 274 2121 +f 1897 2121 1147 +f 2120 2121 1897 +f 181 2118 1914 +f 2118 274 2120 +f 1914 2120 675 +f 2118 2120 1914 +f 656 2122 1983 +f 2122 244 2114 +f 1983 2114 944 +f 2122 2114 1983 +f 23 2123 1999 +f 2123 277 2124 +f 1999 2124 650 +f 2123 2124 1999 +f 1018 2125 2127 +f 2125 1217 2126 +f 2127 2126 1226 +f 2125 2126 2127 +f 1217 2125 2128 +f 2125 1018 1856 +f 2128 1856 1497 +f 2125 1856 2128 +f 870 2129 2016 +f 2129 1375 2008 +f 2016 2008 1404 +f 2129 2008 2016 +f 1219 2130 2131 +f 2130 923 1922 +f 2131 1922 1463 +f 2130 1922 2131 +f 277 2123 2132 +f 2123 23 1865 +f 2132 1865 1473 +f 2123 1865 2132 +f 1093 2009 2133 +f 2009 1018 2127 +f 2133 2127 1226 +f 2009 2127 2133 +f 870 2134 2129 +f 2134 87 1917 +f 2129 1917 1375 +f 2134 1917 2129 +f 966 2002 2135 +f 2002 1093 2133 +f 2135 2133 1226 +f 2002 2133 2135 +f 290 1875 2013 +f 1875 846 2136 +f 2013 2136 1199 +f 1875 2136 2013 +f 295 2020 1929 +f 2020 45 2137 +f 1929 2137 1428 +f 2020 2137 1929 +f 846 1928 2138 +f 1928 37 1795 +f 2138 1795 1306 +f 1928 1795 2138 +f 1199 2136 2139 +f 2136 846 2138 +f 2139 2138 1306 +f 2136 2138 2139 +f 26 1882 2140 +f 1882 1141 1741 +f 2140 1741 1428 +f 1882 1741 2140 +f 756 2032 2142 +f 2032 275 2141 +f 2142 2141 1178 +f 2032 2141 2142 +f 16 2143 2145 +f 2143 249 2144 +f 2145 2144 1041 +f 2143 2144 2145 +f 249 2146 2144 +f 2146 275 2034 +f 2144 2034 1041 +f 2146 2034 2144 +f 756 2147 2039 +f 2147 969 2148 +f 2039 2148 1464 +f 2147 2148 2039 +f 969 2147 2149 +f 2147 756 2142 +f 2149 2142 1178 +f 2147 2142 2149 +f 638 2150 2042 +f 2150 965 2151 +f 2042 2151 1041 +f 2150 2151 2042 +f 965 2152 2151 +f 2152 16 2145 +f 2151 2145 1041 +f 2152 2145 2151 +f 969 2153 2148 +f 2153 1393 2154 +f 2148 2154 1464 +f 2153 2154 2148 +f 1393 2155 2154 +f 2155 1056 2156 +f 2154 2156 1464 +f 2155 2156 2154 +f 1056 2157 2156 +f 2157 204 2158 +f 2156 2158 1464 +f 2157 2158 2156 +f 638 2041 2160 +f 2041 505 2159 +f 2160 2159 959 +f 2041 2159 2160 +f 505 2044 2159 +f 2044 830 2161 +f 2159 2161 959 +f 2044 2161 2159 +f 591 2162 2043 +f 2162 204 2163 +f 2043 2163 830 +f 2162 2163 2043 +f 204 2162 2158 +f 2162 591 2040 +f 2158 2040 1464 +f 2162 2040 2158 +f 214 2164 2046 +f 2164 1139 2165 +f 2046 2165 1225 +f 2164 2165 2046 +f 1225 2165 2167 +f 2165 1139 2166 +f 2167 2166 1419 +f 2165 2166 2167 +f 1367 2168 2169 +f 2168 1029 2050 +f 2169 2050 1401 +f 2168 2050 2169 +f 429 2170 2051 +f 2170 356 2171 +f 2051 2171 474 +f 2170 2171 2051 +f 474 2172 2174 +f 2172 773 2173 +f 2174 2173 1442 +f 2172 2173 2174 +f 1189 1944 2175 +f 1944 1225 2167 +f 2175 2167 1419 +f 1944 2167 2175 +f 1124 2176 2178 +f 2176 109 2177 +f 2178 2177 1432 +f 2176 2177 2178 +f 109 2179 2177 +f 2179 690 2064 +f 2177 2064 1432 +f 2179 2064 2177 +f 172 2180 2181 +f 2180 356 2170 +f 2181 2170 429 +f 2180 2170 2181 +f 474 2182 2052 +f 2182 730 2183 +f 2052 2183 1351 +f 2182 2183 2052 +f 730 2182 2184 +f 2182 474 2174 +f 2184 2174 1442 +f 2182 2174 2184 +f 440 1941 2186 +f 1941 676 2185 +f 2186 2185 730 +f 1941 2185 2186 +f 365 2056 2047 +f 2056 524 2187 +f 2047 2187 1097 +f 2056 2187 2047 +f 1124 2188 2189 +f 2188 1029 2168 +f 2189 2168 1367 +f 2188 2168 2189 +f 241 2190 2054 +f 2190 172 2181 +f 2054 2181 429 +f 2190 2181 2054 +f 730 2191 2183 +f 2191 632 2068 +f 2183 2068 1351 +f 2191 2068 2183 +f 676 2070 2185 +f 2070 632 2191 +f 2185 2191 730 +f 2070 2191 2185 +f 947 2058 2192 +f 2058 1029 2188 +f 2192 2188 1124 +f 2058 2188 2192 +f 201 2193 2078 +f 2193 947 2194 +f 2078 2194 1432 +f 2193 2194 2078 +f 947 2192 2194 +f 2192 1124 2178 +f 2194 2178 1432 +f 2192 2178 2194 +f 495 2073 2196 +f 2073 504 2195 +f 2196 2195 1031 +f 2073 2195 2196 +f 524 2075 2198 +f 2075 391 2197 +f 2198 2197 1063 +f 2075 2197 2198 +f 201 2199 2193 +f 2199 792 2088 +f 2193 2088 947 +f 2199 2088 2193 +f 201 2200 2199 +f 2200 512 2201 +f 2199 2201 792 +f 2200 2201 2199 +f 201 2077 2200 +f 2077 450 2202 +f 2200 2202 512 +f 2077 2202 2200 +f 495 2196 2084 +f 2196 1031 2203 +f 2084 2203 1072 +f 2196 2203 2084 +f 1031 2204 2203 +f 2204 485 2205 +f 2203 2205 1072 +f 2204 2205 2203 +f 902 2206 2093 +f 2206 391 2076 +f 2093 2076 1169 +f 2206 2076 2093 +f 744 2089 2094 +f 2089 36 2207 +f 2094 2207 805 +f 2089 2207 2094 +f 666 2208 2209 +f 2208 253 2097 +f 2209 2097 1260 +f 2208 2097 2209 +f 752 2210 2096 +f 2210 595 2211 +f 2096 2211 1260 +f 2210 2211 2096 +f 595 2210 2212 +f 2210 752 2098 +f 2212 2098 802 +f 2210 2098 2212 +f 345 2100 2213 +f 2100 253 2208 +f 2213 2208 666 +f 2100 2208 2213 +f 1220 2106 2215 +f 2106 657 2214 +f 2215 2214 1459 +f 2106 2214 2215 +f 1339 2109 2216 +f 2109 355 2104 +f 2216 2104 1387 +f 2109 2104 2216 +f 858 1971 2218 +f 1971 659 2217 +f 2218 2217 1308 +f 1971 2217 2218 +f 192 2219 2221 +f 2219 390 2220 +f 2221 2220 1147 +f 2219 2220 2221 +f 1147 2220 1975 +f 2220 390 2222 +f 1975 2222 1383 +f 2220 2222 1975 +f 145 2223 2224 +f 2223 1283 1989 +f 2224 1989 1302 +f 2223 1989 2224 +f 876 2225 2227 +f 2225 656 2226 +f 2227 2226 1179 +f 2225 2226 2227 +f 1179 2226 2228 +f 2226 656 1902 +f 2228 1902 1383 +f 2226 1902 2228 +f 74 2229 2230 +f 2229 1166 2116 +f 2230 2116 1314 +f 2229 2116 2230 +f 74 2231 2229 +f 2231 787 2117 +f 2229 2117 1166 +f 2231 2117 2229 +f 453 2232 2233 +f 2232 625 1976 +f 2233 1976 1415 +f 2232 1976 2233 +f 221 1892 2235 +f 1892 271 2234 +f 2235 2234 891 +f 1892 2234 2235 +f 129 2236 1995 +f 2236 1217 2128 +f 1995 2128 1497 +f 2236 2128 1995 +f 967 2237 2011 +f 2237 277 2132 +f 2011 2132 1473 +f 2237 2132 2011 +f 344 2238 2006 +f 2238 260 2239 +f 2006 2239 881 +f 2238 2239 2006 +f 87 2240 1919 +f 2240 260 2238 +f 1919 2238 344 +f 2240 2238 1919 +f 260 2240 2241 +f 2240 87 2134 +f 2241 2134 870 +f 2240 2134 2241 +f 427 1872 2018 +f 1872 923 2242 +f 2018 2242 1254 +f 1872 2242 2018 +f 923 2130 2242 +f 2130 1219 2243 +f 2242 2243 1254 +f 2130 2243 2242 +f 1217 2023 2126 +f 2023 966 2135 +f 2126 2135 1226 +f 2023 2135 2126 +f 781 2244 2245 +f 2244 260 2241 +f 2245 2241 870 +f 2244 2241 2245 +f 167 2024 2015 +f 2024 781 2245 +f 2015 2245 870 +f 2024 2245 2015 +f 45 2246 2137 +f 2246 1163 2247 +f 2137 2247 1428 +f 2246 2247 2137 +f 1163 2248 2247 +f 2248 26 2140 +f 2247 2140 1428 +f 2248 2140 2247 +f 646 2249 2251 +f 2249 240 2250 +f 2251 2250 653 +f 2249 2250 2251 +f 653 2250 2027 +f 2250 240 1931 +f 2027 1931 1075 +f 2250 1931 2027 +f 328 2028 2252 +f 2028 141 1936 +f 2252 1936 1410 +f 2028 1936 2252 +f 26 2248 2254 +f 2248 1163 2253 +f 2254 2253 1400 +f 2248 2253 2254 +f 509 2255 2257 +f 2255 294 2256 +f 2257 2256 865 +f 2255 2256 2257 +f 457 2258 2260 +f 2258 294 2259 +f 2260 2259 1268 +f 2258 2259 2260 +f 294 2258 2256 +f 2258 457 2261 +f 2256 2261 865 +f 2258 2261 2256 +f 457 2262 2264 +f 2262 883 2263 +f 2264 2263 1019 +f 2262 2263 2264 +f 865 2261 2265 +f 2261 457 2264 +f 2265 2264 1019 +f 2261 2264 2265 +f 883 2262 2266 +f 2262 457 2260 +f 2266 2260 1268 +f 2262 2260 2266 +f 377 2267 2268 +f 2267 883 2266 +f 2268 2266 1268 +f 2267 2266 2268 +f 883 2269 2263 +f 2269 329 2270 +f 2263 2270 1019 +f 2269 2270 2263 +f 275 2146 2141 +f 2146 249 2271 +f 2141 2271 1178 +f 2146 2271 2141 +f 249 2272 2271 +f 2272 176 2273 +f 2271 2273 1178 +f 2272 2273 2271 +f 249 2143 2274 +f 2143 16 2152 +f 2274 2152 965 +f 2143 2152 2274 +f 638 2275 2150 +f 2275 549 2276 +f 2150 2276 965 +f 2275 2276 2150 +f 508 2277 2278 +f 2277 638 2160 +f 2278 2160 959 +f 2277 2160 2278 +f 830 2163 2279 +f 2163 204 2157 +f 2279 2157 1056 +f 2163 2157 2279 +f 191 2280 2282 +f 2280 94 2281 +f 2282 2281 1113 +f 2280 2281 2282 +f 94 2280 2284 +f 2280 191 2283 +f 2284 2283 1214 +f 2280 2283 2284 +f 474 2171 2172 +f 2171 356 2285 +f 2172 2285 773 +f 2171 2285 2172 +f 65 2286 2288 +f 2286 214 2287 +f 2288 2287 1442 +f 2286 2287 2288 +f 214 2045 2287 +f 2045 440 2289 +f 2287 2289 1442 +f 2045 2289 2287 +f 690 2179 2291 +f 2179 109 2290 +f 2291 2290 1171 +f 2179 2290 2291 +f 440 2186 2289 +f 2186 730 2184 +f 2289 2184 1442 +f 2186 2184 2289 +f 999 2292 2293 +f 2292 1189 2175 +f 2293 2175 1419 +f 2292 2175 2293 +f 1097 2187 2295 +f 2187 524 2294 +f 2295 2294 1285 +f 2187 2294 2295 +f 109 2176 2296 +f 2176 1124 2189 +f 2296 2189 1367 +f 2176 2189 2296 +f 690 2297 2299 +f 2297 683 2298 +f 2299 2298 834 +f 2297 2298 2299 +f 683 2297 2300 +f 2297 690 2291 +f 2300 2291 1171 +f 2297 2291 2300 +f 999 2301 2292 +f 2301 652 2302 +f 2292 2302 1189 +f 2301 2302 2292 +f 223 2063 2303 +f 2063 690 2299 +f 2303 2299 834 +f 2063 2299 2303 +f 573 2304 2305 +f 2304 223 2303 +f 2305 2303 834 +f 2304 2303 2305 +f 652 2306 2302 +f 2306 504 2074 +f 2302 2074 1189 +f 2306 2074 2302 +f 450 2060 2307 +f 2060 223 2304 +f 2307 2304 573 +f 2060 2304 2307 +f 943 2308 2309 +f 2308 241 2065 +f 2309 2065 1039 +f 2308 2065 2309 +f 1039 2067 2310 +f 2067 632 2081 +f 2310 2081 1406 +f 2067 2081 2310 +f 512 2311 2201 +f 2311 445 2312 +f 2201 2312 792 +f 2311 2312 2201 +f 450 2313 2202 +f 2313 247 2314 +f 2202 2314 512 +f 2313 2314 2202 +f 1184 2315 2316 +f 2315 1387 2105 +f 2316 2105 1467 +f 2315 2105 2316 +f 71 2317 2111 +f 2317 347 2318 +f 2111 2318 657 +f 2317 2318 2111 +f 170 2319 2321 +f 2319 426 2320 +f 2321 2320 1387 +f 2319 2320 2321 +f 426 2322 2320 +f 2322 1339 2216 +f 2320 2216 1387 +f 2322 2216 2320 +f 1308 2217 2323 +f 2217 659 2110 +f 2323 2110 1339 +f 2217 2110 2323 +f 390 2324 2222 +f 2324 1179 2228 +f 2222 2228 1383 +f 2324 2228 2222 +f 787 2325 1895 +f 2325 1243 2326 +f 1895 2326 1302 +f 2325 2326 1895 +f 244 2122 2327 +f 2122 656 2225 +f 2327 2225 876 +f 2122 2225 2327 +f 244 2327 2115 +f 2327 876 2328 +f 2115 2328 1415 +f 2327 2328 2115 +f 221 2235 1974 +f 2235 891 2329 +f 1974 2329 1314 +f 2235 2329 1974 +f 1283 2330 1990 +f 2330 266 2331 +f 1990 2331 1463 +f 2330 2331 1990 +f 274 2119 2333 +f 2119 650 2332 +f 2333 2332 1129 +f 2119 2332 2333 +f 271 2334 2234 +f 2334 84 2335 +f 2234 2335 891 +f 2334 2335 2234 +f 271 1984 2337 +f 1984 881 2336 +f 2337 2336 1110 +f 1984 2336 2337 +f 650 2124 2332 +f 2124 277 2338 +f 2332 2338 1129 +f 2124 2338 2332 +f 129 2339 2236 +f 2339 273 2340 +f 2236 2340 1217 +f 2339 2340 2236 +f 273 2341 2340 +f 2341 50 2022 +f 2340 2022 1217 +f 2341 2022 2340 +f 1163 2246 2342 +f 2246 45 2019 +f 2342 2019 1254 +f 2246 2019 2342 +f 1121 2343 2344 +f 2343 1199 2139 +f 2344 2139 1306 +f 2343 2139 2344 +f 458 2345 2346 +f 2345 1121 2344 +f 2346 2344 1306 +f 2345 2344 2346 +f 646 2347 2348 +f 2347 458 2346 +f 2348 2346 1306 +f 2347 2346 2348 +f 240 2249 1935 +f 2249 646 2348 +f 1935 2348 1306 +f 2249 2348 1935 +f 173 2349 2351 +f 2349 867 2350 +f 2351 2350 1268 +f 2349 2350 2351 +f 623 2352 2353 +f 2352 509 2257 +f 2353 2257 865 +f 2352 2257 2353 +f 867 2354 2350 +f 2354 377 2268 +f 2350 2268 1268 +f 2354 2268 2350 +f 372 2355 2356 +f 2355 623 2353 +f 2356 2353 865 +f 2355 2353 2356 +f 372 2356 2357 +f 2356 865 2265 +f 2357 2265 1019 +f 2356 2265 2357 +f 883 2267 2359 +f 2267 377 2358 +f 2359 2358 1170 +f 2267 2358 2359 +f 329 2269 2360 +f 2269 883 2359 +f 2360 2359 1170 +f 2269 2359 2360 +f 249 2274 2362 +f 2274 965 2361 +f 2362 2361 1279 +f 2274 2361 2362 +f 176 2272 2363 +f 2272 249 2362 +f 2363 2362 1279 +f 2272 2362 2363 +f 176 2364 2273 +f 2364 751 2365 +f 2273 2365 1178 +f 2364 2365 2273 +f 8 2366 2368 +f 2366 1154 2367 +f 2368 2367 1178 +f 2366 2367 2368 +f 1154 2369 2367 +f 2369 969 2149 +f 2367 2149 1178 +f 2369 2149 2367 +f 969 2370 2153 +f 2370 301 2371 +f 2153 2371 1393 +f 2370 2371 2153 +f 953 2372 2373 +f 2372 301 2370 +f 2373 2370 969 +f 2372 2370 2373 +f 1214 2374 2376 +f 2374 956 2375 +f 2376 2375 1215 +f 2374 2375 2376 +f 956 2377 2375 +f 2377 140 2378 +f 2375 2378 1215 +f 2377 2378 2375 +f 191 2379 2283 +f 2379 956 2374 +f 2283 2374 1214 +f 2379 2374 2283 +f 1109 2380 2381 +f 2380 191 2282 +f 2381 2282 1113 +f 2380 2282 2381 +f 1109 2381 2383 +f 2381 1113 2382 +f 2383 2382 1115 +f 2381 2382 2383 +f 1094 2384 2385 +f 2384 94 2284 +f 2385 2284 1214 +f 2384 2284 2385 +f 112 2386 2387 +f 2386 1094 2385 +f 2387 2385 1214 +f 2386 2385 2387 +f 1210 2388 2389 +f 2388 112 2387 +f 2389 2387 1214 +f 2388 2387 2389 +f 94 2384 2281 +f 2384 1094 2390 +f 2281 2390 1113 +f 2384 2390 2281 +f 112 2391 2386 +f 2391 424 2392 +f 2386 2392 1094 +f 2391 2392 2386 +f 1113 2390 2394 +f 2390 1094 2393 +f 2394 2393 1492 +f 2390 2393 2394 +f 214 2286 2164 +f 2286 65 2395 +f 2164 2395 1139 +f 2286 2395 2164 +f 1097 2396 2049 +f 2396 414 2397 +f 2049 2397 1401 +f 2396 2397 2049 +f 320 2398 2400 +f 2398 356 2399 +f 2400 2399 607 +f 2398 2399 2400 +f 356 2398 2285 +f 2398 320 2401 +f 2285 2401 773 +f 2398 2401 2285 +f 137 2402 2403 +f 2402 1097 2295 +f 2403 2295 1285 +f 2402 2295 2403 +f 137 2404 2402 +f 2404 414 2396 +f 2402 2396 1097 +f 2404 2396 2402 +f 1171 2290 2405 +f 2290 109 2296 +f 2405 2296 1367 +f 2290 2296 2405 +f 356 2180 2399 +f 2180 172 2406 +f 2399 2406 607 +f 2180 2406 2399 +f 524 2198 2294 +f 2198 1063 2407 +f 2294 2407 1285 +f 2198 2407 2294 +f 172 2190 2409 +f 2190 241 2408 +f 2409 2408 615 +f 2190 2408 2409 +f 615 2408 2410 +f 2408 241 2308 +f 2410 2308 943 +f 2408 2308 2410 +f 15 2411 2412 +f 2411 504 2306 +f 2412 2306 652 +f 2411 2306 2412 +f 504 2411 2195 +f 2411 15 2413 +f 2195 2413 1031 +f 2411 2413 2195 +f 247 2313 2414 +f 2313 450 2307 +f 2414 2307 573 +f 2313 2307 2414 +f 247 2414 2416 +f 2414 573 2415 +f 2416 2415 1211 +f 2414 2415 2416 +f 68 2417 2080 +f 2417 212 2418 +f 2080 2418 1406 +f 2417 2418 2080 +f 391 2419 2197 +f 2419 14 2420 +f 2197 2420 1063 +f 2419 2420 2197 +f 14 2419 2421 +f 2419 391 2206 +f 2421 2206 902 +f 2419 2206 2421 +f 445 2422 2312 +f 2422 36 2090 +f 2312 2090 792 +f 2422 2090 2312 +f 445 2311 2424 +f 2311 512 2423 +f 2424 2423 1067 +f 2311 2423 2424 +f 212 2417 2425 +f 2417 68 2091 +f 2425 2091 1072 +f 2417 2091 2425 +f 485 2426 2205 +f 2426 1021 2427 +f 2205 2427 1072 +f 2426 2427 2205 +f 485 2204 2429 +f 2204 1031 2428 +f 2429 2428 1238 +f 2204 2428 2429 +f 36 2422 2207 +f 2422 445 2430 +f 2207 2430 805 +f 2422 2430 2207 +f 902 2095 2432 +f 2095 805 2431 +f 2432 2431 1431 +f 2095 2431 2432 +f 1260 2211 2434 +f 2211 595 2433 +f 2434 2433 1299 +f 2211 2433 2434 +f 555 2435 2436 +f 2435 1184 2316 +f 2436 2316 1467 +f 2435 2316 2436 +f 1184 2437 2315 +f 2437 170 2321 +f 2315 2321 1387 +f 2437 2321 2315 +f 657 2318 2214 +f 2318 347 2438 +f 2214 2438 1459 +f 2318 2438 2214 +f 852 2439 2440 +f 2439 71 2113 +f 2440 2113 1069 +f 2439 2113 2440 +f 1243 2441 2326 +f 2441 145 2224 +f 2326 2224 1302 +f 2441 2224 2326 +f 754 2442 2443 +f 2442 192 2221 +f 2443 2221 1147 +f 2442 2221 2443 +f 145 2444 2223 +f 2444 531 2445 +f 2223 2445 1283 +f 2444 2445 2223 +f 274 2446 2121 +f 2446 754 2443 +f 2121 2443 1147 +f 2446 2443 2121 +f 539 2447 2448 +f 2447 74 2230 +f 2448 2230 1314 +f 2447 2230 2448 +f 876 2449 2328 +f 2449 453 2233 +f 2328 2233 1415 +f 2449 2233 2328 +f 891 2450 2329 +f 2450 539 2448 +f 2329 2448 1314 +f 2450 2448 2329 +f 625 2451 1903 +f 2451 403 2452 +f 1903 2452 1239 +f 2451 2452 1903 +f 453 2453 2232 +f 2453 403 2451 +f 2232 2451 625 +f 2453 2451 2232 +f 273 2339 2455 +f 2339 129 2454 +f 2455 2454 794 +f 2339 2454 2455 +f 881 2239 2336 +f 2239 260 2456 +f 2336 2456 1110 +f 2239 2456 2336 +f 1121 2457 2343 +f 2457 967 2010 +f 2343 2010 1199 +f 2457 2010 2343 +f 50 2341 2026 +f 2341 273 2458 +f 2026 2458 653 +f 2341 2458 2026 +f 260 2244 2460 +f 2244 781 2459 +f 2460 2459 1026 +f 2244 2459 2460 +f 781 2029 2459 +f 2029 328 2461 +f 2459 2461 1026 +f 2029 2461 2459 +f 218 2462 2463 +f 2462 328 2252 +f 2463 2252 1410 +f 2462 2252 2463 +f 1400 2464 2465 +f 2464 218 2463 +f 2465 2463 1410 +f 2464 2463 2465 +f 26 2254 2031 +f 2254 1400 2465 +f 2031 2465 1410 +f 2254 2465 2031 +f 173 2466 2349 +f 2466 699 2467 +f 2349 2467 867 +f 2466 2467 2349 +f 99 2468 2469 +f 2468 377 2354 +f 2469 2354 867 +f 2468 2354 2469 +f 377 2468 2358 +f 2468 99 2470 +f 2358 2470 1170 +f 2468 2470 2358 +f 372 2357 2472 +f 2357 1019 2471 +f 2472 2471 1081 +f 2357 2471 2472 +f 1019 2473 2471 +f 2473 97 2474 +f 2471 2474 1081 +f 2473 2474 2471 +f 329 2475 2270 +f 2475 97 2473 +f 2270 2473 1019 +f 2475 2473 2270 +f 97 2475 2477 +f 2475 329 2476 +f 2477 2476 1032 +f 2475 2476 2477 +f 1032 2476 2478 +f 2476 329 2360 +f 2478 2360 1170 +f 2476 2360 2478 +f 176 2479 2364 +f 2479 501 2480 +f 2364 2480 751 +f 2479 2480 2364 +f 751 2481 2365 +f 2481 8 2368 +f 2365 2368 1178 +f 2481 2368 2365 +f 965 2482 2361 +f 2482 979 2483 +f 2361 2483 1279 +f 2482 2483 2361 +f 953 2373 2484 +f 2373 969 2369 +f 2484 2369 1154 +f 2373 2369 2484 +f 965 2276 2482 +f 2276 549 2485 +f 2482 2485 979 +f 2276 2485 2482 +f 549 2486 2485 +f 2486 973 2487 +f 2485 2487 979 +f 2486 2487 2485 +f 301 2488 2371 +f 2488 165 2489 +f 2371 2489 1393 +f 2488 2489 2371 +f 165 2488 2490 +f 2488 301 2372 +f 2490 2372 953 +f 2488 2372 2490 +f 80 2491 2492 +f 2491 549 2275 +f 2492 2275 638 +f 2491 2275 2492 +f 508 2493 2277 +f 2493 80 2492 +f 2277 2492 638 +f 2493 2492 2277 +f 956 2379 2494 +f 2379 191 2380 +f 2494 2380 1109 +f 2379 2380 2494 +f 4 2495 2496 +f 2495 956 2494 +f 2496 2494 1109 +f 2495 2494 2496 +f 1210 2389 2497 +f 2389 1214 2376 +f 2497 2376 1215 +f 2389 2376 2497 +f 1115 2382 2498 +f 2382 1113 2394 +f 2498 2394 1492 +f 2382 2394 2498 +f 1094 2392 2393 +f 2392 424 2499 +f 2393 2499 1492 +f 2392 2499 2393 +f 142 2500 2501 +f 2500 65 2288 +f 2501 2288 1442 +f 2500 2288 2501 +f 155 2502 2503 +f 2502 1367 2169 +f 2503 2169 1401 +f 2502 2169 2503 +f 683 2300 2505 +f 2300 1171 2504 +f 2505 2504 1390 +f 2300 2504 2505 +f 742 2506 2508 +f 2506 172 2507 +f 2508 2507 1291 +f 2506 2507 2508 +f 607 2406 2509 +f 2406 172 2506 +f 2509 2506 742 +f 2406 2506 2509 +f 320 2400 2511 +f 2400 607 2510 +f 2511 2510 1446 +f 2400 2510 2511 +f 683 2512 2298 +f 2512 707 2513 +f 2298 2513 834 +f 2512 2513 2298 +f 834 2513 2515 +f 2513 707 2514 +f 2515 2514 931 +f 2513 2514 2515 +f 615 2516 2518 +f 2516 1198 2517 +f 2518 2517 1291 +f 2516 2517 2518 +f 172 2409 2507 +f 2409 615 2518 +f 2507 2518 1291 +f 2409 2518 2507 +f 573 2305 2519 +f 2305 834 2515 +f 2519 2515 931 +f 2305 2515 2519 +f 1198 2516 2521 +f 2516 615 2520 +f 2521 2520 1455 +f 2516 2520 2521 +f 573 2519 2523 +f 2519 931 2522 +f 2523 2522 1502 +f 2519 2522 2523 +f 615 2410 2520 +f 2410 943 2524 +f 2520 2524 1455 +f 2410 2524 2520 +f 943 2525 2524 +f 2525 778 2526 +f 2524 2526 1455 +f 2525 2526 2524 +f 778 2525 2528 +f 2525 943 2527 +f 2528 2527 1406 +f 2525 2527 2528 +f 943 2309 2527 +f 2309 1039 2310 +f 2527 2310 1406 +f 2309 2310 2527 +f 1031 2413 2428 +f 2413 15 2529 +f 2428 2529 1238 +f 2413 2529 2428 +f 14 2530 2532 +f 2530 503 2531 +f 2532 2531 1336 +f 2530 2531 2532 +f 1063 2420 2533 +f 2420 14 2532 +f 2533 2532 1336 +f 2420 2532 2533 +f 1067 2534 2535 +f 2534 247 2416 +f 2535 2416 1211 +f 2534 2416 2535 +f 805 2430 2431 +f 2430 445 2536 +f 2431 2536 1431 +f 2430 2536 2431 +f 512 2314 2423 +f 2314 247 2534 +f 2423 2534 1067 +f 2314 2534 2423 +f 1021 2537 2427 +f 2537 212 2425 +f 2427 2425 1072 +f 2537 2425 2427 +f 196 2538 2539 +f 2538 1260 2434 +f 2539 2434 1299 +f 2538 2434 2539 +f 196 2540 2538 +f 2540 666 2209 +f 2538 2209 1260 +f 2540 2209 2538 +f 666 2540 2542 +f 2540 196 2541 +f 2542 2541 1399 +f 2540 2541 2542 +f 595 2543 2433 +f 2543 552 2544 +f 2433 2544 1299 +f 2543 2544 2433 +f 110 2545 2546 +f 2545 666 2542 +f 2546 2542 1399 +f 2545 2542 2546 +f 552 2543 2547 +f 2543 595 2212 +f 2547 2212 802 +f 2543 2212 2547 +f 110 2548 2545 +f 2548 345 2213 +f 2545 2213 666 +f 2548 2213 2545 +f 552 2547 2549 +f 2547 802 2102 +f 2549 2102 1220 +f 2547 2102 2549 +f 299 2550 2551 +f 2550 552 2549 +f 2551 2549 1220 +f 2550 2549 2551 +f 345 2548 2101 +f 2548 110 2552 +f 2101 2552 1467 +f 2548 2552 2101 +f 110 2553 2552 +f 2553 555 2436 +f 2552 2436 1467 +f 2553 2436 2552 +f 299 2551 2554 +f 2551 1220 2215 +f 2554 2215 1459 +f 2551 2215 2554 +f 347 2317 2555 +f 2317 71 2439 +f 2555 2439 852 +f 2317 2439 2555 +f 697 2556 2557 +f 2556 1308 2323 +f 2557 2323 1339 +f 2556 2323 2557 +f 697 2557 2559 +f 2557 1339 2558 +f 2559 2558 1430 +f 2557 2558 2559 +f 633 2560 2562 +f 2560 599 2561 +f 2562 2561 1069 +f 2560 2561 2562 +f 858 2563 1968 +f 2563 633 2562 +f 1968 2562 1069 +f 2563 2562 1968 +f 633 2563 2564 +f 2563 858 2218 +f 2564 2218 1308 +f 2563 2218 2564 +f 74 2447 2566 +f 2447 539 2565 +f 2566 2565 1246 +f 2447 2565 2566 +f 838 2567 2568 +f 2567 266 2330 +f 2568 2330 1283 +f 2567 2330 2568 +f 274 2569 2446 +f 2569 270 2570 +f 2446 2570 754 +f 2569 2570 2446 +f 270 2569 2571 +f 2569 274 2333 +f 2571 2333 1129 +f 2569 2333 2571 +f 403 2453 2573 +f 2453 453 2572 +f 2573 2572 1098 +f 2453 2572 2573 +f 453 2449 2572 +f 2449 876 2574 +f 2572 2574 1098 +f 2449 2574 2572 +f 84 2575 2335 +f 2575 713 2576 +f 2335 2576 891 +f 2575 2576 2335 +f 266 2577 2331 +f 2577 1219 2131 +f 2331 2131 1463 +f 2577 2131 2331 +f 84 2334 2578 +f 2334 271 2337 +f 2578 2337 1110 +f 2334 2337 2578 +f 794 2454 2579 +f 2454 129 1994 +f 2579 1994 1239 +f 2454 1994 2579 +f 403 2580 2452 +f 2580 794 2579 +f 2452 2579 1239 +f 2580 2579 2452 +f 644 2581 2583 +f 2581 294 2582 +f 2583 2582 836 +f 2581 2582 2583 +f 294 2581 2259 +f 2581 644 2584 +f 2259 2584 1268 +f 2581 2584 2259 +f 836 2585 2587 +f 2585 509 2586 +f 2587 2586 1266 +f 2585 2586 2587 +f 294 2255 2582 +f 2255 509 2585 +f 2582 2585 836 +f 2255 2585 2582 +f 644 2588 2584 +f 2588 173 2351 +f 2584 2351 1268 +f 2588 2351 2584 +f 623 2589 2591 +f 2589 312 2590 +f 2591 2590 1423 +f 2589 2590 2591 +f 372 2592 2355 +f 2592 312 2589 +f 2355 2589 623 +f 2592 2589 2355 +f 312 2592 2593 +f 2592 372 2472 +f 2593 2472 1081 +f 2592 2472 2593 +f 99 2594 2470 +f 2594 35 2595 +f 2470 2595 1170 +f 2594 2595 2470 +f 60 2596 2598 +f 2596 97 2597 +f 2598 2597 871 +f 2596 2597 2598 +f 97 2596 2474 +f 2596 60 2599 +f 2474 2599 1081 +f 2596 2599 2474 +f 85 2600 2601 +f 2600 1032 2478 +f 2601 2478 1170 +f 2600 2478 2601 +f 35 2602 2595 +f 2602 85 2601 +f 2595 2601 1170 +f 2602 2601 2595 +f 501 2479 2604 +f 2479 176 2603 +f 2604 2603 550 +f 2479 2603 2604 +f 8 2481 2606 +f 2481 751 2605 +f 2606 2605 785 +f 2481 2605 2606 +f 227 2607 2608 +f 2607 953 2484 +f 2608 2484 1154 +f 2607 2484 2608 +f 549 2491 2486 +f 2491 80 2609 +f 2486 2609 973 +f 2491 2609 2486 +f 593 2610 2611 +f 2610 1056 2155 +f 2611 2155 1393 +f 2610 2155 2611 +f 165 2612 2489 +f 2612 593 2611 +f 2489 2611 1393 +f 2612 2611 2489 +f 1056 2610 2614 +f 2610 593 2613 +f 2614 2613 1295 +f 2610 2613 2614 +f 508 2278 2616 +f 2278 959 2615 +f 2616 2615 1059 +f 2278 2615 2616 +f 1059 2615 2618 +f 2615 959 2617 +f 2618 2617 1427 +f 2615 2617 2618 +f 959 2619 2617 +f 2619 5 2620 +f 2617 2620 1427 +f 2619 2620 2617 +f 830 2621 2161 +f 2621 5 2619 +f 2161 2619 959 +f 2621 2619 2161 +f 830 2279 2623 +f 2279 1056 2622 +f 2623 2622 1070 +f 2279 2622 2623 +f 1070 2622 2624 +f 2622 1056 2614 +f 2624 2614 1295 +f 2622 2614 2624 +f 5 2621 2625 +f 2621 830 2623 +f 2625 2623 1070 +f 2621 2623 2625 +f 1049 2626 2627 +f 2626 112 2388 +f 2627 2388 1210 +f 2626 2388 2627 +f 389 2628 2629 +f 2628 1115 2498 +f 2629 2498 1492 +f 2628 2498 2629 +f 424 2391 2630 +f 2391 112 2626 +f 2630 2626 1049 +f 2391 2626 2630 +f 424 2630 2499 +f 2630 1049 2631 +f 2499 2631 1492 +f 2630 2631 2499 +f 320 2632 2401 +f 2632 655 2633 +f 2401 2633 773 +f 2632 2633 2401 +f 773 2633 2173 +f 2633 655 2634 +f 2173 2634 1442 +f 2633 2634 2173 +f 655 2635 2634 +f 2635 142 2501 +f 2634 2501 1442 +f 2635 2501 2634 +f 65 2500 2395 +f 2500 142 2636 +f 2395 2636 1139 +f 2500 2636 2395 +f 480 2637 2639 +f 2637 780 2638 +f 2639 2638 1419 +f 2637 2638 2639 +f 780 2640 2638 +f 2640 999 2293 +f 2638 2293 1419 +f 2640 2293 2638 +f 414 2641 2397 +f 2641 1369 2642 +f 2397 2642 1401 +f 2641 2642 2397 +f 1369 2643 2642 +f 2643 155 2503 +f 2642 2503 1401 +f 2643 2503 2642 +f 155 2644 2646 +f 2644 69 2645 +f 2646 2645 1171 +f 2644 2645 2646 +f 155 2646 2502 +f 2646 1171 2405 +f 2502 2405 1367 +f 2646 2405 2502 +f 683 2647 2512 +f 2647 61 2648 +f 2512 2648 707 +f 2647 2648 2512 +f 106 2649 2650 +f 2649 607 2509 +f 2650 2509 742 +f 2649 2509 2650 +f 607 2649 2510 +f 2649 106 2651 +f 2510 2651 1446 +f 2649 2651 2510 +f 707 2652 2514 +f 2652 405 2653 +f 2514 2653 931 +f 2652 2653 2514 +f 931 2653 2522 +f 2653 405 2654 +f 2522 2654 1502 +f 2653 2654 2522 +f 1211 2415 2655 +f 2415 573 2523 +f 2655 2523 1502 +f 2415 2523 2655 +f 212 2656 2418 +f 2656 778 2528 +f 2418 2528 1406 +f 2656 2528 2418 +f 1021 2426 2657 +f 2426 485 2429 +f 2657 2429 1238 +f 2426 2429 2657 +f 503 2530 2658 +f 2530 14 2421 +f 2658 2421 902 +f 2530 2421 2658 +f 503 2658 2659 +f 2658 902 2432 +f 2659 2432 1431 +f 2658 2432 2659 +f 196 2660 2541 +f 2660 540 2661 +f 2541 2661 1399 +f 2660 2661 2541 +f 1152 2662 2663 +f 2662 170 2437 +f 2663 2437 1184 +f 2662 2437 2663 +f 426 2319 2665 +f 2319 170 2664 +f 2665 2664 1345 +f 2319 2664 2665 +f 170 2662 2664 +f 2662 1152 2666 +f 2664 2666 1345 +f 2662 2666 2664 +f 347 2667 2669 +f 2667 1310 2668 +f 2669 2668 1323 +f 2667 2668 2669 +f 347 2669 2438 +f 2669 1323 2670 +f 2438 2670 1459 +f 2669 2670 2438 +f 347 2555 2667 +f 2555 852 2671 +f 2667 2671 1310 +f 2555 2671 2667 +f 1339 2322 2558 +f 2322 426 2672 +f 2558 2672 1430 +f 2322 2672 2558 +f 599 2673 2561 +f 2673 852 2440 +f 2561 2440 1069 +f 2673 2440 2561 +f 852 2673 2675 +f 2673 599 2674 +f 2675 2674 1053 +f 2673 2674 2675 +f 876 2227 2677 +f 2227 1179 2676 +f 2677 2676 1469 +f 2227 2676 2677 +f 13 2678 2679 +f 2678 599 2560 +f 2679 2560 633 +f 2678 2560 2679 +f 876 2680 2574 +f 2680 1038 2681 +f 2574 2681 1098 +f 2680 2681 2574 +f 13 2682 2678 +f 2682 590 2683 +f 2678 2683 599 +f 2682 2683 2678 +f 333 2684 2685 +f 2684 633 2564 +f 2685 2564 1308 +f 2684 2564 2685 +f 697 2686 2556 +f 2686 118 2687 +f 2556 2687 1308 +f 2686 2687 2556 +f 863 2688 2689 +f 2688 697 2559 +f 2689 2559 1430 +f 2688 2559 2689 +f 266 2690 2577 +f 2690 1078 2691 +f 2577 2691 1219 +f 2690 2691 2577 +f 13 2679 2693 +f 2679 633 2692 +f 2693 2692 641 +f 2679 2692 2693 +f 633 2684 2692 +f 2684 333 2694 +f 2692 2694 641 +f 2684 2694 2692 +f 333 2685 2696 +f 2685 1308 2695 +f 2696 2695 1439 +f 2685 2695 2696 +f 1308 2687 2695 +f 2687 118 2697 +f 2695 2697 1439 +f 2687 2697 2695 +f 118 2686 2698 +f 2686 697 2688 +f 2698 2688 863 +f 2686 2688 2698 +f 713 2575 2699 +f 2575 84 2578 +f 2699 2578 1110 +f 2575 2578 2699 +f 794 2580 2700 +f 2580 403 2573 +f 2700 2573 1098 +f 2580 2573 2700 +f 590 2682 2701 +f 2682 13 2693 +f 2701 2693 641 +f 2682 2693 2701 +f 118 2702 2697 +f 2702 248 2703 +f 2697 2703 1439 +f 2702 2703 2697 +f 248 2702 2704 +f 2702 118 2698 +f 2704 2698 863 +f 2702 2698 2704 +f 1219 2705 2243 +f 2705 131 2706 +f 2243 2706 1254 +f 2705 2706 2243 +f 546 2707 2708 +f 2707 590 2701 +f 2708 2701 641 +f 2707 2701 2708 +f 260 2460 2456 +f 2460 1026 2709 +f 2456 2709 1110 +f 2460 2709 2456 +f 509 2352 2586 +f 2352 623 2710 +f 2586 2710 1266 +f 2352 2710 2586 +f 699 2711 2467 +f 2711 99 2469 +f 2467 2469 867 +f 2711 2469 2467 +f 99 2712 2714 +f 2712 1222 2713 +f 2714 2713 1490 +f 2712 2713 2714 +f 35 2594 2715 +f 2594 99 2714 +f 2715 2714 1490 +f 2594 2714 2715 +f 371 2716 2718 +f 2716 871 2717 +f 2718 2717 1032 +f 2716 2717 2718 +f 871 2597 2717 +f 2597 97 2477 +f 2717 2477 1032 +f 2597 2477 2717 +f 85 2719 2600 +f 2719 829 2720 +f 2600 2720 1032 +f 2719 2720 2600 +f 993 2721 2723 +f 2721 1279 2722 +f 2723 2722 1324 +f 2721 2722 2723 +f 550 2603 2725 +f 2603 176 2724 +f 2725 2724 993 +f 2603 2724 2725 +f 993 2724 2721 +f 2724 176 2363 +f 2721 2363 1279 +f 2724 2363 2721 +f 8 2606 2366 +f 2606 785 2726 +f 2366 2726 1154 +f 2606 2726 2366 +f 785 2727 2726 +f 2727 242 2728 +f 2726 2728 1154 +f 2727 2728 2726 +f 1279 2483 2722 +f 2483 979 2729 +f 2722 2729 1324 +f 2483 2729 2722 +f 219 2730 2732 +f 2730 501 2731 +f 2732 2731 1035 +f 2730 2731 2732 +f 501 2730 2480 +f 2730 219 2733 +f 2480 2733 751 +f 2730 2733 2480 +f 751 2733 2735 +f 2733 219 2734 +f 2735 2734 1249 +f 2733 2734 2735 +f 1044 2736 2737 +f 2736 751 2735 +f 2737 2735 1249 +f 2736 2735 2737 +f 242 2738 2728 +f 2738 227 2608 +f 2728 2608 1154 +f 2738 2608 2728 +f 929 2739 2740 +f 2739 165 2490 +f 2740 2490 953 +f 2739 2490 2740 +f 593 2612 2741 +f 2612 165 2739 +f 2741 2739 929 +f 2612 2739 2741 +f 80 2493 2743 +f 2493 508 2742 +f 2743 2742 711 +f 2493 2742 2743 +f 711 2742 2744 +f 2742 508 2616 +f 2744 2616 1059 +f 2742 2616 2744 +f 5 2745 2620 +f 2745 832 2746 +f 2620 2746 1427 +f 2745 2746 2620 +f 700 2747 2748 +f 2747 5 2625 +f 2748 2625 1070 +f 2747 2625 2748 +f 5 2747 2745 +f 2747 700 2749 +f 2745 2749 832 +f 2747 2749 2745 +f 956 2495 2751 +f 2495 4 2750 +f 2751 2750 1427 +f 2495 2750 2751 +f 832 2752 2746 +f 2752 956 2751 +f 2746 2751 1427 +f 2752 2751 2746 +f 700 2753 2754 +f 2753 140 2377 +f 2754 2377 956 +f 2753 2377 2754 +f 832 2749 2752 +f 2749 700 2754 +f 2752 2754 956 +f 2749 2754 2752 +f 140 2755 2378 +f 2755 490 2756 +f 2378 2756 1215 +f 2755 2756 2378 +f 4 2496 2758 +f 2496 1109 2757 +f 2758 2757 1495 +f 2496 2757 2758 +f 1427 2750 2759 +f 2750 4 2758 +f 2759 2758 1495 +f 2750 2758 2759 +f 517 2760 2761 +f 2760 1210 2497 +f 2761 2497 1215 +f 2760 2497 2761 +f 1109 2383 2757 +f 2383 1115 2762 +f 2757 2762 1495 +f 2383 2762 2757 +f 1115 2763 2762 +f 2763 990 2764 +f 2762 2764 1495 +f 2763 2764 2762 +f 389 2765 2628 +f 2765 990 2763 +f 2628 2763 1115 +f 2765 2763 2628 +f 106 2650 2767 +f 2650 742 2766 +f 2767 2766 906 +f 2650 2766 2767 +f 456 2768 2769 +f 2768 320 2511 +f 2769 2511 1446 +f 2768 2511 2769 +f 320 2768 2632 +f 2768 456 2770 +f 2632 2770 655 +f 2768 2770 2632 +f 142 2771 2636 +f 2771 480 2772 +f 2636 2772 1139 +f 2771 2772 2636 +f 1139 2772 2166 +f 2772 480 2639 +f 2166 2639 1419 +f 2772 2639 2166 +f 414 2404 2641 +f 2404 137 2773 +f 2641 2773 1369 +f 2404 2773 2641 +f 1171 2645 2504 +f 2645 69 2774 +f 2504 2774 1390 +f 2645 2774 2504 +f 61 2647 2775 +f 2647 683 2505 +f 2775 2505 1390 +f 2647 2505 2775 +f 649 2776 2777 +f 2776 137 2403 +f 2777 2403 1285 +f 2776 2403 2777 +f 137 2776 2773 +f 2776 649 2778 +f 2773 2778 1369 +f 2776 2778 2773 +f 283 2779 2780 +f 2779 405 2652 +f 2780 2652 707 +f 2779 2652 2780 +f 906 2781 2783 +f 2781 1291 2782 +f 2783 2782 1425 +f 2781 2782 2783 +f 906 2766 2781 +f 2766 742 2508 +f 2781 2508 1291 +f 2766 2508 2781 +f 780 2784 2640 +f 2784 652 2301 +f 2640 2301 999 +f 2784 2301 2640 +f 378 2785 2786 +f 2785 649 2777 +f 2786 2777 1285 +f 2785 2777 2786 +f 283 2787 2779 +f 2787 228 2788 +f 2779 2788 405 +f 2787 2788 2779 +f 1291 2517 2782 +f 2517 1198 2789 +f 2782 2789 1425 +f 2517 2789 2782 +f 558 2790 2791 +f 2790 652 2784 +f 2791 2784 780 +f 2790 2784 2791 +f 1063 2792 2407 +f 2792 378 2786 +f 2407 2786 1285 +f 2792 2786 2407 +f 558 2793 2790 +f 2793 15 2412 +f 2790 2412 652 +f 2793 2412 2790 +f 378 2792 2794 +f 2792 1063 2533 +f 2794 2533 1336 +f 2792 2533 2794 +f 602 2795 2796 +f 2795 1198 2521 +f 2796 2521 1455 +f 2795 2521 2796 +f 15 2793 2529 +f 2793 558 2797 +f 2529 2797 1238 +f 2793 2797 2529 +f 778 2656 2799 +f 2656 212 2798 +f 2799 2798 1137 +f 2656 2798 2799 +f 445 2424 2536 +f 2424 1067 2800 +f 2536 2800 1431 +f 2424 2800 2536 +f 552 2801 2544 +f 2801 668 2802 +f 2544 2802 1299 +f 2801 2802 2544 +f 1077 2803 2804 +f 2803 110 2546 +f 2804 2546 1399 +f 2803 2546 2804 +f 555 2805 2435 +f 2805 126 2806 +f 2435 2806 1184 +f 2805 2806 2435 +f 1263 2807 2808 +f 2807 299 2554 +f 2808 2554 1459 +f 2807 2554 2808 +f 426 2665 2672 +f 2665 1345 2809 +f 2672 2809 1430 +f 2665 2809 2672 +f 1345 2810 2809 +f 2810 1341 2811 +f 2809 2811 1430 +f 2810 2811 2809 +f 787 2231 2813 +f 2231 74 2812 +f 2813 2812 1195 +f 2231 2812 2813 +f 787 2813 2325 +f 2813 1195 2814 +f 2325 2814 1243 +f 2813 2814 2325 +f 531 2815 2445 +f 2815 838 2568 +f 2445 2568 1283 +f 2815 2568 2445 +f 599 2683 2674 +f 2683 590 2816 +f 2674 2816 1053 +f 2683 2816 2674 +f 713 2817 2819 +f 2817 385 2818 +f 2819 2818 1246 +f 2817 2818 2819 +f 539 2820 2565 +f 2820 713 2819 +f 2565 2819 1246 +f 2820 2819 2565 +f 713 2820 2576 +f 2820 539 2450 +f 2576 2450 891 +f 2820 2450 2576 +f 277 2821 2338 +f 2821 168 2822 +f 2338 2822 1129 +f 2821 2822 2338 +f 679 2823 2825 +f 2823 590 2824 +f 2825 2824 1374 +f 2823 2824 2825 +f 464 2826 2827 +f 2826 248 2704 +f 2827 2704 863 +f 2826 2704 2827 +f 380 2828 2829 +f 2828 967 2457 +f 2829 2457 1121 +f 2828 2457 2829 +f 590 2707 2824 +f 2707 546 2830 +f 2824 2830 1374 +f 2707 2830 2824 +f 248 2831 2703 +f 2831 1144 2832 +f 2703 2832 1439 +f 2831 2832 2703 +f 198 2833 2834 +f 2833 1163 2342 +f 2834 2342 1254 +f 2833 2342 2834 +f 641 2694 2836 +f 2694 333 2835 +f 2836 2835 1047 +f 2694 2835 2836 +f 671 2837 2838 +f 2837 333 2696 +f 2838 2696 1439 +f 2837 2696 2838 +f 1026 2461 2840 +f 2461 328 2839 +f 2840 2839 1269 +f 2461 2839 2840 +f 546 2708 2842 +f 2708 641 2841 +f 2842 2841 660 +f 2708 2841 2842 +f 660 2841 2843 +f 2841 641 2836 +f 2843 2836 1047 +f 2841 2836 2843 +f 173 2588 2845 +f 2588 644 2844 +f 2845 2844 1465 +f 2588 2844 2845 +f 99 2711 2712 +f 2711 699 2846 +f 2712 2846 1222 +f 2711 2846 2712 +f 386 2847 2848 +f 2847 623 2591 +f 2848 2591 1423 +f 2847 2591 2848 +f 623 2847 2710 +f 2847 386 2849 +f 2710 2849 1266 +f 2847 2849 2710 +f 312 2850 2590 +f 2850 1324 2851 +f 2590 2851 1423 +f 2850 2851 2590 +f 934 2852 2853 +f 2852 35 2715 +f 2853 2715 1490 +f 2852 2715 2853 +f 312 2593 2855 +f 2593 1081 2854 +f 2855 2854 1122 +f 2593 2854 2855 +f 871 2716 2857 +f 2716 371 2856 +f 2857 2856 1050 +f 2716 2856 2857 +f 1032 2720 2859 +f 2720 829 2858 +f 2859 2858 1271 +f 2720 2858 2859 +f 371 2718 2860 +f 2718 1032 2859 +f 2860 2859 1271 +f 2718 2859 2860 +f 85 2602 2862 +f 2602 35 2861 +f 2862 2861 678 +f 2602 2861 2862 +f 678 2861 2863 +f 2861 35 2852 +f 2863 2852 934 +f 2861 2852 2863 +f 1081 2864 2854 +f 2864 370 2865 +f 2854 2865 1122 +f 2864 2865 2854 +f 60 2866 2599 +f 2866 370 2864 +f 2599 2864 1081 +f 2866 2864 2599 +f 21 2867 2869 +f 2867 511 2868 +f 2869 2868 751 +f 2867 2868 2869 +f 751 2868 2605 +f 2868 511 2870 +f 2605 2870 785 +f 2868 2870 2605 +f 501 2604 2731 +f 2604 550 2871 +f 2731 2871 1035 +f 2604 2871 2731 +f 21 2869 2872 +f 2869 751 2736 +f 2872 2736 1044 +f 2869 2736 2872 +f 511 2867 2873 +f 2867 21 2872 +f 2873 2872 1044 +f 2867 2872 2873 +f 419 2874 2876 +f 2874 219 2875 +f 2876 2875 439 +f 2874 2875 2876 +f 219 2874 2734 +f 2874 419 2877 +f 2734 2877 1249 +f 2874 2877 2734 +f 80 2743 2609 +f 2743 711 2878 +f 2609 2878 973 +f 2743 2878 2609 +f 593 2879 2613 +f 2879 1280 2880 +f 2613 2880 1295 +f 2879 2880 2613 +f 490 2881 2882 +f 2881 700 2748 +f 2882 2748 1070 +f 2881 2748 2882 +f 490 2755 2881 +f 2755 140 2753 +f 2881 2753 700 +f 2755 2753 2881 +f 490 2883 2756 +f 2883 517 2761 +f 2756 2761 1215 +f 2883 2761 2756 +f 1210 2760 2885 +f 2760 517 2884 +f 2885 2884 1348 +f 2760 2884 2885 +f 1210 2885 2887 +f 2885 1348 2886 +f 2887 2886 1468 +f 2885 2886 2887 +f 518 2888 2890 +f 2888 389 2889 +f 2890 2889 1028 +f 2888 2889 2890 +f 1049 2627 2891 +f 2627 1210 2887 +f 2891 2887 1468 +f 2627 2887 2891 +f 1028 2889 2892 +f 2889 389 2629 +f 2892 2629 1492 +f 2889 2629 2892 +f 1049 2893 2631 +f 2893 885 2894 +f 2631 2894 1492 +f 2893 2894 2631 +f 885 2893 2895 +f 2893 1049 2891 +f 2895 2891 1468 +f 2893 2891 2895 +f 70 2896 2897 +f 2896 106 2767 +f 2897 2767 906 +f 2896 2767 2897 +f 707 2648 2899 +f 2648 61 2898 +f 2899 2898 1090 +f 2648 2898 2899 +f 283 2780 2900 +f 2780 707 2899 +f 2900 2899 1090 +f 2780 2899 2900 +f 228 2901 2788 +f 2901 43 2902 +f 2788 2902 405 +f 2901 2902 2788 +f 405 2902 2654 +f 2902 43 2903 +f 2654 2903 1502 +f 2902 2903 2654 +f 43 2904 2903 +f 2904 178 2905 +f 2903 2905 1502 +f 2904 2905 2903 +f 1198 2795 2789 +f 2795 602 2906 +f 2789 2906 1425 +f 2795 2906 2789 +f 178 2907 2908 +f 2907 1067 2535 +f 2908 2535 1211 +f 2907 2535 2908 +f 178 2908 2905 +f 2908 1211 2655 +f 2905 2655 1502 +f 2908 2655 2905 +f 503 2909 2531 +f 2909 363 2910 +f 2531 2910 1336 +f 2909 2910 2531 +f 778 2799 2912 +f 2799 1137 2911 +f 2912 2911 1434 +f 2799 2911 2912 +f 212 2537 2798 +f 2537 1021 2913 +f 2798 2913 1137 +f 2537 2913 2798 +f 1060 2914 2916 +f 2914 522 2915 +f 2916 2915 1431 +f 2914 2915 2916 +f 1067 2917 2800 +f 2917 1060 2916 +f 2800 2916 1431 +f 2917 2916 2800 +f 555 2553 2918 +f 2553 110 2803 +f 2918 2803 1077 +f 2553 2803 2918 +f 126 2919 2806 +f 2919 1152 2663 +f 2806 2663 1184 +f 2919 2663 2806 +f 852 2920 2671 +f 2920 987 2921 +f 2671 2921 1310 +f 2920 2921 2671 +f 531 2444 2922 +f 2444 145 2441 +f 2922 2441 1243 +f 2444 2441 2922 +f 590 2823 2816 +f 2823 679 2923 +f 2816 2923 1053 +f 2823 2923 2816 +f 679 2924 2923 +f 2924 987 2925 +f 2923 2925 1053 +f 2924 2925 2923 +f 1341 2926 2811 +f 2926 1010 2927 +f 2811 2927 1430 +f 2926 2927 2811 +f 1010 2928 2927 +f 2928 863 2689 +f 2927 2689 1430 +f 2928 2689 2927 +f 1098 2681 2930 +f 2681 1038 2929 +f 2930 2929 1436 +f 2681 2929 2930 +f 168 2821 2931 +f 2821 277 2237 +f 2931 2237 967 +f 2821 2237 2931 +f 794 2700 2932 +f 2700 1098 2930 +f 2932 2930 1436 +f 2700 2930 2932 +f 464 2827 2933 +f 2827 863 2928 +f 2933 2928 1010 +f 2827 2928 2933 +f 245 2934 2935 +f 2934 385 2817 +f 2935 2817 713 +f 2934 2817 2935 +f 245 2935 2936 +f 2935 713 2699 +f 2936 2699 1110 +f 2935 2699 2936 +f 594 2937 2938 +f 2937 794 2932 +f 2938 2932 1436 +f 2937 2932 2938 +f 776 2939 2940 +f 2939 679 2825 +f 2940 2825 1374 +f 2939 2825 2940 +f 1026 2941 2709 +f 2941 245 2936 +f 2709 2936 1110 +f 2941 2936 2709 +f 967 2828 2943 +f 2828 380 2942 +f 2943 2942 1244 +f 2828 2942 2943 +f 248 2826 2831 +f 2826 464 2944 +f 2831 2944 1144 +f 2826 2944 2831 +f 131 2945 2706 +f 2945 198 2834 +f 2706 2834 1254 +f 2945 2834 2706 +f 594 2946 2937 +f 2946 273 2455 +f 2937 2455 794 +f 2946 2455 2937 +f 273 2946 2948 +f 2946 594 2947 +f 2948 2947 1411 +f 2946 2947 2948 +f 198 2949 2833 +f 2949 992 2950 +f 2833 2950 1163 +f 2949 2950 2833 +f 653 2458 2951 +f 2458 273 2948 +f 2951 2948 1411 +f 2458 2948 2951 +f 1163 2950 2253 +f 2950 992 2952 +f 2253 2952 1400 +f 2950 2952 2253 +f 328 2462 2839 +f 2462 218 2953 +f 2839 2953 1269 +f 2462 2953 2839 +f 458 2347 2955 +f 2347 646 2954 +f 2955 2954 672 +f 2347 2954 2955 +f 333 2837 2835 +f 2837 671 2956 +f 2835 2956 1047 +f 2837 2956 2835 +f 1144 2957 2832 +f 2957 859 2958 +f 2832 2958 1439 +f 2957 2958 2832 +f 546 2959 2830 +f 2959 430 2960 +f 2830 2960 1374 +f 2959 2960 2830 +f 430 2959 2961 +f 2959 546 2842 +f 2961 2842 660 +f 2959 2842 2961 +f 859 2962 2958 +f 2962 671 2838 +f 2958 2838 1439 +f 2962 2838 2958 +f 1047 2956 2964 +f 2956 671 2963 +f 2964 2963 1465 +f 2956 2963 2964 +f 644 2965 2967 +f 2965 620 2966 +f 2967 2966 1047 +f 2965 2966 2967 +f 620 2968 2966 +f 2968 660 2843 +f 2966 2843 1047 +f 2968 2843 2966 +f 644 2967 2844 +f 2967 1047 2964 +f 2844 2964 1465 +f 2967 2964 2844 +f 620 2965 2969 +f 2965 644 2583 +f 2969 2583 836 +f 2965 2583 2969 +f 836 2587 2971 +f 2587 1266 2970 +f 2971 2970 1305 +f 2587 2970 2971 +f 699 2466 2973 +f 2466 173 2972 +f 2973 2972 1230 +f 2466 2972 2973 +f 1230 2972 2974 +f 2972 173 2845 +f 2974 2845 1465 +f 2972 2845 2974 +f 1266 2849 2970 +f 2849 386 2975 +f 2970 2975 1305 +f 2849 2975 2970 +f 386 2976 2975 +f 2976 1207 2977 +f 2975 2977 1305 +f 2976 2977 2975 +f 1222 2846 2978 +f 2846 699 2973 +f 2978 2973 1230 +f 2846 2973 2978 +f 312 2855 2850 +f 2855 1122 2979 +f 2850 2979 1324 +f 2855 2979 2850 +f 370 2866 2981 +f 2866 60 2980 +f 2981 2980 529 +f 2866 2980 2981 +f 529 2980 2982 +f 2980 60 2598 +f 2982 2598 871 +f 2980 2598 2982 +f 784 2983 2984 +f 2983 871 2857 +f 2984 2857 1050 +f 2983 2857 2984 +f 1050 2856 2986 +f 2856 371 2985 +f 2986 2985 1440 +f 2856 2985 2986 +f 371 2860 2985 +f 2860 1271 2987 +f 2985 2987 1440 +f 2860 2987 2985 +f 1122 2865 2989 +f 2865 370 2988 +f 2989 2988 1337 +f 2865 2988 2989 +f 829 2990 2992 +f 2990 678 2991 +f 2992 2991 1102 +f 2990 2991 2992 +f 85 2862 2719 +f 2862 678 2990 +f 2719 2990 829 +f 2862 2990 2719 +f 993 2993 2995 +f 2993 92 2994 +f 2995 2994 1337 +f 2993 2994 2995 +f 550 2725 2996 +f 2725 993 2995 +f 2996 2995 1337 +f 2725 2995 2996 +f 511 2997 2870 +f 2997 658 2998 +f 2870 2998 785 +f 2997 2998 2870 +f 658 2999 2998 +f 2999 678 3000 +f 2998 3000 785 +f 2999 3000 2998 +f 785 3000 3001 +f 3000 678 2863 +f 3001 2863 934 +f 3000 2863 3001 +f 242 2727 3002 +f 2727 785 3001 +f 3002 3001 934 +f 2727 3001 3002 +f 1035 2871 3003 +f 2871 550 2996 +f 3003 2996 1337 +f 2871 2996 3003 +f 979 3004 2729 +f 3004 874 3005 +f 2729 3005 1324 +f 3004 3005 2729 +f 419 3006 2877 +f 3006 795 3007 +f 2877 3007 1249 +f 3006 3007 2877 +f 795 3008 3007 +f 3008 1175 3009 +f 3007 3009 1249 +f 3008 3009 3007 +f 1175 3010 3009 +f 3010 725 3011 +f 3009 3011 1249 +f 3010 3011 3009 +f 439 2875 3012 +f 2875 219 2732 +f 3012 2732 1035 +f 2875 2732 3012 +f 725 3013 3011 +f 3013 1044 2737 +f 3011 2737 1249 +f 3013 2737 3011 +f 973 3014 2487 +f 3014 874 3004 +f 2487 3004 979 +f 3014 3004 2487 +f 719 3015 3016 +f 3015 593 2741 +f 3016 2741 929 +f 3015 2741 3016 +f 604 3017 3018 +f 3017 711 2744 +f 3018 2744 1059 +f 3017 2744 3018 +f 490 2882 3019 +f 2882 1070 2624 +f 3019 2624 1295 +f 2882 2624 3019 +f 517 2883 3020 +f 2883 490 3019 +f 3020 3019 1295 +f 2883 3019 3020 +f 1059 2618 3021 +f 2618 1427 2759 +f 3021 2759 1495 +f 2618 2759 3021 +f 517 3022 2884 +f 3022 706 3023 +f 2884 3023 1348 +f 3022 3023 2884 +f 885 3024 2894 +f 3024 1028 2892 +f 2894 2892 1492 +f 3024 2892 2894 +f 106 2896 2651 +f 2896 70 3025 +f 2651 3025 1446 +f 2896 3025 2651 +f 537 3026 3027 +f 3026 456 2769 +f 3027 2769 1446 +f 3026 2769 3027 +f 142 2635 3029 +f 2635 655 3028 +f 3029 3028 1091 +f 2635 3028 3029 +f 895 3030 3031 +f 3030 155 2643 +f 3031 2643 1369 +f 3030 2643 3031 +f 69 2644 3032 +f 2644 155 3030 +f 3032 3030 895 +f 2644 3030 3032 +f 1090 2898 3033 +f 2898 61 2775 +f 3033 2775 1390 +f 2898 2775 3033 +f 585 3034 3035 +f 3034 283 2900 +f 3035 2900 1090 +f 3034 2900 3035 +f 283 3034 3037 +f 3034 585 3036 +f 3037 3036 762 +f 3034 3036 3037 +f 228 2787 3038 +f 2787 283 3037 +f 3038 3037 762 +f 2787 3037 3038 +f 572 3039 3040 +f 3039 228 3038 +f 3040 3038 762 +f 3039 3038 3040 +f 558 3041 2797 +f 3041 1194 3042 +f 2797 3042 1238 +f 3041 3042 2797 +f 1128 3043 3044 +f 3043 602 2796 +f 3044 2796 1455 +f 3043 2796 3044 +f 1194 3045 3042 +f 3045 1095 3046 +f 3042 3046 1238 +f 3045 3046 3042 +f 778 3047 2526 +f 3047 1128 3044 +f 2526 3044 1455 +f 3047 3044 2526 +f 363 3048 2910 +f 3048 651 3049 +f 2910 3049 1336 +f 3048 3049 2910 +f 491 3050 3052 +f 3050 621 3051 +f 3052 3051 1067 +f 3050 3051 3052 +f 178 3053 2907 +f 3053 491 3052 +f 2907 3052 1067 +f 3053 3052 2907 +f 1128 3047 3054 +f 3047 778 2912 +f 3054 2912 1434 +f 3047 2912 3054 +f 1095 3055 3046 +f 3055 1021 2657 +f 3046 2657 1238 +f 3055 2657 3046 +f 363 2909 3057 +f 2909 503 3056 +f 3057 3056 522 +f 2909 3056 3057 +f 196 3058 3060 +f 3058 1046 3059 +f 3060 3059 1153 +f 3058 3059 3060 +f 552 2550 3062 +f 2550 299 3061 +f 3062 3061 1182 +f 2550 3061 3062 +f 1182 3061 3063 +f 3061 299 2807 +f 3063 2807 1263 +f 3061 2807 3063 +f 1323 3064 2670 +f 3064 1263 2808 +f 2670 2808 1459 +f 3064 2808 2670 +f 1345 2666 3066 +f 2666 1152 3065 +f 3066 3065 1380 +f 2666 3065 3066 +f 390 3067 3069 +f 3067 206 3068 +f 3069 3068 1157 +f 3067 3068 3069 +f 390 3069 2324 +f 3069 1157 3070 +f 2324 3070 1179 +f 3069 3070 2324 +f 192 3071 2219 +f 3071 206 3067 +f 2219 3067 390 +f 3071 3067 2219 +f 206 3071 3073 +f 3071 192 3072 +f 3073 3072 1484 +f 3071 3072 3073 +f 987 2920 2925 +f 2920 852 2675 +f 2925 2675 1053 +f 2920 2675 2925 +f 270 3074 2570 +f 3074 281 3075 +f 2570 3075 754 +f 3074 3075 2570 +f 1038 2680 3076 +f 2680 876 2677 +f 3076 2677 1469 +f 2680 2677 3076 +f 266 2567 2690 +f 2567 838 3077 +f 2690 3077 1078 +f 2567 3077 2690 +f 547 3078 3079 +f 3078 270 2571 +f 3079 2571 1129 +f 3078 2571 3079 +f 168 2931 3080 +f 2931 967 2943 +f 3080 2943 1244 +f 2931 2943 3080 +f 458 2955 2345 +f 2955 672 3081 +f 2345 3081 1121 +f 2955 3081 2345 +f 646 2251 3082 +f 2251 653 2951 +f 3082 2951 1411 +f 2251 2951 3082 +f 220 3083 3085 +f 3083 1036 3084 +f 3085 3084 1144 +f 3083 3084 3085 +f 288 3086 3087 +f 3086 218 2464 +f 3087 2464 1400 +f 3086 2464 3087 +f 992 3088 2952 +f 3088 288 3087 +f 2952 3087 1400 +f 3088 3087 2952 +f 1145 3089 3090 +f 3089 776 2940 +f 3090 2940 1374 +f 3089 2940 3090 +f 430 3091 2960 +f 3091 1145 3090 +f 2960 3090 1374 +f 3091 3090 2960 +f 620 3092 2968 +f 3092 430 2961 +f 2968 2961 660 +f 3092 2961 2968 +f 671 2962 3094 +f 2962 859 3093 +f 3094 3093 888 +f 2962 3093 3094 +f 671 3094 2963 +f 3094 888 3095 +f 2963 3095 1465 +f 3094 3095 2963 +f 888 3096 3095 +f 3096 601 3097 +f 3095 3097 1465 +f 3096 3097 3095 +f 620 2969 3098 +f 2969 836 2971 +f 3098 2971 1305 +f 2969 2971 3098 +f 601 3099 3097 +f 3099 1230 2974 +f 3097 2974 1465 +f 3099 2974 3097 +f 386 3100 2976 +f 3100 569 3101 +f 2976 3101 1207 +f 3100 3101 2976 +f 1222 3102 2713 +f 3102 369 3103 +f 2713 3103 1490 +f 3102 3103 2713 +f 784 3104 2983 +f 3104 529 2982 +f 2983 2982 871 +f 3104 2982 2983 +f 829 2992 2858 +f 2992 1102 3105 +f 2858 3105 1271 +f 2992 3105 2858 +f 1122 3106 2979 +f 3106 92 3107 +f 2979 3107 1324 +f 3106 3107 2979 +f 92 3106 2994 +f 3106 1122 2989 +f 2994 2989 1337 +f 3106 2989 2994 +f 211 3108 3109 +f 3108 784 2984 +f 3109 2984 1050 +f 3108 2984 3109 +f 1307 3110 3111 +f 3110 1050 2986 +f 3111 2986 1440 +f 3110 2986 3111 +f 92 2993 3107 +f 2993 993 2723 +f 3107 2723 1324 +f 2993 2723 3107 +f 205 3112 3114 +f 3112 211 3113 +f 3114 3113 795 +f 3112 3113 3114 +f 795 3113 3115 +f 3113 211 3109 +f 3115 3109 1050 +f 3113 3109 3115 +f 795 3115 3008 +f 3115 1050 3116 +f 3008 3116 1175 +f 3115 3116 3008 +f 1175 3116 3117 +f 3116 1050 3110 +f 3117 3110 1307 +f 3116 3110 3117 +f 678 2999 2991 +f 2999 658 3118 +f 2991 3118 1102 +f 2999 3118 2991 +f 242 3002 3119 +f 3002 934 2853 +f 3119 2853 1490 +f 3002 2853 3119 +f 376 3120 3122 +f 3120 227 3121 +f 3122 3121 1490 +f 3120 3121 3122 +f 227 2738 3121 +f 2738 242 3119 +f 3121 3119 1490 +f 2738 3119 3121 +f 954 3123 3124 +f 3123 1035 3003 +f 3124 3003 1337 +f 3123 3003 3124 +f 18 3125 3126 +f 3125 1175 3117 +f 3126 3117 1307 +f 3125 3117 3126 +f 658 3127 3118 +f 3127 691 3128 +f 3118 3128 1102 +f 3127 3128 3118 +f 691 3127 3130 +f 3127 658 3129 +f 3130 3129 1044 +f 3127 3129 3130 +f 658 2997 3129 +f 2997 511 2873 +f 3129 2873 1044 +f 2997 2873 3129 +f 387 3131 3133 +f 3131 205 3132 +f 3133 3132 439 +f 3131 3132 3133 +f 205 3134 3132 +f 3134 419 2876 +f 3132 2876 439 +f 3134 2876 3132 +f 419 3134 3006 +f 3134 205 3114 +f 3006 3114 795 +f 3134 3114 3006 +f 18 3135 3125 +f 3135 725 3010 +f 3125 3010 1175 +f 3135 3010 3125 +f 954 3136 3123 +f 3136 439 3012 +f 3123 3012 1035 +f 3136 3012 3123 +f 227 3137 2607 +f 3137 929 2740 +f 2607 2740 953 +f 3137 2740 2607 +f 533 3138 3139 +f 3138 874 3014 +f 3139 3014 973 +f 3138 3014 3139 +f 593 3015 2879 +f 3015 719 3140 +f 2879 3140 1280 +f 3015 3140 2879 +f 706 3022 3141 +f 3022 517 3020 +f 3141 3020 1295 +f 3022 3020 3141 +f 234 3142 3144 +f 3142 964 3143 +f 3144 3143 1495 +f 3142 3143 3144 +f 964 3145 3143 +f 3145 1059 3021 +f 3143 3021 1495 +f 3145 3021 3143 +f 622 3146 3148 +f 3146 431 3147 +f 3148 3147 706 +f 3146 3147 3148 +f 431 3146 3150 +f 3146 622 3149 +f 3150 3149 788 +f 3146 3149 3150 +f 234 3151 3153 +f 3151 629 3152 +f 3153 3152 1320 +f 3151 3152 3153 +f 706 3147 3023 +f 3147 431 3154 +f 3023 3154 1348 +f 3147 3154 3023 +f 990 3155 2764 +f 3155 234 3144 +f 2764 3144 1495 +f 3155 3144 2764 +f 431 3150 3157 +f 3150 788 3156 +f 3157 3156 1273 +f 3150 3156 3157 +f 234 3158 3151 +f 3158 225 3159 +f 3151 3159 629 +f 3158 3159 3151 +f 225 3158 3160 +f 3158 234 3155 +f 3160 3155 990 +f 3158 3155 3160 +f 389 2888 2765 +f 2888 518 3161 +f 2765 3161 990 +f 2888 3161 2765 +f 431 3157 3154 +f 3157 1273 3162 +f 3154 3162 1348 +f 3157 3162 3154 +f 1348 3162 2886 +f 3162 1273 3163 +f 2886 3163 1468 +f 3162 3163 2886 +f 225 3160 3165 +f 3160 990 3164 +f 3165 3164 1180 +f 3160 3164 3165 +f 736 3166 3168 +f 3166 1180 3167 +f 3168 3167 1278 +f 3166 3167 3168 +f 1300 3169 3171 +f 3169 1452 3170 +f 3171 3170 1493 +f 3169 3170 3171 +f 736 3168 3173 +f 3168 1278 3172 +f 3173 3172 1498 +f 3168 3172 3173 +f 627 3174 3176 +f 3174 906 3175 +f 3176 3175 1329 +f 3174 3175 3176 +f 627 3177 3174 +f 3177 70 2897 +f 3174 2897 906 +f 3177 2897 3174 +f 70 3178 3025 +f 3178 1088 3179 +f 3025 3179 1446 +f 3178 3179 3025 +f 51 3180 3181 +f 3180 142 3029 +f 3181 3029 1091 +f 3180 3029 3181 +f 142 3180 2771 +f 3180 51 3182 +f 2771 3182 480 +f 3180 3182 2771 +f 1369 3183 3185 +f 3183 1146 3184 +f 3185 3184 1413 +f 3183 3184 3185 +f 895 3031 3186 +f 3031 1369 3185 +f 3186 3185 1413 +f 3031 3185 3186 +f 906 3187 3175 +f 3187 913 3188 +f 3175 3188 1329 +f 3187 3188 3175 +f 913 3187 3189 +f 3187 906 2783 +f 3189 2783 1425 +f 3187 2783 3189 +f 325 3190 3191 +f 3190 913 3189 +f 3191 3189 1425 +f 3190 3189 3191 +f 558 2791 3193 +f 2791 780 3192 +f 3193 3192 1006 +f 2791 3192 3193 +f 43 2901 3195 +f 2901 228 3194 +f 3195 3194 499 +f 2901 3194 3195 +f 499 3194 3196 +f 3194 228 3039 +f 3196 3039 572 +f 3194 3039 3196 +f 1096 3197 3198 +f 3197 378 2794 +f 3198 2794 1336 +f 3197 2794 3198 +f 43 3199 2904 +f 3199 73 3200 +f 2904 3200 178 +f 3199 3200 2904 +f 73 3199 3201 +f 3199 43 3195 +f 3201 3195 499 +f 3199 3195 3201 +f 379 3202 3203 +f 3202 1096 3198 +f 3203 3198 1336 +f 3202 3198 3203 +f 651 3204 3049 +f 3204 379 3203 +f 3049 3203 1336 +f 3204 3203 3049 +f 1067 3051 3206 +f 3051 621 3205 +f 3206 3205 1104 +f 3051 3205 3206 +f 1137 3207 2911 +f 3207 116 3208 +f 2911 3208 1434 +f 3207 3208 2911 +f 522 3056 2915 +f 3056 503 2659 +f 2915 2659 1431 +f 3056 2659 2915 +f 1060 2917 3209 +f 2917 1067 3206 +f 3209 3206 1104 +f 2917 3206 3209 +f 938 3210 3211 +f 3210 116 3207 +f 3211 3207 1137 +f 3210 3207 3211 +f 1021 3212 2913 +f 3212 938 3211 +f 2913 3211 1137 +f 3212 3211 2913 +f 552 3213 2801 +f 3213 665 3214 +f 2801 3214 668 +f 3213 3214 2801 +f 113 3215 3217 +f 3215 555 3216 +f 3217 3216 703 +f 3215 3216 3217 +f 113 3218 3215 +f 3218 126 2805 +f 3215 2805 555 +f 3218 2805 3215 +f 1263 3064 3220 +f 3064 1323 3219 +f 3220 3219 1429 +f 3064 3219 3220 +f 1323 2668 3219 +f 2668 1310 3221 +f 3219 3221 1429 +f 2668 3221 3219 +f 1310 3222 3221 +f 3222 837 3223 +f 3221 3223 1429 +f 3222 3223 3221 +f 825 3224 3225 +f 3224 531 2922 +f 3225 2922 1243 +f 3224 2922 3225 +f 192 2442 3072 +f 2442 754 3226 +f 3072 3226 1484 +f 2442 3226 3072 +f 968 3227 3228 +f 3227 1010 2926 +f 3228 2926 1341 +f 3227 2926 3228 +f 1078 3229 2691 +f 3229 131 2705 +f 2691 2705 1219 +f 3229 2705 2691 +f 679 2939 3231 +f 2939 776 3230 +f 3231 3230 1183 +f 2939 3230 3231 +f 464 2933 3233 +f 2933 1010 3232 +f 3233 3232 1083 +f 2933 3232 3233 +f 220 3234 3235 +f 3234 464 3233 +f 3235 3233 1083 +f 3234 3233 3235 +f 899 3236 3237 +f 3236 1026 2840 +f 3237 2840 1269 +f 3236 2840 3237 +f 464 3234 2944 +f 3234 220 3085 +f 2944 3085 1144 +f 3234 3085 2944 +f 1036 3238 3084 +f 3238 859 2957 +f 3084 2957 1144 +f 3238 2957 3084 +f 888 3093 3239 +f 3093 859 3238 +f 3239 3238 1036 +f 3093 3238 3239 +f 1145 3091 3241 +f 3091 430 3240 +f 3241 3240 1305 +f 3091 3240 3241 +f 430 3092 3240 +f 3092 620 3098 +f 3240 3098 1305 +f 3092 3098 3240 +f 799 3242 3243 +f 3242 1222 2978 +f 3243 2978 1230 +f 3242 2978 3243 +f 1324 3244 2851 +f 3244 210 3245 +f 2851 3245 1423 +f 3244 3245 2851 +f 370 2981 3247 +f 2981 529 3246 +f 3247 3246 879 +f 2981 3246 3247 +f 370 3247 2988 +f 3247 879 3248 +f 2988 3248 1337 +f 3247 3248 2988 +f 529 3104 3246 +f 3104 784 3249 +f 3246 3249 879 +f 3104 3249 3246 +f 879 3250 3248 +f 3250 954 3124 +f 3248 3124 1337 +f 3250 3124 3248 +f 211 3251 3253 +f 3251 387 3252 +f 3253 3252 879 +f 3251 3252 3253 +f 784 3108 3249 +f 3108 211 3253 +f 3249 3253 879 +f 3108 3253 3249 +f 1271 3254 2987 +f 3254 1307 3111 +f 2987 3111 1440 +f 3254 3111 2987 +f 1102 3128 3105 +f 3128 691 3255 +f 3105 3255 1271 +f 3128 3255 3105 +f 691 3256 3257 +f 3256 18 3126 +f 3257 3126 1307 +f 3256 3126 3257 +f 211 3112 3251 +f 3112 205 3131 +f 3251 3131 387 +f 3112 3131 3251 +f 18 3256 3135 +f 3256 691 3258 +f 3135 3258 725 +f 3256 3258 3135 +f 725 3258 3013 +f 3258 691 3130 +f 3013 3130 1044 +f 3258 3130 3013 +f 387 3133 3259 +f 3133 439 3136 +f 3259 3136 954 +f 3133 3136 3259 +f 227 3120 3137 +f 3120 376 3260 +f 3137 3260 929 +f 3120 3260 3137 +f 533 3139 3262 +f 3139 973 3261 +f 3262 3261 1131 +f 3139 3261 3262 +f 973 2878 3261 +f 2878 711 3263 +f 3261 3263 1131 +f 2878 3263 3261 +f 711 3017 3263 +f 3017 604 3264 +f 3263 3264 1131 +f 3017 3264 3263 +f 719 3265 3140 +f 3265 434 3266 +f 3140 3266 1280 +f 3265 3266 3140 +f 964 3267 3145 +f 3267 604 3018 +f 3145 3018 1059 +f 3267 3018 3145 +f 1280 3268 2880 +f 3268 622 3269 +f 2880 3269 1295 +f 3268 3269 2880 +f 964 3142 3270 +f 3142 234 3153 +f 3270 3153 1320 +f 3142 3153 3270 +f 622 3148 3269 +f 3148 706 3141 +f 3269 3141 1295 +f 3148 3141 3269 +f 629 3271 3152 +f 3271 446 3272 +f 3152 3272 1320 +f 3271 3272 3152 +f 788 3273 3275 +f 3273 1188 3274 +f 3275 3274 1231 +f 3273 3274 3275 +f 788 3275 3156 +f 3275 1231 3276 +f 3156 3276 1273 +f 3275 3276 3156 +f 518 3277 3161 +f 3277 47 3278 +f 3161 3278 990 +f 3277 3278 3161 +f 990 3278 3164 +f 3278 47 3279 +f 3164 3279 1180 +f 3278 3279 3164 +f 893 3280 3281 +f 3280 885 2895 +f 3281 2895 1468 +f 3280 2895 3281 +f 256 3282 3284 +f 3282 629 3283 +f 3284 3283 1180 +f 3282 3283 3284 +f 629 3159 3283 +f 3159 225 3165 +f 3283 3165 1180 +f 3159 3165 3283 +f 47 3277 3285 +f 3277 518 2890 +f 3285 2890 1028 +f 3277 2890 3285 +f 893 3286 3287 +f 3286 47 3285 +f 3287 3285 1028 +f 3286 3285 3287 +f 885 3280 3024 +f 3280 893 3287 +f 3024 3287 1028 +f 3280 3287 3024 +f 893 3281 3289 +f 3281 1468 3288 +f 3289 3288 1493 +f 3281 3288 3289 +f 1468 3163 3288 +f 3163 1273 3290 +f 3288 3290 1493 +f 3163 3290 3288 +f 1125 3291 3292 +f 3291 893 3289 +f 3292 3289 1493 +f 3291 3289 3292 +f 1493 3290 3294 +f 3290 1273 3293 +f 3294 3293 1500 +f 3290 3293 3294 +f 1180 3295 3167 +f 3295 1125 3296 +f 3167 3296 1278 +f 3295 3296 3167 +f 1452 3297 3170 +f 3297 1125 3292 +f 3170 3292 1493 +f 3297 3292 3170 +f 736 3298 3166 +f 3298 256 3284 +f 3166 3284 1180 +f 3298 3284 3166 +f 1300 3171 3299 +f 3171 1493 3294 +f 3299 3294 1500 +f 3171 3294 3299 +f 96 3300 3301 +f 3300 256 3298 +f 3301 3298 736 +f 3300 3298 3301 +f 187 3302 3303 +f 3302 1125 3297 +f 3303 3297 1452 +f 3302 3297 3303 +f 1125 3304 3296 +f 3304 351 3305 +f 3296 3305 1278 +f 3304 3305 3296 +f 96 3301 3306 +f 3301 736 3173 +f 3306 3173 1498 +f 3301 3173 3306 +f 133 3307 3308 +f 3307 187 3303 +f 3308 3303 1452 +f 3307 3303 3308 +f 207 3309 3310 +f 3309 133 3308 +f 3310 3308 1452 +f 3309 3308 3310 +f 1300 3311 3169 +f 3311 207 3310 +f 3169 3310 1452 +f 3311 3310 3169 +f 1237 3312 3313 +f 3312 207 3311 +f 3313 3311 1300 +f 3312 3311 3313 +f 1278 3305 3172 +f 3305 351 3314 +f 3172 3314 1498 +f 3305 3314 3172 +f 456 3026 2770 +f 3026 537 3315 +f 2770 3315 655 +f 3026 3315 2770 +f 655 3315 3028 +f 3315 537 3316 +f 3028 3316 1091 +f 3315 3316 3028 +f 70 3177 3178 +f 3177 627 3317 +f 3178 3317 1088 +f 3177 3317 3178 +f 1088 3318 3179 +f 3318 537 3027 +f 3179 3027 1446 +f 3318 3027 3179 +f 649 3319 2778 +f 3319 1146 3183 +f 2778 3183 1369 +f 3319 3183 2778 +f 69 3032 2774 +f 3032 895 3320 +f 2774 3320 1390 +f 3032 3320 2774 +f 1146 3319 3322 +f 3319 649 3321 +f 3322 3321 1321 +f 3319 3321 3322 +f 649 2785 3321 +f 2785 378 3323 +f 3321 3323 1321 +f 2785 3323 3321 +f 597 3324 3325 +f 3324 325 3191 +f 3325 3191 1425 +f 3324 3191 3325 +f 602 3326 2906 +f 3326 597 3325 +f 2906 3325 1425 +f 3326 3325 2906 +f 491 3327 3329 +f 3327 73 3328 +f 3329 3328 1256 +f 3327 3328 3329 +f 178 3200 3053 +f 3200 73 3327 +f 3053 3327 491 +f 3200 3327 3053 +f 597 3326 3330 +f 3326 602 3043 +f 3330 3043 1128 +f 3326 3043 3330 +f 938 3212 3332 +f 3212 1021 3331 +f 3332 3331 1108 +f 3212 3331 3332 +f 1021 3055 3331 +f 3055 1095 3333 +f 3331 3333 1108 +f 3055 3333 3331 +f 797 3334 3336 +f 3334 540 3335 +f 3336 3335 1153 +f 3334 3335 3336 +f 126 3337 2919 +f 3337 564 3338 +f 2919 3338 1152 +f 3337 3338 2919 +f 1152 3338 3065 +f 3338 564 3339 +f 3065 3339 1380 +f 3338 3339 3065 +f 1204 3340 3341 +f 3340 1345 3066 +f 3341 3066 1380 +f 3340 3066 3341 +f 1179 3070 2676 +f 3070 1157 3342 +f 2676 3342 1469 +f 3070 3342 2676 +f 987 3343 2921 +f 3343 837 3222 +f 2921 3222 1310 +f 3343 3222 2921 +f 74 3344 2812 +f 3344 624 3345 +f 2812 3345 1195 +f 3344 3345 2812 +f 754 3075 3226 +f 3075 281 3346 +f 3226 3346 1484 +f 3075 3346 3226 +f 968 3228 3347 +f 3228 1341 2810 +f 3347 2810 1345 +f 3228 2810 3347 +f 1204 3348 3340 +f 3348 968 3347 +f 3340 3347 1345 +f 3348 3347 3340 +f 838 2815 3350 +f 2815 531 3349 +f 3350 3349 1281 +f 2815 3349 3350 +f 624 3344 3351 +f 3344 74 2566 +f 3351 2566 1246 +f 3344 2566 3351 +f 1038 3352 2929 +f 3352 1065 3353 +f 2929 3353 1436 +f 3352 3353 2929 +f 679 3354 2924 +f 3354 330 3355 +f 2924 3355 987 +f 3354 3355 2924 +f 330 3354 3356 +f 3354 679 3231 +f 3356 3231 1183 +f 3354 3231 3356 +f 1010 3227 3232 +f 3227 968 3357 +f 3232 3357 1083 +f 3227 3357 3232 +f 385 2934 3359 +f 2934 245 3358 +f 3359 3358 768 +f 2934 3358 3359 +f 899 3360 3236 +f 3360 245 2941 +f 3236 2941 1026 +f 3360 2941 3236 +f 672 2954 3361 +f 2954 646 3082 +f 3361 3082 1411 +f 2954 3082 3361 +f 218 3086 2953 +f 3086 288 3362 +f 2953 3362 1269 +f 3086 3362 2953 +f 220 3363 3083 +f 3363 28 3364 +f 3083 3364 1036 +f 3363 3364 3083 +f 1207 3365 2977 +f 3365 1145 3241 +f 2977 3241 1305 +f 3365 3241 2977 +f 601 3096 3366 +f 3096 888 3239 +f 3366 3239 1036 +f 3096 3239 3366 +f 601 3367 3099 +f 3367 799 3243 +f 3099 3243 1230 +f 3367 3243 3099 +f 569 3100 3368 +f 3100 386 2848 +f 3368 2848 1423 +f 3100 2848 3368 +f 874 3369 3005 +f 3369 210 3244 +f 3005 3244 1324 +f 3369 3244 3005 +f 369 3370 3103 +f 3370 376 3122 +f 3103 3122 1490 +f 3370 3122 3103 +f 1271 3255 3254 +f 3255 691 3257 +f 3254 3257 1307 +f 3255 3257 3254 +f 879 3252 3250 +f 3252 387 3259 +f 3250 3259 954 +f 3252 3259 3250 +f 22 3371 3372 +f 3371 622 3268 +f 3372 3268 1280 +f 3371 3268 3372 +f 622 3371 3149 +f 3371 22 3373 +f 3149 3373 788 +f 3371 3373 3149 +f 1001 3374 3375 +f 3374 964 3270 +f 3375 3270 1320 +f 3374 3270 3375 +f 446 3271 3377 +f 3271 629 3376 +f 3377 3376 824 +f 3271 3376 3377 +f 1273 3276 3293 +f 3276 1231 3378 +f 3293 3378 1500 +f 3276 3378 3293 +f 629 3282 3376 +f 3282 256 3379 +f 3376 3379 824 +f 3282 3379 3376 +f 824 3379 3381 +f 3379 256 3380 +f 3381 3380 848 +f 3379 3380 3381 +f 47 3382 3279 +f 3382 1125 3295 +f 3279 3295 1180 +f 3382 3295 3279 +f 47 3286 3382 +f 3286 893 3291 +f 3382 3291 1125 +f 3286 3291 3382 +f 256 3300 3380 +f 3300 96 3383 +f 3380 3383 848 +f 3300 3383 3380 +f 362 3384 3386 +f 3384 179 3385 +f 3386 3385 1300 +f 3384 3385 3386 +f 848 3383 3388 +f 3383 96 3387 +f 3388 3387 1004 +f 3383 3387 3388 +f 187 3389 3302 +f 3389 351 3304 +f 3302 3304 1125 +f 3389 3304 3302 +f 1004 3387 3390 +f 3387 96 3306 +f 3390 3306 1498 +f 3387 3306 3390 +f 351 3389 3392 +f 3389 187 3391 +f 3392 3391 631 +f 3389 3391 3392 +f 179 3393 3385 +f 3393 1237 3313 +f 3385 3313 1300 +f 3393 3313 3385 +f 187 3307 3391 +f 3307 133 3394 +f 3391 3394 631 +f 3307 3394 3391 +f 252 3395 3397 +f 3395 605 3396 +f 3397 3396 1498 +f 3395 3396 3397 +f 351 3398 3314 +f 3398 252 3397 +f 3314 3397 1498 +f 3398 3397 3314 +f 631 3394 3400 +f 3394 133 3399 +f 3400 3399 647 +f 3394 3399 3400 +f 133 3309 3399 +f 3309 207 3401 +f 3399 3401 647 +f 3309 3401 3399 +f 537 3402 3316 +f 3402 77 3403 +f 3316 3403 1091 +f 3402 3403 3316 +f 895 3404 3320 +f 3404 1090 3033 +f 3320 3033 1390 +f 3404 3033 3320 +f 480 3182 3406 +f 3182 51 3405 +f 3406 3405 1370 +f 3182 3405 3406 +f 1146 3407 3184 +f 3407 681 3408 +f 3184 3408 1413 +f 3407 3408 3184 +f 780 2637 3409 +f 2637 480 3406 +f 3409 3406 1370 +f 2637 3406 3409 +f 325 3324 3411 +f 3324 597 3410 +f 3411 3410 1008 +f 3324 3410 3411 +f 558 3193 3041 +f 3193 1006 3412 +f 3041 3412 1194 +f 3193 3412 3041 +f 116 3413 3208 +f 3413 1402 3414 +f 3208 3414 1434 +f 3413 3414 3208 +f 9 3415 3416 +f 3415 522 2914 +f 3416 2914 1060 +f 3415 2914 3416 +f 116 3210 3413 +f 3210 938 3417 +f 3413 3417 1402 +f 3210 3417 3413 +f 483 3418 3419 +f 3418 1060 3209 +f 3419 3209 1104 +f 3418 3209 3419 +f 1182 3420 3422 +f 3420 757 3421 +f 3422 3421 1372 +f 3420 3421 3422 +f 757 3420 3423 +f 3420 1182 3063 +f 3423 3063 1263 +f 3420 3063 3423 +f 126 3218 3337 +f 3218 113 3424 +f 3337 3424 564 +f 3218 3424 3337 +f 757 3423 3425 +f 3423 1263 3220 +f 3425 3220 1429 +f 3423 3220 3425 +f 281 3074 3426 +f 3074 270 3078 +f 3426 3078 547 +f 3074 3078 3426 +f 1078 3077 3428 +f 3077 838 3427 +f 3428 3427 1353 +f 3077 3427 3428 +f 1038 3429 3352 +f 3429 545 3430 +f 3352 3430 1065 +f 3429 3430 3352 +f 968 3431 3357 +f 3431 193 3432 +f 3357 3432 1083 +f 3431 3432 3357 +f 385 3359 2818 +f 3359 768 3433 +f 2818 3433 1246 +f 3359 3433 2818 +f 245 3434 3358 +f 3434 12 3435 +f 3358 3435 768 +f 3434 3435 3358 +f 12 3434 3436 +f 3434 245 3360 +f 3436 3360 899 +f 3434 3360 3436 +f 380 2829 3438 +f 2829 1121 3437 +f 3438 3437 1385 +f 2829 3437 3438 +f 103 3439 3440 +f 3439 601 3366 +f 3440 3366 1036 +f 3439 3366 3440 +f 569 3441 3101 +f 3441 54 3442 +f 3101 3442 1207 +f 3441 3442 3101 +f 601 3439 3367 +f 3439 103 3443 +f 3367 3443 799 +f 3439 3443 3367 +f 530 3444 3445 +f 3444 569 3368 +f 3445 3368 1423 +f 3444 3368 3445 +f 210 3446 3245 +f 3446 530 3445 +f 3245 3445 1423 +f 3446 3445 3245 +f 799 3447 3242 +f 3447 600 3448 +f 3242 3448 1222 +f 3447 3448 3242 +f 600 3449 3448 +f 3449 369 3102 +f 3448 3102 1222 +f 3449 3102 3448 +f 929 3260 3451 +f 3260 376 3450 +f 3451 3450 1138 +f 3260 3450 3451 +f 1025 3452 3453 +f 3452 533 3262 +f 3453 3262 1131 +f 3452 3262 3453 +f 434 3265 3455 +f 3265 719 3454 +f 3455 3454 980 +f 3265 3454 3455 +f 604 3456 3264 +f 3456 123 3457 +f 3264 3457 1131 +f 3456 3457 3264 +f 123 3458 3459 +f 3458 964 3374 +f 3459 3374 1001 +f 3458 3374 3459 +f 123 3456 3458 +f 3456 604 3267 +f 3458 3267 964 +f 3456 3267 3458 +f 434 3460 3266 +f 3460 814 3461 +f 3266 3461 1280 +f 3460 3461 3266 +f 814 3462 3461 +f 3462 22 3372 +f 3461 3372 1280 +f 3462 3372 3461 +f 788 3463 3273 +f 3463 814 3464 +f 3273 3464 1188 +f 3463 3464 3273 +f 788 3373 3463 +f 3373 22 3462 +f 3463 3462 814 +f 3373 3462 3463 +f 446 3465 3272 +f 3465 534 3466 +f 3272 3466 1320 +f 3465 3466 3272 +f 1188 3467 3274 +f 3467 349 3468 +f 3274 3468 1231 +f 3467 3468 3274 +f 1231 3469 3378 +f 3469 184 3470 +f 3378 3470 1500 +f 3469 3470 3378 +f 362 3386 3471 +f 3386 1300 3299 +f 3471 3299 1500 +f 3386 3299 3471 +f 199 3472 3473 +f 3472 207 3312 +f 3473 3312 1237 +f 3472 3312 3473 +f 605 3474 3396 +f 3474 261 3475 +f 3396 3475 1498 +f 3474 3475 3396 +f 207 3472 3401 +f 3472 199 3476 +f 3401 3476 647 +f 3472 3476 3401 +f 252 3477 3395 +f 3477 373 3478 +f 3395 3478 605 +f 3477 3478 3395 +f 252 3479 3481 +f 3479 631 3480 +f 3481 3480 714 +f 3479 3480 3481 +f 252 3398 3479 +f 3398 351 3392 +f 3479 3392 631 +f 3398 3392 3479 +f 895 3482 3404 +f 3482 585 3035 +f 3404 3035 1090 +f 3482 3035 3404 +f 321 3483 3484 +f 3483 51 3181 +f 3484 3181 1091 +f 3483 3181 3484 +f 556 3485 3486 +f 3485 895 3186 +f 3486 3186 1413 +f 3485 3186 3486 +f 383 3487 3488 +f 3487 585 3482 +f 3488 3482 895 +f 3487 3482 3488 +f 585 3487 3036 +f 3487 383 3489 +f 3036 3489 762 +f 3487 3489 3036 +f 1006 3192 3490 +f 3192 780 3409 +f 3490 3409 1370 +f 3192 3409 3490 +f 762 3489 3492 +f 3489 383 3491 +f 3492 3491 1167 +f 3489 3491 3492 +f 572 3040 3493 +f 3040 762 3492 +f 3493 3492 1167 +f 3040 3492 3493 +f 913 3190 3494 +f 3190 325 3411 +f 3494 3411 1008 +f 3190 3411 3494 +f 499 3196 3495 +f 3196 572 3493 +f 3495 3493 1167 +f 3196 3493 3495 +f 378 3197 3323 +f 3197 1096 3496 +f 3323 3496 1321 +f 3197 3496 3323 +f 857 3497 3498 +f 3497 499 3495 +f 3498 3495 1167 +f 3497 3495 3498 +f 73 3201 3499 +f 3201 499 3497 +f 3499 3497 857 +f 3201 3497 3499 +f 694 3500 3501 +f 3500 597 3330 +f 3501 3330 1128 +f 3500 3330 3501 +f 522 3415 3503 +f 3415 9 3502 +f 3503 3502 941 +f 3415 3502 3503 +f 363 3057 3504 +f 3057 522 3503 +f 3504 3503 941 +f 3057 3503 3504 +f 350 3505 3506 +f 3505 938 3332 +f 3506 3332 1108 +f 3505 3332 3506 +f 598 3507 3508 +f 3507 9 3416 +f 3508 3416 1060 +f 3507 3416 3508 +f 483 3509 3418 +f 3509 598 3508 +f 3418 3508 1060 +f 3509 3508 3418 +f 621 3050 3511 +f 3050 491 3510 +f 3511 3510 933 +f 3050 3510 3511 +f 621 3512 3205 +f 3512 88 3513 +f 3205 3513 1104 +f 3512 3513 3205 +f 134 3514 3516 +f 3514 843 3515 +f 3516 3515 1434 +f 3514 3515 3516 +f 498 3517 3519 +f 3517 734 3518 +f 3519 3518 908 +f 3517 3518 3519 +f 734 3520 3518 +f 3520 639 3521 +f 3518 3521 908 +f 3520 3521 3518 +f 843 3522 3524 +f 3522 696 3523 +f 3524 3523 1135 +f 3522 3523 3524 +f 748 3525 3527 +f 3525 727 3526 +f 3527 3526 833 +f 3525 3526 3527 +f 611 3528 3530 +f 3528 908 3529 +f 3530 3529 1451 +f 3528 3529 3530 +f 398 3531 3533 +f 3531 635 3532 +f 3533 3532 1282 +f 3531 3532 3533 +f 63 3534 3536 +f 3534 635 3535 +f 3536 3535 748 +f 3534 3535 3536 +f 1186 3537 3539 +f 3537 674 3538 +f 3539 3538 1227 +f 3537 3538 3539 +f 674 3540 3538 +f 3540 462 3541 +f 3538 3541 1227 +f 3540 3541 3538 +f 566 3542 3544 +f 3542 815 3543 +f 3544 3543 1077 +f 3542 3543 3544 +f 235 3545 3547 +f 3545 797 3546 +f 3547 3546 984 +f 3545 3546 3547 +f 996 3548 3549 +f 3548 1186 3539 +f 3549 3539 1227 +f 3548 3539 3549 +f 366 3550 3552 +f 3550 462 3551 +f 3552 3551 1011 +f 3550 3551 3552 +f 462 3550 3554 +f 3550 366 3553 +f 3554 3553 1046 +f 3550 3553 3554 +f 113 3217 3556 +f 3217 703 3555 +f 3556 3555 1472 +f 3217 3555 3556 +f 465 3557 3558 +f 3557 1204 3341 +f 3558 3341 1380 +f 3557 3341 3558 +f 206 3559 3068 +f 3559 156 3560 +f 3068 3560 1157 +f 3559 3560 3068 +f 156 3559 3561 +f 3559 206 3073 +f 3561 3073 1484 +f 3559 3073 3561 +f 1195 3562 2814 +f 3562 825 3225 +f 2814 3225 1243 +f 3562 3225 2814 +f 531 3224 3349 +f 3224 825 3563 +f 3349 3563 1281 +f 3224 3563 3349 +f 330 3564 3355 +f 3564 292 3565 +f 3355 3565 987 +f 3564 3565 3355 +f 292 3566 3565 +f 3566 837 3343 +f 3565 3343 987 +f 3566 3343 3565 +f 193 3431 3567 +f 3431 968 3348 +f 3567 3348 1204 +f 3431 3348 3567 +f 1245 3568 3570 +f 3568 545 3569 +f 3570 3569 1469 +f 3568 3569 3570 +f 545 3429 3569 +f 3429 1038 3076 +f 3569 3076 1469 +f 3429 3076 3569 +f 1246 3433 3572 +f 3433 768 3571 +f 3572 3571 1311 +f 3433 3571 3572 +f 168 3573 2822 +f 3573 547 3079 +f 2822 3079 1129 +f 3573 3079 2822 +f 131 3574 3576 +f 3574 146 3575 +f 3576 3575 613 +f 3574 3575 3576 +f 146 3574 3577 +f 3574 131 3229 +f 3577 3229 1078 +f 3574 3229 3577 +f 1065 3578 3353 +f 3578 20 3579 +f 3353 3579 1436 +f 3578 3579 3353 +f 20 3580 3579 +f 3580 411 3581 +f 3579 3581 1436 +f 3580 3581 3579 +f 411 3582 3581 +f 3582 594 2938 +f 3581 2938 1436 +f 3582 2938 3581 +f 594 3582 2947 +f 3582 411 3583 +f 2947 3583 1411 +f 3582 3583 2947 +f 1121 3081 3437 +f 3081 672 3584 +f 3437 3584 1385 +f 3081 3584 3437 +f 1181 3585 3586 +f 3585 672 3361 +f 3586 3361 1411 +f 3585 3361 3586 +f 672 3585 3584 +f 3585 1181 3587 +f 3584 3587 1385 +f 3585 3587 3584 +f 220 3235 3589 +f 3235 1083 3588 +f 3589 3588 1454 +f 3235 3588 3589 +f 1183 3230 3591 +f 3230 776 3590 +f 3591 3590 1487 +f 3230 3590 3591 +f 776 3592 3590 +f 3592 468 3593 +f 3590 3593 1487 +f 3592 3593 3590 +f 502 3594 3595 +f 3594 220 3589 +f 3595 3589 1454 +f 3594 3589 3595 +f 28 3363 3596 +f 3363 220 3594 +f 3596 3594 502 +f 3363 3594 3596 +f 468 3592 3597 +f 3592 776 3089 +f 3597 3089 1145 +f 3592 3089 3597 +f 54 3598 3442 +f 3598 1145 3365 +f 3442 3365 1207 +f 3598 3365 3442 +f 530 3446 3600 +f 3446 210 3599 +f 3600 3599 628 +f 3446 3599 3600 +f 628 3601 3603 +f 3601 874 3602 +f 3603 3602 1408 +f 3601 3602 3603 +f 874 3138 3602 +f 3138 533 3604 +f 3602 3604 1408 +f 3138 3604 3602 +f 533 3452 3604 +f 3452 1025 3605 +f 3604 3605 1408 +f 3452 3605 3604 +f 980 3606 3607 +f 3606 929 3451 +f 3607 3451 1138 +f 3606 3451 3607 +f 719 3016 3454 +f 3016 929 3606 +f 3454 3606 980 +f 3016 3606 3454 +f 123 3608 3457 +f 3608 1025 3453 +f 3457 3453 1131 +f 3608 3453 3457 +f 534 3609 3466 +f 3609 1001 3375 +f 3466 3375 1320 +f 3609 3375 3466 +f 279 3610 3611 +f 3610 446 3377 +f 3611 3377 824 +f 3610 3377 3611 +f 824 3381 3613 +f 3381 848 3612 +f 3613 3612 1234 +f 3381 3612 3613 +f 184 3614 3470 +f 3614 362 3471 +f 3470 3471 1500 +f 3614 3471 3470 +f 848 3615 3612 +f 3615 482 3616 +f 3612 3616 1234 +f 3615 3616 3612 +f 179 3384 3618 +f 3384 362 3617 +f 3618 3617 882 +f 3384 3617 3618 +f 482 3615 3619 +f 3615 848 3388 +f 3619 3388 1004 +f 3615 3388 3619 +f 179 3618 3393 +f 3618 882 3620 +f 3393 3620 1237 +f 3618 3620 3393 +f 616 3621 3622 +f 3621 199 3473 +f 3622 3473 1237 +f 3621 3473 3622 +f 261 3623 3475 +f 3623 1004 3390 +f 3475 3390 1498 +f 3623 3390 3475 +f 631 3400 3480 +f 3400 647 3624 +f 3480 3624 714 +f 3400 3624 3480 +f 373 3477 3625 +f 3477 252 3481 +f 3625 3481 714 +f 3477 3481 3625 +f 90 3626 3627 +f 3626 77 3402 +f 3627 3402 537 +f 3626 3402 3627 +f 128 3628 3629 +f 3628 627 3176 +f 3629 3176 1329 +f 3628 3176 3629 +f 627 3628 3317 +f 3628 128 3630 +f 3317 3630 1088 +f 3628 3630 3317 +f 51 3483 3405 +f 3483 321 3631 +f 3405 3631 1370 +f 3483 3631 3405 +f 681 3632 3408 +f 3632 404 3633 +f 3408 3633 1413 +f 3632 3633 3408 +f 913 3634 3188 +f 3634 487 3635 +f 3188 3635 1329 +f 3634 3635 3188 +f 487 3636 3635 +f 3636 128 3629 +f 3635 3629 1329 +f 3636 3629 3635 +f 487 3634 3637 +f 3634 913 3494 +f 3637 3494 1008 +f 3634 3494 3637 +f 1006 3638 3412 +f 3638 6 3639 +f 3412 3639 1194 +f 3638 3639 3412 +f 195 3640 3641 +f 3640 379 3204 +f 3641 3204 651 +f 3640 3204 3641 +f 472 3642 3643 +f 3642 1095 3045 +f 3643 3045 1194 +f 3642 3045 3643 +f 1095 3644 3333 +f 3644 977 3645 +f 3333 3645 1108 +f 3644 3645 3333 +f 1128 3646 3648 +f 3646 843 3647 +f 3648 3647 1494 +f 3646 3647 3648 +f 350 3649 3651 +f 3649 970 3650 +f 3651 3650 1402 +f 3649 3650 3651 +f 596 3652 3654 +f 3652 498 3653 +f 3654 3653 1444 +f 3652 3653 3654 +f 364 3655 3656 +f 3655 498 3519 +f 3656 3519 908 +f 3655 3519 3656 +f 833 3526 3658 +f 3526 727 3657 +f 3658 3657 970 +f 3526 3657 3658 +f 498 3655 3653 +f 3655 364 3659 +f 3653 3659 1444 +f 3655 3659 3653 +f 864 3660 3661 +f 3660 843 3524 +f 3661 3524 1135 +f 3660 3524 3661 +f 740 3662 3664 +f 3662 289 3663 +f 3664 3663 1352 +f 3662 3663 3664 +f 635 3665 3532 +f 3665 1186 3666 +f 3532 3666 1282 +f 3665 3666 3532 +f 635 3667 3665 +f 3667 826 3668 +f 3665 3668 1186 +f 3667 3668 3665 +f 826 3669 3668 +f 3669 674 3537 +f 3668 3537 1186 +f 3669 3537 3668 +f 815 3542 3671 +f 3542 566 3670 +f 3671 3670 1451 +f 3542 3670 3671 +f 996 3672 3548 +f 3672 412 3673 +f 3548 3673 1186 +f 3672 3673 3548 +f 462 3540 3551 +f 3540 674 3674 +f 3551 3674 1011 +f 3540 3674 3551 +f 682 3675 3677 +f 3675 868 3676 +f 3677 3676 1153 +f 3675 3676 3677 +f 978 3678 3679 +f 3678 757 3425 +f 3679 3425 1429 +f 3678 3425 3679 +f 1429 3680 3682 +f 3680 861 3681 +f 3682 3681 1479 +f 3680 3681 3682 +f 292 3683 3684 +f 3683 861 3680 +f 3684 3680 1429 +f 3683 3680 3684 +f 837 3566 3223 +f 3566 292 3684 +f 3223 3684 1429 +f 3566 3684 3223 +f 281 3685 3346 +f 3685 553 3686 +f 3346 3686 1484 +f 3685 3686 3346 +f 452 3687 3688 +f 3687 624 3351 +f 3688 3351 1246 +f 3687 3351 3688 +f 281 3426 3690 +f 3426 547 3689 +f 3690 3689 1366 +f 3426 3689 3690 +f 452 3688 3691 +f 3688 1246 3572 +f 3691 3572 1311 +f 3688 3572 3691 +f 768 3692 3694 +f 3692 1116 3693 +f 3694 3693 1437 +f 3692 3693 3694 +f 20 3578 3696 +f 3578 1065 3695 +f 3696 3695 1396 +f 3578 3695 3696 +f 1116 3697 3699 +f 3697 12 3698 +f 3699 3698 1191 +f 3697 3698 3699 +f 768 3435 3692 +f 3435 12 3697 +f 3692 3697 1116 +f 3435 3697 3692 +f 198 2945 3700 +f 2945 131 3576 +f 3700 3576 613 +f 2945 3576 3700 +f 411 3580 3701 +f 3580 20 3696 +f 3701 3696 1396 +f 3580 3696 3701 +f 884 3702 3703 +f 3702 411 3701 +f 3703 3701 1396 +f 3702 3701 3703 +f 12 3436 3698 +f 3436 899 3704 +f 3698 3704 1191 +f 3436 3704 3698 +f 411 3702 3706 +f 3702 884 3705 +f 3706 3705 1181 +f 3702 3705 3706 +f 411 3706 3583 +f 3706 1181 3586 +f 3583 3586 1411 +f 3706 3586 3583 +f 174 3707 3708 +f 3707 899 3237 +f 3708 3237 1269 +f 3707 3237 3708 +f 203 3709 3710 +f 3709 174 3708 +f 3710 3708 1269 +f 3709 3708 3710 +f 288 3711 3362 +f 3711 203 3710 +f 3362 3710 1269 +f 3711 3710 3362 +f 28 3596 3364 +f 3596 502 3712 +f 3364 3712 1036 +f 3596 3712 3364 +f 54 3713 3598 +f 3713 336 3714 +f 3598 3714 1145 +f 3713 3714 3598 +f 530 3715 3444 +f 3715 54 3441 +f 3444 3441 569 +f 3715 3441 3444 +f 103 3716 3443 +f 3716 600 3447 +f 3443 3447 799 +f 3716 3447 3443 +f 376 3370 3717 +f 3370 369 3449 +f 3717 3449 600 +f 3370 3449 3717 +f 376 3717 3450 +f 3717 600 3718 +f 3450 3718 1138 +f 3717 3718 3450 +f 628 3599 3601 +f 3599 210 3369 +f 3601 3369 874 +f 3599 3369 3601 +f 534 3719 3609 +f 3719 428 3720 +f 3609 3720 1001 +f 3719 3720 3609 +f 446 3610 3465 +f 3610 279 3721 +f 3465 3721 534 +f 3610 3721 3465 +f 349 3722 3468 +f 3722 184 3469 +f 3468 3469 1231 +f 3722 3469 3468 +f 279 3611 3723 +f 3611 824 3613 +f 3723 3613 1234 +f 3611 3613 3723 +f 362 3724 3617 +f 3724 810 3725 +f 3617 3725 882 +f 3724 3725 3617 +f 670 3726 3727 +f 3726 482 3619 +f 3727 3619 1004 +f 3726 3619 3727 +f 261 3728 3623 +f 3728 670 3727 +f 3623 3727 1004 +f 3728 3727 3623 +f 209 3729 3730 +f 3729 261 3474 +f 3730 3474 605 +f 3729 3474 3730 +f 605 3478 3732 +f 3478 373 3731 +f 3732 3731 643 +f 3478 3731 3732 +f 209 3730 3733 +f 3730 605 3732 +f 3733 3732 643 +f 3730 3732 3733 +f 647 3734 3624 +f 3734 449 3735 +f 3624 3735 714 +f 3734 3735 3624 +f 889 3736 3737 +f 3736 537 3318 +f 3737 3318 1088 +f 3736 3318 3737 +f 77 3738 3403 +f 3738 581 3739 +f 3403 3739 1091 +f 3738 3739 3403 +f 556 3740 3742 +f 3740 404 3741 +f 3742 3741 680 +f 3740 3741 3742 +f 404 3740 3633 +f 3740 556 3486 +f 3633 3486 1413 +f 3740 3486 3633 +f 581 3743 3739 +f 3743 321 3484 +f 3739 3484 1091 +f 3743 3484 3739 +f 379 3744 3202 +f 3744 972 3745 +f 3202 3745 1096 +f 3744 3745 3202 +f 73 3499 3328 +f 3499 857 3746 +f 3328 3746 1256 +f 3499 3746 3328 +f 363 3747 3048 +f 3747 489 3748 +f 3048 3748 651 +f 3747 3748 3048 +f 489 3749 3748 +f 3749 195 3641 +f 3748 3641 651 +f 3749 3641 3748 +f 472 3750 3642 +f 3750 977 3644 +f 3642 3644 1095 +f 3750 3644 3642 +f 489 3747 3751 +f 3747 363 3504 +f 3751 3504 941 +f 3747 3504 3751 +f 9 3507 3502 +f 3507 598 3752 +f 3502 3752 941 +f 3507 3752 3502 +f 808 3753 3754 +f 3753 350 3506 +f 3754 3506 1108 +f 3753 3506 3754 +f 364 3755 3659 +f 3755 685 3756 +f 3659 3756 1444 +f 3755 3756 3659 +f 826 3757 3759 +f 3757 63 3758 +f 3759 3758 833 +f 3757 3758 3759 +f 588 3760 3761 +f 3760 674 3669 +f 3761 3669 826 +f 3760 3669 3761 +f 412 3762 3764 +f 3762 662 3763 +f 3764 3763 1282 +f 3762 3763 3764 +f 648 3765 3767 +f 3765 396 3766 +f 3767 3766 1312 +f 3765 3766 3767 +f 396 3768 3766 +f 3768 984 3769 +f 3766 3769 1312 +f 3768 3769 3766 +f 674 3760 3771 +f 3760 588 3770 +f 3771 3770 1395 +f 3760 3770 3771 +f 366 3552 3773 +f 3552 1011 3772 +f 3773 3772 1354 +f 3552 3772 3773 +f 703 3774 3555 +f 3774 815 3775 +f 3555 3775 1472 +f 3774 3775 3555 +f 564 3776 3339 +f 3776 673 3777 +f 3339 3777 1380 +f 3776 3777 3339 +f 673 3778 3777 +f 3778 497 3779 +f 3777 3779 1380 +f 3778 3779 3777 +f 497 3780 3779 +f 3780 465 3558 +f 3779 3558 1380 +f 3780 3558 3779 +f 1157 3781 3342 +f 3781 310 3782 +f 3342 3782 1469 +f 3781 3782 3342 +f 825 3783 3563 +f 3783 314 3784 +f 3563 3784 1281 +f 3783 3784 3563 +f 553 3685 3785 +f 3685 281 3690 +f 3785 3690 1366 +f 3685 3690 3785 +f 1311 3571 3786 +f 3571 768 3694 +f 3786 3694 1437 +f 3571 3694 3786 +f 1065 3430 3788 +f 3430 545 3787 +f 3788 3787 1365 +f 3430 3787 3788 +f 146 3577 3789 +f 3577 1078 3428 +f 3789 3428 1353 +f 3577 3428 3789 +f 975 3790 3791 +f 3790 1065 3788 +f 3791 3788 1365 +f 3790 3788 3791 +f 1083 3432 3793 +f 3432 193 3792 +f 3793 3792 1441 +f 3432 3792 3793 +f 460 3794 3795 +f 3794 330 3356 +f 3795 3356 1183 +f 3794 3356 3795 +f 1065 3790 3695 +f 3790 975 3796 +f 3695 3796 1396 +f 3790 3796 3695 +f 460 3795 3797 +f 3795 1183 3591 +f 3797 3591 1487 +f 3795 3591 3797 +f 1083 3793 3588 +f 3793 1441 3798 +f 3588 3798 1454 +f 3793 3798 3588 +f 100 3799 3800 +f 3799 884 3703 +f 3800 3703 1396 +f 3799 3703 3800 +f 899 3801 3704 +f 3801 448 3802 +f 3704 3802 1191 +f 3801 3802 3704 +f 884 3803 3705 +f 3803 948 3804 +f 3705 3804 1181 +f 3803 3804 3705 +f 174 3805 3707 +f 3805 448 3801 +f 3707 3801 899 +f 3805 3801 3707 +f 855 3806 3807 +f 3806 502 3595 +f 3807 3595 1454 +f 3806 3595 3807 +f 1036 3712 3809 +f 3712 502 3808 +f 3809 3808 1290 +f 3712 3808 3809 +f 336 3810 3714 +f 3810 468 3597 +f 3714 3597 1145 +f 3810 3597 3714 +f 103 3440 3811 +f 3440 1036 3809 +f 3811 3809 1290 +f 3440 3809 3811 +f 600 3716 3812 +f 3716 103 3811 +f 3812 3811 1290 +f 3716 3811 3812 +f 123 3459 3608 +f 3459 1001 3813 +f 3608 3813 1025 +f 3459 3813 3608 +f 814 3460 3814 +f 3460 434 3455 +f 3814 3455 980 +f 3460 3455 3814 +f 814 3815 3464 +f 3815 701 3816 +f 3464 3816 1188 +f 3815 3816 3464 +f 701 3817 3816 +f 3817 349 3467 +f 3816 3467 1188 +f 3817 3467 3816 +f 293 3818 3819 +f 3818 184 3722 +f 3819 3722 349 +f 3818 3722 3819 +f 362 3614 3724 +f 3614 184 3820 +f 3724 3820 810 +f 3614 3820 3724 +f 482 3726 3822 +f 3726 670 3821 +f 3822 3821 1213 +f 3726 3821 3822 +f 608 3823 3825 +f 3823 616 3824 +f 3825 3824 882 +f 3823 3824 3825 +f 882 3824 3620 +f 3824 616 3622 +f 3620 3622 1237 +f 3824 3622 3620 +f 199 3621 3827 +f 3621 616 3826 +f 3827 3826 1033 +f 3621 3826 3827 +f 199 3828 3476 +f 3828 449 3734 +f 3476 3734 647 +f 3828 3734 3476 +f 643 3829 3831 +f 3829 869 3830 +f 3831 3830 1160 +f 3829 3830 3831 +f 643 3731 3829 +f 3731 373 3832 +f 3829 3832 869 +f 3731 3832 3829 +f 38 3833 3834 +f 3833 373 3625 +f 3834 3625 714 +f 3833 3625 3834 +f 373 3833 3832 +f 3833 38 3835 +f 3832 3835 869 +f 3833 3835 3832 +f 38 3834 3837 +f 3834 714 3836 +f 3837 3836 945 +f 3834 3836 3837 +f 177 3838 3840 +f 3838 383 3839 +f 3840 3839 1286 +f 3838 3839 3840 +f 487 3637 3842 +f 3637 1008 3841 +f 3842 3841 1190 +f 3637 3841 3842 +f 1008 3843 3841 +f 3843 694 3844 +f 3841 3844 1190 +f 3843 3844 3841 +f 597 3500 3410 +f 3500 694 3843 +f 3410 3843 1008 +f 3500 3843 3410 +f 379 3640 3744 +f 3640 195 3845 +f 3744 3845 972 +f 3640 3845 3744 +f 1256 3746 3847 +f 3746 857 3846 +f 3847 3846 1491 +f 3746 3846 3847 +f 410 3848 3849 +f 3848 694 3501 +f 3849 3501 1128 +f 3848 3501 3849 +f 598 3850 3752 +f 3850 685 3851 +f 3752 3851 941 +f 3850 3851 3752 +f 1376 3852 3853 +f 3852 978 3679 +f 3853 3679 1429 +f 3852 3679 3853 +f 465 3854 3557 +f 3854 352 3855 +f 3557 3855 1204 +f 3854 3855 3557 +f 360 3856 3857 +f 3856 156 3561 +f 3857 3561 1484 +f 3856 3561 3857 +f 156 3858 3560 +f 3858 310 3781 +f 3560 3781 1157 +f 3858 3781 3560 +f 1052 3859 3860 +f 3859 825 3562 +f 3860 3562 1195 +f 3859 3562 3860 +f 624 3861 3345 +f 3861 422 3862 +f 3345 3862 1195 +f 3861 3862 3345 +f 292 3564 3683 +f 3564 330 3863 +f 3683 3863 861 +f 3564 3863 3683 +f 838 3350 3427 +f 3350 1281 3864 +f 3427 3864 1353 +f 3350 3864 3427 +f 545 3568 3787 +f 3568 1245 3865 +f 3787 3865 1365 +f 3568 3865 3787 +f 547 3573 3866 +f 3573 168 3080 +f 3866 3080 1244 +f 3573 3080 3866 +f 380 3867 2942 +f 3867 1085 3868 +f 2942 3868 1244 +f 3867 3868 2942 +f 975 3869 3796 +f 3869 1087 3870 +f 3796 3870 1396 +f 3869 3870 3796 +f 1389 3871 3873 +f 3871 1116 3872 +f 3873 3872 1405 +f 3871 3872 3873 +f 1116 3871 3693 +f 3871 1389 3874 +f 3693 3874 1437 +f 3871 3874 3693 +f 1087 3875 3870 +f 3875 100 3800 +f 3870 3800 1396 +f 3875 3800 3870 +f 1116 3699 3872 +f 3699 1191 3876 +f 3872 3876 1405 +f 3699 3876 3872 +f 198 3877 2949 +f 3877 731 3878 +f 2949 3878 992 +f 3877 3878 2949 +f 528 3879 3880 +f 3879 288 3088 +f 3880 3088 992 +f 3879 3088 3880 +f 731 3881 3878 +f 3881 528 3880 +f 3878 3880 992 +f 3881 3880 3878 +f 884 3882 3803 +f 3882 272 3883 +f 3803 3883 948 +f 3882 3883 3803 +f 448 3805 3885 +f 3805 174 3884 +f 3885 3884 463 +f 3805 3884 3885 +f 174 3709 3884 +f 3709 203 3886 +f 3884 3886 463 +f 3709 3886 3884 +f 203 3711 3887 +f 3711 288 3879 +f 3887 3879 528 +f 3711 3879 3887 +f 468 3888 3593 +f 3888 382 3889 +f 3593 3889 1487 +f 3888 3889 3593 +f 502 3806 3808 +f 3806 855 3890 +f 3808 3890 1290 +f 3806 3890 3808 +f 336 3713 3892 +f 3713 54 3891 +f 3892 3891 1331 +f 3713 3891 3892 +f 54 3715 3893 +f 3715 530 3600 +f 3893 3600 628 +f 3715 3600 3893 +f 54 3893 3891 +f 3893 628 3894 +f 3891 3894 1331 +f 3893 3894 3891 +f 1001 3720 3813 +f 3720 428 3895 +f 3813 3895 1025 +f 3720 3895 3813 +f 814 3814 3896 +f 3814 980 3607 +f 3896 3607 1138 +f 3814 3607 3896 +f 279 3897 3721 +f 3897 428 3719 +f 3721 3719 534 +f 3897 3719 3721 +f 293 3819 3898 +f 3819 349 3817 +f 3898 3817 701 +f 3819 3817 3898 +f 184 3818 3820 +f 3818 293 3899 +f 3820 3899 810 +f 3818 3899 3820 +f 261 3729 3728 +f 3729 209 3900 +f 3728 3900 670 +f 3729 3900 3728 +f 449 3828 3901 +f 3828 199 3827 +f 3901 3827 1033 +f 3828 3827 3901 +f 449 3901 3903 +f 3901 1033 3902 +f 3903 3902 1293 +f 3901 3902 3903 +f 714 3735 3836 +f 3735 449 3904 +f 3836 3904 945 +f 3735 3904 3836 +f 945 3904 3905 +f 3904 449 3903 +f 3905 3903 1293 +f 3904 3903 3905 +f 869 3835 3906 +f 3835 38 3837 +f 3906 3837 945 +f 3835 3837 3906 +f 197 3907 3908 +f 3907 889 3737 +f 3908 3737 1088 +f 3907 3737 3908 +f 383 3488 3839 +f 3488 895 3909 +f 3839 3909 1286 +f 3488 3909 3839 +f 128 3910 3630 +f 3910 197 3908 +f 3630 3908 1088 +f 3910 3908 3630 +f 77 3626 3912 +f 3626 90 3911 +f 3912 3911 721 +f 3626 3911 3912 +f 581 3738 3913 +f 3738 77 3912 +f 3913 3912 721 +f 3738 3912 3913 +f 321 3914 3631 +f 3914 342 3915 +f 3631 3915 1370 +f 3914 3915 3631 +f 197 3910 3916 +f 3910 128 3636 +f 3916 3636 487 +f 3910 3636 3916 +f 82 3917 3918 +f 3917 1006 3490 +f 3918 3490 1370 +f 3917 3490 3918 +f 1096 3919 3496 +f 3919 807 3920 +f 3496 3920 1321 +f 3919 3920 3496 +f 82 3921 3917 +f 3921 798 3922 +f 3917 3922 1006 +f 3921 3922 3917 +f 798 3923 3922 +f 3923 6 3638 +f 3922 3638 1006 +f 3923 3638 3922 +f 972 3924 3745 +f 3924 807 3919 +f 3745 3919 1096 +f 3924 3919 3745 +f 538 3925 3926 +f 3925 857 3498 +f 3926 3498 1167 +f 3925 3498 3926 +f 6 3923 3639 +f 3923 798 3927 +f 3639 3927 1194 +f 3923 3927 3639 +f 1194 3927 3929 +f 3927 798 3928 +f 3929 3928 1233 +f 3927 3928 3929 +f 685 3930 3851 +f 3930 357 3931 +f 3851 3931 941 +f 3930 3931 3851 +f 933 3932 3934 +f 3932 506 3933 +f 3934 3933 1159 +f 3932 3933 3934 +f 685 3935 3937 +f 3935 648 3936 +f 3937 3936 1073 +f 3935 3936 3937 +f 662 3938 3940 +f 3938 577 3939 +f 3940 3939 864 +f 3938 3939 3940 +f 933 3934 3942 +f 3934 1159 3941 +f 3942 3941 1352 +f 3934 3941 3942 +f 588 3943 3770 +f 3943 845 3944 +f 3770 3944 1395 +f 3943 3944 3770 +f 1354 3772 3946 +f 3772 1011 3945 +f 3946 3945 1395 +f 3772 3945 3946 +f 1150 3947 3949 +f 3947 564 3948 +f 3949 3948 1159 +f 3947 3948 3949 +f 673 3776 3950 +f 3776 564 3947 +f 3950 3947 1150 +f 3776 3947 3950 +f 352 3951 3953 +f 3951 497 3952 +f 3953 3952 887 +f 3951 3952 3953 +f 352 3854 3951 +f 3854 465 3780 +f 3951 3780 497 +f 3854 3780 3951 +f 553 3954 3686 +f 3954 360 3857 +f 3686 3857 1484 +f 3954 3857 3686 +f 422 3955 3862 +f 3955 1052 3860 +f 3862 3860 1195 +f 3955 3860 3862 +f 310 3956 3782 +f 3956 1381 3957 +f 3782 3957 1469 +f 3956 3957 3782 +f 553 3785 3959 +f 3785 1366 3958 +f 3959 3958 1480 +f 3785 3958 3959 +f 452 3960 3687 +f 3960 422 3861 +f 3687 3861 624 +f 3960 3861 3687 +f 1281 3784 3962 +f 3784 314 3961 +f 3962 3961 1481 +f 3784 3961 3962 +f 330 3963 3863 +f 3963 62 3964 +f 3863 3964 861 +f 3963 3964 3863 +f 1353 3864 3965 +f 3864 1281 3962 +f 3965 3962 1481 +f 3864 3962 3965 +f 1204 3855 3967 +f 3855 352 3966 +f 3967 3966 1441 +f 3855 3966 3967 +f 193 3567 3792 +f 3567 1204 3967 +f 3792 3967 1441 +f 3567 3967 3792 +f 1368 3968 3969 +f 3968 1311 3786 +f 3969 3786 1437 +f 3968 3786 3969 +f 24 3970 3971 +f 3970 975 3791 +f 3971 3791 1365 +f 3970 3791 3971 +f 1203 3972 3973 +f 3972 460 3797 +f 3973 3797 1487 +f 3972 3797 3973 +f 1441 3974 3798 +f 3974 153 3975 +f 3798 3975 1454 +f 3974 3975 3798 +f 1389 3976 3874 +f 3976 1368 3969 +f 3874 3969 1437 +f 3976 3969 3874 +f 380 3438 3978 +f 3438 1385 3977 +f 3978 3977 1391 +f 3438 3977 3978 +f 153 3979 3975 +f 3979 855 3807 +f 3975 3807 1454 +f 3979 3807 3975 +f 1181 3980 3587 +f 3980 816 3981 +f 3587 3981 1385 +f 3980 3981 3587 +f 948 3982 3804 +f 3982 816 3980 +f 3804 3980 1181 +f 3982 3980 3804 +f 463 3886 3984 +f 3886 203 3983 +f 3984 3983 664 +f 3886 3983 3984 +f 203 3887 3983 +f 3887 528 3985 +f 3983 3985 664 +f 3887 3985 3983 +f 100 3986 3799 +f 3986 272 3882 +f 3799 3882 884 +f 3986 3882 3799 +f 998 3987 3988 +f 3987 100 3875 +f 3988 3875 1087 +f 3987 3875 3988 +f 382 3989 3889 +f 3989 1203 3973 +f 3889 3973 1487 +f 3989 3973 3889 +f 1191 3990 3876 +f 3990 479 3991 +f 3876 3991 1405 +f 3990 3991 3876 +f 448 3992 3802 +f 3992 479 3990 +f 3802 3990 1191 +f 3992 3990 3802 +f 936 3993 3995 +f 3993 1126 3994 +f 3995 3994 1206 +f 3993 3994 3995 +f 382 3996 3997 +f 3996 936 3995 +f 3997 3995 1206 +f 3996 3995 3997 +f 855 3998 4000 +f 3998 772 3999 +f 4000 3999 1501 +f 3998 3999 4000 +f 382 4001 3996 +f 4001 336 4002 +f 3996 4002 936 +f 4001 4002 3996 +f 336 4001 3810 +f 4001 382 3888 +f 3810 3888 468 +f 4001 3888 3810 +f 1290 3890 4003 +f 3890 855 4000 +f 4003 4000 1501 +f 3890 4000 4003 +f 939 4004 4006 +f 4004 484 4005 +f 4006 4005 1290 +f 4004 4005 4006 +f 30 4007 4009 +f 4007 701 4008 +f 4009 4008 1138 +f 4007 4008 4009 +f 1025 3895 3605 +f 3895 428 4010 +f 3605 4010 1408 +f 3895 4010 3605 +f 701 3815 4008 +f 3815 814 3896 +f 4008 3896 1138 +f 3815 3896 4008 +f 279 4011 3897 +f 4011 107 4012 +f 3897 4012 428 +f 4011 4012 3897 +f 107 4011 4013 +f 4011 279 3723 +f 4013 3723 1234 +f 4011 3723 4013 +f 461 4014 4016 +f 4014 608 4015 +f 4016 4015 810 +f 4014 4015 4016 +f 726 4017 4018 +f 4017 482 3822 +f 4018 3822 1213 +f 4017 3822 4018 +f 482 4017 3616 +f 4017 726 4019 +f 3616 4019 1234 +f 4017 4019 3616 +f 810 4015 3725 +f 4015 608 3825 +f 3725 3825 882 +f 4015 3825 3725 +f 1213 3821 4021 +f 3821 670 4020 +f 4021 4020 1340 +f 3821 4020 4021 +f 670 3900 4020 +f 3900 209 4022 +f 4020 4022 1340 +f 3900 4022 4020 +f 209 4023 4022 +f 4023 246 4024 +f 4022 4024 1340 +f 4023 4024 4022 +f 246 4023 4025 +f 4023 209 3733 +f 4025 3733 643 +f 4023 3733 4025 +f 246 4025 4026 +f 4025 643 3831 +f 4026 3831 1160 +f 4025 3831 4026 +f 869 3906 4028 +f 3906 945 4027 +f 4028 4027 1064 +f 3906 4027 4028 +f 90 3627 4029 +f 3627 537 3736 +f 4029 3736 889 +f 3627 3736 4029 +f 197 3916 4031 +f 3916 487 4030 +f 4031 4030 920 +f 3916 4030 4031 +f 265 4032 4033 +f 4032 581 3913 +f 4033 3913 721 +f 4032 3913 4033 +f 265 4034 4032 +f 4034 321 3743 +f 4032 3743 581 +f 4034 3743 4032 +f 404 3632 4036 +f 3632 681 4035 +f 4036 4035 1333 +f 3632 4035 4036 +f 983 4037 4038 +f 4037 404 4036 +f 4038 4036 1333 +f 4037 4036 4038 +f 177 4039 4041 +f 4039 704 4040 +f 4041 4040 1167 +f 4039 4040 4041 +f 383 3838 3491 +f 3838 177 4041 +f 3491 4041 1167 +f 3838 4041 3491 +f 920 4030 4042 +f 4030 487 3842 +f 4042 3842 1190 +f 4030 3842 4042 +f 704 4043 4040 +f 4043 538 3926 +f 4040 3926 1167 +f 4043 3926 4040 +f 857 3925 4045 +f 3925 538 4044 +f 4045 4044 1414 +f 3925 4044 4045 +f 694 4046 3844 +f 4046 53 4047 +f 3844 4047 1190 +f 4046 4047 3844 +f 857 4045 3846 +f 4045 1414 4048 +f 3846 4048 1491 +f 4045 4048 3846 +f 472 3643 4049 +f 3643 1194 3929 +f 4049 3929 1233 +f 3643 3929 4049 +f 195 3749 4051 +f 3749 489 4050 +f 4051 4050 559 +f 3749 4050 4051 +f 1313 4052 4054 +f 4052 410 4053 +f 4054 4053 1494 +f 4052 4053 4054 +f 1100 4055 4057 +f 4055 1073 4056 +f 4057 4056 1312 +f 4055 4056 4057 +f 577 4058 3939 +f 4058 407 4059 +f 3939 4059 864 +f 4058 4059 3939 +f 845 4060 3944 +f 4060 1354 3946 +f 3944 3946 1395 +f 4060 3946 3944 +f 1376 3853 4061 +f 3853 1429 3682 +f 4061 3682 1479 +f 3853 3682 4061 +f 861 4062 3681 +f 4062 49 4063 +f 3681 4063 1479 +f 4062 4063 3681 +f 310 3858 4065 +f 3858 156 4064 +f 4065 4064 1456 +f 3858 4064 4065 +f 314 3783 4067 +f 3783 825 4066 +f 4067 4066 971 +f 3783 4066 4067 +f 62 3963 4068 +f 3963 330 3794 +f 4068 3794 460 +f 3963 3794 4068 +f 1092 4069 4070 +f 4069 460 3972 +f 4070 3972 1203 +f 4069 3972 4070 +f 755 4071 4072 +f 4071 153 3974 +f 4072 3974 1441 +f 4071 3974 4072 +f 988 4073 4074 +f 4073 24 3971 +f 4074 3971 1365 +f 4073 3971 4074 +f 198 3700 3877 +f 3700 613 4075 +f 3877 4075 731 +f 3700 4075 3877 +f 975 3970 4076 +f 3970 24 4073 +f 4076 4073 988 +f 3970 4073 4076 +f 975 4076 3869 +f 4076 988 4077 +f 3869 4077 1087 +f 4076 4077 3869 +f 1087 4077 4079 +f 4077 988 4078 +f 4079 4078 1206 +f 4077 4078 4079 +f 988 4080 4078 +f 4080 541 4081 +f 4078 4081 1206 +f 4080 4081 4078 +f 541 4082 4081 +f 4082 1203 4083 +f 4081 4083 1206 +f 4082 4083 4081 +f 855 3979 4085 +f 3979 153 4084 +f 4085 4084 1023 +f 3979 4084 4085 +f 772 4086 4088 +f 4086 1023 4087 +f 4088 4087 1389 +f 4086 4087 4088 +f 1203 3989 4083 +f 3989 382 3997 +f 4083 3997 1206 +f 3989 3997 4083 +f 40 4089 4090 +f 4089 772 4088 +f 4090 4088 1389 +f 4089 4088 4090 +f 40 4090 4091 +f 4090 1389 3873 +f 4091 3873 1405 +f 4090 3873 4091 +f 1126 4092 3994 +f 4092 1087 4079 +f 3994 4079 1206 +f 4092 4079 3994 +f 772 3998 4086 +f 3998 855 4085 +f 4086 4085 1023 +f 3998 4085 4086 +f 272 3986 4093 +f 3986 100 3987 +f 4093 3987 998 +f 3986 3987 4093 +f 772 4094 3999 +f 4094 1405 4095 +f 3999 4095 1501 +f 4094 4095 3999 +f 772 4089 4094 +f 4089 40 4091 +f 4094 4091 1405 +f 4089 4091 4094 +f 998 3988 4096 +f 3988 1087 4092 +f 4096 4092 1126 +f 3988 4092 4096 +f 936 4097 3993 +f 4097 132 4098 +f 3993 4098 1126 +f 4097 4098 3993 +f 132 4097 4100 +f 4097 936 4099 +f 4100 4099 937 +f 4097 4099 4100 +f 936 4002 4099 +f 4002 336 4101 +f 4099 4101 937 +f 4002 4101 4099 +f 937 4101 4102 +f 4101 336 3892 +f 4102 3892 1331 +f 4101 3892 4102 +f 484 4103 4005 +f 4103 600 3812 +f 4005 3812 1290 +f 4103 3812 4005 +f 1331 3894 4104 +f 3894 628 3603 +f 4104 3603 1408 +f 3894 3603 4104 +f 484 4105 4103 +f 4105 30 4106 +f 4103 4106 600 +f 4105 4106 4103 +f 600 4106 3718 +f 4106 30 4009 +f 3718 4009 1138 +f 4106 4009 3718 +f 1408 4010 4108 +f 4010 428 4107 +f 4108 4107 1466 +f 4010 4107 4108 +f 461 4109 4110 +f 4109 293 3898 +f 4110 3898 701 +f 4109 3898 4110 +f 293 4109 3899 +f 4109 461 4016 +f 3899 4016 810 +f 4109 4016 3899 +f 726 4111 4019 +f 4111 107 4013 +f 4019 4013 1234 +f 4111 4013 4019 +f 1033 4112 3902 +f 4112 790 4113 +f 3902 4113 1293 +f 4112 4113 3902 +f 869 4114 3830 +f 4114 251 4115 +f 3830 4115 1160 +f 4114 4115 3830 +f 185 4116 4117 +f 4116 556 3742 +f 4117 3742 680 +f 4116 3742 4117 +f 571 4118 4119 +f 4118 177 3840 +f 4119 3840 1286 +f 4118 3840 4119 +f 680 3741 4120 +f 3741 404 4037 +f 4120 4037 983 +f 3741 4037 4120 +f 729 4121 4122 +f 4121 920 4042 +f 4122 4042 1190 +f 4121 4042 4122 +f 1414 4123 4048 +f 4123 642 4124 +f 4048 4124 1491 +f 4123 4124 4048 +f 472 4125 3750 +f 4125 586 4126 +f 3750 4126 977 +f 4125 4126 3750 +f 642 4127 4124 +f 4127 506 4128 +f 4124 4128 1491 +f 4127 4128 4124 +f 709 4129 4131 +f 4129 407 4130 +f 4131 4130 1372 +f 4129 4130 4131 +f 156 3856 4064 +f 3856 360 4132 +f 4064 4132 1456 +f 3856 4132 4064 +f 971 4066 4133 +f 4066 825 3859 +f 4133 3859 1052 +f 4066 3859 4133 +f 159 4134 4135 +f 4134 553 3959 +f 4135 3959 1480 +f 4134 3959 4135 +f 1381 4136 3957 +f 4136 1245 3570 +f 3957 3570 1469 +f 4136 3570 3957 +f 547 4137 3689 +f 4137 510 4138 +f 3689 4138 1366 +f 4137 4138 3689 +f 510 4137 4139 +f 4137 547 3866 +f 4139 3866 1244 +f 4137 3866 4139 +f 62 4068 4140 +f 4068 460 4069 +f 4140 4069 1092 +f 4068 4069 4140 +f 1003 4141 4142 +f 4141 62 4140 +f 4142 4140 1092 +f 4141 4140 4142 +f 1245 4143 3865 +f 4143 960 4144 +f 3865 4144 1365 +f 4143 4144 3865 +f 153 4071 4084 +f 4071 755 4145 +f 4084 4145 1023 +f 4071 4145 4084 +f 755 4146 4145 +f 4146 774 4147 +f 4145 4147 1023 +f 4146 4147 4145 +f 774 4148 4149 +f 4148 1368 3976 +f 4149 3976 1389 +f 4148 3976 4149 +f 960 4150 4144 +f 4150 988 4074 +f 4144 4074 1365 +f 4150 4074 4144 +f 960 4151 4150 +f 4151 541 4080 +f 4150 4080 988 +f 4151 4080 4150 +f 541 4152 4082 +f 4152 152 4153 +f 4082 4153 1203 +f 4152 4153 4082 +f 152 4154 4153 +f 4154 1092 4070 +f 4153 4070 1203 +f 4154 4070 4153 +f 1023 4147 4087 +f 4147 774 4149 +f 4087 4149 1389 +f 4147 4149 4087 +f 1385 3981 3977 +f 3981 816 4155 +f 3977 4155 1391 +f 3981 4155 3977 +f 528 4156 3985 +f 4156 478 4157 +f 3985 4157 664 +f 4156 4157 3985 +f 478 4156 4158 +f 4156 528 3881 +f 4158 3881 731 +f 4156 3881 4158 +f 463 3984 4160 +f 3984 664 4159 +f 4160 4159 821 +f 3984 4159 4160 +f 448 3885 3992 +f 3885 463 4161 +f 3992 4161 479 +f 3885 4161 3992 +f 132 4162 4098 +f 4162 998 4096 +f 4098 4096 1126 +f 4162 4096 4098 +f 1405 3991 4095 +f 3991 479 4163 +f 4095 4163 1501 +f 3991 4163 4095 +f 939 4006 4164 +f 4006 1290 4003 +f 4164 4003 1501 +f 4006 4003 4164 +f 1301 4165 4166 +f 4165 939 4164 +f 4166 4164 1501 +f 4165 4164 4166 +f 1117 4167 4168 +f 4167 937 4102 +f 4168 4102 1331 +f 4167 4102 4168 +f 1331 4104 4169 +f 4104 1408 4108 +f 4169 4108 1466 +f 4104 4108 4169 +f 701 4007 4171 +f 4007 30 4170 +f 4171 4170 1338 +f 4007 4170 4171 +f 428 4012 4107 +f 4012 107 4172 +f 4107 4172 1466 +f 4012 4172 4107 +f 616 3823 3826 +f 3823 608 4173 +f 3826 4173 1033 +f 3823 4173 3826 +f 860 4174 4175 +f 4174 246 4026 +f 4175 4026 1160 +f 4174 4026 4175 +f 1061 4176 4177 +f 4176 945 3905 +f 4177 3905 1293 +f 4176 3905 4177 +f 1061 4178 4180 +f 4178 420 4179 +f 4180 4179 1064 +f 4178 4179 4180 +f 945 4176 4027 +f 4176 1061 4180 +f 4027 4180 1064 +f 4176 4180 4027 +f 895 3485 3909 +f 3485 556 4181 +f 3909 4181 1286 +f 3485 4181 3909 +f 556 4116 4181 +f 4116 185 4182 +f 4181 4182 1286 +f 4116 4182 4181 +f 276 4183 4185 +f 4183 587 4184 +f 4185 4184 721 +f 4183 4184 4185 +f 587 4186 4184 +f 4186 265 4033 +f 4184 4033 721 +f 4186 4033 4184 +f 321 4034 3914 +f 4034 265 4187 +f 3914 4187 342 +f 4034 4187 3914 +f 53 4046 4189 +f 4046 694 4188 +f 4189 4188 1313 +f 4046 4188 4189 +f 582 4190 4191 +f 4190 978 3852 +f 4191 3852 1376 +f 4190 3852 4191 +f 878 4192 4193 +f 4192 1376 4061 +f 4193 4061 1479 +f 4192 4061 4193 +f 673 4194 4196 +f 4194 806 4195 +f 4196 4195 887 +f 4194 4195 4196 +f 497 3778 3952 +f 3778 673 4196 +f 3952 4196 887 +f 3778 4196 3952 +f 971 4133 4198 +f 4133 1052 4197 +f 4198 4197 1275 +f 4133 4197 4198 +f 159 4199 4134 +f 4199 360 3954 +f 4134 3954 553 +f 4199 3954 4134 +f 1381 3956 4200 +f 3956 310 4065 +f 4200 4065 1456 +f 3956 4065 4200 +f 49 4062 4202 +f 4062 861 4201 +f 4202 4201 1003 +f 4062 4201 4202 +f 422 4203 3955 +f 4203 496 4204 +f 3955 4204 1052 +f 4203 4204 3955 +f 314 4067 3961 +f 4067 971 4205 +f 3961 4205 1481 +f 4067 4205 3961 +f 861 3964 4201 +f 3964 62 4141 +f 4201 4141 1003 +f 3964 4141 4201 +f 1366 4138 3958 +f 4138 510 4206 +f 3958 4206 1480 +f 4138 4206 3958 +f 313 4207 4208 +f 4207 960 4143 +f 4208 4143 1245 +f 4207 4143 4208 +f 152 4209 4154 +f 4209 401 4210 +f 4154 4210 1092 +f 4209 4210 4154 +f 1066 4211 4212 +f 4211 1311 3968 +f 4212 3968 1368 +f 4211 3968 4212 +f 1085 4213 3868 +f 4213 603 4214 +f 3868 4214 1244 +f 4213 4214 3868 +f 442 4215 4216 +f 4215 541 4151 +f 4216 4151 960 +f 4215 4151 4216 +f 442 4217 4215 +f 4217 152 4152 +f 4215 4152 541 +f 4217 4152 4215 +f 774 4218 4148 +f 4218 1066 4212 +f 4148 4212 1368 +f 4218 4212 4148 +f 1085 3867 4219 +f 3867 380 3978 +f 4219 3978 1391 +f 3867 3978 4219 +f 948 3883 4220 +f 3883 272 4093 +f 4220 4093 998 +f 3883 4093 4220 +f 479 4161 4221 +f 4161 463 4160 +f 4221 4160 821 +f 4161 4160 4221 +f 132 4222 4162 +f 4222 763 4223 +f 4162 4223 998 +f 4222 4223 4162 +f 479 4224 4163 +f 4224 1301 4166 +f 4163 4166 1501 +f 4224 4166 4163 +f 763 4222 4225 +f 4222 132 4100 +f 4225 4100 937 +f 4222 4100 4225 +f 763 4225 4226 +f 4225 937 4167 +f 4226 4167 1117 +f 4225 4167 4226 +f 897 4227 4228 +f 4227 939 4165 +f 4228 4165 1301 +f 4227 4165 4228 +f 30 4105 4230 +f 4105 484 4229 +f 4230 4229 1134 +f 4105 4229 4230 +f 461 4110 4231 +f 4110 701 4171 +f 4231 4171 1338 +f 4110 4171 4231 +f 726 4018 4232 +f 4018 1213 4021 +f 4232 4021 1340 +f 4018 4021 4232 +f 608 4014 4234 +f 4014 461 4233 +f 4234 4233 1202 +f 4014 4233 4234 +f 1033 4173 4235 +f 4173 608 4234 +f 4235 4234 1202 +f 4173 4234 4235 +f 790 4112 4236 +f 4112 1033 4235 +f 4236 4235 1202 +f 4112 4235 4236 +f 246 4237 4024 +f 4237 264 4238 +f 4024 4238 1340 +f 4237 4238 4024 +f 790 4239 4113 +f 4239 441 4240 +f 4113 4240 1293 +f 4239 4240 4113 +f 1160 4115 4242 +f 4115 251 4241 +f 4242 4241 1223 +f 4115 4241 4242 +f 840 4243 4245 +f 4243 251 4244 +f 4245 4244 1064 +f 4243 4244 4245 +f 251 4114 4244 +f 4114 869 4028 +f 4244 4028 1064 +f 4114 4028 4244 +f 276 4246 4247 +f 4246 90 4029 +f 4247 4029 889 +f 4246 4029 4247 +f 889 3907 4248 +f 3907 197 4031 +f 4248 4031 920 +f 3907 4031 4248 +f 90 4246 3911 +f 4246 276 4185 +f 3911 4185 721 +f 4246 4185 3911 +f 681 3407 4250 +f 3407 1146 4249 +f 4250 4249 1288 +f 3407 4249 4250 +f 681 4250 4035 +f 4250 1288 4251 +f 4035 4251 1333 +f 4250 4251 4035 +f 177 4118 4253 +f 4118 571 4252 +f 4253 4252 1303 +f 4118 4252 4253 +f 704 4039 4254 +f 4039 177 4253 +f 4254 4253 1303 +f 4039 4253 4254 +f 515 4255 4256 +f 4255 82 3918 +f 4256 3918 1370 +f 4255 3918 4256 +f 53 4257 4047 +f 4257 850 4258 +f 4047 4258 1190 +f 4257 4258 4047 +f 195 4051 4260 +f 4051 559 4259 +f 4260 4259 1294 +f 4051 4259 4260 +f 972 3845 4261 +f 3845 195 4260 +f 4261 4260 1294 +f 3845 4260 4261 +f 777 4262 4263 +f 4262 642 4123 +f 4263 4123 1414 +f 4262 4123 4263 +f 705 4264 4266 +f 4264 873 4265 +f 4266 4265 1073 +f 4264 4265 4266 +f 586 4267 4269 +f 4267 758 4268 +f 4269 4268 1421 +f 4267 4268 4269 +f 845 4270 4060 +f 4270 346 4271 +f 4060 4271 1354 +f 4270 4271 4060 +f 161 4272 4274 +f 4272 1354 4273 +f 4274 4273 1420 +f 4272 4273 4274 +f 49 4275 4063 +f 4275 686 4276 +f 4063 4276 1479 +f 4275 4276 4063 +f 565 4277 4278 +f 4277 352 3953 +f 4278 3953 887 +f 4277 3953 4278 +f 352 4277 3966 +f 4277 565 4279 +f 3966 4279 1441 +f 4277 4279 3966 +f 496 4203 4281 +f 4203 422 4280 +f 4281 4280 1054 +f 4203 4280 4281 +f 302 4282 4283 +f 4282 1245 4136 +f 4283 4136 1381 +f 4282 4136 4283 +f 422 3960 4280 +f 3960 452 4284 +f 4280 4284 1054 +f 3960 4284 4280 +f 302 4285 4282 +f 4285 313 4208 +f 4282 4208 1245 +f 4285 4208 4282 +f 401 4286 4210 +f 4286 1003 4142 +f 4210 4142 1092 +f 4286 4142 4210 +f 284 4287 4288 +f 4287 755 4072 +f 4288 4072 1441 +f 4287 4072 4288 +f 755 4287 4290 +f 4287 284 4289 +f 4290 4289 1201 +f 4287 4289 4290 +f 565 4291 4279 +f 4291 284 4288 +f 4279 4288 1441 +f 4291 4288 4279 +f 1066 4292 4211 +f 4292 452 3691 +f 4211 3691 1311 +f 4292 3691 4211 +f 121 4293 4294 +f 4293 146 3789 +f 4294 3789 1353 +f 4293 3789 4294 +f 603 4295 4214 +f 4295 510 4139 +f 4214 4139 1244 +f 4295 4139 4214 +f 770 4296 4297 +f 4296 755 4290 +f 4297 4290 1201 +f 4296 4290 4297 +f 755 4296 4146 +f 4296 770 4298 +f 4146 4298 774 +f 4296 4298 4146 +f 146 4293 3575 +f 4293 121 4299 +f 3575 4299 613 +f 4293 4299 3575 +f 613 4299 4301 +f 4299 121 4300 +f 4301 4300 950 +f 4299 4300 4301 +f 886 4302 4303 +f 4302 1085 4219 +f 4303 4219 1391 +f 4302 4219 4303 +f 886 4303 4305 +f 4303 1391 4304 +f 4305 4304 1474 +f 4303 4304 4305 +f 130 4306 4307 +f 4306 816 3982 +f 4307 3982 948 +f 4306 3982 4307 +f 664 4308 4159 +f 4308 34 4309 +f 4159 4309 821 +f 4308 4309 4159 +f 478 4310 4157 +f 4310 34 4308 +f 4157 4308 664 +f 4310 4308 4157 +f 763 4311 4223 +f 4311 948 4220 +f 4223 4220 998 +f 4311 4220 4223 +f 479 4221 4224 +f 4221 821 4312 +f 4224 4312 1301 +f 4221 4312 4224 +f 897 4313 4227 +f 4313 484 4004 +f 4227 4004 939 +f 4313 4004 4227 +f 484 4313 4229 +f 4313 897 4314 +f 4229 4314 1134 +f 4313 4314 4229 +f 1242 4315 4316 +f 4315 1117 4168 +f 4316 4168 1331 +f 4315 4168 4316 +f 557 4317 4318 +f 4317 1242 4316 +f 4318 4316 1331 +f 4317 4316 4318 +f 1134 4319 4321 +f 4319 1136 4320 +f 4321 4320 1338 +f 4319 4320 4321 +f 30 4230 4170 +f 4230 1134 4321 +f 4170 4321 1338 +f 4230 4321 4170 +f 557 4318 4322 +f 4318 1331 4169 +f 4322 4169 1466 +f 4318 4169 4322 +f 107 4111 4172 +f 4111 726 4323 +f 4172 4323 1466 +f 4111 4323 4172 +f 726 4324 4323 +f 4324 789 4325 +f 4323 4325 1466 +f 4324 4325 4323 +f 789 4324 4326 +f 4324 726 4232 +f 4326 4232 1340 +f 4324 4232 4326 +f 239 4327 4328 +f 4327 790 4236 +f 4328 4236 1202 +f 4327 4236 4328 +f 264 4237 4329 +f 4237 246 4174 +f 4329 4174 860 +f 4237 4174 4329 +f 264 4329 4331 +f 4329 860 4330 +f 4331 4330 1438 +f 4329 4330 4331 +f 860 4175 4332 +f 4175 1160 4242 +f 4332 4242 1223 +f 4175 4242 4332 +f 441 4333 4240 +f 4333 1061 4177 +f 4240 4177 1293 +f 4333 4177 4240 +f 441 4334 4333 +f 4334 724 4335 +f 4333 4335 1061 +f 4334 4335 4333 +f 185 4336 4182 +f 4336 688 4337 +f 4182 4337 1286 +f 4336 4337 4182 +f 185 4117 4338 +f 4117 680 4120 +f 4338 4120 983 +f 4117 4120 4338 +f 955 4339 4340 +f 4339 1146 3322 +f 4340 3322 1321 +f 4339 3322 4340 +f 850 4341 4258 +f 4341 729 4122 +f 4258 4122 1190 +f 4341 4122 4258 +f 538 4342 4044 +f 4342 388 4343 +f 4044 4343 1414 +f 4342 4343 4044 +f 586 4125 4344 +f 4125 472 4049 +f 4344 4049 1233 +f 4125 4049 4344 +f 709 4345 4347 +f 4345 93 4346 +f 4347 4346 1313 +f 4345 4346 4347 +f 346 4270 4349 +f 4270 845 4348 +f 4349 4348 989 +f 4270 4348 4349 +f 686 4350 4276 +f 4350 878 4193 +f 4276 4193 1479 +f 4350 4193 4276 +f 804 4351 4352 +f 4351 565 4278 +f 4352 4278 887 +f 4351 4278 4352 +f 669 4353 4354 +f 4353 804 4352 +f 4354 4352 887 +f 4353 4352 4354 +f 360 4199 4356 +f 4199 159 4355 +f 4356 4355 1277 +f 4199 4355 4356 +f 1052 4204 4197 +f 4204 496 4357 +f 4197 4357 1275 +f 4204 4357 4197 +f 7 4358 4359 +f 4358 496 4281 +f 4359 4281 1054 +f 4358 4281 4359 +f 217 4360 4361 +f 4360 1353 3965 +f 4361 3965 1481 +f 4360 3965 4361 +f 2 4362 4364 +f 4362 1054 4363 +f 4364 4363 1066 +f 4362 4363 4364 +f 1054 4284 4363 +f 4284 452 4292 +f 4363 4292 1066 +f 4284 4292 4363 +f 217 4365 4360 +f 4365 121 4294 +f 4360 4294 1353 +f 4365 4294 4360 +f 313 4366 4207 +f 4366 728 4367 +f 4207 4367 960 +f 4366 4367 4207 +f 728 4368 4367 +f 4368 442 4216 +f 4367 4216 960 +f 4368 4216 4367 +f 152 4217 4369 +f 4217 442 4368 +f 4369 4368 728 +f 4217 4368 4369 +f 401 4209 4370 +f 4209 152 4369 +f 4370 4369 728 +f 4209 4369 4370 +f 774 4298 4218 +f 4298 770 4371 +f 4218 4371 1066 +f 4298 4371 4218 +f 770 4372 4371 +f 4372 2 4364 +f 4371 4364 1066 +f 4372 4364 4371 +f 1391 4155 4374 +f 4155 816 4373 +f 4374 4373 1403 +f 4155 4373 4374 +f 816 4306 4373 +f 4306 130 4375 +f 4373 4375 1403 +f 4306 4375 4373 +f 763 4376 4311 +f 4376 130 4307 +f 4311 4307 948 +f 4376 4307 4311 +f 951 4377 4378 +f 4377 763 4226 +f 4378 4226 1117 +f 4377 4226 4378 +f 951 4378 4379 +f 4378 1117 4315 +f 4379 4315 1242 +f 4378 4315 4379 +f 437 4380 4382 +f 4380 98 4381 +f 4382 4381 1338 +f 4380 4381 4382 +f 98 4383 4381 +f 4383 461 4231 +f 4381 4231 1338 +f 4383 4231 4381 +f 461 4383 4233 +f 4383 98 4384 +f 4233 4384 1202 +f 4383 4384 4233 +f 264 4385 4238 +f 4385 789 4326 +f 4238 4326 1340 +f 4385 4326 4238 +f 251 4243 4241 +f 4243 840 4386 +f 4241 4386 1223 +f 4243 4386 4241 +f 66 4387 4388 +f 4387 265 4186 +f 4388 4186 587 +f 4387 4186 4388 +f 265 4387 4187 +f 4387 66 4389 +f 4187 4389 342 +f 4387 4389 4187 +f 342 4390 3915 +f 4390 298 4391 +f 3915 4391 1370 +f 4390 4391 3915 +f 298 4392 4391 +f 4392 515 4256 +f 4391 4256 1370 +f 4392 4256 4391 +f 1146 4339 4249 +f 4339 955 4393 +f 4249 4393 1288 +f 4339 4393 4249 +f 361 4394 4395 +f 4394 704 4254 +f 4395 4254 1303 +f 4394 4254 4395 +f 850 4257 4396 +f 4257 53 4189 +f 4396 4189 1313 +f 4257 4189 4396 +f 559 4397 4259 +f 4397 873 4398 +f 4259 4398 1294 +f 4397 4398 4259 +f 586 4399 4267 +f 4399 230 4400 +f 4267 4400 758 +f 4399 4400 4267 +f 467 4401 4403 +f 4401 93 4402 +f 4403 4402 582 +f 4401 4402 4403 +f 346 4404 4406 +f 4404 630 4405 +f 4406 4405 1420 +f 4404 4405 4406 +f 806 4407 4409 +f 4407 1080 4408 +f 4409 4408 1471 +f 4407 4408 4409 +f 806 4410 4195 +f 4410 669 4354 +f 4195 4354 887 +f 4410 4354 4195 +f 686 4275 4411 +f 4275 49 4202 +f 4411 4202 1003 +f 4275 4202 4411 +f 360 4356 4132 +f 4356 1277 4412 +f 4132 4412 1456 +f 4356 4412 4132 +f 612 4413 4414 +f 4413 1381 4200 +f 4414 4200 1456 +f 4413 4200 4414 +f 459 4415 4416 +f 4415 971 4198 +f 4416 4198 1275 +f 4415 4198 4416 +f 1277 4355 4417 +f 4355 159 4135 +f 4417 4135 1480 +f 4355 4135 4417 +f 971 4415 4205 +f 4415 459 4418 +f 4205 4418 1481 +f 4415 4418 4205 +f 791 4419 4420 +f 4419 1277 4417 +f 4420 4417 1480 +f 4419 4417 4420 +f 510 4421 4206 +f 4421 791 4420 +f 4206 4420 1480 +f 4421 4420 4206 +f 284 4291 4422 +f 4291 565 4351 +f 4422 4351 804 +f 4291 4351 4422 +f 401 4370 4424 +f 4370 728 4423 +f 4424 4423 1356 +f 4370 4423 4424 +f 1003 4286 4425 +f 4286 401 4424 +f 4425 4424 1356 +f 4286 4424 4425 +f 728 4366 4427 +f 4366 313 4426 +f 4427 4426 1161 +f 4366 4426 4427 +f 478 4158 4429 +f 4158 731 4428 +f 4429 4428 1334 +f 4158 4428 4429 +f 1391 4374 4304 +f 4374 1403 4430 +f 4304 4430 1474 +f 4374 4430 4304 +f 34 4310 4431 +f 4310 478 4429 +f 4431 4429 1334 +f 4310 4429 4431 +f 130 4376 4432 +f 4376 763 4377 +f 4432 4377 951 +f 4376 4377 4432 +f 557 4433 4317 +f 4433 905 4434 +f 4317 4434 1242 +f 4433 4434 4317 +f 1136 4319 4436 +f 4319 1134 4435 +f 4436 4435 1164 +f 4319 4435 4436 +f 334 4437 4438 +f 4437 557 4322 +f 4438 4322 1466 +f 4437 4322 4438 +f 64 4439 4441 +f 4439 520 4440 +f 4441 4440 1466 +f 4439 4440 4441 +f 789 4442 4325 +f 4442 64 4441 +f 4325 4441 1466 +f 4442 4441 4325 +f 789 4385 4443 +f 4385 264 4331 +f 4443 4331 1438 +f 4385 4331 4443 +f 441 4239 4445 +f 4239 790 4444 +f 4445 4444 1350 +f 4239 4444 4445 +f 790 4327 4444 +f 4327 239 4446 +f 4444 4446 1350 +f 4327 4446 4444 +f 724 4334 4447 +f 4334 441 4445 +f 4447 4445 1350 +f 4334 4445 4447 +f 542 4448 4449 +f 4448 420 4178 +f 4449 4178 1061 +f 4448 4178 4449 +f 420 4450 4179 +f 4450 840 4245 +f 4179 4245 1064 +f 4450 4245 4179 +f 276 4247 4452 +f 4247 889 4451 +f 4452 4451 949 +f 4247 4451 4452 +f 920 4121 4454 +f 4121 729 4453 +f 4454 4453 1107 +f 4121 4453 4454 +f 82 4255 4456 +f 4255 515 4455 +f 4456 4455 663 +f 4255 4455 4456 +f 361 4457 4394 +f 4457 538 4043 +f 4394 4043 704 +f 4457 4043 4394 +f 82 4456 3921 +f 4456 663 4458 +f 3921 4458 798 +f 4456 4458 3921 +f 798 4458 3928 +f 4458 663 4459 +f 3928 4459 1233 +f 4458 4459 3928 +f 348 4460 4462 +f 4460 230 4461 +f 4462 4461 1233 +f 4460 4461 4462 +f 705 4463 4465 +f 4463 634 4464 +f 4465 4464 1205 +f 4463 4464 4465 +f 630 4466 4405 +f 4466 894 4467 +f 4405 4467 1420 +f 4466 4467 4405 +f 41 4468 4469 +f 4468 467 4403 +f 4469 4403 582 +f 4468 4403 4469 +f 878 4470 4192 +f 4470 582 4191 +f 4192 4191 1376 +f 4470 4191 4192 +f 698 4471 4472 +f 4471 669 4410 +f 4472 4410 806 +f 4471 4410 4472 +f 686 4473 4350 +f 4473 654 4474 +f 4350 4474 878 +f 4473 4474 4350 +f 1277 4475 4412 +f 4475 138 4476 +f 4412 4476 1456 +f 4475 4476 4412 +f 1275 4357 4478 +f 4357 496 4477 +f 4478 4477 1347 +f 4357 4477 4478 +f 612 4479 4413 +f 4479 402 4480 +f 4413 4480 1381 +f 4479 4480 4413 +f 402 4481 4480 +f 4481 302 4283 +f 4480 4283 1381 +f 4481 4283 4480 +f 1224 4482 4483 +f 4482 217 4361 +f 4483 4361 1481 +f 4482 4361 4483 +f 459 4484 4418 +f 4484 1224 4483 +f 4418 4483 1481 +f 4484 4483 4418 +f 313 4285 4426 +f 4285 302 4485 +f 4426 4485 1161 +f 4285 4485 4426 +f 302 4481 4485 +f 4481 402 4486 +f 4485 4486 1161 +f 4481 4486 4485 +f 105 4487 4489 +f 4487 1240 4488 +f 4489 4488 1356 +f 4487 4488 4489 +f 1240 4490 4488 +f 4490 1003 4425 +f 4488 4425 1356 +f 4490 4425 4488 +f 510 4295 4421 +f 4295 603 4491 +f 4421 4491 791 +f 4295 4491 4421 +f 728 4427 4423 +f 4427 1161 4492 +f 4423 4492 1356 +f 4427 4492 4423 +f 2 4372 4494 +f 4372 770 4493 +f 4494 4493 1017 +f 4372 4493 4494 +f 1017 4493 4495 +f 4493 770 4297 +f 4495 4297 1201 +f 4493 4297 4495 +f 2 4494 4362 +f 4494 1017 4496 +f 4362 4496 1054 +f 4494 4496 4362 +f 121 4365 4497 +f 4365 217 4482 +f 4497 4482 1224 +f 4365 4482 4497 +f 950 4300 4498 +f 4300 121 4497 +f 4498 4497 1224 +f 4300 4497 4498 +f 821 4309 4499 +f 4309 34 4431 +f 4499 4431 1334 +f 4309 4431 4499 +f 130 4432 4375 +f 4432 951 4500 +f 4375 4500 1403 +f 4432 4500 4375 +f 821 4501 4312 +f 4501 521 4502 +f 4312 4502 1301 +f 4501 4502 4312 +f 521 4501 4503 +f 4501 821 4499 +f 4503 4499 1334 +f 4501 4499 4503 +f 521 4504 4502 +f 4504 897 4228 +f 4502 4228 1301 +f 4504 4228 4502 +f 1134 4505 4435 +f 4505 521 4506 +f 4435 4506 1164 +f 4505 4506 4435 +f 897 4504 4314 +f 4504 521 4505 +f 4314 4505 1134 +f 4504 4505 4314 +f 1242 4434 4508 +f 4434 905 4507 +f 4508 4507 1470 +f 4434 4507 4508 +f 334 4509 4437 +f 4509 527 4510 +f 4437 4510 557 +f 4509 4510 4437 +f 1158 4511 4512 +f 4511 334 4438 +f 4512 4438 1466 +f 4511 4438 4512 +f 1461 4513 4514 +f 4513 1158 4512 +f 4514 4512 1466 +f 4513 4512 4514 +f 1185 4515 4516 +f 4515 437 4382 +f 4516 4382 1338 +f 4515 4382 4516 +f 520 4517 4440 +f 4517 1461 4514 +f 4440 4514 1466 +f 4517 4514 4440 +f 64 4518 4439 +f 4518 413 4519 +f 4439 4519 520 +f 4518 4519 4439 +f 98 4380 4521 +f 4380 437 4520 +f 4521 4520 1022 +f 4380 4520 4521 +f 98 4522 4384 +f 4522 239 4328 +f 4384 4328 1202 +f 4522 4328 4384 +f 840 4523 4386 +f 4523 820 4524 +f 4386 4524 1223 +f 4523 4524 4386 +f 420 4525 4450 +f 4525 163 4526 +f 4450 4526 840 +f 4525 4526 4450 +f 889 4527 4451 +f 4527 610 4528 +f 4451 4528 949 +f 4527 4528 4451 +f 276 4529 4183 +f 4529 423 4530 +f 4183 4530 587 +f 4529 4530 4183 +f 688 4531 4337 +f 4531 571 4119 +f 4337 4119 1286 +f 4531 4119 4337 +f 889 4248 4532 +f 4248 920 4454 +f 4532 4454 1107 +f 4248 4454 4532 +f 610 4527 4533 +f 4527 889 4532 +f 4533 4532 1107 +f 4527 4532 4533 +f 423 4534 4530 +f 4534 66 4388 +f 4530 4388 587 +f 4534 4388 4530 +f 298 4390 4536 +f 4390 342 4535 +f 4536 4535 809 +f 4390 4535 4536 +f 688 4336 4538 +f 4336 185 4537 +f 4538 4537 1373 +f 4336 4537 4538 +f 822 4539 4540 +f 4539 955 4340 +f 4540 4340 1321 +f 4539 4340 4540 +f 807 4541 3920 +f 4541 822 4540 +f 3920 4540 1321 +f 4541 4540 3920 +f 807 4542 4541 +f 4542 687 4543 +f 4541 4543 822 +f 4542 4543 4541 +f 687 4542 4544 +f 4542 807 3924 +f 4544 3924 972 +f 4542 3924 4544 +f 361 4545 4457 +f 4545 388 4342 +f 4457 4342 538 +f 4545 4342 4457 +f 1233 4459 4547 +f 4459 663 4546 +f 4547 4546 1317 +f 4459 4546 4547 +f 630 4548 4550 +f 4548 989 4549 +f 4550 4549 1475 +f 4548 4549 4550 +f 698 4472 4551 +f 4472 806 4409 +f 4551 4409 1471 +f 4472 4409 4551 +f 138 4552 4476 +f 4552 612 4414 +f 4476 4414 1456 +f 4552 4414 4476 +f 1030 4553 4554 +f 4553 1275 4478 +f 4554 4478 1347 +f 4553 4478 4554 +f 1030 4555 4553 +f 4555 459 4416 +f 4553 4416 1275 +f 4555 4416 4553 +f 496 4358 4477 +f 4358 7 4556 +f 4477 4556 1347 +f 4358 4556 4477 +f 417 4557 4559 +f 4557 592 4558 +f 4559 4558 804 +f 4557 4558 4559 +f 592 4560 4558 +f 4560 284 4422 +f 4558 4422 804 +f 4560 4422 4558 +f 284 4560 4289 +f 4560 592 4561 +f 4289 4561 1201 +f 4560 4561 4289 +f 1017 4562 4496 +f 4562 7 4359 +f 4496 4359 1054 +f 4562 4359 4496 +f 322 4563 4564 +f 4563 105 4489 +f 4564 4489 1356 +f 4563 4489 4564 +f 147 4565 4566 +f 4565 613 4301 +f 4566 4301 950 +f 4565 4301 4566 +f 613 4565 4075 +f 4565 147 4567 +f 4075 4567 731 +f 4565 4567 4075 +f 731 4568 4428 +f 4568 1297 4569 +f 4428 4569 1334 +f 4568 4569 4428 +f 1403 4570 4430 +f 4570 890 4571 +f 4430 4571 1474 +f 4570 4571 4430 +f 951 4572 4500 +f 4572 1014 4573 +f 4500 4573 1403 +f 4572 4573 4500 +f 589 4574 4576 +f 4574 250 4575 +f 4576 4575 1242 +f 4574 4575 4576 +f 250 4577 4575 +f 4577 951 4379 +f 4575 4379 1242 +f 4577 4379 4575 +f 589 4576 4578 +f 4576 1242 4508 +f 4578 4508 1470 +f 4576 4508 4578 +f 575 4579 4580 +f 4579 1136 4436 +f 4580 4436 1164 +f 4579 4436 4580 +f 557 4510 4582 +f 4510 527 4581 +f 4582 4581 900 +f 4510 4581 4582 +f 67 4583 4585 +f 4583 1089 4584 +f 4585 4584 1136 +f 4583 4584 4585 +f 1136 4584 4320 +f 4584 1089 4586 +f 4320 4586 1338 +f 4584 4586 4320 +f 1089 4587 4586 +f 4587 1185 4516 +f 4586 4516 1338 +f 4587 4516 4586 +f 1043 4588 4589 +f 4588 437 4515 +f 4589 4515 1185 +f 4588 4515 4589 +f 1022 4520 4590 +f 4520 437 4588 +f 4590 4588 1043 +f 4520 4588 4590 +f 520 4519 4592 +f 4519 413 4591 +f 4592 4591 847 +f 4519 4591 4592 +f 513 4593 4594 +f 4593 789 4443 +f 4594 4443 1438 +f 4593 4443 4594 +f 239 4595 4446 +f 4595 523 4596 +f 4446 4596 1350 +f 4595 4596 4446 +f 860 4597 4330 +f 4597 716 4598 +f 4330 4598 1438 +f 4597 4598 4330 +f 724 4599 4335 +f 4599 542 4449 +f 4335 4449 1061 +f 4599 4449 4335 +f 163 4525 4600 +f 4525 420 4448 +f 4600 4448 542 +f 4525 4448 4600 +f 342 4389 4602 +f 4389 66 4601 +f 4602 4601 1250 +f 4389 4601 4602 +f 809 4535 4603 +f 4535 342 4602 +f 4603 4602 1250 +f 4535 4602 4603 +f 983 4038 4605 +f 4038 1333 4604 +f 4605 4604 1373 +f 4038 4604 4605 +f 185 4338 4537 +f 4338 983 4605 +f 4537 4605 1373 +f 4338 4605 4537 +f 308 4606 4607 +f 4606 729 4341 +f 4607 4341 850 +f 4606 4341 4607 +f 942 4608 4610 +f 4608 308 4609 +f 4610 4609 1174 +f 4608 4609 4610 +f 687 4544 4611 +f 4544 972 4261 +f 4611 4261 1294 +f 4544 4261 4611 +f 912 4612 4613 +f 4612 687 4611 +f 4613 4611 1294 +f 4612 4611 4613 +f 348 4462 4614 +f 4462 1233 4547 +f 4614 4547 1317 +f 4462 4547 4614 +f 525 4615 4617 +f 4615 470 4616 +f 4617 4616 1294 +f 4615 4616 4617 +f 467 4618 4620 +f 4618 254 4619 +f 4620 4619 1174 +f 4618 4619 4620 +f 630 4621 4466 +f 4621 609 4622 +f 4466 4622 894 +f 4621 4622 4466 +f 467 4468 4624 +f 4468 41 4623 +f 4624 4623 1196 +f 4468 4623 4624 +f 41 4625 4627 +f 4625 878 4626 +f 4627 4626 1082 +f 4625 4626 4627 +f 878 4474 4626 +f 4474 654 4628 +f 4626 4628 1082 +f 4474 4628 4626 +f 617 4629 4630 +f 4629 669 4471 +f 4630 4471 698 +f 4629 4471 4630 +f 654 4473 4632 +f 4473 686 4631 +f 4632 4631 1240 +f 4473 4631 4632 +f 686 4411 4631 +f 4411 1003 4490 +f 4631 4490 1240 +f 4411 4490 4631 +f 263 4633 4634 +f 4633 417 4559 +f 4634 4559 804 +f 4633 4559 4634 +f 618 4635 4636 +f 4635 138 4475 +f 4636 4475 1277 +f 4635 4475 4636 +f 7 4637 4556 +f 4637 667 4638 +f 4556 4638 1347 +f 4637 4638 4556 +f 791 4639 4419 +f 4639 618 4636 +f 4419 4636 1277 +f 4639 4636 4419 +f 459 4555 4484 +f 4555 1030 4640 +f 4484 4640 1224 +f 4555 4640 4484 +f 1201 4561 4642 +f 4561 592 4641 +f 4642 4641 1326 +f 4561 4641 4642 +f 667 4637 4643 +f 4637 7 4562 +f 4643 4562 1017 +f 4637 4562 4643 +f 1161 4644 4492 +f 4644 322 4564 +f 4492 4564 1356 +f 4644 4564 4492 +f 786 4645 4646 +f 4645 322 4644 +f 4646 4644 1161 +f 4645 4644 4646 +f 1017 4495 4647 +f 4495 1201 4642 +f 4647 4642 1326 +f 4495 4642 4647 +f 667 4643 4648 +f 4643 1017 4647 +f 4648 4647 1326 +f 4643 4647 4648 +f 791 4491 4650 +f 4491 603 4649 +f 4650 4649 1253 +f 4491 4649 4650 +f 731 4567 4568 +f 4567 147 4651 +f 4568 4651 1297 +f 4567 4651 4568 +f 1297 4652 4569 +f 4652 17 4653 +f 4569 4653 1334 +f 4652 4653 4569 +f 940 4654 4655 +f 4654 521 4503 +f 4655 4503 1334 +f 4654 4503 4655 +f 1014 4656 4573 +f 4656 1024 4657 +f 4573 4657 1403 +f 4656 4657 4573 +f 743 4658 4659 +f 4658 521 4654 +f 4659 4654 940 +f 4658 4654 4659 +f 951 4577 4572 +f 4577 250 4660 +f 4572 4660 1014 +f 4577 4660 4572 +f 720 4661 4662 +f 4661 575 4580 +f 4662 4580 1164 +f 4661 4580 4662 +f 557 4582 4433 +f 4582 900 4663 +f 4433 4663 905 +f 4582 4663 4433 +f 900 4664 4663 +f 4664 216 4665 +f 4663 4665 905 +f 4664 4665 4663 +f 1136 4579 4667 +f 4579 575 4666 +f 4667 4666 1298 +f 4579 4666 4667 +f 67 4585 4668 +f 4585 1136 4667 +f 4668 4667 1298 +f 4585 4667 4668 +f 67 4668 4670 +f 4668 1298 4669 +f 4670 4669 1462 +f 4668 4669 4670 +f 1089 4583 4671 +f 4583 67 4670 +f 4671 4670 1462 +f 4583 4670 4671 +f 334 4672 4509 +f 4672 157 4673 +f 4509 4673 527 +f 4672 4673 4509 +f 157 4672 4674 +f 4672 334 4511 +f 4674 4511 1158 +f 4672 4511 4674 +f 46 4675 4676 +f 4675 1158 4513 +f 4676 4513 1461 +f 4675 4513 4676 +f 520 4592 4517 +f 4592 847 4677 +f 4517 4677 1461 +f 4592 4677 4517 +f 367 4678 4679 +f 4678 98 4521 +f 4679 4521 1022 +f 4678 4521 4679 +f 98 4678 4681 +f 4678 367 4680 +f 4681 4680 523 +f 4678 4680 4681 +f 513 4682 4593 +f 4682 64 4442 +f 4593 4442 789 +f 4682 4442 4593 +f 413 4518 4683 +f 4518 64 4682 +f 4683 4682 513 +f 4518 4682 4683 +f 239 4522 4595 +f 4522 98 4681 +f 4595 4681 523 +f 4522 4681 4595 +f 86 4684 4686 +f 4684 716 4685 +f 4686 4685 1223 +f 4684 4685 4686 +f 716 4597 4685 +f 4597 860 4332 +f 4685 4332 1223 +f 4597 4332 4685 +f 820 4687 4524 +f 4687 86 4686 +f 4524 4686 1223 +f 4687 4686 4524 +f 163 4688 4526 +f 4688 820 4523 +f 4526 4523 840 +f 4688 4523 4526 +f 423 4529 4689 +f 4529 276 4452 +f 4689 4452 949 +f 4529 4452 4689 +f 729 4690 4453 +f 4690 319 4691 +f 4453 4691 1107 +f 4690 4691 4453 +f 125 4692 4693 +f 4692 361 4395 +f 4693 4395 1303 +f 4692 4395 4693 +f 308 4694 4606 +f 4694 319 4690 +f 4606 4690 729 +f 4694 4690 4606 +f 765 4695 4696 +f 4695 348 4614 +f 4696 4614 1317 +f 4695 4614 4696 +f 684 4697 4698 +f 4697 630 4550 +f 4698 4550 1475 +f 4697 4550 4698 +f 634 4699 4464 +f 4699 800 4700 +f 4464 4700 1205 +f 4699 4700 4464 +f 41 4627 4623 +f 4627 1082 4701 +f 4623 4701 1196 +f 4627 4701 4623 +f 617 4702 4629 +f 4702 263 4703 +f 4629 4703 669 +f 4702 4703 4629 +f 669 4703 4353 +f 4703 263 4634 +f 4353 4634 804 +f 4703 4634 4353 +f 612 4552 4705 +f 4552 138 4704 +f 4705 4704 854 +f 4552 4704 4705 +f 1224 4640 4707 +f 4640 1030 4706 +f 4707 4706 1252 +f 4640 4706 4707 +f 592 4708 4641 +f 4708 877 4709 +f 4641 4709 1326 +f 4708 4709 4641 +f 749 4710 4712 +f 4710 322 4711 +f 4712 4711 796 +f 4710 4711 4712 +f 105 4563 4713 +f 4563 322 4710 +f 4713 4710 749 +f 4563 4710 4713 +f 322 4645 4711 +f 4645 786 4714 +f 4711 4714 796 +f 4645 4714 4711 +f 603 4213 4649 +f 4213 1085 4715 +f 4649 4715 1253 +f 4213 4715 4649 +f 1024 4716 4657 +f 4716 890 4570 +f 4657 4570 1403 +f 4716 4570 4657 +f 237 4717 4718 +f 4717 521 4658 +f 4718 4658 743 +f 4717 4658 4718 +f 164 4719 4720 +f 4719 250 4574 +f 4720 4574 589 +f 4719 4574 4720 +f 521 4717 4506 +f 4717 237 4721 +f 4506 4721 1164 +f 4717 4721 4506 +f 164 4720 4723 +f 4720 589 4722 +f 4723 4722 1076 +f 4720 4722 4723 +f 237 4724 4721 +f 4724 720 4662 +f 4721 4662 1164 +f 4724 4662 4721 +f 527 4673 4726 +f 4673 157 4725 +f 4726 4725 1045 +f 4673 4725 4726 +f 1089 4727 4587 +f 4727 189 4728 +f 4587 4728 1185 +f 4727 4728 4587 +f 189 4729 4728 +f 4729 1043 4589 +f 4728 4589 1185 +f 4729 4589 4728 +f 523 4730 4596 +f 4730 229 4731 +f 4596 4731 1350 +f 4730 4731 4596 +f 892 4732 4734 +f 4732 447 4733 +f 4734 4733 1350 +f 4732 4733 4734 +f 447 4735 4733 +f 4735 724 4447 +f 4733 4447 1350 +f 4735 4447 4733 +f 724 4735 4737 +f 4735 447 4736 +f 4737 4736 733 +f 4735 4736 4737 +f 542 4599 4738 +f 4599 724 4737 +f 4738 4737 733 +f 4599 4737 4738 +f 163 4600 4739 +f 4600 542 4738 +f 4739 4738 733 +f 4600 4738 4739 +f 66 4534 4601 +f 4534 423 4740 +f 4601 4740 1250 +f 4534 4740 4601 +f 1333 4741 4604 +f 4741 10 4742 +f 4604 4742 1373 +f 4741 4742 4604 +f 1288 4743 4251 +f 4743 10 4741 +f 4251 4741 1333 +f 4743 4741 4251 +f 823 4744 4745 +f 4744 610 4533 +f 4745 4533 1107 +f 4744 4533 4745 +f 388 4746 4748 +f 4746 125 4747 +f 4748 4747 408 +f 4746 4747 4748 +f 361 4692 4545 +f 4692 125 4746 +f 4545 4746 388 +f 4692 4746 4545 +f 388 4748 4750 +f 4748 408 4749 +f 4750 4749 732 +f 4748 4749 4750 +f 358 4751 4752 +f 4751 348 4695 +f 4752 4695 765 +f 4751 4695 4752 +f 492 4753 4754 +f 4753 684 4698 +f 4754 4698 1475 +f 4753 4698 4754 +f 654 4632 4756 +f 4632 1240 4755 +f 4756 4755 1457 +f 4632 4755 4756 +f 138 4635 4704 +f 4635 618 4757 +f 4704 4757 854 +f 4635 4757 4704 +f 278 4758 4759 +f 4758 612 4705 +f 4759 4705 854 +f 4758 4705 4759 +f 592 4557 4708 +f 4557 417 4760 +f 4708 4760 877 +f 4557 4760 4708 +f 278 4761 4758 +f 4761 402 4479 +f 4758 4479 612 +f 4761 4479 4758 +f 402 4761 4486 +f 4761 278 4762 +f 4486 4762 1161 +f 4761 4762 4486 +f 749 4763 4765 +f 4763 803 4764 +f 4765 4764 1240 +f 4763 4764 4765 +f 105 4713 4487 +f 4713 749 4765 +f 4487 4765 1240 +f 4713 4765 4487 +f 618 4639 4767 +f 4639 791 4766 +f 4767 4766 1477 +f 4639 4766 4767 +f 278 4768 4762 +f 4768 786 4646 +f 4762 4646 1161 +f 4768 4646 4762 +f 791 4650 4766 +f 4650 1253 4769 +f 4766 4769 1477 +f 4650 4769 4766 +f 507 4770 4771 +f 4770 950 4498 +f 4771 4498 1224 +f 4770 4498 4771 +f 89 4772 4773 +f 4772 147 4566 +f 4773 4566 950 +f 4772 4566 4773 +f 32 4774 4775 +f 4774 17 4652 +f 4775 4652 1297 +f 4774 4652 4775 +f 17 4776 4653 +f 4776 940 4655 +f 4653 4655 1334 +f 4776 4655 4653 +f 164 4777 4779 +f 4777 324 4778 +f 4779 4778 1014 +f 4777 4778 4779 +f 250 4719 4660 +f 4719 164 4779 +f 4660 4779 1014 +f 4719 4779 4660 +f 1076 4722 4780 +f 4722 589 4578 +f 4780 4578 1470 +f 4722 4578 4780 +f 922 4781 4783 +f 4781 720 4782 +f 4783 4782 1388 +f 4781 4782 4783 +f 575 4661 4784 +f 4661 720 4781 +f 4784 4781 922 +f 4661 4781 4784 +f 905 4785 4507 +f 4785 1316 4786 +f 4507 4786 1470 +f 4785 4786 4507 +f 905 4665 4785 +f 4665 216 4787 +f 4785 4787 1316 +f 4665 4787 4785 +f 575 4784 4666 +f 4784 922 4788 +f 4666 4788 1298 +f 4784 4788 4666 +f 216 4664 4790 +f 4664 900 4789 +f 4790 4789 1045 +f 4664 4789 4790 +f 900 4581 4789 +f 4581 527 4726 +f 4789 4726 1045 +f 4581 4726 4789 +f 847 4791 4677 +f 4791 52 4792 +f 4677 4792 1461 +f 4791 4792 4677 +f 52 4791 4794 +f 4791 847 4793 +f 4794 4793 1486 +f 4791 4793 4794 +f 1382 4795 4797 +f 4795 1043 4796 +f 4797 4796 1422 +f 4795 4796 4797 +f 1022 4590 4798 +f 4590 1043 4795 +f 4798 4795 1382 +f 4590 4795 4798 +f 317 4799 4800 +f 4799 367 4679 +f 4800 4679 1022 +f 4799 4679 4800 +f 317 4800 4801 +f 4800 1022 4798 +f 4801 4798 1382 +f 4800 4798 4801 +f 1433 4802 4803 +f 4802 513 4594 +f 4803 4594 1438 +f 4802 4594 4803 +f 716 4804 4598 +f 4804 1433 4803 +f 4598 4803 1438 +f 4804 4803 4598 +f 229 4805 4731 +f 4805 892 4734 +f 4731 4734 1350 +f 4805 4734 4731 +f 163 4739 4807 +f 4739 733 4806 +f 4807 4806 866 +f 4739 4806 4807 +f 423 4689 4740 +f 4689 949 4808 +f 4740 4808 1250 +f 4689 4808 4740 +f 10 4809 4742 +f 4809 494 4810 +f 4742 4810 1373 +f 4809 4810 4742 +f 955 4811 4393 +f 4811 723 4812 +f 4393 4812 1288 +f 4811 4812 4393 +f 494 4813 4810 +f 4813 688 4538 +f 4810 4538 1373 +f 4813 4538 4810 +f 454 4814 4815 +f 4814 571 4531 +f 4815 4531 688 +f 4814 4531 4815 +f 571 4814 4252 +f 4814 454 4816 +f 4252 4816 1303 +f 4814 4816 4252 +f 663 4455 4818 +f 4455 515 4817 +f 4818 4817 695 +f 4455 4817 4818 +f 663 4818 4546 +f 4818 695 4819 +f 4546 4819 1317 +f 4818 4819 4546 +f 358 4820 4821 +f 4820 492 4754 +f 4821 4754 1475 +f 4820 4754 4821 +f 800 4822 4700 +f 4822 759 4823 +f 4700 4823 1205 +f 4822 4823 4700 +f 800 4824 4826 +f 4824 894 4825 +f 4826 4825 1099 +f 4824 4825 4826 +f 285 4827 4829 +f 4827 677 4828 +f 4829 4828 1196 +f 4827 4828 4829 +f 1292 4830 4831 +f 4830 698 4551 +f 4831 4551 1471 +f 4830 4551 4831 +f 718 4832 4833 +f 4832 1292 4831 +f 4833 4831 1471 +f 4832 4831 4833 +f 617 4630 4834 +f 4630 698 4830 +f 4834 4830 1292 +f 4630 4830 4834 +f 618 4835 4757 +f 4835 136 4836 +f 4757 4836 854 +f 4835 4836 4757 +f 417 4837 4760 +f 4837 215 4838 +f 4760 4838 877 +f 4837 4838 4760 +f 667 4839 4638 +f 4839 958 4840 +f 4638 4840 1347 +f 4839 4840 4638 +f 877 4841 4709 +f 4841 1309 4842 +f 4709 4842 1326 +f 4841 4842 4709 +f 1253 4843 4769 +f 4843 392 4844 +f 4769 4844 1477 +f 4843 4844 4769 +f 1057 4845 4847 +f 4845 507 4846 +f 4847 4846 1252 +f 4845 4846 4847 +f 507 4771 4846 +f 4771 1224 4707 +f 4846 4707 1252 +f 4771 4707 4846 +f 507 4848 4770 +f 4848 89 4773 +f 4770 4773 950 +f 4848 4773 4770 +f 1085 4302 4715 +f 4302 886 4849 +f 4715 4849 1253 +f 4302 4849 4715 +f 147 4772 4651 +f 4772 89 4850 +f 4651 4850 1297 +f 4772 4850 4651 +f 493 4851 4852 +f 4851 886 4305 +f 4852 4305 1474 +f 4851 4305 4852 +f 890 4853 4571 +f 4853 108 4854 +f 4571 4854 1474 +f 4853 4854 4571 +f 17 4774 4776 +f 4774 32 4855 +f 4776 4855 940 +f 4774 4855 4776 +f 108 4853 4856 +f 4853 890 4716 +f 4856 4716 1024 +f 4853 4716 4856 +f 743 4659 4858 +f 4659 940 4857 +f 4858 4857 1496 +f 4659 4857 4858 +f 237 4718 4859 +f 4718 743 4858 +f 4859 4858 1496 +f 4718 4858 4859 +f 1388 4782 4861 +f 4782 720 4860 +f 4861 4860 1496 +f 4782 4860 4861 +f 720 4724 4860 +f 4724 237 4859 +f 4860 4859 1496 +f 4724 4859 4860 +f 761 4862 4863 +f 4862 1076 4780 +f 4863 4780 1470 +f 4862 4780 4863 +f 1118 4864 4865 +f 4864 761 4863 +f 4865 4863 1470 +f 4864 4863 4865 +f 1316 4866 4786 +f 4866 1118 4865 +f 4786 4865 1470 +f 4866 4865 4786 +f 922 4867 4788 +f 4867 182 4868 +f 4788 4868 1298 +f 4867 4868 4788 +f 216 4790 4787 +f 4790 1045 4869 +f 4787 4869 1316 +f 4790 4869 4787 +f 46 4870 4675 +f 4870 157 4674 +f 4675 4674 1158 +f 4870 4674 4675 +f 157 4870 4872 +f 4870 46 4871 +f 4872 4871 1458 +f 4870 4871 4872 +f 1043 4873 4796 +f 4873 827 4874 +f 4796 4874 1422 +f 4873 4874 4796 +f 189 4875 4729 +f 4875 827 4873 +f 4729 4873 1043 +f 4875 4873 4729 +f 1382 4797 4877 +f 4797 1422 4876 +f 4877 4876 1443 +f 4797 4876 4877 +f 523 4680 4879 +f 4680 367 4878 +f 4879 4878 708 +f 4680 4878 4879 +f 229 4730 4880 +f 4730 523 4879 +f 4880 4879 708 +f 4730 4879 4880 +f 86 4687 4882 +f 4687 820 4881 +f 4882 4881 916 +f 4687 4881 4882 +f 820 4688 4883 +f 4688 163 4807 +f 4883 4807 866 +f 4688 4807 4883 +f 475 4884 4885 +f 4884 298 4536 +f 4885 4536 809 +f 4884 4536 4885 +f 298 4884 4392 +f 4884 475 4886 +f 4392 4886 515 +f 4884 4886 4392 +f 183 4887 4888 +f 4887 723 4811 +f 4888 4811 955 +f 4887 4811 4888 +f 238 4889 4891 +f 4889 183 4890 +f 4891 4890 822 +f 4889 4890 4891 +f 822 4890 4539 +f 4890 183 4888 +f 4539 4888 955 +f 4890 4888 4539 +f 1303 4816 4893 +f 4816 454 4892 +f 4893 4892 1358 +f 4816 4892 4893 +f 319 4894 4691 +f 4894 823 4745 +f 4691 4745 1107 +f 4894 4745 4691 +f 695 4817 4896 +f 4817 515 4895 +f 4896 4895 753 +f 4817 4895 4896 +f 515 4886 4895 +f 4886 475 4897 +f 4895 4897 753 +f 4886 4897 4895 +f 319 4694 4899 +f 4694 308 4898 +f 4899 4898 1330 +f 4694 4898 4899 +f 745 4900 4902 +f 4900 492 4901 +f 4902 4901 765 +f 4900 4901 4902 +f 57 4903 4905 +f 4903 525 4904 +f 4905 4904 759 +f 4903 4904 4905 +f 1196 4701 4907 +f 4701 1082 4906 +f 4907 4906 1257 +f 4701 4906 4907 +f 1240 4764 4755 +f 4764 803 4908 +f 4755 4908 1457 +f 4764 4908 4755 +f 958 4909 4840 +f 4909 910 4910 +f 4840 4910 1347 +f 4909 4910 4840 +f 910 4911 4910 +f 4911 1030 4554 +f 4910 4554 1347 +f 4911 4554 4910 +f 1030 4911 4706 +f 4911 910 4912 +f 4706 4912 1252 +f 4911 4912 4706 +f 877 4913 4841 +f 4913 339 4914 +f 4841 4914 1309 +f 4913 4914 4841 +f 667 4915 4839 +f 4915 481 4916 +f 4839 4916 958 +f 4915 4916 4839 +f 786 4768 4917 +f 4768 278 4759 +f 4917 4759 854 +f 4768 4759 4917 +f 786 4917 4919 +f 4917 854 4918 +f 4919 4918 1114 +f 4917 4918 4919 +f 796 4714 4920 +f 4714 786 4919 +f 4920 4919 1114 +f 4714 4919 4920 +f 1309 4921 4842 +f 4921 481 4922 +f 4842 4922 1326 +f 4921 4922 4842 +f 481 4915 4922 +f 4915 667 4648 +f 4922 4648 1326 +f 4915 4648 4922 +f 89 4848 4924 +f 4848 507 4923 +f 4924 4923 1335 +f 4848 4923 4924 +f 886 4851 4849 +f 4851 493 4925 +f 4849 4925 1253 +f 4851 4925 4849 +f 89 4926 4850 +f 4926 961 4927 +f 4850 4927 1297 +f 4926 4927 4850 +f 108 4928 4854 +f 4928 493 4852 +f 4854 4852 1474 +f 4928 4852 4854 +f 961 4929 4927 +f 4929 32 4775 +f 4927 4775 1297 +f 4929 4775 4927 +f 940 4930 4857 +f 4930 1398 4931 +f 4857 4931 1496 +f 4930 4931 4857 +f 1014 4778 4656 +f 4778 324 4932 +f 4656 4932 1024 +f 4778 4932 4656 +f 532 4933 4935 +f 4933 324 4934 +f 4935 4934 1120 +f 4933 4934 4935 +f 324 4777 4934 +f 4777 164 4936 +f 4934 4936 1120 +f 4777 4936 4934 +f 164 4723 4936 +f 4723 1076 4937 +f 4936 4937 1120 +f 4723 4937 4936 +f 33 4938 4939 +f 4938 922 4783 +f 4939 4783 1388 +f 4938 4783 4939 +f 33 4940 4938 +f 4940 914 4941 +f 4938 4941 922 +f 4940 4941 4938 +f 1298 4868 4669 +f 4868 182 4942 +f 4669 4942 1462 +f 4868 4942 4669 +f 1045 4725 4943 +f 4725 157 4872 +f 4943 4872 1458 +f 4725 4872 4943 +f 189 4727 4944 +f 4727 1089 4671 +f 4944 4671 1462 +f 4727 4671 4944 +f 827 4875 4945 +f 4875 189 4944 +f 4945 4944 1462 +f 4875 4944 4945 +f 46 4946 4871 +f 4946 443 4947 +f 4871 4947 1458 +f 4946 4947 4871 +f 443 4946 4948 +f 4946 46 4676 +f 4948 4676 1461 +f 4946 4676 4948 +f 443 4949 4951 +f 4949 52 4950 +f 4951 4950 769 +f 4949 4950 4951 +f 52 4949 4792 +f 4949 443 4948 +f 4792 4948 1461 +f 4949 4948 4792 +f 769 4950 4952 +f 4950 52 4794 +f 4952 4794 1486 +f 4950 4794 4952 +f 847 4953 4793 +f 4953 432 4954 +f 4793 4954 1486 +f 4953 4954 4793 +f 413 4955 4591 +f 4955 432 4953 +f 4591 4953 847 +f 4955 4953 4591 +f 367 4799 4878 +f 4799 317 4956 +f 4878 4956 708 +f 4799 4956 4878 +f 413 4683 4957 +f 4683 513 4802 +f 4957 4802 1433 +f 4683 4802 4957 +f 432 4955 4958 +f 4955 413 4957 +f 4958 4957 1433 +f 4955 4957 4958 +f 229 4880 4960 +f 4880 708 4959 +f 4960 4959 1478 +f 4880 4959 4960 +f 716 4684 4961 +f 4684 86 4882 +f 4961 4882 916 +f 4684 4882 4961 +f 447 4732 4963 +f 4732 892 4962 +f 4963 4962 1377 +f 4732 4962 4963 +f 949 4964 4808 +f 4964 1132 4965 +f 4808 4965 1250 +f 4964 4965 4808 +f 1132 4966 4965 +f 4966 809 4603 +f 4965 4603 1250 +f 4966 4603 4965 +f 723 4967 4812 +f 4967 10 4743 +f 4812 4743 1288 +f 4967 4743 4812 +f 494 4809 4968 +f 4809 10 4967 +f 4968 4967 723 +f 4809 4967 4968 +f 949 4528 4964 +f 4528 610 4969 +f 4964 4969 1132 +f 4528 4969 4964 +f 494 4970 4813 +f 4970 454 4815 +f 4813 4815 688 +f 4970 4815 4813 +f 687 4971 4543 +f 4971 238 4891 +f 4543 4891 822 +f 4971 4891 4543 +f 238 4971 4973 +f 4971 687 4972 +f 4973 4972 702 +f 4971 4972 4973 +f 319 4974 4894 +f 4974 297 4975 +f 4894 4975 823 +f 4974 4975 4894 +f 125 4693 4976 +f 4693 1303 4893 +f 4976 4893 1358 +f 4693 4893 4976 +f 297 4974 4977 +f 4974 319 4899 +f 4977 4899 1330 +f 4974 4899 4977 +f 702 4972 4978 +f 4972 687 4612 +f 4978 4612 912 +f 4972 4612 4978 +f 942 4979 4981 +f 4979 677 4980 +f 4981 4980 1322 +f 4979 4980 4981 +f 684 4982 4984 +f 4982 745 4983 +f 4984 4983 1289 +f 4982 4983 4984 +f 745 4985 4983 +f 4985 640 4986 +f 4983 4986 1289 +f 4985 4986 4983 +f 560 4987 4988 +f 4987 800 4826 +f 4988 4826 1099 +f 4987 4826 4988 +f 81 4989 4990 +f 4989 560 4988 +f 4990 4988 1099 +f 4989 4988 4990 +f 285 4829 4992 +f 4829 1196 4991 +f 4992 4991 1409 +f 4829 4991 4992 +f 1292 4832 4994 +f 4832 718 4993 +f 4994 4993 1371 +f 4832 4993 4994 +f 1292 4994 4996 +f 4994 1371 4995 +f 4996 4995 1418 +f 4994 4995 4996 +f 1082 4628 4906 +f 4628 654 4997 +f 4906 4997 1257 +f 4628 4997 4906 +f 617 4834 4998 +f 4834 1292 4996 +f 4998 4996 1418 +f 4834 4996 4998 +f 263 4702 5000 +f 4702 617 4999 +f 5000 4999 1187 +f 4702 4999 5000 +f 154 5001 5002 +f 5001 654 4756 +f 5002 4756 1457 +f 5001 4756 5002 +f 803 5003 4908 +f 5003 957 5004 +f 4908 5004 1457 +f 5003 5004 4908 +f 215 4837 5006 +f 4837 417 5005 +f 5006 5005 1187 +f 4837 5005 5006 +f 417 4633 5005 +f 4633 263 5000 +f 5005 5000 1187 +f 4633 5000 5005 +f 803 4763 5008 +f 4763 749 5007 +f 5008 5007 985 +f 4763 5007 5008 +f 910 5009 4912 +f 5009 1057 4847 +f 4912 4847 1252 +f 5009 4847 4912 +f 749 4712 5007 +f 4712 796 5010 +f 5007 5010 985 +f 4712 5010 5007 +f 985 5010 5011 +f 5010 796 4920 +f 5011 4920 1114 +f 5010 4920 5011 +f 507 4845 4923 +f 4845 1057 5012 +f 4923 5012 1335 +f 4845 5012 4923 +f 493 5013 4925 +f 5013 392 4843 +f 4925 4843 1253 +f 5013 4843 4925 +f 961 4926 5014 +f 4926 89 4924 +f 5014 4924 1335 +f 4926 4924 5014 +f 493 4928 5016 +f 4928 108 5015 +f 5016 5015 692 +f 4928 5015 5016 +f 32 4929 5018 +f 4929 961 5017 +f 5018 5017 1398 +f 4929 5017 5018 +f 940 4855 4930 +f 4855 32 5018 +f 4930 5018 1398 +f 4855 5018 4930 +f 872 5019 5020 +f 5019 108 4856 +f 5020 4856 1024 +f 5019 4856 5020 +f 324 5021 4932 +f 5021 872 5020 +f 4932 5020 1024 +f 5021 5020 4932 +f 747 5022 5023 +f 5022 1388 4861 +f 5023 4861 1496 +f 5022 4861 5023 +f 997 5024 5025 +f 5024 1118 4866 +f 5025 4866 1316 +f 5024 4866 5025 +f 337 5026 5027 +f 5026 997 5025 +f 5027 5025 1316 +f 5026 5025 5027 +f 182 5028 5030 +f 5028 914 5029 +f 5030 5029 1013 +f 5028 5029 5030 +f 914 5028 4941 +f 5028 182 4867 +f 4941 4867 922 +f 5028 4867 4941 +f 1045 5031 4869 +f 5031 337 5027 +f 4869 5027 1316 +f 5031 5027 4869 +f 119 5032 5034 +f 5032 914 5033 +f 5034 5033 1276 +f 5032 5033 5034 +f 914 5035 5033 +f 5035 58 5036 +f 5033 5036 1276 +f 5035 5036 5033 +f 819 5037 5039 +f 5037 236 5038 +f 5039 5038 1443 +f 5037 5038 5039 +f 827 5040 4874 +f 5040 1362 5041 +f 4874 5041 1422 +f 5040 5041 4874 +f 115 5042 5044 +f 5042 562 5043 +f 5044 5043 1486 +f 5042 5043 5044 +f 317 4801 5045 +f 4801 1382 4877 +f 5045 4877 1443 +f 4801 4877 5045 +f 892 4805 5046 +f 4805 229 4960 +f 5046 4960 1478 +f 4805 4960 5046 +f 716 5047 4804 +f 5047 309 5048 +f 4804 5048 1433 +f 5047 5048 4804 +f 309 5047 5049 +f 5047 716 4961 +f 5049 4961 916 +f 5047 4961 5049 +f 733 4736 5050 +f 4736 447 4963 +f 5050 4963 1377 +f 4736 4963 5050 +f 820 5051 4881 +f 5051 851 5052 +f 4881 5052 916 +f 5051 5052 4881 +f 851 5051 5053 +f 5051 820 4883 +f 5053 4883 866 +f 5051 4883 5053 +f 866 4806 5054 +f 4806 733 5050 +f 5054 5050 1377 +f 4806 5050 5054 +f 454 5055 4892 +f 5055 551 5056 +f 4892 5056 1358 +f 5055 5056 4892 +f 305 5057 5058 +f 5057 238 4973 +f 5058 4973 702 +f 5057 4973 5058 +f 702 4978 5060 +f 4978 912 5059 +f 5060 5059 1173 +f 4978 5059 5060 +f 408 5061 5063 +f 5061 1358 5062 +f 5063 5062 1363 +f 5061 5062 5063 +f 408 4747 5061 +f 4747 125 4976 +f 5061 4976 1358 +f 4747 4976 5061 +f 1103 5064 5065 +f 5064 408 5063 +f 5065 5063 1363 +f 5064 5063 5065 +f 57 5066 5068 +f 5066 519 5067 +f 5068 5067 1173 +f 5066 5067 5068 +f 745 4902 5070 +f 4902 765 5069 +f 5070 5069 1200 +f 4902 5069 5070 +f 640 5071 4986 +f 5071 306 5072 +f 4986 5072 1289 +f 5071 5072 4986 +f 1287 5073 5074 +f 5073 285 4992 +f 5074 4992 1409 +f 5073 4992 5074 +f 1371 4993 5076 +f 4993 718 5075 +f 5076 5075 1435 +f 4993 5075 5076 +f 1196 4907 4991 +f 4907 1257 5077 +f 4991 5077 1409 +f 4907 5077 4991 +f 654 5001 4997 +f 5001 154 5078 +f 4997 5078 1257 +f 5001 5078 4997 +f 477 5079 5080 +f 5079 617 4998 +f 5080 4998 1418 +f 5079 4998 5080 +f 617 5079 4999 +f 5079 477 5081 +f 4999 5081 1187 +f 5079 5081 4999 +f 339 5082 5084 +f 5082 215 5083 +f 5084 5083 1241 +f 5082 5083 5084 +f 215 5082 4838 +f 5082 339 4913 +f 4838 4913 877 +f 5082 4913 4838 +f 136 4835 5085 +f 4835 618 4767 +f 5085 4767 1477 +f 4835 4767 5085 +f 136 5086 4836 +f 5086 143 5087 +f 4836 5087 854 +f 5086 5087 4836 +f 339 5088 4914 +f 5088 368 5089 +f 4914 5089 1309 +f 5088 5089 4914 +f 910 4909 5091 +f 4909 958 5090 +f 5091 5090 1040 +f 4909 5090 5091 +f 854 5087 4918 +f 5087 143 5092 +f 4918 5092 1114 +f 5087 5092 4918 +f 481 4921 5094 +f 4921 1309 5093 +f 5094 5093 1325 +f 4921 5093 5094 +f 958 4916 5095 +f 4916 481 5094 +f 5095 5094 1325 +f 4916 5094 5095 +f 918 5096 5097 +f 5096 985 5011 +f 5097 5011 1114 +f 5096 5011 5097 +f 392 5013 5099 +f 5013 493 5098 +f 5099 5098 927 +f 5013 5098 5099 +f 493 5016 5098 +f 5016 692 5100 +f 5098 5100 927 +f 5016 5100 5098 +f 692 5015 5101 +f 5015 108 5019 +f 5101 5019 872 +f 5015 5019 5101 +f 961 5102 5017 +f 5102 619 5103 +f 5017 5103 1398 +f 5102 5103 5017 +f 324 4933 5021 +f 4933 532 5104 +f 5021 5104 872 +f 4933 5104 5021 +f 1398 5105 4931 +f 5105 747 5023 +f 4931 5023 1496 +f 5105 5023 4931 +f 532 4935 5107 +f 4935 1120 5106 +f 5107 5106 1361 +f 4935 5106 5107 +f 747 5108 5022 +f 5108 1384 5109 +f 5022 5109 1388 +f 5108 5109 5022 +f 1120 4937 5111 +f 4937 1076 5110 +f 5111 5110 1123 +f 4937 5110 5111 +f 914 4940 5113 +f 4940 33 5112 +f 5113 5112 1130 +f 4940 5112 5113 +f 58 5035 5114 +f 5035 914 5113 +f 5114 5113 1130 +f 5035 5113 5114 +f 914 5032 5029 +f 5032 119 5115 +f 5029 5115 1013 +f 5032 5115 5029 +f 1013 5116 5118 +f 5116 1148 5117 +f 5118 5117 1462 +f 5116 5117 5118 +f 182 5030 4942 +f 5030 1013 5118 +f 4942 5118 1462 +f 5030 5118 4942 +f 337 5031 5119 +f 5031 1045 4943 +f 5119 4943 1458 +f 5031 4943 5119 +f 924 5120 5122 +f 5120 561 5121 +f 5122 5121 1118 +f 5120 5121 5122 +f 58 5123 5036 +f 5123 819 5124 +f 5036 5124 1276 +f 5123 5124 5036 +f 819 5125 5124 +f 5125 119 5034 +f 5124 5034 1276 +f 5125 5034 5124 +f 1148 5126 5117 +f 5126 827 4945 +f 5117 4945 1462 +f 5126 4945 5117 +f 562 5042 5128 +f 5042 115 5127 +f 5128 5127 924 +f 5042 5127 5128 +f 115 5129 5127 +f 5129 561 5120 +f 5127 5120 924 +f 5129 5120 5127 +f 58 5130 5123 +f 5130 236 5037 +f 5123 5037 819 +f 5130 5037 5123 +f 443 4951 4947 +f 4951 769 5131 +f 4947 5131 1458 +f 4951 5131 4947 +f 562 5132 5043 +f 5132 769 4952 +f 5043 4952 1486 +f 5132 4952 5043 +f 562 5133 5132 +f 5133 114 5134 +f 5132 5134 769 +f 5133 5134 5132 +f 1422 5041 4876 +f 5041 1362 5135 +f 4876 5135 1443 +f 5041 5135 4876 +f 1362 5136 5135 +f 5136 819 5039 +f 5135 5039 1443 +f 5136 5039 5135 +f 236 5137 5038 +f 5137 1264 5138 +f 5038 5138 1443 +f 5137 5138 5038 +f 421 5139 5140 +f 5139 115 5044 +f 5140 5044 1486 +f 5139 5044 5140 +f 1264 5141 5138 +f 5141 317 5045 +f 5138 5045 1443 +f 5141 5045 5138 +f 309 5142 5048 +f 5142 1397 5143 +f 5048 5143 1433 +f 5142 5143 5048 +f 262 5144 5146 +f 5144 1132 5145 +f 5146 5145 1426 +f 5144 5145 5146 +f 262 5147 5144 +f 5147 809 4966 +f 5144 4966 1132 +f 5147 4966 5144 +f 466 5148 5149 +f 5148 494 4968 +f 5149 4968 723 +f 5148 4968 5149 +f 466 5150 5148 +f 5150 454 4970 +f 5148 4970 494 +f 5150 4970 5148 +f 610 4744 5152 +f 4744 823 5151 +f 5152 5151 1426 +f 4744 5151 5152 +f 823 5153 5151 +f 5153 135 5154 +f 5151 5154 1426 +f 5153 5154 5151 +f 1132 4969 5145 +f 4969 610 5152 +f 5145 5152 1426 +f 4969 5152 5145 +f 475 5155 4897 +f 5155 262 5156 +f 4897 5156 753 +f 5155 5156 4897 +f 262 5155 5147 +f 5155 475 4885 +f 5147 4885 809 +f 5155 4885 5147 +f 723 4887 5158 +f 4887 183 5157 +f 5158 5157 1176 +f 4887 5157 5158 +f 183 4889 5157 +f 4889 238 5159 +f 5157 5159 1176 +f 4889 5159 5157 +f 238 5057 5159 +f 5057 305 5160 +f 5159 5160 1176 +f 5057 5160 5159 +f 695 4896 5162 +f 4896 753 5161 +f 5162 5161 1209 +f 4896 5161 5162 +f 1140 5163 5164 +f 5163 702 5060 +f 5164 5060 1173 +f 5163 5060 5164 +f 471 5165 5167 +f 5165 331 5166 +f 5167 5166 1289 +f 5165 5166 5167 +f 306 5168 5072 +f 5168 471 5167 +f 5072 5167 1289 +f 5168 5167 5072 +f 766 5169 5170 +f 5169 1287 5074 +f 5170 5074 1409 +f 5169 5074 5170 +f 828 5171 5172 +f 5171 154 5002 +f 5172 5002 1457 +f 5171 5002 5172 +f 455 5173 5175 +f 5173 190 5174 +f 5175 5174 803 +f 5173 5174 5175 +f 455 5175 5176 +f 5175 803 5008 +f 5176 5008 985 +f 5175 5008 5176 +f 1172 5177 5178 +f 5177 136 5085 +f 5178 5085 1477 +f 5177 5085 5178 +f 143 5086 5179 +f 5086 136 5177 +f 5179 5177 1172 +f 5086 5177 5179 +f 368 5088 5181 +f 5088 339 5180 +f 5181 5180 516 +f 5088 5180 5181 +f 927 5182 5183 +f 5182 1172 5178 +f 5183 5178 1477 +f 5182 5178 5183 +f 392 5099 4844 +f 5099 927 5183 +f 4844 5183 1477 +f 5099 5183 4844 +f 910 5091 5009 +f 5091 1040 5184 +f 5009 5184 1057 +f 5091 5184 5009 +f 143 5185 5092 +f 5185 918 5097 +f 5092 5097 1114 +f 5185 5097 5092 +f 918 5185 5186 +f 5185 143 5179 +f 5186 5179 1172 +f 5185 5179 5186 +f 1309 5089 5093 +f 5089 368 5187 +f 5093 5187 1325 +f 5089 5187 5093 +f 1040 5090 5188 +f 5090 958 5095 +f 5188 5095 1325 +f 5090 5095 5188 +f 1040 5189 5184 +f 5189 78 5190 +f 5184 5190 1057 +f 5189 5190 5184 +f 1057 5190 5012 +f 5190 78 5191 +f 5012 5191 1335 +f 5190 5191 5012 +f 927 5100 5193 +f 5100 692 5192 +f 5193 5192 1265 +f 5100 5192 5193 +f 78 5194 5191 +f 5194 619 5195 +f 5191 5195 1335 +f 5194 5195 5191 +f 619 5102 5195 +f 5102 961 5014 +f 5195 5014 1335 +f 5102 5014 5195 +f 692 5101 5192 +f 5101 872 5196 +f 5192 5196 1265 +f 5101 5196 5192 +f 1265 5196 5198 +f 5196 872 5197 +f 5198 5197 1361 +f 5196 5197 5198 +f 872 5104 5197 +f 5104 532 5107 +f 5197 5107 1361 +f 5104 5107 5197 +f 151 5199 5200 +f 5199 747 5105 +f 5200 5105 1398 +f 5199 5105 5200 +f 1120 5111 5106 +f 5111 1123 5201 +f 5106 5201 1361 +f 5111 5201 5106 +f 747 5199 5108 +f 5199 151 5202 +f 5108 5202 1384 +f 5199 5202 5108 +f 1384 5203 5109 +f 5203 1130 5204 +f 5109 5204 1388 +f 5203 5204 5109 +f 761 5205 4862 +f 5205 811 5206 +f 4862 5206 1076 +f 5205 5206 4862 +f 1076 5206 5110 +f 5206 811 5207 +f 5110 5207 1123 +f 5206 5207 5110 +f 1130 5112 5204 +f 5112 33 4939 +f 5204 4939 1388 +f 5112 4939 5204 +f 811 5205 5208 +f 5205 761 4864 +f 5208 4864 1118 +f 5205 4864 5208 +f 561 5209 5121 +f 5209 811 5208 +f 5121 5208 1118 +f 5209 5208 5121 +f 11 5210 5211 +f 5210 924 5122 +f 5211 5122 1118 +f 5210 5122 5211 +f 997 5212 5024 +f 5212 11 5211 +f 5024 5211 1118 +f 5212 5211 5024 +f 997 5026 5213 +f 5026 337 5119 +f 5213 5119 1458 +f 5026 5119 5213 +f 614 5214 5215 +f 5214 11 5212 +f 5215 5212 997 +f 5214 5212 5215 +f 11 5214 5210 +f 5214 614 5216 +f 5210 5216 924 +f 5214 5216 5210 +f 119 5217 5115 +f 5217 150 5218 +f 5115 5218 1013 +f 5217 5218 5115 +f 614 5215 5219 +f 5215 997 5213 +f 5219 5213 1458 +f 5215 5213 5219 +f 150 5217 5220 +f 5217 119 5125 +f 5220 5125 819 +f 5217 5125 5220 +f 614 5221 5216 +f 5221 562 5128 +f 5216 5128 924 +f 5221 5128 5216 +f 150 5220 5222 +f 5220 819 5136 +f 5222 5136 1362 +f 5220 5136 5222 +f 827 5126 5040 +f 5126 1148 5223 +f 5040 5223 1362 +f 5126 5223 5040 +f 114 5224 5134 +f 5224 614 5225 +f 5134 5225 769 +f 5224 5225 5134 +f 769 5225 5131 +f 5225 614 5219 +f 5131 5219 1458 +f 5225 5219 5131 +f 114 5133 5224 +f 5133 562 5221 +f 5224 5221 614 +f 5133 5221 5224 +f 236 5130 5226 +f 5130 58 5114 +f 5226 5114 1130 +f 5130 5114 5226 +f 432 5227 4954 +f 5227 421 5140 +f 4954 5140 1486 +f 5227 5140 4954 +f 1397 5228 5143 +f 5228 432 4958 +f 5143 4958 1433 +f 5228 4958 5143 +f 708 5229 4959 +f 5229 1355 5230 +f 4959 5230 1478 +f 5229 5230 4959 +f 354 5231 5232 +f 5231 866 5054 +f 5232 5054 1377 +f 5231 5054 5232 +f 354 5233 5231 +f 5233 851 5053 +f 5231 5053 866 +f 5233 5053 5231 +f 1192 5234 5235 +f 5234 262 5146 +f 5235 5146 1426 +f 5234 5146 5235 +f 1016 5236 5237 +f 5236 723 5158 +f 5237 5158 1176 +f 5236 5158 5237 +f 466 5149 5238 +f 5149 723 5236 +f 5238 5236 1016 +f 5149 5236 5238 +f 454 5150 5055 +f 5150 466 5239 +f 5055 5239 551 +f 5150 5239 5055 +f 262 5240 5156 +f 5240 282 5241 +f 5156 5241 753 +f 5240 5241 5156 +f 753 5241 5161 +f 5241 282 5242 +f 5161 5242 1209 +f 5241 5242 5161 +f 551 5243 5056 +f 5243 909 5244 +f 5056 5244 1358 +f 5243 5244 5056 +f 823 4975 5246 +f 4975 297 5245 +f 5246 5245 1416 +f 4975 5245 5246 +f 305 5058 5248 +f 5058 702 5247 +f 5248 5247 925 +f 5058 5247 5248 +f 305 5248 5160 +f 5248 925 5249 +f 5160 5249 1176 +f 5248 5249 5160 +f 1358 5244 5062 +f 5244 909 5250 +f 5062 5250 1363 +f 5244 5250 5062 +f 297 4977 5245 +f 4977 1330 5251 +f 5245 5251 1416 +f 4977 5251 5245 +f 925 5247 5252 +f 5247 702 5163 +f 5252 5163 1140 +f 5247 5163 5252 +f 1363 5250 5254 +f 5250 909 5253 +f 5254 5253 1364 +f 5250 5253 5254 +f 327 5255 5256 +f 5255 1363 5254 +f 5256 5254 1364 +f 5255 5254 5256 +f 782 5257 5258 +f 5257 745 5070 +f 5258 5070 1200 +f 5257 5070 5258 +f 578 5259 5261 +f 5259 327 5260 +f 5261 5260 1235 +f 5259 5260 5261 +f 640 5262 5264 +f 5262 771 5263 +f 5264 5263 986 +f 5262 5263 5264 +f 1235 5265 5267 +f 5265 576 5266 +f 5267 5266 1435 +f 5265 5266 5267 +f 306 5268 5270 +f 5268 986 5269 +f 5270 5269 1304 +f 5268 5269 5270 +f 307 5271 5272 +f 5271 1371 5076 +f 5272 5076 1435 +f 5271 5076 5272 +f 215 5006 5083 +f 5006 1187 5273 +f 5083 5273 1241 +f 5006 5273 5083 +f 1187 5274 5273 +f 5274 1101 5275 +f 5273 5275 1241 +f 5274 5275 5273 +f 803 5174 5003 +f 5174 190 5276 +f 5003 5276 957 +f 5174 5276 5003 +f 516 5180 5277 +f 5180 339 5084 +f 5277 5084 1241 +f 5180 5084 5277 +f 122 5278 5279 +f 5278 516 5277 +f 5279 5277 1241 +f 5278 5277 5279 +f 750 5280 5281 +f 5280 455 5176 +f 5281 5176 985 +f 5280 5176 5281 +f 918 5282 5096 +f 5282 750 5281 +f 5096 5281 985 +f 5282 5281 5096 +f 455 5280 5284 +f 5280 750 5283 +f 5284 5283 1489 +f 5280 5283 5284 +f 368 5181 5286 +f 5181 516 5285 +f 5286 5285 1259 +f 5181 5285 5286 +f 927 5287 5182 +f 5287 1007 5288 +f 5182 5288 1172 +f 5287 5288 5182 +f 222 5289 5290 +f 5289 918 5186 +f 5290 5186 1172 +f 5289 5186 5290 +f 222 5291 5289 +f 5291 750 5282 +f 5289 5282 918 +f 5291 5282 5289 +f 368 5286 5187 +f 5286 1259 5292 +f 5187 5292 1325 +f 5286 5292 5187 +f 78 5293 5194 +f 5293 359 5294 +f 5194 5294 619 +f 5293 5294 5194 +f 359 5293 5295 +f 5293 78 5189 +f 5295 5189 1040 +f 5293 5189 5295 +f 1007 5287 5296 +f 5287 927 5193 +f 5296 5193 1265 +f 5287 5193 5296 +f 1007 5297 5288 +f 5297 222 5290 +f 5288 5290 1172 +f 5297 5290 5288 +f 750 5291 5298 +f 5291 222 5297 +f 5298 5297 1007 +f 5291 5297 5298 +f 1259 5299 5292 +f 5299 359 5300 +f 5292 5300 1325 +f 5299 5300 5292 +f 359 5295 5300 +f 5295 1040 5188 +f 5300 5188 1325 +f 5295 5188 5300 +f 526 5301 5302 +f 5301 359 5299 +f 5302 5299 1259 +f 5301 5299 5302 +f 750 5298 5283 +f 5298 1007 5303 +f 5283 5303 1489 +f 5298 5303 5283 +f 359 5301 5294 +f 5301 526 5304 +f 5294 5304 619 +f 5301 5304 5294 +f 526 5302 5306 +f 5302 1259 5305 +f 5306 5305 1384 +f 5302 5305 5306 +f 1007 5307 5303 +f 5307 1361 5308 +f 5303 5308 1489 +f 5307 5308 5303 +f 1007 5296 5307 +f 5296 1265 5198 +f 5307 5198 1361 +f 5296 5198 5307 +f 526 5309 5304 +f 5309 151 5310 +f 5304 5310 619 +f 5309 5310 5304 +f 151 5309 5202 +f 5309 526 5306 +f 5202 5306 1384 +f 5309 5306 5202 +f 619 5310 5103 +f 5310 151 5200 +f 5103 5200 1398 +f 5310 5200 5103 +f 561 5311 5209 +f 5311 304 5312 +f 5209 5312 811 +f 5311 5312 5209 +f 1013 5218 5116 +f 5218 150 5313 +f 5116 5313 1148 +f 5218 5313 5116 +f 1148 5313 5223 +f 5313 150 5222 +f 5223 5222 1362 +f 5313 5222 5223 +f 115 5314 5129 +f 5314 304 5311 +f 5129 5311 561 +f 5314 5311 5129 +f 236 5226 5137 +f 5226 1130 5315 +f 5137 5315 1264 +f 5226 5315 5137 +f 304 5314 5316 +f 5314 115 5139 +f 5316 5139 421 +f 5314 5139 5316 +f 304 5316 5318 +f 5316 421 5317 +f 5318 5317 921 +f 5316 5317 5318 +f 421 5227 5317 +f 5227 432 5319 +f 5317 5319 921 +f 5227 5319 5317 +f 708 4956 5229 +f 4956 317 5320 +f 5229 5320 1355 +f 4956 5320 5229 +f 1377 4962 5321 +f 4962 892 5046 +f 5321 5046 1478 +f 4962 5046 5321 +f 406 5322 5323 +f 5322 1377 5321 +f 5323 5321 1478 +f 5322 5321 5323 +f 200 5324 5325 +f 5324 309 5049 +f 5325 5049 916 +f 5324 5049 5325 +f 406 5326 5322 +f 5326 354 5232 +f 5322 5232 1377 +f 5326 5232 5322 +f 135 5327 5154 +f 5327 1192 5235 +f 5154 5235 1426 +f 5327 5235 5154 +f 551 5239 5328 +f 5239 466 5238 +f 5328 5238 1016 +f 5239 5238 5328 +f 282 5329 5331 +f 5329 1192 5330 +f 5331 5330 1424 +f 5329 5330 5331 +f 282 5240 5329 +f 5240 262 5234 +f 5329 5234 1192 +f 5240 5234 5329 +f 135 5153 5332 +f 5153 823 5246 +f 5332 5246 1416 +f 5153 5246 5332 +f 1192 5327 5333 +f 5327 135 5332 +f 5333 5332 1416 +f 5327 5332 5333 +f 1416 5334 5336 +f 5334 341 5335 +f 5336 5335 1450 +f 5334 5335 5336 +f 418 5337 5338 +f 5337 925 5252 +f 5338 5252 1140 +f 5337 5252 5338 +f 771 5339 5263 +f 5339 583 5340 +f 5263 5340 986 +f 5339 5340 5263 +f 766 5341 5169 +f 5341 928 5342 +f 5169 5342 1287 +f 5341 5342 5169 +f 1084 5343 5345 +f 5343 331 5344 +f 5345 5344 1284 +f 5343 5344 5345 +f 48 5346 5347 +f 5346 307 5272 +f 5347 5272 1435 +f 5346 5272 5347 +f 576 5348 5266 +f 5348 48 5347 +f 5266 5347 1435 +f 5348 5347 5266 +f 75 5349 5350 +f 5349 766 5170 +f 5350 5170 1409 +f 5349 5170 5350 +f 307 5351 5271 +f 5351 1236 5352 +f 5271 5352 1371 +f 5351 5352 5271 +f 1371 5353 4995 +f 5353 267 5354 +f 4995 5354 1418 +f 5353 5354 4995 +f 444 5355 5356 +f 5355 190 5173 +f 5356 5173 455 +f 5355 5173 5356 +f 335 5357 5358 +f 5357 455 5284 +f 5358 5284 1489 +f 5357 5284 5358 +f 516 5278 5285 +f 5278 122 5359 +f 5285 5359 1259 +f 5278 5359 5285 +f 1229 5360 5362 +f 5360 435 5361 +f 5362 5361 1384 +f 5360 5361 5362 +f 122 5363 5364 +f 5363 1229 5362 +f 5364 5362 1384 +f 5363 5362 5364 +f 1259 5359 5305 +f 5359 122 5364 +f 5305 5364 1384 +f 5359 5364 5305 +f 1123 5365 5367 +f 5365 835 5366 +f 5367 5366 1489 +f 5365 5366 5367 +f 1361 5201 5308 +f 5201 1123 5367 +f 5308 5367 1489 +f 5201 5367 5308 +f 811 5368 5207 +f 5368 835 5365 +f 5207 5365 1123 +f 5368 5365 5207 +f 435 5369 5361 +f 5369 1315 5370 +f 5361 5370 1384 +f 5369 5370 5361 +f 1315 5371 5370 +f 5371 1130 5203 +f 5370 5203 1384 +f 5371 5203 5370 +f 1130 5372 5315 +f 5372 793 5373 +f 5315 5373 1264 +f 5372 5373 5315 +f 317 5141 5320 +f 5141 1264 5374 +f 5320 5374 1355 +f 5141 5374 5320 +f 1355 5375 5230 +f 5375 231 5376 +f 5230 5376 1478 +f 5375 5376 5230 +f 309 5377 5142 +f 5377 904 5378 +f 5142 5378 1397 +f 5377 5378 5142 +f 851 5379 5052 +f 5379 200 5325 +f 5052 5325 916 +f 5379 5325 5052 +f 374 5380 5381 +f 5380 200 5379 +f 5381 5379 851 +f 5380 5379 5381 +f 354 5382 5233 +f 5382 374 5381 +f 5233 5381 851 +f 5382 5381 5233 +f 1192 5333 5330 +f 5333 1416 5383 +f 5330 5383 1424 +f 5333 5383 5330 +f 1209 5242 5384 +f 5242 282 5331 +f 5384 5331 1424 +f 5242 5331 5384 +f 767 5385 5386 +f 5385 1016 5237 +f 5386 5237 1176 +f 5385 5237 5386 +f 925 5387 5249 +f 5387 767 5386 +f 5249 5386 1176 +f 5387 5386 5249 +f 767 5388 5385 +f 5388 909 5389 +f 5385 5389 1016 +f 5388 5389 5385 +f 909 5243 5389 +f 5243 551 5328 +f 5389 5328 1016 +f 5243 5328 5389 +f 909 5388 5391 +f 5388 767 5390 +f 5391 5390 1357 +f 5388 5390 5391 +f 500 5392 5393 +f 5392 1209 5384 +f 5393 5384 1424 +f 5392 5384 5393 +f 909 5391 5253 +f 5391 1357 5394 +f 5253 5394 1364 +f 5391 5394 5253 +f 925 5337 5396 +f 5337 418 5395 +f 5396 5395 1357 +f 5337 5395 5396 +f 341 5397 5335 +f 5397 1212 5398 +f 5335 5398 1450 +f 5397 5398 5335 +f 1212 5399 5398 +f 5399 326 5400 +f 5398 5400 1450 +f 5399 5400 5398 +f 186 5401 5403 +f 5401 83 5402 +f 5403 5402 1364 +f 5401 5402 5403 +f 500 5404 5406 +f 5404 326 5405 +f 5406 5405 1447 +f 5404 5405 5406 +f 782 5407 5409 +f 5407 637 5408 +f 5409 5408 1447 +f 5407 5408 5409 +f 186 5410 5412 +f 5410 158 5411 +f 5412 5411 1235 +f 5410 5411 5412 +f 583 5339 5414 +f 5339 771 5413 +f 5414 5413 782 +f 5339 5413 5414 +f 338 5415 5417 +f 5415 438 5416 +f 5417 5416 583 +f 5415 5416 5417 +f 338 5417 5419 +f 5417 583 5418 +f 5419 5418 1447 +f 5417 5418 5419 +f 901 5420 5421 +f 5420 576 5265 +f 5421 5265 1235 +f 5420 5265 5421 +f 257 5422 5424 +f 5422 901 5423 +f 5424 5423 1034 +f 5422 5423 5424 +f 451 5425 5427 +f 5425 783 5426 +f 5427 5426 928 +f 5425 5426 5427 +f 451 5428 5425 +f 5428 120 5429 +f 5425 5429 783 +f 5428 5429 5425 +f 901 5422 5431 +f 5422 257 5430 +f 5431 5430 911 +f 5422 5430 5431 +f 48 5432 5433 +f 5432 901 5431 +f 5433 5431 911 +f 5432 5431 5433 +f 764 5434 5435 +f 5434 1084 5345 +f 5435 5345 1284 +f 5434 5345 5435 +f 766 5436 5341 +f 5436 451 5427 +f 5341 5427 928 +f 5436 5427 5341 +f 471 5168 5437 +f 5168 306 5270 +f 5437 5270 1304 +f 5168 5270 5437 +f 331 5438 5344 +f 5438 775 5439 +f 5344 5439 1284 +f 5438 5439 5344 +f 331 5165 5438 +f 5165 471 5440 +f 5438 5440 775 +f 5165 5440 5438 +f 48 5433 5442 +f 5433 911 5441 +f 5442 5441 1236 +f 5433 5441 5442 +f 307 5346 5351 +f 5346 48 5442 +f 5351 5442 1236 +f 5346 5442 5351 +f 1257 5078 5444 +f 5078 154 5443 +f 5444 5443 1448 +f 5078 5443 5444 +f 149 5445 5446 +f 5445 477 5080 +f 5446 5080 1418 +f 5445 5080 5446 +f 477 5447 5081 +f 5447 291 5448 +f 5081 5448 1187 +f 5447 5448 5081 +f 957 5449 5004 +f 5449 828 5172 +f 5004 5172 1457 +f 5449 5172 5004 +f 335 5450 5357 +f 5450 444 5356 +f 5357 5356 455 +f 5450 5356 5357 +f 835 5451 5366 +f 5451 335 5358 +f 5366 5358 1489 +f 5451 5358 5366 +f 835 5368 5453 +f 5368 811 5452 +f 5453 5452 844 +f 5368 5452 5453 +f 304 5454 5312 +f 5454 486 5455 +f 5312 5455 811 +f 5454 5455 5312 +f 793 5372 5456 +f 5372 1130 5371 +f 5456 5371 1315 +f 5372 5371 5456 +f 921 5319 5457 +f 5319 432 5228 +f 5457 5228 1397 +f 5319 5228 5457 +f 231 5458 5376 +f 5458 1248 5459 +f 5376 5459 1478 +f 5458 5459 5376 +f 309 5324 5377 +f 5324 200 5460 +f 5377 5460 904 +f 5324 5460 5377 +f 1248 5461 5459 +f 5461 406 5323 +f 5459 5323 1478 +f 5461 5323 5459 +f 767 5387 5390 +f 5387 925 5396 +f 5390 5396 1357 +f 5387 5396 5390 +f 338 5462 5463 +f 5462 326 5399 +f 5463 5399 1212 +f 5462 5399 5463 +f 901 5464 5466 +f 5464 158 5465 +f 5466 5465 1261 +f 5464 5465 5466 +f 120 5467 5429 +f 5467 316 5468 +f 5429 5468 783 +f 5467 5468 5429 +f 986 5469 5269 +f 5469 316 5470 +f 5269 5470 1304 +f 5469 5470 5269 +f 257 5471 5472 +f 5471 764 5435 +f 5472 5435 1284 +f 5471 5435 5472 +f 911 5430 5473 +f 5430 257 5472 +f 5473 5472 1284 +f 5430 5472 5473 +f 120 5428 5475 +f 5428 451 5474 +f 5475 5474 1453 +f 5428 5474 5475 +f 316 5467 5476 +f 5467 120 5475 +f 5476 5475 1453 +f 5467 5475 5476 +f 1304 5470 5477 +f 5470 316 5476 +f 5477 5476 1453 +f 5470 5476 5477 +f 399 5478 5479 +f 5478 911 5473 +f 5479 5473 1284 +f 5478 5473 5479 +f 399 5480 5478 +f 5480 579 5481 +f 5478 5481 911 +f 5480 5481 5478 +f 911 5481 5441 +f 5481 579 5482 +f 5441 5482 1236 +f 5481 5482 5441 +f 741 5483 5484 +f 5483 451 5436 +f 5484 5436 766 +f 5483 5436 5484 +f 75 5485 5349 +f 5485 741 5484 +f 5349 5484 766 +f 5485 5484 5349 +f 76 5486 5487 +f 5486 1257 5444 +f 5487 5444 1448 +f 5486 5444 5487 +f 154 5171 5443 +f 5171 828 5488 +f 5443 5488 1448 +f 5171 5488 5443 +f 291 5447 5490 +f 5447 477 5489 +f 5490 5489 535 +f 5447 5489 5490 +f 957 5276 5492 +f 5276 190 5491 +f 5492 5491 1228 +f 5276 5491 5492 +f 580 5493 5494 +f 5493 122 5279 +f 5494 5279 1241 +f 5493 5279 5494 +f 122 5493 5363 +f 5493 580 5495 +f 5363 5495 1229 +f 5493 5495 5363 +f 102 5496 5497 +f 5496 335 5451 +f 5497 5451 835 +f 5496 5451 5497 +f 779 5498 5499 +f 5498 102 5497 +f 5499 5497 835 +f 5498 5497 5499 +f 435 5500 5369 +f 5500 425 5501 +f 5369 5501 1315 +f 5500 5501 5369 +f 286 5502 5503 +f 5502 835 5453 +f 5503 5453 844 +f 5502 5453 5503 +f 286 5504 5502 +f 5504 779 5499 +f 5502 5499 835 +f 5504 5499 5502 +f 425 5505 5501 +f 5505 737 5506 +f 5501 5506 1315 +f 5505 5506 5501 +f 811 5455 5452 +f 5455 486 5507 +f 5452 5507 844 +f 5455 5507 5452 +f 1270 5508 5509 +f 5508 921 5457 +f 5509 5457 1397 +f 5508 5457 5509 +f 200 5380 5511 +f 5380 374 5510 +f 5511 5510 875 +f 5380 5510 5511 +f 374 5382 5513 +f 5382 354 5512 +f 5513 5512 544 +f 5382 5512 5513 +f 544 5512 5515 +f 5512 354 5514 +f 5515 5514 1248 +f 5512 5514 5515 +f 354 5326 5514 +f 5326 406 5461 +f 5514 5461 1248 +f 5326 5461 5514 +f 451 5483 5474 +f 5483 741 5516 +f 5474 5516 1453 +f 5483 5516 5474 +f 1257 5517 5077 +f 5517 818 5518 +f 5077 5518 1409 +f 5517 5518 5077 +f 477 5445 5489 +f 5445 149 5519 +f 5489 5519 535 +f 5445 5519 5489 +f 828 5520 5488 +f 5520 160 5521 +f 5488 5521 1448 +f 5520 5521 5488 +f 1101 5522 5524 +f 5522 291 5523 +f 5524 5523 1485 +f 5522 5523 5524 +f 828 5449 5525 +f 5449 957 5492 +f 5525 5492 1228 +f 5449 5492 5525 +f 194 5526 5527 +f 5526 828 5525 +f 5527 5525 1228 +f 5526 5525 5527 +f 291 5522 5448 +f 5522 1101 5274 +f 5448 5274 1187 +f 5522 5274 5448 +f 190 5355 5491 +f 5355 444 5528 +f 5491 5528 1228 +f 5355 5528 5491 +f 1101 5529 5275 +f 5529 580 5494 +f 5275 5494 1241 +f 5529 5494 5275 +f 102 5530 5532 +f 5530 415 5531 +f 5532 5531 444 +f 5530 5531 5532 +f 580 5533 5495 +f 5533 1221 5534 +f 5495 5534 1229 +f 5533 5534 5495 +f 335 5496 5450 +f 5496 102 5532 +f 5450 5532 444 +f 5496 5532 5450 +f 102 5498 5536 +f 5498 779 5535 +f 5536 5535 1062 +f 5498 5535 5536 +f 1062 5535 5538 +f 5535 779 5537 +f 5538 5537 1151 +f 5535 5537 5538 +f 1151 5539 5541 +f 5539 425 5540 +f 5541 5540 1229 +f 5539 5540 5541 +f 1062 5538 5542 +f 5538 1151 5541 +f 5542 5541 1229 +f 5538 5541 5542 +f 425 5500 5540 +f 5500 435 5360 +f 5540 5360 1229 +f 5500 5360 5540 +f 286 5543 5545 +f 5543 255 5544 +f 5545 5544 1151 +f 5543 5544 5545 +f 779 5504 5537 +f 5504 286 5545 +f 5537 5545 1151 +f 5504 5545 5537 +f 255 5546 5544 +f 5546 737 5547 +f 5544 5547 1151 +f 5546 5547 5544 +f 737 5505 5547 +f 5505 425 5539 +f 5547 5539 1151 +f 5505 5539 5547 +f 286 5503 5549 +f 5503 844 5548 +f 5549 5548 976 +f 5503 5548 5549 +f 255 5543 5550 +f 5543 286 5549 +f 5550 5549 976 +f 5543 5549 5550 +f 737 5546 5552 +f 5546 255 5551 +f 5552 5551 813 +f 5546 5551 5552 +f 737 5553 5506 +f 5553 226 5554 +f 5506 5554 1315 +f 5553 5554 5506 +f 844 5507 5548 +f 5507 486 5555 +f 5548 5555 976 +f 5507 5555 5548 +f 226 5556 5554 +f 5556 793 5456 +f 5554 5456 1315 +f 5556 5456 5554 +f 486 5454 5558 +f 5454 304 5557 +f 5558 5557 574 +f 5454 5557 5558 +f 793 5559 5373 +f 5559 44 5560 +f 5373 5560 1264 +f 5559 5560 5373 +f 574 5557 5561 +f 5557 304 5318 +f 5561 5318 921 +f 5557 5318 5561 +f 904 5562 5378 +f 5562 1270 5509 +f 5378 5509 1397 +f 5562 5509 5378 +f 904 5460 5564 +f 5460 200 5563 +f 5564 5563 1394 +f 5460 5563 5564 +f 200 5511 5563 +f 5511 875 5565 +f 5563 5565 1394 +f 5511 5565 5563 +f 374 5513 5510 +f 5513 544 5566 +f 5510 5566 875 +f 5513 5566 5510 +f 775 5567 5439 +f 5567 399 5479 +f 5439 5479 1284 +f 5567 5479 5439 +f 1048 5568 5569 +f 5568 75 5350 +f 5569 5350 1409 +f 5568 5350 5569 +f 267 5570 5354 +f 5570 149 5446 +f 5354 5446 1418 +f 5570 5446 5354 +f 1005 5571 5572 +f 5571 194 5527 +f 5572 5527 1228 +f 5571 5527 5572 +f 444 5573 5528 +f 5573 903 5574 +f 5528 5574 1228 +f 5573 5574 5528 +f 580 5529 5576 +f 5529 1101 5575 +f 5576 5575 1482 +f 5529 5575 5576 +f 444 5531 5573 +f 5531 415 5577 +f 5573 5577 903 +f 5531 5577 5573 +f 415 5578 5580 +f 5578 1062 5579 +f 5580 5579 1221 +f 5578 5579 5580 +f 415 5530 5578 +f 5530 102 5536 +f 5578 5536 1062 +f 5530 5536 5578 +f 1221 5579 5534 +f 5579 1062 5542 +f 5534 5542 1229 +f 5579 5542 5534 +f 813 5551 5581 +f 5551 255 5550 +f 5581 5550 976 +f 5551 5550 5581 +f 226 5553 5582 +f 5553 737 5552 +f 5582 5552 813 +f 5553 5552 5582 +f 976 5555 5584 +f 5555 486 5583 +f 5584 5583 1476 +f 5555 5583 5584 +f 486 5558 5583 +f 5558 574 5585 +f 5583 5585 1476 +f 5558 5585 5583 +f 574 5561 5586 +f 5561 921 5508 +f 5586 5508 1270 +f 5561 5508 5586 +f 44 5587 5560 +f 5587 946 5588 +f 5560 5588 1264 +f 5587 5588 5560 +f 1264 5588 5374 +f 5588 946 5589 +f 5374 5589 1355 +f 5588 5589 5374 +f 231 5590 5592 +f 5590 946 5591 +f 5592 5591 1392 +f 5590 5591 5592 +f 946 5590 5589 +f 5590 231 5375 +f 5589 5375 1355 +f 5590 5375 5589 +f 1270 5562 5593 +f 5562 904 5564 +f 5593 5564 1394 +f 5562 5564 5593 +f 1248 5458 5594 +f 5458 231 5592 +f 5594 5592 1392 +f 5458 5592 5594 +f 544 5515 5595 +f 5515 1248 5594 +f 5595 5594 1392 +f 5515 5594 5595 +f 775 5440 5597 +f 5440 471 5596 +f 5597 5596 817 +f 5440 5596 5597 +f 818 5598 5518 +f 5598 1048 5569 +f 5518 5569 1409 +f 5598 5569 5518 +f 76 5599 5486 +f 5599 818 5517 +f 5486 5517 1257 +f 5599 5517 5486 +f 291 5600 5523 +f 5600 1020 5601 +f 5523 5601 1485 +f 5600 5601 5523 +f 291 5490 5600 +f 5490 535 5602 +f 5600 5602 1020 +f 5490 5602 5600 +f 1221 5533 5603 +f 5533 580 5576 +f 5603 5576 1482 +f 5533 5576 5603 +f 746 5604 5605 +f 5604 44 5559 +f 5605 5559 793 +f 5604 5559 5605 +f 44 5604 5587 +f 5604 746 5606 +f 5587 5606 946 +f 5604 5606 5587 +f 574 5586 5585 +f 5586 1270 5607 +f 5585 5607 1476 +f 5586 5607 5585 +f 544 5608 5566 +f 5608 202 5609 +f 5566 5609 875 +f 5608 5609 5566 +f 202 5608 5610 +f 5608 544 5595 +f 5610 5595 1392 +f 5608 5595 5610 +f 1247 5611 5612 +f 5611 1304 5477 +f 5612 5477 1453 +f 5611 5477 5612 +f 817 5596 5613 +f 5596 471 5437 +f 5613 5437 1304 +f 5596 5437 5613 +f 1247 5614 5611 +f 5614 817 5613 +f 5611 5613 1304 +f 5614 5613 5611 +f 715 5615 5616 +f 5615 399 5567 +f 5616 5567 775 +f 5615 5567 5616 +f 280 5617 5618 +f 5617 399 5615 +f 5618 5615 715 +f 5617 5615 5618 +f 715 5616 5619 +f 5616 775 5597 +f 5619 5597 817 +f 5616 5597 5619 +f 741 5485 5620 +f 5485 75 5568 +f 5620 5568 1048 +f 5485 5568 5620 +f 169 5621 5622 +f 5621 741 5620 +f 5622 5620 1048 +f 5621 5620 5622 +f 180 5623 5625 +f 5623 856 5624 +f 5625 5624 1236 +f 5623 5624 5625 +f 856 5626 5627 +f 5626 267 5353 +f 5627 5353 1371 +f 5626 5353 5627 +f 1236 5624 5352 +f 5624 856 5627 +f 5352 5627 1371 +f 5624 5627 5352 +f 149 5570 5629 +f 5570 267 5628 +f 5629 5628 849 +f 5570 5628 5629 +f 194 5630 5526 +f 5630 160 5520 +f 5526 5520 828 +f 5630 5520 5526 +f 160 5630 5632 +f 5630 194 5631 +f 5632 5631 1197 +f 5630 5631 5632 +f 1020 5633 5601 +f 5633 188 5634 +f 5601 5634 1485 +f 5633 5634 5601 +f 1482 5575 5635 +f 5575 1101 5524 +f 5635 5524 1485 +f 5575 5524 5635 +f 903 5636 5574 +f 5636 1005 5572 +f 5574 5572 1228 +f 5636 5572 5574 +f 415 5637 5577 +f 5637 400 5638 +f 5577 5638 903 +f 5637 5638 5577 +f 400 5637 5639 +f 5637 415 5580 +f 5639 5580 1221 +f 5637 5580 5639 +f 400 5639 5640 +f 5639 1221 5603 +f 5640 5603 1482 +f 5639 5603 5640 +f 746 5641 5642 +f 5641 226 5582 +f 5642 5582 813 +f 5641 5582 5642 +f 915 5643 5644 +f 5643 976 5584 +f 5644 5584 1476 +f 5643 5584 5644 +f 226 5641 5556 +f 5641 746 5605 +f 5556 5605 793 +f 5641 5605 5556 +f 1270 5593 5607 +f 5593 1394 5645 +f 5607 5645 1476 +f 5593 5645 5607 +f 1394 5646 5645 +f 5646 842 5647 +f 5645 5647 1476 +f 5646 5647 5645 +f 946 5648 5591 +f 5648 213 5649 +f 5591 5649 1392 +f 5648 5649 5591 +f 875 5650 5565 +f 5650 842 5646 +f 5565 5646 1394 +f 5650 5646 5565 +f 202 5651 5609 +f 5651 842 5650 +f 5609 5650 875 +f 5651 5650 5609 +f 213 5652 5649 +f 5652 202 5610 +f 5649 5610 1392 +f 5652 5610 5649 +f 296 5653 5654 +f 5653 1247 5612 +f 5654 5612 1453 +f 5653 5612 5654 +f 399 5617 5480 +f 5617 280 5655 +f 5480 5655 579 +f 5617 5655 5480 +f 741 5621 5516 +f 5621 169 5656 +f 5516 5656 1453 +f 5621 5656 5516 +f 169 5657 5656 +f 5657 296 5654 +f 5656 5654 1453 +f 5657 5654 5656 +f 715 5619 5659 +f 5619 817 5658 +f 5659 5658 1068 +f 5619 5658 5659 +f 579 5660 5482 +f 5660 180 5625 +f 5482 5625 1236 +f 5660 5625 5482 +f 849 5628 5661 +f 5628 267 5626 +f 5661 5626 856 +f 5628 5626 5661 +f 818 5599 5662 +f 5599 76 5487 +f 5662 5487 1448 +f 5599 5487 5662 +f 535 5519 5663 +f 5519 149 5629 +f 5663 5629 849 +f 5519 5629 5663 +f 194 5571 5631 +f 5571 1005 5664 +f 5631 5664 1197 +f 5571 5664 5631 +f 567 5665 5666 +f 5665 1482 5635 +f 5666 5635 1485 +f 5665 5635 5666 +f 95 5667 5669 +f 5667 813 5668 +f 5669 5668 915 +f 5667 5668 5669 +f 915 5668 5643 +f 5668 813 5581 +f 5643 5581 976 +f 5668 5581 5643 +f 95 5670 5667 +f 5670 746 5642 +f 5667 5642 813 +f 5670 5642 5667 +f 469 5671 5673 +f 5671 213 5672 +f 5673 5672 746 +f 5671 5672 5673 +f 746 5672 5606 +f 5672 213 5648 +f 5606 5648 946 +f 5672 5648 5606 +f 842 5674 5647 +f 5674 915 5644 +f 5647 5644 1476 +f 5674 5644 5647 +f 202 5675 5651 +f 5675 469 5676 +f 5651 5676 842 +f 5675 5676 5651 +f 202 5652 5675 +f 5652 213 5671 +f 5675 5671 469 +f 5652 5671 5675 +f 340 5677 5678 +f 5677 817 5614 +f 5678 5614 1247 +f 5677 5614 5678 +f 817 5677 5658 +f 5677 340 5679 +f 5658 5679 1068 +f 5677 5679 5658 +f 395 5680 5681 +f 5680 818 5662 +f 5681 5662 1448 +f 5680 5662 5681 +f 535 5663 5602 +f 5663 849 5682 +f 5602 5682 1020 +f 5663 5682 5602 +f 160 5632 5521 +f 5632 1197 5683 +f 5521 5683 1448 +f 5632 5683 5521 +f 1197 5664 5685 +f 5664 1005 5684 +f 5685 5684 1386 +f 5664 5684 5685 +f 1005 5636 5687 +f 5636 903 5686 +f 5687 5686 1412 +f 5636 5686 5687 +f 903 5638 5686 +f 5638 400 5688 +f 5686 5688 1412 +f 5638 5688 5686 +f 469 5689 5690 +f 5689 95 5669 +f 5690 5669 915 +f 5689 5669 5690 +f 95 5689 5670 +f 5689 469 5673 +f 5670 5673 746 +f 5689 5673 5670 +f 842 5676 5674 +f 5676 469 5690 +f 5674 5690 915 +f 5676 5690 5674 +f 974 5691 5692 +f 5691 169 5622 +f 5692 5622 1048 +f 5691 5622 5692 +f 79 5693 5695 +f 5693 849 5694 +f 5695 5694 1127 +f 5693 5694 5695 +f 849 5661 5694 +f 5661 856 5696 +f 5694 5696 1127 +f 5661 5696 5694 +f 188 5697 5634 +f 5697 963 5698 +f 5634 5698 1485 +f 5697 5698 5634 +f 963 5699 5698 +f 5699 567 5666 +f 5698 5666 1485 +f 5699 5666 5698 +f 296 5700 5653 +f 5700 488 5701 +f 5653 5701 1247 +f 5700 5701 5653 +f 926 5702 5703 +f 5702 715 5659 +f 5703 5659 1068 +f 5702 5659 5703 +f 224 5704 5705 +f 5704 715 5702 +f 5705 5702 926 +f 5704 5702 5705 +f 224 5706 5704 +f 5706 280 5618 +f 5704 5618 715 +f 5706 5618 5704 +f 280 5707 5655 +f 5707 180 5660 +f 5655 5660 579 +f 5707 5660 5655 +f 180 5707 5709 +f 5707 280 5708 +f 5709 5708 436 +f 5707 5708 5709 +f 180 5709 5711 +f 5709 436 5710 +f 5711 5710 1127 +f 5709 5710 5711 +f 856 5623 5696 +f 5623 180 5711 +f 5696 5711 1127 +f 5623 5711 5696 +f 974 5692 5713 +f 5692 1048 5712 +f 5713 5712 1086 +f 5692 5712 5713 +f 1048 5598 5712 +f 5598 818 5714 +f 5712 5714 1086 +f 5598 5714 5712 +f 818 5680 5714 +f 5680 395 5715 +f 5714 5715 1086 +f 5680 5715 5714 +f 79 5716 5718 +f 5716 693 5717 +f 5718 5717 1020 +f 5716 5717 5718 +f 849 5693 5682 +f 5693 79 5718 +f 5682 5718 1020 +f 5693 5718 5682 +f 1197 5719 5683 +f 5719 395 5681 +f 5683 5681 1448 +f 5719 5681 5683 +f 952 5720 5721 +f 5720 567 5699 +f 5721 5699 963 +f 5720 5699 5721 +f 400 5722 5688 +f 5722 56 5723 +f 5688 5723 1412 +f 5722 5723 5688 +f 56 5722 5724 +f 5722 400 5640 +f 5724 5640 1482 +f 5722 5640 5724 +f 567 5725 5665 +f 5725 56 5724 +f 5665 5724 1482 +f 5725 5724 5665 +f 280 5706 5708 +f 5706 224 5726 +f 5708 5726 436 +f 5706 5726 5708 +f 296 5657 5727 +f 5657 169 5691 +f 5727 5691 974 +f 5657 5691 5727 +f 488 5700 5728 +f 5700 296 5727 +f 5728 5727 974 +f 5700 5727 5728 +f 340 5678 5730 +f 5678 1247 5729 +f 5730 5729 1349 +f 5678 5729 5730 +f 104 5731 5732 +f 5731 340 5730 +f 5732 5730 1349 +f 5731 5730 5732 +f 340 5731 5679 +f 5731 104 5733 +f 5679 5733 1068 +f 5731 5733 5679 +f 917 5734 5735 +f 5734 926 5703 +f 5735 5703 1068 +f 5734 5703 5735 +f 104 5736 5733 +f 5736 917 5735 +f 5733 5735 1068 +f 5736 5735 5733 +f 693 5716 5737 +f 5716 79 5695 +f 5737 5695 1127 +f 5716 5695 5737 +f 606 5738 5739 +f 5738 395 5719 +f 5739 5719 1197 +f 5738 5719 5739 +f 606 5739 5740 +f 5739 1197 5685 +f 5740 5685 1386 +f 5739 5685 5740 +f 693 5741 5717 +f 5741 963 5742 +f 5717 5742 1020 +f 5741 5742 5717 +f 963 5697 5742 +f 5697 188 5633 +f 5742 5633 1020 +f 5697 5633 5742 +f 56 5743 5745 +f 5743 315 5744 +f 5745 5744 760 +f 5743 5744 5745 +f 1386 5684 5746 +f 5684 1005 5687 +f 5746 5687 1412 +f 5684 5687 5746 +f 722 5747 5748 +f 5747 1386 5746 +f 5748 5746 1412 +f 5747 5746 5748 +f 56 5745 5723 +f 5745 760 5749 +f 5723 5749 1412 +f 5745 5749 5723 +f 315 5743 5751 +f 5743 56 5750 +f 5751 5750 952 +f 5743 5750 5751 +f 56 5725 5750 +f 5725 567 5720 +f 5750 5720 952 +f 5725 5720 5750 +f 1247 5701 5729 +f 5701 488 5752 +f 5729 5752 1349 +f 5701 5752 5729 +f 436 5726 5754 +f 5726 224 5753 +f 5754 5753 1074 +f 5726 5753 5754 +f 917 5755 5734 +f 5755 853 5756 +f 5734 5756 926 +f 5755 5756 5734 +f 853 5757 5756 +f 5757 127 5758 +f 5756 5758 926 +f 5757 5758 5756 +f 436 5754 5710 +f 5754 1074 5759 +f 5710 5759 1127 +f 5754 5759 5710 +f 232 5760 5761 +f 5760 104 5732 +f 5761 5732 1349 +f 5760 5732 5761 +f 104 5760 5736 +f 5760 232 5762 +f 5736 5762 917 +f 5760 5762 5736 +f 1074 5763 5759 +f 5763 693 5737 +f 5759 5737 1127 +f 5763 5737 5759 +f 395 5738 5715 +f 5738 606 5764 +f 5715 5764 1086 +f 5738 5764 5715 +f 232 5765 5762 +f 5765 760 5766 +f 5762 5766 917 +f 5765 5766 5762 +f 693 5767 5741 +f 5767 952 5721 +f 5741 5721 963 +f 5767 5721 5741 +f 722 5768 5747 +f 5768 606 5740 +f 5747 5740 1386 +f 5768 5740 5747 +f 760 5744 5770 +f 5744 315 5769 +f 5770 5769 853 +f 5744 5769 5770 +f 488 5771 5752 +f 5771 148 5772 +f 5752 5772 1349 +f 5771 5772 5752 +f 224 5773 5753 +f 5773 127 5774 +f 5753 5774 1074 +f 5773 5774 5753 +f 127 5773 5758 +f 5773 224 5705 +f 5758 5705 926 +f 5773 5705 5758 +f 148 5771 5775 +f 5771 488 5728 +f 5775 5728 974 +f 5771 5728 5775 +f 148 5775 5776 +f 5775 974 5713 +f 5776 5713 1086 +f 5775 5713 5776 +f 148 5776 5778 +f 5776 1086 5777 +f 5778 5777 1155 +f 5776 5777 5778 +f 148 5778 5772 +f 5778 1155 5779 +f 5772 5779 1349 +f 5778 5779 5772 +f 1086 5764 5777 +f 5764 606 5780 +f 5777 5780 1155 +f 5764 5780 5777 +f 127 5781 5774 +f 5781 72 5782 +f 5774 5782 1074 +f 5781 5782 5774 +f 1155 5783 5779 +f 5783 232 5761 +f 5779 5761 1349 +f 5783 5761 5779 +f 72 5781 5784 +f 5781 127 5757 +f 5784 5757 853 +f 5781 5757 5784 +f 606 5768 5780 +f 5768 722 5785 +f 5780 5785 1155 +f 5768 5785 5780 +f 760 5770 5766 +f 5770 853 5755 +f 5766 5755 917 +f 5770 5755 5766 +f 72 5786 5782 +f 5786 693 5763 +f 5782 5763 1074 +f 5786 5763 5782 +f 760 5765 5787 +f 5765 232 5783 +f 5787 5783 1155 +f 5765 5783 5787 +f 315 5788 5769 +f 5788 72 5784 +f 5769 5784 853 +f 5788 5784 5769 +f 722 5789 5785 +f 5789 760 5787 +f 5785 5787 1155 +f 5789 5787 5785 +f 72 5788 5790 +f 5788 315 5751 +f 5790 5751 952 +f 5788 5751 5790 +f 693 5786 5767 +f 5786 72 5790 +f 5767 5790 952 +f 5786 5790 5767 +f 760 5789 5749 +f 5789 722 5748 +f 5749 5748 1412 +f 5789 5748 5749 +f 1046 3058 5791 +f 3058 196 2539 +f 5791 2539 1299 +f 3058 2539 5791 +f 540 2660 3335 +f 2660 196 3060 +f 3335 3060 1153 +f 2660 3060 3335 +f 665 3213 5792 +f 3213 552 3062 +f 5792 3062 1182 +f 3213 3062 5792 +f 668 5793 2802 +f 5793 1046 5791 +f 2802 5791 1299 +f 5793 5791 2802 +f 540 3334 2661 +f 3334 797 5794 +f 2661 5794 1399 +f 3334 5794 2661 +f 668 3214 5796 +f 3214 665 5795 +f 5796 5795 1227 +f 3214 5795 5796 +f 462 5797 3541 +f 5797 668 5796 +f 3541 5796 1227 +f 5797 5796 3541 +f 235 5798 5799 +f 5798 1077 2804 +f 5799 2804 1399 +f 5798 2804 5799 +f 596 5800 5801 +f 5800 483 3419 +f 5801 3419 1104 +f 5800 3419 5801 +f 639 5802 3521 +f 5802 740 5803 +f 3521 5803 908 +f 5802 5803 3521 +f 696 5804 5806 +f 5804 259 5805 +f 5806 5805 748 +f 5804 5805 5806 +f 696 5807 3523 +f 5807 398 5808 +f 3523 5808 1135 +f 5807 5808 3523 +f 398 5807 5809 +f 5807 696 5806 +f 5809 5806 748 +f 5807 5806 5809 +f 908 5803 3529 +f 5803 740 5810 +f 3529 5810 1451 +f 5803 5810 3529 +f 797 3545 5794 +f 3545 235 5799 +f 5794 5799 1399 +f 3545 5799 5794 +f 668 5797 5793 +f 5797 462 3554 +f 5793 3554 1046 +f 5797 3554 5793 +f 665 5811 5795 +f 5811 996 3549 +f 5795 3549 1227 +f 5811 3549 5795 +f 996 5811 5812 +f 5811 665 5792 +f 5812 5792 1182 +f 5811 5792 5812 +f 366 5813 3553 +f 5813 682 5814 +f 3553 5814 1046 +f 5813 5814 3553 +f 703 3216 5815 +f 3216 555 2918 +f 5815 2918 1077 +f 3216 2918 5815 +f 938 3505 3417 +f 3505 350 3651 +f 3417 3651 1402 +f 3505 3651 3417 +f 843 3646 3515 +f 3646 1128 3054 +f 3515 3054 1434 +f 3646 3054 3515 +f 483 5800 5816 +f 5800 596 3654 +f 5816 3654 1444 +f 5800 3654 5816 +f 598 3509 5817 +f 3509 483 5816 +f 5817 5816 1444 +f 3509 5816 5817 +f 88 3512 5818 +f 3512 621 3511 +f 5818 3511 933 +f 3512 3511 5818 +f 1402 5819 3414 +f 5819 134 3516 +f 3414 3516 1434 +f 5819 3516 3414 +f 88 5820 3513 +f 5820 596 5801 +f 3513 5801 1104 +f 5820 5801 3513 +f 258 5821 5822 +f 5821 259 5804 +f 5822 5804 696 +f 5821 5804 5822 +f 259 5823 5805 +f 5823 727 3525 +f 5805 3525 748 +f 5823 3525 5805 +f 259 5821 5823 +f 5821 258 5824 +f 5823 5824 727 +f 5821 5824 5823 +f 639 3520 5826 +f 3520 734 5825 +f 5826 5825 1216 +f 3520 5825 5826 +f 289 5827 5828 +f 5827 639 5826 +f 5828 5826 1216 +f 5827 5826 5828 +f 639 5827 5802 +f 5827 289 3662 +f 5802 3662 740 +f 5827 3662 5802 +f 611 5829 3528 +f 5829 364 3656 +f 3528 3656 908 +f 5829 3656 3528 +f 1135 5808 5830 +f 5808 398 3533 +f 5830 3533 1282 +f 5808 3533 5830 +f 635 3531 3535 +f 3531 398 5809 +f 3535 5809 748 +f 3531 5809 3535 +f 740 3664 5810 +f 3664 1352 5831 +f 5810 5831 1451 +f 3664 5831 5810 +f 815 3774 3543 +f 3774 703 5815 +f 3543 5815 1077 +f 3774 5815 3543 +f 235 5832 5798 +f 5832 566 3544 +f 5798 3544 1077 +f 5832 3544 5798 +f 566 5832 5833 +f 5832 235 3547 +f 5833 3547 984 +f 5832 3547 5833 +f 868 5834 3676 +f 5834 797 3336 +f 3676 3336 1153 +f 5834 3336 3676 +f 933 3510 5835 +f 3510 491 3329 +f 5835 3329 1256 +f 3510 3329 5835 +f 970 5836 3650 +f 5836 375 5837 +f 3650 5837 1402 +f 5836 5837 3650 +f 734 5838 5825 +f 5838 88 5839 +f 5825 5839 1216 +f 5838 5839 5825 +f 134 5840 5842 +f 5840 375 5841 +f 5842 5841 727 +f 5840 5841 5842 +f 375 5840 5837 +f 5840 134 5819 +f 5837 5819 1402 +f 5840 5819 5837 +f 596 5820 5843 +f 5820 88 5838 +f 5843 5838 734 +f 5820 5838 5843 +f 134 5844 3514 +f 5844 258 5845 +f 3514 5845 843 +f 5844 5845 3514 +f 258 5844 5824 +f 5844 134 5842 +f 5824 5842 727 +f 5844 5842 5824 +f 88 5818 5839 +f 5818 933 5846 +f 5839 5846 1216 +f 5818 5846 5839 +f 258 5822 5845 +f 5822 696 3522 +f 5845 3522 843 +f 5822 3522 5845 +f 727 5841 3657 +f 5841 375 5836 +f 3657 5836 970 +f 5841 5836 3657 +f 498 3652 3517 +f 3652 596 5843 +f 3517 5843 734 +f 3652 5843 3517 +f 289 5828 3663 +f 5828 1216 5847 +f 3663 5847 1352 +f 5828 5847 3663 +f 662 5848 3763 +f 5848 1135 5830 +f 3763 5830 1282 +f 5848 5830 3763 +f 63 3536 3758 +f 3536 748 3527 +f 3758 3527 833 +f 3536 3527 3758 +f 396 5849 5850 +f 5849 611 3530 +f 5850 3530 1451 +f 5849 3530 5850 +f 566 5851 3670 +f 5851 396 5850 +f 3670 5850 1451 +f 5851 5850 3670 +f 396 5851 3768 +f 5851 566 5833 +f 3768 5833 984 +f 5851 5833 3768 +f 797 5834 3546 +f 5834 868 5852 +f 3546 5852 984 +f 5834 5852 3546 +f 1186 3673 3666 +f 3673 412 3764 +f 3666 3764 1282 +f 3673 3764 3666 +f 996 5812 5853 +f 5812 1182 3422 +f 5853 3422 1372 +f 5812 3422 5853 +f 410 3849 4053 +f 3849 1128 3648 +f 4053 3648 1494 +f 3849 3648 4053 +f 506 3932 5854 +f 3932 933 5835 +f 5854 5835 1256 +f 3932 5835 5854 +f 506 5854 4128 +f 5854 1256 3847 +f 4128 3847 1491 +f 5854 3847 4128 +f 350 3753 3649 +f 3753 808 5855 +f 3649 5855 970 +f 3753 5855 3649 +f 364 5856 3755 +f 5856 648 3935 +f 3755 3935 685 +f 5856 3935 3755 +f 843 3660 3647 +f 3660 864 5857 +f 3647 5857 1494 +f 3660 5857 3647 +f 808 5858 5859 +f 5858 826 3759 +f 5859 3759 833 +f 5858 3759 5859 +f 808 5859 5855 +f 5859 833 3658 +f 5855 3658 970 +f 5859 3658 5855 +f 808 5860 5858 +f 5860 588 3761 +f 5858 3761 826 +f 5860 3761 5858 +f 364 5829 5856 +f 5829 611 5861 +f 5856 5861 648 +f 5829 5861 5856 +f 611 5849 5861 +f 5849 396 3765 +f 5861 3765 648 +f 5849 3765 5861 +f 635 3534 3667 +f 3534 63 3757 +f 3667 3757 826 +f 3534 3757 3667 +f 1352 5862 5831 +f 5862 815 3671 +f 5831 3671 1451 +f 5862 3671 5831 +f 984 5852 3769 +f 5852 868 5863 +f 3769 5863 1312 +f 5852 5863 3769 +f 868 3675 5865 +f 3675 682 5864 +f 5865 5864 1460 +f 3675 5864 5865 +f 577 5866 5867 +f 5866 412 3672 +f 5867 3672 996 +f 5866 3672 5867 +f 577 5867 5868 +f 5867 996 5853 +f 5868 5853 1372 +f 5867 5853 5868 +f 682 5813 5869 +f 5813 366 3773 +f 5869 3773 1354 +f 5813 3773 5869 +f 1046 5814 3059 +f 5814 682 3677 +f 3059 3677 1153 +f 5814 3677 3059 +f 977 5870 3645 +f 5870 808 3754 +f 3645 3754 1108 +f 5870 3754 3645 +f 685 3850 3756 +f 3850 598 5817 +f 3756 5817 1444 +f 3850 5817 3756 +f 1216 5846 5847 +f 5846 933 3942 +f 5847 3942 1352 +f 5846 3942 5847 +f 662 3940 5848 +f 3940 864 3661 +f 5848 3661 1135 +f 3940 3661 5848 +f 412 5866 3762 +f 5866 577 3938 +f 3762 3938 662 +f 5866 3938 3762 +f 1073 3936 4056 +f 3936 648 3767 +f 4056 3767 1312 +f 3936 3767 4056 +f 1352 3941 5872 +f 3941 1159 5871 +f 5872 5871 1472 +f 3941 5871 5872 +f 815 5862 3775 +f 5862 1352 5872 +f 3775 5872 1472 +f 5862 5872 3775 +f 1011 3674 3945 +f 3674 674 3771 +f 3945 3771 1395 +f 3674 3771 3945 +f 682 5873 5864 +f 5873 161 5874 +f 5864 5874 1460 +f 5873 5874 5864 +f 564 3424 3948 +f 3424 113 5875 +f 3948 5875 1159 +f 3424 5875 3948 +f 1159 5875 5871 +f 5875 113 3556 +f 5871 3556 1472 +f 5875 3556 5871 +f 586 5876 4126 +f 5876 416 5877 +f 4126 5877 977 +f 5876 5877 4126 +f 416 5878 5877 +f 5878 808 5870 +f 5877 5870 977 +f 5878 5870 5877 +f 357 3930 5879 +f 3930 685 3937 +f 5879 3937 1073 +f 3930 3937 5879 +f 588 5860 5881 +f 5860 808 5880 +f 5881 5880 1421 +f 5860 5880 5881 +f 1312 5863 5882 +f 5863 868 5865 +f 5882 5865 1460 +f 5863 5865 5882 +f 407 4058 4130 +f 4058 577 5868 +f 4130 5868 1372 +f 4058 5868 4130 +f 978 5883 5884 +f 5883 709 4131 +f 5884 4131 1372 +f 5883 4131 5884 +f 757 3678 3421 +f 3678 978 5884 +f 3421 5884 1372 +f 3678 5884 3421 +f 694 3848 4188 +f 3848 410 4052 +f 4188 4052 1313 +f 3848 4052 4188 +f 864 4059 5857 +f 4059 407 5885 +f 5857 5885 1494 +f 4059 5885 5857 +f 808 5878 5880 +f 5878 416 5886 +f 5880 5886 1421 +f 5878 5886 5880 +f 845 3943 5887 +f 3943 588 5881 +f 5887 5881 1421 +f 3943 5881 5887 +f 1100 4057 5888 +f 4057 1312 5882 +f 5888 5882 1460 +f 4057 5882 5888 +f 489 5889 4050 +f 5889 357 5890 +f 4050 5890 559 +f 5889 5890 4050 +f 357 5889 3931 +f 5889 489 3751 +f 3931 3751 941 +f 5889 3751 3931 +f 407 5891 5885 +f 5891 1313 4054 +f 5885 4054 1494 +f 5891 4054 5885 +f 506 4127 5893 +f 4127 642 5892 +f 5893 5892 1150 +f 4127 5892 5893 +f 416 5876 5886 +f 5876 586 4269 +f 5886 4269 1421 +f 5876 4269 5886 +f 506 5893 3933 +f 5893 1150 3949 +f 3933 3949 1159 +f 5893 3949 3933 +f 559 5890 4397 +f 5890 357 5894 +f 4397 5894 873 +f 5890 5894 4397 +f 873 5894 4265 +f 5894 357 5879 +f 4265 5879 1073 +f 5894 5879 4265 +f 642 5895 5892 +f 5895 1080 5896 +f 5892 5896 1150 +f 5895 5896 5892 +f 989 4348 5897 +f 4348 845 5887 +f 5897 5887 1421 +f 4348 5887 5897 +f 407 4129 5891 +f 4129 709 4347 +f 5891 4347 1313 +f 4129 4347 5891 +f 582 5898 4190 +f 5898 709 5883 +f 4190 5883 978 +f 5898 5883 4190 +f 1080 5899 5896 +f 5899 673 3950 +f 5896 3950 1150 +f 5899 3950 5896 +f 758 5900 4268 +f 5900 989 5897 +f 4268 5897 1421 +f 5900 5897 4268 +f 705 4266 5901 +f 4266 1073 4055 +f 5901 4055 1100 +f 4266 4055 5901 +f 582 4402 5898 +f 4402 93 4345 +f 5898 4345 709 +f 4402 4345 5898 +f 161 5873 4272 +f 5873 682 5869 +f 4272 5869 1354 +f 5873 5869 4272 +f 1354 4271 4273 +f 4271 346 4406 +f 4273 4406 1420 +f 4271 4406 4273 +f 634 4463 5902 +f 4463 705 5901 +f 5902 5901 1100 +f 4463 5901 5902 +f 1420 5903 5904 +f 5903 1100 5888 +f 5904 5888 1460 +f 5903 5888 5904 +f 161 4274 5874 +f 4274 1420 5904 +f 5874 5904 1460 +f 4274 5904 5874 +f 806 4194 4407 +f 4194 673 5899 +f 4407 5899 1080 +f 4194 5899 4407 +f 93 4401 5905 +f 4401 467 4620 +f 5905 4620 1174 +f 4401 4620 5905 +f 630 4404 4548 +f 4404 346 4349 +f 4548 4349 989 +f 4404 4349 4548 +f 634 5902 5906 +f 5902 1100 5903 +f 5906 5903 1420 +f 5902 5903 5906 +f 388 5907 4343 +f 5907 777 4263 +f 4343 4263 1414 +f 5907 4263 4343 +f 388 4750 5907 +f 4750 732 5908 +f 5907 5908 777 +f 4750 5908 5907 +f 93 5905 4346 +f 5905 1174 5909 +f 4346 5909 1313 +f 5905 5909 4346 +f 873 4264 5910 +f 4264 705 4465 +f 5910 4465 1205 +f 4264 4465 5910 +f 642 4262 5895 +f 4262 777 5911 +f 5895 5911 1080 +f 4262 5911 5895 +f 230 4399 4461 +f 4399 586 4344 +f 4461 4344 1233 +f 4399 4344 4461 +f 1080 5912 4408 +f 5912 1002 5913 +f 4408 5913 1471 +f 5912 5913 4408 +f 777 5914 5911 +f 5914 1002 5912 +f 5911 5912 1080 +f 5914 5912 5911 +f 894 5915 4467 +f 5915 634 5906 +f 4467 5906 1420 +f 5915 5906 4467 +f 41 4469 4625 +f 4469 582 4470 +f 4625 4470 878 +f 4469 4470 4625 +f 1174 5916 5909 +f 5916 850 4396 +f 5909 4396 1313 +f 5916 4396 5909 +f 777 5908 5914 +f 5908 732 5917 +f 5914 5917 1002 +f 5908 5917 5914 +f 230 4460 5918 +f 4460 348 4751 +f 5918 4751 358 +f 4460 4751 5918 +f 873 5919 4398 +f 5919 525 4617 +f 4398 4617 1294 +f 5919 4617 4398 +f 758 4400 5921 +f 4400 230 5920 +f 5921 5920 1475 +f 4400 5920 5921 +f 989 5900 4549 +f 5900 758 5921 +f 4549 5921 1475 +f 5900 5921 4549 +f 308 4607 4609 +f 4607 850 5916 +f 4609 5916 1174 +f 4607 5916 4609 +f 470 5922 4616 +f 5922 912 4613 +f 4616 4613 1294 +f 5922 4613 4616 +f 525 5919 5923 +f 5919 873 5910 +f 5923 5910 1205 +f 5919 5910 5923 +f 609 4621 5924 +f 4621 630 4697 +f 5924 4697 684 +f 4621 4697 5924 +f 254 4618 5925 +f 4618 467 4624 +f 5925 4624 1196 +f 4618 4624 5925 +f 230 5918 5920 +f 5918 358 4821 +f 5920 4821 1475 +f 5918 4821 5920 +f 800 4699 4824 +f 4699 634 5915 +f 4824 5915 894 +f 4699 5915 4824 +f 732 5926 5917 +f 5926 584 5927 +f 5917 5927 1002 +f 5926 5927 5917 +f 254 5928 4619 +f 5928 942 4610 +f 4619 4610 1174 +f 5928 4610 4619 +f 759 4904 4823 +f 4904 525 5923 +f 4823 5923 1205 +f 4904 5923 4823 +f 1002 5929 5913 +f 5929 718 4833 +f 5913 4833 1471 +f 5929 4833 5913 +f 308 4608 5930 +f 4608 942 4981 +f 5930 4981 1322 +f 4608 4981 5930 +f 308 5930 4898 +f 5930 1322 5931 +f 4898 5931 1330 +f 5930 5931 4898 +f 470 5932 5922 +f 5932 57 5933 +f 5922 5933 912 +f 5932 5933 5922 +f 254 5934 5928 +f 5934 677 4979 +f 5928 4979 942 +f 5934 4979 5928 +f 584 5935 5927 +f 5935 718 5929 +f 5927 5929 1002 +f 5935 5929 5927 +f 609 5924 5936 +f 5924 684 4984 +f 5936 4984 1289 +f 5924 4984 5936 +f 677 5934 4828 +f 5934 254 5925 +f 4828 5925 1196 +f 5934 5925 4828 +f 894 4622 5937 +f 4622 609 5936 +f 5937 5936 1289 +f 4622 5936 5937 +f 1099 4825 5938 +f 4825 894 5937 +f 5938 5937 1289 +f 4825 5937 5938 +f 732 4749 5939 +f 4749 408 5064 +f 5939 5064 1103 +f 4749 5064 5939 +f 584 5926 5940 +f 5926 732 5939 +f 5940 5939 1103 +f 5926 5939 5940 +f 57 5932 4903 +f 5932 470 4615 +f 4903 4615 525 +f 5932 4615 4903 +f 519 5066 5941 +f 5066 57 4905 +f 5941 4905 759 +f 5066 4905 5941 +f 492 4820 4901 +f 4820 358 4752 +f 4901 4752 765 +f 4820 4752 4901 +f 684 4753 4982 +f 4753 492 4900 +f 4982 4900 745 +f 4753 4900 4982 +f 560 5942 4987 +f 5942 759 4822 +f 4987 4822 800 +f 5942 4822 4987 +f 584 5943 5935 +f 5943 578 5944 +f 5935 5944 718 +f 5943 5944 5935 +f 912 5933 5059 +f 5933 57 5068 +f 5059 5068 1173 +f 5933 5068 5059 +f 1200 5069 5945 +f 5069 765 4696 +f 5945 4696 1317 +f 5069 4696 5945 +f 578 5943 5946 +f 5943 584 5940 +f 5946 5940 1103 +f 5943 5940 5946 +f 331 5947 5166 +f 5947 1099 5938 +f 5166 5938 1289 +f 5947 5938 5166 +f 695 5948 4819 +f 5948 1200 5945 +f 4819 5945 1317 +f 5948 5945 4819 +f 677 5949 4980 +f 5949 1267 5950 +f 4980 5950 1322 +f 5949 5950 4980 +f 677 4827 5949 +f 4827 285 5951 +f 5949 5951 1267 +f 4827 5951 5949 +f 560 5952 5942 +f 5952 519 5941 +f 5942 5941 759 +f 5952 5941 5942 +f 718 5944 5075 +f 5944 578 5953 +f 5075 5953 1435 +f 5944 5953 5075 +f 1267 5951 5954 +f 5951 285 5073 +f 5954 5073 1287 +f 5951 5073 5954 +f 1200 5948 5955 +f 5948 695 5162 +f 5955 5162 1209 +f 5948 5162 5955 +f 637 5956 5957 +f 5956 1200 5955 +f 5957 5955 1209 +f 5956 5955 5957 +f 1322 5958 5931 +f 5958 341 5959 +f 5931 5959 1330 +f 5958 5959 5931 +f 327 5960 5255 +f 5960 1103 5065 +f 5255 5065 1363 +f 5960 5065 5255 +f 1267 5961 5950 +f 5961 548 5962 +f 5950 5962 1322 +f 5961 5962 5950 +f 327 5259 5960 +f 5259 578 5946 +f 5960 5946 1103 +f 5259 5946 5960 +f 519 5952 5964 +f 5952 560 5963 +f 5964 5963 735 +f 5952 5963 5964 +f 331 5965 5947 +f 5965 81 4990 +f 5947 4990 1099 +f 5965 4990 5947 +f 81 5965 5966 +f 5965 331 5343 +f 5966 5343 1084 +f 5965 5343 5966 +f 1330 5959 5251 +f 5959 341 5334 +f 5251 5334 1416 +f 5959 5334 5251 +f 548 5967 5962 +f 5967 341 5958 +f 5962 5958 1322 +f 5967 5958 5962 +f 637 5407 5956 +f 5407 782 5258 +f 5956 5258 1200 +f 5407 5258 5956 +f 1173 5968 5970 +f 5968 735 5969 +f 5970 5969 1232 +f 5968 5969 5970 +f 519 5964 5067 +f 5964 735 5968 +f 5067 5968 1173 +f 5964 5968 5067 +f 771 5971 5413 +f 5971 745 5257 +f 5413 5257 782 +f 5971 5257 5413 +f 640 4985 5262 +f 4985 745 5971 +f 5262 5971 771 +f 4985 5971 5262 +f 560 4989 5972 +f 4989 81 5966 +f 5972 5966 1084 +f 4989 5966 5972 +f 735 5963 5973 +f 5963 560 5972 +f 5973 5972 1084 +f 5963 5972 5973 +f 764 5974 5434 +f 5974 735 5973 +f 5434 5973 1084 +f 5974 5973 5434 +f 306 5071 5268 +f 5071 640 5264 +f 5268 5264 986 +f 5071 5264 5268 +f 500 5975 5392 +f 5975 637 5957 +f 5392 5957 1209 +f 5975 5957 5392 +f 637 5975 5408 +f 5975 500 5406 +f 5408 5406 1447 +f 5975 5406 5408 +f 1140 5164 5976 +f 5164 1173 5970 +f 5976 5970 1232 +f 5164 5970 5976 +f 341 5967 5397 +f 5967 548 5977 +f 5397 5977 1212 +f 5967 5977 5397 +f 83 5978 5402 +f 5978 327 5256 +f 5402 5256 1364 +f 5978 5256 5402 +f 548 5979 5977 +f 5979 353 5980 +f 5977 5980 1212 +f 5979 5980 5977 +f 353 5979 5981 +f 5979 548 5961 +f 5981 5961 1267 +f 5979 5961 5981 +f 735 5982 5969 +f 5982 1034 5983 +f 5969 5983 1232 +f 5982 5983 5969 +f 578 5261 5953 +f 5261 1235 5267 +f 5953 5267 1435 +f 5261 5267 5953 +f 353 5981 5984 +f 5981 1267 5954 +f 5984 5954 1287 +f 5981 5954 5984 +f 928 5985 5342 +f 5985 353 5984 +f 5342 5984 1287 +f 5985 5984 5342 +f 500 5393 5987 +f 5393 1424 5986 +f 5987 5986 1450 +f 5393 5986 5987 +f 1424 5383 5986 +f 5383 1416 5336 +f 5986 5336 1450 +f 5383 5336 5986 +f 1357 5395 5394 +f 5395 418 5988 +f 5394 5988 1364 +f 5395 5988 5394 +f 1140 5976 5990 +f 5976 1232 5989 +f 5990 5989 1261 +f 5976 5989 5990 +f 326 5404 5400 +f 5404 500 5987 +f 5400 5987 1450 +f 5404 5987 5400 +f 186 5991 5993 +f 5991 418 5992 +f 5993 5992 1261 +f 5991 5992 5993 +f 418 5991 5988 +f 5991 186 5403 +f 5988 5403 1364 +f 5991 5403 5988 +f 418 5338 5992 +f 5338 1140 5990 +f 5992 5990 1261 +f 5338 5990 5992 +f 83 5401 5994 +f 5401 186 5412 +f 5994 5412 1235 +f 5401 5412 5994 +f 327 5978 5260 +f 5978 83 5994 +f 5260 5994 1235 +f 5978 5994 5260 +f 353 5995 5980 +f 5995 338 5463 +f 5980 5463 1212 +f 5995 5463 5980 +f 583 5414 5418 +f 5414 782 5409 +f 5418 5409 1447 +f 5414 5409 5418 +f 338 5995 5996 +f 5995 353 5985 +f 5996 5985 928 +f 5995 5985 5996 +f 438 5415 5997 +f 5415 338 5996 +f 5997 5996 928 +f 5415 5996 5997 +f 1232 5983 5989 +f 5983 1034 5998 +f 5989 5998 1261 +f 5983 5998 5989 +f 1034 5423 5998 +f 5423 901 5466 +f 5998 5466 1261 +f 5423 5466 5998 +f 158 5464 5411 +f 5464 901 5421 +f 5411 5421 1235 +f 5464 5421 5411 +f 735 5974 5982 +f 5974 764 5999 +f 5982 5999 1034 +f 5974 5999 5982 +f 764 5471 5999 +f 5471 257 5424 +f 5999 5424 1034 +f 5471 5424 5999 +f 583 5416 6001 +f 5416 438 6000 +f 6001 6000 783 +f 5416 6000 6001 +f 583 6001 5340 +f 6001 783 6002 +f 5340 6002 986 +f 6001 6002 5340 +f 783 6000 5426 +f 6000 438 5997 +f 5426 5997 928 +f 6000 5997 5426 +f 48 5348 5432 +f 5348 576 5420 +f 5432 5420 901 +f 5348 5420 5432 +f 783 5468 6002 +f 5468 316 5469 +f 6002 5469 986 +f 5468 5469 6002 +f 326 5462 5405 +f 5462 338 5419 +f 5405 5419 1447 +f 5462 5419 5405 +f 158 5410 5465 +f 5410 186 5993 +f 5465 5993 1261 +f 5410 5993 5465 \ No newline at end of file diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..e71486e --- /dev/null +++ b/flake.nix @@ -0,0 +1,30 @@ + +{ + description = "A simple hybrid renderer"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { self, nixpkgs, flake-utils }: + flake-utils.lib.eachDefaultSystem (system: + let + pkgs = import nixpkgs { inherit system; }; + venv = ".venv"; + in { + devShells.default = pkgs.mkShell { + name = "kale"; + + packages = with pkgs; [ + sdl3 + glm + gcc + shaderc + gnumake + ]; + + }; + } + ); +} diff --git a/shaders/blit.frag b/shaders/blit.frag new file mode 100644 index 0000000..b6dff6b --- /dev/null +++ b/shaders/blit.frag @@ -0,0 +1,110 @@ +#version 450 + +layout(location = 0) in vec2 uv; +layout(location = 0) out vec4 out_color; +layout(set = 2, binding = 0) uniform sampler2D screen; + +layout(std140, set = 3, binding = 0) uniform UniformBlock { + mat4 model; + mat4 view; + mat4 projection; + float time; +}; + + +float road(float x) { return cos(x); } + +vec3 backup(vec2 uv) { + float x_scale = time * 12.0; + float y_scale = uv.x; + + uv.x *= x_scale; + uv.y *= 2.0; + uv.y -= 1.0; + uv.y /= 0.75; + uv.y /= y_scale; + + float y = road(uv.x); + + float dist = length(uv.y - y); + + vec3 col = vec3(cos(time / 10.0)) - vec3(exp(-dist), cos(dist), sin(dist)); + return (0.005 * (1.2 + abs(cos(time)))) / col; +} + +const int MAX_MARCH_STEPS = 64; +const float EPS_DIST = 1e-6; + +float sdf(vec3 point) { +// return length(point - vec3(6.0 * sin(time), 8.0*abs(sin(time * 0.7)*cos(time)), 5.0 * cos(time * 1.2))) - 0.4; + float size = 8.0 + (3.0* sin(time)); + vec3 s1_local = mod(point, vec3(size)) - vec3(size/2.0); + float s1 = length(s1_local) - 0.3; + return s1; +} + +vec3 getnormal(vec3 p) { + float e = EPS_DIST; + return normalize(vec3( + sdf(p + vec3(e, 0.0, 0.0)) - sdf(p - vec3(e, 0.0, 0.0)), + sdf(p + vec3(0.0, e, 0.0)) - sdf(p - vec3(0.0, e, 0.0)), + sdf(p + vec3(0.0, 0.0, e)) - sdf(p - vec3(0.0, 0.0, e)) + )); +} + + + +vec4 march(vec3 point, vec3 ray) { + float MAX_DEPTH = texture(screen, uv).w * 1000.0; + float totaldist = 0.0; + + int i; + for (i = 0; i < MAX_MARCH_STEPS && totaldist < MAX_DEPTH; i += 1) { + float h = sdf(point); + point += h * ray; + if (h < EPS_DIST) { + return vec4(point, totaldist + h); + } + + totaldist += h; + } + + return vec4(-1.0); +} + +vec3 camray() { + vec2 ndc = uv * 2.0 - 1.0; + ndc.y = -ndc.y; + vec4 clip = vec4(ndc, 1.0, 1.0); + vec4 view_pos = inverse(projection) * clip; + view_pos /= view_pos.w; + + vec3 ray_dir_view = normalize(view_pos.xyz); + + vec3 ray_dir_world = normalize((inverse(view) * vec4(ray_dir_view, 0.0)).xyz); + + return ray_dir_world; +} + +vec3 camorigin() { return (inverse(view) * vec4(0, 0, 0, 1)).xyz; } + +vec4 kernel() { + vec3 cam_pos = camorigin(); + vec3 cam_ray = camray(); + + return march(cam_pos, cam_ray); +} + +float t(float x, float y) { return length(texture(screen, vec2(x, y)).xyz); } + +void main() { + + vec2 bg = (projection * view * vec4(uv, 1.0, 1.0)).xy; + vec3 b = backup(bg); + vec4 hit = kernel(); + if (hit.w > 0.0 && ((t(uv.x, uv.y) < 0.01) || (hit.w < (texture(screen, uv).w * 1000.0)))) { + out_color = vec4(getnormal(hit.xyz), 1.0); + } else { + out_color = texture(screen, uv); + } +} diff --git a/shaders/blit.vert b/shaders/blit.vert new file mode 100644 index 0000000..ee04010 --- /dev/null +++ b/shaders/blit.vert @@ -0,0 +1,11 @@ +#version 450 + +layout(location = 0) out vec2 uv; + +void main() { + float x = float((gl_VertexIndex << 1) & 2); + float y = float(gl_VertexIndex & 2); + uv = vec2(x, y); + gl_Position = vec4(uv * 2.0 - 1.0, 0.0, 1.0); + gl_Position.y *= -1.0; +} diff --git a/shaders/post.frag b/shaders/post.frag new file mode 100644 index 0000000..30c978e --- /dev/null +++ b/shaders/post.frag @@ -0,0 +1,46 @@ +#version 450 + +layout(location = 0) in vec2 uv; +layout(location = 0) out vec4 out_color; +layout(set = 2, binding = 0) uniform sampler2D screen; + +layout(std140, set = 3, binding = 0) uniform UniformBlock { + mat4 model; + mat4 view; + mat4 projection; + float time; +}; + +float t(float x, float y) { return length(texture(screen, vec2(x, y)).xyz); } + +mat3 neighborhood() { + vec2 d = 1.0 / vec2(textureSize(screen, 0)); + return mat3(t(uv.x - d.x, uv.y - d.y), t(uv.x + 0.0, uv.y - d.y), + t(uv.x + d.x, uv.y - d.y), t(uv.x - d.x, uv.y - 0.0), + t(uv.x + 0.0, uv.y + 0.0), t(uv.x + d.x, uv.y - 0.0), + t(uv.x - d.x, uv.y + d.y), t(uv.x + 0.0, uv.y + d.y), + t(uv.x + d.x, uv.y + d.y)); +} + +float sum3(mat3 m) { + float s = 0.0; + for (int c = 0; c < 3; ++c) { + vec3 col = m[c]; + s += col.x + col.y + col.z; + } + return s; +} + +float f(mat3 kernel) { + return abs(sum3(matrixCompMult(kernel, neighborhood()))); +} + + +void main() { + const mat3 sobelx = mat3(-1.0, -2.0, -1.0, 0.0, 0.0, 0.0, 1.0, 2.0, 1.0); + + const mat3 sobely = mat3(-1.0, 0.0, 1.0, -2.0, 0.0, 2.0, -1.0, 0.0, 1.0); + + out_color = texture(screen, uv) + ((t(uv.x, uv.y) > 0.01)? + vec4(abs(f(sobelx) + f(sobely)), 0.0, 0.0, 1.0) : vec4(0.0)); +} \ No newline at end of file diff --git a/shaders/scene.frag b/shaders/scene.frag new file mode 100644 index 0000000..5e056f0 --- /dev/null +++ b/shaders/scene.frag @@ -0,0 +1,16 @@ +#version 460 +layout(location = 0) in vec4 v_color; +layout(location = 1) in float depth; +layout(location = 2) in vec3 v_normal_vs; + +layout(location = 0) out vec4 out_color; + +void main() { + vec3 light_dir = normalize(vec3(0.5, 1.0, 0.8)); + + float ambient = 0.2; + float diffuse = max(dot(v_normal_vs, light_dir), 0.0); + float lighting = ambient + (1.0 - ambient) * diffuse; + + out_color = vec4(v_color.rgb * lighting, v_color.a); +} diff --git a/shaders/scene.vert b/shaders/scene.vert new file mode 100644 index 0000000..b6faca0 --- /dev/null +++ b/shaders/scene.vert @@ -0,0 +1,26 @@ +#version 460 +layout(location = 0) in vec3 a_pos; +layout(location = 1) in vec4 a_color; +layout(location = 2) in vec3 a_normal; + +layout(location = 0) out vec4 v_color; +layout(location = 1) out float depth; +layout(location = 2) out vec3 v_normal_vs; // view-space normal + +layout(std140, set = 1, binding = 0) uniform UniformBlock { + mat4 model; + mat4 view; + mat4 projection; + float time; +}; + +void main() { + vec4 view_pos = view * model * vec4(a_pos, 1.0); + depth = -view_pos.z / 1000.0; + gl_Position = projection * view_pos; + v_color = a_color; + + // For uniform scale this shortcut is fine: + mat3 normal_mat = mat3(transpose(inverse(view * model))); + v_normal_vs = normalize(normal_mat * a_normal); +} diff --git a/src/camera.cpp b/src/camera.cpp new file mode 100644 index 0000000..94fb750 --- /dev/null +++ b/src/camera.cpp @@ -0,0 +1,65 @@ +#include "camera.h" + +vec3 Camera::dir() const { + return normalize(vec3( + cos(radians(yaw)) * cos(radians(pitch)), + sin(radians(pitch)), + sin(radians(yaw)) * cos(radians(pitch)) + )); +} + +void Camera::update() { + if (look_up) pitch += look_speed; + if (look_down) pitch -= look_speed; + if (look_left) yaw -= look_speed; + if (look_right) yaw += look_speed; + pitch = clamp(pitch, -89.0f, 89.0f); + + vec3 d = dir(); + vec3 right = normalize(cross(d, up)); + target = pos + d; + float shift_speed = shifted? 10.0 : 1.0; + float speed = move_speed * shift_speed; + + if (move_forward) { pos += d * speed; target += d * speed; } + if (move_backward) { pos -= d * speed; target -= d * speed; } + if (move_left) { pos -= right * speed; target -= right * speed; } + if (move_right) { pos += right * speed; target += right * speed; } + if (move_up) { pos += up * speed; target += up * speed; } + if (move_down) { pos -= up * speed; target -= up * speed; } +} + +void Camera::on_key(SDL_Scancode scancode, bool pressed) { + switch (scancode) { + case SDL_SCANCODE_W: move_forward = pressed; break; + case SDL_SCANCODE_S: move_backward = pressed; break; + case SDL_SCANCODE_A: move_left = pressed; break; + case SDL_SCANCODE_D: move_right = pressed; break; + case SDL_SCANCODE_SPACE: move_up = pressed; break; + case SDL_SCANCODE_LCTRL: move_down = pressed; break; + case SDL_SCANCODE_UP: look_up = pressed; break; + case SDL_SCANCODE_DOWN: look_down = pressed; break; + case SDL_SCANCODE_LEFT: look_left = pressed; break; + case SDL_SCANCODE_RIGHT: look_right = pressed; break; + case SDL_SCANCODE_LSHIFT: + case SDL_SCANCODE_RSHIFT: + shifted |= pressed; + break; + default: break; + } +} + +void Camera::on_mouse_motion(float dx, float dy) { + yaw += dx * look_speed * 0.1f; + pitch -= dy * look_speed * 0.1f; + pitch = clamp(pitch, -89.0f, 89.0f); +} + +CameraUBO Camera::ubo(float aspect) const { + return CameraUBO { + .model = mat4(1.0f), + .view = lookAt(pos, target, up), + .proj = perspective(radians(fov), aspect, 0.01f, 1000.0f), + .time = (float)SDL_GetTicks() / 1000.0f, + }; +} diff --git a/src/camera.h b/src/camera.h new file mode 100644 index 0000000..2371ae0 --- /dev/null +++ b/src/camera.h @@ -0,0 +1,35 @@ +#pragma once +#include "types.h" +#include +#include + +struct Camera { + vec3 pos = vec3(0.0f, 0.0f, 2.0f); + vec3 target = vec3(0.0f, 0.0f, 0.0f); + vec3 up = vec3(0.0f, 1.0f, 0.0f); + float fov = 60.0f; + float move_speed = 0.05f; + float look_speed = 1.0f; + float pitch = 0.0f; + float yaw = -90.0f; + + bool move_forward = false; + bool move_backward = false; + bool move_left = false; + bool move_right = false; + bool move_up = false; + bool move_down = false; + bool look_up = false; + bool look_down = false; + bool look_left = false; + bool look_right = false; + bool shifted = false; + + void update(); + void on_key(SDL_Scancode scancode, bool pressed); + void on_mouse_motion(float dx, float dy); + CameraUBO ubo(float aspect) const; + +private: + vec3 dir() const; +}; diff --git a/src/gpu.cpp b/src/gpu.cpp new file mode 100644 index 0000000..e5a52d5 --- /dev/null +++ b/src/gpu.cpp @@ -0,0 +1,80 @@ +#include "gpu.h" +#include +#include + +SDL_GPUShader* load_shader(SDL_GPUDevice* dev, const char* path, SDL_GPUShaderStage stage, + uint32_t num_samplers, uint32_t num_uniform_buffers) { + size_t code_size; + void* code = SDL_LoadFile(path, &code_size); + if (!code) { + std::cerr << "Failed to load " << path << ": " << SDL_GetError() << std::endl; + return nullptr; + } + + SDL_GPUShaderCreateInfo info { + .code_size = code_size, + .code = (uint8_t*)code, + .entrypoint = "main", + .format = SDL_GPU_SHADERFORMAT_SPIRV, + .stage = stage, + .num_samplers = num_samplers, + .num_uniform_buffers = num_uniform_buffers, + }; + + SDL_GPUShader* shader = SDL_CreateGPUShader(dev, &info); + if (!shader) + std::cerr << "Shader creation failed (" << path << "): " << SDL_GetError() << std::endl; + SDL_free(code); + return shader; +} + +SDL_GPUTexture* create_render_texture(SDL_GPUDevice* dev, SDL_Window* win, + uint32_t w, uint32_t h) { + SDL_GPUTextureCreateInfo info { + .type = SDL_GPU_TEXTURETYPE_2D, + .format = SDL_GetGPUSwapchainTextureFormat(dev, win), + .usage = SDL_GPU_TEXTUREUSAGE_SAMPLER | SDL_GPU_TEXTUREUSAGE_COLOR_TARGET, + .width = w, + .height = h, + .layer_count_or_depth = 1, + .num_levels = 1, + }; + + SDL_GPUTexture* tex = SDL_CreateGPUTexture(dev, &info); + if (!tex) + std::cerr << "Render texture creation failed: " << SDL_GetError() << std::endl; + return tex; +} + +SDL_GPUSampler* create_linear_sampler(SDL_GPUDevice* dev) { + SDL_GPUSamplerCreateInfo info { + .min_filter = SDL_GPU_FILTER_LINEAR, + .mag_filter = SDL_GPU_FILTER_LINEAR, + .address_mode_u = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE, + .address_mode_v = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE, + }; + return SDL_CreateGPUSampler(dev, &info); +} + +void upload_buffer(SDL_GPUDevice* dev, SDL_GPUBuffer* dst, const void* data, uint32_t size) { + SDL_GPUTransferBufferCreateInfo trans_info { + .usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD, + .size = size, + }; + SDL_GPUTransferBuffer* trans = SDL_CreateGPUTransferBuffer(dev, &trans_info); + + void* mapped = SDL_MapGPUTransferBuffer(dev, trans, false); + memcpy(mapped, data, size); + SDL_UnmapGPUTransferBuffer(dev, trans); + + SDL_GPUCommandBuffer* cmd = SDL_AcquireGPUCommandBuffer(dev); + SDL_GPUCopyPass* copy = SDL_BeginGPUCopyPass(cmd); + + SDL_GPUTransferBufferLocation src { .transfer_buffer = trans, .offset = 0 }; + SDL_GPUBufferRegion reg { .buffer = dst, .offset = 0, .size = size }; + SDL_UploadToGPUBuffer(copy, &src, ®, true); + + SDL_EndGPUCopyPass(copy); + SDL_ReleaseGPUTransferBuffer(dev, trans); + SDL_SubmitGPUCommandBuffer(cmd); +} diff --git a/src/gpu.h b/src/gpu.h new file mode 100644 index 0000000..f09cc65 --- /dev/null +++ b/src/gpu.h @@ -0,0 +1,13 @@ +#pragma once +#include +#include + +SDL_GPUShader* load_shader(SDL_GPUDevice* dev, const char* path, SDL_GPUShaderStage stage, + uint32_t num_samplers, uint32_t num_uniform_buffers); + +SDL_GPUTexture* create_render_texture(SDL_GPUDevice* dev, SDL_Window* win, + uint32_t w, uint32_t h); + +SDL_GPUSampler* create_linear_sampler(SDL_GPUDevice* dev); + +void upload_buffer(SDL_GPUDevice* dev, SDL_GPUBuffer* dst, const void* data, uint32_t size); diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..8666ce7 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,64 @@ +#include +#include +#define SDL_MAIN_USE_CALLBACKS +#include +#include + +#include "camera.h" +#include "renderer.h" + +static Camera camera; +static Renderer renderer; + +SDL_AppResult SDL_AppInit(void** appstate, int argc, char** argv) { + (void)appstate; + (void)argc; + (void)argv; + SDL_Window* win = SDL_CreateWindow("Kale", 960, 540, SDL_WINDOW_RESIZABLE); + SDL_SetWindowRelativeMouseMode(win, true); + + if (!renderer.init(win)) + return SDL_APP_FAILURE; + + return SDL_APP_CONTINUE; +} + +SDL_AppResult SDL_AppIterate(void* appstate) { + (void)appstate; + camera.update(); + + uint32_t sw_w = renderer.render_w; + uint32_t sw_h = renderer.render_h; + CameraUBO ubo = camera.ubo((float)sw_w / (float)(sw_h ? sw_h : 1)); + + renderer.draw(ubo); + + return SDL_APP_CONTINUE; +} + +SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event) { + (void)appstate; + switch (event->type) { + case SDL_EVENT_WINDOW_CLOSE_REQUESTED: + case SDL_EVENT_QUIT: + return SDL_APP_SUCCESS; + + case SDL_EVENT_KEY_DOWN: + case SDL_EVENT_KEY_UP: + if(event->key.scancode == SDL_SCANCODE_ESCAPE) + return SDL_APP_SUCCESS; + camera.on_key(event->key.scancode, event->type == SDL_EVENT_KEY_DOWN); + break; + case SDL_EVENT_MOUSE_MOTION: + camera.on_mouse_motion(event->motion.xrel, event->motion.yrel); + break; + } + return SDL_APP_CONTINUE; +} + +void SDL_AppQuit(void* appstate, SDL_AppResult result) { + (void)appstate; + (void)result; + renderer.destroy(); + SDL_DestroyWindow(renderer.win); +} diff --git a/src/pipelines.cpp b/src/pipelines.cpp new file mode 100644 index 0000000..cb535b1 --- /dev/null +++ b/src/pipelines.cpp @@ -0,0 +1,146 @@ +#include "pipelines.h" +#include "gpu.h" +#include "types.h" +#include + +void ScenePipeline::create(SDL_GPUDevice* dev, SDL_Window* win) { + vert = load_shader(dev, "shaders/scene.vert.spv", SDL_GPU_SHADERSTAGE_VERTEX, 0, 1); + frag = load_shader(dev, "shaders/scene.frag.spv", SDL_GPU_SHADERSTAGE_FRAGMENT, 0, 0); + + SDL_GPUVertexBufferDescription vert_buf { + .slot = 0, + .pitch = sizeof(Vertex), + .input_rate = SDL_GPU_VERTEXINPUTRATE_VERTEX, + .instance_step_rate = 0, + }; + + SDL_GPUVertexAttribute attrs[3] = { + { .location = 0, .buffer_slot = 0, .format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT3, .offset = 0 }, + { .location = 1, .buffer_slot = 0, .format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT4, .offset = (uint32_t)offsetof(Vertex, color) }, + { .location = 2, .buffer_slot = 0, .format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT3, .offset = (uint32_t)offsetof(Vertex, normal) }, + }; + + SDL_GPUColorTargetDescription color_tgt { + .format = SDL_GetGPUSwapchainTextureFormat(dev, win), + .blend_state = { + .src_color_blendfactor = SDL_GPU_BLENDFACTOR_SRC_ALPHA, + .dst_color_blendfactor = SDL_GPU_BLENDFACTOR_ONE_MINUS_SRC_ALPHA, + .color_blend_op = SDL_GPU_BLENDOP_ADD, + .src_alpha_blendfactor = SDL_GPU_BLENDFACTOR_SRC_ALPHA, + .dst_alpha_blendfactor = SDL_GPU_BLENDFACTOR_ONE_MINUS_SRC_ALPHA, + .alpha_blend_op = SDL_GPU_BLENDOP_ADD, + .enable_blend = false, + } + }; + + SDL_GPUGraphicsPipelineCreateInfo info { + .vertex_shader = vert, + .fragment_shader = frag, + .vertex_input_state = { + .vertex_buffer_descriptions = &vert_buf, + .num_vertex_buffers = 1, + .vertex_attributes = attrs, + .num_vertex_attributes = sizeof(attrs)/sizeof(attrs[0]), + }, + .primitive_type = SDL_GPU_PRIMITIVETYPE_TRIANGLELIST, + .rasterizer_state = { + .fill_mode = SDL_GPU_FILLMODE_FILL, + .cull_mode = SDL_GPU_CULLMODE_NONE, + .front_face = SDL_GPU_FRONTFACE_COUNTER_CLOCKWISE, + }, + .target_info = { + .color_target_descriptions = &color_tgt, + .num_color_targets = 1, + }, + }; + + pipeline = SDL_CreateGPUGraphicsPipeline(dev, &info); + if (!pipeline) + std::cerr << "Scene pipeline failed: " << SDL_GetError() << std::endl; +} + +void ScenePipeline::destroy(SDL_GPUDevice* dev) { + if (pipeline) SDL_ReleaseGPUGraphicsPipeline(dev, pipeline); + if (vert) SDL_ReleaseGPUShader(dev, vert); + if (frag) SDL_ReleaseGPUShader(dev, frag); +} + +void BlitPipeline::create(SDL_GPUDevice* dev, SDL_Window* win) { + vert = load_shader(dev, "shaders/blit.vert.spv", SDL_GPU_SHADERSTAGE_VERTEX, 0, 0); + frag = load_shader(dev, "shaders/blit.frag.spv", SDL_GPU_SHADERSTAGE_FRAGMENT, 1, 1); + + SDL_GPUColorTargetDescription color_tgt { + .format = SDL_GetGPUSwapchainTextureFormat(dev, win), + }; + + SDL_GPUGraphicsPipelineCreateInfo info { + .vertex_shader = vert, + .fragment_shader = frag, + .vertex_input_state = { + .vertex_buffer_descriptions = nullptr, + .num_vertex_buffers = 0, + .vertex_attributes = nullptr, + .num_vertex_attributes = 0, + }, + .primitive_type = SDL_GPU_PRIMITIVETYPE_TRIANGLELIST, + .rasterizer_state = { + .fill_mode = SDL_GPU_FILLMODE_FILL, + .cull_mode = SDL_GPU_CULLMODE_NONE, + .front_face = SDL_GPU_FRONTFACE_COUNTER_CLOCKWISE, + }, + .target_info = { + .color_target_descriptions = &color_tgt, + .num_color_targets = 1, + }, + }; + + pipeline = SDL_CreateGPUGraphicsPipeline(dev, &info); + if (!pipeline) + std::cerr << "Blit pipeline failed: " << SDL_GetError() << std::endl; +} + +void BlitPipeline::destroy(SDL_GPUDevice* dev) { + if (pipeline) SDL_ReleaseGPUGraphicsPipeline(dev, pipeline); + if (vert) SDL_ReleaseGPUShader(dev, vert); + if (frag) SDL_ReleaseGPUShader(dev, frag); +} + +void PostPipeline::create(SDL_GPUDevice* dev, SDL_Window* win) { + vert = load_shader(dev, "shaders/blit.vert.spv", SDL_GPU_SHADERSTAGE_VERTEX, 0, 0); + frag = load_shader(dev, "shaders/post.frag.spv", SDL_GPU_SHADERSTAGE_FRAGMENT, 1, 1); + + SDL_GPUColorTargetDescription color_tgt { + .format = SDL_GetGPUSwapchainTextureFormat(dev, win), + }; + + SDL_GPUGraphicsPipelineCreateInfo info { + .vertex_shader = vert, + .fragment_shader = frag, + .vertex_input_state = { + .vertex_buffer_descriptions = nullptr, + .num_vertex_buffers = 0, + .vertex_attributes = nullptr, + .num_vertex_attributes = 0, + }, + .primitive_type = SDL_GPU_PRIMITIVETYPE_TRIANGLELIST, + .rasterizer_state = { + .fill_mode = SDL_GPU_FILLMODE_FILL, + .cull_mode = SDL_GPU_CULLMODE_NONE, + .front_face = SDL_GPU_FRONTFACE_COUNTER_CLOCKWISE, + }, + .target_info = { + .color_target_descriptions = &color_tgt, + .num_color_targets = 1, + }, + }; + + pipeline = SDL_CreateGPUGraphicsPipeline(dev, &info); + if (!pipeline) + std::cerr << "Post pipeline failed: " << SDL_GetError() << std::endl; +} + +void PostPipeline::destroy(SDL_GPUDevice* dev) { + if (pipeline) SDL_ReleaseGPUGraphicsPipeline(dev, pipeline); + if (vert) SDL_ReleaseGPUShader(dev, vert); + if (frag) SDL_ReleaseGPUShader(dev, frag); +} \ No newline at end of file diff --git a/src/pipelines.h b/src/pipelines.h new file mode 100644 index 0000000..12281c7 --- /dev/null +++ b/src/pipelines.h @@ -0,0 +1,29 @@ +#pragma once +#include + +struct ScenePipeline { + SDL_GPUGraphicsPipeline* pipeline = nullptr; + SDL_GPUShader* vert = nullptr; + SDL_GPUShader* frag = nullptr; + + void create(SDL_GPUDevice* dev, SDL_Window* win); + void destroy(SDL_GPUDevice* dev); +}; + +struct BlitPipeline { + SDL_GPUGraphicsPipeline* pipeline = nullptr; + SDL_GPUShader* vert = nullptr; + SDL_GPUShader* frag = nullptr; + + void create(SDL_GPUDevice* dev, SDL_Window* win); + void destroy(SDL_GPUDevice* dev); +}; + +struct PostPipeline { + SDL_GPUGraphicsPipeline* pipeline = nullptr; + SDL_GPUShader* vert = nullptr; + SDL_GPUShader* frag = nullptr; + + void create(SDL_GPUDevice* dev, SDL_Window* win); + void destroy(SDL_GPUDevice* dev); +}; \ No newline at end of file diff --git a/src/renderer.cpp b/src/renderer.cpp new file mode 100644 index 0000000..adf235f --- /dev/null +++ b/src/renderer.cpp @@ -0,0 +1,183 @@ +#include "renderer.h" +#include "gpu.h" +#include +#define TINYOBJLOADER_IMPLEMENTATION +#include "tiny_obj_loader.h" + + +bool Renderer::init(SDL_Window* w) { + win = w; + dev = SDL_CreateGPUDevice(SDL_GPU_SHADERFORMAT_SPIRV, true, NULL); + if (!dev) { std::cerr << "GPU device failed: " << SDL_GetError() << std::endl; return false; } + + SDL_ClaimWindowForGPUDevice(dev, win); + + load_obj(); + + render_sampler = create_linear_sampler(dev); + resize_render_texture(960, 540); + + scene.create(dev, win); + blit.create(dev, win); + post.create(dev, win); + + return scene.pipeline && blit.pipeline; +} + +void Renderer::destroy() { + if (render_tex) SDL_ReleaseGPUTexture(dev, render_tex); + if (post_tex) SDL_ReleaseGPUTexture(dev, post_tex); + if (render_sampler) SDL_ReleaseGPUSampler(dev, render_sampler); + if (vert_buff) SDL_ReleaseGPUBuffer(dev, vert_buff); + scene.destroy(dev); + blit.destroy(dev); + post.destroy(dev); + SDL_DestroyGPUDevice(dev); +} + +bool Renderer::load_obj() { + const std::string& path = "assets/homer.obj"; + tinyobj::attrib_t attrib; + std::vector shapes; + std::vector materials; + std::string warn, err; + if(!tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err, path.c_str())) { + std::cerr << "OBJ fail: " << warn << err << std::endl; + return false; + } + + vertices.clear(); + for(const auto& shape : shapes) { + const auto& indices = shape.mesh.indices; + for(size_t i = 0; i < indices.size(); i += 3) { + // Use OBJ normals if present, otherwise compute face normal + vec3 pos[3]; + vec3 nor[3]; + bool has_normals = true; + + for(int v = 0; v < 3; v++) { + const auto& idx = indices[i + v]; + pos[v] = vec3( + attrib.vertices[3 * idx.vertex_index + 0], + attrib.vertices[3 * idx.vertex_index + 1], + attrib.vertices[3 * idx.vertex_index + 2] + ); + if(idx.normal_index >= 0) { + nor[v] = vec3( + attrib.normals[3 * idx.normal_index + 0], + attrib.normals[3 * idx.normal_index + 1], + attrib.normals[3 * idx.normal_index + 2] + ); + } else { + has_normals = false; + } + } + + if(!has_normals) { + vec3 face_normal = glm::normalize(glm::cross(pos[1] - pos[0], pos[2] - pos[0])); + nor[0] = nor[1] = nor[2] = face_normal; + } + + for(int v = 0; v < 3; v++) { + vertices.push_back(Vertex { + .pos = pos[v], + .color = vec4(abs(sin(pos[v].x)), abs(cos(pos[v].y)), abs(sin(pos[v].z) * cos(pos[v].y)), 1.0f), + .normal = nor[v], + }); + } + } + } + + SDL_GPUBufferCreateInfo info { + .usage = SDL_GPU_BUFFERUSAGE_VERTEX, + .size = static_cast(vertices.size() * sizeof(Vertex)), + }; + vert_buff = SDL_CreateGPUBuffer(dev, &info); + upload_buffer(dev, vert_buff, vertices.data(), info.size); + return true; +} + +void Renderer::resize_render_texture(uint32_t w, uint32_t h) { + SDL_WaitForGPUIdle(dev); + if (render_tex) SDL_ReleaseGPUTexture(dev, render_tex); + if (post_tex) SDL_ReleaseGPUTexture(dev, post_tex); + render_tex = create_render_texture(dev, win, w, h); + post_tex = create_render_texture(dev, win, w, h); + render_w = w; + render_h = h; +} + + +void Renderer::pass_scene(SDL_GPUCommandBuffer* cmd, const CameraUBO& ubo) { + SDL_PushGPUVertexUniformData(cmd, 0, &ubo, sizeof(ubo)); + + SDL_GPUColorTargetInfo tgt { + .texture = render_tex, + .clear_color = { 0.0, 0.0, 0.0, 1.0}, + .load_op = SDL_GPU_LOADOP_CLEAR, + .store_op = SDL_GPU_STOREOP_STORE, + }; + + SDL_GPURenderPass* pass = SDL_BeginGPURenderPass(cmd, &tgt, 1, NULL); + SDL_BindGPUGraphicsPipeline(pass, scene.pipeline); + SDL_GPUBufferBinding binding { .buffer = vert_buff, .offset = 0 }; + SDL_BindGPUVertexBuffers(pass, 0, &binding, 1); + SDL_DrawGPUPrimitives(pass, vertices.size(), 1, 0, 0); + SDL_EndGPURenderPass(pass); +} + +void Renderer::pass_blit(SDL_GPUCommandBuffer* cmd, const CameraUBO& ubo) { + SDL_PushGPUFragmentUniformData(cmd, 0, &ubo, sizeof(ubo)); + + SDL_GPUColorTargetInfo tgt { + .texture = post_tex, + .load_op = SDL_GPU_LOADOP_CLEAR, + .store_op = SDL_GPU_STOREOP_STORE, + }; + + SDL_GPURenderPass* pass = SDL_BeginGPURenderPass(cmd, &tgt, 1, NULL); + SDL_BindGPUGraphicsPipeline(pass, blit.pipeline); + SDL_GPUTextureSamplerBinding tex { .texture = render_tex, .sampler = render_sampler }; + SDL_BindGPUFragmentSamplers(pass, 0, &tex, 1); + SDL_DrawGPUPrimitives(pass, 3, 1, 0, 0); + SDL_EndGPURenderPass(pass); +} + +void Renderer::pass_post(SDL_GPUCommandBuffer* cmd, SDL_GPUTexture* swapchain, const CameraUBO& ubo) { + SDL_PushGPUFragmentUniformData(cmd, 0, &ubo, sizeof(ubo)); + + SDL_GPUColorTargetInfo tgt { + .texture = swapchain, + .load_op = SDL_GPU_LOADOP_CLEAR, + .store_op = SDL_GPU_STOREOP_STORE, + }; + + SDL_GPURenderPass* pass = SDL_BeginGPURenderPass(cmd, &tgt, 1, NULL); + SDL_BindGPUGraphicsPipeline(pass, post.pipeline); + SDL_GPUTextureSamplerBinding tex { .texture = post_tex, .sampler = render_sampler }; + SDL_BindGPUFragmentSamplers(pass, 0, &tex, 1); + SDL_DrawGPUPrimitives(pass, 3, 1, 0, 0); + SDL_EndGPURenderPass(pass); +} + +void Renderer::draw(const CameraUBO& ubo) { + SDL_GPUCommandBuffer* cmd = SDL_AcquireGPUCommandBuffer(dev); + + SDL_GPUTexture* swapchain; + uint32_t sw_w, sw_h; + SDL_WaitAndAcquireGPUSwapchainTexture(cmd, win, &swapchain, &sw_w, &sw_h); + + if (!swapchain) { + SDL_SubmitGPUCommandBuffer(cmd); + return; + } + + if (sw_w != render_w || sw_h != render_h) + resize_render_texture(sw_w, sw_h); + + pass_scene(cmd, ubo); + pass_blit(cmd, ubo); + pass_post(cmd, swapchain, ubo); + + SDL_SubmitGPUCommandBuffer(cmd); +} diff --git a/src/renderer.h b/src/renderer.h new file mode 100644 index 0000000..09f1ef1 --- /dev/null +++ b/src/renderer.h @@ -0,0 +1,34 @@ +#pragma once +#include "types.h" +#include "pipelines.h" +#include +#include + +struct Renderer { + SDL_GPUDevice* dev = nullptr; + SDL_Window* win = nullptr; + + ScenePipeline scene; + BlitPipeline blit; + PostPipeline post; + + SDL_GPUBuffer* vert_buff = nullptr; + SDL_GPUTexture* render_tex = nullptr; + SDL_GPUTexture* post_tex = nullptr; + SDL_GPUSampler* render_sampler = nullptr; + uint32_t render_w = 0, render_h = 0; + + std::vector vertices; + + bool init(SDL_Window* win); + void destroy(); + + void draw(const CameraUBO& ubo); + +private: + bool load_obj(); + void resize_render_texture(uint32_t w, uint32_t h); + void pass_scene(SDL_GPUCommandBuffer* cmd, const CameraUBO& ubo); + void pass_blit(SDL_GPUCommandBuffer* cmd, const CameraUBO& ubo); + void pass_post(SDL_GPUCommandBuffer* cmd, SDL_GPUTexture* swapchain, const CameraUBO& ubo); +}; diff --git a/src/tiny_obj_loader.h b/src/tiny_obj_loader.h new file mode 100644 index 0000000..2a949fd --- /dev/null +++ b/src/tiny_obj_loader.h @@ -0,0 +1,9267 @@ +/* +The MIT License (MIT) + +Copyright (c) 2012-Present, Syoyo Fujita and many contributors. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +// +// version 2.0.0 : Add new object oriented API. 1.x API is still provided. +// * Add python binding. +// * Support line primitive. +// * Support points primitive. +// * Support multiple search path for .mtl(v1 API). +// * Support vertex skinning weight `vw`(as an tinyobj +// extension). Note that this differs vertex weight([w] +// component in `v` line) +// * Support escaped whitespece in mtllib +// * Add robust triangulation using Mapbox +// earcut(TINYOBJLOADER_USE_MAPBOX_EARCUT). +// version 1.4.0 : Modifed ParseTextureNameAndOption API +// version 1.3.1 : Make ParseTextureNameAndOption API public +// version 1.3.0 : Separate warning and error message(breaking API of LoadObj) +// version 1.2.3 : Added color space extension('-colorspace') to tex opts. +// version 1.2.2 : Parse multiple group names. +// version 1.2.1 : Added initial support for line('l') primitive(PR #178) +// version 1.2.0 : Hardened implementation(#175) +// version 1.1.1 : Support smoothing groups(#162) +// version 1.1.0 : Support parsing vertex color(#144) +// version 1.0.8 : Fix parsing `g` tag just after `usemtl`(#138) +// version 1.0.7 : Support multiple tex options(#126) +// version 1.0.6 : Add TINYOBJLOADER_USE_DOUBLE option(#124) +// version 1.0.5 : Ignore `Tr` when `d` exists in MTL(#43) +// version 1.0.4 : Support multiple filenames for 'mtllib'(#112) +// version 1.0.3 : Support parsing texture options(#85) +// version 1.0.2 : Improve parsing speed by about a factor of 2 for large +// files(#105) +// version 1.0.1 : Fixes a shape is lost if obj ends with a 'usemtl'(#104) +// version 1.0.0 : Change data structure. Change license from BSD to MIT. +// + +// +// Use this in *one* .cc +// #define TINYOBJLOADER_IMPLEMENTATION +// #include "tiny_obj_loader.h" +// + +#ifndef TINY_OBJ_LOADER_H_ +#define TINY_OBJ_LOADER_H_ + +#include +#include +#include + +namespace tinyobj { + +// C++11 is now the minimum required standard. +#if __cplusplus < 201103L && (!defined(_MSVC_LANG) || _MSVC_LANG < 201103L) +#error "tinyobjloader requires C++11 or later. Compile with -std=c++11 or higher." +#endif +#define TINYOBJ_OVERRIDE override + +#ifdef __clang__ +#pragma clang diagnostic push +#if __has_warning("-Wzero-as-null-pointer-constant") +#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" +#endif + +#pragma clang diagnostic ignored "-Wpadded" + +#endif + +// https://en.wikipedia.org/wiki/Wavefront_.obj_file says ... +// +// -blendu on | off # set horizontal texture blending +// (default on) +// -blendv on | off # set vertical texture blending +// (default on) +// -boost real_value # boost mip-map sharpness +// -mm base_value gain_value # modify texture map values (default +// 0 1) +// # base_value = brightness, +// gain_value = contrast +// -o u [v [w]] # Origin offset (default +// 0 0 0) +// -s u [v [w]] # Scale (default +// 1 1 1) +// -t u [v [w]] # Turbulence (default +// 0 0 0) +// -texres resolution # texture resolution to create +// -clamp on | off # only render texels in the clamped +// 0-1 range (default off) +// # When unclamped, textures are +// repeated across a surface, +// # when clamped, only texels which +// fall within the 0-1 +// # range are rendered. +// -bm mult_value # bump multiplier (for bump maps +// only) +// +// -imfchan r | g | b | m | l | z # specifies which channel of the file +// is used to +// # create a scalar or bump texture. +// r:red, g:green, +// # b:blue, m:matte, l:luminance, +// z:z-depth.. +// # (the default for bump is 'l' and +// for decal is 'm') +// bump -imfchan r bumpmap.tga # says to use the red channel of +// bumpmap.tga as the bumpmap +// +// For reflection maps... +// +// -type sphere # specifies a sphere for a "refl" +// reflection map +// -type cube_top | cube_bottom | # when using a cube map, the texture +// file for each +// cube_front | cube_back | # side of the cube is specified +// separately +// cube_left | cube_right +// +// TinyObjLoader extension. +// +// -colorspace SPACE # Color space of the texture. e.g. +// 'sRGB` or 'linear' +// + +#ifdef TINYOBJLOADER_USE_DOUBLE +//#pragma message "using double" +typedef double real_t; +#else +//#pragma message "using float" +typedef float real_t; +#endif + +typedef enum { + TEXTURE_TYPE_NONE, // default + TEXTURE_TYPE_SPHERE, + TEXTURE_TYPE_CUBE_TOP, + TEXTURE_TYPE_CUBE_BOTTOM, + TEXTURE_TYPE_CUBE_FRONT, + TEXTURE_TYPE_CUBE_BACK, + TEXTURE_TYPE_CUBE_LEFT, + TEXTURE_TYPE_CUBE_RIGHT +} texture_type_t; + +struct texture_option_t { + texture_type_t type; // -type (default TEXTURE_TYPE_NONE) + real_t sharpness; // -boost (default 1.0?) + real_t brightness; // base_value in -mm option (default 0) + real_t contrast; // gain_value in -mm option (default 1) + real_t origin_offset[3]; // -o u [v [w]] (default 0 0 0) + real_t scale[3]; // -s u [v [w]] (default 1 1 1) + real_t turbulence[3]; // -t u [v [w]] (default 0 0 0) + int texture_resolution; // -texres resolution (No default value in the spec. + // We'll use -1) + bool clamp; // -clamp (default false) + char imfchan; // -imfchan (the default for bump is 'l' and for decal is 'm') + bool blendu; // -blendu (default on) + bool blendv; // -blendv (default on) + real_t bump_multiplier; // -bm (for bump maps only, default 1.0) + + // extension + std::string colorspace; // Explicitly specify color space of stored texel + // value. Usually `sRGB` or `linear` (default empty). +}; + +struct material_t { + std::string name; + + real_t ambient[3]; + real_t diffuse[3]; + real_t specular[3]; + real_t transmittance[3]; + real_t emission[3]; + real_t shininess; + real_t ior; // index of refraction + real_t dissolve; // 1 == opaque; 0 == fully transparent + // illumination model (see http://www.fileformat.info/format/material/) + int illum; + + int dummy; // Suppress padding warning. + + std::string ambient_texname; // map_Ka. For ambient or ambient occlusion. + std::string diffuse_texname; // map_Kd + std::string specular_texname; // map_Ks + std::string specular_highlight_texname; // map_Ns + std::string bump_texname; // map_bump, map_Bump, bump + std::string displacement_texname; // disp + std::string alpha_texname; // map_d + std::string reflection_texname; // refl + + texture_option_t ambient_texopt; + texture_option_t diffuse_texopt; + texture_option_t specular_texopt; + texture_option_t specular_highlight_texopt; + texture_option_t bump_texopt; + texture_option_t displacement_texopt; + texture_option_t alpha_texopt; + texture_option_t reflection_texopt; + + // PBR extension + // http://exocortex.com/blog/extending_wavefront_mtl_to_support_pbr + real_t roughness; // [0, 1] default 0 + real_t metallic; // [0, 1] default 0 + real_t sheen; // [0, 1] default 0 + real_t clearcoat_thickness; // [0, 1] default 0 + real_t clearcoat_roughness; // [0, 1] default 0 + real_t anisotropy; // aniso. [0, 1] default 0 + real_t anisotropy_rotation; // anisor. [0, 1] default 0 + real_t pad0; + std::string roughness_texname; // map_Pr + std::string metallic_texname; // map_Pm + std::string sheen_texname; // map_Ps + std::string emissive_texname; // map_Ke + std::string normal_texname; // norm. For normal mapping. + + texture_option_t roughness_texopt; + texture_option_t metallic_texopt; + texture_option_t sheen_texopt; + texture_option_t emissive_texopt; + texture_option_t normal_texopt; + + int pad2; + + std::map unknown_parameter; + +#ifdef TINY_OBJ_LOADER_PYTHON_BINDING + // For pybind11 + std::array GetDiffuse() { + std::array values; + values[0] = double(diffuse[0]); + values[1] = double(diffuse[1]); + values[2] = double(diffuse[2]); + + return values; + } + + std::array GetSpecular() { + std::array values; + values[0] = double(specular[0]); + values[1] = double(specular[1]); + values[2] = double(specular[2]); + + return values; + } + + std::array GetTransmittance() { + std::array values; + values[0] = double(transmittance[0]); + values[1] = double(transmittance[1]); + values[2] = double(transmittance[2]); + + return values; + } + + std::array GetEmission() { + std::array values; + values[0] = double(emission[0]); + values[1] = double(emission[1]); + values[2] = double(emission[2]); + + return values; + } + + std::array GetAmbient() { + std::array values; + values[0] = double(ambient[0]); + values[1] = double(ambient[1]); + values[2] = double(ambient[2]); + + return values; + } + + void SetDiffuse(std::array &a) { + diffuse[0] = real_t(a[0]); + diffuse[1] = real_t(a[1]); + diffuse[2] = real_t(a[2]); + } + + void SetAmbient(std::array &a) { + ambient[0] = real_t(a[0]); + ambient[1] = real_t(a[1]); + ambient[2] = real_t(a[2]); + } + + void SetSpecular(std::array &a) { + specular[0] = real_t(a[0]); + specular[1] = real_t(a[1]); + specular[2] = real_t(a[2]); + } + + void SetTransmittance(std::array &a) { + transmittance[0] = real_t(a[0]); + transmittance[1] = real_t(a[1]); + transmittance[2] = real_t(a[2]); + } + + std::string GetCustomParameter(const std::string &key) { + std::map::const_iterator it = + unknown_parameter.find(key); + + if (it != unknown_parameter.end()) { + return it->second; + } + return std::string(); + } + +#endif +}; + +struct tag_t { + std::string name; + + std::vector intValues; + std::vector floatValues; + std::vector stringValues; +}; + +struct joint_and_weight_t { + int joint_id; + real_t weight; +}; + +struct skin_weight_t { + int vertex_id; // Corresponding vertex index in `attrib_t::vertices`. + // Compared to `index_t`, this index must be positive and + // start with 0(does not allow relative indexing) + std::vector weightValues; +}; + +// Index struct to support different indices for vtx/normal/texcoord. +// -1 means not used. +struct index_t { + int vertex_index; + int normal_index; + int texcoord_index; +}; + +struct mesh_t { + std::vector indices; + std::vector + num_face_vertices; // The number of vertices per + // face. 3 = triangle, 4 = quad, ... + std::vector material_ids; // per-face material ID + std::vector smoothing_group_ids; // per-face smoothing group + // ID(0 = off. positive value + // = group id) + std::vector tags; // SubD tag +}; + +// struct path_t { +// std::vector indices; // pairs of indices for lines +//}; + +struct lines_t { + // Linear flattened indices. + std::vector indices; // indices for vertices(poly lines) + std::vector num_line_vertices; // The number of vertices per line. +}; + +struct points_t { + std::vector indices; // indices for points +}; + +struct shape_t { + std::string name; + mesh_t mesh; + lines_t lines; + points_t points; +}; + +// Vertex attributes +struct attrib_t { + std::vector vertices; // 'v'(xyz) + + // For backward compatibility, we store vertex weight in separate array. + std::vector vertex_weights; // 'v'(w) + std::vector normals; // 'vn' + std::vector texcoords; // 'vt'(uv) + + // For backward compatibility, we store texture coordinate 'w' in separate + // array. + std::vector texcoord_ws; // 'vt'(w) + std::vector colors; // extension: vertex colors + + // + // TinyObj extension. + // + + // NOTE(syoyo): array index is based on the appearance order. + // To get a corresponding skin weight for a specific vertex id `vid`, + // Need to reconstruct a look up table: `skin_weight_t::vertex_id` == `vid` + // (e.g. using std::map, std::unordered_map) + std::vector skin_weights; + + attrib_t() {} + + // + // For pybind11 + // + const std::vector &GetVertices() const { return vertices; } + + const std::vector &GetVertexWeights() const { return vertex_weights; } +}; + +struct callback_t { + // W is optional and set to 1 if there is no `w` item in `v` line + void (*vertex_cb)(void *user_data, real_t x, real_t y, real_t z, real_t w); + void (*vertex_color_cb)(void *user_data, real_t x, real_t y, real_t z, + real_t r, real_t g, real_t b, bool has_color); + void (*normal_cb)(void *user_data, real_t x, real_t y, real_t z); + + // y and z are optional and set to 0 if there is no `y` and/or `z` item(s) in + // `vt` line. + void (*texcoord_cb)(void *user_data, real_t x, real_t y, real_t z); + + // called per 'f' line. num_indices is the number of face indices(e.g. 3 for + // triangle, 4 for quad) + // 0 will be passed for undefined index in index_t members. + void (*index_cb)(void *user_data, index_t *indices, int num_indices); + // `name` material name, `material_id` = the array index of material_t[]. -1 + // if + // a material not found in .mtl + void (*usemtl_cb)(void *user_data, const char *name, int material_id); + // `materials` = parsed material data. + void (*mtllib_cb)(void *user_data, const material_t *materials, + int num_materials); + // There may be multiple group names + void (*group_cb)(void *user_data, const char **names, int num_names); + void (*object_cb)(void *user_data, const char *name); + + callback_t() + : vertex_cb(NULL), + vertex_color_cb(NULL), + normal_cb(NULL), + texcoord_cb(NULL), + index_cb(NULL), + usemtl_cb(NULL), + mtllib_cb(NULL), + group_cb(NULL), + object_cb(NULL) {} +}; + +class MaterialReader { + public: + MaterialReader() {} + virtual ~MaterialReader(); + + virtual bool operator()(const std::string &matId, + std::vector *materials, + std::map *matMap, std::string *warn, + std::string *err) = 0; +}; + +/// +/// Read .mtl from a file. +/// +class MaterialFileReader : public MaterialReader { + public: + // Path could contain separator(';' in Windows, ':' in Posix) + explicit MaterialFileReader(const std::string &mtl_basedir) + : m_mtlBaseDir(mtl_basedir) {} + virtual ~MaterialFileReader() TINYOBJ_OVERRIDE {} + virtual bool operator()(const std::string &matId, + std::vector *materials, + std::map *matMap, std::string *warn, + std::string *err) TINYOBJ_OVERRIDE; + + private: + std::string m_mtlBaseDir; +}; + +/// +/// Read .mtl from a stream. +/// +class MaterialStreamReader : public MaterialReader { + public: + explicit MaterialStreamReader(std::istream &inStream) + : m_inStream(inStream) {} + virtual ~MaterialStreamReader() TINYOBJ_OVERRIDE {} + virtual bool operator()(const std::string &matId, + std::vector *materials, + std::map *matMap, std::string *warn, + std::string *err) TINYOBJ_OVERRIDE; + + private: + std::istream &m_inStream; +}; + +// v2 API +struct ObjReaderConfig { + bool triangulate; // triangulate polygon? + + // Currently not used. + // "simple" or empty: Create triangle fan + // "earcut": Use the algorithm based on Ear clipping + std::string triangulation_method; + + /// Parse vertex color. + /// If vertex color is not present, its filled with default value. + /// false = no vertex color + /// This will increase memory of parsed .obj + bool vertex_color; + + /// + /// Search path to .mtl file. + /// Default = "" = search from the same directory of .obj file. + /// Valid only when loading .obj from a file. + /// + std::string mtl_search_path; + + ObjReaderConfig() + : triangulate(true), triangulation_method("simple"), vertex_color(true) {} +}; + +/// +/// Wavefront .obj reader class(v2 API) +/// +class ObjReader { + public: + ObjReader() : valid_(false) {} + + /// + /// Load .obj and .mtl from a file. + /// + /// @param[in] filename wavefront .obj filename + /// @param[in] config Reader configuration + /// + bool ParseFromFile(const std::string &filename, + const ObjReaderConfig &config = ObjReaderConfig()); + + /// + /// Parse .obj from a text string. + /// Need to supply .mtl text string by `mtl_text`. + /// This function ignores `mtllib` line in .obj text. + /// + /// @param[in] obj_text wavefront .obj filename + /// @param[in] mtl_text wavefront .mtl filename + /// @param[in] config Reader configuration + /// + bool ParseFromString(const std::string &obj_text, const std::string &mtl_text, + const ObjReaderConfig &config = ObjReaderConfig()); + + /// + /// .obj was loaded or parsed correctly. + /// + bool Valid() const { return valid_; } + + const attrib_t &GetAttrib() const { return attrib_; } + + const std::vector &GetShapes() const { return shapes_; } + + const std::vector &GetMaterials() const { return materials_; } + + /// + /// Warning message(may be filled after `Load` or `Parse`) + /// + const std::string &Warning() const { return warning_; } + + /// + /// Error message(filled when `Load` or `Parse` failed) + /// + const std::string &Error() const { return error_; } + + private: + bool valid_; + + attrib_t attrib_; + std::vector shapes_; + std::vector materials_; + + std::string warning_; + std::string error_; +}; + +/// ==>>========= Legacy v1 API ============================================= + +/// Loads .obj from a file. +/// 'attrib', 'shapes' and 'materials' will be filled with parsed shape data +/// 'shapes' will be filled with parsed shape data +/// Returns true when loading .obj become success. +/// Returns warning message into `warn`, and error message into `err` +/// 'mtl_basedir' is optional, and used for base directory for .mtl file. +/// In default(`NULL'), .mtl file is searched from an application's working +/// directory. +/// 'triangulate' is optional, and used whether triangulate polygon face in .obj +/// or not. +/// Option 'default_vcols_fallback' specifies whether vertex colors should +/// always be defined, even if no colors are given (fallback to white). +bool LoadObj(attrib_t *attrib, std::vector *shapes, + std::vector *materials, std::string *warn, + std::string *err, const char *filename, + const char *mtl_basedir = NULL, bool triangulate = true, + bool default_vcols_fallback = true); + +/// Loads .obj from a file with custom user callback. +/// .mtl is loaded as usual and parsed material_t data will be passed to +/// `callback.mtllib_cb`. +/// Returns true when loading .obj/.mtl become success. +/// Returns warning message into `warn`, and error message into `err` +/// See `examples/callback_api/` for how to use this function. +bool LoadObjWithCallback(std::istream &inStream, const callback_t &callback, + void *user_data = NULL, + MaterialReader *readMatFn = NULL, + std::string *warn = NULL, std::string *err = NULL); + +/// Loads object from a std::istream, uses `readMatFn` to retrieve +/// std::istream for materials. +/// Returns true when loading .obj become success. +/// Returns warning and error message into `err` +bool LoadObj(attrib_t *attrib, std::vector *shapes, + std::vector *materials, std::string *warn, + std::string *err, std::istream *inStream, + MaterialReader *readMatFn = NULL, bool triangulate = true, + bool default_vcols_fallback = true); + +/// Loads materials into std::map +void LoadMtl(std::map *material_map, + std::vector *materials, std::istream *inStream, + std::string *warning, std::string *err); + +/// +/// Parse texture name and texture option for custom texture parameter through +/// material::unknown_parameter +/// +/// @param[out] texname Parsed texture name +/// @param[out] texopt Parsed texopt +/// @param[in] linebuf Input string +/// +bool ParseTextureNameAndOption(std::string *texname, texture_option_t *texopt, + const char *linebuf); + +/// =<<========== Legacy v1 API ============================================= + +} // namespace tinyobj + +#endif // TINY_OBJ_LOADER_H_ + +#ifdef TINYOBJLOADER_IMPLEMENTATION +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef _WIN32 +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#ifndef NOMINMAX +#define NOMINMAX +#endif +#include +#endif + +#ifdef TINYOBJLOADER_USE_MMAP +#if !defined(_WIN32) +// POSIX headers for mmap +#include +#include +#include +#include +#endif +#endif // TINYOBJLOADER_USE_MMAP +#include +#include +#include + +#ifdef TINYOBJLOADER_USE_MAPBOX_EARCUT + +#ifdef TINYOBJLOADER_DONOT_INCLUDE_MAPBOX_EARCUT +// Assume earcut.hpp is included outside of tiny_obj_loader.h +#else + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Weverything" +#endif + +#include + +#include "mapbox/earcut.hpp" + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +#endif + +#endif // TINYOBJLOADER_USE_MAPBOX_EARCUT + +#ifdef _WIN32 +// Converts a UTF-8 encoded string to a UTF-16 wide string for use with +// Windows file APIs that support Unicode paths (including paths longer than +// MAX_PATH when combined with the extended-length path prefix). +static std::wstring UTF8ToWchar(const std::string &str) { + if (str.empty()) return std::wstring(); + int size_needed = + MultiByteToWideChar(CP_UTF8, 0, str.c_str(), + static_cast(str.size()), NULL, 0); + if (size_needed == 0) return std::wstring(); + std::wstring wstr(static_cast(size_needed), L'\0'); + int result = + MultiByteToWideChar(CP_UTF8, 0, str.c_str(), + static_cast(str.size()), &wstr[0], size_needed); + if (result == 0) return std::wstring(); + return wstr; +} + +// Prepends the Windows extended-length path prefix ("\\?\") to an absolute +// path when the path length meets or exceeds MAX_PATH (260 characters). +// This allows Windows APIs to handle paths up to 32767 characters long. +// UNC paths (starting with "\\") are converted to "\\?\UNC\" form. +static std::wstring LongPathW(const std::wstring &wpath) { + const std::wstring kLongPathPrefix = L"\\\\?\\"; + const std::wstring kUNCPrefix = L"\\\\"; + const std::wstring kLongUNCPathPrefix = L"\\\\?\\UNC\\"; + + // Already has the extended-length prefix; return as-is. + if (wpath.size() >= kLongPathPrefix.size() && + wpath.substr(0, kLongPathPrefix.size()) == kLongPathPrefix) { + return wpath; + } + + // Only add the prefix when the path is long enough to require it. + if (wpath.size() < MAX_PATH) { + return wpath; + } + + // Normalize forward slashes to backslashes: the extended-length "\\?\" + // prefix requires backslash separators only. + std::wstring normalized = wpath; + for (std::wstring::size_type i = 0; i < normalized.size(); ++i) { + if (normalized[i] == L'/') normalized[i] = L'\\'; + } + + // UNC path: "\\server\share\..." -> "\\?\UNC\server\share\..." + if (normalized.size() >= kUNCPrefix.size() && + normalized.substr(0, kUNCPrefix.size()) == kUNCPrefix) { + return kLongUNCPathPrefix + normalized.substr(kUNCPrefix.size()); + } + + // Absolute path with drive letter: "C:\..." -> "\\?\C:\..." + if (normalized.size() >= 2 && normalized[1] == L':') { + return kLongPathPrefix + normalized; + } + + return normalized; +} +#endif // _WIN32 + +// -------------------------------------------------------------------------- +// Embedded fast_float v8.0.2 for high-performance, bit-exact float parsing. +// Disable by defining TINYOBJLOADER_DISABLE_FAST_FLOAT before including +// this file with TINYOBJLOADER_IMPLEMENTATION. +// -------------------------------------------------------------------------- +#ifndef TINYOBJLOADER_DISABLE_FAST_FLOAT + +// Standard headers needed by the embedded fast_float. +#include +#include + +namespace tinyobj_ff { + +// --- integral_constant, true_type, false_type --- +template +struct integral_constant { + static const T value = V; + typedef T value_type; + typedef integral_constant type; + operator value_type() const { return value; } +}; +typedef integral_constant true_type; +typedef integral_constant false_type; + +// --- is_same --- +template struct is_same : false_type {}; +template struct is_same : true_type {}; + +// --- enable_if --- +template struct enable_if {}; +template struct enable_if { typedef T type; }; + +// --- conditional --- +template struct conditional { typedef T type; }; +template struct conditional { typedef F type; }; + +// --- is_integral --- +template struct is_integral : false_type {}; +template <> struct is_integral : true_type {}; +template <> struct is_integral : true_type {}; +template <> struct is_integral : true_type {}; +template <> struct is_integral : true_type {}; +template <> struct is_integral : true_type {}; +template <> struct is_integral : true_type {}; +template <> struct is_integral : true_type {}; +template <> struct is_integral : true_type {}; +template <> struct is_integral : true_type {}; +template <> struct is_integral : true_type {}; +template <> struct is_integral : true_type {}; +template <> struct is_integral : true_type {}; +template <> struct is_integral : true_type {}; +template <> struct is_integral : true_type {}; +template <> struct is_integral : true_type {}; + +// --- is_signed --- +template struct is_signed : integral_constant {}; + +// --- underlying_type (uses compiler builtin) --- +template struct underlying_type { + typedef __underlying_type(T) type; +}; + +// --- ff_errc (replaces std::errc, our own enum - no system_error needed) --- +enum class ff_errc { ok = 0, invalid_argument = 22, result_out_of_range = 34 }; + +// --- min_val (replaces std::min, avoids Windows min/max macro conflicts) --- +template +inline T min_val(T a, T b) { return (b < a) ? b : a; } + +// --- copy_n --- +template +inline OutputIt copy_n(InputIt first, Size count, OutputIt result) { + for (Size i = 0; i < count; ++i) *result++ = *first++; + return result; +} + +// --- copy_backward --- +template +inline BidirIt2 copy_backward(BidirIt1 first, BidirIt1 last, BidirIt2 d_last) { + while (first != last) *(--d_last) = *(--last); + return d_last; +} + +// --- fill --- +template +inline void fill(ForwardIt first, ForwardIt last, const T &value) { + for (; first != last; ++first) *first = value; +} + +// --- distance --- +template +inline typename conditional::type +distance(It first, It last) { + return last - first; +} + +} // namespace tinyobj_ff + +// --- Begin embedded fast_float v8.0.2 (MIT / Apache-2.0 / BSL-1.0) --- +// https://github.com/fastfloat/fast_float +// fast_float by Daniel Lemire +// fast_float by João Paulo Magalhaes +// +// +// with contributions from Eugene Golushkov +// with contributions from Maksim Kita +// with contributions from Marcin Wojdyr +// with contributions from Neal Richardson +// with contributions from Tim Paine +// with contributions from Fabio Pellacini +// with contributions from Lénárd Szolnoki +// with contributions from Jan Pharago +// with contributions from Maya Warrier +// with contributions from Taha Khokhar +// with contributions from Anders Dalvander +// +// +// Licensed under the Apache License, Version 2.0, or the +// MIT License or the Boost License. This file may not be copied, +// modified, or distributed except according to those terms. +// +// MIT License Notice +// +// MIT License +// +// Copyright (c) 2021 The fast_float authors +// +// Permission is hereby granted, free of charge, to any +// person obtaining a copy of this software and associated +// documentation files (the "Software"), to deal in the +// Software without restriction, including without +// limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice +// shall be included in all copies or substantial portions +// of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// +// Apache License (Version 2.0) Notice +// +// Copyright 2021 The fast_float authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// +// BOOST License Notice +// +// Boost Software License - Version 1.0 - August 17th, 2003 +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + +#ifndef FASTFLOAT_CONSTEXPR_FEATURE_DETECT_H +#define FASTFLOAT_CONSTEXPR_FEATURE_DETECT_H + +#ifdef __has_include +#if __has_include() +#include +#endif +#endif + +// Testing for https://wg21.link/N3652, adopted in C++14 +#if defined(__cpp_constexpr) && __cpp_constexpr >= 201304 +#define FASTFLOAT_CONSTEXPR14 constexpr +#else +#define FASTFLOAT_CONSTEXPR14 +#endif + +#if defined(__cpp_lib_bit_cast) && __cpp_lib_bit_cast >= 201806L +#define FASTFLOAT_HAS_BIT_CAST 1 +#else +#define FASTFLOAT_HAS_BIT_CAST 0 +#endif + +#if defined(__cpp_lib_is_constant_evaluated) && \ + __cpp_lib_is_constant_evaluated >= 201811L +#define FASTFLOAT_HAS_IS_CONSTANT_EVALUATED 1 +#else +#define FASTFLOAT_HAS_IS_CONSTANT_EVALUATED 0 +#endif + +#if defined(__cpp_if_constexpr) && __cpp_if_constexpr >= 201606L +#define FASTFLOAT_IF_CONSTEXPR17(x) if constexpr (x) +#else +#define FASTFLOAT_IF_CONSTEXPR17(x) if (x) +#endif + +// Testing for relevant C++20 constexpr library features +#if FASTFLOAT_HAS_IS_CONSTANT_EVALUATED && FASTFLOAT_HAS_BIT_CAST && \ + defined(__cpp_lib_constexpr_algorithms) && \ + __cpp_lib_constexpr_algorithms >= 201806L /*For std::copy and std::fill*/ +#define FASTFLOAT_CONSTEXPR20 constexpr +#define FASTFLOAT_IS_CONSTEXPR 1 +#else +#define FASTFLOAT_CONSTEXPR20 +#define FASTFLOAT_IS_CONSTEXPR 0 +#endif + +#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) +#define FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE 0 +#else +#define FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE 1 +#endif + +#endif // FASTFLOAT_CONSTEXPR_FEATURE_DETECT_H + +#ifndef FASTFLOAT_FLOAT_COMMON_H +#define FASTFLOAT_FLOAT_COMMON_H + +#include +#include +#include +#ifdef __has_include +#if __has_include() && (__cplusplus > 202002L || (defined(_MSVC_LANG) && (_MSVC_LANG > 202002L))) +#include +#endif +#endif + +#define FASTFLOAT_VERSION_MAJOR 8 +#define FASTFLOAT_VERSION_MINOR 0 +#define FASTFLOAT_VERSION_PATCH 2 + +#define FASTFLOAT_STRINGIZE_IMPL(x) #x +#define FASTFLOAT_STRINGIZE(x) FASTFLOAT_STRINGIZE_IMPL(x) + +#define FASTFLOAT_VERSION_STR \ + FASTFLOAT_STRINGIZE(FASTFLOAT_VERSION_MAJOR) \ + "." FASTFLOAT_STRINGIZE(FASTFLOAT_VERSION_MINOR) "." FASTFLOAT_STRINGIZE( \ + FASTFLOAT_VERSION_PATCH) + +#define FASTFLOAT_VERSION \ + (FASTFLOAT_VERSION_MAJOR * 10000 + FASTFLOAT_VERSION_MINOR * 100 + \ + FASTFLOAT_VERSION_PATCH) + +namespace fast_float { + +enum class chars_format : uint64_t; + +namespace detail { +constexpr chars_format basic_json_fmt = chars_format(1 << 5); +constexpr chars_format basic_fortran_fmt = chars_format(1 << 6); +} // namespace detail + +enum class chars_format : uint64_t { + scientific = 1 << 0, + fixed = 1 << 2, + hex = 1 << 3, + no_infnan = 1 << 4, + // RFC 8259: https://datatracker.ietf.org/doc/html/rfc8259#section-6 + json = uint64_t(detail::basic_json_fmt) | fixed | scientific | no_infnan, + // Extension of RFC 8259 where, e.g., "inf" and "nan" are allowed. + json_or_infnan = uint64_t(detail::basic_json_fmt) | fixed | scientific, + fortran = uint64_t(detail::basic_fortran_fmt) | fixed | scientific, + general = fixed | scientific, + allow_leading_plus = 1 << 7, + skip_white_space = 1 << 8, +}; + +template struct from_chars_result_t { + UC const *ptr; + tinyobj_ff::ff_errc ec; +}; + +using from_chars_result = from_chars_result_t; + +template struct parse_options_t { + constexpr explicit parse_options_t(chars_format fmt = chars_format::general, + UC dot = UC('.'), int b = 10) + : format(fmt), decimal_point(dot), base(b) {} + + /** Which number formats are accepted */ + chars_format format; + /** The character used as decimal point */ + UC decimal_point; + /** The base used for integers */ + int base; +}; + +using parse_options = parse_options_t; + +} // namespace fast_float + +#if FASTFLOAT_HAS_BIT_CAST +#include +#endif + +#if (defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \ + defined(__amd64) || defined(__aarch64__) || defined(_M_ARM64) || \ + defined(__MINGW64__) || defined(__s390x__) || \ + (defined(__ppc64__) || defined(__PPC64__) || defined(__ppc64le__) || \ + defined(__PPC64LE__)) || \ + defined(__loongarch64)) +#define FASTFLOAT_64BIT 1 +#elif (defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ + defined(__arm__) || defined(_M_ARM) || defined(__ppc__) || \ + defined(__MINGW32__) || defined(__EMSCRIPTEN__)) +#define FASTFLOAT_32BIT 1 +#else + // Need to check incrementally, since SIZE_MAX is a size_t, avoid overflow. +// We can never tell the register width, but the SIZE_MAX is a good +// approximation. UINTPTR_MAX and INTPTR_MAX are optional, so avoid them for max +// portability. +#if SIZE_MAX == 0xffff +#error Unknown platform (16-bit, unsupported) +#elif SIZE_MAX == 0xffffffff +#define FASTFLOAT_32BIT 1 +#elif SIZE_MAX == 0xffffffffffffffff +#define FASTFLOAT_64BIT 1 +#else +#error Unknown platform (not 32-bit, not 64-bit?) +#endif +#endif + +#if ((defined(_WIN32) || defined(_WIN64)) && !defined(__clang__)) || \ + (defined(_M_ARM64) && !defined(__MINGW32__)) +#include +#endif + +#if defined(_MSC_VER) && !defined(__clang__) +#define FASTFLOAT_VISUAL_STUDIO 1 +#endif + +#if defined __BYTE_ORDER__ && defined __ORDER_BIG_ENDIAN__ +#define FASTFLOAT_IS_BIG_ENDIAN (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) +#elif defined _WIN32 +#define FASTFLOAT_IS_BIG_ENDIAN 0 +#else +#if defined(__APPLE__) || defined(__FreeBSD__) +#include +#elif defined(sun) || defined(__sun) +#include +#elif defined(__MVS__) +#include +#else +#ifdef __has_include +#if __has_include() +#include +#endif //__has_include() +#endif //__has_include +#endif +# +#ifndef __BYTE_ORDER__ +// safe choice +#define FASTFLOAT_IS_BIG_ENDIAN 0 +#endif +# +#ifndef __ORDER_LITTLE_ENDIAN__ +// safe choice +#define FASTFLOAT_IS_BIG_ENDIAN 0 +#endif +# +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +#define FASTFLOAT_IS_BIG_ENDIAN 0 +#else +#define FASTFLOAT_IS_BIG_ENDIAN 1 +#endif +#endif + +#if defined(__SSE2__) || (defined(FASTFLOAT_VISUAL_STUDIO) && \ + (defined(_M_AMD64) || defined(_M_X64) || \ + (defined(_M_IX86_FP) && _M_IX86_FP == 2))) +#define FASTFLOAT_SSE2 1 +#endif + +#if defined(__aarch64__) || defined(_M_ARM64) +#define FASTFLOAT_NEON 1 +#endif + +#if defined(FASTFLOAT_SSE2) || defined(FASTFLOAT_NEON) +#define FASTFLOAT_HAS_SIMD 1 +#endif + +#if defined(__GNUC__) +// disable -Wcast-align=strict (GCC only) +#define FASTFLOAT_SIMD_DISABLE_WARNINGS \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wcast-align\"") +#else +#define FASTFLOAT_SIMD_DISABLE_WARNINGS +#endif + +#if defined(__GNUC__) +#define FASTFLOAT_SIMD_RESTORE_WARNINGS _Pragma("GCC diagnostic pop") +#else +#define FASTFLOAT_SIMD_RESTORE_WARNINGS +#endif + +#ifdef FASTFLOAT_VISUAL_STUDIO +#define fastfloat_really_inline __forceinline +#else +#define fastfloat_really_inline inline __attribute__((always_inline)) +#endif + +#ifndef FASTFLOAT_ASSERT +#define FASTFLOAT_ASSERT(x) \ + { ((void)(x)); } +#endif + +#ifndef FASTFLOAT_DEBUG_ASSERT +#define FASTFLOAT_DEBUG_ASSERT(x) \ + { ((void)(x)); } +#endif + +// rust style `try!()` macro, or `?` operator +#define FASTFLOAT_TRY(x) \ + { \ + if (!(x)) \ + return false; \ + } + +#define FASTFLOAT_ENABLE_IF(...) \ + typename tinyobj_ff::enable_if<(__VA_ARGS__), int>::type + +namespace fast_float { + +fastfloat_really_inline constexpr bool cpp20_and_in_constexpr() { +#if FASTFLOAT_HAS_IS_CONSTANT_EVALUATED + return std::is_constant_evaluated(); +#else + return false; +#endif +} + +template +struct is_supported_float_type + : tinyobj_ff::integral_constant< + bool, tinyobj_ff::is_same::value || tinyobj_ff::is_same::value +#ifdef __STDCPP_FLOAT64_T__ + || tinyobj_ff::is_same::value +#endif +#ifdef __STDCPP_FLOAT32_T__ + || tinyobj_ff::is_same::value +#endif +#ifdef __STDCPP_FLOAT16_T__ + || tinyobj_ff::is_same::value +#endif +#ifdef __STDCPP_BFLOAT16_T__ + || tinyobj_ff::is_same::value +#endif + > { +}; + +template +using equiv_uint_t = typename tinyobj_ff::conditional< + sizeof(T) == 1, uint8_t, + typename tinyobj_ff::conditional< + sizeof(T) == 2, uint16_t, + typename tinyobj_ff::conditional::type>::type>::type; + +template struct is_supported_integer_type : tinyobj_ff::is_integral {}; + +template +struct is_supported_char_type + : tinyobj_ff::integral_constant::value || + tinyobj_ff::is_same::value || + tinyobj_ff::is_same::value || + tinyobj_ff::is_same::value +#ifdef __cpp_char8_t + || tinyobj_ff::is_same::value +#endif + > { +}; + +// Compares two ASCII strings in a case insensitive manner. +template +inline FASTFLOAT_CONSTEXPR14 bool +fastfloat_strncasecmp(UC const *actual_mixedcase, UC const *expected_lowercase, + size_t length) { + for (size_t i = 0; i < length; ++i) { + UC const actual = actual_mixedcase[i]; + if ((actual < 256 ? actual | 32 : actual) != expected_lowercase[i]) { + return false; + } + } + return true; +} + +#ifndef FLT_EVAL_METHOD +#error "FLT_EVAL_METHOD should be defined, please include cfloat." +#endif + +// a pointer and a length to a contiguous block of memory +template struct span { + T const *ptr; + size_t length; + + constexpr span(T const *_ptr, size_t _length) : ptr(_ptr), length(_length) {} + + constexpr span() : ptr(nullptr), length(0) {} + + constexpr size_t len() const noexcept { return length; } + + FASTFLOAT_CONSTEXPR14 const T &operator[](size_t index) const noexcept { + FASTFLOAT_DEBUG_ASSERT(index < length); + return ptr[index]; + } +}; + +struct value128 { + uint64_t low; + uint64_t high; + + constexpr value128(uint64_t _low, uint64_t _high) : low(_low), high(_high) {} + + constexpr value128() : low(0), high(0) {} +}; + +/* Helper C++14 constexpr generic implementation of leading_zeroes */ +fastfloat_really_inline FASTFLOAT_CONSTEXPR14 int +leading_zeroes_generic(uint64_t input_num, int last_bit = 0) { + if (input_num & uint64_t(0xffffffff00000000)) { + input_num >>= 32; + last_bit |= 32; + } + if (input_num & uint64_t(0xffff0000)) { + input_num >>= 16; + last_bit |= 16; + } + if (input_num & uint64_t(0xff00)) { + input_num >>= 8; + last_bit |= 8; + } + if (input_num & uint64_t(0xf0)) { + input_num >>= 4; + last_bit |= 4; + } + if (input_num & uint64_t(0xc)) { + input_num >>= 2; + last_bit |= 2; + } + if (input_num & uint64_t(0x2)) { /* input_num >>= 1; */ + last_bit |= 1; + } + return 63 - last_bit; +} + +/* result might be undefined when input_num is zero */ +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 int +leading_zeroes(uint64_t input_num) { + assert(input_num > 0); + if (cpp20_and_in_constexpr()) { + return leading_zeroes_generic(input_num); + } +#ifdef FASTFLOAT_VISUAL_STUDIO +#if defined(_M_X64) || defined(_M_ARM64) + unsigned long leading_zero = 0; + // Search the mask data from most significant bit (MSB) + // to least significant bit (LSB) for a set bit (1). + _BitScanReverse64(&leading_zero, input_num); + return (int)(63 - leading_zero); +#else + return leading_zeroes_generic(input_num); +#endif +#else + return __builtin_clzll(input_num); +#endif +} + +// slow emulation routine for 32-bit +fastfloat_really_inline constexpr uint64_t emulu(uint32_t x, uint32_t y) { + return x * (uint64_t)y; +} + +fastfloat_really_inline FASTFLOAT_CONSTEXPR14 uint64_t +umul128_generic(uint64_t ab, uint64_t cd, uint64_t *hi) { + uint64_t ad = emulu((uint32_t)(ab >> 32), (uint32_t)cd); + uint64_t bd = emulu((uint32_t)ab, (uint32_t)cd); + uint64_t adbc = ad + emulu((uint32_t)ab, (uint32_t)(cd >> 32)); + uint64_t adbc_carry = (uint64_t)(adbc < ad); + uint64_t lo = bd + (adbc << 32); + *hi = emulu((uint32_t)(ab >> 32), (uint32_t)(cd >> 32)) + (adbc >> 32) + + (adbc_carry << 32) + (uint64_t)(lo < bd); + return lo; +} + +#ifdef FASTFLOAT_32BIT + +// slow emulation routine for 32-bit +#if !defined(__MINGW64__) +fastfloat_really_inline FASTFLOAT_CONSTEXPR14 uint64_t _umul128(uint64_t ab, + uint64_t cd, + uint64_t *hi) { + return umul128_generic(ab, cd, hi); +} +#endif // !__MINGW64__ + +#endif // FASTFLOAT_32BIT + +// compute 64-bit a*b +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 value128 +full_multiplication(uint64_t a, uint64_t b) { + if (cpp20_and_in_constexpr()) { + value128 answer; + answer.low = umul128_generic(a, b, &answer.high); + return answer; + } + value128 answer; +#if defined(_M_ARM64) && !defined(__MINGW32__) + // ARM64 has native support for 64-bit multiplications, no need to emulate + // But MinGW on ARM64 doesn't have native support for 64-bit multiplications + answer.high = __umulh(a, b); + answer.low = a * b; +#elif defined(FASTFLOAT_32BIT) || \ + (defined(_WIN64) && !defined(__clang__) && !defined(_M_ARM64)) + answer.low = _umul128(a, b, &answer.high); // _umul128 not available on ARM64 +#elif defined(FASTFLOAT_64BIT) && defined(__SIZEOF_INT128__) + __uint128_t r = ((__uint128_t)a) * b; + answer.low = uint64_t(r); + answer.high = uint64_t(r >> 64); +#else + answer.low = umul128_generic(a, b, &answer.high); +#endif + return answer; +} + +struct adjusted_mantissa { + uint64_t mantissa{0}; + int32_t power2{0}; // a negative value indicates an invalid result + adjusted_mantissa() = default; + + constexpr bool operator==(adjusted_mantissa const &o) const { + return mantissa == o.mantissa && power2 == o.power2; + } + + constexpr bool operator!=(adjusted_mantissa const &o) const { + return mantissa != o.mantissa || power2 != o.power2; + } +}; + +// Bias so we can get the real exponent with an invalid adjusted_mantissa. +constexpr static int32_t invalid_am_bias = -0x8000; + +// used for binary_format_lookup_tables::max_mantissa +constexpr uint64_t constant_55555 = 5 * 5 * 5 * 5 * 5; + +template struct binary_format_lookup_tables; + +template struct binary_format : binary_format_lookup_tables { + using equiv_uint = equiv_uint_t; + + static constexpr int mantissa_explicit_bits(); + static constexpr int minimum_exponent(); + static constexpr int infinite_power(); + static constexpr int sign_index(); + static constexpr int + min_exponent_fast_path(); // used when fegetround() == FE_TONEAREST + static constexpr int max_exponent_fast_path(); + static constexpr int max_exponent_round_to_even(); + static constexpr int min_exponent_round_to_even(); + static constexpr uint64_t max_mantissa_fast_path(int64_t power); + static constexpr uint64_t + max_mantissa_fast_path(); // used when fegetround() == FE_TONEAREST + static constexpr int largest_power_of_ten(); + static constexpr int smallest_power_of_ten(); + static constexpr T exact_power_of_ten(int64_t power); + static constexpr size_t max_digits(); + static constexpr equiv_uint exponent_mask(); + static constexpr equiv_uint mantissa_mask(); + static constexpr equiv_uint hidden_bit_mask(); +}; + +template struct binary_format_lookup_tables { + static constexpr double powers_of_ten[] = { + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, + 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22}; + + // Largest integer value v so that (5**index * v) <= 1<<53. + // 0x20000000000000 == 1 << 53 + static constexpr uint64_t max_mantissa[] = { + 0x20000000000000, + 0x20000000000000 / 5, + 0x20000000000000 / (5 * 5), + 0x20000000000000 / (5 * 5 * 5), + 0x20000000000000 / (5 * 5 * 5 * 5), + 0x20000000000000 / (constant_55555), + 0x20000000000000 / (constant_55555 * 5), + 0x20000000000000 / (constant_55555 * 5 * 5), + 0x20000000000000 / (constant_55555 * 5 * 5 * 5), + 0x20000000000000 / (constant_55555 * 5 * 5 * 5 * 5), + 0x20000000000000 / (constant_55555 * constant_55555), + 0x20000000000000 / (constant_55555 * constant_55555 * 5), + 0x20000000000000 / (constant_55555 * constant_55555 * 5 * 5), + 0x20000000000000 / (constant_55555 * constant_55555 * 5 * 5 * 5), + 0x20000000000000 / (constant_55555 * constant_55555 * constant_55555), + 0x20000000000000 / (constant_55555 * constant_55555 * constant_55555 * 5), + 0x20000000000000 / + (constant_55555 * constant_55555 * constant_55555 * 5 * 5), + 0x20000000000000 / + (constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5), + 0x20000000000000 / + (constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5 * 5), + 0x20000000000000 / + (constant_55555 * constant_55555 * constant_55555 * constant_55555), + 0x20000000000000 / (constant_55555 * constant_55555 * constant_55555 * + constant_55555 * 5), + 0x20000000000000 / (constant_55555 * constant_55555 * constant_55555 * + constant_55555 * 5 * 5), + 0x20000000000000 / (constant_55555 * constant_55555 * constant_55555 * + constant_55555 * 5 * 5 * 5), + 0x20000000000000 / (constant_55555 * constant_55555 * constant_55555 * + constant_55555 * 5 * 5 * 5 * 5)}; +}; + +#if FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE + +template +constexpr double binary_format_lookup_tables::powers_of_ten[]; + +template +constexpr uint64_t binary_format_lookup_tables::max_mantissa[]; + +#endif + +template struct binary_format_lookup_tables { + static constexpr float powers_of_ten[] = {1e0f, 1e1f, 1e2f, 1e3f, 1e4f, 1e5f, + 1e6f, 1e7f, 1e8f, 1e9f, 1e10f}; + + // Largest integer value v so that (5**index * v) <= 1<<24. + // 0x1000000 == 1<<24 + static constexpr uint64_t max_mantissa[] = { + 0x1000000, + 0x1000000 / 5, + 0x1000000 / (5 * 5), + 0x1000000 / (5 * 5 * 5), + 0x1000000 / (5 * 5 * 5 * 5), + 0x1000000 / (constant_55555), + 0x1000000 / (constant_55555 * 5), + 0x1000000 / (constant_55555 * 5 * 5), + 0x1000000 / (constant_55555 * 5 * 5 * 5), + 0x1000000 / (constant_55555 * 5 * 5 * 5 * 5), + 0x1000000 / (constant_55555 * constant_55555), + 0x1000000 / (constant_55555 * constant_55555 * 5)}; +}; + +#if FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE + +template +constexpr float binary_format_lookup_tables::powers_of_ten[]; + +template +constexpr uint64_t binary_format_lookup_tables::max_mantissa[]; + +#endif + +template <> +inline constexpr int binary_format::min_exponent_fast_path() { +#if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0) + return 0; +#else + return -22; +#endif +} + +template <> +inline constexpr int binary_format::min_exponent_fast_path() { +#if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0) + return 0; +#else + return -10; +#endif +} + +template <> +inline constexpr int binary_format::mantissa_explicit_bits() { + return 52; +} + +template <> +inline constexpr int binary_format::mantissa_explicit_bits() { + return 23; +} + +template <> +inline constexpr int binary_format::max_exponent_round_to_even() { + return 23; +} + +template <> +inline constexpr int binary_format::max_exponent_round_to_even() { + return 10; +} + +template <> +inline constexpr int binary_format::min_exponent_round_to_even() { + return -4; +} + +template <> +inline constexpr int binary_format::min_exponent_round_to_even() { + return -17; +} + +template <> inline constexpr int binary_format::minimum_exponent() { + return -1023; +} + +template <> inline constexpr int binary_format::minimum_exponent() { + return -127; +} + +template <> inline constexpr int binary_format::infinite_power() { + return 0x7FF; +} + +template <> inline constexpr int binary_format::infinite_power() { + return 0xFF; +} + +template <> inline constexpr int binary_format::sign_index() { + return 63; +} + +template <> inline constexpr int binary_format::sign_index() { + return 31; +} + +template <> +inline constexpr int binary_format::max_exponent_fast_path() { + return 22; +} + +template <> +inline constexpr int binary_format::max_exponent_fast_path() { + return 10; +} + +template <> +inline constexpr uint64_t binary_format::max_mantissa_fast_path() { + return uint64_t(2) << mantissa_explicit_bits(); +} + +template <> +inline constexpr uint64_t binary_format::max_mantissa_fast_path() { + return uint64_t(2) << mantissa_explicit_bits(); +} + +// credit: Jakub Jelínek +#ifdef __STDCPP_FLOAT16_T__ +template struct binary_format_lookup_tables { + static constexpr std::float16_t powers_of_ten[] = {1e0f16, 1e1f16, 1e2f16, + 1e3f16, 1e4f16}; + + // Largest integer value v so that (5**index * v) <= 1<<11. + // 0x800 == 1<<11 + static constexpr uint64_t max_mantissa[] = {0x800, + 0x800 / 5, + 0x800 / (5 * 5), + 0x800 / (5 * 5 * 5), + 0x800 / (5 * 5 * 5 * 5), + 0x800 / (constant_55555)}; +}; + +#if FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE + +template +constexpr std::float16_t + binary_format_lookup_tables::powers_of_ten[]; + +template +constexpr uint64_t + binary_format_lookup_tables::max_mantissa[]; + +#endif + +template <> +inline constexpr std::float16_t +binary_format::exact_power_of_ten(int64_t power) { + // Work around clang bug https://godbolt.org/z/zedh7rrhc + return (void)powers_of_ten[0], powers_of_ten[power]; +} + +template <> +inline constexpr binary_format::equiv_uint +binary_format::exponent_mask() { + return 0x7C00; +} + +template <> +inline constexpr binary_format::equiv_uint +binary_format::mantissa_mask() { + return 0x03FF; +} + +template <> +inline constexpr binary_format::equiv_uint +binary_format::hidden_bit_mask() { + return 0x0400; +} + +template <> +inline constexpr int binary_format::max_exponent_fast_path() { + return 4; +} + +template <> +inline constexpr int binary_format::mantissa_explicit_bits() { + return 10; +} + +template <> +inline constexpr uint64_t +binary_format::max_mantissa_fast_path() { + return uint64_t(2) << mantissa_explicit_bits(); +} + +template <> +inline constexpr uint64_t +binary_format::max_mantissa_fast_path(int64_t power) { + // caller is responsible to ensure that + // power >= 0 && power <= 4 + // + // Work around clang bug https://godbolt.org/z/zedh7rrhc + return (void)max_mantissa[0], max_mantissa[power]; +} + +template <> +inline constexpr int binary_format::min_exponent_fast_path() { + return 0; +} + +template <> +inline constexpr int +binary_format::max_exponent_round_to_even() { + return 5; +} + +template <> +inline constexpr int +binary_format::min_exponent_round_to_even() { + return -22; +} + +template <> +inline constexpr int binary_format::minimum_exponent() { + return -15; +} + +template <> +inline constexpr int binary_format::infinite_power() { + return 0x1F; +} + +template <> inline constexpr int binary_format::sign_index() { + return 15; +} + +template <> +inline constexpr int binary_format::largest_power_of_ten() { + return 4; +} + +template <> +inline constexpr int binary_format::smallest_power_of_ten() { + return -27; +} + +template <> +inline constexpr size_t binary_format::max_digits() { + return 22; +} +#endif // __STDCPP_FLOAT16_T__ + +// credit: Jakub Jelínek +#ifdef __STDCPP_BFLOAT16_T__ +template struct binary_format_lookup_tables { + static constexpr std::bfloat16_t powers_of_ten[] = {1e0bf16, 1e1bf16, 1e2bf16, + 1e3bf16}; + + // Largest integer value v so that (5**index * v) <= 1<<8. + // 0x100 == 1<<8 + static constexpr uint64_t max_mantissa[] = {0x100, 0x100 / 5, 0x100 / (5 * 5), + 0x100 / (5 * 5 * 5), + 0x100 / (5 * 5 * 5 * 5)}; +}; + +#if FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE + +template +constexpr std::bfloat16_t + binary_format_lookup_tables::powers_of_ten[]; + +template +constexpr uint64_t + binary_format_lookup_tables::max_mantissa[]; + +#endif + +template <> +inline constexpr std::bfloat16_t +binary_format::exact_power_of_ten(int64_t power) { + // Work around clang bug https://godbolt.org/z/zedh7rrhc + return (void)powers_of_ten[0], powers_of_ten[power]; +} + +template <> +inline constexpr int binary_format::max_exponent_fast_path() { + return 3; +} + +template <> +inline constexpr binary_format::equiv_uint +binary_format::exponent_mask() { + return 0x7F80; +} + +template <> +inline constexpr binary_format::equiv_uint +binary_format::mantissa_mask() { + return 0x007F; +} + +template <> +inline constexpr binary_format::equiv_uint +binary_format::hidden_bit_mask() { + return 0x0080; +} + +template <> +inline constexpr int binary_format::mantissa_explicit_bits() { + return 7; +} + +template <> +inline constexpr uint64_t +binary_format::max_mantissa_fast_path() { + return uint64_t(2) << mantissa_explicit_bits(); +} + +template <> +inline constexpr uint64_t +binary_format::max_mantissa_fast_path(int64_t power) { + // caller is responsible to ensure that + // power >= 0 && power <= 3 + // + // Work around clang bug https://godbolt.org/z/zedh7rrhc + return (void)max_mantissa[0], max_mantissa[power]; +} + +template <> +inline constexpr int binary_format::min_exponent_fast_path() { + return 0; +} + +template <> +inline constexpr int +binary_format::max_exponent_round_to_even() { + return 3; +} + +template <> +inline constexpr int +binary_format::min_exponent_round_to_even() { + return -24; +} + +template <> +inline constexpr int binary_format::minimum_exponent() { + return -127; +} + +template <> +inline constexpr int binary_format::infinite_power() { + return 0xFF; +} + +template <> inline constexpr int binary_format::sign_index() { + return 15; +} + +template <> +inline constexpr int binary_format::largest_power_of_ten() { + return 38; +} + +template <> +inline constexpr int binary_format::smallest_power_of_ten() { + return -60; +} + +template <> +inline constexpr size_t binary_format::max_digits() { + return 98; +} +#endif // __STDCPP_BFLOAT16_T__ + +template <> +inline constexpr uint64_t +binary_format::max_mantissa_fast_path(int64_t power) { + // caller is responsible to ensure that + // power >= 0 && power <= 22 + // + // Work around clang bug https://godbolt.org/z/zedh7rrhc + return (void)max_mantissa[0], max_mantissa[power]; +} + +template <> +inline constexpr uint64_t +binary_format::max_mantissa_fast_path(int64_t power) { + // caller is responsible to ensure that + // power >= 0 && power <= 10 + // + // Work around clang bug https://godbolt.org/z/zedh7rrhc + return (void)max_mantissa[0], max_mantissa[power]; +} + +template <> +inline constexpr double +binary_format::exact_power_of_ten(int64_t power) { + // Work around clang bug https://godbolt.org/z/zedh7rrhc + return (void)powers_of_ten[0], powers_of_ten[power]; +} + +template <> +inline constexpr float binary_format::exact_power_of_ten(int64_t power) { + // Work around clang bug https://godbolt.org/z/zedh7rrhc + return (void)powers_of_ten[0], powers_of_ten[power]; +} + +template <> inline constexpr int binary_format::largest_power_of_ten() { + return 308; +} + +template <> inline constexpr int binary_format::largest_power_of_ten() { + return 38; +} + +template <> +inline constexpr int binary_format::smallest_power_of_ten() { + return -342; +} + +template <> inline constexpr int binary_format::smallest_power_of_ten() { + return -64; +} + +template <> inline constexpr size_t binary_format::max_digits() { + return 769; +} + +template <> inline constexpr size_t binary_format::max_digits() { + return 114; +} + +template <> +inline constexpr binary_format::equiv_uint +binary_format::exponent_mask() { + return 0x7F800000; +} + +template <> +inline constexpr binary_format::equiv_uint +binary_format::exponent_mask() { + return 0x7FF0000000000000; +} + +template <> +inline constexpr binary_format::equiv_uint +binary_format::mantissa_mask() { + return 0x007FFFFF; +} + +template <> +inline constexpr binary_format::equiv_uint +binary_format::mantissa_mask() { + return 0x000FFFFFFFFFFFFF; +} + +template <> +inline constexpr binary_format::equiv_uint +binary_format::hidden_bit_mask() { + return 0x00800000; +} + +template <> +inline constexpr binary_format::equiv_uint +binary_format::hidden_bit_mask() { + return 0x0010000000000000; +} + +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void +to_float(bool negative, adjusted_mantissa am, T &value) { + using equiv_uint = equiv_uint_t; + equiv_uint word = equiv_uint(am.mantissa); + word = equiv_uint(word | equiv_uint(am.power2) + << binary_format::mantissa_explicit_bits()); + word = + equiv_uint(word | equiv_uint(negative) << binary_format::sign_index()); +#if FASTFLOAT_HAS_BIT_CAST + value = std::bit_cast(word); +#else + ::memcpy(&value, &word, sizeof(T)); +#endif +} + +template struct space_lut { + static constexpr bool value[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +}; + +#if FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE + +template constexpr bool space_lut::value[]; + +#endif + +template constexpr bool is_space(UC c) { + return c < 256 && space_lut<>::value[uint8_t(c)]; +} + +template static constexpr uint64_t int_cmp_zeros() { + static_assert((sizeof(UC) == 1) || (sizeof(UC) == 2) || (sizeof(UC) == 4), + "Unsupported character size"); + return (sizeof(UC) == 1) ? 0x3030303030303030 + : (sizeof(UC) == 2) + ? (uint64_t(UC('0')) << 48 | uint64_t(UC('0')) << 32 | + uint64_t(UC('0')) << 16 | UC('0')) + : (uint64_t(UC('0')) << 32 | UC('0')); +} + +template static constexpr int int_cmp_len() { + return sizeof(uint64_t) / sizeof(UC); +} + +template constexpr UC const *str_const_nan(); + +template <> constexpr char const *str_const_nan() { return "nan"; } + +template <> constexpr wchar_t const *str_const_nan() { return L"nan"; } + +template <> constexpr char16_t const *str_const_nan() { + return u"nan"; +} + +template <> constexpr char32_t const *str_const_nan() { + return U"nan"; +} + +#ifdef __cpp_char8_t +template <> constexpr char8_t const *str_const_nan() { + return u8"nan"; +} +#endif + +template constexpr UC const *str_const_inf(); + +template <> constexpr char const *str_const_inf() { return "infinity"; } + +template <> constexpr wchar_t const *str_const_inf() { + return L"infinity"; +} + +template <> constexpr char16_t const *str_const_inf() { + return u"infinity"; +} + +template <> constexpr char32_t const *str_const_inf() { + return U"infinity"; +} + +#ifdef __cpp_char8_t +template <> constexpr char8_t const *str_const_inf() { + return u8"infinity"; +} +#endif + +template struct int_luts { + static constexpr uint8_t chdigit[] = { + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, + 255, 255, 255, 255, 255, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 255, 255, 255, 255, 255, 255, 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255}; + + static constexpr size_t maxdigits_u64[] = { + 64, 41, 32, 28, 25, 23, 22, 21, 20, 19, 18, 18, 17, 17, 16, 16, 16, 16, + 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13}; + + static constexpr uint64_t min_safe_u64[] = { + 9223372036854775808ull, 12157665459056928801ull, 4611686018427387904, + 7450580596923828125, 4738381338321616896, 3909821048582988049, + 9223372036854775808ull, 12157665459056928801ull, 10000000000000000000ull, + 5559917313492231481, 2218611106740436992, 8650415919381337933, + 2177953337809371136, 6568408355712890625, 1152921504606846976, + 2862423051509815793, 6746640616477458432, 15181127029874798299ull, + 1638400000000000000, 3243919932521508681, 6221821273427820544, + 11592836324538749809ull, 876488338465357824, 1490116119384765625, + 2481152873203736576, 4052555153018976267, 6502111422497947648, + 10260628712958602189ull, 15943230000000000000ull, 787662783788549761, + 1152921504606846976, 1667889514952984961, 2386420683693101056, + 3379220508056640625, 4738381338321616896}; +}; + +#if FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE + +template constexpr uint8_t int_luts::chdigit[]; + +template constexpr size_t int_luts::maxdigits_u64[]; + +template constexpr uint64_t int_luts::min_safe_u64[]; + +#endif + +template +fastfloat_really_inline constexpr uint8_t ch_to_digit(UC c) { + return int_luts<>::chdigit[static_cast(c)]; +} + +fastfloat_really_inline constexpr size_t max_digits_u64(int base) { + return int_luts<>::maxdigits_u64[base - 2]; +} + +// If a u64 is exactly max_digits_u64() in length, this is +// the value below which it has definitely overflowed. +fastfloat_really_inline constexpr uint64_t min_safe_u64(int base) { + return int_luts<>::min_safe_u64[base - 2]; +} + +static_assert(tinyobj_ff::is_same, uint64_t>::value, + "equiv_uint should be uint64_t for double"); +static_assert(std::numeric_limits::is_iec559, + "double must fulfill the requirements of IEC 559 (IEEE 754)"); + +static_assert(tinyobj_ff::is_same, uint32_t>::value, + "equiv_uint should be uint32_t for float"); +static_assert(std::numeric_limits::is_iec559, + "float must fulfill the requirements of IEC 559 (IEEE 754)"); + +#ifdef __STDCPP_FLOAT64_T__ +static_assert(tinyobj_ff::is_same, uint64_t>::value, + "equiv_uint should be uint64_t for std::float64_t"); +static_assert( + std::numeric_limits::is_iec559, + "std::float64_t must fulfill the requirements of IEC 559 (IEEE 754)"); +#endif // __STDCPP_FLOAT64_T__ + +#ifdef __STDCPP_FLOAT32_T__ +static_assert(tinyobj_ff::is_same, uint32_t>::value, + "equiv_uint should be uint32_t for std::float32_t"); +static_assert( + std::numeric_limits::is_iec559, + "std::float32_t must fulfill the requirements of IEC 559 (IEEE 754)"); +#endif // __STDCPP_FLOAT32_T__ + +#ifdef __STDCPP_FLOAT16_T__ +static_assert( + tinyobj_ff::is_same::equiv_uint, uint16_t>::value, + "equiv_uint should be uint16_t for std::float16_t"); +static_assert( + std::numeric_limits::is_iec559, + "std::float16_t must fulfill the requirements of IEC 559 (IEEE 754)"); +#endif // __STDCPP_FLOAT16_T__ + +#ifdef __STDCPP_BFLOAT16_T__ +static_assert( + tinyobj_ff::is_same::equiv_uint, uint16_t>::value, + "equiv_uint should be uint16_t for std::bfloat16_t"); +static_assert( + std::numeric_limits::is_iec559, + "std::bfloat16_t must fulfill the requirements of IEC 559 (IEEE 754)"); +#endif // __STDCPP_BFLOAT16_T__ + +constexpr chars_format operator~(chars_format rhs) noexcept { + using int_type = tinyobj_ff::underlying_type::type; + return static_cast(~static_cast(rhs)); +} + +constexpr chars_format operator&(chars_format lhs, chars_format rhs) noexcept { + using int_type = tinyobj_ff::underlying_type::type; + return static_cast(static_cast(lhs) & + static_cast(rhs)); +} + +constexpr chars_format operator|(chars_format lhs, chars_format rhs) noexcept { + using int_type = tinyobj_ff::underlying_type::type; + return static_cast(static_cast(lhs) | + static_cast(rhs)); +} + +constexpr chars_format operator^(chars_format lhs, chars_format rhs) noexcept { + using int_type = tinyobj_ff::underlying_type::type; + return static_cast(static_cast(lhs) ^ + static_cast(rhs)); +} + +fastfloat_really_inline FASTFLOAT_CONSTEXPR14 chars_format & +operator&=(chars_format &lhs, chars_format rhs) noexcept { + return lhs = (lhs & rhs); +} + +fastfloat_really_inline FASTFLOAT_CONSTEXPR14 chars_format & +operator|=(chars_format &lhs, chars_format rhs) noexcept { + return lhs = (lhs | rhs); +} + +fastfloat_really_inline FASTFLOAT_CONSTEXPR14 chars_format & +operator^=(chars_format &lhs, chars_format rhs) noexcept { + return lhs = (lhs ^ rhs); +} + +namespace detail { +// adjust for deprecated feature macros +constexpr chars_format adjust_for_feature_macros(chars_format fmt) { + return fmt +#ifdef FASTFLOAT_ALLOWS_LEADING_PLUS + | chars_format::allow_leading_plus +#endif +#ifdef FASTFLOAT_SKIP_WHITE_SPACE + | chars_format::skip_white_space +#endif + ; +} +} // namespace detail + +} // namespace fast_float + +#endif + + +#ifndef FASTFLOAT_FAST_FLOAT_H +#define FASTFLOAT_FAST_FLOAT_H + + +namespace fast_float { +/** + * This function parses the character sequence [first,last) for a number. It + * parses floating-point numbers expecting a locale-indepent format equivalent + * to what is used by std::strtod in the default ("C") locale. The resulting + * floating-point value is the closest floating-point values (using either float + * or double), using the "round to even" convention for values that would + * otherwise fall right in-between two values. That is, we provide exact parsing + * according to the IEEE standard. + * + * Given a successful parse, the pointer (`ptr`) in the returned value is set to + * point right after the parsed number, and the `value` referenced is set to the + * parsed value. In case of error, the returned `ec` contains a representative + * error, otherwise the default (`tinyobj_ff::ff_errc()`) value is stored. + * + * The implementation does not throw and does not allocate memory (e.g., with + * `new` or `malloc`). + * + * Like the C++17 standard, the `fast_float::from_chars` functions take an + * optional last argument of the type `fast_float::chars_format`. It is a bitset + * value: we check whether `fmt & fast_float::chars_format::fixed` and `fmt & + * fast_float::chars_format::scientific` are set to determine whether we allow + * the fixed point and scientific notation respectively. The default is + * `fast_float::chars_format::general` which allows both `fixed` and + * `scientific`. + */ +template ::value)> +FASTFLOAT_CONSTEXPR20 from_chars_result_t +from_chars(UC const *first, UC const *last, T &value, + chars_format fmt = chars_format::general) noexcept; + +/** + * Like from_chars, but accepts an `options` argument to govern number parsing. + * Both for floating-point types and integer types. + */ +template +FASTFLOAT_CONSTEXPR20 from_chars_result_t +from_chars_advanced(UC const *first, UC const *last, T &value, + parse_options_t options) noexcept; + +/** + * from_chars for integer types. + */ +template ::value)> +FASTFLOAT_CONSTEXPR20 from_chars_result_t +from_chars(UC const *first, UC const *last, T &value, int base = 10) noexcept; + +} // namespace fast_float + +#endif // FASTFLOAT_FAST_FLOAT_H + +#ifndef FASTFLOAT_ASCII_NUMBER_H +#define FASTFLOAT_ASCII_NUMBER_H + +#include +#include +#include + + +#ifdef FASTFLOAT_SSE2 +#include +#endif + +#ifdef FASTFLOAT_NEON +#include +#endif + +namespace fast_float { + +template fastfloat_really_inline constexpr bool has_simd_opt() { +#ifdef FASTFLOAT_HAS_SIMD + return tinyobj_ff::is_same::value; +#else + return false; +#endif +} + +// Next function can be micro-optimized, but compilers are entirely +// able to optimize it well. +template +fastfloat_really_inline constexpr bool is_integer(UC c) noexcept { + return !(c > UC('9') || c < UC('0')); +} + +fastfloat_really_inline constexpr uint64_t byteswap(uint64_t val) { + return (val & 0xFF00000000000000) >> 56 | (val & 0x00FF000000000000) >> 40 | + (val & 0x0000FF0000000000) >> 24 | (val & 0x000000FF00000000) >> 8 | + (val & 0x00000000FF000000) << 8 | (val & 0x0000000000FF0000) << 24 | + (val & 0x000000000000FF00) << 40 | (val & 0x00000000000000FF) << 56; +} + +// Read 8 UC into a u64. Truncates UC if not char. +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 uint64_t +read8_to_u64(UC const *chars) { + if (cpp20_and_in_constexpr() || !tinyobj_ff::is_same::value) { + uint64_t val = 0; + for (int i = 0; i < 8; ++i) { + val |= uint64_t(uint8_t(*chars)) << (i * 8); + ++chars; + } + return val; + } + uint64_t val; + ::memcpy(&val, chars, sizeof(uint64_t)); +#if FASTFLOAT_IS_BIG_ENDIAN == 1 + // Need to read as-if the number was in little-endian order. + val = byteswap(val); +#endif + return val; +} + +#ifdef FASTFLOAT_SSE2 + +fastfloat_really_inline uint64_t simd_read8_to_u64(__m128i const data) { + FASTFLOAT_SIMD_DISABLE_WARNINGS + __m128i const packed = _mm_packus_epi16(data, data); +#ifdef FASTFLOAT_64BIT + return uint64_t(_mm_cvtsi128_si64(packed)); +#else + uint64_t value; + // Visual Studio + older versions of GCC don't support _mm_storeu_si64 + _mm_storel_epi64(reinterpret_cast<__m128i *>(&value), packed); + return value; +#endif + FASTFLOAT_SIMD_RESTORE_WARNINGS +} + +fastfloat_really_inline uint64_t simd_read8_to_u64(char16_t const *chars) { + FASTFLOAT_SIMD_DISABLE_WARNINGS + return simd_read8_to_u64( + _mm_loadu_si128(reinterpret_cast<__m128i const *>(chars))); + FASTFLOAT_SIMD_RESTORE_WARNINGS +} + +#elif defined(FASTFLOAT_NEON) + +fastfloat_really_inline uint64_t simd_read8_to_u64(uint16x8_t const data) { + FASTFLOAT_SIMD_DISABLE_WARNINGS + uint8x8_t utf8_packed = vmovn_u16(data); + return vget_lane_u64(vreinterpret_u64_u8(utf8_packed), 0); + FASTFLOAT_SIMD_RESTORE_WARNINGS +} + +fastfloat_really_inline uint64_t simd_read8_to_u64(char16_t const *chars) { + FASTFLOAT_SIMD_DISABLE_WARNINGS + return simd_read8_to_u64( + vld1q_u16(reinterpret_cast(chars))); + FASTFLOAT_SIMD_RESTORE_WARNINGS +} + +#endif // FASTFLOAT_SSE2 + +// MSVC SFINAE is broken pre-VS2017 +#if defined(_MSC_VER) && _MSC_VER <= 1900 +template +#else +template ()) = 0> +#endif +// dummy for compile +uint64_t simd_read8_to_u64(UC const *) { + return 0; +} + +// credit @aqrit +fastfloat_really_inline FASTFLOAT_CONSTEXPR14 uint32_t +parse_eight_digits_unrolled(uint64_t val) { + uint64_t const mask = 0x000000FF000000FF; + uint64_t const mul1 = 0x000F424000000064; // 100 + (1000000ULL << 32) + uint64_t const mul2 = 0x0000271000000001; // 1 + (10000ULL << 32) + val -= 0x3030303030303030; + val = (val * 10) + (val >> 8); // val = (val * 2561) >> 8; + val = (((val & mask) * mul1) + (((val >> 16) & mask) * mul2)) >> 32; + return uint32_t(val); +} + +// Call this if chars are definitely 8 digits. +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 uint32_t +parse_eight_digits_unrolled(UC const *chars) noexcept { + if (cpp20_and_in_constexpr() || !has_simd_opt()) { + return parse_eight_digits_unrolled(read8_to_u64(chars)); // truncation okay + } + return parse_eight_digits_unrolled(simd_read8_to_u64(chars)); +} + +// credit @aqrit +fastfloat_really_inline constexpr bool +is_made_of_eight_digits_fast(uint64_t val) noexcept { + return !((((val + 0x4646464646464646) | (val - 0x3030303030303030)) & + 0x8080808080808080)); +} + +#ifdef FASTFLOAT_HAS_SIMD + +// Call this if chars might not be 8 digits. +// Using this style (instead of is_made_of_eight_digits_fast() then +// parse_eight_digits_unrolled()) ensures we don't load SIMD registers twice. +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 bool +simd_parse_if_eight_digits_unrolled(char16_t const *chars, + uint64_t &i) noexcept { + if (cpp20_and_in_constexpr()) { + return false; + } +#ifdef FASTFLOAT_SSE2 + FASTFLOAT_SIMD_DISABLE_WARNINGS + __m128i const data = + _mm_loadu_si128(reinterpret_cast<__m128i const *>(chars)); + + // (x - '0') <= 9 + // http://0x80.pl/articles/simd-parsing-int-sequences.html + __m128i const t0 = _mm_add_epi16(data, _mm_set1_epi16(32720)); + __m128i const t1 = _mm_cmpgt_epi16(t0, _mm_set1_epi16(-32759)); + + if (_mm_movemask_epi8(t1) == 0) { + i = i * 100000000 + parse_eight_digits_unrolled(simd_read8_to_u64(data)); + return true; + } else + return false; + FASTFLOAT_SIMD_RESTORE_WARNINGS +#elif defined(FASTFLOAT_NEON) + FASTFLOAT_SIMD_DISABLE_WARNINGS + uint16x8_t const data = vld1q_u16(reinterpret_cast(chars)); + + // (x - '0') <= 9 + // http://0x80.pl/articles/simd-parsing-int-sequences.html + uint16x8_t const t0 = vsubq_u16(data, vmovq_n_u16('0')); + uint16x8_t const mask = vcltq_u16(t0, vmovq_n_u16('9' - '0' + 1)); + + if (vminvq_u16(mask) == 0xFFFF) { + i = i * 100000000 + parse_eight_digits_unrolled(simd_read8_to_u64(data)); + return true; + } else + return false; + FASTFLOAT_SIMD_RESTORE_WARNINGS +#else + (void)chars; + (void)i; + return false; +#endif // FASTFLOAT_SSE2 +} + +#endif // FASTFLOAT_HAS_SIMD + +// MSVC SFINAE is broken pre-VS2017 +#if defined(_MSC_VER) && _MSC_VER <= 1900 +template +#else +template ()) = 0> +#endif +// dummy for compile +bool simd_parse_if_eight_digits_unrolled(UC const *, uint64_t &) { + return 0; +} + +template ::value) = 0> +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void +loop_parse_if_eight_digits(UC const *&p, UC const *const pend, uint64_t &i) { + if (!has_simd_opt()) { + return; + } + while ((tinyobj_ff::distance(p, pend) >= 8) && + simd_parse_if_eight_digits_unrolled( + p, i)) { // in rare cases, this will overflow, but that's ok + p += 8; + } +} + +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void +loop_parse_if_eight_digits(char const *&p, char const *const pend, + uint64_t &i) { + // optimizes better than parse_if_eight_digits_unrolled() for UC = char. + while ((tinyobj_ff::distance(p, pend) >= 8) && + is_made_of_eight_digits_fast(read8_to_u64(p))) { + i = i * 100000000 + + parse_eight_digits_unrolled(read8_to_u64( + p)); // in rare cases, this will overflow, but that's ok + p += 8; + } +} + +enum class parse_error { + no_error, + // [JSON-only] The minus sign must be followed by an integer. + missing_integer_after_sign, + // A sign must be followed by an integer or dot. + missing_integer_or_dot_after_sign, + // [JSON-only] The integer part must not have leading zeros. + leading_zeros_in_integer_part, + // [JSON-only] The integer part must have at least one digit. + no_digits_in_integer_part, + // [JSON-only] If there is a decimal point, there must be digits in the + // fractional part. + no_digits_in_fractional_part, + // The mantissa must have at least one digit. + no_digits_in_mantissa, + // Scientific notation requires an exponential part. + missing_exponential_part, +}; + +template struct parsed_number_string_t { + int64_t exponent{0}; + uint64_t mantissa{0}; + UC const *lastmatch{nullptr}; + bool negative{false}; + bool valid{false}; + bool too_many_digits{false}; + // contains the range of the significant digits + span integer{}; // non-nullable + span fraction{}; // nullable + parse_error error{parse_error::no_error}; +}; + +using byte_span = span; +using parsed_number_string = parsed_number_string_t; + +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 parsed_number_string_t +report_parse_error(UC const *p, parse_error error) { + parsed_number_string_t answer; + answer.valid = false; + answer.lastmatch = p; + answer.error = error; + return answer; +} + +// Assuming that you use no more than 19 digits, this will +// parse an ASCII string. +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 parsed_number_string_t +parse_number_string(UC const *p, UC const *pend, + parse_options_t options) noexcept { + chars_format const fmt = detail::adjust_for_feature_macros(options.format); + UC const decimal_point = options.decimal_point; + + parsed_number_string_t answer; + answer.valid = false; + answer.too_many_digits = false; + // assume p < pend, so dereference without checks; + answer.negative = (*p == UC('-')); + // C++17 20.19.3.(7.1) explicitly forbids '+' sign here + if ((*p == UC('-')) || (uint64_t(fmt & chars_format::allow_leading_plus) && + !basic_json_fmt && *p == UC('+'))) { + ++p; + if (p == pend) { + return report_parse_error( + p, parse_error::missing_integer_or_dot_after_sign); + } + FASTFLOAT_IF_CONSTEXPR17(basic_json_fmt) { + if (!is_integer(*p)) { // a sign must be followed by an integer + return report_parse_error(p, + parse_error::missing_integer_after_sign); + } + } + else { + if (!is_integer(*p) && + (*p != + decimal_point)) { // a sign must be followed by an integer or the dot + return report_parse_error( + p, parse_error::missing_integer_or_dot_after_sign); + } + } + } + UC const *const start_digits = p; + + uint64_t i = 0; // an unsigned int avoids signed overflows (which are bad) + + while ((p != pend) && is_integer(*p)) { + // a multiplication by 10 is cheaper than an arbitrary integer + // multiplication + i = 10 * i + + uint64_t(*p - + UC('0')); // might overflow, we will handle the overflow later + ++p; + } + UC const *const end_of_integer_part = p; + int64_t digit_count = int64_t(end_of_integer_part - start_digits); + answer.integer = span(start_digits, size_t(digit_count)); + FASTFLOAT_IF_CONSTEXPR17(basic_json_fmt) { + // at least 1 digit in integer part, without leading zeros + if (digit_count == 0) { + return report_parse_error(p, parse_error::no_digits_in_integer_part); + } + if ((start_digits[0] == UC('0') && digit_count > 1)) { + return report_parse_error(start_digits, + parse_error::leading_zeros_in_integer_part); + } + } + + int64_t exponent = 0; + bool const has_decimal_point = (p != pend) && (*p == decimal_point); + if (has_decimal_point) { + ++p; + UC const *before = p; + // can occur at most twice without overflowing, but let it occur more, since + // for integers with many digits, digit parsing is the primary bottleneck. + loop_parse_if_eight_digits(p, pend, i); + + while ((p != pend) && is_integer(*p)) { + uint8_t digit = uint8_t(*p - UC('0')); + ++p; + i = i * 10 + digit; // in rare cases, this will overflow, but that's ok + } + exponent = before - p; + answer.fraction = span(before, size_t(p - before)); + digit_count -= exponent; + } + FASTFLOAT_IF_CONSTEXPR17(basic_json_fmt) { + // at least 1 digit in fractional part + if (has_decimal_point && exponent == 0) { + return report_parse_error(p, + parse_error::no_digits_in_fractional_part); + } + } + else if (digit_count == 0) { // we must have encountered at least one integer! + return report_parse_error(p, parse_error::no_digits_in_mantissa); + } + int64_t exp_number = 0; // explicit exponential part + if ((uint64_t(fmt & chars_format::scientific) && (p != pend) && + ((UC('e') == *p) || (UC('E') == *p))) || + (uint64_t(fmt & detail::basic_fortran_fmt) && (p != pend) && + ((UC('+') == *p) || (UC('-') == *p) || (UC('d') == *p) || + (UC('D') == *p)))) { + UC const *location_of_e = p; + if ((UC('e') == *p) || (UC('E') == *p) || (UC('d') == *p) || + (UC('D') == *p)) { + ++p; + } + bool neg_exp = false; + if ((p != pend) && (UC('-') == *p)) { + neg_exp = true; + ++p; + } else if ((p != pend) && + (UC('+') == + *p)) { // '+' on exponent is allowed by C++17 20.19.3.(7.1) + ++p; + } + if ((p == pend) || !is_integer(*p)) { + if (!uint64_t(fmt & chars_format::fixed)) { + // The exponential part is invalid for scientific notation, so it must + // be a trailing token for fixed notation. However, fixed notation is + // disabled, so report a scientific notation error. + return report_parse_error(p, parse_error::missing_exponential_part); + } + // Otherwise, we will be ignoring the 'e'. + p = location_of_e; + } else { + while ((p != pend) && is_integer(*p)) { + uint8_t digit = uint8_t(*p - UC('0')); + if (exp_number < 0x10000000) { + exp_number = 10 * exp_number + digit; + } + ++p; + } + if (neg_exp) { + exp_number = -exp_number; + } + exponent += exp_number; + } + } else { + // If it scientific and not fixed, we have to bail out. + if (uint64_t(fmt & chars_format::scientific) && + !uint64_t(fmt & chars_format::fixed)) { + return report_parse_error(p, parse_error::missing_exponential_part); + } + } + answer.lastmatch = p; + answer.valid = true; + + // If we frequently had to deal with long strings of digits, + // we could extend our code by using a 128-bit integer instead + // of a 64-bit integer. However, this is uncommon. + // + // We can deal with up to 19 digits. + if (digit_count > 19) { // this is uncommon + // It is possible that the integer had an overflow. + // We have to handle the case where we have 0.0000somenumber. + // We need to be mindful of the case where we only have zeroes... + // E.g., 0.000000000...000. + UC const *start = start_digits; + while ((start != pend) && (*start == UC('0') || *start == decimal_point)) { + if (*start == UC('0')) { + digit_count--; + } + start++; + } + + if (digit_count > 19) { + answer.too_many_digits = true; + // Let us start again, this time, avoiding overflows. + // We don't need to check if is_integer, since we use the + // pre-tokenized spans from above. + i = 0; + p = answer.integer.ptr; + UC const *int_end = p + answer.integer.len(); + uint64_t const minimal_nineteen_digit_integer{1000000000000000000}; + while ((i < minimal_nineteen_digit_integer) && (p != int_end)) { + i = i * 10 + uint64_t(*p - UC('0')); + ++p; + } + if (i >= minimal_nineteen_digit_integer) { // We have a big integers + exponent = end_of_integer_part - p + exp_number; + } else { // We have a value with a fractional component. + p = answer.fraction.ptr; + UC const *frac_end = p + answer.fraction.len(); + while ((i < minimal_nineteen_digit_integer) && (p != frac_end)) { + i = i * 10 + uint64_t(*p - UC('0')); + ++p; + } + exponent = answer.fraction.ptr - p + exp_number; + } + // We have now corrected both exponent and i, to a truncated value + } + } + answer.exponent = exponent; + answer.mantissa = i; + return answer; +} + +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 from_chars_result_t +parse_int_string(UC const *p, UC const *pend, T &value, + parse_options_t options) { + chars_format const fmt = detail::adjust_for_feature_macros(options.format); + int const base = options.base; + + from_chars_result_t answer; + + UC const *const first = p; + + bool const negative = (*p == UC('-')); +#ifdef FASTFLOAT_VISUAL_STUDIO +#pragma warning(push) +#pragma warning(disable : 4127) +#endif + if (!tinyobj_ff::is_signed::value && negative) { +#ifdef FASTFLOAT_VISUAL_STUDIO +#pragma warning(pop) +#endif + answer.ec = tinyobj_ff::ff_errc::invalid_argument; + answer.ptr = first; + return answer; + } + if ((*p == UC('-')) || + (uint64_t(fmt & chars_format::allow_leading_plus) && (*p == UC('+')))) { + ++p; + } + + UC const *const start_num = p; + + while (p != pend && *p == UC('0')) { + ++p; + } + + bool const has_leading_zeros = p > start_num; + + UC const *const start_digits = p; + + uint64_t i = 0; + if (base == 10) { + loop_parse_if_eight_digits(p, pend, i); // use SIMD if possible + } + while (p != pend) { + uint8_t digit = ch_to_digit(*p); + if (digit >= base) { + break; + } + i = uint64_t(base) * i + digit; // might overflow, check this later + p++; + } + + size_t digit_count = size_t(p - start_digits); + + if (digit_count == 0) { + if (has_leading_zeros) { + value = 0; + answer.ec = tinyobj_ff::ff_errc(); + answer.ptr = p; + } else { + answer.ec = tinyobj_ff::ff_errc::invalid_argument; + answer.ptr = first; + } + return answer; + } + + answer.ptr = p; + + // check u64 overflow + size_t max_digits = max_digits_u64(base); + if (digit_count > max_digits) { + answer.ec = tinyobj_ff::ff_errc::result_out_of_range; + return answer; + } + // this check can be eliminated for all other types, but they will all require + // a max_digits(base) equivalent + if (digit_count == max_digits && i < min_safe_u64(base)) { + answer.ec = tinyobj_ff::ff_errc::result_out_of_range; + return answer; + } + + // check other types overflow + if (!tinyobj_ff::is_same::value) { + if (i > uint64_t(std::numeric_limits::max()) + uint64_t(negative)) { + answer.ec = tinyobj_ff::ff_errc::result_out_of_range; + return answer; + } + } + + if (negative) { +#ifdef FASTFLOAT_VISUAL_STUDIO +#pragma warning(push) +#pragma warning(disable : 4146) +#endif + // this weird workaround is required because: + // - converting unsigned to signed when its value is greater than signed max + // is UB pre-C++23. + // - reinterpret_casting (~i + 1) would work, but it is not constexpr + // this is always optimized into a neg instruction (note: T is an integer + // type) + value = T(-std::numeric_limits::max() - + T(i - uint64_t(std::numeric_limits::max()))); +#ifdef FASTFLOAT_VISUAL_STUDIO +#pragma warning(pop) +#endif + } else { + value = T(i); + } + + answer.ec = tinyobj_ff::ff_errc(); + return answer; +} + +} // namespace fast_float + +#endif + +#ifndef FASTFLOAT_FAST_TABLE_H +#define FASTFLOAT_FAST_TABLE_H + +namespace fast_float { + +/** + * When mapping numbers from decimal to binary, + * we go from w * 10^q to m * 2^p but we have + * 10^q = 5^q * 2^q, so effectively + * we are trying to match + * w * 2^q * 5^q to m * 2^p. Thus the powers of two + * are not a concern since they can be represented + * exactly using the binary notation, only the powers of five + * affect the binary significand. + */ + +/** + * The smallest non-zero float (binary64) is 2^-1074. + * We take as input numbers of the form w x 10^q where w < 2^64. + * We have that w * 10^-343 < 2^(64-344) 5^-343 < 2^-1076. + * However, we have that + * (2^64-1) * 10^-342 = (2^64-1) * 2^-342 * 5^-342 > 2^-1074. + * Thus it is possible for a number of the form w * 10^-342 where + * w is a 64-bit value to be a non-zero floating-point number. + ********* + * Any number of form w * 10^309 where w>= 1 is going to be + * infinite in binary64 so we never need to worry about powers + * of 5 greater than 308. + */ +template struct powers_template { + + constexpr static int smallest_power_of_five = + binary_format::smallest_power_of_ten(); + constexpr static int largest_power_of_five = + binary_format::largest_power_of_ten(); + constexpr static int number_of_entries = + 2 * (largest_power_of_five - smallest_power_of_five + 1); + // Powers of five from 5^-342 all the way to 5^308 rounded toward one. + constexpr static uint64_t power_of_five_128[number_of_entries] = { + 0xeef453d6923bd65a, 0x113faa2906a13b3f, + 0x9558b4661b6565f8, 0x4ac7ca59a424c507, + 0xbaaee17fa23ebf76, 0x5d79bcf00d2df649, + 0xe95a99df8ace6f53, 0xf4d82c2c107973dc, + 0x91d8a02bb6c10594, 0x79071b9b8a4be869, + 0xb64ec836a47146f9, 0x9748e2826cdee284, + 0xe3e27a444d8d98b7, 0xfd1b1b2308169b25, + 0x8e6d8c6ab0787f72, 0xfe30f0f5e50e20f7, + 0xb208ef855c969f4f, 0xbdbd2d335e51a935, + 0xde8b2b66b3bc4723, 0xad2c788035e61382, + 0x8b16fb203055ac76, 0x4c3bcb5021afcc31, + 0xaddcb9e83c6b1793, 0xdf4abe242a1bbf3d, + 0xd953e8624b85dd78, 0xd71d6dad34a2af0d, + 0x87d4713d6f33aa6b, 0x8672648c40e5ad68, + 0xa9c98d8ccb009506, 0x680efdaf511f18c2, + 0xd43bf0effdc0ba48, 0x212bd1b2566def2, + 0x84a57695fe98746d, 0x14bb630f7604b57, + 0xa5ced43b7e3e9188, 0x419ea3bd35385e2d, + 0xcf42894a5dce35ea, 0x52064cac828675b9, + 0x818995ce7aa0e1b2, 0x7343efebd1940993, + 0xa1ebfb4219491a1f, 0x1014ebe6c5f90bf8, + 0xca66fa129f9b60a6, 0xd41a26e077774ef6, + 0xfd00b897478238d0, 0x8920b098955522b4, + 0x9e20735e8cb16382, 0x55b46e5f5d5535b0, + 0xc5a890362fddbc62, 0xeb2189f734aa831d, + 0xf712b443bbd52b7b, 0xa5e9ec7501d523e4, + 0x9a6bb0aa55653b2d, 0x47b233c92125366e, + 0xc1069cd4eabe89f8, 0x999ec0bb696e840a, + 0xf148440a256e2c76, 0xc00670ea43ca250d, + 0x96cd2a865764dbca, 0x380406926a5e5728, + 0xbc807527ed3e12bc, 0xc605083704f5ecf2, + 0xeba09271e88d976b, 0xf7864a44c633682e, + 0x93445b8731587ea3, 0x7ab3ee6afbe0211d, + 0xb8157268fdae9e4c, 0x5960ea05bad82964, + 0xe61acf033d1a45df, 0x6fb92487298e33bd, + 0x8fd0c16206306bab, 0xa5d3b6d479f8e056, + 0xb3c4f1ba87bc8696, 0x8f48a4899877186c, + 0xe0b62e2929aba83c, 0x331acdabfe94de87, + 0x8c71dcd9ba0b4925, 0x9ff0c08b7f1d0b14, + 0xaf8e5410288e1b6f, 0x7ecf0ae5ee44dd9, + 0xdb71e91432b1a24a, 0xc9e82cd9f69d6150, + 0x892731ac9faf056e, 0xbe311c083a225cd2, + 0xab70fe17c79ac6ca, 0x6dbd630a48aaf406, + 0xd64d3d9db981787d, 0x92cbbccdad5b108, + 0x85f0468293f0eb4e, 0x25bbf56008c58ea5, + 0xa76c582338ed2621, 0xaf2af2b80af6f24e, + 0xd1476e2c07286faa, 0x1af5af660db4aee1, + 0x82cca4db847945ca, 0x50d98d9fc890ed4d, + 0xa37fce126597973c, 0xe50ff107bab528a0, + 0xcc5fc196fefd7d0c, 0x1e53ed49a96272c8, + 0xff77b1fcbebcdc4f, 0x25e8e89c13bb0f7a, + 0x9faacf3df73609b1, 0x77b191618c54e9ac, + 0xc795830d75038c1d, 0xd59df5b9ef6a2417, + 0xf97ae3d0d2446f25, 0x4b0573286b44ad1d, + 0x9becce62836ac577, 0x4ee367f9430aec32, + 0xc2e801fb244576d5, 0x229c41f793cda73f, + 0xf3a20279ed56d48a, 0x6b43527578c1110f, + 0x9845418c345644d6, 0x830a13896b78aaa9, + 0xbe5691ef416bd60c, 0x23cc986bc656d553, + 0xedec366b11c6cb8f, 0x2cbfbe86b7ec8aa8, + 0x94b3a202eb1c3f39, 0x7bf7d71432f3d6a9, + 0xb9e08a83a5e34f07, 0xdaf5ccd93fb0cc53, + 0xe858ad248f5c22c9, 0xd1b3400f8f9cff68, + 0x91376c36d99995be, 0x23100809b9c21fa1, + 0xb58547448ffffb2d, 0xabd40a0c2832a78a, + 0xe2e69915b3fff9f9, 0x16c90c8f323f516c, + 0x8dd01fad907ffc3b, 0xae3da7d97f6792e3, + 0xb1442798f49ffb4a, 0x99cd11cfdf41779c, + 0xdd95317f31c7fa1d, 0x40405643d711d583, + 0x8a7d3eef7f1cfc52, 0x482835ea666b2572, + 0xad1c8eab5ee43b66, 0xda3243650005eecf, + 0xd863b256369d4a40, 0x90bed43e40076a82, + 0x873e4f75e2224e68, 0x5a7744a6e804a291, + 0xa90de3535aaae202, 0x711515d0a205cb36, + 0xd3515c2831559a83, 0xd5a5b44ca873e03, + 0x8412d9991ed58091, 0xe858790afe9486c2, + 0xa5178fff668ae0b6, 0x626e974dbe39a872, + 0xce5d73ff402d98e3, 0xfb0a3d212dc8128f, + 0x80fa687f881c7f8e, 0x7ce66634bc9d0b99, + 0xa139029f6a239f72, 0x1c1fffc1ebc44e80, + 0xc987434744ac874e, 0xa327ffb266b56220, + 0xfbe9141915d7a922, 0x4bf1ff9f0062baa8, + 0x9d71ac8fada6c9b5, 0x6f773fc3603db4a9, + 0xc4ce17b399107c22, 0xcb550fb4384d21d3, + 0xf6019da07f549b2b, 0x7e2a53a146606a48, + 0x99c102844f94e0fb, 0x2eda7444cbfc426d, + 0xc0314325637a1939, 0xfa911155fefb5308, + 0xf03d93eebc589f88, 0x793555ab7eba27ca, + 0x96267c7535b763b5, 0x4bc1558b2f3458de, + 0xbbb01b9283253ca2, 0x9eb1aaedfb016f16, + 0xea9c227723ee8bcb, 0x465e15a979c1cadc, + 0x92a1958a7675175f, 0xbfacd89ec191ec9, + 0xb749faed14125d36, 0xcef980ec671f667b, + 0xe51c79a85916f484, 0x82b7e12780e7401a, + 0x8f31cc0937ae58d2, 0xd1b2ecb8b0908810, + 0xb2fe3f0b8599ef07, 0x861fa7e6dcb4aa15, + 0xdfbdcece67006ac9, 0x67a791e093e1d49a, + 0x8bd6a141006042bd, 0xe0c8bb2c5c6d24e0, + 0xaecc49914078536d, 0x58fae9f773886e18, + 0xda7f5bf590966848, 0xaf39a475506a899e, + 0x888f99797a5e012d, 0x6d8406c952429603, + 0xaab37fd7d8f58178, 0xc8e5087ba6d33b83, + 0xd5605fcdcf32e1d6, 0xfb1e4a9a90880a64, + 0x855c3be0a17fcd26, 0x5cf2eea09a55067f, + 0xa6b34ad8c9dfc06f, 0xf42faa48c0ea481e, + 0xd0601d8efc57b08b, 0xf13b94daf124da26, + 0x823c12795db6ce57, 0x76c53d08d6b70858, + 0xa2cb1717b52481ed, 0x54768c4b0c64ca6e, + 0xcb7ddcdda26da268, 0xa9942f5dcf7dfd09, + 0xfe5d54150b090b02, 0xd3f93b35435d7c4c, + 0x9efa548d26e5a6e1, 0xc47bc5014a1a6daf, + 0xc6b8e9b0709f109a, 0x359ab6419ca1091b, + 0xf867241c8cc6d4c0, 0xc30163d203c94b62, + 0x9b407691d7fc44f8, 0x79e0de63425dcf1d, + 0xc21094364dfb5636, 0x985915fc12f542e4, + 0xf294b943e17a2bc4, 0x3e6f5b7b17b2939d, + 0x979cf3ca6cec5b5a, 0xa705992ceecf9c42, + 0xbd8430bd08277231, 0x50c6ff782a838353, + 0xece53cec4a314ebd, 0xa4f8bf5635246428, + 0x940f4613ae5ed136, 0x871b7795e136be99, + 0xb913179899f68584, 0x28e2557b59846e3f, + 0xe757dd7ec07426e5, 0x331aeada2fe589cf, + 0x9096ea6f3848984f, 0x3ff0d2c85def7621, + 0xb4bca50b065abe63, 0xfed077a756b53a9, + 0xe1ebce4dc7f16dfb, 0xd3e8495912c62894, + 0x8d3360f09cf6e4bd, 0x64712dd7abbbd95c, + 0xb080392cc4349dec, 0xbd8d794d96aacfb3, + 0xdca04777f541c567, 0xecf0d7a0fc5583a0, + 0x89e42caaf9491b60, 0xf41686c49db57244, + 0xac5d37d5b79b6239, 0x311c2875c522ced5, + 0xd77485cb25823ac7, 0x7d633293366b828b, + 0x86a8d39ef77164bc, 0xae5dff9c02033197, + 0xa8530886b54dbdeb, 0xd9f57f830283fdfc, + 0xd267caa862a12d66, 0xd072df63c324fd7b, + 0x8380dea93da4bc60, 0x4247cb9e59f71e6d, + 0xa46116538d0deb78, 0x52d9be85f074e608, + 0xcd795be870516656, 0x67902e276c921f8b, + 0x806bd9714632dff6, 0xba1cd8a3db53b6, + 0xa086cfcd97bf97f3, 0x80e8a40eccd228a4, + 0xc8a883c0fdaf7df0, 0x6122cd128006b2cd, + 0xfad2a4b13d1b5d6c, 0x796b805720085f81, + 0x9cc3a6eec6311a63, 0xcbe3303674053bb0, + 0xc3f490aa77bd60fc, 0xbedbfc4411068a9c, + 0xf4f1b4d515acb93b, 0xee92fb5515482d44, + 0x991711052d8bf3c5, 0x751bdd152d4d1c4a, + 0xbf5cd54678eef0b6, 0xd262d45a78a0635d, + 0xef340a98172aace4, 0x86fb897116c87c34, + 0x9580869f0e7aac0e, 0xd45d35e6ae3d4da0, + 0xbae0a846d2195712, 0x8974836059cca109, + 0xe998d258869facd7, 0x2bd1a438703fc94b, + 0x91ff83775423cc06, 0x7b6306a34627ddcf, + 0xb67f6455292cbf08, 0x1a3bc84c17b1d542, + 0xe41f3d6a7377eeca, 0x20caba5f1d9e4a93, + 0x8e938662882af53e, 0x547eb47b7282ee9c, + 0xb23867fb2a35b28d, 0xe99e619a4f23aa43, + 0xdec681f9f4c31f31, 0x6405fa00e2ec94d4, + 0x8b3c113c38f9f37e, 0xde83bc408dd3dd04, + 0xae0b158b4738705e, 0x9624ab50b148d445, + 0xd98ddaee19068c76, 0x3badd624dd9b0957, + 0x87f8a8d4cfa417c9, 0xe54ca5d70a80e5d6, + 0xa9f6d30a038d1dbc, 0x5e9fcf4ccd211f4c, + 0xd47487cc8470652b, 0x7647c3200069671f, + 0x84c8d4dfd2c63f3b, 0x29ecd9f40041e073, + 0xa5fb0a17c777cf09, 0xf468107100525890, + 0xcf79cc9db955c2cc, 0x7182148d4066eeb4, + 0x81ac1fe293d599bf, 0xc6f14cd848405530, + 0xa21727db38cb002f, 0xb8ada00e5a506a7c, + 0xca9cf1d206fdc03b, 0xa6d90811f0e4851c, + 0xfd442e4688bd304a, 0x908f4a166d1da663, + 0x9e4a9cec15763e2e, 0x9a598e4e043287fe, + 0xc5dd44271ad3cdba, 0x40eff1e1853f29fd, + 0xf7549530e188c128, 0xd12bee59e68ef47c, + 0x9a94dd3e8cf578b9, 0x82bb74f8301958ce, + 0xc13a148e3032d6e7, 0xe36a52363c1faf01, + 0xf18899b1bc3f8ca1, 0xdc44e6c3cb279ac1, + 0x96f5600f15a7b7e5, 0x29ab103a5ef8c0b9, + 0xbcb2b812db11a5de, 0x7415d448f6b6f0e7, + 0xebdf661791d60f56, 0x111b495b3464ad21, + 0x936b9fcebb25c995, 0xcab10dd900beec34, + 0xb84687c269ef3bfb, 0x3d5d514f40eea742, + 0xe65829b3046b0afa, 0xcb4a5a3112a5112, + 0x8ff71a0fe2c2e6dc, 0x47f0e785eaba72ab, + 0xb3f4e093db73a093, 0x59ed216765690f56, + 0xe0f218b8d25088b8, 0x306869c13ec3532c, + 0x8c974f7383725573, 0x1e414218c73a13fb, + 0xafbd2350644eeacf, 0xe5d1929ef90898fa, + 0xdbac6c247d62a583, 0xdf45f746b74abf39, + 0x894bc396ce5da772, 0x6b8bba8c328eb783, + 0xab9eb47c81f5114f, 0x66ea92f3f326564, + 0xd686619ba27255a2, 0xc80a537b0efefebd, + 0x8613fd0145877585, 0xbd06742ce95f5f36, + 0xa798fc4196e952e7, 0x2c48113823b73704, + 0xd17f3b51fca3a7a0, 0xf75a15862ca504c5, + 0x82ef85133de648c4, 0x9a984d73dbe722fb, + 0xa3ab66580d5fdaf5, 0xc13e60d0d2e0ebba, + 0xcc963fee10b7d1b3, 0x318df905079926a8, + 0xffbbcfe994e5c61f, 0xfdf17746497f7052, + 0x9fd561f1fd0f9bd3, 0xfeb6ea8bedefa633, + 0xc7caba6e7c5382c8, 0xfe64a52ee96b8fc0, + 0xf9bd690a1b68637b, 0x3dfdce7aa3c673b0, + 0x9c1661a651213e2d, 0x6bea10ca65c084e, + 0xc31bfa0fe5698db8, 0x486e494fcff30a62, + 0xf3e2f893dec3f126, 0x5a89dba3c3efccfa, + 0x986ddb5c6b3a76b7, 0xf89629465a75e01c, + 0xbe89523386091465, 0xf6bbb397f1135823, + 0xee2ba6c0678b597f, 0x746aa07ded582e2c, + 0x94db483840b717ef, 0xa8c2a44eb4571cdc, + 0xba121a4650e4ddeb, 0x92f34d62616ce413, + 0xe896a0d7e51e1566, 0x77b020baf9c81d17, + 0x915e2486ef32cd60, 0xace1474dc1d122e, + 0xb5b5ada8aaff80b8, 0xd819992132456ba, + 0xe3231912d5bf60e6, 0x10e1fff697ed6c69, + 0x8df5efabc5979c8f, 0xca8d3ffa1ef463c1, + 0xb1736b96b6fd83b3, 0xbd308ff8a6b17cb2, + 0xddd0467c64bce4a0, 0xac7cb3f6d05ddbde, + 0x8aa22c0dbef60ee4, 0x6bcdf07a423aa96b, + 0xad4ab7112eb3929d, 0x86c16c98d2c953c6, + 0xd89d64d57a607744, 0xe871c7bf077ba8b7, + 0x87625f056c7c4a8b, 0x11471cd764ad4972, + 0xa93af6c6c79b5d2d, 0xd598e40d3dd89bcf, + 0xd389b47879823479, 0x4aff1d108d4ec2c3, + 0x843610cb4bf160cb, 0xcedf722a585139ba, + 0xa54394fe1eedb8fe, 0xc2974eb4ee658828, + 0xce947a3da6a9273e, 0x733d226229feea32, + 0x811ccc668829b887, 0x806357d5a3f525f, + 0xa163ff802a3426a8, 0xca07c2dcb0cf26f7, + 0xc9bcff6034c13052, 0xfc89b393dd02f0b5, + 0xfc2c3f3841f17c67, 0xbbac2078d443ace2, + 0x9d9ba7832936edc0, 0xd54b944b84aa4c0d, + 0xc5029163f384a931, 0xa9e795e65d4df11, + 0xf64335bcf065d37d, 0x4d4617b5ff4a16d5, + 0x99ea0196163fa42e, 0x504bced1bf8e4e45, + 0xc06481fb9bcf8d39, 0xe45ec2862f71e1d6, + 0xf07da27a82c37088, 0x5d767327bb4e5a4c, + 0x964e858c91ba2655, 0x3a6a07f8d510f86f, + 0xbbe226efb628afea, 0x890489f70a55368b, + 0xeadab0aba3b2dbe5, 0x2b45ac74ccea842e, + 0x92c8ae6b464fc96f, 0x3b0b8bc90012929d, + 0xb77ada0617e3bbcb, 0x9ce6ebb40173744, + 0xe55990879ddcaabd, 0xcc420a6a101d0515, + 0x8f57fa54c2a9eab6, 0x9fa946824a12232d, + 0xb32df8e9f3546564, 0x47939822dc96abf9, + 0xdff9772470297ebd, 0x59787e2b93bc56f7, + 0x8bfbea76c619ef36, 0x57eb4edb3c55b65a, + 0xaefae51477a06b03, 0xede622920b6b23f1, + 0xdab99e59958885c4, 0xe95fab368e45eced, + 0x88b402f7fd75539b, 0x11dbcb0218ebb414, + 0xaae103b5fcd2a881, 0xd652bdc29f26a119, + 0xd59944a37c0752a2, 0x4be76d3346f0495f, + 0x857fcae62d8493a5, 0x6f70a4400c562ddb, + 0xa6dfbd9fb8e5b88e, 0xcb4ccd500f6bb952, + 0xd097ad07a71f26b2, 0x7e2000a41346a7a7, + 0x825ecc24c873782f, 0x8ed400668c0c28c8, + 0xa2f67f2dfa90563b, 0x728900802f0f32fa, + 0xcbb41ef979346bca, 0x4f2b40a03ad2ffb9, + 0xfea126b7d78186bc, 0xe2f610c84987bfa8, + 0x9f24b832e6b0f436, 0xdd9ca7d2df4d7c9, + 0xc6ede63fa05d3143, 0x91503d1c79720dbb, + 0xf8a95fcf88747d94, 0x75a44c6397ce912a, + 0x9b69dbe1b548ce7c, 0xc986afbe3ee11aba, + 0xc24452da229b021b, 0xfbe85badce996168, + 0xf2d56790ab41c2a2, 0xfae27299423fb9c3, + 0x97c560ba6b0919a5, 0xdccd879fc967d41a, + 0xbdb6b8e905cb600f, 0x5400e987bbc1c920, + 0xed246723473e3813, 0x290123e9aab23b68, + 0x9436c0760c86e30b, 0xf9a0b6720aaf6521, + 0xb94470938fa89bce, 0xf808e40e8d5b3e69, + 0xe7958cb87392c2c2, 0xb60b1d1230b20e04, + 0x90bd77f3483bb9b9, 0xb1c6f22b5e6f48c2, + 0xb4ecd5f01a4aa828, 0x1e38aeb6360b1af3, + 0xe2280b6c20dd5232, 0x25c6da63c38de1b0, + 0x8d590723948a535f, 0x579c487e5a38ad0e, + 0xb0af48ec79ace837, 0x2d835a9df0c6d851, + 0xdcdb1b2798182244, 0xf8e431456cf88e65, + 0x8a08f0f8bf0f156b, 0x1b8e9ecb641b58ff, + 0xac8b2d36eed2dac5, 0xe272467e3d222f3f, + 0xd7adf884aa879177, 0x5b0ed81dcc6abb0f, + 0x86ccbb52ea94baea, 0x98e947129fc2b4e9, + 0xa87fea27a539e9a5, 0x3f2398d747b36224, + 0xd29fe4b18e88640e, 0x8eec7f0d19a03aad, + 0x83a3eeeef9153e89, 0x1953cf68300424ac, + 0xa48ceaaab75a8e2b, 0x5fa8c3423c052dd7, + 0xcdb02555653131b6, 0x3792f412cb06794d, + 0x808e17555f3ebf11, 0xe2bbd88bbee40bd0, + 0xa0b19d2ab70e6ed6, 0x5b6aceaeae9d0ec4, + 0xc8de047564d20a8b, 0xf245825a5a445275, + 0xfb158592be068d2e, 0xeed6e2f0f0d56712, + 0x9ced737bb6c4183d, 0x55464dd69685606b, + 0xc428d05aa4751e4c, 0xaa97e14c3c26b886, + 0xf53304714d9265df, 0xd53dd99f4b3066a8, + 0x993fe2c6d07b7fab, 0xe546a8038efe4029, + 0xbf8fdb78849a5f96, 0xde98520472bdd033, + 0xef73d256a5c0f77c, 0x963e66858f6d4440, + 0x95a8637627989aad, 0xdde7001379a44aa8, + 0xbb127c53b17ec159, 0x5560c018580d5d52, + 0xe9d71b689dde71af, 0xaab8f01e6e10b4a6, + 0x9226712162ab070d, 0xcab3961304ca70e8, + 0xb6b00d69bb55c8d1, 0x3d607b97c5fd0d22, + 0xe45c10c42a2b3b05, 0x8cb89a7db77c506a, + 0x8eb98a7a9a5b04e3, 0x77f3608e92adb242, + 0xb267ed1940f1c61c, 0x55f038b237591ed3, + 0xdf01e85f912e37a3, 0x6b6c46dec52f6688, + 0x8b61313bbabce2c6, 0x2323ac4b3b3da015, + 0xae397d8aa96c1b77, 0xabec975e0a0d081a, + 0xd9c7dced53c72255, 0x96e7bd358c904a21, + 0x881cea14545c7575, 0x7e50d64177da2e54, + 0xaa242499697392d2, 0xdde50bd1d5d0b9e9, + 0xd4ad2dbfc3d07787, 0x955e4ec64b44e864, + 0x84ec3c97da624ab4, 0xbd5af13bef0b113e, + 0xa6274bbdd0fadd61, 0xecb1ad8aeacdd58e, + 0xcfb11ead453994ba, 0x67de18eda5814af2, + 0x81ceb32c4b43fcf4, 0x80eacf948770ced7, + 0xa2425ff75e14fc31, 0xa1258379a94d028d, + 0xcad2f7f5359a3b3e, 0x96ee45813a04330, + 0xfd87b5f28300ca0d, 0x8bca9d6e188853fc, + 0x9e74d1b791e07e48, 0x775ea264cf55347e, + 0xc612062576589dda, 0x95364afe032a819e, + 0xf79687aed3eec551, 0x3a83ddbd83f52205, + 0x9abe14cd44753b52, 0xc4926a9672793543, + 0xc16d9a0095928a27, 0x75b7053c0f178294, + 0xf1c90080baf72cb1, 0x5324c68b12dd6339, + 0x971da05074da7bee, 0xd3f6fc16ebca5e04, + 0xbce5086492111aea, 0x88f4bb1ca6bcf585, + 0xec1e4a7db69561a5, 0x2b31e9e3d06c32e6, + 0x9392ee8e921d5d07, 0x3aff322e62439fd0, + 0xb877aa3236a4b449, 0x9befeb9fad487c3, + 0xe69594bec44de15b, 0x4c2ebe687989a9b4, + 0x901d7cf73ab0acd9, 0xf9d37014bf60a11, + 0xb424dc35095cd80f, 0x538484c19ef38c95, + 0xe12e13424bb40e13, 0x2865a5f206b06fba, + 0x8cbccc096f5088cb, 0xf93f87b7442e45d4, + 0xafebff0bcb24aafe, 0xf78f69a51539d749, + 0xdbe6fecebdedd5be, 0xb573440e5a884d1c, + 0x89705f4136b4a597, 0x31680a88f8953031, + 0xabcc77118461cefc, 0xfdc20d2b36ba7c3e, + 0xd6bf94d5e57a42bc, 0x3d32907604691b4d, + 0x8637bd05af6c69b5, 0xa63f9a49c2c1b110, + 0xa7c5ac471b478423, 0xfcf80dc33721d54, + 0xd1b71758e219652b, 0xd3c36113404ea4a9, + 0x83126e978d4fdf3b, 0x645a1cac083126ea, + 0xa3d70a3d70a3d70a, 0x3d70a3d70a3d70a4, + 0xcccccccccccccccc, 0xcccccccccccccccd, + 0x8000000000000000, 0x0, + 0xa000000000000000, 0x0, + 0xc800000000000000, 0x0, + 0xfa00000000000000, 0x0, + 0x9c40000000000000, 0x0, + 0xc350000000000000, 0x0, + 0xf424000000000000, 0x0, + 0x9896800000000000, 0x0, + 0xbebc200000000000, 0x0, + 0xee6b280000000000, 0x0, + 0x9502f90000000000, 0x0, + 0xba43b74000000000, 0x0, + 0xe8d4a51000000000, 0x0, + 0x9184e72a00000000, 0x0, + 0xb5e620f480000000, 0x0, + 0xe35fa931a0000000, 0x0, + 0x8e1bc9bf04000000, 0x0, + 0xb1a2bc2ec5000000, 0x0, + 0xde0b6b3a76400000, 0x0, + 0x8ac7230489e80000, 0x0, + 0xad78ebc5ac620000, 0x0, + 0xd8d726b7177a8000, 0x0, + 0x878678326eac9000, 0x0, + 0xa968163f0a57b400, 0x0, + 0xd3c21bcecceda100, 0x0, + 0x84595161401484a0, 0x0, + 0xa56fa5b99019a5c8, 0x0, + 0xcecb8f27f4200f3a, 0x0, + 0x813f3978f8940984, 0x4000000000000000, + 0xa18f07d736b90be5, 0x5000000000000000, + 0xc9f2c9cd04674ede, 0xa400000000000000, + 0xfc6f7c4045812296, 0x4d00000000000000, + 0x9dc5ada82b70b59d, 0xf020000000000000, + 0xc5371912364ce305, 0x6c28000000000000, + 0xf684df56c3e01bc6, 0xc732000000000000, + 0x9a130b963a6c115c, 0x3c7f400000000000, + 0xc097ce7bc90715b3, 0x4b9f100000000000, + 0xf0bdc21abb48db20, 0x1e86d40000000000, + 0x96769950b50d88f4, 0x1314448000000000, + 0xbc143fa4e250eb31, 0x17d955a000000000, + 0xeb194f8e1ae525fd, 0x5dcfab0800000000, + 0x92efd1b8d0cf37be, 0x5aa1cae500000000, + 0xb7abc627050305ad, 0xf14a3d9e40000000, + 0xe596b7b0c643c719, 0x6d9ccd05d0000000, + 0x8f7e32ce7bea5c6f, 0xe4820023a2000000, + 0xb35dbf821ae4f38b, 0xdda2802c8a800000, + 0xe0352f62a19e306e, 0xd50b2037ad200000, + 0x8c213d9da502de45, 0x4526f422cc340000, + 0xaf298d050e4395d6, 0x9670b12b7f410000, + 0xdaf3f04651d47b4c, 0x3c0cdd765f114000, + 0x88d8762bf324cd0f, 0xa5880a69fb6ac800, + 0xab0e93b6efee0053, 0x8eea0d047a457a00, + 0xd5d238a4abe98068, 0x72a4904598d6d880, + 0x85a36366eb71f041, 0x47a6da2b7f864750, + 0xa70c3c40a64e6c51, 0x999090b65f67d924, + 0xd0cf4b50cfe20765, 0xfff4b4e3f741cf6d, + 0x82818f1281ed449f, 0xbff8f10e7a8921a4, + 0xa321f2d7226895c7, 0xaff72d52192b6a0d, + 0xcbea6f8ceb02bb39, 0x9bf4f8a69f764490, + 0xfee50b7025c36a08, 0x2f236d04753d5b4, + 0x9f4f2726179a2245, 0x1d762422c946590, + 0xc722f0ef9d80aad6, 0x424d3ad2b7b97ef5, + 0xf8ebad2b84e0d58b, 0xd2e0898765a7deb2, + 0x9b934c3b330c8577, 0x63cc55f49f88eb2f, + 0xc2781f49ffcfa6d5, 0x3cbf6b71c76b25fb, + 0xf316271c7fc3908a, 0x8bef464e3945ef7a, + 0x97edd871cfda3a56, 0x97758bf0e3cbb5ac, + 0xbde94e8e43d0c8ec, 0x3d52eeed1cbea317, + 0xed63a231d4c4fb27, 0x4ca7aaa863ee4bdd, + 0x945e455f24fb1cf8, 0x8fe8caa93e74ef6a, + 0xb975d6b6ee39e436, 0xb3e2fd538e122b44, + 0xe7d34c64a9c85d44, 0x60dbbca87196b616, + 0x90e40fbeea1d3a4a, 0xbc8955e946fe31cd, + 0xb51d13aea4a488dd, 0x6babab6398bdbe41, + 0xe264589a4dcdab14, 0xc696963c7eed2dd1, + 0x8d7eb76070a08aec, 0xfc1e1de5cf543ca2, + 0xb0de65388cc8ada8, 0x3b25a55f43294bcb, + 0xdd15fe86affad912, 0x49ef0eb713f39ebe, + 0x8a2dbf142dfcc7ab, 0x6e3569326c784337, + 0xacb92ed9397bf996, 0x49c2c37f07965404, + 0xd7e77a8f87daf7fb, 0xdc33745ec97be906, + 0x86f0ac99b4e8dafd, 0x69a028bb3ded71a3, + 0xa8acd7c0222311bc, 0xc40832ea0d68ce0c, + 0xd2d80db02aabd62b, 0xf50a3fa490c30190, + 0x83c7088e1aab65db, 0x792667c6da79e0fa, + 0xa4b8cab1a1563f52, 0x577001b891185938, + 0xcde6fd5e09abcf26, 0xed4c0226b55e6f86, + 0x80b05e5ac60b6178, 0x544f8158315b05b4, + 0xa0dc75f1778e39d6, 0x696361ae3db1c721, + 0xc913936dd571c84c, 0x3bc3a19cd1e38e9, + 0xfb5878494ace3a5f, 0x4ab48a04065c723, + 0x9d174b2dcec0e47b, 0x62eb0d64283f9c76, + 0xc45d1df942711d9a, 0x3ba5d0bd324f8394, + 0xf5746577930d6500, 0xca8f44ec7ee36479, + 0x9968bf6abbe85f20, 0x7e998b13cf4e1ecb, + 0xbfc2ef456ae276e8, 0x9e3fedd8c321a67e, + 0xefb3ab16c59b14a2, 0xc5cfe94ef3ea101e, + 0x95d04aee3b80ece5, 0xbba1f1d158724a12, + 0xbb445da9ca61281f, 0x2a8a6e45ae8edc97, + 0xea1575143cf97226, 0xf52d09d71a3293bd, + 0x924d692ca61be758, 0x593c2626705f9c56, + 0xb6e0c377cfa2e12e, 0x6f8b2fb00c77836c, + 0xe498f455c38b997a, 0xb6dfb9c0f956447, + 0x8edf98b59a373fec, 0x4724bd4189bd5eac, + 0xb2977ee300c50fe7, 0x58edec91ec2cb657, + 0xdf3d5e9bc0f653e1, 0x2f2967b66737e3ed, + 0x8b865b215899f46c, 0xbd79e0d20082ee74, + 0xae67f1e9aec07187, 0xecd8590680a3aa11, + 0xda01ee641a708de9, 0xe80e6f4820cc9495, + 0x884134fe908658b2, 0x3109058d147fdcdd, + 0xaa51823e34a7eede, 0xbd4b46f0599fd415, + 0xd4e5e2cdc1d1ea96, 0x6c9e18ac7007c91a, + 0x850fadc09923329e, 0x3e2cf6bc604ddb0, + 0xa6539930bf6bff45, 0x84db8346b786151c, + 0xcfe87f7cef46ff16, 0xe612641865679a63, + 0x81f14fae158c5f6e, 0x4fcb7e8f3f60c07e, + 0xa26da3999aef7749, 0xe3be5e330f38f09d, + 0xcb090c8001ab551c, 0x5cadf5bfd3072cc5, + 0xfdcb4fa002162a63, 0x73d9732fc7c8f7f6, + 0x9e9f11c4014dda7e, 0x2867e7fddcdd9afa, + 0xc646d63501a1511d, 0xb281e1fd541501b8, + 0xf7d88bc24209a565, 0x1f225a7ca91a4226, + 0x9ae757596946075f, 0x3375788de9b06958, + 0xc1a12d2fc3978937, 0x52d6b1641c83ae, + 0xf209787bb47d6b84, 0xc0678c5dbd23a49a, + 0x9745eb4d50ce6332, 0xf840b7ba963646e0, + 0xbd176620a501fbff, 0xb650e5a93bc3d898, + 0xec5d3fa8ce427aff, 0xa3e51f138ab4cebe, + 0x93ba47c980e98cdf, 0xc66f336c36b10137, + 0xb8a8d9bbe123f017, 0xb80b0047445d4184, + 0xe6d3102ad96cec1d, 0xa60dc059157491e5, + 0x9043ea1ac7e41392, 0x87c89837ad68db2f, + 0xb454e4a179dd1877, 0x29babe4598c311fb, + 0xe16a1dc9d8545e94, 0xf4296dd6fef3d67a, + 0x8ce2529e2734bb1d, 0x1899e4a65f58660c, + 0xb01ae745b101e9e4, 0x5ec05dcff72e7f8f, + 0xdc21a1171d42645d, 0x76707543f4fa1f73, + 0x899504ae72497eba, 0x6a06494a791c53a8, + 0xabfa45da0edbde69, 0x487db9d17636892, + 0xd6f8d7509292d603, 0x45a9d2845d3c42b6, + 0x865b86925b9bc5c2, 0xb8a2392ba45a9b2, + 0xa7f26836f282b732, 0x8e6cac7768d7141e, + 0xd1ef0244af2364ff, 0x3207d795430cd926, + 0x8335616aed761f1f, 0x7f44e6bd49e807b8, + 0xa402b9c5a8d3a6e7, 0x5f16206c9c6209a6, + 0xcd036837130890a1, 0x36dba887c37a8c0f, + 0x802221226be55a64, 0xc2494954da2c9789, + 0xa02aa96b06deb0fd, 0xf2db9baa10b7bd6c, + 0xc83553c5c8965d3d, 0x6f92829494e5acc7, + 0xfa42a8b73abbf48c, 0xcb772339ba1f17f9, + 0x9c69a97284b578d7, 0xff2a760414536efb, + 0xc38413cf25e2d70d, 0xfef5138519684aba, + 0xf46518c2ef5b8cd1, 0x7eb258665fc25d69, + 0x98bf2f79d5993802, 0xef2f773ffbd97a61, + 0xbeeefb584aff8603, 0xaafb550ffacfd8fa, + 0xeeaaba2e5dbf6784, 0x95ba2a53f983cf38, + 0x952ab45cfa97a0b2, 0xdd945a747bf26183, + 0xba756174393d88df, 0x94f971119aeef9e4, + 0xe912b9d1478ceb17, 0x7a37cd5601aab85d, + 0x91abb422ccb812ee, 0xac62e055c10ab33a, + 0xb616a12b7fe617aa, 0x577b986b314d6009, + 0xe39c49765fdf9d94, 0xed5a7e85fda0b80b, + 0x8e41ade9fbebc27d, 0x14588f13be847307, + 0xb1d219647ae6b31c, 0x596eb2d8ae258fc8, + 0xde469fbd99a05fe3, 0x6fca5f8ed9aef3bb, + 0x8aec23d680043bee, 0x25de7bb9480d5854, + 0xada72ccc20054ae9, 0xaf561aa79a10ae6a, + 0xd910f7ff28069da4, 0x1b2ba1518094da04, + 0x87aa9aff79042286, 0x90fb44d2f05d0842, + 0xa99541bf57452b28, 0x353a1607ac744a53, + 0xd3fa922f2d1675f2, 0x42889b8997915ce8, + 0x847c9b5d7c2e09b7, 0x69956135febada11, + 0xa59bc234db398c25, 0x43fab9837e699095, + 0xcf02b2c21207ef2e, 0x94f967e45e03f4bb, + 0x8161afb94b44f57d, 0x1d1be0eebac278f5, + 0xa1ba1ba79e1632dc, 0x6462d92a69731732, + 0xca28a291859bbf93, 0x7d7b8f7503cfdcfe, + 0xfcb2cb35e702af78, 0x5cda735244c3d43e, + 0x9defbf01b061adab, 0x3a0888136afa64a7, + 0xc56baec21c7a1916, 0x88aaa1845b8fdd0, + 0xf6c69a72a3989f5b, 0x8aad549e57273d45, + 0x9a3c2087a63f6399, 0x36ac54e2f678864b, + 0xc0cb28a98fcf3c7f, 0x84576a1bb416a7dd, + 0xf0fdf2d3f3c30b9f, 0x656d44a2a11c51d5, + 0x969eb7c47859e743, 0x9f644ae5a4b1b325, + 0xbc4665b596706114, 0x873d5d9f0dde1fee, + 0xeb57ff22fc0c7959, 0xa90cb506d155a7ea, + 0x9316ff75dd87cbd8, 0x9a7f12442d588f2, + 0xb7dcbf5354e9bece, 0xc11ed6d538aeb2f, + 0xe5d3ef282a242e81, 0x8f1668c8a86da5fa, + 0x8fa475791a569d10, 0xf96e017d694487bc, + 0xb38d92d760ec4455, 0x37c981dcc395a9ac, + 0xe070f78d3927556a, 0x85bbe253f47b1417, + 0x8c469ab843b89562, 0x93956d7478ccec8e, + 0xaf58416654a6babb, 0x387ac8d1970027b2, + 0xdb2e51bfe9d0696a, 0x6997b05fcc0319e, + 0x88fcf317f22241e2, 0x441fece3bdf81f03, + 0xab3c2fddeeaad25a, 0xd527e81cad7626c3, + 0xd60b3bd56a5586f1, 0x8a71e223d8d3b074, + 0x85c7056562757456, 0xf6872d5667844e49, + 0xa738c6bebb12d16c, 0xb428f8ac016561db, + 0xd106f86e69d785c7, 0xe13336d701beba52, + 0x82a45b450226b39c, 0xecc0024661173473, + 0xa34d721642b06084, 0x27f002d7f95d0190, + 0xcc20ce9bd35c78a5, 0x31ec038df7b441f4, + 0xff290242c83396ce, 0x7e67047175a15271, + 0x9f79a169bd203e41, 0xf0062c6e984d386, + 0xc75809c42c684dd1, 0x52c07b78a3e60868, + 0xf92e0c3537826145, 0xa7709a56ccdf8a82, + 0x9bbcc7a142b17ccb, 0x88a66076400bb691, + 0xc2abf989935ddbfe, 0x6acff893d00ea435, + 0xf356f7ebf83552fe, 0x583f6b8c4124d43, + 0x98165af37b2153de, 0xc3727a337a8b704a, + 0xbe1bf1b059e9a8d6, 0x744f18c0592e4c5c, + 0xeda2ee1c7064130c, 0x1162def06f79df73, + 0x9485d4d1c63e8be7, 0x8addcb5645ac2ba8, + 0xb9a74a0637ce2ee1, 0x6d953e2bd7173692, + 0xe8111c87c5c1ba99, 0xc8fa8db6ccdd0437, + 0x910ab1d4db9914a0, 0x1d9c9892400a22a2, + 0xb54d5e4a127f59c8, 0x2503beb6d00cab4b, + 0xe2a0b5dc971f303a, 0x2e44ae64840fd61d, + 0x8da471a9de737e24, 0x5ceaecfed289e5d2, + 0xb10d8e1456105dad, 0x7425a83e872c5f47, + 0xdd50f1996b947518, 0xd12f124e28f77719, + 0x8a5296ffe33cc92f, 0x82bd6b70d99aaa6f, + 0xace73cbfdc0bfb7b, 0x636cc64d1001550b, + 0xd8210befd30efa5a, 0x3c47f7e05401aa4e, + 0x8714a775e3e95c78, 0x65acfaec34810a71, + 0xa8d9d1535ce3b396, 0x7f1839a741a14d0d, + 0xd31045a8341ca07c, 0x1ede48111209a050, + 0x83ea2b892091e44d, 0x934aed0aab460432, + 0xa4e4b66b68b65d60, 0xf81da84d5617853f, + 0xce1de40642e3f4b9, 0x36251260ab9d668e, + 0x80d2ae83e9ce78f3, 0xc1d72b7c6b426019, + 0xa1075a24e4421730, 0xb24cf65b8612f81f, + 0xc94930ae1d529cfc, 0xdee033f26797b627, + 0xfb9b7cd9a4a7443c, 0x169840ef017da3b1, + 0x9d412e0806e88aa5, 0x8e1f289560ee864e, + 0xc491798a08a2ad4e, 0xf1a6f2bab92a27e2, + 0xf5b5d7ec8acb58a2, 0xae10af696774b1db, + 0x9991a6f3d6bf1765, 0xacca6da1e0a8ef29, + 0xbff610b0cc6edd3f, 0x17fd090a58d32af3, + 0xeff394dcff8a948e, 0xddfc4b4cef07f5b0, + 0x95f83d0a1fb69cd9, 0x4abdaf101564f98e, + 0xbb764c4ca7a4440f, 0x9d6d1ad41abe37f1, + 0xea53df5fd18d5513, 0x84c86189216dc5ed, + 0x92746b9be2f8552c, 0x32fd3cf5b4e49bb4, + 0xb7118682dbb66a77, 0x3fbc8c33221dc2a1, + 0xe4d5e82392a40515, 0xfabaf3feaa5334a, + 0x8f05b1163ba6832d, 0x29cb4d87f2a7400e, + 0xb2c71d5bca9023f8, 0x743e20e9ef511012, + 0xdf78e4b2bd342cf6, 0x914da9246b255416, + 0x8bab8eefb6409c1a, 0x1ad089b6c2f7548e, + 0xae9672aba3d0c320, 0xa184ac2473b529b1, + 0xda3c0f568cc4f3e8, 0xc9e5d72d90a2741e, + 0x8865899617fb1871, 0x7e2fa67c7a658892, + 0xaa7eebfb9df9de8d, 0xddbb901b98feeab7, + 0xd51ea6fa85785631, 0x552a74227f3ea565, + 0x8533285c936b35de, 0xd53a88958f87275f, + 0xa67ff273b8460356, 0x8a892abaf368f137, + 0xd01fef10a657842c, 0x2d2b7569b0432d85, + 0x8213f56a67f6b29b, 0x9c3b29620e29fc73, + 0xa298f2c501f45f42, 0x8349f3ba91b47b8f, + 0xcb3f2f7642717713, 0x241c70a936219a73, + 0xfe0efb53d30dd4d7, 0xed238cd383aa0110, + 0x9ec95d1463e8a506, 0xf4363804324a40aa, + 0xc67bb4597ce2ce48, 0xb143c6053edcd0d5, + 0xf81aa16fdc1b81da, 0xdd94b7868e94050a, + 0x9b10a4e5e9913128, 0xca7cf2b4191c8326, + 0xc1d4ce1f63f57d72, 0xfd1c2f611f63a3f0, + 0xf24a01a73cf2dccf, 0xbc633b39673c8cec, + 0x976e41088617ca01, 0xd5be0503e085d813, + 0xbd49d14aa79dbc82, 0x4b2d8644d8a74e18, + 0xec9c459d51852ba2, 0xddf8e7d60ed1219e, + 0x93e1ab8252f33b45, 0xcabb90e5c942b503, + 0xb8da1662e7b00a17, 0x3d6a751f3b936243, + 0xe7109bfba19c0c9d, 0xcc512670a783ad4, + 0x906a617d450187e2, 0x27fb2b80668b24c5, + 0xb484f9dc9641e9da, 0xb1f9f660802dedf6, + 0xe1a63853bbd26451, 0x5e7873f8a0396973, + 0x8d07e33455637eb2, 0xdb0b487b6423e1e8, + 0xb049dc016abc5e5f, 0x91ce1a9a3d2cda62, + 0xdc5c5301c56b75f7, 0x7641a140cc7810fb, + 0x89b9b3e11b6329ba, 0xa9e904c87fcb0a9d, + 0xac2820d9623bf429, 0x546345fa9fbdcd44, + 0xd732290fbacaf133, 0xa97c177947ad4095, + 0x867f59a9d4bed6c0, 0x49ed8eabcccc485d, + 0xa81f301449ee8c70, 0x5c68f256bfff5a74, + 0xd226fc195c6a2f8c, 0x73832eec6fff3111, + 0x83585d8fd9c25db7, 0xc831fd53c5ff7eab, + 0xa42e74f3d032f525, 0xba3e7ca8b77f5e55, + 0xcd3a1230c43fb26f, 0x28ce1bd2e55f35eb, + 0x80444b5e7aa7cf85, 0x7980d163cf5b81b3, + 0xa0555e361951c366, 0xd7e105bcc332621f, + 0xc86ab5c39fa63440, 0x8dd9472bf3fefaa7, + 0xfa856334878fc150, 0xb14f98f6f0feb951, + 0x9c935e00d4b9d8d2, 0x6ed1bf9a569f33d3, + 0xc3b8358109e84f07, 0xa862f80ec4700c8, + 0xf4a642e14c6262c8, 0xcd27bb612758c0fa, + 0x98e7e9cccfbd7dbd, 0x8038d51cb897789c, + 0xbf21e44003acdd2c, 0xe0470a63e6bd56c3, + 0xeeea5d5004981478, 0x1858ccfce06cac74, + 0x95527a5202df0ccb, 0xf37801e0c43ebc8, + 0xbaa718e68396cffd, 0xd30560258f54e6ba, + 0xe950df20247c83fd, 0x47c6b82ef32a2069, + 0x91d28b7416cdd27e, 0x4cdc331d57fa5441, + 0xb6472e511c81471d, 0xe0133fe4adf8e952, + 0xe3d8f9e563a198e5, 0x58180fddd97723a6, + 0x8e679c2f5e44ff8f, 0x570f09eaa7ea7648, + }; +}; + +#if FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE + +template +constexpr uint64_t + powers_template::power_of_five_128[number_of_entries]; + +#endif + +using powers = powers_template<>; + +} // namespace fast_float + +#endif + +#ifndef FASTFLOAT_DECIMAL_TO_BINARY_H +#define FASTFLOAT_DECIMAL_TO_BINARY_H + +#include +#include +#include + +namespace fast_float { + +// This will compute or rather approximate w * 5**q and return a pair of 64-bit +// words approximating the result, with the "high" part corresponding to the +// most significant bits and the low part corresponding to the least significant +// bits. +// +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 value128 +compute_product_approximation(int64_t q, uint64_t w) { + int const index = 2 * int(q - powers::smallest_power_of_five); + // For small values of q, e.g., q in [0,27], the answer is always exact + // because The line value128 firstproduct = full_multiplication(w, + // power_of_five_128[index]); gives the exact answer. + value128 firstproduct = + full_multiplication(w, powers::power_of_five_128[index]); + static_assert((bit_precision >= 0) && (bit_precision <= 64), + " precision should be in (0,64]"); + constexpr uint64_t precision_mask = + (bit_precision < 64) ? (uint64_t(0xFFFFFFFFFFFFFFFF) >> bit_precision) + : uint64_t(0xFFFFFFFFFFFFFFFF); + if ((firstproduct.high & precision_mask) == + precision_mask) { // could further guard with (lower + w < lower) + // regarding the second product, we only need secondproduct.high, but our + // expectation is that the compiler will optimize this extra work away if + // needed. + value128 secondproduct = + full_multiplication(w, powers::power_of_five_128[index + 1]); + firstproduct.low += secondproduct.high; + if (secondproduct.high > firstproduct.low) { + firstproduct.high++; + } + } + return firstproduct; +} + +namespace detail { +/** + * For q in (0,350), we have that + * f = (((152170 + 65536) * q ) >> 16); + * is equal to + * floor(p) + q + * where + * p = log(5**q)/log(2) = q * log(5)/log(2) + * + * For negative values of q in (-400,0), we have that + * f = (((152170 + 65536) * q ) >> 16); + * is equal to + * -ceil(p) + q + * where + * p = log(5**-q)/log(2) = -q * log(5)/log(2) + */ +constexpr fastfloat_really_inline int32_t power(int32_t q) noexcept { + return (((152170 + 65536) * q) >> 16) + 63; +} +} // namespace detail + +// create an adjusted mantissa, biased by the invalid power2 +// for significant digits already multiplied by 10 ** q. +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR14 adjusted_mantissa +compute_error_scaled(int64_t q, uint64_t w, int lz) noexcept { + int hilz = int(w >> 63) ^ 1; + adjusted_mantissa answer; + answer.mantissa = w << hilz; + int bias = binary::mantissa_explicit_bits() - binary::minimum_exponent(); + answer.power2 = int32_t(detail::power(int32_t(q)) + bias - hilz - lz - 62 + + invalid_am_bias); + return answer; +} + +// w * 10 ** q, without rounding the representation up. +// the power2 in the exponent will be adjusted by invalid_am_bias. +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa +compute_error(int64_t q, uint64_t w) noexcept { + int lz = leading_zeroes(w); + w <<= lz; + value128 product = + compute_product_approximation(q, w); + return compute_error_scaled(q, product.high, lz); +} + +// Computers w * 10 ** q. +// The returned value should be a valid number that simply needs to be +// packed. However, in some very rare cases, the computation will fail. In such +// cases, we return an adjusted_mantissa with a negative power of 2: the caller +// should recompute in such cases. +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa +compute_float(int64_t q, uint64_t w) noexcept { + adjusted_mantissa answer; + if ((w == 0) || (q < binary::smallest_power_of_ten())) { + answer.power2 = 0; + answer.mantissa = 0; + // result should be zero + return answer; + } + if (q > binary::largest_power_of_ten()) { + // we want to get infinity: + answer.power2 = binary::infinite_power(); + answer.mantissa = 0; + return answer; + } + // At this point in time q is in [powers::smallest_power_of_five, + // powers::largest_power_of_five]. + + // We want the most significant bit of i to be 1. Shift if needed. + int lz = leading_zeroes(w); + w <<= lz; + + // The required precision is binary::mantissa_explicit_bits() + 3 because + // 1. We need the implicit bit + // 2. We need an extra bit for rounding purposes + // 3. We might lose a bit due to the "upperbit" routine (result too small, + // requiring a shift) + + value128 product = + compute_product_approximation(q, w); + // The computed 'product' is always sufficient. + // Mathematical proof: + // Noble Mushtak and Daniel Lemire, Fast Number Parsing Without Fallback (to + // appear) See script/mushtak_lemire.py + + // The "compute_product_approximation" function can be slightly slower than a + // branchless approach: value128 product = compute_product(q, w); but in + // practice, we can win big with the compute_product_approximation if its + // additional branch is easily predicted. Which is best is data specific. + int upperbit = int(product.high >> 63); + int shift = upperbit + 64 - binary::mantissa_explicit_bits() - 3; + + answer.mantissa = product.high >> shift; + + answer.power2 = int32_t(detail::power(int32_t(q)) + upperbit - lz - + binary::minimum_exponent()); + if (answer.power2 <= 0) { // we have a subnormal? + // Here have that answer.power2 <= 0 so -answer.power2 >= 0 + if (-answer.power2 + 1 >= + 64) { // if we have more than 64 bits below the minimum exponent, you + // have a zero for sure. + answer.power2 = 0; + answer.mantissa = 0; + // result should be zero + return answer; + } + // next line is safe because -answer.power2 + 1 < 64 + answer.mantissa >>= -answer.power2 + 1; + // Thankfully, we can't have both "round-to-even" and subnormals because + // "round-to-even" only occurs for powers close to 0 in the 32-bit and + // and 64-bit case (with no more than 19 digits). + answer.mantissa += (answer.mantissa & 1); // round up + answer.mantissa >>= 1; + // There is a weird scenario where we don't have a subnormal but just. + // Suppose we start with 2.2250738585072013e-308, we end up + // with 0x3fffffffffffff x 2^-1023-53 which is technically subnormal + // whereas 0x40000000000000 x 2^-1023-53 is normal. Now, we need to round + // up 0x3fffffffffffff x 2^-1023-53 and once we do, we are no longer + // subnormal, but we can only know this after rounding. + // So we only declare a subnormal if we are smaller than the threshold. + answer.power2 = + (answer.mantissa < (uint64_t(1) << binary::mantissa_explicit_bits())) + ? 0 + : 1; + return answer; + } + + // usually, we round *up*, but if we fall right in between and and we have an + // even basis, we need to round down + // We are only concerned with the cases where 5**q fits in single 64-bit word. + if ((product.low <= 1) && (q >= binary::min_exponent_round_to_even()) && + (q <= binary::max_exponent_round_to_even()) && + ((answer.mantissa & 3) == 1)) { // we may fall between two floats! + // To be in-between two floats we need that in doing + // answer.mantissa = product.high >> (upperbit + 64 - + // binary::mantissa_explicit_bits() - 3); + // ... we dropped out only zeroes. But if this happened, then we can go + // back!!! + if ((answer.mantissa << shift) == product.high) { + answer.mantissa &= ~uint64_t(1); // flip it so that we do not round up + } + } + + answer.mantissa += (answer.mantissa & 1); // round up + answer.mantissa >>= 1; + if (answer.mantissa >= (uint64_t(2) << binary::mantissa_explicit_bits())) { + answer.mantissa = (uint64_t(1) << binary::mantissa_explicit_bits()); + answer.power2++; // undo previous addition + } + + answer.mantissa &= ~(uint64_t(1) << binary::mantissa_explicit_bits()); + if (answer.power2 >= binary::infinite_power()) { // infinity + answer.power2 = binary::infinite_power(); + answer.mantissa = 0; + } + return answer; +} + +} // namespace fast_float + +#endif + +#ifndef FASTFLOAT_BIGINT_H +#define FASTFLOAT_BIGINT_H + +#include + + +namespace fast_float { + +// the limb width: we want efficient multiplication of double the bits in +// limb, or for 64-bit limbs, at least 64-bit multiplication where we can +// extract the high and low parts efficiently. this is every 64-bit +// architecture except for sparc, which emulates 128-bit multiplication. +// we might have platforms where `CHAR_BIT` is not 8, so let's avoid +// doing `8 * sizeof(limb)`. +#if defined(FASTFLOAT_64BIT) && !defined(__sparc) +#define FASTFLOAT_64BIT_LIMB 1 +typedef uint64_t limb; +constexpr size_t limb_bits = 64; +#else +#define FASTFLOAT_32BIT_LIMB +typedef uint32_t limb; +constexpr size_t limb_bits = 32; +#endif + +typedef span limb_span; + +// number of bits in a bigint. this needs to be at least the number +// of bits required to store the largest bigint, which is +// `log2(10**(digits + max_exp))`, or `log2(10**(767 + 342))`, or +// ~3600 bits, so we round to 4000. +constexpr size_t bigint_bits = 4000; +constexpr size_t bigint_limbs = bigint_bits / limb_bits; + +// vector-like type that is allocated on the stack. the entire +// buffer is pre-allocated, and only the length changes. +template struct stackvec { + limb data[size]; + // we never need more than 150 limbs + uint16_t length{0}; + + stackvec() = default; + stackvec(stackvec const &) = delete; + stackvec &operator=(stackvec const &) = delete; + stackvec(stackvec &&) = delete; + stackvec &operator=(stackvec &&other) = delete; + + // create stack vector from existing limb span. + FASTFLOAT_CONSTEXPR20 stackvec(limb_span s) { + FASTFLOAT_ASSERT(try_extend(s)); + } + + FASTFLOAT_CONSTEXPR14 limb &operator[](size_t index) noexcept { + FASTFLOAT_DEBUG_ASSERT(index < length); + return data[index]; + } + + FASTFLOAT_CONSTEXPR14 const limb &operator[](size_t index) const noexcept { + FASTFLOAT_DEBUG_ASSERT(index < length); + return data[index]; + } + + // index from the end of the container + FASTFLOAT_CONSTEXPR14 const limb &rindex(size_t index) const noexcept { + FASTFLOAT_DEBUG_ASSERT(index < length); + size_t rindex = length - index - 1; + return data[rindex]; + } + + // set the length, without bounds checking. + FASTFLOAT_CONSTEXPR14 void set_len(size_t len) noexcept { + length = uint16_t(len); + } + + constexpr size_t len() const noexcept { return length; } + + constexpr bool is_empty() const noexcept { return length == 0; } + + constexpr size_t capacity() const noexcept { return size; } + + // append item to vector, without bounds checking + FASTFLOAT_CONSTEXPR14 void push_unchecked(limb value) noexcept { + data[length] = value; + length++; + } + + // append item to vector, returning if item was added + FASTFLOAT_CONSTEXPR14 bool try_push(limb value) noexcept { + if (len() < capacity()) { + push_unchecked(value); + return true; + } else { + return false; + } + } + + // add items to the vector, from a span, without bounds checking + FASTFLOAT_CONSTEXPR20 void extend_unchecked(limb_span s) noexcept { + limb *ptr = data + length; + tinyobj_ff::copy_n(s.ptr, s.len(), ptr); + set_len(len() + s.len()); + } + + // try to add items to the vector, returning if items were added + FASTFLOAT_CONSTEXPR20 bool try_extend(limb_span s) noexcept { + if (len() + s.len() <= capacity()) { + extend_unchecked(s); + return true; + } else { + return false; + } + } + + // resize the vector, without bounds checking + // if the new size is longer than the vector, assign value to each + // appended item. + FASTFLOAT_CONSTEXPR20 + void resize_unchecked(size_t new_len, limb value) noexcept { + if (new_len > len()) { + size_t count = new_len - len(); + limb *first = data + len(); + limb *last = first + count; + tinyobj_ff::fill(first, last, value); + set_len(new_len); + } else { + set_len(new_len); + } + } + + // try to resize the vector, returning if the vector was resized. + FASTFLOAT_CONSTEXPR20 bool try_resize(size_t new_len, limb value) noexcept { + if (new_len > capacity()) { + return false; + } else { + resize_unchecked(new_len, value); + return true; + } + } + + // check if any limbs are non-zero after the given index. + // this needs to be done in reverse order, since the index + // is relative to the most significant limbs. + FASTFLOAT_CONSTEXPR14 bool nonzero(size_t index) const noexcept { + while (index < len()) { + if (rindex(index) != 0) { + return true; + } + index++; + } + return false; + } + + // normalize the big integer, so most-significant zero limbs are removed. + FASTFLOAT_CONSTEXPR14 void normalize() noexcept { + while (len() > 0 && rindex(0) == 0) { + length--; + } + } +}; + +fastfloat_really_inline FASTFLOAT_CONSTEXPR14 uint64_t +empty_hi64(bool &truncated) noexcept { + truncated = false; + return 0; +} + +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 uint64_t +uint64_hi64(uint64_t r0, bool &truncated) noexcept { + truncated = false; + int shl = leading_zeroes(r0); + return r0 << shl; +} + +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 uint64_t +uint64_hi64(uint64_t r0, uint64_t r1, bool &truncated) noexcept { + int shl = leading_zeroes(r0); + if (shl == 0) { + truncated = r1 != 0; + return r0; + } else { + int shr = 64 - shl; + truncated = (r1 << shl) != 0; + return (r0 << shl) | (r1 >> shr); + } +} + +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 uint64_t +uint32_hi64(uint32_t r0, bool &truncated) noexcept { + return uint64_hi64(r0, truncated); +} + +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 uint64_t +uint32_hi64(uint32_t r0, uint32_t r1, bool &truncated) noexcept { + uint64_t x0 = r0; + uint64_t x1 = r1; + return uint64_hi64((x0 << 32) | x1, truncated); +} + +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 uint64_t +uint32_hi64(uint32_t r0, uint32_t r1, uint32_t r2, bool &truncated) noexcept { + uint64_t x0 = r0; + uint64_t x1 = r1; + uint64_t x2 = r2; + return uint64_hi64(x0, (x1 << 32) | x2, truncated); +} + +// add two small integers, checking for overflow. +// we want an efficient operation. for msvc, where +// we don't have built-in intrinsics, this is still +// pretty fast. +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 limb +scalar_add(limb x, limb y, bool &overflow) noexcept { + limb z; +// gcc and clang +#if defined(__has_builtin) +#if __has_builtin(__builtin_add_overflow) + if (!cpp20_and_in_constexpr()) { + overflow = __builtin_add_overflow(x, y, &z); + return z; + } +#endif +#endif + + // generic, this still optimizes correctly on MSVC. + z = x + y; + overflow = z < x; + return z; +} + +// multiply two small integers, getting both the high and low bits. +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 limb +scalar_mul(limb x, limb y, limb &carry) noexcept { +#ifdef FASTFLOAT_64BIT_LIMB +#if defined(__SIZEOF_INT128__) + // GCC and clang both define it as an extension. + __uint128_t z = __uint128_t(x) * __uint128_t(y) + __uint128_t(carry); + carry = limb(z >> limb_bits); + return limb(z); +#else + // fallback, no native 128-bit integer multiplication with carry. + // on msvc, this optimizes identically, somehow. + value128 z = full_multiplication(x, y); + bool overflow; + z.low = scalar_add(z.low, carry, overflow); + z.high += uint64_t(overflow); // cannot overflow + carry = z.high; + return z.low; +#endif +#else + uint64_t z = uint64_t(x) * uint64_t(y) + uint64_t(carry); + carry = limb(z >> limb_bits); + return limb(z); +#endif +} + +// add scalar value to bigint starting from offset. +// used in grade school multiplication +template +inline FASTFLOAT_CONSTEXPR20 bool small_add_from(stackvec &vec, limb y, + size_t start) noexcept { + size_t index = start; + limb carry = y; + bool overflow; + while (carry != 0 && index < vec.len()) { + vec[index] = scalar_add(vec[index], carry, overflow); + carry = limb(overflow); + index += 1; + } + if (carry != 0) { + FASTFLOAT_TRY(vec.try_push(carry)); + } + return true; +} + +// add scalar value to bigint. +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 bool +small_add(stackvec &vec, limb y) noexcept { + return small_add_from(vec, y, 0); +} + +// multiply bigint by scalar value. +template +inline FASTFLOAT_CONSTEXPR20 bool small_mul(stackvec &vec, + limb y) noexcept { + limb carry = 0; + for (size_t index = 0; index < vec.len(); index++) { + vec[index] = scalar_mul(vec[index], y, carry); + } + if (carry != 0) { + FASTFLOAT_TRY(vec.try_push(carry)); + } + return true; +} + +// add bigint to bigint starting from index. +// used in grade school multiplication +template +FASTFLOAT_CONSTEXPR20 bool large_add_from(stackvec &x, limb_span y, + size_t start) noexcept { + // the effective x buffer is from `xstart..x.len()`, so exit early + // if we can't get that current range. + if (x.len() < start || y.len() > x.len() - start) { + FASTFLOAT_TRY(x.try_resize(y.len() + start, 0)); + } + + bool carry = false; + for (size_t index = 0; index < y.len(); index++) { + limb xi = x[index + start]; + limb yi = y[index]; + bool c1 = false; + bool c2 = false; + xi = scalar_add(xi, yi, c1); + if (carry) { + xi = scalar_add(xi, 1, c2); + } + x[index + start] = xi; + carry = c1 | c2; + } + + // handle overflow + if (carry) { + FASTFLOAT_TRY(small_add_from(x, 1, y.len() + start)); + } + return true; +} + +// add bigint to bigint. +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 bool +large_add_from(stackvec &x, limb_span y) noexcept { + return large_add_from(x, y, 0); +} + +// grade-school multiplication algorithm +template +FASTFLOAT_CONSTEXPR20 bool long_mul(stackvec &x, limb_span y) noexcept { + limb_span xs = limb_span(x.data, x.len()); + stackvec z(xs); + limb_span zs = limb_span(z.data, z.len()); + + if (y.len() != 0) { + limb y0 = y[0]; + FASTFLOAT_TRY(small_mul(x, y0)); + for (size_t index = 1; index < y.len(); index++) { + limb yi = y[index]; + stackvec zi; + if (yi != 0) { + // re-use the same buffer throughout + zi.set_len(0); + FASTFLOAT_TRY(zi.try_extend(zs)); + FASTFLOAT_TRY(small_mul(zi, yi)); + limb_span zis = limb_span(zi.data, zi.len()); + FASTFLOAT_TRY(large_add_from(x, zis, index)); + } + } + } + + x.normalize(); + return true; +} + +// grade-school multiplication algorithm +template +FASTFLOAT_CONSTEXPR20 bool large_mul(stackvec &x, limb_span y) noexcept { + if (y.len() == 1) { + FASTFLOAT_TRY(small_mul(x, y[0])); + } else { + FASTFLOAT_TRY(long_mul(x, y)); + } + return true; +} + +template struct pow5_tables { + static constexpr uint32_t large_step = 135; + static constexpr uint64_t small_power_of_5[] = { + 1UL, + 5UL, + 25UL, + 125UL, + 625UL, + 3125UL, + 15625UL, + 78125UL, + 390625UL, + 1953125UL, + 9765625UL, + 48828125UL, + 244140625UL, + 1220703125UL, + 6103515625UL, + 30517578125UL, + 152587890625UL, + 762939453125UL, + 3814697265625UL, + 19073486328125UL, + 95367431640625UL, + 476837158203125UL, + 2384185791015625UL, + 11920928955078125UL, + 59604644775390625UL, + 298023223876953125UL, + 1490116119384765625UL, + 7450580596923828125UL, + }; +#ifdef FASTFLOAT_64BIT_LIMB + constexpr static limb large_power_of_5[] = { + 1414648277510068013UL, 9180637584431281687UL, 4539964771860779200UL, + 10482974169319127550UL, 198276706040285095UL}; +#else + constexpr static limb large_power_of_5[] = { + 4279965485U, 329373468U, 4020270615U, 2137533757U, 4287402176U, + 1057042919U, 1071430142U, 2440757623U, 381945767U, 46164893U}; +#endif +}; + +#if FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE + +template constexpr uint32_t pow5_tables::large_step; + +template constexpr uint64_t pow5_tables::small_power_of_5[]; + +template constexpr limb pow5_tables::large_power_of_5[]; + +#endif + +// big integer type. implements a small subset of big integer +// arithmetic, using simple algorithms since asymptotically +// faster algorithms are slower for a small number of limbs. +// all operations assume the big-integer is normalized. +struct bigint : pow5_tables<> { + // storage of the limbs, in little-endian order. + stackvec vec; + + FASTFLOAT_CONSTEXPR20 bigint() : vec() {} + + bigint(bigint const &) = delete; + bigint &operator=(bigint const &) = delete; + bigint(bigint &&) = delete; + bigint &operator=(bigint &&other) = delete; + + FASTFLOAT_CONSTEXPR20 bigint(uint64_t value) : vec() { +#ifdef FASTFLOAT_64BIT_LIMB + vec.push_unchecked(value); +#else + vec.push_unchecked(uint32_t(value)); + vec.push_unchecked(uint32_t(value >> 32)); +#endif + vec.normalize(); + } + + // get the high 64 bits from the vector, and if bits were truncated. + // this is to get the significant digits for the float. + FASTFLOAT_CONSTEXPR20 uint64_t hi64(bool &truncated) const noexcept { +#ifdef FASTFLOAT_64BIT_LIMB + if (vec.len() == 0) { + return empty_hi64(truncated); + } else if (vec.len() == 1) { + return uint64_hi64(vec.rindex(0), truncated); + } else { + uint64_t result = uint64_hi64(vec.rindex(0), vec.rindex(1), truncated); + truncated |= vec.nonzero(2); + return result; + } +#else + if (vec.len() == 0) { + return empty_hi64(truncated); + } else if (vec.len() == 1) { + return uint32_hi64(vec.rindex(0), truncated); + } else if (vec.len() == 2) { + return uint32_hi64(vec.rindex(0), vec.rindex(1), truncated); + } else { + uint64_t result = + uint32_hi64(vec.rindex(0), vec.rindex(1), vec.rindex(2), truncated); + truncated |= vec.nonzero(3); + return result; + } +#endif + } + + // compare two big integers, returning the large value. + // assumes both are normalized. if the return value is + // negative, other is larger, if the return value is + // positive, this is larger, otherwise they are equal. + // the limbs are stored in little-endian order, so we + // must compare the limbs in ever order. + FASTFLOAT_CONSTEXPR20 int compare(bigint const &other) const noexcept { + if (vec.len() > other.vec.len()) { + return 1; + } else if (vec.len() < other.vec.len()) { + return -1; + } else { + for (size_t index = vec.len(); index > 0; index--) { + limb xi = vec[index - 1]; + limb yi = other.vec[index - 1]; + if (xi > yi) { + return 1; + } else if (xi < yi) { + return -1; + } + } + return 0; + } + } + + // shift left each limb n bits, carrying over to the new limb + // returns true if we were able to shift all the digits. + FASTFLOAT_CONSTEXPR20 bool shl_bits(size_t n) noexcept { + // Internally, for each item, we shift left by n, and add the previous + // right shifted limb-bits. + // For example, we transform (for u8) shifted left 2, to: + // b10100100 b01000010 + // b10 b10010001 b00001000 + FASTFLOAT_DEBUG_ASSERT(n != 0); + FASTFLOAT_DEBUG_ASSERT(n < sizeof(limb) * 8); + + size_t shl = n; + size_t shr = limb_bits - shl; + limb prev = 0; + for (size_t index = 0; index < vec.len(); index++) { + limb xi = vec[index]; + vec[index] = (xi << shl) | (prev >> shr); + prev = xi; + } + + limb carry = prev >> shr; + if (carry != 0) { + return vec.try_push(carry); + } + return true; + } + + // move the limbs left by `n` limbs. + FASTFLOAT_CONSTEXPR20 bool shl_limbs(size_t n) noexcept { + FASTFLOAT_DEBUG_ASSERT(n != 0); + if (n + vec.len() > vec.capacity()) { + return false; + } else if (!vec.is_empty()) { + // move limbs + limb *dst = vec.data + n; + limb const *src = vec.data; + tinyobj_ff::copy_backward(src, src + vec.len(), dst + vec.len()); + // fill in empty limbs + limb *first = vec.data; + limb *last = first + n; + tinyobj_ff::fill(first, last, 0); + vec.set_len(n + vec.len()); + return true; + } else { + return true; + } + } + + // move the limbs left by `n` bits. + FASTFLOAT_CONSTEXPR20 bool shl(size_t n) noexcept { + size_t rem = n % limb_bits; + size_t div = n / limb_bits; + if (rem != 0) { + FASTFLOAT_TRY(shl_bits(rem)); + } + if (div != 0) { + FASTFLOAT_TRY(shl_limbs(div)); + } + return true; + } + + // get the number of leading zeros in the bigint. + FASTFLOAT_CONSTEXPR20 int ctlz() const noexcept { + if (vec.is_empty()) { + return 0; + } else { +#ifdef FASTFLOAT_64BIT_LIMB + return leading_zeroes(vec.rindex(0)); +#else + // no use defining a specialized leading_zeroes for a 32-bit type. + uint64_t r0 = vec.rindex(0); + return leading_zeroes(r0 << 32); +#endif + } + } + + // get the number of bits in the bigint. + FASTFLOAT_CONSTEXPR20 int bit_length() const noexcept { + int lz = ctlz(); + return int(limb_bits * vec.len()) - lz; + } + + FASTFLOAT_CONSTEXPR20 bool mul(limb y) noexcept { return small_mul(vec, y); } + + FASTFLOAT_CONSTEXPR20 bool add(limb y) noexcept { return small_add(vec, y); } + + // multiply as if by 2 raised to a power. + FASTFLOAT_CONSTEXPR20 bool pow2(uint32_t exp) noexcept { return shl(exp); } + + // multiply as if by 5 raised to a power. + FASTFLOAT_CONSTEXPR20 bool pow5(uint32_t exp) noexcept { + // multiply by a power of 5 + size_t large_length = sizeof(large_power_of_5) / sizeof(limb); + limb_span large = limb_span(large_power_of_5, large_length); + while (exp >= large_step) { + FASTFLOAT_TRY(large_mul(vec, large)); + exp -= large_step; + } +#ifdef FASTFLOAT_64BIT_LIMB + uint32_t small_step = 27; + limb max_native = 7450580596923828125UL; +#else + uint32_t small_step = 13; + limb max_native = 1220703125U; +#endif + while (exp >= small_step) { + FASTFLOAT_TRY(small_mul(vec, max_native)); + exp -= small_step; + } + if (exp != 0) { + // Work around clang bug https://godbolt.org/z/zedh7rrhc + // This is similar to https://github.com/llvm/llvm-project/issues/47746, + // except the workaround described there don't work here + FASTFLOAT_TRY(small_mul( + vec, limb(((void)small_power_of_5[0], small_power_of_5[exp])))); + } + + return true; + } + + // multiply as if by 10 raised to a power. + FASTFLOAT_CONSTEXPR20 bool pow10(uint32_t exp) noexcept { + FASTFLOAT_TRY(pow5(exp)); + return pow2(exp); + } +}; + +} // namespace fast_float + +#endif + +#ifndef FASTFLOAT_DIGIT_COMPARISON_H +#define FASTFLOAT_DIGIT_COMPARISON_H + +#include + + +namespace fast_float { + +// 1e0 to 1e19 +constexpr static uint64_t powers_of_ten_uint64[] = {1UL, + 10UL, + 100UL, + 1000UL, + 10000UL, + 100000UL, + 1000000UL, + 10000000UL, + 100000000UL, + 1000000000UL, + 10000000000UL, + 100000000000UL, + 1000000000000UL, + 10000000000000UL, + 100000000000000UL, + 1000000000000000UL, + 10000000000000000UL, + 100000000000000000UL, + 1000000000000000000UL, + 10000000000000000000UL}; + +// calculate the exponent, in scientific notation, of the number. +// this algorithm is not even close to optimized, but it has no practical +// effect on performance: in order to have a faster algorithm, we'd need +// to slow down performance for faster algorithms, and this is still fast. +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR14 int32_t +scientific_exponent(parsed_number_string_t &num) noexcept { + uint64_t mantissa = num.mantissa; + int32_t exponent = int32_t(num.exponent); + while (mantissa >= 10000) { + mantissa /= 10000; + exponent += 4; + } + while (mantissa >= 100) { + mantissa /= 100; + exponent += 2; + } + while (mantissa >= 10) { + mantissa /= 10; + exponent += 1; + } + return exponent; +} + +// this converts a native floating-point number to an extended-precision float. +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa +to_extended(T value) noexcept { + using equiv_uint = equiv_uint_t; + constexpr equiv_uint exponent_mask = binary_format::exponent_mask(); + constexpr equiv_uint mantissa_mask = binary_format::mantissa_mask(); + constexpr equiv_uint hidden_bit_mask = binary_format::hidden_bit_mask(); + + adjusted_mantissa am; + int32_t bias = binary_format::mantissa_explicit_bits() - + binary_format::minimum_exponent(); + equiv_uint bits; +#if FASTFLOAT_HAS_BIT_CAST + bits = std::bit_cast(value); +#else + ::memcpy(&bits, &value, sizeof(T)); +#endif + if ((bits & exponent_mask) == 0) { + // denormal + am.power2 = 1 - bias; + am.mantissa = bits & mantissa_mask; + } else { + // normal + am.power2 = int32_t((bits & exponent_mask) >> + binary_format::mantissa_explicit_bits()); + am.power2 -= bias; + am.mantissa = (bits & mantissa_mask) | hidden_bit_mask; + } + + return am; +} + +// get the extended precision value of the halfway point between b and b+u. +// we are given a native float that represents b, so we need to adjust it +// halfway between b and b+u. +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa +to_extended_halfway(T value) noexcept { + adjusted_mantissa am = to_extended(value); + am.mantissa <<= 1; + am.mantissa += 1; + am.power2 -= 1; + return am; +} + +// round an extended-precision float to the nearest machine float. +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR14 void round(adjusted_mantissa &am, + callback cb) noexcept { + int32_t mantissa_shift = 64 - binary_format::mantissa_explicit_bits() - 1; + if (-am.power2 >= mantissa_shift) { + // have a denormal float + int32_t shift = -am.power2 + 1; + cb(am, tinyobj_ff::min_val(shift, 64)); + // check for round-up: if rounding-nearest carried us to the hidden bit. + am.power2 = (am.mantissa < + (uint64_t(1) << binary_format::mantissa_explicit_bits())) + ? 0 + : 1; + return; + } + + // have a normal float, use the default shift. + cb(am, mantissa_shift); + + // check for carry + if (am.mantissa >= + (uint64_t(2) << binary_format::mantissa_explicit_bits())) { + am.mantissa = (uint64_t(1) << binary_format::mantissa_explicit_bits()); + am.power2++; + } + + // check for infinite: we could have carried to an infinite power + am.mantissa &= ~(uint64_t(1) << binary_format::mantissa_explicit_bits()); + if (am.power2 >= binary_format::infinite_power()) { + am.power2 = binary_format::infinite_power(); + am.mantissa = 0; + } +} + +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR14 void +round_nearest_tie_even(adjusted_mantissa &am, int32_t shift, + callback cb) noexcept { + uint64_t const mask = (shift == 64) ? UINT64_MAX : (uint64_t(1) << shift) - 1; + uint64_t const halfway = (shift == 0) ? 0 : uint64_t(1) << (shift - 1); + uint64_t truncated_bits = am.mantissa & mask; + bool is_above = truncated_bits > halfway; + bool is_halfway = truncated_bits == halfway; + + // shift digits into position + if (shift == 64) { + am.mantissa = 0; + } else { + am.mantissa >>= shift; + } + am.power2 += shift; + + bool is_odd = (am.mantissa & 1) == 1; + am.mantissa += uint64_t(cb(is_odd, is_halfway, is_above)); +} + +fastfloat_really_inline FASTFLOAT_CONSTEXPR14 void +round_down(adjusted_mantissa &am, int32_t shift) noexcept { + if (shift == 64) { + am.mantissa = 0; + } else { + am.mantissa >>= shift; + } + am.power2 += shift; +} + +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void +skip_zeros(UC const *&first, UC const *last) noexcept { + uint64_t val; + while (!cpp20_and_in_constexpr() && + tinyobj_ff::distance(first, last) >= int_cmp_len()) { + ::memcpy(&val, first, sizeof(uint64_t)); + if (val != int_cmp_zeros()) { + break; + } + first += int_cmp_len(); + } + while (first != last) { + if (*first != UC('0')) { + break; + } + first++; + } +} + +// determine if any non-zero digits were truncated. +// all characters must be valid digits. +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 bool +is_truncated(UC const *first, UC const *last) noexcept { + // do 8-bit optimizations, can just compare to 8 literal 0s. + uint64_t val; + while (!cpp20_and_in_constexpr() && + tinyobj_ff::distance(first, last) >= int_cmp_len()) { + ::memcpy(&val, first, sizeof(uint64_t)); + if (val != int_cmp_zeros()) { + return true; + } + first += int_cmp_len(); + } + while (first != last) { + if (*first != UC('0')) { + return true; + } + ++first; + } + return false; +} + +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 bool +is_truncated(span s) noexcept { + return is_truncated(s.ptr, s.ptr + s.len()); +} + +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void +parse_eight_digits(UC const *&p, limb &value, size_t &counter, + size_t &count) noexcept { + value = value * 100000000 + parse_eight_digits_unrolled(p); + p += 8; + counter += 8; + count += 8; +} + +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR14 void +parse_one_digit(UC const *&p, limb &value, size_t &counter, + size_t &count) noexcept { + value = value * 10 + limb(*p - UC('0')); + p++; + counter++; + count++; +} + +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void +add_native(bigint &big, limb power, limb value) noexcept { + big.mul(power); + big.add(value); +} + +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void +round_up_bigint(bigint &big, size_t &count) noexcept { + // need to round-up the digits, but need to avoid rounding + // ....9999 to ...10000, which could cause a false halfway point. + add_native(big, 10, 1); + count++; +} + +// parse the significant digits into a big integer +template +inline FASTFLOAT_CONSTEXPR20 void +parse_mantissa(bigint &result, parsed_number_string_t &num, + size_t max_digits, size_t &digits) noexcept { + // try to minimize the number of big integer and scalar multiplication. + // therefore, try to parse 8 digits at a time, and multiply by the largest + // scalar value (9 or 19 digits) for each step. + size_t counter = 0; + digits = 0; + limb value = 0; +#ifdef FASTFLOAT_64BIT_LIMB + size_t step = 19; +#else + size_t step = 9; +#endif + + // process all integer digits. + UC const *p = num.integer.ptr; + UC const *pend = p + num.integer.len(); + skip_zeros(p, pend); + // process all digits, in increments of step per loop + while (p != pend) { + while ((tinyobj_ff::distance(p, pend) >= 8) && (step - counter >= 8) && + (max_digits - digits >= 8)) { + parse_eight_digits(p, value, counter, digits); + } + while (counter < step && p != pend && digits < max_digits) { + parse_one_digit(p, value, counter, digits); + } + if (digits == max_digits) { + // add the temporary value, then check if we've truncated any digits + add_native(result, limb(powers_of_ten_uint64[counter]), value); + bool truncated = is_truncated(p, pend); + if (num.fraction.ptr != nullptr) { + truncated |= is_truncated(num.fraction); + } + if (truncated) { + round_up_bigint(result, digits); + } + return; + } else { + add_native(result, limb(powers_of_ten_uint64[counter]), value); + counter = 0; + value = 0; + } + } + + // add our fraction digits, if they're available. + if (num.fraction.ptr != nullptr) { + p = num.fraction.ptr; + pend = p + num.fraction.len(); + if (digits == 0) { + skip_zeros(p, pend); + } + // process all digits, in increments of step per loop + while (p != pend) { + while ((tinyobj_ff::distance(p, pend) >= 8) && (step - counter >= 8) && + (max_digits - digits >= 8)) { + parse_eight_digits(p, value, counter, digits); + } + while (counter < step && p != pend && digits < max_digits) { + parse_one_digit(p, value, counter, digits); + } + if (digits == max_digits) { + // add the temporary value, then check if we've truncated any digits + add_native(result, limb(powers_of_ten_uint64[counter]), value); + bool truncated = is_truncated(p, pend); + if (truncated) { + round_up_bigint(result, digits); + } + return; + } else { + add_native(result, limb(powers_of_ten_uint64[counter]), value); + counter = 0; + value = 0; + } + } + } + + if (counter != 0) { + add_native(result, limb(powers_of_ten_uint64[counter]), value); + } +} + +template +inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa +positive_digit_comp(bigint &bigmant, int32_t exponent) noexcept { + FASTFLOAT_ASSERT(bigmant.pow10(uint32_t(exponent))); + adjusted_mantissa answer; + bool truncated; + answer.mantissa = bigmant.hi64(truncated); + int bias = binary_format::mantissa_explicit_bits() - + binary_format::minimum_exponent(); + answer.power2 = bigmant.bit_length() - 64 + bias; + + round(answer, [truncated](adjusted_mantissa &a, int32_t shift) { + round_nearest_tie_even( + a, shift, + [truncated](bool is_odd, bool is_halfway, bool is_above) -> bool { + return is_above || (is_halfway && truncated) || + (is_odd && is_halfway); + }); + }); + + return answer; +} + +// the scaling here is quite simple: we have, for the real digits `m * 10^e`, +// and for the theoretical digits `n * 2^f`. Since `e` is always negative, +// to scale them identically, we do `n * 2^f * 5^-f`, so we now have `m * 2^e`. +// we then need to scale by `2^(f- e)`, and then the two significant digits +// are of the same magnitude. +template +inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa negative_digit_comp( + bigint &bigmant, adjusted_mantissa am, int32_t exponent) noexcept { + bigint &real_digits = bigmant; + int32_t real_exp = exponent; + + // get the value of `b`, rounded down, and get a bigint representation of b+h + adjusted_mantissa am_b = am; + // gcc7 buf: use a lambda to remove the noexcept qualifier bug with + // -Wnoexcept-type. + round(am_b, + [](adjusted_mantissa &a, int32_t shift) { round_down(a, shift); }); + T b; + to_float(false, am_b, b); + adjusted_mantissa theor = to_extended_halfway(b); + bigint theor_digits(theor.mantissa); + int32_t theor_exp = theor.power2; + + // scale real digits and theor digits to be same power. + int32_t pow2_exp = theor_exp - real_exp; + uint32_t pow5_exp = uint32_t(-real_exp); + if (pow5_exp != 0) { + FASTFLOAT_ASSERT(theor_digits.pow5(pow5_exp)); + } + if (pow2_exp > 0) { + FASTFLOAT_ASSERT(theor_digits.pow2(uint32_t(pow2_exp))); + } else if (pow2_exp < 0) { + FASTFLOAT_ASSERT(real_digits.pow2(uint32_t(-pow2_exp))); + } + + // compare digits, and use it to director rounding + int ord = real_digits.compare(theor_digits); + adjusted_mantissa answer = am; + round(answer, [ord](adjusted_mantissa &a, int32_t shift) { + round_nearest_tie_even( + a, shift, [ord](bool is_odd, bool _, bool __) -> bool { + (void)_; // not needed, since we've done our comparison + (void)__; // not needed, since we've done our comparison + if (ord > 0) { + return true; + } else if (ord < 0) { + return false; + } else { + return is_odd; + } + }); + }); + + return answer; +} + +// parse the significant digits as a big integer to unambiguously round the +// the significant digits. here, we are trying to determine how to round +// an extended float representation close to `b+h`, halfway between `b` +// (the float rounded-down) and `b+u`, the next positive float. this +// algorithm is always correct, and uses one of two approaches. when +// the exponent is positive relative to the significant digits (such as +// 1234), we create a big-integer representation, get the high 64-bits, +// determine if any lower bits are truncated, and use that to direct +// rounding. in case of a negative exponent relative to the significant +// digits (such as 1.2345), we create a theoretical representation of +// `b` as a big-integer type, scaled to the same binary exponent as +// the actual digits. we then compare the big integer representations +// of both, and use that to direct rounding. +template +inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa +digit_comp(parsed_number_string_t &num, adjusted_mantissa am) noexcept { + // remove the invalid exponent bias + am.power2 -= invalid_am_bias; + + int32_t sci_exp = scientific_exponent(num); + size_t max_digits = binary_format::max_digits(); + size_t digits = 0; + bigint bigmant; + parse_mantissa(bigmant, num, max_digits, digits); + // can't underflow, since digits is at most max_digits. + int32_t exponent = sci_exp + 1 - int32_t(digits); + if (exponent >= 0) { + return positive_digit_comp(bigmant, exponent); + } else { + return negative_digit_comp(bigmant, am, exponent); + } +} + +} // namespace fast_float + +#endif + +#ifndef FASTFLOAT_PARSE_NUMBER_H +#define FASTFLOAT_PARSE_NUMBER_H + + +#include +#include +#include + +namespace fast_float { + +namespace detail { +/** + * Special case +inf, -inf, nan, infinity, -infinity. + * The case comparisons could be made much faster given that we know that the + * strings a null-free and fixed. + **/ +template +from_chars_result_t + FASTFLOAT_CONSTEXPR14 parse_infnan(UC const *first, UC const *last, + T &value, chars_format fmt) noexcept { + from_chars_result_t answer{}; + answer.ptr = first; + answer.ec = tinyobj_ff::ff_errc(); // be optimistic + // assume first < last, so dereference without checks; + bool const minusSign = (*first == UC('-')); + // C++17 20.19.3.(7.1) explicitly forbids '+' sign here + if ((*first == UC('-')) || + (uint64_t(fmt & chars_format::allow_leading_plus) && + (*first == UC('+')))) { + ++first; + } + if (last - first >= 3) { + if (fastfloat_strncasecmp(first, str_const_nan(), 3)) { + answer.ptr = (first += 3); + value = minusSign ? -std::numeric_limits::quiet_NaN() + : std::numeric_limits::quiet_NaN(); + // Check for possible nan(n-char-seq-opt), C++17 20.19.3.7, + // C11 7.20.1.3.3. At least MSVC produces nan(ind) and nan(snan). + if (first != last && *first == UC('(')) { + for (UC const *ptr = first + 1; ptr != last; ++ptr) { + if (*ptr == UC(')')) { + answer.ptr = ptr + 1; // valid nan(n-char-seq-opt) + break; + } else if (!((UC('a') <= *ptr && *ptr <= UC('z')) || + (UC('A') <= *ptr && *ptr <= UC('Z')) || + (UC('0') <= *ptr && *ptr <= UC('9')) || *ptr == UC('_'))) + break; // forbidden char, not nan(n-char-seq-opt) + } + } + return answer; + } + if (fastfloat_strncasecmp(first, str_const_inf(), 3)) { + if ((last - first >= 8) && + fastfloat_strncasecmp(first + 3, str_const_inf() + 3, 5)) { + answer.ptr = first + 8; + } else { + answer.ptr = first + 3; + } + value = minusSign ? -std::numeric_limits::infinity() + : std::numeric_limits::infinity(); + return answer; + } + } + answer.ec = tinyobj_ff::ff_errc::invalid_argument; + return answer; +} + +/** + * Returns true if the floating-pointing rounding mode is to 'nearest'. + * It is the default on most system. This function is meant to be inexpensive. + * Credit : @mwalcott3 + */ +fastfloat_really_inline bool rounds_to_nearest() noexcept { + // https://lemire.me/blog/2020/06/26/gcc-not-nearest/ +#if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0) + return false; +#endif + // See + // A fast function to check your floating-point rounding mode + // https://lemire.me/blog/2022/11/16/a-fast-function-to-check-your-floating-point-rounding-mode/ + // + // This function is meant to be equivalent to : + // prior: #include + // return fegetround() == FE_TONEAREST; + // However, it is expected to be much faster than the fegetround() + // function call. + // + // The volatile keyword prevents the compiler from computing the function + // at compile-time. + // There might be other ways to prevent compile-time optimizations (e.g., + // asm). The value does not need to be std::numeric_limits::min(), any + // small value so that 1 + x should round to 1 would do (after accounting for + // excess precision, as in 387 instructions). + static float volatile fmin = std::numeric_limits::min(); + float fmini = fmin; // we copy it so that it gets loaded at most once. +// +// Explanation: +// Only when fegetround() == FE_TONEAREST do we have that +// fmin + 1.0f == 1.0f - fmin. +// +// FE_UPWARD: +// fmin + 1.0f > 1 +// 1.0f - fmin == 1 +// +// FE_DOWNWARD or FE_TOWARDZERO: +// fmin + 1.0f == 1 +// 1.0f - fmin < 1 +// +// Note: This may fail to be accurate if fast-math has been +// enabled, as rounding conventions may not apply. +#ifdef FASTFLOAT_VISUAL_STUDIO +#pragma warning(push) +// todo: is there a VS warning? +// see +// https://stackoverflow.com/questions/46079446/is-there-a-warning-for-floating-point-equality-checking-in-visual-studio-2013 +#elif defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wfloat-equal" +#elif defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wfloat-equal" +#endif + return (fmini + 1.0f == 1.0f - fmini); +#ifdef FASTFLOAT_VISUAL_STUDIO +#pragma warning(pop) +#elif defined(__clang__) +#pragma clang diagnostic pop +#elif defined(__GNUC__) +#pragma GCC diagnostic pop +#endif +} + +} // namespace detail + +template struct from_chars_caller { + template + FASTFLOAT_CONSTEXPR20 static from_chars_result_t + call(UC const *first, UC const *last, T &value, + parse_options_t options) noexcept { + return from_chars_advanced(first, last, value, options); + } +}; + +#ifdef __STDCPP_FLOAT32_T__ +template <> struct from_chars_caller { + template + FASTFLOAT_CONSTEXPR20 static from_chars_result_t + call(UC const *first, UC const *last, std::float32_t &value, + parse_options_t options) noexcept { + // if std::float32_t is defined, and we are in C++23 mode; macro set for + // float32; set value to float due to equivalence between float and + // float32_t + float val; + auto ret = from_chars_advanced(first, last, val, options); + value = val; + return ret; + } +}; +#endif + +#ifdef __STDCPP_FLOAT64_T__ +template <> struct from_chars_caller { + template + FASTFLOAT_CONSTEXPR20 static from_chars_result_t + call(UC const *first, UC const *last, std::float64_t &value, + parse_options_t options) noexcept { + // if std::float64_t is defined, and we are in C++23 mode; macro set for + // float64; set value as double due to equivalence between double and + // float64_t + double val; + auto ret = from_chars_advanced(first, last, val, options); + value = val; + return ret; + } +}; +#endif + +template +FASTFLOAT_CONSTEXPR20 from_chars_result_t +from_chars(UC const *first, UC const *last, T &value, + chars_format fmt /*= chars_format::general*/) noexcept { + return from_chars_caller::call(first, last, value, + parse_options_t(fmt)); +} + +/** + * This function overload takes parsed_number_string_t structure that is created + * and populated either by from_chars_advanced function taking chars range and + * parsing options or other parsing custom function implemented by user. + */ +template +FASTFLOAT_CONSTEXPR20 from_chars_result_t +from_chars_advanced(parsed_number_string_t &pns, T &value) noexcept { + + static_assert(is_supported_float_type::value, + "only some floating-point types are supported"); + static_assert(is_supported_char_type::value, + "only char, wchar_t, char16_t and char32_t are supported"); + + from_chars_result_t answer; + + answer.ec = tinyobj_ff::ff_errc(); // be optimistic + answer.ptr = pns.lastmatch; + // The implementation of the Clinger's fast path is convoluted because + // we want round-to-nearest in all cases, irrespective of the rounding mode + // selected on the thread. + // We proceed optimistically, assuming that detail::rounds_to_nearest() + // returns true. + if (binary_format::min_exponent_fast_path() <= pns.exponent && + pns.exponent <= binary_format::max_exponent_fast_path() && + !pns.too_many_digits) { + // Unfortunately, the conventional Clinger's fast path is only possible + // when the system rounds to the nearest float. + // + // We expect the next branch to almost always be selected. + // We could check it first (before the previous branch), but + // there might be performance advantages at having the check + // be last. + if (!cpp20_and_in_constexpr() && detail::rounds_to_nearest()) { + // We have that fegetround() == FE_TONEAREST. + // Next is Clinger's fast path. + if (pns.mantissa <= binary_format::max_mantissa_fast_path()) { + value = T(pns.mantissa); + if (pns.exponent < 0) { + value = value / binary_format::exact_power_of_ten(-pns.exponent); + } else { + value = value * binary_format::exact_power_of_ten(pns.exponent); + } + if (pns.negative) { + value = -value; + } + return answer; + } + } else { + // We do not have that fegetround() == FE_TONEAREST. + // Next is a modified Clinger's fast path, inspired by Jakub Jelínek's + // proposal + if (pns.exponent >= 0 && + pns.mantissa <= + binary_format::max_mantissa_fast_path(pns.exponent)) { +#if defined(__clang__) || defined(FASTFLOAT_32BIT) + // Clang may map 0 to -0.0 when fegetround() == FE_DOWNWARD + if (pns.mantissa == 0) { + value = pns.negative ? T(-0.) : T(0.); + return answer; + } +#endif + value = T(pns.mantissa) * + binary_format::exact_power_of_ten(pns.exponent); + if (pns.negative) { + value = -value; + } + return answer; + } + } + } + adjusted_mantissa am = + compute_float>(pns.exponent, pns.mantissa); + if (pns.too_many_digits && am.power2 >= 0) { + if (am != compute_float>(pns.exponent, pns.mantissa + 1)) { + am = compute_error>(pns.exponent, pns.mantissa); + } + } + // If we called compute_float>(pns.exponent, pns.mantissa) + // and we have an invalid power (am.power2 < 0), then we need to go the long + // way around again. This is very uncommon. + if (am.power2 < 0) { + am = digit_comp(pns, am); + } + to_float(pns.negative, am, value); + // Test for over/underflow. + if ((pns.mantissa != 0 && am.mantissa == 0 && am.power2 == 0) || + am.power2 == binary_format::infinite_power()) { + answer.ec = tinyobj_ff::ff_errc::result_out_of_range; + } + return answer; +} + +template +FASTFLOAT_CONSTEXPR20 from_chars_result_t +from_chars_float_advanced(UC const *first, UC const *last, T &value, + parse_options_t options) noexcept { + + static_assert(is_supported_float_type::value, + "only some floating-point types are supported"); + static_assert(is_supported_char_type::value, + "only char, wchar_t, char16_t and char32_t are supported"); + + chars_format const fmt = detail::adjust_for_feature_macros(options.format); + + from_chars_result_t answer; + if (uint64_t(fmt & chars_format::skip_white_space)) { + while ((first != last) && fast_float::is_space(*first)) { + first++; + } + } + if (first == last) { + answer.ec = tinyobj_ff::ff_errc::invalid_argument; + answer.ptr = first; + return answer; + } + parsed_number_string_t pns = + uint64_t(fmt & detail::basic_json_fmt) + ? parse_number_string(first, last, options) + : parse_number_string(first, last, options); + if (!pns.valid) { + if (uint64_t(fmt & chars_format::no_infnan)) { + answer.ec = tinyobj_ff::ff_errc::invalid_argument; + answer.ptr = first; + return answer; + } else { + return detail::parse_infnan(first, last, value, fmt); + } + } + + // call overload that takes parsed_number_string_t directly. + return from_chars_advanced(pns, value); +} + +template +FASTFLOAT_CONSTEXPR20 from_chars_result_t +from_chars(UC const *first, UC const *last, T &value, int base) noexcept { + + static_assert(is_supported_integer_type::value, + "only integer types are supported"); + static_assert(is_supported_char_type::value, + "only char, wchar_t, char16_t and char32_t are supported"); + + parse_options_t options; + options.base = base; + return from_chars_advanced(first, last, value, options); +} + +template +FASTFLOAT_CONSTEXPR20 from_chars_result_t +from_chars_int_advanced(UC const *first, UC const *last, T &value, + parse_options_t options) noexcept { + + static_assert(is_supported_integer_type::value, + "only integer types are supported"); + static_assert(is_supported_char_type::value, + "only char, wchar_t, char16_t and char32_t are supported"); + + chars_format const fmt = detail::adjust_for_feature_macros(options.format); + int const base = options.base; + + from_chars_result_t answer; + if (uint64_t(fmt & chars_format::skip_white_space)) { + while ((first != last) && fast_float::is_space(*first)) { + first++; + } + } + if (first == last || base < 2 || base > 36) { + answer.ec = tinyobj_ff::ff_errc::invalid_argument; + answer.ptr = first; + return answer; + } + + return parse_int_string(first, last, value, options); +} + +template struct from_chars_advanced_caller { + static_assert(TypeIx > 0, "unsupported type"); +}; + +template <> struct from_chars_advanced_caller<1> { + template + FASTFLOAT_CONSTEXPR20 static from_chars_result_t + call(UC const *first, UC const *last, T &value, + parse_options_t options) noexcept { + return from_chars_float_advanced(first, last, value, options); + } +}; + +template <> struct from_chars_advanced_caller<2> { + template + FASTFLOAT_CONSTEXPR20 static from_chars_result_t + call(UC const *first, UC const *last, T &value, + parse_options_t options) noexcept { + return from_chars_int_advanced(first, last, value, options); + } +}; + +template +FASTFLOAT_CONSTEXPR20 from_chars_result_t +from_chars_advanced(UC const *first, UC const *last, T &value, + parse_options_t options) noexcept { + return from_chars_advanced_caller< + size_t(is_supported_float_type::value) + + 2 * size_t(is_supported_integer_type::value)>::call(first, last, value, + options); +} + +} // namespace fast_float + +#endif + + +// --- End embedded fast_float --- + +// Clean up fast_float macros to avoid polluting the user's namespace. +#undef FASTFLOAT_32BIT +#undef FASTFLOAT_32BIT_LIMB +#undef FASTFLOAT_64BIT +#undef FASTFLOAT_64BIT_LIMB +#undef FASTFLOAT_ASCII_NUMBER_H +#undef FASTFLOAT_ASSERT +#undef FASTFLOAT_BIGINT_H +#undef FASTFLOAT_CONSTEXPR14 +#undef FASTFLOAT_CONSTEXPR20 +#undef FASTFLOAT_CONSTEXPR_FEATURE_DETECT_H +#undef FASTFLOAT_DEBUG_ASSERT +#undef FASTFLOAT_DECIMAL_TO_BINARY_H +#undef FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE +#undef FASTFLOAT_DIGIT_COMPARISON_H +#undef FASTFLOAT_ENABLE_IF +#undef FASTFLOAT_FAST_FLOAT_H +#undef FASTFLOAT_FAST_TABLE_H +#undef FASTFLOAT_FLOAT_COMMON_H +#undef FASTFLOAT_HAS_BIT_CAST +#undef FASTFLOAT_HAS_IS_CONSTANT_EVALUATED +#undef FASTFLOAT_HAS_SIMD +#undef FASTFLOAT_IF_CONSTEXPR17 +#undef FASTFLOAT_IS_BIG_ENDIAN +#undef FASTFLOAT_IS_CONSTEXPR +#undef FASTFLOAT_NEON +#undef FASTFLOAT_PARSE_NUMBER_H +#undef fastfloat_really_inline +#undef FASTFLOAT_SIMD_DISABLE_WARNINGS +#undef FASTFLOAT_SIMD_RESTORE_WARNINGS +#undef FASTFLOAT_SSE2 +#undef FASTFLOAT_STRINGIZE +#undef FASTFLOAT_STRINGIZE_IMPL +#undef FASTFLOAT_TRY +#undef FASTFLOAT_VERSION +#undef FASTFLOAT_VERSION_MAJOR +#undef FASTFLOAT_VERSION_MINOR +#undef FASTFLOAT_VERSION_PATCH +#undef FASTFLOAT_VERSION_STR +#undef FASTFLOAT_VISUAL_STUDIO + +#endif // TINYOBJLOADER_DISABLE_FAST_FLOAT + +namespace tinyobj { + +MaterialReader::~MaterialReader() {} + +// Byte-stream reader for bounds-checked text parsing. +// Replaces raw `const char*` token pointers with `(buf, len, idx)` triple. +// Every byte access is guarded by an EOF check. +class StreamReader { + public: +// Maximum number of bytes StreamReader will buffer from std::istream. +// Define this macro to a larger value if your application needs to parse +// very large streamed OBJ/MTL content. +#ifndef TINYOBJLOADER_STREAM_READER_MAX_BYTES +#define TINYOBJLOADER_STREAM_READER_MAX_BYTES (size_t(256) * size_t(1024) * size_t(1024)) +#endif + + StreamReader(const char *buf, size_t length) + : buf_(buf), length_(length), idx_(0), line_num_(1), col_num_(1) {} + + // Non-copyable, non-movable: buf_ may point into owned_buf_. + StreamReader(const StreamReader &) /* = delete */; + StreamReader &operator=(const StreamReader &) /* = delete */; + + // Build from std::istream by reading all content into an internal buffer. + explicit StreamReader(std::istream &is) : buf_(NULL), length_(0), idx_(0), line_num_(1), col_num_(1) { + const size_t max_stream_bytes = TINYOBJLOADER_STREAM_READER_MAX_BYTES; + std::streampos start_pos = is.tellg(); + bool can_seek = (start_pos != std::streampos(-1)); + if (can_seek) { + is.seekg(0, std::ios::end); + std::streampos end_pos = is.tellg(); + if (end_pos >= start_pos) { + std::streamoff remaining_off = static_cast(end_pos - start_pos); + is.seekg(start_pos); + unsigned long long remaining_ull = static_cast(remaining_off); + if (remaining_ull > static_cast((std::numeric_limits::max)())) { + std::stringstream ss; + ss << "input stream too large for this platform (" << remaining_ull + << " bytes exceeds size_t max " << (std::numeric_limits::max)() << ")\n"; + push_error(ss.str()); + buf_ = ""; + length_ = 0; + return; + } + size_t remaining_size = static_cast(remaining_ull); + if (remaining_size > max_stream_bytes) { + std::stringstream ss; + ss << "input stream too large (" << remaining_size + << " bytes exceeds limit " << max_stream_bytes << " bytes)\n"; + push_error(ss.str()); + buf_ = ""; + length_ = 0; + return; + } + owned_buf_.resize(remaining_size); + if (remaining_size > 0) { + is.read(&owned_buf_[0], static_cast(remaining_size)); + } + size_t actually_read = static_cast(is.gcount()); + owned_buf_.resize(actually_read); + } + } + if (!can_seek || owned_buf_.empty()) { + // Stream doesn't support seeking, or seek probing failed. + if (can_seek) is.seekg(start_pos); + is.clear(); + std::vector content; + char chunk[4096]; + size_t total_read = 0; + while (is.good()) { + is.read(chunk, static_cast(sizeof(chunk))); + std::streamsize nread = is.gcount(); + if (nread <= 0) break; + size_t n = static_cast(nread); + if (n > (max_stream_bytes - total_read)) { + std::stringstream ss; + ss << "input stream too large (exceeds limit " << max_stream_bytes + << " bytes)\n"; + push_error(ss.str()); + owned_buf_.clear(); + buf_ = ""; + length_ = 0; + return; + } + content.insert(content.end(), chunk, chunk + n); + total_read += n; + } + owned_buf_.swap(content); + } + buf_ = owned_buf_.empty() ? "" : &owned_buf_[0]; + length_ = owned_buf_.size(); + } + + bool eof() const { return idx_ >= length_; } + size_t tell() const { return idx_; } + size_t size() const { return length_; } + size_t line_num() const { return line_num_; } + size_t col_num() const { return col_num_; } + + char peek() const { + if (idx_ >= length_) return '\0'; + return buf_[idx_]; + } + + char get() { + if (idx_ >= length_) return '\0'; + char c = buf_[idx_++]; + if (c == '\n') { line_num_++; col_num_ = 1; } else { col_num_++; } + return c; + } + + void advance(size_t n) { + for (size_t i = 0; i < n && idx_ < length_; i++) { + if (buf_[idx_] == '\n') { line_num_++; col_num_ = 1; } else { col_num_++; } + idx_++; + } + } + + void skip_space() { + while (idx_ < length_ && (buf_[idx_] == ' ' || buf_[idx_] == '\t')) { + col_num_++; + idx_++; + } + } + + void skip_space_and_cr() { + while (idx_ < length_ && (buf_[idx_] == ' ' || buf_[idx_] == '\t' || buf_[idx_] == '\r')) { + col_num_++; + idx_++; + } + } + + void skip_line() { + while (idx_ < length_) { + char c = buf_[idx_]; + if (c == '\n') { + idx_++; + line_num_++; + col_num_ = 1; + return; + } + if (c == '\r') { + idx_++; + if (idx_ < length_ && buf_[idx_] == '\n') { + idx_++; + } + line_num_++; + col_num_ = 1; + return; + } + col_num_++; + idx_++; + } + } + + bool at_line_end() const { + if (idx_ >= length_) return true; + char c = buf_[idx_]; + return (c == '\n' || c == '\r' || c == '\0'); + } + + std::string read_line() { + std::string result; + while (idx_ < length_) { + char c = buf_[idx_]; + if (c == '\n' || c == '\r') break; + result += c; + col_num_++; + idx_++; + } + return result; + } + + // Reads a whitespace-delimited token. Used by tests and as a general utility. + std::string read_token() { + skip_space(); + std::string result; + while (idx_ < length_) { + char c = buf_[idx_]; + if (c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\0') break; + result += c; + col_num_++; + idx_++; + } + return result; + } + + bool match(const char *prefix, size_t len) const { + if (idx_ >= length_ || len > length_ - idx_) return false; + return (memcmp(buf_ + idx_, prefix, len) == 0); + } + + bool char_at(size_t offset, char c) const { + if (idx_ >= length_ || offset >= length_ - idx_) return false; + return buf_[idx_ + offset] == c; + } + + char peek_at(size_t offset) const { + if (idx_ >= length_ || offset >= length_ - idx_) return '\0'; + return buf_[idx_ + offset]; + } + + const char *current_ptr() const { + if (idx_ >= length_) return ""; + return buf_ + idx_; + } + + size_t remaining() const { + return (idx_ < length_) ? (length_ - idx_) : 0; + } + + // Returns the full text of the current line (for diagnostic display). + std::string current_line_text() const { + // Scan backward to find line start + size_t line_start = idx_; + while (line_start > 0 && buf_[line_start - 1] != '\n' && buf_[line_start - 1] != '\r') { + line_start--; + } + // Scan forward to find line end + size_t line_end = idx_; + while (line_end < length_ && buf_[line_end] != '\n' && buf_[line_end] != '\r') { + line_end++; + } + return std::string(buf_ + line_start, line_end - line_start); + } + + // Clang-style formatted error with file:line:col and caret. + std::string format_error(const std::string &filename, const std::string &msg) const { + std::stringstream line_ss, col_ss; + line_ss << line_num_; + col_ss << col_num_; + std::string result; + result += filename + ":" + line_ss.str() + ":" + col_ss.str() + ": error: " + msg + "\n"; + std::string line_text = current_line_text(); + result += line_text + "\n"; + // Build caret line preserving tab alignment + std::string caret; + size_t caret_pos = (col_num_ > 0) ? (col_num_ - 1) : 0; + for (size_t i = 0; i < caret_pos && i < line_text.size(); i++) { + caret += (line_text[i] == '\t') ? '\t' : ' '; + } + caret += "^"; + result += caret + "\n"; + return result; + } + + std::string format_error(const std::string &msg) const { + return format_error("", msg); + } + + // Error stack + void push_error(const std::string &msg) { + errors_.push_back(msg); + } + + void push_formatted_error(const std::string &filename, const std::string &msg) { + errors_.push_back(format_error(filename, msg)); + } + + bool has_errors() const { return !errors_.empty(); } + + std::string get_errors() const { + std::string result; + for (size_t i = 0; i < errors_.size(); i++) { + result += errors_[i]; + } + return result; + } + + const std::vector &error_stack() const { return errors_; } + + void clear_errors() { errors_.clear(); } + + private: + const char *buf_; + size_t length_; + size_t idx_; + size_t line_num_; + size_t col_num_; + std::vector owned_buf_; + std::vector errors_; +}; + +#ifdef TINYOBJLOADER_USE_MMAP +// RAII wrapper for memory-mapped file I/O. +// Opens a file and maps it into memory; the mapping is released on destruction. +// For empty files, data is set to "" and is_mapped remains false so close() +// will not attempt to unmap a string literal. +struct MappedFile { + const char *data; + size_t size; + bool is_mapped; // true when data points to an actual mapped region +#if defined(_WIN32) + HANDLE hFile; + HANDLE hMapping; +#else + void *mapped_ptr; +#endif + + MappedFile() : data(NULL), size(0), is_mapped(false) +#if defined(_WIN32) + , hFile(INVALID_HANDLE_VALUE), hMapping(NULL) +#else + , mapped_ptr(NULL) +#endif + {} + + // Opens and maps the file. Returns true on success. + bool open(const char *filepath) { +#if defined(_WIN32) + std::wstring wfilepath = LongPathW(UTF8ToWchar(std::string(filepath))); + hFile = CreateFileW(wfilepath.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile == INVALID_HANDLE_VALUE) return false; + LARGE_INTEGER fileSize; + if (!GetFileSizeEx(hFile, &fileSize)) { close(); return false; } + if (fileSize.QuadPart < 0) { close(); return false; } + unsigned long long fsize = static_cast(fileSize.QuadPart); + if (fsize > static_cast((std::numeric_limits::max)())) { + close(); + return false; + } + size = static_cast(fsize); + if (size == 0) { data = ""; return true; } // valid but empty; is_mapped stays false + hMapping = CreateFileMappingA(hFile, NULL, PAGE_READONLY, 0, 0, NULL); + if (hMapping == NULL) { close(); return false; } + data = static_cast(MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0)); + if (!data) { close(); return false; } + is_mapped = true; + return true; +#else + int fd = ::open(filepath, O_RDONLY); + if (fd == -1) return false; + struct stat sb; + if (fstat(fd, &sb) != 0) { ::close(fd); return false; } + if (sb.st_size < 0) { ::close(fd); return false; } + if (static_cast(sb.st_size) > + static_cast((std::numeric_limits::max)())) { + ::close(fd); + return false; + } + size = static_cast(sb.st_size); + if (size == 0) { ::close(fd); data = ""; return true; } // valid but empty + mapped_ptr = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); + ::close(fd); + if (mapped_ptr == MAP_FAILED) { mapped_ptr = NULL; size = 0; return false; } + data = static_cast(mapped_ptr); + is_mapped = true; + return true; +#endif + } + + void close() { +#if defined(_WIN32) + if (is_mapped && data) { UnmapViewOfFile(data); } + data = NULL; + is_mapped = false; + if (hMapping != NULL) { CloseHandle(hMapping); hMapping = NULL; } + if (hFile != INVALID_HANDLE_VALUE) { CloseHandle(hFile); hFile = INVALID_HANDLE_VALUE; } +#else + if (is_mapped && mapped_ptr && mapped_ptr != MAP_FAILED) { munmap(mapped_ptr, size); } + mapped_ptr = NULL; + data = NULL; + is_mapped = false; +#endif + size = 0; + } + + ~MappedFile() { close(); } + + private: + MappedFile(const MappedFile &); // non-copyable + MappedFile &operator=(const MappedFile &); // non-copyable +}; +#endif // TINYOBJLOADER_USE_MMAP + + +struct vertex_index_t { + int v_idx, vt_idx, vn_idx; + vertex_index_t() : v_idx(-1), vt_idx(-1), vn_idx(-1) {} + explicit vertex_index_t(int idx) : v_idx(idx), vt_idx(idx), vn_idx(idx) {} + vertex_index_t(int vidx, int vtidx, int vnidx) + : v_idx(vidx), vt_idx(vtidx), vn_idx(vnidx) {} +}; + +// Internal data structure for face representation +// index + smoothing group. +struct face_t { + unsigned int + smoothing_group_id; // smoothing group id. 0 = smoothing groupd is off. + int pad_; + std::vector vertex_indices; // face vertex indices. + + face_t() : smoothing_group_id(0), pad_(0) {} +}; + +// Internal data structure for line representation +struct __line_t { + // l v1/vt1 v2/vt2 ... + // In the specification, line primitrive does not have normal index, but + // TinyObjLoader allow it + std::vector vertex_indices; +}; + +// Internal data structure for points representation +struct __points_t { + // p v1 v2 ... + // In the specification, point primitrive does not have normal index and + // texture coord index, but TinyObjLoader allow it. + std::vector vertex_indices; +}; + +struct tag_sizes { + tag_sizes() : num_ints(0), num_reals(0), num_strings(0) {} + int num_ints; + int num_reals; + int num_strings; +}; + +struct obj_shape { + std::vector v; + std::vector vn; + std::vector vt; +}; + +// +// Manages group of primitives(face, line, points, ...) +struct PrimGroup { + std::vector faceGroup; + std::vector<__line_t> lineGroup; + std::vector<__points_t> pointsGroup; + + void clear() { + faceGroup.clear(); + lineGroup.clear(); + pointsGroup.clear(); + } + + bool IsEmpty() const { + return faceGroup.empty() && lineGroup.empty() && pointsGroup.empty(); + } + + // TODO(syoyo): bspline, surface, ... +}; + +// See +// http://stackoverflow.com/questions/6089231/getting-std-ifstream-to-handle-lf-cr-and-crlf +#define IS_SPACE(x) (((x) == ' ') || ((x) == '\t')) +#define IS_DIGIT(x) \ + (static_cast((x) - '0') < static_cast(10)) +#define IS_NEW_LINE(x) (((x) == '\r') || ((x) == '\n') || ((x) == '\0')) + +template +static inline std::string toString(const T &t) { + std::stringstream ss; + ss << t; + return ss.str(); +} + +static inline std::string removeUtf8Bom(const std::string& input) { + // UTF-8 BOM = 0xEF,0xBB,0xBF + if (input.size() >= 3 && + static_cast(input[0]) == 0xEF && + static_cast(input[1]) == 0xBB && + static_cast(input[2]) == 0xBF) { + return input.substr(3); // Skip BOM + } + return input; +} + +// Trim trailing spaces and tabs from a string. +static inline std::string trimTrailingWhitespace(const std::string &s) { + size_t end = s.find_last_not_of(" \t"); + if (end == std::string::npos) return ""; + return s.substr(0, end + 1); +} + +struct warning_context { + std::string *warn; + size_t line_number; + std::string filename; +}; + +// Safely convert size_t to int, clamping at INT_MAX to prevent overflow. +static inline int size_to_int(size_t sz) { + return sz > static_cast(INT_MAX) ? INT_MAX : static_cast(sz); +} + +// Make index zero-base, and also support relative index. +static inline bool fixIndex(int idx, int n, int *ret, bool allow_zero, + const warning_context &context) { + if (!ret) { + return false; + } + + if (idx > 0) { + (*ret) = idx - 1; + return true; + } + + if (idx == 0) { + // zero is not allowed according to the spec. + if (context.warn) { + (*context.warn) += + context.filename + ":" + toString(context.line_number) + + ": warning: zero value index found (will have a value of -1 for " + "normal and tex indices)\n"; + } + + (*ret) = idx - 1; + return allow_zero; + } + + if (idx < 0) { + (*ret) = n + idx; // negative value = relative + if ((*ret) < 0) { + return false; // invalid relative index + } + return true; + } + + return false; // never reach here. +} + +static inline std::string parseString(const char **token) { + std::string s; + (*token) += strspn((*token), " \t"); + size_t e = strcspn((*token), " \t\r"); + s = std::string((*token), &(*token)[e]); + (*token) += e; + return s; +} + +static inline int parseInt(const char **token) { + (*token) += strspn((*token), " \t"); + int i = atoi((*token)); + (*token) += strcspn((*token), " \t\r"); + return i; +} + +#ifndef TINYOBJLOADER_DISABLE_FAST_FLOAT + +// ---- fast_float-based float parser (bit-exact with strtod, ~3x faster) ---- + +namespace detail_fp { + +// Case-insensitive prefix match. Returns pointer past matched prefix, or NULL. +static inline const char *match_iprefix(const char *p, const char *end, + const char *prefix) { + while (*prefix) { + if (p == end) return NULL; + char c = *p; + char e = *prefix; + if (c >= 'A' && c <= 'Z') c += 32; + if (e >= 'A' && e <= 'Z') e += 32; + if (c != e) return NULL; + ++p; + ++prefix; + } + return p; +} + +// Try to parse nan/inf. Returns true if matched, sets *result and *end_ptr. +static inline bool tryParseNanInf(const char *first, const char *last, + double *result, const char **end_ptr) { + if (first >= last) return false; + + const char *p = first; + bool negative = false; + + if (*p == '-') { + negative = true; + ++p; + } else if (*p == '+') { + ++p; + } + + if (p >= last) return false; + + // Try "nan" + const char *after = match_iprefix(p, last, "nan"); + if (after) { + *result = 0.0; // nan -> 0.0 for OBJ + *end_ptr = after; + return true; + } + + // Try "infinity" first (longer match), then "inf" + after = match_iprefix(p, last, "infinity"); + if (after) { + *result = negative ? std::numeric_limits::lowest() + : (std::numeric_limits::max)(); + *end_ptr = after; + return true; + } + + after = match_iprefix(p, last, "inf"); + if (after) { + *result = negative ? std::numeric_limits::lowest() + : (std::numeric_limits::max)(); + *end_ptr = after; + return true; + } + + return false; +} + +} // namespace detail_fp + +// Tries to parse a floating point number located at s. +// Uses fast_float::from_chars for bit-exact, high-performance parsing. +// Handles OBJ quirks: leading '+', nan/inf with replacement values. +// +// s_end should be a location in the string where reading should absolutely +// stop. For example at the end of the string, to prevent buffer overflows. +// +// If the parsing is a success, result is set to the parsed value and true +// is returned. +// +static bool tryParseDouble(const char *s, const char *s_end, double *result) { + if (!s || !s_end || !result || s >= s_end) { + return false; + } + + // Check for nan/inf (starts with [nNiI] or [+-] followed by [nNiI]) + const char *p = s; + if (p < s_end && (*p == '+' || *p == '-')) ++p; + if (p < s_end) { + char fc = *p; + if (fc >= 'A' && fc <= 'Z') fc += 32; + if (fc == 'n' || fc == 'i') { + const char *end_ptr; + if (detail_fp::tryParseNanInf(s, s_end, result, &end_ptr)) { + return true; + } + } + } + + // Use allow_leading_plus so fast_float handles '+' natively. + double tmp; + auto r = fast_float::from_chars(s, s_end, tmp, + fast_float::chars_format::general | + fast_float::chars_format::allow_leading_plus); + if (r.ec == tinyobj_ff::ff_errc::ok) { + *result = tmp; + return true; + } + // On error (invalid_argument, result_out_of_range), *result is unchanged. + + return false; +} + +static inline real_t parseReal(const char **token, double default_value = 0.0) { + (*token) += strspn((*token), " \t"); + const char *end = (*token) + strcspn((*token), " \t\r"); + double val = default_value; + tryParseDouble((*token), end, &val); + real_t f = static_cast(val); + (*token) = end; + return f; +} + +static inline bool parseReal(const char **token, real_t *out) { + (*token) += strspn((*token), " \t"); + const char *end = (*token) + strcspn((*token), " \t\r"); + double val; + bool ret = tryParseDouble((*token), end, &val); + if (ret) { + real_t f = static_cast(val); + (*out) = f; + } + (*token) = end; + return ret; +} + +#else // TINYOBJLOADER_DISABLE_FAST_FLOAT + +// ---- Legacy hand-written float parser (fallback) ---- + +// Tries to parse a floating point number located at s. +// +// s_end should be a location in the string where reading should absolutely +// stop. For example at the end of the string, to prevent buffer overflows. +// +// Parses the following EBNF grammar: +// sign = "+" | "-" ; +// END = ? anything not in digit ? +// digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ; +// integer = [sign] , digit , {digit} ; +// decimal = integer , ["." , integer] ; +// float = ( decimal , END ) | ( decimal , ("E" | "e") , integer , END ) ; +// +// Valid strings are for example: +// -0 +3.1417e+2 -0.0E-3 1.0324 -1.41 11e2 +// +// If the parsing is a success, result is set to the parsed value and true +// is returned. +// +// The function is greedy and will parse until any of the following happens: +// - a non-conforming character is encountered. +// - s_end is reached. +// +// The following situations triggers a failure: +// - s >= s_end. +// - parse failure. +// +static bool tryParseDouble(const char *s, const char *s_end, double *result) { + if (s >= s_end) { + return false; + } + + double mantissa = 0.0; + // This exponent is base 2 rather than 10. + // However the exponent we parse is supposed to be one of ten, + // thus we must take care to convert the exponent/and or the + // mantissa to a * 2^E, where a is the mantissa and E is the + // exponent. + // To get the final double we will use ldexp, it requires the + // exponent to be in base 2. + int exponent = 0; + + // NOTE: THESE MUST BE DECLARED HERE SINCE WE ARE NOT ALLOWED + // TO JUMP OVER DEFINITIONS. + char sign = '+'; + char exp_sign = '+'; + char const *curr = s; + + // How many characters were read in a loop. + int read = 0; + // Tells whether a loop terminated due to reaching s_end. + bool end_not_reached = false; + bool leading_decimal_dots = false; + + /* + BEGIN PARSING. + */ + + // Find out what sign we've got. + if (*curr == '+' || *curr == '-') { + sign = *curr; + curr++; + if ((curr != s_end) && (*curr == '.')) { + // accept. Somethig like `.7e+2`, `-.5234` + leading_decimal_dots = true; + } + } else if (IS_DIGIT(*curr)) { /* Pass through. */ + } else if (*curr == '.') { + // accept. Somethig like `.7e+2`, `-.5234` + leading_decimal_dots = true; + } else { + goto fail; + } + + // Read the integer part. + end_not_reached = (curr != s_end); + if (!leading_decimal_dots) { + while (end_not_reached && IS_DIGIT(*curr)) { + mantissa *= 10; + mantissa += static_cast(*curr - 0x30); + curr++; + read++; + end_not_reached = (curr != s_end); + } + + // We must make sure we actually got something. + if (read == 0) goto fail; + } + + // We allow numbers of form "#", "###" etc. + if (!end_not_reached) goto assemble; + + // Read the decimal part. + if (*curr == '.') { + curr++; + read = 1; + end_not_reached = (curr != s_end); + while (end_not_reached && IS_DIGIT(*curr)) { + static const double pow_lut[] = { + 1.0, 0.1, 0.01, 0.001, 0.0001, 0.00001, 0.000001, 0.0000001, + }; + const int lut_entries = sizeof pow_lut / sizeof pow_lut[0]; + + // NOTE: Don't use powf here, it will absolutely murder precision. + mantissa += static_cast(*curr - 0x30) * + (read < lut_entries ? pow_lut[read] : std::pow(10.0, -read)); + read++; + curr++; + end_not_reached = (curr != s_end); + } + } else if (*curr == 'e' || *curr == 'E') { + } else { + goto assemble; + } + + if (!end_not_reached) goto assemble; + + // Read the exponent part. + if (*curr == 'e' || *curr == 'E') { + curr++; + // Figure out if a sign is present and if it is. + end_not_reached = (curr != s_end); + if (end_not_reached && (*curr == '+' || *curr == '-')) { + exp_sign = *curr; + curr++; + } else if (IS_DIGIT(*curr)) { /* Pass through. */ + } else { + // Empty E is not allowed. + goto fail; + } + + read = 0; + end_not_reached = (curr != s_end); + while (end_not_reached && IS_DIGIT(*curr)) { + // To avoid annoying MSVC's min/max macro definiton, + // Use hardcoded int max value + if (exponent > + ((2147483647 - 9) / 10)) { // (INT_MAX - 9) / 10, guards both multiply and add + // Integer overflow + goto fail; + } + exponent *= 10; + exponent += static_cast(*curr - 0x30); + curr++; + read++; + end_not_reached = (curr != s_end); + } + exponent *= (exp_sign == '+' ? 1 : -1); + if (read == 0) goto fail; + } + +assemble: + *result = (sign == '+' ? 1 : -1) * + (exponent ? std::ldexp(mantissa * std::pow(5.0, exponent), exponent) + : mantissa); + return true; +fail: + return false; +} + +static inline real_t parseReal(const char **token, double default_value = 0.0) { + (*token) += strspn((*token), " \t"); + const char *end = (*token) + strcspn((*token), " \t\r"); + double val = default_value; + tryParseDouble((*token), end, &val); + real_t f = static_cast(val); + (*token) = end; + return f; +} + +static inline bool parseReal(const char **token, real_t *out) { + (*token) += strspn((*token), " \t"); + const char *end = (*token) + strcspn((*token), " \t\r"); + double val; + bool ret = tryParseDouble((*token), end, &val); + if (ret) { + real_t f = static_cast(val); + (*out) = f; + } + (*token) = end; + return ret; +} + +#endif // TINYOBJLOADER_DISABLE_FAST_FLOAT + +static inline void parseReal2(real_t *x, real_t *y, const char **token, + const double default_x = 0.0, + const double default_y = 0.0) { + (*x) = parseReal(token, default_x); + (*y) = parseReal(token, default_y); +} + +static inline void parseReal3(real_t *x, real_t *y, real_t *z, + const char **token, const double default_x = 0.0, + const double default_y = 0.0, + const double default_z = 0.0) { + (*x) = parseReal(token, default_x); + (*y) = parseReal(token, default_y); + (*z) = parseReal(token, default_z); +} + +#if 0 // not used +static inline void parseV(real_t *x, real_t *y, real_t *z, real_t *w, + const char **token, const double default_x = 0.0, + const double default_y = 0.0, + const double default_z = 0.0, + const double default_w = 1.0) { + (*x) = parseReal(token, default_x); + (*y) = parseReal(token, default_y); + (*z) = parseReal(token, default_z); + (*w) = parseReal(token, default_w); +} +#endif + +// Extension: parse vertex with colors(6 items) +// Return 3: xyz, 4: xyzw, 6: xyzrgb +// `r`: red(case 6) or [w](case 4) +static inline int parseVertexWithColor(real_t *x, real_t *y, real_t *z, + real_t *r, real_t *g, real_t *b, + const char **token, + const double default_x = 0.0, + const double default_y = 0.0, + const double default_z = 0.0) { + // TODO: Check error + (*x) = parseReal(token, default_x); + (*y) = parseReal(token, default_y); + (*z) = parseReal(token, default_z); + + // - 4 components(x, y, z, w) ot 6 components + bool has_r = parseReal(token, r); + + if (!has_r) { + (*r) = (*g) = (*b) = 1.0; + return 3; + } + + bool has_g = parseReal(token, g); + + if (!has_g) { + (*g) = (*b) = 1.0; + return 4; + } + + bool has_b = parseReal(token, b); + + if (!has_b) { + (*r) = (*g) = (*b) = 1.0; + return 3; // treated as xyz + } + + return 6; +} + +static inline bool parseOnOff(const char **token, bool default_value = true) { + (*token) += strspn((*token), " \t"); + const char *end = (*token) + strcspn((*token), " \t\r"); + + bool ret = default_value; + if ((0 == strncmp((*token), "on", 2))) { + ret = true; + } else if ((0 == strncmp((*token), "off", 3))) { + ret = false; + } + + (*token) = end; + return ret; +} + +static inline texture_type_t parseTextureType( + const char **token, texture_type_t default_value = TEXTURE_TYPE_NONE) { + (*token) += strspn((*token), " \t"); + const char *end = (*token) + strcspn((*token), " \t\r"); + texture_type_t ty = default_value; + + if ((0 == strncmp((*token), "cube_top", strlen("cube_top")))) { + ty = TEXTURE_TYPE_CUBE_TOP; + } else if ((0 == strncmp((*token), "cube_bottom", strlen("cube_bottom")))) { + ty = TEXTURE_TYPE_CUBE_BOTTOM; + } else if ((0 == strncmp((*token), "cube_left", strlen("cube_left")))) { + ty = TEXTURE_TYPE_CUBE_LEFT; + } else if ((0 == strncmp((*token), "cube_right", strlen("cube_right")))) { + ty = TEXTURE_TYPE_CUBE_RIGHT; + } else if ((0 == strncmp((*token), "cube_front", strlen("cube_front")))) { + ty = TEXTURE_TYPE_CUBE_FRONT; + } else if ((0 == strncmp((*token), "cube_back", strlen("cube_back")))) { + ty = TEXTURE_TYPE_CUBE_BACK; + } else if ((0 == strncmp((*token), "sphere", strlen("sphere")))) { + ty = TEXTURE_TYPE_SPHERE; + } + + (*token) = end; + return ty; +} + +static tag_sizes parseTagTriple(const char **token) { + tag_sizes ts; + + (*token) += strspn((*token), " \t"); + ts.num_ints = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + return ts; + } + + (*token)++; // Skip '/' + + (*token) += strspn((*token), " \t"); + ts.num_reals = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + return ts; + } + (*token)++; // Skip '/' + + ts.num_strings = parseInt(token); + + return ts; +} + +// Parse triples with index offsets: i, i/j/k, i//k, i/j +static bool parseTriple(const char **token, int vsize, int vnsize, int vtsize, + vertex_index_t *ret, const warning_context &context) { + if (!ret) { + return false; + } + + vertex_index_t vi(-1); + + if (!fixIndex(atoi((*token)), vsize, &vi.v_idx, false, context)) { + return false; + } + + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + (*ret) = vi; + return true; + } + (*token)++; + + // i//k + if ((*token)[0] == '/') { + (*token)++; + if (!fixIndex(atoi((*token)), vnsize, &vi.vn_idx, true, context)) { + return false; + } + (*token) += strcspn((*token), "/ \t\r"); + (*ret) = vi; + return true; + } + + // i/j/k or i/j + if (!fixIndex(atoi((*token)), vtsize, &vi.vt_idx, true, context)) { + return false; + } + + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + (*ret) = vi; + return true; + } + + // i/j/k + (*token)++; // skip '/' + if (!fixIndex(atoi((*token)), vnsize, &vi.vn_idx, true, context)) { + return false; + } + (*token) += strcspn((*token), "/ \t\r"); + + (*ret) = vi; + + return true; +} + +// Parse raw triples: i, i/j/k, i//k, i/j +static vertex_index_t parseRawTriple(const char **token) { + vertex_index_t vi(static_cast(0)); // 0 is an invalid index in OBJ + + vi.v_idx = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + return vi; + } + (*token)++; + + // i//k + if ((*token)[0] == '/') { + (*token)++; + vi.vn_idx = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + return vi; + } + + // i/j/k or i/j + vi.vt_idx = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + return vi; + } + + // i/j/k + (*token)++; // skip '/' + vi.vn_idx = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + return vi; +} + +// --- Stream-based parse functions --- + +static inline std::string sr_parseString(StreamReader &sr) { + sr.skip_space(); + std::string s; + while (!sr.eof()) { + char c = sr.peek(); + if (c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\0') break; + s += c; + sr.advance(1); + } + return s; +} + +static inline int sr_parseInt(StreamReader &sr) { + sr.skip_space(); + const char *start = sr.current_ptr(); + size_t rem = sr.remaining(); + size_t len = 0; + while (len < rem) { + char c = start[len]; + if (c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\0') break; + len++; + } + int i = 0; + if (len > 0) { + char tmp[64]; + size_t copy_len = len < 63 ? len : 63; + if (copy_len != len) { + sr.advance(len); + return 0; + } + memcpy(tmp, start, copy_len); + tmp[copy_len] = '\0'; + errno = 0; + char *endptr = NULL; + long val = strtol(tmp, &endptr, 10); + const bool has_error = + (errno == ERANGE || endptr == tmp || + val > (std::numeric_limits::max)() || + val < (std::numeric_limits::min)()); + if (!has_error) { + i = static_cast(val); + } + } + sr.advance(len); + return i; +} + +static inline real_t sr_parseReal(StreamReader &sr, double default_value = 0.0) { + sr.skip_space(); + const char *start = sr.current_ptr(); + size_t rem = sr.remaining(); + size_t len = 0; + while (len < rem) { + char c = start[len]; + if (c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\0') break; + len++; + } + double val = default_value; + if (len > 0) { + tryParseDouble(start, start + len, &val); + } + sr.advance(len); + return static_cast(val); +} + +static inline bool sr_parseReal(StreamReader &sr, real_t *out) { + sr.skip_space(); + const char *start = sr.current_ptr(); + size_t rem = sr.remaining(); + size_t len = 0; + while (len < rem) { + char c = start[len]; + if (c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\0') break; + len++; + } + if (len == 0) return false; + double val; + bool ret = tryParseDouble(start, start + len, &val); + if (ret) { + (*out) = static_cast(val); + } + sr.advance(len); + return ret; +} + +static inline void sr_parseReal2(real_t *x, real_t *y, StreamReader &sr, + const double default_x = 0.0, + const double default_y = 0.0) { + (*x) = sr_parseReal(sr, default_x); + (*y) = sr_parseReal(sr, default_y); +} + +static inline void sr_parseReal3(real_t *x, real_t *y, real_t *z, + StreamReader &sr, + const double default_x = 0.0, + const double default_y = 0.0, + const double default_z = 0.0) { + (*x) = sr_parseReal(sr, default_x); + (*y) = sr_parseReal(sr, default_y); + (*z) = sr_parseReal(sr, default_z); +} + +static inline int sr_parseVertexWithColor(real_t *x, real_t *y, real_t *z, + real_t *r, real_t *g, real_t *b, + StreamReader &sr, + const double default_x = 0.0, + const double default_y = 0.0, + const double default_z = 0.0) { + (*x) = sr_parseReal(sr, default_x); + (*y) = sr_parseReal(sr, default_y); + (*z) = sr_parseReal(sr, default_z); + + bool has_r = sr_parseReal(sr, r); + if (!has_r) { + (*r) = (*g) = (*b) = 1.0; + return 3; + } + + bool has_g = sr_parseReal(sr, g); + if (!has_g) { + (*g) = (*b) = 1.0; + return 4; + } + + bool has_b = sr_parseReal(sr, b); + if (!has_b) { + (*r) = (*g) = (*b) = 1.0; + return 3; + } + + return 6; +} + +// --- Error-reporting overloads --- +// These overloads push clang-style diagnostics into `err` when parsing fails +// and return false so callers can early-return on unrecoverable parse errors. +// The original signatures are preserved above for backward compatibility. + +static inline bool sr_parseInt(StreamReader &sr, int *out, std::string *err, + const std::string &filename) { + sr.skip_space(); + const char *start = sr.current_ptr(); + size_t rem = sr.remaining(); + size_t len = 0; + while (len < rem) { + char c = start[len]; + if (c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\0') break; + len++; + } + if (len == 0) { + if (err) { + (*err) += sr.format_error(filename, "expected integer value"); + } + *out = 0; + return false; + } + char tmp[64]; + size_t copy_len = len < 63 ? len : 63; + memcpy(tmp, start, copy_len); + tmp[copy_len] = '\0'; + if (copy_len != len) { + if (err) { + (*err) += sr.format_error(filename, "integer value too long"); + } + *out = 0; + sr.advance(len); + return false; + } + errno = 0; + char *endptr = NULL; + long val = strtol(tmp, &endptr, 10); + if (errno == ERANGE || val > (std::numeric_limits::max)() || + val < (std::numeric_limits::min)()) { + if (err) { + (*err) += sr.format_error(filename, + "integer value out of range, got '" + std::string(tmp) + "'"); + } + *out = 0; + sr.advance(len); + return false; + } + if (endptr == tmp || (*endptr != '\0' && *endptr != ' ' && *endptr != '\t')) { + if (err) { + (*err) += sr.format_error(filename, + "expected integer, got '" + std::string(tmp) + "'"); + } + *out = 0; + sr.advance(len); + return false; + } + *out = static_cast(val); + sr.advance(len); + return true; +} + +static inline bool sr_parseReal(StreamReader &sr, real_t *out, + double default_value, + std::string *err, + const std::string &filename) { + sr.skip_space(); + const char *start = sr.current_ptr(); + size_t rem = sr.remaining(); + size_t len = 0; + while (len < rem) { + char c = start[len]; + if (c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\0') break; + len++; + } + if (len == 0) { + // No token to parse — not necessarily an error (e.g. optional component). + *out = static_cast(default_value); + return true; + } + double val; + if (!tryParseDouble(start, start + len, &val)) { + if (err) { + char tmp[64]; + size_t copy_len = len < 63 ? len : 63; + memcpy(tmp, start, copy_len); + tmp[copy_len] = '\0'; + (*err) += sr.format_error(filename, + "expected number, got '" + std::string(tmp) + "'"); + } + *out = static_cast(default_value); + sr.advance(len); + return false; + } + *out = static_cast(val); + sr.advance(len); + return true; +} + +static inline bool sr_parseReal2(real_t *x, real_t *y, StreamReader &sr, + std::string *err, + const std::string &filename, + const double default_x = 0.0, + const double default_y = 0.0) { + if (!sr_parseReal(sr, x, default_x, err, filename)) return false; + if (!sr_parseReal(sr, y, default_y, err, filename)) return false; + return true; +} + +static inline bool sr_parseReal3(real_t *x, real_t *y, real_t *z, + StreamReader &sr, + std::string *err, + const std::string &filename, + const double default_x = 0.0, + const double default_y = 0.0, + const double default_z = 0.0) { + if (!sr_parseReal(sr, x, default_x, err, filename)) return false; + if (!sr_parseReal(sr, y, default_y, err, filename)) return false; + if (!sr_parseReal(sr, z, default_z, err, filename)) return false; + return true; +} + +// Returns number of components parsed (3, 4, or 6) on success, -1 on error. +static inline int sr_parseVertexWithColor(real_t *x, real_t *y, real_t *z, + real_t *r, real_t *g, real_t *b, + StreamReader &sr, + std::string *err, + const std::string &filename, + const double default_x = 0.0, + const double default_y = 0.0, + const double default_z = 0.0) { + if (!sr_parseReal(sr, x, default_x, err, filename)) return -1; + if (!sr_parseReal(sr, y, default_y, err, filename)) return -1; + if (!sr_parseReal(sr, z, default_z, err, filename)) return -1; + + bool has_r = sr_parseReal(sr, r); + if (!has_r) { + (*r) = (*g) = (*b) = 1.0; + return 3; + } + + bool has_g = sr_parseReal(sr, g); + if (!has_g) { + (*g) = (*b) = 1.0; + return 4; + } + + bool has_b = sr_parseReal(sr, b); + if (!has_b) { + (*r) = (*g) = (*b) = 1.0; + return 3; + } + + return 6; +} + +static inline int sr_parseIntNoSkip(StreamReader &sr); + +// Advance past remaining characters in a tag triple field (stops at '/', whitespace, or line end). +static inline void sr_skipTagField(StreamReader &sr) { + while (!sr.eof() && !sr.at_line_end() && !IS_SPACE(sr.peek()) && + sr.peek() != '/') { + sr.advance(1); + } +} + +static tag_sizes sr_parseTagTriple(StreamReader &sr) { + tag_sizes ts; + + sr.skip_space(); + ts.num_ints = sr_parseIntNoSkip(sr); + sr_skipTagField(sr); + if (!sr.eof() && sr.peek() == '/') { + sr.advance(1); + sr.skip_space(); + ts.num_reals = sr_parseIntNoSkip(sr); + sr_skipTagField(sr); + if (!sr.eof() && sr.peek() == '/') { + sr.advance(1); + ts.num_strings = sr_parseInt(sr); + } + } + return ts; +} + +static inline int sr_parseIntNoSkip(StreamReader &sr) { + const char *start = sr.current_ptr(); + size_t rem = sr.remaining(); + size_t len = 0; + if (len < rem && (start[len] == '+' || start[len] == '-')) len++; + while (len < rem && start[len] >= '0' && start[len] <= '9') len++; + int i = 0; + if (len > 0) { + char tmp[64]; + size_t copy_len = len < 63 ? len : 63; + if (copy_len != len) { + sr.advance(len); + return 0; + } + memcpy(tmp, start, copy_len); + tmp[copy_len] = '\0'; + errno = 0; + char *endptr = NULL; + long val = strtol(tmp, &endptr, 10); + if (errno == 0 && endptr != tmp && *endptr == '\0' && + val <= (std::numeric_limits::max)() && + val >= (std::numeric_limits::min)()) { + i = static_cast(val); + } + } + sr.advance(len); + return i; +} + +static inline void sr_skipUntil(StreamReader &sr, const char *delims) { + while (!sr.eof()) { + char c = sr.peek(); + for (const char *d = delims; *d; d++) { + if (c == *d) return; + } + sr.advance(1); + } +} + +static bool sr_parseTriple(StreamReader &sr, int vsize, int vnsize, int vtsize, + vertex_index_t *ret, const warning_context &context) { + if (!ret) return false; + + vertex_index_t vi(-1); + + sr.skip_space(); + if (!fixIndex(sr_parseIntNoSkip(sr), vsize, &vi.v_idx, false, context)) { + return false; + } + + sr_skipUntil(sr, "/ \t\r\n"); + if (sr.eof() || sr.peek() != '/') { + (*ret) = vi; + return true; + } + sr.advance(1); + + // i//k + if (!sr.eof() && sr.peek() == '/') { + sr.advance(1); + if (!fixIndex(sr_parseIntNoSkip(sr), vnsize, &vi.vn_idx, true, context)) { + return false; + } + sr_skipUntil(sr, "/ \t\r\n"); + (*ret) = vi; + return true; + } + + // i/j/k or i/j + if (!fixIndex(sr_parseIntNoSkip(sr), vtsize, &vi.vt_idx, true, context)) { + return false; + } + + sr_skipUntil(sr, "/ \t\r\n"); + if (sr.eof() || sr.peek() != '/') { + (*ret) = vi; + return true; + } + + // i/j/k + sr.advance(1); + if (!fixIndex(sr_parseIntNoSkip(sr), vnsize, &vi.vn_idx, true, context)) { + return false; + } + sr_skipUntil(sr, "/ \t\r\n"); + + (*ret) = vi; + return true; +} + +static vertex_index_t sr_parseRawTriple(StreamReader &sr) { + vertex_index_t vi(static_cast(0)); + + sr.skip_space(); + vi.v_idx = sr_parseIntNoSkip(sr); + sr_skipUntil(sr, "/ \t\r\n"); + if (sr.eof() || sr.peek() != '/') return vi; + sr.advance(1); + + // i//k + if (!sr.eof() && sr.peek() == '/') { + sr.advance(1); + vi.vn_idx = sr_parseIntNoSkip(sr); + sr_skipUntil(sr, "/ \t\r\n"); + return vi; + } + + // i/j/k or i/j + vi.vt_idx = sr_parseIntNoSkip(sr); + sr_skipUntil(sr, "/ \t\r\n"); + if (sr.eof() || sr.peek() != '/') return vi; + + sr.advance(1); + vi.vn_idx = sr_parseIntNoSkip(sr); + sr_skipUntil(sr, "/ \t\r\n"); + return vi; +} + +bool ParseTextureNameAndOption(std::string *texname, texture_option_t *texopt, + const char *linebuf) { + // @todo { write more robust lexer and parser. } + bool found_texname = false; + std::string texture_name; + + const char *token = linebuf; // Assume line ends with NULL + + while (!IS_NEW_LINE((*token))) { + token += strspn(token, " \t"); // skip space + if ((0 == strncmp(token, "-blendu", 7)) && IS_SPACE((token[7]))) { + token += 8; + texopt->blendu = parseOnOff(&token, /* default */ true); + } else if ((0 == strncmp(token, "-blendv", 7)) && IS_SPACE((token[7]))) { + token += 8; + texopt->blendv = parseOnOff(&token, /* default */ true); + } else if ((0 == strncmp(token, "-clamp", 6)) && IS_SPACE((token[6]))) { + token += 7; + texopt->clamp = parseOnOff(&token, /* default */ true); + } else if ((0 == strncmp(token, "-boost", 6)) && IS_SPACE((token[6]))) { + token += 7; + texopt->sharpness = parseReal(&token, 1.0); + } else if ((0 == strncmp(token, "-bm", 3)) && IS_SPACE((token[3]))) { + token += 4; + texopt->bump_multiplier = parseReal(&token, 1.0); + } else if ((0 == strncmp(token, "-o", 2)) && IS_SPACE((token[2]))) { + token += 3; + parseReal3(&(texopt->origin_offset[0]), &(texopt->origin_offset[1]), + &(texopt->origin_offset[2]), &token); + } else if ((0 == strncmp(token, "-s", 2)) && IS_SPACE((token[2]))) { + token += 3; + parseReal3(&(texopt->scale[0]), &(texopt->scale[1]), &(texopt->scale[2]), + &token, 1.0, 1.0, 1.0); + } else if ((0 == strncmp(token, "-t", 2)) && IS_SPACE((token[2]))) { + token += 3; + parseReal3(&(texopt->turbulence[0]), &(texopt->turbulence[1]), + &(texopt->turbulence[2]), &token); + } else if ((0 == strncmp(token, "-type", 5)) && IS_SPACE((token[5]))) { + token += 5; + texopt->type = parseTextureType((&token), TEXTURE_TYPE_NONE); + } else if ((0 == strncmp(token, "-texres", 7)) && IS_SPACE((token[7]))) { + token += 7; + // TODO(syoyo): Check if arg is int type. + texopt->texture_resolution = parseInt(&token); + } else if ((0 == strncmp(token, "-imfchan", 8)) && IS_SPACE((token[8]))) { + token += 9; + token += strspn(token, " \t"); + const char *end = token + strcspn(token, " \t\r"); + if ((end - token) == 1) { // Assume one char for -imfchan + texopt->imfchan = (*token); + } + token = end; + } else if ((0 == strncmp(token, "-mm", 3)) && IS_SPACE((token[3]))) { + token += 4; + parseReal2(&(texopt->brightness), &(texopt->contrast), &token, 0.0, 1.0); + } else if ((0 == strncmp(token, "-colorspace", 11)) && + IS_SPACE((token[11]))) { + token += 12; + texopt->colorspace = parseString(&token); + } else { +// Assume texture filename +#if 0 + size_t len = strcspn(token, " \t\r"); // untile next space + texture_name = std::string(token, token + len); + token += len; + + token += strspn(token, " \t"); // skip space +#else + // Read filename until line end to parse filename containing whitespace + // TODO(syoyo): Support parsing texture option flag after the filename. + texture_name = std::string(token); + token += texture_name.length(); +#endif + + found_texname = true; + } + } + + if (found_texname) { + (*texname) = texture_name; + return true; + } else { + return false; + } +} + +static void InitTexOpt(texture_option_t *texopt, const bool is_bump) { + if (is_bump) { + texopt->imfchan = 'l'; + } else { + texopt->imfchan = 'm'; + } + texopt->bump_multiplier = static_cast(1.0); + texopt->clamp = false; + texopt->blendu = true; + texopt->blendv = true; + texopt->sharpness = static_cast(1.0); + texopt->brightness = static_cast(0.0); + texopt->contrast = static_cast(1.0); + texopt->origin_offset[0] = static_cast(0.0); + texopt->origin_offset[1] = static_cast(0.0); + texopt->origin_offset[2] = static_cast(0.0); + texopt->scale[0] = static_cast(1.0); + texopt->scale[1] = static_cast(1.0); + texopt->scale[2] = static_cast(1.0); + texopt->turbulence[0] = static_cast(0.0); + texopt->turbulence[1] = static_cast(0.0); + texopt->turbulence[2] = static_cast(0.0); + texopt->texture_resolution = -1; + texopt->type = TEXTURE_TYPE_NONE; +} + +static void InitMaterial(material_t *material) { + InitTexOpt(&material->ambient_texopt, /* is_bump */ false); + InitTexOpt(&material->diffuse_texopt, /* is_bump */ false); + InitTexOpt(&material->specular_texopt, /* is_bump */ false); + InitTexOpt(&material->specular_highlight_texopt, /* is_bump */ false); + InitTexOpt(&material->bump_texopt, /* is_bump */ true); + InitTexOpt(&material->displacement_texopt, /* is_bump */ false); + InitTexOpt(&material->alpha_texopt, /* is_bump */ false); + InitTexOpt(&material->reflection_texopt, /* is_bump */ false); + InitTexOpt(&material->roughness_texopt, /* is_bump */ false); + InitTexOpt(&material->metallic_texopt, /* is_bump */ false); + InitTexOpt(&material->sheen_texopt, /* is_bump */ false); + InitTexOpt(&material->emissive_texopt, /* is_bump */ false); + InitTexOpt(&material->normal_texopt, + /* is_bump */ false); // @fixme { is_bump will be true? } + material->name = ""; + material->ambient_texname = ""; + material->diffuse_texname = ""; + material->specular_texname = ""; + material->specular_highlight_texname = ""; + material->bump_texname = ""; + material->displacement_texname = ""; + material->reflection_texname = ""; + material->alpha_texname = ""; + for (int i = 0; i < 3; i++) { + material->ambient[i] = static_cast(0.0); + material->diffuse[i] = static_cast(0.0); + material->specular[i] = static_cast(0.0); + material->transmittance[i] = static_cast(0.0); + material->emission[i] = static_cast(0.0); + } + material->illum = 0; + material->dissolve = static_cast(1.0); + material->shininess = static_cast(1.0); + material->ior = static_cast(1.0); + + material->roughness = static_cast(0.0); + material->metallic = static_cast(0.0); + material->sheen = static_cast(0.0); + material->clearcoat_thickness = static_cast(0.0); + material->clearcoat_roughness = static_cast(0.0); + material->anisotropy_rotation = static_cast(0.0); + material->anisotropy = static_cast(0.0); + material->roughness_texname = ""; + material->metallic_texname = ""; + material->sheen_texname = ""; + material->emissive_texname = ""; + material->normal_texname = ""; + + material->unknown_parameter.clear(); +} + +// code from https://wrf.ecse.rpi.edu//Research/Short_Notes/pnpoly.html +template +static int pnpoly(int nvert, T *vertx, T *verty, T testx, T testy) { + int i, j, c = 0; + for (i = 0, j = nvert - 1; i < nvert; j = i++) { + if (((verty[i] > testy) != (verty[j] > testy)) && + (testx < + (vertx[j] - vertx[i]) * (testy - verty[i]) / (verty[j] - verty[i]) + + vertx[i])) + c = !c; + } + return c; +} + +struct TinyObjPoint { + real_t x, y, z; + TinyObjPoint() : x(0), y(0), z(0) {} + TinyObjPoint(real_t x_, real_t y_, real_t z_) : x(x_), y(y_), z(z_) {} +}; + +inline TinyObjPoint cross(const TinyObjPoint &v1, const TinyObjPoint &v2) { + return TinyObjPoint(v1.y * v2.z - v1.z * v2.y, v1.z * v2.x - v1.x * v2.z, + v1.x * v2.y - v1.y * v2.x); +} + +inline real_t dot(const TinyObjPoint &v1, const TinyObjPoint &v2) { + return (v1.x * v2.x + v1.y * v2.y + v1.z * v2.z); +} + +inline real_t GetLength(TinyObjPoint &e) { + return std::sqrt(e.x * e.x + e.y * e.y + e.z * e.z); +} + +inline TinyObjPoint Normalize(TinyObjPoint e) { + real_t len = GetLength(e); + if (len <= real_t(0)) return TinyObjPoint(real_t(0), real_t(0), real_t(0)); + real_t inv_length = real_t(1) / len; + return TinyObjPoint(e.x * inv_length, e.y * inv_length, e.z * inv_length); +} + +inline TinyObjPoint WorldToLocal(const TinyObjPoint &a, const TinyObjPoint &u, + const TinyObjPoint &v, const TinyObjPoint &w) { + return TinyObjPoint(dot(a, u), dot(a, v), dot(a, w)); +} + +// TODO(syoyo): refactor function. +static bool exportGroupsToShape(shape_t *shape, const PrimGroup &prim_group, + const std::vector &tags, + const int material_id, const std::string &name, + bool triangulate, const std::vector &v, + std::string *warn) { + if (prim_group.IsEmpty()) { + return false; + } + + shape->name = name; + + // polygon + if (!prim_group.faceGroup.empty()) { + // Flatten vertices and indices + for (size_t i = 0; i < prim_group.faceGroup.size(); i++) { + const face_t &face = prim_group.faceGroup[i]; + + size_t npolys = face.vertex_indices.size(); + + if (npolys < 3) { + // Face must have 3+ vertices. + if (warn) { + (*warn) += "Degenerated face found\n."; + } + continue; + } + + if (triangulate && npolys != 3) { + if (npolys == 4) { + vertex_index_t i0 = face.vertex_indices[0]; + vertex_index_t i1 = face.vertex_indices[1]; + vertex_index_t i2 = face.vertex_indices[2]; + vertex_index_t i3 = face.vertex_indices[3]; + + if (i0.v_idx < 0 || i1.v_idx < 0 || i2.v_idx < 0 || i3.v_idx < 0) { + if (warn) { + (*warn) += "Face with invalid vertex index found.\n"; + } + continue; + } + + size_t vi0 = size_t(i0.v_idx); + size_t vi1 = size_t(i1.v_idx); + size_t vi2 = size_t(i2.v_idx); + size_t vi3 = size_t(i3.v_idx); + + if (((3 * vi0 + 2) >= v.size()) || ((3 * vi1 + 2) >= v.size()) || + ((3 * vi2 + 2) >= v.size()) || ((3 * vi3 + 2) >= v.size())) { + // Invalid triangle. + // FIXME(syoyo): Is it ok to simply skip this invalid triangle? + if (warn) { + (*warn) += "Face with invalid vertex index found.\n"; + } + continue; + } + + real_t v0x = v[vi0 * 3 + 0]; + real_t v0y = v[vi0 * 3 + 1]; + real_t v0z = v[vi0 * 3 + 2]; + real_t v1x = v[vi1 * 3 + 0]; + real_t v1y = v[vi1 * 3 + 1]; + real_t v1z = v[vi1 * 3 + 2]; + real_t v2x = v[vi2 * 3 + 0]; + real_t v2y = v[vi2 * 3 + 1]; + real_t v2z = v[vi2 * 3 + 2]; + real_t v3x = v[vi3 * 3 + 0]; + real_t v3y = v[vi3 * 3 + 1]; + real_t v3z = v[vi3 * 3 + 2]; + + // There are two candidates to split the quad into two triangles. + // + // Choose the shortest edge. + // TODO: Is it better to determine the edge to split by calculating + // the area of each triangle? + // + // +---+ + // |\ | + // | \ | + // | \| + // +---+ + // + // +---+ + // | /| + // | / | + // |/ | + // +---+ + + real_t e02x = v2x - v0x; + real_t e02y = v2y - v0y; + real_t e02z = v2z - v0z; + real_t e13x = v3x - v1x; + real_t e13y = v3y - v1y; + real_t e13z = v3z - v1z; + + real_t sqr02 = e02x * e02x + e02y * e02y + e02z * e02z; + real_t sqr13 = e13x * e13x + e13y * e13y + e13z * e13z; + + index_t idx0, idx1, idx2, idx3; + + idx0.vertex_index = i0.v_idx; + idx0.normal_index = i0.vn_idx; + idx0.texcoord_index = i0.vt_idx; + idx1.vertex_index = i1.v_idx; + idx1.normal_index = i1.vn_idx; + idx1.texcoord_index = i1.vt_idx; + idx2.vertex_index = i2.v_idx; + idx2.normal_index = i2.vn_idx; + idx2.texcoord_index = i2.vt_idx; + idx3.vertex_index = i3.v_idx; + idx3.normal_index = i3.vn_idx; + idx3.texcoord_index = i3.vt_idx; + + if (sqr02 < sqr13) { + // [0, 1, 2], [0, 2, 3] + shape->mesh.indices.push_back(idx0); + shape->mesh.indices.push_back(idx1); + shape->mesh.indices.push_back(idx2); + + shape->mesh.indices.push_back(idx0); + shape->mesh.indices.push_back(idx2); + shape->mesh.indices.push_back(idx3); + } else { + // [0, 1, 3], [1, 2, 3] + shape->mesh.indices.push_back(idx0); + shape->mesh.indices.push_back(idx1); + shape->mesh.indices.push_back(idx3); + + shape->mesh.indices.push_back(idx1); + shape->mesh.indices.push_back(idx2); + shape->mesh.indices.push_back(idx3); + } + + // Two triangle faces + shape->mesh.num_face_vertices.push_back(3); + shape->mesh.num_face_vertices.push_back(3); + + shape->mesh.material_ids.push_back(material_id); + shape->mesh.material_ids.push_back(material_id); + + shape->mesh.smoothing_group_ids.push_back(face.smoothing_group_id); + shape->mesh.smoothing_group_ids.push_back(face.smoothing_group_id); + + } else { +#ifdef TINYOBJLOADER_USE_MAPBOX_EARCUT + // Validate all vertex indices before accessing the vertex array. + { + bool valid_poly = true; + for (size_t k = 0; k < npolys; ++k) { + size_t vi = size_t(face.vertex_indices[k].v_idx); + if ((3 * vi + 2) >= v.size()) { + valid_poly = false; + break; + } + } + if (!valid_poly) { + if (warn) { + (*warn) += "Face with invalid vertex index found.\n"; + } + continue; + } + } + + vertex_index_t i0 = face.vertex_indices[0]; + vertex_index_t i0_2 = i0; + + // TMW change: Find the normal axis of the polygon using Newell's + // method + TinyObjPoint n; + for (size_t k = 0; k < npolys; ++k) { + i0 = face.vertex_indices[k % npolys]; + size_t vi0 = size_t(i0.v_idx); + + size_t j = (k + 1) % npolys; + i0_2 = face.vertex_indices[j]; + size_t vi0_2 = size_t(i0_2.v_idx); + + real_t v0x = v[vi0 * 3 + 0]; + real_t v0y = v[vi0 * 3 + 1]; + real_t v0z = v[vi0 * 3 + 2]; + + real_t v0x_2 = v[vi0_2 * 3 + 0]; + real_t v0y_2 = v[vi0_2 * 3 + 1]; + real_t v0z_2 = v[vi0_2 * 3 + 2]; + + const TinyObjPoint point1(v0x, v0y, v0z); + const TinyObjPoint point2(v0x_2, v0y_2, v0z_2); + + TinyObjPoint a(point1.x - point2.x, point1.y - point2.y, + point1.z - point2.z); + TinyObjPoint b(point1.x + point2.x, point1.y + point2.y, + point1.z + point2.z); + + n.x += (a.y * b.z); + n.y += (a.z * b.x); + n.z += (a.x * b.y); + } + real_t length_n = GetLength(n); + // Check if zero length normal + if (length_n <= 0) { + continue; + } + // Negative is to flip the normal to the correct direction + real_t inv_length = -real_t(1.0) / length_n; + n.x *= inv_length; + n.y *= inv_length; + n.z *= inv_length; + + TinyObjPoint axis_w, axis_v, axis_u; + axis_w = n; + TinyObjPoint a; + if (std::fabs(axis_w.x) > real_t(0.9999999)) { + a = TinyObjPoint(0, 1, 0); + } else { + a = TinyObjPoint(1, 0, 0); + } + axis_v = Normalize(cross(axis_w, a)); + axis_u = cross(axis_w, axis_v); + using Point = std::array; + + // first polyline define the main polygon. + // following polylines define holes(not used in tinyobj). + std::vector > polygon; + + std::vector polyline; + + // TMW change: Find best normal and project v0x and v0y to those + // coordinates, instead of picking a plane aligned with an axis (which + // can flip polygons). + + // Fill polygon data(facevarying vertices). + for (size_t k = 0; k < npolys; k++) { + i0 = face.vertex_indices[k]; + size_t vi0 = size_t(i0.v_idx); + + assert(((3 * vi0 + 2) < v.size())); + + real_t v0x = v[vi0 * 3 + 0]; + real_t v0y = v[vi0 * 3 + 1]; + real_t v0z = v[vi0 * 3 + 2]; + + TinyObjPoint polypoint(v0x, v0y, v0z); + TinyObjPoint loc = WorldToLocal(polypoint, axis_u, axis_v, axis_w); + + polyline.push_back({loc.x, loc.y}); + } + + polygon.push_back(polyline); + std::vector indices = mapbox::earcut(polygon); + // => result = 3 * faces, clockwise + + assert(indices.size() % 3 == 0); + + // Reconstruct vertex_index_t + for (size_t k = 0; k < indices.size() / 3; k++) { + { + index_t idx0, idx1, idx2; + idx0.vertex_index = face.vertex_indices[indices[3 * k + 0]].v_idx; + idx0.normal_index = + face.vertex_indices[indices[3 * k + 0]].vn_idx; + idx0.texcoord_index = + face.vertex_indices[indices[3 * k + 0]].vt_idx; + idx1.vertex_index = face.vertex_indices[indices[3 * k + 1]].v_idx; + idx1.normal_index = + face.vertex_indices[indices[3 * k + 1]].vn_idx; + idx1.texcoord_index = + face.vertex_indices[indices[3 * k + 1]].vt_idx; + idx2.vertex_index = face.vertex_indices[indices[3 * k + 2]].v_idx; + idx2.normal_index = + face.vertex_indices[indices[3 * k + 2]].vn_idx; + idx2.texcoord_index = + face.vertex_indices[indices[3 * k + 2]].vt_idx; + + shape->mesh.indices.push_back(idx0); + shape->mesh.indices.push_back(idx1); + shape->mesh.indices.push_back(idx2); + + shape->mesh.num_face_vertices.push_back(3); + shape->mesh.material_ids.push_back(material_id); + shape->mesh.smoothing_group_ids.push_back( + face.smoothing_group_id); + } + } + +#else // Built-in ear clipping triangulation + vertex_index_t i0 = face.vertex_indices[0]; + vertex_index_t i1(-1); + vertex_index_t i2 = face.vertex_indices[1]; + + // find the two axes to work in + size_t axes[2] = {1, 2}; + for (size_t k = 0; k < npolys; ++k) { + i0 = face.vertex_indices[(k + 0) % npolys]; + i1 = face.vertex_indices[(k + 1) % npolys]; + i2 = face.vertex_indices[(k + 2) % npolys]; + size_t vi0 = size_t(i0.v_idx); + size_t vi1 = size_t(i1.v_idx); + size_t vi2 = size_t(i2.v_idx); + + if (((3 * vi0 + 2) >= v.size()) || ((3 * vi1 + 2) >= v.size()) || + ((3 * vi2 + 2) >= v.size())) { + // Invalid triangle. + // FIXME(syoyo): Is it ok to simply skip this invalid triangle? + continue; + } + real_t v0x = v[vi0 * 3 + 0]; + real_t v0y = v[vi0 * 3 + 1]; + real_t v0z = v[vi0 * 3 + 2]; + real_t v1x = v[vi1 * 3 + 0]; + real_t v1y = v[vi1 * 3 + 1]; + real_t v1z = v[vi1 * 3 + 2]; + real_t v2x = v[vi2 * 3 + 0]; + real_t v2y = v[vi2 * 3 + 1]; + real_t v2z = v[vi2 * 3 + 2]; + real_t e0x = v1x - v0x; + real_t e0y = v1y - v0y; + real_t e0z = v1z - v0z; + real_t e1x = v2x - v1x; + real_t e1y = v2y - v1y; + real_t e1z = v2z - v1z; + real_t cx = std::fabs(e0y * e1z - e0z * e1y); + real_t cy = std::fabs(e0z * e1x - e0x * e1z); + real_t cz = std::fabs(e0x * e1y - e0y * e1x); + const real_t epsilon = std::numeric_limits::epsilon(); + // std::cout << "cx " << cx << ", cy " << cy << ", cz " << cz << + // "\n"; + if (cx > epsilon || cy > epsilon || cz > epsilon) { + // std::cout << "corner\n"; + // found a corner + if (cx > cy && cx > cz) { + // std::cout << "pattern0\n"; + } else { + // std::cout << "axes[0] = 0\n"; + axes[0] = 0; + if (cz > cx && cz > cy) { + // std::cout << "axes[1] = 1\n"; + axes[1] = 1; + } + } + break; + } + } + + face_t remainingFace = face; // copy + size_t guess_vert = 0; + vertex_index_t ind[3]; + real_t vx[3]; + real_t vy[3]; + + // How many iterations can we do without decreasing the remaining + // vertices. + size_t remainingIterations = face.vertex_indices.size(); + size_t previousRemainingVertices = + remainingFace.vertex_indices.size(); + + while (remainingFace.vertex_indices.size() > 3 && + remainingIterations > 0) { + // std::cout << "remainingIterations " << remainingIterations << + // "\n"; + + npolys = remainingFace.vertex_indices.size(); + if (guess_vert >= npolys) { + guess_vert -= npolys; + } + + if (previousRemainingVertices != npolys) { + // The number of remaining vertices decreased. Reset counters. + previousRemainingVertices = npolys; + remainingIterations = npolys; + } else { + // We didn't consume a vertex on previous iteration, reduce the + // available iterations. + remainingIterations--; + } + + for (size_t k = 0; k < 3; k++) { + ind[k] = remainingFace.vertex_indices[(guess_vert + k) % npolys]; + size_t vi = size_t(ind[k].v_idx); + if (((vi * 3 + axes[0]) >= v.size()) || + ((vi * 3 + axes[1]) >= v.size())) { + // ??? + vx[k] = static_cast(0.0); + vy[k] = static_cast(0.0); + } else { + vx[k] = v[vi * 3 + axes[0]]; + vy[k] = v[vi * 3 + axes[1]]; + } + } + + // + // area is calculated per face + // + real_t e0x = vx[1] - vx[0]; + real_t e0y = vy[1] - vy[0]; + real_t e1x = vx[2] - vx[1]; + real_t e1y = vy[2] - vy[1]; + real_t cross = e0x * e1y - e0y * e1x; + // std::cout << "axes = " << axes[0] << ", " << axes[1] << "\n"; + // std::cout << "e0x, e0y, e1x, e1y " << e0x << ", " << e0y << ", " + // << e1x << ", " << e1y << "\n"; + + real_t area = + (vx[0] * vy[1] - vy[0] * vx[1]) * static_cast(0.5); + // std::cout << "cross " << cross << ", area " << area << "\n"; + // if an internal angle + if (cross * area < static_cast(0.0)) { + // std::cout << "internal \n"; + guess_vert += 1; + // std::cout << "guess vert : " << guess_vert << "\n"; + continue; + } + + // check all other verts in case they are inside this triangle + bool overlap = false; + for (size_t otherVert = 3; otherVert < npolys; ++otherVert) { + size_t idx = (guess_vert + otherVert) % npolys; + + if (idx >= remainingFace.vertex_indices.size()) { + // std::cout << "???0\n"; + // ??? + continue; + } + + size_t ovi = size_t(remainingFace.vertex_indices[idx].v_idx); + + if (((ovi * 3 + axes[0]) >= v.size()) || + ((ovi * 3 + axes[1]) >= v.size())) { + // std::cout << "???1\n"; + // ??? + continue; + } + real_t tx = v[ovi * 3 + axes[0]]; + real_t ty = v[ovi * 3 + axes[1]]; + if (pnpoly(3, vx, vy, tx, ty)) { + // std::cout << "overlap\n"; + overlap = true; + break; + } + } + + if (overlap) { + // std::cout << "overlap2\n"; + guess_vert += 1; + continue; + } + + // this triangle is an ear + { + index_t idx0, idx1, idx2; + idx0.vertex_index = ind[0].v_idx; + idx0.normal_index = ind[0].vn_idx; + idx0.texcoord_index = ind[0].vt_idx; + idx1.vertex_index = ind[1].v_idx; + idx1.normal_index = ind[1].vn_idx; + idx1.texcoord_index = ind[1].vt_idx; + idx2.vertex_index = ind[2].v_idx; + idx2.normal_index = ind[2].vn_idx; + idx2.texcoord_index = ind[2].vt_idx; + + shape->mesh.indices.push_back(idx0); + shape->mesh.indices.push_back(idx1); + shape->mesh.indices.push_back(idx2); + + shape->mesh.num_face_vertices.push_back(3); + shape->mesh.material_ids.push_back(material_id); + shape->mesh.smoothing_group_ids.push_back( + face.smoothing_group_id); + } + + // remove v1 from the list + size_t removed_vert_index = (guess_vert + 1) % npolys; + while (removed_vert_index + 1 < npolys) { + remainingFace.vertex_indices[removed_vert_index] = + remainingFace.vertex_indices[removed_vert_index + 1]; + removed_vert_index += 1; + } + remainingFace.vertex_indices.pop_back(); + } + + // std::cout << "remainingFace.vi.size = " << + // remainingFace.vertex_indices.size() << "\n"; + if (remainingFace.vertex_indices.size() == 3) { + i0 = remainingFace.vertex_indices[0]; + i1 = remainingFace.vertex_indices[1]; + i2 = remainingFace.vertex_indices[2]; + { + index_t idx0, idx1, idx2; + idx0.vertex_index = i0.v_idx; + idx0.normal_index = i0.vn_idx; + idx0.texcoord_index = i0.vt_idx; + idx1.vertex_index = i1.v_idx; + idx1.normal_index = i1.vn_idx; + idx1.texcoord_index = i1.vt_idx; + idx2.vertex_index = i2.v_idx; + idx2.normal_index = i2.vn_idx; + idx2.texcoord_index = i2.vt_idx; + + shape->mesh.indices.push_back(idx0); + shape->mesh.indices.push_back(idx1); + shape->mesh.indices.push_back(idx2); + + shape->mesh.num_face_vertices.push_back(3); + shape->mesh.material_ids.push_back(material_id); + shape->mesh.smoothing_group_ids.push_back( + face.smoothing_group_id); + } + } +#endif + } // npolys + } else { + for (size_t k = 0; k < npolys; k++) { + index_t idx; + idx.vertex_index = face.vertex_indices[k].v_idx; + idx.normal_index = face.vertex_indices[k].vn_idx; + idx.texcoord_index = face.vertex_indices[k].vt_idx; + shape->mesh.indices.push_back(idx); + } + + shape->mesh.num_face_vertices.push_back( + static_cast(npolys)); + shape->mesh.material_ids.push_back(material_id); // per face + shape->mesh.smoothing_group_ids.push_back( + face.smoothing_group_id); // per face + } + } + + shape->mesh.tags = tags; + } + + // line + if (!prim_group.lineGroup.empty()) { + // Flatten indices + for (size_t i = 0; i < prim_group.lineGroup.size(); i++) { + for (size_t j = 0; j < prim_group.lineGroup[i].vertex_indices.size(); + j++) { + const vertex_index_t &vi = prim_group.lineGroup[i].vertex_indices[j]; + + index_t idx; + idx.vertex_index = vi.v_idx; + idx.normal_index = vi.vn_idx; + idx.texcoord_index = vi.vt_idx; + + shape->lines.indices.push_back(idx); + } + + shape->lines.num_line_vertices.push_back( + int(prim_group.lineGroup[i].vertex_indices.size())); + } + } + + // points + if (!prim_group.pointsGroup.empty()) { + // Flatten & convert indices + for (size_t i = 0; i < prim_group.pointsGroup.size(); i++) { + for (size_t j = 0; j < prim_group.pointsGroup[i].vertex_indices.size(); + j++) { + const vertex_index_t &vi = prim_group.pointsGroup[i].vertex_indices[j]; + + index_t idx; + idx.vertex_index = vi.v_idx; + idx.normal_index = vi.vn_idx; + idx.texcoord_index = vi.vt_idx; + + shape->points.indices.push_back(idx); + } + } + } + + return true; +} + +// Split a string with specified delimiter character and escape character. +// https://rosettacode.org/wiki/Tokenize_a_string_with_escaping#C.2B.2B +static void SplitString(const std::string &s, char delim, char escape, + std::vector &elems) { + std::string token; + + bool escaping = false; + for (size_t i = 0; i < s.size(); ++i) { + char ch = s[i]; + if (escaping) { + escaping = false; + } else if (ch == escape) { + if ((i + 1) < s.size()) { + const char next = s[i + 1]; + if ((next == delim) || (next == escape)) { + escaping = true; + continue; + } + } + } else if (ch == delim) { + if (!token.empty()) { + elems.push_back(token); + } + token.clear(); + continue; + } + token += ch; + } + + elems.push_back(token); +} + +static void RemoveEmptyTokens(std::vector *tokens) { + if (!tokens) return; + + const std::vector &src = *tokens; + std::vector filtered; + filtered.reserve(src.size()); + for (size_t i = 0; i < src.size(); i++) { + if (!src[i].empty()) { + filtered.push_back(src[i]); + } + } + tokens->swap(filtered); +} + +static std::string JoinPath(const std::string &dir, + const std::string &filename) { + if (dir.empty()) { + return filename; + } else { + // check '/' + char lastChar = *dir.rbegin(); + if (lastChar != '/') { + return dir + std::string("/") + filename; + } else { + return dir + filename; + } + } +} + +static bool LoadMtlInternal(std::map *material_map, + std::vector *materials, + StreamReader &sr, + std::string *warning, std::string *err, + const std::string &filename = "") { + if (sr.has_errors()) { + if (err) { + (*err) += sr.get_errors(); + } + return false; + } + + material_t material; + InitMaterial(&material); + + // Issue 43. `d` wins against `Tr` since `Tr` is not in the MTL specification. + bool has_d = false; + bool has_tr = false; + + // has_kd is used to set a default diffuse value when map_Kd is present + // and Kd is not. + bool has_kd = false; + + std::stringstream warn_ss; + + // Handle BOM + if (sr.remaining() >= 3 && + static_cast(sr.peek()) == 0xEF && + static_cast(sr.peek_at(1)) == 0xBB && + static_cast(sr.peek_at(2)) == 0xBF) { + sr.advance(3); + } + + while (!sr.eof()) { + sr.skip_space(); + if (sr.at_line_end()) { sr.skip_line(); continue; } + if (sr.peek() == '#') { sr.skip_line(); continue; } + + size_t line_num = sr.line_num(); + + // new mtl + if (sr.match("newmtl", 6) && (sr.peek_at(6) == ' ' || sr.peek_at(6) == '\t')) { + // flush previous material. + if (!material.name.empty()) { + material_map->insert(std::pair( + material.name, static_cast(materials->size()))); + materials->push_back(material); + } + + InitMaterial(&material); + + has_d = false; + has_tr = false; + has_kd = false; + + sr.advance(7); + { + std::string namebuf = sr_parseString(sr); + if (namebuf.empty()) { + if (warning) { + (*warning) += "empty material name in `newmtl`\n"; + } + } + material.name = namebuf; + } + sr.skip_line(); + continue; + } + + // ambient + if (sr.peek() == 'K' && sr.peek_at(1) == 'a' && (sr.peek_at(2) == ' ' || sr.peek_at(2) == '\t')) { + sr.advance(2); + real_t r, g, b; + if (!sr_parseReal3(&r, &g, &b, sr, err, filename)) return false; + material.ambient[0] = r; + material.ambient[1] = g; + material.ambient[2] = b; + sr.skip_line(); + continue; + } + + // diffuse + if (sr.peek() == 'K' && sr.peek_at(1) == 'd' && (sr.peek_at(2) == ' ' || sr.peek_at(2) == '\t')) { + sr.advance(2); + real_t r, g, b; + if (!sr_parseReal3(&r, &g, &b, sr, err, filename)) return false; + material.diffuse[0] = r; + material.diffuse[1] = g; + material.diffuse[2] = b; + has_kd = true; + sr.skip_line(); + continue; + } + + // specular + if (sr.peek() == 'K' && sr.peek_at(1) == 's' && (sr.peek_at(2) == ' ' || sr.peek_at(2) == '\t')) { + sr.advance(2); + real_t r, g, b; + if (!sr_parseReal3(&r, &g, &b, sr, err, filename)) return false; + material.specular[0] = r; + material.specular[1] = g; + material.specular[2] = b; + sr.skip_line(); + continue; + } + + // transmittance + if ((sr.peek() == 'K' && sr.peek_at(1) == 't' && (sr.peek_at(2) == ' ' || sr.peek_at(2) == '\t')) || + (sr.peek() == 'T' && sr.peek_at(1) == 'f' && (sr.peek_at(2) == ' ' || sr.peek_at(2) == '\t'))) { + sr.advance(2); + real_t r, g, b; + if (!sr_parseReal3(&r, &g, &b, sr, err, filename)) return false; + material.transmittance[0] = r; + material.transmittance[1] = g; + material.transmittance[2] = b; + sr.skip_line(); + continue; + } + + // ior(index of refraction) + if (sr.peek() == 'N' && sr.peek_at(1) == 'i' && (sr.peek_at(2) == ' ' || sr.peek_at(2) == '\t')) { + sr.advance(2); + if (!sr_parseReal(sr, &material.ior, 0.0, err, filename)) return false; + sr.skip_line(); + continue; + } + + // emission + if (sr.peek() == 'K' && sr.peek_at(1) == 'e' && (sr.peek_at(2) == ' ' || sr.peek_at(2) == '\t')) { + sr.advance(2); + real_t r, g, b; + if (!sr_parseReal3(&r, &g, &b, sr, err, filename)) return false; + material.emission[0] = r; + material.emission[1] = g; + material.emission[2] = b; + sr.skip_line(); + continue; + } + + // shininess + if (sr.peek() == 'N' && sr.peek_at(1) == 's' && (sr.peek_at(2) == ' ' || sr.peek_at(2) == '\t')) { + sr.advance(2); + if (!sr_parseReal(sr, &material.shininess, 0.0, err, filename)) return false; + sr.skip_line(); + continue; + } + + // illum model + if (sr.match("illum", 5) && (sr.peek_at(5) == ' ' || sr.peek_at(5) == '\t')) { + sr.advance(6); + if (!sr_parseInt(sr, &material.illum, err, filename)) return false; + sr.skip_line(); + continue; + } + + // dissolve + if (sr.peek() == 'd' && (sr.peek_at(1) == ' ' || sr.peek_at(1) == '\t')) { + sr.advance(1); + if (!sr_parseReal(sr, &material.dissolve, 0.0, err, filename)) return false; + + if (has_tr) { + warn_ss << "Both `d` and `Tr` parameters defined for \"" + << material.name + << "\". Use the value of `d` for dissolve (line " << line_num + << " in .mtl.)\n"; + } + has_d = true; + sr.skip_line(); + continue; + } + if (sr.peek() == 'T' && sr.peek_at(1) == 'r' && (sr.peek_at(2) == ' ' || sr.peek_at(2) == '\t')) { + sr.advance(2); + if (has_d) { + warn_ss << "Both `d` and `Tr` parameters defined for \"" + << material.name + << "\". Use the value of `d` for dissolve (line " << line_num + << " in .mtl.)\n"; + } else { + real_t tr_val; + if (!sr_parseReal(sr, &tr_val, 0.0, err, filename)) return false; + material.dissolve = static_cast(1.0) - tr_val; + } + has_tr = true; + sr.skip_line(); + continue; + } + + // PBR: roughness + if (sr.peek() == 'P' && sr.peek_at(1) == 'r' && (sr.peek_at(2) == ' ' || sr.peek_at(2) == '\t')) { + sr.advance(2); + if (!sr_parseReal(sr, &material.roughness, 0.0, err, filename)) return false; + sr.skip_line(); + continue; + } + + // PBR: metallic + if (sr.peek() == 'P' && sr.peek_at(1) == 'm' && (sr.peek_at(2) == ' ' || sr.peek_at(2) == '\t')) { + sr.advance(2); + if (!sr_parseReal(sr, &material.metallic, 0.0, err, filename)) return false; + sr.skip_line(); + continue; + } + + // PBR: sheen + if (sr.peek() == 'P' && sr.peek_at(1) == 's' && (sr.peek_at(2) == ' ' || sr.peek_at(2) == '\t')) { + sr.advance(2); + if (!sr_parseReal(sr, &material.sheen, 0.0, err, filename)) return false; + sr.skip_line(); + continue; + } + + // PBR: clearcoat thickness + if (sr.peek() == 'P' && sr.peek_at(1) == 'c' && (sr.peek_at(2) == ' ' || sr.peek_at(2) == '\t')) { + sr.advance(2); + if (!sr_parseReal(sr, &material.clearcoat_thickness, 0.0, err, filename)) return false; + sr.skip_line(); + continue; + } + + // PBR: clearcoat roughness + if (sr.match("Pcr", 3) && (sr.peek_at(3) == ' ' || sr.peek_at(3) == '\t')) { + sr.advance(4); + if (!sr_parseReal(sr, &material.clearcoat_roughness, 0.0, err, filename)) return false; + sr.skip_line(); + continue; + } + + // PBR: anisotropy + if (sr.match("aniso", 5) && (sr.peek_at(5) == ' ' || sr.peek_at(5) == '\t')) { + sr.advance(6); + if (!sr_parseReal(sr, &material.anisotropy, 0.0, err, filename)) return false; + sr.skip_line(); + continue; + } + + // PBR: anisotropy rotation + if (sr.match("anisor", 6) && (sr.peek_at(6) == ' ' || sr.peek_at(6) == '\t')) { + sr.advance(7); + if (!sr_parseReal(sr, &material.anisotropy_rotation, 0.0, err, filename)) return false; + sr.skip_line(); + continue; + } + + // For texture directives, read rest of line and delegate to + // ParseTextureNameAndOption (which uses the old const char* parse functions). + + // ambient or ambient occlusion texture + if (sr.match("map_Ka", 6) && (sr.peek_at(6) == ' ' || sr.peek_at(6) == '\t')) { + sr.advance(7); + std::string line_rest = trimTrailingWhitespace(sr.read_line()); + ParseTextureNameAndOption(&(material.ambient_texname), + &(material.ambient_texopt), line_rest.c_str()); + sr.skip_line(); + continue; + } + + // diffuse texture + if (sr.match("map_Kd", 6) && (sr.peek_at(6) == ' ' || sr.peek_at(6) == '\t')) { + sr.advance(7); + std::string line_rest = trimTrailingWhitespace(sr.read_line()); + ParseTextureNameAndOption(&(material.diffuse_texname), + &(material.diffuse_texopt), line_rest.c_str()); + if (!has_kd) { + material.diffuse[0] = static_cast(0.6); + material.diffuse[1] = static_cast(0.6); + material.diffuse[2] = static_cast(0.6); + } + sr.skip_line(); + continue; + } + + // specular texture + if (sr.match("map_Ks", 6) && (sr.peek_at(6) == ' ' || sr.peek_at(6) == '\t')) { + sr.advance(7); + std::string line_rest = trimTrailingWhitespace(sr.read_line()); + ParseTextureNameAndOption(&(material.specular_texname), + &(material.specular_texopt), line_rest.c_str()); + sr.skip_line(); + continue; + } + + // specular highlight texture + if (sr.match("map_Ns", 6) && (sr.peek_at(6) == ' ' || sr.peek_at(6) == '\t')) { + sr.advance(7); + std::string line_rest = trimTrailingWhitespace(sr.read_line()); + ParseTextureNameAndOption(&(material.specular_highlight_texname), + &(material.specular_highlight_texopt), line_rest.c_str()); + sr.skip_line(); + continue; + } + + // bump texture + if ((sr.match("map_bump", 8) || sr.match("map_Bump", 8)) && + (sr.peek_at(8) == ' ' || sr.peek_at(8) == '\t')) { + sr.advance(9); + std::string line_rest = trimTrailingWhitespace(sr.read_line()); + ParseTextureNameAndOption(&(material.bump_texname), + &(material.bump_texopt), line_rest.c_str()); + sr.skip_line(); + continue; + } + + // bump texture (short form) + if (sr.match("bump", 4) && (sr.peek_at(4) == ' ' || sr.peek_at(4) == '\t')) { + sr.advance(5); + std::string line_rest = trimTrailingWhitespace(sr.read_line()); + ParseTextureNameAndOption(&(material.bump_texname), + &(material.bump_texopt), line_rest.c_str()); + sr.skip_line(); + continue; + } + + // alpha texture + if (sr.match("map_d", 5) && (sr.peek_at(5) == ' ' || sr.peek_at(5) == '\t')) { + sr.advance(6); + std::string line_rest = trimTrailingWhitespace(sr.read_line()); + ParseTextureNameAndOption(&(material.alpha_texname), + &(material.alpha_texopt), line_rest.c_str()); + sr.skip_line(); + continue; + } + + // displacement texture + if ((sr.match("map_disp", 8) || sr.match("map_Disp", 8)) && + (sr.peek_at(8) == ' ' || sr.peek_at(8) == '\t')) { + sr.advance(9); + std::string line_rest = trimTrailingWhitespace(sr.read_line()); + ParseTextureNameAndOption(&(material.displacement_texname), + &(material.displacement_texopt), line_rest.c_str()); + sr.skip_line(); + continue; + } + + // displacement texture (short form) + if (sr.match("disp", 4) && (sr.peek_at(4) == ' ' || sr.peek_at(4) == '\t')) { + sr.advance(5); + std::string line_rest = trimTrailingWhitespace(sr.read_line()); + ParseTextureNameAndOption(&(material.displacement_texname), + &(material.displacement_texopt), line_rest.c_str()); + sr.skip_line(); + continue; + } + + // reflection map + if (sr.match("refl", 4) && (sr.peek_at(4) == ' ' || sr.peek_at(4) == '\t')) { + sr.advance(5); + std::string line_rest = trimTrailingWhitespace(sr.read_line()); + ParseTextureNameAndOption(&(material.reflection_texname), + &(material.reflection_texopt), line_rest.c_str()); + sr.skip_line(); + continue; + } + + // PBR: roughness texture + if (sr.match("map_Pr", 6) && (sr.peek_at(6) == ' ' || sr.peek_at(6) == '\t')) { + sr.advance(7); + std::string line_rest = trimTrailingWhitespace(sr.read_line()); + ParseTextureNameAndOption(&(material.roughness_texname), + &(material.roughness_texopt), line_rest.c_str()); + sr.skip_line(); + continue; + } + + // PBR: metallic texture + if (sr.match("map_Pm", 6) && (sr.peek_at(6) == ' ' || sr.peek_at(6) == '\t')) { + sr.advance(7); + std::string line_rest = trimTrailingWhitespace(sr.read_line()); + ParseTextureNameAndOption(&(material.metallic_texname), + &(material.metallic_texopt), line_rest.c_str()); + sr.skip_line(); + continue; + } + + // PBR: sheen texture + if (sr.match("map_Ps", 6) && (sr.peek_at(6) == ' ' || sr.peek_at(6) == '\t')) { + sr.advance(7); + std::string line_rest = trimTrailingWhitespace(sr.read_line()); + ParseTextureNameAndOption(&(material.sheen_texname), + &(material.sheen_texopt), line_rest.c_str()); + sr.skip_line(); + continue; + } + + // PBR: emissive texture + if (sr.match("map_Ke", 6) && (sr.peek_at(6) == ' ' || sr.peek_at(6) == '\t')) { + sr.advance(7); + std::string line_rest = trimTrailingWhitespace(sr.read_line()); + ParseTextureNameAndOption(&(material.emissive_texname), + &(material.emissive_texopt), line_rest.c_str()); + sr.skip_line(); + continue; + } + + // PBR: normal map texture + if (sr.match("norm", 4) && (sr.peek_at(4) == ' ' || sr.peek_at(4) == '\t')) { + sr.advance(5); + std::string line_rest = trimTrailingWhitespace(sr.read_line()); + ParseTextureNameAndOption(&(material.normal_texname), + &(material.normal_texopt), line_rest.c_str()); + sr.skip_line(); + continue; + } + + // unknown parameter + { + std::string line_rest = trimTrailingWhitespace(sr.read_line()); + const char *_lp = line_rest.c_str(); + const char *_space = strchr(_lp, ' '); + if (!_space) { + _space = strchr(_lp, '\t'); + } + if (_space) { + std::ptrdiff_t len = _space - _lp; + std::string key(_lp, static_cast(len)); + std::string value = _space + 1; + material.unknown_parameter.insert( + std::pair(key, value)); + } + } + sr.skip_line(); + } + // flush last material (only if it was actually defined). + if (!material.name.empty()) { + material_map->insert(std::pair( + material.name, static_cast(materials->size()))); + materials->push_back(material); + } + + if (warning) { + (*warning) += warn_ss.str(); + } + + return true; +} + +void LoadMtl(std::map *material_map, + std::vector *materials, std::istream *inStream, + std::string *warning, std::string *err) { + StreamReader sr(*inStream); + LoadMtlInternal(material_map, materials, sr, warning, err); +} + + +bool MaterialFileReader::operator()(const std::string &matId, + std::vector *materials, + std::map *matMap, + std::string *warn, std::string *err) { + if (!m_mtlBaseDir.empty()) { +#ifdef _WIN32 + char sep = ';'; +#else + char sep = ':'; +#endif + + // https://stackoverflow.com/questions/5167625/splitting-a-c-stdstring-using-tokens-e-g + std::vector paths; + std::istringstream f(m_mtlBaseDir); + + std::string s; + while (getline(f, s, sep)) { + paths.push_back(s); + } + + for (size_t i = 0; i < paths.size(); i++) { + std::string filepath = JoinPath(paths[i], matId); + +#ifdef TINYOBJLOADER_USE_MMAP + { + MappedFile mf; + if (!mf.open(filepath.c_str())) continue; + if (mf.size > TINYOBJLOADER_STREAM_READER_MAX_BYTES) { + if (err) { + std::stringstream ss; + ss << "input stream too large (" << mf.size + << " bytes exceeds limit " + << TINYOBJLOADER_STREAM_READER_MAX_BYTES << " bytes)\n"; + (*err) += ss.str(); + } + return false; + } + StreamReader sr(mf.data, mf.size); + return LoadMtlInternal(matMap, materials, sr, warn, err, filepath); + } +#else // !TINYOBJLOADER_USE_MMAP +#ifdef _WIN32 + std::ifstream matIStream(LongPathW(UTF8ToWchar(filepath)).c_str()); +#else + std::ifstream matIStream(filepath.c_str()); +#endif + if (matIStream) { + StreamReader mtl_sr(matIStream); + return LoadMtlInternal(matMap, materials, mtl_sr, warn, err, filepath); + } +#endif // TINYOBJLOADER_USE_MMAP + } + + std::stringstream ss; + ss << "Material file [ " << matId + << " ] not found in a path : " << m_mtlBaseDir << "\n"; + if (warn) { + (*warn) += ss.str(); + } + return false; + + } else { + std::string filepath = matId; + +#ifdef TINYOBJLOADER_USE_MMAP + { + MappedFile mf; + if (mf.open(filepath.c_str())) { + if (mf.size > TINYOBJLOADER_STREAM_READER_MAX_BYTES) { + if (err) { + std::stringstream ss; + ss << "input stream too large (" << mf.size + << " bytes exceeds limit " + << TINYOBJLOADER_STREAM_READER_MAX_BYTES << " bytes)\n"; + (*err) += ss.str(); + } + return false; + } + StreamReader sr(mf.data, mf.size); + return LoadMtlInternal(matMap, materials, sr, warn, err, filepath); + } + } +#else // !TINYOBJLOADER_USE_MMAP +#ifdef _WIN32 + std::ifstream matIStream(LongPathW(UTF8ToWchar(filepath)).c_str()); +#else + std::ifstream matIStream(filepath.c_str()); +#endif + if (matIStream) { + StreamReader mtl_sr(matIStream); + return LoadMtlInternal(matMap, materials, mtl_sr, warn, err, filepath); + } +#endif // TINYOBJLOADER_USE_MMAP + + std::stringstream ss; + ss << "Material file [ " << filepath + << " ] not found in a path : " << m_mtlBaseDir << "\n"; + if (warn) { + (*warn) += ss.str(); + } + + return false; + } +} + +bool MaterialStreamReader::operator()(const std::string &matId, + std::vector *materials, + std::map *matMap, + std::string *warn, std::string *err) { + (void)matId; + if (!m_inStream) { + std::stringstream ss; + ss << "Material stream in error state. \n"; + if (warn) { + (*warn) += ss.str(); + } + return false; + } + + StreamReader mtl_sr(m_inStream); + return LoadMtlInternal(matMap, materials, mtl_sr, warn, err, ""); +} + +static bool LoadObjInternal(attrib_t *attrib, std::vector *shapes, + std::vector *materials, + std::string *warn, std::string *err, + StreamReader &sr, + MaterialReader *readMatFn, bool triangulate, + bool default_vcols_fallback, + const std::string &filename = "") { + if (sr.has_errors()) { + if (err) { + (*err) += sr.get_errors(); + } + return false; + } + + std::vector v; + std::vector vertex_weights; + std::vector vn; + std::vector vt; + std::vector vt_w; // optional [w] component in `vt` + std::vector vc; + std::vector vw; + std::vector tags; + PrimGroup prim_group; + std::string name; + + // material + std::set material_filenames; + std::map material_map; + int material = -1; + + unsigned int current_smoothing_id = 0; + + int greatest_v_idx = -1; + int greatest_vn_idx = -1; + int greatest_vt_idx = -1; + + shape_t shape; + + bool found_all_colors = true; + + // Handle BOM + if (sr.remaining() >= 3 && + static_cast(sr.peek()) == 0xEF && + static_cast(sr.peek_at(1)) == 0xBB && + static_cast(sr.peek_at(2)) == 0xBF) { + sr.advance(3); + } + + warning_context context; + context.warn = warn; + context.filename = filename; + + while (!sr.eof()) { + sr.skip_space(); + if (sr.at_line_end()) { sr.skip_line(); continue; } + if (sr.peek() == '#') { sr.skip_line(); continue; } + + size_t line_num = sr.line_num(); + + // vertex + if (sr.peek() == 'v' && (sr.peek_at(1) == ' ' || sr.peek_at(1) == '\t')) { + sr.advance(2); + real_t x, y, z; + real_t r, g, b; + + int num_components = sr_parseVertexWithColor(&x, &y, &z, &r, &g, &b, sr, err, filename); + if (num_components < 0) return false; + found_all_colors &= (num_components == 6); + + v.push_back(x); + v.push_back(y); + v.push_back(z); + + vertex_weights.push_back(r); + + if ((num_components == 6) || default_vcols_fallback) { + vc.push_back(r); + vc.push_back(g); + vc.push_back(b); + } + + sr.skip_line(); + continue; + } + + // normal + if (sr.peek() == 'v' && sr.peek_at(1) == 'n' && (sr.peek_at(2) == ' ' || sr.peek_at(2) == '\t')) { + sr.advance(3); + real_t x, y, z; + if (!sr_parseReal3(&x, &y, &z, sr, err, filename)) return false; + vn.push_back(x); + vn.push_back(y); + vn.push_back(z); + sr.skip_line(); + continue; + } + + // texcoord + if (sr.peek() == 'v' && sr.peek_at(1) == 't' && (sr.peek_at(2) == ' ' || sr.peek_at(2) == '\t')) { + sr.advance(3); + real_t x, y; + if (!sr_parseReal2(&x, &y, sr, err, filename)) return false; + vt.push_back(x); + vt.push_back(y); + + // Parse optional w component + real_t w = static_cast(0.0); + sr_parseReal(sr, &w); + vt_w.push_back(w); + + sr.skip_line(); + continue; + } + + // skin weight. tinyobj extension + if (sr.peek() == 'v' && sr.peek_at(1) == 'w' && (sr.peek_at(2) == ' ' || sr.peek_at(2) == '\t')) { + sr.advance(3); + + int vid; + if (!sr_parseInt(sr, &vid, err, filename)) return false; + + skin_weight_t sw; + sw.vertex_id = vid; + + size_t vw_loop_max = sr.remaining() + 1; + size_t vw_loop_iter = 0; + while (!sr.at_line_end() && sr.peek() != '#' && + vw_loop_iter < vw_loop_max) { + real_t j, w; + sr_parseReal2(&j, &w, sr, -1.0); + + if (j < static_cast(0)) { + if (err) { + (*err) += sr.format_error(filename, + "failed to parse `vw' line: joint_id is negative"); + } + return false; + } + + joint_and_weight_t jw; + jw.joint_id = int(j); + jw.weight = w; + + sw.weightValues.push_back(jw); + sr.skip_space_and_cr(); + vw_loop_iter++; + } + + vw.push_back(sw); + sr.skip_line(); + continue; + } + + context.line_number = line_num; + + // line + if (sr.peek() == 'l' && (sr.peek_at(1) == ' ' || sr.peek_at(1) == '\t')) { + sr.advance(2); + + __line_t line; + + size_t l_loop_max = sr.remaining() + 1; + size_t l_loop_iter = 0; + while (!sr.at_line_end() && sr.peek() != '#' && + l_loop_iter < l_loop_max) { + vertex_index_t vi; + if (!sr_parseTriple(sr, size_to_int(v.size() / 3), + size_to_int(vn.size() / 3), + size_to_int(vt.size() / 2), &vi, context)) { + if (err) { + (*err) += sr.format_error(filename, + "failed to parse `l' line (invalid vertex index)"); + } + return false; + } + + line.vertex_indices.push_back(vi); + sr.skip_space_and_cr(); + l_loop_iter++; + } + + prim_group.lineGroup.push_back(line); + sr.skip_line(); + continue; + } + + // points + if (sr.peek() == 'p' && (sr.peek_at(1) == ' ' || sr.peek_at(1) == '\t')) { + sr.advance(2); + + __points_t pts; + + size_t p_loop_max = sr.remaining() + 1; + size_t p_loop_iter = 0; + while (!sr.at_line_end() && sr.peek() != '#' && + p_loop_iter < p_loop_max) { + vertex_index_t vi; + if (!sr_parseTriple(sr, size_to_int(v.size() / 3), + size_to_int(vn.size() / 3), + size_to_int(vt.size() / 2), &vi, context)) { + if (err) { + (*err) += sr.format_error(filename, + "failed to parse `p' line (invalid vertex index)"); + } + return false; + } + + pts.vertex_indices.push_back(vi); + sr.skip_space_and_cr(); + p_loop_iter++; + } + + prim_group.pointsGroup.push_back(pts); + sr.skip_line(); + continue; + } + + // face + if (sr.peek() == 'f' && (sr.peek_at(1) == ' ' || sr.peek_at(1) == '\t')) { + sr.advance(2); + sr.skip_space(); + + face_t face; + + face.smoothing_group_id = current_smoothing_id; + face.vertex_indices.reserve(3); + + size_t f_loop_max = sr.remaining() + 1; + size_t f_loop_iter = 0; + while (!sr.at_line_end() && sr.peek() != '#' && + f_loop_iter < f_loop_max) { + vertex_index_t vi; + if (!sr_parseTriple(sr, size_to_int(v.size() / 3), + size_to_int(vn.size() / 3), + size_to_int(vt.size() / 2), &vi, context)) { + if (err) { + (*err) += sr.format_error(filename, + "failed to parse `f' line (invalid vertex index)"); + } + return false; + } + + greatest_v_idx = greatest_v_idx > vi.v_idx ? greatest_v_idx : vi.v_idx; + greatest_vn_idx = + greatest_vn_idx > vi.vn_idx ? greatest_vn_idx : vi.vn_idx; + greatest_vt_idx = + greatest_vt_idx > vi.vt_idx ? greatest_vt_idx : vi.vt_idx; + + face.vertex_indices.push_back(vi); + sr.skip_space_and_cr(); + f_loop_iter++; + } + + prim_group.faceGroup.push_back(face); + sr.skip_line(); + continue; + } + + // use mtl + if (sr.match("usemtl", 6) && (sr.peek_at(6) == ' ' || sr.peek_at(6) == '\t')) { + sr.advance(6); + std::string namebuf = sr_parseString(sr); + + int newMaterialId = -1; + std::map::const_iterator it = + material_map.find(namebuf); + if (it != material_map.end()) { + newMaterialId = it->second; + } else { + if (warn) { + (*warn) += "material [ '" + namebuf + "' ] not found in .mtl\n"; + } + } + + if (newMaterialId != material) { + exportGroupsToShape(&shape, prim_group, tags, material, name, + triangulate, v, warn); + prim_group.faceGroup.clear(); + material = newMaterialId; + } + + sr.skip_line(); + continue; + } + + // load mtl + if (sr.match("mtllib", 6) && (sr.peek_at(6) == ' ' || sr.peek_at(6) == '\t')) { + if (readMatFn) { + sr.advance(7); + + std::string line_rest = trimTrailingWhitespace(sr.read_line()); + std::vector filenames; + SplitString(line_rest, ' ', '\\', filenames); + RemoveEmptyTokens(&filenames); + + if (filenames.empty()) { + if (warn) { + std::stringstream ss; + ss << "Looks like empty filename for mtllib. Use default " + "material (line " + << line_num << ".)\n"; + + (*warn) += ss.str(); + } + } else { + bool found = false; + for (size_t s = 0; s < filenames.size(); s++) { + if (material_filenames.count(filenames[s]) > 0) { + found = true; + continue; + } + + std::string warn_mtl; + std::string err_mtl; + bool ok = (*readMatFn)(filenames[s].c_str(), materials, + &material_map, &warn_mtl, &err_mtl); + if (warn && (!warn_mtl.empty())) { + (*warn) += warn_mtl; + } + + if (err && (!err_mtl.empty())) { + (*err) += err_mtl; + } + + if (ok) { + found = true; + material_filenames.insert(filenames[s]); + break; + } + } + + if (!found) { + if (warn) { + (*warn) += + "Failed to load material file(s). Use default " + "material.\n"; + } + } + } + } + + sr.skip_line(); + continue; + } + + // group name + if (sr.peek() == 'g' && (sr.peek_at(1) == ' ' || sr.peek_at(1) == '\t')) { + // flush previous face group. + bool ret = exportGroupsToShape(&shape, prim_group, tags, material, name, + triangulate, v, warn); + (void)ret; + + if (shape.mesh.indices.size() > 0) { + shapes->push_back(shape); + } + + shape = shape_t(); + + // material = -1; + prim_group.clear(); + + std::vector names; + + size_t g_loop_max = sr.remaining() + 1; + size_t g_loop_iter = 0; + while (!sr.at_line_end() && sr.peek() != '#' && + g_loop_iter < g_loop_max) { + std::string str = sr_parseString(sr); + names.push_back(str); + sr.skip_space_and_cr(); + g_loop_iter++; + } + + // names[0] must be 'g' + + if (names.size() < 2) { + // 'g' with empty names + if (warn) { + std::stringstream ss; + ss << "Empty group name. line: " << line_num << "\n"; + (*warn) += ss.str(); + name = ""; + } + } else { + std::stringstream ss; + ss << names[1]; + + for (size_t i = 2; i < names.size(); i++) { + ss << " " << names[i]; + } + + name = ss.str(); + } + + sr.skip_line(); + continue; + } + + // object name + if (sr.peek() == 'o' && (sr.peek_at(1) == ' ' || sr.peek_at(1) == '\t')) { + // flush previous face group. + bool ret = exportGroupsToShape(&shape, prim_group, tags, material, name, + triangulate, v, warn); + (void)ret; + + if (shape.mesh.indices.size() > 0 || shape.lines.indices.size() > 0 || + shape.points.indices.size() > 0) { + shapes->push_back(shape); + } + + // material = -1; + prim_group.clear(); + shape = shape_t(); + + sr.advance(2); + std::string rest = sr.read_line(); + name = rest; + + sr.skip_line(); + continue; + } + + if (sr.peek() == 't' && (sr.peek_at(1) == ' ' || sr.peek_at(1) == '\t')) { + const int max_tag_nums = 8192; + tag_t tag; + + sr.advance(2); + + tag.name = sr_parseString(sr); + + tag_sizes ts = sr_parseTagTriple(sr); + + if (ts.num_ints < 0) { + ts.num_ints = 0; + } + if (ts.num_ints > max_tag_nums) { + ts.num_ints = max_tag_nums; + } + + if (ts.num_reals < 0) { + ts.num_reals = 0; + } + if (ts.num_reals > max_tag_nums) { + ts.num_reals = max_tag_nums; + } + + if (ts.num_strings < 0) { + ts.num_strings = 0; + } + if (ts.num_strings > max_tag_nums) { + ts.num_strings = max_tag_nums; + } + + tag.intValues.resize(static_cast(ts.num_ints)); + + for (size_t i = 0; i < static_cast(ts.num_ints); ++i) { + tag.intValues[i] = sr_parseInt(sr); + } + + tag.floatValues.resize(static_cast(ts.num_reals)); + for (size_t i = 0; i < static_cast(ts.num_reals); ++i) { + tag.floatValues[i] = sr_parseReal(sr); + } + + tag.stringValues.resize(static_cast(ts.num_strings)); + for (size_t i = 0; i < static_cast(ts.num_strings); ++i) { + tag.stringValues[i] = sr_parseString(sr); + } + + tags.push_back(tag); + + sr.skip_line(); + continue; + } + + if (sr.peek() == 's' && (sr.peek_at(1) == ' ' || sr.peek_at(1) == '\t')) { + // smoothing group id + sr.advance(2); + sr.skip_space(); + + if (sr.at_line_end()) { + sr.skip_line(); + continue; + } + + if (sr.peek() == '\r') { + sr.skip_line(); + continue; + } + + if (sr.remaining() >= 3 && sr.match("off", 3)) { + current_smoothing_id = 0; + } else { + int smGroupId = sr_parseInt(sr); + if (smGroupId < 0) { + current_smoothing_id = 0; + } else { + current_smoothing_id = static_cast(smGroupId); + } + } + + sr.skip_line(); + continue; + } + + // Ignore unknown command. + sr.skip_line(); + } + + // not all vertices have colors, no default colors desired? -> clear colors + if (!found_all_colors && !default_vcols_fallback) { + vc.clear(); + } + + if (greatest_v_idx >= size_to_int(v.size() / 3)) { + if (warn) { + std::stringstream ss; + ss << "Vertex indices out of bounds (line " << sr.line_num() << ".)\n\n"; + (*warn) += ss.str(); + } + } + if (greatest_vn_idx >= size_to_int(vn.size() / 3)) { + if (warn) { + std::stringstream ss; + ss << "Vertex normal indices out of bounds (line " << sr.line_num() + << ".)\n\n"; + (*warn) += ss.str(); + } + } + if (greatest_vt_idx >= size_to_int(vt.size() / 2)) { + if (warn) { + std::stringstream ss; + ss << "Vertex texcoord indices out of bounds (line " << sr.line_num() + << ".)\n\n"; + (*warn) += ss.str(); + } + } + + bool ret = exportGroupsToShape(&shape, prim_group, tags, material, name, + triangulate, v, warn); + if (ret || shape.mesh.indices.size()) { + shapes->push_back(shape); + } + prim_group.clear(); + + attrib->vertices.swap(v); + attrib->vertex_weights.swap(vertex_weights); + attrib->normals.swap(vn); + attrib->texcoords.swap(vt); + attrib->texcoord_ws.swap(vt_w); + attrib->colors.swap(vc); + attrib->skin_weights.swap(vw); + + return true; +} + +bool LoadObj(attrib_t *attrib, std::vector *shapes, + std::vector *materials, std::string *warn, + std::string *err, const char *filename, const char *mtl_basedir, + bool triangulate, bool default_vcols_fallback) { + attrib->vertices.clear(); + attrib->vertex_weights.clear(); + attrib->normals.clear(); + attrib->texcoords.clear(); + attrib->texcoord_ws.clear(); + attrib->colors.clear(); + attrib->skin_weights.clear(); + shapes->clear(); + + std::string baseDir = mtl_basedir ? mtl_basedir : ""; + if (!baseDir.empty()) { +#ifndef _WIN32 + const char dirsep = '/'; +#else + const char dirsep = '\\'; +#endif + if (baseDir[baseDir.length() - 1] != dirsep) baseDir += dirsep; + } + MaterialFileReader matFileReader(baseDir); + +#ifdef TINYOBJLOADER_USE_MMAP + { + MappedFile mf; + if (!mf.open(filename)) { + if (err) { + std::stringstream ss; + ss << "Cannot open file [" << filename << "]\n"; + (*err) = ss.str(); + } + return false; + } + if (mf.size > TINYOBJLOADER_STREAM_READER_MAX_BYTES) { + if (err) { + std::stringstream ss; + ss << "input stream too large (" << mf.size + << " bytes exceeds limit " + << TINYOBJLOADER_STREAM_READER_MAX_BYTES << " bytes)\n"; + (*err) += ss.str(); + } + return false; + } + StreamReader sr(mf.data, mf.size); + return LoadObjInternal(attrib, shapes, materials, warn, err, sr, + &matFileReader, triangulate, default_vcols_fallback, + filename); + } +#else // !TINYOBJLOADER_USE_MMAP +#ifdef _WIN32 + std::ifstream ifs(LongPathW(UTF8ToWchar(filename)).c_str()); +#else + std::ifstream ifs(filename); +#endif + if (!ifs) { + if (err) { + std::stringstream ss; + ss << "Cannot open file [" << filename << "]\n"; + (*err) = ss.str(); + } + return false; + } + { + StreamReader sr(ifs); + return LoadObjInternal(attrib, shapes, materials, warn, err, sr, + &matFileReader, triangulate, default_vcols_fallback, + filename); + } +#endif // TINYOBJLOADER_USE_MMAP +} + +bool LoadObj(attrib_t *attrib, std::vector *shapes, + std::vector *materials, std::string *warn, + std::string *err, std::istream *inStream, + MaterialReader *readMatFn /*= NULL*/, bool triangulate, + bool default_vcols_fallback) { + attrib->vertices.clear(); + attrib->vertex_weights.clear(); + attrib->normals.clear(); + attrib->texcoords.clear(); + attrib->texcoord_ws.clear(); + attrib->colors.clear(); + attrib->skin_weights.clear(); + shapes->clear(); + + StreamReader sr(*inStream); + return LoadObjInternal(attrib, shapes, materials, warn, err, sr, + readMatFn, triangulate, default_vcols_fallback); +} + + +static bool LoadObjWithCallbackInternal(StreamReader &sr, + const callback_t &callback, + void *user_data, + MaterialReader *readMatFn, + std::string *warn, + std::string *err) { + if (sr.has_errors()) { + if (err) { + (*err) += sr.get_errors(); + } + return false; + } + + // material + std::set material_filenames; + std::map material_map; + int material_id = -1; + + std::vector indices; + std::vector materials; + std::vector names; + names.reserve(2); + std::vector names_out; + + // Handle BOM + if (sr.remaining() >= 3 && + static_cast(sr.peek()) == 0xEF && + static_cast(sr.peek_at(1)) == 0xBB && + static_cast(sr.peek_at(2)) == 0xBF) { + sr.advance(3); + } + + while (!sr.eof()) { + sr.skip_space(); + if (sr.at_line_end()) { sr.skip_line(); continue; } + if (sr.peek() == '#') { sr.skip_line(); continue; } + + // vertex + if (sr.peek() == 'v' && (sr.peek_at(1) == ' ' || sr.peek_at(1) == '\t')) { + sr.advance(2); + real_t x, y, z; + real_t r, g, b; + + int num_components = sr_parseVertexWithColor(&x, &y, &z, &r, &g, &b, sr, err, std::string()); + if (num_components < 0) { + return false; + } + if (callback.vertex_cb) { + callback.vertex_cb(user_data, x, y, z, r); + } + if (callback.vertex_color_cb) { + bool found_color = (num_components == 6); + callback.vertex_color_cb(user_data, x, y, z, r, g, b, found_color); + } + sr.skip_line(); + continue; + } + + // normal + if (sr.peek() == 'v' && sr.peek_at(1) == 'n' && (sr.peek_at(2) == ' ' || sr.peek_at(2) == '\t')) { + sr.advance(3); + real_t x, y, z; + sr_parseReal3(&x, &y, &z, sr); + if (callback.normal_cb) { + callback.normal_cb(user_data, x, y, z); + } + sr.skip_line(); + continue; + } + + // texcoord + if (sr.peek() == 'v' && sr.peek_at(1) == 't' && (sr.peek_at(2) == ' ' || sr.peek_at(2) == '\t')) { + sr.advance(3); + real_t x, y, z; + sr_parseReal3(&x, &y, &z, sr); + if (callback.texcoord_cb) { + callback.texcoord_cb(user_data, x, y, z); + } + sr.skip_line(); + continue; + } + + // face + if (sr.peek() == 'f' && (sr.peek_at(1) == ' ' || sr.peek_at(1) == '\t')) { + sr.advance(2); + sr.skip_space(); + + indices.clear(); + size_t cf_loop_max = sr.remaining() + 1; + size_t cf_loop_iter = 0; + while (!sr.at_line_end() && sr.peek() != '#' && + cf_loop_iter < cf_loop_max) { + vertex_index_t vi = sr_parseRawTriple(sr); + + index_t idx; + idx.vertex_index = vi.v_idx; + idx.normal_index = vi.vn_idx; + idx.texcoord_index = vi.vt_idx; + + indices.push_back(idx); + sr.skip_space_and_cr(); + cf_loop_iter++; + } + + if (callback.index_cb && indices.size() > 0) { + callback.index_cb(user_data, &indices.at(0), + static_cast(indices.size())); + } + + sr.skip_line(); + continue; + } + + // use mtl + if (sr.match("usemtl", 6) && (sr.peek_at(6) == ' ' || sr.peek_at(6) == '\t')) { + sr.advance(6); + std::string namebuf = sr_parseString(sr); + + int newMaterialId = -1; + std::map::const_iterator it = + material_map.find(namebuf); + if (it != material_map.end()) { + newMaterialId = it->second; + } else { + if (warn && (!callback.usemtl_cb)) { + (*warn) += "material [ " + namebuf + " ] not found in .mtl\n"; + } + } + + if (newMaterialId != material_id) { + material_id = newMaterialId; + } + + if (callback.usemtl_cb) { + callback.usemtl_cb(user_data, namebuf.c_str(), material_id); + } + + sr.skip_line(); + continue; + } + + // load mtl + if (sr.match("mtllib", 6) && (sr.peek_at(6) == ' ' || sr.peek_at(6) == '\t')) { + if (readMatFn) { + sr.advance(7); + + std::string line_rest = trimTrailingWhitespace(sr.read_line()); + std::vector filenames; + SplitString(line_rest, ' ', '\\', filenames); + RemoveEmptyTokens(&filenames); + + if (filenames.empty()) { + if (warn) { + (*warn) += + "Looks like empty filename for mtllib. Use default " + "material. \n"; + } + } else { + bool found = false; + for (size_t s = 0; s < filenames.size(); s++) { + if (material_filenames.count(filenames[s]) > 0) { + found = true; + continue; + } + + std::string warn_mtl; + std::string err_mtl; + bool ok = (*readMatFn)(filenames[s].c_str(), &materials, + &material_map, &warn_mtl, &err_mtl); + + if (warn && (!warn_mtl.empty())) { + (*warn) += warn_mtl; + } + + if (err && (!err_mtl.empty())) { + (*err) += err_mtl; + } + + if (ok) { + found = true; + material_filenames.insert(filenames[s]); + break; + } + } + + if (!found) { + if (warn) { + (*warn) += + "Failed to load material file(s). Use default " + "material.\n"; + } + } else { + if (callback.mtllib_cb && !materials.empty()) { + callback.mtllib_cb(user_data, &materials.at(0), + static_cast(materials.size())); + } + } + } + } + + sr.skip_line(); + continue; + } + + // group name + if (sr.peek() == 'g' && (sr.peek_at(1) == ' ' || sr.peek_at(1) == '\t')) { + names.clear(); + + size_t cg_loop_max = sr.remaining() + 1; + size_t cg_loop_iter = 0; + while (!sr.at_line_end() && sr.peek() != '#' && + cg_loop_iter < cg_loop_max) { + std::string str = sr_parseString(sr); + names.push_back(str); + sr.skip_space_and_cr(); + cg_loop_iter++; + } + + assert(names.size() > 0); + + if (callback.group_cb) { + if (names.size() > 1) { + names_out.resize(names.size() - 1); + for (size_t j = 0; j < names_out.size(); j++) { + names_out[j] = names[j + 1].c_str(); + } + callback.group_cb(user_data, &names_out.at(0), + static_cast(names_out.size())); + + } else { + callback.group_cb(user_data, NULL, 0); + } + } + + sr.skip_line(); + continue; + } + + // object name + if (sr.peek() == 'o' && (sr.peek_at(1) == ' ' || sr.peek_at(1) == '\t')) { + sr.advance(2); + std::string object_name = sr.read_line(); + + if (callback.object_cb) { + callback.object_cb(user_data, object_name.c_str()); + } + + sr.skip_line(); + continue; + } + +#if 0 // @todo + if (sr.peek() == 't' && (sr.peek_at(1) == ' ' || sr.peek_at(1) == '\t')) { + tag_t tag; + + sr.advance(2); + tag.name = sr_parseString(sr); + + tag_sizes ts = sr_parseTagTriple(sr); + + tag.intValues.resize(static_cast(ts.num_ints)); + + for (size_t i = 0; i < static_cast(ts.num_ints); ++i) { + tag.intValues[i] = sr_parseInt(sr); + } + + tag.floatValues.resize(static_cast(ts.num_reals)); + for (size_t i = 0; i < static_cast(ts.num_reals); ++i) { + tag.floatValues[i] = sr_parseReal(sr); + } + + tag.stringValues.resize(static_cast(ts.num_strings)); + for (size_t i = 0; i < static_cast(ts.num_strings); ++i) { + tag.stringValues[i] = sr_parseString(sr); + } + + tags.push_back(tag); + } +#endif + + // Ignore unknown command. + sr.skip_line(); + } + + return true; +} + +bool LoadObjWithCallback(std::istream &inStream, const callback_t &callback, + void *user_data /*= NULL*/, + MaterialReader *readMatFn /*= NULL*/, + std::string *warn, /* = NULL*/ + std::string *err /*= NULL*/) { + StreamReader sr(inStream); + return LoadObjWithCallbackInternal(sr, callback, user_data, readMatFn, + warn, err); +} + +bool ObjReader::ParseFromFile(const std::string &filename, + const ObjReaderConfig &config) { + std::string mtl_search_path; + + if (config.mtl_search_path.empty()) { + // + // split at last '/'(for unixish system) or '\\'(for windows) to get + // the base directory of .obj file + // + size_t pos = filename.find_last_of("/\\"); + if (pos != std::string::npos) { + mtl_search_path = filename.substr(0, pos); + } + } else { + mtl_search_path = config.mtl_search_path; + } + + valid_ = LoadObj(&attrib_, &shapes_, &materials_, &warning_, &error_, + filename.c_str(), mtl_search_path.c_str(), + config.triangulate, config.vertex_color); + + return valid_; +} + +bool ObjReader::ParseFromString(const std::string &obj_text, + const std::string &mtl_text, + const ObjReaderConfig &config) { + std::stringbuf obj_buf(obj_text); + std::stringbuf mtl_buf(mtl_text); + + std::istream obj_ifs(&obj_buf); + std::istream mtl_ifs(&mtl_buf); + + MaterialStreamReader mtl_ss(mtl_ifs); + + valid_ = LoadObj(&attrib_, &shapes_, &materials_, &warning_, &error_, + &obj_ifs, &mtl_ss, config.triangulate, config.vertex_color); + + return valid_; +} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif +} // namespace tinyobj + +#endif \ No newline at end of file diff --git a/src/types.h b/src/types.h new file mode 100644 index 0000000..2315cbd --- /dev/null +++ b/src/types.h @@ -0,0 +1,17 @@ +#pragma once +#include + +using namespace glm; + +struct Vertex { + vec3 pos; + vec4 color; + vec3 normal; +}; + +struct CameraUBO { + mat4 model; + mat4 view; + mat4 proj; + float time; +};